You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by rv...@apache.org on 2015/04/28 23:40:06 UTC

[01/51] [partial] incubator-geode git commit: Init

Repository: incubator-geode
Updated Branches:
  refs/heads/master [created] 194590531


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/control/ResourceManager.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/control/ResourceManager.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/control/ResourceManager.java
new file mode 100644
index 0000000..d7ec83c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/control/ResourceManager.java
@@ -0,0 +1,176 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache.control;
+
+import java.util.Set;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.EvictionAttributes;
+import com.gemstone.gemfire.cache.LowMemoryException;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.execute.Function;
+import com.gemstone.gemfire.cache.query.QueryService;
+import com.gemstone.gemfire.cache.server.CacheServer;
+
+/**
+ * Provides support for managing resources used by the local
+ * {@link com.gemstone.gemfire.cache GemFire Cache}.
+ * <p>
+ * Re-balancing the GemFire Cache resources can be accomplished using a {@link
+ * RebalanceOperation}:
+ * <pre>
+ * ResourceManager resourceManager = cache.getResourceManager();
+ * RebalanceOperation rebalanceOp = resourceManager.createRebalanceFactory().start();
+ * </pre>
+ * Monitoring of heap utilization is enabled by setting the critical heap
+ * percentage using {@link #setCriticalHeapPercentage(float)}.
+ * 
+ * @since 6.0
+ */
+public interface ResourceManager {
+  
+  /**
+   * The default percent of heap memory at which the VM is considered in a 
+   * critical state. Current value is <code>0.0</code>.
+   * 
+   * @see ResourceManager#setCriticalHeapPercentage(float)
+   * @see ResourceManager#getCriticalHeapPercentage()
+   */
+  public static final float DEFAULT_CRITICAL_HEAP_PERCENTAGE = 0.0f;
+
+  /**
+   * The default percent of heap memory at which the VM should begin evicting
+   * data. Current value is <code>0.0</code>.
+   * Note that if a HeapLRU is created and the eviction heap percentage has not
+   * been set then it will default <code>80.0</code> unless the critical heap percentage
+   * has been set in which case it will default to a value <code>5.0</code> less than
+   * the critical heap percentage.
+   * 
+   * @see ResourceManager#setEvictionHeapPercentage(float)
+   * @see ResourceManager#getEvictionHeapPercentage()
+   */
+  public static final float DEFAULT_EVICTION_HEAP_PERCENTAGE = 0.0f;
+  
+  /**
+   * Creates a factory for defining and starting {@link RebalanceOperation
+   * RebalanceOperations}.
+   * 
+   * @return a factory for defining and starting RebalanceOperations
+   */
+  public RebalanceFactory createRebalanceFactory();
+  
+  /**
+   * Returns a set of all active {@link RebalanceOperation
+   * RebalanceOperations} that were started locally on this member.
+   *
+   * @return a set of all active RebalanceOperations started locally
+   */
+  public Set<RebalanceOperation> getRebalanceOperations();
+
+  /**
+   * Set the percentage of heap at or above which the cache is considered in
+   * danger of becoming inoperable due to garbage collection pauses or out of
+   * memory exceptions.
+   *
+   * <p>
+   * Changing this value can cause {@link LowMemoryException} to be thrown from
+   * the following {@link Cache} operations:
+   * <ul>
+   * <li>{@link Region#put(Object, Object)}
+   * <li>{@link Region#put(Object, Object, Object)}
+   * <li>{@link Region#create(Object, Object)}
+   * <li>{@link Region#create(Object, Object, Object)}
+   * <li>{@link Region#putAll(java.util.Map)}
+   * <li>{@linkplain QueryService#createIndex(String, com.gemstone.gemfire.cache.query.IndexType, String, String) index creation}
+   * <li>Execution of {@link Function}s whose {@link Function#optimizeForWrite()} returns true.
+   * </ul>
+   *
+   * <p>
+   * Only one change to this attribute or the eviction heap percentage will be
+   * allowed at any given time and its effect will be fully realized before the
+   * next change is allowed.
+   * 
+   * When using this threshold, the VM must be launched with the <code>-Xmx</code> and
+   * <code>-Xms</code> switches set to the same values. Many virtual machine implementations
+   * have additional VM switches to control the behavior of the garbage
+   * collector. We suggest that you investigate tuning the garbage collector
+   * when using this type of eviction controller.  A collector that frequently
+   * collects is needed to keep our heap usage up to date. 
+   * In particular, on the Sun <A href="http://java.sun.com/docs/hotspot/gc/index.html">HotSpot</a> VM, the
+   * <code>-XX:+UseConcMarkSweepGC</code> flag needs to be set, and 
+   * <code>-XX:CMSInitiatingOccupancyFraction=N</code> should be set with N being a percentage 
+   * that is less than the {@link ResourceManager} critical and eviction heap thresholds.
+   * 
+   * The JRockit VM has similar flags, <code>-Xgc:gencon</code> and <code>-XXgcTrigger:N</code>, which are 
+   * required if using this feature. Please Note: the JRockit gcTrigger flag is based on heap free, not
+   * heap in use like the GemFire parameter. This means you need to set gcTrigger to 100-N. for example, if your
+   * eviction threshold is 30 percent, you will need to set gcTrigger to 70 percent.
+   * 
+   * On the IBM VM, the flag to get a similar collector is <code>-Xgcpolicy:gencon</code>, but there is no 
+   * corollary to the gcTrigger/CMSInitiatingOccupancyFraction flags, so when using this feature with an
+   * IBM VM, the heap usage statistics might lag the true memory usage of the VM, and thresholds may need
+   * to be set sufficiently high that the VM will initiate GC before the thresholds are crossed. 
+   *
+   * @param heapPercentage a percentage of the maximum tenured heap for the VM
+   * @throws IllegalStateException if the heapPercentage value is not >= 0 or
+   * <= 100 or when less than the current eviction heap percentage
+   * @see #getCriticalHeapPercentage()
+   * @see #getEvictionHeapPercentage()
+   * @since 6.0
+   */
+  public void setCriticalHeapPercentage(float heapPercentage);
+
+  /**
+   * Get the percentage of heap at or above which the cache is considered in
+   * danger of becoming inoperable.
+   *
+   * @return either the current or recently used percentage of the maximum
+   * tenured heap
+   * @see #setCriticalHeapPercentage(float)
+   * @since 6.0
+   */
+  public float getCriticalHeapPercentage();
+
+  /**
+   * Set the percentage of heap at or above which the eviction should begin on
+   * Regions configured for {@linkplain 
+   * EvictionAttributes#createLRUHeapAttributes() HeapLRU eviction}.
+   *
+   * <p>
+   * Changing this value may cause eviction to begin immediately.
+   *
+   * <p>
+   * Only one change to this attribute or critical heap percentage will be
+   * allowed at any given time and its effect will be fully realized before the
+   * next change is allowed.
+   *
+   * This feature requires additional VM flags to perform properly. See {@linkplain 
+   * ResourceManager#setCriticalHeapPercentage(float) setCriticalHeapPercentage() for details.}
+   * 
+   * @param heapPercentage a percentage of the maximum tenured heap for the VM
+   * @throws IllegalStateException if the heapPercentage value is not >= 0 or 
+   * <= 100 or when greater than the current critical heap percentage.
+   * @see #getEvictionHeapPercentage()
+   * @see #getCriticalHeapPercentage()
+   * @since 6.0
+   */
+  public void setEvictionHeapPercentage(float heapPercentage);
+
+  /**
+   * Get the percentage of heap at or above which the eviction should begin on
+   * Regions configured for {@linkplain 
+   * EvictionAttributes#createLRUHeapAttributes() HeapLRU eviction}.
+   *
+   * @return either the current or recently used percentage of the maximum 
+   * tenured heap
+   * @see #setEvictionHeapPercentage(float)
+   * @since 6.0
+   */
+  public float getEvictionHeapPercentage();
+}


[13/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionStats.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionStats.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionStats.java
new file mode 100644
index 0000000..d324db8
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionStats.java
@@ -0,0 +1,3283 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+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.distributed.internal.DistributionStats;
+import com.gemstone.gemfire.internal.StatisticsTypeFactoryImpl;
+import com.gemstone.gemfire.internal.cache.PoolStats;
+import com.gemstone.gemfire.internal.cache.tier.sockets.MessageStats;
+
+/**
+ * Stats for a client to server {@link Connection}
+ * @author darrel
+ * @since 5.7
+ */
+public class ConnectionStats implements MessageStats {
+  // static fields 
+  private static final StatisticsType type;
+  private static final StatisticsType sendType;
+
+  ///////////////////////////////////////////////////////////////////////
+  /*
+  private final static int opInProgressId;
+  private final static int opSendInProgressId;
+  private final static int opSendFailedId;
+  private final static int opSendId;
+  private final static int opSendDurationId;
+  private final static int opTimedOutId;
+  private final static int opFailedId;
+  private final static int opId;
+  private final static int opDurationId;
+  */
+  ///////////////////////////////////////////////////////////////////////
+
+  private final static int getInProgressId;
+  private final static int getSendInProgressId;
+  private final static int getSendFailedId;
+  private final static int getSendId;
+  private final static int getSendDurationId;
+  private final static int getTimedOutId;
+  private final static int getFailedId;
+  private final static int getId;
+  private final static int getDurationId;
+
+  private final static int putInProgressId;
+  private final static int putSendInProgressId;
+  private final static int putSendFailedId;
+  private final static int putSendId;
+  private final static int putSendDurationId;
+  private final static int putTimedOutId;
+  private final static int putFailedId;
+  private final static int putId;
+  private final static int putDurationId;
+
+  private final static int destroyInProgressId;
+  private final static int destroySendInProgressId;
+  private final static int destroySendFailedId;
+  private final static int destroySendId;
+  private final static int destroySendDurationId;
+  private final static int destroyTimedOutId;
+  private final static int destroyFailedId;
+  private final static int destroyId;
+  private final static int destroyDurationId;
+
+  private final static int destroyRegionInProgressId;
+  private final static int destroyRegionSendInProgressId;
+  private final static int destroyRegionSendFailedId;
+  private final static int destroyRegionSendId;
+  private final static int destroyRegionSendDurationId;
+  private final static int destroyRegionTimedOutId;
+  private final static int destroyRegionFailedId;
+  private final static int destroyRegionId;
+  private final static int destroyRegionDurationId;
+
+  private final static int clearInProgressId;
+  private final static int clearSendInProgressId;
+  private final static int clearSendFailedId;
+  private final static int clearSendId;
+  private final static int clearSendDurationId;
+  private final static int clearTimedOutId;
+  private final static int clearFailedId;
+  private final static int clearId;
+  private final static int clearDurationId;
+
+  private final static int containsKeyInProgressId;
+  private final static int containsKeySendInProgressId;
+  private final static int containsKeySendFailedId;
+  private final static int containsKeySendId;
+  private final static int containsKeySendDurationId;
+  private final static int containsKeyTimedOutId;
+  private final static int containsKeyFailedId;
+  private final static int containsKeyId;
+  private final static int containsKeyDurationId;
+
+  private final static int keySetInProgressId;
+  private final static int keySetSendInProgressId;
+  private final static int keySetSendFailedId;
+  private final static int keySetSendId;
+  private final static int keySetSendDurationId;
+  private final static int keySetTimedOutId;
+  private final static int keySetFailedId;
+  private final static int keySetId;
+  private final static int keySetDurationId;
+  
+  private final static int commitInProgressId;
+  private final static int commitSendInProgressId;
+  private final static int commitSendFailedId;
+  private final static int commitSendId;
+  private final static int commitSendDurationId;
+  
+  private final static int commitFailedId;
+  private final static int commitTimedOutId;
+  private final static int commitId;
+  private final static int commitDurationId;
+  
+  private final static int rollbackInProgressId;
+  private final static int rollbackSendInProgressId;
+  private final static int rollbackSendFailedId;
+  private final static int rollbackSendId;
+  private final static int rollbackSendDurationId;
+  
+  private final static int rollbackFailedId;
+  private final static int rollbackTimedOutId;
+  private final static int rollbackId;
+  private final static int rollbackDurationId;
+  
+  private final static int getEntryInProgressId;
+  private final static int getEntrySendInProgressId;
+  private final static int getEntrySendFailedId;
+  private final static int getEntrySendId;
+  private final static int getEntrySendDurationId;
+  
+  private final static int getEntryFailedId;
+  private final static int getEntryTimedOutId;
+  private final static int getEntryId;
+  private final static int getEntryDurationId;
+  
+  private final static int txSynchronizationInProgressId;
+  private final static int txSynchronizationSendInProgressId;
+  private final static int txSynchronizationSendFailedId;
+  private final static int txSynchronizationSendId;
+  private final static int txSynchronizationSendDurationId;
+  
+  private final static int txSynchronizationFailedId;
+  private final static int txSynchronizationTimedOutId;
+  private final static int txSynchronizationId;
+  private final static int txSynchronizationDurationId;
+  
+  private final static int txFailoverInProgressId;
+  private final static int txFailoverSendInProgressId;
+  private final static int txFailoverSendFailedId;
+  private final static int txFailoverSendId;
+  private final static int txFailoverSendDurationId;
+  
+  private final static int txFailoverFailedId;
+  private final static int txFailoverTimedOutId;
+  private final static int txFailoverId;
+  private final static int txFailoverDurationId;
+  
+  private final static int sizeInProgressId;
+  private final static int sizeSendInProgressId;
+  private final static int sizeSendFailedId;
+  private final static int sizeSendId;
+  private final static int sizeSendDurationId;
+  
+  private final static int sizeFailedId;
+  private final static int sizeTimedOutId;
+  private final static int sizeId;
+  private final static int sizeDurationId;
+  
+  private final static int invalidateInProgressId;
+  private final static int invalidateSendInProgressId;
+  private final static int invalidateSendFailedId;
+  private final static int invalidateSendId;
+  private final static int invalidateSendDurationId;
+  
+  private final static int invalidateFailedId;
+  private final static int invalidateTimedOutId;
+  private final static int invalidateId;
+  private final static int invalidateDurationId;
+  
+  
+  private final static int registerInterestInProgressId;
+  private final static int registerInterestSendInProgressId;
+  private final static int registerInterestSendFailedId;
+  private final static int registerInterestSendId;
+  private final static int registerInterestSendDurationId;
+  private final static int registerInterestTimedOutId;
+  private final static int registerInterestFailedId;
+  private final static int registerInterestId;
+  private final static int registerInterestDurationId;
+
+  private final static int unregisterInterestInProgressId;
+  private final static int unregisterInterestSendInProgressId;
+  private final static int unregisterInterestSendFailedId;
+  private final static int unregisterInterestSendId;
+  private final static int unregisterInterestSendDurationId;
+  private final static int unregisterInterestTimedOutId;
+  private final static int unregisterInterestFailedId;
+  private final static int unregisterInterestId;
+  private final static int unregisterInterestDurationId;
+
+  private final static int queryInProgressId;
+  private final static int querySendInProgressId;
+  private final static int querySendFailedId;
+  private final static int querySendId;
+  private final static int querySendDurationId;
+  private final static int queryTimedOutId;
+  private final static int queryFailedId;
+  private final static int queryId;
+  private final static int queryDurationId;
+
+  private final static int createCQInProgressId;
+  private final static int createCQSendInProgressId;
+  private final static int createCQSendFailedId;
+  private final static int createCQSendId;
+  private final static int createCQSendDurationId;
+  private final static int createCQTimedOutId;
+  private final static int createCQFailedId;
+  private final static int createCQId;
+  private final static int createCQDurationId;
+  private final static int stopCQInProgressId;
+  private final static int stopCQSendInProgressId;
+  private final static int stopCQSendFailedId;
+  private final static int stopCQSendId;
+  private final static int stopCQSendDurationId;
+  private final static int stopCQTimedOutId;
+  private final static int stopCQFailedId;
+  private final static int stopCQId;
+  private final static int stopCQDurationId;
+  private final static int closeCQInProgressId;
+  private final static int closeCQSendInProgressId;
+  private final static int closeCQSendFailedId;
+  private final static int closeCQSendId;
+  private final static int closeCQSendDurationId;
+  private final static int closeCQTimedOutId;
+  private final static int closeCQFailedId;
+  private final static int closeCQId;
+  private final static int closeCQDurationId;
+  private final static int gatewayBatchInProgressId;
+  private final static int gatewayBatchSendInProgressId;
+  private final static int gatewayBatchSendFailedId;
+  private final static int gatewayBatchSendId;
+  private final static int gatewayBatchSendDurationId;
+  private final static int gatewayBatchTimedOutId;
+  private final static int gatewayBatchFailedId;
+  private final static int gatewayBatchId;
+  private final static int gatewayBatchDurationId;
+  private final static int getDurableCQsInProgressId;
+  private final static int getDurableCQsSendsInProgressId;
+  private final static int getDurableCQsSendFailedId;
+  private final static int getDurableCQsSendId;
+  private final static int getDurableCQsSendDurationId;
+  private final static int getDurableCQsTimedOutId;
+  private final static int getDurableCQsFailedId;
+  private final static int getDurableCQsId;
+  private final static int getDurableCQsDurationId;
+
+  private final static int readyForEventsInProgressId;
+  private final static int readyForEventsSendInProgressId;
+  private final static int readyForEventsSendFailedId;
+  private final static int readyForEventsSendId;
+  private final static int readyForEventsSendDurationId;
+  private final static int readyForEventsTimedOutId;
+  private final static int readyForEventsFailedId;
+  private final static int readyForEventsId;
+  private final static int readyForEventsDurationId;
+
+  private final static int makePrimaryInProgressId;
+  private final static int makePrimarySendInProgressId;
+  private final static int makePrimarySendFailedId;
+  private final static int makePrimarySendId;
+  private final static int makePrimarySendDurationId;
+  private final static int makePrimaryTimedOutId;
+  private final static int makePrimaryFailedId;
+  private final static int makePrimaryId;
+  private final static int makePrimaryDurationId;
+
+  private final static int closeConInProgressId;
+  private final static int closeConSendInProgressId;
+  private final static int closeConSendFailedId;
+  private final static int closeConSendId;
+  private final static int closeConSendDurationId;
+  private final static int closeConTimedOutId;
+  private final static int closeConFailedId;
+  private final static int closeConId;
+  private final static int closeConDurationId;
+
+  private final static int primaryAckInProgressId;
+  private final static int primaryAckSendInProgressId;
+  private final static int primaryAckSendFailedId;
+  private final static int primaryAckSendId;
+  private final static int primaryAckSendDurationId;
+  private final static int primaryAckTimedOutId;
+  private final static int primaryAckFailedId;
+  private final static int primaryAckId;
+  private final static int primaryAckDurationId;
+
+  private final static int pingInProgressId;
+  private final static int pingSendInProgressId;
+  private final static int pingSendFailedId;
+  private final static int pingSendId;
+  private final static int pingSendDurationId;
+  private final static int pingTimedOutId;
+  private final static int pingFailedId;
+  private final static int pingId;
+  private final static int pingDurationId;
+
+  private final static int registerInstantiatorsInProgressId;
+  private final static int registerInstantiatorsSendInProgressId;
+  private final static int registerInstantiatorsSendFailedId;
+  private final static int registerInstantiatorsSendId;
+  private final static int registerInstantiatorsSendDurationId;
+  private final static int registerInstantiatorsTimedOutId;
+  private final static int registerInstantiatorsFailedId;
+  private final static int registerInstantiatorsId;
+  private final static int registerInstantiatorsDurationId;
+  
+  private final static int registerDataSerializersInProgressId;
+  private final static int registerDataSerializersSendInProgressId;
+  private final static int registerDataSerializersSendFailedId;
+  private final static int registerDataSerializersSendId;
+  private final static int registerDataSerializersSendDurationId;
+  private final static int registerDataSerializersTimedOutId;
+  private final static int registerDataSerializersFailedId;
+  private final static int registerDataSerializersId;
+  private final static int registerDataSerializersDurationId;
+  
+  private final static int putAllInProgressId;
+  private final static int putAllSendInProgressId;
+  private final static int putAllSendFailedId;
+  private final static int putAllSendId;
+  private final static int putAllSendDurationId;
+  private final static int putAllTimedOutId;
+  private final static int putAllFailedId;
+  private final static int putAllId;
+  private final static int putAllDurationId;
+
+  private final static int removeAllInProgressId;
+  private final static int removeAllSendInProgressId;
+  private final static int removeAllSendFailedId;
+  private final static int removeAllSendId;
+  private final static int removeAllSendDurationId;
+  private final static int removeAllTimedOutId;
+  private final static int removeAllFailedId;
+  private final static int removeAllId;
+  private final static int removeAllDurationId;
+
+  private final static int getAllInProgressId;
+  private final static int getAllSendInProgressId;
+  private final static int getAllSendFailedId;
+  private final static int getAllSendId;
+  private final static int getAllSendDurationId;
+  private final static int getAllTimedOutId;
+  private final static int getAllFailedId;
+  private final static int getAllId;
+  private final static int getAllDurationId;
+
+  private final static int connectionsId;
+  private final static int connectsId;
+  private final static int disconnectsId;
+  private final static int messagesBeingReceivedId;
+  private final static int messageBytesBeingReceivedId;
+  private final static int receivedBytesId;
+  private final static int sentBytesId;
+  
+  private final static int executeFunctionInProgressId;
+  private final static int executeFunctionSendInProgressId;
+  private final static int executeFunctionSendFailedId;
+  private final static int executeFunctionSendId;
+  private final static int executeFunctionSendDurationId;
+  private final static int executeFunctionTimedOutId;
+  private final static int executeFunctionFailedId;
+  private final static int executeFunctionId;
+  private final static int executeFunctionDurationId;
+  
+  private final static int getClientPRMetadataInProgressId;
+  private final static int getClientPRMetadataSendInProgressId;
+  private final static int getClientPRMetadataSendFailedId;
+  private final static int getClientPRMetadataSendId;
+  private final static int getClientPRMetadataSendDurationId;
+  private final static int getClientPRMetadataTimedOutId;
+  private final static int getClientPRMetadataFailedId;
+  private final static int getClientPRMetadataId;
+  private final static int getClientPRMetadataDurationId;
+
+  private final static int getClientPartitionAttributesInProgressId;
+  private final static int getClientPartitionAttributesSendInProgressId;
+  private final static int getClientPartitionAttributesSendFailedId;
+  private final static int getClientPartitionAttributesSendId;
+  private final static int getClientPartitionAttributesSendDurationId;
+  private final static int getClientPartitionAttributesTimedOutId;
+  private final static int getClientPartitionAttributesFailedId;
+  private final static int getClientPartitionAttributesId;
+  private final static int getClientPartitionAttributesDurationId;
+  
+  private final static int getPDXIdForTypeInProgressId;
+  private final static int getPDXIdForTypeSendInProgressId;
+  private final static int getPDXIdForTypeSendFailedId;
+  private final static int getPDXIdForTypeSendId;
+  private final static int getPDXIdForTypeSendDurationId;
+  private final static int getPDXIdForTypeTimedOutId;
+  private final static int getPDXIdForTypeFailedId;
+  private final static int getPDXIdForTypeId;
+  private final static int getPDXIdForTypeDurationId;
+  
+  private final static int getPDXTypeByIdInProgressId;
+  private final static int getPDXTypeByIdSendInProgressId;
+  private final static int getPDXTypeByIdSendFailedId;
+  private final static int getPDXTypeByIdSendId;
+  private final static int getPDXTypeByIdSendDurationId;
+  private final static int getPDXTypeByIdTimedOutId;
+  private final static int getPDXTypeByIdFailedId;
+  private final static int getPDXTypeByIdId;
+  private final static int getPDXTypeByIdDurationId;
+  
+  private final static int addPdxTypeInProgressId;
+  private final static int addPdxTypeSendInProgressId;
+  private final static int addPdxTypeSendFailedId;
+  private final static int addPdxTypeSendId;
+  private final static int addPdxTypeSendDurationId;
+  private final static int addPdxTypeTimedOutId;
+  private final static int addPdxTypeFailedId;
+  private final static int addPdxTypeId;
+  private final static int addPdxTypeDurationId;
+
+  
+  //An array of all of the ids that represent operation statistics. This
+  //is used by the getOps method to aggregate the individual stats
+  //into a total value for all operations.
+  private static int[] opIds;
+
+  static {
+    try {
+    StatisticsTypeFactory f = StatisticsTypeFactoryImpl.singleton();
+    type = f.createType(
+      "ClientStats", 
+      "Statistics about client to server communication",
+      new StatisticDescriptor[] {
+        ///////////////////////////////////////////////////////////////////////
+        /*
+        f.createIntGauge("opsInProgress", "Current number of ops being executed", "ops"), 
+        f.createIntCounter("ops", "Total number of ops completed successfully", "ops"), 
+        f.createIntCounter("opFailures", "Total number of op attempts that have failed", "ops"), 
+        f.createIntCounter("opTimeouts", "Total number of op attempts that have timed out", "ops"), 
+        f.createLongCounter("opTime", "Total amount of time, in nanoseconds spent doing ops", "nanoseconds"),
+        */
+        ///////////////////////////////////////////////////////////////////////
+        f.createIntGauge("getsInProgress", "Current number of gets being executed", "gets"), 
+        f.createIntCounter("gets", "Total number of gets completed successfully", "gets"), 
+        f.createIntCounter("getFailures", "Total number of get attempts that have failed", "gets"), 
+        f.createIntCounter("getTimeouts", "Total number of get attempts that have timed out", "gets"), 
+        f.createLongCounter("getTime", "Total amount of time, in nanoseconds spent doing gets", "nanoseconds"), 
+        f.createIntGauge("putsInProgress", "Current number of puts being executed", "puts"), 
+        f.createIntCounter("puts", "Total number of puts completed successfully", "puts"), 
+        f.createIntCounter("putFailures", "Total number of put attempts that have failed", "puts"), 
+        f.createIntCounter("putTimeouts", "Total number of put attempts that have timed out", "puts"), 
+        f.createLongCounter("putTime", "Total amount of time, in nanoseconds spent doing puts", "nanoseconds"), 
+        f.createIntGauge("destroysInProgress", "Current number of destroys being executed", "destroys"), 
+        f.createIntCounter("destroys", "Total number of destroys completed successfully", "destroys"), 
+        f.createIntCounter("destroyFailures", "Total number of destroy attempts that have failed", "destroys"), 
+        f.createIntCounter("destroyTimeouts", "Total number of destroy attempts that have timed out", "destroys"), 
+        f.createLongCounter("destroyTime", "Total amount of time, in nanoseconds spent doing destroys", "nanoseconds"), 
+        f.createIntGauge("destroyRegionsInProgress", "Current number of destroyRegions being executed", "destroyRegions"), 
+        f.createIntCounter("destroyRegions", "Total number of destroyRegions completed successfully", "destroyRegions"), 
+        f.createIntCounter("destroyRegionFailures", "Total number of destroyRegion attempts that have failed", "destroyRegions"), 
+        f.createIntCounter("destroyRegionTimeouts", "Total number of destroyRegion attempts that have timed out", "destroyRegions"), 
+        f.createLongCounter("destroyRegionTime", "Total amount of time, in nanoseconds spent doing destroyRegions", "nanoseconds"), 
+        f.createIntGauge("clearsInProgress", "Current number of clears being executed", "clears"), 
+        f.createIntCounter("clears", "Total number of clears completed successfully", "clears"), 
+        f.createIntCounter("clearFailures", "Total number of clear attempts that have failed", "clears"), 
+        f.createIntCounter("clearTimeouts", "Total number of clear attempts that have timed out", "clears"), 
+        f.createLongCounter("clearTime", "Total amount of time, in nanoseconds spent doing clears", "nanoseconds"), 
+        f.createIntGauge("containsKeysInProgress", "Current number of containsKeys being executed", "containsKeys"), 
+        f.createIntCounter("containsKeys", "Total number of containsKeys completed successfully", "containsKeys"), 
+        f.createIntCounter("containsKeyFailures", "Total number of containsKey attempts that have failed", "containsKeys"), 
+        f.createIntCounter("containsKeyTimeouts", "Total number of containsKey attempts that have timed out", "containsKeys"), 
+        f.createLongCounter("containsKeyTime", "Total amount of time, in nanoseconds spent doing containsKeys", "nanoseconds"), 
+        f.createIntGauge("keySetsInProgress", "Current number of keySets being executed", "keySets"), 
+        f.createIntCounter("keySets", "Total number of keySets completed successfully", "keySets"), 
+        f.createIntCounter("keySetFailures", "Total number of keySet attempts that have failed", "keySets"), 
+        f.createIntCounter("keySetTimeouts", "Total number of keySet attempts that have timed out", "keySets"), 
+        f.createLongCounter("keySetTime", "Total amount of time, in nanoseconds spent doing keySets", "nanoseconds"),
+
+        f.createIntGauge("commitsInProgress", "Current number of commits being executed", "commits"), 
+        f.createIntCounter("commits", "Total number of commits completed successfully", "commits"),
+        f.createIntCounter("commitFailures", "Total number of commit attempts that have failed", "commits"),
+        f.createIntCounter("commitTimeouts", "Total number of commit attempts that have timed out", "commits"),
+        f.createLongCounter("commitTime", "Total amount of time, in nanoseconds spent doing commits", "nanoseconds"),
+        
+        f.createIntGauge("rollbacksInProgress", "Current number of rollbacks being executed", "rollbacks"), 
+        f.createIntCounter("rollbacks", "Total number of rollbacks completed successfully", "rollbacks"),
+        f.createIntCounter("rollbackFailures", "Total number of rollback attempts that have failed", "rollbacks"),
+        f.createIntCounter("rollbackTimeouts", "Total number of rollback attempts that have timed out", "rollbacks"),
+        f.createLongCounter("rollbackTime", "Total amount of time, in nanoseconds spent doing rollbacks", "nanoseconds"),
+        
+        f.createIntGauge("getEntrysInProgress", "Current number of getEntry messages being executed", "messages"), 
+        f.createIntCounter("getEntrys", "Total number of getEntry messages completed successfully", "messages"),
+        f.createIntCounter("getEntryFailures", "Total number of getEntry attempts that have failed", "attempts"),
+        f.createIntCounter("getEntryTimeouts", "Total number of getEntry attempts that have timed out", "attempts"),
+        f.createLongCounter("getEntryTime", "Total amount of time, in nanoseconds spent doing getEntry processings", "nanoseconds"),
+        
+        f.createIntGauge("jtaSynchronizationsInProgress", "Current number of jtaSynchronizations being executed", "sizes"), 
+        f.createIntCounter("jtaSynchronizations", "Total number of jtaSynchronizations completed successfully", "jtaSynchronizations"),
+        f.createIntCounter("jtaSynchronizationFailures", "Total number of jtaSynchronization attempts that have failed", "jtaSynchronizations"),
+        f.createIntCounter("jtaSynchronizationTimeouts", "Total number of jtaSynchronization attempts that have timed out", "jtaSynchronizations"),
+        f.createLongCounter("jtaSynchronizationTime", "Total amount of time, in nanoseconds spent doing jtaSynchronizations", "nanoseconds"),
+        
+        f.createIntGauge("txFailoversInProgress", "Current number of txFailovers being executed", "txFailovers"), 
+        f.createIntCounter("txFailovers", "Total number of txFailovers completed successfully", "txFailovers"),
+        f.createIntCounter("txFailoverFailures", "Total number of txFailover attempts that have failed", "txFailovers"),
+        f.createIntCounter("txFailoverTimeouts", "Total number of txFailover attempts that have timed out", "sizes"),
+        f.createLongCounter("txFailoverTime", "Total amount of time, in nanoseconds spent doing txFailovers", "nanoseconds"),
+        
+        f.createIntGauge("sizesInProgress", "Current number of sizes being executed", "sizes"), 
+        f.createIntCounter("sizes", "Total number of sizes completed successfully", "sizes"),
+        f.createIntCounter("sizeFailures", "Total number of size attempts that have failed", "sizes"),
+        f.createIntCounter("sizeTimeouts", "Total number of size attempts that have timed out", "sizes"),
+        f.createLongCounter("sizeTime", "Total amount of time, in nanoseconds spent doing sizes", "nanoseconds"),
+        
+        f.createIntGauge("invalidatesInProgress", "Current number of invalidates being executed", "invalidates"), 
+        f.createIntCounter("invalidates", "Total number of invalidates completed successfully", "invalidates"),
+        f.createIntCounter("invalidateFailures", "Total number of invalidate attempts that have failed", "invalidates"),
+        f.createIntCounter("invalidateTimeouts", "Total number of invalidate attempts that have timed out", "invalidates"),
+        f.createLongCounter("invalidateTime", "Total amount of time, in nanoseconds spent doing invalidates", "nanoseconds"),
+        
+        
+        f.createIntGauge("registerInterestsInProgress", "Current number of registerInterests being executed", "registerInterests"), 
+        f.createIntCounter("registerInterests", "Total number of registerInterests completed successfully", "registerInterests"), 
+        f.createIntCounter("registerInterestFailures", "Total number of registerInterest attempts that have failed", "registerInterests"), 
+        f.createIntCounter("registerInterestTimeouts", "Total number of registerInterest attempts that have timed out", "registerInterests"), 
+        f.createLongCounter("registerInterestTime", "Total amount of time, in nanoseconds spent doing registerInterests", "nanoseconds"), 
+        f.createIntGauge("unregisterInterestsInProgress", "Current number of unregisterInterests being executed", "unregisterInterests"), 
+        f.createIntCounter("unregisterInterests", "Total number of unregisterInterests completed successfully", "unregisterInterests"), 
+        f.createIntCounter("unregisterInterestFailures", "Total number of unregisterInterest attempts that have failed", "unregisterInterests"), 
+        f.createIntCounter("unregisterInterestTimeouts", "Total number of unregisterInterest attempts that have timed out", "unregisterInterests"), 
+        f.createLongCounter("unregisterInterestTime", "Total amount of time, in nanoseconds spent doing unregisterInterests", "nanoseconds"), 
+        f.createIntGauge("querysInProgress", "Current number of querys being executed", "querys"), 
+        f.createIntCounter("querys", "Total number of querys completed successfully", "querys"), 
+        f.createIntCounter("queryFailures", "Total number of query attempts that have failed", "querys"), 
+        f.createIntCounter("queryTimeouts", "Total number of query attempts that have timed out", "querys"), 
+        f.createLongCounter("queryTime", "Total amount of time, in nanoseconds spent doing querys", "nanoseconds"), 
+        f.createIntGauge("createCQsInProgress", "Current number of createCQs being executed", "createCQs"), 
+        f.createIntCounter("createCQs", "Total number of createCQs completed successfully", "createCQs"), 
+        f.createIntCounter("createCQFailures", "Total number of createCQ attempts that have failed", "createCQs"), 
+        f.createIntCounter("createCQTimeouts", "Total number of createCQ attempts that have timed out", "createCQs"), 
+        f.createLongCounter("createCQTime", "Total amount of time, in nanoseconds spent doing createCQs", "nanoseconds"), 
+        f.createIntGauge("stopCQsInProgress", "Current number of stopCQs being executed", "stopCQs"), 
+        f.createIntCounter("stopCQs", "Total number of stopCQs completed successfully", "stopCQs"), 
+        f.createIntCounter("stopCQFailures", "Total number of stopCQ attempts that have failed", "stopCQs"), 
+        f.createIntCounter("stopCQTimeouts", "Total number of stopCQ attempts that have timed out", "stopCQs"), 
+        f.createLongCounter("stopCQTime", "Total amount of time, in nanoseconds spent doing stopCQs", "nanoseconds"), 
+        f.createIntGauge("closeCQsInProgress", "Current number of closeCQs being executed", "closeCQs"), 
+        f.createIntCounter("closeCQs", "Total number of closeCQs completed successfully", "closeCQs"), 
+        f.createIntCounter("closeCQFailures", "Total number of closeCQ attempts that have failed", "closeCQs"), 
+        f.createIntCounter("closeCQTimeouts", "Total number of closeCQ attempts that have timed out", "closeCQs"), 
+        f.createLongCounter("closeCQTime", "Total amount of time, in nanoseconds spent doing closeCQs", "nanoseconds"), 
+        f.createIntGauge("gatewayBatchsInProgress", "Current number of gatewayBatchs being executed", "gatewayBatchs"), 
+        f.createIntCounter("gatewayBatchs", "Total number of gatewayBatchs completed successfully", "gatewayBatchs"), 
+        f.createIntCounter("gatewayBatchFailures", "Total number of gatewayBatch attempts that have failed", "gatewayBatchs"), 
+        f.createIntCounter("gatewayBatchTimeouts", "Total number of gatewayBatch attempts that have timed out", "gatewayBatchs"), 
+        f.createLongCounter("gatewayBatchTime", "Total amount of time, in nanoseconds spent doing gatewayBatchs", "nanoseconds"), 
+        f.createIntGauge("getDurableCQsInProgress", "Current number of getDurableCQs being executed", "getDurableCQs"), 
+        f.createIntCounter("getDurableCQs", "Total number of getDurableCQs completed successfully", "getDurableCQs"), 
+        f.createIntCounter("getDurableCQsFailures", "Total number of getDurableCQs attempts that have failed", "getDurableCQs"), 
+        f.createIntCounter("getDurableCQsTimeouts", "Total number of getDurableCQs attempts that have timed out", "getDurableCQs"), 
+        f.createLongCounter("getDurableCQsTime", "Total amount of time, in nanoseconds spent doing getDurableCQs", "nanoseconds"), 
+        f.createIntGauge("readyForEventsInProgress", "Current number of readyForEvents being executed", "readyForEvents"), 
+        f.createIntCounter("readyForEvents", "Total number of readyForEvents completed successfully", "readyForEvents"), 
+        f.createIntCounter("readyForEventsFailures", "Total number of readyForEvents attempts that have failed", "readyForEvents"), 
+        f.createIntCounter("readyForEventsTimeouts", "Total number of readyForEvents attempts that have timed out", "readyForEvents"), 
+        f.createLongCounter("readyForEventsTime", "Total amount of time, in nanoseconds spent doing readyForEvents", "nanoseconds"), 
+        f.createIntGauge("makePrimarysInProgress", "Current number of makePrimarys being executed", "makePrimarys"), 
+        f.createIntCounter("makePrimarys", "Total number of makePrimarys completed successfully", "makePrimarys"), 
+        f.createIntCounter("makePrimaryFailures", "Total number of makePrimary attempts that have failed", "makePrimarys"), 
+        f.createIntCounter("makePrimaryTimeouts", "Total number of makePrimary attempts that have timed out", "makePrimarys"), 
+        f.createLongCounter("makePrimaryTime", "Total amount of time, in nanoseconds spent doing makePrimarys", "nanoseconds"), 
+
+        f.createIntGauge("closeConsInProgress", "Current number of closeCons being executed", "closeCons"), 
+        f.createIntCounter("closeCons", "Total number of closeCons completed successfully", "closeCons"), 
+        f.createIntCounter("closeConFailures", "Total number of closeCon attempts that have failed", "closeCons"), 
+        f.createIntCounter("closeConTimeouts", "Total number of closeCon attempts that have timed out", "closeCons"), 
+        f.createLongCounter("closeConTime", "Total amount of time, in nanoseconds spent doing closeCons", "nanoseconds"), 
+
+        f.createIntGauge("primaryAcksInProgress", "Current number of primaryAcks being executed", "primaryAcks"), 
+        f.createIntCounter("primaryAcks", "Total number of primaryAcks completed successfully", "primaryAcks"), 
+        f.createIntCounter("primaryAckFailures", "Total number of primaryAck attempts that have failed", "primaryAcks"), 
+        f.createIntCounter("primaryAckTimeouts", "Total number of primaryAck attempts that have timed out", "primaryAcks"), 
+        f.createLongCounter("primaryAckTime", "Total amount of time, in nanoseconds spent doing primaryAcks", "nanoseconds"), 
+
+        f.createIntGauge("pingsInProgress", "Current number of pings being executed", "pings"), 
+        f.createIntCounter("pings", "Total number of pings completed successfully", "pings"), 
+        f.createIntCounter("pingFailures", "Total number of ping attempts that have failed", "pings"), 
+        f.createIntCounter("pingTimeouts", "Total number of ping attempts that have timed out", "pings"), 
+        f.createLongCounter("pingTime", "Total amount of time, in nanoseconds spent doing pings", "nanoseconds"), 
+
+        f.createIntGauge("registerInstantiatorsInProgress", "Current number of registerInstantiators being executed", "registerInstantiators"), 
+        f.createIntCounter("registerInstantiators", "Total number of registerInstantiators completed successfully", "registerInstantiators"), 
+        f.createIntCounter("registerInstantiatorsFailures", "Total number of registerInstantiators attempts that have failed", "registerInstantiators"), 
+        f.createIntCounter("registerInstantiatorsTimeouts", "Total number of registerInstantiators attempts that have timed out", "registerInstantiators"), 
+        f.createLongCounter("registerInstantiatorsTime", "Total amount of time, in nanoseconds spent doing registerInstantiators", "nanoseconds"), 
+        
+        f.createIntGauge("registerDataSerializersInProgress", "Current number of registerDataSerializers being executed", "registerDataSerializers"), 
+        f.createIntCounter("registerDataSerializers", "Total number of registerDataSerializers completed successfully", "registerDataSerializers"), 
+        f.createIntCounter("registerDataSerializersFailures", "Total number of registerDataSerializers attempts that have failed", "registerDataSerializers"), 
+        f.createIntCounter("registerDataSerializersTimeouts", "Total number of registerDataSerializers attempts that have timed out", "registerDataSerializers"), 
+        f.createLongCounter("registerDataSerializersTime", "Total amount of time, in nanoseconds spent doing registerDataSerializers", "nanoseconds"), 
+        
+        f.createIntGauge("connections", "Current number of connections", "connections"),
+        f.createIntCounter("connects", "Total number of times a connection has been created.", "connects"),
+        f.createIntCounter("disconnects", "Total number of times a connection has been destroyed.", "disconnects"),
+        f.createIntGauge("putAllsInProgress", "Current number of putAlls being executed", "putAlls"), 
+        f.createIntCounter("putAlls", "Total number of putAlls completed successfully", "putAlls"), 
+        f.createIntCounter("putAllFailures", "Total number of putAll attempts that have failed", "putAlls"), 
+        f.createIntCounter("putAllTimeouts", "Total number of putAll attempts that have timed out", "putAlls"), 
+        f.createLongCounter("putAllTime", "Total amount of time, in nanoseconds spent doing putAlls", "nanoseconds"),
+        f.createIntGauge("removeAllsInProgress", "Current number of removeAlls being executed", "removeAlls"), 
+        f.createIntCounter("removeAlls", "Total number of removeAlls completed successfully", "removeAlls"), 
+        f.createIntCounter("removeAllFailures", "Total number of removeAll attempts that have failed", "removeAlls"), 
+        f.createIntCounter("removeAllTimeouts", "Total number of removeAll attempts that have timed out", "removeAlls"), 
+        f.createLongCounter("removeAllTime", "Total amount of time, in nanoseconds spent doing removeAlls", "nanoseconds"),
+        f.createIntGauge("getAllsInProgress", "Current number of getAlls being executed", "getAlls"), 
+        f.createIntCounter("getAlls", "Total number of getAlls completed successfully", "getAlls"), 
+        f.createIntCounter("getAllFailures", "Total number of getAll attempts that have failed", "getAlls"), 
+        f.createIntCounter("getAllTimeouts", "Total number of getAll attempts that have timed out", "getAlls"), 
+        f.createLongCounter("getAllTime", "Total amount of time, in nanoseconds spent doing getAlls", "nanoseconds"),
+        f.createLongCounter("receivedBytes",
+                            "Total number of bytes received (as responses) from server over a client-to-server connection.",
+                            "bytes"),
+        f.createLongCounter("sentBytes",
+                            "Total number of bytes sent to server over a client-to-server connection.",
+                            "bytes"),
+        f.createIntGauge("messagesBeingReceived", "Current number of message being received off the network or being processed after reception over a client-to-server connection.", "messages"),
+        f.createLongGauge("messageBytesBeingReceived", "Current number of bytes consumed by messages being received or processed over a client-to-server connection.", "bytes"),
+        
+        f.createIntGauge("executeFunctionsInProgress", "Current number of Functions being executed", "executeFunctions"), 
+        f.createIntCounter("executeFunctions", "Total number of Functions completed successfully", "executeFunctions"), 
+        f.createIntCounter("executeFunctionFailures", "Total number of Function attempts that have failed", "executeFunctions"), 
+        f.createIntCounter("executeFunctionTimeouts", "Total number of Function attempts that have timed out", "executeFunctions"), 
+        f.createLongCounter("executeFunctionTime", "Total amount of time, in nanoseconds spent doing Functions", "nanoseconds"),
+        
+        f.createIntGauge("asyncExecuteFunctionsInProgress", "Current number of Functions being executed asynchronously", "asyncExecuteFunctions"), 
+        f.createIntCounter("asyncExecuteFunctions", "Total number of asynchronous Functions completed successfully", "asyncExecuteFunctions"), 
+        f.createIntCounter("asyncExecuteFunctionFailures", "Total number of asynchronous Function attempts that have failed", "asyncExecuteFunctions"), 
+        f.createIntCounter("asyncExecuteFunctionTimeouts", "Total number of asynchronous Function attempts that have timed out", "asyncExecuteFunctions"), 
+        f.createLongCounter("asyncExecuteFunctionTime", "Total amount of time, in nanoseconds spent doing asynchronous Functions", "nanoseconds"),
+        
+        f.createIntGauge("getClientPRMetadataInProgress", "Current number of getClientPRMetadata operations being executed", "getClientPRMetadata"),
+        f.createIntCounter("getClientPRMetadataFailures", "Total number of getClientPRMetadata operation attempts that have failed", "getClientPRMetadata"), 
+        f.createIntCounter("getClientPRMetadataSuccessful", "Total number of getClientPRMetadata operations completed successfully", "getClientPRMetadata"),
+        f.createIntCounter("getClientPRMetadataTimeouts", "Total number of getClientPRMetadata operation attempts that have timed out", "getClientPRMetadata"),
+        f.createLongCounter("getClientPRMetadataTime", "Total amount of time, in nanoseconds spent doing getClientPRMetadata successfully/unsuccessfully", "nanoseconds"),
+        
+        f.createIntGauge("getClientPartitionAttributesInProgress", "Current number of getClientPartitionAttributes operations being executed", "getClientPartitionAttributes"),
+        f.createIntCounter("getClientPartitionAttributesFailures", "Total number of getClientPartitionAttributes operation attempts that have failed", "getClientPartitionAttributes"), 
+        f.createIntCounter("getClientPartitionAttributesSuccessful", "Total number of getClientPartitionAttributes operations completed successfully", "getClientPartitionAttributes"),
+        f.createIntCounter("getClientPartitionAttributesTimeouts", "Total number of getClientPartitionAttributes operation attempts that have timed out", "getClientPartitionAttributes"),
+        f.createLongCounter("getClientPartitionAttributesTime", "Total amount of time, in nanoseconds spent doing getClientPartitionAttributes successfully/unsuccessfully.", "nanoseconds"),        
+        
+        f.createIntGauge("getPDXTypeByIdInProgress", "Current number of getPDXTypeById operations being executed", "getPDXTypeById"),
+        f.createIntCounter("getPDXTypeByIdFailures", "Total number of getPDXTypeById operation attempts that have failed", "getPDXTypeById"), 
+        f.createIntCounter("getPDXTypeByIdSuccessful", "Total number of getPDXTypeById operations completed successfully", "getPDXTypeById"),
+        f.createIntCounter("getPDXTypeByIdTimeouts", "Total number of getPDXTypeById operation attempts that have timed out", "getPDXTypeById"),
+        f.createLongCounter("getPDXTypeByIdTime", "Total amount of time, in nanoseconds spent doing getPDXTypeById successfully/unsuccessfully.", "nanoseconds"),
+        
+        f.createIntGauge("getPDXIdForTypeInProgress", "Current number of getPDXIdForType operations being executed", "getPDXIdForType"),
+        f.createIntCounter("getPDXIdForTypeFailures", "Total number of getPDXIdForType operation attempts that have failed", "getPDXIdForType"), 
+        f.createIntCounter("getPDXIdForTypeSuccessful", "Total number of getPDXIdForType operations completed successfully", "getPDXIdForType"),
+        f.createIntCounter("getPDXIdForTypeTimeouts", "Total number of getPDXIdForType operation attempts that have timed out", "getPDXIdForType"),
+        f.createLongCounter("getPDXIdForTypeTime", "Total amount of time, in nanoseconds spent doing getPDXIdForType successfully/unsuccessfully.", "nanoseconds"),
+        
+        f.createIntGauge("addPdxTypeInProgress", "Current number of addPdxType operations being executed", "addPdxType"),
+        f.createIntCounter("addPdxTypeFailures", "Total number of addPdxType operation attempts that have failed", "addPdxType"), 
+        f.createIntCounter("addPdxTypeSuccessful", "Total number of addPdxType operations completed successfully", "addPdxType"),
+        f.createIntCounter("addPdxTypeTimeouts", "Total number of addPdxType operation attempts that have timed out", "addPdxType"),
+        f.createLongCounter("addPdxTypeTime", "Total amount of time, in nanoseconds spent doing addPdxType successfully/unsuccessfully.", "nanoseconds"),
+      }
+    );
+
+    sendType = f.createType(
+      "ClientSendStats", 
+      "Statistics about client to server communication",
+      new StatisticDescriptor[] {
+        ///////////////////////////////////////////////////////////////////////
+        /*
+        f.createIntGauge("opSendsInProgress", "Current number of op sends being executed", "sends"), 
+        f.createIntCounter("opSends", "Total number of op sends that have completed successfully", "sends"), 
+        f.createIntCounter("opSendFailures", "Total number of op sends that have failed", "sends"), 
+        f.createLongCounter("opSendTime", "Total amount of time, in nanoseconds spent doing op sends", "nanoseconds"), 
+        */
+        ///////////////////////////////////////////////////////////////////////
+        f.createIntGauge("getSendsInProgress", "Current number of get sends being executed", "sends"), 
+        f.createIntCounter("getSends", "Total number of get sends that have completed successfully", "sends"), 
+        f.createIntCounter("getSendFailures", "Total number of get sends that have failed", "sends"), 
+        f.createLongCounter("getSendTime", "Total amount of time, in nanoseconds spent doing get sends", "nanoseconds"), 
+        f.createIntGauge("putSendsInProgress", "Current number of put sends being executed", "sends"), 
+        f.createIntCounter("putSends", "Total number of put sends that have completed successfully", "sends"), 
+        f.createIntCounter("putSendFailures", "Total number of put sends that have failed", "sends"), 
+        f.createLongCounter("putSendTime", "Total amount of time, in nanoseconds spent doing put sends", "nanoseconds"), 
+        f.createIntGauge("destroySendsInProgress", "Current number of destroy sends being executed", "sends"), 
+        f.createIntCounter("destroySends", "Total number of destroy sends that have completed successfully", "sends"), 
+        f.createIntCounter("destroySendFailures", "Total number of destroy sends that have failed", "sends"), 
+        f.createLongCounter("destroySendTime", "Total amount of time, in nanoseconds spent doing destroy sends", "nanoseconds"), 
+        f.createIntGauge("destroyRegionSendsInProgress", "Current number of destroyRegion sends being executed", "sends"), 
+        f.createIntCounter("destroyRegionSends", "Total number of destroyRegion sends that have completed successfully", "sends"), 
+        f.createIntCounter("destroyRegionSendFailures", "Total number of destroyRegion sends that have failed", "sends"), 
+        f.createLongCounter("destroyRegionSendTime", "Total amount of time, in nanoseconds spent doing destroyRegion sends", "nanoseconds"), 
+        f.createIntGauge("clearSendsInProgress", "Current number of clear sends being executed", "sends"), 
+        f.createIntCounter("clearSends", "Total number of clear sends that have completed successfully", "sends"), 
+        f.createIntCounter("clearSendFailures", "Total number of clear sends that have failed", "sends"), 
+        f.createLongCounter("clearSendTime", "Total amount of time, in nanoseconds spent doing clear sends", "nanoseconds"), 
+        f.createIntGauge("containsKeySendsInProgress", "Current number of containsKey sends being executed", "sends"), 
+        f.createIntCounter("containsKeySends", "Total number of containsKey sends that have completed successfully", "sends"), 
+        f.createIntCounter("containsKeySendFailures", "Total number of containsKey sends that have failed", "sends"), 
+        f.createLongCounter("containsKeySendTime", "Total amount of time, in nanoseconds spent doing containsKey sends", "nanoseconds"), 
+        f.createIntGauge("keySetSendsInProgress", "Current number of keySet sends being executed", "sends"), 
+        f.createIntCounter("keySetSends", "Total number of keySet sends that have completed successfully", "sends"), 
+        f.createIntCounter("keySetSendFailures", "Total number of keySet sends that have failed", "sends"), 
+        f.createLongCounter("keySetSendTime", "Total amount of time, in nanoseconds spent doing keySet sends", "nanoseconds"), 
+
+        f.createIntGauge("commitSendsInProgress", "Current number of commit sends being executed", "sends"), 
+        f.createIntCounter("commitSendFailures", "Total number of commit sends that have failed", "sends"),
+        f.createIntCounter("commitSends", "Total number of commit sends that have failed", "sends"),
+        f.createLongCounter("commitSendTime", "Total amount of time, in nanoseconds spent doing commits", "nanoseconds"),
+        f.createIntGauge("rollbackSendsInProgress", "Current number of rollback sends being executed", "sends"), 
+        f.createIntCounter("rollbackSendFailures", "Total number of rollback sends that have failed", "sends"),
+        f.createIntCounter("rollbackSends", "Total number of rollback sends that have failed", "sends"),
+        f.createLongCounter("rollbackSendTime", "Total amount of time, in nanoseconds spent doing rollbacks", "nanoseconds"),
+        f.createIntGauge("getEntrySendsInProgress", "Current number of getEntry sends being executed", "sends"), 
+        f.createIntCounter("getEntrySendFailures", "Total number of getEntry sends that have failed", "sends"),
+        f.createIntCounter("getEntrySends", "Total number of getEntry sends that have failed", "sends"),
+        f.createLongCounter("getEntrySendTime", "Total amount of time, in nanoseconds spent sending getEntry messages", "nanoseconds"),
+        f.createIntGauge("jtaSynchronizationSendsInProgress", "Current number of jtaSynchronization sends being executed", "sends"), 
+        f.createIntCounter("jtaSynchronizationSendFailures", "Total number of jtaSynchronization sends that have failed", "sends"),
+        f.createIntCounter("jtaSynchronizationSends", "Total number of jtaSynchronization sends that have failed", "sends"),
+        f.createLongCounter("jtaSynchronizationSendTime", "Total amount of time, in nanoseconds spent doing jtaSynchronizations", "nanoseconds"),
+        f.createIntGauge("txFailoverSendsInProgress", "Current number of txFailover sends being executed", "sends"), 
+        f.createIntCounter("txFailoverSendFailures", "Total number of txFailover sends that have failed", "sends"),
+        f.createIntCounter("txFailoverSends", "Total number of txFailover sends that have failed", "sends"),
+        f.createLongCounter("txFailoverSendTime", "Total amount of time, in nanoseconds spent doing txFailovers", "nanoseconds"),
+        f.createIntGauge("sizeSendsInProgress", "Current number of size sends being executed", "sends"), 
+        f.createIntCounter("sizeSendFailures", "Total number of size sends that have failed", "sends"),
+        f.createIntCounter("sizeSends", "Total number of size sends that have failed", "sends"),
+        f.createLongCounter("sizeSendTime", "Total amount of time, in nanoseconds spent doing sizes", "nanoseconds"),
+        f.createIntGauge("invalidateSendsInProgress", "Current number of invalidate sends being executed", "sends"), 
+        f.createIntCounter("invalidateSendFailures", "Total number of invalidate sends that have failed", "sends"),
+        f.createIntCounter("invalidateSends", "Total number of invalidate sends that have failed", "sends"),
+        f.createLongCounter("invalidateSendTime", "Total amount of time, in nanoseconds spent doing invalidates", "nanoseconds"),
+        f.createIntGauge("registerInterestSendsInProgress", "Current number of registerInterest sends being executed", "sends"), 
+        f.createIntCounter("registerInterestSends", "Total number of registerInterest sends that have completed successfully", "sends"), 
+        f.createIntCounter("registerInterestSendFailures", "Total number of registerInterest sends that have failed", "sends"), 
+        f.createLongCounter("registerInterestSendTime", "Total amount of time, in nanoseconds spent doing registerInterest sends", "nanoseconds"), 
+        f.createIntGauge("unregisterInterestSendsInProgress", "Current number of unregisterInterest sends being executed", "sends"), 
+        f.createIntCounter("unregisterInterestSends", "Total number of unregisterInterest sends that have completed successfully", "sends"), 
+        f.createIntCounter("unregisterInterestSendFailures", "Total number of unregisterInterest sends that have failed", "sends"), 
+        f.createLongCounter("unregisterInterestSendTime", "Total amount of time, in nanoseconds spent doing unregisterInterest sends", "nanoseconds"), 
+        f.createIntGauge("querySendsInProgress", "Current number of query sends being executed", "sends"), 
+        f.createIntCounter("querySends", "Total number of query sends that have completed successfully", "sends"), 
+        f.createIntCounter("querySendFailures", "Total number of query sends that have failed", "sends"), 
+        f.createLongCounter("querySendTime", "Total amount of time, in nanoseconds spent doing query sends", "nanoseconds"), 
+        f.createIntGauge("createCQSendsInProgress", "Current number of createCQ sends being executed", "sends"), 
+        f.createIntCounter("createCQSends", "Total number of createCQ sends that have completed successfully", "sends"), 
+        f.createIntCounter("createCQSendFailures", "Total number of createCQ sends that have failed", "sends"), 
+        f.createLongCounter("createCQSendTime", "Total amount of time, in nanoseconds spent doing createCQ sends", "nanoseconds"), 
+        f.createIntGauge("stopCQSendsInProgress", "Current number of stopCQ sends being executed", "sends"), 
+        f.createIntCounter("stopCQSends", "Total number of stopCQ sends that have completed successfully", "sends"), 
+        f.createIntCounter("stopCQSendFailures", "Total number of stopCQ sends that have failed", "sends"), 
+        f.createLongCounter("stopCQSendTime", "Total amount of time, in nanoseconds spent doing stopCQ sends", "nanoseconds"), 
+        f.createIntGauge("closeCQSendsInProgress", "Current number of closeCQ sends being executed", "sends"), 
+        f.createIntCounter("closeCQSends", "Total number of closeCQ sends that have completed successfully", "sends"), 
+        f.createIntCounter("closeCQSendFailures", "Total number of closeCQ sends that have failed", "sends"), 
+        f.createLongCounter("closeCQSendTime", "Total amount of time, in nanoseconds spent doing closeCQ sends", "nanoseconds"), 
+        f.createIntGauge("gatewayBatchSendsInProgress", "Current number of gatewayBatch sends being executed", "sends"), 
+        f.createIntCounter("gatewayBatchSends", "Total number of gatewayBatch sends that have completed successfully", "sends"), 
+        f.createIntCounter("gatewayBatchSendFailures", "Total number of gatewayBatch sends that have failed", "sends"), 
+        f.createLongCounter("gatewayBatchSendTime", "Total amount of time, in nanoseconds spent doing gatewayBatch sends", "nanoseconds"), 
+        f.createIntGauge("getDurableCQsSendsInProgressId", "Current number of getDurableCQs sends being executed", "sends"), 
+        f.createIntCounter("getDurableCQsSends", "Total number of getDurableCQs sends that have completed successfully", "sends"), 
+        f.createIntCounter("getDurableCQsSendFailures", "Total number of getDurableCQs sends that have failed", "sends"), 
+        f.createLongCounter("getDurableCQsSendTime", "Total amount of time, in nanoseconds spent doing getDurableCQs sends", "nanoseconds"), 
+        f.createIntGauge("readyForEventsSendsInProgress", "Current number of readyForEvents sends being executed", "sends"), 
+        f.createIntCounter("readyForEventsSends", "Total number of readyForEvents sends that have completed successfully", "sends"), 
+        f.createIntCounter("readyForEventsSendFailures", "Total number of readyForEvents sends that have failed", "sends"), 
+        f.createLongCounter("readyForEventsSendTime", "Total amount of time, in nanoseconds spent doing readyForEvents sends", "nanoseconds"), 
+        f.createIntGauge("makePrimarySendsInProgress", "Current number of makePrimary sends being executed", "sends"), 
+        f.createIntCounter("makePrimarySends", "Total number of makePrimary sends that have completed successfully", "sends"), 
+        f.createIntCounter("makePrimarySendFailures", "Total number of makePrimary sends that have failed", "sends"), 
+        f.createLongCounter("makePrimarySendTime", "Total amount of time, in nanoseconds spent doing makePrimary sends", "nanoseconds"), 
+        f.createIntGauge("closeConSendsInProgress", "Current number of closeCon sends being executed", "sends"), 
+        f.createIntCounter("closeConSends", "Total number of closeCon sends that have completed successfully", "sends"), 
+        f.createIntCounter("closeConSendFailures", "Total number of closeCon sends that have failed", "sends"), 
+        f.createLongCounter("closeConSendTime", "Total amount of time, in nanoseconds spent doing closeCon sends", "nanoseconds"), 
+        f.createIntGauge("primaryAckSendsInProgress", "Current number of primaryAck sends being executed", "sends"), 
+        f.createIntCounter("primaryAckSends", "Total number of primaryAck sends that have completed successfully", "sends"), 
+        f.createIntCounter("primaryAckSendFailures", "Total number of primaryAck sends that have failed", "sends"), 
+        f.createLongCounter("primaryAckSendTime", "Total amount of time, in nanoseconds spent doing primaryAck sends", "nanoseconds"), 
+        f.createIntGauge("pingSendsInProgress", "Current number of ping sends being executed", "sends"), 
+        f.createIntCounter("pingSends", "Total number of ping sends that have completed successfully", "sends"), 
+        f.createIntCounter("pingSendFailures", "Total number of ping sends that have failed", "sends"), 
+        f.createLongCounter("pingSendTime", "Total amount of time, in nanoseconds spent doing ping sends", "nanoseconds"), 
+        f.createIntGauge("registerInstantiatorsSendsInProgress", "Current number of registerInstantiators sends being executed", "sends"), 
+        f.createIntCounter("registerInstantiatorsSends", "Total number of registerInstantiators sends that have completed successfully", "sends"), 
+        f.createIntCounter("registerInstantiatorsSendFailures", "Total number of registerInstantiators sends that have failed", "sends"), 
+        f.createLongCounter("registerInstantiatorsSendTime", "Total amount of time, in nanoseconds spent doing registerInstantiators sends", "nanoseconds"), 
+        f.createIntGauge("registerDataSerializersSendInProgress", "Current number of registerDataSerializers sends being executed", "sends"), 
+        f.createIntCounter("registerDataSerializersSends", "Total number of registerDataSerializers sends that have completed successfully", "sends"), 
+        f.createIntCounter("registerDataSerializersSendFailures", "Total number of registerDataSerializers sends that have failed", "sends"), 
+        f.createLongCounter("registerDataSerializersSendTime", "Total amount of time, in nanoseconds spent doing registerDataSerializers sends", "nanoseconds"), 
+        f.createIntGauge("putAllSendsInProgress", "Current number of putAll sends being executed", "sends"), 
+        f.createIntCounter("putAllSends", "Total number of putAll sends that have completed successfully", "sends"), 
+        f.createIntCounter("putAllSendFailures", "Total number of putAll sends that have failed", "sends"), 
+        f.createLongCounter("putAllSendTime", "Total amount of time, in nanoseconds spent doing putAll sends", "nanoseconds"), 
+        f.createIntGauge("removeAllSendsInProgress", "Current number of removeAll sends being executed", "sends"), 
+        f.createIntCounter("removeAllSends", "Total number of removeAll sends that have completed successfully", "sends"), 
+        f.createIntCounter("removeAllSendFailures", "Total number of removeAll sends that have failed", "sends"), 
+        f.createLongCounter("removeAllSendTime", "Total amount of time, in nanoseconds spent doing removeAll sends", "nanoseconds"), 
+        f.createIntGauge("getAllSendsInProgress", "Current number of getAll sends being executed", "sends"), 
+        f.createIntCounter("getAllSends", "Total number of getAll sends that have completed successfully", "sends"), 
+        f.createIntCounter("getAllSendFailures", "Total number of getAll sends that have failed", "sends"), 
+        f.createLongCounter("getAllSendTime", "Total amount of time, in nanoseconds spent doing getAll sends", "nanoseconds"), 
+        f.createIntGauge("executeFunctionSendsInProgress", "Current number of Function sends being executed", "sends"), 
+        f.createIntCounter("executeFunctionSends", "Total number of Function sends that have completed successfully", "sends"), 
+        f.createIntCounter("executeFunctionSendFailures", "Total number of Function sends that have failed", "sends"), 
+        f.createLongCounter("executeFunctionSendTime", "Total amount of time, in nanoseconds spent doing Function sends", "nanoseconds"), 
+        f.createIntGauge("asyncExecuteFunctionSendsInProgress", "Current number of Function sends being executed asynchronously", "sends"), 
+        f.createIntCounter("asyncExecuteFunctionSends", "Total number of asynchronous Function sends that have completed successfully", "sends"), 
+        f.createIntCounter("asyncExecuteFunctionSendFailures", "Total number of asynchronous Function sends that have failed", "sends"), 
+        f.createLongCounter("asyncExecuteFunctionSendTime", "Total amount of time, in nanoseconds spent doing asynchronous Function sends", "nanoseconds"), 
+        f.createIntGauge("getClientPRMetadataSendsInProgress", "Current number of getClientPRMetadata operation's request messages being send from the client to server", "sends"), 
+        f.createIntCounter("getClientPRMetadataSendFailures", "Total number of getClientPRMetadata operation's request messages not sent successfully from the client to server", "sends"),
+        f.createIntCounter("getClientPRMetadataSendsSuccessful", "Total number of getClientPRMetadata operation's request messages sent successfully from the client to server", "sends"), 
+        f.createLongCounter("getClientPRMetadataSendTime" ,"Total amount of time, in nanoseconds spent sending getClientPRMetadata operation's request messages successfully/unsuccessfully from the client to server", "nanoseconds"),
+        f.createIntGauge("getClientPartitionAttributesSendsInProgress", "Current number of getClientPartitionAttributes operation's request messages being send from the client to server", "sends"), 
+        f.createIntCounter("getClientPartitionAttributesSendFailures", "Total number of getClientPartitionAttributes operation's request messages not sent successfully from the client to server", "sends"),
+        f.createIntCounter("getClientPartitionAttributesSendsSuccessful", "Total number of getClientPartitionAttributes operation's request messages sent successfully from the client to server", "sends"), 
+        f.createLongCounter("getClientPartitionAttributesSendTime","Total amount of time, in nanoseconds spent sending getClientPartitionAttributes operation's request messages successfully/unsuccessfully from the client to server", "nanoseconds"),
+        f.createIntGauge("getPDXTypeByIdSendsInProgress", "Current number of getPDXTypeById operation's request messages being send from the client to server", "sends"), 
+        f.createIntCounter("getPDXTypeByIdSendFailures", "Total number of getPDXTypeById operation's request messages not sent successfully from the client to server", "sends"),
+        f.createIntCounter("getPDXTypeByIdSendsSuccessful", "Total number of getPDXTypeById operation's request messages sent successfully from the client to server", "sends"), 
+        f.createLongCounter("getPDXTypeByIdSendTime","Total amount of time, in nanoseconds spent sending getPDXTypeById operation's request messages successfully/unsuccessfully from the client to server", "nanoseconds"),
+        f.createIntGauge("getPDXIdForTypeSendsInProgress", "Current number of getPDXIdForType operation's request messages being send from the client to server", "sends"), 
+        f.createIntCounter("getPDXIdForTypeSendFailures", "Total number of getPDXIdForType operation's request messages not sent successfully from the client to server", "sends"),
+        f.createIntCounter("getPDXIdForTypeSendsSuccessful", "Total number of getPDXIdForType operation's request messages sent successfully from the client to server", "sends"), 
+        f.createLongCounter("getPDXIdForTypeSendTime","Total amount of time, in nanoseconds spent sending getPDXIdForType operation's request messages successfully/unsuccessfully from the client to server", "nanoseconds"),
+        f.createIntGauge("addPdxTypeSendsInProgress", "Current number of addPdxType operation's request messages being send from the client to server", "sends"), 
+        f.createIntCounter("addPdxTypeSendFailures", "Total number of addPdxType operation's request messages not sent successfully from the client to server", "sends"),
+        f.createIntCounter("addPdxTypeSendsSuccessful", "Total number of addPdxType operation's request messages sent successfully from the client to server", "sends"), 
+        f.createLongCounter("addPdxTypeSendTime","Total amount of time, in nanoseconds spent sending addPdxType operation's request messages successfully/unsuccessfully from the client to server", "nanoseconds"),
+      }
+    );
+    ///////////////////////////////////////////////////////////////////////
+      /*
+    opInProgressId = type.nameToId("opsInProgress");
+    opSendInProgressId = sendType.nameToId("opSendsInProgress");
+    opSendFailedId = sendType.nameToId("opSendFailures");
+    opSendId = sendType.nameToId("opSends");
+    opSendDurationId = sendType.nameToId("opSendTime");
+    opTimedOutId = type.nameToId("opTimeouts");
+    opFailedId = type.nameToId("opFailures");
+    opId = type.nameToId("ops");
+    opDurationId = type.nameToId("opTime");
+      */
+    ///////////////////////////////////////////////////////////////////////
+    getInProgressId = type.nameToId("getsInProgress");
+    getSendInProgressId = sendType.nameToId("getSendsInProgress");
+    getSendFailedId = sendType.nameToId("getSendFailures");
+    getSendId = sendType.nameToId("getSends");
+    getSendDurationId = sendType.nameToId("getSendTime");
+    getTimedOutId = type.nameToId("getTimeouts");
+    getFailedId = type.nameToId("getFailures");
+    getId = type.nameToId("gets");
+    getDurationId = type.nameToId("getTime");
+    putInProgressId = type.nameToId("putsInProgress");
+    putSendInProgressId = sendType.nameToId("putSendsInProgress");
+    putSendFailedId = sendType.nameToId("putSendFailures");
+    putSendId = sendType.nameToId("putSends");
+    putSendDurationId = sendType.nameToId("putSendTime");
+    putTimedOutId = type.nameToId("putTimeouts");
+    putFailedId = type.nameToId("putFailures");
+    putId = type.nameToId("puts");
+    putDurationId = type.nameToId("putTime");
+    destroyInProgressId = type.nameToId("destroysInProgress");
+    destroySendInProgressId = sendType.nameToId("destroySendsInProgress");
+    destroySendFailedId = sendType.nameToId("destroySendFailures");
+    destroySendId = sendType.nameToId("destroySends");
+    destroySendDurationId = sendType.nameToId("destroySendTime");
+    destroyTimedOutId = type.nameToId("destroyTimeouts");
+    destroyFailedId = type.nameToId("destroyFailures");
+    destroyId = type.nameToId("destroys");
+    destroyDurationId = type.nameToId("destroyTime");
+    destroyRegionInProgressId = type.nameToId("destroyRegionsInProgress");
+    destroyRegionSendInProgressId = sendType.nameToId("destroyRegionSendsInProgress");
+    destroyRegionSendFailedId = sendType.nameToId("destroyRegionSendFailures");
+    destroyRegionSendId = sendType.nameToId("destroyRegionSends");
+    destroyRegionSendDurationId = sendType.nameToId("destroyRegionSendTime");
+    destroyRegionTimedOutId = type.nameToId("destroyRegionTimeouts");
+    destroyRegionFailedId = type.nameToId("destroyRegionFailures");
+    destroyRegionId = type.nameToId("destroyRegions");
+    destroyRegionDurationId = type.nameToId("destroyRegionTime");
+    clearInProgressId = type.nameToId("clearsInProgress");
+    clearSendInProgressId = sendType.nameToId("clearSendsInProgress");
+    clearSendFailedId = sendType.nameToId("clearSendFailures");
+    clearSendId = sendType.nameToId("clearSends");
+    clearSendDurationId = sendType.nameToId("clearSendTime");
+    clearTimedOutId = type.nameToId("clearTimeouts");
+    clearFailedId = type.nameToId("clearFailures");
+    clearId = type.nameToId("clears");
+    clearDurationId = type.nameToId("clearTime");
+    containsKeyInProgressId = type.nameToId("containsKeysInProgress");
+    containsKeySendInProgressId = sendType.nameToId("containsKeySendsInProgress");
+    containsKeySendFailedId = sendType.nameToId("containsKeySendFailures");
+    containsKeySendId = sendType.nameToId("containsKeySends");
+    containsKeySendDurationId = sendType.nameToId("containsKeySendTime");
+    containsKeyTimedOutId = type.nameToId("containsKeyTimeouts");
+    containsKeyFailedId = type.nameToId("containsKeyFailures");
+    containsKeyId = type.nameToId("containsKeys");
+    containsKeyDurationId = type.nameToId("containsKeyTime");
+
+    keySetInProgressId = type.nameToId("keySetsInProgress");
+    keySetSendInProgressId = sendType.nameToId("keySetSendsInProgress");
+    keySetSendFailedId = sendType.nameToId("keySetSendFailures");
+    keySetSendId = sendType.nameToId("keySetSends");
+    keySetSendDurationId = sendType.nameToId("keySetSendTime");
+    keySetTimedOutId = type.nameToId("keySetTimeouts");
+    keySetFailedId = type.nameToId("keySetFailures");
+    keySetId = type.nameToId("keySets");
+    keySetDurationId = type.nameToId("keySetTime");
+    
+    commitInProgressId = type.nameToId("commitsInProgress");
+    commitSendInProgressId = sendType.nameToId("commitSendsInProgress");
+    commitSendFailedId = sendType.nameToId("commitSendFailures");
+    commitSendId = sendType.nameToId("commitSends");
+    commitSendDurationId = sendType.nameToId("commitSendTime");
+    commitDurationId = type.nameToId("commitTime");
+    commitTimedOutId = type.nameToId("commitTimeouts");
+    commitFailedId = type.nameToId("commitFailures");
+    commitId = type.nameToId("commits");
+    
+    rollbackInProgressId = type.nameToId("rollbacksInProgress");
+    rollbackSendInProgressId = sendType.nameToId("rollbackSendsInProgress");
+    rollbackSendFailedId = sendType.nameToId("rollbackSendFailures");
+    rollbackSendId = sendType.nameToId("rollbackSends");
+    rollbackSendDurationId = sendType.nameToId("rollbackSendTime");
+    rollbackDurationId = type.nameToId("rollbackTime");
+    rollbackTimedOutId = type.nameToId("rollbackTimeouts");
+    rollbackFailedId = type.nameToId("rollbackFailures");
+    rollbackId = type.nameToId("rollbacks");
+    
+    getEntryInProgressId = type.nameToId("getEntrysInProgress");
+    getEntrySendInProgressId = sendType.nameToId("getEntrySendsInProgress");
+    getEntrySendFailedId = sendType.nameToId("getEntrySendFailures");
+    getEntrySendId = sendType.nameToId("getEntrySends");
+    getEntrySendDurationId = sendType.nameToId("getEntrySendTime");
+    getEntryDurationId = type.nameToId("getEntryTime");
+    getEntryTimedOutId = type.nameToId("getEntryTimeouts");
+    getEntryFailedId = type.nameToId("getEntryFailures");
+    getEntryId = type.nameToId("getEntrys");
+    
+    txSynchronizationInProgressId = type.nameToId("jtaSynchronizationsInProgress");
+    txSynchronizationSendInProgressId = sendType.nameToId("jtaSynchronizationSendsInProgress");
+    txSynchronizationSendFailedId = sendType.nameToId("jtaSynchronizationSendFailures");
+    txSynchronizationSendId = sendType.nameToId("jtaSynchronizationSends");
+    txSynchronizationSendDurationId = sendType.nameToId("jtaSynchronizationSendTime");
+    txSynchronizationDurationId = type.nameToId("jtaSynchronizationTime");
+    txSynchronizationTimedOutId = type.nameToId("jtaSynchronizationTimeouts");
+    txSynchronizationFailedId = type.nameToId("jtaSynchronizationFailures");
+    txSynchronizationId = type.nameToId("jtaSynchronizations");
+    
+    txFailoverInProgressId = type.nameToId("txFailoversInProgress");
+    txFailoverSendInProgressId = sendType.nameToId("txFailoverSendsInProgress");
+    txFailoverSendFailedId = sendType.nameToId("txFailoverSendFailures");
+    txFailoverSendId = sendType.nameToId("txFailoverSends");
+    txFailoverSendDurationId = sendType.nameToId("txFailoverSendTime");
+    txFailoverDurationId = type.nameToId("txFailoverTime");
+    txFailoverTimedOutId = type.nameToId("txFailoverTimeouts");
+    txFailoverFailedId = type.nameToId("txFailoverFailures");
+    txFailoverId = type.nameToId("txFailovers");
+    
+    sizeInProgressId = type.nameToId("sizesInProgress");
+    sizeSendInProgressId = sendType.nameToId("sizeSendsInProgress");
+    sizeSendFailedId = sendType.nameToId("sizeSendFailures");
+    sizeSendId = sendType.nameToId("sizeSends");
+    sizeSendDurationId = sendType.nameToId("sizeSendTime");
+    sizeDurationId = type.nameToId("sizeTime");
+    sizeTimedOutId = type.nameToId("sizeTimeouts");
+    sizeFailedId = type.nameToId("sizeFailures");
+    sizeId = type.nameToId("sizes");
+    
+    
+    invalidateInProgressId = type.nameToId("invalidatesInProgress");
+    invalidateSendInProgressId = sendType.nameToId("invalidateSendsInProgress");
+    invalidateSendFailedId = sendType.nameToId("invalidateSendFailures");
+    invalidateSendId = sendType.nameToId("invalidateSends");
+    invalidateSendDurationId = sendType.nameToId("invalidateSendTime");
+    invalidateDurationId = type.nameToId("invalidateTime");
+    invalidateTimedOutId = type.nameToId("invalidateTimeouts");
+    invalidateFailedId = type.nameToId("invalidateFailures");
+    invalidateId = type.nameToId("invalidates");
+    
+    
+    registerInterestInProgressId = type.nameToId("registerInterestsInProgress");
+    registerInterestSendInProgressId = sendType.nameToId("registerInterestSendsInProgress");
+    registerInterestSendFailedId = sendType.nameToId("registerInterestSendFailures");
+    registerInterestSendId = sendType.nameToId("registerInterestSends");
+    registerInterestSendDurationId = sendType.nameToId("registerInterestSendTime");
+    registerInterestTimedOutId = type.nameToId("registerInterestTimeouts");
+    registerInterestFailedId = type.nameToId("registerInterestFailures");
+    registerInterestId = type.nameToId("registerInterests");
+    registerInterestDurationId = type.nameToId("registerInterestTime");
+    unregisterInterestInProgressId = type.nameToId("unregisterInterestsInProgress");
+    unregisterInterestSendInProgressId = sendType.nameToId("unregisterInterestSendsInProgress");
+    unregisterInterestSendFailedId = sendType.nameToId("unregisterInterestSendFailures");
+    unregisterInterestSendId = sendType.nameToId("unregisterInterestSends");
+    unregisterInterestSendDurationId = sendType.nameToId("unregisterInterestSendTime");
+    unregisterInterestTimedOutId = type.nameToId("unregisterInterestTimeouts");
+    unregisterInterestFailedId = type.nameToId("unregisterInterestFailures");
+    unregisterInterestId = type.nameToId("unregisterInterests");
+    unregisterInterestDurationId = type.nameToId("unregisterInterestTime");
+    queryInProgressId = type.nameToId("querysInProgress");
+    querySendInProgressId = sendType.nameToId("querySendsInProgress");
+    querySendFailedId = sendType.nameToId("querySendFailures");
+    querySendId = sendType.nameToId("querySends");
+    querySendDurationId = sendType.nameToId("querySendTime");
+    queryTimedOutId = type.nameToId("queryTimeouts");
+    queryFailedId = type.nameToId("queryFailures");
+    queryId = type.nameToId("querys");
+    queryDurationId = type.nameToId("queryTime");
+    createCQInProgressId = type.nameToId("createCQsInProgress");
+    createCQSendInProgressId = sendType.nameToId("createCQSendsInProgress");
+    createCQSendFailedId = sendType.nameToId("createCQSendFailures");
+    createCQSendId = sendType.nameToId("createCQSends");
+    createCQSendDurationId = sendType.nameToId("createCQSendTime");
+    createCQTimedOutId = type.nameToId("createCQTimeouts");
+    createCQFailedId = type.nameToId("createCQFailures");
+    createCQId = type.nameToId("createCQs");
+    createCQDurationId = type.nameToId("createCQTime");
+    stopCQInProgressId = type.nameToId("stopCQsInProgress");
+    stopCQSendInProgressId = sendType.nameToId("stopCQSendsInProgress");
+    stopCQSendFailedId = sendType.nameToId("stopCQSendFailures");
+    stopCQSendId = sendType.nameToId("stopCQSends");
+    stopCQSendDurationId = sendType.nameToId("stopCQSendTime");
+    stopCQTimedOutId = type.nameToId("stopCQTimeouts");
+    stopCQFailedId = type.nameToId("stopCQFailures");
+    stopCQId = type.nameToId("stopCQs");
+    stopCQDurationId = type.nameToId("stopCQTime");
+    closeCQInProgressId = type.nameToId("closeCQsInProgress");
+    closeCQSendInProgressId = sendType.nameToId("closeCQSendsInProgress");
+    closeCQSendFailedId = sendType.nameToId("closeCQSendFailures");
+    closeCQSendId = sendType.nameToId("closeCQSends");
+    closeCQSendDurationId = sendType.nameToId("closeCQSendTime");
+    closeCQTimedOutId = type.nameToId("closeCQTimeouts");
+    closeCQFailedId = type.nameToId("closeCQFailures");
+    closeCQId = type.nameToId("closeCQs");
+    closeCQDurationId = type.nameToId("closeCQTime");
+    gatewayBatchInProgressId = type.nameToId("gatewayBatchsInProgress");
+    gatewayBatchSendInProgressId = sendType.nameToId("gatewayBatchSendsInProgress");
+    gatewayBatchSendFailedId = sendType.nameToId("gatewayBatchSendFailures");
+    gatewayBatchSendId = sendType.nameToId("gatewayBatchSends");
+    gatewayBatchSendDurationId = sendType.nameToId("gatewayBatchSendTime");
+    gatewayBatchTimedOutId = type.nameToId("gatewayBatchTimeouts");
+    gatewayBatchFailedId = type.nameToId("gatewayBatchFailures");
+    gatewayBatchId = type.nameToId("gatewayBatchs");
+    gatewayBatchDurationId = type.nameToId("gatewayBatchTime");
+    getDurableCQsInProgressId = type.nameToId("getDurableCQsInProgress");
+    getDurableCQsSendsInProgressId = sendType.nameToId("getDurableCQsSendsInProgressId");
+    getDurableCQsSendFailedId = sendType.nameToId("getDurableCQsSendFailures");
+    getDurableCQsSendId = sendType.nameToId("getDurableCQsSends");
+    getDurableCQsSendDurationId = sendType.nameToId("getDurableCQsSendTime");
+    getDurableCQsTimedOutId = type.nameToId("getDurableCQsTimeouts");
+    getDurableCQsFailedId = type.nameToId("getDurableCQsFailures");
+    getDurableCQsId = type.nameToId("getDurableCQs");
+    getDurableCQsDurationId = type.nameToId("getDurableCQsTime");
+    readyForEventsInProgressId = type.nameToId("readyForEventsInProgress");
+    readyForEventsSendInProgressId = sendType.nameToId("readyForEventsSendsInProgress");
+    readyForEventsSendFailedId = sendType.nameToId("readyForEventsSendFailures");
+    readyForEventsSendId = sendType.nameToId("readyForEventsSends");
+    readyForEventsSendDurationId = sendType.nameToId("readyForEventsSendTime");
+    readyForEventsTimedOutId = type.nameToId("readyForEventsTimeouts");
+    readyForEventsFailedId = type.nameToId("readyForEventsFailures");
+    readyForEventsId = type.nameToId("readyForEvents");
+    readyForEventsDurationId = type.nameToId("readyForEventsTime");
+    makePrimaryInProgressId = type.nameToId("makePrimarysInProgress");
+    makePrimarySendInProgressId = sendType.nameToId("makePrimarySendsInProgress");
+    makePrimarySendFailedId = sendType.nameToId("makePrimarySendFailures");
+    makePrimarySendId = sendType.nameToId("makePrimarySends");
+    makePrimarySendDurationId = sendType.nameToId("makePrimarySendTime");
+    makePrimaryTimedOutId = type.nameToId("makePrimaryTimeouts");
+    makePrimaryFailedId = type.nameToId("makePrimaryFailures");
+    makePrimaryId = type.nameToId("makePrimarys");
+    makePrimaryDurationId = type.nameToId("makePrimaryTime");
+
+    closeConInProgressId = type.nameToId("closeConsInProgress");
+    closeConSendInProgressId = sendType.nameToId("closeConSendsInProgress");
+    closeConSendFailedId = sendType.nameToId("closeConSendFailures");
+    closeConSendId = sendType.nameToId("closeConSends");
+    closeConSendDurationId = sendType.nameToId("closeConSendTime");
+    closeConTimedOutId = type.nameToId("closeConTimeouts");
+    closeConFailedId = type.nameToId("closeConFailures");
+    closeConId = type.nameToId("closeCons");
+    closeConDurationId = type.nameToId("closeConTime");
+
+    primaryAckInProgressId = type.nameToId("primaryAcksInProgress");
+    primaryAckSendInProgressId = sendType.nameToId("primaryAckSendsInProgress");
+    primaryAckSendFailedId = sendType.nameToId("primaryAckSendFailures");
+    primaryAckSendId = sendType.nameToId("primaryAckSends");
+    primaryAckSendDurationId = sendType.nameToId("primaryAckSendTime");
+    primaryAckTimedOutId = type.nameToId("primaryAckTimeouts");
+    primaryAckFailedId = type.nameToId("primaryAckFailures");
+    primaryAckId = type.nameToId("primaryAcks");
+    primaryAckDurationId = type.nameToId("primaryAckTime");
+
+    pingInProgressId = type.nameToId("pingsInProgress");
+    pingSendInProgressId = sendType.nameToId("pingSendsInProgress");
+    pingSendFailedId = sendType.nameToId("pingSendFailures");
+    pingSendId = sendType.nameToId("pingSends");
+    pingSendDurationId = sendType.nameToId("pingSendTime");
+    pingTimedOutId = type.nameToId("pingTimeouts");
+    pingFailedId = type.nameToId("pingFailures");
+    pingId = type.nameToId("pings");
+    pingDurationId = type.nameToId("pingTime");
+
+    registerInstantiatorsInProgressId = type.nameToId("registerInstantiatorsInProgress");
+    registerInstantiatorsSendInProgressId = sendType.nameToId("registerInstantiatorsSendsInProgress");
+    registerInstantiatorsSendFailedId = sendType.nameToId("registerInstantiatorsSendFailures");
+    registerInstantiatorsSendId = sendType.nameToId("registerInstantiatorsSends");
+    registerInstantiatorsSendDurationId = sendType.nameToId("registerInstantiatorsSendTime");
+    registerInstantiatorsTimedOutId = type.nameToId("registerInstantiatorsTimeouts");
+    registerInstantiatorsFailedId = type.nameToId("registerInstantiatorsFailures");
+    registerInstantiatorsId = type.nameToId("registerInstantiators");
+    registerInstantiatorsDurationId = type.nameToId("registerInstantiatorsTime");
+
+    registerDataSerializersInProgressId = type.nameToId("registerDataSerializersInProgress");
+    registerDataSerializersSendInProgressId = sendType.nameToId("registerDataSerializersSendInProgress");
+    registerDataSerializersSendFailedId = sendType.nameToId("registerDataSerializersSendFailures");
+    registerDataSerializersSendId = sendType.nameToId("registerDataSerializersSends");
+    registerDataSerializersSendDurationId = sendType.nameToId("registerDataSerializersSendTime");
+    registerDataSerializersTimedOutId = type.nameToId("registerDataSerializersTimeouts");
+    registerDataSerializersFailedId = type.nameToId("registerDataSerializersFailures");
+    registerDataSerializersId = type.nameToId("registerDataSerializers");
+    registerDataSerializersDurationId = type.nameToId("registerDataSerializersTime");
+    
+    putAllInProgressId = type.nameToId("putAllsInProgress");
+    putAllSendInProgressId = sendType.nameToId("putAllSendsInProgress");
+    putAllSendFailedId = sendType.nameToId("putAllSendFailures");
+    putAllSendId = sendType.nameToId("putAllSends");
+    putAllSendDurationId = sendType.nameToId("putAllSendTime");
+    putAllTimedOutId = type.nameToId("putAllTimeouts");
+    putAllFailedId = type.nameToId("putAllFailures");
+    putAllId = type.nameToId("putAlls");
+    putAllDurationId = type.nameToId("putAllTime");
+    
+    removeAllInProgressId = type.nameToId("removeAllsInProgress");
+    removeAllSendInProgressId = sendType.nameToId("removeAllSendsInProgress");
+    removeAllSendFailedId = sendType.nameToId("removeAllSendFailures");
+    removeAllSendId = sendType.nameToId("removeAllSends");
+    removeAllSendDurationId = sendType.nameToId("removeAllSendTime");
+    removeAllTimedOutId = type.nameToId("removeAllTimeouts");
+    removeAllFailedId = type.nameToId("removeAllFailures");
+    removeAllId = type.nameToId("removeAlls");
+    removeAllDurationId = type.nameToId("removeAllTime");
+
+    getAllInProgressId = type.nameToId("getAllsInProgress");
+    getAllSendInProgressId = sendType.nameToId("getAllSendsInProgress");
+    getAllSendFailedId = sendType.nameToId("getAllSendFailures");
+    getAllSendId = sendType.nameToId("getAllSends");
+    getAllSendDurationId = sendType.nameToId("getAllSendTime");
+    getAllTimedOutId = type.nameToId("getAllTimeouts");
+    getAllFailedId = type.nameToId("getAllFailures");
+    getAllId = type.nameToId("getAlls");
+    getAllDurationId = type.nameToId("getAllTime");
+
+    connectionsId = type.nameToId("connections");
+    connectsId = type.nameToId("connects");
+    disconnectsId = type.nameToId("disconnects");
+    
+    receivedBytesId = type.nameToId("receivedBytes");
+    sentBytesId = type.nameToId("sentBytes");
+    messagesBeingReceivedId = type.nameToId("messagesBeingReceived");
+    messageBytesBeingReceivedId = type.nameToId("messageBytesBeingReceived");
+    
+    executeFunctionInProgressId = type.nameToId("executeFunctionsInProgress");
+    executeFunctionSendInProgressId = sendType.nameToId("executeFunctionSendsInProgress");
+    executeFunctionSendFailedId = sendType.nameToId("executeFunctionSendFailures");
+    executeFunctionSendId = sendType.nameToId("executeFunctionSends");
+    executeFunctionSendDurationId = sendType.nameToId("executeFunctionSendTime");
+    executeFunctionTimedOutId = type.nameToId("executeFunctionTimeouts");
+    executeFunctionFailedId = type.nameToId("executeFunctionFailures");
+    executeFunctionId = type.nameToId("executeFunctions");
+    executeFunctionDurationId = type.

<TRUNCATED>

[09/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/InvalidateOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/InvalidateOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/InvalidateOp.java
new file mode 100644
index 0000000..f15260f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/InvalidateOp.java
@@ -0,0 +1,112 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+import com.gemstone.gemfire.internal.cache.tier.MessageType;
+import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
+import com.gemstone.gemfire.internal.cache.versions.VersionTag;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * Does a region invalidate on a server
+ * @author gregp
+ * @since 6.6
+ */
+public class InvalidateOp {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  public static final int HAS_VERSION_TAG = 0x01;
+  
+  /**
+   * Does a region invalidate 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 void execute(ExecutablePool pool,
+                            String region, EntryEventImpl event)
+  {
+    AbstractOp op = new InvalidateOpImpl(region, event);
+    pool.execute(op);
+  }
+                                                               
+  private InvalidateOp() {
+    // no instances allowed
+  }
+  
+  private static class InvalidateOpImpl extends AbstractOp {
+    private EntryEventImpl event;
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public InvalidateOpImpl(String region,
+                         EntryEventImpl event) {
+      super(MessageType.INVALIDATE, event.getCallbackArgument() != null ? 4 : 3);
+      Object callbackArg = event.getCallbackArgument();
+      this.event = event;
+      getMessage().addStringPart(region);
+      getMessage().addStringOrObjPart(event.getKeyInfo().getKey());
+      getMessage().addBytesPart(event.getEventId().calcBytes());
+      if (callbackArg != null) {
+        getMessage().addObjPart(callbackArg);
+      }
+    }
+
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      throw new UnsupportedOperationException();
+    }
+    
+    
+    @Override
+    protected Object processResponse(Message msg, Connection con) throws Exception {
+       processAck(msg, "invalidate");
+       boolean isReply = (msg.getMessageType() == MessageType.REPLY);
+       int partIdx = 0;
+       int flags = 0;
+       if (isReply) {
+         flags = msg.getPart(partIdx++).getInt();
+         if ((flags & HAS_VERSION_TAG) != 0) {
+           VersionTag tag = (VersionTag)msg.getPart(partIdx++).getObject();
+           // we use the client's ID since we apparently don't track the server's ID in connections
+           tag.replaceNullIDs((InternalDistributedMember)  con.getEndpoint().getMemberId());
+           this.event.setVersionTag(tag);
+           if (logger.isDebugEnabled()) {
+             logger.debug("received Invalidate response with {}", tag);
+           }
+         } else {
+           if (logger.isDebugEnabled()) {
+             logger.debug("received Invalidate response");
+           }
+         }
+       }
+       return null;
+    }
+    @Override  
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.INVALIDATE_ERROR;
+    }
+    @Override  
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startInvalidate();
+    }
+    @Override  
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endInvalidateSend(start, hasFailed());
+    }
+    @Override  
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endInvalidate(start, hasTimedOut(), hasFailed());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/KeySetOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/KeySetOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/KeySetOp.java
new file mode 100644
index 0000000..26cc4a2
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/KeySetOp.java
@@ -0,0 +1,121 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import com.gemstone.gemfire.InternalGemFireError;
+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.ChunkedMessage;
+import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
+import com.gemstone.gemfire.cache.client.ServerOperationException;
+
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * Does a region keySet on a server
+ * @author darrel
+ * @since 5.7
+ */
+public class KeySetOp {
+  /**
+   * Does a region entry keySet 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 Set execute(ExecutablePool pool,
+                            String region)
+  {
+    AbstractOp op = new KeySetOpImpl(region);
+    return (Set)pool.execute(op);
+  }
+                                                               
+  private KeySetOp() {
+    // no instances allowed
+  }
+  
+  private static class KeySetOpImpl extends AbstractOp {
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public KeySetOpImpl(String region) {
+      super(MessageType.KEY_SET, 1);
+      getMessage().addStringPart(region);
+    }
+    @Override  
+    protected Message createResponseMessage() {
+      return new ChunkedMessage(1, Version.CURRENT);
+    }
+    @Override  
+    protected Object processResponse(Message msg) throws Exception {
+      
+      ChunkedMessage keySetResponseMessage = (ChunkedMessage)msg;
+      final HashSet result = new HashSet();
+      final Exception[] exceptionRef = new Exception[1];
+      
+      keySetResponseMessage.readHeader();
+      final int msgType = keySetResponseMessage.getMessageType();
+      if (msgType == MessageType.RESPONSE) {
+        do {
+          keySetResponseMessage.receiveChunk();
+          //callback.handle(msg);
+          Part part = keySetResponseMessage.getPart(0);
+          Object o = part.getObject();
+          if (o instanceof Throwable) {
+            String s = "While performing a remote keySet";
+            exceptionRef[0] = new ServerOperationException(s, (Throwable)o);
+          } else {
+            result.addAll((List)o);
+          }
+        } while (!keySetResponseMessage.isLastChunk());
+      } else {
+        if (msgType == MessageType.EXCEPTION) {
+          keySetResponseMessage.receiveChunk();
+          Part part = msg.getPart(0);
+          String s = "While performing a remote " +  "keySet";
+          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)) {
+          keySetResponseMessage.receiveChunk();
+          Part part = msg.getPart(0);
+          throw new ServerOperationException(part.getString());
+        } else {
+          throw new InternalGemFireError("Unexpected message type "
+                                         + MessageType.getString(msgType));
+        }
+      }
+      
+      if (exceptionRef[0] != null) {
+        throw exceptionRef[0];
+      } else {
+        return result;
+      }
+    }
+    @Override  
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.KEY_SET_DATA_ERROR;
+    }
+    @Override  
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startKeySet();
+    }
+    @Override  
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endKeySetSend(start, hasFailed());
+    }
+    @Override  
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endKeySet(start, hasTimedOut(), hasFailed());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/LiveServerPinger.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/LiveServerPinger.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/LiveServerPinger.java
new file mode 100644
index 0000000..1f01cf5
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/LiveServerPinger.java
@@ -0,0 +1,108 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.Future;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.cache.client.internal.EndpointManager.EndpointListenerAdapter;
+import com.gemstone.gemfire.cache.client.internal.PoolImpl.PoolTask;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * Responsible for pinging live
+ * servers to make sure they
+ * are still alive.
+ * @author dsmith
+ *
+ */
+public class LiveServerPinger  extends EndpointListenerAdapter {
+  private static final Logger logger = LogService.getLogger();
+  
+  private static final long NANOS_PER_MS = 1000000L;
+  
+  private final ConcurrentMap/*<Endpoint,Future>*/ taskFutures = new ConcurrentHashMap();
+  protected final InternalPool pool;
+  protected final long pingIntervalNanos;
+  
+  public LiveServerPinger(InternalPool pool) {
+    this.pool = pool;
+    this.pingIntervalNanos = pool.getPingInterval() * NANOS_PER_MS;
+  }
+
+  @Override
+  public void endpointCrashed(Endpoint endpoint) {
+    cancelFuture(endpoint);
+  }
+
+  @Override
+  public void endpointNoLongerInUse(Endpoint endpoint) {
+    cancelFuture(endpoint);
+  }
+
+  @Override
+  public void endpointNowInUse(Endpoint endpoint) {
+    try {
+      Future future = pool.getBackgroundProcessor().scheduleWithFixedDelay(
+          new PingTask(endpoint), pingIntervalNanos, pingIntervalNanos,
+          TimeUnit.NANOSECONDS);
+      taskFutures.put(endpoint, future);
+    } catch (RejectedExecutionException e) {
+      if (pool.getCancelCriterion().cancelInProgress() == null) {
+        throw e;
+      }
+    }
+  }
+  
+  private void cancelFuture(Endpoint endpoint) {
+    Future future = (Future) taskFutures.remove(endpoint);
+    if(future != null) {
+      future.cancel(false);
+    }
+  }
+  
+  private class PingTask extends PoolTask {
+    private final Endpoint endpoint;
+    
+    public PingTask(Endpoint endpoint) {
+      this.endpoint = endpoint;
+    }
+
+    @Override
+    public void run2() {
+      if(endpoint.timeToPing(pingIntervalNanos)) {
+//      logger.fine("DEBUG pinging " + server);
+        try {
+          PingOp.execute(pool, endpoint.getLocation());
+        } catch(Exception e) {
+          if(logger.isDebugEnabled()) {
+            logger.debug("Error occured while pinging server: {} - {}", endpoint.getLocation(), e.getMessage());
+          }
+          GemFireCacheImpl cache = GemFireCacheImpl.getInstance();          
+          if (cache != null) {
+            ClientMetadataService cms = cache.getClientMetadataService();
+            cms.removeBucketServerLocation(endpoint.getLocation());
+          }        
+          //any failure to ping the server should be considered a crash (eg.
+          //socket timeout exception, security exception, failure to connect).
+          pool.getEndpointManager().serverCrashed(endpoint);
+        }
+      } else {
+//      logger.fine("DEBUG skipping ping of " + server
+//      + " because lastAccessed=" + endpoint.getLastAccessed());
+      }
+    }
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/LocatorDiscoveryCallback.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/LocatorDiscoveryCallback.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/LocatorDiscoveryCallback.java
new file mode 100644
index 0000000..02ccbd9
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/LocatorDiscoveryCallback.java
@@ -0,0 +1,38 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.List;
+
+/**
+ * A callback to receive notifications about locator discovery. Currently 
+ * only used internally.
+ * @author dsmith
+ * @since 5.7
+ */
+public interface LocatorDiscoveryCallback {
+  
+  /**
+   * Called to indicate that new locators
+   * have been discovered
+   * @param locators a list of InetSocketAddresses of new
+   * locators that have been discovered.
+   */
+  void locatorsDiscovered(List locators);
+  
+  /**
+   * Called to indicated that locators
+   * have been removed from the list
+   * of available locators.
+   * @param locators a list of InetSocketAddresses
+   * of locators that have been removed
+   */
+  void locatorsRemoved(List locators);
+  
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/LocatorDiscoveryCallbackAdapter.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/LocatorDiscoveryCallbackAdapter.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/LocatorDiscoveryCallbackAdapter.java
new file mode 100644
index 0000000..b8ba3aa
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/LocatorDiscoveryCallbackAdapter.java
@@ -0,0 +1,27 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.List;
+
+/**
+ * A locator discovery callback that does nothing.
+ * @author dsmith
+ * @since 5.7
+ *
+ */
+public class LocatorDiscoveryCallbackAdapter implements
+    LocatorDiscoveryCallback {
+
+  public void locatorsDiscovered(List locators) {
+  }
+
+  public void locatorsRemoved(List locators) {
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/MakePrimaryOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/MakePrimaryOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/MakePrimaryOp.java
new file mode 100644
index 0000000..79d2e1f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/MakePrimaryOp.java
@@ -0,0 +1,82 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().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/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/Op.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/Op.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/Op.java
new file mode 100644
index 0000000..403a112
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/Op.java
@@ -0,0 +1,34 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+/**
+ * An operation to perform on a server. Used by
+ * {@link ExecutablePool} to attempt the operation on 
+ * multiple servers until the retryAttempts is exceeded.
+ * @author dsmith
+ * @since 5.7
+ *
+ */
+public interface Op {
+
+  /**
+   * Attempts to execute this operation by sending its message out on the
+   * given connection, waiting for a response, and returning it.
+   * @param cnx the connection to use when attempting execution of the operation.
+   * @return the result of the operation
+   *         or <code>null</code if the operation has no result.
+   * @throws Exception if the execute failed
+   */
+  Object attempt(Connection cnx) throws Exception;
+
+  /**
+   * @return true if this Op should use a threadLocalConnection, false otherwise
+   */
+  boolean useThreadLocalConnection();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/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
new file mode 100644
index 0000000..967a8c3
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/OpExecutorImpl.java
@@ -0,0 +1,964 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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.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.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 (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) {
+      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/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PdxRegistryRecoveryListener.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PdxRegistryRecoveryListener.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PdxRegistryRecoveryListener.java
new file mode 100644
index 0000000..c70e312
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PdxRegistryRecoveryListener.java
@@ -0,0 +1,81 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.pdx.internal.TypeRegistry;
+
+/**
+ * A listener which will wipe out the PDX registry on the client side if the
+ * entire server distributed system was lost and came back on line. <br>
+ * <br>
+ * TODO - There is a window in which all of the servers could crash and come
+ * back up and we would connect to a new server before realizing that all the
+ * servers crashed. To fix this, we would need to get some kind of birthdate of
+ * the server ds we connect and use that to decide if we need to recover
+ * the PDX registry.
+ * 
+ * We can also lose connectivity with the servers, even if the servers are still
+ * running. Maybe for the PDX registry we need some way of telling if the PDX
+ * registry was lost at the server side in the interval. 
+ * 
+ * 
+ * @author dsmith
+ * 
+ */
+public class PdxRegistryRecoveryListener extends EndpointManager.EndpointListenerAdapter {
+  private static final Logger logger = LogService.getLogger();
+  
+  private final AtomicInteger endpointCount = new AtomicInteger();
+  private final InternalPool pool;
+  
+  public PdxRegistryRecoveryListener(InternalPool pool) {
+    this.pool = pool;
+  }
+  
+  @Override
+  public void endpointCrashed(Endpoint endpoint) {
+    int count = endpointCount.decrementAndGet();
+    if (logger.isDebugEnabled()) {
+      logger.debug("PdxRegistryRecoveryListener - EndpointCrashed. Now have {} endpoints", count);
+    }
+  }
+
+  @Override
+  public void endpointNoLongerInUse(Endpoint endpoint) {
+    int count = endpointCount.decrementAndGet();
+    if (logger.isDebugEnabled()) {
+      logger.debug("PdxRegistryRecoveryListener - EndpointNoLongerInUse. Now have {} endpoints", count);
+    }
+  }
+
+  @Override
+  public void endpointNowInUse(Endpoint endpoint) {
+    int count  = endpointCount.incrementAndGet();
+    if (logger.isDebugEnabled()) {
+      logger.debug("PdxRegistryRecoveryListener - EndpointNowInUse. Now have {} endpoints", count);
+    }
+    if(count == 1) {
+      GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+      if(cache == null) {
+        return;
+      }
+      TypeRegistry registry = cache.getPdxRegistry();
+      
+      if(registry == null) {
+        return;
+      }
+      registry.clear();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PingOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PingOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PingOp.java
new file mode 100644
index 0000000..ac32e39
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PingOp.java
@@ -0,0 +1,104 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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));
+      startTime = System.currentTimeMillis();
+      getMessage().send(false);
+      Message.messageType.set(MessageType.PING);
+    }
+
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      processAck(msg, "ping");
+      final int msgType = msg.getMessageType();
+      if (msgType == MessageType.REPLY  &&  msg.getNumberOfParts() > 1) {
+        long endTime = System.currentTimeMillis();
+        long serverTime = msg.getPart(1).getLong();
+        // the new clock offset is computed assuming that the server's timestamp was
+        // taken mid-way between when the ping was sent and the reply was
+        // received:
+        //    timestampElapsedTime = (endTime - startTime)/2
+        //    localTime = startTime + timestampElapsedTime
+        //    offsetFromServer = serverTime - localTime
+        long newCacheTimeOffset = serverTime - startTime/2 - endTime/2;
+        InternalDistributedSystem ds = InternalDistributedSystem.getConnectedInstance();
+        if (ds != null && ds.isLoner()) { // check for loner so we don't jump time offsets across WAN connections
+          ds.getClock().setCacheTimeOffset(null, newCacheTimeOffset, false);
+        }
+      }
+      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());
+    }
+  }
+}


[51/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
Init


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

Branch: refs/heads/master
Commit: 194590531e50039c23459956a162c4c5257640a4
Parents: 
Author: Roman Shaposhnik <rv...@apache.org>
Authored: Tue Apr 28 14:37:16 2015 -0700
Committer: Roman Shaposhnik <rv...@apache.org>
Committed: Tue Apr 28 14:37:16 2015 -0700

----------------------------------------------------------------------
 .gitignore                                      |    19 +
 COMPILING.txt                                   |    13 +
 LICENSE.txt                                     |   202 +
 NOTICE                                          |   339 +
 README.md                                       |    90 +
 RUNNING.txt                                     |    23 +
 build.gradle                                    |   267 +
 etc/eclipseFormatterProfile.xml                 |   264 +
 etc/intellijIdeaCodeStyle.xml                   |   109 +
 gemfire-assembly/build.gradle                   |   171 +
 gemfire-assembly/src/main/dist/bin/gfsh         |   138 +
 .../src/main/dist/bin/gfsh-completion.bash      |    88 +
 gemfire-assembly/src/main/dist/bin/gfsh.bat     |    73 +
 gemfire-core/build.gradle                       |   133 +
 .../internal/ra/GFConnectionFactoryImpl.java    |    57 +
 .../gemfire/internal/ra/GFConnectionImpl.java   |    62 +
 .../internal/ra/spi/JCALocalTransaction.java    |   227 +
 .../internal/ra/spi/JCAManagedConnection.java   |   290 +
 .../ra/spi/JCAManagedConnectionFactory.java     |   136 +
 .../ra/spi/JCAManagedConnectionMetaData.java    |    58 +
 gemfire-core/src/jca/ra.xml                     |    37 +
 .../com/gemstone/gemfire/CancelCriterion.java   |   100 +
 .../com/gemstone/gemfire/CancelException.java   |    55 +
 .../gemstone/gemfire/CanonicalInstantiator.java |    77 +
 .../com/gemstone/gemfire/CopyException.java     |    58 +
 .../java/com/gemstone/gemfire/CopyHelper.java   |   259 +
 .../com/gemstone/gemfire/DataSerializable.java  |   131 +
 .../com/gemstone/gemfire/DataSerializer.java    |  3542 +++++
 .../main/java/com/gemstone/gemfire/Delta.java   |    57 +
 .../gemfire/DeltaSerializationException.java    |    50 +
 .../gemfire/ForcedDisconnectException.java      |    32 +
 .../gemstone/gemfire/GemFireCacheException.java |    41 +
 .../gemfire/GemFireCheckedException.java        |    81 +
 .../gemfire/GemFireConfigException.java         |    33 +
 .../com/gemstone/gemfire/GemFireException.java  |   140 +
 .../gemstone/gemfire/GemFireIOException.java    |    32 +
 .../gemstone/gemfire/GemFireRethrowable.java    |    38 +
 .../gemfire/IncompatibleSystemException.java    |    29 +
 .../java/com/gemstone/gemfire/Instantiator.java |   303 +
 .../gemstone/gemfire/InternalGemFireError.java  |   145 +
 .../gemfire/InternalGemFireException.java       |    47 +
 .../gemstone/gemfire/InvalidDeltaException.java |    54 +
 .../gemstone/gemfire/InvalidValueException.java |    33 +
 .../gemfire/InvalidVersionException.java        |     9 +
 .../com/gemstone/gemfire/LicenseException.java  |    45 +
 .../java/com/gemstone/gemfire/LogWriter.java    |   292 +
 .../com/gemstone/gemfire/NoSystemException.java |    39 +
 .../gemfire/SerializationException.java         |    36 +
 .../gemstone/gemfire/StatisticDescriptor.java   |    73 +
 .../java/com/gemstone/gemfire/Statistics.java   |   437 +
 .../com/gemstone/gemfire/StatisticsFactory.java |   145 +
 .../com/gemstone/gemfire/StatisticsType.java    |    63 +
 .../gemstone/gemfire/StatisticsTypeFactory.java |   188 +
 .../gemfire/SystemConnectException.java         |    33 +
 .../com/gemstone/gemfire/SystemFailure.java     |  1215 ++
 .../gemfire/SystemIsRunningException.java       |    37 +
 .../gemfire/ThreadInterruptedException.java     |    15 +
 .../com/gemstone/gemfire/ToDataException.java   |    33 +
 .../gemfire/UncreatedSystemException.java       |    39 +
 .../gemstone/gemfire/UnmodifiableException.java |    27 +
 .../gemfire/UnstartedSystemException.java       |    40 +
 .../com/gemstone/gemfire/admin/AdminConfig.java |   148 +
 .../gemfire/admin/AdminDistributedSystem.java   |   479 +
 .../admin/AdminDistributedSystemFactory.java    |   154 +
 .../gemstone/gemfire/admin/AdminException.java  |    81 +
 .../gemfire/admin/AdminXmlException.java        |    39 +
 .../java/com/gemstone/gemfire/admin/Alert.java  |    47 +
 .../com/gemstone/gemfire/admin/AlertLevel.java  |   165 +
 .../gemstone/gemfire/admin/AlertListener.java   |    21 +
 .../gemstone/gemfire/admin/BackupStatus.java    |    40 +
 .../admin/CacheDoesNotExistException.java       |    78 +
 .../gemfire/admin/CacheHealthConfig.java        |   148 +
 .../com/gemstone/gemfire/admin/CacheServer.java |    37 +
 .../gemfire/admin/CacheServerConfig.java        |    46 +
 .../com/gemstone/gemfire/admin/CacheVm.java     |    29 +
 .../gemstone/gemfire/admin/CacheVmConfig.java   |    45 +
 .../gemfire/admin/ConfigurationParameter.java   |    65 +
 .../gemfire/admin/DistributedSystemConfig.java  |   673 +
 .../admin/DistributedSystemHealthConfig.java    |    68 +
 .../gemfire/admin/DistributionLocator.java      |    38 +
 .../admin/DistributionLocatorConfig.java        |    81 +
 .../gemstone/gemfire/admin/GemFireHealth.java   |   225 +
 .../gemfire/admin/GemFireHealthConfig.java      |    49 +
 .../gemfire/admin/GemFireMemberStatus.java      |   705 +
 .../gemstone/gemfire/admin/ManagedEntity.java   |   116 +
 .../gemfire/admin/ManagedEntityConfig.java      |    91 +
 .../gemfire/admin/MemberHealthConfig.java       |   133 +
 .../admin/OperationCancelledException.java      |    39 +
 .../gemfire/admin/RegionNotFoundException.java  |    30 +
 .../gemfire/admin/RegionSubRegionSnapshot.java  |   184 +
 .../gemfire/admin/RuntimeAdminException.java    |    41 +
 .../com/gemstone/gemfire/admin/Statistic.java   |    57 +
 .../gemfire/admin/StatisticResource.java        |    77 +
 .../gemstone/gemfire/admin/SystemMember.java    |   139 +
 .../gemfire/admin/SystemMemberBridgeServer.java |   301 +
 .../gemfire/admin/SystemMemberCache.java        |   223 +
 .../gemfire/admin/SystemMemberCacheEvent.java   |    18 +
 .../admin/SystemMemberCacheListener.java        |    64 +
 .../gemfire/admin/SystemMemberCacheServer.java  |   300 +
 .../gemfire/admin/SystemMemberRegion.java       |   313 +
 .../gemfire/admin/SystemMemberRegionEvent.java  |    17 +
 .../gemfire/admin/SystemMemberType.java         |   137 +
 .../gemfire/admin/SystemMembershipEvent.java    |    32 +
 .../gemfire/admin/SystemMembershipListener.java |    53 +
 .../UnmodifiableConfigurationException.java     |    80 +
 .../admin/internal/AbstractHealthEvaluator.java |   176 +
 .../internal/AdminDistributedSystemImpl.java    |  2507 ++++
 .../admin/internal/BackupStatusImpl.java        |    53 +
 .../admin/internal/CacheHealthConfigImpl.java   |    83 +
 .../admin/internal/CacheHealthEvaluator.java    |   315 +
 .../admin/internal/CacheServerConfigImpl.java   |   127 +
 .../gemfire/admin/internal/CacheServerImpl.java |   190 +
 .../internal/ConfigurationParameterImpl.java    |   272 +
 .../ConfigurationParameterListener.java         |    26 +
 .../DisabledManagedEntityController.java        |    83 +
 .../internal/DistributedSystemConfigImpl.java   |  1095 ++
 .../DistributedSystemHealthConfigImpl.java      |    50 +
 .../DistributedSystemHealthEvaluator.java       |   163 +
 .../DistributedSystemHealthMonitor.java         |   428 +
 .../internal/DistributionLocatorConfigImpl.java |   183 +
 .../admin/internal/DistributionLocatorImpl.java |   322 +
 .../EnabledManagedEntityController.java         |   403 +
 .../admin/internal/FinishBackupRequest.java     |   159 +
 .../admin/internal/FinishBackupResponse.java    |    70 +
 .../admin/internal/FlushToDiskRequest.java      |    89 +
 .../admin/internal/FlushToDiskResponse.java     |    37 +
 .../admin/internal/GemFireHealthConfigImpl.java |    75 +
 .../admin/internal/GemFireHealthEvaluator.java  |   179 +
 .../admin/internal/GemFireHealthImpl.java       |   527 +
 .../gemfire/admin/internal/InetAddressUtil.java |   200 +
 .../admin/internal/InternalManagedEntity.java   |    97 +
 .../gemfire/admin/internal/LogCollator.java     |   128 +
 .../admin/internal/ManagedEntityConfigImpl.java |   254 +
 .../admin/internal/ManagedEntityConfigXml.java  |   161 +
 .../ManagedEntityConfigXmlGenerator.java        |   394 +
 .../internal/ManagedEntityConfigXmlParser.java  |   614 +
 .../admin/internal/ManagedEntityController.java |    65 +
 .../ManagedEntityControllerFactory.java         |    52 +
 .../admin/internal/ManagedSystemMemberImpl.java |   262 +
 .../admin/internal/MemberHealthConfigImpl.java  |    87 +
 .../admin/internal/MemberHealthEvaluator.java   |   233 +
 .../admin/internal/PrepareBackupRequest.java    |   124 +
 .../admin/internal/PrepareBackupResponse.java   |    73 +
 .../gemfire/admin/internal/StatisticImpl.java   |    88 +
 .../admin/internal/StatisticResourceImpl.java   |   174 +
 .../internal/SystemMemberBridgeServerImpl.java  |   225 +
 .../internal/SystemMemberCacheEventImpl.java    |    52 +
 .../SystemMemberCacheEventProcessor.java        |   139 +
 .../admin/internal/SystemMemberCacheImpl.java   |   317 +
 .../admin/internal/SystemMemberImpl.java        |   511 +
 .../internal/SystemMemberRegionEventImpl.java   |    54 +
 .../admin/internal/SystemMemberRegionImpl.java  |   372 +
 .../internal/SystemMembershipEventImpl.java     |    62 +
 .../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         |    37 +
 .../com/gemstone/gemfire/admin/jmx/Agent.java   |   156 +
 .../gemstone/gemfire/admin/jmx/AgentConfig.java |   875 ++
 .../gemfire/admin/jmx/AgentFactory.java         |    43 +
 .../internal/AdminDistributedSystemJmxImpl.java |  2332 ++++
 .../admin/jmx/internal/AgentConfigImpl.java     |  1847 +++
 .../gemfire/admin/jmx/internal/AgentImpl.java   |  1615 +++
 .../admin/jmx/internal/AgentLauncher.java       |   880 ++
 .../admin/jmx/internal/CacheServerJmxImpl.java  |   633 +
 .../admin/jmx/internal/ConfigAttributeInfo.java |    69 +
 .../internal/ConfigurationParameterJmxImpl.java |   161 +
 .../DistributedSystemHealthConfigJmxImpl.java   |    99 +
 .../internal/DistributionLocatorJmxImpl.java    |   178 +
 .../admin/jmx/internal/DynamicManagedBean.java  |   134 +
 .../internal/GemFireHealthConfigJmxImpl.java    |   214 +
 .../jmx/internal/GemFireHealthJmxImpl.java      |   170 +
 .../admin/jmx/internal/GenerateMBeanHTML.java   |   505 +
 .../gemfire/admin/jmx/internal/MBeanUtil.java   |   761 +
 .../admin/jmx/internal/MX4JModelMBean.java      |  1246 ++
 .../jmx/internal/MX4JServerSocketFactory.java   |   152 +
 .../gemfire/admin/jmx/internal/MailManager.java |   324 +
 .../admin/jmx/internal/ManagedResource.java     |    69 +
 .../admin/jmx/internal/ManagedResourceType.java |   201 +
 .../jmx/internal/MemberInfoWithStatsMBean.java  |  1379 ++
 .../admin/jmx/internal/RMIRegistryService.java  |   231 +
 .../jmx/internal/RMIRegistryServiceMBean.java   |    77 +
 .../jmx/internal/RefreshNotificationType.java   |   124 +
 .../jmx/internal/StatAlertNotification.java     |   153 +
 .../jmx/internal/StatAlertsAggregator.java      |   116 +
 .../jmx/internal/StatisticAttributeInfo.java    |    71 +
 .../jmx/internal/StatisticResourceJmxImpl.java  |   352 +
 .../SystemMemberBridgeServerJmxImpl.java        |   126 +
 .../jmx/internal/SystemMemberCacheJmxImpl.java  |   479 +
 .../admin/jmx/internal/SystemMemberJmx.java     |   499 +
 .../admin/jmx/internal/SystemMemberJmxImpl.java |   584 +
 .../jmx/internal/SystemMemberRegionJmxImpl.java |   131 +
 .../gemfire/admin/jmx/internal/package.html     |   150 +
 .../com/gemstone/gemfire/admin/jmx/package.html |    12 +
 .../com/gemstone/gemfire/admin/package.html     |    62 +
 .../gemfire/cache/AttributesFactory.java        |  1999 +++
 .../gemfire/cache/AttributesMutator.java        |   194 +
 .../java/com/gemstone/gemfire/cache/Cache.java  |   474 +
 .../gemstone/gemfire/cache/CacheCallback.java   |    38 +
 .../gemfire/cache/CacheClosedException.java     |    68 +
 .../com/gemstone/gemfire/cache/CacheEvent.java  |   101 +
 .../gemstone/gemfire/cache/CacheException.java  |    61 +
 .../gemfire/cache/CacheExistsException.java     |    57 +
 .../gemstone/gemfire/cache/CacheFactory.java    |   397 +
 .../gemstone/gemfire/cache/CacheListener.java   |   165 +
 .../com/gemstone/gemfire/cache/CacheLoader.java |    55 +
 .../gemfire/cache/CacheLoaderException.java     |    57 +
 .../gemfire/cache/CacheRuntimeException.java    |    72 +
 .../gemstone/gemfire/cache/CacheStatistics.java |   121 +
 .../gemfire/cache/CacheTransactionManager.java  |   322 +
 .../com/gemstone/gemfire/cache/CacheWriter.java |   142 +
 .../gemfire/cache/CacheWriterException.java     |    61 +
 .../gemfire/cache/CacheXmlException.java        |    41 +
 .../gemstone/gemfire/cache/ClientSession.java   |   189 +
 .../gemfire/cache/CommitConflictException.java  |    48 +
 .../cache/CommitDistributionException.java      |    72 +
 .../cache/CommitIncompleteException.java        |    15 +
 .../gemstone/gemfire/cache/CustomExpiry.java    |    33 +
 .../com/gemstone/gemfire/cache/DataPolicy.java  |   246 +
 .../com/gemstone/gemfire/cache/Declarable.java  |    68 +
 .../gemfire/cache/DiskAccessException.java      |   132 +
 .../com/gemstone/gemfire/cache/DiskStore.java   |   207 +
 .../gemfire/cache/DiskStoreFactory.java         |   234 +
 .../gemfire/cache/DiskWriteAttributes.java      |    99 +
 .../cache/DiskWriteAttributesFactory.java       |   254 +
 .../DuplicatePrimaryPartitionException.java     |    56 +
 .../gemfire/cache/DynamicRegionFactory.java     |  1118 ++
 .../gemfire/cache/DynamicRegionListener.java    |    61 +
 .../gemfire/cache/EntryDestroyedException.java  |    52 +
 .../com/gemstone/gemfire/cache/EntryEvent.java  |   146 +
 .../gemfire/cache/EntryExistsException.java     |    53 +
 .../gemfire/cache/EntryNotFoundException.java   |    42 +
 .../gemfire/cache/EntryNotFoundInRegion.java    |    41 +
 .../gemstone/gemfire/cache/EntryOperation.java  |    77 +
 .../gemstone/gemfire/cache/EvictionAction.java  |   105 +
 .../gemfire/cache/EvictionAlgorithm.java        |   141 +
 .../gemfire/cache/EvictionAttributes.java       |   486 +
 .../cache/EvictionAttributesMutator.java        |    31 +
 .../gemfire/cache/ExpirationAction.java         |   114 +
 .../gemfire/cache/ExpirationAttributes.java     |   135 +
 .../cache/FailedSynchronizationException.java   |    46 +
 .../gemfire/cache/FixedPartitionAttributes.java |   106 +
 .../gemfire/cache/FixedPartitionResolver.java   |    71 +
 .../cache/GatewayConfigurationException.java    |    36 +
 .../gemfire/cache/GatewayException.java         |    59 +
 .../gemstone/gemfire/cache/GemFireCache.java    |   254 +
 .../cache/IncompatibleVersionException.java     |    39 +
 .../gemstone/gemfire/cache/InterestPolicy.java  |   140 +
 .../cache/InterestRegistrationEvent.java        |    83 +
 .../cache/InterestRegistrationListener.java     |    75 +
 .../gemfire/cache/InterestResultPolicy.java     |   113 +
 .../gemstone/gemfire/cache/LoaderHelper.java    |    72 +
 .../com/gemstone/gemfire/cache/LossAction.java  |   140 +
 .../gemfire/cache/LowMemoryException.java       |    58 +
 .../gemfire/cache/MembershipAttributes.java     |   260 +
 .../com/gemstone/gemfire/cache/MirrorType.java  |   127 +
 .../cache/NoQueueServersAvailableException.java |    55 +
 ...NoSubscriptionServersAvailableException.java |    55 +
 .../com/gemstone/gemfire/cache/Operation.java   |   987 ++
 .../cache/OperationAbortedException.java        |    54 +
 .../gemfire/cache/PartitionAttributes.java      |   162 +
 .../cache/PartitionAttributesFactory.java       |   445 +
 .../gemfire/cache/PartitionResolver.java        |    76 +
 .../PartitionedRegionDistributionException.java |    37 +
 .../PartitionedRegionStorageException.java      |    87 +
 .../java/com/gemstone/gemfire/cache/Region.java |  2385 ++++
 .../gemfire/cache/RegionAccessException.java    |   109 +
 .../gemfire/cache/RegionAttributes.java         |   450 +
 .../gemfire/cache/RegionDestroyedException.java |    43 +
 .../cache/RegionDistributionException.java      |   114 +
 .../com/gemstone/gemfire/cache/RegionEvent.java |    32 +
 .../gemfire/cache/RegionExistsException.java    |    56 +
 .../gemstone/gemfire/cache/RegionFactory.java   |   893 ++
 .../gemfire/cache/RegionMembershipListener.java |    74 +
 .../cache/RegionReinitializedException.java     |    39 +
 .../gemfire/cache/RegionRoleException.java      |    54 +
 .../gemfire/cache/RegionRoleListener.java       |    45 +
 .../gemstone/gemfire/cache/RegionService.java   |   133 +
 .../gemstone/gemfire/cache/RegionShortcut.java  |   229 +
 .../cache/RemoteTransactionException.java       |    33 +
 .../gemstone/gemfire/cache/RequiredRoles.java   |   108 +
 .../gemfire/cache/ResourceException.java        |    52 +
 .../gemfire/cache/ResumptionAction.java         |   105 +
 .../com/gemstone/gemfire/cache/RoleEvent.java   |    30 +
 .../gemstone/gemfire/cache/RoleException.java   |    59 +
 .../java/com/gemstone/gemfire/cache/Scope.java  |   159 +
 .../gemfire/cache/SerializedCacheValue.java     |    40 +
 .../cache/StatisticsDisabledException.java      |    59 +
 .../gemfire/cache/SubscriptionAttributes.java   |   108 +
 .../SynchronizationCommitConflictException.java |    40 +
 .../gemfire/cache/TimeoutException.java         |    64 +
 ...TransactionDataNodeHasDepartedException.java |    33 +
 .../TransactionDataNotColocatedException.java   |    37 +
 .../TransactionDataRebalancedException.java     |    29 +
 .../gemfire/cache/TransactionEvent.java         |   105 +
 .../gemfire/cache/TransactionException.java     |    34 +
 .../gemstone/gemfire/cache/TransactionId.java   |    24 +
 .../cache/TransactionInDoubtException.java      |    33 +
 .../gemfire/cache/TransactionListener.java      |    57 +
 .../gemfire/cache/TransactionWriter.java        |    35 +
 .../cache/TransactionWriterException.java       |    36 +
 ...upportedOperationInTransactionException.java |    28 +
 .../cache/UnsupportedVersionException.java      |    35 +
 .../gemfire/cache/VersionException.java         |    41 +
 .../gemfire/cache/asyncqueue/AsyncEvent.java    |    33 +
 .../cache/asyncqueue/AsyncEventListener.java    |    67 +
 .../cache/asyncqueue/AsyncEventQueue.java       |   142 +
 .../asyncqueue/AsyncEventQueueFactory.java      |   182 +
 .../internal/AsyncEventQueueFactoryImpl.java    |   279 +
 .../internal/AsyncEventQueueImpl.java           |   188 +
 .../internal/AsyncEventQueueStats.java          |   177 +
 .../internal/ParallelAsyncEventQueueImpl.java   |   244 +
 .../internal/SerialAsyncEventQueueImpl.java     |   241 +
 .../client/AllConnectionsInUseException.java    |    52 +
 .../gemfire/cache/client/ClientCache.java       |   159 +
 .../cache/client/ClientCacheFactory.java        |   680 +
 .../cache/client/ClientNotReadyException.java   |    47 +
 .../cache/client/ClientRegionFactory.java       |   337 +
 .../cache/client/ClientRegionShortcut.java      |    99 +
 .../client/NoAvailableLocatorsException.java    |    50 +
 .../client/NoAvailableServersException.java     |    50 +
 .../com/gemstone/gemfire/cache/client/Pool.java |   242 +
 .../gemfire/cache/client/PoolFactory.java       |   462 +
 .../gemfire/cache/client/PoolManager.java       |    89 +
 .../client/ServerConnectivityException.java     |    54 +
 .../cache/client/ServerOperationException.java  |    77 +
 .../ServerRefusedConnectionException.java       |    32 +
 .../client/SubscriptionNotEnabledException.java |    54 +
 .../client/doc-files/example-client-cache.xml   |    30 +
 .../cache/client/internal/AbstractOp.java       |   427 +
 .../cache/client/internal/AddPDXEnumOp.java     |    89 +
 .../cache/client/internal/AddPDXTypeOp.java     |    89 +
 .../client/internal/AuthenticateUserOp.java     |   301 +
 .../internal/AutoConnectionSourceImpl.java      |   378 +
 .../cache/client/internal/BridgePoolImpl.java   |   479 +
 .../internal/BridgeServerLoadMessage.java       |    99 +
 .../gemfire/cache/client/internal/ClearOp.java  |    97 +
 .../client/internal/ClientMetadataService.java  |   835 ++
 .../client/internal/ClientPartitionAdvisor.java |   279 +
 .../internal/ClientRegionFactoryImpl.java       |   262 +
 .../cache/client/internal/ClientUpdater.java    |    27 +
 .../client/internal/CloseConnectionOp.java      |    86 +
 .../gemfire/cache/client/internal/CommitOp.java |   100 +
 .../cache/client/internal/Connection.java       |    75 +
 .../client/internal/ConnectionFactory.java      |    59 +
 .../client/internal/ConnectionFactoryImpl.java  |   305 +
 .../cache/client/internal/ConnectionImpl.java   |   326 +
 .../cache/client/internal/ConnectionSource.java |    68 +
 .../cache/client/internal/ConnectionStats.java  |  3283 +++++
 .../cache/client/internal/ContainsKeyOp.java    |    93 +
 .../DataSerializerRecoveryListener.java         |   144 +
 .../cache/client/internal/DestroyOp.java        |   282 +
 .../cache/client/internal/DestroyRegionOp.java  |    95 +
 .../gemfire/cache/client/internal/Endpoint.java |   102 +
 .../cache/client/internal/EndpointManager.java  |    91 +
 .../client/internal/EndpointManagerImpl.java    |   301 +
 .../cache/client/internal/ExecutablePool.java   |   141 +
 .../client/internal/ExecuteFunctionHelper.java  |    21 +
 .../client/internal/ExecuteFunctionNoAckOp.java |   234 +
 .../client/internal/ExecuteFunctionOp.java      |   644 +
 .../internal/ExecuteRegionFunctionNoAckOp.java  |   218 +
 .../internal/ExecuteRegionFunctionOp.java       |   615 +
 .../ExecuteRegionFunctionSingleHopOp.java       |   491 +
 .../internal/ExplicitConnectionSourceImpl.java  |   341 +
 .../gemfire/cache/client/internal/GetAllOp.java |   233 +
 .../client/internal/GetClientPRMetaDataOp.java  |   162 +
 .../GetClientPartitionAttributesOp.java         |   169 +
 .../cache/client/internal/GetEntryOp.java       |    73 +
 .../cache/client/internal/GetEventValueOp.java  |   113 +
 .../client/internal/GetFunctionAttributeOp.java |    75 +
 .../gemfire/cache/client/internal/GetOp.java    |   241 +
 .../cache/client/internal/GetPDXEnumByIdOp.java |    85 +
 .../cache/client/internal/GetPDXEnumsOp.java    |   103 +
 .../client/internal/GetPDXIdForEnumOp.java      |   106 +
 .../client/internal/GetPDXIdForTypeOp.java      |   106 +
 .../cache/client/internal/GetPDXTypeByIdOp.java |    85 +
 .../cache/client/internal/GetPDXTypesOp.java    |   103 +
 .../internal/InstantiatorRecoveryListener.java  |   150 +
 .../cache/client/internal/InternalPool.java     |    34 +
 .../cache/client/internal/InvalidateOp.java     |   112 +
 .../gemfire/cache/client/internal/KeySetOp.java |   121 +
 .../cache/client/internal/LiveServerPinger.java |   108 +
 .../internal/LocatorDiscoveryCallback.java      |    38 +
 .../LocatorDiscoveryCallbackAdapter.java        |    27 +
 .../cache/client/internal/MakePrimaryOp.java    |    82 +
 .../gemfire/cache/client/internal/Op.java       |    34 +
 .../cache/client/internal/OpExecutorImpl.java   |   964 ++
 .../internal/PdxRegistryRecoveryListener.java   |    81 +
 .../gemfire/cache/client/internal/PingOp.java   |   104 +
 .../gemfire/cache/client/internal/PoolImpl.java |  1513 ++
 .../cache/client/internal/PrimaryAckOp.java     |    92 +
 .../cache/client/internal/ProxyCache.java       |   239 +
 .../client/internal/ProxyCacheCloseOp.java      |   115 +
 .../cache/client/internal/ProxyRegion.java      |   689 +
 .../gemfire/cache/client/internal/PutAllOp.java |   417 +
 .../gemfire/cache/client/internal/PutOp.java    |   540 +
 .../gemfire/cache/client/internal/QueryOp.java  |   194 +
 .../client/internal/QueueConnectionImpl.java    |   216 +
 .../cache/client/internal/QueueManager.java     |    48 +
 .../cache/client/internal/QueueManagerImpl.java |  1478 ++
 .../cache/client/internal/QueueState.java       |    17 +
 .../cache/client/internal/QueueStateImpl.java   |   440 +
 .../cache/client/internal/ReadyForEventsOp.java |    82 +
 .../internal/RegisterDataSerializersOp.java     |   129 +
 .../internal/RegisterInstantiatorsOp.java       |   171 +
 .../client/internal/RegisterInterestListOp.java |   138 +
 .../client/internal/RegisterInterestOp.java     |   287 +
 .../internal/RegisterInterestTracker.java       |   410 +
 .../cache/client/internal/RemoveAllOp.java      |   382 +
 .../cache/client/internal/RollbackOp.java       |    90 +
 .../cache/client/internal/ServerBlackList.java  |   179 +
 .../cache/client/internal/ServerProxy.java      |    60 +
 .../client/internal/ServerRegionDataAccess.java |   134 +
 .../client/internal/ServerRegionProxy.java      |   894 ++
 .../internal/SingleHopClientExecutor.java       |   387 +
 .../internal/SingleHopOperationCallable.java    |    74 +
 .../gemfire/cache/client/internal/SizeOp.java   |    83 +
 .../cache/client/internal/TXFailoverOp.java     |    84 +
 .../client/internal/TXSynchronizationOp.java    |   154 +
 .../internal/UnregisterInterestListOp.java      |    91 +
 .../client/internal/UnregisterInterestOp.java   |    89 +
 .../cache/client/internal/UserAttributes.java   |    50 +
 .../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        |    59 +
 .../locator/ClientConnectionResponse.java       |    76 +
 .../locator/ClientReplacementRequest.java       |    66 +
 .../internal/locator/GetAllServersRequest.java  |    50 +
 .../internal/locator/GetAllServersResponse.java |    72 +
 .../internal/locator/LocatorListRequest.java    |    27 +
 .../internal/locator/LocatorListResponse.java   |    83 +
 .../internal/locator/LocatorStatusRequest.java  |    29 +
 .../internal/locator/LocatorStatusResponse.java |   313 +
 .../locator/QueueConnectionRequest.java         |    90 +
 .../locator/QueueConnectionResponse.java        |    78 +
 .../internal/locator/SerializationHelper.java   |   114 +
 .../internal/locator/ServerLocationRequest.java |    52 +
 .../locator/ServerLocationResponse.java         |    24 +
 .../locator/wan/LocatorJoinMessage.java         |    96 +
 .../locator/wan/LocatorMembershipListener.java  |    48 +
 .../locator/wan/RemoteLocatorJoinRequest.java   |    78 +
 .../locator/wan/RemoteLocatorJoinResponse.java  |    80 +
 .../locator/wan/RemoteLocatorPingRequest.java   |    47 +
 .../locator/wan/RemoteLocatorPingResponse.java  |    46 +
 .../locator/wan/RemoteLocatorRequest.java       |    57 +
 .../locator/wan/RemoteLocatorResponse.java      |    65 +
 .../gemfire/cache/client/internal/package.html  |    47 +
 .../pooling/ConnectionDestroyedException.java   |    39 +
 .../internal/pooling/ConnectionManager.java     |   123 +
 .../internal/pooling/ConnectionManagerImpl.java |  1573 +++
 .../internal/pooling/PooledConnection.java      |   344 +
 .../gemstone/gemfire/cache/client/package.html  |    52 +
 .../gemfire/cache/control/RebalanceFactory.java |    57 +
 .../cache/control/RebalanceOperation.java       |    66 +
 .../gemfire/cache/control/RebalanceResults.java |    97 +
 .../gemfire/cache/control/ResourceManager.java  |   176 +
 .../gemstone/gemfire/cache/control/package.html |     7 +
 .../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   |    82 +
 .../gemfire/cache/doc-files/example2-cache.xml  |    46 +
 .../gemfire/cache/doc-files/example3-cache.xml  |    44 +
 .../cache/doc-files/partitioned-regions.fig     |   267 +
 .../cache/doc-files/partitioned-regions.gif     |   Bin 0 -> 9494 bytes
 .../execute/EmtpyRegionFunctionException.java   |    55 +
 .../gemfire/cache/execute/Execution.java        |   216 +
 .../gemfire/cache/execute/Function.java         |   104 +
 .../gemfire/cache/execute/FunctionAdapter.java  |   116 +
 .../gemfire/cache/execute/FunctionContext.java  |    72 +
 .../cache/execute/FunctionException.java        |   121 +
 .../FunctionInvocationTargetException.java      |    85 +
 .../gemfire/cache/execute/FunctionService.java  |   363 +
 .../cache/execute/RegionFunctionContext.java    |    63 +
 .../gemfire/cache/execute/ResultCollector.java  |   128 +
 .../gemfire/cache/execute/ResultSender.java     |    86 +
 .../internal/FunctionServiceManager.java        |   453 +
 .../gemstone/gemfire/cache/execute/package.html |   147 +
 .../operations/CloseCQOperationContext.java     |    56 +
 .../operations/DestroyOperationContext.java     |    54 +
 .../operations/ExecuteCQOperationContext.java   |    59 +
 .../ExecuteFunctionOperationContext.java        |    88 +
 .../GetDurableCQsOperationContext.java          |    51 +
 .../cache/operations/GetOperationContext.java   |    77 +
 .../operations/InterestOperationContext.java    |    75 +
 .../gemfire/cache/operations/InterestType.java  |   143 +
 .../operations/InvalidateOperationContext.java  |    55 +
 .../cache/operations/KeyOperationContext.java   |   116 +
 .../operations/KeySetOperationContext.java      |    88 +
 .../operations/KeyValueOperationContext.java    |   152 +
 .../cache/operations/OperationContext.java      |   508 +
 .../operations/PutAllOperationContext.java      |   398 +
 .../cache/operations/PutOperationContext.java   |   135 +
 .../cache/operations/QueryOperationContext.java |   163 +
 .../operations/RegionClearOperationContext.java |    42 +
 .../RegionCreateOperationContext.java           |    52 +
 .../RegionDestroyOperationContext.java          |    42 +
 .../operations/RegionOperationContext.java      |    78 +
 .../RegisterInterestOperationContext.java       |    63 +
 .../operations/RemoveAllOperationContext.java   |    92 +
 .../operations/StopCQOperationContext.java      |    57 +
 .../UnregisterInterestOperationContext.java     |    45 +
 .../gemfire/cache/operations/package.html       |    91 +
 .../com/gemstone/gemfire/cache/package.html     |   593 +
 .../cache/partition/PartitionListener.java      |   124 +
 .../partition/PartitionListenerAdapter.java     |    41 +
 .../cache/partition/PartitionManager.java       |   369 +
 .../cache/partition/PartitionMemberInfo.java    |    65 +
 .../PartitionNotAvailableException.java         |    57 +
 .../cache/partition/PartitionRebalanceInfo.java |   141 +
 .../cache/partition/PartitionRegionHelper.java  |   544 +
 .../cache/partition/PartitionRegionInfo.java    |   104 +
 .../gemfire/cache/partition/package.html        |     7 +
 .../ConflictingPersistentDataException.java     |    48 +
 .../persistence/PartitionOfflineException.java  |    68 +
 .../gemfire/cache/persistence/PersistentID.java |    50 +
 .../PersistentReplicatesOfflineException.java   |    35 +
 .../persistence/RevokeFailedException.java      |    42 +
 .../RevokedPersistentDataException.java         |    49 +
 .../cache/query/AmbiguousNameException.java     |    38 +
 .../gemfire/cache/query/CqAttributes.java       |    41 +
 .../cache/query/CqAttributesFactory.java        |   310 +
 .../cache/query/CqAttributesMutator.java        |    48 +
 .../gemfire/cache/query/CqClosedException.java  |    48 +
 .../gemstone/gemfire/cache/query/CqEvent.java   |    84 +
 .../gemfire/cache/query/CqException.java        |    48 +
 .../gemfire/cache/query/CqExistsException.java  |    44 +
 .../gemfire/cache/query/CqListener.java         |    50 +
 .../gemstone/gemfire/cache/query/CqQuery.java   |   146 +
 .../gemstone/gemfire/cache/query/CqResults.java |    42 +
 .../cache/query/CqServiceStatistics.java        |    61 +
 .../gemstone/gemfire/cache/query/CqState.java   |    46 +
 .../gemfire/cache/query/CqStatistics.java       |    44 +
 .../gemfire/cache/query/CqStatusListener.java   |    33 +
 .../cache/query/FunctionDomainException.java    |    27 +
 .../com/gemstone/gemfire/cache/query/Index.java |   103 +
 .../cache/query/IndexCreationException.java     |    37 +
 .../cache/query/IndexExistsException.java       |    43 +
 .../cache/query/IndexInvalidException.java      |    55 +
 .../cache/query/IndexMaintenanceException.java  |    57 +
 .../cache/query/IndexNameConflictException.java |    43 +
 .../gemfire/cache/query/IndexStatistics.java    |    67 +
 .../gemstone/gemfire/cache/query/IndexType.java |    97 +
 .../query/MultiIndexCreationException.java      |    66 +
 .../cache/query/NameNotFoundException.java      |    39 +
 .../cache/query/NameResolutionException.java    |    38 +
 .../query/ParameterCountInvalidException.java   |    29 +
 .../com/gemstone/gemfire/cache/query/Query.java |   319 +
 .../gemfire/cache/query/QueryException.java     |    57 +
 .../query/QueryExecutionLowMemoryException.java |    58 +
 .../query/QueryExecutionTimeoutException.java   |    53 +
 .../cache/query/QueryInvalidException.java      |    39 +
 .../query/QueryInvocationTargetException.java   |    45 +
 .../gemfire/cache/query/QueryService.java       |   847 ++
 .../gemfire/cache/query/QueryStatistics.java    |    29 +
 .../cache/query/RegionNotFoundException.java    |    36 +
 .../gemfire/cache/query/SelectResults.java      |   113 +
 .../gemstone/gemfire/cache/query/Struct.java    |    50 +
 .../cache/query/TypeMismatchException.java      |    36 +
 .../query/internal/AbstractCompiledValue.java   |   314 +
 .../internal/AbstractGroupOrRangeJunction.java  |   589 +
 .../cache/query/internal/AllGroupJunction.java  |   269 +
 .../query/internal/AttributeDescriptor.java     |   412 +
 .../query/internal/CompiledBindArgument.java    |    89 +
 .../query/internal/CompiledComparison.java      |   860 ++
 .../query/internal/CompiledConstruction.java    |    70 +
 .../cache/query/internal/CompiledFunction.java  |   109 +
 .../cache/query/internal/CompiledID.java        |    91 +
 .../cache/query/internal/CompiledIn.java        |  1037 ++
 .../query/internal/CompiledIndexOperation.java  |   175 +
 .../query/internal/CompiledIteratorDef.java     |   370 +
 .../cache/query/internal/CompiledJunction.java  |  1189 ++
 .../cache/query/internal/CompiledLike.java      |   522 +
 .../cache/query/internal/CompiledLiteral.java   |    77 +
 .../cache/query/internal/CompiledNegation.java  |    71 +
 .../cache/query/internal/CompiledOperation.java |   325 +
 .../cache/query/internal/CompiledPath.java      |   169 +
 .../cache/query/internal/CompiledRegion.java    |   103 +
 .../cache/query/internal/CompiledSelect.java    |  1519 ++
 .../query/internal/CompiledSortCriterion.java   |    70 +
 .../query/internal/CompiledUnaryMinus.java      |    93 +
 .../cache/query/internal/CompiledUndefined.java |   313 +
 .../cache/query/internal/CompiledValue.java     |   133 +
 .../query/internal/CompositeGroupJunction.java  |   550 +
 .../gemfire/cache/query/internal/CqEntry.java   |   103 +
 .../cache/query/internal/CqQueryVsdStats.java   |   333 +
 .../cache/query/internal/CqStateImpl.java       |    96 +
 .../cache/query/internal/DefaultQuery.java      |  1094 ++
 .../query/internal/DefaultQueryService.java     |   995 ++
 .../cache/query/internal/ExecutionContext.java  |   714 +
 .../gemfire/cache/query/internal/Filter.java    |   170 +
 .../gemfire/cache/query/internal/Functions.java |   198 +
 .../cache/query/internal/GroupJunction.java     |   181 +
 .../cache/query/internal/HashingStrategy.java   |    46 +
 .../gemfire/cache/query/internal/IndexInfo.java |    71 +
 .../internal/IndexTrackingQueryObserver.java    |   215 +
 .../cache/query/internal/IndexUpdater.java      |   114 +
 .../gemfire/cache/query/internal/Indexable.java |    46 +
 .../cache/query/internal/LinkedResultSet.java   |   126 +
 .../cache/query/internal/LinkedStructSet.java   |   348 +
 .../cache/query/internal/MapIndexable.java      |    10 +
 .../cache/query/internal/MethodDispatch.java    |   224 +
 .../gemfire/cache/query/internal/Negatable.java |    18 +
 .../gemfire/cache/query/internal/NullToken.java |    68 +
 .../cache/query/internal/ObjectIntHashMap.java  |  1132 ++
 .../cache/query/internal/OrganizedOperands.java |    46 +
 .../cache/query/internal/PRQueryTraceInfo.java  |   101 +
 .../gemfire/cache/query/internal/PathUtils.java |   198 +
 .../gemfire/cache/query/internal/PlanInfo.java  |    28 +
 .../cache/query/internal/ProxyQueryService.java |   442 +
 .../gemfire/cache/query/internal/QCompiler.java |   598 +
 .../gemfire/cache/query/internal/QRegion.java   |   530 +
 .../gemfire/cache/query/internal/QScope.java    |    82 +
 .../QueryExecutionCanceledException.java        |    54 +
 .../query/internal/QueryExecutionContext.java   |   238 +
 .../cache/query/internal/QueryExecutor.java     |    31 +
 .../cache/query/internal/QueryMonitor.java      |   364 +
 .../cache/query/internal/QueryObserver.java     |   323 +
 .../query/internal/QueryObserverAdapter.java    |   328 +
 .../query/internal/QueryObserverHolder.java     |    76 +
 .../cache/query/internal/QueryUtils.java        |  1971 +++
 .../cache/query/internal/RangeJunction.java     |  1236 ++
 .../cache/query/internal/ResultsBag.java        |   718 +
 .../ResultsCollectionCopyOnReadWrapper.java     |   219 +
 ...ResultsCollectionPdxDeserializerWrapper.java |   210 +
 .../internal/ResultsCollectionWrapper.java      |   654 +
 .../cache/query/internal/ResultsSet.java        |   140 +
 .../cache/query/internal/RuntimeIterator.java   |   333 +
 .../query/internal/SelectResultsComparator.java |    52 +
 .../cache/query/internal/SortedResultSet.java   |   120 +
 .../cache/query/internal/SortedStructSet.java   |   337 +
 .../gemfire/cache/query/internal/StructBag.java |   458 +
 .../cache/query/internal/StructImpl.java        |   172 +
 .../gemfire/cache/query/internal/StructSet.java |   435 +
 .../gemfire/cache/query/internal/Support.java   |    87 +
 .../gemfire/cache/query/internal/Undefined.java |    77 +
 .../cache/query/internal/cq/ClientCQ.java       |    26 +
 .../cache/query/internal/cq/CqService.java      |   247 +
 .../query/internal/cq/CqServiceProvider.java    |    56 +
 .../query/internal/cq/InternalCqQuery.java      |    66 +
 .../query/internal/cq/MissingCqService.java     |   201 +
 .../internal/cq/MissingCqServiceStatistics.java |    36 +
 .../cache/query/internal/cq/ServerCQ.java       |    71 +
 .../query/internal/cq/spi/CqServiceFactory.java |    20 +
 .../query/internal/index/AbstractIndex.java     |  2378 ++++
 .../query/internal/index/AbstractMapIndex.java  |   433 +
 .../internal/index/CompactMapRangeIndex.java    |   204 +
 .../query/internal/index/CompactRangeIndex.java |  1775 +++
 .../query/internal/index/DummyQRegion.java      |   215 +
 .../index/FunctionalIndexCreationHelper.java    |   713 +
 .../cache/query/internal/index/HashIndex.java   |  1561 +++
 .../query/internal/index/HashIndexSet.java      |  1220 ++
 .../query/internal/index/HashIndexStrategy.java |    81 +
 .../query/internal/index/IMQException.java      |    50 +
 .../internal/index/IndexConcurrentHashSet.java  |    69 +
 .../query/internal/index/IndexCreationData.java |   157 +
 .../internal/index/IndexCreationHelper.java     |   104 +
 .../cache/query/internal/index/IndexData.java   |    63 +
 .../query/internal/index/IndexElemArray.java    |   324 +
 .../query/internal/index/IndexManager.java      |  1684 +++
 .../query/internal/index/IndexProtocol.java     |   214 +
 .../cache/query/internal/index/IndexStats.java  |   214 +
 .../cache/query/internal/index/IndexStore.java  |   144 +
 .../cache/query/internal/index/IndexUtils.java  |   126 +
 .../index/IndexedExpressionEvaluator.java       |    43 +
 .../query/internal/index/MapIndexStore.java     |   327 +
 .../query/internal/index/MapRangeIndex.java     |   186 +
 .../query/internal/index/MemoryIndexStore.java  |   765 +
 .../query/internal/index/PartitionedIndex.java  |   633 +
 .../query/internal/index/PrimaryKeyIndex.java   |   383 +
 .../index/PrimaryKeyIndexCreationHelper.java    |   115 +
 .../cache/query/internal/index/RangeIndex.java  |  1669 +++
 .../cache/query/internal/index/package.html     |   630 +
 .../gemfire/cache/query/internal/package.html   |    27 +
 .../cache/query/internal/parse/ASTAnd.java      |    30 +
 .../query/internal/parse/ASTCombination.java    |    37 +
 .../query/internal/parse/ASTCompareOp.java      |    29 +
 .../query/internal/parse/ASTConstruction.java   |    36 +
 .../query/internal/parse/ASTConversionExpr.java |    33 +
 .../cache/query/internal/parse/ASTCount.java    |    45 +
 .../cache/query/internal/parse/ASTHint.java     |    43 +
 .../query/internal/parse/ASTHintIdentifier.java |    43 +
 .../query/internal/parse/ASTIdentifier.java     |    33 +
 .../cache/query/internal/parse/ASTImport.java   |    48 +
 .../cache/query/internal/parse/ASTIn.java       |    34 +
 .../query/internal/parse/ASTIteratorDef.java    |    70 +
 .../cache/query/internal/parse/ASTLike.java     |    38 +
 .../cache/query/internal/parse/ASTLimit.java    |    32 +
 .../cache/query/internal/parse/ASTLiteral.java  |   223 +
 .../internal/parse/ASTMethodInvocation.java     |    59 +
 .../cache/query/internal/parse/ASTOr.java       |    29 +
 .../cache/query/internal/parse/ASTOrderBy.java  |    35 +
 .../query/internal/parse/ASTParameter.java      |    31 +
 .../cache/query/internal/parse/ASTPostfix.java  |    61 +
 .../query/internal/parse/ASTProjection.java     |    39 +
 .../query/internal/parse/ASTRegionPath.java     |    32 +
 .../cache/query/internal/parse/ASTSelect.java   |   125 +
 .../query/internal/parse/ASTSortCriterion.java  |    35 +
 .../cache/query/internal/parse/ASTTrace.java    |    32 +
 .../cache/query/internal/parse/ASTType.java     |    58 +
 .../cache/query/internal/parse/ASTTypeCast.java |    35 +
 .../cache/query/internal/parse/ASTUnary.java    |    56 +
 .../query/internal/parse/ASTUndefinedExpr.java  |    33 +
 .../query/internal/parse/ASTUnsupported.java    |    36 +
 .../cache/query/internal/parse/GemFireAST.java  |    52 +
 .../cache/query/internal/parse/OQLLexer.java    |  2265 +++
 .../internal/parse/OQLLexerTokenTypes.java      |   149 +
 .../query/internal/parse/OQLLexerTokenTypes.txt |   141 +
 .../cache/query/internal/parse/OQLParser.java   |  3684 +++++
 .../cache/query/internal/parse/UtilParser.java  |    83 +
 .../cache/query/internal/parse/fixantlr.sh      |    37 +
 .../gemfire/cache/query/internal/parse/oql.g    |  1146 ++
 .../internal/types/CollectionTypeImpl.java      |   105 +
 .../types/ExtendedNumericComparator.java        |    44 +
 .../cache/query/internal/types/MapTypeImpl.java |    91 +
 .../query/internal/types/NumericComparator.java |    88 +
 .../query/internal/types/ObjectTypeImpl.java    |    91 +
 .../query/internal/types/StructTypeImpl.java    |   151 +
 .../internal/types/TemporalComparator.java      |    69 +
 .../cache/query/internal/types/TypeUtils.java   |   444 +
 .../gemstone/gemfire/cache/query/package.html   |   692 +
 .../cache/query/types/CollectionType.java       |    38 +
 .../gemfire/cache/query/types/MapType.java      |    33 +
 .../gemfire/cache/query/types/ObjectType.java   |    51 +
 .../gemfire/cache/query/types/StructType.java   |    43 +
 .../gemfire/cache/server/CacheServer.java       |   503 +
 .../cache/server/ClientSubscriptionConfig.java  |   139 +
 .../gemfire/cache/server/ServerLoad.java        |   178 +
 .../gemfire/cache/server/ServerLoadProbe.java   |    66 +
 .../cache/server/ServerLoadProbeAdapter.java    |    34 +
 .../gemfire/cache/server/ServerMetrics.java     |    44 +
 .../server/internal/ConnectionCountProbe.java   |    85 +
 .../cache/server/internal/LoadMonitor.java      |   233 +
 .../server/internal/ServerMetricsImpl.java      |    70 +
 .../gemstone/gemfire/cache/server/package.html  |    27 +
 .../cache/snapshot/CacheSnapshotService.java    |   140 +
 .../cache/snapshot/RegionSnapshotService.java   |   131 +
 .../gemfire/cache/snapshot/SnapshotFilter.java  |    36 +
 .../cache/snapshot/SnapshotIterator.java        |    53 +
 .../gemfire/cache/snapshot/SnapshotOptions.java |    53 +
 .../gemfire/cache/snapshot/SnapshotReader.java  |    49 +
 .../gemfire/cache/snapshot/package.html         |    39 +
 .../cache/util/BoundedLinkedHashMap.java        |    82 +
 .../gemfire/cache/util/BridgeClient.java        |   156 +
 .../gemfire/cache/util/BridgeLoader.java        |   607 +
 .../gemfire/cache/util/BridgeMembership.java    |    55 +
 .../cache/util/BridgeMembershipEvent.java       |    23 +
 .../cache/util/BridgeMembershipListener.java    |    41 +
 .../util/BridgeMembershipListenerAdapter.java   |    43 +
 .../gemfire/cache/util/BridgeServer.java        |   442 +
 .../gemfire/cache/util/BridgeWriter.java        |   795 ++
 .../cache/util/BridgeWriterException.java       |    48 +
 .../cache/util/CacheListenerAdapter.java        |    58 +
 .../gemfire/cache/util/CacheWriterAdapter.java  |    45 +
 .../gemfire/cache/util/CqListenerAdapter.java   |    57 +
 .../util/EndpointDoesNotExistException.java     |    34 +
 .../gemfire/cache/util/EndpointException.java   |    61 +
 .../cache/util/EndpointExistsException.java     |    28 +
 .../cache/util/EndpointInUseException.java      |    27 +
 .../cache/util/GatewayConflictHelper.java       |    25 +
 .../cache/util/GatewayConflictResolver.java     |    39 +
 .../gemfire/cache/util/GatewayEvent.java        |    82 +
 .../util/IncompatibleVersionException.java      |    47 +
 .../gemfire/cache/util/ObjectSizer.java         |    74 +
 .../gemfire/cache/util/ObjectSizerImpl.java     |    19 +
 .../util/RegionMembershipListenerAdapter.java   |    35 +
 .../cache/util/RegionRoleListenerAdapter.java   |    31 +
 .../util/ServerRefusedConnectionException.java  |    36 +
 .../cache/util/TimestampedEntryEvent.java       |    31 +
 .../cache/util/TransactionListenerAdapter.java  |    34 +
 .../UniversalMembershipListenerAdapter.java     |   352 +
 .../cache/util/UnknownVersionException.java     |    39 +
 .../gemfire/cache/util/VersionException.java    |    45 +
 .../gemstone/gemfire/cache/util/package.html    |    19 +
 .../gemfire/cache/wan/EventSequenceID.java      |    95 +
 .../gemfire/cache/wan/GatewayEventFilter.java   |    56 +
 .../wan/GatewayEventSubstitutionFilter.java     |    31 +
 .../gemfire/cache/wan/GatewayQueueEvent.java    |    65 +
 .../gemfire/cache/wan/GatewayReceiver.java      |   166 +
 .../cache/wan/GatewayReceiverFactory.java       |   114 +
 .../gemfire/cache/wan/GatewaySender.java        |   405 +
 .../gemfire/cache/wan/GatewaySenderFactory.java |   231 +
 .../cache/wan/GatewayTransportFilter.java       |    19 +
 .../compression/CompressionException.java       |    34 +
 .../gemfire/compression/Compressor.java         |    39 +
 .../gemfire/compression/SnappyCompressor.java   |   102 +
 .../gemfire/distributed/AbstractLauncher.java   |   916 ++
 .../distributed/ClientSocketFactory.java        |    38 +
 .../distributed/DistributedLockService.java     |   384 +
 .../gemfire/distributed/DistributedMember.java  |    71 +
 .../gemfire/distributed/DistributedSystem.java  |  2026 +++
 .../DistributedSystemDisconnectedException.java |    38 +
 .../distributed/DurableClientAttributes.java    |   138 +
 .../distributed/FutureCancelledException.java   |    38 +
 .../distributed/GatewayCancelledException.java  |    37 +
 .../distributed/LeaseExpiredException.java      |    29 +
 .../gemstone/gemfire/distributed/Locator.java   |   543 +
 .../gemfire/distributed/LocatorLauncher.java    |  1999 +++
 .../distributed/LockNotHeldException.java       |    42 +
 .../LockServiceDestroyedException.java          |    42 +
 .../distributed/OplogCancelledException.java    |    38 +
 .../distributed/PoolCancelledException.java     |    38 +
 .../com/gemstone/gemfire/distributed/Role.java  |    47 +
 .../gemfire/distributed/ServerLauncher.java     |  2497 ++++
 .../TXManagerCancelledException.java            |    38 +
 .../internal/AbstractDistributionConfig.java    |  3242 +++++
 .../distributed/internal/AdminMessageType.java  |     7 +
 .../internal/AtomicLongWithTerminalState.java   |    58 +
 .../internal/CollectingReplyProcessor.java      |    47 +
 .../distributed/internal/ConflationKey.java     |    69 +
 .../gemfire/distributed/internal/DM.java        |   463 +
 .../gemfire/distributed/internal/DMStats.java   |   634 +
 .../gemfire/distributed/internal/DSClock.java   |   297 +
 .../internal/DirectReplyProcessor.java          |   163 +
 .../distributed/internal/DistributedState.java  |   134 +
 .../internal/DistributionAdvisee.java           |    84 +
 .../internal/DistributionAdvisor.java           |  1669 +++
 .../internal/DistributionChannel.java           |   155 +
 .../internal/DistributionConfig.java            |  3548 +++++
 .../internal/DistributionConfigImpl.java        |  3526 +++++
 .../internal/DistributionConfigSnapshot.java    |    62 +
 .../internal/DistributionException.java         |    28 +
 .../internal/DistributionManager.java           |  5065 +++++++
 .../internal/DistributionManagerConfig.java     |    93 +
 .../internal/DistributionMessage.java           |   674 +
 .../internal/DistributionMessageObserver.java   |    66 +
 .../distributed/internal/DistributionStats.java |  2127 +++
 .../distributed/internal/FlowControlParams.java |   105 +
 .../internal/ForceDisconnectOperation.java      |    33 +
 .../FunctionExecutionPooledExecutor.java        |   303 +
 .../distributed/internal/HealthMonitor.java     |    37 +
 .../distributed/internal/HealthMonitorImpl.java |   139 +
 .../internal/HighPriorityAckedMessage.java      |   222 +
 .../HighPriorityDistributionMessage.java        |    22 +
 .../distributed/internal/IgnoredByManager.java  |    10 +
 .../internal/InternalDistributedSystem.java     |  3020 ++++
 .../distributed/internal/InternalLocator.java   |  1504 ++
 .../internal/LocatorLoadSnapshot.java           |   687 +
 .../distributed/internal/LocatorStats.java      |   236 +
 .../internal/LonerDistributionManager.java      |   862 ++
 .../gemfire/distributed/internal/MQueue.java    |    16 +
 .../internal/MembershipListener.java            |    67 +
 .../distributed/internal/MessageFactory.java    |    47 +
 .../distributed/internal/MessageWithReply.java  |    34 +
 .../internal/OverflowQueueWithDMStats.java      |   165 +
 .../distributed/internal/PoolStatHelper.java    |    29 +
 .../internal/PooledDistributionMessage.java     |    25 +
 .../internal/PooledExecutorWithDMStats.java     |   226 +
 .../distributed/internal/ProcessorKeeper21.java |   120 +
 .../distributed/internal/ProductUseLog.java     |   138 +
 .../distributed/internal/ProfileListener.java   |    46 +
 .../distributed/internal/QueueStatHelper.java   |    33 +
 .../internal/ReliableReplyException.java        |    28 +
 .../internal/ReliableReplyProcessor21.java      |   107 +
 .../distributed/internal/ReplyException.java    |   192 +
 .../distributed/internal/ReplyMessage.java      |   355 +
 .../distributed/internal/ReplyProcessor21.java  |  1289 ++
 .../distributed/internal/ReplySender.java       |    30 +
 .../distributed/internal/ResourceEvent.java     |    44 +
 .../internal/ResourceEventsListener.java        |    30 +
 .../internal/RuntimeDistributionConfigImpl.java |   153 +
 .../internal/SerialAckedMessage.java            |   150 +
 .../internal/SerialDistributionMessage.java     |    25 +
 .../SerialQueuedExecutorWithDMStats.java        |    42 +
 .../distributed/internal/ServerLocation.java    |   169 +
 .../distributed/internal/ServerLocator.java     |   477 +
 .../internal/SharedConfiguration.java           |   945 ++
 .../distributed/internal/ShutdownMessage.java   |   112 +
 .../gemfire/distributed/internal/Sizeable.java  |    12 +
 .../distributed/internal/SizeableRunnable.java  |    30 +
 .../distributed/internal/StartupMessage.java    |   477 +
 .../internal/StartupMessageData.java            |   238 +
 .../internal/StartupMessageReplyProcessor.java  |   109 +
 .../distributed/internal/StartupOperation.java  |   133 +
 .../internal/StartupResponseMessage.java        |   326 +
 .../StartupResponseWithVersionMessage.java      |   122 +
 .../internal/ThrottledMemQueueStatHelper.java   |    40 +
 .../internal/ThrottledQueueStatHelper.java      |    30 +
 .../ThrottlingMemLinkedQueueWithDMStats.java    |   156 +
 .../internal/WaitForViewInstallation.java       |   117 +
 .../internal/WanLocatorDiscoverer.java          |    15 +
 .../deadlock/DLockDependencyMonitor.java        |   138 +
 .../internal/deadlock/DeadlockDetector.java     |   219 +
 .../internal/deadlock/Dependency.java           |    79 +
 .../internal/deadlock/DependencyGraph.java      |   187 +
 .../internal/deadlock/DependencyMonitor.java    |    36 +
 .../deadlock/DependencyMonitorManager.java      |    98 +
 .../deadlock/GemFireDeadlockDetector.java       |   133 +
 .../internal/deadlock/LocalLockInfo.java        |    92 +
 .../internal/deadlock/LocalThread.java          |   111 +
 .../deadlock/MessageDependencyMonitor.java      |   144 +
 .../internal/deadlock/ThreadReference.java      |    19 +
 .../internal/deadlock/UnsafeThreadLocal.java    |    84 +
 .../internal/direct/DirectChannel.java          |   988 ++
 .../internal/direct/MissingStubException.java   |    28 +
 .../internal/distribution-overview.html         |    26 +
 .../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           |   445 +
 .../distributed/internal/locks/DLockBatch.java  |    37 +
 .../internal/locks/DLockBatchId.java            |    22 +
 .../internal/locks/DLockGrantor.java            |  3781 +++++
 .../locks/DLockLessorDepartureHandler.java      |    26 +
 .../internal/locks/DLockQueryProcessor.java     |   510 +
 .../locks/DLockRecoverGrantorProcessor.java     |   451 +
 .../internal/locks/DLockReleaseProcessor.java   |   441 +
 .../internal/locks/DLockRemoteToken.java        |   226 +
 .../internal/locks/DLockRequestProcessor.java   |  1275 ++
 .../internal/locks/DLockService.java            |  3358 +++++
 .../distributed/internal/locks/DLockStats.java  |   878 ++
 .../distributed/internal/locks/DLockToken.java  |   563 +
 .../internal/locks/DeposeGrantorProcessor.java  |   201 +
 .../internal/locks/DistributedLockStats.java    |   192 +
 .../internal/locks/DistributedMemberLock.java   |   288 +
 .../internal/locks/DummyDLockStats.java         |   171 +
 .../internal/locks/ElderInitProcessor.java      |   305 +
 .../distributed/internal/locks/ElderState.java  |   390 +
 .../distributed/internal/locks/GrantorInfo.java |    78 +
 .../internal/locks/GrantorRequestProcessor.java |   742 +
 .../locks/LockGrantorDestroyedException.java    |    42 +
 .../internal/locks/LockGrantorId.java           |   234 +
 .../locks/NonGrantorDestroyedProcessor.java     |   299 +
 .../internal/locks/RemoteThread.java            |    79 +
 .../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     |   297 +
 .../DistributedMembershipListener.java          |    83 +
 .../membership/InternalDistributedMember.java   |  1180 ++
 .../internal/membership/InternalRole.java       |   160 +
 .../internal/membership/MemberAttributes.java   |   246 +
 .../internal/membership/MemberFactory.java      |    91 +
 .../internal/membership/MemberServices.java     |    74 +
 .../internal/membership/MembershipManager.java  |   344 +
 .../internal/membership/MembershipTestHook.java |    31 +
 .../internal/membership/NetMember.java          |    70 +
 .../internal/membership/NetView.java            |    98 +
 .../internal/membership/QuorumChecker.java      |    42 +
 .../membership/jgroup/GFJGBasicAdapter.java     |   546 +
 .../membership/jgroup/GFJGPeerAdapter.java      |   484 +
 .../membership/jgroup/JGroupMember.java         |   251 +
 .../membership/jgroup/JGroupMemberFactory.java  |   119 +
 .../jgroup/JGroupMembershipManager.java         |  4212 ++++++
 .../internal/membership/jgroup/LocatorImpl.java |   474 +
 .../membership/jgroup/QuorumCheckerImpl.java    |   291 +
 .../internal/membership/jgroup/ViewMessage.java |    73 +
 .../internal/membership/jgroup/package.html     |    43 +
 .../gemfire/distributed/internal/package.html   |    39 +
 .../internal/streaming/StreamingOperation.java  |   579 +
 .../internal/tcpserver/InfoRequest.java         |    33 +
 .../internal/tcpserver/InfoResponse.java        |    48 +
 .../internal/tcpserver/ShutdownRequest.java     |    31 +
 .../internal/tcpserver/ShutdownResponse.java    |    32 +
 .../internal/tcpserver/TcpClient.java           |   210 +
 .../internal/tcpserver/TcpHandler.java          |    45 +
 .../internal/tcpserver/TcpServer.java           |   566 +
 .../internal/tcpserver/VersionRequest.java      |    25 +
 .../internal/tcpserver/VersionResponse.java     |    38 +
 .../unsafe/RegisterSignalHandlerSupport.java    |    27 +
 .../gemstone/gemfire/distributed/package.html   |    21 +
 .../doc-files/data-serialization-exceptions.fig |   135 +
 .../doc-files/data-serialization-exceptions.gif |   Bin 0 -> 3666 bytes
 .../gemstone/gemfire/i18n/LogWriterI18n.java    |   413 +
 .../com/gemstone/gemfire/i18n/StringIdImpl.java |   153 +
 .../gemfire/internal/AbstractConfig.java        |   418 +
 .../internal/AbstractStatisticsFactory.java     |   331 +
 .../gemfire/internal/ArchiveSplitter.java       |   513 +
 .../com/gemstone/gemfire/internal/Assert.java   |   168 +
 .../gemfire/internal/AvailablePort.java         |   572 +
 .../com/gemstone/gemfire/internal/Banner.java   |   152 +
 .../gemfire/internal/ByteArrayDataInput.java    |   449 +
 .../internal/ByteBufferOutputStream.java        |    93 +
 .../gemfire/internal/ClassLoadUtil.java         |   115 +
 .../gemfire/internal/ClassPathLoader.java       |   717 +
 .../com/gemstone/gemfire/internal/Config.java   |   101 +
 .../gemstone/gemfire/internal/ConfigSource.java |    95 +
 .../gemfire/internal/CopyOnWriteHashSet.java    |   168 +
 .../com/gemstone/gemfire/internal/DSCODE.java   |   407 +
 .../gemstone/gemfire/internal/DSFIDFactory.java |  1336 ++
 .../internal/DSFIDNotFoundException.java        |    43 +
 .../internal/DataSerializableFixedID.java       |   854 ++
 .../gemfire/internal/DistributionLocator.java   |   181 +
 .../internal/DummyStatisticsFactory.java        |   125 +
 .../gemfire/internal/DummyStatisticsImpl.java   |   190 +
 .../gemfire/internal/ExternalizableDSFID.java   |    34 +
 .../com/gemstone/gemfire/internal/FileUtil.java |   322 +
 .../gemfire/internal/GemFireStatSampler.java    |   498 +
 .../gemfire/internal/GemFireUtilLauncher.java   |   157 +
 .../gemfire/internal/GemFireVersion.java        |   672 +
 .../internal/GfeConsoleReaderFactory.java       |    79 +
 .../gemfire/internal/HeapDataOutputStream.java  |  1134 ++
 .../gemfire/internal/HistogramStats.java        |    73 +
 .../gemfire/internal/HostStatHelper.java        |   280 +
 .../gemfire/internal/HostStatSampler.java       |   535 +
 .../InsufficientDiskSpaceException.java         |    45 +
 .../internal/InternalDataSerializer.java        |  4113 ++++++
 .../gemfire/internal/InternalEntity.java        |    14 +
 .../gemfire/internal/InternalInstantiator.java  |  1052 ++
 .../InternalStatisticsDisabledException.java    |    61 +
 .../gemfire/internal/JarClassLoader.java        |   693 +
 .../gemstone/gemfire/internal/JarDeployer.java  |   631 +
 .../gemfire/internal/LinuxProcFsStatistics.java |   746 +
 .../gemfire/internal/LinuxProcessStats.java     |    70 +
 .../gemfire/internal/LinuxSystemStats.java      |   302 +
 .../gemfire/internal/LocalStatListener.java     |    32 +
 .../internal/LocalStatisticsFactory.java        |    90 +
 .../gemfire/internal/LocalStatisticsImpl.java   |   260 +
 .../gemstone/gemfire/internal/ManagerInfo.java  |   378 +
 .../gemfire/internal/MigrationClient.java       |   251 +
 .../gemfire/internal/MigrationServer.java       |   557 +
 .../gemstone/gemfire/internal/NanoTimer.java    |   148 +
 .../gemfire/internal/NullDataOutputStream.java  |   370 +
 .../gemstone/gemfire/internal/OSProcess.java    |   743 +
 .../gemfire/internal/OSXProcessStats.java       |    74 +
 .../gemfire/internal/OSXSystemStats.java        |   219 +
 .../gemfire/internal/ObjIdConcurrentMap.java    |  1357 ++
 .../com/gemstone/gemfire/internal/ObjIdMap.java |   328 +
 .../internal/ObjToByteArraySerializer.java      |    26 +
 .../gemfire/internal/OneTaskOnlyExecutor.java   |   166 +
 .../gemfire/internal/OsStatisticsFactory.java   |    33 +
 .../gemfire/internal/PdxSerializerObject.java   |    24 +
 .../gemfire/internal/ProcessOutputReader.java   |   126 +
 .../gemstone/gemfire/internal/ProcessStats.java |    52 +
 .../gemstone/gemfire/internal/PureJavaMode.java |    71 +
 ...cheduledThreadPoolExecutorWithKeepAlive.java |   304 +
 .../gemfire/internal/SerializationVersions.java |    33 +
 .../com/gemstone/gemfire/internal/SetUtils.java |    60 +
 .../gemfire/internal/SharedLibrary.java         |   201 +
 .../gemfire/internal/SimpleStatSampler.java     |   105 +
 .../com/gemstone/gemfire/internal/SmHelper.java |   174 +
 .../gemfire/internal/SocketCreator.java         |  1484 ++
 .../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   |   208 +
 .../gemfire/internal/SolarisSystemStats.java    |   419 +
 .../gemfire/internal/StatArchiveFormat.java     |   188 +
 .../gemfire/internal/StatArchiveReader.java     |  3329 +++++
 .../gemfire/internal/StatArchiveWriter.java     |   741 +
 .../gemfire/internal/StatSamplerStats.java      |   114 +
 .../internal/StatisticDescriptorImpl.java       |   376 +
 .../gemfire/internal/StatisticsImpl.java        |   445 +
 .../gemfire/internal/StatisticsManager.java     |    70 +
 .../internal/StatisticsTypeFactoryImpl.java     |   132 +
 .../gemfire/internal/StatisticsTypeImpl.java    |   251 +
 .../gemfire/internal/StatisticsTypeXml.java     |   271 +
 .../gemstone/gemfire/internal/SystemAdmin.java  |  2289 +++
 .../gemfire/internal/SystemFailureTestHook.java |    39 +
 .../gemstone/gemfire/internal/SystemTimer.java  |   458 +
 .../gemfire/internal/UniqueIdGenerator.java     |   248 +
 .../com/gemstone/gemfire/internal/VMStats.java  |    78 +
 .../gemfire/internal/VMStatsContract.java       |    27 +
 .../internal/VMStatsContractFactory.java        |    51 +
 .../com/gemstone/gemfire/internal/Version.java  |   609 +
 .../internal/VersionedDataInputStream.java      |    58 +
 .../internal/VersionedDataOutputStream.java     |    48 +
 .../internal/VersionedDataSerializable.java     |    18 +
 .../gemfire/internal/VersionedDataStream.java   |    44 +
 .../gemfire/internal/VersionedObjectInput.java  |   236 +
 .../gemfire/internal/VersionedObjectOutput.java |   190 +
 .../gemfire/internal/WindowsProcessStats.java   |   151 +
 .../gemfire/internal/WindowsSystemStats.java    |   258 +
 .../internal/admin/AdminBridgeServer.java       |    17 +
 .../gemstone/gemfire/internal/admin/Alert.java  |    60 +
 .../gemfire/internal/admin/AlertListener.java   |    20 +
 .../gemfire/internal/admin/ApplicationVM.java   |    27 +
 .../gemfire/internal/admin/CacheCollector.java  |   268 +
 .../gemfire/internal/admin/CacheInfo.java       |    93 +
 .../gemfire/internal/admin/CacheSnapshot.java   |    25 +
 .../admin/ClientHealthMonitoringRegion.java     |   108 +
 .../internal/admin/ClientMembershipMessage.java |   178 +
 .../internal/admin/ClientStatsManager.java      |   257 +
 .../internal/admin/CompoundEntrySnapshot.java   |   192 +
 .../internal/admin/CompoundRegionSnapshot.java  |   378 +
 .../gemfire/internal/admin/DLockInfo.java       |    26 +
 .../gemfire/internal/admin/EntrySnapshot.java   |    20 +
 .../gemfire/internal/admin/EntryValueNode.java  |    44 +
 .../gemfire/internal/admin/GemFireVM.java       |   387 +
 .../gemfire/internal/admin/GfManagerAgent.java  |   103 +
 .../internal/admin/GfManagerAgentConfig.java    |    78 +
 .../internal/admin/GfManagerAgentFactory.java   |    33 +
 .../gemfire/internal/admin/GfObject.java        |    19 +
 .../gemfire/internal/admin/HealthListener.java  |    35 +
 .../internal/admin/JoinLeaveListener.java       |    18 +
 .../gemfire/internal/admin/ListenerIdMap.java   |   309 +
 .../gemfire/internal/admin/RegionSnapshot.java  |    22 +
 .../gemfire/internal/admin/SSLConfig.java       |   122 +
 .../gemfire/internal/admin/SnapshotClient.java  |    29 +
 .../gemstone/gemfire/internal/admin/Stat.java   |    35 +
 .../gemfire/internal/admin/StatAlert.java       |   131 +
 .../internal/admin/StatAlertDefinition.java     |    94 +
 .../internal/admin/StatAlertsManager.java       |   399 +
 .../gemfire/internal/admin/StatListener.java    |    34 +
 .../gemfire/internal/admin/StatResource.java    |    33 +
 .../gemfire/internal/admin/TransportConfig.java |    18 +
 .../admin/doc-files/class-hierarchy.fig         |   224 +
 .../admin/doc-files/class-hierarchy.gif         |   Bin 0 -> 11971 bytes
 .../gemfire/internal/admin/package.html         |    13 +
 .../admin/remote/AddHealthListenerRequest.java  |    80 +
 .../admin/remote/AddHealthListenerResponse.java |    67 +
 .../admin/remote/AddStatListenerRequest.java    |    76 +
 .../admin/remote/AddStatListenerResponse.java   |    70 +
 .../remote/AdminConsoleDisconnectMessage.java   |   116 +
 .../admin/remote/AdminConsoleMessage.java       |    74 +
 .../admin/remote/AdminFailureResponse.java      |    64 +
 .../remote/AdminMultipleReplyProcessor.java     |    82 +
 .../internal/admin/remote/AdminRegion.java      |   572 +
 .../admin/remote/AdminReplyProcessor.java       |   139 +
 .../internal/admin/remote/AdminRequest.java     |   184 +
 .../internal/admin/remote/AdminResponse.java    |    81 +
 .../internal/admin/remote/AdminWaiters.java     |   175 +
 .../admin/remote/AlertLevelChangeMessage.java   |    88 +
 .../admin/remote/AlertListenerMessage.java      |   138 +
 .../admin/remote/AlertsNotificationMessage.java |   101 +
 .../admin/remote/AppCacheSnapshotMessage.java   |   154 +
 .../admin/remote/BridgeServerRequest.java       |   193 +
 .../admin/remote/BridgeServerResponse.java      |   172 +
 .../admin/remote/CacheConfigRequest.java        |    79 +
 .../admin/remote/CacheConfigResponse.java       |   110 +
 .../internal/admin/remote/CacheDisplay.java     |    77 +
 .../internal/admin/remote/CacheInfoRequest.java |    64 +
 .../admin/remote/CacheInfoResponse.java         |    74 +
 .../admin/remote/CancelStatListenerRequest.java |    70 +
 .../remote/CancelStatListenerResponse.java      |    65 +
 .../internal/admin/remote/Cancellable.java      |    18 +
 .../admin/remote/CancellationMessage.java       |    61 +
 .../admin/remote/CancellationRegistry.java      |    86 +
 .../remote/ChangeRefreshIntervalMessage.java    |    89 +
 .../internal/admin/remote/CliLegacyMessage.java |    42 +
 .../admin/remote/ClientHealthStats.java         |   299 +
 .../internal/admin/remote/CompactRequest.java   |   136 +
 .../internal/admin/remote/CompactResponse.java  |    57 +
 .../admin/remote/DestroyEntryMessage.java       |    91 +
 .../admin/remote/DestroyRegionMessage.java      |    87 +
 .../admin/remote/DistributionLocatorId.java     |   386 +
 .../internal/admin/remote/DummyEntry.java       |    68 +
 .../admin/remote/DurableClientInfoRequest.java  |   101 +
 .../admin/remote/DurableClientInfoResponse.java |   100 +
 .../admin/remote/EntryValueNodeImpl.java        |   384 +
 .../admin/remote/FetchDistLockInfoRequest.java  |    59 +
 .../admin/remote/FetchDistLockInfoResponse.java |    84 +
 .../remote/FetchHealthDiagnosisRequest.java     |    82 +
 .../remote/FetchHealthDiagnosisResponse.java    |    83 +
 .../internal/admin/remote/FetchHostRequest.java |    61 +
 .../admin/remote/FetchHostResponse.java         |   164 +
 .../remote/FetchResourceAttributesRequest.java  |    61 +
 .../remote/FetchResourceAttributesResponse.java |    72 +
 .../admin/remote/FetchStatsRequest.java         |    63 +
 .../admin/remote/FetchStatsResponse.java        |   137 +
 .../admin/remote/FetchSysCfgRequest.java        |    67 +
 .../admin/remote/FetchSysCfgResponse.java       |    68 +
 .../remote/FlushAppCacheSnapshotMessage.java    |    60 +
 .../admin/remote/HealthListenerMessage.java     |    80 +
 .../remote/InspectionClasspathManager.java      |    81 +
 .../admin/remote/LicenseInfoRequest.java        |    63 +
 .../admin/remote/LicenseInfoResponse.java       |    70 +
 .../remote/MissingPersistentIDsRequest.java     |   132 +
 .../remote/MissingPersistentIDsResponse.java    |   106 +
 .../admin/remote/ObjectDetailsRequest.java      |    94 +
 .../admin/remote/ObjectDetailsResponse.java     |   146 +
 .../admin/remote/ObjectNamesRequest.java        |    80 +
 .../admin/remote/ObjectNamesResponse.java       |    89 +
 .../PrepareRevokePersistentIDRequest.java       |   118 +
 .../remote/RefreshMemberSnapshotRequest.java    |    65 +
 .../remote/RefreshMemberSnapshotResponse.java   |    86 +
 .../admin/remote/RegionAdminMessage.java        |    57 +
 .../admin/remote/RegionAdminRequest.java        |    65 +
 .../admin/remote/RegionAttributesRequest.java   |    65 +
 .../admin/remote/RegionAttributesResponse.java  |    66 +
 .../internal/admin/remote/RegionRequest.java    |   166 +
 .../internal/admin/remote/RegionResponse.java   |   140 +
 .../admin/remote/RegionSizeRequest.java         |    81 +
 .../admin/remote/RegionSizeResponse.java        |    87 +
 .../admin/remote/RegionStatisticsRequest.java   |    65 +
 .../admin/remote/RegionStatisticsResponse.java  |    66 +
 .../remote/RegionSubRegionSizeRequest.java      |    86 +
 .../remote/RegionSubRegionsSizeResponse.java    |   154 +
 .../internal/admin/remote/RemoteAlert.java      |   196 +
 .../admin/remote/RemoteApplicationVM.java       |    52 +
 .../admin/remote/RemoteBridgeServer.java        |   295 +
 .../internal/admin/remote/RemoteCacheInfo.java  |   183 +
 .../admin/remote/RemoteCacheStatistics.java     |    78 +
 .../internal/admin/remote/RemoteDLockInfo.java  |   106 +
 .../admin/remote/RemoteEntrySnapshot.java       |   122 +
 .../internal/admin/remote/RemoteGemFireVM.java  |   989 ++
 .../admin/remote/RemoteGfManagerAgent.java      |  1485 ++
 .../internal/admin/remote/RemoteObjectName.java |    86 +
 .../admin/remote/RemoteRegionAttributes.java    |   768 +
 .../admin/remote/RemoteRegionSnapshot.java      |   149 +
 .../internal/admin/remote/RemoteStat.java       |   109 +
 .../admin/remote/RemoteStatResource.java        |   145 +
 .../admin/remote/RemoteTransportConfig.java     |   406 +
 .../remote/RemoveHealthListenerRequest.java     |    71 +
 .../remote/RemoveHealthListenerResponse.java    |    58 +
 .../admin/remote/ResetHealthStatusRequest.java  |    71 +
 .../admin/remote/ResetHealthStatusResponse.java |    63 +
 .../admin/remote/RevokePersistentIDRequest.java |    94 +
 .../remote/RevokePersistentIDResponse.java      |    27 +
 .../admin/remote/RootRegionRequest.java         |    67 +
 .../admin/remote/RootRegionResponse.java        |   106 +
 .../admin/remote/ShutdownAllRequest.java        |   288 +
 .../admin/remote/ShutdownAllResponse.java       |    71 +
 .../admin/remote/SnapshotResultMessage.java     |    76 +
 .../remote/StatAlertsManagerAssignMessage.java  |   143 +
 .../admin/remote/StatListenerMessage.java       |   109 +
 .../admin/remote/StoreSysCfgRequest.java        |    72 +
 .../admin/remote/StoreSysCfgResponse.java       |    68 +
 .../internal/admin/remote/SubRegionRequest.java |    65 +
 .../admin/remote/SubRegionResponse.java         |    91 +
 .../internal/admin/remote/TailLogRequest.java   |    53 +
 .../internal/admin/remote/TailLogResponse.java  |   160 +
 .../remote/UpdateAlertDefinitionMessage.java    |   153 +
 .../admin/remote/VersionInfoRequest.java        |    64 +
 .../admin/remote/VersionInfoResponse.java       |    65 +
 .../admin/remote/VersionMismatchAlert.java      |    57 +
 .../gemfire/internal/admin/remote/package.html  |    25 +
 .../admin/statalerts/BaseDecoratorImpl.java     |   215 +
 .../statalerts/DummyStatisticInfoImpl.java      |   137 +
 .../admin/statalerts/FunctionDecoratorImpl.java |   124 +
 .../admin/statalerts/FunctionHelper.java        |   249 +
 .../statalerts/GaugeThresholdDecoratorImpl.java |   147 +
 .../statalerts/MultiAttrDefinitionImpl.java     |   198 +
 .../NumberThresholdDecoratorImpl.java           |   144 +
 .../statalerts/SingleAttrDefinitionImpl.java    |   204 +
 .../admin/statalerts/StatisticInfo.java         |    76 +
 .../admin/statalerts/StatisticInfoImpl.java     |   148 +
 .../internal/cache/AbstractBridgeServer.java    |   425 +
 .../cache/AbstractBucketRegionQueue.java        |   539 +
 .../cache/AbstractDiskLRURegionEntry.java       |    33 +
 .../internal/cache/AbstractDiskRegion.java      |   952 ++
 .../internal/cache/AbstractDiskRegionEntry.java |    46 +
 .../internal/cache/AbstractLRURegionEntry.java  |    37 +
 .../internal/cache/AbstractLRURegionMap.java    |   830 ++
 .../cache/AbstractOplogDiskRegionEntry.java     |   156 +
 .../gemfire/internal/cache/AbstractRegion.java  |  1996 +++
 .../internal/cache/AbstractRegionEntry.java     |  1791 +++
 .../internal/cache/AbstractRegionMap.java       |  3989 ++++++
 .../internal/cache/AbstractUpdateOperation.java |   326 +
 .../gemfire/internal/cache/AcceptHelper.java    |    92 +
 .../cache/AddCacheServerProfileMessage.java     |   152 +
 .../gemfire/internal/cache/BackupLock.java      |    82 +
 .../internal/cache/BridgeEventConflator.java    |   158 +
 .../gemfire/internal/cache/BridgeObserver.java  |    89 +
 .../internal/cache/BridgeObserverAdapter.java   |   107 +
 .../internal/cache/BridgeObserverHolder.java    |    53 +
 .../internal/cache/BridgeRegionEventImpl.java   |   108 +
 .../internal/cache/BridgeServerAdvisor.java     |   165 +
 .../internal/cache/BridgeServerImpl.java        |   816 ++
 .../gemfire/internal/cache/BucketAdvisor.java   |  2939 ++++
 .../gemfire/internal/cache/BucketDump.java      |   135 +
 .../internal/cache/BucketNotFoundException.java |    29 +
 .../cache/BucketPersistenceAdvisor.java         |   454 +
 .../gemfire/internal/cache/BucketRegion.java    |  2319 ++++
 .../internal/cache/BucketRegionEvictior.java    |    54 +
 .../internal/cache/BucketRegionQueue.java       |   492 +
 .../internal/cache/BucketServerLocation.java    |    80 +
 .../internal/cache/BucketServerLocation66.java  |   105 +
 .../cache/BytesAndBitsForCompactor.java         |    68 +
 .../internal/cache/CacheClientStatus.java       |    92 +
 .../gemfire/internal/cache/CacheConfig.java     |   203 +
 .../cache/CacheDistributionAdvisee.java         |    49 +
 .../cache/CacheDistributionAdvisor.java         |  1229 ++
 .../internal/cache/CacheLifecycleListener.java  |    28 +
 .../gemfire/internal/cache/CacheObserver.java   |   177 +
 .../internal/cache/CacheObserverAdapter.java    |   141 +
 .../internal/cache/CacheObserverHolder.java     |    69 +
 .../gemfire/internal/cache/CachePerfStats.java  |  1325 ++
 .../internal/cache/CacheServerLauncher.java     |  1236 ++
 .../internal/cache/CacheStatisticsImpl.java     |   102 +
 .../internal/cache/CachedDeserializable.java    |   105 +
 .../cache/CachedDeserializableFactory.java      |   259 +
 .../cache/ClientSubscriptionConfigImpl.java     |   169 +
 .../internal/cache/CloseCacheMessage.java       |   107 +
 .../cache/ClusterConfigurationLoader.java       |   229 +
 .../internal/cache/ColocationHelper.java        |   489 +
 .../internal/cache/CommitReplyException.java    |    64 +
 .../internal/cache/CompactableOplog.java        |    28 +
 .../gemfire/internal/cache/Conflatable.java     |    67 +
 .../internal/cache/ControllerAdvisor.java       |   162 +
 .../internal/cache/CountingDataInputStream.java |   116 +
 .../internal/cache/CreateRegionProcessor.java   |   893 ++
 .../internal/cache/CustomEntryExpiryTask.java   |    33 +
 .../internal/cache/DataLocationException.java   |    34 +
 .../internal/cache/DestroyOperation.java        |   282 +
 .../cache/DestroyPartitionedRegionMessage.java  |   243 +
 .../internal/cache/DestroyRegionOperation.java  |   538 +
 .../gemfire/internal/cache/DestroyedEntry.java  |    76 +
 .../internal/cache/DirectReplyMessage.java      |    49 +
 .../gemfire/internal/cache/DirectoryHolder.java |   114 +
 .../internal/cache/DiskDirectoryStats.java      |   108 +
 .../gemfire/internal/cache/DiskEntry.java       |  1532 ++
 .../gemstone/gemfire/internal/cache/DiskId.java |   721 +
 .../gemfire/internal/cache/DiskInitFile.java    |  2818 ++++
 .../gemfire/internal/cache/DiskRegion.java      |   855 ++
 .../gemfire/internal/cache/DiskRegionStats.java |   295 +
 .../internal/cache/DiskStoreAttributes.java     |   187 +
 .../gemfire/internal/cache/DiskStoreBackup.java |    89 +
 .../internal/cache/DiskStoreFactoryImpl.java    |   282 +
 .../gemfire/internal/cache/DiskStoreImpl.java   |  4857 +++++++
 .../internal/cache/DiskStoreMonitor.java        |   404 +
 .../internal/cache/DiskStoreObserver.java       |    54 +
 .../gemfire/internal/cache/DiskStoreStats.java  |   519 +
 .../gemfire/internal/cache/DiskStoreTask.java   |    18 +
 .../internal/cache/DiskWriteAttributesImpl.java |   555 +
 .../cache/DistributedCacheOperation.java        |  1504 ++
 .../cache/DistributedClearOperation.java        |   351 +
 .../cache/DistributedPutAllOperation.java       |  1301 ++
 .../internal/cache/DistributedRegion.java       |  4254 ++++++
 ...stributedRegionFunctionStreamingMessage.java |   446 +
 .../cache/DistributedRemoveAllOperation.java    |  1043 ++
 .../cache/DistributedTombstoneOperation.java    |   227 +
 .../internal/cache/DummyCachePerfStats.java     |   476 +
 .../internal/cache/DynamicRegionAttributes.java |    43 +
 .../cache/DynamicRegionFactoryImpl.java         |    35 +
 .../gemfire/internal/cache/EntriesMap.java      |   146 +
 .../gemfire/internal/cache/EntriesSet.java      |   285 +
 .../gemfire/internal/cache/EntryBits.java       |   119 +
 .../gemfire/internal/cache/EntryEventImpl.java  |  2285 +++
 .../gemfire/internal/cache/EntryExpiryTask.java |   330 +
 .../internal/cache/EntryOperationImpl.java      |   110 +
 .../gemfire/internal/cache/EntrySnapshot.java   |   276 +
 .../internal/cache/EnumListenerEvent.java       |   467 +
 .../gemfire/internal/cache/EventID.java         |   795 ++
 .../internal/cache/EventStateHelper.java        |   187 +
 .../gemfire/internal/cache/EventTracker.java    |   772 ++
 .../internal/cache/EvictionAttributesImpl.java  |   234 +
 .../internal/cache/ExpirationScheduler.java     |   123 +
 .../gemfire/internal/cache/ExpiryTask.java      |   505 +
 .../internal/cache/ExportDiskRegion.java        |    68 +
 .../gemfire/internal/cache/FilterProfile.java   |  2521 ++++
 .../internal/cache/FilterRoutingInfo.java       |   510 +
 .../cache/FindDurableQueueProcessor.java        |   247 +
 .../internal/cache/FindRemoteTXMessage.java     |   272 +
 .../internal/cache/FindVersionTagOperation.java |   245 +
 .../cache/FixedPartitionAttributesImpl.java     |   147 +
 .../internal/cache/ForceReattemptException.java |   112 +
 .../cache/ForceableLinkedBlockingQueue.java     |   855 ++
 .../FunctionStreamingOrderedReplyMessage.java   |    55 +
 .../cache/FunctionStreamingReplyMessage.java    |   136 +
 .../internal/cache/GatewayEventFilter.java      |    11 +
 .../internal/cache/GemFireCacheImpl.java        |  5006 +++++++
 .../internal/cache/GemfireCacheHelper.java      |    29 +
 .../gemfire/internal/cache/GridAdvisor.java     |   433 +
 .../gemfire/internal/cache/HARegion.java        |   601 +
 .../internal/cache/HasCachePerfStats.java       |     6 +
 .../internal/cache/IdentityArrayList.java       |   473 +
 .../gemfire/internal/cache/ImageState.java      |    80 +
 .../cache/InMemoryPersistentMemberView.java     |   127 +
 .../internal/cache/IncomingGatewayStatus.java   |    74 +
 .../internal/cache/InitialImageFlowControl.java |   244 +
 .../internal/cache/InitialImageOperation.java   |  4317 ++++++
 .../gemfire/internal/cache/InlineKeyHelper.java |    62 +
 .../gemfire/internal/cache/InterestEvent.java   |    59 +
 .../gemfire/internal/cache/InterestFilter.java  |    25 +
 .../cache/InterestRegistrationEventImpl.java    |   143 +
 .../gemfire/internal/cache/InternalCache.java   |    36 +
 .../internal/cache/InternalCacheEvent.java      |    78 +
 .../internal/cache/InternalDataView.java        |   242 +
 .../internal/cache/InternalRegionArguments.java |   312 +
 .../internal/cache/InvalidateOperation.java     |   227 +
 .../InvalidatePartitionedRegionMessage.java     |    93 +
 .../cache/InvalidateRegionOperation.java        |    99 +
 .../cache/JtaAfterCompletionMessage.java        |   119 +
 .../cache/JtaBeforeCompletionMessage.java       |    73 +
 .../gemfire/internal/cache/KeyInfo.java         |    86 +
 .../internal/cache/KeyWithRegionContext.java    |    62 +
 .../gemfire/internal/cache/ListOfDeltas.java    |    92 +
 .../internal/cache/LoaderHelperFactory.java     |    31 +
 .../internal/cache/LoaderHelperImpl.java        |   160 +
 .../gemfire/internal/cache/LocalDataSet.java    |   741 +
 .../gemfire/internal/cache/LocalRegion.java     | 12333 +++++++++++++++++
 .../internal/cache/LocalRegionDataView.java     |   264 +
 .../cache/MemberFunctionStreamingMessage.java   |   401 +
 .../cache/MinimumSystemRequirements.java        |    83 +
 .../cache/NetSearchExpirationCalculator.java    |    40 +
 .../gemstone/gemfire/internal/cache/Node.java   |   179 +
 .../internal/cache/NonLocalRegionEntry.java     |   534 +
 .../cache/NonLocalRegionEntryWithStats.java     |    77 +
 .../cache/OfflineCompactionDiskRegion.java      |   115 +
 .../gemstone/gemfire/internal/cache/OpType.java |    50 +
 .../gemstone/gemfire/internal/cache/Oplog.java  |  7890 +++++++++++
 .../gemfire/internal/cache/OplogSet.java        |    18 +
 .../internal/cache/OrderedTombstoneMap.java     |   114 +
 .../gemfire/internal/cache/OverflowOplog.java   |  1607 +++
 .../internal/cache/OverflowOplogSet.java        |   318 +
 .../internal/cache/PRContainsValueFunction.java |    51 +
 .../internal/cache/PRHARedundancyProvider.java  |  2376 ++++
 .../internal/cache/PRQueryProcessor.java        |   591 +
 .../internal/cache/PRSystemPropertyGetter.java  |    61 +
 .../internal/cache/PartitionAttributesImpl.java |   689 +
 .../internal/cache/PartitionRegionConfig.java   |   468 +
 .../cache/PartitionRegionConfigValidator.java   |   502 +
 .../internal/cache/PartitionedRegion.java       | 10824 +++++++++++++++
 .../PartitionedRegionBucketMgmtHelper.java      |    46 +
 .../cache/PartitionedRegionDataStore.java       |  3207 +++++
 .../cache/PartitionedRegionDataView.java        |   133 +
 .../cache/PartitionedRegionException.java       |    39 +
 .../internal/cache/PartitionedRegionHelper.java |  1124 ++
 .../cache/PartitionedRegionQueryEvaluator.java  |  1755 +++
 .../internal/cache/PartitionedRegionStats.java  |  1248 ++
 .../internal/cache/PartitionedRegionStatus.java |    77 +
 .../gemfire/internal/cache/PeerTXStateStub.java |   252 +
 .../internal/cache/PersistentOplogSet.java      |  1174 ++
 .../internal/cache/PlaceHolderDiskRegion.java   |   190 +
 .../gemfire/internal/cache/PoolFactoryImpl.java |   680 +
 .../gemfire/internal/cache/PoolManagerImpl.java |   340 +
 .../gemfire/internal/cache/PoolStats.java       |   310 +
 .../cache/PreferBytesCachedDeserializable.java  |   148 +
 .../internal/cache/PrimaryBucketException.java  |    40 +
 .../cache/ProfileExchangeProcessor.java         |    32 +
 .../internal/cache/ProxyBucketRegion.java       |   647 +
 .../gemfire/internal/cache/ProxyRegionMap.java  |   712 +
 .../cache/PutAllPartialResultException.java     |   220 +
 .../gemfire/internal/cache/QueuedOperation.java |   190 +
 .../internal/cache/RegionClearedException.java  |    53 +
 .../gemfire/internal/cache/RegionEntry.java     |   454 +
 .../internal/cache/RegionEntryContext.java      |    28 +
 .../internal/cache/RegionEntryFactory.java      |    34 +
 .../gemfire/internal/cache/RegionEventImpl.java |   343 +
 .../internal/cache/RegionEvictorTask.java       |   135 +
 .../internal/cache/RegionExpiryTask.java        |   150 +
 .../internal/cache/RegionFactoryImpl.java       |    41 +
 .../internal/cache/RegionIdleExpiryTask.java    |    63 +
 .../gemfire/internal/cache/RegionMap.java       |   378 +
 .../internal/cache/RegionMapFactory.java        |    62 +
 .../gemfire/internal/cache/RegionQueue.java     |   147 +
 .../internal/cache/RegionQueueException.java    |    40 +
 .../gemfire/internal/cache/RegionStatus.java    |    79 +
 .../internal/cache/RegionTTLExpiryTask.java     |    66 +
 .../internal/cache/ReleaseClearLockMessage.java |   104 +
 .../cache/ReliableDistributionData.java         |    34 +
 .../internal/cache/ReliableMessageQueue.java    |    57 +
 .../cache/ReliableMessageQueueFactory.java      |    34 +
 .../cache/ReliableMessageQueueFactoryImpl.java  |   221 +
 .../cache/RemoteContainsKeyValueMessage.java    |   334 +
 .../internal/cache/RemoteDestroyMessage.java    |   704 +
 .../internal/cache/RemoteFetchEntryMessage.java |   378 +
 .../cache/RemoteFetchVersionMessage.java        |   253 +
 .../internal/cache/RemoteGetMessage.java        |   448 +
 .../internal/cache/RemoteInvalidateMessage.java |   425 +
 .../cache/RemoteOperationException.java         |   110 +
 .../internal/cache/RemoteOperationMessage.java  |   616 +
 .../RemoteOperationMessageWithDirectReply.java  |    76 +
 .../internal/cache/RemotePutAllMessage.java     |   526 +
 .../internal/cache/RemotePutMessage.java        |  1159 ++
 .../internal/cache/RemoteRegionOperation.java   |   216 +
 .../internal/cache/RemoteRemoveAllMessage.java  |   509 +
 .../gemfire/internal/cache/RoleEventImpl.java   |    87 +
 .../cache/SearchLoadAndWriteProcessor.java      |  2780 ++++
 .../internal/cache/SendQueueOperation.java      |   182 +
 .../internal/cache/SerializationHelper.java     |     8 +
 .../internal/cache/StateFlushOperation.java     |   775 ++
 .../cache/StoreAllCachedDeserializable.java     |   150 +
 .../internal/cache/TXBucketRegionState.java     |    28 +
 .../gemfire/internal/cache/TXCommitMessage.java |  2384 ++++
 .../gemfire/internal/cache/TXEntry.java         |   263 +
 .../gemfire/internal/cache/TXEntryState.java    |  2067 +++
 .../internal/cache/TXEntryStateFactory.java     |    29 +
 .../internal/cache/TXEntryUserAttrState.java    |    58 +
 .../gemfire/internal/cache/TXEvent.java         |   125 +
 .../internal/cache/TXFarSideCMTracker.java      |   351 +
 .../gemstone/gemfire/internal/cache/TXId.java   |   122 +
 .../gemfire/internal/cache/TXLockRequest.java   |   135 +
 .../gemfire/internal/cache/TXManagerImpl.java   |  1369 ++
 .../gemfire/internal/cache/TXMessage.java       |   200 +
 .../internal/cache/TXRegionLockRequestImpl.java |   200 +
 .../gemfire/internal/cache/TXRegionState.java   |   444 +
 .../internal/cache/TXRemoteCommitMessage.java   |   311 +
 .../internal/cache/TXRemoteRollbackMessage.java |    79 +
 .../internal/cache/TXReservationMgr.java        |   145 +
 .../gemfire/internal/cache/TXRmtEvent.java      |   224 +
 .../gemfire/internal/cache/TXState.java         |  1752 +++
 .../internal/cache/TXStateInterface.java        |   181 +
 .../gemfire/internal/cache/TXStateProxy.java    |    87 +
 .../internal/cache/TXStateProxyImpl.java        |   989 ++
 .../gemfire/internal/cache/TXStateStub.java     |   529 +
 .../cache/TXSynchronizationRunnable.java        |   151 +
 .../cache/TestHeapThresholdObserver.java        |    53 +
 .../cache/TimestampedEntryEventImpl.java        |    64 +
 .../gemstone/gemfire/internal/cache/Token.java  |   286 +
 .../internal/cache/TombstoneService.java        |   991 ++
 .../internal/cache/TransactionMessage.java      |    60 +
 .../gemfire/internal/cache/TxEntryFactory.java  |    19 +
 .../internal/cache/UnsharedImageState.java      |   284 +
 .../cache/UpdateAttributesProcessor.java        |   544 +
 .../cache/UpdateEntryVersionOperation.java      |   187 +
 .../gemfire/internal/cache/UpdateOperation.java |   647 +
 .../cache/UserSpecifiedDiskStoreAttributes.java |   182 +
 .../cache/UserSpecifiedRegionAttributes.java    |   569 +
 .../internal/cache/VMCachedDeserializable.java  |   254 +
 .../gemfire/internal/cache/VMLRURegionMap.java  |    56 +
 .../gemfire/internal/cache/VMRegionMap.java     |    30 +
 .../cache/VMStatsDiskLRURegionEntry.java        |    31 +
 .../cache/VMStatsDiskLRURegionEntryHeap.java    |    56 +
 .../VMStatsDiskLRURegionEntryHeapIntKey.java    |   334 +
 .../VMStatsDiskLRURegionEntryHeapLongKey.java   |   334 +
 .../VMStatsDiskLRURegionEntryHeapObjectKey.java |   327 +
 ...VMStatsDiskLRURegionEntryHeapStringKey1.java |   396 +
 ...VMStatsDiskLRURegionEntryHeapStringKey2.java |   437 +
 .../VMStatsDiskLRURegionEntryHeapUUIDKey.java   |   338 +
 .../internal/cache/VMStatsDiskRegionEntry.java  |    30 +
 .../cache/VMStatsDiskRegionEntryHeap.java       |    56 +
 .../cache/VMStatsDiskRegionEntryHeapIntKey.java |   235 +
 .../VMStatsDiskRegionEntryHeapLongKey.java      |   235 +
 .../VMStatsDiskRegionEntryHeapObjectKey.java    |   228 +
 .../VMStatsDiskRegionEntryHeapStringKey1.java   |   297 +
 .../VMStatsDiskRegionEntryHeapStringKey2.java   |   338 +
 .../VMStatsDiskRegionEntryHeapUUIDKey.java      |   239 +
 .../internal/cache/VMStatsLRURegionEntry.java   |    34 +
 .../cache/VMStatsLRURegionEntryHeap.java        |    56 +
 .../cache/VMStatsLRURegionEntryHeapIntKey.java  |   245 +
 .../cache/VMStatsLRURegionEntryHeapLongKey.java |   245 +
 .../VMStatsLRURegionEntryHeapObjectKey.java     |   238 +
 .../VMStatsLRURegionEntryHeapStringKey1.java    |   307 +
 .../VMStatsLRURegionEntryHeapStringKey2.java    |   348 +
 .../cache/VMStatsLRURegionEntryHeapUUIDKey.java |   249 +
 .../internal/cache/VMStatsRegionEntry.java      |    30 +
 .../internal/cache/VMStatsRegionEntryHeap.java  |    56 +
 .../cache/VMStatsRegionEntryHeapIntKey.java     |   162 +
 .../cache/VMStatsRegionEntryHeapLongKey.java    |   162 +
 .../cache/VMStatsRegionEntryHeapObjectKey.java  |   155 +
 .../cache/VMStatsRegionEntryHeapStringKey1.java |   224 +
 .../cache/VMStatsRegionEntryHeapStringKey2.java |   265 +
 .../cache/VMStatsRegionEntryHeapUUIDKey.java    |   166 +
 .../cache/VMThinDiskLRURegionEntry.java         |    30 +
 .../cache/VMThinDiskLRURegionEntryHeap.java     |    56 +
 .../VMThinDiskLRURegionEntryHeapIntKey.java     |   269 +
 .../VMThinDiskLRURegionEntryHeapLongKey.java    |   269 +
 .../VMThinDiskLRURegionEntryHeapObjectKey.java  |   262 +
 .../VMThinDiskLRURegionEntryHeapStringKey1.java |   331 +
 .../VMThinDiskLRURegionEntryHeapStringKey2.java |   372 +
 .../VMThinDiskLRURegionEntryHeapUUIDKey.java    |   273 +
 .../internal/cache/VMThinDiskRegionEntry.java   |    32 +
 .../cache/VMThinDiskRegionEntryHeap.java        |    56 +
 .../cache/VMThinDiskRegionEntryHeapIntKey.java  |   169 +
 .../cache/VMThinDiskRegionEntryHeapLongKey.java |   169 +
 .../VMThinDiskRegionEntryHeapObjectKey.java     |   162 +
 .../VMThinDiskRegionEntryHeapStringKey1.java    |   231 +
 .../VMThinDiskRegionEntryHeapStringKey2.java    |   272 +
 .../cache/VMThinDiskRegionEntryHeapUUIDKey.java |   173 +
 .../internal/cache/VMThinLRURegionEntry.java    |    28 +
 .../cache/VMThinLRURegionEntryHeap.java         |    56 +
 .../cache/VMThinLRURegionEntryHeapIntKey.java   |   180 +
 .../cache/VMThinLRURegionEntryHeapLongKey.java  |   180 +
 .../VMThinLRURegionEntryHeapObjectKey.java      |   173 +
 .../VMThinLRURegionEntryHeapStringKey1.java     |   242 +
 .../VMThinLRURegionEntryHeapStringKey2.java     |   283 +
 .../cache/VMThinLRURegionEntryHeapUUIDKey.java  |   184 +
 .../internal/cache/VMThinRegionEntry.java       |    26 +
 .../internal/cache/VMThinRegionEntryHeap.java   |    58 +
 .../cache/VMThinRegionEntryHeapIntKey.java      |    96 +
 .../cache/VMThinRegionEntryHeapLongKey.java     |    96 +
 .../cache/VMThinRegionEntryHeapObjectKey.java   |    89 +
 .../cache/VMThinRegionEntryHeapStringKey1.java  |   158 +
 .../cache/VMThinRegionEntryHeapStringKey2.java  |   199 +
 .../cache/VMThinRegionEntryHeapUUIDKey.java     |   100 +
 .../internal/cache/ValidatingDiskRegion.java    |   477 +
 .../internal/cache/ValueByteWrapper.java        |    61 +
 .../internal/cache/VersionTimestamp.java        |    38 +
 .../cache/VersionedStatsDiskLRURegionEntry.java |    24 +
 .../VersionedStatsDiskLRURegionEntryHeap.java   |    57 +
 ...sionedStatsDiskLRURegionEntryHeapIntKey.java |   419 +
 ...ionedStatsDiskLRURegionEntryHeapLongKey.java |   419 +
 ...nedStatsDiskLRURegionEntryHeapObjectKey.java |   412 +
 ...edStatsDiskLRURegionEntryHeapStringKey1.java |   481 +
 ...edStatsDiskLRURegionEntryHeapStringKey2.java |   522 +
 ...ionedStatsDiskLRURegionEntryHeapUUIDKey.java |   423 +
 .../cache/VersionedStatsDiskRegionEntry.java    |    24 +
 .../VersionedStatsDiskRegionEntryHeap.java      |    57 +
 ...VersionedStatsDiskRegionEntryHeapIntKey.java |   320 +
 ...ersionedStatsDiskRegionEntryHeapLongKey.java |   320 +
 ...sionedStatsDiskRegionEntryHeapObjectKey.java |   313 +
 ...ionedStatsDiskRegionEntryHeapStringKey1.java |   382 +
 ...ionedStatsDiskRegionEntryHeapStringKey2.java |   423 +
 ...ersionedStatsDiskRegionEntryHeapUUIDKey.java |   324 +
 .../cache/VersionedStatsLRURegionEntry.java     |    25 +
 .../cache/VersionedStatsLRURegionEntryHeap.java |    57 +
 .../VersionedStatsLRURegionEntryHeapIntKey.java |   330 +
 ...VersionedStatsLRURegionEntryHeapLongKey.java |   330 +
 ...rsionedStatsLRURegionEntryHeapObjectKey.java |   323 +
 ...sionedStatsLRURegionEntryHeapStringKey1.java |   392 +
 ...sionedStatsLRURegionEntryHeapStringKey2.java |   433 +
 ...VersionedStatsLRURegionEntryHeapUUIDKey.java |   334 +
 .../cache/VersionedStatsRegionEntry.java        |    25 +
 .../cache/VersionedStatsRegionEntryHeap.java    |    56 +
 .../VersionedStatsRegionEntryHeapIntKey.java    |   247 +
 .../VersionedStatsRegionEntryHeapLongKey.java   |   247 +
 .../VersionedStatsRegionEntryHeapObjectKey.java |   240 +
 ...VersionedStatsRegionEntryHeapStringKey1.java |   309 +
 ...VersionedStatsRegionEntryHeapStringKey2.java |   350 +
 .../VersionedStatsRegionEntryHeapUUIDKey.java   |   251 +
 .../cache/VersionedThinDiskLRURegionEntry.java  |    24 +
 .../VersionedThinDiskLRURegionEntryHeap.java    |    57 +
 ...rsionedThinDiskLRURegionEntryHeapIntKey.java |   354 +
 ...sionedThinDiskLRURegionEntryHeapLongKey.java |   354 +
 ...onedThinDiskLRURegionEntryHeapObjectKey.java |   347 +
 ...nedThinDiskLRURegionEntryHeapStringKey1.java |   416 +
 ...nedThinDiskLRURegionEntryHeapStringKey2.java |   457 +
 ...sionedThinDiskLRURegionEntryHeapUUIDKey.java |   358 +
 .../cache/VersionedThinDiskRegionEntry.java     |    24 +
 .../cache/VersionedThinDiskRegionEntryHeap.java |    57 +
 .../VersionedThinDiskRegionEntryHeapIntKey.java |   254 +
 ...VersionedThinDiskRegionEntryHeapLongKey.java |   254 +
 ...rsionedThinDiskRegionEntryHeapObjectKey.java |   247 +
 ...sionedThinDiskRegionEntryHeapStringKey1.java |   316 +
 ...sionedThinDiskRegionEntryHeapStringKey2.java |   357 +
 ...VersionedThinDiskRegionEntryHeapUUIDKey.java |   258 +
 .../cache/VersionedThinLRURegionEntry.java      |    29 +
 .../cache/VersionedThinLRURegionEntryHeap.java  |    56 +
 .../VersionedThinLRURegionEntryHeapIntKey.java  |   265 +
 .../VersionedThinLRURegionEntryHeapLongKey.java |   265 +
 ...ersionedThinLRURegionEntryHeapObjectKey.java |   258 +
 ...rsionedThinLRURegionEntryHeapStringKey1.java |   327 +
 ...rsionedThinLRURegionEntryHeapStringKey2.java |   368 +
 .../VersionedThinLRURegionEntryHeapUUIDKey.java |   269 +
 .../cache/VersionedThinRegionEntry.java         |    24 +
 .../cache/VersionedThinRegionEntryHeap.java     |    56 +
 .../VersionedThinRegionEntryHeapIntKey.java     |   181 +
 .../VersionedThinRegionEntryHeapLongKey.java    |   181 +
 .../VersionedThinRegionEntryHeapObjectKey.java  |   174 +
 .../VersionedThinRegionEntryHeapStringKey1.java |   243 +
 .../VersionedThinRegionEntryHeapStringKey2.java |   284 +
 .../VersionedThinRegionEntryHeapUUIDKey.java    |   185 +
 .../internal/cache/WrappedCallbackArgument.java |    96 +
 .../cache/WrappedRegionMembershipListener.java  |   191 +
 .../CompressedCachedDeserializable.java         |   188 +
 .../SnappyCompressedCachedDeserializable.java   |    74 +
 .../internal/cache/control/FilterByPath.java    |    57 +
 .../cache/control/InternalResourceManager.java  |  1806 +++
 .../internal/cache/control/MemoryEvent.java     |    57 +
 .../internal/cache/control/MemoryEventImpl.java |   187 +
 .../internal/cache/control/MemoryEventType.java |   352 +
 .../control/PartitionRebalanceDetailsImpl.java  |   150 +
 .../cache/control/PartitionRebalanceEvent.java  |    24 +
 .../control/PartitionRebalanceEventImpl.java    |    51 +
 .../control/PartitionRebalanceEventType.java    |    29 +
 .../cache/control/RebalanceOperationImpl.java   |   185 +
 .../cache/control/RebalanceResultsImpl.java     |    81 +
 .../internal/cache/control/RegionFilter.java    |    18 +
 .../internal/cache/control/ResourceAdvisor.java |   429 +
 .../internal/cache/control/ResourceEvent.java   |    18 +
 .../cache/control/ResourceListener.java         |    24 +
 .../cache/control/ResourceManagerStats.java     |   511 +
 .../gemfire/internal/cache/delta/Delta.java     |    48 +
 .../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    |  3945 ++++++
 .../cache/doc-files/region-implementation.fig   |   262 +
 .../cache/execute/AbstractExecution.java        |   626 +
 .../cache/execute/BucketMovedException.java     |    48 +
 .../cache/execute/DefaultResultCollector.java   |   100 +
 .../DistributedRegionFunctionExecutor.java      |   437 +
 .../DistributedRegionFunctionResultSender.java  |   254 +
 .../DistributedRegionFunctionResultWaiter.java  |    51 +
 .../cache/execute/FunctionContextImpl.java      |    98 +
 .../execute/FunctionExecutionNodePruner.java    |   251 +
 .../cache/execute/FunctionRemoteContext.java    |   122 +
 .../cache/execute/FunctionServiceStats.java     |   433 +
 .../internal/cache/execute/FunctionStats.java   |   527 +
 .../FunctionStreamingResultCollector.java       |   627 +
 .../cache/execute/InternalExecution.java        |   105 +
 .../execute/InternalFunctionException.java      |    69 +
 ...ternalFunctionInvocationTargetException.java |    87 +
 .../cache/execute/InternalFunctionService.java  |   203 +
 .../execute/InternalRegionFunctionContext.java  |    75 +
 .../cache/execute/InternalResultSender.java     |    26 +
 .../cache/execute/LocalResultCollector.java     |    35 +
 .../cache/execute/LocalResultCollectorImpl.java |   203 +
 .../cache/execute/MemberFunctionExecutor.java   |   274 +
 .../execute/MemberFunctionResultSender.java     |   270 +
 .../execute/MemberFunctionResultWaiter.java     |    42 +
 .../cache/execute/MemberMappedArgument.java     |    66 +
 .../execute/MultiRegionFunctionContext.java     |    41 +
 .../execute/MultiRegionFunctionContextImpl.java |    47 +
 .../execute/MultiRegionFunctionExecutor.java    |   407 +
 .../MultiRegionFunctionResultWaiter.java        |    52 +
 .../internal/cache/execute/NoResult.java        |    71 +
 .../PartitionedRegionFunctionExecutor.java      |   369 +
 .../PartitionedRegionFunctionResultSender.java  |   332 +
 .../PartitionedRegionFunctionResultWaiter.java  |   116 +
 .../execute/RegionFunctionContextImpl.java      |   151 +
 .../cache/execute/ServerFunctionExecutor.java   |   437 +
 .../execute/ServerRegionFunctionExecutor.java   |   492 +
 .../ServerToClientFunctionResultSender.java     |   311 +
 .../ServerToClientFunctionResultSender65.java   |   281 +
 .../execute/StreamingFunctionOperation.java     |   118 +
 .../execute/TransactionFunctionService.java     |   184 +
 .../cache/execute/util/CommitFunction.java      |   135 +
 .../util/FindRestEnabledServersFunction.java    |    74 +
 .../execute/util/NestedTransactionFunction.java |   108 +
 .../cache/execute/util/RollbackFunction.java    |   130 +
 .../internal/cache/extension/Extensible.java    |    34 +
 .../internal/cache/extension/Extension.java     |    44 +
 .../cache/extension/ExtensionPoint.java         |    56 +
 .../cache/extension/SimpleExtensionPoint.java   |    76 +
 .../internal/cache/ha/HAContainerMap.java       |   194 +
 .../internal/cache/ha/HAContainerRegion.java    |   161 +
 .../internal/cache/ha/HAContainerWrapper.java   |    38 +
 .../internal/cache/ha/HARegionQueue.java        |  4205 ++++++
 .../cache/ha/HARegionQueueAttributes.java       |   100 +
 .../internal/cache/ha/HARegionQueueStats.java   |   402 +
 .../internal/cache/ha/QueueRemovalMessage.java  |   231 +
 .../internal/cache/ha/ThreadIdentifier.java     |   321 +
 .../locks/GFEAbstractQueuedSynchronizer.java    |  1706 +++
 .../locks/ReentrantReadWriteWriteShareLock.java |   468 +
 .../cache/locks/TXLessorDepartureHandler.java   |    93 +
 .../internal/cache/locks/TXLockBatch.java       |   139 +
 .../gemfire/internal/cache/locks/TXLockId.java  |    26 +
 .../internal/cache/locks/TXLockIdImpl.java      |   131 +
 .../internal/cache/locks/TXLockService.java     |   152 +
 .../internal/cache/locks/TXLockServiceImpl.java |   269 +
 .../internal/cache/locks/TXLockToken.java       |    86 +
 .../locks/TXLockUpdateParticipantsMessage.java  |   177 +
 .../locks/TXOriginatorRecoveryProcessor.java    |   303 +
 .../locks/TXRecoverGrantorMessageProcessor.java |   148 +
 .../cache/locks/TXRegionLockRequest.java        |    30 +
 .../gemfire/internal/cache/lru/EnableLRU.java   |   113 +
 .../gemfire/internal/cache/lru/HeapEvictor.java |   344 +
 .../cache/lru/HeapLRUCapacityController.java    |   315 +
 .../internal/cache/lru/HeapLRUStatistics.java   |    59 +
 .../internal/cache/lru/LRUAlgorithm.java        |   343 +
 .../cache/lru/LRUCapacityController.java        |   347 +
 .../internal/cache/lru/LRUClockNode.java        |    36 +
 .../gemfire/internal/cache/lru/LRUEntry.java    |    23 +
 .../internal/cache/lru/LRUMapCallbacks.java     |    52 +
 .../internal/cache/lru/LRUStatistics.java       |   201 +
 .../cache/lru/MemLRUCapacityController.java     |   528 +
 .../internal/cache/lru/NewLIFOClockHand.java    |    59 +
 .../internal/cache/lru/NewLRUClockHand.java     |   449 +
 .../gemfire/internal/cache/lru/Sizeable.java    |    54 +
 .../operations/ContainsKeyOperationContext.java |    43 +
 .../gemfire/internal/cache/package.html         |   225 +
 .../AllBucketProfilesUpdateMessage.java         |   161 +
 .../partitioned/BecomePrimaryBucketMessage.java |   323 +
 .../internal/cache/partitioned/Bucket.java      |    71 +
 .../cache/partitioned/BucketBackupMessage.java  |   129 +
 .../partitioned/BucketProfileUpdateMessage.java |   183 +
 .../cache/partitioned/BucketSizeMessage.java    |   277 +
 .../partitioned/ContainsKeyValueMessage.java    |   340 +
 .../cache/partitioned/CreateBucketMessage.java  |   362 +
 .../partitioned/CreateMissingBucketsTask.java   |    61 +
 .../partitioned/DeposePrimaryBucketMessage.java |   276 +
 .../cache/partitioned/DestroyMessage.java       |   593 +
 .../partitioned/DumpAllPRConfigMessage.java     |    69 +
 .../cache/partitioned/DumpB2NRegion.java        |   335 +
 .../cache/partitioned/DumpBucketsMessage.java   |   102 +
 .../partitioned/EndBucketCreationMessage.java   |   140 +
 .../partitioned/FetchBulkEntriesMessage.java    |   661 +
 .../cache/partitioned/FetchEntriesMessage.java  |   651 +
 .../cache/partitioned/FetchEntryMessage.java    |   423 +
 .../cache/partitioned/FetchKeysMessage.java     |   573 +
 .../FetchPartitionDetailsMessage.java           |   388 +
 .../cache/partitioned/FlushMessage.java         |   145 +
 .../internal/cache/partitioned/GetMessage.java  |   610 +
 .../partitioned/IdentityRequestMessage.java     |   334 +
 .../partitioned/IdentityUpdateMessage.java      |   158 +
 .../cache/partitioned/IndexCreationMsg.java     |   707 +
 .../cache/partitioned/InterestEventMessage.java |   275 +
 .../cache/partitioned/InternalPRInfo.java       |    35 +
 .../partitioned/InternalPartitionDetails.java   |    36 +
 .../cache/partitioned/InvalidateMessage.java    |   396 +
 .../internal/cache/partitioned/LoadProbe.java   |    24 +
 .../internal/cache/partitioned/LockObject.java  |    33 +
 .../partitioned/ManageBackupBucketMessage.java  |   428 +
 .../cache/partitioned/ManageBucketMessage.java  |   410 +
 .../cache/partitioned/MoveBucketMessage.java    |   315 +
 .../cache/partitioned/OfflineMemberDetails.java |    39 +
 .../partitioned/OfflineMemberDetailsImpl.java   |    70 +
 .../cache/partitioned/PREntriesIterator.java    |    35 +
 .../PRFunctionStreamingResultCollector.java     |   427 +
 .../internal/cache/partitioned/PRLoad.java      |   145 +
 .../PRLocallyDestroyedException.java            |    31 +
 .../cache/partitioned/PRSanityCheckMessage.java |   155 +
 .../cache/partitioned/PRTombstoneMessage.java   |   183 +
 .../PRUpdateEntryVersionMessage.java            |   286 +
 .../partitioned/PartitionMemberInfoImpl.java    |   158 +
 .../cache/partitioned/PartitionMessage.java     |   776 ++
 .../PartitionMessageWithDirectReply.java        |   132 +
 .../partitioned/PartitionRegionInfoImpl.java    |   130 +
 ...rtitionedRegionFunctionStreamingMessage.java |   196 +
 .../partitioned/PartitionedRegionObserver.java  |    30 +
 .../PartitionedRegionObserverAdapter.java       |    34 +
 .../PartitionedRegionObserverHolder.java        |    54 +
 .../PartitionedRegionRebalanceOp.java           |   844 ++
 .../partitioned/PrimaryRequestMessage.java      |   229 +
 .../cache/partitioned/PutAllPRMessage.java      |   826 ++
 .../internal/cache/partitioned/PutMessage.java  |  1310 ++
 .../cache/partitioned/QueryMessage.java         |   286 +
 .../cache/partitioned/RecoveryRunnable.java     |    77 +
 .../RedundancyAlreadyMetException.java          |    33 +
 .../cache/partitioned/RedundancyLogger.java     |   386 +
 .../cache/partitioned/RegionAdvisor.java        |  1948 +++
 .../partitioned/RemoteFetchKeysMessage.java     |   480 +
 .../cache/partitioned/RemoteSizeMessage.java    |   354 +
 .../cache/partitioned/RemoveAllPRMessage.java   |   787 ++
 .../cache/partitioned/RemoveBucketMessage.java  |   314 +
 .../cache/partitioned/RemoveIndexesMessage.java |   536 +
 .../internal/cache/partitioned/SizeMessage.java |   342 +
 .../cache/partitioned/SizedBasedLoadProbe.java  |    74 +
 .../StreamingPartitionOperation.java            |   465 +
 .../partitioned/rebalance/BucketOperator.java   |    60 +
 .../rebalance/CompositeDirector.java            |   118 +
 .../rebalance/ExplicitMoveDirector.java         |    90 +
 .../partitioned/rebalance/FPRDirector.java      |    70 +
 .../partitioned/rebalance/MoveBuckets.java      |    54 +
 .../partitioned/rebalance/MovePrimaries.java    |    54 +
 .../partitioned/rebalance/MovePrimariesFPR.java |    96 +
 .../rebalance/PartitionedRegionLoadModel.java   |  1602 +++
 .../rebalance/PercentageMoveDirector.java       |   156 +
 .../rebalance/RebalanceDirector.java            |    70 +
 .../rebalance/RebalanceDirectorAdapter.java     |    30 +
 .../rebalance/RemoveOverRedundancy.java         |    73 +
 .../rebalance/SatisfyRedundancy.java            |    78 +
 .../rebalance/SatisfyRedundancyFPR.java         |    80 +
 .../rebalance/SimulatedBucketOperator.java      |    41 +
 .../cache/persistence/BackupInspector.java      |   336 +
 .../cache/persistence/BackupManager.java        |   360 +
 .../cache/persistence/BytesAndBits.java         |    42 +
 .../cache/persistence/CanonicalIdHolder.java    |    92 +
 .../CreatePersistentRegionProcessor.java        |    49 +
 .../cache/persistence/DiskExceptionHandler.java |    29 +
 .../persistence/DiskInitFileInterpreter.java    |   139 +
 .../cache/persistence/DiskInitFileParser.java   |   610 +
 .../cache/persistence/DiskRecoveryStore.java    |    57 +
 .../cache/persistence/DiskRegionView.java       |    98 +
 .../cache/persistence/DiskStoreFilter.java      |    48 +
 .../internal/cache/persistence/DiskStoreID.java |   147 +
 .../persistence/MembershipFlushRequest.java     |   132 +
 .../persistence/MembershipViewRequest.java      |   245 +
 .../internal/cache/persistence/OplogType.java   |    16 +
 .../cache/persistence/PRPersistentConfig.java   |    65 +
 .../cache/persistence/PersistenceAdvisor.java   |   181 +
 .../persistence/PersistenceAdvisorImpl.java     |  1295 ++
 .../persistence/PersistenceObserverHolder.java  |    93 +
 .../cache/persistence/PersistentMemberID.java   |   162 +
 .../persistence/PersistentMemberManager.java    |   261 +
 .../persistence/PersistentMemberPattern.java    |   220 +
 .../persistence/PersistentMemberState.java      |    32 +
 .../cache/persistence/PersistentMemberView.java |   142 +
 .../persistence/PersistentMembershipView.java   |   103 +
 .../persistence/PersistentStateListener.java    |    29 +
 .../PersistentStateQueryMessage.java            |   299 +
 .../PersistentStateQueryResults.java            |    48 +
 .../PrepareNewPersistentMemberMessage.java      |   159 +
 .../RemovePersistentMemberMessage.java          |   173 +
 .../cache/persistence/RestoreScript.java        |   214 +
 .../persistence/UninterruptibleFileChannel.java |    13 +
 .../UninterruptibleRandomAccessFile.java        |   235 +
 .../persistence/query/CloseableIterator.java    |    17 +
 .../persistence/query/IdentityExtractor.java    |    10 +
 .../cache/persistence/query/IndexMap.java       |   178 +
 .../cache/persistence/query/ResultBag.java      |    51 +
 .../cache/persistence/query/ResultList.java     |    49 +
 .../cache/persistence/query/ResultMap.java      |   115 +
 .../cache/persistence/query/ResultSet.java      |    51 +
 .../persistence/query/SortKeyExtractor.java     |     5 +
 .../query/TemporaryResultSetFactory.java        |    70 +
 .../persistence/query/mock/ByteComparator.java  |    77 +
 .../mock/CachedDeserializableComparator.java    |    45 +
 .../persistence/query/mock/IndexMapImpl.java    |   269 +
 .../persistence/query/mock/ItrAdapter.java      |    53 +
 .../query/mock/NaturalComparator.java           |    17 +
 .../cache/persistence/query/mock/Pair.java      |    63 +
 .../persistence/query/mock/PairComparator.java  |    37 +
 .../persistence/query/mock/ResultListImpl.java  |    46 +
 .../query/mock/ReverseComparator.java           |    31 +
 .../query/mock/SortedResultBagImpl.java         |    55 +
 .../query/mock/SortedResultMapImpl.java         |   175 +
 .../query/mock/SortedResultSetImpl.java         |    43 +
 .../persistence/soplog/AbstractCompactor.java   |   524 +
 .../soplog/AbstractKeyValueIterator.java        |    67 +
 .../soplog/AbstractSortedReader.java            |   126 +
 .../soplog/ArraySerializedComparator.java       |   135 +
 .../persistence/soplog/ByteComparator.java      |    53 +
 .../cache/persistence/soplog/Compactor.java     |   165 +
 .../soplog/CompositeSerializedComparator.java   |    48 +
 .../soplog/DelegatingSerializedComparator.java  |    29 +
 .../soplog/IndexSerializedComparator.java       |   118 +
 .../persistence/soplog/KeyValueIterator.java    |    34 +
 .../cache/persistence/soplog/LevelTracker.java  |   111 +
 .../soplog/LexicographicalComparator.java       |   451 +
 .../cache/persistence/soplog/NonCompactor.java  |   101 +
 .../soplog/ReversingSerializedComparator.java   |    58 +
 .../persistence/soplog/SizeTieredCompactor.java |   189 +
 .../cache/persistence/soplog/SoplogToken.java   |   107 +
 .../cache/persistence/soplog/SortedBuffer.java  |   358 +
 .../cache/persistence/soplog/SortedOplog.java   |   149 +
 .../persistence/soplog/SortedOplogFactory.java  |   246 +
 .../persistence/soplog/SortedOplogSet.java      |   109 +
 .../persistence/soplog/SortedOplogSetImpl.java  |   771 ++
 .../soplog/SortedOplogStatistics.java           |   468 +
 .../cache/persistence/soplog/SortedReader.java  |   259 +
 .../persistence/soplog/TrackedReference.java    |   100 +
 .../soplog/nofile/NoFileSortedOplog.java        |   235 +
 .../soplog/nofile/NoFileSortedOplogFactory.java |    32 +
 .../snapshot/CacheSnapshotServiceImpl.java      |   121 +
 .../internal/cache/snapshot/ClientExporter.java |   220 +
 .../cache/snapshot/ExportedRegistry.java        |    95 +
 .../internal/cache/snapshot/FlowController.java |   341 +
 .../internal/cache/snapshot/GFSnapshot.java     |   408 +
 .../internal/cache/snapshot/LocalExporter.java  |    49 +
 .../snapshot/RegionSnapshotServiceImpl.java     |   556 +
 .../cache/snapshot/SnapshotFileMapper.java      |    84 +
 .../cache/snapshot/SnapshotOptionsImpl.java     |   115 +
 .../internal/cache/snapshot/SnapshotPacket.java |   252 +
 .../cache/snapshot/WindowedExporter.java        |   392 +
 .../gemfire/internal/cache/tier/Acceptor.java   |   106 +
 .../internal/cache/tier/BatchException.java     |    63 +
 .../internal/cache/tier/CachedRegionHelper.java |   100 +
 .../internal/cache/tier/ClientHandShake.java    |    37 +
 .../gemfire/internal/cache/tier/Command.java    |    27 +
 .../internal/cache/tier/ConnectionProxy.java    |   184 +
 .../internal/cache/tier/InterestType.java       |    55 +
 .../cache/tier/InternalBridgeMembership.java    |   715 +
 .../internal/cache/tier/MessageType.java        |   560 +
 .../gemfire/internal/cache/tier/package.html    |     7 +
 .../cache/tier/sockets/AcceptorImpl.java        |  1887 +++
 .../cache/tier/sockets/BaseCommand.java         |  1616 +++
 .../cache/tier/sockets/BaseCommandQuery.java    |   562 +
 .../cache/tier/sockets/CacheClientNotifier.java |  2751 ++++
 .../tier/sockets/CacheClientNotifierStats.java  |   286 +
 .../cache/tier/sockets/CacheClientProxy.java    |  3068 ++++
 .../tier/sockets/CacheClientProxyStats.java     |   396 +
 .../cache/tier/sockets/CacheClientUpdater.java  |  1985 +++
 .../cache/tier/sockets/CacheServerHelper.java   |   178 +
 .../cache/tier/sockets/CacheServerStats.java    |  1139 ++
 .../cache/tier/sockets/ChunkedMessage.java      |   370 +
 .../tier/sockets/ClientBlacklistProcessor.java  |   165 +
 .../sockets/ClientDataSerializerMessage.java    |   247 +
 .../cache/tier/sockets/ClientHealthMonitor.java |   963 ++
 .../tier/sockets/ClientInstantiatorMessage.java |   222 +
 .../tier/sockets/ClientInterestMessageImpl.java |   265 +
 .../tier/sockets/ClientMarkerMessageImpl.java   |   118 +
 .../cache/tier/sockets/ClientMessage.java       |    37 +
 .../tier/sockets/ClientPingMessageImpl.java     |   102 +
 .../tier/sockets/ClientProxyMembershipID.java   |   622 +
 .../tier/sockets/ClientTombstoneMessage.java    |   179 +
 .../cache/tier/sockets/ClientUpdateMessage.java |   179 +
 .../tier/sockets/ClientUpdateMessageImpl.java   |  1675 +++
 .../cache/tier/sockets/ClientUserAuths.java     |   192 +
 .../cache/tier/sockets/CommandInitializer.java  |   323 +
 .../cache/tier/sockets/ConnectionListener.java  |    46 +
 .../tier/sockets/ConnectionListenerAdapter.java |    29 +
 .../cache/tier/sockets/HAEventWrapper.java      |   426 +
 .../internal/cache/tier/sockets/HandShake.java  |  1908 +++
 .../tier/sockets/InterestResultPolicyImpl.java  |    50 +
 .../internal/cache/tier/sockets/Message.java    |  1111 ++
 .../cache/tier/sockets/MessageStats.java        |    20 +
 .../cache/tier/sockets/ObjectPartList.java      |   254 +
 .../cache/tier/sockets/ObjectPartList651.java   |   157 +
 .../internal/cache/tier/sockets/Part.java       |   350 +
 .../RemoveClientFromBlacklistMessage.java       |   105 +
 .../tier/sockets/SerializedObjectPartList.java  |   123 +
 .../cache/tier/sockets/ServerConnection.java    |  2014 +++
 .../tier/sockets/ServerHandShakeProcessor.java  |   455 +
 .../cache/tier/sockets/ServerQueueStatus.java   |   123 +
 .../tier/sockets/ServerResponseMatrix.java      |   133 +
 .../tier/sockets/UnregisterAllInterest.java     |    41 +
 .../cache/tier/sockets/UserAuthAttributes.java  |    72 +
 .../cache/tier/sockets/VersionedObjectList.java |   744 +
 .../cache/tier/sockets/command/AddPdxEnum.java  |    64 +
 .../cache/tier/sockets/command/AddPdxType.java  |    69 +
 .../cache/tier/sockets/command/ClearRegion.java |   141 +
 .../cache/tier/sockets/command/ClientReady.java |    67 +
 .../tier/sockets/command/CloseConnection.java   |    68 +
 .../tier/sockets/command/CommitCommand.java     |   131 +
 .../cache/tier/sockets/command/ContainsKey.java |   136 +
 .../tier/sockets/command/ContainsKey66.java     |   153 +
 .../tier/sockets/command/CreateRegion.java      |   128 +
 .../cache/tier/sockets/command/Default.java     |    43 +
 .../cache/tier/sockets/command/Destroy.java     |   210 +
 .../cache/tier/sockets/command/Destroy65.java   |   331 +
 .../cache/tier/sockets/command/Destroy70.java   |   109 +
 .../tier/sockets/command/DestroyRegion.java     |   166 +
 .../tier/sockets/command/ExecuteFunction.java   |   231 +
 .../tier/sockets/command/ExecuteFunction65.java |   263 +
 .../tier/sockets/command/ExecuteFunction66.java |   420 +
 .../tier/sockets/command/ExecuteFunction70.java |   135 +
 .../sockets/command/ExecuteRegionFunction.java  |   262 +
 .../command/ExecuteRegionFunction61.java        |   284 +
 .../command/ExecuteRegionFunction65.java        |   392 +
 .../command/ExecuteRegionFunction66.java        |   428 +
 .../command/ExecuteRegionFunctionSingleHop.java |   413 +
 .../sockets/command/GatewayReceiverCommand.java |   795 ++
 .../cache/tier/sockets/command/Get70.java       |   438 +
 .../cache/tier/sockets/command/GetAll.java      |   251 +
 .../cache/tier/sockets/command/GetAll651.java   |   275 +
 .../cache/tier/sockets/command/GetAll70.java    |   265 +
 .../cache/tier/sockets/command/GetAllForRI.java |    43 +
 .../sockets/command/GetAllWithCallback.java     |   258 +
 .../command/GetClientPRMetadataCommand.java     |   106 +
 .../command/GetClientPRMetadataCommand66.java   |    97 +
 .../GetClientPartitionAttributesCommand.java    |   133 +
 .../GetClientPartitionAttributesCommand66.java  |   150 +
 .../cache/tier/sockets/command/GetEntry70.java  |    62 +
 .../tier/sockets/command/GetEntryCommand.java   |    55 +
 .../sockets/command/GetFunctionAttribute.java   |    72 +
 .../tier/sockets/command/GetPDXEnumById.java    |    64 +
 .../tier/sockets/command/GetPDXIdForEnum.java   |    65 +
 .../tier/sockets/command/GetPDXIdForType.java   |    66 +
 .../tier/sockets/command/GetPDXTypeById.java    |    64 +
 .../tier/sockets/command/GetPdxEnums70.java     |    59 +
 .../tier/sockets/command/GetPdxTypes70.java     |    58 +
 .../cache/tier/sockets/command/Invalid.java     |    40 +
 .../cache/tier/sockets/command/Invalidate.java  |   240 +
 .../tier/sockets/command/Invalidate70.java      |    98 +
 .../cache/tier/sockets/command/KeySet.java      |   184 +
 .../cache/tier/sockets/command/MakePrimary.java |    57 +
 .../tier/sockets/command/ManagementCommand.java |    30 +
 .../cache/tier/sockets/command/PeriodicAck.java |    70 +
 .../cache/tier/sockets/command/Ping.java        |    93 +
 .../cache/tier/sockets/command/Put.java         |   252 +
 .../cache/tier/sockets/command/Put61.java       |   310 +
 .../cache/tier/sockets/command/Put65.java       |   530 +
 .../cache/tier/sockets/command/Put70.java       |   117 +
 .../cache/tier/sockets/command/PutAll.java      |   259 +
 .../cache/tier/sockets/command/PutAll70.java    |   371 +
 .../cache/tier/sockets/command/PutAll80.java    |   460 +
 .../sockets/command/PutAllWithCallback.java     |    44 +
 .../sockets/command/PutUserCredentials.java     |    72 +
 .../cache/tier/sockets/command/Query.java       |    98 +
 .../cache/tier/sockets/command/Query651.java    |   128 +
 .../command/RegisterDataSerializers.java        |   105 +
 .../sockets/command/RegisterInstantiators.java  |   139 +
 .../tier/sockets/command/RegisterInterest.java  |   236 +
 .../sockets/command/RegisterInterest61.java     |   273 +
 .../sockets/command/RegisterInterestList.java   |   244 +
 .../sockets/command/RegisterInterestList61.java |   256 +
 .../sockets/command/RegisterInterestList66.java |   258 +
 .../cache/tier/sockets/command/RemoveAll.java   |   395 +
 .../tier/sockets/command/RemoveUserAuth.java    |    75 +
 .../cache/tier/sockets/command/Request.java     |   264 +
 .../tier/sockets/command/RequestEventValue.java |   168 +
 .../tier/sockets/command/RollbackCommand.java   |    81 +
 .../cache/tier/sockets/command/Size.java        |   158 +
 .../tier/sockets/command/TXFailoverCommand.java |   123 +
 .../command/TXSynchronizationCommand.java       |   200 +
 .../sockets/command/UnregisterInterest.java     |   143 +
 .../sockets/command/UnregisterInterestList.java |   162 +
 .../command/UpdateClientNotification.java       |    70 +
 .../doc-files/communication-architecture.fig    |   158 +
 .../doc-files/communication-architecture.gif    |   Bin 0 -> 5485 bytes
 .../internal/cache/tier/sockets/package.html    |     7 +
 .../cache/tx/AbstractPeerTXRegionStub.java      |    47 +
 .../internal/cache/tx/ClientTXRegionStub.java   |   149 +
 .../internal/cache/tx/ClientTXStateStub.java    |   283 +
 .../cache/tx/DistributedTXRegionStub.java       |   246 +
 .../cache/tx/PartitionedTXRegionStub.java       |   518 +
 .../gemfire/internal/cache/tx/TXRegionStub.java |    56 +
 .../cache/tx/TransactionalOperation.java        |   105 +
 .../cache/versions/CompactVersionHolder.java    |    96 +
 .../ConcurrentCacheModificationException.java   |    32 +
 .../cache/versions/DiskRegionVersionVector.java |    94 +
 .../internal/cache/versions/DiskVersionTag.java |    74 +
 .../internal/cache/versions/RVVException.java   |   198 +
 .../internal/cache/versions/RVVExceptionB.java  |   287 +
 .../internal/cache/versions/RVVExceptionT.java  |   274 +
 .../cache/versions/RegionVersionHolder.java     |   757 +
 .../cache/versions/RegionVersionVector.java     |  1524 ++
 .../cache/versions/VMRegionVersionVector.java   |    92 +
 .../internal/cache/versions/VMVersionTag.java   |    65 +
 .../internal/cache/versions/VersionHolder.java  |    48 +
 .../internal/cache/versions/VersionSource.java  |    32 +
 .../internal/cache/versions/VersionStamp.java   |    84 +
 .../internal/cache/versions/VersionTag.java     |   530 +
 .../internal/cache/vmotion/VMotionObserver.java |    36 +
 .../cache/vmotion/VMotionObserverAdapter.java   |    41 +
 .../cache/vmotion/VMotionObserverHolder.java    |    49 +
 .../cache/wan/AbstractGatewaySender.java        |  1246 ++
 .../AbstractGatewaySenderEventProcessor.java    |  1311 ++
 .../AsyncEventQueueConfigurationException.java  |    64 +
 .../internal/cache/wan/BatchException70.java    |    99 +
 .../cache/wan/DistributedSystemListener.java    |    16 +
 .../cache/wan/GatewayEventFilterImpl.java       |    36 +
 .../cache/wan/GatewayReceiverException.java     |    60 +
 .../cache/wan/GatewayReceiverStats.java         |   269 +
 .../cache/wan/GatewaySenderAdvisor.java         |   701 +
 .../cache/wan/GatewaySenderAttributes.java      |   180 +
 .../GatewaySenderConfigurationException.java    |    40 +
 .../wan/GatewaySenderEventCallbackArgument.java |   193 +
 .../GatewaySenderEventCallbackDispatcher.java   |   195 +
 .../cache/wan/GatewaySenderEventDispatcher.java |    26 +
 .../cache/wan/GatewaySenderEventImpl.java       |   941 ++
 .../cache/wan/GatewaySenderException.java       |    54 +
 .../internal/cache/wan/GatewaySenderStats.java  |   735 +
 .../cache/wan/InternalGatewaySenderFactory.java |    22 +
 .../cache/wan/TransportFilterServerSocket.java  |    31 +
 .../cache/wan/TransportFilterSocket.java        |    69 +
 .../cache/wan/TransportFilterSocketFactory.java |    32 +
 .../internal/cache/wan/WANServiceProvider.java  |    60 +
 .../BucketRegionQueueUnavailableException.java  |    19 +
 ...rentParallelGatewaySenderEventProcessor.java |   352 +
 .../ConcurrentParallelGatewaySenderQueue.java   |   214 +
 .../ParallelGatewaySenderEventProcessor.java    |   163 +
 .../parallel/ParallelGatewaySenderQueue.java    |  1800 +++
 .../ParallelQueueBatchRemovalMessage.java       |   270 +
 .../parallel/ParallelQueueRemovalMessage.java   |   273 +
 .../cache/wan/parallel/RREventIDResolver.java   |    45 +
 .../cache/wan/serial/BatchDestroyOperation.java |   228 +
 ...urrentSerialGatewaySenderEventProcessor.java |   354 +
 .../SerialGatewaySenderEventProcessor.java      |   819 ++
 .../wan/serial/SerialGatewaySenderQueue.java    |  1226 ++
 .../serial/SerialSecondaryGatewayListener.java  |    90 +
 .../internal/cache/wan/spi/WANFactory.java      |    21 +
 .../cache/xmlcache/AbstractXmlParser.java       |    86 +
 .../cache/xmlcache/AsyncEventQueueCreation.java |   205 +
 .../cache/xmlcache/BindingCreation.java         |    52 +
 .../cache/xmlcache/BridgeServerCreation.java    |   213 +
 .../internal/cache/xmlcache/CacheCreation.java  |  1621 +++
 .../CacheTransactionManagerCreation.java        |   128 +
 .../internal/cache/xmlcache/CacheXml.java       |   995 ++
 .../cache/xmlcache/CacheXmlGenerator.java       |  2820 ++++
 .../internal/cache/xmlcache/CacheXmlParser.java |  3574 +++++
 .../xmlcache/CacheXmlPropertyResolver.java      |   138 +
 .../CacheXmlPropertyResolverHelper.java         |   143 +
 .../cache/xmlcache/CacheXmlVersion.java         |   118 +
 .../cache/xmlcache/ClientCacheCreation.java     |   302 +
 .../cache/xmlcache/ClientHaQueueCreation.java   |    91 +
 .../internal/cache/xmlcache/Declarable2.java    |    30 +
 .../cache/xmlcache/DefaultEntityResolver2.java  |    66 +
 .../xmlcache/DiskStoreAttributesCreation.java   |   305 +
 .../cache/xmlcache/FunctionServiceCreation.java |    44 +
 .../cache/xmlcache/GatewayReceiverCreation.java |   181 +
 .../cache/xmlcache/IndexCreationData.java       |   135 +
 .../ParallelAsyncEventQueueCreation.java        |   110 +
 .../xmlcache/ParallelGatewaySenderCreation.java |   110 +
 .../cache/xmlcache/PivotalEntityResolver.java   |    49 +
 .../cache/xmlcache/PropertyResolver.java        |    48 +
 .../xmlcache/RegionAttributesCreation.java      |  1601 +++
 .../internal/cache/xmlcache/RegionCreation.java |   960 ++
 .../cache/xmlcache/ResourceManagerCreation.java |   127 +
 .../xmlcache/SerialAsyncEventQueueCreation.java |   106 +
 .../xmlcache/SerialGatewaySenderCreation.java   |   106 +
 .../cache/xmlcache/SerializerCreation.java      |    99 +
 .../internal/cache/xmlcache/XmlGenerator.java   |    53 +
 .../cache/xmlcache/XmlGeneratorUtils.java       |   142 +
 .../internal/cache/xmlcache/XmlParser.java      |    49 +
 .../internal/cache/xmlcache/package.html        |    16 +
 .../gemfire/internal/concurrent/Atomics.java    |    58 +
 .../concurrent/CompactConcurrentHashSet2.java   |  2498 ++++
 .../internal/concurrent/ConcurrentHashSet.java  |    80 +
 .../gemfire/internal/concurrent/LI.java         |    86 +
 .../internal/datasource/AbstractDataSource.java |   232 +
 .../internal/datasource/AbstractPoolCache.java  |   546 +
 .../ClientConnectionFactoryWrapper.java         |    45 +
 .../internal/datasource/ConfigProperty.java     |    56 +
 .../ConfiguredDataSourceProperties.java         |   279 +
 .../ConnectionEventListenerAdaptor.java         |    67 +
 .../datasource/ConnectionPoolCache.java         |    43 +
 .../datasource/ConnectionPoolCacheImpl.java     |    95 +
 .../internal/datasource/ConnectionProvider.java |    41 +
 .../datasource/ConnectionProviderException.java |    58 +
 .../datasource/DataSourceCreateException.java   |    53 +
 .../internal/datasource/DataSourceFactory.java  |   365 +
 .../datasource/DataSourceResources.java         |    40 +
 .../FacetsJCAConnectionManagerImpl.java         |   260 +
 .../datasource/GemFireBasicDataSource.java      |   141 +
 .../datasource/GemFireConnPooledDataSource.java |   216 +
 .../GemFireConnectionPoolManager.java           |    99 +
 .../GemFireTransactionDataSource.java           |   255 +
 .../datasource/JCAConnectionManagerImpl.java    |   211 +
 .../datasource/ManagedPoolCacheImpl.java        |    95 +
 .../internal/datasource/PoolException.java      |    46 +
 .../internal/datasource/TranxPoolCacheImpl.java |    93 +
 .../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
 .../i18n/AbstractStringIdResourceBundle.java    |   148 +
 .../gemfire/internal/i18n/LocalizedStrings.java |  2065 +++
 .../internal/i18n/ParentLocalizedStrings.java   |  2416 ++++
 .../internal/io/CompositeOutputStream.java      |   167 +
 .../internal/io/CompositePrintStream.java       |    70 +
 .../gemfire/internal/io/TeeOutputStream.java    |    84 +
 .../gemfire/internal/io/TeePrintStream.java     |    36 +
 .../gemfire/internal/jndi/ContextImpl.java      |   770 +
 .../jndi/InitialContextFactoryImpl.java         |    93 +
 .../gemfire/internal/jndi/JNDIInvoker.java      |   392 +
 .../gemfire/internal/jndi/NameParserImpl.java   |    46 +
 .../gemfire/internal/jta/GlobalTransaction.java |   720 +
 .../gemfire/internal/jta/TransactionImpl.java   |   261 +
 .../internal/jta/TransactionManagerImpl.java    |   858 ++
 .../gemfire/internal/jta/TransactionUtils.java  |    50 +
 .../internal/jta/UserTransactionImpl.java       |   136 +
 .../gemstone/gemfire/internal/jta/XidImpl.java  |    85 +
 .../gemfire/internal/lang/ClassUtils.java       |   123 +
 .../gemstone/gemfire/internal/lang/Filter.java  |    20 +
 .../gemfire/internal/lang/InOutParameter.java   |    94 +
 .../gemfire/internal/lang/Initable.java         |    28 +
 .../gemfire/internal/lang/Initializer.java      |    37 +
 .../internal/lang/MutableIdentifiable.java      |    31 +
 .../gemfire/internal/lang/ObjectUtils.java      |   184 +
 .../gemfire/internal/lang/Orderable.java        |    33 +
 .../gemstone/gemfire/internal/lang/Ordered.java |    36 +
 .../gemfire/internal/lang/StringUtils.java      |   346 +
 .../gemfire/internal/lang/SystemUtils.java      |   167 +
 .../gemfire/internal/lang/ThreadUtils.java      |   123 +
 .../gemfire/internal/logging/DateFormatter.java |    78 +
 .../internal/logging/DebugLogWriter.java        |   117 +
 .../internal/logging/GemFireFormatter.java      |    95 +
 .../internal/logging/GemFireHandler.java        |    72 +
 .../gemfire/internal/logging/GemFireLevel.java  |    69 +
 .../internal/logging/InternalLogWriter.java     |   119 +
 .../internal/logging/LocalLogWriter.java        |    86 +
 .../gemfire/internal/logging/LogConfig.java     |    37 +
 .../gemfire/internal/logging/LogFileParser.java |   496 +
 .../gemfire/internal/logging/LogService.java    |   326 +
 .../internal/logging/LogWriterFactory.java      |    93 +
 .../gemfire/internal/logging/LogWriterImpl.java |  1042 ++
 .../internal/logging/LoggingThreadGroup.java    |   331 +
 .../internal/logging/ManagerLogWriter.java      |   683 +
 .../gemfire/internal/logging/MergeLogFiles.java |  1005 ++
 .../gemfire/internal/logging/PureLogWriter.java |   274 +
 .../logging/SecurityLocalLogWriter.java         |    78 +
 .../internal/logging/SecurityLogConfig.java     |    50 +
 .../internal/logging/SecurityLogWriter.java     |    71 +
 .../logging/SecurityManagerLogWriter.java       |    64 +
 .../gemfire/internal/logging/SortLogFile.java   |   140 +
 .../internal/logging/StandardErrorPrinter.java  |    27 +
 .../internal/logging/StandardOutputPrinter.java |    27 +
 .../internal/logging/log4j/AlertAppender.java   |   324 +
 .../internal/logging/log4j/AppenderContext.java |    64 +
 .../internal/logging/log4j/Configurator.java    |   113 +
 .../internal/logging/log4j/FastLogger.java      |    85 +
 .../internal/logging/log4j/GemFireLogger.java   |   907 ++
 .../logging/log4j/LocalizedMessage.java         |    64 +
 .../internal/logging/log4j/LogMarker.java       |    83 +
 .../logging/log4j/LogWriterAppender.java        |   196 +
 .../logging/log4j/LogWriterAppenders.java       |   283 +
 .../internal/logging/log4j/LogWriterLogger.java |  2026 +++
 .../logging/log4j/ThreadIdPatternConverter.java |    45 +
 .../gemfire/internal/memcached/Command.java     |   492 +
 .../internal/memcached/CommandProcessor.java    |    33 +
 .../internal/memcached/ConnectionHandler.java   |    84 +
 .../gemfire/internal/memcached/KeyWrapper.java  |    86 +
 .../gemfire/internal/memcached/Reply.java       |   112 +
 .../internal/memcached/RequestReader.java       |   282 +
 .../internal/memcached/ResponseStatus.java      |    55 +
 .../internal/memcached/ValueWrapper.java        |   137 +
 .../memcached/commands/AbstractCommand.java     |   214 +
 .../internal/memcached/commands/AddCommand.java |    81 +
 .../memcached/commands/AddQCommand.java         |    14 +
 .../memcached/commands/AppendCommand.java       |    83 +
 .../memcached/commands/AppendQCommand.java      |    13 +
 .../internal/memcached/commands/CASCommand.java |    67 +
 .../memcached/commands/ClientError.java         |    30 +
 .../memcached/commands/DecrementCommand.java    |   164 +
 .../memcached/commands/DecrementQCommand.java   |    13 +
 .../memcached/commands/DeleteCommand.java       |    92 +
 .../memcached/commands/DeleteQCommand.java      |    13 +
 .../memcached/commands/FlushAllCommand.java     |   110 +
 .../memcached/commands/FlushAllQCommand.java    |    13 +
 .../internal/memcached/commands/GATCommand.java |    13 +
 .../memcached/commands/GATQCommand.java         |    13 +
 .../internal/memcached/commands/GetCommand.java |   220 +
 .../memcached/commands/GetKCommand.java         |    14 +
 .../memcached/commands/GetKQCommand.java        |    14 +
 .../memcached/commands/GetQCommand.java         |    29 +
 .../memcached/commands/IncrementCommand.java    |   161 +
 .../memcached/commands/IncrementQCommand.java   |    13 +
 .../memcached/commands/NoOpCommand.java         |    31 +
 .../memcached/commands/NotSupportedCommand.java |    32 +
 .../memcached/commands/PrependCommand.java      |    79 +
 .../memcached/commands/PrependQCommand.java     |    13 +
 .../memcached/commands/QuitCommand.java         |    47 +
 .../memcached/commands/QuitQCommand.java        |    13 +
 .../memcached/commands/ReplaceCommand.java      |    93 +
 .../memcached/commands/ReplaceQCommand.java     |    13 +
 .../internal/memcached/commands/SetCommand.java |    81 +
 .../memcached/commands/SetQCommand.java         |    14 +
 .../memcached/commands/StatsCommand.java        |    41 +
 .../memcached/commands/StorageCommand.java      |   209 +
 .../memcached/commands/TouchCommand.java        |    95 +
 .../memcached/commands/VerbosityCommand.java    |    39 +
 .../memcached/commands/VersionCommand.java      |    40 +
 .../modules/util/RegionConfiguration.java       |   284 +
 .../gemfire/internal/net/SocketUtils.java       |    68 +
 .../com/gemstone/gemfire/internal/package.html  |    29 +
 .../internal/process/AttachProcessUtils.java    |    31 +
 ...usterConfigurationNotAvailableException.java |    15 +
 .../process/ConnectionFailedException.java      |    41 +
 .../internal/process/ControlFileWatchdog.java   |   142 +
 .../process/ControlNotificationHandler.java     |    16 +
 .../internal/process/ControllableProcess.java   |   116 +
 .../process/FileAlreadyExistsException.java     |    43 +
 .../process/FileControllerParameters.java       |    17 +
 .../internal/process/FileProcessController.java |   125 +
 .../process/LocalProcessController.java         |   469 +
 .../internal/process/LocalProcessLauncher.java  |   119 +
 .../process/MBeanControllerParameters.java      |    21 +
 .../process/MBeanInvocationFailedException.java |    41 +
 .../process/MBeanProcessController.java         |   375 +
 .../internal/process/NativeProcessUtils.java    |    27 +
 .../process/PidUnavailableException.java        |    42 +
 .../internal/process/ProcessController.java     |    45 +
 .../process/ProcessControllerFactory.java       |   134 +
 .../process/ProcessControllerParameters.java    |    14 +
 .../process/ProcessLauncherContext.java         |   167 +
 .../internal/process/ProcessStreamReader.java   |   175 +
 .../ProcessTerminatedAbnormallyException.java   |    82 +
 .../gemfire/internal/process/ProcessType.java   |    53 +
 .../gemfire/internal/process/ProcessUtils.java  |   145 +
 .../gemfire/internal/process/StartupStatus.java |    47 +
 .../internal/process/StartupStatusListener.java |    14 +
 .../UnableToControlProcessException.java        |    35 +
 .../AbstractSignalNotificationHandler.java      |   171 +
 .../gemfire/internal/process/signal/Signal.java |   120 +
 .../internal/process/signal/SignalEvent.java    |    45 +
 .../internal/process/signal/SignalListener.java |    26 +
 .../internal/process/signal/SignalType.java     |    36 +
 .../internal/security/AuthorizeRequest.java     |   747 +
 .../internal/security/AuthorizeRequestPP.java   |   240 +
 .../security/FilterPostAuthorization.java       |   226 +
 .../security/FilterPreAuthorization.java        |   151 +
 .../internal/security/ObjectWithAuthz.java      |    60 +
 .../gemfire/internal/security/package.html      |     9 +
 .../internal/sequencelog/EntryLogger.java       |   196 +
 .../gemfire/internal/sequencelog/GraphType.java |    51 +
 .../internal/sequencelog/MembershipLogger.java  |    38 +
 .../internal/sequencelog/MessageLogger.java     |    31 +
 .../internal/sequencelog/RegionLogger.java      |    79 +
 .../internal/sequencelog/SequenceLogger.java    |    54 +
 .../sequencelog/SequenceLoggerImpl.java         |   140 +
 .../internal/sequencelog/Transition.java        |    79 +
 .../gemfire/internal/sequencelog/io/Filter.java |    23 +
 .../sequencelog/io/GemfireLogConverter.java     |   242 +
 .../internal/sequencelog/io/GraphReader.java    |    81 +
 .../sequencelog/io/InputStreamReader.java       |    94 +
 .../sequencelog/io/OutputStreamAppender.java    |   108 +
 .../internal/sequencelog/model/Edge.java        |   102 +
 .../internal/sequencelog/model/Graph.java       |    96 +
 .../internal/sequencelog/model/GraphID.java     |    86 +
 .../sequencelog/model/GraphReaderCallback.java  |    28 +
 .../internal/sequencelog/model/GraphSet.java    |   156 +
 .../internal/sequencelog/model/Vertex.java      |   115 +
 .../visualization/text/TextDisplay.java         |    76 +
 .../gemfire/internal/shared/NativeCalls.java    |   626 +
 .../internal/shared/NativeCallsJNAImpl.java     |  1172 ++
 .../internal/shared/NativeErrorException.java   |    34 +
 .../gemfire/internal/shared/OSType.java         |    84 +
 .../internal/shared/StringPrintWriter.java      |   227 +
 .../internal/shared/TCPSocketOptions.java       |    39 +
 .../internal/size/CachingSingleObjectSizer.java |    42 +
 .../size/InstrumentationSingleObjectSizer.java  |    33 +
 .../gemfire/internal/size/ObjectGraphSizer.java |   250 +
 .../gemfire/internal/size/ObjectTraverser.java  |   203 +
 .../internal/size/ReflectionObjectSizer.java    |    85 +
 .../size/ReflectionSingleObjectSizer.java       |   174 +
 .../internal/size/SingleObjectSizer.java        |    12 +
 .../internal/size/SizeClassOnceObjectSizer.java |    87 +
 .../gemfire/internal/size/SizeOfUtil0.java      |    24 +
 .../internal/size/WellKnownClassSizer.java      |    51 +
 .../internal/statistics/CounterMonitor.java     |    49 +
 .../internal/statistics/GaugeMonitor.java       |    44 +
 .../statistics/IgnoreResourceException.java     |    56 +
 .../MapBasedStatisticsNotification.java         |    79 +
 .../internal/statistics/ResourceInstance.java   |   111 +
 .../internal/statistics/ResourceType.java       |    61 +
 .../internal/statistics/SampleCollector.java    |   779 ++
 .../internal/statistics/SampleHandler.java      |    63 +
 .../internal/statistics/SimpleStatisticId.java  |    58 +
 .../statistics/StatArchiveDescriptor.java       |   125 +
 .../internal/statistics/StatArchiveHandler.java |   667 +
 .../statistics/StatArchiveHandlerConfig.java    |    58 +
 .../internal/statistics/StatMonitorHandler.java |   327 +
 .../internal/statistics/StatisticId.java        |    30 +
 .../statistics/StatisticNotFoundException.java  |    53 +
 .../internal/statistics/StatisticsListener.java |    18 +
 .../internal/statistics/StatisticsMonitor.java  |   157 +
 .../statistics/StatisticsNotification.java      |    57 +
 .../internal/statistics/StatisticsSampler.java  |    48 +
 .../internal/statistics/ValueMonitor.java       |   124 +
 .../gemfire/internal/statistics/package.html    |    15 +
 .../stats50/Atomic50StatisticsImpl.java         |   488 +
 .../gemfire/internal/stats50/VMStats50.java     |   694 +
 .../gemfire/internal/tcp/BaseMsgStreamer.java   |    56 +
 .../gemstone/gemfire/internal/tcp/Buffers.java  |   161 +
 .../internal/tcp/ByteBufferInputStream.java     |   347 +
 .../gemfire/internal/tcp/ConnectExceptions.java |    84 +
 .../gemfire/internal/tcp/Connection.java        |  4096 ++++++
 .../internal/tcp/ConnectionException.java       |    29 +
 .../gemfire/internal/tcp/ConnectionTable.java   |  1322 ++
 .../gemfire/internal/tcp/DirectReplySender.java |    96 +
 .../tcp/ImmutableByteBufferInputStream.java     |    73 +
 .../internal/tcp/MemberShunnedException.java    |    40 +
 .../gemfire/internal/tcp/MsgDestreamer.java     |   527 +
 .../gemfire/internal/tcp/MsgIdGenerator.java    |    45 +
 .../gemfire/internal/tcp/MsgOutputStream.java   |   418 +
 .../gemfire/internal/tcp/MsgReader.java         |   120 +
 .../gemfire/internal/tcp/MsgStreamer.java       |   951 ++
 .../gemfire/internal/tcp/MsgStreamerList.java   |   150 +
 .../gemfire/internal/tcp/NIOMsgReader.java      |   104 +
 .../gemfire/internal/tcp/OioMsgReader.java      |    34 +
 .../internal/tcp/ReenteredConnectException.java |    42 +
 .../gemfire/internal/tcp/ServerDelegate.java    |    37 +
 .../com/gemstone/gemfire/internal/tcp/Stub.java |   155 +
 .../gemfire/internal/tcp/TCPConduit.java        |  1393 ++
 .../tcp/VersionedByteBufferInputStream.java     |    70 +
 .../internal/tcp/VersionedMsgStreamer.java      |    51 +
 .../gemstone/gemfire/internal/tcp/package.html  |   122 +
 .../gfsh/aggregator/AggregateFunction.java      |    67 +
 .../tools/gfsh/aggregator/AggregateResults.java |   126 +
 .../aggregator/AggregatorPartitionFunction.java |    54 +
 .../tools/gfsh/app/CommandExecutable.java       |     8 +
 .../gemfire/internal/tools/gfsh/app/Gfsh.java   |  2027 +++
 .../internal/tools/gfsh/app/GfshVersion.java    |   455 +
 .../internal/tools/gfsh/app/Nextable.java       |     8 +
 .../tools/gfsh/app/ServerExecutable.java        |    11 +
 .../app/aggregator/AggregateFunctionTask.java   |    62 +
 .../tools/gfsh/app/aggregator/Aggregator.java   |   549 +
 .../app/aggregator/AggregatorException.java     |    50 +
 .../gfsh/app/aggregator/AggregatorPeer.java     |   254 +
 .../functions/util/LocalRegionInfoFunction.java |   235 +
 .../functions/util/RegionCreateFunction.java    |    81 +
 .../functions/util/RegionDestroyFunction.java   |    86 +
 .../tools/gfsh/app/cache/CacheBase.java         |   178 +
 .../gfsh/app/cache/InstantiatorClassLoader.java |   101 +
 .../tools/gfsh/app/cache/data/GenericMap.java   |   196 +
 .../gfsh/app/cache/data/GenericMessage.java     |   807 ++
 .../app/cache/data/InvalidTypeException.java    |    28 +
 .../tools/gfsh/app/cache/data/ListMap.java      |   197 +
 .../gfsh/app/cache/data/ListMapMessage.java     |   615 +
 .../tools/gfsh/app/cache/data/ListMessage.java  |   594 +
 .../tools/gfsh/app/cache/data/Listable.java     |    45 +
 .../tools/gfsh/app/cache/data/MapMessage.java   |   629 +
 .../tools/gfsh/app/cache/data/Mappable.java     |    50 +
 .../tools/gfsh/app/cache/index/EntryMap.java    |    80 +
 .../tools/gfsh/app/cache/index/IndexInfo.java   |    52 +
 .../tools/gfsh/app/cache/index/Indexer.java     |    13 +
 .../gfsh/app/cache/index/IndexerManager.java    |    32 +
 .../gfsh/app/cache/index/LookupService.java     |   352 +
 .../app/cache/index/LookupServiceException.java |    64 +
 .../gfsh/app/cache/index/task/ForceGCTask.java  |    32 +
 .../app/cache/index/task/IndexInfoTask.java     |   131 +
 .../app/cache/index/task/QuerySizeTask.java     |   134 +
 .../gfsh/app/cache/index/task/QueryTask.java    |   323 +
 .../tools/gfsh/app/command/CommandClient.java   |   417 +
 .../gfsh/app/command/CommandException.java      |    31 +
 .../app/command/CommandResultsListener.java     |    15 +
 .../tools/gfsh/app/command/task/EchoTask.java   |    63 +
 .../task/PartitionedRegionAttributeTask.java    |   205 +
 .../gfsh/app/command/task/QueryResults.java     |   123 +
 .../tools/gfsh/app/command/task/QueryTask.java  |   522 +
 .../task/RefreshAggregatorRegionTask.java       |    53 +
 .../gfsh/app/command/task/RegionClearTask.java  |    85 +
 .../gfsh/app/command/task/RegionCreateTask.java |   162 +
 .../app/command/task/RegionDestroyTask.java     |    97 +
 .../gfsh/app/command/task/RegionPathTask.java   |   156 +
 .../gfsh/app/command/task/RegionSizeTask.java   |    70 +
 .../gfsh/app/command/task/data/MemberInfo.java  |    79 +
 .../task/data/PartitionAttributeInfo.java       |   124 +
 .../command/task/data/RegionAttributeInfo.java  |   286 +
 .../internal/tools/gfsh/app/commands/bcp.java   |   527 +
 .../internal/tools/gfsh/app/commands/cd.java    |    79 +
 .../tools/gfsh/app/commands/classloader.java    |   323 +
 .../internal/tools/gfsh/app/commands/clear.java |   197 +
 .../tools/gfsh/app/commands/connect.java        |   124 +
 .../internal/tools/gfsh/app/commands/db.java    |   312 +
 .../internal/tools/gfsh/app/commands/debug.java |    48 +
 .../tools/gfsh/app/commands/deploy.java         |   271 +
 .../internal/tools/gfsh/app/commands/echo.java  |    59 +
 .../internal/tools/gfsh/app/commands/fetch.java |    48 +
 .../internal/tools/gfsh/app/commands/gc.java    |    93 +
 .../internal/tools/gfsh/app/commands/get.java   |   143 +
 .../internal/tools/gfsh/app/commands/help.java  |    40 +
 .../internal/tools/gfsh/app/commands/index.java |   395 +
 .../internal/tools/gfsh/app/commands/key.java   |    67 +
 .../internal/tools/gfsh/app/commands/local.java |   101 +
 .../internal/tools/gfsh/app/commands/ls.java    |   584 +
 .../internal/tools/gfsh/app/commands/mkdir.java |   253 +
 .../internal/tools/gfsh/app/commands/next.java  |    63 +
 .../tools/gfsh/app/commands/optional/look.java  |   166 +
 .../tools/gfsh/app/commands/optional/perf.java  |   150 +
 .../internal/tools/gfsh/app/commands/pr.java    |   209 +
 .../tools/gfsh/app/commands/property.java       |    85 +
 .../internal/tools/gfsh/app/commands/put.java   |   490 +
 .../internal/tools/gfsh/app/commands/pwd.java   |    37 +
 .../tools/gfsh/app/commands/rebalance.java      |   186 +
 .../tools/gfsh/app/commands/refresh.java        |    67 +
 .../internal/tools/gfsh/app/commands/rm.java    |   175 +
 .../internal/tools/gfsh/app/commands/rmdir.java |   249 +
 .../tools/gfsh/app/commands/select.java         |   139 +
 .../internal/tools/gfsh/app/commands/show.java  |   240 +
 .../internal/tools/gfsh/app/commands/size.java  |   281 +
 .../internal/tools/gfsh/app/commands/value.java |    48 +
 .../internal/tools/gfsh/app/commands/which.java |   189 +
 .../internal/tools/gfsh/app/commands/zone.java  |    49 +
 .../tools/gfsh/app/function/GfshData.java       |    86 +
 .../tools/gfsh/app/function/GfshFunction.java   |   149 +
 .../tools/gfsh/app/function/command/clear.java  |    95 +
 .../tools/gfsh/app/function/command/deploy.java |   111 +
 .../tools/gfsh/app/function/command/gc.java     |    49 +
 .../tools/gfsh/app/function/command/index.java  |   199 +
 .../tools/gfsh/app/function/command/ls.java     |    80 +
 .../tools/gfsh/app/function/command/pr.java     |   118 +
 .../gfsh/app/function/command/rebalance.java    |   129 +
 .../tools/gfsh/app/function/command/rm.java     |    43 +
 .../tools/gfsh/app/function/command/which.java  |   159 +
 .../tools/gfsh/app/misc/util/ClassFinder.java   |   209 +
 .../gfsh/app/misc/util/DataSerializerEx.java    |    98 +
 .../app/misc/util/QueueDispatcherListener.java  |    11 +
 .../app/misc/util/QueueDispatcherThread.java    |    87 +
 .../gfsh/app/misc/util/ReflectionUtil.java      |   303 +
 .../tools/gfsh/app/misc/util/StringUtil.java    |   142 +
 .../app/misc/util/SystemClassPathManager.java   |   171 +
 .../gfsh/app/pogo/InvalidKeyException.java      |    34 +
 .../internal/tools/gfsh/app/pogo/KeyType.java   |    96 +
 .../tools/gfsh/app/pogo/KeyTypeManager.java     |   199 +
 .../internal/tools/gfsh/app/pogo/MapLite.java   |  1136 ++
 .../tools/gfsh/app/pogo/MapLiteSerializer.java  |   338 +
 .../internal/tools/gfsh/app/util/DBUtil.java    |  1094 ++
 .../tools/gfsh/app/util/DBUtilException.java    |    48 +
 .../tools/gfsh/app/util/GfshResultsBag.java     |   600 +
 .../tools/gfsh/app/util/ObjectUtil.java         |   164 +
 .../tools/gfsh/app/util/OutputUtil.java         |   255 +
 .../internal/tools/gfsh/app/util/PrintUtil.java |  1683 +++
 .../tools/gfsh/app/util/SimplePrintUtil.java    |  1366 ++
 .../tools/gfsh/command/AbstractCommandTask.java |   136 +
 .../gfsh/command/CommandExecLoaderListener.java |    96 +
 .../tools/gfsh/command/CommandResults.java      |   119 +
 .../tools/gfsh/command/CommandTask.java         |    23 +
 .../internal/tools/gfsh/util/RegionUtil.java    |   829 ++
 .../internal/util/AbortableTaskService.java     |   165 +
 .../gemfire/internal/util/ArrayUtils.java       |   238 +
 .../gemfire/internal/util/BlobHelper.java       |   166 +
 .../gemfire/internal/util/Breadcrumbs.java      |   256 +
 .../gemstone/gemfire/internal/util/Bytes.java   |   250 +
 .../gemfire/internal/util/Callable.java         |    39 +
 .../gemfire/internal/util/CollectionUtils.java  |   273 +
 .../gemfire/internal/util/DebuggerSupport.java  |    55 +
 .../gemfire/internal/util/DelayedAction.java    |    56 +
 .../com/gemstone/gemfire/internal/util/Hex.java |    48 +
 .../gemstone/gemfire/internal/util/IOUtils.java |   338 +
 .../internal/util/JavaCommandBuilder.java       |   114 +
 .../gemfire/internal/util/LogFileUtils.java     |   169 +
 .../internal/util/ObjectIntProcedure.java       |    14 +
 .../gemfire/internal/util/ObjectProcedure.java  |    14 +
 .../gemfire/internal/util/PasswordUtil.java     |   124 +
 .../gemfire/internal/util/PluckStacks.java      |   492 +
 .../gemfire/internal/util/PrimeFinder.java      |   159 +
 .../gemfire/internal/util/StopWatch.java        |    71 +
 .../internal/util/SunAPINotFoundException.java  |    38 +
 .../gemfire/internal/util/TransformUtils.java   |   123 +
 .../gemfire/internal/util/Transformer.java      |    24 +
 .../gemfire/internal/util/Versionable.java      |    28 +
 .../internal/util/VersionedArrayList.java       |   338 +
 .../util/concurrent/CopyOnWriteHashMap.java     |   160 +
 .../util/concurrent/CopyOnWriteWeakHashMap.java |    77 +
 .../CustomEntryConcurrentHashMap.java           |  2588 ++++
 .../internal/util/concurrent/FutureResult.java  |    84 +
 .../util/concurrent/ReentrantSemaphore.java     |   152 +
 .../util/concurrent/SemaphoreReadWriteLock.java |   208 +
 .../util/concurrent/StoppableCondition.java     |   104 +
 .../concurrent/StoppableCountDownLatch.java     |    89 +
 .../concurrent/StoppableCountDownOrUpLatch.java |   202 +
 .../concurrent/StoppableNonReentrantLock.java   |    83 +
 .../util/concurrent/StoppableReadWriteLock.java |    19 +
 .../util/concurrent/StoppableReentrantLock.java |   122 +
 .../StoppableReentrantReadWriteLock.java        |   235 +
 .../internal/util/doc-files/call-stack.fig      |    34 +
 .../internal/util/doc-files/class-loaders.fig   |    49 +
 .../lang/AttachAPINotFoundException.java        |    59 +
 .../com/gemstone/gemfire/lang/Identifiable.java |    32 +
 .../management/AlreadyRunningException.java     |    37 +
 .../management/AsyncEventQueueMXBean.java       |   110 +
 .../gemfire/management/CacheServerMXBean.java   |   389 +
 .../gemfire/management/ClientHealthStatus.java  |   338 +
 .../gemfire/management/ClientQueueDetail.java   |   156 +
 .../DependenciesNotFoundException.java          |    50 +
 .../gemfire/management/DiskBackupResult.java    |    58 +
 .../gemfire/management/DiskBackupStatus.java    |    65 +
 .../gemfire/management/DiskMetrics.java         |   116 +
 .../gemfire/management/DiskStoreMXBean.java     |   204 +
 .../DistributedLockServiceMXBean.java           |    58 +
 .../management/DistributedRegionMXBean.java     |   298 +
 .../management/DistributedSystemMXBean.java     |   680 +
 .../management/EvictionAttributesData.java      |    96 +
 .../FixedPartitionAttributesData.java           |    78 +
 .../management/GatewayReceiverMXBean.java       |   203 +
 .../gemfire/management/GatewaySenderMXBean.java |   241 +
 .../gemfire/management/GemFireProperties.java   |  1564 +++
 .../gemfire/management/JMXNotificationType.java |   206 +
 .../management/JMXNotificationUserData.java     |    44 +
 .../gemstone/gemfire/management/JVMMetrics.java |   136 +
 .../gemfire/management/LocatorMXBean.java       |    68 +
 .../gemfire/management/LockServiceMXBean.java   |    77 +
 .../gemfire/management/ManagementException.java |    80 +
 .../gemfire/management/ManagementService.java   |   418 +
 .../gemfire/management/ManagerMXBean.java       |    75 +
 .../gemfire/management/MemberMXBean.java        |   810 ++
 .../management/MembershipAttributesData.java    |    88 +
 .../gemfire/management/NetworkMetrics.java      |    51 +
 .../gemstone/gemfire/management/OSMetrics.java  |   215 +
 .../management/PartitionAttributesData.java     |   131 +
 .../management/PersistentMemberDetails.java     |    55 +
 .../management/RegionAttributesData.java        |   408 +
 .../gemfire/management/RegionMXBean.java        |   340 +
 .../gemfire/management/ServerLoadData.java      |    78 +
 .../gemfire/management/cli/CliMetaData.java     |    96 +
 .../cli/CommandProcessingException.java         |   117 +
 .../gemfire/management/cli/CommandService.java  |   197 +
 .../management/cli/CommandServiceException.java |    60 +
 .../management/cli/CommandStatement.java        |    50 +
 .../gemfire/management/cli/ConverterHint.java   |    44 +
 .../gemstone/gemfire/management/cli/Result.java |   121 +
 .../gemfire/management/cli/package.html         |     7 +
 .../management/internal/AlertDetails.java       |   153 +
 .../management/internal/ArrayConverter.java     |    74 +
 .../internal/BaseManagementService.java         |   176 +
 .../internal/CollectionConverter.java           |   102 +
 .../management/internal/CompositeConverter.java |   138 +
 .../management/internal/EnumConverter.java      |    42 +
 .../management/internal/FederatingManager.java  |   618 +
 .../internal/FederationComponent.java           |   298 +
 .../management/internal/FilterChain.java        |    51 +
 .../management/internal/FilterParam.java        |    63 +
 .../management/internal/IdentityConverter.java  |    39 +
 .../management/internal/JettyHelper.java        |   218 +
 .../management/internal/JmxManagerAdvisee.java  |   144 +
 .../management/internal/JmxManagerAdvisor.java  |   376 +
 .../management/internal/JmxManagerLocator.java  |   232 +
 .../internal/JmxManagerLocatorRequest.java      |   121 +
 .../internal/JmxManagerLocatorResponse.java     |    96 +
 .../management/internal/LocalFilterChain.java   |    55 +
 .../management/internal/LocalManager.java       |   458 +
 .../management/internal/MBeanJMXAdapter.java    |   613 +
 .../management/internal/MBeanProxyFactory.java  |   349 +
 .../internal/MBeanProxyInfoRepository.java      |   163 +
 .../internal/MBeanProxyInvocationHandler.java   |   537 +
 .../internal/MXBeanProxyInvocationHandler.java  |   252 +
 .../management/internal/ManagementAgent.java    |   573 +
 .../internal/ManagementCacheListener.java       |   114 +
 .../internal/ManagementConstants.java           |   179 +
 .../management/internal/ManagementFunction.java |   165 +
 .../internal/ManagementMembershipListener.java  |    86 +
 .../internal/ManagementResourceRepo.java        |   254 +
 .../management/internal/ManagementStrings.java  |   146 +
 .../gemfire/management/internal/Manager.java    |    81 +
 .../internal/ManagerStartupMessage.java         |    67 +
 .../management/internal/MemberMessenger.java    |    97 +
 .../internal/MonitoringRegionCacheListener.java |   108 +
 .../internal/NotificationBroadCasterProxy.java  |    30 +
 .../internal/NotificationCacheListener.java     |   112 +
 .../management/internal/NotificationHub.java    |   198 +
 .../internal/NotificationHubClient.java         |    69 +
 .../management/internal/NotificationKey.java    |    58 +
 .../gemfire/management/internal/OpenMethod.java |   182 +
 .../management/internal/OpenTypeConverter.java  |  1010 ++
 .../management/internal/OpenTypeUtil.java       |   109 +
 .../gemfire/management/internal/ProxyInfo.java  |    75 +
 .../management/internal/ProxyInterface.java     |    32 +
 .../management/internal/ProxyListener.java      |   129 +
 .../management/internal/RemoteFilterChain.java  |    87 +
 .../gemfire/management/internal/RestAgent.java  |   239 +
 .../gemfire/management/internal/SSLUtil.java    |    66 +
 .../management/internal/StringBasedFilter.java  |   114 +
 .../internal/SystemManagementService.java       |   829 ++
 .../management/internal/TableConverter.java     |    94 +
 .../internal/beans/AggregateHandler.java        |    84 +
 .../internal/beans/AsyncEventQueueMBean.java    |   105 +
 .../beans/AsyncEventQueueMBeanBridge.java       |   113 +
 .../internal/beans/BeanUtilFuncs.java           |   385 +
 .../internal/beans/CacheServerBridge.java       |   762 +
 .../internal/beans/CacheServerMBean.java        |   309 +
 .../internal/beans/DiskRegionBridge.java        |   130 +
 .../internal/beans/DiskStoreMBean.java          |   174 +
 .../internal/beans/DiskStoreMBeanBridge.java    |   280 +
 .../beans/DistributedLockServiceBridge.java     |   219 +
 .../beans/DistributedLockServiceMBean.java      |    60 +
 .../internal/beans/DistributedRegionBridge.java |   671 +
 .../internal/beans/DistributedRegionMBean.java  |   318 +
 .../internal/beans/DistributedSystemBridge.java |  1853 +++
 .../internal/beans/DistributedSystemMBean.java  |   448 +
 .../internal/beans/GatewayReceiverMBean.java    |   212 +
 .../beans/GatewayReceiverMBeanBridge.java       |   216 +
 .../internal/beans/GatewaySenderMBean.java      |   218 +
 .../beans/GatewaySenderMBeanBridge.java         |   291 +
 .../management/internal/beans/LocatorMBean.java |    71 +
 .../internal/beans/LocatorMBeanBridge.java      |   149 +
 .../internal/beans/LockServiceMBean.java        |    86 +
 .../internal/beans/LockServiceMBeanBridge.java  |   121 +
 .../internal/beans/MBeanAggregator.java         |   427 +
 .../internal/beans/ManagementAdapter.java       |  1122 ++
 .../internal/beans/ManagementListener.java      |   207 +
 .../management/internal/beans/ManagerMBean.java |    63 +
 .../internal/beans/ManagerMBeanBridge.java      |    72 +
 .../management/internal/beans/MemberMBean.java  |   645 +
 .../internal/beans/MemberMBeanBridge.java       |  1878 +++
 .../internal/beans/MetricsCalculator.java       |   130 +
 .../internal/beans/PartitionedRegionBridge.java |   293 +
 .../internal/beans/QueryDataFunction.java       |   605 +
 .../management/internal/beans/RegionMBean.java  |   310 +
 .../internal/beans/RegionMBeanBridge.java       |   588 +
 .../beans/RegionMBeanCompositeDataFactory.java  |   220 +
 .../internal/beans/SequenceNumber.java          |    42 +
 .../management/internal/beans/ServerBridge.java |   175 +
 .../stats/AggregateRegionStatsMonitor.java      |   290 +
 .../internal/beans/stats/GCStatsMonitor.java    |    86 +
 .../GatewayReceiverClusterStatsMonitor.java     |    72 +
 .../stats/GatewaySenderClusterStatsMonitor.java |    85 +
 .../stats/IntegerStatsDeltaAggregator.java      |    84 +
 .../beans/stats/LongStatsDeltaAggregator.java   |    83 +
 .../internal/beans/stats/MBeanStatsMonitor.java |   112 +
 .../beans/stats/MemberClusterStatsMonitor.java  |   233 +
 .../beans/stats/MemberLevelDiskMonitor.java     |   303 +
 .../beans/stats/RegionClusterStatsMonitor.java  |   460 +
 .../beans/stats/ServerClusterStatsMonitor.java  |    78 +
 .../internal/beans/stats/StatType.java          |    21 +
 .../internal/beans/stats/StatsAggregator.java   |   297 +
 .../beans/stats/StatsAverageLatency.java        |    47 +
 .../internal/beans/stats/StatsKey.java          |   348 +
 .../internal/beans/stats/StatsLatency.java      |    62 +
 .../internal/beans/stats/StatsRate.java         |    84 +
 .../internal/beans/stats/VMStatsMonitor.java    |   121 +
 .../cli/AbstractCliAroundInterceptor.java       |   125 +
 .../internal/cli/CliAroundInterceptor.java      |    28 +
 .../management/internal/cli/CliUtil.java        |   750 +
 .../management/internal/cli/CommandManager.java |   624 +
 .../management/internal/cli/CommandRequest.java |   125 +
 .../internal/cli/CommandResponse.java           |   342 +
 .../internal/cli/CommandResponseBuilder.java    |    80 +
 .../internal/cli/CommandResponseWriter.java     |    58 +
 .../internal/cli/GfshParseResult.java           |    94 +
 .../management/internal/cli/GfshParser.java     |  1513 ++
 .../management/internal/cli/Launcher.java       |   303 +
 .../management/internal/cli/LogWrapper.java     |   432 +
 .../internal/cli/MultipleValueAdapter.java      |    30 +
 .../internal/cli/MultipleValueConverter.java    |    51 +
 .../internal/cli/annotation/CliArgument.java    |    80 +
 .../cli/commands/AbstractCommandsSupport.java   |   189 +
 .../internal/cli/commands/ClientCommands.java   |   320 +
 .../internal/cli/commands/ConfigCommands.java   |   476 +
 .../CreateAlterDestroyRegionCommands.java       |  1174 ++
 .../internal/cli/commands/DataCommands.java     |  1391 ++
 .../internal/cli/commands/DeployCommands.java   |   337 +
 .../cli/commands/DiskStoreCommands.java         |  1402 ++
 .../cli/commands/DurableClientCommands.java     |   422 +
 ...ExportImportSharedConfigurationCommands.java |   283 +
 .../internal/cli/commands/FunctionCommands.java |   634 +
 .../internal/cli/commands/GfshHelpCommands.java |    98 +
 .../internal/cli/commands/IndexCommands.java    |   666 +
 .../cli/commands/LauncherLifecycleCommands.java |  2701 ++++
 .../internal/cli/commands/MemberCommands.java   |   190 +
 .../cli/commands/MiscellaneousCommands.java     |  2089 +++
 .../internal/cli/commands/PDXCommands.java      |   270 +
 .../internal/cli/commands/QueueCommands.java    |   273 +
 .../internal/cli/commands/RegionCommands.java   |   485 +
 .../internal/cli/commands/ShellCommands.java    |  1063 ++
 .../internal/cli/commands/StatusCommands.java   |    83 +
 .../internal/cli/commands/WanCommands.java      |  1272 ++
 .../cli/commands/dto/RegionAttributesInfo.java  |   155 +
 .../cli/commands/dto/RegionDetails.java         |   222 +
 .../cli/commands/dto/RegionMemberDetails.java   |   190 +
 .../cli/converters/BooleanConverter.java        |    46 +
 .../ClusterMemberIdNameConverter.java           |    72 +
 .../converters/ConnectionEndpointConverter.java |   136 +
 .../internal/cli/converters/DirConverter.java   |   166 +
 .../cli/converters/DirPathConverter.java        |   135 +
 .../cli/converters/DiskStoreNameConverter.java  |    85 +
 .../internal/cli/converters/EnumConverter.java  |    59 +
 .../cli/converters/FilePathConverter.java       |   128 +
 .../cli/converters/FilePathStringConverter.java |   124 +
 .../converters/GatewayReceiverIdsConverter.java |    64 +
 .../converters/GatewaySenderIdConverter.java    |    73 +
 .../internal/cli/converters/HelpConverter.java  |    65 +
 .../cli/converters/HintTopicConverter.java      |    66 +
 .../cli/converters/IndexTypeConverter.java      |    48 +
 .../LocatorDiscoveryConfigConverter.java        |    72 +
 .../cli/converters/LocatorIdNameConverter.java  |    71 +
 .../cli/converters/LogLevelConverter.java       |    56 +
 .../cli/converters/MemberGroupConverter.java    |    75 +
 .../cli/converters/MemberIdNameConverter.java   |    74 +
 .../cli/converters/RegionPathConverter.java     |    92 +
 .../cli/converters/StringArrayConverter.java    |    51 +
 .../cli/converters/StringListConverter.java     |    52 +
 .../cli/domain/AsyncEventQueueDetails.java      |    68 +
 .../internal/cli/domain/CacheServerInfo.java    |    63 +
 .../cli/domain/ConnectToLocatorResult.java      |    48 +
 .../internal/cli/domain/DataCommandRequest.java |   205 +
 .../internal/cli/domain/DataCommandResult.java  |   895 ++
 .../internal/cli/domain/DiskStoreDetails.java   |   682 +
 .../cli/domain/DurableCqNamesResult.java        |    55 +
 .../cli/domain/EvictionAttributesInfo.java      |    91 +
 .../domain/FixedPartitionAttributesInfo.java    |    61 +
 .../internal/cli/domain/IndexDetails.java       |   322 +
 .../internal/cli/domain/IndexInfo.java          |    94 +
 .../cli/domain/MemberConfigurationInfo.java     |   109 +
 .../internal/cli/domain/MemberInformation.java  |   187 +
 .../internal/cli/domain/MemberResult.java       |   105 +
 .../cli/domain/PartitionAttributesInfo.java     |   167 +
 .../cli/domain/RegionAttributesInfo.java        |   455 +
 .../internal/cli/domain/RegionDescription.java  |   238 +
 .../cli/domain/RegionDescriptionPerMember.java  |   128 +
 .../internal/cli/domain/RegionInformation.java  |   149 +
 .../cli/domain/StackTracesPerMember.java        |    30 +
 .../cli/domain/SubscriptionQueueSizeResult.java |    42 +
 .../cli/exceptions/CliCommandException.java     |    57 +
 .../exceptions/CliCommandInvalidException.java  |    25 +
 .../CliCommandMultiModeOptionException.java     |    32 +
 .../CliCommandNotAvailableException.java        |    25 +
 .../exceptions/CliCommandOptionException.java   |    45 +
 ...CommandOptionHasMultipleValuesException.java |    25 +
 .../CliCommandOptionInvalidException.java       |    26 +
 .../CliCommandOptionMissingException.java       |    27 +
 .../CliCommandOptionNotApplicableException.java |    28 +
 ...liCommandOptionValueConversionException.java |    28 +
 .../CliCommandOptionValueException.java         |    34 +
 .../CliCommandOptionValueMissingException.java  |    28 +
 .../internal/cli/exceptions/CliException.java   |    13 +
 .../exceptions/CreateSubregionException.java    |    33 +
 .../cli/exceptions/ExceptionGenerator.java      |    38 +
 .../cli/exceptions/ExceptionHandler.java        |    98 +
 .../cli/exceptions/IndexNotFoundException.java  |    19 +
 .../functions/AlterRuntimeConfigFunction.java   |    87 +
 .../cli/functions/ChangeLogLevelFunction.java   |    88 +
 .../cli/functions/CliFunctionResult.java        |   239 +
 .../functions/CloseDurableClientFunction.java   |    68 +
 .../cli/functions/CloseDurableCqFunction.java   |    70 +
 .../cli/functions/ContunuousQueryFunction.java  |   144 +
 .../CreateAsyncEventQueueFunction.java          |   174 +
 .../functions/CreateDefinedIndexesFunction.java |    75 +
 .../cli/functions/CreateDiskStoreFunction.java  |    82 +
 .../cli/functions/CreateIndexFunction.java      |    91 +
 .../cli/functions/DataCommandFunction.java      |  1039 ++
 .../internal/cli/functions/DeployFunction.java  |   106 +
 .../functions/DescribeDiskStoreFunction.java    |   249 +
 .../cli/functions/DestroyDiskStoreFunction.java |    94 +
 .../cli/functions/DestroyIndexFunction.java     |   113 +
 .../cli/functions/ExportConfigFunction.java     |   123 +
 .../cli/functions/ExportDataFunction.java       |    65 +
 .../ExportSharedConfigurationFunction.java      |    63 +
 .../FetchRegionAttributesFunction.java          |   136 +
 .../FetchSharedConfigurationStatusFunction.java |    45 +
 .../functions/GarbageCollectionFunction.java    |    84 +
 .../GatewayReceiverCreateFunction.java          |   217 +
 .../functions/GatewayReceiverFunctionArgs.java  |    71 +
 .../functions/GatewaySenderCreateFunction.java  |   210 +
 .../functions/GatewaySenderFunctionArgs.java    |   135 +
 .../GetMemberConfigInformationFunction.java     |   204 +
 .../functions/GetMemberInformationFunction.java |   140 +
 .../functions/GetRegionDescriptionFunction.java |    54 +
 .../cli/functions/GetRegionsFunction.java       |    67 +
 .../cli/functions/GetStackTracesFunction.java   |    45 +
 .../GetSubscriptionQueueSizeFunction.java       |    92 +
 .../cli/functions/ImportDataFunction.java       |    61 +
 ...ortSharedConfigurationArtifactsFunction.java |    68 +
 .../functions/ListAsyncEventQueuesFunction.java |    99 +
 .../cli/functions/ListDeployedFunction.java     |    97 +
 .../cli/functions/ListDiskStoresFunction.java   |    75 +
 .../functions/ListDurableCqNamesFunction.java   |    91 +
 .../cli/functions/ListFunctionFunction.java     |   106 +
 .../cli/functions/ListIndexFunction.java        |    66 +
 .../LoadSharedConfigurationFunction.java        |    56 +
 .../internal/cli/functions/LogFileFunction.java |   289 +
 .../cli/functions/MemberRegionFunction.java     |    76 +
 .../cli/functions/MembersForRegionFunction.java |    88 +
 .../internal/cli/functions/NetstatFunction.java |   264 +
 .../cli/functions/RebalanceFunction.java        |   115 +
 .../cli/functions/RegionAlterFunction.java      |   336 +
 .../cli/functions/RegionCreateFunction.java     |   397 +
 .../cli/functions/RegionDestroyFunction.java    |    77 +
 .../cli/functions/RegionFunctionArgs.java       |   725 +
 .../cli/functions/ShutDownFunction.java         |    78 +
 .../cli/functions/UndeployFunction.java         |   124 +
 .../cli/functions/UnregisterFunction.java       |    67 +
 .../cli/functions/UserFunctionExecution.java    |   219 +
 .../management/internal/cli/help/CliTopic.java  |   123 +
 .../internal/cli/help/format/Block.java         |    37 +
 .../internal/cli/help/format/DataNode.java      |    43 +
 .../internal/cli/help/format/Help.java          |    39 +
 .../internal/cli/help/format/NewHelp.java       |    47 +
 .../internal/cli/help/format/Row.java           |    22 +
 .../internal/cli/help/utils/FormatOutput.java   |    19 +
 .../internal/cli/help/utils/HelpUtils.java      |   410 +
 .../internal/cli/i18n/CliStrings.java           |  2202 +++
 .../internal/cli/json/GfJsonArray.java          |   234 +
 .../internal/cli/json/GfJsonException.java      |    29 +
 .../internal/cli/json/GfJsonObject.java         |   385 +
 .../management/internal/cli/json/TypedJson.java |   812 ++
 .../internal/cli/modes/CommandModes.java        |   139 +
 .../cli/multistep/CLIMultiStepHelper.java       |   391 +
 .../internal/cli/multistep/CLIRemoteStep.java   |    19 +
 .../internal/cli/multistep/CLIStep.java         |    18 +
 .../cli/multistep/CLIStepExecption.java         |    29 +
 .../cli/multistep/MultiStepCommand.java         |    18 +
 .../internal/cli/parser/Argument.java           |    68 +
 .../internal/cli/parser/AvailabilityTarget.java |    99 +
 .../internal/cli/parser/CommandTarget.java      |   180 +
 .../internal/cli/parser/GfshMethodTarget.java   |   126 +
 .../internal/cli/parser/GfshOptionParser.java   |    32 +
 .../internal/cli/parser/MethodParameter.java    |    34 +
 .../management/internal/cli/parser/Option.java  |   215 +
 .../internal/cli/parser/OptionSet.java          |   124 +
 .../internal/cli/parser/Parameter.java          |   111 +
 .../internal/cli/parser/ParserUtils.java        |   182 +
 .../internal/cli/parser/SyntaxConstants.java    |    29 +
 .../cli/parser/jopt/JoptOptionParser.java       |   290 +
 .../preprocessor/EnclosingCharacters.java       |    27 +
 .../cli/parser/preprocessor/Preprocessor.java   |   132 +
 .../parser/preprocessor/PreprocessorUtils.java  |   329 +
 .../internal/cli/parser/preprocessor/Stack.java |    47 +
 .../cli/parser/preprocessor/TrimmedInput.java   |    39 +
 .../cli/remote/CommandExecutionContext.java     |   119 +
 .../internal/cli/remote/CommandProcessor.java   |   158 +
 .../cli/remote/CommandStatementImpl.java        |    92 +
 .../cli/remote/MemberCommandService.java        |    76 +
 .../cli/remote/RemoteExecutionStrategy.java     |   161 +
 .../internal/cli/remote/WrapperThreadLocal.java |    34 +
 .../internal/cli/result/AbstractResultData.java |   332 +
 .../cli/result/CliJsonSerializable.java         |    37 +
 .../cli/result/CliJsonSerializableFactory.java  |    39 +
 .../cli/result/CliJsonSerializableIds.java      |    26 +
 .../internal/cli/result/CommandResult.java      |   653 +
 .../cli/result/CommandResultException.java      |    30 +
 .../cli/result/CompositeResultData.java         |   353 +
 .../internal/cli/result/ErrorResultData.java    |    96 +
 .../internal/cli/result/FileResult.java         |   109 +
 .../internal/cli/result/InfoResultData.java     |    83 +
 .../internal/cli/result/ObjectResultData.java   |    80 +
 .../internal/cli/result/ResultBuilder.java      |   467 +
 .../internal/cli/result/ResultData.java         |    45 +
 .../cli/result/ResultDataException.java         |    27 +
 .../internal/cli/result/TableBuilder.java       |   460 +
 .../internal/cli/result/TableBuilderHelper.java |   167 +
 .../internal/cli/result/TabularResultData.java  |   166 +
 .../management/internal/cli/shell/Gfsh.java     |  1213 ++
 .../internal/cli/shell/GfshConfig.java          |   207 +
 .../cli/shell/GfshExecutionStrategy.java        |   286 +
 .../cli/shell/JMXConnectionException.java       |    48 +
 .../cli/shell/JMXInvocationException.java       |    34 +
 .../internal/cli/shell/JmxOperationInvoker.java |   406 +
 .../internal/cli/shell/MultiCommandHelper.java  |    54 +
 .../internal/cli/shell/OperationInvoker.java    |   127 +
 .../internal/cli/shell/jline/ANSIHandler.java   |   106 +
 .../cli/shell/jline/CygwinMinttyTerminal.java   |   176 +
 .../internal/cli/shell/jline/GfshHistory.java   |    43 +
 .../shell/jline/GfshUnsupportedTerminal.java    |    25 +
 .../cli/shell/unsafe/GfshSignalHandler.java     |    76 +
 .../internal/cli/util/CLIConsoleBufferUtil.java |    28 +
 .../internal/cli/util/CauseFinder.java          |   206 +
 .../cli/util/ClasspathScanLoadHelper.java       |   250 +
 .../internal/cli/util/CommandStringBuilder.java |    97 +
 .../internal/cli/util/CommentSkipHelper.java    |    70 +
 .../internal/cli/util/ConnectionEndpoint.java   |    64 +
 .../internal/cli/util/DiskStoreCompacter.java   |   126 +
 .../cli/util/DiskStoreNotFoundException.java    |    39 +
 .../internal/cli/util/DiskStoreUpgrader.java    |   121 +
 .../internal/cli/util/DiskStoreValidater.java   |    53 +
 .../cli/util/EvictionAttributesInfo.java        |    54 +
 .../cli/util/FixedPartitionAttributesInfo.java  |    56 +
 .../internal/cli/util/GfshConsoleReader.java    |    82 +
 .../cli/util/JConsoleNotFoundException.java     |    39 +
 .../management/internal/cli/util/JsonUtil.java  |   598 +
 .../internal/cli/util/MemberInformation.java    |   149 +
 .../cli/util/MemberNotFoundException.java       |    39 +
 .../management/internal/cli/util/MergeLogs.java |    78 +
 .../internal/cli/util/ReadWriteFile.java        |   223 +
 .../cli/util/RegionAttributesDefault.java       |    80 +
 .../cli/util/RegionAttributesNames.java         |    77 +
 .../internal/cli/util/RegionPath.java           |   120 +
 .../cli/util/VisualVmNotFoundException.java     |    40 +
 .../internal/cli/util/spring/Assert.java        |    27 +
 .../internal/cli/util/spring/ObjectUtils.java   |   291 +
 .../cli/util/spring/ReflectionUtils.java        |   123 +
 .../internal/cli/util/spring/StringUtils.java   |   220 +
 .../SharedConfigurationWriter.java              |   171 +
 .../callbacks/ConfigurationChangeListener.java  |    50 +
 .../configuration/domain/CacheElement.java      |   245 +
 .../configuration/domain/Configuration.java     |   198 +
 .../domain/ConfigurationChangeResult.java       |   117 +
 .../domain/SharedConfigurationStatus.java       |    10 +
 .../configuration/domain/XmlEntity.java         |   542 +
 .../configuration/functions/AddJarFunction.java |    58 +
 .../functions/AddXmlEntityFunction.java         |    51 +
 .../functions/DeleteJarFunction.java            |    59 +
 .../functions/DeleteXmlEntityFunction.java      |    56 +
 .../functions/GetAllJarsFunction.java           |    58 +
 .../functions/ModifyPropertiesFunction.java     |    56 +
 .../handlers/ConfigurationRequestHandler.java   |    76 +
 ...SharedConfigurationStatusRequestHandler.java |    56 +
 .../messages/ConfigurationRequest.java          |   117 +
 .../messages/ConfigurationResponse.java         |   165 +
 .../SharedConfigurationStatusRequest.java       |    35 +
 .../SharedConfigurationStatusResponse.java      |    69 +
 .../configuration/utils/DtdResolver.java        |    76 +
 .../configuration/utils/XmlConstants.java       |    47 +
 .../internal/configuration/utils/XmlUtils.java  |   676 +
 .../internal/configuration/utils/ZipUtils.java  |   113 +
 .../internal/messages/CompactRequest.java       |   166 +
 .../internal/messages/CompactResponse.java      |    62 +
 .../internal/security/AccessControl.java        |    35 +
 .../internal/security/AccessControlContext.java |    21 +
 .../internal/security/AccessControlMXBean.java  |     7 +
 .../internal/security/CLIOperationContext.java  |   122 +
 .../internal/security/JMXOperationContext.java  |   161 +
 .../internal/security/JSONAuthorization.java    |   292 +
 .../internal/security/MBeanServerWrapper.java   |   270 +
 .../security/ManagementInterceptor.java         |   255 +
 .../management/internal/security/Resource.java  |    10 +
 .../internal/security/ResourceConstants.java    |    99 +
 .../internal/security/ResourceOperation.java    |    18 +
 .../security/ResourceOperationContext.java      |   187 +
 .../unsafe/ReadOpFileAccessController.java      |    54 +
 .../controllers/AbstractCommandsController.java |   606 +
 .../AbstractMultiPartCommandsController.java    |    69 +
 .../controllers/ClientCommandsController.java   |    51 +
 .../controllers/ClusterCommandsController.java  |    42 +
 .../controllers/ConfigCommandsController.java   |   211 +
 .../web/controllers/DataCommandsController.java |   232 +
 .../controllers/DeployCommandsController.java   |   101 +
 .../DiskStoreCommandsController.java            |   168 +
 .../DurableClientCommandsController.java        |   149 +
 .../controllers/FunctionCommandsController.java |   133 +
 .../controllers/IndexCommandsController.java    |   163 +
 .../LauncherLifecycleCommandsController.java    |    46 +
 .../controllers/MemberCommandsController.java   |    69 +
 .../MiscellaneousCommandsController.java        |   262 +
 .../web/controllers/PdxCommandsController.java  |   106 +
 .../controllers/QueueCommandsController.java    |   124 +
 .../controllers/RegionCommandsController.java   |   323 +
 .../controllers/ShellCommandsController.java    |   271 +
 .../web/controllers/WanCommandsController.java  |   394 +
 .../EnvironmentVariablesHandlerInterceptor.java |    84 +
 .../support/MemberMXBeanAdapter.java            |   616 +
 .../management/internal/web/domain/Link.java    |   152 +
 .../internal/web/domain/LinkIndex.java          |   131 +
 .../web/domain/QueryParameterSource.java        |    54 +
 .../internal/web/http/ClientHttpRequest.java    |   442 +
 .../internal/web/http/HttpHeader.java           |    91 +
 .../internal/web/http/HttpMethod.java           |    27 +
 .../SerializableObjectHttpMessageConverter.java |    94 +
 .../web/http/support/SimpleHttpRequester.java   |   131 +
 .../internal/web/io/MultipartFileAdapter.java   |    59 +
 .../web/io/MultipartFileResourceAdapter.java    |    59 +
 .../web/shell/AbstractHttpOperationInvoker.java |   792 ++
 .../web/shell/HttpOperationInvoker.java         |    15 +
 .../web/shell/MBeanAccessException.java         |    36 +
 .../RestApiCallForCommandNotFoundException.java |    35 +
 .../web/shell/RestHttpOperationInvoker.java     |   415 +
 .../web/shell/SimpleHttpOperationInvoker.java   |   152 +
 .../shell/support/HttpInvocationHandler.java    |    86 +
 .../shell/support/HttpMBeanProxyFactory.java    |    32 +
 .../internal/web/util/ConvertUtils.java         |   123 +
 .../management/internal/web/util/UriUtils.java  |   248 +
 .../management/membership/ClientMembership.java |    58 +
 .../membership/ClientMembershipEvent.java       |    42 +
 .../membership/ClientMembershipListener.java    |    39 +
 .../ClientMembershipListenerAdapter.java        |    43 +
 .../management/membership/MembershipEvent.java  |    33 +
 .../membership/MembershipListener.java          |    44 +
 .../UniversalMembershipListenerAdapter.java     |   375 +
 .../gemstone/gemfire/management/package.html    |     8 +
 .../memcached/GemFireMemcachedServer.java       |   275 +
 .../main/java/com/gemstone/gemfire/package.html |    70 +
 .../com/gemstone/gemfire/pdx/FieldType.java     |   149 +
 .../com/gemstone/gemfire/pdx/JSONFormatter.java |   614 +
 .../gemfire/pdx/JSONFormatterException.java     |    38 +
 .../gemfire/pdx/NonPortableClassException.java  |    18 +
 .../gemfire/pdx/PdxConfigurationException.java  |    32 +
 .../pdx/PdxFieldAlreadyExistsException.java     |    37 +
 .../pdx/PdxFieldDoesNotExistException.java      |    33 +
 .../pdx/PdxFieldTypeMismatchException.java      |    37 +
 .../gemfire/pdx/PdxInitializationException.java |    42 +
 .../com/gemstone/gemfire/pdx/PdxInstance.java   |   193 +
 .../gemfire/pdx/PdxInstanceFactory.java         |   463 +
 .../com/gemstone/gemfire/pdx/PdxReader.java     |   256 +
 .../pdx/PdxRegistryMismatchException.java       |    31 +
 .../gemstone/gemfire/pdx/PdxSerializable.java   |    62 +
 .../gemfire/pdx/PdxSerializationException.java  |    44 +
 .../com/gemstone/gemfire/pdx/PdxSerializer.java |    85 +
 .../gemstone/gemfire/pdx/PdxUnreadFields.java   |    33 +
 .../com/gemstone/gemfire/pdx/PdxWriter.java     |   470 +
 .../pdx/ReflectionBasedAutoSerializer.java      |   543 +
 .../gemfire/pdx/WritablePdxInstance.java        |    35 +
 .../pdx/internal/AutoSerializableManager.java   |  2302 +++
 .../pdx/internal/CheckTypeRegistryState.java    |   101 +
 .../pdx/internal/ClientTypeRegistration.java    |   409 +
 .../gemfire/pdx/internal/ComparableEnum.java    |     8 +
 .../pdx/internal/ConvertableToBytes.java        |     7 +
 .../gemstone/gemfire/pdx/internal/DataSize.java |    40 +
 .../gemfire/pdx/internal/DefaultPdxField.java   |    28 +
 .../gemstone/gemfire/pdx/internal/EnumId.java   |    87 +
 .../gemstone/gemfire/pdx/internal/EnumInfo.java |   324 +
 .../pdx/internal/FieldNotFoundInPdxVersion.java |    11 +
 .../gemfire/pdx/internal/InternalPdxReader.java |    76 +
 .../pdx/internal/LonerTypeRegistration.java     |   177 +
 .../pdx/internal/NullTypeRegistration.java      |   111 +
 .../gemstone/gemfire/pdx/internal/PdxField.java |   250 +
 .../gemfire/pdx/internal/PdxInputStream.java    |   424 +
 .../gemfire/pdx/internal/PdxInstanceEnum.java   |   174 +
 .../pdx/internal/PdxInstanceFactoryImpl.java    |   260 +
 .../gemfire/pdx/internal/PdxInstanceImpl.java   |   635 +
 .../pdx/internal/PdxInstanceInputStream.java    |   106 +
 .../gemfire/pdx/internal/PdxOutputStream.java   |   226 +
 .../gemfire/pdx/internal/PdxReaderImpl.java     |   891 ++
 .../gemfire/pdx/internal/PdxString.java         |   201 +
 .../gemstone/gemfire/pdx/internal/PdxType.java  |   486 +
 .../gemfire/pdx/internal/PdxUnreadData.java     |   108 +
 .../gemfire/pdx/internal/PdxWriterImpl.java     |   900 ++
 .../pdx/internal/PeerTypeRegistration.java      |   754 +
 .../pdx/internal/TrackingPdxReaderImpl.java     |   345 +
 .../gemfire/pdx/internal/TypeRegistration.java  |    93 +
 .../gemfire/pdx/internal/TypeRegistry.java      |   513 +
 .../gemfire/pdx/internal/UnreadPdxType.java     |    64 +
 .../internal/WeakConcurrentIdentityHashMap.java |   128 +
 .../pdx/internal/WritablePdxInstanceImpl.java   |   279 +
 .../gemfire/pdx/internal/json/JsonHelper.java   |   173 +
 .../pdx/internal/json/PdxInstanceHelper.java    |   186 +
 .../pdx/internal/json/PdxListHelper.java        |   181 +
 .../gemfire/pdx/internal/json/PdxToJSON.java    |   313 +
 .../pdx/internal/unsafe/UnsafeWrapper.java      |   176 +
 .../java/com/gemstone/gemfire/pdx/package.html  |    97 +
 .../com/gemstone/gemfire/ra/GFConnection.java   |    11 +
 .../gemfire/ra/GFConnectionFactory.java         |    13 +
 .../gemfire/security/AccessControl.java         |    86 +
 .../gemfire/security/AuthInitialize.java        |    79 +
 .../security/AuthenticationFailedException.java |    45 +
 .../AuthenticationRequiredException.java        |    45 +
 .../gemfire/security/Authenticator.java         |    78 +
 .../security/GemFireSecurityException.java      |    46 +
 .../security/NotAuthorizedException.java        |    54 +
 .../com/gemstone/gemfire/security/package.html  |    23 +
 .../util/concurrent/SynchronousQueueNoSpin.java |  1144 ++
 .../config/GemFireFileConfigurationMonitor.java |   145 +
 .../config/xml/GemFireXmlConfiguration.java     |   344 +
 .../xml/GemFireXmlConfigurationFactory.java     |    59 +
 .../message/GemFireParameterizedMessage.java    |   554 +
 .../GemFireParameterizedMessageFactory.java     |    54 +
 .../src/main/java/external-overview.html        |    27 +
 .../src/main/java/internal-overview.html        |    10 +
 .../gemfire/cache/cache-8.1.xsd                 |  1496 ++
 .../services/org.xml.sax.ext.EntityResolver2    |     1 +
 .../gemstone/gemfire/admin/doc-files/ds4_0.dtd  |   161 +
 .../gemstone/gemfire/admin/doc-files/ds5_0.dtd  |   153 +
 .../internal/doc-files/mbeans-descriptors.dtd   |   232 +
 .../gemfire/admin/jmx/mbeans-descriptors.xml    |  1435 ++
 .../gemfire/cache/doc-files/cache3_0.dtd        |   281 +
 .../gemfire/cache/doc-files/cache4_0.dtd        |   377 +
 .../gemfire/cache/doc-files/cache4_1.dtd        |   470 +
 .../gemfire/cache/doc-files/cache5_0.dtd        |   504 +
 .../gemfire/cache/doc-files/cache5_1.dtd        |   519 +
 .../gemfire/cache/doc-files/cache5_5.dtd        |   636 +
 .../gemfire/cache/doc-files/cache5_7.dtd        |   761 +
 .../gemfire/cache/doc-files/cache5_8.dtd        |   779 ++
 .../gemfire/cache/doc-files/cache6_0.dtd        |   847 ++
 .../gemfire/cache/doc-files/cache6_1.dtd        |   856 ++
 .../gemfire/cache/doc-files/cache6_5.dtd        |   934 ++
 .../gemfire/cache/doc-files/cache6_6.dtd        |   991 ++
 .../gemfire/cache/doc-files/cache7_0.dtd        |  1072 ++
 .../gemfire/cache/doc-files/cache8_0.dtd        |  1092 ++
 .../distributed/internal/javagroups-config.txt  |   101 +
 .../distributed/internal/javagroups-mcast.txt   |    97 +
 .../internal/i18n/StringIdResourceBundle_ja.txt |  3811 +++++
 .../internal/logging/log4j/log4j2-cli.xml       |    17 +
 .../internal/logging/log4j/log4j2-default.xml   |    21 +
 .../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   |    68 +
 .../internal/cli/commands/support/gfmon.html    |    20 +
 .../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     |    72 +
 .../gemstone/gemfire/admin/AdminTestHelper.java |    29 +
 ...ibutedSystemFactoryIntegrationJUnitTest.java |    76 +
 .../DistributedSystemFactoryJUnitTest.java      |   149 +
 .../cache/AttributesFactoryJUnitTest.java       |   429 +
 .../gemfire/cache/Bug36619JUnitTest.java        |    68 +
 .../gemfire/cache/OperationJUnitTest.java       |   924 ++
 .../gemfire/cache/RoleExceptionJUnitTest.java   |   130 +
 .../internal/OpExecutorImplJUnitTest.java       |   658 +
 .../internal/ServerBlackListJUnitTest.java      |   135 +
 .../locator/LocatorStatusResponseJUnitTest.java |    69 +
 .../gemfire/cache/query/data/Address.java       |    42 +
 .../gemstone/gemfire/cache/query/data/City.java |    47 +
 .../cache/query/data/CollectionHolder.java      |    80 +
 .../cache/query/data/ComparableWrapper.java     |    60 +
 .../gemfire/cache/query/data/Country.java       |    91 +
 .../gemstone/gemfire/cache/query/data/Data.java |    37 +
 .../gemfire/cache/query/data/District.java      |    55 +
 .../gemfire/cache/query/data/Employee.java      |    63 +
 .../gemfire/cache/query/data/Inventory.java     |   118 +
 .../gemfire/cache/query/data/Keywords.java      |    81 +
 .../gemfire/cache/query/data/Manager.java       |    34 +
 .../gemfire/cache/query/data/Numbers.java       |    43 +
 .../gemfire/cache/query/data/PhoneNo.java       |    33 +
 .../gemfire/cache/query/data/Portfolio.java     |   292 +
 .../gemfire/cache/query/data/PortfolioData.java |   145 +
 .../gemfire/cache/query/data/PortfolioPdx.java  |   292 +
 .../gemfire/cache/query/data/Position.java      |   157 +
 .../gemfire/cache/query/data/PositionPdx.java   |   173 +
 .../query/data/ProhibitedSecurityQuote.java     |    57 +
 .../gemfire/cache/query/data/Quote.java         |   105 +
 .../gemfire/cache/query/data/Restricted.java    |    71 +
 .../cache/query/data/SecurityMaster.java        |   253 +
 .../gemfire/cache/query/data/State.java         |    72 +
 .../gemfire/cache/query/data/Street.java        |    29 +
 .../gemfire/cache/query/data/Student.java       |    68 +
 .../gemfire/cache/query/data/Vehicle.java       |    30 +
 .../gemfire/cache/query/data/Village.java       |    46 +
 .../internal/OrderByComparatorJUnitTest.java    |    63 +
 .../QueryObjectSerializationJUnitTest.java      |   142 +
 .../query/internal/ResultsBagJUnitTest.java     |   305 +
 .../ResultsBagLimitBehaviourJUnitTest.java      |   576 +
 .../ResultsCollectionWrapperLimitJUnitTest.java |   358 +
 .../SelectResultsComparatorJUnitTest.java       |    82 +
 .../StructBagLimitBehaviourJUnitTest.java       |   120 +
 .../query/internal/StructSetJUnitTest.java      |    68 +
 .../internal/index/IndexElemArrayJUnitTest.java |   123 +
 .../internal/ConnectionCountProbeJUnitTest.java |    42 +
 .../cache/util/PasswordUtilJUnitTest.java       |    32 +
 .../distributed/AbstractLauncherJUnitTest.java  |   354 +
 .../AbstractLauncherServiceStatusJUnitTest.java |   264 +
 .../distributed/CommonLauncherTestSuite.java    |    45 +
 .../distributed/LocatorLauncherJUnitTest.java   |   498 +
 .../distributed/ServerLauncherJUnitTest.java    |   980 ++
 .../AtomicLongWithTerminalStateJUnitTest.java   |    32 +
 .../internal/ProductUseLogJUnitTest.java        |    77 +
 .../internal/ServerLocatorJUnitTest.java        |    66 +
 .../internal/SharedConfigurationJUnitTest.java  |    48 +
 .../internal/StartupMessageDataJUnitTest.java   |   310 +
 .../deadlock/DeadlockDetectorJUnitTest.java     |   311 +
 .../deadlock/DependencyGraphJUnitTest.java      |    78 +
 .../deadlock/UnsafeThreadLocalJUnitTest.java    |    52 +
 ...entrantReadWriteWriteShareLockJUnitTest.java |   448 +
 .../membership/MembershipJUnitTest.java         |    99 +
 .../support/DistributedSystemAdapter.java       |   249 +
 .../internal/AvailablePortJUnitTest.java        |    65 +
 .../gemfire/internal/ByteArrayData.java         |    64 +
 .../gemstone/gemfire/internal/ClassBuilder.java |   283 +
 .../internal/ClassPathLoaderJUnitTest.java      |  1253 ++
 .../internal/CopyOnWriteHashSetJUnitTest.java   |    94 +
 .../gemfire/internal/FileUtilJUnitTest.java     |    63 +
 .../internal/GemFireVersionJUnitTest.java       |    93 +
 .../internal/HeapDataOutputStreamJUnitTest.java |    41 +
 .../internal/JarClassLoaderJUnitTest.java       |   773 ++
 .../gemfire/internal/LineWrapUnitJUnitTest.java |    43 +
 .../gemfire/internal/NanoTimer2JUnitTest.java   |    79 +
 .../gemfire/internal/ObjIdMapJUnitTest.java     |   247 +
 .../internal/OneTaskOnlyDecoratorJUnitTest.java |   156 +
 .../PutAllOperationContextJUnitTest.java        |   188 +
 .../internal/UniqueIdGeneratorJUnitTest.java    |    59 +
 .../internal/cache/AbstractRegionJUnitTest.java |   504 +
 .../gemfire/internal/cache/DiskIdJUnitTest.java |   231 +
 .../internal/cache/DiskInitFileJUnitTest.java   |   104 +
 .../cache/DiskWriteAttributesJUnitTest.java     |   214 +
 .../cache/EnumListenerEventJUnitTest.java       |    64 +
 .../gemfire/internal/cache/OldVLJUnitTest.java  |    83 +
 .../cache/OplogEntryIdMapJUnitTest.java         |    90 +
 .../cache/OplogEntryIdSetJUnitTest.java         |    74 +
 .../internal/cache/OplogRVVJUnitTest.java       |   164 +
 .../cache/OrderedTombstoneMapJUnitTest.java     |    50 +
 .../cache/PartitionedRegionHelperJUnitTest.java |    39 +
 .../gemfire/internal/cache/VLJUnitTest.java     |   121 +
 .../cache/control/FilterByPathJUnitTest.java    |    87 +
 .../SimpleExtensionPointJUnitTest.java          |   206 +
 .../cache/ha/EventIdOptimizationJUnitTest.java  |   245 +
 .../cache/ha/ThreadIdentifierJUnitTest.java     |   107 +
 .../classpathloaderjunittest/DoesExist.java     |     5 +
 .../compression/SnappyCompressorJUnitTest.java  |    57 +
 .../util/AbortableTaskServiceJUnitTest.java     |   193 +
 .../internal/util/ArrayUtilsJUnitTest.java      |   170 +
 .../gemfire/internal/util/BytesJUnitTest.java   |   107 +
 .../internal/util/CollectionUtilsJUnitTest.java |   477 +
 .../internal/util/DelayedActionJUnitTest.java   |    47 +
 .../gemfire/internal/util/IOUtilsJUnitTest.java |   306 +
 .../gemfire/internal/util/SerializableImpl.java |    31 +
 .../util/SerializableImplWithValue.java         |    50 +
 .../gemstone/gemfire/internal/util/Sizeof.java  |   164 +
 .../gemfire/internal/util/Valuable.java         |    31 +
 .../CompactConcurrentHashSetJUnitTest.java      |    87 +
 .../ConcurrentHashMapIteratorJUnitTest.java     |   115 +
 .../concurrent/ReentrantSemaphoreJUnitTest.java |   104 +
 .../SemaphoreReadWriteLockJUnitTest.java        |   176 +
 .../internal/security/JSONAuthCodeTest.java     |   184 +
 .../security/JSONAuthorizationTest.java         |   152 +
 .../security/ResourceOperationJUnit.java        |   378 +
 .../gemstone/gemfire/util/test/TestUtil.java    |    49 +
 .../java/org/xerial/snappy/SnappyUtils.java     |     9 +
 .../internal/SharedConfigurationJUnitTest.xml   |     6 +
 .../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 +
 gemfire-jgroups/build.gradle                    |    31 +
 .../java/com/gemstone/org/jgroups/Address.java  |    46 +
 .../com/gemstone/org/jgroups/BlockEvent.java    |    15 +
 .../java/com/gemstone/org/jgroups/Channel.java  |   508 +
 .../org/jgroups/ChannelClosedException.java     |    27 +
 .../gemstone/org/jgroups/ChannelException.java  |    28 +
 .../gemstone/org/jgroups/ChannelFactory.java    |    38 +
 .../gemstone/org/jgroups/ChannelListener.java   |    20 +
 .../jgroups/ChannelNotConnectedException.java   |    26 +
 .../java/com/gemstone/org/jgroups/Event.java    |   225 +
 .../com/gemstone/org/jgroups/ExitEvent.java     |    14 +
 .../com/gemstone/org/jgroups/GetStateEvent.java |    22 +
 .../java/com/gemstone/org/jgroups/Global.java   |    44 +
 .../java/com/gemstone/org/jgroups/Header.java   |    51 +
 .../java/com/gemstone/org/jgroups/JChannel.java |  1723 +++
 .../gemstone/org/jgroups/JChannelFactory.java   |   129 +
 .../gemstone/org/jgroups/JGroupsVersion.java    |    95 +
 .../com/gemstone/org/jgroups/Membership.java    |   358 +
 .../org/jgroups/MembershipListener.java         |    53 +
 .../com/gemstone/org/jgroups/MergeView.java     |   166 +
 .../java/com/gemstone/org/jgroups/Message.java  |   784 ++
 .../com/gemstone/org/jgroups/Message.java.old   |   711 +
 .../gemstone/org/jgroups/MessageListener.java   |    34 +
 .../java/com/gemstone/org/jgroups/Receiver.java |    13 +
 .../gemstone/org/jgroups/ReceiverAdapter.java   |    35 +
 .../com/gemstone/org/jgroups/SetStateEvent.java |    37 +
 .../org/jgroups/ShunnedAddressException.java    |    14 +
 .../com/gemstone/org/jgroups/SuspectEvent.java  |    26 +
 .../com/gemstone/org/jgroups/SuspectMember.java |    42 +
 .../org/jgroups/SuspectedException.java         |    21 +
 .../gemstone/org/jgroups/TimeoutException.java  |    43 +
 .../com/gemstone/org/jgroups/Transport.java     |    22 +
 .../com/gemstone/org/jgroups/UpHandler.java     |    18 +
 .../java/com/gemstone/org/jgroups/View.java     |   528 +
 .../java/com/gemstone/org/jgroups/ViewId.java   |   174 +
 .../org/jgroups/blocks/ConnectionTable.java     |  1051 ++
 .../org/jgroups/blocks/ConnectionTableNIO.java  |  1519 ++
 .../jgroups/blocks/DistributedHashtable.java    |   656 +
 .../jgroups/blocks/DistributedLockManager.java  |   742 +
 .../org/jgroups/blocks/DistributedQueue.java    |   758 +
 .../org/jgroups/blocks/DistributedTree.java     |   756 +
 .../org/jgroups/blocks/GroupRequest.java        |   636 +
 .../org/jgroups/blocks/GroupRequest.java.old    |   641 +
 .../com/gemstone/org/jgroups/blocks/Link.java   |   680 +
 .../com/gemstone/org/jgroups/blocks/Link.txt    |    48 +
 .../org/jgroups/blocks/LockManager.java         |    87 +
 .../blocks/LockMultiLockedException.java        |    26 +
 .../jgroups/blocks/LockNotGrantedException.java |    24 +
 .../blocks/LockNotReleasedException.java        |    24 +
 .../org/jgroups/blocks/LockingException.java    |    38 +
 .../org/jgroups/blocks/LogicalLink.java         |   340 +
 .../blocks/MembershipListenerAdapter.java       |    91 +
 .../org/jgroups/blocks/MessageDispatcher.java   |   845 ++
 .../jgroups/blocks/MessageListenerAdapter.java  |   123 +
 .../gemstone/org/jgroups/blocks/MethodCall.java |   529 +
 .../org/jgroups/blocks/MethodLookup.java        |    15 +
 .../org/jgroups/blocks/NBMessageForm_NIO.java   |    94 +
 .../org/jgroups/blocks/NotificationBus.java     |   458 +
 .../org/jgroups/blocks/PullPushAdapter.java     |   434 +
 .../org/jgroups/blocks/ReplicatedHashtable.java |   530 +
 .../org/jgroups/blocks/ReplicatedTree.java      |  1121 ++
 .../org/jgroups/blocks/ReplicationData.java     |   148 +
 .../org/jgroups/blocks/ReplicationManager.java  |   345 +
 .../org/jgroups/blocks/ReplicationReceiver.java |    69 +
 .../org/jgroups/blocks/RequestCorrelator.java   |   911 ++
 .../org/jgroups/blocks/RequestHandler.java      |    15 +
 .../org/jgroups/blocks/RpcDispatcher.java       |   392 +
 .../org/jgroups/blocks/RspCollector.java        |    18 +
 .../jgroups/blocks/TwoPhaseVotingAdapter.java   |   173 +
 .../jgroups/blocks/TwoPhaseVotingListener.java  |    35 +
 .../org/jgroups/blocks/UpdateException.java     |    19 +
 .../org/jgroups/blocks/VoteException.java       |    19 +
 .../jgroups/blocks/VoteResponseProcessor.java   |    31 +
 .../org/jgroups/blocks/VotingAdapter.java       |   472 +
 .../org/jgroups/blocks/VotingListener.java      |    26 +
 .../com/gemstone/org/jgroups/blocks/Xid.java    |   164 +
 .../gemstone/org/jgroups/blocks/package.html    |    13 +
 .../org/jgroups/conf/ClassConfigurator.java     |   228 +
 .../com/gemstone/org/jgroups/conf/ClassMap.java |    75 +
 .../jgroups/conf/ClassPathEntityResolver.java   |    63 +
 .../org/jgroups/conf/ConfiguratorFactory.java   |   449 +
 .../org/jgroups/conf/MagicNumberReader.java     |   402 +
 .../org/jgroups/conf/PlainConfigurator.java     |    48 +
 .../gemstone/org/jgroups/conf/ProtocolData.java |   130 +
 .../org/jgroups/conf/ProtocolParameter.java     |    64 +
 .../jgroups/conf/ProtocolStackConfigurator.java |    18 +
 .../org/jgroups/conf/XmlConfigurator.java       |   463 +
 .../gemstone/org/jgroups/conf/XmlValidator.java |   146 +
 .../com/gemstone/org/jgroups/conf/package.html  |     5 +
 .../gemstone/org/jgroups/debug/Debugger.java    |   133 +
 .../org/jgroups/debug/JChannelTestHook.java     |    14 +
 .../gemstone/org/jgroups/debug/Profiler.java    |   160 +
 .../org/jgroups/debug/ProtocolSpecificView.java |    24 +
 .../org/jgroups/debug/ProtocolTester.java       |   142 +
 .../org/jgroups/debug/ProtocolView.java         |    90 +
 .../gemstone/org/jgroups/debug/QUEUEView.java   |    28 +
 .../gemstone/org/jgroups/debug/Simulator.java   |   249 +
 .../com/gemstone/org/jgroups/debug/package.html |     5 +
 .../com/gemstone/org/jgroups/gemstonizing.txt   |    28 +
 .../org/jgroups/oswego/concurrent/Barrier.java  |    65 +
 .../oswego/concurrent/BoundedBuffer.java        |   190 +
 .../oswego/concurrent/BoundedChannel.java       |    37 +
 .../oswego/concurrent/BoundedLinkedQueue.java   |   384 +
 .../oswego/concurrent/BoundedPriorityQueue.java |   123 +
 .../concurrent/BrokenBarrierException.java      |    48 +
 .../org/jgroups/oswego/concurrent/Callable.java |    39 +
 .../org/jgroups/oswego/concurrent/Channel.java  |   309 +
 .../jgroups/oswego/concurrent/ClockDaemon.java  |   403 +
 .../org/jgroups/oswego/concurrent/CondVar.java  |   277 +
 .../jgroups/oswego/concurrent/CountDown.java    |   126 +
 .../oswego/concurrent/CyclicBarrier.java        |   299 +
 .../concurrent/DefaultChannelCapacity.java      |    58 +
 .../oswego/concurrent/DirectExecutor.java       |    36 +
 .../org/jgroups/oswego/concurrent/Executor.java |    70 +
 .../oswego/concurrent/FIFOReadWriteLock.java    |   198 +
 .../oswego/concurrent/FIFOSemaphore.java        |    84 +
 .../org/jgroups/oswego/concurrent/FJTask.java   |   535 +
 .../jgroups/oswego/concurrent/FJTaskRunner.java |   979 ++
 .../oswego/concurrent/FJTaskRunnerGroup.java    |   625 +
 .../jgroups/oswego/concurrent/FutureResult.java |   209 +
 .../org/jgroups/oswego/concurrent/Heap.java     |   151 +
 .../org/jgroups/oswego/concurrent/Latch.java    |   103 +
 .../jgroups/oswego/concurrent/LayeredSync.java  |    96 +
 .../jgroups/oswego/concurrent/LinkedNode.java   |    29 +
 .../jgroups/oswego/concurrent/LinkedQueue.java  |   192 +
 .../oswego/concurrent/LockedExecutor.java       |    62 +
 .../org/jgroups/oswego/concurrent/Mutex.java    |   173 +
 .../org/jgroups/oswego/concurrent/NullSync.java |    51 +
 .../oswego/concurrent/PooledExecutor.java       |   924 ++
 .../oswego/concurrent/PrioritySemaphore.java    |    96 +
 .../concurrent/PropertyChangeMulticaster.java   |   466 +
 .../org/jgroups/oswego/concurrent/Puttable.java |    68 +
 .../oswego/concurrent/QueuedExecutor.java       |   220 +
 .../oswego/concurrent/QueuedSemaphore.java      |   181 +
 .../oswego/concurrent/ReadWriteLock.java        |    86 +
 .../ReaderPreferenceReadWriteLock.java          |    35 +
 .../oswego/concurrent/ReentrantLock.java        |   151 +
 .../ReentrantWriterPreferenceReadWriteLock.java |   169 +
 .../jgroups/oswego/concurrent/Rendezvous.java   |   422 +
 .../jgroups/oswego/concurrent/Semaphore.java    |   193 +
 .../concurrent/SemaphoreControlledChannel.java  |   164 +
 .../org/jgroups/oswego/concurrent/Slot.java     |    88 +
 .../org/jgroups/oswego/concurrent/Sync.java     |   344 +
 .../oswego/concurrent/SyncCollection.java       |   514 +
 .../org/jgroups/oswego/concurrent/SyncList.java |   327 +
 .../org/jgroups/oswego/concurrent/SyncMap.java  |   314 +
 .../org/jgroups/oswego/concurrent/SyncSet.java  |    82 +
 .../oswego/concurrent/SyncSortedMap.java        |   129 +
 .../oswego/concurrent/SyncSortedSet.java        |   129 +
 .../oswego/concurrent/SynchronizedBoolean.java  |   182 +
 .../oswego/concurrent/SynchronizedByte.java     |   253 +
 .../oswego/concurrent/SynchronizedChar.java     |   176 +
 .../oswego/concurrent/SynchronizedDouble.java   |   181 +
 .../oswego/concurrent/SynchronizedFloat.java    |   181 +
 .../oswego/concurrent/SynchronizedInt.java      |   250 +
 .../oswego/concurrent/SynchronizedLong.java     |   252 +
 .../oswego/concurrent/SynchronizedRef.java      |   107 +
 .../oswego/concurrent/SynchronizedShort.java    |   254 +
 .../oswego/concurrent/SynchronizedVariable.java |   209 +
 .../oswego/concurrent/SynchronousChannel.java   |   379 +
 .../org/jgroups/oswego/concurrent/Takable.java  |    67 +
 .../oswego/concurrent/ThreadFactory.java        |    35 +
 .../oswego/concurrent/ThreadFactoryUser.java    |    62 +
 .../oswego/concurrent/ThreadedExecutor.java     |    40 +
 .../oswego/concurrent/TimedCallable.java        |    68 +
 .../oswego/concurrent/TimeoutException.java     |    53 +
 .../jgroups/oswego/concurrent/TimeoutSync.java  |    75 +
 .../concurrent/VetoableChangeMulticaster.java   |   577 +
 .../oswego/concurrent/WaitFreeQueue.java        |   208 +
 .../oswego/concurrent/WaitableBoolean.java      |   141 +
 .../jgroups/oswego/concurrent/WaitableByte.java |   238 +
 .../jgroups/oswego/concurrent/WaitableChar.java |   170 +
 .../oswego/concurrent/WaitableDouble.java       |   173 +
 .../oswego/concurrent/WaitableFloat.java        |   173 +
 .../jgroups/oswego/concurrent/WaitableInt.java  |   239 +
 .../jgroups/oswego/concurrent/WaitableLong.java |   239 +
 .../jgroups/oswego/concurrent/WaitableRef.java  |   112 +
 .../oswego/concurrent/WaitableShort.java        |   238 +
 .../concurrent/WaiterPreferenceSemaphore.java   |   155 +
 .../WriterPreferenceReadWriteLock.java          |   337 +
 .../org/jgroups/oswego/concurrent/package.html  |   998 ++
 .../java/com/gemstone/org/jgroups/overview.html |    15 +
 .../java/com/gemstone/org/jgroups/package.html  |     5 +
 .../persistence/CannotConnectException.java     |    55 +
 .../CannotCreateSchemaException.java            |    45 +
 .../persistence/CannotPersistException.java     |    44 +
 .../persistence/CannotRemoveException.java      |    45 +
 .../persistence/CannotRetrieveException.java    |    44 +
 .../persistence/DBPersistenceManager.java       |   877 ++
 .../persistence/FilePersistenceManager.java     |   173 +
 .../jgroups/persistence/PersistenceFactory.java |   207 +
 .../jgroups/persistence/PersistenceManager.java |    69 +
 .../org/jgroups/persistence/package.html        |     5 +
 .../com/gemstone/org/jgroups/primarychanges.txt |    80 +
 .../gemstone/org/jgroups/protocols/AUTH.java    |   438 +
 .../org/jgroups/protocols/AUTOCONF.java         |   249 +
 .../org/jgroups/protocols/AuthHeader.java       |   108 +
 .../gemstone/org/jgroups/protocols/CAUSAL.java  |   296 +
 .../org/jgroups/protocols/COMPRESS.java         |   188 +
 .../org/jgroups/protocols/DEADLOCK.java         |   250 +
 .../gemstone/org/jgroups/protocols/DELAY.java   |   116 +
 .../com/gemstone/org/jgroups/protocols/DESIGN   |   283 +
 .../gemstone/org/jgroups/protocols/DISCARD.java |   150 +
 .../gemstone/org/jgroups/protocols/DUMMY.java   |    85 +
 .../org/jgroups/protocols/DUMMY_TP.java         |    84 +
 .../gemstone/org/jgroups/protocols/Digest.java  |    38 +
 .../org/jgroups/protocols/Discovery.java        |   484 +
 .../gemstone/org/jgroups/protocols/ENCRYPT.java |  1390 ++
 .../org/jgroups/protocols/ENCRYPT1_4.java       |   566 +
 .../gemstone/org/jgroups/protocols/EXAMPLE.java |   104 +
 .../com/gemstone/org/jgroups/protocols/FC.java  |  1025 ++
 .../com/gemstone/org/jgroups/protocols/FD.java  |  1100 ++
 .../gemstone/org/jgroups/protocols/FD_PID.java  |   640 +
 .../gemstone/org/jgroups/protocols/FD_PROB.java |   628 +
 .../org/jgroups/protocols/FD_SIMPLE.java        |   357 +
 .../gemstone/org/jgroups/protocols/FD_SOCK.java |  2607 ++++
 .../org/jgroups/protocols/FD_SOCK.java.new      |  1153 ++
 .../org/jgroups/protocols/FLOWCONTROL.java      |    89 +
 .../org/jgroups/protocols/FLOW_CONTROL.java     |   317 +
 .../gemstone/org/jgroups/protocols/FLUSH.java   |   466 +
 .../gemstone/org/jgroups/protocols/FRAG.java    |   572 +
 .../gemstone/org/jgroups/protocols/FRAG2.java   |   773 ++
 .../gemstone/org/jgroups/protocols/FRAG3.java   |    35 +
 .../org/jgroups/protocols/FlushRsp.java         |    31 +
 .../org/jgroups/protocols/FragHeader.java       |    80 +
 .../gemstone/org/jgroups/protocols/GMS.java.rmi |   219 +
 .../org/jgroups/protocols/GemFireTimeSync.java  |   719 +
 .../gemstone/org/jgroups/protocols/HDRS.java    |    53 +
 .../gemstone/org/jgroups/protocols/HTOTAL.java  |   207 +
 .../org/jgroups/protocols/LOOPBACK.java         |   115 +
 .../gemstone/org/jgroups/protocols/LOSS.java    |   118 +
 .../gemstone/org/jgroups/protocols/MERGE.java   |   376 +
 .../gemstone/org/jgroups/protocols/MERGE2.java  |   362 +
 .../gemstone/org/jgroups/protocols/MERGE3.java  |   312 +
 .../org/jgroups/protocols/MERGEFAST.java        |   118 +
 .../protocols/MessageProtocolEXAMPLE.java       |    64 +
 .../protocols/NAKACK.java.MessageProtocol       |   422 +
 .../org/jgroups/protocols/NAKACK.java.separate  |   484 +
 .../org/jgroups/protocols/NakAckHeader.java     |   113 +
 .../org/jgroups/protocols/PARTITIONER.java      |   185 +
 .../gemstone/org/jgroups/protocols/PERF.java    |   284 +
 .../gemstone/org/jgroups/protocols/PERF_TP.java |   172 +
 .../org/jgroups/protocols/PIGGYBACK.java        |   271 +
 .../gemstone/org/jgroups/protocols/PING.java    |   297 +
 .../org/jgroups/protocols/PRINTMETHODS.java     |    64 +
 .../org/jgroups/protocols/PRINTOBJS.java        |   120 +
 .../org/jgroups/protocols/PerfHeader.java       |   451 +
 .../org/jgroups/protocols/PingHeader.java       |    79 +
 .../gemstone/org/jgroups/protocols/PingRsp.java |   107 +
 .../org/jgroups/protocols/PingSender.java       |   109 +
 .../org/jgroups/protocols/PingWaiter.java       |   301 +
 .../gemstone/org/jgroups/protocols/QUEUE.java   |   184 +
 .../jgroups/protocols/RpcProtocolEXAMPLE.java   |    64 +
 .../gemstone/org/jgroups/protocols/SHUFFLE.java |   146 +
 .../gemstone/org/jgroups/protocols/SIZE.java    |   186 +
 .../gemstone/org/jgroups/protocols/SMACK.java   |   393 +
 .../org/jgroups/protocols/STATE_TRANSFER.java   |   448 +
 .../gemstone/org/jgroups/protocols/STATS.java   |   211 +
 .../com/gemstone/org/jgroups/protocols/TCP.java |   308 +
 .../org/jgroups/protocols/TCPGOSSIP.java        |   429 +
 .../gemstone/org/jgroups/protocols/TCPPING.java |   144 +
 .../gemstone/org/jgroups/protocols/TCP_NIO.java |   118 +
 .../gemstone/org/jgroups/protocols/TOTAL.java   |  1055 ++
 .../com/gemstone/org/jgroups/protocols/TP.java  |  2009 +++
 .../gemstone/org/jgroups/protocols/TP.java.mt   |  1522 ++
 .../gemstone/org/jgroups/protocols/TRACE.java   |    47 +
 .../gemstone/org/jgroups/protocols/TUNNEL.java  |   459 +
 .../org/jgroups/protocols/TcpHeader.java        |    55 +
 .../org/jgroups/protocols/TpHeader.java         |    64 +
 .../protocols/TransportedVectorTime.java        |   185 +
 .../org/jgroups/protocols/TunnelHeader.java     |    47 +
 .../com/gemstone/org/jgroups/protocols/UDP.java |  1462 ++
 .../gemstone/org/jgroups/protocols/UDP.java.mt  |  1005 ++
 .../jgroups/protocols/UDP.java.packethandler    |   592 +
 .../gemstone/org/jgroups/protocols/UDP_NIO.java |  1567 +++
 .../gemstone/org/jgroups/protocols/UNICAST.java |   981 ++
 .../org/jgroups/protocols/UdpHeader.java        |    62 +
 .../org/jgroups/protocols/VERIFY_SUSPECT.java   |   470 +
 .../org/jgroups/protocols/VIEW_ENFORCER.java    |    81 +
 .../org/jgroups/protocols/VIEW_SYNC.java        |   499 +
 .../org/jgroups/protocols/VectorTime.java       |   270 +
 .../gemstone/org/jgroups/protocols/WANPING.java |   106 +
 .../gemstone/org/jgroups/protocols/WANPIPE.java |   441 +
 .../org/jgroups/protocols/WanPipeAddress.java   |   140 +
 .../gemstone/org/jgroups/protocols/dump2.log    |     0
 .../jgroups/protocols/obsolete/ENCRYPT.java.txt |   408 +
 .../org/jgroups/protocols/obsolete/FC.java.txt  |   643 +
 .../jgroups/protocols/obsolete/FD_RAND.java.txt |   287 +
 .../jgroups/protocols/obsolete/FD_SHUN.java.txt |   323 +
 .../org/jgroups/protocols/obsolete/TCP.java.txt |   493 +
 .../org/jgroups/protocols/obsolete/UDP.java.txt |  1921 +++
 .../jgroups/protocols/obsolete/UNIFORM.java.txt |   349 +
 .../gemstone/org/jgroups/protocols/package.html |     6 +
 .../jgroups/protocols/pbcast/ClientGmsImpl.java |   898 ++
 .../jgroups/protocols/pbcast/CoordGmsImpl.java  |  1103 ++
 .../org/jgroups/protocols/pbcast/DESIGN         |   478 +
 .../org/jgroups/protocols/pbcast/Digest.java    |   534 +
 .../jgroups/protocols/pbcast/Digest.java.old    |   558 +
 .../org/jgroups/protocols/pbcast/FD.java        |   273 +
 .../org/jgroups/protocols/pbcast/GMS.java       |  2729 ++++
 .../org/jgroups/protocols/pbcast/GmsImpl.java   |   111 +
 .../org/jgroups/protocols/pbcast/Gossip.java    |   134 +
 .../org/jgroups/protocols/pbcast/JoinRsp.java   |   126 +
 .../org/jgroups/protocols/pbcast/MergeData.java |   118 +
 .../org/jgroups/protocols/pbcast/NAKACK.java    |  1631 +++
 .../jgroups/protocols/pbcast/NakAckHeader.java  |   148 +
 .../org/jgroups/protocols/pbcast/PBCAST.java    |  1043 ++
 .../protocols/pbcast/ParticipantGmsImpl.java    |   371 +
 .../jgroups/protocols/pbcast/PbcastHeader.java  |   110 +
 .../org/jgroups/protocols/pbcast/README         |   140 +
 .../org/jgroups/protocols/pbcast/STABLE.java    |   907 ++
 .../jgroups/protocols/pbcast/STABLE.java.latest |   897 ++
 .../jgroups/protocols/pbcast/STABLE.java.new    |   890 ++
 .../jgroups/protocols/pbcast/STABLE.java.old    |   855 ++
 .../protocols/pbcast/STATE_TRANSFER.java        |   461 +
 .../org/jgroups/protocols/pbcast/package.html   |     5 +
 .../org/jgroups/protocols/ring/RingNode.java    |    26 +
 .../protocols/ring/RingNodeFlowControl.java     |   135 +
 .../org/jgroups/protocols/ring/RingToken.java   |   245 +
 .../org/jgroups/protocols/ring/TcpRingNode.java |   205 +
 .../protocols/ring/TokenLostException.java      |    63 +
 .../org/jgroups/protocols/ring/package.html     |     5 +
 .../jgroups/stack/AckMcastReceiverWindow.java   |   169 +
 .../org/jgroups/stack/AckMcastSenderWindow.java |   601 +
 .../org/jgroups/stack/AckReceiverWindow.java    |   184 +
 .../org/jgroups/stack/AckSenderWindow.java      |   354 +
 .../org/jgroups/stack/BoundedLinkedHashMap.java |    82 +
 .../org/jgroups/stack/Configurator.java         |   764 +
 .../org/jgroups/stack/GFBasicAdapter.java       |    95 +
 .../org/jgroups/stack/GFBasicAdapterImpl.java   |   466 +
 .../org/jgroups/stack/GFPeerAdapter.java        |   168 +
 .../org/jgroups/stack/GFPeerAdapterImpl.java    |   321 +
 .../org/jgroups/stack/GossipClient.java         |   819 ++
 .../gemstone/org/jgroups/stack/GossipData.java  |   232 +
 .../org/jgroups/stack/GossipServer.java         |   633 +
 .../gemstone/org/jgroups/stack/Interval.java    |    40 +
 .../gemstone/org/jgroups/stack/IpAddress.java   |   780 ++
 .../org/jgroups/stack/LogicalAddress.java       |   370 +
 .../org/jgroups/stack/MessageProtocol.java      |   243 +
 .../org/jgroups/stack/NakReceiverWindow.java    |   914 ++
 .../gemstone/org/jgroups/stack/Protocol.java    |   837 ++
 .../org/jgroups/stack/ProtocolObserver.java     |    81 +
 .../org/jgroups/stack/ProtocolStack.java        |   504 +
 .../org/jgroups/stack/Retransmitter.java        |   480 +
 .../com/gemstone/org/jgroups/stack/Router.java  |   577 +
 .../gemstone/org/jgroups/stack/RouterStub.java  |   419 +
 .../gemstone/org/jgroups/stack/RpcProtocol.java |   166 +
 .../org/jgroups/stack/SockCreatorImpl.java      |    47 +
 .../org/jgroups/stack/StateTransferInfo.java    |    64 +
 .../com/gemstone/org/jgroups/stack/package.html |     5 +
 .../gemstone/org/jgroups/util/AckCollector.java |   149 +
 .../gemstone/org/jgroups/util/BoundedList.java  |    53 +
 .../com/gemstone/org/jgroups/util/Buffer.java   |    64 +
 .../com/gemstone/org/jgroups/util/Command.java  |    16 +
 .../com/gemstone/org/jgroups/util/CondVar.java  |   139 +
 .../org/jgroups/util/ConnectionWatcher.java     |    25 +
 .../jgroups/util/ContextObjectInputStream.java  |    91 +
 .../util/ExposedBufferedInputStream.java        |    61 +
 .../util/ExposedBufferedOutputStream.java       |    44 +
 .../util/ExposedByteArrayInputStream.java       |    58 +
 .../util/ExposedByteArrayOutputStream.java      |    31 +
 .../jgroups/util/ExposedDataOutputStream.java   |    31 +
 .../org/jgroups/util/ExternalStrings.java       |   841 ++
 .../gemstone/org/jgroups/util/GFLogWriter.java  |    55 +
 .../org/jgroups/util/GFStringIdImpl.java        |    68 +
 .../org/jgroups/util/GemFireTracer.java         |   468 +
 .../org/jgroups/util/GetNetworkInterfaces.java  |    34 +
 .../org/jgroups/util/LinkedListQueue.java       |   422 +
 .../com/gemstone/org/jgroups/util/List.java     |   462 +
 .../jgroups/util/MagicObjectInputStream.java    |    55 +
 .../jgroups/util/MagicObjectOutputStream.java   |    60 +
 .../gemstone/org/jgroups/util/Marshaller.java   |   152 +
 .../org/jgroups/util/NullReadWriteLock.java     |    25 +
 .../com/gemstone/org/jgroups/util/NullSync.java |    26 +
 .../gemstone/org/jgroups/util/PrintXMLTree.java |   168 +
 .../com/gemstone/org/jgroups/util/Promise.java  |   161 +
 .../com/gemstone/org/jgroups/util/Proxy.java    |   870 ++
 .../com/gemstone/org/jgroups/util/Queue.java    |   653 +
 .../org/jgroups/util/Queue.java.concurrent      |   113 +
 .../com/gemstone/org/jgroups/util/Queue2.java   |   715 +
 .../org/jgroups/util/QueueClosedException.java  |    29 +
 .../com/gemstone/org/jgroups/util/Range.java    |    58 +
 .../org/jgroups/util/ReentrantLatch.java        |    65 +
 .../org/jgroups/util/ReusableThread.java        |   295 +
 .../java/com/gemstone/org/jgroups/util/Rsp.java |    82 +
 .../com/gemstone/org/jgroups/util/RspList.java  |   193 +
 .../gemstone/org/jgroups/util/Scheduler.java    |   270 +
 .../org/jgroups/util/SchedulerListener.java     |    29 +
 .../gemstone/org/jgroups/util/SockCreator.java  |    20 +
 .../com/gemstone/org/jgroups/util/Stack.java    |   108 +
 .../gemstone/org/jgroups/util/Streamable.java   |    26 +
 .../org/jgroups/util/StreamableFixedID.java     |    19 +
 .../com/gemstone/org/jgroups/util/StringId.java |    49 +
 .../gemstone/org/jgroups/util/ThreadPool.java   |   105 +
 .../org/jgroups/util/TimeScheduler.java         |   720 +
 .../gemstone/org/jgroups/util/TimedWriter.java  |   295 +
 .../com/gemstone/org/jgroups/util/Util.java     |  1869 +++
 .../org/jgroups/util/VersionedStreamable.java   |    18 +
 .../com/gemstone/org/jgroups/util/package.html  |     5 +
 .../java/com/gemstone/org/jgroups/util/todo.txt |    80 +
 .../gemstone/org/jgroups/conf/jg-magic-map.dtd  |    55 +
 .../gemstone/org/jgroups/conf/jg-magic-map.xml  |   269 +
 .../com/gemstone/org/jgroups/log4j2-default.xml |    21 +
 .../org/jgroups/stack/jboss-service.xml         |   146 +
 .../gemstone/org/jgroups/JChannelJUnitTest.java |   271 +
 .../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    |   234 +
 .../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      |  1612 +++
 .../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 +
 .../com/gemstone/junit/DistributedTest.java     |     9 +
 .../com/gemstone/junit/IntegrationTest.java     |     9 +
 .../com/gemstone/junit/PerformanceTest.java     |     9 +
 .../test/java/com/gemstone/junit/UnitTest.java  |     9 +
 .../test/java/com/gemstone/junit/WanTest.java   |     8 +
 gemfire-web-api/build.gradle                    |    42 +
 .../web/controllers/AbstractBaseController.java |   832 ++
 .../web/controllers/BaseControllerAdvice.java   |   138 +
 .../web/controllers/CommonCrudController.java   |   240 +
 .../controllers/FunctionAccessController.java   |   237 +
 .../web/controllers/PdxBasedCrudController.java |   345 +
 .../web/controllers/QueryAccessController.java  |   345 +
 .../web/controllers/support/JSONTypes.java      |     9 +
 .../controllers/support/QueryResultTypes.java   |    23 +
 .../web/controllers/support/RegionData.java     |   161 +
 .../controllers/support/RegionEntryData.java    |    96 +
 .../support/RestServersResultCollector.java     |    39 +
 .../web/controllers/support/UpdateOp.java       |    22 +
 .../DataTypeNotSupportedException.java          |    41 +
 .../web/exception/GemfireRestException.java     |    39 +
 .../web/exception/MalformedJsonException.java   |    42 +
 .../web/exception/RegionNotFoundException.java  |    35 +
 .../exception/ResourceNotFoundException.java    |    36 +
 ...stomMappingJackson2HttpMessageConverter.java |   145 +
 .../web/swagger/config/RestApiPathProvider.java |    64 +
 .../web/swagger/config/SwaggerConfig.java       |   165 +
 .../rest/internal/web/util/ArrayUtils.java      |    51 +
 .../rest/internal/web/util/DateTimeUtils.java   |    45 +
 .../internal/web/util/IdentifiableUtils.java    |   100 +
 .../rest/internal/web/util/JSONUtils.java       |   244 +
 .../rest/internal/web/util/JsonWriter.java      |   588 +
 .../rest/internal/web/util/NumberUtils.java     |   137 +
 .../rest/internal/web/util/ValidationUtils.java |    32 +
 .../main/webapp/WEB-INF/gemfire-api-servlet.xml |    69 +
 gemfire-web-api/src/main/webapp/WEB-INF/web.xml |    49 +
 .../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
 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                        |    25 +
 .../src/main/webapp/WEB-INF/gemfire-servlet.xml |    43 +
 gemfire-web/src/main/webapp/WEB-INF/web.xml     |    40 +
 .../internal/web/AbstractWebTestCase.java       |    88 +
 .../ShellCommandsControllerJUnitTest.java       |   206 +
 ...entVariablesHandlerInterceptorJUnitTest.java |   257 +
 .../internal/web/domain/LinkIndexJUnitTest.java |   228 +
 .../internal/web/domain/LinkJUnitTest.java      |   115 +
 .../domain/QueryParameterSourceJUnitTest.java   |    84 +
 .../web/http/ClientHttpRequestJUnitTest.java    |   501 +
 ...ableObjectHttpMessageConverterJUnitTest.java |   157 +
 .../RestHttpOperationInvokerJUnitTest.java      |   445 +
 .../SimpleHttpOperationInvokerJUnitTest.java    |   190 +
 .../web/util/ConvertUtilsJUnitTest.java         |   162 +
 .../internal/web/util/UriUtilsJUnitTest.java    |   110 +
 gradle.properties                               |     7 +
 gradle/wrapper/gradle-wrapper.jar               |   Bin 0 -> 51018 bytes
 gradle/wrapper/gradle-wrapper.properties        |     6 +
 gradlew                                         |   164 +
 gradlew.bat                                     |    90 +
 settings.gradle                                 |    10 +
 3849 files changed, 1039268 insertions(+)
----------------------------------------------------------------------



[08/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PoolImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PoolImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PoolImpl.java
new file mode 100644
index 0000000..1c22037
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PoolImpl.java
@@ -0,0 +1,1513 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+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.ConcurrentHashMap;
+import java.util.concurrent.ScheduledExecutorService;
+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.CancelCriterion;
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.StatisticsFactory;
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.NoSubscriptionServersAvailableException;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionService;
+import com.gemstone.gemfire.cache.client.Pool;
+import com.gemstone.gemfire.cache.client.ServerConnectivityException;
+import com.gemstone.gemfire.cache.client.SubscriptionNotEnabledException;
+import com.gemstone.gemfire.cache.client.internal.pooling.ConnectionManager;
+import com.gemstone.gemfire.cache.client.internal.pooling.ConnectionManagerImpl;
+import com.gemstone.gemfire.cache.query.QueryService;
+import com.gemstone.gemfire.cache.query.internal.DefaultQueryService;
+import com.gemstone.gemfire.cache.wan.GatewaySender;
+import com.gemstone.gemfire.distributed.PoolCancelledException;
+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.internal.DummyStatisticsFactory;
+import com.gemstone.gemfire.internal.ScheduledThreadPoolExecutorWithKeepAlive;
+import com.gemstone.gemfire.internal.admin.ClientStatsManager;
+import com.gemstone.gemfire.internal.cache.EventID;
+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.PoolStats;
+import com.gemstone.gemfire.internal.cache.tier.sockets.AcceptorImpl;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
+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.log4j.LocalizedMessage;
+
+/**
+ * Manages the client side of client to server connections
+ * and client queues. 
+ * 
+ * @author dsmith
+ * @since 5.7
+ */
+public class PoolImpl implements InternalPool {
+  private static final Logger logger = LogService.getLogger();
+  
+  public static final int HANDSHAKE_TIMEOUT = Long.getLong("gemfire.PoolImpl.HANDSHAKE_TIMEOUT", AcceptorImpl.DEFAULT_HANDSHAKE_TIMEOUT_MS).intValue();
+  public static final long SHUTDOWN_TIMEOUT = Long.getLong("gemfire.PoolImpl.SHUTDOWN_TIMEOUT", 30000).longValue();
+  public static final int BACKGROUND_TASK_POOL_SIZE = Integer.getInteger("gemfire.PoolImpl.BACKGROUND_TASK_POOL_SIZE", 20).intValue();
+  public static final int BACKGROUND_TASK_POOL_KEEP_ALIVE = Integer.getInteger("gemfire.PoolImpl.BACKGROUND_TASK_POOL_KEEP_ALIVE", 1000).intValue();
+  //For durable client tests only. Connection Sources read this flag
+  //and return an empty list of servers.
+  public volatile static boolean TEST_DURABLE_IS_NET_DOWN = false;
+
+  private final String name;
+  private final int freeConnectionTimeout;
+  private final int loadConditioningInterval;
+  private final int socketBufferSize;
+  private final boolean threadLocalConnections;
+  private final int readTimeout;
+  private final boolean subscriptionEnabled;
+  private final boolean prSingleHopEnabled;
+  private final int subscriptionRedundancyLevel;
+  private final int subscriptionMessageTrackingTimeout;
+  private final int subscriptionAckInterval;
+  private final String serverGroup;
+  private final List<InetSocketAddress> locators;
+  private final List<InetSocketAddress> servers;
+  private final boolean startDisabled;
+  private final boolean usedByGateway;
+  private final int maxConnections;
+  private final int minConnections;
+  private final int retryAttempts;
+  private final long idleTimeout;
+  private final long pingInterval;
+  private final int statisticInterval;
+  private final boolean multiuserSecureModeEnabled;
+
+  private final ConnectionSource source;
+  private final ConnectionManager manager;
+  private QueueManager queueManager;
+  protected final EndpointManager endpointManager;
+  private final PoolManagerImpl pm;
+  protected final InternalLogWriter securityLogWriter;
+  protected volatile boolean destroyed;
+  private final PoolStats stats;
+  private ScheduledExecutorService backgroundProcessor; 
+  private final OpExecutorImpl executor;
+  private final RegisterInterestTracker riTracker = new RegisterInterestTracker();
+  private final InternalDistributedSystem dsys; 
+
+  private final ClientProxyMembershipID proxyId;
+  protected final CancelCriterion cancelCriterion;
+  private final ConnectionFactoryImpl connectionFactory;
+
+  private final ArrayList<ProxyCache> proxyCacheList;
+  
+  private final GatewaySender gatewaySender;
+  
+  private boolean keepAlive=false;
+  private static Object simpleLock=new Object();
+
+  public static final int PRIMARY_QUEUE_NOT_AVAILABLE = -2;
+  public static final int PRIMARY_QUEUE_TIMED_OUT = -1;
+  private AtomicInteger primaryQueueSize = new AtomicInteger(PRIMARY_QUEUE_NOT_AVAILABLE);
+
+  public static PoolImpl create(PoolManagerImpl pm, String name, Pool attributes) {
+    PoolImpl pool = new PoolImpl(pm, name, attributes);
+    pool.finishCreate(pm);
+    return pool;
+  }
+  
+  public boolean isUsedByGateway() {
+    return usedByGateway;
+  }
+
+  /**
+   * @since 5.7
+   */
+  protected void finishCreate(PoolManagerImpl pm) {
+    pm.register(this);
+    try {
+      start();
+    } catch(RuntimeException e) {
+      try {
+        destroy(false);
+      } catch(RuntimeException e2) {
+        //do nothing
+      }
+      throw e;
+    }
+  }
+
+  protected PoolImpl(PoolManagerImpl pm, String name, Pool attributes) {
+  	this.pm = pm;
+    this.name = name;
+    this.freeConnectionTimeout = attributes.getFreeConnectionTimeout();
+    this.loadConditioningInterval = attributes.getLoadConditioningInterval();
+    this.socketBufferSize = attributes.getSocketBufferSize();
+    this.threadLocalConnections = attributes.getThreadLocalConnections();
+    this.readTimeout = attributes.getReadTimeout();
+    this.minConnections = attributes.getMinConnections();
+    this.maxConnections = attributes.getMaxConnections();
+    this.retryAttempts = attributes.getRetryAttempts();
+    this.idleTimeout = attributes.getIdleTimeout();
+    this.pingInterval = attributes.getPingInterval();
+    this.statisticInterval = attributes.getStatisticInterval();
+    this.subscriptionEnabled = attributes.getSubscriptionEnabled();
+    this.prSingleHopEnabled = attributes.getPRSingleHopEnabled();
+    this.subscriptionRedundancyLevel = attributes.getSubscriptionRedundancy();
+    this.subscriptionMessageTrackingTimeout = attributes.getSubscriptionMessageTrackingTimeout();
+    this.subscriptionAckInterval = attributes.getSubscriptionAckInterval();
+    this.serverGroup = attributes.getServerGroup();
+    this.multiuserSecureModeEnabled = attributes.getMultiuserAuthentication();
+    this.locators = attributes.getLocators();
+    this.servers = attributes.getServers();
+    this.startDisabled = ((PoolFactoryImpl.PoolAttributes)attributes).startDisabled
+      || !pm.isNormal();
+    this.usedByGateway = ((PoolFactoryImpl.PoolAttributes)attributes).isGateway();
+    this.gatewaySender = ((PoolFactoryImpl.PoolAttributes)attributes).getGatewaySender();
+//    if (this.subscriptionEnabled && this.multiuserSecureModeEnabled) {
+//      throw new IllegalStateException(
+//          "subscription-enabled and multiuser-authentication both cannot be true.");
+//    }
+    InternalDistributedSystem ds = InternalDistributedSystem.getAnyInstance();
+    if(ds==null) {
+      throw new IllegalStateException(LocalizedStrings.PoolImpl_DISTRIBUTED_SYSTEM_MUST_BE_CREATED_BEFORE_CREATING_POOL.toLocalizedString());
+    }
+    this.securityLogWriter = ds.getSecurityInternalLogWriter();
+    if (!ds.getConfig().getStatisticSamplingEnabled()
+        && this.statisticInterval > 0) {
+      logger.info(LocalizedMessage.create(
+              LocalizedStrings.PoolImpl_STATISTIC_SAMPLING_MUST_BE_ENABLED_FOR_SAMPLING_RATE_OF_0_TO_TAKE_AFFECT,
+              this.statisticInterval));
+    }
+    this.dsys = ds;
+    this.cancelCriterion = new Stopper();
+    if(Boolean.getBoolean("gemfire.SPECIAL_DURABLE")) {
+	    ClientProxyMembershipID.setPoolName(name);
+	    this.proxyId = ClientProxyMembershipID.getNewProxyMembership(ds);
+	    ClientProxyMembershipID.setPoolName(null);
+    } else {
+    	this.proxyId = ClientProxyMembershipID.getNewProxyMembership(ds);
+    }
+    StatisticsFactory statFactory = null;
+    if(this.gatewaySender != null){
+      statFactory = new DummyStatisticsFactory();
+    }else{
+      statFactory = ds;
+    }
+    this.stats = this.startDisabled
+      ? null
+      : new PoolStats(statFactory, getName()+"->"+(serverGroup==null || serverGroup.equals("") ? "[any servers]" : "["+getServerGroup()+"]"));
+    
+    source = getSourceImpl(((PoolFactoryImpl.PoolAttributes)attributes).locatorCallback);
+    endpointManager = new EndpointManagerImpl(name, ds,this.cancelCriterion, this.stats);
+    connectionFactory = new ConnectionFactoryImpl(source, endpointManager, ds,
+        socketBufferSize, HANDSHAKE_TIMEOUT, readTimeout, proxyId, this.cancelCriterion,
+        usedByGateway,gatewaySender, pingInterval, multiuserSecureModeEnabled, this);
+    if(subscriptionEnabled) {
+      queueManager = new QueueManagerImpl(this, endpointManager, source,
+          connectionFactory, subscriptionRedundancyLevel, pingInterval, securityLogWriter,
+          proxyId);
+    }
+    
+    manager = new ConnectionManagerImpl(name, connectionFactory, endpointManager,
+                                        maxConnections, minConnections,
+                                        idleTimeout, loadConditioningInterval,
+                                        securityLogWriter, pingInterval,
+                                        cancelCriterion, getStats());
+    //Fix for 43468 - make sure we check the cache cancel criterion if we get 
+    //an exception, by passing in the poolOrCache stopper
+    executor = new OpExecutorImpl(manager, queueManager, endpointManager,
+        riTracker, retryAttempts, freeConnectionTimeout, threadLocalConnections,
+        new PoolOrCacheStopper(), this);
+    if (this.multiuserSecureModeEnabled) {
+      this.proxyCacheList = new ArrayList<ProxyCache>();
+    } else {
+      this.proxyCacheList = null;
+    }
+  }
+
+  /**
+   * Return true if the given Pool is compatible with these attributes.
+   * Currently this does what equals would but in the future we might
+   * decide to weaken the compatibility contract.
+   * @since 6.5
+   */
+  public boolean isCompatible(Pool p) {
+    if (p == null) return false;
+    return getFreeConnectionTimeout() ==            p.getFreeConnectionTimeout()
+      && getLoadConditioningInterval() ==           p.getLoadConditioningInterval()
+      && getSocketBufferSize() ==                   p.getSocketBufferSize()
+      && getMinConnections() ==                     p.getMinConnections()
+      && getMaxConnections() ==                     p.getMaxConnections()
+      && getIdleTimeout() ==                        p.getIdleTimeout()
+      && getPingInterval() ==                       p.getPingInterval()
+      && getStatisticInterval() ==                  p.getStatisticInterval()
+      && getRetryAttempts() ==                      p.getRetryAttempts()
+      && getThreadLocalConnections() ==             p.getThreadLocalConnections()
+      && getReadTimeout() ==                        p.getReadTimeout()
+      && getSubscriptionEnabled() ==                p.getSubscriptionEnabled()
+      && getPRSingleHopEnabled() ==                 p.getPRSingleHopEnabled()
+      && getSubscriptionRedundancy() ==             p.getSubscriptionRedundancy()
+      && getSubscriptionMessageTrackingTimeout() == p.getSubscriptionMessageTrackingTimeout()
+      && getSubscriptionAckInterval() ==            p.getSubscriptionAckInterval()
+      && getServerGroup().equals(                   p.getServerGroup())
+      && getMultiuserAuthentication() ==         p.getMultiuserAuthentication()
+      && getLocators().equals(                      p.getLocators())
+      && getServers().equals(                       p.getServers());
+  }
+  
+  private void start() {
+    if (this.startDisabled) return;
+    
+    final boolean isDebugEnabled = logger.isDebugEnabled();
+    if(isDebugEnabled) {
+      List locators = getLocators();
+      if(!locators.isEmpty()) {
+        logger.debug("PoolImpl - starting pool with locators: {}", locators);
+      } else {
+        logger.debug("PoolImpl -starting pool with servers: {}", getServers());
+      }
+    }
+    
+    final String timerName = "poolTimer-" + getName() + "-";
+    backgroundProcessor = new ScheduledThreadPoolExecutorWithKeepAlive(
+        BACKGROUND_TASK_POOL_SIZE, BACKGROUND_TASK_POOL_KEEP_ALIVE,
+        TimeUnit.MILLISECONDS, new ThreadFactory() {
+      AtomicInteger threadNum = new AtomicInteger();
+      public Thread newThread(final Runnable r) {
+        Thread result = new Thread(r, timerName + threadNum.incrementAndGet());
+        result.setDaemon(true);
+        return result;
+      }
+    });
+    ((ScheduledThreadPoolExecutorWithKeepAlive) backgroundProcessor)
+        .setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
+    ((ScheduledThreadPoolExecutorWithKeepAlive) backgroundProcessor)
+    .setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+    
+    source.start(this);
+    connectionFactory.start(backgroundProcessor);
+    endpointManager.addListener(new InstantiatorRecoveryListener(backgroundProcessor, this));
+    endpointManager.addListener(new DataSerializerRecoveryListener(backgroundProcessor, this));
+    if(Boolean.getBoolean("gemfire.ON_DISCONNECT_CLEAR_PDXTYPEIDS"))
+      endpointManager.addListener(new PdxRegistryRecoveryListener(this));
+    endpointManager.addListener(new LiveServerPinger(this));
+    
+    manager.start(backgroundProcessor);
+    if(queueManager != null) {
+      if (isDebugEnabled) {
+        logger.debug("starting queueManager");
+      }
+      queueManager.start(backgroundProcessor);
+    }
+    if (isDebugEnabled) {
+      logger.debug("scheduling pings every {} milliseconds", pingInterval);
+    }
+    
+
+    if (this.statisticInterval > 0 && this.dsys.getConfig().getStatisticSamplingEnabled()) {
+      backgroundProcessor.scheduleWithFixedDelay(new PublishClientStatsTask(), statisticInterval, statisticInterval, TimeUnit.MILLISECONDS);
+    }
+    // LOG: changed from config to info
+    logger.info(LocalizedMessage.create(
+            LocalizedStrings.PoolImpl_POOL_0_STARTED_WITH_MULTIUSER_SECURE_MODE_ENABLED_1,
+            new Object[] {this.name, this.multiuserSecureModeEnabled}));
+  }
+  
+  /**
+   * Returns the cancellation criterion for this proxy
+   * @return the cancellation criterion
+   */
+  public CancelCriterion getCancelCriterion() {
+    return this.cancelCriterion;
+  }
+
+  public void releaseThreadLocalConnection() {
+    executor.releaseThreadLocalConnection();
+  }
+  
+  public void setupServerAffinity(boolean allowFailover) {
+    executor.setupServerAffinity(allowFailover);
+  }
+  
+  public void releaseServerAffinity() {
+    executor.releaseServerAffinity();
+  }
+  
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.Pool#getName()
+   */
+  public String getName() {
+    return this.name;
+  }
+  public int getFreeConnectionTimeout() {
+    return this.freeConnectionTimeout;
+  }
+  public int getLoadConditioningInterval() {
+    return this.loadConditioningInterval;
+  }
+  public int getMaxConnections() {
+    return maxConnections;
+  }
+  public int getMinConnections() {
+    return minConnections;
+  }
+  public int getRetryAttempts() {
+    return retryAttempts;
+  }
+  public long getIdleTimeout() {
+    return idleTimeout;
+  }
+  public long getPingInterval() {
+    return pingInterval;
+  }
+  public int getStatisticInterval() {
+    return this.statisticInterval;
+  }
+  public int getSocketBufferSize() {
+    return this.socketBufferSize;
+  }
+  public boolean getThreadLocalConnections() {
+    return this.threadLocalConnections;
+  }
+  public int getReadTimeout() {
+    return this.readTimeout;
+  }
+  public boolean getSubscriptionEnabled() {
+    return this.subscriptionEnabled;
+  }
+  
+  public boolean getPRSingleHopEnabled() {
+    return this.prSingleHopEnabled;
+  }
+  
+  public int getSubscriptionRedundancy() {
+    return this.subscriptionRedundancyLevel;
+  }
+  public int getSubscriptionMessageTrackingTimeout() {
+    return this.subscriptionMessageTrackingTimeout;
+  }
+  public int getSubscriptionAckInterval() {
+    return subscriptionAckInterval;
+  }
+  public String getServerGroup() {
+    return this.serverGroup;
+  }
+
+  public boolean getMultiuserAuthentication() {
+    return this.multiuserSecureModeEnabled;
+  }
+
+  public List<InetSocketAddress> getLocators() {
+    return this.locators;
+  }
+  public List<InetSocketAddress> getServers() {
+    return this.servers;
+  }
+
+  public GatewaySender getGatewaySender() {
+    return gatewaySender;
+  }
+  
+  public InternalLogWriter getSecurityInternalLogWriter() {
+    return this.securityLogWriter;
+  }
+  
+  public void destroy() {
+    destroy(false);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder(100);
+    sb.append(this.getClass().getSimpleName()).append('@')
+        .append(System.identityHashCode(this)).append(" name=")
+        .append(getName());
+    return sb.toString();
+  }
+
+  public boolean getKeepAlive(){
+      return this.keepAlive;
+  }
+  
+  public void destroy(boolean keepAlive) {
+    int cnt = getAttachCount();
+    this.keepAlive = keepAlive;
+    boolean SPECIAL_DURABLE = Boolean.getBoolean("gemfire.SPECIAL_DURABLE");
+        if (cnt > 0) {
+        //special case to allow closing durable client pool under the keep alive flag
+            //closing regions prior to closing pool can cause them to unregister interest
+            if (SPECIAL_DURABLE) {
+                synchronized (simpleLock) {
+                    try {
+                        if (!CacheFactory.getAnyInstance().isClosed() && this.getPoolOrCacheCancelInProgress() == null) {
+                            Set<Region<?, ?>> regions = CacheFactory.getInstance(dsys).rootRegions();
+                            for (Region<?, ?> roots : regions) {
+                                Set<Region<?, ?>> subregions = roots.subregions(true);
+                                for (Region<?, ?> subroots : subregions) {
+                                    if (!subroots.isDestroyed() &&  subroots.getAttributes().getPoolName() != null
+                                            && subroots.getAttributes().getPoolName().equals(this.name) ) {
+                                        if (logger.isDebugEnabled()) {
+                                            logger.debug("PoolImpl.destroy[ Region connected count:{} Region subroot closing:{} Pool Name:{} ]", cnt, subroots.getName(), this.name);
+                                        }
+                                        subroots.close();
+                                    }
+                                }
+
+                                if (!roots.isDestroyed() && roots.getAttributes().getPoolName() != null
+                                        && roots.getAttributes().getPoolName().equals(this.name)) {
+                                    if (logger.isDebugEnabled()) {
+                                        logger.debug("PoolImpl.destroy[ Region connected count:{} Region root closing:{} Pool Name:{} ]", cnt, roots.getName(), this.name);
+                                    }
+                                    roots.close();
+                                }
+                            }
+                        }
+                    } catch (CacheClosedException ccex) {
+                      if (logger.isDebugEnabled()) {
+                        logger.debug(ccex.getMessage(), ccex);
+                      }
+                    } catch (Exception ex) {
+                      if (logger.isDebugEnabled()) {
+                        logger.debug(ex.getMessage(), ex);
+                      }
+                    }
+                }
+            } //end special case
+        
+            cnt = getAttachCount();
+    if (cnt > 0) {
+      throw new IllegalStateException( LocalizedStrings.PoolImpl_POOL_COULD_NOT_BE_DESTROYED_BECAUSE_IT_IS_STILL_IN_USE_BY_0_REGIONS.toLocalizedString(Integer.valueOf(cnt)));
+    }
+        }
+    if (this.pm.unregister(this)) {
+      basicDestroy(keepAlive);
+    }
+  }
+
+  /**
+   * Destroys this pool but does not unregister it.
+   * This is used by the PoolManagerImpl when it wants to close all its pools.
+   */
+  public synchronized void basicDestroy(boolean keepAlive) {
+    if (!isDestroyed()) {
+      this.destroyed = true;
+      // LOG: changed from config to info
+      logger.info(LocalizedMessage.create(LocalizedStrings.PoolImpl_DESTROYING_CONNECTION_POOL_0, name));
+
+      try {
+        if (backgroundProcessor != null) {
+          backgroundProcessor.shutdown();
+          if(!backgroundProcessor.awaitTermination(SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS)) {
+            logger.warn(LocalizedMessage.create(LocalizedStrings.PoolImpl_TIMEOUT_WAITING_FOR_BACKGROUND_TASKS_TO_COMPLETE));
+          }
+        }
+      } catch(RuntimeException e) {
+        logger.error(LocalizedMessage.create(LocalizedStrings.PoolImpl_ERROR_ENCOUNTERED_WHILE_STOPPING_BACKGROUNDPROCESSOR), e);
+      } catch(InterruptedException e) {
+        logger.error(LocalizedMessage.create(LocalizedStrings.PoolImpl_INTERRUPTED_WHILE_STOPPING_BACKGROUNDPROCESSOR), e);
+      }
+
+      try {
+        if (this.source != null) {
+          this.source.stop();
+        }
+      } catch(RuntimeException e) {
+        logger.error(LocalizedMessage.create(LocalizedStrings.PoolImpl_ERROR_ENCOUNTERED_WHILE_STOPPING_CONNECTION_SOURCE), e);
+      } 
+
+      try {
+        if(this.manager != null) {
+          manager.close(keepAlive);
+        }
+      } catch(RuntimeException e) {
+        logger.error(LocalizedMessage.create(LocalizedStrings.PoolImpl_ERROR_ENCOUNTERED_WHILE_STOPPING_CONNECTION_MANAGER), e);
+      }
+      
+      try {
+        if(this.queueManager != null) {
+          queueManager.close(keepAlive);
+        }
+      } catch(RuntimeException e) {
+        logger.error(LocalizedMessage.create(LocalizedStrings.PoolImpl_ERROR_ENCOUNTERED_WHILE_STOPPING_SUBSCRIPTION_MANAGER), e);
+      }
+      
+      try {
+        endpointManager.close();
+      } catch(RuntimeException e) {
+        logger.error(LocalizedMessage.create(LocalizedStrings.PoolImpl_ERROR_ENCOUNTERED_WHILE_STOPPING_ENDPOINT_MANAGER), e);
+      }
+
+      try {
+        if(this.stats!=null) {
+          this.stats.close();
+        }
+      } catch(RuntimeException e) {
+        logger.error(LocalizedMessage.create(LocalizedStrings.PoolImpl_ERROR_WHILE_CLOSING_STATISTICS), e);
+      }
+    }
+  }
+  
+  public boolean isDestroyed() {
+    return destroyed;
+  }
+  
+  
+  private ConnectionSource getSourceImpl(LocatorDiscoveryCallback locatorDiscoveryCallback) {
+    List<InetSocketAddress> locators = getLocators();
+    if (locators.isEmpty()) {
+      return new ExplicitConnectionSourceImpl(getServers());
+    }
+    else {
+      AutoConnectionSourceImpl source = new AutoConnectionSourceImpl(locators,
+          getServerGroup(), HANDSHAKE_TIMEOUT);
+      if(locatorDiscoveryCallback != null) {
+        source.setLocatorDiscoveryCallback(locatorDiscoveryCallback);
+      }
+      return source;
+    }
+  }
+  /**
+   * Used internally by xml parsing code.
+   */
+  public void sameAs(Object obj) {
+    if (!(obj instanceof PoolImpl)) {
+      throw new RuntimeException( 
+          LocalizedStrings.PoolImpl__0_IS_NOT_THE_SAME_AS_1_BECAUSE_IT_SHOULD_HAVE_BEEN_A_POOLIMPL
+          .toLocalizedString(new Object[] {this, obj}));
+    }
+    PoolImpl other = (PoolImpl)obj;
+    if (!getName().equals(other.getName())) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_ARE_DIFFERENT.toLocalizedString("names"));
+    }
+    if (getFreeConnectionTimeout() != other.getFreeConnectionTimeout()) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_IS_DIFFERENT.toLocalizedString("connectionTimeout"));
+    }
+    if (getLoadConditioningInterval() != other.getLoadConditioningInterval()) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_IS_DIFFERENT.toLocalizedString("connectionLifetime"));
+    }
+    if (getSocketBufferSize() != other.getSocketBufferSize()) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_IS_DIFFERENT.toLocalizedString("socketBufferSize"));
+    }
+    if (getThreadLocalConnections() != other.getThreadLocalConnections()) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_IS_DIFFERENT.toLocalizedString("threadLocalConnections"));
+    }
+    if (getReadTimeout() != other.getReadTimeout()) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_IS_DIFFERENT.toLocalizedString("readTimeout"));
+    }
+    if (getMinConnections() != other.getMinConnections()) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_IS_DIFFERENT.toLocalizedString("MinConnections"));
+    }
+    if (getMaxConnections() != other.getMaxConnections()) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_IS_DIFFERENT.toLocalizedString("MaxConnections"));
+    }
+    if (getRetryAttempts() != other.getRetryAttempts()) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_IS_DIFFERENT.toLocalizedString("RetryAttempts"));
+    }
+    if (getIdleTimeout() != other.getIdleTimeout()) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_IS_DIFFERENT.toLocalizedString("IdleTimeout"));
+    }
+    if (getPingInterval() != other.getPingInterval()) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_IS_DIFFERENT.toLocalizedString("PingInterval"));
+    }
+    if (getStatisticInterval() != other.getStatisticInterval()) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_IS_DIFFERENT.toLocalizedString("StatisticInterval"));
+    }
+    if (getSubscriptionAckInterval() != other.getSubscriptionAckInterval()) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_IS_DIFFERENT.toLocalizedString("subscriptionAckInterval"));
+    }
+    if (getSubscriptionEnabled() != other.getSubscriptionEnabled()) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_IS_DIFFERENT.toLocalizedString("subscriptionEnabled"));
+    }
+    if (getSubscriptionMessageTrackingTimeout() != other.getSubscriptionMessageTrackingTimeout()) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_IS_DIFFERENT.toLocalizedString("subscriptionMessageTrackingTimeout"));
+    }
+    if (getSubscriptionRedundancy() != other.getSubscriptionRedundancy()) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_IS_DIFFERENT.toLocalizedString("subscriptionRedundancyLevel"));
+    }
+    if (!getServerGroup().equals(other.getServerGroup())) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_IS_DIFFERENT.toLocalizedString("serverGroup"));
+    }
+    if (!getLocators().equals(other.getLocators())) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_ARE_DIFFERENT.toLocalizedString("locators"));
+    }
+    if (!getServers().equals(other.getServers())) {
+      throw new RuntimeException(
+          LocalizedStrings.PoolImpl_0_ARE_DIFFERENT.toLocalizedString("servers"));
+    }
+    // ignore startDisabled
+  }
+  
+  public PoolStats getStats() {
+    return this.stats;
+  }
+
+
+  /**
+   * Execute the given op on the servers that this pool connects to.
+   * This method is responsible for retrying the op if an attempt fails.
+   * It will only execute it once and on one server.
+   * @param op the operation to execute
+   * @return the result of execution if any; null if not
+   * @since 5.7
+   */
+  public Object execute(Op op) {
+    //if(multiuser)
+    //get a server from threadlocal cache else throw cacheWriterException 
+    //executeOn(ServerLocation server, Op op, boolean accessed,boolean onlyUseExistingCnx)
+
+    // Retries are ignored here. FIX IT - FIXED.
+    // But this may lead to a user getting authenticated on all servers, even if
+    // a single server could have serviced all its requests.
+    authenticateIfRequired(op);
+    return executor.execute(op);
+  }
+
+  /**
+   * Execute the given op on the servers that this pool connects to.
+   * This method is responsible for retrying the op if an attempt fails.
+   * It will only execute it once and on one server.
+   * @param op the operation to execute
+   * @param retries how many times to retry the operation
+   * @return the result of execution if any; null if not
+   * @since 5.7
+   */
+  public Object execute(Op op, int retries) {
+    authenticateIfRequired(op);
+    return executor.execute(op, retries);
+  }
+
+  /**
+   * Execute the given op on the given server.
+   * @param server the server to do the execution on
+   * @param op the operation to execute
+   * @return the result of execution if any; null if not
+   */
+  public Object executeOn(ServerLocation server, Op op) {
+    authenticateIfRequired(server, op);
+    return executor.executeOn(server, op);
+  }
+  /**
+   * Execute the given op on the given server.
+   * @param server the server to do the execution on
+   * @param op the operation to execute
+   * @param accessed true if the connection is accessed by this execute
+   * @return the result of execution if any; null if not
+   */
+  public Object executeOn(ServerLocation server, Op op, boolean accessed,boolean onlyUseExistingCnx) {
+    authenticateIfRequired(server, op);
+    return executor.executeOn(server, op, accessed,onlyUseExistingCnx);
+  }
+  
+  /**
+   * Execute the given op on the given connection.
+   * @param con the connection to do the execution on
+   * @param op the operation to execute
+   * @return the result of execution if any; null if not
+   */
+  public Object executeOn(Connection con, Op op) {
+    authenticateIfRequired(con.getServer(), op);
+    return executor.executeOn(con, op);
+  }
+
+  public Object executeOn(Connection con, Op op, boolean timeoutFatal) {
+    return executor.executeOn(con, op, timeoutFatal);
+  }
+
+  /**
+   * Execute the given op on all the servers that have server-to-client
+   * queues for this pool
+   * @param op the operation to execute
+   * @return the result of execution if any; null if not
+   * @since 5.7
+   */
+  public Object executeOnQueuesAndReturnPrimaryResult(Op op) {
+    authenticateOnAllServers(op);
+    return executor.executeOnQueuesAndReturnPrimaryResult(op);
+  }
+
+  public void executeOnAllQueueServers(Op op)
+    throws NoSubscriptionServersAvailableException, SubscriptionNotEnabledException {
+    authenticateOnAllServers(op);
+    executor.executeOnAllQueueServers(op);
+  }
+
+  /**
+   * Execute the given op on the current primary server.
+   * @param op the operation to execute
+   * @return the result of execution if any; null if not
+   */
+  public Object executeOnPrimary(Op op) {
+    return executor.executeOnPrimary(op);
+  }
+  
+  public Map<ServerLocation, Endpoint> getEndpointMap() {
+    return endpointManager.getEndpointMap();
+  }
+  
+  public ScheduledExecutorService getBackgroundProcessor() {
+    return backgroundProcessor;
+  }
+  
+  public RegisterInterestTracker getRITracker() {
+    return this.riTracker;
+  }
+
+  /**
+   * Test hook that returns the number of servers we currently have connections to.
+   */
+  public int getConnectedServerCount() {
+    return this.endpointManager.getConnectedServerCount();
+  }
+  /**
+   * Test hook.
+   * Verify if this EventId is already present in the map or not. If it is
+   * already present then return true.
+   *
+   * @param eventId the EventId of the incoming event
+   * @return true if it is already present
+   * @since 5.1
+   */
+  public boolean verifyIfDuplicate(EventID eventId) {
+    return ((QueueStateImpl)this.queueManager.getState()).verifyIfDuplicate(eventId);
+  }
+
+  public boolean verifyIfDuplicate(EventID eventId, boolean addToMap) {
+    return ((QueueStateImpl)this.queueManager.getState()).verifyIfDuplicate(eventId);
+  }
+
+  /**
+   * Borrows a connection from the pool.. Used by gateway and tests.
+   * Any connection that is acquired using this method must be returned using
+   * returnConnection, even if it is destroyed.
+   * 
+   * TODO - The use of the this method should be removed
+   * from the gateway code. This method is fine for tests,
+   * but these connections should really be managed inside
+   * the pool code. If the gateway needs to persistent connection
+   * to a single server, which should create have the OpExecutor
+   * that holds a reference to the connection (similar to the way
+   * we do with thread local connections).
+   * TODO use {@link ExecutablePool#setupServerAffinity(boolean)} for
+   * gateway code
+   */
+  public Connection acquireConnection() {
+    return manager.borrowConnection(45000L);
+  }
+  
+  /**
+   * Hook to return connections that were acquired using 
+   * acquireConnection.
+   * @param conn
+   */
+  public void returnConnection(Connection conn) {
+    manager.returnConnection(conn);
+  }
+  
+  /**
+   * Test hook that acquires and returns a connection from the pool with a given ServerLocation.
+   */
+  public Connection acquireConnection(ServerLocation loc) {
+    return manager.borrowConnection(loc,15000L,false);
+  }
+
+  /**
+   * Test hook that returns an unnmodifiable list of the current blacklisted servers
+   */
+  public Set getBlacklistedServers() {
+    return connectionFactory.getBlackList().getBadServers();
+  }
+  /**
+   * Test hook to handle an exception that happened on the given connection
+   */
+  public void processException(Throwable e, Connection con) {
+    executor.handleException(e, con, 0, false);
+  }
+  /**
+   * Test hook that returns the ThreadIdToSequenceIdMap
+   */
+  public Map getThreadIdToSequenceIdMap() {
+    if (this.queueManager == null) return Collections.EMPTY_MAP;
+    if (this.queueManager.getState() == null) return Collections.EMPTY_MAP;
+    return this.queueManager.getState().getThreadIdToSequenceIdMap();
+  }
+  
+  /**
+   * Test hook that returns true if we have a primary and its updater thread
+   * is alive.
+   */
+  public boolean isPrimaryUpdaterAlive() {
+    return ((QueueManagerImpl)this.queueManager).isPrimaryUpdaterAlive();
+  }
+  /**
+   * Test hook used to simulate a kill of the primaryEndpoint
+   */
+  public void killPrimaryEndpoint() //throws ServerException
+  {
+    boolean ok = false;
+    if (this.queueManager != null) {
+      QueueManager.QueueConnections cons = this.queueManager.getAllConnections();
+      Connection con = cons.getPrimary();
+      if (con != null) {
+        final String msg = "killing primary endpoint";
+        logger.info("<ExpectedException action=add>{}</ExpectedException>", msg);
+        Exception e = new Exception(msg);
+        try {
+          processException(e, con);
+        } catch (ServerConnectivityException expected) {
+        } finally {
+          logger.info("<ExpectedException action=remove>{}</ExpectedException>", msg);
+        }
+        // do some validation here that we are no longer connected to "sl"
+        ok = true;
+      }
+    }
+    if (!ok) {
+      throw new IllegalStateException("primaryEndpoint was null");
+    }
+  }
+
+  // Pool that are declared in a cache.xml will set this property to true.
+  private boolean declaredInXML;
+
+  public void setDeclaredInXML(boolean v) {
+    this.declaredInXML = v;
+  }
+  public boolean getDeclaredInXML() {
+    return this.declaredInXML;
+  }
+
+  // used by unit tests to confirm if readyForEvents has been called on a pool
+  private boolean readyForEventsCalled;
+
+  public boolean getReadyForEventsCalled() {
+    return this.readyForEventsCalled;
+  }
+  
+  public void readyForEvents(InternalDistributedSystem system) {
+    if(!isDurableClient() || queueManager == null) {
+      return;
+    }
+    this.readyForEventsCalled = true;
+    queueManager.readyForEvents(system);
+    
+  }
+  
+  public boolean isDurableClient() {
+    boolean isDurable = false;
+    InternalDistributedSystem system = InternalDistributedSystem.getAnyInstance();
+    DistributionConfig config = system.getConfig();
+    String durableClientId = config.getDurableClientId();
+    isDurable = durableClientId != null && durableClientId.length() > 0;
+    return isDurable;
+  }
+  
+  /**
+   * Test hook that returns a string consisting of the host name and port of the primary server.
+   * Null is returned if we have no primary.
+   */
+  public String getPrimaryName() {
+    String result = null;
+    ServerLocation sl = getPrimary();
+    if (sl != null) {
+      result = sl.getHostName() + sl.getPort();
+    }
+    return result;
+  }
+  /**
+   * Test hook that returns an int which the port of the primary server.
+   * -1 is returned if we have no primary.
+   */
+  public int getPrimaryPort() {
+    int result = -1;
+    ServerLocation sl = getPrimary();
+    if (sl != null) {
+      result = sl.getPort();
+    }
+    return result;
+  }
+  /**
+   * Test hook that returns a string consisting of the host name and port of the primary server.
+   * Null is returned if we have no primary.
+   */
+  public ServerLocation getPrimary() {
+    ServerLocation result = null;
+    if (this.queueManager != null) {
+      QueueManager.QueueConnections cons = this.queueManager.getAllConnections();
+      Connection con = cons.getPrimary();
+      result = con.getServer();
+    }
+    return result;
+  }
+  
+  /**
+   * Test hook to get a connection to the primary server.
+   */
+  public Connection getPrimaryConnection() {
+    if (this.queueManager != null) {
+      QueueManager.QueueConnections cons = this.queueManager.getAllConnections();
+      return cons.getPrimary();
+    }
+    return null;
+  }
+  
+  /**
+   * Test hook that returns a list of strings. Each string consists of the host name and port of a redundant server.
+   * An empty list is returned if we have no redundant servers.
+   */
+  public List<String> getRedundantNames() {
+    List result = Collections.EMPTY_LIST;
+    if (this.queueManager != null) {
+      QueueManager.QueueConnections cons = this.queueManager.getAllConnections();
+      List<Connection> backupCons = cons.getBackups();
+      if (backupCons.size() > 0) {
+        result = new ArrayList(backupCons.size());
+        Iterator<Connection> it = backupCons.iterator();
+        while (it.hasNext()) {
+          Connection con = it.next();
+          ServerLocation sl = con.getServer();
+          result.add(sl.getHostName() + sl.getPort());
+        }
+      }
+    }
+    return result;
+  }
+  /**
+   * Test hook that returns a list of ServerLocation instances.
+   * Each ServerLocation describes a redundant server.
+   * An empty list is returned if we have no redundant servers.
+   */
+  public List<ServerLocation> getRedundants() {
+    List result = Collections.EMPTY_LIST;
+    if (this.queueManager != null) {
+      QueueManager.QueueConnections cons = this.queueManager.getAllConnections();
+      List<Connection> backupCons = cons.getBackups();
+      if (backupCons.size() > 0) {
+        result = new ArrayList(backupCons.size());
+        Iterator<Connection> it = backupCons.iterator();
+        while (it.hasNext()) {
+          Connection con = it.next();
+          result.add(con.getServer());
+        }
+      }
+    }
+    return result;
+  }
+  /**
+   * Test hook to find out current number of connections this pool has.
+   */
+  public int getConnectionCount() {
+    return manager.getConnectionCount();
+  }
+  
+  /**
+   * Atomic counter used to keep track of services using this pool.
+   * @since 5.7
+   */
+  private final AtomicInteger attachCount = new AtomicInteger();
+  public static volatile boolean IS_INSTANTIATOR_CALLBACK = false ;
+
+  /**
+   * Returns number of services currently using/attached to this pool.
+   * <p>Made public so it can be used by tests
+   * @since 5.7
+   */
+  public int getAttachCount() {
+    return this.attachCount.get();
+  }
+  /**
+   * This needs to be called when a service (like a Region or CQService)
+   * starts using a pool.
+   * @since 5.7
+   */
+  public void attach() {
+    this.attachCount.getAndIncrement();
+  }
+  /**
+   * This needs to be called when a service (like a Region or CQService)
+   * stops using a pool.
+   * @since 5.7
+   */
+  public void detach() {
+    this.attachCount.getAndDecrement();
+  }
+
+  /**
+   * Get the connection held by this thread
+   * if we're using thread local connections
+   * 
+   * This is a a hook for hydra code to pass
+   * thread local connections between threads.
+   * @return the connection from the thread local,
+   * or null if there is no thread local connection.
+   */
+  public Connection getThreadLocalConnection() {
+    return executor.getThreadLocalConnection();
+  }
+
+  /**
+   * Returns a list of ServerLocation instances;
+   * one for each server we are currently connected to.
+   */
+  public List<ServerLocation> getCurrentServers() {
+    ArrayList result = new ArrayList();
+    Map endpointMap = endpointManager.getEndpointMap();
+    result.addAll(endpointMap.keySet());
+    return result;
+  }
+  /**
+   * Test hook that returns a list of server names (host+port);
+   * one for each server we are currently connected to.
+   */
+  public List<String> getCurrentServerNames() {
+    List<ServerLocation> servers = getCurrentServers();
+    ArrayList<String> result = new ArrayList(servers.size());
+    Iterator it = servers.iterator();
+    while (it.hasNext()) {
+      ServerLocation sl = (ServerLocation)it.next();
+      String name = sl.getHostName() + sl.getPort();
+      result.add(name);
+    }
+    return result;
+  }
+  
+  public EndpointManager getEndpointManager() {
+    return endpointManager;
+  }
+
+  /**
+   * Fetch the connection source for this pool
+   * @return the source
+   */
+  public ConnectionSource getConnectionSource() {
+    return source;
+  }
+
+  private static void setTEST_DURABLE_IS_NET_DOWN(boolean v) {
+    TEST_DURABLE_IS_NET_DOWN = v;
+  }
+  
+  /**
+   * test hook
+   */
+  public void endpointsNetDownForDUnitTest() {
+    logger.debug("PoolImpl - endpointsNetDownForDUnitTest");
+    setTEST_DURABLE_IS_NET_DOWN(true);
+    try {
+      java.lang.Thread.sleep(this.pingInterval * 2);
+    }
+    catch (java.lang.InterruptedException ex) {
+      // do nothing.
+    }
+    
+    Map endpoints = endpointManager.getEndpointMap();
+    for(Iterator itr = endpoints.values().iterator(); itr.hasNext();) {
+      Endpoint endpoint = (Endpoint) itr.next();
+      logger.debug("PoolImpl Simulating crash of endpoint {}", endpoint);
+      endpointManager.serverCrashed(endpoint);
+    }
+  }
+  /**
+   * test hook
+   */
+  public void endpointsNetUpForDUnitTest() {
+    setTEST_DURABLE_IS_NET_DOWN(false);
+    try {
+      java.lang.Thread.sleep(this.pingInterval * 2);
+    }
+    catch (java.lang.InterruptedException ex) {
+      // do nothing.
+    }
+  }
+  /**
+   * test hook
+   */
+  public int getInvalidateCount() {
+    return ((QueueStateImpl)this.queueManager.getState()).getInvalidateCount();
+  }
+  /**
+   * Set the connection held by this thread
+   * if we're using thread local connections
+   * 
+   * This is a a hook for hydra code to pass
+   * thread local connections between threads.
+   */
+  public void setThreadLocalConnection(Connection conn) {
+    executor.setThreadLocalConnection(conn);
+  }
+  
+  public ServerLocation getServerAffinityLocation() {
+    return executor.getServerAffinityLocation();
+  }
+  
+  public void setServerAffinityLocation(ServerLocation serverLocation) {
+    executor.setServerAffinityLocation(serverLocation);
+  }
+  
+  public ServerLocation getNextOpServerLocation() {
+    return executor.getNextOpServerLocation();
+  }
+  
+  /**
+   * Test hook for getting the client proxy membership id from this proxy.
+   */
+  public ClientProxyMembershipID getProxyID() {
+    return proxyId;
+  }
+  
+
+  public void emergencyClose() {
+    destroyed = true;
+    manager.emergencyClose();
+    queueManager.emergencyClose();
+  }
+  
+  ///////////////////// start test hooks ///////////////////////
+  /**
+   * A debug flag used for testing used in BridgeObserver
+   */
+  public static volatile boolean AFTER_PRIMARY_IDENTIFICATION_FROM_BACKUP_CALLBACK_FLAG = false;
+
+  /**
+   * A debug flag used for testing used in BridgeObserver
+   */
+  public static volatile boolean BEFORE_REGISTER_CALLBACK_FLAG = false;
+
+  /**
+   * A debug flag used for testing used in BridgeObserver
+   */
+  public static volatile boolean BEFORE_RECOVER_INTERST_CALLBACK_FLAG = false;
+
+  /**
+   * A debug flag used for testing used in BridgeObserver
+   */
+  public static volatile boolean AFTER_REGISTER_CALLBACK_FLAG = false;
+
+  /**
+   * A debug flag used for testing used in BridgeObserver
+   */
+  public static volatile boolean BEFORE_PRIMARY_IDENTIFICATION_FROM_BACKUP_CALLBACK_FLAG = false;
+
+  /**
+   * A debug flag used for testing used in BridgeObserver
+   */
+  public static volatile boolean BEFORE_SENDING_CLIENT_ACK_CALLBACK_FLAG = false;
+  /**
+   * A debug flag used for testing used in BridgeObserver
+   */  
+  public static volatile boolean AFTER_QUEUE_DESTROY_MESSAGE_FLAG = false;
+  
+  /**
+   * Test hook flag to notify observer(s) that a primary is recovered
+   * either from a backup or from a new connection.
+   */
+  public static volatile boolean AFTER_PRIMARY_RECOVERED_CALLBACK_FLAG = false;
+  
+  public static abstract class PoolTask implements Runnable {
+    
+    public final void run() {
+      try {
+        run2();
+      } catch(VirtualMachineError e) {
+        SystemFailure.initiateFailure(e);
+        throw e;
+      } 
+      catch (CancelException e) {
+//        throw e;
+        if (logger.isDebugEnabled()) {
+          logger.debug("Pool task <{}> cancelled", this, logger.isTraceEnabled() ? e : null);
+        }
+      } catch(Throwable t) {
+        logger.error(LocalizedMessage.create(LocalizedStrings.PoolImpl_UNEXPECTED_ERROR_IN_POOL_TASK_0, this), t);
+      }
+      
+    }
+    
+    public abstract void run2();
+  }
+  
+  ///////////////////// end test hooks ///////////////////////
+
+  protected class PublishClientStatsTask extends PoolTask {
+    @Override
+    public void run2() {
+      ClientStatsManager.publishClientStats(PoolImpl.this);
+    }
+  }
+  
+  /**
+   * A cancel criterion that checks both the pool and the cache
+   * for canceled status.
+   */
+  protected class PoolOrCacheStopper extends CancelCriterion {
+
+    @Override
+    public String cancelInProgress() {
+      return getPoolOrCacheCancelInProgress();
+    }
+    
+    @Override
+    public RuntimeException generateCancelledException(Throwable e) {
+      return generatePoolOrCacheCancelledException(e);
+    }
+    
+  }
+
+  /**
+   * A cancel criterion that checks only if this pool has been
+   * closed. This is necessary because there are some things that
+   * we want to allow even after the cache has started closing.
+   */
+  protected class Stopper extends CancelCriterion {
+
+    @Override
+    public String cancelInProgress() {
+      if(destroyed) {
+        return "Pool " + PoolImpl.this + " is shut down";
+      } else {
+        return null;
+      }
+    }
+
+    @Override
+    public RuntimeException generateCancelledException(Throwable t) {
+      String reason = cancelInProgress();
+      if (reason == null) {
+        return null;
+      }
+      return new PoolCancelledException(reason, t);
+    }
+  }
+
+  public static void loadEmergencyClasses() {
+    QueueManagerImpl.loadEmergencyClasses();
+    ConnectionManagerImpl.loadEmergencyClasses();
+    EndpointManagerImpl.loadEmergencyClasses();
+  }
+  
+  /**
+   * Returns the QueryService, that can be used to execute Query functions on 
+   * the servers associated with this pool.
+   * @return the QueryService 
+   */
+  public QueryService getQueryService() {
+    Cache cache = CacheFactory.getInstance(InternalDistributedSystem.getAnyInstance());
+    DefaultQueryService queryService = new DefaultQueryService((InternalCache) cache);
+    queryService.setPool(this);
+    return queryService;
+  }
+
+  public RegionService createAuthenticatedCacheView(Properties properties) {
+    if (!this.multiuserSecureModeEnabled) {
+      throw new UnsupportedOperationException(
+          "Operation not supported when multiuser-authentication is false.");
+    }
+    if (properties == null || properties.isEmpty()) {
+      throw new IllegalArgumentException("Security properties cannot be empty.");
+    }
+    Cache cache = CacheFactory.getInstance(InternalDistributedSystem
+        .getAnyInstance());
+
+    Properties props = new Properties();
+    for (Entry<Object, Object> entry : properties.entrySet()) {
+      props.setProperty((String)entry.getKey(), (String)entry.getValue());
+    }
+    ProxyCache proxy = new ProxyCache(props, (GemFireCacheImpl)cache, this);
+    synchronized (this.proxyCacheList) {
+      this.proxyCacheList.add(proxy);
+    }
+    return proxy;
+  }
+
+  private volatile CancelCriterion cacheCriterion = null;
+  
+  private RuntimeException generatePoolOrCacheCancelledException(Throwable e) {
+    RuntimeException re = getCancelCriterion().generateCancelledException(e);
+    if(re != null) {
+      return re;
+    }
+    Cache cache = GemFireCacheImpl.getInstance();
+    if (cache == null) {
+      if (cacheCriterion != null) {
+        return cacheCriterion.generateCancelledException(e);
+      }
+    } else {
+      if (cacheCriterion == null) {
+        cacheCriterion = cache.getCancelCriterion();
+      } else if (cacheCriterion != cache.getCancelCriterion()) {
+        /*
+         * If the cache instance has somehow changed, we need to get a reference
+         * to the new criterion. This is pretty unlikely because the cache
+         * closes all the pools when it shuts down, but I wanted to be safe.
+         */
+        cacheCriterion = cache.getCancelCriterion();
+      }
+      return cacheCriterion.generateCancelledException(e);
+    }
+    return null;
+  }
+
+  public String getPoolOrCacheCancelInProgress() {
+    String reason = null;
+    try {
+      reason = getCancelCriterion().cancelInProgress();
+      if(reason!=null) {
+        return reason;
+      }
+      Cache cache = GemFireCacheImpl.getInstance();
+      if(cache==null) {
+         if(cacheCriterion!=null) {
+            return cacheCriterion.cancelInProgress();
+	 }
+         return null;
+      } else {
+        if(cacheCriterion==null) {
+	  cacheCriterion = cache.getCancelCriterion();
+	} else if(cacheCriterion!=cache.getCancelCriterion()) {
+	  /* 
+	  If the cache instance has somehow changed, we need to 
+	  get a reference to the new criterion. This is pretty unlikely
+	  because the cache closes all the pools when it shuts down,
+	  but I wanted to be safe.
+	  */
+	  cacheCriterion = cache.getCancelCriterion();
+	}
+        return cacheCriterion.cancelInProgress();  
+      }
+    } catch(CancelException cce) {
+      if(cce.getMessage()!=null) {
+        return cce.getMessage();
+      } else {
+        return "cache is closed";
+      }
+    } 
+  }
+
+  public ArrayList<ProxyCache> getProxyCacheList() {
+    return this.proxyCacheList;
+  }
+
+  private void authenticateIfRequired(Op op) {
+    authenticateIfRequired(null, op);
+  }
+
+  /**
+   * Assert thread-local var is not null, if it has
+   * multiuser-authentication set to true.
+   * 
+   * If serverLocation is non-null, check if the the user is authenticated on
+   * that server. If not, authenticate it and return.
+   * 
+   * @param serverLocation
+   * @param op
+   */
+  private void authenticateIfRequired(ServerLocation serverLocation, Op op) {
+    if (this.multiuserSecureModeEnabled && op instanceof AbstractOp
+        && ((AbstractOp)op).needsUserId()) {
+      UserAttributes userAttributes = UserAttributes.userAttributes.get();
+      if (userAttributes == null) {
+        throw new UnsupportedOperationException(LocalizedStrings.MultiUserSecurityEnabled_USE_POOL_API.toLocalizedString());
+      }
+      if (serverLocation != null) {
+        if (!userAttributes.getServerToId().containsKey(serverLocation)) {
+          Long userId = (Long)AuthenticateUserOp.executeOn(serverLocation,
+              this, userAttributes.getCredentials());
+          if (userId != null) {
+            userAttributes.setServerToId(serverLocation, userId);
+          }
+        }
+      }
+    }
+  }
+
+  private void authenticateOnAllServers(Op op) {
+    if (this.multiuserSecureModeEnabled && ((AbstractOp)op).needsUserId()) {
+      UserAttributes userAttributes = UserAttributes.userAttributes.get();
+      if (userAttributes != null) {
+        ConcurrentHashMap<ServerLocation, Long> map = userAttributes
+            .getServerToId();
+
+        if (this.queueManager == null) {
+          throw new SubscriptionNotEnabledException();
+        }
+        Connection primary = this.queueManager.getAllConnectionsNoWait()
+            .getPrimary();
+        if (primary != null && !map.containsKey(primary.getServer())) {
+          Long userId = (Long)AuthenticateUserOp.executeOn(primary.getServer(),
+              this, userAttributes.getCredentials());
+          if (userId != null) {
+            map.put(primary.getServer(), userId);
+          }
+        }
+
+        List<Connection> backups = this.queueManager.getAllConnectionsNoWait().getBackups();
+        for (int i = 0; i < backups.size(); i++) {
+          Connection conn = backups.get(i);
+          if (!map.containsKey(conn.getServer())) {
+            Long userId = (Long)AuthenticateUserOp.executeOn(conn.getServer(),
+                this, userAttributes.getCredentials());
+            if (userId != null) {
+              map.put(conn.getServer(), userId);
+            }
+          }
+        }
+      } else {
+        throw new UnsupportedOperationException(LocalizedStrings.MultiUserSecurityEnabled_USE_POOL_API.toLocalizedString());
+      }
+    }
+  }
+
+  public void setPendingEventCount(int count) {
+    this.primaryQueueSize.set(count);
+  }
+
+  public int getPendingEventCount() {
+    if(!isDurableClient() || this.queueManager == null) {
+      throw new IllegalStateException(LocalizedStrings.PoolManagerImpl_ONLY_DURABLE_CLIENTS_SHOULD_CALL_GETPENDINGEVENTCOUNT.toLocalizedString());
+    }
+    if (this.readyForEventsCalled) {
+      throw new IllegalStateException(LocalizedStrings.PoolManagerImpl_GETPENDINGEVENTCOUNT_SHOULD_BE_CALLED_BEFORE_INVOKING_READYFOREVENTS.toLocalizedString());
+    }
+    return this.primaryQueueSize.get();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PrimaryAckOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PrimaryAckOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PrimaryAckOp.java
new file mode 100644
index 0000000..48c9e0e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PrimaryAckOp.java
@@ -0,0 +1,92 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().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/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ProxyCache.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ProxyCache.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ProxyCache.java
new file mode 100755
index 0000000..1fb9cf0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ProxyCache.java
@@ -0,0 +1,239 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.ArrayList;
+import com.gemstone.gemfire.CancelCriterion;
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionService;
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.query.QueryService;
+import com.gemstone.gemfire.cache.query.internal.ProxyQueryService;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.pdx.PdxInstance;
+import com.gemstone.gemfire.pdx.PdxInstanceFactory;
+import com.gemstone.gemfire.pdx.internal.PdxInstanceFactoryImpl;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+
+/**
+ * A wrapper class over an actual Cache instance. This is used when the
+ * multiuser-authentication attribute is set to true. Application must use
+ * its {@link #getRegion(String)} API instead that of actual Cache instance for
+ * getting a reference to Region instances, to perform operations on server.
+ * 
+ * TODO Avoid creating multiple instances of ProxyCache for a single user.
+ * 
+ * @see ClientCache#createAuthenticatedView(Properties)
+ * @see ProxyQueryService
+ * @see ProxyRegion
+ * @since 6.5
+ */
+public class ProxyCache implements RegionService {
+  
+  private final GemFireCacheImpl cache;
+  private UserAttributes userAttributes;
+  private ProxyQueryService proxyQueryService;
+  private boolean isClosed = false;
+  private final Stopper stopper = new Stopper();
+
+  public ProxyCache(Properties properties, GemFireCacheImpl cache, PoolImpl pool) {
+    this.userAttributes = new UserAttributes(properties, pool);
+    this.cache = cache;
+  }
+
+  public void close() {
+    close(false);
+  }
+  
+  public void close(boolean keepAlive) {
+    if (this.isClosed) {
+      return;
+    }
+    // It should go to all the servers it has authenticated itself on and ask
+    // them to clean-up its entry from their auth-data structures.
+    try {
+      if (this.proxyQueryService != null) {
+        this.proxyQueryService.closeCqs(keepAlive);
+      }
+      UserAttributes.userAttributes.set(this.getUserAttributes());
+      Iterator<ServerLocation> iter = this.userAttributes.getServerToId()
+          .keySet().iterator();
+      while (iter.hasNext()) {
+        ProxyCacheCloseOp.executeOn(iter.next(), (PoolImpl)this.userAttributes.getPool(),
+            getProperties(), keepAlive);
+      }
+      ArrayList<ProxyCache> proxyCache = ((PoolImpl)this.userAttributes.getPool()).getProxyCacheList();
+      synchronized (proxyCache) {
+        proxyCache.remove(this);
+      }
+    } finally {
+      // @todo I think some NPE will be caused by this code.
+      // It would be safer to not null things out.
+      // It is really bad that we null out and then set isClosed true.
+      this.isClosed = true;
+      this.proxyQueryService = null;
+      this.userAttributes.setCredentials(null);
+      this.userAttributes = null;
+      UserAttributes.userAttributes.set(null);
+    }
+  }
+
+  // TODO remove this method
+  public String getName() {
+    return this.cache.getName();
+  }
+
+  public QueryService getQueryService() {
+    preOp();
+    if (this.proxyQueryService == null) {
+      this.proxyQueryService = new ProxyQueryService(this, userAttributes
+          .getPool().getQueryService());
+    }
+    return this.proxyQueryService;
+  }
+
+  public <K, V> Region<K, V> getRegion(String path) {
+    preOp();
+    // TODO Auto-generated method stub
+    // ProxyRegion region = this.proxyRegionList.get(path);
+    // if (region != null) {
+    //   return region;
+    // }
+    // else {
+    if (this.cache.getRegion(path) == null) {
+      return null;
+    } else {
+      if (!this.cache.getRegion(path).getAttributes().getDataPolicy().isEmpty()) {
+        throw new IllegalStateException(
+            "Region's data-policy must be EMPTY when multiuser-authentication is true");
+      }
+      return new ProxyRegion(this, this.cache.getRegion(path));
+    }
+    // }
+  }
+
+  public boolean isClosed() {
+    return this.isClosed;
+  }
+
+  public void setProperties(Properties properties) {
+    preOp();
+    this.userAttributes.setCredentials(properties);
+  }
+
+  public Properties getProperties() {
+    preOp();
+    return this.userAttributes.getCredentials();
+  }
+
+  public void setUserAttributes(UserAttributes userAttributes) {
+    preOp();
+    this.userAttributes = userAttributes;
+  }
+
+  public UserAttributes getUserAttributes() {
+    preOp();
+    return this.userAttributes;
+  }
+
+  public Object getUserId(Object key) {
+    preOp();
+    if (!(key instanceof ServerLocation)) {
+      throw new IllegalArgumentException(
+          "Key must be of type ServerLocation, but is " + key.getClass());
+    }
+    return this.userAttributes.getServerToId().get(key);
+  }
+
+  private void preOp() {
+    this.stopper.checkCancelInProgress(null);
+  }
+
+  protected class Stopper extends CancelCriterion {
+    /* (non-Javadoc)
+     * @see com.gemstone.gemfire.CancelCriterion#cancelInProgress()
+     */
+    @Override
+    public String cancelInProgress() {
+      String reason = cache.getCancelCriterion().cancelInProgress();
+      if (reason != null) {
+        return reason;
+      }
+      if (isClosed()) {
+        return "Authenticated cache view is closed for this user.";
+      }
+      return null;
+    }
+
+    /* (non-Javadoc)
+     * @see com.gemstone.gemfire.CancelCriterion#generateCancelledException(java.lang.Throwable)
+     */
+    @Override
+    public RuntimeException generateCancelledException(Throwable e) {
+      String reason = cancelInProgress();
+      if (reason == null) {
+        return null;
+      }
+      RuntimeException result = cache.getCancelCriterion().generateCancelledException(e);
+      if (result != null) {
+        return result;
+      }
+      if (e == null) {
+        // Caller did not specify  any root cause, so just use our own.
+        return new CacheClosedException(reason);
+      }
+
+      try {
+        return new CacheClosedException(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 CacheClosedException(reason);
+      }
+    }
+  }
+  
+  public CancelCriterion getCancelCriterion() {
+    return this.stopper;
+  }
+
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.RegionService#rootRegions()
+   */
+  public Set<Region<?, ?>> rootRegions() {
+    preOp();
+    Set<Region<?, ?>> rRegions = new HashSet<Region<?,?>>(); 
+    Iterator<LocalRegion> it = this.cache.rootRegions().iterator();
+    while (it.hasNext()) {
+      LocalRegion lr = it.next();
+      if (!lr.getAttributes().getDataPolicy().withStorage()) {
+        rRegions.add(new ProxyRegion(this, lr));
+      }
+    }
+    return Collections.unmodifiableSet(rRegions);
+  }
+
+  public PdxInstanceFactory createPdxInstanceFactory(String className) {
+    return PdxInstanceFactoryImpl.newCreator(className, true);
+  }
+  public PdxInstanceFactory createPdxInstanceFactory(String className, boolean b) {
+    return PdxInstanceFactoryImpl.newCreator(className, b);
+  }
+  public PdxInstance createPdxEnum(String className, String enumName, int enumOrdinal) {
+    return PdxInstanceFactoryImpl.createPdxEnum(className, enumName, enumOrdinal, this.cache);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ProxyCacheCloseOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ProxyCacheCloseOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ProxyCacheCloseOp.java
new file mode 100644
index 0000000..5271b73
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ProxyCacheCloseOp.java
@@ -0,0 +1,115 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().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());
+    }
+  }
+
+}


[02/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/pooling/ConnectionManagerImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/pooling/ConnectionManagerImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/pooling/ConnectionManagerImpl.java
new file mode 100644
index 0000000..5be50ec
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/pooling/ConnectionManagerImpl.java
@@ -0,0 +1,1573 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.pooling;
+
+import com.gemstone.gemfire.CancelCriterion;
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.cache.GatewayConfigurationException;
+import com.gemstone.gemfire.cache.client.AllConnectionsInUseException;
+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.internal.Connection;
+import com.gemstone.gemfire.cache.client.internal.ConnectionFactory;
+import com.gemstone.gemfire.cache.client.internal.Endpoint;
+import com.gemstone.gemfire.cache.client.internal.EndpointManager;
+import com.gemstone.gemfire.cache.client.internal.PoolImpl;
+import com.gemstone.gemfire.cache.client.internal.PoolImpl.PoolTask;
+import com.gemstone.gemfire.cache.client.internal.QueueConnectionImpl;
+import com.gemstone.gemfire.distributed.PoolCancelledException;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.cache.PoolManagerImpl;
+import com.gemstone.gemfire.internal.cache.PoolStats;
+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.log4j.LocalizedMessage;
+import com.gemstone.gemfire.security.GemFireSecurityException;
+import com.gemstone.org.jgroups.util.StringId;
+
+import java.util.ArrayList;
+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.Set;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.apache.logging.log4j.Logger;
+
+/**
+ * Manages client to server connections for the connection pool. This class contains
+ * all of the pooling logic to checkout/checkin connections.
+ * @author dsmith
+ * 
+ * @since 5.7
+ *
+ */
+public class ConnectionManagerImpl implements ConnectionManager {
+  private static final Logger logger = LogService.getLogger();
+  
+  static long AQUIRE_TIMEOUT = Long.getLong("gemfire.ConnectionManager.AQUIRE_TIMEOUT", 10 * 1000).longValue();
+  private final String poolName;
+  private final PoolStats poolStats;
+  protected final long prefillRetry; // ms // make this an int
+//  private final long pingInterval; // ms // make this an int
+  private final LinkedList/*<PooledConnection>*/ availableConnections = new LinkedList/*<PooledConnection>*/();
+  protected final ConnectionMap allConnectionsMap = new ConnectionMap();
+  private final EndpointManager endpointManager;
+  private final int maxConnections;
+  protected final int minConnections;
+  private final long idleTimeout; // make this an int
+  protected final long idleTimeoutNanos;
+  final int lifetimeTimeout;
+  final long lifetimeTimeoutNanos;
+  private final InternalLogWriter securityLogWriter;
+  protected final CancelCriterion cancelCriterion;
+
+  protected volatile int connectionCount;
+  protected ScheduledExecutorService backgroundProcessor;
+  protected ScheduledThreadPoolExecutor loadConditioningProcessor;
+  
+  protected ReentrantLock lock = new ReentrantLock();
+  protected Condition freeConnection = lock.newCondition();
+  private ConnectionFactory connectionFactory;
+  protected boolean haveIdleExpireConnectionsTask;
+  protected boolean havePrefillTask;
+  private boolean keepAlive=false;
+  protected volatile boolean shuttingDown;
+  private EndpointManager.EndpointListenerAdapter endpointListener;
+
+  private static final long NANOS_PER_MS = 1000000L;
+
+  /**
+   * Create a connection manager
+   * @param poolName the name of the pool that owns us
+   * @param factory the factory for new connections
+   * @param maxConnections The maximum number of connections that can exist
+   * @param minConnections The minimum number of connections that can exist
+   * @param idleTimeout The amount of time to wait to expire idle connections. -1 means that
+   * idle connections are never expired.
+   * @param lifetimeTimeout the lifetimeTimeout in ms.
+   * @param securityLogger 
+   */
+  public ConnectionManagerImpl(String poolName,
+                               ConnectionFactory factory,
+                               EndpointManager endpointManager,
+                               int maxConnections, int minConnections,
+                               long idleTimeout, int lifetimeTimeout,
+                               InternalLogWriter securityLogger, long pingInterval,
+                               CancelCriterion cancelCriterion, PoolStats poolStats) {
+    this.poolName = poolName;
+    this.poolStats = poolStats;
+    if(maxConnections < minConnections && maxConnections != -1) {
+      throw new IllegalArgumentException("Max connections " + maxConnections + " is less than minConnections " + minConnections);
+    }
+    if(maxConnections <= 0 && maxConnections != -1) {
+      throw new IllegalArgumentException("Max connections " + maxConnections + " must be greater than 0");
+    }
+    if(minConnections < 0) {
+      throw new IllegalArgumentException("Min connections " + minConnections + " must be greater than or equals to 0");
+    }
+    
+    this.connectionFactory = factory;
+    this.endpointManager = endpointManager;
+    this.maxConnections = maxConnections == -1 ? Integer.MAX_VALUE : maxConnections;
+    this.minConnections = minConnections;
+    this.lifetimeTimeout = lifetimeTimeout;
+    this.lifetimeTimeoutNanos = lifetimeTimeout * NANOS_PER_MS;
+    if (lifetimeTimeout != -1) {
+      if (idleTimeout > lifetimeTimeout || idleTimeout == -1) {
+        // lifetimeTimeout takes precedence over longer idle timeouts
+        idleTimeout = lifetimeTimeout;
+      }
+    }
+    this.idleTimeout = idleTimeout;
+    this.idleTimeoutNanos = this.idleTimeout * NANOS_PER_MS;
+    this.securityLogWriter = securityLogger;
+    this.prefillRetry = pingInterval;
+//    this.pingInterval = pingInterval;
+    this.cancelCriterion = cancelCriterion;
+    this.endpointListener = new EndpointManager.EndpointListenerAdapter() {
+      @Override
+      public void endpointCrashed(Endpoint endpoint) {
+        invalidateServer(endpoint);
+      }
+    };
+  }
+  
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.pooling.ConnectionManager#borrowConnection(long)
+   */
+  public Connection borrowConnection(long acquireTimeout) throws AllConnectionsInUseException, NoAvailableServersException {
+    
+    long startTime = System.currentTimeMillis();
+    long remainingTime = acquireTimeout;
+    
+    //wait for a connection to become free
+    lock.lock();
+    try {
+      while(connectionCount >= maxConnections && availableConnections.isEmpty() &&remainingTime > 0 && !shuttingDown) {
+        final long start = getPoolStats().beginConnectionWait();
+        boolean interrupted = false;
+        try {
+          freeConnection.await(remainingTime, TimeUnit.MILLISECONDS);
+        }
+        catch (InterruptedException e) {
+          interrupted = true;
+          cancelCriterion.checkCancelInProgress(e);
+          throw new AllConnectionsInUseException();
+        }
+        finally {
+          if (interrupted) {
+            Thread.currentThread().interrupt();
+          }
+          getPoolStats().endConnectionWait(start);
+        }
+        remainingTime = acquireTimeout - (System.currentTimeMillis() - startTime);
+      }
+      if(shuttingDown) {
+        throw new PoolCancelledException();
+      }
+
+      while (!availableConnections.isEmpty()) {
+        PooledConnection connection = (PooledConnection) availableConnections.removeFirst();
+        try {
+          connection.activate();
+          return connection;
+        }
+        catch (ConnectionDestroyedException ex) {
+          // whoever destroyed it already decremented connectionCount
+        }
+      }
+      if (connectionCount >= maxConnections) {
+        throw new AllConnectionsInUseException();
+      }
+      else {
+        //We need to create a connection. Reserve space for it.
+        connectionCount++;
+//         logger.info("DEBUG: borrowConnection conCount(+1)->" + connectionCount);
+//         getPoolStats().incConCount(1);
+      }
+      
+    }
+    finally {
+      lock.unlock();
+    }
+    
+    PooledConnection connection = null;
+    try {
+      Connection plainConnection = connectionFactory.createClientToServerConnection(Collections.EMPTY_SET);
+      
+      connection = addConnection(plainConnection);
+    }
+    catch(GemFireSecurityException e) {
+      throw new ServerOperationException(e);
+    }
+    catch(GatewayConfigurationException e) {
+      throw new ServerOperationException(e);
+    }
+    catch(ServerRefusedConnectionException srce) {
+      throw new NoAvailableServersException(srce);
+    }
+    finally {
+      //if we failed, release the space we reserved for our connection
+      if(connection == null) {
+        lock.lock();
+        try {
+//           getPoolStats().incConCount(-1);
+          --connectionCount;
+//           logger.info("DEBUG: borrowConnection conCount(-1)->" + connectionCount);
+          if(connectionCount < minConnections) {
+            startBackgroundPrefill();
+          }
+        }
+        finally {
+          lock.unlock();
+        }
+      }
+    }
+    
+    if(connection == null) {
+      this.cancelCriterion.checkCancelInProgress(null);
+      throw new NoAvailableServersException();
+    }
+    
+    return connection;
+  }
+  
+//   public Connection borrowConnection(ServerLocation server, long acquireTimeout)
+//       throws AllConnectionsInUseException, NoAvailableServersException {
+//     return borrowConnection(server, acquireTimeout, false);
+//   }
+
+//   /**
+//    * Used to tell a caller of borrowConnection that it did not find an existing connnection.
+//    */
+//   public static final Connection NO_EXISTING_CONNECTION = new ConnectionImpl(null, null);
+  
+  /**
+   * Borrow a connection to a specific server. This task currently
+   * allows us to break the connection limit, because it is used by
+   * tasks from the background thread that shouldn't be constrained
+   * by the limit. They will only violate the limit by 1 connection, and 
+   * that connection will be destroyed when returned to the pool.
+   */
+  public Connection borrowConnection(ServerLocation server, long acquireTimeout
+                                     , boolean onlyUseExistingCnx)
+    throws AllConnectionsInUseException, NoAvailableServersException {
+    lock.lock();
+    try {
+      if(shuttingDown) {
+        throw new PoolCancelledException();
+      }
+      for(Iterator itr = availableConnections.iterator(); itr.hasNext(); ) {
+        PooledConnection nextConnection = (PooledConnection) itr.next();
+        try {
+          nextConnection.activate();
+          if(nextConnection.getServer().equals(server)) {
+            itr.remove();
+            return nextConnection;
+          }
+          nextConnection.passivate(false);
+        } catch (ConnectionDestroyedException ex) {
+          // someone else already destroyed this connection so ignore it
+          // but remove it from availableConnections
+        }
+        //Fix for 41516. Before we let this method exceed the max connections
+        //by creating a new connection, we need to make sure that they're
+        //aren't bogus connections sitting in the available connection list
+        //otherwise, the length of that list might exceed max connections,
+        //but with some bad connections. That can cause members to 
+        //get a bad connection but have no permits to create a new connection.
+        if(nextConnection.shouldDestroy()) {
+          itr.remove();
+        }
+      }
+
+      if (onlyUseExistingCnx) {
+        throw new AllConnectionsInUseException();
+      }
+
+      // We need to create a connection. Reserve space for it.
+      connectionCount++;
+//       logger.info("DEBUG: borrowConnection conCount(+1)->" + connectionCount);
+//       getPoolStats().incConCount(1);
+    } finally {
+      lock.unlock();
+    }
+    
+    PooledConnection connection = null;
+    try {
+      Connection plainConnection = connectionFactory.createClientToServerConnection(server, false);
+      connection = addConnection(plainConnection);
+    } catch(GemFireSecurityException e) {
+      throw new ServerOperationException(e);
+    } finally {
+      //if we failed, release the space we reserved for our connection
+      if(connection == null) {
+        lock.lock();
+        try {
+//           getPoolStats().incConCount(-1);
+          --connectionCount;
+//           logger.info("DEBUG: borrowConnection conCount(-1)->" + connectionCount);
+          if(connectionCount < minConnections) {
+            startBackgroundPrefill();
+          }
+        } finally {
+          lock.unlock();
+        }
+      }
+    }
+    if(connection == null) {
+      throw new ServerConnectivityException("Could not create a new connection to server " + server);
+    }
+    return connection;
+  }
+  
+  public Connection exchangeConnection(Connection oldConnection,
+      Set/* <ServerLocation> */excludedServers, long acquireTimeout)
+      throws AllConnectionsInUseException {
+    assert oldConnection instanceof PooledConnection;
+    PooledConnection newConnection = null;
+    PooledConnection oldPC = (PooledConnection) oldConnection;
+//     while (!allConnectionsMap.containsConnection(oldPC)) {
+//       // ok the connection has already been removed so we really can't do an
+//       // exchange yet.
+//       // As a quick hack lets just get a connection using borrow.
+//       // If it turns out to be in our excludedServer set then
+//       // we can loop and try to exchange it.
+//       // But first make sure oldPC's socket gets closed.
+//       oldPC.internalDestroy();
+//       newConnection = (PooledConnection)borrowConnection(acquireTimeout);
+//       if (excludedServers.contains(newConnection.getServer())) {
+//         oldPC = newConnection; // loop and try to exchange it
+//         newConnection = null;
+//       } else {
+//         // we found one so we can just return it
+//         return newConnection;
+//       }
+//     }
+
+    boolean needToUndoEstimate = false;
+    lock.lock();
+    try {
+      if(shuttingDown) {
+        throw new PoolCancelledException();
+      }
+      for(Iterator itr = availableConnections.iterator(); itr.hasNext(); ) {
+        PooledConnection nextConnection = (PooledConnection) itr.next();
+        if(!excludedServers.contains(nextConnection.getServer())) {
+          itr.remove();
+          try {
+            nextConnection.activate();
+            newConnection = nextConnection;
+//             logger.info("DEBUG: exchangeConnection removeCon(" + oldPC +")");
+            if (allConnectionsMap.removeConnection(oldPC)) {
+//               getPoolStats().incConCount(-1);
+              --connectionCount;
+//               logger.info("DEBUG: exchangeConnection conCount(-1)->" + connectionCount + " oldPC=" + oldPC);
+              if(connectionCount < minConnections) {
+                startBackgroundPrefill();
+              }
+            }
+            break;
+          }
+          catch (ConnectionDestroyedException ex) {
+            // someone else already destroyed this connection so ignore it
+            // but remove it from availableConnections
+          }
+        }
+      }
+      if (newConnection == null) {
+        if (!allConnectionsMap.removeConnection(oldPC)) {
+          // need to reserve space for the following create
+//           if (connectionCount >= maxConnections) {
+//             throw new AllConnectionsInUseException();
+//           } else {
+          // WARNING: we may be going over maxConnections here
+          // @todo grid: this needs to be fixed
+            //We need to create a connection. Reserve space for it.
+            needToUndoEstimate = true;
+            connectionCount++;
+//             logger.info("DEBUG: exchangeConnection conCount(+1)->" + connectionCount);
+//             getPoolStats().incConCount(1);
+//           }
+        }
+      }
+    }
+    finally {
+      lock.unlock();
+    }
+
+    if(newConnection == null) {
+      try {
+        Connection plainConnection = connectionFactory.createClientToServerConnection(excludedServers);
+        newConnection = addConnection(plainConnection);
+//         logger.info("DEBUG: exchangeConnection newConnection=" + newConnection);
+      }
+      catch(GemFireSecurityException e) {
+        throw new ServerOperationException(e);
+      }
+      catch(ServerRefusedConnectionException srce) {
+        throw new NoAvailableServersException(srce);
+      }
+      finally {
+        if (needToUndoEstimate && newConnection == null) {
+          lock.lock();
+          try {
+//             getPoolStats().incConCount(-1);
+            --connectionCount;
+//             logger.info("DEBUG: exchangeConnection conCount(-1)->" + connectionCount);
+            if(connectionCount < minConnections) {
+              startBackgroundPrefill();
+            }
+          }
+          finally {
+            lock.unlock();
+          }
+        }
+      }
+    }
+    
+    if(newConnection == null) {
+      throw new NoAvailableServersException();
+    }
+
+//     logger.info("DEBUG: exchangeConnection internalDestroy(" + oldPC +")");
+    oldPC.internalDestroy();
+    
+    return newConnection;
+  }
+
+  protected/*GemStoneAddition*/ String getPoolName() {
+    return this.poolName;
+  }
+  
+  private PooledConnection addConnection(Connection conn) {
+      
+    if(conn == null) {
+      if (logger.isDebugEnabled()) {
+        logger.debug("Unable to create a connection in the allowed time");
+      }
+      return null;
+    }
+    PooledConnection pooledConn= new PooledConnection(this, conn);
+    allConnectionsMap.addConnection(pooledConn);
+    if(logger.isDebugEnabled()) {
+      logger.debug("Created a new connection. {} Connection count is now {}", pooledConn, connectionCount);
+    }
+    return pooledConn;
+  }
+  
+  private void destroyConnection(PooledConnection connection) {
+    lock.lock();
+    try {
+      if (allConnectionsMap.removeConnection(connection)) {
+        if(logger.isDebugEnabled()) {
+          logger.debug("Invalidating connection {} connection count is now {}", connection, connectionCount);
+        }
+      
+//         getPoolStats().incConCount(-1);
+//         logger.info("DEBUG: destroyConnection conCount(-1)->" + connectionCount);
+        if(connectionCount < minConnections) {
+          startBackgroundPrefill();
+        }
+        freeConnection.signalAll();
+      }
+      --connectionCount; // fix for bug #50333
+    }
+    finally {
+      lock.unlock();
+    }
+    
+    connection.internalDestroy();
+  }
+  
+
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.pooling.ConnectionManager#invalidateServer(com.gemstone.gemfire.distributed.internal.ServerLocation)
+   */
+  protected void invalidateServer(Endpoint endpoint) {
+    Set badConnections = allConnectionsMap.removeEndpoint(endpoint);
+    if(badConnections == null) {
+      return;
+    }
+    
+    lock.lock();
+    try {
+      if(shuttingDown) {
+        return;
+      }
+      if(logger.isDebugEnabled()) {
+        logger.debug("Invalidating {} connections to server {}", badConnections.size(), endpoint);
+      }
+
+      //mark connections for destruction now, so if anyone tries
+      //to return a connection they'll get an exception
+      for(Iterator itr = badConnections.iterator(); itr.hasNext(); ) {
+        PooledConnection conn = (PooledConnection) itr.next();
+        if (!conn.setShouldDestroy()) {
+          // this might not be true; they make have just had an exception
+//           itr.remove(); // someone else is destroying it
+        }
+      }
+      
+      for(Iterator itr = availableConnections.iterator(); itr.hasNext(); ) {
+        PooledConnection conn = (PooledConnection) itr.next();
+        if(badConnections.contains(conn)) {
+          itr.remove();
+        }
+      }
+      
+//       getPoolStats().incConCount(-badConnections.size());
+      connectionCount -= badConnections.size();
+//       logger.info("DEBUG: invalidateServer conCount(" + (-badConnections.size()) + ")->" + connectionCount);
+      
+      if(connectionCount < minConnections) {
+        startBackgroundPrefill();
+      }
+
+      // TODO (ashetkar) This for loop may well be outside the lock. But this
+      // change was tested thoroughly for #42185 and also it may not impact perf
+      // because this method gets called only when a server goes down.
+      for(Iterator itr = badConnections.iterator(); itr.hasNext(); ) {
+        PooledConnection conn = (PooledConnection) itr.next();
+        conn.internalDestroy();
+      }
+
+      if(connectionCount < maxConnections) {
+        freeConnection.signalAll();
+      }
+    }
+    finally {
+      lock.unlock();
+    }
+  }
+  
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.pooling.ConnectionManager#returnConnection(com.gemstone.gemfire.cache.client.internal.Connection)
+   */
+  public void returnConnection(Connection connection) {
+    returnConnection(connection, true);
+  }
+  
+  public void returnConnection(Connection connection, boolean accessed) {
+
+    assert connection instanceof PooledConnection;
+    PooledConnection pooledConn = (PooledConnection)connection;
+
+    boolean shouldClose = false;
+
+    lock.lock();
+    try {
+      if (pooledConn.isDestroyed()) {
+        return;
+      }
+
+      if (pooledConn.shouldDestroy()) {
+        destroyConnection(pooledConn);
+      } else {
+        // thread local connections are already passive at this point
+        if (pooledConn.isActive()) {
+          pooledConn.passivate(accessed);
+        }
+
+        // borrowConnection(ServerLocation, long) allows us to break the
+        // connection limit in order to get a connection to a server. So we need
+        // to get our pool back to size if we're above the limit
+        if (connectionCount > maxConnections) {
+          if (allConnectionsMap.removeConnection(pooledConn)) {
+            shouldClose = true;
+            // getPoolStats().incConCount(-1);
+            --connectionCount;
+            // logger.info("DEBUG: returnConnection conCount(-1)->" + connectionCount);
+          }
+        } else {
+          availableConnections.addFirst(pooledConn);
+          freeConnection.signalAll();
+        }
+      }
+    } finally {
+      lock.unlock();
+    }
+
+    if (shouldClose) {
+      try {
+          PoolImpl localpool=(PoolImpl)PoolManagerImpl.getPMI().find(poolName);
+          Boolean durable=false;
+          if(localpool!=null){
+            durable=localpool.isDurableClient();
+            }
+        pooledConn.internalClose(durable||this.keepAlive);
+      } catch (Exception e) {
+        logger.warn(LocalizedMessage.create(
+            LocalizedStrings.ConnectionManagerImpl_ERROR_CLOSING_CONNECTION_0,
+            pooledConn), e);
+      }
+    }
+  }  
+
+  /* (non-Javadoc)
+   */
+  public void start(ScheduledExecutorService backgroundProcessor) {
+    this.backgroundProcessor = backgroundProcessor;
+    this.loadConditioningProcessor = new ScheduledThreadPoolExecutor(1/*why not 0?*/, new ThreadFactory() {
+        public Thread newThread(final Runnable r) {
+          Thread result = new Thread(r, "poolLoadConditioningMonitor-" + getPoolName());
+          result.setDaemon(true);
+          return result;
+        }
+      });
+    this.loadConditioningProcessor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+    
+    endpointManager.addListener(endpointListener);
+    
+    lock.lock();
+    try {
+      startBackgroundPrefill();
+    }
+    finally {
+      lock.unlock();
+    }
+  }
+  
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.pooling.ConnectionManager#close(boolean, long)
+   */
+  public void close(boolean keepAlive) {
+    if(logger.isDebugEnabled()) {
+      logger.debug("Shutting down connection manager with keepAlive {}", keepAlive);
+    }
+    this.keepAlive=keepAlive;
+    endpointManager.removeListener(endpointListener);
+    
+    lock.lock();
+    try {
+      if(shuttingDown) {
+        return;
+      }
+      shuttingDown = true;
+    }
+    finally {
+      lock.unlock();
+    }
+
+    // do this early as it might help lifetimeProcessor shutdown
+//     closeReplacementConnection();
+    try {
+      if (this.loadConditioningProcessor != null) {
+        this.loadConditioningProcessor.shutdown();
+        if(!this.loadConditioningProcessor.awaitTermination(PoolImpl.SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS)) {
+          logger.warn(LocalizedMessage.create(LocalizedStrings.ConnectionManagerImpl_TIMEOUT_WAITING_FOR_LOAD_CONDITIONING_TASKS_TO_COMPLETE));
+        }
+      }
+    }
+    catch (RuntimeException e) {
+      logger.error(LocalizedMessage.create(LocalizedStrings.ConnectionManagerImpl_ERROR_STOPPING_LOADCONDITIONINGPROCESSOR), e);
+    }
+    catch (InterruptedException e) {
+      logger.error(LocalizedMessage.create(LocalizedStrings.ConnectionManagerImpl_INTERRUPTED_STOPPING_LOADCONDITIONINGPROCESSOR), e);
+    }
+    // one more time in case of race with lifetimeProcessor
+//     closeReplacementConnection();
+    allConnectionsMap.close(keepAlive);
+  }
+  
+  public void emergencyClose() {
+    shuttingDown = true;
+    if (this.loadConditioningProcessor != null) {
+      this.loadConditioningProcessor.shutdown();
+    }
+//     closeReplacementConnection();
+    allConnectionsMap.emergencyClose();
+  }
+
+  protected void startBackgroundExpiration() {
+    if (idleTimeout >= 0) {
+      synchronized (this.allConnectionsMap) {
+        if(!haveIdleExpireConnectionsTask) {
+          haveIdleExpireConnectionsTask = true;
+          try {
+            backgroundProcessor.schedule(new IdleExpireConnectionsTask(), idleTimeout, TimeUnit.MILLISECONDS);
+          }
+          catch (RejectedExecutionException e) {
+            // ignore, the timer has been cancelled, which means we're shutting
+            // down.
+          }
+        }
+      }
+    }
+  }
+
+  /** Always called with lock held */
+  protected void startBackgroundPrefill() {
+    if(!havePrefillTask) {
+      havePrefillTask = true;
+      try {
+        backgroundProcessor.execute(new PrefillConnectionsTask());
+      }
+      catch (RejectedExecutionException e) {
+        // ignore, the timer has been cancelled, which means we're shutting
+        // down.
+      }
+    }
+  }
+  
+  protected boolean prefill() {
+    try {
+      while (connectionCount < minConnections) {
+        if (cancelCriterion.cancelInProgress() != null) {
+          return true;
+        }
+        boolean createdConnection= prefillConnection();
+        if (!createdConnection) {
+          return false;
+        }
+      }
+    }
+    catch(Throwable t) {
+      cancelCriterion.checkCancelInProgress(t);
+      if(t.getCause()!=null) {
+        t = t.getCause();
+      }
+      logInfo(LocalizedStrings.ConnectionManagerImpl_ERROR_PREFILLING_CONNECTIONS, t);
+      return false;
+    }
+    
+    return true;
+  }
+
+  public int getConnectionCount() {
+    return this.connectionCount;
+  }
+
+  protected PoolStats getPoolStats() {
+    return this.poolStats;
+  }
+  
+  public Connection getConnection(Connection conn) {
+    if (conn instanceof PooledConnection) {
+      return ((PooledConnection)conn).getConnection();
+    } else if (conn instanceof QueueConnectionImpl) { 
+      return ((QueueConnectionImpl)conn).getConnection();
+    } else {
+      return conn;
+    }
+  }
+
+  private boolean prefillConnection() {
+    boolean createConnection = false;
+    lock.lock();
+    try {
+      if (shuttingDown) { 
+        return false;
+      }
+      if (connectionCount < minConnections) {
+//         getPoolStats().incConCount(1);
+        connectionCount++;
+//         logger.info("DEBUG: prefillConnection conCount(+1)->" + connectionCount);
+        createConnection = true;
+      }
+    }
+    finally {
+      lock.unlock();
+    }
+    
+    if (createConnection) {
+      PooledConnection connection= null;
+      try {
+        Connection plainConnection = connectionFactory.createClientToServerConnection(Collections.EMPTY_SET);
+        if(plainConnection == null) {
+          return false;
+        }
+        connection = addConnection(plainConnection);
+        connection.passivate(false);
+        getPoolStats().incPrefillConnect();
+      }
+      catch (ServerConnectivityException ex) {
+        logger.info(LocalizedMessage.create(LocalizedStrings.ConnectionManagerImpl_UNABLE_TO_PREFILL_POOL_TO_MINIMUM_BECAUSE_0, ex), null);
+        return false;
+      }
+      finally {
+        lock.lock();
+        try {
+          if(connection == null) {
+//             getPoolStats().incConCount(-1);
+            connectionCount--;
+//             logger.info("DEBUG: prefillConnection conCount(-1)->" + connectionCount);
+            if(logger.isDebugEnabled()) {
+              logger.debug("Unable to prefill pool to minimum, connection count is now {}", connectionCount);
+            }
+          }
+          else {
+            availableConnections.addFirst(connection);
+            freeConnection.signalAll();
+            if(logger.isDebugEnabled()) {
+              logger.debug("Prefilled connection {} connection count is now {}", connection, connectionCount);
+            }
+          }
+        }
+        finally {
+          lock.unlock();
+        }
+      }
+    }
+    
+    return true;
+  }
+  
+  public static void loadEmergencyClasses() {
+    PooledConnection.loadEmergencyClasses();
+  }
+  
+  protected class LifetimeExpireConnectionsTask implements Runnable {
+    public void run() {
+      try {
+//         logger.info("DEBUG: lifetimeTask=" + this);
+        allConnectionsMap.checkLifetimes();
+      }
+      catch (CancelException ignore) {
+      }
+      catch (VirtualMachineError e) {
+        SystemFailure.initiateFailure(e);
+        // NOTREACHED
+        throw e; // for safety
+      }
+      catch (Throwable t) {
+        SystemFailure.checkFailure();
+        logger.warn(LocalizedMessage.create(LocalizedStrings.ConnectionManagerImpl_LOADCONDITIONINGTASK_0_ENCOUNTERED_EXCEPTION, this), t);
+        // Don't rethrow, it will just get eaten and kill the timer
+      }
+    }
+  }
+  
+  protected class IdleExpireConnectionsTask implements Runnable {
+    public void run() {
+      try {
+        getPoolStats().incIdleCheck();
+        allConnectionsMap.checkIdleExpiration();
+      }
+      catch (CancelException ignore) {
+      }
+      catch (VirtualMachineError e) {
+        SystemFailure.initiateFailure(e);
+        // NOTREACHED
+        throw e; // for safety
+      }
+      catch (Throwable t) {
+        SystemFailure.checkFailure();
+        logger.warn(LocalizedMessage.create(LocalizedStrings.ConnectionManagerImpl_IDLEEXPIRECONNECTIONSTASK_0_ENCOUNTERED_EXCEPTION, this), t);
+        // Don't rethrow, it will just get eaten and kill the timer
+      }
+    }
+  }
+  
+  protected class PrefillConnectionsTask extends PoolTask {
+
+    @Override
+    public void run2() {
+      if (logger.isTraceEnabled()) {
+        logger.trace("Prefill Connections task running");
+      }
+
+      prefill();
+      lock.lock();
+      try {
+        if(connectionCount < minConnections && cancelCriterion.cancelInProgress() == null) {
+          try {
+            backgroundProcessor.schedule(new PrefillConnectionsTask(), prefillRetry, TimeUnit.MILLISECONDS);
+          } catch(RejectedExecutionException e) {
+            //ignore, the timer has been cancelled, which means we're shutting down.
+          }
+        }
+        else {
+          havePrefillTask = false;
+        }
+      }
+      finally {
+        lock.unlock();
+      }
+    }
+  }
+
+//   private final AR/*<ReplacementConnection>*/ replacement = CFactory.createAR();
+
+//   private void closeReplacementConnection() {
+//     ReplacementConnection rc = (ReplacementConnection)this.replacement.getAndSet(null);
+//     if (rc != null) {
+//       rc.getConnection().destroy();
+//     }
+//   }
+
+  /**
+   * Offer the replacement "con" to any cnx currently connected to "currentServer".
+   * @return true if someone takes our offer; false if not
+   */
+  private boolean offerReplacementConnection(Connection con, ServerLocation currentServer) {
+    boolean retry;
+    do {
+      retry = false;
+      PooledConnection target = this.allConnectionsMap.findReplacementTarget(currentServer);
+      if (target != null) {
+        final Endpoint targetEP = target.getEndpoint();
+        boolean interrupted = false;
+        try {
+          if (target.switchConnection(con)) {
+            getPoolStats().incLoadConditioningDisconnect();
+            this.allConnectionsMap.addReplacedCnx(target, targetEP);
+            return true;
+          }
+          else {
+//             // target was destroyed; we have already removed it from
+//             // allConnectionsMap but didn't dec the stat
+//             getPoolStats().incPoolConnections(-1);
+//             logger.info("DEBUG: offerReplacementConnection incPoolConnections(-1)->" + getPoolStats().getPoolConnections());
+            retry = true;
+          }
+        }
+        catch (InterruptedException e) {
+          // thrown by switchConnection
+          interrupted = true;
+          cancelCriterion.checkCancelInProgress(e);
+          retry = false;
+        }
+        finally {
+          if (interrupted) {
+            Thread.currentThread().interrupt();
+          }
+        }
+      }
+    } while (retry);
+    getPoolStats().incLoadConditioningReplaceTimeouts();
+    con.destroy();
+    return false;
+  }
+
+  /**
+   * An existing connections lifetime has expired.
+   * We only want to create one replacement connection at a time
+   * so this guy should block until this connection replaces an existing one.
+   * Note that if a connection is created here it must not count against
+   * the pool max and its idle time and lifetime must not begin until
+   * it actually replaces the existing one.
+   * @param currentServer the server the candidate connection is connected to
+   * @param idlePossible true if we have more cnxs than minPoolSize
+   * @return true if caller should recheck for expired lifetimes;
+   *         false if a background check was scheduled or no expirations are possible.
+   */
+  public boolean createLifetimeReplacementConnection(ServerLocation currentServer,
+                                                      boolean idlePossible) {
+    HashSet excludedServers = new HashSet();
+    ServerLocation sl = this.connectionFactory.findBestServer(currentServer, excludedServers);
+
+//    boolean replacementConsumed = false;
+    while (sl != null) {
+      if (sl.equals(currentServer)) {
+        this.allConnectionsMap.extendLifeOfCnxToServer(currentServer);
+        break;
+      }
+      else {
+        if (!this.allConnectionsMap.hasExpiredCnxToServer(currentServer)) {
+          break;
+        }
+        Connection con = null;
+        try {
+          //           logger.fine("DEBUG: creating replacement connection to " + sl);
+          con = this.connectionFactory.createClientToServerConnection(sl, false);
+          //           logger.fine("DEBUG: created replacement connection: " + con);
+        }
+        catch (GemFireSecurityException e) {
+          securityLogWriter.warning(
+              LocalizedStrings.ConnectionManagerImpl_SECURITY_EXCEPTION_CONNECTING_TO_SERVER_0_1,
+              new Object[] {sl, e});
+        }
+        catch (ServerRefusedConnectionException srce) {
+          logger.warn(LocalizedMessage.create(
+              LocalizedStrings.ConnectionManagerImpl_SERVER_0_REFUSED_NEW_CONNECTION_1,
+              new Object[] {sl, srce}));
+        } 
+        if (con == null) {
+          excludedServers.add(sl);
+          sl = this.connectionFactory.findBestServer(currentServer, excludedServers);
+        }
+        else {
+          getPoolStats().incLoadConditioningConnect();
+          if (!this.allConnectionsMap.hasExpiredCnxToServer(currentServer)) {
+            getPoolStats().incLoadConditioningReplaceTimeouts();
+            con.destroy();
+            break;
+          }
+          offerReplacementConnection(con, currentServer);
+          break;
+        }
+      }
+    }
+    if (sl == null) {
+      // we didn't find a server to create a replacement cnx on so
+      // extends the currentServers life
+      this.allConnectionsMap.extendLifeOfCnxToServer(currentServer);
+    }
+    return this.allConnectionsMap.checkForReschedule(true);
+  }
+  
+  protected class ConnectionMap {
+    private final HashMap/*<Endpoint, HashSet<PooledConnection>*/ map = new HashMap();
+    private final LinkedList/*<PooledConnection>*/ allConnections = new LinkedList/*<PooledConnection>*/(); // in the order they were created
+    private boolean haveLifetimeExpireConnectionsTask;
+
+    public synchronized boolean isIdleExpirePossible() {
+      return this.allConnections.size() > minConnections;
+    }
+
+    @Override
+    public synchronized String toString() {
+      final long now = System.nanoTime();
+      StringBuffer sb = new StringBuffer();
+      sb.append("<");
+      for (Iterator it = this.allConnections.iterator(); it.hasNext();) {
+        PooledConnection pc = (PooledConnection)it.next();
+        sb.append(pc.getServer());
+        if (pc.shouldDestroy()) {
+          sb.append("-DESTROYED");
+        }
+        else if ( pc.hasIdleExpired(now, idleTimeoutNanos) ) {
+          sb.append("-IDLE");
+        }
+        else if ( pc.remainingLife(now, lifetimeTimeoutNanos) <= 0 ) {
+          sb.append("-EOL");
+        }
+        if (it.hasNext()) {
+          sb.append(",");
+        }
+      }
+      sb.append(">");
+      return sb.toString();
+    }
+    
+    public synchronized void addConnection(PooledConnection connection) {
+      addToEndpointMap(connection);
+
+      // we want the smallest birthDate (e.g. oldest cnx) at the front of the list
+      getPoolStats().incPoolConnections(1);
+//       logger.info("DEBUG: addConnection incPoolConnections(1)->" + getPoolStats().getPoolConnections() + " con="+connection,
+//                   new RuntimeException("STACK"));
+      this.allConnections.addLast(connection);
+      if (isIdleExpirePossible()) {
+        startBackgroundExpiration();
+      }
+      if (lifetimeTimeout != -1 && !haveLifetimeExpireConnectionsTask) {
+        if (checkForReschedule(true)) {
+          // something has already expired so start processing with no delay
+//           logger.info("DEBUG: rescheduling lifetime expire to be now");
+          startBackgroundLifetimeExpiration(0);
+        }
+        else {
+          // either no possible lifetime expires or we scheduled one
+        }
+      }
+    }
+
+    public synchronized void addReplacedCnx(PooledConnection con, Endpoint oldEndpoint) {
+      if (this.allConnections.remove(con)) {
+        // otherwise someone else has removed it and closed it
+        removeFromEndpointMap(oldEndpoint, con);
+        addToEndpointMap(con);
+        this.allConnections.addLast(con);
+        if (isIdleExpirePossible()) {
+          startBackgroundExpiration();
+        }
+      }
+    }
+    
+    public synchronized Set removeEndpoint(Endpoint endpoint) {
+      final Set endpointConnections = (Set) this.map.remove(endpoint);
+      if(endpointConnections != null) {
+        int count = 0;
+        for (Iterator it = this.allConnections.iterator(); it.hasNext();) {
+          if (endpointConnections.contains(it.next())) {
+            count++;
+            it.remove();
+          }
+        }
+        if (count != 0) {
+          getPoolStats().incPoolConnections(-count);
+//           logger.info("DEBUG: removedEndpoint incPoolConnections(" + (-count) + ")->" + getPoolStats().getPoolConnections() + " cons.size=" + endpointConnections.size() + " cons=" + endpointConnections);
+        }
+      }
+      return endpointConnections;
+    }
+
+    public synchronized boolean containsConnection(PooledConnection connection) {
+      return this.allConnections.contains(connection);
+    }
+    
+    public synchronized boolean removeConnection(PooledConnection connection) {
+      // @todo darrel: allConnections.remove could be optimized by making
+      // allConnections a linkedHashSet
+      boolean result = this.allConnections.remove(connection);
+      if (result) {
+        getPoolStats().incPoolConnections(-1);
+//         logger.info("DEBUG: removedConnection incPoolConnections(-1)->" + getPoolStats().getPoolConnections() + " con="+connection);
+      }
+
+      removeFromEndpointMap(connection);
+      return result;
+    }
+
+    private synchronized void addToEndpointMap(PooledConnection connection) {
+      Set endpointConnections = (Set) map.get(connection.getEndpoint());
+      if(endpointConnections == null) {
+        endpointConnections = new HashSet();
+        map.put(connection.getEndpoint(), endpointConnections);
+      }
+      endpointConnections.add(connection);
+    }
+    
+    private void removeFromEndpointMap(PooledConnection connection) {
+      removeFromEndpointMap(connection.getEndpoint(), connection);
+    }
+    
+    private synchronized void removeFromEndpointMap(Endpoint endpoint, PooledConnection connection) {
+      Set endpointConnections = (Set) this.map.get(endpoint);
+      if (endpointConnections != null) {
+        endpointConnections.remove(connection);
+        if(endpointConnections.size() == 0) {
+          this.map.remove(endpoint);
+        }
+      }
+    }
+
+    public synchronized void close(boolean keepAlive) {
+      map.clear();
+      int count = 0;
+      while (!this.allConnections.isEmpty()) {
+        PooledConnection pc = (PooledConnection)this.allConnections.removeFirst();
+        count++;
+        if (!pc.isDestroyed()) {
+          try {
+            pc.internalClose(keepAlive);
+          } catch(Exception e) {
+            logger.warn(LocalizedMessage.create(
+                LocalizedStrings.ConnectionManagerImpl_ERROR_CLOSING_CONNECTION_TO_SERVER_0, 
+                pc.getServer()), e);
+          }
+        }
+      }
+      if (count != 0) {
+        getPoolStats().incPoolConnections(-count);
+//         logger.info("DEBUG: close incPoolConnections(" + (-count) + ")->" + getPoolStats().getPoolConnections());
+      }
+    }
+
+    public synchronized void emergencyClose() {
+      map.clear();
+      while (!this.allConnections.isEmpty()) {
+        PooledConnection pc = (PooledConnection)this.allConnections.removeFirst();
+        pc.emergencyClose();
+      }
+    }
+
+    /**
+     * Returns a pooled connection that can have its underlying cnx
+     * to currentServer replaced by a new connection.
+     * @return null if a target could not be found
+     */
+    public synchronized PooledConnection findReplacementTarget(ServerLocation currentServer) {
+      final long now = System.nanoTime();
+      for (Iterator it = this.allConnections.iterator(); it.hasNext();) {
+        PooledConnection pc = (PooledConnection)it.next();
+        if (currentServer.equals(pc.getServer())) {
+          if (!pc.shouldDestroy()
+              && pc.remainingLife(now, lifetimeTimeoutNanos) <= 0) {
+            removeFromEndpointMap(pc);
+            return pc;
+          }
+        }
+      }
+      return null;
+    }
+    
+    /**
+     * Return true if we have a connection to the currentServer whose
+     * lifetime has expired.
+     * Otherwise return false;
+     */
+    public synchronized boolean hasExpiredCnxToServer(ServerLocation currentServer) {
+      if (!this.allConnections.isEmpty()) {
+        //boolean idlePossible = isIdleExpirePossible();
+        final long now = System.nanoTime();
+        for (Iterator it = this.allConnections.iterator(); it.hasNext();) {
+          PooledConnection pc = (PooledConnection)it.next();
+          if (pc.shouldDestroy()) {
+            // this con has already been destroyed so ignore it
+            continue;
+          }
+          else if ( currentServer.equals(pc.getServer()) ) {
+            /*if (idlePossible && pc.hasIdleExpired(now, idleTimeoutNanos)) {
+              // this con has already idle expired so ignore it
+              continue;
+              } else*/ {
+              long life = pc.remainingLife(now, lifetimeTimeoutNanos);
+              if (life <= 0) {
+                return true;
+              }
+            }
+          }
+        }
+      }
+      return false;
+    }
+    /**
+     * Returns true if caller should recheck for expired lifetimes
+     * Returns false if a background check was scheduled or no expirations are possible.
+     */
+    public synchronized boolean checkForReschedule(boolean rescheduleOk) {
+      if (!this.allConnections.isEmpty()) {
+        final long now = System.nanoTime();
+        for (Iterator it = this.allConnections.iterator(); it.hasNext();) {
+          PooledConnection pc = (PooledConnection)it.next();
+          if (pc.hasIdleExpired(now, idleTimeoutNanos)) {
+            // this con has already idle expired so ignore it
+            continue;
+          }
+          else if ( pc.shouldDestroy() ) {
+            // this con has already been destroyed so ignore it
+            continue;
+          }
+          else {
+            long life = pc.remainingLife(now, lifetimeTimeoutNanos);
+            if (life > 0) {
+              if (rescheduleOk) {
+//                 logger.info("DEBUG: 2 rescheduling lifetime expire to be in: "
+//                             + life + " nanos");
+                startBackgroundLifetimeExpiration(life);
+                return false;
+              }
+              else {
+                return false;
+              }
+            }
+            else {
+              return true;
+            }
+          }
+        }
+      }
+      return false;
+    }
+
+    /**
+     * See if any of the expired connections (that have not idle expired)
+     * are already connected to this sl and have not idle expired.
+     * If so then just update them in-place to simulate a replace.
+     * @param sl the location of the server we should see if we are connected to
+     * @return true if we were able to extend an existing connection's lifetime
+     *         or if we have no connection's whose lifetime has expired.
+     *         false if we need to create a replacement connection.
+     */
+    public synchronized boolean tryToExtendLifeTime(ServerLocation sl) {
+      // a better approach might be to get the most loaded server
+      // (if they are not balanced) and then scan through and extend the lifetime
+      // of everyone not connected to that server and do a replace on just one
+      // of the guys who has lifetime expired to the most loaded server
+      boolean result = true;
+      if (!this.allConnections.isEmpty()) {
+        final long now = System.nanoTime();
+        for (Iterator it = this.allConnections.iterator(); it.hasNext();) {
+          PooledConnection pc = (PooledConnection)it.next();
+          if (pc.remainingLife(now, lifetimeTimeoutNanos) > 0) {
+            // no more connections whose lifetime could have expired
+            break;
+            // note don't ignore idle guys because they are still connected
+//           } else if (pc.remainingIdle(now, idleTimeoutNanos) <= 0) {
+//             // this con has already idle expired so ignore it
+          }
+          else if ( pc.shouldDestroy() ) {
+            // this con has already been destroyed so ignore it
+          }
+          else if ( sl.equals(pc.getEndpoint().getLocation()) ) {
+            // we found a guy to whose lifetime we can extend
+            it.remove();
+//             logger.fine("DEBUG: tryToExtendLifeTime extending life of: " + pc);
+            pc.setBirthDate(now);
+            getPoolStats().incLoadConditioningExtensions();
+            this.allConnections.addLast(pc);
+            return true;
+          }
+          else {
+            // the current pc is a candidate for reconnection to another server
+            // so set result to false which will stick unless we find another con
+            // whose life can be extended.
+            result = false;
+          }
+        }
+      }
+//       if (result) {
+//         logger.fine("DEBUG: tryToExtendLifeTime found no one to extend");
+//       }
+      return result;
+    }
+
+    /**
+     * Extend the life of the first expired connection to sl.
+     */
+    public synchronized void extendLifeOfCnxToServer(ServerLocation sl) {
+      if (!this.allConnections.isEmpty()) {
+        final long now = System.nanoTime();
+        for (Iterator it = this.allConnections.iterator(); it.hasNext() ;) {
+          PooledConnection pc = (PooledConnection)it.next();
+          if (pc.remainingLife(now, lifetimeTimeoutNanos) > 0) {
+            // no more connections whose lifetime could have expired
+            break;
+            // note don't ignore idle guys because they are still connected
+//           } else if (pc.remainingIdle(now, idleTimeoutNanos) <= 0) {
+//             // this con has already idle expired so ignore it
+          }
+          else if ( pc.shouldDestroy() ) {
+            // this con has already been destroyed so ignore it
+          }
+          else if ( sl.equals(pc.getEndpoint().getLocation()) ) {
+            // we found a guy to whose lifetime we can extend
+            it.remove();
+//             logger.fine("DEBUG: tryToExtendLifeTime extending life of: " + pc);
+            pc.setBirthDate(now);
+            getPoolStats().incLoadConditioningExtensions();
+            this.allConnections.addLast(pc);
+            // break so we only do this to the oldest guy
+            break;
+          }
+        }
+      }
+    }
+    
+    public synchronized void startBackgroundLifetimeExpiration(long delay) {
+      if(!this.haveLifetimeExpireConnectionsTask) {
+        this.haveLifetimeExpireConnectionsTask = true;
+        try {
+//           logger.info("DEBUG: scheduling lifetime expire check in: " + delay + " ns");
+          LifetimeExpireConnectionsTask task = new LifetimeExpireConnectionsTask();
+//           logger.info("DEBUG: scheduling lifetimeTask=" + task);
+          loadConditioningProcessor.schedule(task, delay, TimeUnit.NANOSECONDS);
+        }
+        catch (RejectedExecutionException e) {
+          //ignore, the timer has been cancelled, which means we're shutting down.
+        }
+      }
+    }
+
+    public void checkIdleExpiration() {
+      int expireCount = 0;
+      List<PooledConnection> toClose = null;
+      synchronized (this) {
+        haveIdleExpireConnectionsTask = false;
+        if(shuttingDown) {
+          return;
+        }
+        if (logger.isTraceEnabled()) {
+          logger.trace("Looking for connections to expire");
+        }
+
+        // because we expire thread local connections we need to scan allConnections
+
+        //find connections which have idle expired
+        int conCount = this.allConnections.size();
+        if (conCount <= minConnections) {
+          return;
+        }
+        final long now = System.nanoTime();
+        long minRemainingIdle = Long.MAX_VALUE;
+        toClose = new ArrayList<PooledConnection>(conCount-minConnections);
+        for (Iterator it = this.allConnections.iterator();
+             it.hasNext() && conCount > minConnections;) {
+          PooledConnection pc = (PooledConnection)it.next();
+          if (pc.shouldDestroy()) {
+            // ignore these connections
+            conCount--;
+          }
+          else {
+            long remainingIdle = pc.doIdleTimeout(now, idleTimeoutNanos);
+            if (remainingIdle >= 0) {
+              if (remainingIdle == 0) {
+                // someone else already destroyed pc so ignore it
+                conCount--;
+              }
+              else if ( remainingIdle < minRemainingIdle ) {
+                minRemainingIdle = remainingIdle;
+              }
+            }
+            else /* (remainingIdle < 0) */{
+              // this means that we idleExpired the connection
+              expireCount++;
+              conCount--;
+              removeFromEndpointMap(pc);
+              toClose.add(pc);
+              it.remove();
+            }
+          }
+        }
+        if (conCount > minConnections && minRemainingIdle < Long.MAX_VALUE) {
+          try {
+            backgroundProcessor.schedule(new IdleExpireConnectionsTask(),
+                                         minRemainingIdle,
+                                         TimeUnit.NANOSECONDS);
+          }
+          catch (RejectedExecutionException e) {
+            //ignore, the timer has been cancelled, which means we're shutting down.
+          }
+          haveIdleExpireConnectionsTask = true;
+        }
+      }
+
+      if (expireCount > 0) {
+        getPoolStats().incIdleExpire(expireCount);
+        getPoolStats().incPoolConnections(-expireCount);
+//         logger.info("DEBUG: checkIdleExpiration incPoolConnections(" + (-expireCount) + ")->" + getPoolStats().getPoolConnections());
+        // do this outside the above sync
+        lock.lock();
+        try {
+//           getPoolStats().incConCount(-expireCount);
+          connectionCount -= expireCount;
+//           logger.info("DEBUG: checkIdleExpiration conCount(" + (-expireCount) + ")->" + connectionCount);
+          freeConnection.signalAll();
+          if(connectionCount < minConnections) {
+            startBackgroundPrefill();
+          }
+        }
+        finally {
+          lock.unlock();
+        }
+      }
+      //now destroy all of the connections, outside the sync
+//      if (toClose != null) (cannot be null) 
+      final boolean isDebugEnabled = logger.isDebugEnabled();
+      {
+        for (Iterator itr = toClose.iterator(); itr.hasNext(); ) {
+          PooledConnection connection = (PooledConnection) itr.next();
+          if (isDebugEnabled) {
+            logger.debug("Idle connection detected. Expiring connection {}", connection);
+          }
+          try {
+            connection.internalClose(false);
+          }
+          catch (Exception e) {
+            logger.warn(LocalizedMessage.create(LocalizedStrings.ConnectionManagerImpl_ERROR_EXPIRING_CONNECTION_0, 
+                connection));
+          }
+        }
+      }
+    }
+
+    public void checkLifetimes() {
+        //      logger.info("DEBUG: Looking for connections whose lifetime has expired");
+      boolean done;
+      synchronized (this) {
+        this.haveLifetimeExpireConnectionsTask = false;
+        if(shuttingDown) {
+          return;
+        }
+      }
+      do {
+        getPoolStats().incLoadConditioningCheck();
+        long firstLife = -1;
+        done = true;
+        ServerLocation candidate = null;
+        boolean idlePossible = true;
+        
+        synchronized (this) {
+          if(shuttingDown) {
+            return;
+          }
+          // find a connection whose lifetime has expired
+          // and who is not already being replaced
+          long now = System.nanoTime();
+          long life = 0;
+          idlePossible = isIdleExpirePossible();
+          for (Iterator it = this.allConnections.iterator();
+               it.hasNext() && life <= 0 && (candidate == null);) {
+            PooledConnection pc = (PooledConnection)it.next();
+            // skip over idle expired and destroyed
+            life = pc.remainingLife(now, lifetimeTimeoutNanos);
+//             logger.fine("DEBUG: life remaining in " + pc + " is: " + life);
+            if (life <= 0) {
+               boolean idleTimedOut = idlePossible
+                 ? pc.hasIdleExpired(now, idleTimeoutNanos)
+                 : false;
+              boolean destroyed = pc.shouldDestroy();
+//               logger.fine("DEBUG: idleTimedOut=" + idleTimedOut
+//                           + " destroyed=" + destroyed);
+              if (!idleTimedOut && !destroyed) {
+                candidate = pc.getServer();
+              }
+            }
+            else if ( firstLife == -1 ) {
+              firstLife = life;
+            }
+          }
+        }
+        if (candidate != null) {
+//           logger.fine("DEBUG: calling createLifetimeReplacementConnection");
+          done = !createLifetimeReplacementConnection(candidate, idlePossible);
+//           logger.fine("DEBUG: createLifetimeReplacementConnection returned " + !done);
+        }
+        else {
+//           logger.fine("DEBUG: reschedule " + firstLife);
+          if (firstLife >= 0) {
+            // reschedule
+//             logger.info("DEBUG: rescheduling lifetime expire to be in: "
+//                         + firstLife + " nanos");
+            startBackgroundLifetimeExpiration(firstLife);
+          }
+          done = true; // just to be clear
+        }
+      } while (!done);
+      // If a lifetimeExpire task is not scheduled at this point then
+      // schedule one that will do a check in our configured lifetimeExpire.
+      // this should not be needed but seems to currently help.
+      startBackgroundLifetimeExpiration(lifetimeTimeoutNanos);
+    }
+  }
+
+  private void logInfo(StringId message, Throwable t) {
+    if(t instanceof GemFireSecurityException) {
+      securityLogWriter.info(LocalizedStrings.TWO_ARG_COLON, 
+            new Object[] {message.toLocalizedString(), t}, t);
+    } else {
+      logger.info(LocalizedMessage.create(LocalizedStrings.TWO_ARG_COLON,
+         new Object[] {message.toLocalizedString(), t}), t);
+    }
+  }
+  
+  private void logError(StringId message, Throwable t) {
+    if(t instanceof GemFireSecurityException) {
+      securityLogWriter.error(message, t);
+    }
+    else { 
+      logger.error(message, t);
+    }
+  }
+  
+  public void activate(Connection conn) {
+    assert conn instanceof PooledConnection;
+    ((PooledConnection)conn).activate();
+  }
+  public void passivate(Connection conn, boolean accessed) {
+    assert conn instanceof PooledConnection;
+    ((PooledConnection)conn).passivate(accessed);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/pooling/PooledConnection.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/pooling/PooledConnection.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/pooling/PooledConnection.java
new file mode 100644
index 0000000..db38b8b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/pooling/PooledConnection.java
@@ -0,0 +1,344 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.pooling;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import com.gemstone.gemfire.InternalGemFireException;
+import com.gemstone.gemfire.cache.client.internal.Connection;
+import com.gemstone.gemfire.cache.client.internal.ConnectionImpl;
+import com.gemstone.gemfire.cache.client.internal.ConnectionStats;
+import com.gemstone.gemfire.cache.client.internal.Endpoint;
+import com.gemstone.gemfire.cache.client.internal.Op;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ServerQueueStatus;
+
+/**
+ * A connection managed by the connection manager. Keeps track
+ * of the current state of the connection. 
+ * @author dsmith
+ * @since 5.7
+ *
+ */
+class PooledConnection implements Connection {
+
+  /* connection is volatile because we may asynchronously
+   * destroy the pooled connection while shutting down. */
+  private volatile Connection connection;
+  private volatile Endpoint endpoint;
+  private volatile long birthDate;
+  private long lastAccessed; // read & written while synchronized
+  private boolean active = true; // read and write while synchronized on this
+  private final AtomicBoolean shouldDestroy = new AtomicBoolean();
+  private boolean waitingToSwitch = false;
+//  private final ConnectionManagerImpl manager;
+
+  public PooledConnection(ConnectionManagerImpl manager, Connection connection) {
+//    this.manager = manager;
+    this.connection = connection;
+    this.endpoint = connection.getEndpoint();
+    this.birthDate = System.nanoTime();
+    this.lastAccessed = this.birthDate;
+  }
+
+  public ServerLocation getServer() {
+    return getEndpoint().getLocation();
+  }
+
+  public boolean isActive() {
+    synchronized (this) {
+      return this.active;
+    }
+  }
+  
+  public void internalDestroy() {
+    this.shouldDestroy.set(true); // probably already set but make sure
+    synchronized (this) {
+      this.active = false;
+      notifyAll();
+      Connection myCon = connection;
+      if (myCon != null) {
+        myCon.destroy();
+        connection = null;
+      }
+    }
+  }
+
+  /** When a pooled connection is destroyed, it's not destroyed
+   * right away, but when it is returned to the pool.
+   */
+  public void destroy() {
+    this.shouldDestroy.set(true);
+  }
+  
+  public void internalClose(boolean keepAlive) throws Exception {
+    try {
+      Connection con = this.connection;
+      if (con != null) {
+        con.close(keepAlive);
+      }
+    } finally {
+      internalDestroy();
+    }
+  }
+  
+  public void close(boolean keepAlive) throws Exception {
+    // needed to junit test
+    internalClose(keepAlive);
+//     throw new UnsupportedOperationException(
+//         "Pooled connections should only be closed by the connection manager");
+  }
+  
+  public void emergencyClose() {
+    Connection con = this.connection;
+    if (con != null) {
+      this.connection.emergencyClose();
+    }
+    this.connection = null;
+    
+  }
+
+  Connection getConnection() {
+    Connection result = this.connection;
+    if (result == null) {
+      throw new ConnectionDestroyedException();
+    }
+    return result;
+  }
+
+  /**
+   * Set the destroy bit if it is not already set.
+   * @return true if we were able to set to bit; false if someone else already did
+   */
+  public boolean setShouldDestroy() {
+    return this.shouldDestroy.compareAndSet(false, true);
+  }
+  
+  public boolean shouldDestroy() {
+    return this.shouldDestroy.get();
+  }
+  
+  public boolean isDestroyed() {
+    return connection == null;
+  }
+
+  public void passivate(final boolean accessed) {
+    long now = 0L;
+    if (accessed) {
+      // do this outside the sync
+      now = System.nanoTime();
+    }
+    synchronized (this) {
+      if(isDestroyed()) {
+        return;
+      }
+      if(!this.active) {
+        throw new InternalGemFireException("Connection not active");
+      }
+      this.active = false;
+      notifyAll();
+      if (accessed) {
+        this.lastAccessed = now; // do this while synchronized
+      }
+    }
+  }
+  
+  
+  public synchronized boolean switchConnection(Connection newCon)
+    throws InterruptedException {
+    Connection oldCon = null;
+    synchronized (this) {
+      if (shouldDestroy()) return false;
+      
+      if (this.active && !shouldDestroy()) {
+          this.waitingToSwitch = true;
+          try {
+            while (this.active && !shouldDestroy()) {
+              wait();
+            }
+          } finally {
+            this.waitingToSwitch = false;
+            notifyAll();
+          }
+      }
+      if (shouldDestroy()) return false;
+      assert !this.active;
+      final long now = System.nanoTime();
+      oldCon = this.connection;
+      this.connection = newCon;
+      this.endpoint = newCon.getEndpoint();
+      this.birthDate = now;
+    }
+    if (oldCon != null) {
+      try {
+        // do this outside of sync
+        oldCon.close(false);
+      } catch (Exception e) {
+        // ignore
+      }
+    }
+    return true;
+  }
+
+  public void activate() {
+    synchronized (this) {
+      try {
+        while (this.waitingToSwitch) {
+          wait();
+        }
+      } catch (InterruptedException ex) {
+        Thread.currentThread().interrupt();
+      }
+      getConnection(); // it checks if we are destroyed
+      if(active) {
+        throw new InternalGemFireException("Connection already active");
+      }
+      if(shouldDestroy()) {
+        throw new ConnectionDestroyedException();
+      }
+      active = true;
+    }
+  }
+
+  private synchronized long getLastAccessed() {
+    return lastAccessed;
+  }
+
+  public long getBirthDate() {
+    return this.birthDate;
+  }
+  
+  public void setBirthDate(long ts) {
+    this.birthDate = ts;
+  }
+
+  /**
+   * Returns the number of nanos remaining is this guys life.
+   */
+  public long remainingLife(long now, long timeoutNanos) {
+    return (getBirthDate() - now) + timeoutNanos;
+  }
+
+  private long remainingIdle(long now, long timeoutNanos) {
+    return (getLastAccessed() - now) + timeoutNanos;
+  }
+
+  /**
+   * If we were able to idle timeout this connection then return
+   * -1.
+   * If this connection has already been destroyed return 0.
+   * Otherwise return the amount of idle time he has remaining.
+   * If he is active we can't time him out now and a hint is returned
+   * as when we should check him next.
+   
+   * 
+   */
+  public long doIdleTimeout(long now, long timeoutNanos) {
+    if (shouldDestroy()) return 0;
+    synchronized (this) {
+      if (isActive()) {
+        // this is a reasonable value to return since odds are that
+        // when he goes inactive he will be resetting his access time.
+        return timeoutNanos;
+      } else {
+        long idleRemaining = remainingIdle(now, timeoutNanos);
+        if (idleRemaining <= 0) {
+          if (setShouldDestroy()) {
+            // we were able to set the destroy bit
+            return -1;
+          } else {
+            // someone else already destroyed it
+            return 0;
+          }
+        } else {
+          return idleRemaining;
+        }
+      }
+    }
+  }
+  /**
+   * Return true if the connection has been idle long enough to expire.
+   */
+  public boolean hasIdleExpired(long now, long timeoutNanos) {
+    synchronized (this) {
+      if (isActive()) {
+        return false;
+      } else {
+        return remainingIdle(now, timeoutNanos) <= 0;
+      }
+    }
+  }
+
+  public ByteBuffer getCommBuffer() {
+    return getConnection().getCommBuffer();
+  }
+
+  public Socket getSocket() {
+    return getConnection().getSocket();
+  }
+  
+  public OutputStream getOutputStream() {
+    return getConnection().getOutputStream();
+  }
+  
+  public InputStream getInputStream() {
+    return getConnection().getInputStream();
+  }
+
+  public ConnectionStats getStats() {
+    return getEndpoint().getStats();
+  }
+  
+  public Endpoint getEndpoint() {
+    return this.endpoint;
+  }
+  public ServerQueueStatus getQueueStatus() {
+    return getConnection().getQueueStatus();
+  }
+
+  @Override
+  public String toString() {
+    Connection myCon = connection;
+    if (myCon != null) {
+      return "Pooled Connection to " + this.endpoint + ": " + myCon.toString();
+    } else {
+      return "Pooled Connection to " + this.endpoint + ": Connection[DESTROYED]";
+    }
+  }
+
+  public Object execute(Op op) throws Exception {
+    return getConnection().execute(op);
+  }
+
+  public static void loadEmergencyClasses() {
+    ConnectionImpl.loadEmergencyClasses();
+  }
+  public short getWanSiteVersion(){
+    return getConnection().getWanSiteVersion();
+  }
+  
+  public int getDistributedSystemId() {
+    return getConnection().getDistributedSystemId();
+  }
+  
+  public void setWanSiteVersion(short wanSiteVersion){
+    getConnection().setWanSiteVersion(wanSiteVersion);
+  }
+
+  public void setConnectionID(long id) {
+    this.connection.setConnectionID(id);
+  }
+
+  public long getConnectionID() {
+    return this.connection.getConnectionID();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/package.html
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/package.html b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/package.html
new file mode 100644
index 0000000..e2f7bce
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/package.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<HTML>
+  <HEAD>
+    <TITLE>com.gemstone.gemfire.cache.client package</TITLE>
+  </HEAD>
+  <BODY>
+  The <code>com.gemstone.gemfire.cache.client</code> package provides APIs used
+  for client connectivity and caching.
+<p>
+Most clients will only need to create a 
+{@link com.gemstone.gemfire.cache.client.ClientCache}
+using a
+{@link com.gemstone.gemfire.cache.client.ClientCacheFactory}.
+<p>
+A client configures the servers it will connect to by creating one or more
+{@link com.gemstone.gemfire.cache.client.Pool pools}.
+For most use cases one pool per client is all you need and the easiest
+way to get a single pool is to use
+{@link com.gemstone.gemfire.cache.client.ClientCacheFactory}.
+If you do need more than one pool use a
+{@link com.gemstone.gemfire.cache.client.PoolFactory pool factory} obtained from the
+{@link com.gemstone.gemfire.cache.client.PoolManager pool manager} before you
+create the cache using 
+{@link com.gemstone.gemfire.cache.client.ClientCacheFactory}.
+<p>
+An alternative to these APIs is to use the <code>pool</code> XML element
+as described in the <code>cache6_5.dtd</code>.
+<p>
+If you create more than one pool then for regions that will use a pool you
+need to configure the pool name on the regions.
+This can be done by setting the
+pool name on the region using the
+{@link com.gemstone.gemfire.cache.client.ClientRegionFactory#setPoolName API}
+or using the <code>pool-name</code> attribute on the <code>region-attributes</code>
+as described in the <code>cache6_5.dtd</code>.
+
+<a name="declarative"><h2>Client Declarative Caching</h2>
+
+<p>A "caching XML file" declares regions, entries, and attributes.  When
+a <code>ClientCache</code> is created its contents can be initialized
+according to a caching XML file.
+The top level element must be a client-cache element.
+</p>
+
+<p>The Document Type Definition for a declarative cache XML file can
+be found in <code>"doc-files/cache6_5.dtd"</code>.
+For examples of declarative cache XML files see <A
+href="doc-files/example-client-cache.xml">example1</A>.
+
+  </BODY>
+</HTML>

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/control/RebalanceFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/control/RebalanceFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/control/RebalanceFactory.java
new file mode 100644
index 0000000..0db0b3a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/control/RebalanceFactory.java
@@ -0,0 +1,57 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache.control;
+
+import java.util.Set;
+
+/**
+ * Factory for defining and starting a {@link RebalanceOperation}.
+ * 
+ * @since 6.0
+ */
+public interface RebalanceFactory {
+  
+  /**
+   * Specify which regions to include in the rebalance operation. The default,
+   * <code>null<code>, means
+   * all regions should be rebalanced. Includes take precedence over excludes.
+   * 
+   * @param regions
+   *          A set containing the names of regions to include.
+   * @since 6.5
+   */
+  RebalanceFactory includeRegions(Set<String> regions);
+  
+  /**
+   * Exclude specific regions from the rebalancing operation. The default,
+   * <code>null<code>, means
+   * don't exclude any regions.
+   * 
+   * @param regions
+   *          A set containing the names of regions to exclude.
+   * @since 6.5
+   */
+  RebalanceFactory excludeRegions(Set<String> regions);
+  
+  /**
+   * Asynchronously starts a new rebalance operation. Only the GemFire
+   * controlled cache resources used by this member will be rebalanced.
+   * Operation may queue as needed for resources in contention by other
+   * active rebalance operations.
+   */
+  public RebalanceOperation start();
+
+  /**
+   * Simulates a rebalance of the GemFire controlled cache resources on this
+   * member. This operation will not make any actual changes. It will only
+   * produce a report of what the results would have been had this been a real
+   * rebalance operation.
+   */
+  public RebalanceOperation simulate();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/control/RebalanceOperation.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/control/RebalanceOperation.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/control/RebalanceOperation.java
new file mode 100644
index 0000000..a7fc69a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/control/RebalanceOperation.java
@@ -0,0 +1,66 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache.control;
+
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Operation for rebalancing resources used by the {@link 
+ * com.gemstone.gemfire.cache GemFire Cache}.
+ * 
+ * @since 6.0
+ */
+public interface RebalanceOperation {
+  
+  // NOTE: cancelled is the spelling used in java.util.concurrent.Future
+  
+  /**
+   * Returns true if this operation was cancelled before it completed.
+   */
+  public boolean isCancelled();
+
+  /**
+   * Returns true if this operation completed.
+   */
+  public boolean isDone();
+
+  /**
+   * Cancels this rebalance operation. The rebalance operation will find a
+   * safe point and then stop.
+   *
+   * @return false if this operation could not be cancelled, typically because
+   * it has already completed; true otherwise
+   */
+  public boolean cancel();
+
+  /**
+   * Wait for this operation to complete and return the results.
+   *
+   * @return the rebalance results
+   * @throws CancellationException if the operation was cancelled
+   * @throws InterruptedException if the wait was interrupted
+   */
+  public RebalanceResults getResults() 
+  throws CancellationException, InterruptedException;
+
+  /**
+   * Wait for this operation to complete and return the results.
+   *
+   * @param timeout the maximum time to wait
+   * @param unit the time unit of the timeout argument
+   * @return the rebalance results
+   * @throws CancellationException if the operation was cancelled
+   * @throws TimeoutException if the wait timed out
+   * @throws InterruptedException if the wait was interrupted 
+   */
+  public RebalanceResults getResults(long timeout, TimeUnit unit)
+  throws CancellationException, TimeoutException, InterruptedException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/control/RebalanceResults.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/control/RebalanceResults.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/control/RebalanceResults.java
new file mode 100644
index 0000000..987618a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/control/RebalanceResults.java
@@ -0,0 +1,97 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache.control;
+
+import java.util.Set;
+
+import com.gemstone.gemfire.cache.partition.PartitionRebalanceInfo;
+
+/**
+ * The results of rebalancing <code>Cache</code> resources.
+ * 
+ * @since 6.0
+ */
+public interface RebalanceResults {
+  
+  /**
+   * Returns a <code>Set</code> of detailed information about each partitioned
+   * region that was rebalanced.
+   * 
+   * @return a <code>Set</code> of detailed information about each partitioned
+   * region that was rebalanced
+   */
+  public Set<PartitionRebalanceInfo> getPartitionRebalanceDetails();
+  
+  /**
+   * Returns the total time, in milliseconds, that the rebalance operation took.
+   * 
+   * @return the total time, in milliseconds, that the rebalance operation took
+   */
+  public long getTotalTime();
+  
+  /**
+   * Returns the total number of buckets created during the rebalance operation.
+   * 
+   * @return the total number of buckets created during the rebalance operation
+   */
+  public int getTotalBucketCreatesCompleted();
+  
+  /**
+   * Returns the total size, in bytes, of all of the buckets that were created
+   * as part of the rebalance operation.
+   * 
+   * @return the total size, in bytes, of all of the buckets that were created
+   * as part of the rebalance operation
+   */
+  public long getTotalBucketCreateBytes();
+  
+  /**
+   * Returns the total time, in milliseconds, taken to create buckets.
+   * 
+   * @return the total time, in milliseconds, taken to create buckets
+   */
+  public long getTotalBucketCreateTime();
+  
+  /**
+   * Returns the total number of buckets transferred.
+   * 
+   * @return the total number of buckets transferred
+   */
+  public int getTotalBucketTransfersCompleted();
+  
+  /**
+   * Returns the total size, in bytes, of buckets that were transferred.
+   * 
+   * @return the total size, in bytes, of buckets that were transferred
+   */
+  public long getTotalBucketTransferBytes();
+  
+  /**
+   * Returns the total amount of time, in milliseconds, it took to transfer
+   * buckets.
+   * 
+   * @return the total amount of time, in milliseconds, it took to transfer 
+   * buckets
+   */
+  public long getTotalBucketTransferTime();
+  
+  /**
+   * Returns the total number of primaries that were transferred.
+   * 
+   * @return the total number of primaries that were transferred
+   */
+  public int getTotalPrimaryTransfersCompleted();
+  
+  /**
+   * Returns the total time, in milliseconds, spent transferring primaries.
+   * 
+   * @return the total time, in milliseconds, spent transferring primaries
+   */
+  public long getTotalPrimaryTransferTime();
+}


[42/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/AdminDistributedSystemImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/AdminDistributedSystemImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/AdminDistributedSystemImpl.java
new file mode 100755
index 0000000..3dcea3c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/AdminDistributedSystemImpl.java
@@ -0,0 +1,2507 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.LogWriter;
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.Alert;
+import com.gemstone.gemfire.admin.AlertLevel;
+import com.gemstone.gemfire.admin.AlertListener;
+import com.gemstone.gemfire.admin.BackupStatus;
+import com.gemstone.gemfire.admin.CacheServer;
+import com.gemstone.gemfire.admin.CacheServerConfig;
+import com.gemstone.gemfire.admin.CacheVm;
+import com.gemstone.gemfire.admin.ConfigurationParameter;
+import com.gemstone.gemfire.admin.DistributedSystemConfig;
+import com.gemstone.gemfire.admin.DistributionLocator;
+import com.gemstone.gemfire.admin.DistributionLocatorConfig;
+import com.gemstone.gemfire.admin.GemFireHealth;
+import com.gemstone.gemfire.admin.ManagedEntity;
+import com.gemstone.gemfire.admin.ManagedEntityConfig;
+import com.gemstone.gemfire.admin.OperationCancelledException;
+import com.gemstone.gemfire.admin.RuntimeAdminException;
+import com.gemstone.gemfire.admin.SystemMember;
+import com.gemstone.gemfire.admin.SystemMemberCacheListener;
+import com.gemstone.gemfire.admin.SystemMembershipEvent;
+import com.gemstone.gemfire.admin.SystemMembershipListener;
+import com.gemstone.gemfire.cache.persistence.PersistentID;
+import com.gemstone.gemfire.distributed.DistributedMember;
+import com.gemstone.gemfire.distributed.FutureCancelledException;
+import com.gemstone.gemfire.distributed.internal.DM;
+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.Assert;
+import com.gemstone.gemfire.internal.Banner;
+import com.gemstone.gemfire.internal.admin.ApplicationVM;
+import com.gemstone.gemfire.internal.admin.GemFireVM;
+import com.gemstone.gemfire.internal.admin.GfManagerAgent;
+import com.gemstone.gemfire.internal.admin.GfManagerAgentConfig;
+import com.gemstone.gemfire.internal.admin.GfManagerAgentFactory;
+import com.gemstone.gemfire.internal.admin.SSLConfig;
+import com.gemstone.gemfire.internal.admin.remote.CompactRequest;
+import com.gemstone.gemfire.internal.admin.remote.DistributionLocatorId;
+import com.gemstone.gemfire.internal.admin.remote.MissingPersistentIDsRequest;
+import com.gemstone.gemfire.internal.admin.remote.PrepareRevokePersistentIDRequest;
+import com.gemstone.gemfire.internal.admin.remote.RemoteApplicationVM;
+import com.gemstone.gemfire.internal.admin.remote.RemoteTransportConfig;
+import com.gemstone.gemfire.internal.admin.remote.RevokePersistentIDRequest;
+import com.gemstone.gemfire.internal.admin.remote.ShutdownAllRequest;
+import com.gemstone.gemfire.internal.cache.persistence.PersistentMemberPattern;
+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.log4j.LocalizedMessage;
+import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
+import com.gemstone.gemfire.internal.logging.log4j.LogWriterAppender;
+import com.gemstone.gemfire.internal.logging.log4j.LogWriterAppenders;
+import com.gemstone.gemfire.internal.util.concurrent.FutureResult;
+
+/**
+ * Represents a GemFire distributed system for remote administration/management.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ */
+public class AdminDistributedSystemImpl
+implements com.gemstone.gemfire.admin.AdminDistributedSystem,
+           com.gemstone.gemfire.internal.admin.JoinLeaveListener,
+           com.gemstone.gemfire.internal.admin.AlertListener,
+           com.gemstone.gemfire.distributed.internal.InternalDistributedSystem.DisconnectListener {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  /** String identity of this distributed system */
+  private String id;
+  
+  /** Latest alert broadcast by any system members */
+  private Alert latestAlert;
+  
+  // -------------------------------------------------------------------------
+
+  /** Internal admin agent to delegate low-level work to */
+  private volatile GfManagerAgent gfManagerAgent;
+
+  /** Monitors the health of this distributed system */
+  private GemFireHealth health;
+
+  /** Set of non-Manager members in this system */
+  private final Set applicationSet = new HashSet();
+  
+  /** Set of DistributionLocators for this system */
+  private final Set locatorSet = new HashSet();
+
+  /** Set of dedicated CacheServer members in this system */
+  private final Set cacheServerSet = new HashSet();
+
+  /** Configuration defining this distributed system */
+  private final DistributedSystemConfigImpl config;
+  
+  /** Controller for starting and stopping managed entities */
+  private ManagedEntityController controller;
+  
+  /** Log file collator for gathering and merging system member logs */
+  private LogCollator logCollator = new LogCollator();
+  
+  /** The level above which alerts will be delivered to the alert
+   * listeners */
+  private AlertLevel alertLevel = AlertLevel.WARNING;
+
+  /** The alert listeners registered on this distributed system. */
+  private volatile Set<AlertListener> alertListeners = Collections.emptySet();
+  private final Object alertLock = new Object();
+  
+  private LogWriterAppender logWriterAppender;
+  
+  private InternalLogWriter logWriter;
+  
+  /** The membership listeners registered on this distributed system */
+  private volatile Set membershipListeners = Collections.EMPTY_SET;
+  private final Object membershipLock = new Object();
+  
+  /* The region listeners registered on this distributed system */
+  //for feature requests #32887
+  private volatile List cacheListeners = Collections.EMPTY_LIST;
+  private final Object cacheListLock = new Object();
+  
+  /** 
+   * reference to AdminDistributedSystemImpl instance 
+   * for feature requests #32887. 
+   * <p>
+   * Guarded by {@link #CONNECTION_SYNC}.
+   * <p>
+   * TODO: reimplement this change and SystemMemberCacheEventProcessor to avoid
+   * using this static. SystemMemberCacheEvents should only be sent to Admin 
+   * VMs that express interest.
+   * <p>
+   * This is volatile to allow SystemFailure to deliver fatal poison-pill
+   * to thisAdminDS without waiting on synchronization.
+   * 
+   * @guarded.By CONNECTION_SYNC
+   */
+  private static volatile AdminDistributedSystemImpl thisAdminDS;
+
+  /**
+   * Provides synchronization for {@link #connect()} and {@link #disconnect()}.
+   * {@link #thisAdminDS} is also now protected by CONNECTION_SYNC and has its
+   * lifecycle properly tied to connect/disconnect.
+   */
+  private static final Object CONNECTION_SYNC = new Object();
+   
+  
+  // -------------------------------------------------------------------------
+  //   Constructor(s)
+  // -------------------------------------------------------------------------
+  
+  /** 
+   * Constructs new DistributedSystemImpl with the given configuration.
+   *
+   * @param config  configuration defining this distributed system
+   */
+  public AdminDistributedSystemImpl(DistributedSystemConfigImpl config) {
+                          
+    // init from config...
+    this.config = config;
+
+    String systemId = this.config.getSystemId();
+    if (systemId != null && systemId.length() > 0) {
+      this.id = systemId;
+
+    } if (this.getLocators() != null && this.getLocators().length() > 0) {
+      this.id = this.getLocators();
+
+    } else {
+      this.id = new StringBuffer(this.getMcastAddress()).append("[").append(
+          this.getMcastPort()).append("]").toString();
+    }
+
+    // LOG: create LogWriterAppender unless one already exists
+    this.logWriterAppender = LogWriterAppenders.getOrCreateAppender(LogWriterAppenders.Identifier.MAIN, false, this.config.createLogConfig(), false);
+    
+    // LOG: look in DistributedSystemConfigImpl for existing LogWriter to use
+    InternalLogWriter existingLogWriter = this.config.getInternalLogWriter();
+    if (existingLogWriter != null) {
+      this.logWriter = existingLogWriter;
+    } else {      
+      // LOG: create LogWriterLogger
+      this.logWriter = LogWriterFactory.createLogWriterLogger(false, false, this.config.createLogConfig(), false);
+      // LOG: changed statement from config to info
+      this.logWriter.info(Banner.getString(null));
+      // Set this log writer in DistributedSystemConfigImpl
+      this.config.setInternalLogWriter(this.logWriter);
+    }
+    
+    // set up other details that depend on config attrs...
+    this.controller = ManagedEntityControllerFactory.createManagedEntityController(this);
+    initializeDistributionLocators();
+    initializeCacheServers();
+  }
+  
+  // -------------------------------------------------------------------------
+  //   Initialization
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Creates DistributionLocator instances for every locator entry in the
+   * {@link com.gemstone.gemfire.admin.DistributedSystemConfig}
+   */
+  private void initializeDistributionLocators() {
+    DistributionLocatorConfig[] configs =
+      this.config.getDistributionLocatorConfigs();
+    if (configs.length == 0) {
+      // No work to do
+      return;
+    }
+
+    for (int i = 0; i < configs.length; i++) {
+      // the Locator impl may vary in this class from the config...
+      DistributionLocatorConfig conf = configs[i];
+      DistributionLocator locator =
+        createDistributionLocatorImpl(conf);
+      this.locatorSet.add(new FutureResult(locator));
+    }
+    // update locators string...
+    setLocators(parseLocatorSet());
+  }
+  
+  /**
+   * Creates <code>CacheServer</code> instances for every cache server
+   * entry in the {@link
+   * com.gemstone.gemfire.admin.DistributedSystemConfig}
+   */
+  private void initializeCacheServers() {
+    CacheServerConfig[] cacheServerConfigs =
+      this.config.getCacheServerConfigs();
+    for (int i = 0; i < cacheServerConfigs.length; i++) {
+      try {
+        CacheServerConfig conf = cacheServerConfigs[i];
+        CacheServerConfigImpl copy =
+          new CacheServerConfigImpl(conf);
+        this.cacheServerSet.add(new FutureResult(createCacheServer(copy)));
+      } catch (java.lang.Exception e) {
+        logger.warn(e.getMessage(), e);
+        continue;
+      } 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 (java.lang.Error 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();
+        logger.error(e.getMessage(), e);
+        continue;
+      }
+    }
+  }
+
+  /**
+   * Checks to make sure that {@link #connect()} has been called.
+   *
+   * @throws IllegalStateException
+   *         If {@link #connect()} has not been called.
+   */
+  private void checkConnectCalled() {
+    if (this.gfManagerAgent == null) {
+      throw new IllegalStateException(LocalizedStrings.AdminDistributedSystemImpl_CONNECT_HAS_NOT_BEEN_INVOKED_ON_THIS_ADMINDISTRIBUTEDSYSTEM.toLocalizedString());
+    }
+  }
+
+  // -------------------------------------------------------------------------
+  //   Attributes of this DistributedSystem
+  // -------------------------------------------------------------------------
+  
+  public GfManagerAgent getGfManagerAgent() {
+    return this.gfManagerAgent;
+  }
+  
+  public boolean isConnected() {
+    return this.gfManagerAgent != null && this.gfManagerAgent.isConnected();
+  }
+
+  public String getId() {
+    return this.id;
+  }
+  
+  public String getName() {
+    String name = this.config.getSystemName();
+    if (name != null && name.length() > 0) {
+      return name;        
+
+    } else {
+      return getId();
+    }
+  }
+
+  public String getSystemName() {
+    return this.config.getSystemName();
+  }
+
+  public String getRemoteCommand() {
+    return this.config.getRemoteCommand();
+  }
+
+  public void setRemoteCommand(String remoteCommand) {
+    this.config.setRemoteCommand(remoteCommand);
+  }
+
+  public void setAlertLevel(AlertLevel level) {
+    if (this.isConnected()) {
+      this.gfManagerAgent.setAlertLevel(level.getSeverity());
+    }
+
+    this.alertLevel = level;
+  }
+
+  public AlertLevel getAlertLevel() {
+    return this.alertLevel;
+  }
+
+  public void addAlertListener(AlertListener listener) {
+    synchronized (this.alertLock) {
+      Set<AlertListener> oldListeners = this.alertListeners;
+      if (!oldListeners.contains(listener)) {
+        Set<AlertListener> newListeners = new HashSet<AlertListener>(oldListeners);
+        newListeners.add(listener);
+        this.alertListeners = newListeners;
+      }
+    }
+  }
+
+  public int getAlertListenerCount() {
+    synchronized (this.alertLock) {
+      return this.alertListeners.size();
+    }
+  }
+  
+  public void removeAlertListener(AlertListener listener) {
+    synchronized (this.alertLock) {
+      Set<AlertListener> oldListeners = this.alertListeners;
+      if (oldListeners.contains(listener)) { // fixed bug 34687
+        Set<AlertListener> newListeners = new HashSet<AlertListener>(oldListeners);
+        if (newListeners.remove(listener)) {
+          this.alertListeners = newListeners;
+        }
+      }
+    }
+  }
+
+  public void addMembershipListener(SystemMembershipListener listener) {
+    synchronized (this.membershipLock) {
+      Set oldListeners = this.membershipListeners;
+      if (!oldListeners.contains(listener)) {
+        Set newListeners = new HashSet(oldListeners);
+        newListeners.add(listener);
+        this.membershipListeners = newListeners;
+      }
+    }
+  }
+
+  public void removeMembershipListener(SystemMembershipListener listener) {
+    synchronized (this.membershipLock) {
+      Set oldListeners = this.membershipListeners;
+      if (oldListeners.contains(listener)) { // fixed bug 34687
+        Set newListeners = new HashSet(oldListeners);
+        if (newListeners.remove(listener)) {
+          this.membershipListeners = newListeners;
+        }
+      }
+    }
+  }
+
+  public String getMcastAddress() {
+    return this.config.getMcastAddress();
+  }
+
+  public int getMcastPort() {
+    return this.config.getMcastPort();
+  }
+  
+  public boolean getDisableTcp() {
+    return this.config.getDisableTcp();
+  }
+  
+  public boolean getDisableAutoReconnect() {
+    return this.config.getDisableAutoReconnect();
+  }
+
+  public String getLocators() {
+    return this.config.getLocators();
+  }
+  
+  protected void setLocators(String locators) {
+    this.config.setLocators(locators);
+  }
+  
+  public String getMembershipPortRange() {
+    return this.getConfig().getMembershipPortRange();
+  }
+  
+  /** get the direct-channel port to use, or zero if not set */
+  public int getTcpPort() {
+    return this.getConfig().getTcpPort();
+  }
+  
+  public void setTcpPort(int port) {
+    this.getConfig().setTcpPort(port);
+  }
+
+  public void setMembershipPortRange(String membershipPortRange) {
+    this.getConfig().setMembershipPortRange(membershipPortRange);
+  }
+
+  public DistributedSystemConfig getConfig() {
+    return this.config;
+  }
+  
+  /**
+   * Returns true if any members of this system are currently running.
+   */
+  public boolean isRunning() {
+    if (this.gfManagerAgent == null) return false;
+    // is there a better way??
+    // this.gfManagerAgent.isConnected() ... this.gfManagerAgent.isListening()
+    
+    if (isAnyMemberRunning()) return true;
+    return false;
+  }
+  
+  /** Returns true if this system is using multicast instead of locators */
+  public boolean isMcastDiscovery() {
+    return this.isMcastEnabled() && (this.getLocators().length() == 0);
+  }
+  
+  /** Returns true if this system can use multicast for communications */
+  public boolean isMcastEnabled() {
+    return this.getMcastPort() > 0 ;
+  }
+  
+  ManagedEntityController getEntityController() {
+    return this.controller;
+  }
+  
+  static private final String TIMEOUT_MS_NAME 
+      = "AdminDistributedSystemImpl.TIMEOUT_MS";
+  static private final int TIMEOUT_MS_DEFAULT = 60000; // 30000 -- see bug36470
+  static private final int TIMEOUT_MS 
+      = Integer.getInteger(TIMEOUT_MS_NAME, TIMEOUT_MS_DEFAULT).intValue();
+  
+
+  // -------------------------------------------------------------------------
+  //   Operations of this DistributedSystem
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Starts all managed entities in this system.
+   */
+  public void start() throws AdminException {
+    // Wait for each managed entity to start (see bug 32569)
+    DistributionLocator[] locs = getDistributionLocators();
+    for (int i = 0; i < locs.length; i++) {
+      locs[i].start();
+    }
+    for (int i = 0; i < locs.length; i++) {
+      try {
+        if (!locs[i].waitToStart(TIMEOUT_MS)) {
+          throw new AdminException(LocalizedStrings.AdminDistributedSystemImpl_0_DID_NOT_START_AFTER_1_MS.toLocalizedString(new Object[] {locs[i], Integer.valueOf(TIMEOUT_MS)}));
+        }
+
+      } catch (InterruptedException ex) {
+        Thread.currentThread().interrupt();
+        throw new AdminException(LocalizedStrings.AdminDistributedSystemImpl_INTERRUPTED_WHILE_WAITING_FOR_0_TO_START.toLocalizedString(locs[i]), ex);
+      }
+    }
+
+    CacheServer[] servers = getCacheServers();
+    for (int i = 0; i < servers.length; i++) {
+      servers[i].start();
+    }
+    for (int i = 0; i < servers.length; i++) {
+      try {
+        if (!servers[i].waitToStart(TIMEOUT_MS)) {
+          throw new AdminException(LocalizedStrings.AdminDistributedSystemImpl_0_DID_NOT_START_AFTER_1_MS.toLocalizedString(new Object[] {servers[i], Integer.valueOf(TIMEOUT_MS)}));
+        }
+
+      } catch (InterruptedException ex) {
+        Thread.currentThread().interrupt();
+        throw new AdminException(LocalizedStrings.AdminDistributedSystemImpl_INTERRUPTED_WHILE_WAITING_FOR_0_TO_START.toLocalizedString(servers[i]), ex);
+      }
+    }
+  }
+  
+  /**
+   * Stops all GemFire managers that are members of this system.
+   */
+  public void stop() throws AdminException {
+    // Stop cache server before GemFire managers because the cache
+    // server might host a cache proxy that is dependent on the
+    // manager.  See bug 32569.
+
+    // Wait for each managed entity to stop (see bug 32569)
+    long timeout = 30;
+
+    CacheServer[] servers = getCacheServers();
+    for (int i = 0; i < servers.length; i++) {
+      servers[i].stop();
+    }
+    for (int i = 0; i < servers.length; i++) {
+      try {
+        if (!servers[i].waitToStop(timeout * 1000)) {
+          throw new AdminException(LocalizedStrings.AdminDistributedSystemImpl_0_DID_NOT_STOP_AFTER_1_SECONDS.toLocalizedString(new Object[] {servers[i], Long.valueOf(timeout)}));
+        }
+
+      } catch (InterruptedException ex) {
+        Thread.currentThread().interrupt();
+        throw new AdminException(LocalizedStrings.AdminDistributedSystemImpl_INTERRUPTED_WHILE_WAITING_FOR_0_TO_STOP.toLocalizedString(servers[i]), ex);
+      }
+    }
+
+    DistributionLocator[] locs = getDistributionLocators();
+    for (int i = 0; i < locs.length; i++) {
+      locs[i].stop();
+    }
+    for (int i = 0; i < locs.length; i++) {
+      try {
+        if (!locs[i].waitToStop(timeout * 1000)) {
+          throw new AdminException(LocalizedStrings.AdminDistributedSystemImpl_0_DID_NOT_STOP_AFTER_1_SECONDS.toLocalizedString(new Object[] {locs[i], Long.valueOf(timeout)}));
+        }
+
+      } catch (InterruptedException ex) {
+        Thread.currentThread().interrupt();
+        throw new AdminException(LocalizedStrings.AdminDistributedSystemImpl_INTERRUPTED_WHILE_WAITING_FOR_0_TO_STOP.toLocalizedString(locs[i]), ex);
+      }
+    }
+  }
+  
+  /** Display merged system member logs */
+  public String displayMergedLogs() {
+    return this.logCollator.collateLogs(this.gfManagerAgent);
+  }
+
+   /**
+   * Returns the license for this GemFire product; else null if unable to
+   * retrieve license information
+   *
+   * @return license for this GemFire product
+   */
+  public java.util.Properties getLicense() {
+    SystemMember member = findFirstRunningMember();
+    if (member != null) {
+      return new Properties();
+    } else {
+      return null;
+    }
+  }
+
+  /**
+   * Sets the distribution-related portion of the given managed entity's
+   * configuration so that the entity is part of this distributed system.
+   * 
+   * @throws AdminException
+   *                 TODO-javadocs
+   */
+  private void setDistributionParameters(SystemMember member) 
+    throws AdminException {
+
+    Assert.assertTrue(member instanceof ManagedSystemMemberImpl);
+
+    // set some config parms to match this system...
+    ConfigurationParameter[] configParms = new ConfigurationParameter[] {
+        new ConfigurationParameterImpl(
+            DistributionConfig.MCAST_PORT_NAME, 
+            Integer.valueOf(this.config.getMcastPort())),
+        new ConfigurationParameterImpl(
+            DistributionConfig.LOCATORS_NAME, 
+            this.config.getLocators()),
+        new ConfigurationParameterImpl(
+            DistributionConfig.MCAST_ADDRESS_NAME, 
+            InetAddressUtil.toInetAddress(this.config.getMcastAddress())),
+        new ConfigurationParameterImpl(
+            DistributionConfig.DISABLE_TCP_NAME,
+            Boolean.valueOf(this.config.getDisableTcp()) ),
+      };
+    member.setConfiguration(configParms);
+  }
+
+  /**
+   * Handles an <code>ExecutionException</code> by examining its cause
+   * and throwing an appropriate runtime exception.
+   */
+  private static void handle(ExecutionException ex) {
+    Throwable cause = ex.getCause();
+
+    if (cause instanceof OperationCancelledException) {
+      // Operation was cancelled, we don't necessary want to propagate
+      // this up to the user.
+      return;
+    }
+    if (cause instanceof CancelException) { // bug 37285
+      throw new FutureCancelledException(LocalizedStrings.AdminDistributedSystemImpl_FUTURE_CANCELLED_DUE_TO_SHUTDOWN.toLocalizedString(), ex);
+    }
+
+    // Don't just throw the cause because the stack trace can be
+    // misleading.  For instance, the cause might have occurred in a
+    // different thread.  In addition to the cause, we also want to
+    // know which code was waiting for the Future.
+    throw new RuntimeAdminException(LocalizedStrings.AdminDistributedSystemImpl_WHILE_WAITING_FOR_FUTURE.toLocalizedString(), ex);
+  }
+  
+  protected void checkCancellation() {
+    DM dm = this.getDistributionManager();
+    // TODO does dm == null mean we're dead?
+    if (dm != null) {
+      dm.getCancelCriterion().checkCancelInProgress(null);
+    }
+  }
+  /**
+   * Returns a list of manageable SystemMember instances for each
+   * member of this distributed system.
+   *
+   * @return array of system members for each non-manager member
+   */
+  public SystemMember[] getSystemMemberApplications()
+  throws com.gemstone.gemfire.admin.AdminException {
+    synchronized(this.applicationSet) {
+      Collection coll = new ArrayList(this.applicationSet.size());
+      APPS: for (Iterator iter = this.applicationSet.iterator();
+           iter.hasNext(); ) {
+        Future future = (Future) iter.next();
+//         this.logger.info("DEBUG: getSystemMemberApplications: " + future);
+        for (;;) {
+          checkCancellation();
+          boolean interrupted = Thread.interrupted();
+          try {
+            coll.add(future.get());
+            break;
+          } 
+          catch (InterruptedException ex) {
+            interrupted = true;
+            continue; // keep trying
+          } 
+          catch (CancellationException ex) {
+//             this.logger.info("DEBUG: cancelled: " + future, ex);
+            continue APPS;
+          } 
+          catch (ExecutionException ex) {
+//             this.logger.info("DEBUG: executed: " + future);
+            handle(ex);
+            continue APPS;
+          }
+          finally {
+            if (interrupted) {
+              Thread.currentThread().interrupt();
+            }
+          }
+        } // for
+      } // APPS
+      SystemMember[] array = new SystemMember[coll.size()];
+      coll.toArray(array);
+      return array;
+    }
+  }
+
+  /**
+   * Display in readable format the latest Alert in this distributed system.
+   *
+   * TODO: create an external admin api object for Alert
+   */
+  public String getLatestAlert() {
+    if (this.latestAlert == null) {
+      return "";
+    }
+    return this.latestAlert.toString();
+  }
+  
+  /**
+   * Connects to the currently configured system.
+   */
+  public void connect() {
+    connect(this.logWriter);
+  }
+
+  /**
+   * Connects to the currently configured system.  This method is
+   * public for internal use only (testing, for example).
+   *
+   * <p>
+   *
+   * See {@link
+   * com.gemstone.gemfire.distributed.DistributedSystem#connect} for a
+   * list of exceptions that may be thrown.
+   *
+   * @param logWriter the InternalLogWriter to use for any logging
+   */
+  public void connect(InternalLogWriter logWriter) {
+    synchronized (CONNECTION_SYNC) {
+      //Check if the gfManagerAgent is NOT null. 
+      //If it is already listening, then just return since the connection is already established OR in process.
+      //Otherwise cleanup the state of AdminDistributedSystemImpl. This needs to happen automatically.
+      if(this.gfManagerAgent != null) {
+       if(this.gfManagerAgent.isListening()) {
+         if (logger.isDebugEnabled()) {
+           logger.debug("The RemoteGfManagerAgent is already listening for this AdminDistributedSystem.");
+         }
+         return;
+       }
+       this.disconnect();
+      }
+      
+      if (thisAdminDS != null) { // TODO: beef up toString and add thisAdminDS
+        throw new IllegalStateException(LocalizedStrings.AdminDistributedSystemImpl_ONLY_ONE_ADMINDISTRIBUTEDSYSTEM_CONNECTION_CAN_BE_MADE_AT_ONCE.toLocalizedString());
+      }
+      
+      thisAdminDS = this; //added for feature requests #32887
+      
+      if (this.getLocators().length() == 0) {
+        this.id =
+          this.getMcastAddress() + "[" + this.getMcastPort() + "]";
+  
+      } else {
+        this.id = this.getLocators();
+      }
+  
+      if (this.config instanceof DistributedSystemConfigImpl) {
+        ((DistributedSystemConfigImpl) this.config).validate();
+        ((DistributedSystemConfigImpl) this.config).setDistributedSystem(this);
+      }
+  
+      // LOG: passes the AdminDistributedSystemImpl LogWriterLogger into GfManagerAgentConfig for RemoteGfManagerAgent
+      GfManagerAgent agent = 
+          GfManagerAgentFactory.getManagerAgent(buildAgentConfig(logWriter));         
+      this.gfManagerAgent = agent;
+  
+      // sync to prevent bug 33341 Admin API can double-represent system members
+      synchronized(this.membershipListenerLock) {
+      // build the list of applications...
+        ApplicationVM[] apps = this.gfManagerAgent.listApplications();
+        for (int i = 0; i < apps.length; i++) {
+          nodeJoined(null, apps[i]);
+        }
+      }
+
+      // Build admin objects for all locators (see bug 31959)
+      String locators = this.getLocators();
+      StringTokenizer st = new StringTokenizer(locators, ",");
+  NEXT:
+      while(st.hasMoreTokens()) {
+        String locator = st.nextToken();
+        int first = locator.indexOf("[");
+        int last = locator.indexOf("]");
+        String host = locator.substring(0, first);
+        int colidx = host.lastIndexOf('@');
+        if (colidx < 0) {
+          colidx = host.lastIndexOf(':');
+        }
+        String bindAddr = null;
+        if (colidx > 0 && colidx < (host.length()-1)) {
+          String orig = host;
+          bindAddr = host.substring(colidx+1, host.length());
+          host = host.substring(0, colidx);
+          // if the host contains a colon and there's no '@', we probably
+          // parsed an ipv6 address incorrectly - try again
+          if (host.indexOf(':') >= 0) {
+            int bindidx = orig.lastIndexOf('@');
+            if (bindidx >= 0) {
+              host = orig.substring(0, bindidx);
+              bindAddr = orig.substring(bindidx+1);
+            }
+            else {
+              host = orig;
+              bindAddr = null;
+            }
+          }
+        }
+        int port = Integer.parseInt(locator.substring(first+1, last));
+
+        synchronized (this.locatorSet) {
+          LOCATORS:
+            for (Iterator iter = this.locatorSet.iterator();
+               iter.hasNext(); ) {
+            Future future = (Future) iter.next();
+            DistributionLocatorImpl impl = null;
+            for (;;) {
+              checkCancellation();
+              boolean interrupted = Thread.interrupted();
+              try {
+                impl = (DistributionLocatorImpl) future.get();
+                break; // success
+              } 
+              catch (InterruptedException ex) {
+                interrupted = true;
+                continue; // keep trying
+              } 
+              catch (CancellationException ex) {
+                continue LOCATORS;
+              } 
+              catch (ExecutionException ex) {
+                handle(ex);
+                continue LOCATORS;
+              }
+              finally {
+                if (interrupted) {
+                  Thread.currentThread().interrupt();
+                }
+              }
+            } // for
+
+            DistributionLocatorConfig conf = impl.getConfig();
+
+            InetAddress host1 = InetAddressUtil.toInetAddress(host);
+            InetAddress host2 =
+              InetAddressUtil.toInetAddress(conf.getHost());
+            if (port == conf.getPort() && host1.equals(host2)) {
+              // Already have an admin object for this locator
+              continue NEXT;
+            }
+          }
+        }
+
+        // None of the existing locators matches the locator in the
+        // string.  Contact the locator to get information and create
+        // an admin object for it.
+        InetAddress bindAddress = null;
+        if (bindAddr != null) {
+          bindAddress = InetAddressUtil.toInetAddress(bindAddr);
+        }
+        DistributionLocatorConfig conf =
+          DistributionLocatorConfigImpl.createConfigFor(host, port,
+                                                        bindAddress);
+        if (conf != null) {
+          DistributionLocator impl = 
+            createDistributionLocatorImpl(conf);
+          synchronized (this.locatorSet) {
+            this.locatorSet.add(new FutureResult(impl));
+          }
+        }
+      }
+    }
+  }
+  
+  /**
+   * Polls to determine whether or not the connection to the
+   * distributed system has been made.
+   */
+  public boolean waitToBeConnected(long timeout) 
+    throws InterruptedException {
+
+    if (Thread.interrupted()) throw new InterruptedException();
+    
+    checkConnectCalled();
+
+    long start = System.currentTimeMillis();
+    while (System.currentTimeMillis() - start < timeout) {
+      if (this.gfManagerAgent.isInitialized()) {
+        return true;
+
+      } else {
+        Thread.sleep(100);
+      }
+    }
+
+    return this.isConnected();
+  }
+
+  /** 
+   * Closes all connections and resources to the connected distributed system.
+   *
+   * @see com.gemstone.gemfire.distributed.DistributedSystem#disconnect()
+   */
+  public void disconnect() {
+    synchronized (CONNECTION_SYNC) {
+//      if (!isConnected()) {
+//        throw new IllegalStateException(this + " is not connected");
+//      }
+//      Assert.assertTrue(thisAdminDS == this);
+      if (this.logWriterAppender != null) {
+        LogWriterAppenders.stop(LogWriterAppenders.Identifier.MAIN);
+      }
+      try {
+      if (thisAdminDS == this) {
+        thisAdminDS = null;
+      }
+      if (this.gfManagerAgent != null && this.gfManagerAgent.isListening()){
+        synchronized (this) {
+          if (this.health != null) {
+            this.health.close();
+          }
+        }
+        this.gfManagerAgent.removeJoinLeaveListener(this);
+        this.gfManagerAgent.disconnect();
+      }
+      this.gfManagerAgent = null;
+      if (this.config instanceof DistributedSystemConfigImpl) {
+        ((DistributedSystemConfigImpl) this.config).setDistributedSystem(null);
+      }
+      } finally {
+        if (logWriterAppender != null) {
+          LogWriterAppenders.destroy(LogWriterAppenders.Identifier.MAIN);
+        }
+      }
+    }
+  }
+  
+  /**
+   * Returns the DistributionManager this implementation is using to
+   * connect to the distributed system.
+   */
+  public DM getDistributionManager() {
+    if (this.gfManagerAgent == null) {
+      return null;
+    }
+    return this.gfManagerAgent.getDM();
+    
+  }
+  
+  /**
+   * Returns the internal admin API's agent used for administering
+   * this <code>AdminDistributedSystem</code>.
+   *
+   * @since 4.0
+   */
+  public GfManagerAgent getAdminAgent() {
+    return this.gfManagerAgent;
+  }
+  
+  /**
+   * Adds a new, unstarted <code>DistributionLocator</code> to this
+   * distributed system.
+   */
+  public DistributionLocator addDistributionLocator() {
+    DistributionLocatorConfig conf =
+      new DistributionLocatorConfigImpl();
+    DistributionLocator locator = 
+      createDistributionLocatorImpl(conf);
+    synchronized (this.locatorSet) {
+      this.locatorSet.add(new FutureResult(locator));
+    }
+
+    // update locators string...
+    setLocators(parseLocatorSet());
+    return locator;
+  }
+  
+  public DistributionLocator[] getDistributionLocators() {
+    synchronized(this.locatorSet) {
+      Collection coll = new ArrayList(this.locatorSet.size());
+      LOCATORS: for (Iterator iter = this.locatorSet.iterator();
+           iter.hasNext();) {
+        Future future = (Future) iter.next();
+        for (;;) {
+          checkCancellation();
+          boolean interrupted = Thread.interrupted();
+          try {
+            coll.add(future.get());
+            break; // success
+          } 
+          catch (InterruptedException ex) {
+            interrupted = true;
+            continue; // keep trying
+          } 
+          catch (CancellationException ex) {
+            continue LOCATORS;
+          } 
+          catch (ExecutionException ex) {
+            handle(ex);
+            continue LOCATORS;
+          }
+          finally {
+            if (interrupted) {
+              Thread.currentThread().interrupt();
+            }
+          }
+        } // for
+      }
+
+      DistributionLocator[] array =
+        new DistributionLocator[coll.size()];
+      coll.toArray(array);
+      return array;
+    }
+  }
+  
+  /**
+   * Updates the locator string that is used to discover members of
+   * the distributed system.
+   *
+   * @see #getLocators
+   */
+  void updateLocatorsString() {
+    this.setLocators(parseLocatorSet());
+  }
+
+  protected String parseLocatorSet() {
+    StringBuffer sb = new StringBuffer();
+    LOCATORS: for (Iterator iter = this.locatorSet.iterator(); iter.hasNext();) {
+      Future future = (Future) iter.next();
+      DistributionLocator locator = null;
+      for (;;) {
+        checkCancellation();
+        boolean interrupted = Thread.interrupted();
+        try {
+          locator = (DistributionLocator) future.get();
+          break; // success
+        } 
+        catch (InterruptedException ex) {
+          interrupted = true;
+          continue; // keep trying
+        } 
+        catch (CancellationException ex) {
+          continue LOCATORS;
+        } 
+        catch (ExecutionException ex) {
+          handle(ex);
+          continue LOCATORS;
+        }
+        finally {
+          if (interrupted) {
+            Thread.currentThread().interrupt();
+          }
+        }
+      }
+      sb.append(locator.getConfig().getHost());
+      sb.append("[").append(locator.getConfig().getPort()).append("]");
+
+      if (iter.hasNext()) {
+        sb.append(",");
+      }
+    }
+    return sb.toString();
+  }
+  
+  // -------------------------------------------------------------------------
+  //   Listener callback methods
+  // -------------------------------------------------------------------------
+  
+  /** sync to prevent bug 33341 Admin API can double-represent system members */
+  private final Object membershipListenerLock = new Object();
+  
+  // --------- com.gemstone.gemfire.internal.admin.JoinLeaveListener ---------
+  /** 
+   * Listener callback for when a member has joined this DistributedSystem.
+   * <p>
+   * React by adding the SystemMember to this system's
+   * internal lists, if they are not already there.  Notice that we
+   * add a {@link Future} into the list so that the admin object is
+   * not initialized while locks are held.
+   *
+   * @param source  the distributed system that fired nodeJoined
+   * @param vm  the VM that joined
+   * @see com.gemstone.gemfire.internal.admin.JoinLeaveListener#nodeJoined
+   */
+  public void nodeJoined(GfManagerAgent source, final GemFireVM vm) {
+    // sync to prevent bug 33341 Admin API can double-represent system members
+    synchronized(this.membershipListenerLock) {
+//     this.logger.info("DEBUG: nodeJoined: " + vm.getId(), new RuntimeException("STACK"));
+
+    // does it already exist?
+    SystemMember member = findSystemMember(vm);
+    
+    // if not then create it...
+    if (member == null) {
+//       this.logger.info("DEBUG: no existing member: " + vm.getId());
+      FutureTask future = null;
+      //try {
+        if (vm instanceof ApplicationVM) {
+          final ApplicationVM app = (ApplicationVM) vm;
+          if (app.isDedicatedCacheServer()) {
+            synchronized (this.cacheServerSet) {
+              future = new AdminFutureTask(vm.getId(), new Callable() {
+                  public Object call() throws Exception {
+                    logger.info(LogMarker.DM, LocalizedMessage.create(LocalizedStrings.AdminDistributedSystemImpl_ADDING_NEW_CACHESERVER_FOR__0, vm));
+                    return createCacheServer(app);
+                  }
+                });
+                                      
+              this.cacheServerSet.add(future);
+            }
+
+          } else {
+            synchronized (this.applicationSet) {
+              future = new AdminFutureTask(vm.getId(), new Callable() {
+                  public Object call() throws Exception {
+                    logger.info(LogMarker.DM, LocalizedMessage.create(LocalizedStrings.AdminDistributedSystemImpl_ADDING_NEW_APPLICATION_FOR__0, vm));
+                    return createSystemMember(app); 
+                  }
+                });
+              this.applicationSet.add(future);
+            }
+          }
+
+        } else {
+          Assert.assertTrue(false, "Unknown GemFireVM type: " +
+                            vm.getClass().getName());
+        } 
+
+//      } catch (AdminException ex) {
+//        String s = "Could not create a SystemMember for " + vm;
+//        this.logger.warning(s, ex);
+//      }
+
+      // Wait for the SystemMember to be created.  We want to do this
+      // outside of the "set" locks.
+      future.run();
+      for (;;) {
+        checkCancellation();
+        boolean interrupted = Thread.interrupted();
+        try {
+          member = (SystemMember) future.get();
+          break; // success
+        } 
+        catch (InterruptedException ex) {
+          interrupted = true;
+          continue; // keep trying
+        } 
+        catch (CancellationException ex) {
+//           this.logger.info("DEBUG: run cancelled: " + future, ex);
+          return;
+        } 
+        catch (ExecutionException ex) {
+//           this.logger.info("DEBUG: run executed: " + future, ex);
+          handle(ex);
+          return;
+        }
+        finally {
+          if (interrupted) {
+            Thread.currentThread().interrupt();
+          }
+        }
+      } // for
+
+      Assert.assertTrue(member != null);
+
+      // moved this up into the if that creates a new member to fix bug 34517
+      SystemMembershipEvent event = new SystemMembershipEventImpl(member.getDistributedMember());
+      for (Iterator iter = this.membershipListeners.iterator();
+           iter.hasNext(); ) {
+        SystemMembershipListener listener =
+          (SystemMembershipListener) iter.next();
+        listener.memberJoined(event);
+      }
+//     } else {
+//       this.logger.info("DEBUG: found existing member: " + member);
+    }
+
+    }
+  }
+  
+  /** 
+   * Listener callback for when a member of this DistributedSystem has left.
+   * <p>
+   * Reacts by removing the member.
+   *
+   * @param source  the distributed system that fired nodeCrashed
+   * @param vm    the VM that left
+   * @see com.gemstone.gemfire.internal.admin.JoinLeaveListener#nodeLeft
+   */
+  public void nodeLeft(GfManagerAgent source, GemFireVM vm) {
+    // sync to prevent bug 33341 Admin API can double-represent system members
+    synchronized(this.membershipListenerLock) {
+      // member has left...
+      SystemMember member = 
+          AdminDistributedSystemImpl.this.removeSystemMember(vm.getId());
+      if (member == null) {
+        return; // reinstated this early-out because removal does not fix 39429
+      }
+  
+      // Can't call member.getId() because it is nulled-out when the
+      // SystemMember is removed.
+      SystemMembershipEvent event = new SystemMembershipEventImpl(vm.getId());
+      for (Iterator iter = this.membershipListeners.iterator();
+           iter.hasNext(); ) {
+        SystemMembershipListener listener =
+          (SystemMembershipListener) iter.next();
+        listener.memberLeft(event);
+      }
+    }
+  }
+  
+  /** 
+   * Listener callback for when a member of this DistributedSystem has crashed.
+   * <p>
+   * Reacts by removing the member.
+   *
+   * @param source  the distributed system that fired nodeCrashed
+   * @param vm the VM that crashed
+   * @see com.gemstone.gemfire.internal.admin.JoinLeaveListener#nodeCrashed
+   */
+  public void nodeCrashed(GfManagerAgent source, GemFireVM vm) {
+    // sync to prevent bug 33341 Admin API can double-represent system members
+    synchronized(this.membershipListenerLock) {
+      // member has crashed...
+      SystemMember member = 
+        AdminDistributedSystemImpl.this.removeSystemMember(vm.getId());
+      if (member == null) {
+        // Unknown member crashed.  Hmm...
+        return;
+      }
+
+      // Can't call member.getId() because it is nulled-out when the
+      // SystemMember is removed.
+      SystemMembershipEvent event = new SystemMembershipEventImpl(vm.getId());
+      for (Iterator iter = this.membershipListeners.iterator();
+      iter.hasNext(); ) {
+        SystemMembershipListener listener =
+          (SystemMembershipListener) iter.next();
+        listener.memberCrashed(event);
+      }
+    }
+  }
+
+  // ----------- com.gemstone.gemfire.internal.admin.AlertListener -----------
+  /** 
+   * Listener callback for when a SystemMember of this DistributedSystem has 
+   * crashed. 
+   *
+   * @param alert   the latest alert from the system
+   * @see com.gemstone.gemfire.internal.admin.AlertListener#alert
+   */
+  public void alert(com.gemstone.gemfire.internal.admin.Alert alert) {
+    if (AlertLevel.forSeverity(alert.getLevel()).ordinal < alertLevel.ordinal) {
+      return;
+    }
+    Alert alert2 = new AlertImpl(alert);
+    this.latestAlert = alert2;
+    for (Iterator<AlertListener> iter = this.alertListeners.iterator();
+         iter.hasNext(); ) {
+      AlertListener listener = iter.next();
+      listener.alert(alert2);
+    }
+  }
+  
+  public void onDisconnect(InternalDistributedSystem sys) {
+   logger.debug("Calling AdminDistributedSystemImpl#onDisconnect");	 
+   disconnect();
+   logger.debug("Completed AdminDistributedSystemImpl#onDisconnect");
+  }
+  
+  // -------------------------------------------------------------------------
+  //   Template methods overriden from superclass...
+  // -------------------------------------------------------------------------
+  
+  protected CacheServer createCacheServer(ApplicationVM member) 
+    throws AdminException {
+
+    return new CacheServerImpl(this, member);
+  }
+
+  protected CacheServer createCacheServer(CacheServerConfigImpl conf) 
+    throws AdminException {
+
+    return new CacheServerImpl(this, conf);
+  }
+
+  /** Override createSystemMember by instantiating SystemMemberImpl
+   * 
+   *  @throws AdminException TODO-javadocs
+   */
+  protected SystemMember createSystemMember(ApplicationVM app)
+  throws com.gemstone.gemfire.admin.AdminException {
+    return new SystemMemberImpl(this, app);
+  }
+
+  /**
+   * Constructs & returns a SystemMember instance using the corresponding
+   * InternalDistributedMember object.
+   * 
+   * @param member
+   *          InternalDistributedMember instance for which a SystemMember
+   *          instance is to be constructed.
+   * @return constructed SystemMember instance
+   * @throws com.gemstone.gemfire.admin.AdminException
+   *           if construction of SystemMember instance fails
+   * @since 6.5
+   */
+  protected SystemMember createSystemMember(InternalDistributedMember member)
+    throws com.gemstone.gemfire.admin.AdminException {
+    return new SystemMemberImpl(this, member);
+  }
+
+  /** 
+   * Template-method for creating a new
+   * <code>DistributionLocatorImpl</code> instance.  
+   */
+  protected DistributionLocatorImpl
+    createDistributionLocatorImpl(DistributionLocatorConfig conf) {
+    return new DistributionLocatorImpl(conf, this);
+  }
+  
+  // -------------------------------------------------------------------------
+  //   Non-public implementation methods... TODO: narrow access levels
+  // -------------------------------------------------------------------------
+
+  // TODO: public void connect(...) could stand to have some internals factored out
+  
+  /** 
+   * Returns List of Locators including Locators or Multicast.
+   *
+   * @return list of locators or multicast values
+   */
+  protected List parseLocators() {
+
+    // assumes host[port] format, delimited by ","
+    List locatorIds = new ArrayList();
+    if (isMcastEnabled()) {
+      String mcastId = new StringBuffer(
+          this.getMcastAddress()).append("[").append(
+          this.getMcastPort()).append("]").toString();
+      locatorIds.add(new DistributionLocatorId(mcastId));
+    }
+    if (!isMcastDiscovery()) {
+      StringTokenizer st = new StringTokenizer(this.getLocators(), ",");
+      while (st.hasMoreTokens()) {
+        locatorIds.add(new DistributionLocatorId(st.nextToken()));
+      }
+    }
+
+    if (logger.isDebugEnabled()) {
+      StringBuffer sb = new StringBuffer("Locator set is: ");
+      for (Iterator iter = locatorIds.iterator(); iter.hasNext(); ) {
+        sb.append(iter.next());
+        sb.append(" ");
+      }
+      logger.debug(sb);
+    }
+
+    return locatorIds;
+  }
+  
+  /**
+   * Returns whether or not a <code>SystemMember</code> corresponds
+   * to a <code>GemFireVM</code>.
+   *
+   * @param examineConfig
+   *        Should we take the configuration of the member into
+   *        consideration?  In general, we want to consider the
+   *        configuration when a member starts up.  But when we are
+   *        notified that it has shut down, we do not want to examine
+   *        the configuration because that might involve contacting
+   *        the member.  Which, of course, cannot be done because it
+   *        has shut down.
+   */
+  private boolean isSame(SystemMemberImpl member, GemFireVM vm,
+                         boolean examineConfig) {
+    if (vm.equals(member.getGemFireVM())) {
+      return true;
+    }
+
+    InternalDistributedMember memberId = member.getInternalId();
+    InternalDistributedMember vmId = vm.getId();
+
+    if (vmId.equals(memberId)) {
+      return true;
+    }
+
+    if ((member instanceof ManagedSystemMemberImpl) &&
+        examineConfig) {
+
+      // We can't compare information about managers because the
+      // member might have already gone away.  Attempts to send it
+      // messages (to get its product directory, for instance) will
+      // time out.
+
+      ManagedSystemMemberImpl entity =
+        (ManagedSystemMemberImpl) member;
+
+      // Make sure that the type of the managed entity matches the
+      // type of the internal admin object.
+      if (entity instanceof CacheServer) {
+        if (!(vm instanceof ApplicationVM)) {
+          return false;
+        }
+
+        ApplicationVM app = (ApplicationVM) vm;
+        if (!app.isDedicatedCacheServer()) {
+          return false;
+        }
+      }
+
+      ManagedEntityConfig conf = entity.getEntityConfig();
+      InetAddress managedHost =
+        InetAddressUtil.toInetAddress(conf.getHost());
+      File managedWorkingDir = new File(conf.getWorkingDirectory());
+      File managedProdDir = new File(conf.getProductDirectory());
+      
+      InetAddress vmHost = vm.getHost();
+      File vmWorkingDir = vm.getWorkingDirectory();
+      File vmProdDir = vm.getGemFireDir();
+
+      if (vmHost.equals(managedHost) && 
+          isSameFile(vmWorkingDir, managedWorkingDir) &&
+          isSameFile(vmProdDir, managedProdDir)) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Returns whether or not the names of the two files represent the
+   * same file.
+   */
+  private boolean isSameFile(File file1, File file2) {
+    if (file1.equals(file2)) {
+      return true;
+    }
+
+    if (file1.getAbsoluteFile().equals(file2.getAbsoluteFile())) {
+      return true;
+    }
+
+    try {
+      if (file1.getCanonicalFile().equals(file2.getCanonicalFile())) {
+        return true;
+      }
+
+//       StringBuffer sb = new StringBuffer();
+//       sb.append("File 1: ");
+//       sb.append(file1);
+//       sb.append("\nFile 2: ");
+//       sb.append(file2);
+//       sb.append("\n  Absolute 1: ");
+//       sb.append(file1.getAbsoluteFile());
+//       sb.append("\n  Absolute 2: ");
+//       sb.append(file2.getAbsoluteFile());
+//       sb.append("\n  Canonical 1: ");
+//       sb.append(file1.getCanonicalFile());
+//       sb.append("\n  Canonical 2: ");
+//       sb.append(file2.getCanonicalFile());
+//       logger.info(sb.toString());
+
+    } catch (IOException ex) {
+      // oh well...
+      logger.info(LocalizedMessage.create(LocalizedStrings.AdminDistributedSystemImpl_WHILE_GETTING_CANONICAL_FILE), ex);
+    }
+
+    return false;
+  }
+
+  /**
+   * Finds and returns the <code>SystemMember</code> that corresponds
+   * to the given <code>GemFireVM</code> or <code>null</code> if no
+   * <code>SystemMember</code> corresponds.
+   */
+  protected SystemMember findSystemMember(GemFireVM vm) {
+    return findSystemMember(vm, true);
+  }
+
+  /**
+   * Finds and returns the <code>SystemMember</code> that corresponds to the
+   * given <code>GemFireVM</code> or <code>null</code> if no Finds and returns
+   * the <code>SystemMember</code> that corresponds to the given
+   * <code>GemFireVM</code> or <code>null</code> if no <code>SystemMember</code>
+   * corresponds.
+   * 
+   * 
+   * @param vm
+   *          GemFireVM instance
+   * @param compareConfig
+   *          Should the members' configurations be compared? <code>true</code>
+   *          when the member has joined, <code>false</code> when the member has
+   *          left Should the members' configurations be compared?
+   *          <code>true</code> when the member has joined, <code>false</code>
+   *          when the member has left. Additionally also used to check if system 
+   *          member config is to be synchronized with the VM.
+   * 
+   * @throws AdminException
+   *           if member configuration can not be synchronized with VM
+   */
+   protected SystemMember findSystemMember(GemFireVM vm,
+                                           boolean compareConfig) {
+
+    SystemMemberImpl member = null;
+
+      synchronized (this.cacheServerSet) {
+        SERVERS: for (Iterator iter = this.cacheServerSet.iterator();
+             iter.hasNext(); ) {
+          Future future = (Future) iter.next();
+          CacheServerImpl cacheServer = null;
+          for (;;) {
+            checkCancellation();
+            boolean interrupted = Thread.interrupted();
+            try {
+              cacheServer = (CacheServerImpl) future.get();
+              break; // success
+            } 
+            catch (InterruptedException ex) {
+              interrupted = true;
+              continue; // keep trying
+            } 
+            catch (CancellationException ex) {
+              continue SERVERS;
+            } 
+            catch (ExecutionException ex) {
+              handle(ex);
+              continue SERVERS;
+            }
+            finally {
+              if (interrupted) {
+                Thread.currentThread().interrupt();
+              }
+            }
+          } // for
+
+          if (isSame(cacheServer, vm, compareConfig)) {
+            member = cacheServer;
+            break;
+          }
+        }      
+      }
+
+    if (member == null) {
+      synchronized (this.applicationSet) {
+        APPS: for (Iterator iter = this.applicationSet.iterator();
+             iter.hasNext(); ) {
+          Future future = (Future) iter.next();
+          SystemMemberImpl application = null;
+          for (;;) {
+            checkCancellation();
+            boolean interrupted = Thread.interrupted();
+            try {
+              application = (SystemMemberImpl) future.get();
+              break; // success
+            } 
+            catch (InterruptedException ex) {
+              interrupted = true;
+              continue; // keep trying
+            } 
+            catch (CancellationException ex) {
+              continue APPS;
+            } 
+            catch (ExecutionException ex) {
+              handle(ex);
+              continue APPS;
+            }
+            finally {
+              if (interrupted) {
+                Thread.currentThread().interrupt();
+              }
+            }
+          } // for
+
+          if (isSame(application, vm, compareConfig)) {
+            member = application;
+            break;
+          }
+        } // APPS
+      }
+    }
+
+    if (member != null && compareConfig) {
+      try {
+        member.setGemFireVM(vm);
+
+      } catch (AdminException ex) {
+        logger.warn(LocalizedMessage.create(LocalizedStrings.AdminDistributedSystem_COULD_NOT_SET_THE_GEMFIRE_VM), ex);
+      }
+    }
+
+    return member;
+  }
+  
+  /** 
+   * Removes a SystemMember from this system's list of known members.
+   *
+   * @param systemMember  the member to remove
+   * @return the system member that was removed; null if no match was found
+   */
+  protected SystemMember removeSystemMember(SystemMember systemMember) {
+    return removeSystemMember(
+        ((SystemMemberImpl) systemMember).getInternalId());
+  }
+  
+  /** 
+   * Removes a SystemMember from this system's list of known members.  This 
+   * method is called in response to a member leaving the system.
+   * TODO: this method is a mess of defns
+   *
+   * @param internalId  the unique id that specifies which member to remove
+   * @return the system member that was removed; null if no match was found
+   */
+  protected SystemMember removeSystemMember(InternalDistributedMember internalId) {
+    if (internalId == null) return null;
+
+//     this.logger.info("DEBUG: removeSystemMember: " + internalId, new RuntimeException("STACK"));
+
+    boolean found = false;
+    SystemMemberImpl member = null;
+
+    synchronized(this.cacheServerSet) {
+      SERVERS: for (Iterator iter = this.cacheServerSet.iterator();
+           iter.hasNext() && !found; ) {
+        Future future = (Future) iter.next();
+        if (future instanceof AdminFutureTask) {
+          AdminFutureTask task = (AdminFutureTask) future;
+          if (task.getMemberId().equals(internalId)) {
+//             this.logger.info("DEBUG: removeSystemMember cs cancelling: " + future);
+            future.cancel(true);
+
+          } else {
+            // This is not the member we are looking for...
+            continue SERVERS;
+          }
+        }
+        for (;;) {
+          checkCancellation();
+          boolean interrupted = Thread.interrupted();
+          try {
+            member = (SystemMemberImpl) future.get();
+            break; // success
+          } catch (InterruptedException ex) {
+            interrupted = true;
+            continue; // keep trying
+          } catch (CancellationException ex) {
+            continue SERVERS;
+          } catch (ExecutionException ex) {
+            handle(ex);
+            return null;          // Dead code
+          } finally {
+            if (interrupted) {
+              Thread.currentThread().interrupt();
+            }
+          }
+        }
+
+        InternalDistributedMember cacheServerId = member.getInternalId();
+        if (internalId.equals(cacheServerId)) {
+          // found a match...
+          iter.remove();
+          found = true;
+        }
+      } // SERVERS
+    }    
+
+    synchronized(this.applicationSet) {
+      for (Iterator iter = this.applicationSet.iterator();
+           iter.hasNext() && !found; ) {
+        Future future = (Future) iter.next();
+        try {
+          if (future instanceof AdminFutureTask) {
+            AdminFutureTask task = (AdminFutureTask) future;
+            if (task.getMemberId().equals(internalId)) {
+              iter.remove();        // Only remove applications
+              found = true;
+              if (future.isDone()) {
+                member = (SystemMemberImpl) future.get();
+              }
+              break;
+            } else {
+              // This is not the member we are looking for...
+              continue;
+            } 
+          }
+          if (future.isDone()) {
+            member = (SystemMemberImpl) future.get();
+          } else {
+//             this.logger.info("DEBUG: removeSystemMember as cancelling: " + future);
+            future.cancel(true);
+          }
+
+        } catch (InterruptedException ex) {
+          Thread.currentThread().interrupt();
+          checkCancellation();
+          throw new RuntimeException(LocalizedStrings.AdminDistributedSystemImpl_INTERRUPTED.toLocalizedString(), ex);
+          
+        } catch (CancellationException ex) {
+          continue;
+
+        } catch (ExecutionException ex) {
+          handle(ex);
+          return null;          // Dead code
+        }
+
+        InternalDistributedMember applicationId = member.getInternalId();
+        if (internalId.equals(applicationId)) {
+          // found a match...
+          iter.remove();        // Only remove applications
+          found = true;
+        }
+      }
+    }    
+
+    if (found) {
+      try {
+        if (member != null) {
+          member.setGemFireVM(null);
+        }
+        
+      } catch (AdminException ex) {
+        logger.fatal(LocalizedMessage.create(LocalizedStrings.AdminDistributedSystem_UNEXPECTED_ADMINEXCEPTION), ex);
+      }
+      return member;
+      
+    } else {
+      if (logger.isDebugEnabled()) {
+        logger.debug("Couldn't remove member {}", internalId);
+      }
+      return null;
+    }
+  }
+  
+  /**  
+   * Builds the configuration needed to connect to a GfManagerAgent which is the
+   * main gateway into the internal.admin api.  GfManagerAgent is used to 
+   * actually connect to the distributed gemfire system.
+   *
+   * @param logWriter the LogWriterI18n to use for any logging
+   * @return the configuration needed to connect to a GfManagerAgent
+   */
+  // LOG: saves LogWriterLogger from AdminDistributedSystemImpl for RemoteGfManagerAgentConfig
+  private GfManagerAgentConfig buildAgentConfig(InternalLogWriter logWriter) {
+    RemoteTransportConfig conf = new RemoteTransportConfig(
+        isMcastEnabled(), isMcastDiscovery(), getDisableTcp(),
+        getDisableAutoReconnect(),
+        getBindAddress(), buildSSLConfig(), parseLocators(), 
+        getMembershipPortRange(), getTcpPort());
+    return new GfManagerAgentConfig(
+        getSystemName(), conf, logWriter, this.alertLevel.getSeverity(), this, this);
+  }
+  
+  protected SSLConfig buildSSLConfig() {
+    SSLConfig conf = new SSLConfig();
+    if (getConfig() != null) {
+      conf.setEnabled(getConfig().isSSLEnabled());
+      conf.setProtocols(getConfig().getSSLProtocols());
+      conf.setCiphers(getConfig().getSSLCiphers());
+      conf.setRequireAuth(getConfig().isSSLAuthenticationRequired());
+      conf.setProperties(getConfig().getSSLProperties());
+    }
+    return conf;
+  }
+  
+  /**
+   * Returns the currently configured address to bind to when administering
+   * this system.
+   */
+  private String getBindAddress() {
+    return this.config.getBindAddress();
+
+//     String bindAddress = 
+//         System.getProperty("gemfire.jg-bind-address");
+//     if (bindAddress == null || bindAddress.length() == 0) {
+//       return DistributionConfig.DEFAULT_BIND_ADDRESS;
+//     }
+//     return bindAddress;
+  }
+
+  /** Returns whether or not the given member is running */
+  private boolean isRunning(SystemMember member) {
+    if (member instanceof ManagedEntity) {
+      return ((ManagedEntity) member).isRunning();
+
+    } else {
+      // member must be an application VM.  It is running
+      return true;
+    }
+  }
+
+  /** Returns any member manager that is known to be running */
+  private SystemMember findFirstRunningMember() {
+    synchronized(this.cacheServerSet) {
+      SERVERS: for (Iterator iter = this.cacheServerSet.iterator();
+           iter.hasNext();){
+        Future future = (Future) iter.next();
+        SystemMember member = null;
+        for (;;) {
+          checkCancellation();
+          boolean interrupted = Thread.interrupted();
+          try {
+            member = (SystemMember) future.get();
+            break; // success
+          } 
+          catch (InterruptedException ex) {
+            interrupted = true;
+            continue; // keep trying
+          } 
+          catch (CancellationException ex) {
+            continue SERVERS;
+          } 
+          catch (ExecutionException ex) {
+            handle(ex);
+            return null;          // Dead code
+          }
+          finally {
+            if (interrupted) {
+              Thread.currentThread().interrupt();
+            }
+          }
+        } // for
+
+        if (isRunning(member)) {
+          return member;
+        }
+      }
+    }
+
+    synchronized(this.applicationSet) {
+      APPS: for (Iterator iter = this.applicationSet.iterator();
+           iter.hasNext();) {
+        Future future = (Future) iter.next();
+        SystemMember member = null;
+        for (;;) {
+          checkCancellation();
+          boolean interrupted = Thread.interrupted();
+          try {
+            member = (SystemMember) future.get();
+            break; // success
+          } 
+          catch (InterruptedException ex) {
+            interrupted = true;
+            continue; // keep trying
+          } 
+          catch (CancellationException ex) {
+            continue APPS;
+          } 
+          catch (ExecutionException ex) {
+            handle(ex);
+            return null;          // Dead code
+          }
+          finally {
+            if (interrupted) {
+              Thread.currentThread().interrupt();
+            }
+          }
+        } //  for
+
+        if (isRunning(member)) {
+          return member;
+        }
+      } // APPS
+    }
+
+    return null;
+  }
+
+  /**
+   * Returns the instance of system member that is running either as a CacheVm
+   * or only ApplicationVm for the given string representation of the id.
+   * 
+   * @param memberId
+   *          string representation of the member identifier
+   * @return instance of system member which could be either as a CacheVm or
+   *         Application VM
+   */
+  protected SystemMember findCacheOrAppVmById(String memberId) {
+    SystemMember found = null;
+    
+    if (memberId != null) {
+      try {
+        boolean foundSender = false;
+        CacheVm[] cacheVms = getCacheVms();
+        
+        /* cacheVms could be null. See 
+         * AdminDistributedSystemImpl.getCacheVmsCollection() for 
+         * ExecutionException */
+        if (cacheVms != null) {
+          for (CacheVm cacheVm : cacheVms) {
+            if (cacheVm.getId().equals(memberId) && 
+                cacheVm instanceof CacheVm) {
+              found = (SystemMember) cacheVm;    
+              foundSender = true;
+              break;
+            }
+          }
+        }
+        
+        if (!foundSender) {
+          SystemMember[] appVms = getSystemMemberApplications();
+          
+          for (SystemMember appVm : appVms) {
+            if (appVm.getId().equals(memberId) && 
+                appVm instanceof SystemMember) {
+              found = (SystemMember) appVm;
+              foundSender = true;
+              break;
+            }
+          }
+          
+        }
+      } catch (AdminException e) {
+        if (logger.isDebugEnabled()) {
+          logger.debug("Could not find System Member for member id: {}", memberId, e);
+        }
+      }
+    }
+    
+    return found;
+  }  
+  
+  /** Returns true if any member application is known to be running */
+  protected boolean isAnyMemberRunning() {
+    return findFirstRunningMember() != null;
+  }
+  
+  // -------------------------------------------------------------------------
+  //   Health methods
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Lazily initializes the GemFire health monitor 
+   *
+   * @see #createGemFireHealth
+   */
+  public final GemFireHealth getGemFireHealth() {
+    synchronized (this) {
+      if (this.health == null || this.health.isClosed()) {
+        try {
+          this.health = createGemFireHealth(this.gfManagerAgent);
+
+        } catch (AdminException ex) {
+          throw new RuntimeAdminException(LocalizedStrings.AdminDistributedSystemImpl_AN_ADMINEXCEPTION_WAS_THROWN_WHILE_GETTING_THE_GEMFIRE_HEALTH.toLocalizedString(), ex);
+        }
+      }
+
+      return this.health;
+    }
+  }
+
+  /**
+   * A "template factory" method for creating an instance of
+   * <code>GemFireHealth</code>.  It can be overridden by subclasses
+   * to produce instances of different <code>GemFireHealth</code>
+   * implementations.
+   *
+   * @see #getGemFireHealth
+   */
+  protected GemFireHealth createGemFireHealth(GfManagerAgent agent) 
+    throws AdminException {
+
+    if (agent == null) {
+      throw new IllegalStateException(LocalizedStrings.AdminDistributedSystemImpl_GFMANAGERAGENT_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+    return new GemFireHealthImpl(agent, this);
+  }
+    
+  public CacheVm addCacheVm() throws AdminException {
+    return (CacheVm)addCacheServer();
+  }
+  
+  public CacheServer addCacheServer() throws AdminException {
+    CacheServerConfigImpl conf = new CacheServerConfigImpl();
+    CacheServer server  = createCacheServer(conf);
+    setDistributionParameters(server);
+
+    synchronized (this.cacheServerSet) {
+      this.cacheServerSet.add(new FutureResult(server));
+    }
+
+    return server;
+  }
+
+  private Collection getCacheVmsCollection() throws AdminException {
+    synchronized(this.cacheServerSet) {
+      Collection coll = new ArrayList(this.cacheServerSet.size());
+      SERVERS: for (Iterator iter = this.cacheServerSet.iterator();
+           iter.hasNext(); ) {
+        Future future = (Future) iter.next();
+        Object get = null;
+        for (;;) {
+          checkCancellation();
+          boolean interrupted = Thread.interrupted();
+          try {
+            get = future.get();
+            break; // success
+          } 
+          catch (InterruptedException ex) {
+            interrupted = true;
+            continue; // keep trying
+          } 
+          catch (CancellationException ex) {
+            continue SERVERS;
+          } 
+          catch (ExecutionException ex) {
+            handle(ex);
+            return null;          // Dead code
+          }
+          finally {
+            if (interrupted) {
+              Thread.currentThread().interrupt();
+            }
+          }
+        } // for
+        coll.add(get);
+      } // SERVERS
+      return coll;
+    }
+  }
+
+  /**
+   * Returns all the cache server members of the distributed system which are
+   * hosting a client queue for the particular durable-client having the given
+   * durableClientId
+   * 
+   * @param durableClientId -
+   *                durable-id of the client
+   * @return array of CacheServer(s) having the queue for the durable client
+   * @throws AdminException
+   * 
+   * @since 5.6
+   */
+  public CacheServer[] getCacheServers(String durableClientId)
+      throws AdminException
+  {
+    Collection serversForDurableClient = new ArrayList();
+    CacheServer[] servers = getCacheServers();
+
+    for (int i = 0; i < servers.length; i++) {
+      RemoteApplicationVM vm = (RemoteApplicationVM)((CacheServerImpl)servers[i])
+          .getGemFireVM();
+      if (vm != null && vm.hasDurableClient(durableClientId)) {
+        serversForDurableClient.add(servers[i]);
+      }
+    }
+    CacheServer[] array = new CacheServer[serversForDurableClient.size()];
+    serversForDurableClient.toArray(array);
+    return array;
+  }
+  
+  public CacheVm[] getCacheVms() throws AdminException {
+    Collection coll = getCacheVmsCollection();
+    if (coll == null) return null;
+    CacheVm[] array = new CacheVm[coll.size()];
+    coll.toArray(array);
+    return array;
+  }
+  public CacheServer[] getCacheServers() throws AdminException {
+    Collection coll = getCacheVmsCollection();
+    if (coll == null) return null;
+    CacheServer[] array = new CacheServer[coll.size()];
+    coll.toArray(array);
+    return array;
+  }
+
+  // -------------------------------------------------------------------------
+  //   Overriden java.lang.Object methods
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Returns a string representation of the object.
+   * 
+   * @return a string representation of the object
+   */
+  @Override // GemStoneAddition
+  public String toString() {
+    return getName();
+  }
+
+  /**
+   * returns instance of AdminDistributedSystem that is current connected. See
+   * <code>thisAdminDS</code>. (for feature requests #32887)
+   * <p>
+   * TODO: remove this static method during reimplementation of 
+   * {@link SystemMemberCacheEventProcessor}
+   * 
+   * @return AdminDistributedSystem
+   */
+  public static AdminDistributedSystemImpl getConnectedInstance() {
+    synchronized (CONNECTION_SYNC) {
+      return thisAdminDS;
+    }
+  }
+  
+  public void addCacheListener(SystemMemberCacheListener listener) {
+    synchronized (this.cacheListLock) {
+      // never modify cacheListeners in place.
+      // this allows iteration without concurrent mod worries
+      List oldListeners = this.cacheListeners;
+      if (!oldListeners.contains(listener)) {
+        List newListeners = new ArrayList(oldListeners);
+        newListeners.add(listener);
+        this.cacheListeners = newListeners;
+      }
+    }
+  }
+
+  public void removeCacheListener(SystemMemberCacheListener listener) {
+    synchronized (this.cacheListLock) {
+      List oldListeners = this.cacheListeners;
+      if (oldListeners.contains(listener)) {
+        List newListeners = new ArrayList(oldListeners);
+        if (newListeners.remove(listener)) {
+          if (newListeners.isEmpty()) {
+            newListeners = Collections.EMPTY_LIST;
+          }
+          this.cacheListeners = newListeners;
+        }
+      }
+    }
+  }
+
+  public List getCacheListeners() {
+    return this.cacheListeners;
+  }
+
+  public SystemMember lookupSystemMember(DistributedMember distributedMember) 
+  throws AdminException {
+    if (distributedMember == null) return null;
+    SystemMember[] members = getSystemMemberApplications();
+    for (int i = 0; i < members.length; i++) {
+      if (distributedMember.equals(members[i].getDistributedMember())) {
+        return members[i];
+      }
+    }
+    return null;
+  }
+  
+  ////////////////////////  Inner Classes  ////////////////////////
+
+  /**
+   * Object that converts an <code>internal.admin.Alert</code> into an
+   * external <code>admin.Alert</code>.
+   */
+  public class AlertImpl implements Alert {
+    /** The Alert to which most behavior is delegated */
+    private final com.gemstone.gemfire.internal.admin.Alert alert;
+    private SystemMember systemMember;
+
+    ///////////////////////  Constructors  ///////////////////////
+
+    /**
+     * Creates a new <code>Alert</code> that delegates to the given
+     * object. 
+     */
+    AlertImpl(com.gemstone.gemfire.internal.admin.Alert alert) {
+      this.alert   = alert;
+      GemFireVM vm = alert.getGemFireVM();
+
+      /*
+       * Related to #39657.
+       * Avoid setting GemFireVM again in the system member.
+       * Eager initialization of member variable - systemMember.
+       */
+      this.systemMember = vm == null ? null : findSystemMember(vm, false);
+      if (this.systemMember == null) {
+        /*
+         * try to use sender information to construct the SystemMember that can
+         * be used for disply purpose at least
+         */
+        InternalDistributedMember sender = alert.getSender();
+        if (sender != null) {
+          try {
+            this.systemMember = 
+              AdminDistributedSystemImpl.this.createSystemMember(sender);
+          } catch (AdminException e) {
+            /*
+             * AdminException might be thrown if creation of System Member
+             * instance fails.
+             */
+            this.systemMember = null;
+          }
+        } //else this.systemMember will be null
+      }
+    }
+    
+    //////////////////////  Instance Methods  //////////////////////
+
+    public AlertLevel getLevel() {
+      return AlertLevel.forSeverity(alert.getLevel());
+    }
+
+    /*
+     * Eager initialization of system member is done while creating this alert 
+     * only.
+     */
+    public SystemMember getSystemMember() {
+      return systemMember;
+    }
+
+    public String getConnectionName() {
+      return alert.getConnectionName();
+    }
+
+    public String getSourceId() {
+      return alert.getSourceId();
+    }
+
+    public String getMessage() {
+      return alert.getMessage();
+    }
+
+    public java.util.Date getDate() {
+      return alert.getDate();
+    }
+
+    @Override
+    public String toString() {
+      return alert.toString();
+    }
+  }
+  
+  /**
+   * A JSR-166 <code>FutureTask</code> whose {@link #get} method
+   * properly handles an <code>ExecutionException</code> that wraps an
+   * <code>InterruptedException</code>.  This is necessary because
+   * there are places in the admin API that wrap
+   * <code>InterruptedException</code>s.  See bug 32634.
+   *
+   * <P>
+   *
+   * This is by no means an ideal solution to this problem.  It would
+   * be better to modify the code invoked by the <code>Callable</code>
+   * to explicitly throw <code>InterruptedException</code>.
+   */
+  static class AdminFutureTask extends FutureTask  {
+
+    /** The id of the member whose admin object we are creating.
+     * Keeping track of this allows us to cancel a FutureTask for a
+     * member that has gone away. */
+    private final InternalDistributedMember memberId;
+
+    public AdminFutureTask(InternalDistributedMember memberId,
+                           Callable callable) {
+      super(callable);
+      this.memberId = memberId;
+    }
+
+    /**
+     * Returns the id of the member of the distributed system for
+     * which this <code>FutureTask</code> is doing work.
+     */
+    public InternalDistributedMember getMemberId() {
+      return this.memberId;
+    }
+
+    /**
+     * If the <code>ExecutionException</code> is caused by an
+     * <code>InterruptedException</code>, throw the
+     * <code>CancellationException</code> instead.
+     */
+    @Override
+    public Object get()
+      throws InterruptedException, ExecutionException {
+
+      if (Thread.interrupted()) throw new InterruptedException();
+      try {
+        return super.get();
+
+      } catch (ExecutionException ex) {
+        for (Throwable cause = ex.getCause(); cause != null;
+             cause = cause.getCause()) {
+          if (cause instanceof InterruptedException) {
+            // We interrupted the runnable but we don't want the thread
+            // that called get to think he was interrupted.
+            CancellationException ex2 = new CancellationException(LocalizedStrings.AdminDistributedSystemImpl_BY_INTERRUPT.toLocalizedString());
+            ex2.setStackTrace(cause.getStackTrace());
+            throw ex2;
+          }
+        }
+
+        throw ex;
+      }
+
+    }
+
+  }
+  
+  public DistributedMember getDistributedMember() {
+    return getDistributionManager().getId();
+  }
+
+  private void connectAdminDS() {
+    connect((InternalLogWriter)this.logWriter);
+    try {
+      thisAdminDS.waitToBeConnected(3000);
+    } catch (InterruptedException ie) {
+      logger.warn("Interrupted while waiting to connect", ie);
+    }
+  }
+  
+  public Set<PersistentID> getMissingPersistentMembers()
+      throws AdminException {
+    connectAdminDS();
+    DM dm = getDistributionManager();
+    if(dm == null) {
+      throw new IllegalStateException(LocalizedStrings.AdminDistributedSystemImpl_CONNECT_HAS_NOT_BEEN_INVOKED_ON_THIS_ADMINDISTRIBUTEDSYSTEM.toLocalizedString());
+    }
+    return getMissingPersistentMembers(dm);
+  }
+
+  public static Set<PersistentID> getMissingPersistentMembers(DM dm) {
+    return MissingPersistentIDsRequest.send(dm);
+  }
+
+  public void revokePersistentMember(InetAddress host,
+      String directory) throws AdminException {
+    connectAdminDS();
+    DM dm = getDistributionManager();
+    if(dm == null) {
+      throw new IllegalStateException(LocalizedStrings.AdminDistributedSystemImpl_CONNECT_HAS_NOT_BEEN_INVOKED_ON_THIS_ADMINDISTRIBUTEDSYSTEM.toLocalizedString());
+    }
+    revokePersistentMember(dm, host, directory);
+    
+  }
+  
+  public void revokePersistentMember(UUID diskStoreID) throws AdminException {
+    connectAdminDS();
+    DM dm = getDistributionManager();
+    if(dm == null) {
+      throw new IllegalStateException(LocalizedStrings.AdminDistributedSystemImpl_CONNECT_HAS_NOT_BEEN_INVOKED_ON_THIS_ADMINDISTRIBUTEDSYSTEM.toLocalizedString());
+    }
+    revokePersistentMember(dm, diskStoreID);
+    
+  }
+  
+  public static void revokePersistentMember(DM dm, UUID diskStoreID) {
+    PersistentMemberPattern pattern = new PersistentMemberPattern(diskStoreID);
+    boolean success = false;
+    try {
+      // make sure that the disk store we're revoking is actually missing
+      boolean found = false;
+      Set<PersistentID> details = getMissingPersistentMembers(dm);
+      if (details != null) {
+        for (PersistentID id : details) {
+          if (id.getUUID().equals(diskStoreID)) {
+            found = true;
+            break;
+          }
+        }
+      }
+      if (!found) {
+        return;
+      }
+      
+      //Fix for 42607 - verify that the persistent id is not already
+      //running before revoking it.
+      PrepareRevokePersistentIDRequest.send(dm, pattern);
+      success = true;
+    } finally {
+      if(success) {
+        //revoke the persistent member if were able to prepare the revoke
+        RevokePersistentIDRequest.send(dm, pattern);
+      } else {
+        //otherwise, cancel the revoke.
+        PrepareRevokePersistentIDRequest.cancel(dm, pattern);
+      }
+    }
+  }
+
+  /**
+   * 
+   * @deprecated use {@link #revokePersistentMember(UUID)} instead
+   */
+  public static void revokePersistentMember(DM dm, InetAddress host, String directory) {
+    
+    PersistentMemberPattern pattern = new PersistentMemberPattern(host, directory, System.currentTimeMillis());
+    boolean success = false;
+    try {
+      //Fix for 42607 - verify that the persistent id is not already
+      //running before revoking it.
+      PrepareRevokePersistentIDRequest.send(dm, pattern);
+      success = true;
+    } finally {
+      if(success) {
+        //revoke the persistent member if were able to prepare the revoke
+        RevokePersistentIDRequest.send(dm, pattern);
+      } else {
+        //otherwise, cancel the revoke.
+        PrepareRevokePersistentIDRequest.cancel(dm, pattern);
+      }
+    }
+  }
+  
+  public Set shutDownAllMembers() throws AdminException {
+    return shutDownAllMembers(0);
+  }
+  
+  public Set shutDownAllMembers(long timeout) throws AdminException {
+    connectAdminDS();
+    DM dm = getDistributionManager();
+    if(dm == null) {
+      throw new IllegalStateException(LocalizedStrings.AdminDistributedSystemImpl_CONNECT_HAS_NOT_BEEN_INVOKED_ON_THIS_ADMINDISTRIBUTEDSYSTEM.toLocalizedString());
+    }
+    return shutDownAllMembers(dm, timeout);
+  }
+
+  /**
+   * Shutdown all members.
+   * @param dm
+   * @param timeout the amount of time (in ms) to spending trying to shutdown the members
+   * gracefully. After this time period, the members will be forceable shut down. If the
+   * timeout is exceeded, persistent recovery after the shutdown may need to do a GII. -1
+   *  indicates that the shutdown should wait forever. 
+   */
+  public static Set shutDownAllMembers(DM dm, long timeout) {
+    return ShutdownAllRequest.send(dm, timeout);
+  }
+  
+  public BackupStatus backupAllMembers(File targetDir) throws AdminException {
+    return backupAllMembers(targetDir, null);
+  }
+  
+  public BackupStatus backupAllMembers(File targetDir, File baselineDir) throws AdminException {
+    connectAdminDS();
+    DM dm = getDistributionManager();
+    if(dm == null) {
+      throw new IllegalStateException(LocalizedStrings.AdminDistributedSystemImpl_CONNECT_HAS_NOT_BEEN_INVOKED_ON_THIS_ADMINDISTRIBUTEDSYSTEM.toLocalizedString());
+    }
+    return backupAllMembers(dm, targetDir, baselineDir);
+  }
+
+  public static BackupStatus backupAllMembers(DM dm, File targetDir, File baselineDir)
+      throws AdminException {
+    Set<PersistentID> missingMembers = getMissingPersistentMembers(dm);
+    Set recipients = dm.getOtherDistributionManagerIds();
+    
+    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
+    targetDir = new File(targetDir, format.format(new Date()));
+    FlushToDiskRequest.send(dm, recipients);
+    Map<DistributedMember, Set<PersistentID>> existingDataStores 
+        = PrepareBackupRequest.send(dm, recipients);
+    Map<DistributedMember, Set<PersistentID>> successfulMembers 
+        = FinishBackupRequest.send(dm, recipients, targetDir, baselineDir);
+    
+    // It's possible that when calling getMissingPersistentMembers, some members are 
+    // still creating/recovering regions, and at FinishBackupRequest.send, the 
+    // regions at the members are ready. Logically, since the members in successfulMembers
+    // should override the previous missingMembers
+    for(Set<PersistentID> onlineMembersIds : successfulMembers.values()) {
+      missingMembers.removeAll(onlineMembersIds);
+    }
+    
+    existingDataStores.keySet().removeAll(successfulMembers.keySet());
+    for(Set<PersistentID> lostMembersIds : existingDataStores.values()) {
+      missingMembers.addAll(lostMembersIds);
+    }
+    
+    return new BackupStatusImpl(successfulMembers, missingMembers);
+  }
+  
+  public Map<DistributedMember, Set<PersistentID>> compactAllDiskStores() throws AdminException {
+    connectAdminDS();
+    DM dm = getDistributionManager();
+    if(dm == null) {
+      throw new IllegalStateException(LocalizedStrings.AdminDistributedSystemImpl_CONNECT_HAS_NOT_BEEN_INVOKED_ON_THIS_ADMINDISTRIBUTEDSYSTEM.toLocalizedString());
+    }
+    return compactAllDiskStores(dm);
+  }
+
+  public static Map<DistributedMember, Set<PersistentID>> compactAllDiskStores(DM dm)
+      throws AdminException {
+    return CompactRequest.send(dm);
+  }
+  
+  /**
+   * This method can be used to process ClientMembership events sent for
+   * BridgeMembership by bridge servers to all admin members.
+   * 
+   * NOTE: Not implemented currently. JMX implementation which is a subclass of 
+   * this class i.e. AdminDistributedSystemJmxImpl implements it.
+   * 
+   * @param senderId
+   *          id of the member that sent the ClientMembership changes for
+   *          processing (could be null)
+   * @param clientId
+   *          id of a client for which the notification was sent
+   * @param clientHost
+   *          host on which the client is/was running
+   * @param eventType
+   *          denotes whether the client Joined/Left/Crashed should be one of
+   *          ClientMembershipMessage#JOINED, ClientMembershipMessage#LEFT,
+   *          ClientMembershipMessage#CRASHED
+   */
+  public void processClientMembership(String senderId, String clientId,
+      String clientHost, int eventType) {
+  }
+
+  public void setAlertLevelAsString(String level)  {
+    AlertLevel newAlertLevel = AlertLevel.forName(level);
+    
+    if (newAlertLevel != null) {    
+      setAlertLevel(newAlertLevel);
+    } else {
+      System.out.println("ERROR:: "+level+" is invalid. Allowed alert levels are: WARNING, ERROR, SEVERE, OFF");
+      throw new IllegalArgumentException(LocalizedStrings.DEBUG.toLocalizedString(level+" is invalid. Allowed alert levels are: WARNING, ERROR, SEVERE, OFF"));
+    }
+  }
+
+  public String getAlertLevelAsString() {
+    return getAlertLevel().getName();
+  }
+}
+


[30/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MemberInfoWithStatsMBean.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MemberInfoWithStatsMBean.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MemberInfoWithStatsMBean.java
new file mode 100644
index 0000000..23766c8
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MemberInfoWithStatsMBean.java
@@ -0,0 +1,1379 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import java.net.InetAddress;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationEmitter;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.OperationsException;
+import javax.management.ReflectionException;
+
+import org.apache.logging.log4j.Logger;
+
+import mx4j.AbstractDynamicMBean;
+
+import com.gemstone.gemfire.admin.AdminDistributedSystem;
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.CacheVm;
+import com.gemstone.gemfire.admin.ConfigurationParameter;
+import com.gemstone.gemfire.admin.GemFireMemberStatus;
+import com.gemstone.gemfire.admin.RegionSubRegionSnapshot;
+import com.gemstone.gemfire.admin.StatisticResource;
+import com.gemstone.gemfire.admin.SystemMember;
+import com.gemstone.gemfire.admin.SystemMemberCacheServer;
+import com.gemstone.gemfire.admin.jmx.Agent;
+import com.gemstone.gemfire.cache.InterestPolicy;
+import com.gemstone.gemfire.cache.SubscriptionAttributes;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.internal.GemFireVersion;
+import com.gemstone.gemfire.internal.admin.remote.ClientHealthStats;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+
+/**
+ * This class uses the JMX Attributes/Operations that use (return/throw) 
+ * GemFire types. This is the single MBean accessible with ObjectName string
+ * {@link MemberInfoWithStatsMBean#MBEAN_NAME}}. This MBean can be used to 
+ * retrieve the all member details as plain java types.
+ * 
+ * This MBean also acts as a Notification Hub for all the Notifications that are 
+ * defined for Admin Distributed System. 
+ * 
+ * @author abhishek
+ * 
+ * @since 6.5
+ */
+public class MemberInfoWithStatsMBean extends AbstractDynamicMBean 
+                                 implements NotificationEmitter {
+  private static final Logger logger = LogService.getLogger();
+  
+  /* constants defining max no of attributes/operations/notifications */
+  private static final int MAX_ATTRIBUTES_COUNT    = 3;
+  private static final int MAX_OPERATIONS_COUNT    = 3;
+  private static final int MAX_NOTIFICATIONS_COUNT = 9;
+  
+  private static final String NOT_AVAILABLE_STR = "N/A";
+  private static final String NOT_AVAILABLE = null;
+  private static final Number NOT_AVAILABLE_NUMBER = null;
+
+  /* String constant used for a region that is used on admin side just as a root 
+   * for rootRegions defined on the member */
+  private static final String PLACE_HOLDER_ROOT_REGION = "/Root/";
+
+  /* String that are used to form QueryExp/ObjectName for querying MBeanServer */
+  private static final String REGION_QUERY_EXPRESSION = "*GemFire.Cache*:*,owner={0},type=Region";  
+  private static final String STATS_QUERY_EXPRESSION  = "*GemFire.Statistic*:*,source={0},name={1}";
+  
+  /** mbean name string for this MBean */
+  /*default*/static final String  MBEAN_NAME = "GemFire:type=MemberInfoWithStatsMBean";
+
+  /** ObjectName handle for this MBean */
+  private ObjectName objectName;
+  
+  /** version of the GemFire Enterprise system that is running */
+  private String                        version;
+  private int                           refreshInterval;
+  private String                        id;
+  
+  private Agent                         agent;
+  private AdminDistributedSystemJmxImpl adminDSJmx;
+  
+  private NotificationForwarder         forwarder;
+  private boolean                       isInitialized;//needs synchronization?
+
+  /**
+   * Default Constructor
+   * 
+   * @param agent Admin Agent instance
+   * @throws OperationsException if ObjectName can't be formed for this MBean
+   * @throws MBeanRegistrationException 
+   * @throws AdminException 
+   */
+  MemberInfoWithStatsMBean(Agent agent) throws OperationsException, MBeanRegistrationException, AdminException {
+    this.agent           = agent;
+    this.objectName      = ObjectName.getInstance(MBEAN_NAME);
+    this.version         = GemFireVersion.getGemFireVersion();
+    this.refreshInterval = -1;
+    this.id              = NOT_AVAILABLE_STR;
+    this.forwarder       = new NotificationForwarder(agent.getMBeanServer());
+  }
+
+  /**
+   * Returns attributes defined for this MBean as an array of 
+   * MBeanAttributeInfo objects.
+   * 
+   * @return attributes defined as an array of MBeanAttributeInfo objects.
+   */
+  @Override
+  protected MBeanAttributeInfo[] createMBeanAttributeInfo() {
+    MBeanAttributeInfo[] attributesInfo = new MBeanAttributeInfo[MAX_ATTRIBUTES_COUNT];
+    
+    /* First letter in attribute name has to be 'V' so that getVersion is 
+     * called. With 'v' it looks for getversion, same for others */
+    attributesInfo[0] = new MBeanAttributeInfo("Version", 
+                                               String.class.getName(), 
+                                               "GemFire Enterprise Version", 
+                                               true,  /*readable*/ 
+                                               false, /*writable*/ 
+                                               false);/*has getter with name like 'is****'*/
+    
+    attributesInfo[1] = new MBeanAttributeInfo("RefreshInterval", 
+                                               String.class.getName(), 
+                                               "The interval (in seconds) between auto-polling for updating member & statistics resources. If this is '-1', it means the this MBean has not yet been initialized. First call to getMembers operation will initialize this MBean.", 
+                                               true,  /*readable*/ 
+                                               false, /*writable*/ 
+                                               false);/*has getter with name like 'is****'*/
+    
+    attributesInfo[2] = new MBeanAttributeInfo("Id", 
+                                               String.class.getName(), 
+                                               "Identifier of the GemFire Enterprise. If this is 'N/A', it means the this MBean has not yet been initialized. First call to getMembers operation will initialize this MBean.", 
+                                               true,  /*readable*/ 
+                                               false, /*writable*/ 
+                                               false);/*has getter with name like 'is****'*/   
+    
+    
+    return attributesInfo;
+  }
+  
+  /**
+   * Returns operations defined for this MBean as an array of 
+   * MBeanOperationInfo objects.
+   * 
+   * @return operations defined as an array of MBeanOperationInfo objects. 
+   */
+  @Override
+  protected MBeanOperationInfo[] createMBeanOperationInfo() {
+    MBeanOperationInfo[] operationsInfo = new MBeanOperationInfo[MAX_OPERATIONS_COUNT];
+    
+    operationsInfo[0] = new MBeanOperationInfo("getMembers", 
+                                               "Returns ids as strings for all the members - Application Peers & Cache Servers.", 
+                                               new MBeanParameterInfo[] {}, 
+                                               String[].class.getName(), 
+                                               MBeanOperationInfo.ACTION_INFO);
+    
+    MBeanParameterInfo[] getMemberDetailsArgs = new MBeanParameterInfo[1];
+    getMemberDetailsArgs[0] = new MBeanParameterInfo("memberId", String.class.getName(), "Id of the member for all the details are to be retrieved.");
+    operationsInfo[1] = new MBeanOperationInfo("getMemberDetails", 
+                                                "Returns details for a given member", 
+                                                getMemberDetailsArgs, 
+                                                Map.class.getName(), 
+                                                MBeanOperationInfo.ACTION_INFO);
+    
+    /* For retrieving ObjectNames of existing Region MBeans, MBeanServerConnection.queryMBeans(), could be called */
+    MBeanParameterInfo[] getRegionSnapArgs = new MBeanParameterInfo[1];
+    getRegionSnapArgs[0] = new MBeanParameterInfo("memberId", String.class.getName(), "Id of the member on which we want to discover all the region MBean.");
+    operationsInfo[2] = new MBeanOperationInfo("getRegions", 
+                                                "Returns a java.util.Map of details of regions on a member", 
+                                                getRegionSnapArgs, 
+                                                Map.class.getName(), 
+                                                MBeanOperationInfo.ACTION_INFO);
+
+    
+    return operationsInfo;
+  }
+
+  /**
+   * Returns notifications defined for this MBean as an array of
+   * MBeanNotificationInfo objects.
+   * 
+   * @return notification definitions as an array of MBeanNotificationInfo
+   *         objects.
+   */
+  @Override
+  protected MBeanNotificationInfo[] createMBeanNotificationInfo() {
+    MBeanNotificationInfo[] notificationsInfo = new MBeanNotificationInfo[MAX_NOTIFICATIONS_COUNT];
+    
+    String[] notificationTypes = new String[] {AdminDistributedSystemJmxImpl.NOTIF_MEMBER_JOINED};
+    notificationsInfo[0] = new MBeanNotificationInfo(notificationTypes,
+                                                    Notification.class.getName(), 
+                                                    "A GemFire manager, cache, or other member has joined this distributed system.");
+    
+    notificationTypes = new String[] {AdminDistributedSystemJmxImpl.NOTIF_MEMBER_LEFT};
+    notificationsInfo[1] = new MBeanNotificationInfo(notificationTypes, 
+                                                    Notification.class.getName(), 
+                                                    "A GemFire manager, cache, or other member has left the distributed system.");
+    
+    notificationTypes = new String[] {AdminDistributedSystemJmxImpl.NOTIF_MEMBER_CRASHED};
+    notificationsInfo[2] = new MBeanNotificationInfo(notificationTypes, 
+                                                    Notification.class.getName(), 
+                                                    "A member of this distributed system has crashed instead of leaving cleanly.");
+    
+    notificationTypes = new String[] {AdminDistributedSystemJmxImpl.NOTIF_ALERT};
+    notificationsInfo[3] = new MBeanNotificationInfo(notificationTypes, 
+                                                    Notification.class.getName(), 
+                                                    "A member of this distributed system has generated an alert.");
+    
+    notificationTypes = new String[] {AdminDistributedSystemJmxImpl.NOTIF_ADMIN_SYSTEM_DISCONNECT};
+    notificationsInfo[4] = new MBeanNotificationInfo(notificationTypes, 
+                                                    Notification.class.getName(), 
+                                                    "A GemFire manager, cache, or other member has joined this distributed system.");
+    
+    notificationTypes = new String[] {SystemMemberJmx.NOTIF_CACHE_CREATED};
+    notificationsInfo[5] = new MBeanNotificationInfo(notificationTypes, 
+                                                    Notification.class.getName(), 
+                                                    "A cache got created on a member of this distributed system.");
+    
+    notificationTypes = new String[] {SystemMemberJmx.NOTIF_CACHE_CLOSED};
+    notificationsInfo[6] = new MBeanNotificationInfo(notificationTypes, 
+                                                    Notification.class.getName(), 
+                                                    "A cache is closed on a member of this distributed system.");
+    
+    notificationTypes = new String[] {SystemMemberJmx.NOTIF_REGION_CREATED};
+    notificationsInfo[7] = new MBeanNotificationInfo(notificationTypes, 
+                                                    Notification.class.getName(), 
+                                                    "A region is created in a cache on a member of this distributed system.");
+    
+    notificationTypes = new String[] {SystemMemberJmx.NOTIF_REGION_LOST};
+    notificationsInfo[8] = new MBeanNotificationInfo(notificationTypes, 
+                                                    Notification.class.getName(), 
+                                                    "A region was removed from a cache on a member of this distributed system.");
+
+//  String[] notificationTypes5 = new String[] {AdminDistributedSystemJmxImpl.NOTIF_STAT_ALERT};
+//  notificationsInfo[9] = new MBeanNotificationInfo(notificationTypes5, 
+//                                                  Notification.class.getName(), 
+//                                                  "An alert based on statistic(s) has been raised.");    
+
+    return notificationsInfo;
+  }
+  
+  /**
+   * 
+   * @return ObjectName of this MBean
+   */
+  /*default*/ ObjectName getObjectName() {
+    return objectName;
+  }
+
+  /**
+   * Returns the version of the GemFire Enterprise instance as a string.
+   * 
+   * @return GemFire Enterprise version string derived from {@link GemFireVersion}
+   */
+  /* getter for attribute - Version */
+  public String getVersion() {
+    return version;
+  }
+
+  /**
+   * @return the refreshInterval
+   */
+  public int getRefreshInterval() {
+    return refreshInterval;
+  }
+
+  /**
+   * @return the id
+   */
+  public String getId() {
+    return id;
+  }
+
+  /**
+   * Connects the Admin Agent in the DS
+   * 
+   * @return AdminDistributedSystem MBean ObjectName
+   * @throws OperationsException
+   *           if connection to the DS fails
+   * @throws AdminException
+   *           if connection to the DS fails
+   */
+  private ObjectName connectToSystem() throws OperationsException, AdminException {
+    ObjectName adminDsObjName = agent.connectToSystem();
+    
+    AdminDistributedSystem adminDS = agent.getDistributedSystem();
+    if (adminDSJmx == null && adminDS instanceof AdminDistributedSystemJmxImpl) {//instanceof checks for null
+      adminDSJmx      = (AdminDistributedSystemJmxImpl) adminDS;
+      refreshInterval = adminDSJmx.getRefreshInterval();
+      id              = adminDSJmx.getId();
+      forwarder.registerNotificationListener(adminDSJmx.getObjectName());
+    }
+
+    return adminDsObjName;
+  }
+  
+  /**
+   * 
+   * @param memberId
+   * @return SystemMemberJmx instance for given memberId
+   * @throws AdminException
+   */
+  private SystemMemberJmx findMember(String memberId) throws AdminException {
+    SystemMemberJmx foundMember = null;
+    
+    if (agent.isConnected()) {
+      SystemMember[] members = adminDSJmx.getSystemMemberApplications();
+      for (SystemMember app : members) {
+        if (app.getId().equals(memberId)) {
+          foundMember = (SystemMemberJmx) app;
+          break;
+        }
+      }
+      
+      if (foundMember == null) {
+        members = adminDSJmx.getCacheVms();
+        for (SystemMember cacheVm : members) {
+          if (cacheVm.getId().equals(memberId)) {
+            foundMember = (SystemMemberJmx) cacheVm;
+            break;
+          }
+        }
+      }
+    }
+    
+    return foundMember;
+  }
+
+  /**
+   * Return ObjectNames for all the Member MBeans in the DS.
+   * 
+   * @return Array of ObjectNames of all Member MBeans
+   * @throws OperationsException
+   *           if (1)agent could not connect in the DS OR 
+   *           (2)Notification Listener could not be registered for the Admin 
+   *              DS MBean OR
+   *           (3)fails to retrieve information from Admin DS
+   */
+  public String[] getMembers() throws OperationsException {
+    String[] members = new String[0];
+      
+    try {
+      if (!isInitialized) {
+        initializeAll(); //initialize if not yet
+      }
+
+      if (adminDSJmx != null) {
+        CacheVm[]      cacheVms = adminDSJmx.getCacheVms();
+        SystemMember[] appVms   = adminDSJmx.getSystemMemberApplications();
+        
+        List<String> membersList = new ArrayList<String>();
+        if (cacheVms != null && cacheVms.length !=0) {
+          for (SystemMember cacheVm : cacheVms) {
+            membersList.add(cacheVm.getId());
+          }
+        }
+        if (appVms != null && appVms.length !=0) {
+          for (SystemMember appVm : appVms) {
+            membersList.add(appVm.getId());
+          }
+        }
+        members = new String[membersList.size()];
+        members = membersList.toArray(members);
+      }
+    } catch (AdminException e) {
+      logger.warn(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_FOR_OPERATION_0, "getMembers"), e);
+      throw new OperationsException(e.getMessage());
+    } catch (Exception e) {
+      logger.warn(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_FOR_OPERATION_0, "getMembers"), e);
+      throw new OperationsException(e.getMessage());
+    }
+    
+    return members;
+  }
+
+  /**
+   * Returns information including ObjectNames for all regions on a member with
+   * given member id.
+   * 
+   * @param memberId
+   *          member identifier as a String
+   * @return Map of details of all regions on a member with given id
+   * @throws OperationsException
+   *           if fails to retrieve the regions information
+   */
+  public Map<String, Map<String, ?>> getRegions(String memberId) throws OperationsException {
+    Map<String, Map<String, ?>> regionsInfo = new LinkedHashMap<String, Map<String, ?>>();
+    
+    if (memberId != null) {
+      try {
+        SystemMemberJmx foundMember = findMember(memberId);
+        if (foundMember != null) {
+          SystemMemberCacheJmxImpl cache = (SystemMemberCacheJmxImpl) foundMember.getCache();
+          if (cache != null) {
+            Map<String, ObjectName> existingRegionMbeans = getExistingRegionMbeansFullPaths(memberId);
+            //TODO: this is in-efficient
+            //Can a region.create JMX notification be used?
+            regionsInfo = getAllRegionsDetails(cache, existingRegionMbeans);
+            existingRegionMbeans.clear();
+          }
+        }
+      } catch (AdminException e) {
+        logger.warn(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_FOR_OPERATION_0_FOR_MEMBER_1, new Object[]{"getRegions", memberId}), e);
+        throw new OperationsException(e.getMessage());
+      } catch (Exception e) {
+        logger.warn(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_FOR_OPERATION_0_FOR_MEMBER_1, new Object[]{"getRegions", memberId}), e);
+        throw new OperationsException(e.getMessage());
+      }
+    }
+    
+    return regionsInfo;
+  }
+  
+  /* **************************************************************************/
+  /* ************* INITIALIZE THE ENTIRE ADMIN DS AT A TIME *******************/
+  /* **************************************************************************/
+  /**
+   * Initializes all the possible MBeans for all the members.
+   * 
+   */
+  private void initializeAll() throws OperationsException {
+    try {
+      connectToSystem();
+      if (adminDSJmx != null) {
+        //Members are already inited after connectToSystem. Now init Cache, Region & Stats MBeans
+        SystemMember[] cacheVms = adminDSJmx.getCacheVms();
+        for (int i = 0; i < cacheVms.length; i++) {
+          try {
+            initializeCacheRegionsAndStats((SystemMemberJmx)cacheVms[i]);
+          } catch (AdminException e) {
+            logger.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_INTIALIZING_0_CONTINUING, 
+                           cacheVms[i].getId()), e);
+          }
+        }
+        SystemMember[] appVms = adminDSJmx.getSystemMemberApplications();
+        for (int i = 0; i < appVms.length; i++) {
+          try {
+            initializeCacheRegionsAndStats((SystemMemberJmx)appVms[i]);
+          } catch (AdminException e) {
+            logger.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_INTIALIZING_0_CONTINUING, 
+                           appVms[i].getId()), e);
+          }
+        }
+      }
+    } catch (AdminException e) {
+      logger.warn(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_INTIALIZING), e);
+      throw new OperationsException(e.getMessage());
+    } catch (Exception e) {
+      logger.warn(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_INTIALIZING), e);
+      throw new OperationsException(e.getMessage());
+    }
+    
+    isInitialized = true;
+  }
+  
+  /**
+   * Initializes Cache, Regions & Statistics Types MBeans for the given Member.
+   * 
+   * @param memberJmx
+   *          Member Mbean instance
+   * @throws OperationsException
+   *           if fails to initialize required MBeans
+   * @throws AdminException
+   *           if fails to initialize required MBeans
+   */
+  private void initializeCacheRegionsAndStats(SystemMemberJmx memberJmx) 
+    throws OperationsException, AdminException {
+    if (memberJmx != null) {
+      SystemMemberCacheJmxImpl cache = (SystemMemberCacheJmxImpl) memberJmx.getCache();
+      if (cache != null) {
+        RegionSubRegionSnapshot regionSnapshot = cache.getRegionSnapshot();
+        initializeRegionSubRegions(cache, regionSnapshot);
+      }
+      initStats(memberJmx);
+    }
+  }
+
+  /**
+   * Initializes statistics for a member with the given mbean.
+   * 
+   * @param memberJmx
+   *          Member Mbean instance
+   * @throws AdminException
+   *           if fails to initialize required statistic MBeans
+   */
+  private void initStats(SystemMemberJmx memberJmx) throws AdminException {
+    StatisticResource[] statResources = memberJmx.getStats();
+    for (StatisticResource statResource : statResources) {
+      statResource.getStatistics();
+    }
+  }
+
+  /**
+   * Initializes all regions & its subregions using the Cache MBean and the
+   * RegionSubRegionSnapshot for this cache MBean.
+   * 
+   * @param cache
+   *          Cache MBean resource
+   * @param regionSnapshot
+   *          RegionSubRegionSnapshot instance for the cache
+   * @throws MalformedObjectNameException
+   *           if fails to initialize the region MBean
+   * @throws AdminException
+   *           if fails to initialize the region MBean
+   */
+  @SuppressWarnings("rawtypes")
+  private void initializeRegionSubRegions(SystemMemberCacheJmxImpl cache, 
+                                 RegionSubRegionSnapshot regionSnapshot) 
+                                   throws MalformedObjectNameException, 
+                                          AdminException {
+    String fullPath = regionSnapshot.getFullPath();
+    if (!fullPath.equals(PLACE_HOLDER_ROOT_REGION)) {
+      fullPath = fullPath.substring(PLACE_HOLDER_ROOT_REGION.length()-1);
+
+      cache.manageRegion(fullPath);
+    }
+    
+    Set subRegionSnapshots = regionSnapshot.getSubRegionSnapshots();
+    
+    for (Iterator iterator = subRegionSnapshots.iterator(); iterator.hasNext();) {
+      RegionSubRegionSnapshot subRegion = (RegionSubRegionSnapshot) iterator.next();
+      try {
+        initializeRegionSubRegions(cache, subRegion);
+      } catch (AdminException e) {
+        logger.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_INTIALIZING_0_CONTINUING, subRegion.getFullPath()), e);
+      }
+    }
+  }
+  
+  
+  /* **************************************************************************/
+  /* ********************** EVERYTHING HYPERIC NEEDS **************************/
+  /* **************************************************************************/
+  
+  /* constants defined that could be used simply retrieve needed info from Map */
+  private static final String TYPE_NAME_CACHESERVER = "Cache Server";
+  private static final String TYPE_NAME_APPLICATION = "Application Peer";
+  /*
+   * NOTE -
+   * (My Understanding about the followings - abhishek)  
+   * 1. CacheVM - a VM started using Cache Server Launcher. This is considered 
+   * to be a dedicated cache VM because there is only GemFire Cache code 
+   * running here.
+   * 2. ApplicationVM - a VM started with a written code using APIs and we can 
+   * not guarantee that there will be ONLY GemFire code running in this VM.
+   * 3. Cache Server - Responsible for serving requests from the clients. There 
+   * could be multiple of these per Cache and hence per VM - one of 1 or 2 above.
+   * These could be specified by <cache-server> (or deprecated <bridge-server>)
+   * element(s) in the cache-xml file or using an API Cache.addCacheServer().
+   */
+
+//  private static final String VERSION          = "gemfire.version.string";
+//  private static final String MEMBER_COUNT     = "gemfire.membercount.int";
+//  private static final String GATEWAYHUB_COUNT = "gemfire.gatewayhubcount.int";
+//  private static final String CLIENT_COUNT     = "gemfire.clientcount.int";
+
+  private static final String MEMBER_ID       = "gemfire.member.id.string";
+  private static final String MEMBER_NAME     = "gemfire.member.name.string";
+  private static final String MEMBER_HOST     = "gemfire.member.host.string";
+  private static final String MEMBER_PORT     = "gemfire.member.port.int";
+  private static final String MEMBER_UPTIME   = "gemfire.member.uptime.long";
+  private static final String MEMBER_CLIENTS  = "gemfire.member.clients.map";
+  private static final String MEMBER_REGIONS  = "gemfire.member.regions.map";
+  private static final String MEMBER_TYPE     = "gemfire.member.type.string";
+  private static final String IS_SERVER       = "gemfire.member.isserver.boolean";
+  private static final String IS_GATEWAY      = "gemfire.member.isgateway.boolean";
+
+  private static final String MEMBER_STATSAMPLING_ENABLED = "gemfire.member.config.statsamplingenabled.boolean";
+  private static final String MEMBER_TIME_STATS_ENABLED   = "gemfire.member.config.timestatsenabled.boolean";
+  
+  private static final String STATS_PROCESSCPUTIME = "gemfire.member.stat.processcputime.long";
+  private static final String STATS_CPUS           = "gemfire.member.stat.cpus.int";
+  private static final String STATS_USEDMEMORY     = "gemfire.member.stat.usedmemory.long";
+  private static final String STATS_MAXMEMORY      = "gemfire.member.stat.maxmemory.long";
+  private static final String STATS_GETS           = "gemfire.member.stat.gets.int";
+  private static final String STATS_GETTIME        = "gemfire.member.stat.gettime.long";
+  private static final String STATS_PUTS           = "gemfire.member.stat.puts.int";
+  private static final String STATS_PUTTIME        = "gemfire.member.stat.puttime.long";
+  
+  private static final String REGION_NAME           = "gemfire.region.name.string";
+  private static final String REGION_PATH           = "gemfire.region.path.string";
+  private static final String REGION_SCOPE          = "gemfire.region.scope.string";
+  private static final String REGION_DATAPOLICY     = "gemfire.region.datapolicy.string";
+  private static final String REGION_INTERESTPOLICY = "gemfire.region.interestpolicy.string";
+  private static final String REGION_ENTRYCOUNT     = "gemfire.region.entrycount.int";
+  private static final String REGION_DISKATTRS      = "gemfire.region.diskattrs.string";
+
+  private static final String CLIENT_ID                = "gemfire.client.id.string";
+  private static final String CLIENT_NAME              = "gemfire.client.name.string";
+  private static final String CLIENT_HOST              = "gemfire.client.host.string";
+  private static final String CLIENT_QUEUESIZE         = "gemfire.client.queuesize.int";
+  private static final String CLIENT_STATS_GETS        = "gemfire.client.stats.gets.int";
+  private static final String CLIENT_STATS_PUTS        = "gemfire.client.stats.puts.int";
+  private static final String CLIENT_STATS_CACHEMISSES = "gemfire.client.stats.cachemisses.int";
+  private static final String CLIENT_STATS_CPUUSAGE    = "gemfire.client.stats.cpuusage.long";
+  private static final String CLIENT_STATS_CPUS        = "gemfire.client.stats.cpus.int";
+  private static final String CLIENT_STATS_UPDATETIME  = "gemfire.client.stats.updatetime.long";
+  private static final String CLIENT_STATS_THREADS     = "gemfire.client.stats.threads.int";
+  
+  /**
+   * 
+   * @param memberId
+   * @return All the required details for a member with given memberId 
+   * @throws OperationsException
+   */
+  public Map<String, Object> getMemberDetails(String memberId) 
+    throws OperationsException {
+    Map<String, Object> allDetails = new TreeMap<String, Object>();
+
+    if (memberId != null) {
+      try {
+        SystemMemberJmx member = findMember(memberId);
+        if (member != null) {
+          SystemMemberCacheJmxImpl cache = (SystemMemberCacheJmxImpl) member.getCache();
+          GemFireMemberStatus snapshot   = cache.getSnapshot();
+          boolean isServer     = snapshot.getIsServer();
+          boolean isGatewayHub = snapshot.getIsGatewayHub();
+          
+          //1. Member info
+          allDetails.put(MEMBER_ID, member.getId());
+          allDetails.put(MEMBER_NAME, member.getName());
+          String host = member.getHost();//from of GemFireVM.getHost
+          InetAddress hostAddr = member.getHostAddress();
+          //possibility of null host address
+          if (hostAddr != null) {
+            host = hostAddr.getHostName();
+          }
+          allDetails.put(MEMBER_HOST, host);
+          allDetails.put(MEMBER_UPTIME, snapshot.getUpTime());
+          allDetails.put(IS_SERVER, isServer);
+          allDetails.put(IS_GATEWAY, isGatewayHub);
+          
+          String memberType = "";
+          if (member instanceof CacheServerJmxImpl) {
+            memberType = TYPE_NAME_CACHESERVER;
+          } else {//Mark it of Application type if neither a gateway hub nor a server
+            memberType = TYPE_NAME_APPLICATION;
+          }
+//          if (isGatewayHub) {
+//            memberType = TYPE_NAME_GATEWAYHUB;
+//          } else if (isServer) {
+//            memberType = TYPE_NAME_CACHESERVER;
+//          } else {//Mark it of Application type if neither a gateway nor a server
+//            memberType = TYPE_NAME_APPLICATION;
+//          }
+          allDetails.put(MEMBER_TYPE, memberType);
+
+          //2. Region info
+          Map<String, ObjectName> existingRegionMbeans = getExistingRegionMbeansFullPaths(memberId);
+          allDetails.put(MEMBER_REGIONS, getAllRegionsDetails(cache, existingRegionMbeans));
+          existingRegionMbeans.clear();
+
+          //3. Clients info
+          allDetails.put(MEMBER_CLIENTS, getClientDetails(snapshot));
+          
+          boolean statSamplingEnabled = true;
+          //assuming will never return as per current implementation
+          ConfigurationParameter[] configParams = member.getConfiguration();
+          for (ConfigurationParameter configParam : configParams) {
+            if (DistributionConfig.STATISTIC_SAMPLING_ENABLED_NAME.equals(configParam.getName())) {
+              allDetails.put(MEMBER_STATSAMPLING_ENABLED, configParam.getValue());
+              statSamplingEnabled = Boolean.parseBoolean(""+configParam.getValue());
+            } else if (DistributionConfig.ENABLE_TIME_STATISTICS_NAME.equals(configParam.getName())) {
+              allDetails.put(MEMBER_TIME_STATS_ENABLED, configParam.getValue());
+            }
+          }
+          
+          //5. Stats info
+          allDetails.putAll(getRequiredStats(member, statSamplingEnabled));
+
+          SystemMemberCacheServer[] cacheServers = cache.getCacheServers();
+          //attempt refreshing the cache info once
+          if (cacheServers.length == 0) {
+            cache.refresh();
+            cacheServers = cache.getCacheServers();
+          }
+          Integer memberCacheServerPort = Integer.valueOf(0);
+          if (cacheServers.length != 0) {
+            /*
+             * Taking the first cache server port.
+             * We don't recommend multiple cache severs for a cache.
+             */
+            memberCacheServerPort = Integer.valueOf(cacheServers[0].getPort());
+          }
+          allDetails.put(MEMBER_PORT, memberCacheServerPort);
+        }
+        
+      } catch (AdminException e) {
+        logger.warn(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_FOR_OPERATION_0_FOR_MEMBER_1, 
+                          new Object[] {"getMemberDetails", memberId}), e);
+        throw new OperationsException(e.getMessage());
+      } catch (Exception e) {
+        logger.warn(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_FOR_OPERATION_0_FOR_MEMBER_1, 
+                          new Object[] {"getMemberDetails", memberId}), e);
+        throw new OperationsException(e.getMessage());
+      }
+    }
+    
+    return allDetails;
+  }
+  
+  /**
+   * 
+   * @param snapshot
+   * @return Map of client details 
+   */
+  @SuppressWarnings("rawtypes")
+  private Map<String, Map<String, ?>> getClientDetails(GemFireMemberStatus snapshot) {
+    Map<String, Map<String, ?>> clientsInfo = 
+      new LinkedHashMap<String, Map<String, ?>>();
+    
+    Set connectedClients = snapshot.getConnectedClients();
+    if (!connectedClients.isEmpty()) {
+      Map clientHealthStatsMap = snapshot.getClientHealthStats();
+      
+      for (Iterator iterator = connectedClients.iterator(); iterator.hasNext();) {
+        Map<String, Object> clientData = new HashMap<String, Object>();
+        String clientId = (String) iterator.next();
+        String host     = snapshot.getClientHostName(clientId);
+        clientData.put(CLIENT_ID, clientId);
+        clientData.put(CLIENT_NAME, extractClientName(clientId, host));
+        clientData.put(CLIENT_HOST, host);
+        clientData.put(CLIENT_QUEUESIZE, snapshot.getClientQueueSize(clientId));
+  
+        ClientHealthStats clientHealthStats = (ClientHealthStats) clientHealthStatsMap.get(clientId);
+        if (clientHealthStats != null) {
+          clientData.put(CLIENT_STATS_GETS, clientHealthStats.getNumOfGets());
+          clientData.put(CLIENT_STATS_PUTS, clientHealthStats.getNumOfPuts());
+          clientData.put(CLIENT_STATS_CACHEMISSES, clientHealthStats.getNumOfMisses());
+          clientData.put(CLIENT_STATS_CPUUSAGE, clientHealthStats.getProcessCpuTime());
+          clientData.put(CLIENT_STATS_CPUS, clientHealthStats.getCpus());
+          clientData.put(CLIENT_STATS_UPDATETIME, clientHealthStats.getUpdateTime().getTime());
+          clientData.put(CLIENT_STATS_THREADS, clientHealthStats.getNumOfThreads());
+        } else {
+          clientData.put(CLIENT_STATS_GETS, Integer.valueOf(0));
+          clientData.put(CLIENT_STATS_PUTS, Integer.valueOf(0));
+          clientData.put(CLIENT_STATS_CACHEMISSES, Integer.valueOf(0));
+          clientData.put(CLIENT_STATS_CPUUSAGE, Long.valueOf(0));
+          clientData.put(CLIENT_STATS_CPUS, Integer.valueOf(0));
+          clientData.put(CLIENT_STATS_UPDATETIME, Long.valueOf(0));
+          clientData.put(CLIENT_STATS_THREADS, Integer.valueOf(0));
+        }
+        
+        clientsInfo.put(clientId, clientData);
+      }
+    }
+    
+    return clientsInfo;
+  }
+
+  /**
+   * Returns a Map containing information about regions.
+   * 
+   * @param cache
+   *          Reference to an MBean representing a Cache on a member
+   * @param existingRegionMbeans
+   *          Map of Path against Region MBean ObjectNames
+   * @return Map of all region details
+   * @throws OperationsException
+   *           if fails to retrieve
+   */
+  private Map<String, Map<String, ?>> getAllRegionsDetails(
+                                  SystemMemberCacheJmxImpl cache, 
+                                  Map<String, ObjectName> existingRegionMbeans) 
+                                  throws OperationsException {
+    Map<String, Map<String, ?>> regionsInfo = 
+                        new TreeMap<String, Map<String, ?>>();
+    
+    if (cache != null) {
+      try {
+        RegionSubRegionSnapshot regionSnapshot = cache.getRegionSnapshot();
+        collectAllRegionsDetails(cache, regionSnapshot, regionsInfo, existingRegionMbeans);
+      } catch (AdminException e) {
+        logger.warn(LocalizedMessage.create(LocalizedStrings.ONE_ARG, "Exception occurred while getting region details."), e);
+        throw new OperationsException(e.getMessage());
+      } catch (Exception e) {
+        logger.warn(LocalizedMessage.create(LocalizedStrings.ONE_ARG, "Exception occurred while getting region details."), e);
+        throw new OperationsException(e.getMessage());
+      }
+    }
+    
+    return regionsInfo;
+  }
+
+  /**
+   * Collects all the region details from the RegionSubRegionSnapshot instance
+   * passed and the Cache MBean. Checks in the set of existingRegionMbeans
+   * before initializing Region Mbeans if there are not initialized yet.
+   * 
+   * @param cache
+   *          Cache MBean instance
+   * @param regionSnapshot
+   *          RegionSubRegionSnapshot instance
+   * @param regionsInfo
+   *          Map of regions information that gets populated recursively
+   * @param existingRegionMbeans
+   *          Map of ObjectNames of existing region MBeans
+   * @throws AdminException
+   *           if unable to initialize region MBean
+   * @throws OperationsException
+   *           if fails to retrieve the Region MBean attribute info
+   * @throws MBeanException
+   *           if fails to retrieve the Region MBean attribute info
+   * @throws ReflectionException
+   *           if fails to retrieve the Region MBean attribute info
+   */
+  @SuppressWarnings("rawtypes")
+  private void collectAllRegionsDetails(SystemMemberCacheJmxImpl cache, 
+                                 RegionSubRegionSnapshot regionSnapshot, 
+                                 Map<String, Map<String, ?>> regionsInfo,
+                                 Map<String, ObjectName> existingRegionMbeans) 
+                                 throws AdminException, OperationsException, 
+                                        MBeanException, ReflectionException {
+    String fullPath = regionSnapshot.getFullPath();
+    if (!fullPath.equals(PLACE_HOLDER_ROOT_REGION)) {
+      fullPath = fullPath.substring(PLACE_HOLDER_ROOT_REGION.length()-1);
+      String name = regionSnapshot.getName();
+      Integer entryCount = Integer.valueOf(regionSnapshot.getEntryCount());
+      Map<String, Object> details = new TreeMap<String, Object>();
+      details.put(REGION_NAME, name);
+      details.put(REGION_PATH, fullPath);
+      details.put(REGION_ENTRYCOUNT, entryCount);
+      
+      ObjectName regionObjectName = existingRegionMbeans.get(fullPath);
+      if (regionObjectName == null) {//initialize if has not yet been 
+        regionObjectName = cache.manageRegion(fullPath);
+      }
+
+      Object attribute = getAttribute(regionObjectName, "scope", NOT_AVAILABLE);
+      attribute = attribute != null ? attribute.toString() : attribute;
+      details.put(REGION_SCOPE, attribute);
+      
+      attribute = getAttribute(regionObjectName, "dataPolicy", NOT_AVAILABLE);
+      attribute = attribute != null ? attribute.toString() : attribute;
+      details.put(REGION_DATAPOLICY, attribute);
+
+      SubscriptionAttributes interestPolicyAttr = 
+          (SubscriptionAttributes) getAttribute(regionObjectName, 
+                                                "subscriptionAttributes", null);
+      String interestPolicyStr = NOT_AVAILABLE;
+      if (interestPolicyAttr != null) {
+        InterestPolicy interestPolicy = interestPolicyAttr.getInterestPolicy();
+        if (interestPolicy != null) {
+          interestPolicyStr = interestPolicy.toString();
+        }
+      }
+      details.put(REGION_INTERESTPOLICY, interestPolicyStr);
+
+      attribute = getAttribute(regionObjectName, "diskWriteAttributes", NOT_AVAILABLE);
+      attribute = attribute != null ? attribute.toString() : attribute;
+      details.put(REGION_DISKATTRS, attribute);
+      
+      regionsInfo.put(fullPath, details);
+    }
+    
+    Set subRegionSnapshots = regionSnapshot.getSubRegionSnapshots();
+    
+    for (Iterator iterator = subRegionSnapshots.iterator(); iterator.hasNext();) {
+      RegionSubRegionSnapshot subRegion = (RegionSubRegionSnapshot) iterator.next();
+      collectAllRegionsDetails(cache, subRegion, regionsInfo, existingRegionMbeans);
+    }
+  }
+  
+  /**
+   * Checks if the given host name string contains ':' as in IPv6 host address.
+   * 
+   * @param host
+   *          host name string
+   * @return true if the host string contains ':', false otherwise
+   */
+  private static boolean isIPv6(String host) {
+    return host.contains(":");
+  }
+
+  /**
+   * Checks if the given host name is actually a String representation of an
+   * IPv4 address.
+   * 
+   * @param host
+   *          host name string
+   * @return true if given host name is a String representation of an IPv4
+   *         address, false otherwise
+   */
+  private static boolean isIPv4(String host) {
+    String regex = "\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3}";
+    
+    return host.matches(regex);
+  }
+  
+  /**
+   * Excludes the host name from the client id and returns the String. If the
+   * host name can not be detected, returns an empty string. Typically, the
+   * client id looks like: HOST(VM_PID:VM_KIND):PORT:RANDOM_STRING:CLIENT_NAME
+   * 
+   * Extracts the client name from the client id. If the client id is not in the
+   * expected format, returns 'N/A'
+   * 
+   * @param clientId
+   *          string identifier for a client
+   * @param host
+   *          host name (FQDN) the client is running on
+   * @return name extracted from given client id
+   */
+  /*
+   * Some examples of Client Id format: 
+   * (1) Java Client:
+   * nase(21716:loner):51789:42e9a0bf:client_nase_21716
+   * nase(2560:loner):2:7a84729a:Feeder
+   * 
+   * (2) Native Client:
+   * nase(21045:loner):2:GFNative_OnNnEpyRWL:ExampleDistributedSystem
+   * 
+   * (3) IPv6 Host whose name can not be resolved:
+   * fdf0:76cf:a0ed:9449:0:0:0:1001(21716:loner):51789:42e9a0b:client_nase_21716
+   * fdf0:76cf:a0ed:9449:0:0:0:1001:51789:42e9a0b:client_nase_21716 
+   */
+  private static String extractClientName(String clientId, String host) {
+    /* This isIPv6, isIPv4, extractClientName is taken from GFMon code base*/
+    String hostExcludedId = "";
+    if ( (isIPv6(host) || isIPv4(host))&& clientId.startsWith(host)) {
+      hostExcludedId = clientId.substring(host.length());
+    } else {
+      int firstDotIndex = host.indexOf(".");
+      if (firstDotIndex != -1) {
+        String hostShortName = host.substring(0, firstDotIndex);
+        hostExcludedId = clientId.substring(hostShortName.length());
+      }
+    }
+    
+    String vmPIDAndKindRegex = "\\(\\w+:\\w+\\)";
+    String regex             = "(\\<ec\\>)?:[0-9]+(:\\w+){2}+";
+    String name              = NOT_AVAILABLE;
+    String temp              = hostExcludedId;
+
+    int openIndex = temp.indexOf("(");
+    if (openIndex != -1) {      
+      regex = vmPIDAndKindRegex + regex;
+    }
+
+    if (temp.matches(regex)) {
+      String[] splitted = temp.split(":");
+      name = splitted[splitted.length - 1];
+    }
+    
+    return name;
+  }
+
+  /**
+   * Returns a Map of all the statistics required for Hyperic currently. It
+   * relies on the attribute of the StatisticsResource Mbeans.
+   * 
+   * @param member
+   *          instance for which the stats are needed
+   * @return Map of all the statistics required for Hyperic currently.
+   * @throws OperationsException
+   *           exceptions thrown while retrieving the attributes
+   */
+  private Map<String, Object> getRequiredStats(SystemMemberJmx member, boolean statSamplingEnabled) throws OperationsException {
+    Map<String, Object> statDetails = new TreeMap<String, Object>();
+    
+    try {
+      if (!statSamplingEnabled) {
+        statDetails.put(STATS_PROCESSCPUTIME, NOT_AVAILABLE_NUMBER);
+        statDetails.put(STATS_CPUS, NOT_AVAILABLE_NUMBER);
+        statDetails.put(STATS_MAXMEMORY, NOT_AVAILABLE_NUMBER);
+        statDetails.put(STATS_USEDMEMORY, NOT_AVAILABLE_NUMBER);
+        statDetails.put(STATS_GETS, NOT_AVAILABLE_NUMBER);
+        statDetails.put(STATS_GETTIME, NOT_AVAILABLE_NUMBER);
+        statDetails.put(STATS_PUTS, NOT_AVAILABLE_NUMBER);
+        statDetails.put(STATS_PUTTIME, NOT_AVAILABLE_NUMBER);
+      } else {
+        MBeanServer mBeanServer = agent.getMBeanServer();
+        Number defaultVal     = NOT_AVAILABLE_NUMBER;
+        Number processCpuTime = defaultVal;
+        Number cpus           = defaultVal;
+        Number maxMemory      = defaultVal;
+        Number usedMemory     = defaultVal;
+        Number gets           = defaultVal;
+        Number getTime        = defaultVal;
+        Number puts           = defaultVal;
+        Number putTime        = defaultVal;
+        
+        ObjectName[] vmMemoryUsageStats = getExistingStats(member.getId(), "vmHeapMemoryStats");
+        ObjectName[] vmStats            = getExistingStats(member.getId(), "vmStats");
+        ObjectName[] cachePerfStats     = getExistingStats(member.getId(), "cachePerfStats");
+        boolean needToReinit = false;
+        if (vmMemoryUsageStats.length == 0 || vmStats.length == 0 || cachePerfStats.length == 0) {
+          //if the StatisticResource MBeans are not created
+          needToReinit = true;
+        }
+        if(!needToReinit) {
+          /*
+           * To handle a case when the StatisticResource MBeans are created but 
+           * not registered with RefreshTimer. If VMMemoryUsageStats are 
+           * present, maxMemory should always be non-zero. */
+          for (int i = 0; i < vmMemoryUsageStats.length; i++) {//ideally there should be a single instance
+            String type = (String) mBeanServer.getAttribute(vmMemoryUsageStats[i], "type");
+            
+            if ("VMMemoryUsageStats".equals(type)) { //first instance that has Statistics Type name
+              maxMemory  = (Number) getAttribute(vmMemoryUsageStats[i], "maxMemory", defaultVal);
+              break;
+            }
+          }
+          
+          needToReinit = 0 == maxMemory.longValue(); 
+        }
+
+        if(needToReinit) {
+          logger.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_REINITIALIZING_STATS_FOR_0, member.getId()));
+          initStats(member);
+
+          vmMemoryUsageStats = getExistingStats(member.getId(), "vmHeapMemoryStats");
+          vmStats            = getExistingStats(member.getId(), "vmStats");
+          cachePerfStats     = getExistingStats(member.getId(), "cachePerfStats");
+        }
+        
+        for (int i = 0; i < vmMemoryUsageStats.length; i++) {//ideally there should be a single instance
+          String type = (String) mBeanServer.getAttribute(vmMemoryUsageStats[i], "type");
+          
+          if ("VMMemoryUsageStats".equals(type)) { //first instance that has Statistics Type name
+            maxMemory  = (Number) getAttribute(vmMemoryUsageStats[i], "maxMemory", defaultVal);
+            usedMemory = (Number) getAttribute(vmMemoryUsageStats[i], "usedMemory", defaultVal);
+            break;
+          }
+        }
+
+        for (int i = 0; i < vmStats.length; i++) {//ideally there should be a single instance
+          String type = (String) mBeanServer.getAttribute(vmStats[i], "type");
+          
+          if ("VMStats".equals(type)) { //first instance that has Statistics Type name
+            processCpuTime = (Number) getAttribute(vmStats[i], "processCpuTime", defaultVal);
+            cpus           = (Number) getAttribute(vmStats[i], "cpus", defaultVal);
+            break;
+          }
+        }
+        
+        for (int i = 0; i < cachePerfStats.length; i++) {//ideally there should be a single instance
+          String type = (String) mBeanServer.getAttribute(cachePerfStats[i], "type");
+          
+          if ("CachePerfStats".equals(type)) { //first instance that has Statistics Type name
+            gets    = (Number) getAttribute(cachePerfStats[i], "gets", defaultVal);
+            getTime = (Number) getAttribute(cachePerfStats[i], "getTime", defaultVal);
+            puts    = (Number) getAttribute(cachePerfStats[i], "puts", defaultVal);
+            putTime = (Number) getAttribute(cachePerfStats[i], "putTime", defaultVal);
+            break;
+          }
+        }
+        
+        statDetails.put(STATS_PROCESSCPUTIME, processCpuTime == NOT_AVAILABLE_NUMBER ? NOT_AVAILABLE_NUMBER : processCpuTime.longValue());
+        statDetails.put(STATS_CPUS, cpus == NOT_AVAILABLE_NUMBER ? NOT_AVAILABLE_NUMBER : cpus.intValue());
+        statDetails.put(STATS_MAXMEMORY,  maxMemory == NOT_AVAILABLE_NUMBER ? NOT_AVAILABLE_NUMBER : maxMemory.longValue());
+        statDetails.put(STATS_USEDMEMORY, usedMemory == NOT_AVAILABLE_NUMBER ? NOT_AVAILABLE_NUMBER : usedMemory.longValue());
+        statDetails.put(STATS_GETS, gets == NOT_AVAILABLE_NUMBER ? NOT_AVAILABLE_NUMBER : gets.intValue());
+        statDetails.put(STATS_GETTIME, getTime == NOT_AVAILABLE_NUMBER ? NOT_AVAILABLE_NUMBER : getTime.intValue());
+        statDetails.put(STATS_PUTS, puts == NOT_AVAILABLE_NUMBER ? NOT_AVAILABLE_NUMBER : puts.intValue());
+        statDetails.put(STATS_PUTTIME, putTime == NOT_AVAILABLE_NUMBER ? NOT_AVAILABLE_NUMBER : putTime.longValue());
+      }
+    } catch (Exception e) {
+      logger.warn(e.getMessage(), e);
+      throw new OperationsException(e.getMessage());
+    }
+    
+    return statDetails;
+  }
+
+  /**
+   * Returns attribute with given attribute name on MBean with given ObjectName.
+   * 
+   * 
+   * @param objectName
+   *          ObjectName for the MBean
+   * @param attribute
+   *          attribute name
+   * @param unavailableValue
+   *          return this value if the attribute value is null
+   * @return value of attribute with given attribute name
+   * @throws OperationsException
+   *           if attribute is not found for MBean with this ObjectName or MBean
+   *           instance is not found
+   * @throws MBeanException
+   *           if MBeans getter throws exception
+   * @throws ReflectionException
+   *           thrown when trying to invoke the setter.
+   */
+  private Object getAttribute(ObjectName objectName, String attribute, 
+      Object unavailableValue) 
+        throws OperationsException, MBeanException, ReflectionException {
+    /* NOTE: callers methods rely on non-null value being returned */
+    Object value = null;
+    
+    MBeanServer mBeanServer = agent.getMBeanServer();
+    value = mBeanServer.getAttribute(objectName, attribute);
+    
+    value = (value != null)? value : unavailableValue;
+    
+    return value;
+  }
+
+  /**
+   * Return Map of region full against the ObjectName of existing region MBeans.
+   * 
+   * @param memberId
+   *          string identifier of a member
+   * @return Map of region path vs ObjectName for existing region MBeans
+   * @throws MalformedObjectNameException
+   *           If the query expression used is not valid
+   */
+  private Map<String, ObjectName> getExistingRegionMbeansFullPaths(String memberId) throws MalformedObjectNameException {
+    Map<String, ObjectName> pathsToObjName = new HashMap<String, ObjectName>();
+
+    if (memberId != null && memberId.trim().length() != 0) {
+      Object[] params = new Object[] {MBeanUtil.makeCompliantMBeanNameProperty(memberId)};
+      Set<ObjectName> queryNames = queryObjectNames(REGION_QUERY_EXPRESSION, params);
+      for (ObjectName objectName : queryNames) {
+        pathsToObjName.put(objectName.getKeyProperty("path"), objectName);
+      }
+    }
+    
+    return pathsToObjName;
+  }
+
+  /**
+   * Returns an array of ObjectNames existing statistics types MBeans
+   * 
+   * @param memberId
+   *          string identifier of a member
+   * @param name
+   *          text id of the stats which appears in the stats ObjectName as name
+   *          keyProperty
+   * @return Array of Stats MBean ObjectNames
+   * @throws MalformedObjectNameException
+   *           If the query expression used is not valid
+   */
+  private ObjectName[] getExistingStats(String memberId, String name) throws MalformedObjectNameException {
+    ObjectName[] statObjectNames = new ObjectName[0];
+    
+    if (memberId != null && memberId.trim().length() != 0) {
+      Object[] params = new Object[] {MBeanUtil.makeCompliantMBeanNameProperty(memberId), name};
+      Set<ObjectName> queryNames = queryObjectNames(STATS_QUERY_EXPRESSION, params);
+      statObjectNames = new ObjectName[queryNames.size()];
+      statObjectNames = queryNames.toArray(statObjectNames);
+    }
+    
+    return statObjectNames;
+  }
+
+  /**
+   * Queries the MBean server with the string formed using placing the params in
+   * the parameterized string passed as queryStr.
+   * 
+   * @param queryStr
+   *          parameterized string
+   * @param params
+   *          params to put in the string
+   * @return results of an ObjectName query
+   * @throws MalformedObjectNameException
+   *           If the query expression ObjectName formed is not valid
+   */
+  private Set<ObjectName> queryObjectNames(String queryStr, Object ... params) 
+    throws MalformedObjectNameException {
+    Set<ObjectName> queried = Collections.emptySet();    
+    
+    queryStr = MessageFormat.format(queryStr, params);    
+    ObjectName queryExp = ObjectName.getInstance(queryStr);
+    queried = agent.getMBeanServer().queryNames(null, queryExp);
+    
+    return queried;
+  }
+  
+  
+  /* *************************************************************************/
+  /* **************** NOTIFICATION EMITTER IMPLEMENTATION ********************/
+  /* *************************************************************************/
+
+  /**
+   * @see NotificationEmitter#addNotificationListener(NotificationListener, NotificationFilter, Object)
+   */
+  public void addNotificationListener(NotificationListener listener,
+      NotificationFilter filter, Object handback)
+      throws IllegalArgumentException {
+    forwarder.addNotificationListener(listener, filter, handback);
+  }
+
+  /**
+   * @see NotificationEmitter#removeNotificationListener(NotificationListener)
+   */
+  public void removeNotificationListener(NotificationListener listener)
+      throws ListenerNotFoundException {
+    forwarder.removeNotificationListener(listener);
+  }
+
+  /**
+   * @see NotificationEmitter#getNotificationInfo()
+   */
+  public MBeanNotificationInfo[] getNotificationInfo() {
+    return getMBeanInfo().getNotifications();
+  }
+  
+  /**
+   * @see NotificationEmitter#removeNotificationListener(NotificationListener, NotificationFilter, Object)
+   */
+  public void removeNotificationListener(NotificationListener listener,
+      NotificationFilter filter, Object handback)
+      throws ListenerNotFoundException {
+    forwarder.removeNotificationListener(listener, filter, handback);
+  }
+  
+}
+
+/**
+ * This class acts as a hub for the Notifications defined on
+ * AdminDistributedSystem & SystemMember MBeans. This acts as a listener for
+ * these notifications and broadcasts them as notifications from the
+ * {@link MemberInfoWithStatsMBean} MBean. This class extends
+ * {@link NotificationBroadcasterSupport} only to have the functionality to send
+ * notifications.
+ * 
+ * @author abhishek
+ * 
+ * @since 6.5
+ */
+class NotificationForwarder extends NotificationBroadcasterSupport 
+  implements NotificationListener {
+  
+  private static final Logger logger = LogService.getLogger();
+  
+  /* sequence generator for notifications from GemFireTypesWrapper MBean */
+  private static AtomicLong notificationSequenceNumber = new AtomicLong();
+
+  /* reference to the MBeanServer instance */
+  private MBeanServer   mBeanServer;
+
+  /**
+   * Default Constructor
+   * 
+   * @param mBeanServer
+   *          reference to the MBeanServer instance
+   */
+  /*default*/NotificationForwarder(MBeanServer mBeanServer) {
+    this.mBeanServer = mBeanServer;
+  }
+
+  /**
+   * Handles notifications as: 1. Member Joined: Registers this
+   * NotificationForwarder as a notification listener for Cache/Region
+   * Notifications. 2. Member Left/Crashed: Unregisters this
+   * NotificationForwarder as a notification listener for Cache/Region
+   * Notifications. 3. AdminDistributedSystem Disconnected: Unregisters this
+   * NotificationForwarder as a notification listener for member Notifications.
+   * 
+   * Forwards the notifications to the JMX Clients that have registered for
+   * notifications on this MBean
+   * 
+   * @param notification
+   *          notification to be handled
+   * @param handback
+   *          handback object used while NotificationForwarder was registered
+   * 
+   * @see NotificationListener#handleNotification(Notification, Object)
+   */
+  public void handleNotification(Notification notification, Object handback) {
+    Object notifSource = notification.getSource();
+    if (AdminDistributedSystemJmxImpl.NOTIF_MEMBER_JOINED.equals(notification.getType())) {
+      ObjectName source = (ObjectName) notifSource;
+      //initialize statistics/register with refreshTimer for new member
+      String[] noArgs = {};
+      try {
+        ObjectName[] stats = (ObjectName[]) mBeanServer.invoke(source, "manageStats", noArgs, noArgs);
+        if (stats != null) {
+          for (ObjectName stat : stats) {
+            mBeanServer.invoke(stat, "getStatistics", noArgs, noArgs);
+          }
+        }
+        logger.debug("getStatistics call completed with no exceptions.");
+      } catch (ReflectionException e) {
+        logger.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_INITIALIZING_STATISICS_FOR_0, source.toString()), e);
+      } catch (MBeanException e) {
+        logger.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_INITIALIZING_STATISICS_FOR_0, source.toString()), e);
+      } catch (InstanceNotFoundException e) {
+        logger.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_INITIALIZING_STATISICS_FOR_0, source.toString()), e);
+      }
+      //register this listener for joined member's cache/region notifications
+      try {
+        registerNotificationListener(source);
+      } catch (OperationsException e) {
+        logger.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_REGISTERING_NOTIFICATION_LISTENER_FOR_0, source.toString()), e);
+      }
+    } /*else if (AdminDistributedSystemJmxImpl.NOTIF_MEMBER_LEFT.equals(notification.getType()) || 
+               AdminDistributedSystemJmxImpl.NOTIF_MEMBER_CRASHED.equals(notification.getType())) {
+      ObjectName source = (ObjectName) notifSource;
+      //unregister this listener from left member's cache/region notifications
+      try {
+        unregisterNotificationListener(source);
+      } catch (OperationsException e) {
+        logwriter.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_UNREGISTERING_NOTIFICATION_LISTENER_FOR_0, source.toString(), e);
+      }
+    } else if (AdminDistributedSystemJmxImpl.NOTIF_ADMIN_SYSTEM_DISCONNECT.equals(notification.getType())) {
+      String source = (String) notifSource;
+      //This notification does not have ObjectName as a source. 
+      try {
+        ObjectName instance = ObjectName.getInstance(source);
+        unregisterNotificationListener(instance);
+      } catch (OperationsException e) {
+        logwriter.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_UNREGISTERING_NOTIFICATION_LISTENER_FOR_0, source.toString(), e);
+      } catch (NullPointerException e) {
+        logwriter.info(LocalizedMessage.create(LocalizedStrings.MemberInfoWithStatsMBean_EXCEPTION_WHILE_UNREGISTERING_NOTIFICATION_LISTENER_FOR_0, source.toString(), e);
+      }
+    } */
+    //NOTIF_ALERT is sent as is
+    
+    //TODO: Check if same notification instance can be reused by simply changing the sequence number 
+    notification = new Notification(notification.getType(), notifSource, 
+                                    notificationSequenceNumber.addAndGet(1L), 
+                                    notification.getTimeStamp(), 
+                                    notification.getMessage());
+    
+    sendNotification(notification);
+  }
+
+  /**
+   * Registers itself as a NotificationListener for Notifications sent from
+   * MBean with the ObjectName given as source.
+   * 
+   * @param source
+   *          source of notifications
+   * @throws InstanceNotFoundException
+   *           The MBean name provided does not match any of the registered
+   *           MBeans.
+   */
+  /*default*/void registerNotificationListener(ObjectName source) 
+    throws InstanceNotFoundException {
+    mBeanServer.addNotificationListener(source, this, null/*handback*/, source);
+  }
+
+  /**
+   * Unregisters itself as a NotificationListener for Notifications sent from
+   * MBean with the ObjectName given as source.
+   * 
+   * @param source source of notifications
+   * @throws InstanceNotFoundException
+   *           The MBean name provided does not match any of the registered
+   *           MBeans.
+   * @throws ListenerNotFoundException
+   *           The listener is not registered in the MBean.
+   */
+  /*default*/void unregisterNotificationListener(ObjectName source) 
+    throws InstanceNotFoundException, ListenerNotFoundException {
+    mBeanServer.removeNotificationListener(source, this);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/RMIRegistryService.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/RMIRegistryService.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/RMIRegistryService.java
new file mode 100644
index 0000000..318b38b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/RMIRegistryService.java
@@ -0,0 +1,231 @@
+/*
+ *  =========================================================================
+ *  Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *  ========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.UnknownHostException;
+import java.rmi.NoSuchObjectException;
+import java.rmi.NotBoundException;
+import java.rmi.RemoteException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.rmi.server.RMIServerSocketFactory;
+import java.rmi.server.UnicastRemoteObject;
+
+/**
+ * This MBean is an implementation of {@link RMIRegistryServiceMBean}.
+ * 
+ * @author abhishek
+ */
+public class RMIRegistryService implements RMIRegistryServiceMBean {
+  /* RMI Registry host */
+  private String host;
+  /* RMI Registry port */
+  private int port;
+  /* RMI Registry */
+  private Registry registry;
+  /* RMI Server Socket Factory */
+  private RMIServerSocketFactory ssf;
+  /* Whether RMI Registry is started & running */
+  private boolean isRunning;
+
+  /**
+   * Constructor to configure RMI Registry to start using default RMI Registry 
+   * port: {@link Registry#REGISTRY_PORT}
+   */
+  public RMIRegistryService() {
+    this(Registry.REGISTRY_PORT);
+  }
+
+  /**
+   * Constructor to configure RMI Registry to start using given RMI Registry
+   * port.
+   * 
+   * @param port
+   *          to run RMI Registry on
+   */
+  public RMIRegistryService(int port) {
+    setPort(port);
+  }
+
+  /**
+   * Constructor to configure RMI Registry to start using given RMI Registry
+   * port & host bind address.
+   * 
+   * @param host
+   *          to bind RMI Registry to
+   * @param port
+   *          to run RMI Registry on
+   * 
+   * @throws UnknownHostException
+   *           if IP Address can not be resolved for the given host string while
+   *           creating the RMIServerSocketFactory
+   */
+  public RMIRegistryService(String host, int port) throws UnknownHostException {
+    setPort(port);
+    setHost(host);
+    if (host != null && !host.trim().equals("")) {
+      ssf = new RMIServerSocketFactoryImpl(host);
+    }
+  }
+  
+  /**
+   * Returns the host on which rmiregistry listens for incoming connections
+   *
+   * @return the host on which rmiregistry listens for incoming connections
+   */
+  public String getHost() {
+    return host;
+  }
+
+  /**
+   * Sets the host on which rmiregistry listens for incoming connections
+   * 
+   * @param host
+   *          the host on which rmiregistry listens for incoming connections
+   */
+  protected void setHost(String host) {
+    if (isRunning()) { 
+      throw new IllegalStateException("RMIRegistryService is running, cannot change the host");
+    }
+    this.host = host;
+  }
+  
+  /**
+   * Returns the port on which rmiregistry listens for incoming connections
+   * 
+   * @return the port on which rmiregistry listens for incoming connections
+   */
+  public int getPort() {
+    return port;
+  }
+
+  /**
+   * Sets the port on which rmiregistry listens for incoming connections
+   * 
+   * @param port
+   *          the port on which rmiregistry listens for incoming connections
+   */
+  protected void setPort(int port) {
+    if (isRunning()) { 
+      throw new IllegalStateException("RMIRegistryService is running, cannot change the port");
+    }
+    this.port = port;
+  }
+
+  /**
+   * Starts this MBean: rmiregistry can now accept incoming calls
+   * 
+   * @see #stop
+   * @see #isRunning
+   */
+  public synchronized void start() throws RemoteException {
+    if (!isRunning()) {
+      if (ssf != null) {
+        registry = LocateRegistry.createRegistry(port, 
+                                                 null, //RMIClientSocketFactory 
+                                                 ssf); //RMIServerSocketFactory
+      } else {
+        registry = LocateRegistry.createRegistry(port);
+      }
+      
+      isRunning = true;
+    }
+  }
+
+  /**
+   * Returns whether this MBean has been started and not yet stopped.
+   * 
+   * @return whether this MBean has been started and not yet stopped.
+   * @see #start
+   */
+  public synchronized boolean isRunning() {
+    return isRunning;
+  }
+
+  /**
+   * Stops this MBean: rmiregistry cannot accept anymore incoming calls
+   * 
+   * @see #start
+   */
+  public synchronized void stop() throws NoSuchObjectException {
+    if (isRunning()) {
+      isRunning = !UnicastRemoteObject.unexportObject(registry, true);
+    }
+  }
+
+  /**
+   * Returns an array of the names bound in the rmiregistry
+   * 
+   * @return an array of the names bound in the rmiregistry
+   * @see java.rmi.registry.Registry#list()
+   */
+  public String[] list() throws RemoteException {
+    if (!isRunning()) {
+      throw new IllegalStateException("RMIRegistryService is not running");
+    }
+    return registry.list();
+  }
+
+  /**
+   * Removes the binding for the specified <code>name</code> in the rmiregistry
+   * 
+   * @see java.rmi.registry.Registry#unbind(String)
+   */
+  public void unbind(String name) throws RemoteException, NotBoundException {
+    if (!isRunning()) {
+      throw new IllegalStateException("RMIRegistryService is not running");
+    }
+    registry.unbind(name);
+  }
+}
+
+/**
+ * Custom implementation of the {@link RMIServerSocketFactory}
+ * 
+ * @author abhishek
+ */
+class RMIServerSocketFactoryImpl implements RMIServerSocketFactory {
+  /* IP address to use for creating ServerSocket */
+  private InetAddress bindAddress;
+
+  /**
+   * Constructs a RMIServerSocketFactory. The given rmiBindAddress is used to
+   * bind the ServerSockets created from this factory.
+   * 
+   * @param rmiBindAddress
+   *          String representation of the address to bind the ServerSockets to
+   * 
+   * @throws UnknownHostException
+   *           if IP Address can not be resolved for the given host string
+   */
+  /*default */RMIServerSocketFactoryImpl(String rmiBindAddress) 
+    throws UnknownHostException {
+    this.bindAddress = InetAddress.getByName(rmiBindAddress);
+  }
+
+  /**
+   * Create a server socket on the specified port (port 0 indicates an anonymous
+   * port).
+   * 
+   * @param port
+   *          the port number
+   * @return the server socket on the specified port
+   * @exception IOException
+   *              if an I/O error occurs during server socket creation
+   */
+  public ServerSocket createServerSocket(int port) throws IOException {
+    return new ServerSocket(port, 
+                            0/*backlog - for '0' internally uses the default*/, 
+                            bindAddress);
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/RMIRegistryServiceMBean.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/RMIRegistryServiceMBean.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/RMIRegistryServiceMBean.java
new file mode 100644
index 0000000..4f4c5dc
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/RMIRegistryServiceMBean.java
@@ -0,0 +1,77 @@
+/*
+ *  =========================================================================
+ *  Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *  ========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import java.rmi.NoSuchObjectException;
+import java.rmi.NotBoundException;
+import java.rmi.RemoteException;
+
+/**
+ * This interface is similar to {@link mx4j.tools.naming.NamingServiceMBean}.
+ * Features that differ are:
+ * 1. This MBean interface additionally provides a way to specify the host that 
+ * the RMI Registry should get bound to.
+ * 2. Port property can not be changed once set.
+ * 
+ * @author abhishek
+ */
+public interface RMIRegistryServiceMBean {
+
+  /**
+   * Returns the host on which rmiregistry listens for incoming connections
+   *
+   * @return the host on which rmiregistry listens for incoming connections
+   */
+  public String getHost();
+
+  /**
+   * Returns the port on which rmiregistry listens for incoming connections
+   * 
+   * @return the port on which rmiregistry listens for incoming connections
+   */
+  public int getPort();
+
+  /**
+   * Returns whether this MBean has been started and not yet stopped.
+   * 
+   * @return whether this MBean has been started and not yet stopped.
+   * @see #start
+   */
+  public boolean isRunning();
+
+  /**
+   * Starts this MBean: rmiregistry can now accept incoming calls
+   * 
+   * @see #stop
+   * @see #isRunning
+   */
+  public void start() throws RemoteException;
+
+  /**
+   * Stops this MBean: rmiregistry cannot accept anymore incoming calls
+   * 
+   * @see #start
+   */
+  public void stop() throws NoSuchObjectException;
+
+  /**
+   * Returns an array of the names bound in the rmiregistry
+   * 
+   * @return an array of the names bound in the rmiregistry
+   * @see java.rmi.registry.Registry#list()
+   */
+  public String[] list() throws RemoteException;
+
+  /**
+   * Removes the binding for the specified <code>name</code> in the rmiregistry
+   * 
+   * @see java.rmi.registry.Registry#unbind(String)
+   */
+  public void unbind(String name) throws RemoteException, NotBoundException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/RefreshNotificationType.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/RefreshNotificationType.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/RefreshNotificationType.java
new file mode 100755
index 0000000..283cb3c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/RefreshNotificationType.java
@@ -0,0 +1,124 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+/**
+ * Type-safe definition for refresh notifications.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ */
+public class RefreshNotificationType implements java.io.Serializable {
+  private static final long serialVersionUID = 4376763592395613794L;
+    
+  /** Notify StatisticResource to refresh statistics */
+  public static final RefreshNotificationType STATISTIC_RESOURCE_STATISTICS = 
+      new RefreshNotificationType(
+          "GemFire.Timer.StatisticResource.statistics.refresh", 
+          "refresh");
+
+  /** Notify SystemMember to refresh config */
+  public static final RefreshNotificationType SYSTEM_MEMBER_CONFIG = 
+      new RefreshNotificationType(
+          "GemFire.Timer.SystemMember.config.refresh", 
+          "refresh");
+
+  /** Notification type for the javax.management.Notification */
+  private final transient String type;
+  
+  /** Notification msg for the javax.management.Notification */
+  private final transient String msg;
+  
+  // The 4 declarations below are necessary for serialization
+  /** int used as ordinal to represent this Scope */
+  public final int ordinal = nextOrdinal++;
+
+  private static int nextOrdinal = 0;
+  
+  private static final RefreshNotificationType[] VALUES =
+    { STATISTIC_RESOURCE_STATISTICS, SYSTEM_MEMBER_CONFIG };
+
+  private Object readResolve() throws java.io.ObjectStreamException {
+    return VALUES[ordinal];  // Canonicalize
+  }
+  
+  /** Creates a new instance of RefreshNotificationType. */
+  private RefreshNotificationType(String type, String msg) {
+    this.type = type;
+    this.msg = msg;
+  }
+    
+  /** Return the RefreshNotificationType represented by specified ordinal */
+  public static RefreshNotificationType fromOrdinal(int ordinal) {
+    return VALUES[ordinal];
+  }
+
+	public String getType() {
+		return this.type;
+	}
+
+	public String getMessage() {
+		return this.msg;
+	}
+  
+  /** 
+   * Returns a string representation for this notification type.
+   *
+   * @return the type string for this Notification
+   */
+  @Override
+  public String toString() {
+      return this.type;
+  }
+
+	/**
+	 * Indicates whether some other object is "equal to" this one.
+	 *
+	 * @param  other  the reference object with which to compare.
+	 * @return true if this object is the same as the obj argument;
+	 *         false otherwise.
+	 */
+  @Override
+	public boolean equals(Object other) {
+		if (other == this) return true;
+		if (other == null) return false;
+		if (!(other instanceof RefreshNotificationType)) return  false;
+		final RefreshNotificationType that = (RefreshNotificationType) other;
+
+		if (this.type != that.type &&
+	  		!(this.type != null &&
+	  		this.type.equals(that.type))) return false;
+		if (this.msg != that.msg &&
+	  		!(this.msg != null &&
+	  		this.msg.equals(that.msg))) return false;
+
+		return true;
+	}
+  
+	/**
+	 * Returns a hash code for the object. This method is supported for the
+	 * benefit of hashtables such as those provided by java.util.Hashtable.
+	 *
+	 * @return the integer 0 if description is null; otherwise a unique integer.
+	 */
+  @Override
+	public int hashCode() {
+		int result = 17;
+		final int mult = 37;
+
+		result = mult * result + 
+			(this.type == null ? 0 : this.type.hashCode());
+		result = mult * result + 
+			(this.msg == null ? 0 : this.msg.hashCode());
+
+		return result;
+	}
+  
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/StatAlertNotification.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/StatAlertNotification.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/StatAlertNotification.java
new file mode 100644
index 0000000..f47614f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/StatAlertNotification.java
@@ -0,0 +1,153 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.Serializable;
+import java.io.IOException;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.admin.StatAlert;
+import com.gemstone.gemfire.internal.admin.StatAlertDefinition;
+
+/**
+ * Notification to be sent to clients (e.g GFMon2.0 ). It incorporates
+ * 
+ * @see StatAlert raised and also Gemfire member id which raised the alert
+ * 
+ * @author abhishek
+ * 
+ * @since 5.7
+ */
+public class StatAlertNotification extends StatAlert implements Serializable, DataSerializable, DataSerializableFixedID {
+  private static final long serialVersionUID = -1634729103430107871L;
+  private String memberId;
+
+  public StatAlertNotification() {
+  }
+
+  public StatAlertNotification(StatAlert statAlert, String memberId) {
+    this.setDefinitionId(statAlert.getDefinitionId());
+    this.setValues(statAlert.getValues());
+    this.setTime(statAlert.getTime());
+    this.memberId = memberId;
+  }
+
+  public int getDSFID() {
+    return DataSerializableFixedID.STAT_ALERT_NOTIFICATION;
+  }
+
+  /**
+   * @return the memberId
+   */
+  public String getMemberId() {
+    return memberId;
+  }
+
+  /**
+   * 
+   * @param id
+   *                of gemfire member which raised the alert
+   */
+  public void setMemberId(String id) {
+    memberId = id;
+  }
+
+  /**
+   * @return String representation of this object
+   */
+  @Override
+  public String toString() {
+    StringBuffer buf = new StringBuffer();
+    buf.append("[");
+    for (int i = 0; i < getValues().length; i++) {
+      buf.append(getValues()[i] + ", ");
+    }
+    buf.append("]");
+    return Integer.valueOf(getDefinitionId()) + ":" + buf.toString();
+  }
+
+  /**
+   * The notification is something like this
+   * "For Member ID: <ID>
+   * [
+   *  <StatName> = <Value>
+   *  .. 
+   * ]"
+   * @param defn
+   *                {@link StatAlertDefinition}
+   * @return String representation of this object based on
+   *         {@link StatAlertDefinition}
+   */
+  public String toString(StatAlertDefinition defn) {
+    StringBuffer buf = new StringBuffer();
+    buf.append("For Member ID: ");
+    buf.append(this.memberId);
+    buf.append("\n");
+    buf.append("[ ");
+    for (int i = 0; i < getValues().length; i++) {
+      buf.append(defn.getStatisticInfo()[i].toString() + "=" + getValues()[i]
+          + "\n");
+    }
+    buf.append("]");
+    return getTime().toString() + ":" + buf.toString();
+  }
+
+  @Override
+  public boolean equals(Object object) {
+    if (object != null && !(object instanceof StatAlertNotification)) {
+      return false;
+    }
+
+    StatAlertNotification other = (StatAlertNotification)object;
+
+    int defId = getDefinitionId();
+
+    if (defId != -1 && defId == other.getDefinitionId() && memberId != null
+        && memberId.equals(other.getMemberId())) {
+      return true;
+    }
+
+    return false;
+  }
+
+  @Override
+  public int hashCode() {
+    return memberId.hashCode();
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    // Do not modify StatAlert to allow 57 cacheservers to function with 57+ agent
+    // However, update of a new StatAlertDefn on 57 server from 57+ agent not covered with this
+    DataSerializer.writePrimitiveInt(this.getDefinitionId(), out);
+    DataSerializer.writeDate(this.getTime(), out);
+    DataSerializer.writeObjectArray(this.getValues(), out);
+
+    DataSerializer.writeString(this.memberId, out);
+  }
+
+  public void fromData(DataInput in)
+    throws IOException, ClassNotFoundException {
+    // Do not modify StatAlert to allow 57 cacheservers to function with 57+ agent
+    // However, update of a new StatAlertDefn on 57 server from 57+ agent not covered with this
+    this.setDefinitionId(DataSerializer.readPrimitiveInt(in));
+    this.setTime(DataSerializer.readDate(in));
+    this.setValues((Number[])DataSerializer.readObjectArray(in));
+
+    this.memberId = DataSerializer.readString(in);
+  }
+
+  @Override
+  public Version[] getSerializationVersions() {
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/StatAlertsAggregator.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/StatAlertsAggregator.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/StatAlertsAggregator.java
new file mode 100644
index 0000000..1fc5423
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/StatAlertsAggregator.java
@@ -0,0 +1,116 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import com.gemstone.gemfire.internal.admin.GemFireVM;
+import com.gemstone.gemfire.internal.admin.StatAlert;
+import com.gemstone.gemfire.internal.admin.StatAlertDefinition;
+
+/**
+ * This interface represents an Aggregator entity and resides in JMXAgent.
+ * Responsibilities are as follows:
+ * <ol>
+ * <li> set AlertsManager in the newly joined members
+ * <li> create/update/remove alert
+ * <li> manage refresh interval
+ * <li> process notification from members
+ * <li> Aggregate stats & make available for clients thro' JMXAgent
+ * </ol>
+ * 
+ * @author abhishek
+ */
+public interface StatAlertsAggregator {
+
+  /**
+   * This method can be used to get an alert definition.
+   * 
+   * @param alertDefinition
+   *                StatAlertDefinition to retrieve
+   * @return StatAlertDefinition
+   */
+  public StatAlertDefinition getAlertDefinition(
+      StatAlertDefinition alertDefinition);
+
+  /**
+   * This method can be used to retrieve all available stat alert definitions.
+   * 
+   * @return An array of all available StatAlertDefinition objects
+   */
+  public StatAlertDefinition[] getAllStatAlertDefinitions();
+
+  /**
+   * This method can be used to update alert definition for the Stat mentioned.
+   * This method should update the collection maintained at the aggregator and
+   * should notify members for the newly added alert definitions.
+   * <p>
+   * A new alert definition will be created if matching one not found.
+   * 
+   * @param alertDefinition
+   *                alertDefinition to be updated
+   */
+  public void updateAlertDefinition(StatAlertDefinition alertDefinition);
+
+  /**
+   * This method can be used to remove alert definition for the Stat mentioned.
+   * <p>
+   * This method should update the collection maintained at the aggregator and
+   * should notify members for the newly added alert definitions.
+   * 
+   * @param defId
+   *                id of the alert definition to be removed
+   */
+  public void removeAlertDefinition(Integer defId);
+
+  /**
+   * Convenience method to check whether an alert definition is created.
+   * 
+   * @param alert
+   *                alert definition to check whether already created
+   * @return true if the alert definition is already created, false otherwise
+   */
+  public boolean isAlertDefinitionCreated(StatAlertDefinition alert);
+
+  /**
+   * This method can be used to set the AlertManager for the newly joined member
+   * VM.
+   * 
+   * @param memberVM
+   *                Member VM to set AlertsManager for
+   */
+  public void setAlertsManager(GemFireVM memberVM);
+
+  /**
+   * Returns the refresh interval for the Stats in seconds.
+   * 
+   * @return refresh interval for the Stats(in seconds)
+   */
+  public int getRefreshIntervalForStatAlerts();
+
+  /**
+   * This method is used to set the refresh interval for the Stats Alerts in
+   * seconds
+   * 
+   * @param refreshInterval
+   *                refresh interval for the Stats(in seconds)
+   */
+  public void setRefreshIntervalForStatAlerts(int refreshInterval);
+
+  /**
+   * This method can be used to process the notifications sent by the member(s).
+   * Actual aggregation of stats can occur here. The array contains alert
+   * objects with alert def. ID & value. AlertHelper class can be used to
+   * retrieve the corresponding alert definition.
+   * 
+   * @param alerts
+   *                array of Alert class(contains alert def. ID & value)
+   * @param remoteVM
+   */
+  public void processNotifications(StatAlert[] alerts, GemFireVM remoteVM);
+
+  public void processSystemwideNotifications();
+}


[07/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ProxyRegion.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ProxyRegion.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ProxyRegion.java
new file mode 100755
index 0000000..72bb1d5
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ProxyRegion.java
@@ -0,0 +1,689 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.locks.Lock;
+
+import com.gemstone.gemfire.cache.AttributesMutator;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.RegionService;
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.CacheLoaderException;
+import com.gemstone.gemfire.cache.CacheStatistics;
+import com.gemstone.gemfire.cache.CacheWriterException;
+import com.gemstone.gemfire.cache.EntryExistsException;
+import com.gemstone.gemfire.cache.EntryNotFoundException;
+import com.gemstone.gemfire.cache.InterestResultPolicy;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionAttributes;
+import com.gemstone.gemfire.cache.RegionExistsException;
+import com.gemstone.gemfire.cache.StatisticsDisabledException;
+import com.gemstone.gemfire.cache.TimeoutException;
+import com.gemstone.gemfire.cache.query.FunctionDomainException;
+import com.gemstone.gemfire.cache.query.NameResolutionException;
+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.snapshot.RegionSnapshotService;
+import com.gemstone.gemfire.internal.cache.snapshot.RegionSnapshotServiceImpl;
+
+/**
+ * A wrapper class over an actual Region instance. This is used when the
+ * multiuser-authentication attribute is set to true.
+ * 
+ * @see ProxyCache
+ * @since 6.5
+ */
+public class ProxyRegion implements Region {
+  
+  private final ProxyCache proxyCache;
+  private final Region realRegion;
+  
+  public ProxyRegion(ProxyCache proxyCache, Region realRegion) {
+    this.proxyCache = proxyCache;
+    this.realRegion = realRegion;
+  }
+
+  public void becomeLockGrantor() {
+    throw new UnsupportedOperationException();
+  }
+
+  public void clear() {
+    try {
+      preOp();
+      this.realRegion.clear();
+    } finally {
+      postOp();
+    }
+  }
+
+  public void close() {
+    try {
+      preOp();
+      this.realRegion.close();
+    } finally {
+      postOp();
+    }
+  }
+
+  public boolean containsKey(Object key) {
+    try {
+      preOp();
+      return this.realRegion.containsKey(key);
+    } finally {
+      postOp();
+    }
+  }
+
+  public boolean containsKeyOnServer(Object key) {
+    try {
+      preOp();
+      return this.realRegion.containsKeyOnServer(key);
+    } finally {
+      postOp();
+    }
+  }
+
+  public boolean containsValue(Object value) {
+    try {
+      preOp();
+      return this.realRegion.containsValue(value);
+    } finally {
+      postOp();
+    }
+  }
+
+  public boolean containsValueForKey(Object key) {
+    try {
+      preOp();
+      return this.realRegion.containsValueForKey(key);
+    } finally {
+      postOp();
+    }
+  }
+
+  public void create(Object key, Object value) throws TimeoutException,
+      EntryExistsException, CacheWriterException {
+    try {
+      preOp();
+      this.realRegion.create(key, value);
+    } finally {
+      postOp();
+    }
+  }
+
+  public void create(Object key, Object value, Object callbackArgument)
+      throws TimeoutException, EntryExistsException, CacheWriterException {
+    try {
+      preOp();
+      this.realRegion.create(key, value, callbackArgument);
+    } finally {
+      postOp();
+    }
+  }
+
+  public Region createSubregion(String subregionName,
+      RegionAttributes regionAttributes) throws RegionExistsException,
+      TimeoutException {
+    throw new UnsupportedOperationException();
+  }
+
+  public Object destroy(Object key) throws TimeoutException,
+      EntryNotFoundException, CacheWriterException {
+    try {
+      preOp();
+      return this.realRegion.destroy(key);
+    } finally {
+      postOp();
+    }
+  }
+
+  public Object destroy(Object key, Object callbackArgument)
+      throws TimeoutException, EntryNotFoundException, CacheWriterException {
+    try {
+      preOp();
+      return this.realRegion.destroy(key, callbackArgument);
+    } finally {
+      postOp();
+    }
+  }
+
+  public void destroyRegion() throws CacheWriterException, TimeoutException {
+    try {
+      preOp();
+      this.realRegion.destroyRegion();
+    } finally {
+      postOp();
+    }
+  }
+
+  public void destroyRegion(Object callbackArgument)
+      throws CacheWriterException, TimeoutException {
+    try {
+      preOp();
+      this.realRegion.destroyRegion(callbackArgument);
+    } finally {
+      postOp();
+    }
+  }
+
+  public Set entries(boolean recursive) {
+    try {
+      preOp();
+      return this.realRegion.entries(recursive);
+    } finally {
+      postOp();
+    }
+  }
+
+  public Set entrySet(boolean recursive) {
+    try {
+      preOp();
+      return this.realRegion.entrySet(recursive);
+    } finally {
+      postOp();
+    }
+  }
+
+  public Set entrySet() {
+    try {
+      preOp();
+      return this.realRegion.entrySet();
+    } finally {
+      postOp();
+    }
+  }
+
+  public boolean existsValue(String queryPredicate)
+      throws FunctionDomainException, TypeMismatchException,
+      NameResolutionException, QueryInvocationTargetException {
+    try {
+      preOp();
+      return this.realRegion.existsValue(queryPredicate);
+    } finally {
+      postOp();
+    }
+  }
+
+  public void forceRolling() {
+    throw new UnsupportedOperationException();
+  }
+
+  public Object get(Object key) throws CacheLoaderException, TimeoutException {
+    try {
+      preOp();
+      return this.realRegion.get(key);
+    } finally {
+      postOp();
+    }
+  }
+
+  public Object get(Object key, Object callbackArgument)
+      throws TimeoutException, CacheLoaderException {
+    try {
+      preOp();
+      return this.realRegion.get(key, callbackArgument);
+    } finally {
+      postOp();
+    }
+  }
+
+  public Map getAll(Collection keys) {
+    return getAll(keys, null);
+  }
+
+  public Map getAll(Collection keys, Object callback) {
+    try {
+      preOp();
+      return this.realRegion.getAll(keys, callback);
+    } finally {
+      postOp();
+    }
+  }
+
+  public RegionAttributes getAttributes() {
+    return realRegion.getAttributes();
+  }
+
+  public AttributesMutator getAttributesMutator() {
+    throw new UnsupportedOperationException();
+  }
+
+  public Cache getCache() {
+    throw new UnsupportedOperationException();
+  }
+
+  public RegionService getRegionService() {
+    return this.proxyCache;
+  }
+  
+  public ProxyCache getAuthenticatedCache() {
+    return this.proxyCache;    
+  }
+
+  public Lock getDistributedLock(Object key) throws IllegalStateException {
+    throw new UnsupportedOperationException();
+  }
+
+  public Entry getEntry(Object key) {
+    try {
+      preOp();
+      return this.realRegion.getEntry(key);
+    } finally {
+      postOp();
+    }
+  }
+
+  public String getFullPath() {
+    return this.realRegion.getFullPath();
+  }
+
+  public List getInterestList() {
+    throw new UnsupportedOperationException();
+  }
+
+  public List getInterestListRegex() {
+    throw new UnsupportedOperationException();
+  }
+
+  public String getName() {
+    return this.realRegion.getName();
+  }
+
+  public Region getParentRegion() {
+    return this.realRegion.getParentRegion();
+  }
+
+  public Lock getRegionDistributedLock() throws IllegalStateException {
+    throw new UnsupportedOperationException();
+  }
+
+  public CacheStatistics getStatistics() throws StatisticsDisabledException {
+    return this.realRegion.getStatistics();
+  }
+
+  public Region getSubregion(String path) {
+    Region region = this.realRegion.getSubregion(path);
+    return region != null ? new ProxyRegion(this.proxyCache, region) : null;
+  }
+
+  public Object getUserAttribute() {
+    return this.realRegion.getUserAttribute();
+  }
+
+  public void invalidate(Object key) throws TimeoutException,
+      EntryNotFoundException {
+    try {
+      preOp();
+      this.realRegion.invalidate(key);
+    } finally {
+      postOp();
+    }
+  }
+
+  public void invalidate(Object key, Object callbackArgument)
+      throws TimeoutException, EntryNotFoundException {
+    try {
+      preOp();
+      this.realRegion.invalidate(key, callbackArgument);
+    } finally {
+      postOp();
+    }
+  }
+
+  public void invalidateRegion() throws TimeoutException {
+    try {
+      preOp();
+      this.realRegion.invalidateRegion();
+    } finally {
+      postOp();
+    }
+  }
+
+  public void invalidateRegion(Object callbackArgument) throws TimeoutException {
+    try {
+      preOp();
+      this.realRegion.invalidateRegion(callbackArgument);
+    } finally {
+      postOp();
+    }
+  }
+
+  public boolean isDestroyed() {
+    return this.realRegion.isDestroyed();
+  }
+
+  public boolean isEmpty() {
+    return this.realRegion.isEmpty();
+  }
+
+  public Set keySet() {
+    return this.realRegion.keySet();
+  }
+
+  public Set keySetOnServer() {
+    try {
+      preOp();
+      return this.realRegion.keySetOnServer();
+    } finally {
+      postOp();
+    }
+  }
+
+  public Set keys() {
+    try {
+      preOp();
+      return this.realRegion.keys();
+    } finally {
+      postOp();
+    }
+  }
+
+  public void loadSnapshot(InputStream inputStream) throws IOException,
+      ClassNotFoundException, CacheWriterException, TimeoutException {
+    throw new UnsupportedOperationException();
+  }
+
+  public void localClear() {
+    throw new UnsupportedOperationException(
+        "Local operations are not supported when multiuser-authentication is true.");
+  }
+
+  public void localDestroy(Object key) throws EntryNotFoundException {
+    throw new UnsupportedOperationException(
+        "Local operations are not supported when multiuser-authentication is true.");
+  }
+
+  public void localDestroy(Object key, Object callbackArgument)
+      throws EntryNotFoundException {
+    throw new UnsupportedOperationException(
+        "Local operations are not supported when multiuser-authentication is true.");
+  }
+
+  public void localDestroyRegion() {
+    throw new UnsupportedOperationException(
+        "Local operations are not supported when multiuser-authentication is true.");
+  }
+
+  public void localDestroyRegion(Object callbackArgument) {
+    throw new UnsupportedOperationException(
+        "Local operations are not supported when multiuser-authentication is true.");
+  }
+
+  public void localInvalidate(Object key) throws EntryNotFoundException {
+    throw new UnsupportedOperationException(
+        "Local operations are not supported when multiuser-authentication is true.");
+  }
+
+  public void localInvalidate(Object key, Object callbackArgument)
+      throws EntryNotFoundException {
+    throw new UnsupportedOperationException(
+        "Local operations are not supported when multiuser-authentication is true.");
+  }
+
+  public void localInvalidateRegion() {
+    throw new UnsupportedOperationException(
+        "Local operations are not supported when multiuser-authentication is true.");
+  }
+
+  public void localInvalidateRegion(Object callbackArgument) {
+    throw new UnsupportedOperationException(
+        "Local operations are not supported when multiuser-authentication is true.");
+  }
+
+  public Object put(Object key, Object value) throws TimeoutException,
+      CacheWriterException {
+    try {
+      preOp();
+      return this.realRegion.put(key, value);
+    } finally {
+      postOp();
+    }
+  }
+
+  public Object put(Object key, Object value, Object callbackArgument)
+      throws TimeoutException, CacheWriterException {
+    try {
+      preOp();
+      return this.realRegion.put(key, value, callbackArgument);
+    } finally {
+      postOp();
+    }
+  }
+
+  public void putAll(Map map) {
+    putAll(map, null);
+  }
+  
+  @Override
+  public void putAll(Map map, Object callbackArg) {
+    try {
+      preOp();
+      this.realRegion.putAll(map, callbackArg);
+    } finally {
+      postOp();
+    }
+  }
+
+  public SelectResults query(String queryPredicate)
+      throws FunctionDomainException, TypeMismatchException,
+      NameResolutionException, QueryInvocationTargetException {
+    try {
+      preOp();
+      return this.realRegion.query(queryPredicate);
+    } finally {
+      postOp();
+    }
+  }
+
+  public void registerInterest(Object key) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void registerInterest(Object key, InterestResultPolicy policy) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void registerInterest(Object key, boolean isDurable) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void registerInterest(Object key, boolean isDurable,
+      boolean receiveValues) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void registerInterest(Object key, InterestResultPolicy policy,
+      boolean isDurable, boolean receiveValues) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void registerInterest(Object key, InterestResultPolicy policy,
+      boolean isDurable) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void registerInterestRegex(String regex) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void registerInterestRegex(String regex, InterestResultPolicy policy) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void registerInterestRegex(String regex, boolean isDurable) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void registerInterestRegex(String regex, boolean isDurable,
+      boolean receiveValues) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void registerInterestRegex(String regex, InterestResultPolicy policy,
+      boolean isDurable) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void registerInterestRegex(String regex, InterestResultPolicy policy,
+      boolean isDurable, boolean receiveValues) {
+    throw new UnsupportedOperationException();
+  }
+
+  public Object remove(Object key) {
+    try {
+      preOp();
+      return this.realRegion.remove(key);
+    } finally {
+      postOp();
+    }
+  }
+
+  public void saveSnapshot(OutputStream outputStream) throws IOException {
+    throw new UnsupportedOperationException();
+  }
+
+  public Object selectValue(String queryPredicate)
+      throws FunctionDomainException, TypeMismatchException,
+      NameResolutionException, QueryInvocationTargetException {
+    try {
+      preOp();
+      return this.realRegion.selectValue(queryPredicate);
+    } finally {
+      postOp();
+    }
+  }
+
+  public void setUserAttribute(Object value) {
+    throw new UnsupportedOperationException();
+  }
+
+  public int size() {
+    try {
+      preOp();
+      return this.realRegion.size();
+    } finally {
+      postOp();
+    }
+  }
+
+  public Set subregions(boolean recursive) {
+    return this.realRegion.subregions(recursive);
+  }
+
+  public void unregisterInterest(Object key) {
+    throw new UnsupportedOperationException();
+  }
+
+  public void unregisterInterestRegex(String regex) {
+    throw new UnsupportedOperationException();
+  }
+
+  public Collection values() {
+    try {
+      preOp();
+      return this.realRegion.values();
+    } finally {
+      postOp();
+    }
+  }
+
+  public void writeToDisk() {
+    throw new UnsupportedOperationException();
+  }
+
+  private void preOp() {
+    if (this.proxyCache.isClosed()) {
+      throw new CacheClosedException("Cache is closed for this user.");
+    }
+    UserAttributes.userAttributes.set(this.proxyCache.getUserAttributes());
+  }
+
+  private void postOp() {
+    this.proxyCache.setUserAttributes(UserAttributes.userAttributes.get());
+    UserAttributes.userAttributes.set(null);
+  }
+
+  public Region getRealRegion() {
+    return realRegion;
+  }
+
+  /* (non-Javadoc)
+   * @see java.util.concurrent.ConcurrentMap#putIfAbsent(java.lang.Object, java.lang.Object)
+   */
+  public Object putIfAbsent(Object key, Object value) {
+    try {
+      preOp();
+      return this.realRegion.putIfAbsent(key, value);
+    } finally {
+      postOp();
+}
+  }
+
+  /* (non-Javadoc)
+   * @see java.util.concurrent.ConcurrentMap#remove(java.lang.Object, java.lang.Object)
+   */
+  public boolean remove(Object key, Object value) {
+    try {
+      preOp();
+      return this.realRegion.remove(key, value);
+    } finally {
+      postOp();
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see java.util.concurrent.ConcurrentMap#replace(java.lang.Object, java.lang.Object)
+   */
+  public Object replace(Object key, Object value) {
+    try {
+      preOp();
+      return this.realRegion.replace(key, value);
+    } finally {
+      postOp();
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see java.util.concurrent.ConcurrentMap#replace(java.lang.Object, java.lang.Object, java.lang.Object)
+   */
+  public boolean replace(Object key, Object oldValue, Object newValue) {
+    try {
+      preOp();
+      return this.realRegion.replace(key, oldValue, newValue);
+    } finally {
+      postOp();
+    }
+  }
+  
+  public RegionSnapshotService<?, ?> getSnapshotService() {
+    return new RegionSnapshotServiceImpl(this);
+  }
+
+  @Override
+  public void removeAll(Collection keys) {
+    removeAll(keys, null);
+  }
+
+  @Override
+  public void removeAll(Collection keys, Object aCallbackArgument) {
+    try {
+      preOp();
+      this.realRegion.removeAll(keys, aCallbackArgument);
+    } finally {
+      postOp();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PutAllOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PutAllOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PutAllOp.java
new file mode 100644
index 0000000..a112bda
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PutAllOp.java
@@ -0,0 +1,417 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.ArrayList;
+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.Set;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.DataPolicy;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.client.ServerOperationException;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.cache.CachedDeserializable;
+import com.gemstone.gemfire.internal.cache.EventID;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.cache.PutAllPartialResultException;
+import com.gemstone.gemfire.internal.cache.PutAllPartialResultException.PutAllPartialResult;
+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.VersionedObjectList;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * Does a region putAll on a server
+ * @author darrel
+ * @since 5.7
+ */
+public class PutAllOp {
+  
+  private static final Logger logger = LogService.getLogger();
+  
+  public static final int FLAG_EMPTY = 0x01;
+  public static final int FLAG_CONCURRENCY_CHECKS = 0x02;
+
+  /**
+   * Does a region put 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 putAll on
+   * @param map the Map of keys and values to put
+   * @param eventId the event id for this putAll
+   * @param skipCallbacks true if no callbacks will be invoked
+   */
+  public static VersionedObjectList execute(ExecutablePool pool,
+                             Region region,
+                             Map map,
+                             EventID eventId,
+                             boolean skipCallbacks,
+                             boolean isRetry, Object callbackArg)
+  {
+    PutAllOpImpl op = new PutAllOpImpl(region, map,
+        eventId, ((PoolImpl)pool).getPRSingleHopEnabled(), skipCallbacks, callbackArg);
+    op.initMessagePart();
+    if(isRetry) {
+      op.getMessage().setIsRetry();
+    }
+    return (VersionedObjectList)pool.execute(op);
+  }
+  
+  /**
+   * Does a region put 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 putAll on
+   * @param map the Map of keys and values to put
+   * @param eventId the event id for this putAll
+   */
+  public static VersionedObjectList execute(ExecutablePool pool,
+                             Region region,
+                             Map map,
+                             EventID eventId, 
+                             boolean skipCallbacks,
+                             int retryAttempts, Object callbackArg)
+  {
+    ClientMetadataService cms = ((LocalRegion)region).getCache()
+        .getClientMetadataService();
+
+    Map<ServerLocation, HashSet> serverToFilterMap = cms.getServerToFilterMap(
+        map.keySet(), region, true);
+
+    if (serverToFilterMap == null || serverToFilterMap.isEmpty()) {
+      AbstractOp op = new PutAllOpImpl(region, map,
+          eventId, ((PoolImpl)pool).getPRSingleHopEnabled(), skipCallbacks, callbackArg);
+      op.initMessagePart();
+      return (VersionedObjectList)pool.execute(op);
+    }
+
+    List callableTasks = constructAndGetPutAllTasks(region, map,
+        eventId, skipCallbacks, serverToFilterMap, (PoolImpl)pool, callbackArg);
+
+    final boolean isDebugEnabled = logger.isDebugEnabled();
+    if (isDebugEnabled) {
+      logger.debug("PutAllOp#execute : Number of putAll tasks is : {}", callableTasks.size());
+    }
+    HashMap<ServerLocation, RuntimeException> failedServers = new HashMap<ServerLocation,RuntimeException>();
+    PutAllPartialResult result = new PutAllPartialResult(map.size());
+    try {
+      Map<ServerLocation, Object> results = SingleHopClientExecutor
+          .submitBulkOp(callableTasks, cms, (LocalRegion)region, failedServers);
+      for (Map.Entry<ServerLocation, Object> entry: results.entrySet()) {
+        Object value = entry.getValue();
+        if (value instanceof PutAllPartialResultException) {
+          PutAllPartialResultException pap = (PutAllPartialResultException)value;
+          if (isDebugEnabled) {
+            logger.debug("PutAll SingleHop encountered PutAllPartialResultException exception: {}, failedServers are {}", pap, failedServers.keySet());
+          }
+          result.consolidate(pap.getResult());
+        } else {
+          if (value != null) {
+            VersionedObjectList list = (VersionedObjectList)value;
+            result.addKeysAndVersions(list);
+          }
+        }
+      }
+    } catch (RuntimeException ex) {
+      if (isDebugEnabled) {
+        logger.debug("single-hop putAll encountered unexpected exception: ", ex);
+      }
+      throw ex;
+    }
+
+    if (!failedServers.isEmpty()) {
+      if (retryAttempts == 0) {
+        throw failedServers.values().iterator().next();
+      }
+
+      // if the partial result set doesn't already have keys (for tracking version tags)
+      // then we need to gather up the keys that we know have succeeded so far and
+      // add them to the partial result set
+      if (result.getSucceededKeysAndVersions().size() == 0) {
+        // if there're failed servers, we need to save the succeed keys in submitPutAll
+        // if retry succeeded, everything is ok, otherwise, the saved "succeeded
+        // keys" should be consolidated into PutAllPartialResultException
+      // succeedKeySet is used to send back to client in PartialResult case
+      // so it's not a must to use LinkedHashSet
+      Set succeedKeySet = new LinkedHashSet();
+      Set<ServerLocation> serverSet = serverToFilterMap.keySet();
+      for (ServerLocation server : serverSet) {
+        if (!failedServers.containsKey(server)) {
+          succeedKeySet.addAll(serverToFilterMap.get(server));
+        }
+      }
+  
+      // save succeedKeys, but if retries all succeeded, discard the PutAllPartialResult
+        result.addKeys(succeedKeySet);
+      }
+      
+      // send maps for the failed servers one by one instead of merging 
+      // them into one big map. The reason is, we have to keep the same event
+      // ids for each sub map. There is a unit test in PutAllCSDUnitTest for
+      // the otherwise case.
+      boolean oneSubMapRetryFailed = false;
+      Set<ServerLocation> failedServerSet = failedServers.keySet();
+      for (ServerLocation failedServer : failedServerSet) {
+        //        Throwable failedServers.values().iterator().next();
+        RuntimeException savedRTE = failedServers.get(failedServer);
+        if (savedRTE instanceof PutAllPartialResultException) {
+          // will not retry for PutAllPartialResultException
+          // but it means at least one sub map ever failed 
+          oneSubMapRetryFailed = true;
+          continue;
+        }
+        Map newMap = new LinkedHashMap();
+        Set keySet = serverToFilterMap.get(failedServer);
+        for (Object key : keySet) {
+          newMap.put(key, map.get(key));
+        }
+
+        try {
+          VersionedObjectList v = PutAllOp.execute(pool, region, newMap, eventId, skipCallbacks, true, callbackArg);
+          if (v == null) {
+            result.addKeys(keySet);
+          } else {
+            result.addKeysAndVersions(v);
+          }
+        } catch (PutAllPartialResultException pre) {
+          oneSubMapRetryFailed = true;
+          if (logger.isDebugEnabled()) {
+            logger.debug("Retry failed with PutAllPartialResultException: {} Before retry: {}", pre, result.getKeyListString());
+          }
+          result.consolidate(pre.getResult());
+        } catch (Exception rte) {
+          oneSubMapRetryFailed = true;
+            Object firstKey = newMap.keySet().iterator().next();
+            result.saveFailedKey(firstKey, rte);
+          }
+      } // for failedServer
+
+      // If all retries succeeded, the PRE in first tries can be ignored
+      if (oneSubMapRetryFailed && result.hasFailure()) {
+        PutAllPartialResultException pre = new PutAllPartialResultException(result);
+        throw pre;
+      }
+    } // failedServers!=null
+
+    return result.getSucceededKeysAndVersions();
+  }
+  
+  private PutAllOp() {
+    // no instances allowed
+  }
+  
+  
+  static List constructAndGetPutAllTasks(Region region, final Map map,
+      final EventID eventId, 
+      boolean skipCallbacks,
+      final Map<ServerLocation, HashSet> serverToFilterMap,
+      final PoolImpl pool, Object callbackArg) {
+    final List<SingleHopOperationCallable> tasks = new ArrayList<SingleHopOperationCallable>();
+    ArrayList<ServerLocation> servers = new ArrayList<ServerLocation>(
+        serverToFilterMap.keySet());
+
+    if (logger.isDebugEnabled()) {
+      logger.debug("Constructing tasks for the servers {}", servers);
+    }
+    for (ServerLocation server : servers) {
+      Set filterSet = serverToFilterMap.get(server);
+      Map newKeysValuesMap = new LinkedHashMap();
+      // iterator 1: for single hop, both iterator filterSet and newKeysValuesMap
+      for (Object key : filterSet) {
+        newKeysValuesMap.put(key, map.get(key));
+      }
+      AbstractOp putAllOp = new PutAllOpImpl(region,
+          newKeysValuesMap, eventId, true, skipCallbacks, callbackArg);
+
+      SingleHopOperationCallable task = new SingleHopOperationCallable(
+          new ServerLocation(server.getHostName(), server.getPort()), pool,
+          putAllOp,UserAttributes.userAttributes.get());
+      tasks.add(task);
+    }
+    return tasks;
+  }
+
+  private static class PutAllOpImpl extends AbstractOp {
+    
+    private boolean prSingleHopEnabled = false;
+    
+    private LocalRegion region = null;
+    
+    private Map map = null;
+    private final Object callbackArg;
+    private ArrayList keys = null;
+    
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public PutAllOpImpl(Region region, Map map,
+        EventID eventId, boolean prSingleHopEnabled, boolean skipCallbacks, Object callbackArg) {
+      super(callbackArg != null ? MessageType.PUT_ALL_WITH_CALLBACK : MessageType.PUTALL, (callbackArg != null ? 6 : 5) + (map.size() * 2));
+      this.prSingleHopEnabled = prSingleHopEnabled;
+      this.region = (LocalRegion)region;
+      getMessage().addStringPart(region.getFullPath());
+      getMessage().addBytesPart(eventId.calcBytes());
+      getMessage().addIntPart(skipCallbacks ? 1 : 0);
+      this.map = map;
+      this.callbackArg = callbackArg;
+    }
+    
+    @Override
+    protected void initMessagePart() {
+      int size = map.size();
+      int flags = 0;
+      if (region.getDataPolicy() == DataPolicy.EMPTY) {
+        flags |= FLAG_EMPTY;
+      }
+      if (region.getConcurrencyChecksEnabled()) {
+        flags |= FLAG_CONCURRENCY_CHECKS;
+      }
+      getMessage().addIntPart(flags);
+      getMessage().addIntPart(size);
+      if (this.callbackArg != null) {
+        getMessage().addObjPart(this.callbackArg);
+      }
+      this.keys = new ArrayList(size);
+      Iterator iterator = map.entrySet().iterator();
+      while (iterator.hasNext()) {
+        Map.Entry mapEntry = (Map.Entry)iterator.next();
+        Object key = mapEntry.getKey();
+        this.keys.add(key);
+        getMessage().addStringOrObjPart(key);
+        Object value = mapEntry.getValue();
+        if (value instanceof CachedDeserializable) {
+          {
+            Object cdValue = ((CachedDeserializable)value).getValue();
+            if (cdValue instanceof byte[]) {
+              getMessage().addRawPart((byte[])cdValue, true);
+            } else {
+              getMessage().addObjPart(cdValue);
+            }
+          }
+        } else {
+          getMessage().addObjPart(value);
+        }
+      }      
+    }
+    @Override  
+    protected Message createResponseMessage() {
+      return new ChunkedMessage(2, Version.CURRENT);
+    }
+    
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      throw new UnsupportedOperationException();
+    }
+    
+    @Override
+    protected Object processResponse(final Message msg, final Connection con) throws Exception {
+      final VersionedObjectList result = new VersionedObjectList();
+      final Exception[] exceptionRef = new Exception[1];
+      try {
+        processChunkedResponse((ChunkedMessage)msg,
+                             "putAll",
+                             new ChunkHandler() {
+                               public void handle(ChunkedMessage cm) throws Exception {
+                                 int numParts = msg.getNumberOfParts();
+                                 final boolean isDebugEnabled = logger.isDebugEnabled();
+                                 if (isDebugEnabled) {
+                                   logger.debug("putAllOp.processChunkedResponse processing message with {} parts", numParts);
+                                 }
+                                 for (int partNo=0; partNo < numParts; partNo++) {
+                                   Part part = cm.getPart(partNo);
+                                   try {
+                                     Object o = part.getObject();
+                                     if (isDebugEnabled) {
+                                       logger.debug("part({}) contained {}", partNo, o);
+                                     }
+                                     if (o == null) {
+                                       // no response is an okay response
+                                     } else if (o instanceof byte[]) {
+                                       if (prSingleHopEnabled) {
+                                         byte[] bytesReceived = part.getSerializedForm();
+                                         if (/*bytesReceived.length==1 &&*/ bytesReceived[0] != ClientMetadataService.INITIAL_VERSION) { // nw hop
+                                           if (region != null) {
+                                             ClientMetadataService cms;
+                                             try {
+                                               cms = region.getCache().getClientMetadataService();
+                                               cms.scheduleGetPRMetaData(region, false,bytesReceived[1]);
+                                             }
+                                             catch (CacheClosedException e) {
+                                             }
+                                           }
+                                         }
+                                       }
+                                     } else if (o instanceof Throwable) {
+                                       String s = "While performing a remote putAll";
+                                       exceptionRef[0] = new ServerOperationException(s, (Throwable)o);
+                                     } else {
+                                       VersionedObjectList chunk = (VersionedObjectList)o;
+                                       chunk.replaceNullIDs(con.getEndpoint().getMemberId());
+                                       result.addAll(chunk);
+                                     }
+                                   } catch(Exception e) {
+                                     exceptionRef[0] = new ServerOperationException("Unable to deserialize value" , e);
+                                   }
+                                 }
+                               }
+                             });
+      } catch (ServerOperationException e) {
+        if (e.getCause() instanceof PutAllPartialResultException) {
+          PutAllPartialResultException cause = (PutAllPartialResultException)e.getCause(); 
+          cause.getSucceededKeysAndVersions().replaceNullIDs(con.getEndpoint().getMemberId());
+          throw cause;
+        } else {
+          throw e;
+        }
+      }
+      if (exceptionRef[0] != null) {
+        throw exceptionRef[0];
+      } else {
+        // v7.0.1: fill in the keys
+        if (result.hasVersions() && result.getKeys().isEmpty()) {
+          if (logger.isTraceEnabled()) {
+            logger.trace("setting keys of response to {}", this.keys);
+          }
+          result.setKeys(this.keys);
+        }
+      }
+      return result;
+    }
+    
+    @Override
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.PUT_DATA_ERROR;
+    }
+
+    @Override
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startPutAll();
+    }
+    @Override
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endPutAllSend(start, hasFailed());
+    }
+    @Override
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endPutAll(start, hasTimedOut(), hasFailed());
+    }
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PutOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PutOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PutOp.java
new file mode 100644
index 0000000..56181e2
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/PutOp.java
@@ -0,0 +1,540 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.InternalGemFireError;
+import com.gemstone.gemfire.cache.Operation;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.client.AllConnectionsInUseException;
+import com.gemstone.gemfire.cache.client.ServerConnectivityException;
+import com.gemstone.gemfire.cache.client.ServerOperationException;
+import com.gemstone.gemfire.cache.util.BridgeWriterException;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.internal.cache.CachedDeserializable;
+import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+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.versions.VersionTag;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+
+import org.apache.logging.log4j.Logger;
+
+/**
+ * Does a region put (or create) on a server
+ * @author darrel
+ * @since 5.7
+ */
+public class PutOp {
+  
+  private static final Logger logger = LogService.getLogger();
+  
+  /**
+   * Does a region put 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 region to do the put on
+   * @param key the entry key to do the put on
+   * @param value the entry value to put
+   * @param event the event for this put
+   * @param requireOldValue
+   * @param expectedOldValue
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   */
+  public static Object execute(ExecutablePool pool,
+                             LocalRegion region,
+                             Object key,
+                             Object value,
+                             byte[] deltaBytes,
+                             EntryEventImpl event,
+                             Operation operation,
+                             boolean requireOldValue, Object expectedOldValue,
+                             Object callbackArg,
+                             boolean prSingleHopEnabled)
+  {
+    AbstractOp op = new PutOpImpl(region, key, value, deltaBytes, event,
+        operation, requireOldValue,
+        expectedOldValue, callbackArg,
+        false/*donot send full obj; send delta*/, prSingleHopEnabled);
+
+    if (prSingleHopEnabled) {
+      ClientMetadataService cms = region.getCache().getClientMetadataService();
+      ServerLocation server = cms.getBucketServerLocation(region,
+          Operation.UPDATE, key, value, callbackArg);
+      if (server != null) {
+        try {
+          PoolImpl poolImpl = (PoolImpl)pool;
+          boolean onlyUseExistingCnx = ((poolImpl.getMaxConnections() != -1 && poolImpl
+              .getConnectionCount() >= poolImpl.getMaxConnections()) ? true
+              : false);
+          return pool.executeOn(new ServerLocation(server.getHostName(), server
+              .getPort()), op, true, onlyUseExistingCnx);
+        }
+        catch (AllConnectionsInUseException e) {
+        }
+        catch (ServerConnectivityException e) {
+          if (e instanceof ServerOperationException) {
+            throw e; // fixed 44656
+          }
+          cms.removeBucketServerLocation(server);
+        }
+        catch (BridgeWriterException e) {
+          if (e.getCause() instanceof ServerConnectivityException)
+            cms.removeBucketServerLocation(server);
+        }
+      }
+    }
+    return pool.execute(op);
+  }
+  
+  public static Object execute(ExecutablePool pool, String regionName,
+      Object key, Object value, byte[] deltaBytes, EntryEventImpl event, Operation operation,
+      boolean requireOldValue, Object expectedOldValue,
+      Object callbackArg, boolean prSingleHopEnabled, boolean isMetaRegionPutOp) {
+    AbstractOp op = new PutOpImpl(regionName, key, value, deltaBytes, event,
+        operation, requireOldValue,
+        expectedOldValue, callbackArg,
+        false/*donot send full obj; send delta*/,  prSingleHopEnabled);
+    ((PutOpImpl)op).setMetaRegionPutOp(isMetaRegionPutOp);
+    return pool.execute(op);
+  }
+
+  
+  /**
+   * This is a unit test method.
+   * It does a region put on a server using the given connection from the given pool
+   * to communicate with the server. Do not call this method if the value is 
+   * Delta instance.
+   * @param con the connection to use 
+   * @param pool the pool to use to communicate with the server.
+   * @param regionName the name of the region to do the put on
+   * @param key the entry key to do the put on
+   * @param value the entry value to put
+   * @param event the event for this put
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   */
+  public static void execute(Connection con,
+                             ExecutablePool pool,
+                             String regionName,
+                             Object key,
+                             Object value,
+                             EntryEventImpl event,
+                             Object callbackArg,
+                             boolean prSingleHopEnabled)
+  {
+    AbstractOp op = new PutOpImpl(regionName, key, value, null,
+        event, Operation.CREATE, false,
+        null, callbackArg, false /*donot send full Obj; send delta*/, prSingleHopEnabled);
+    pool.executeOn(con, op);
+  }
+
+  public static final byte HAS_OLD_VALUE_FLAG = 0x01;
+  public static final byte OLD_VALUE_IS_OBJECT_FLAG = 0x02;
+  public static final byte HAS_VERSION_TAG = 0x04;
+                                                               
+  private PutOp() {
+    // no instances allowed
+  }
+  
+  private static class PutOpImpl extends AbstractOp {
+
+    private Object key;
+
+    
+    private LocalRegion region;
+    
+    /**
+     * the operation will have either a region or a regionName.  Names seem
+     * to be used by unit tests to exercise operations without creating a
+     * real region 
+     */
+    private String regionName;
+
+    private Object value;
+    
+    private boolean deltaSent = false;
+
+    private EntryEventImpl event;
+    
+    private Object callbackArg;
+
+    private boolean isMetaRegionPutOp;
+
+    private boolean prSingleHopEnabled;
+    
+    private boolean requireOldValue;
+
+    private Object expectedOldValue;
+    
+    public PutOpImpl(String regionName , Object key, Object value, byte[] deltaBytes, 
+        EntryEventImpl event,
+        Operation op, boolean requireOldValue,
+        Object expectedOldValue, Object callbackArg,
+        boolean sendFullObj, boolean prSingleHopEnabled) {
+        super(MessageType.PUT, 7 + (callbackArg != null? 1:0) + (expectedOldValue != null? 1:0));
+        final boolean isDebugEnabled = logger.isDebugEnabled();
+        if (isDebugEnabled) {
+          logger.debug("PutOpImpl constructing(1) message for {}; operation={}", event.getEventId(), op);
+        }
+        this.key = key;
+        this.callbackArg = callbackArg;
+        this.event = event;
+        this.value = value;
+        this.regionName = regionName;
+        this.prSingleHopEnabled = prSingleHopEnabled;
+        this.requireOldValue = requireOldValue;
+        this.expectedOldValue = expectedOldValue;
+        getMessage().addStringPart(regionName);
+        getMessage().addObjPart(op);
+        int flags = 0;
+        if (requireOldValue) flags |= 0x01;
+        if (expectedOldValue != null) flags |= 0x02;
+        getMessage().addIntPart(flags);
+        if (expectedOldValue != null) {
+          getMessage().addObjPart(expectedOldValue);
+        }
+        getMessage().addStringOrObjPart(key);
+        // Add message part for sending either delta or full value
+        if (!sendFullObj && deltaBytes != null && op == Operation.UPDATE) {
+          getMessage().addObjPart(Boolean.TRUE);
+          getMessage().addBytesPart(deltaBytes);
+          this.deltaSent = true;
+          if (isDebugEnabled) {
+            logger.debug("PutOp: Sending delta for key {}", this.key);
+          }
+        }
+        else if (value instanceof CachedDeserializable) {
+          {
+            getMessage().addObjPart(Boolean.FALSE);
+            Object cdValue = ((CachedDeserializable)value).getValue();
+            if (cdValue instanceof byte[]) {
+              getMessage().addRawPart((byte[])cdValue, true);
+            }
+            else {
+              getMessage().addObjPart(cdValue);
+            }
+          }
+        }
+        else {
+          getMessage().addObjPart(Boolean.FALSE);
+          getMessage().addObjPart(value);
+        }
+        getMessage().addBytesPart(event.getEventId().calcBytes());
+        if (callbackArg != null) {
+          getMessage().addObjPart(callbackArg);
+        }
+    }
+
+    public PutOpImpl(Region region, Object key, Object value, byte[] deltaBytes,
+        EntryEventImpl event, 
+        Operation op, boolean requireOldValue, 
+        Object expectedOldValue, Object callbackArg,
+        boolean sendFullObj, boolean prSingleHopEnabled) {
+      super(MessageType.PUT, 7 + (callbackArg != null? 1:0) + (expectedOldValue != null? 1:0));
+      this.key = key;
+      this.callbackArg = callbackArg;
+      this.event = event;
+      this.value = value;
+      this.region = (LocalRegion)region;
+      this.regionName = region.getFullPath();
+      this.prSingleHopEnabled = prSingleHopEnabled;
+      final boolean isDebugEnabled = logger.isDebugEnabled();
+      if (isDebugEnabled) {
+        logger.debug("PutOpImpl constructing message with operation={}", op);
+      }
+      getMessage().addStringPart(region.getFullPath());
+      getMessage().addObjPart(op);
+      int flags = 0;
+      if (requireOldValue) flags |= 0x01;
+      if (expectedOldValue != null) flags |= 0x02;
+      getMessage().addIntPart(flags);
+      if (expectedOldValue != null) {
+        getMessage().addObjPart(expectedOldValue);
+      }
+      getMessage().addStringOrObjPart(key);
+      // Add message part for sending either delta or full value
+      if (!sendFullObj && deltaBytes != null && op == Operation.UPDATE) {
+        getMessage().addObjPart(Boolean.TRUE);
+        getMessage().addBytesPart(deltaBytes);
+        this.deltaSent = true;
+        if (isDebugEnabled) {
+          logger.debug("PutOp: Sending delta for key {}", this.key);
+        }
+      }
+      else if (value instanceof CachedDeserializable) {
+        {
+          getMessage().addObjPart(Boolean.FALSE);
+          Object cdValue = ((CachedDeserializable)value).getValue();
+          if (cdValue instanceof byte[]) {
+            getMessage().addRawPart((byte[])cdValue, true);
+          }
+          else {
+            getMessage().addObjPart(cdValue);
+          }
+        }
+      }
+      else {
+        getMessage().addObjPart(Boolean.FALSE);
+        getMessage().addObjPart(value);
+      }
+      getMessage().addBytesPart(event.getEventId().calcBytes());
+      if (callbackArg != null) {
+        getMessage().addObjPart(callbackArg);
+      }
+    }
+
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      throw new UnsupportedOperationException("processResponse should not be invoked in PutOp.  Use processResponse(Message, Connection)");
+//      processAck(msg, "put");
+//      if (prSingleHopEnabled) {
+//        byte version = 0;
+//        Part part = msg.getPart(0);
+//        byte[] bytesReceived = part.getSerializedForm();
+//        if (bytesReceived[0] != ClientMetadataService.INITIAL_VERSION
+//            && bytesReceived.length == ClientMetadataService.SIZE_BYTES_ARRAY_RECEIVED) { // nw hop
+//          if (this.region != null) {
+//            ClientMetadataService cms;
+//            try {
+//              cms = region.getCache().getClientMetadataService();
+//              version = cms.getMetaDataVersion(region, Operation.UPDATE,
+//                  key, value, callbackArg);
+//            }
+//            catch (CacheClosedException e) {
+//              return null;
+//            }
+//            if (bytesReceived[0] != version) {
+//              cms.scheduleGetPRMetaData(region, false,bytesReceived[1]);
+//            }
+//          }
+//        }
+//      }
+//      return null;
+    }
+
+    /*
+     * Process a response that contains an ack.
+     * 
+     * @param msg
+     *                the message containing the response
+     * @param con
+     *                Connection on which this op is executing
+     * @throws Exception
+     *                 if response could not be processed or we received a
+     *                 response with a server exception.
+     * @since 6.1
+     */
+    @Override
+    protected Object processResponse(Message msg, Connection con)
+        throws Exception {
+      processAck(msg, "put", con);
+      byte version = 0 ;
+      if (prSingleHopEnabled) {
+        Part part = msg.getPart(0);
+        byte[] bytesReceived = part.getSerializedForm();
+        if (bytesReceived[0] != ClientMetadataService.INITIAL_VERSION
+            && bytesReceived.length == ClientMetadataService.SIZE_BYTES_ARRAY_RECEIVED) {
+          if (this.region != null) {
+            ClientMetadataService cms;
+              cms = region.getCache().getClientMetadataService();
+              version = cms.getMetaDataVersion(region, Operation.UPDATE,
+                  key, value, callbackArg);
+            if (bytesReceived[0] != version) {
+              cms.scheduleGetPRMetaData(region, false, bytesReceived[1]);
+            }
+          }
+        }
+      }
+      if (msg.getMessageType() == MessageType.REPLY
+          &&  msg.getNumberOfParts() > 1) {
+        int flags = msg.getPart(1).getInt();
+        int partIdx = 2;
+        Object oldValue = null;
+        if ((flags & HAS_OLD_VALUE_FLAG) != 0) {
+          oldValue = msg.getPart(partIdx++).getObject();
+          if ((flags & OLD_VALUE_IS_OBJECT_FLAG) != 0 && oldValue instanceof byte[]) {
+            ByteArrayInputStream in = new ByteArrayInputStream((byte[])oldValue);
+            DataInputStream din = new DataInputStream(in);
+            oldValue = DataSerializer.readObject(din);
+          }
+//          if (lw.fineEnabled()) {
+//            lw.fine("read old value from server response: " + oldValue);
+//          }
+        }
+        // if the server has versioning we will attach it to the client's event
+        // here so it can be applied to the cache
+        if ((flags & HAS_VERSION_TAG) != 0) {
+          VersionTag tag = (VersionTag)msg.getPart(partIdx++).getObject();
+          // we use the client's ID since we apparently don't track the server's ID in connections
+          tag.replaceNullIDs((InternalDistributedMember) con.getEndpoint().getMemberId());
+          this.event.setVersionTag(tag);
+        }
+        return oldValue;
+      }
+      return null;
+    }
+    
+    /**
+     * Process a response that contains an ack.
+     * 
+     * @param msg
+     *                the message containing the response
+     * @param opName
+     *                text describing this op
+     * @param con
+     *                Connection on which this op is executing
+     * @throws Exception
+     *                 if response could not be processed or we received a
+     *                 response with a server exception.
+     * @since 6.1
+     */
+    private final void processAck(Message msg, String opName, Connection con)
+        throws Exception
+    {
+      final int msgType = msg.getMessageType();
+      // Update delta stats
+      if (this.deltaSent && this.region != null) {
+        this.region.getCachePerfStats().incDeltasSent();
+      }
+      if (msgType == MessageType.REPLY) {
+        return;
+      }
+      else {
+        Part part = msg.getPart(0);
+        if (msgType == MessageType.PUT_DELTA_ERROR) {
+          if (logger.isDebugEnabled()) {
+            logger.debug("PutOp: Sending full value as delta failed on server...");
+          }
+          AbstractOp op = new PutOpImpl(this.regionName, this.key, this.value,
+                null, this.event, Operation.CREATE, this.requireOldValue,
+                this.expectedOldValue, this.callbackArg,
+                true /* send full obj */, this.prSingleHopEnabled);
+          
+          op.attempt(con);
+          if (this.region != null) {
+            this.region.getCachePerfStats().incDeltaFullValuesSent();
+          }
+        }
+        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));
+        }
+      }
+    }
+
+    @Override
+    protected void sendMessage(Connection cnx) throws Exception {
+      if (!this.isMetaRegionPutOp) {
+        super.sendMessage(cnx);
+      } else {
+        getMessage().send(false);
+      }
+    }
+
+    @Override
+    protected void processSecureBytes(Connection cnx, Message message)
+        throws Exception {
+      if (!this.isMetaRegionPutOp) {
+        super.processSecureBytes(cnx, message);
+      }
+    }
+
+    @Override
+    protected boolean needsUserId() {
+      boolean ret = this.isMetaRegionPutOp ? false : super.needsUserId();
+      return ret;
+    }
+
+    @Override
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.PUT_DATA_ERROR;
+    }
+
+    @Override
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startPut();
+    }
+    @Override
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endPutSend(start, hasFailed());
+    }
+    @Override
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endPut(start, hasTimedOut(), hasFailed());
+    }
+    
+    @Override
+    public String toString() {
+      return "PutOp:"+key;
+    }
+    
+ /**
+   * 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
+   */
+    @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(msg, cnx);
+          }
+          finally {
+            msg.unsetComms();
+            processSecureBytes(cnx, msg);
+          }
+        }
+        else {
+          try {
+            msg.recv();
+          }
+          finally {
+            msg.unsetComms();
+            processSecureBytes(cnx, msg);
+          }
+          return processResponse(msg, cnx);
+        }
+      }
+      else {
+        return null;
+      }
+    }
+
+    void setMetaRegionPutOp(boolean bool) {
+      this.isMetaRegionPutOp = bool;
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueryOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueryOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueryOp.java
new file mode 100644
index 0000000..a729ba7
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueryOp.java
@@ -0,0 +1,194 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.Arrays;
+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.ChunkedMessage;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ObjectPartList;
+import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
+import com.gemstone.gemfire.cache.query.SelectResults;
+import com.gemstone.gemfire.cache.query.types.CollectionType;
+import com.gemstone.gemfire.cache.query.types.ObjectType;
+import com.gemstone.gemfire.cache.query.internal.QueryUtils;
+import com.gemstone.gemfire.cache.query.internal.StructImpl;
+import com.gemstone.gemfire.cache.query.internal.types.StructTypeImpl;
+import com.gemstone.gemfire.cache.query.internal.types.TypeUtils;
+import com.gemstone.gemfire.SerializationException;
+import com.gemstone.gemfire.cache.client.ServerOperationException;
+
+/**
+ * Does a region query on a server
+ * @author darrel
+ * @since 5.7
+ */
+public class QueryOp {
+  /**
+   * Does a region query 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 queryPredicate A query language boolean query predicate
+   * @return  A <code>SelectResults</code> containing the values
+   *            that match the <code>queryPredicate</code>.
+   */
+  public static SelectResults execute(ExecutablePool pool, String queryPredicate,
+                                      Object[] queryParams)
+  {
+    AbstractOp op = null;
+    
+    if (queryParams != null && queryParams.length > 0) {
+      op = new QueryOpImpl(queryPredicate, queryParams);
+    } else {
+      op = new QueryOpImpl(queryPredicate);      
+    }
+    return (SelectResults)pool.execute(op);
+  }
+                                                               
+  private QueryOp() {
+    // no instances allowed
+  }
+
+  /**
+   * Note: this class is extended by CreateCQWithIROpImpl.
+   */
+  protected static class QueryOpImpl extends AbstractOp {
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public QueryOpImpl(String queryPredicate) {
+      super(MessageType.QUERY, 1);
+      getMessage().addStringPart(queryPredicate);
+    }
+
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public QueryOpImpl(String queryPredicate, Object[] queryParams) {
+      super(MessageType.QUERY_WITH_PARAMETERS, 2 + queryParams.length);
+      getMessage().addStringPart(queryPredicate);
+      getMessage().addIntPart(queryParams.length);
+      for (Object param : queryParams){
+        getMessage().addObjPart(param);
+      }
+    }
+
+    /**
+     * This constructor is used by our subclass CreateCQWithIROpImpl
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    protected QueryOpImpl(int msgType, int numParts) {
+      super(msgType, numParts);
+    }
+    @Override  
+    protected Message createResponseMessage() {
+      return new ChunkedMessage(2, Version.CURRENT);
+    }
+    @Override  
+    protected Object processResponse(Message msg) throws Exception {
+      final SelectResults[] resultRef = new SelectResults[1];
+      final Exception[] exceptionRef = new Exception[1];
+      ChunkHandler ch = new ChunkHandler() {
+          public void handle(ChunkedMessage cm) throws Exception {
+            Part collectionTypePart = cm.getPart(0);
+            Object o = collectionTypePart.getObject();
+            if (o instanceof Throwable) {
+              String s = "While performing a remote " + getOpName();
+              exceptionRef[0] = new ServerOperationException(s, (Throwable)o);
+              return;
+            }
+            CollectionType collectionType = (CollectionType)o;
+            Part resultPart = cm.getPart(1);
+            Object queryResult = null;
+            try {
+              queryResult = resultPart.getObject();
+            } catch (Exception e) {
+              String s = "While deserializing " + getOpName() + " result";
+              exceptionRef[0] = new SerializationException(s, e);
+              return;
+            }
+            if (queryResult instanceof Throwable) {
+              String s = "While performing a remote " + getOpName();
+              exceptionRef[0] = new ServerOperationException(s, (Throwable)queryResult);
+              return;
+            } else if (queryResult instanceof Integer) {
+              // Create the appropriate SelectResults instance if necessary
+              if (resultRef[0] == null) {
+                resultRef[0] = QueryUtils.
+                               getEmptySelectResults(TypeUtils.OBJECT_TYPE,
+                                                     null);
+              }
+              resultRef[0].add(queryResult);
+            } else { // typical query result
+              // Create the appropriate SelectResults instance if necessary
+              if (resultRef[0] == null) {
+                resultRef[0] = QueryUtils.getEmptySelectResults(collectionType,
+                                                                null);
+              }
+              SelectResults selectResults = resultRef[0];
+              ObjectType objectType = collectionType.getElementType();
+              Object[] resultArray;
+             // for select * queries, the serialized object byte arrays are
+             // returned as part of ObjectPartList
+              boolean isObjectPartList = false;
+              if (queryResult instanceof ObjectPartList) {
+                isObjectPartList = true;
+                resultArray = ((ObjectPartList) queryResult).getObjects().toArray();
+              } else{ 
+                // Add the results to the SelectResults
+                resultArray = (Object[]) queryResult;
+              }
+              if (objectType.isStructType()) {
+                for (int i = 0; i < resultArray.length; i++) {
+                  if (isObjectPartList) {
+                    selectResults
+                        .add(new StructImpl((StructTypeImpl) objectType,
+                            ((ObjectPartList) resultArray[i]).getObjects()
+                                .toArray()));
+                  } else {
+                    selectResults.add(new StructImpl((StructTypeImpl) objectType,
+                        (Object[]) resultArray[i]));
+                  }
+                }
+              } else {
+                selectResults.addAll(Arrays.asList(resultArray));
+              }
+            }
+          }
+        };
+      processChunkedResponse((ChunkedMessage)msg, getOpName(), ch);
+      if (exceptionRef[0] != null) {
+        throw exceptionRef[0];
+      } else {
+        return resultRef[0];
+      }
+    }
+    protected String getOpName() {
+      return "query";
+    }
+    @Override  
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.QUERY_DATA_ERROR
+        || msgType == MessageType.CQDATAERROR_MSG_TYPE
+        || msgType == MessageType.CQ_EXCEPTION_TYPE;
+    }
+    @Override  
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startQuery();
+    }
+    @Override  
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endQuerySend(start, hasFailed());
+    }
+    @Override  
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endQuery(start, hasTimedOut(), hasFailed());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueConnectionImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueConnectionImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueConnectionImpl.java
new file mode 100644
index 0000000..7a4f2ff
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueConnectionImpl.java
@@ -0,0 +1,216 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.cache.client.internal.ServerBlackList.FailureTracker;
+import com.gemstone.gemfire.cache.client.internal.pooling.ConnectionDestroyedException;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ServerQueueStatus;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+
+/**
+ * A wrapper that holds a client to server connection and
+ * a server to client connection.
+ * 
+ *  The clientToServerConnection should not
+ *  be used outside of this class.
+ * @author dsmith
+ *
+ */
+public class QueueConnectionImpl implements Connection {
+  private static final Logger logger = LogService.getLogger();
+
+  private final AtomicReference/*<Connection>*/ clientToServerConn = new AtomicReference();
+  private final Endpoint endpoint;
+  private volatile ClientUpdater updater;
+  private boolean shouldDestroy;
+  private QueueManagerImpl manager;
+  private final AtomicBoolean sentClientReady = new AtomicBoolean();
+  private FailureTracker failureTracker;
+  
+  public QueueConnectionImpl(QueueManagerImpl manager, Connection clientToServer,
+      ClientUpdater updater, FailureTracker failureTracker) {
+    this.manager = manager;
+    this.clientToServerConn.set(clientToServer);
+    this.endpoint = clientToServer.getEndpoint();
+    this.updater = updater;
+    this.failureTracker = failureTracker;
+  }
+
+  public void close(boolean keepAlive) throws Exception {
+    throw new UnsupportedOperationException("Subscription connections should only be closed by subscription manager");
+  }
+  
+  public void emergencyClose() {
+    Connection conn = (Connection) clientToServerConn.getAndSet(null);
+    if(conn != null) {
+      conn.emergencyClose();
+    }
+  }
+  
+  public void internalClose(boolean keepAlive) throws Exception {
+    try {
+      getConnection().close(keepAlive);
+    } finally {
+      updater.close();
+    }
+  }
+
+  public void destroy() {
+    Connection conn = (Connection)this.clientToServerConn.get();
+    if (conn != null) {
+      manager.connectionCrashed(conn);
+    } // else someone else destroyed it
+  }
+  
+  public void internalDestroy() {
+    Connection currentConn = (Connection)this.clientToServerConn.get();
+    if(currentConn != null) {
+      if (!this.clientToServerConn.compareAndSet(currentConn, null)) {
+        // someone else did (or is doing) the internalDestroy so return
+        return;
+      }
+      try {
+        currentConn.destroy();
+      } catch(Exception e) {
+        if (logger.isDebugEnabled()) {
+          logger.debug("SubscriptionConnectionImpl - error destroying client to server connection", e);
+        }
+      }
+    } 
+
+    ClientUpdater currentUpdater = updater;
+    if(currentUpdater != null) {
+      try {
+        currentUpdater.close();
+      } catch(Exception e) {
+        if (logger.isDebugEnabled()) {
+          logger.debug("SubscriptionConnectionImpl - error destroying client updater", e);
+        }
+      }
+    }
+    updater = null;
+  }
+
+  /**
+   * test hook
+   */
+  public ClientUpdater getUpdater() {
+    return this.updater;
+  }
+  
+  public boolean isDestroyed() {
+    return clientToServerConn.get() == null;
+  }
+  
+  public boolean getShouldDestroy() {
+    return shouldDestroy;
+  }
+
+  public ByteBuffer getCommBuffer() {
+    return getConnection().getCommBuffer();
+  }
+
+  public Endpoint getEndpoint() {
+    return this.endpoint;
+  }
+
+  public ServerQueueStatus getQueueStatus() {
+    return getConnection().getQueueStatus();
+  }
+
+  public ServerLocation getServer() {
+    return getEndpoint().getLocation();
+  }
+
+  public Socket getSocket() {
+    return getConnection().getSocket();
+  }
+  
+  public OutputStream getOutputStream() {
+    return getConnection().getOutputStream();
+  }
+  
+  public InputStream getInputStream() {
+    return getConnection().getInputStream();
+  }
+
+  public ConnectionStats getStats() {
+    return getEndpoint().getStats();
+  }
+
+  public Object execute(Op op) throws Exception {
+    return getConnection().execute(op);
+  }
+  
+  public Connection getConnection() {
+    Connection result = (Connection)this.clientToServerConn.get();
+    if (result == null) {
+      throw new ConnectionDestroyedException();
+    }
+    return result;
+  }
+  
+  public FailureTracker getFailureTracker() {
+    return failureTracker;
+  }
+  
+  /**
+   * Indicate that we have, or are about to send
+   * the client create message on this connection.
+   * 
+   * @return true if we have not yet sent client ready.
+   */
+  public boolean sendClientReady() {
+    return sentClientReady.compareAndSet(false, true);
+  }
+  
+  @Override
+  public String toString() { 
+    Connection result = (Connection)this.clientToServerConn.get();
+    if(result != null) {
+      return result.toString();
+    } else {
+      return "SubscriptionConnectionImpl[" + getServer() + ":closed]";
+    }
+  }
+
+  public static void loadEmergencyClasses() {
+    ConnectionImpl.loadEmergencyClasses();
+  }
+  
+  public short getWanSiteVersion(){
+    throw new UnsupportedOperationException();
+  }
+  
+  public int getDistributedSystemId() {
+    throw new UnsupportedOperationException();
+  }
+  
+  public void setWanSiteVersion(short wanSiteVersion){
+    throw new UnsupportedOperationException();
+  }
+
+  public void setConnectionID(long id) {
+    ((Connection)this.clientToServerConn.get()).setConnectionID(id);
+  }
+
+  public long getConnectionID() {
+    return ((Connection)this.clientToServerConn.get()).getConnectionID();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueManager.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueManager.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueManager.java
new file mode 100644
index 0000000..062bee6
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueManager.java
@@ -0,0 +1,48 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.List;
+
+import java.util.concurrent.ScheduledExecutorService;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.internal.logging.InternalLogWriter;
+
+/**
+ * @author dsmith
+ * @since 5.7
+ * 
+ */
+public interface QueueManager {
+  
+  public QueueConnections getAllConnectionsNoWait();
+
+  public QueueConnections getAllConnections();
+
+  void start(ScheduledExecutorService background);
+
+  void close(boolean keepAlive);
+  
+  public static interface QueueConnections {
+    Connection getPrimary();
+    List/*<Connection>*/ getBackups();
+    QueueConnectionImpl getConnection(Endpoint endpoint);
+  }
+
+  public QueueState getState();
+
+  public InternalPool getPool();
+  
+  public InternalLogWriter getSecurityLogger();
+
+  public void readyForEvents(InternalDistributedSystem system);
+
+  public void emergencyClose();
+  
+  public void checkEndpoint(ClientUpdater qc, Endpoint endpoint);
+}


[38/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedSystemMemberImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedSystemMemberImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedSystemMemberImpl.java
new file mode 100644
index 0000000..839304b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedSystemMemberImpl.java
@@ -0,0 +1,262 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.ConfigurationParameter;
+import com.gemstone.gemfire.admin.ManagedEntityConfig;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.internal.admin.GemFireVM;
+
+/**
+ * A <code>SystemMember</code> that is also managed (or manageable) by
+ * the admin API.
+ *
+ * This class must be public so that its methods can be invoked
+ * reflectively (for MBean operations) on instances of its
+ * subclasses. 
+ *
+ * @author David Whitlock
+ * @since 4.0
+ */
+public abstract class ManagedSystemMemberImpl extends SystemMemberImpl
+  implements InternalManagedEntity {
+
+  /** Controller for starting and stopping local or remote managers */
+  protected ManagedEntityController controller;
+  
+  /** The state of this managed entity (see bug 32455) */
+  private int state = UNKNOWN;
+
+  /** A lock that is obtained while this entity's state changes */
+  private final Object stateChange = new Object();
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>ManagedSystemMemberImpl</code> that
+   * represents an existing member of an
+   * <code>AdminDistributedSystem</code>.
+   */
+  protected ManagedSystemMemberImpl(AdminDistributedSystemImpl system, 
+                                    GemFireVM vm) 
+    throws AdminException {
+
+    super(system, vm);
+    this.controller = system.getEntityController();
+  }
+
+  /**
+   * Creates a new <code>ManagedSystemMemberImpl</code> that
+   * represents a non-existing member with the given
+   * <code>ManagedEntityConfig</code> that has not yet been started.
+   */
+  protected ManagedSystemMemberImpl(AdminDistributedSystemImpl system,
+                                    ManagedEntityConfig config) 
+    throws AdminException {
+
+    super(system);
+    this.internalId = null;
+    this.id = getNewId();
+    this.host = config.getHost();
+    this.name = this.id;
+    this.controller = system.getEntityController();
+  }
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  public String getWorkingDirectory() {
+    return this.getEntityConfig().getWorkingDirectory();
+  }
+
+  public void setWorkingDirectory(String workingDirectory) {
+    this.getEntityConfig().setWorkingDirectory(workingDirectory);
+  }
+
+  public String getProductDirectory() {
+    return this.getEntityConfig().getProductDirectory();
+  }
+
+  public void setProductDirectory(String productDirectory) {
+    this.getEntityConfig().setProductDirectory(productDirectory);
+  }
+
+  @Override
+  public String getHost() {
+    return this.getEntityConfig().getHost();
+  }
+
+  public int setState(int state) {
+    if (this.stateChange == null) {
+      // The initial state is set in the constructor before
+      // stateChange is initialized.
+      int oldState = this.state;
+      this.state = state;
+      return oldState;
+      
+    } else {
+      synchronized (this.stateChange) {
+        int oldState = this.state;
+        this.state = state;
+
+        this.stateChange.notifyAll();
+        
+        return oldState;
+      }
+    }
+  }
+
+  /**
+   * Returns whether or not this managed system member needs to be
+   * stopped.  If this member is stopped or is stopping, then it does
+   * not need to be stopped.  Otherwise, it will atomically place this
+   * member in the {@link #STOPPING} state.  See bug 32455.
+   */
+  protected boolean needToStop() {
+    synchronized (this.stateChange) {
+      if (this.state == STOPPED || this.state == STOPPING) {
+        return false;
+
+      } else {
+        setState(STOPPING);
+        return true;
+      }
+    }
+  }
+
+  /**
+   * Returns whether or not this managed system member needs to be
+   * started.  If this member is started or is starting, then it
+   * does not need to be started.  Otherwise, it will atomically
+   * place this member in the {@link #STARTING} state.  See bug
+   * 32455.
+   */
+  protected boolean needToStart() {
+    synchronized (this.stateChange) {
+      if (this.state == RUNNING || this.state == STARTING) {
+        return false;
+
+      } else {
+        setState(STARTING);
+        return true;
+      }
+    }
+  }
+
+  /**
+   * Sets the state of this managed system member depending on whether
+   * or not <code>vm</code> is <code>null</code>.
+   */
+  @Override
+  void setGemFireVM(GemFireVM vm) throws AdminException {
+    super.setGemFireVM(vm);
+    if (vm != null) {
+      this.setState(RUNNING);
+
+    } else {
+      this.setState(STOPPED);
+    }
+  }
+
+  /**
+   * Waits until this system member's "state" is {@link #RUNNING}.
+   */
+  public boolean waitToStart(long timeout) 
+    throws InterruptedException {
+
+    if (Thread.interrupted()) throw new InterruptedException();
+    
+    long start = System.currentTimeMillis();
+    while (System.currentTimeMillis() - start < timeout) {
+      synchronized (this.stateChange) {
+        if (this.state == RUNNING) {
+          break;
+
+        } else {
+          this.stateChange.wait(System.currentTimeMillis() - start);
+        }
+      }
+    }
+
+    synchronized (this.stateChange) {
+      return this.state == RUNNING;
+    }
+  }
+
+  /**
+   * Waits until this system member's "state" is {@link #STOPPED}.
+   */
+  public boolean waitToStop(long timeout) 
+    throws InterruptedException {
+
+    if (Thread.interrupted()) throw new InterruptedException();
+    long start = System.currentTimeMillis();
+    while (System.currentTimeMillis() - start < timeout) {
+      synchronized (this.stateChange) {
+        if (this.state == STOPPED) {
+          break;
+
+        } else {
+          this.stateChange.wait(System.currentTimeMillis() - start);
+        }
+      }
+    }
+
+    synchronized (this.stateChange) {
+      return this.state == STOPPED;
+    }
+  }
+
+  /**
+   * Appends configuration information to a <code>StringBuffer</code>
+   * that contains a command line.  Handles certain configuration
+   * parameters specially.
+   */
+  protected void appendConfiguration(StringBuffer sb) {
+    ConfigurationParameter[] params = this.getConfiguration();
+    for (int i = 0; i < params.length; i++) {
+      ConfigurationParameter param = params[i];
+
+      if (!param.isModifiable()) {
+        continue;
+      }
+
+      String name = param.getName();
+      String value = param.getValueAsString();
+
+      if (value != null && !value.equals("")) {
+        if (name.equals(DistributionConfig.LOCATORS_NAME)) {
+          // Use the new locator syntax so that is plays nicely with
+          // rsh.  See bug 32306.
+          String locator = value;
+          int firstBracket = locator.indexOf('[');
+          int lastBracket = locator.indexOf(']');
+
+          if (firstBracket > -1 && lastBracket > -1) {
+            String host = locator.substring(0, firstBracket);
+            String port =
+              locator.substring(firstBracket + 1, lastBracket);
+            locator = host + ":" + port;
+          }
+
+          sb.append(" ");
+          sb.append(name);
+          sb.append("=");
+          sb.append(locator);
+
+        } else {
+          sb.append(" ");
+          sb.append(name);
+          sb.append("=");
+          sb.append(value);
+        }
+      }
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/MemberHealthConfigImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/MemberHealthConfigImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/MemberHealthConfigImpl.java
new file mode 100644
index 0000000..73c02d4
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/MemberHealthConfigImpl.java
@@ -0,0 +1,87 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.*;
+
+// @todo Make this class (and all of its subclasses) {@link java.io.Externalizable} or
+// {@link com.gemstone.gemfire.DataSerializable}. 
+/**
+ * The implementation of <code>MemberHealthConfig</code>
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ */
+public abstract class MemberHealthConfigImpl
+  implements MemberHealthConfig, java.io.Serializable {
+
+  private static final long serialVersionUID = 3966032573073580490L;
+  
+  /** The maximum process size (in megabytes) of a healthy member of
+   * the distributed system. */
+  private long maxVMProcessSize = DEFAULT_MAX_VM_PROCESS_SIZE;
+
+  /** The maximum number of enqueued incoming or outgoing
+   * messages that a healthy member of a distributed system can
+   * have. */
+  private long maxMessageQueueSize = DEFAULT_MAX_MESSAGE_QUEUE_SIZE;
+
+  /** The maximum number message replies that can timeout in a healthy
+   * member. */
+  private long maxReplyTimeouts = DEFAULT_MAX_REPLY_TIMEOUTS;
+
+  /** The maximum multicast retransmit / multicast message count ratio
+   */
+  private double maxRetransmissionRatio = DEFAULT_MAX_RETRANSMISSION_RATIO;
+
+
+  ///////////////////////  Constructors  ///////////////////////
+
+  /**
+   * Creates a new <code>MemberHealthConfigImpl</code> with the
+   * default configuration.
+   */
+  MemberHealthConfigImpl() {
+
+  }
+
+  /////////////////////  Instance Methods  //////////////////////
+
+  public long getMaxVMProcessSize() {
+    return this.maxVMProcessSize;
+  }
+
+  public void setMaxVMProcessSize(long size) {
+    this.maxVMProcessSize = size;
+  }
+
+  public long getMaxMessageQueueSize() {
+    return this.maxMessageQueueSize;
+  }
+
+  public void setMaxMessageQueueSize(long maxMessageQueueSize) {
+    this.maxMessageQueueSize = maxMessageQueueSize;
+  }
+
+  public long getMaxReplyTimeouts() {
+    return this.maxReplyTimeouts;
+  }
+
+  public void setMaxReplyTimeouts(long maxReplyTimeouts) {
+    this.maxReplyTimeouts = maxReplyTimeouts;
+  }
+
+  public double getMaxRetransmissionRatio() {
+    return this.maxRetransmissionRatio;
+  }
+
+  public void setMaxRetransmissionRatio(double ratio) {
+    this.maxRetransmissionRatio = ratio;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/MemberHealthEvaluator.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/MemberHealthEvaluator.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/MemberHealthEvaluator.java
new file mode 100644
index 0000000..3358db0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/MemberHealthEvaluator.java
@@ -0,0 +1,233 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.admin.*;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.distributed.internal.*;
+import com.gemstone.gemfire.internal.*;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.cache.CachePerfStats;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+
+import java.util.*;
+
+/**
+ * Contains the logic for evaluating the health of a GemFire
+ * distributed system member according to the thresholds provided in a
+ * {@link MemberHealthConfig}.  
+ *
+ * @see VMStats
+ * @see ProcessStats
+ * @see DMStats
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ */
+/**
+ * @author rdubey
+ *
+ */
+class MemberHealthEvaluator extends AbstractHealthEvaluator {
+
+  /** The config from which we get the evaluation criteria */
+  private MemberHealthConfig config;
+
+  /** The description of the member being evaluated */
+  private String description;
+
+//  /** Statistics about this VM (may be null) */
+//  private VMStatsContract vmStats;
+
+  /** Statistics about this process (may be null) */
+  private ProcessStats processStats;
+
+  /** Statistics about the distribution manager */
+  private DMStats dmStats;
+
+  /** The previous value of the reply timeouts stat */
+  private long prevReplyTimeouts;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>MemberHealthEvaluator</code>
+   */
+  MemberHealthEvaluator(GemFireHealthConfig config,
+                        DM dm) {
+    super(config, dm);
+
+    this.config = config;
+    InternalDistributedSystem system = dm.getSystem();
+
+    GemFireStatSampler sampler = system.getStatSampler();
+    if (sampler != null) {
+      // Sampling is enabled
+//      this.vmStats = sampler.getVMStats();
+      this.processStats = sampler.getProcessStats();
+    }
+
+    this.dmStats = dm.getStats();
+    
+    StringBuffer sb = new StringBuffer();
+    sb.append("Application VM member ");
+    sb.append(dm.getId());
+    int pid = OSProcess.getId();
+    if (pid != 0) {
+      sb.append(" with pid ");
+      sb.append(pid);
+    }
+    this.description = sb.toString();
+  }
+
+  ////////////////////  Instance Methods  ////////////////////
+
+  @Override
+  protected String getDescription() {
+    return this.description;
+  }
+
+  /**
+   * Checks to make sure that the {@linkplain
+   * ProcessStats#getProcessSize VM's process size} is less than the
+   * {@linkplain MemberHealthConfig#getMaxVMProcessSize threshold}.
+   * If not, the status is "okay" health.
+   */
+  void checkVMProcessSize(List status) {
+    // There is no need to check isFirstEvaluation()
+    if (this.processStats == null) {
+      return;
+    }
+
+    long vmSize = this.processStats.getProcessSize();
+    long threshold = this.config.getMaxVMProcessSize();
+    if (vmSize > threshold) {
+      String s = LocalizedStrings.MemberHealthEvaluator_THE_SIZE_OF_THIS_VM_0_MEGABYTES_EXCEEDS_THE_THRESHOLD_1_MEGABYTES.toLocalizedString(new Object[] {Long.valueOf(vmSize), Long.valueOf(threshold)});
+      status.add(okayHealth(s));
+    }
+  }
+
+  /**
+   * Checks to make sure that the size of the distribution manager's
+   * {@linkplain DMStats#getOverflowQueueSize() overflow} message
+   * queue does not exceed the {@linkplain
+   * MemberHealthConfig#getMaxMessageQueueSize threshold}.  If not,
+   * the status is "okay" health.
+   */
+  void checkMessageQueueSize(List status) {
+    long threshold = this.config.getMaxMessageQueueSize();
+    long overflowSize = this.dmStats.getOverflowQueueSize();
+    if (overflowSize > threshold) {
+      String s = LocalizedStrings.MemberHealthEvaluator_THE_SIZE_OF_THE_OVERFLOW_QUEUE_0_EXCEEDS_THE_THRESHOLD_1.toLocalizedString(new Object[] { Long.valueOf(overflowSize), Long.valueOf(threshold)});
+      status.add(okayHealth(s));
+    }
+  }
+
+  /**
+   * Checks to make sure that the number of {@linkplain
+   * DMStats#getReplyTimeouts reply timeouts} does not exceed the
+   * {@linkplain MemberHealthConfig#getMaxReplyTimeouts threshold}.
+   * If not, the status is "okay" health.
+   */
+  void checkReplyTimeouts(List status) {
+    if (isFirstEvaluation()) {
+      return;
+    }
+
+    long threshold = this.config.getMaxReplyTimeouts();
+    long deltaReplyTimeouts =
+      this.dmStats.getReplyTimeouts() - prevReplyTimeouts;
+    if (deltaReplyTimeouts > threshold) {
+      String s = LocalizedStrings.MemberHealthEvaluator_THE_NUMBER_OF_MESSAGE_REPLY_TIMEOUTS_0_EXCEEDS_THE_THRESHOLD_1.toLocalizedString(new Object[] { Long.valueOf(deltaReplyTimeouts), Long.valueOf(threshold)}); 
+      status.add(okayHealth(s));
+    }
+  }
+
+  /**
+   * See if the multicast retransmission ratio is okay
+   */
+  void checkRetransmissionRatio(List status) {
+    double threshold = this.config.getMaxRetransmissionRatio();
+    int mcastMessages = this.dmStats.getMcastWrites();
+    if (mcastMessages > 100000) { // avoid initial state & int overflow
+      // the ratio we actually use here is (retransmit requests) / (mcast datagram writes)
+      // a single retransmit request may include multiple missed messages
+      double ratio = (this.dmStats.getMcastRetransmits() * 1.0) /
+                    (this.dmStats.getMcastWrites() * 1.0);
+      if (ratio > threshold) {
+        String s = "The number of message retransmissions (" +
+          ratio + ") exceeds the threshold (" + threshold + ")";
+        status.add(okayHealth(s));
+      }
+    }
+  }
+  
+/**
+ * The function keeps updating the health of the cache based on 
+ * roles required by the regions and their reliablity policies.
+ * 
+ * */
+  
+  void checkCacheRequiredRolesMeet(List status){
+	// will have to call here okeyHealth() or poorHealth()
+	//GemFireCache cache = (GemFireCache)CacheFactory.getAnyInstance();
+	
+	//CachePerfStats cPStats= null;
+	try{
+		GemFireCacheImpl cache = (GemFireCacheImpl)CacheFactory.getAnyInstance();
+		CachePerfStats cPStats= null;
+		cPStats= cache.getCachePerfStats();
+	
+		if(cPStats.getReliableRegionsMissingFullAccess()> 0){
+			// health is okay.
+			int numRegions = cPStats.getReliableRegionsMissingFullAccess();
+			status.add(okayHealth(LocalizedStrings.MemberHealthEvaluator_THERE_ARE_0_REGIONS_MISSING_REQUIRED_ROLES_BUT_ARE_CONFIGURED_FOR_FULL_ACCESS.toLocalizedString(Integer.valueOf(numRegions))));
+		}else if(cPStats.getReliableRegionsMissingLimitedAccess() > 0){
+			// health is poor
+			int numRegions = cPStats.getReliableRegionsMissingLimitedAccess();
+			status.add(poorHealth(LocalizedStrings.MemberHealthEvaluator_THERE_ARE_0_REGIONS_MISSING_REQUIRED_ROLES_AND_CONFIGURED_WITH_LIMITED_ACCESS.toLocalizedString(Integer.valueOf(numRegions))));
+		}else if (cPStats.getReliableRegionsMissingNoAccess() > 0){
+			// health is poor
+			int numRegions = cPStats.getReliableRegionsMissingNoAccess();
+			status.add(poorHealth(LocalizedStrings.MemberHealthEvaluator_THERE_ARE_0_REGIONS_MISSING_REQUIRED_ROLES_AND_CONFIGURED_WITHOUT_ACCESS.toLocalizedString(Integer.valueOf(numRegions))));
+		}//else{
+			// health is good/okay
+		//	status.add(okayHealth("All regions have there required roles meet"));
+		//}
+	}
+	catch (CancelException ignore) {
+	}
+  }
+
+    
+  /**
+   * Updates the previous values of statistics
+   */
+  private void updatePrevious() {
+    this.prevReplyTimeouts = this.dmStats.getReplyTimeouts();
+  }
+
+  @Override
+  protected void check(List status) {
+    checkVMProcessSize(status);
+    checkMessageQueueSize(status);
+    checkReplyTimeouts(status);
+    // will have to add another call to check for roles 
+    // missing and reliablity attributed.
+    checkCacheRequiredRolesMeet(status);
+
+    updatePrevious();
+  }
+
+  @Override
+  void close() {
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/PrepareBackupRequest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/PrepareBackupRequest.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/PrepareBackupRequest.java
new file mode 100644
index 0000000..ea7a768
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/PrepareBackupRequest.java
@@ -0,0 +1,124 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.cache.persistence.PersistentID;
+import com.gemstone.gemfire.distributed.DistributedMember;
+import com.gemstone.gemfire.distributed.internal.DM;
+import com.gemstone.gemfire.distributed.internal.DistributionManager;
+import com.gemstone.gemfire.distributed.internal.DistributionMessage;
+import com.gemstone.gemfire.distributed.internal.ReplyException;
+import com.gemstone.gemfire.internal.admin.remote.AdminFailureResponse;
+import com.gemstone.gemfire.internal.admin.remote.AdminMultipleReplyProcessor;
+import com.gemstone.gemfire.internal.admin.remote.AdminResponse;
+import com.gemstone.gemfire.internal.admin.remote.CliLegacyMessage;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.persistence.BackupManager;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+
+/**
+ * A request to from an admin VM to all non admin members
+ * to start a backup. In the prepare phase of the backup,
+ * the members will suspend bucket destroys to make sure
+ * buckets aren't missed during the backup.
+ * 
+ * @author dsmith
+ *
+ */
+public class PrepareBackupRequest  extends CliLegacyMessage {
+  private static final Logger logger = LogService.getLogger();
+  
+  public PrepareBackupRequest() {
+    
+  }
+  
+  public static Map<DistributedMember, Set<PersistentID>> send(DM dm, Set recipients) {
+    PrepareBackupRequest request = new PrepareBackupRequest();
+    request.setRecipients(recipients);
+
+    PrepareBackupReplyProcessor replyProcessor = new PrepareBackupReplyProcessor(dm, recipients);
+    request.msgId = replyProcessor.getProcessorId();
+    dm.putOutgoing(request);
+    try {
+      replyProcessor.waitForReplies();
+    } catch (ReplyException e) {
+      if(!(e.getCause() instanceof CancelException)) {
+        throw e;
+      }
+    } catch (InterruptedException e) {
+      e.printStackTrace();
+    }
+    AdminResponse response = request.createResponse((DistributionManager)dm);
+    response.setSender(dm.getDistributionManagerId());
+    replyProcessor.process(response);
+    return replyProcessor.results;
+  }
+  
+  @Override
+  protected AdminResponse createResponse(DistributionManager dm) {
+    GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+    HashSet<PersistentID> persistentIds;
+    if(cache == null) {
+      persistentIds = new HashSet<PersistentID>();
+    } else {
+      try {
+        BackupManager manager = cache.startBackup(getSender());
+        persistentIds = manager.prepareBackup();
+      } catch(IOException e) {
+        logger.error(LocalizedMessage.create(LocalizedStrings.CliLegacyMessage_ERROR, this.getClass()), e);
+        return AdminFailureResponse.create(dm, getSender(), e);        
+      }
+    }
+
+
+    return new PrepareBackupResponse(this.getSender(), persistentIds);
+  }
+
+  public int getDSFID() {
+    return PREPARE_BACKUP_REQUEST;
+  }
+  
+  private static class PrepareBackupReplyProcessor extends AdminMultipleReplyProcessor {
+    Map<DistributedMember, Set<PersistentID>> results = Collections.synchronizedMap(new HashMap<DistributedMember, Set<PersistentID>>());
+    public PrepareBackupReplyProcessor(DM dm, Collection initMembers) {
+      super(dm, initMembers);
+    }
+    
+    @Override
+    protected boolean stopBecauseOfExceptions() {
+      return false;
+    }
+
+    @Override
+    protected void process(DistributionMessage msg, boolean warn) {
+      if(msg instanceof PrepareBackupResponse) {
+        final HashSet<PersistentID> persistentIds = ((PrepareBackupResponse) msg).getPersistentIds();
+        if(persistentIds != null && !persistentIds.isEmpty()) {
+          results.put(msg.getSender(), persistentIds);
+        }
+      }
+      super.process(msg, warn);
+    }
+    
+    
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/PrepareBackupResponse.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/PrepareBackupResponse.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/PrepareBackupResponse.java
new file mode 100644
index 0000000..d6adc51
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/PrepareBackupResponse.java
@@ -0,0 +1,73 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.HashSet;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.persistence.PersistentID;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.internal.admin.remote.AdminResponse;
+
+/**
+ * The response to the {@link PrepareBackupRequest}
+ * 
+ * @author dsmith
+ *
+ */
+public class PrepareBackupResponse extends AdminResponse {
+
+  private HashSet<PersistentID> persistentIds;
+  
+  public PrepareBackupResponse() {
+    super();
+  }
+
+  public PrepareBackupResponse(InternalDistributedMember sender, HashSet<PersistentID> persistentIds) {
+    this.setRecipient(sender);
+    this.persistentIds = persistentIds;
+  }
+  
+  public HashSet<PersistentID> getPersistentIds() {
+    return persistentIds;
+  }
+
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    super.fromData(in);
+    persistentIds = DataSerializer.readHashSet(in);
+  }
+
+
+
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    super.toData(out);    
+    DataSerializer.writeHashSet(persistentIds, out);
+  }
+
+
+
+  @Override
+  protected Object clone() throws CloneNotSupportedException {
+    // TODO Auto-generated method stub
+    return super.clone();
+  }
+
+  public int getDSFID() {
+    return PREPARE_BACKUP_RESPONSE;
+  }
+  
+  @Override
+  public String toString() {
+    return getClass().getName() + ": " + persistentIds;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/StatisticImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/StatisticImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/StatisticImpl.java
new file mode 100755
index 0000000..209b07b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/StatisticImpl.java
@@ -0,0 +1,88 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.internal.admin.Stat;
+
+/**
+ * Implementation of a single statistic in a <code>StatisticResource</code>
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ */
+public class StatisticImpl
+implements com.gemstone.gemfire.admin.Statistic {
+
+  private static final long serialVersionUID = 3899296873901634399L;
+  
+  private Stat internalStat;
+
+  protected StatisticImpl() {
+  }
+
+  protected StatisticImpl(Stat internalStat) {
+    this.internalStat = internalStat;
+  }
+    
+  /**
+   * @return the identifying name of this stat 
+   */
+  public String getName() {
+    return this.internalStat.getName();
+  }
+  
+  /**
+   * @return the value of this stat as a <code>java.lang.Number</code> 
+   */
+  public Number getValue() {
+    return this.internalStat.getValue();
+  }
+  
+  /**
+   * @return a display string for the unit of measurement (if any) this stat represents
+   */
+  public String getUnits() {
+    return this.internalStat.getUnits();
+  }
+  
+  /**
+   * @return true if this stat represents a numeric value which always increases
+   */
+  public boolean isCounter() {
+    return this.internalStat.isCounter();
+  }
+  
+  /**
+   * @return the full description of this stat
+   */
+  public String getDescription() {
+    return this.internalStat.getDescription();
+  }
+  
+  /**
+   * Sets the internal stat which allows us to reuse the wrapper object and
+   * handle refreshes along with isWriteable set to false on the attribute.
+   */
+  protected void setStat(Stat internalStat) {
+    this.internalStat = internalStat;
+  }
+    
+	/**
+	 * Returns a string representation of the object.
+	 * 
+	 * @return a string representation of the object
+	 */
+  @Override
+	public String toString() {
+		return getName();
+	}
+  
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/StatisticResourceImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/StatisticResourceImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/StatisticResourceImpl.java
new file mode 100755
index 0000000..fef370b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/StatisticResourceImpl.java
@@ -0,0 +1,174 @@
+/*
+ *  =========================================================================
+ *  Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *  ========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.SystemMember;
+import com.gemstone.gemfire.admin.Statistic;
+import com.gemstone.gemfire.internal.Assert;
+import com.gemstone.gemfire.internal.admin.Stat;
+import com.gemstone.gemfire.internal.admin.StatResource;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+//import com.gemstone.gemfire.internal.admin.SystemMember;
+
+import java.util.ArrayList;
+//import java.util.Date;
+import java.util.List;
+
+/**
+ * Provides monitoring of a statistic resource.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ */
+public class StatisticResourceImpl 
+implements com.gemstone.gemfire.admin.StatisticResource {
+
+  /** The underlying remote StatResource which this object delegates to */
+  protected StatResource statResource;
+  /** Displayable name of this statistic resource */
+  protected String name;
+  /** Description of this statistic resource */
+  protected String description;
+  /** Classification type of this statistic resource */
+  protected String type;
+  /** GemFire system member which owns this statistic resource */
+  protected SystemMember member;
+  /** The array of statistics in this resource */
+  protected Statistic[] statistics; // = new Statistic[0];
+  
+  // -------------------------------------------------------------------------
+  //   Constructor(s)
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Constructs an instance of StatisticResourceImpl.
+   *
+   * @param statResource  the admin StatResource to manage/monitor
+   * @param member        the SystemMember owning this resource
+   * @exception com.gemstone.gemfire.admin.AdminException 
+   *            if unable to create this StatisticResource for administration
+   */
+  public StatisticResourceImpl(StatResource statResource,
+                               SystemMember member)
+                        throws com.gemstone.gemfire.admin.AdminException {
+    this.statResource = statResource;
+    this.member = member;
+    this.name = this.statResource.getName();
+    this.description = this.statResource.getDescription();
+    this.type = this.statResource.getType();
+  }
+
+  // -------------------------------------------------------------------------
+  //   Attributes accessors and mutators
+  // -------------------------------------------------------------------------
+
+	public String getName() {
+		return this.name;
+	}
+  
+	public String getDescription() {
+		return this.description;
+	}
+  
+  public String getType() {
+    return this.type;
+  }
+  
+	public String getOwner() {
+		return this.member.toString();
+	}
+  
+  public Statistic[] getStatistics() {
+    if (this.statistics == null) {
+      try {
+        refresh();
+      }
+      catch (AdminException e) {
+        this.statistics = new Statistic[0];
+      }
+    }
+    return this.statistics;
+  }
+
+  public long getUniqueId() {
+    return this.statResource.getResourceUniqueID();
+  }
+  
+  // -------------------------------------------------------------------------
+  //   Operations
+  // -------------------------------------------------------------------------
+
+  public void refresh() throws com.gemstone.gemfire.admin.AdminException {
+    Stat[] stats = null;
+    if (this.statResource != null) {
+      stats = this.statResource.getStats();
+    }
+    if (stats == null || stats.length < 1) {
+      throw new AdminException(LocalizedStrings.StatisticResourceImpl_FAILED_TO_REFRESH_STATISTICS_0_FOR_1.toLocalizedString(getType()+"-"+getName(), getOwner()));
+    }
+    
+    if (this.statistics == null || this.statistics.length < 1) {
+      // define new statistics instances...
+      List statList = new ArrayList();
+      for (int i = 0; i < stats.length; i++) {
+        statList.add(createStatistic(stats[i]));
+      }
+      this.statistics = (Statistic[]) statList.toArray(new Statistic[0]);
+    }
+    else {
+      // update the existing instances...
+      for (int i = 0; i < stats.length; i++) {
+        updateStatistic(stats[i]);
+      }
+    }
+  }
+
+  // -------------------------------------------------------------------------
+  //   Non-public implementation methods
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Updates the value of the {@link Statistic} corresponding to the internal 
+   * {@link com.gemstone.gemfire.internal.admin.Stat}
+   *
+   * @param stat  the internal stat to use in updating the matching statistic
+   */
+  private void updateStatistic(Stat stat) {
+    for (int i = 0; i < this.statistics.length; i++) {
+      if (this.statistics[i].getName().equals(stat.getName())) {
+        ((StatisticImpl)this.statistics[i]).setStat(stat);
+        return;
+      }
+    }
+    Assert.assertTrue(false, "Unknown stat: " + stat.getName());
+  }
+  
+  /**
+   * Creates a new {@link StatisticImpl} to represent the internal {@link 
+   * com.gemstone.gemfire.internal.admin.Stat}
+   *
+   * @param stat  the internal stat to wrap in a new statistic
+   */
+  protected Statistic createStatistic(Stat stat) {
+    return new StatisticImpl(stat);
+  }
+  
+	/**
+	 * Returns a string representation of the object.
+	 * 
+	 * @return a string representation of the object
+	 */
+  @Override
+	public String toString() {
+		return getName();
+	}
+  
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberBridgeServerImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberBridgeServerImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberBridgeServerImpl.java
new file mode 100644
index 0000000..fcdbd4d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberBridgeServerImpl.java
@@ -0,0 +1,225 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.io.Serializable;
+
+import com.gemstone.gemfire.InternalGemFireException;
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.SystemMemberBridgeServer;
+import com.gemstone.gemfire.admin.SystemMemberCacheServer;
+import com.gemstone.gemfire.cache.server.ServerLoadProbe;
+import com.gemstone.gemfire.internal.admin.*;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+/**
+ * Implementation of an object used for managing cache servers.
+ *
+ * @author David Whitlock
+ * @since 4.0
+ */
+public class SystemMemberBridgeServerImpl
+  implements SystemMemberCacheServer, SystemMemberBridgeServer {
+
+  /** The VM in which the bridge server resides */
+  private final GemFireVM vm;
+
+  /** The cache server by this bridge server */
+  private CacheInfo cache;
+
+  /** Information about the bridge server */
+  private AdminBridgeServer bridgeInfo;
+
+  /////////////////////  Constructors  /////////////////////
+
+  /**
+   * Creates a new <code>SystemMemberBridgeServerImpl</code> that
+   * administers the given bridge server in the given VM.
+   */
+  protected SystemMemberBridgeServerImpl(SystemMemberCacheImpl cache,
+                                         AdminBridgeServer bridgeInfo)
+                                         
+    throws AdminException {
+
+    this.vm = cache.getVM();
+    this.cache = cache.getCacheInfo();
+    this.bridgeInfo = bridgeInfo;
+  }
+
+  ////////////////////  Instance Methods  ////////////////////
+
+  /**
+   * Throws an <code>AdminException</code> if this bridge server is
+   * running.
+   */
+  private void checkRunning() throws AdminException {
+    if (this.isRunning()) {
+      throw new AdminException(LocalizedStrings.SystemMemberBridgeServerImpl_CANNOT_CHANGE_THE_CONFIGURATION_OF_A_RUNNING_BRIDGE_SERVER.toLocalizedString());
+    }
+  }
+
+  public int getPort() {
+    return this.bridgeInfo.getPort();
+  }
+
+  public void setPort(int port) throws AdminException {
+    checkRunning();
+    this.bridgeInfo.setPort(port);
+  }
+
+  public void start() throws AdminException {
+    this.vm.startBridgeServer(this.cache, this.bridgeInfo);
+  }
+
+  public boolean isRunning() {
+    return this.bridgeInfo.isRunning();
+  }
+
+  public void stop() throws AdminException {
+    this.vm.stopBridgeServer(this.cache, this.bridgeInfo);
+  }
+
+  /**
+   * Returns the VM-unique id of this bridge server
+   */
+  protected int getBridgeId() {
+    return this.bridgeInfo.getId();
+  }
+
+  public void refresh() {
+    try {
+      this.bridgeInfo =
+        this.vm.getBridgeInfo(this.cache, this.bridgeInfo.getId());
+
+    } catch (AdminException ex) {
+      throw new InternalGemFireException(LocalizedStrings.SystemMemberBridgeServerImpl_UNEXPECTED_EXCEPTION_WHILE_REFRESHING.toLocalizedString(), ex);
+    }
+  }
+
+  public String getBindAddress() {
+    return this.bridgeInfo.getBindAddress();
+  }
+
+  public void setBindAddress(String address) throws AdminException {
+    checkRunning();
+    this.bridgeInfo.setBindAddress(address);
+  }
+
+  public String getHostnameForClients() {
+    return this.bridgeInfo.getHostnameForClients();
+  }
+
+  public void setHostnameForClients(String name) throws AdminException {
+    checkRunning();
+    this.bridgeInfo.setHostnameForClients(name);
+  }
+
+  public void setNotifyBySubscription(boolean b) throws AdminException {
+    checkRunning();
+    this.bridgeInfo.setNotifyBySubscription(b);
+  }
+
+  public boolean getNotifyBySubscription() {
+    return this.bridgeInfo.getNotifyBySubscription();
+  }
+
+  public void setSocketBufferSize(int socketBufferSize) throws AdminException {
+    checkRunning();
+    this.bridgeInfo.setSocketBufferSize(socketBufferSize);
+  }
+
+  public int getSocketBufferSize() {
+    return this.bridgeInfo.getSocketBufferSize();
+  }
+  
+  public void setTcpDelay(boolean setting) throws AdminException {
+    checkRunning();
+    this.bridgeInfo.setTcpNoDelay(setting);
+  }
+  
+  public boolean getTcpDelay() {
+    return this.bridgeInfo.getTcpNoDelay();
+  }
+
+  public void setMaximumTimeBetweenPings(int maximumTimeBetweenPings) throws AdminException {
+    checkRunning();
+    this.bridgeInfo.setMaximumTimeBetweenPings(maximumTimeBetweenPings);
+  }
+
+  public int getMaximumTimeBetweenPings() {
+    return this.bridgeInfo.getMaximumTimeBetweenPings();
+  }
+
+  public int getMaxConnections() {
+    return this.bridgeInfo.getMaxConnections();
+  }
+
+  public void setMaxConnections(int maxCons) throws AdminException {
+    checkRunning();
+    this.bridgeInfo.setMaxConnections(maxCons);
+  }
+
+  public int getMaxThreads() {
+    return this.bridgeInfo.getMaxThreads();
+  }
+
+  public void setMaxThreads(int maxThreads) throws AdminException {
+    checkRunning();
+    this.bridgeInfo.setMaxThreads(maxThreads);
+  }
+
+  public int getMaximumMessageCount() {
+    return this.bridgeInfo.getMaximumMessageCount();
+  }
+
+  public void setMaximumMessageCount(int maxMessageCount) throws AdminException {
+    checkRunning();
+    this.bridgeInfo.setMaximumMessageCount(maxMessageCount);
+  }
+
+  public int getMessageTimeToLive() {
+    return this.bridgeInfo.getMessageTimeToLive();
+  }
+
+  public void setMessageTimeToLive(int messageTimeToLive) throws AdminException {
+    checkRunning();
+    this.bridgeInfo.setMessageTimeToLive(messageTimeToLive);
+  }
+
+  public void setGroups(String[] groups) throws AdminException {
+    checkRunning();
+    this.bridgeInfo.setGroups(groups);
+  }
+
+  public String[] getGroups() {
+    return this.bridgeInfo.getGroups();
+  }
+  
+  public String getLoadProbe() {
+    return this.bridgeInfo.getLoadProbe().toString();
+  }
+
+  public void setLoadProbe(ServerLoadProbe loadProbe) throws AdminException {
+    checkRunning();
+    if(!(loadProbe instanceof Serializable)) {
+      throw new IllegalArgumentException("Load probe must be Serializable to be used with admin API");
+    }
+    this.bridgeInfo.setLoadProbe(loadProbe);
+  }
+
+  public long getLoadPollInterval() {
+    return this.bridgeInfo.getLoadPollInterval();
+  }
+
+  public void setLoadPollInterval(long loadPollInterval) throws AdminException {
+    checkRunning();
+    this.bridgeInfo.setLoadPollInterval(loadPollInterval);
+  }
+  
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberCacheEventImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberCacheEventImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberCacheEventImpl.java
new file mode 100644
index 0000000..3fdf384
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberCacheEventImpl.java
@@ -0,0 +1,52 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.*;
+import com.gemstone.gemfire.distributed.DistributedMember;
+import com.gemstone.gemfire.cache.Operation;
+
+/**
+ * An event that describes an operation on a cache.
+ * Instances of this are delivered to a {@link SystemMemberCacheListener} when a
+ * a cache is created or closed.
+ *
+ * @author Darrel Schneider
+ * @since 5.0
+ */
+public class SystemMemberCacheEventImpl
+  extends SystemMembershipEventImpl
+  implements SystemMemberCacheEvent
+{
+
+  /** The operation done by this event */
+  private Operation op;
+
+  ///////////////////////  Constructors  ///////////////////////
+
+  /**
+   * Creates a new <code>SystemMemberCacheEvent</code> for the member
+   * with the given id.
+   */
+  protected SystemMemberCacheEventImpl(DistributedMember id, Operation op) {
+    super(id);
+    this.op = op;
+  }
+
+  /////////////////////  Instance Methods  /////////////////////
+
+  public Operation getOperation() {
+    return this.op;
+  }
+
+  @Override
+  public String toString() {
+    return super.toString() + " op=" + this.op;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberCacheEventProcessor.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberCacheEventProcessor.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberCacheEventProcessor.java
new file mode 100644
index 0000000..885ecbb
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberCacheEventProcessor.java
@@ -0,0 +1,139 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.admin.SystemMemberCacheEvent;
+import com.gemstone.gemfire.admin.SystemMemberCacheListener;
+import com.gemstone.gemfire.admin.SystemMemberRegionEvent;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.Operation;
+import com.gemstone.gemfire.cache.Region;
+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.internal.logging.LogService;
+
+/**
+ * This class processes the message to be delivered to admin node.
+ * [This needs to be redesigned and reimplemented... see 32887]
+ * @author Darrel Schneider
+ * @since 5.0
+ */
+public class SystemMemberCacheEventProcessor {
+  private static final Logger logger = LogService.getLogger();
+
+  
+  /*
+   * Sends cache create/close message to Admin VMs
+   */
+  public static void send(Cache c, Operation op) {
+    send(c, null, op);
+  }
+
+  /*
+   * Sends region creation/destroy message to Admin VMs
+   */
+  public static void send(Cache c, Region region, Operation op) {
+    InternalDistributedSystem system = (InternalDistributedSystem)c.getDistributedSystem();
+    Set recps = system.getDistributionManager().getAdminMemberSet();
+    // @todo darrel: find out if any of these guys have region listeners
+    if (recps.isEmpty()) {
+      return;
+    }
+    SystemMemberCacheMessage msg = new SystemMemberCacheMessage();
+    if (region == null) {
+      msg.regionPath = null;
+    } else {
+      msg.regionPath = region.getFullPath();
+    }
+    msg.setRecipients(recps);
+    msg.op = op;
+    system.getDistributionManager().putOutgoing(msg);
+  }
+  
+  
+  public static final class SystemMemberCacheMessage extends HighPriorityDistributionMessage
+  {
+    protected String regionPath;
+    protected Operation op;
+
+    @Override
+    protected void process(DistributionManager dm) {
+      AdminDistributedSystemImpl admin = AdminDistributedSystemImpl.getConnectedInstance();
+      if (admin == null) {
+        if (logger.isDebugEnabled()) {
+          logger.debug("Ignoring message because there is no admin distributed system present: {}", this);
+        }
+        return;  // probably shutting down or still connecting
+      }
+      List listeners = admin.getCacheListeners();
+      Iterator itr = listeners.iterator();
+      SystemMemberCacheListener listener = null;
+      while(itr.hasNext()){
+        listener = (SystemMemberCacheListener)itr.next();
+        if (this.regionPath == null) {
+          SystemMemberCacheEvent event = new SystemMemberCacheEventImpl(getSender(), this.op);
+          if (this.op == Operation.CACHE_CREATE) {
+            listener.afterCacheCreate(event);
+          } else {
+            listener.afterCacheClose(event);
+          }
+        } else {
+          SystemMemberRegionEvent event = new SystemMemberRegionEventImpl(getSender(), this.op, this.regionPath);
+          if (this.op.isRegionDestroy()) {
+            listener.afterRegionLoss(event);
+          } else {
+            listener.afterRegionCreate(event);
+          }
+        }
+      }
+    }
+
+    public int getDSFID() {
+      return ADMIN_CACHE_EVENT_MESSAGE;
+    }
+
+    @Override
+    public void fromData(DataInput in)
+      throws IOException, ClassNotFoundException {
+      super.fromData(in);
+      this.regionPath = DataSerializer.readString(in);
+      this.op = Operation.fromOrdinal(in.readByte());
+    }
+
+    @Override
+    public void toData(DataOutput out) throws IOException {
+      super.toData(out);
+      DataSerializer.writeString(this.regionPath, out);
+      out.writeByte(this.op.ordinal);
+    }
+
+    @Override
+    public String toString() {
+      StringBuffer buff = new StringBuffer();
+      buff.append("SystemMemberCacheMessage (region='");
+      buff.append(this.regionPath);
+      buff.append("'; sender=");
+      buff.append(this.sender);
+      buff.append("; op=");
+      buff.append(this.op);
+      buff.append(")");
+      return buff.toString();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberCacheImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberCacheImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberCacheImpl.java
new file mode 100644
index 0000000..d823c5e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberCacheImpl.java
@@ -0,0 +1,317 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.*;
+import com.gemstone.gemfire.cache.*;
+import com.gemstone.gemfire.internal.Assert;
+import com.gemstone.gemfire.internal.ObjIdMap;
+import com.gemstone.gemfire.internal.admin.*;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import java.util.*;
+
+/**
+ * View of a GemFire system member's cache.
+ *
+ * @author    Darrel Schneider
+ * @since     3.5
+ */
+public class SystemMemberCacheImpl implements SystemMemberCache {
+  protected final GemFireVM vm;
+  protected CacheInfo info;
+  protected Statistic[] statistics;
+
+  /** Maps the id of a bridge server to its SystemMemberBridgeServer */ 
+  private ObjIdMap bridgeServers = new ObjIdMap();
+  
+  // constructors
+  public SystemMemberCacheImpl(GemFireVM vm)
+    throws CacheDoesNotExistException
+  {
+    this.vm = vm;
+    this.info = vm.getCacheInfo();
+    if (this.info == null) {
+      throw new CacheDoesNotExistException(LocalizedStrings.SystemMemberCacheImpl_THE_VM_0_DOES_NOT_CURRENTLY_HAVE_A_CACHE.toLocalizedString(vm.getId()));
+    }
+    initStats();
+  }
+  
+  // attributes
+  /**
+   * The name of the cache.
+   */
+  public String getName() {
+    String result = this.info.getName();
+    if (result == null || result.length() == 0) {
+      result = "default";
+    }
+    return result;
+  }
+  /**
+   * Value that uniquely identifies an instance of a cache for a given member.
+   */
+  public int getId() {
+    return this.info.getId();
+  }
+
+  public boolean isClosed() {
+    return this.info.isClosed();
+  }
+  public int getLockTimeout() {
+    return this.info.getLockTimeout();
+  }
+  public void setLockTimeout(int seconds) throws AdminException {
+    this.info = this.vm.setCacheLockTimeout(this.info, seconds);
+  }
+  public int getLockLease() {
+    return this.info.getLockLease();
+  }
+  public void setLockLease(int seconds) throws AdminException {
+    this.info = this.vm.setCacheLockLease(this.info, seconds);
+  }
+  public int getSearchTimeout() {
+    return this.info.getSearchTimeout();
+  }
+  public void setSearchTimeout(int seconds) throws AdminException {
+    this.info = this.vm.setCacheSearchTimeout(this.info, seconds);
+  }
+  public int getUpTime() {
+    return this.info.getUpTime();
+  }
+  public java.util.Set getRootRegionNames() {
+    Set set = this.info.getRootRegionNames();
+    if (set == null) {
+      set = Collections.EMPTY_SET;
+    }
+    return set;
+  }
+  // operations
+
+  public void refresh() {
+    if (!this.info.isClosed()) {
+      CacheInfo cur = vm.getCacheInfo();
+      if (cur == null || (this.info.getId() != cur.getId())) {
+        // it is a different instance of the cache. So set our version
+        // to closed
+        this.info.setClosed();
+      } else {
+        this.info = cur;
+        updateStats();
+      }
+    }
+  }
+
+  public GemFireMemberStatus getSnapshot()
+  {
+	  //System.out.println(">>>SystemMemberCacheJmxImpl::getSnapshot:pre::: " + this.vm);
+	  GemFireMemberStatus stat = this.vm.getSnapshot();
+	  //System.out.println(">>>SystemMemberCacheJmxImpl::getSnapshot:post::: " + stat);
+	  return stat;
+  }
+
+  public RegionSubRegionSnapshot getRegionSnapshot()
+  {
+	  //System.out.println(">>>SystemMemberCacheJmxImpl::getRegionSnapshot:pre::: " + this.vm);
+	  RegionSubRegionSnapshot snap = this.vm.getRegionSnapshot();
+	  //System.out.println(">>>SystemMemberCacheJmxImpl::getRegionSnapshot:post::: " + snap);
+	  return snap;
+  }
+  
+  public Statistic[] getStatistics() {
+    return this.statistics;
+  }
+
+  public SystemMemberRegion getRegion(String path)
+    throws com.gemstone.gemfire.admin.AdminException
+  {
+    Region r = this.vm.getRegion(this.info, path);
+    if (r == null) {
+      return null;
+    } else {
+      return createSystemMemberRegion(r);
+    }
+  }
+
+  public SystemMemberRegion createRegion(String name,
+                                         RegionAttributes attrs)
+    throws AdminException
+  {
+    Region r = this.vm.createVMRootRegion(this.info, name, attrs);
+    if (r == null) {
+      return null;
+
+    } else {
+      return createSystemMemberRegion(r);
+    }
+  }
+  
+  public SystemMemberRegion createVMRegion(String name,
+                                           RegionAttributes attrs)
+    throws AdminException
+  {
+    return createRegion(name, attrs);
+  }
+
+
+  // internal methods
+  private void initStats() {
+    StatResource resource = this.info.getPerfStats();
+    if (resource == null) {
+      // See bug 31397
+      Assert.assertTrue(this.isClosed());
+      return;
+    }
+
+    Stat[] stats = resource.getStats();
+    if (stats == null || stats.length < 1) {
+      this.statistics = new Statistic[0];
+      return;
+    }
+    
+    // define new statistics instances...
+    List statList = new ArrayList();
+    for (int i = 0; i < stats.length; i++) {
+      statList.add(createStatistic(stats[i]));
+    }
+    this.statistics = (Statistic[]) statList.toArray(new Statistic[statList.size()]);
+  }
+  private void updateStats() {
+    StatResource resource = this.info.getPerfStats();
+    if (resource == null) {
+      // See bug 31397
+      Assert.assertTrue(this.isClosed());
+      return;
+    }
+
+    Stat[] stats = resource.getStats();
+    if (stats == null || stats.length < 1) {
+      return;
+    }
+    
+    for (int i = 0; i < stats.length; i++) {
+      updateStatistic(stats[i]);
+    }
+  }
+
+  private void updateStatistic(Stat stat) {
+    for (int i = 0; i < this.statistics.length; i++) {
+      if (this.statistics[i].getName().equals(stat.getName())) {
+        ((StatisticImpl)this.statistics[i]).setStat(stat);
+        return;
+      }
+    }
+    Assert.assertTrue(false, "Unknown stat: " + stat.getName());
+  }
+
+  /**
+   * Returns the <code>CacheInfo</code> that describes this cache.
+   * Note that this operation does not {@link #refresh} the
+   * <code>CacheInfo</code>. 
+   */
+  public CacheInfo getCacheInfo() {
+    return this.info;
+  }
+
+  public GemFireVM getVM() {
+    return this.vm;
+  }
+
+  protected Statistic createStatistic(Stat stat) {
+    return new StatisticImpl(stat);
+  }
+  protected SystemMemberRegion createSystemMemberRegion(Region r)
+    throws com.gemstone.gemfire.admin.AdminException
+  {
+    SystemMemberRegionImpl sysMemberRegion = new SystemMemberRegionImpl(this, r);
+    sysMemberRegion.refresh();
+    return sysMemberRegion;
+  }
+
+  public SystemMemberCacheServer addCacheServer()
+    throws AdminException {
+    return (SystemMemberCacheServer)addBridgeServer();
+  }
+
+  public SystemMemberBridgeServer addBridgeServer()
+    throws AdminException {
+
+    AdminBridgeServer bridge = this.vm.addBridgeServer(this.info);
+    SystemMemberBridgeServer admin =
+      createSystemMemberBridgeServer(bridge);
+    bridgeServers.put(bridge.getId(), admin);
+    return admin;
+  }
+
+  private Collection getCacheServersCollection()
+    throws AdminException {
+    Collection bridges = new ArrayList();
+
+    int[] bridgeIds = this.info.getBridgeServerIds();
+    for (int i = 0; i < bridgeIds.length; i++) {
+      int id = bridgeIds[i];
+      SystemMemberBridgeServer bridge =
+        (SystemMemberBridgeServer) bridgeServers.get(id);
+      if (bridge == null) {
+        AdminBridgeServer info = this.vm.getBridgeInfo(this.info, id);
+        if (info != null) {
+          bridge = createSystemMemberBridgeServer(info);
+          bridgeServers.put(info.getId(), bridge);
+        }
+      }
+
+      if (bridge != null) {
+        bridges.add(bridge);
+      }
+    }
+    return bridges;
+  }
+
+  public SystemMemberCacheServer[] getCacheServers()
+    throws AdminException {
+    Collection bridges = getCacheServersCollection();
+    SystemMemberCacheServer[] array =
+      new SystemMemberCacheServer[bridges.size()];
+    return (SystemMemberCacheServer[]) bridges.toArray(array);
+  };
+
+  public SystemMemberBridgeServer[] getBridgeServers()
+    throws AdminException {
+    Collection bridges = getCacheServersCollection();
+    SystemMemberBridgeServer[] array =
+      new SystemMemberBridgeServer[bridges.size()];
+    return (SystemMemberBridgeServer[]) bridges.toArray(array);
+  }
+
+  /**
+   * Creates a new instance of <Code>SystemMemberBridgeServer</code>
+   * with the given configuration.
+   */
+  protected SystemMemberBridgeServerImpl
+    createSystemMemberBridgeServer(AdminBridgeServer bridge) 
+    throws AdminException {
+
+    return new SystemMemberBridgeServerImpl(this, bridge);
+  }
+
+  public boolean isServer() throws AdminException {
+    return this.info.isServer();
+  }
+  
+  
+  /**
+   * Returns a string representation of the object.
+   * 
+   * @return a string representation of the object
+   */
+  @Override
+  public String toString() {
+	return getName();
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberImpl.java
new file mode 100755
index 0000000..361834c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberImpl.java
@@ -0,0 +1,511 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.net.InetAddress;
+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 org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.admin.AdminDistributedSystem;
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.CacheDoesNotExistException;
+import com.gemstone.gemfire.admin.ConfigurationParameter;
+import com.gemstone.gemfire.admin.RuntimeAdminException;
+import com.gemstone.gemfire.admin.StatisticResource;
+import com.gemstone.gemfire.admin.SystemMemberCache;
+import com.gemstone.gemfire.admin.SystemMemberType;
+import com.gemstone.gemfire.distributed.DistributedMember;
+import com.gemstone.gemfire.distributed.Role;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.distributed.internal.DistributionConfigImpl;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.internal.Config;
+import com.gemstone.gemfire.internal.ConfigSource;
+import com.gemstone.gemfire.internal.admin.GemFireVM;
+import com.gemstone.gemfire.internal.admin.StatResource;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * Member of a GemFire system.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ */
+public class SystemMemberImpl 
+implements com.gemstone.gemfire.admin.SystemMember,
+           com.gemstone.gemfire.admin.internal.ConfigurationParameterListener {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  /** Identifying name of this member.
+   * Note that by default this is the string form of internalId but the
+   * ManagedSystemMemberImpl subclass resets it to getNewId()
+   */
+  protected String id;
+
+  /** Unique internal id that the system impl identifies this member with */
+  protected InternalDistributedMember internalId;
+
+  /** The name of this system member */
+  protected String name;
+
+  /** Host name of the machine this member resides on */
+  protected String host;
+
+  /** The internal configuration this impl delegates to for runtime config */
+//  private Config config;
+
+  /** The configuration parameters for this member.  Maps the name of
+      the ConfigurationParameter to the ConfigurationParameter. */
+  protected Map parms = new HashMap();
+
+  /** The {@link AdminDistributedSystem} this is a member of */
+  protected AdminDistributedSystem system;
+
+  /** Internal GemFire vm to delegate to */
+  private GemFireVM vm;
+  
+  // -------------------------------------------------------------------------
+  //   Constructor(s)
+  // -------------------------------------------------------------------------
+
+  /** 
+   * Constructs new <code>SystemMemberImpl</code> for a
+   * <code>ManagedEntity</code> that has yet to be started.
+   *
+   * @param system  the distributed system this member belongs to
+   */
+  protected SystemMemberImpl(AdminDistributedSystem system) 
+    throws AdminException {
+
+    this.system = system;
+    refreshConfig(getDefaultConfig());
+  }
+
+  /** 
+   * Constructs new <code>SystemMemberImpl</code> from the given
+   * <code>GemFireVM</code>.  This constructor is invoked when we
+   * discover a new member of the distributed system.
+   *
+   * @param system      the distributed system this member belongs to
+   * @param vm internal GemFire vm to delegate to
+   */
+  public SystemMemberImpl(AdminDistributedSystem system, 
+                          GemFireVM vm)
+    throws AdminException {
+
+    this(system);
+    setGemFireVM(vm);
+  }
+
+  /**
+   * Constructs the instance of SystemMember using the corresponding
+   * InternalDistributedMember instance of a DS member for the given
+   * AdminDistributedSystem.
+   * 
+   * @param system
+   *          Current AdminDistributedSystem instance
+   * @param member
+   *          InternalDistributedMember instance for which a SystemMember
+   *          instance is to be constructed.
+   * @throws AdminException
+   *           if construction of SystemMember fails
+   *           
+   * @since 6.5
+   */
+  protected SystemMemberImpl(AdminDistributedSystem system,
+                          InternalDistributedMember member) 
+                          throws AdminException {
+    this(system);
+    updateByInternalDistributedMember(member);
+  }
+
+  // -------------------------------------------------------------------------
+  //   Attribute accessors and mutators
+  // -------------------------------------------------------------------------
+
+  /**
+   * Returns a <code>Config</code> object with the appropriate default
+   * values for a newly-created system member.
+   */
+  protected Config getDefaultConfig() {
+    Properties props = new Properties();
+    return new DistributionConfigImpl(props);
+  }
+
+  public final AdminDistributedSystem getDistributedSystem() {
+    return this.system;
+  }
+  
+  public final InternalDistributedMember getInternalId() {
+    return internalId;
+  }
+
+  public final String getId() {
+    return this.id;
+  }
+
+  public final String getName() {
+    return this.name;
+  }
+  
+  public String getHost() {
+    return this.host;
+  }
+  
+  public final InetAddress getHostAddress() {
+    return InetAddressUtil.toInetAddress(this.getHost());
+  }
+
+  // -------------------------------------------------------------------------
+  //   Operations
+  // -------------------------------------------------------------------------
+  
+  public final String getLog() {
+    String childTail = null;
+    String mainTail = null;
+    GemFireVM vm = getGemFireVM();
+    if (vm != null) {
+      String[] log = vm.getSystemLogs();
+      if (log != null && log.length > 0) mainTail = log[0];
+      if (log != null && log.length > 1) childTail = log[1];
+    }
+    
+    if (childTail == null && mainTail == null) {
+      return LocalizedStrings.SystemMemberImpl_NO_LOG_FILE_CONFIGURED_LOG_MESSAGES_WILL_BE_DIRECTED_TO_STDOUT.toLocalizedString();
+    } 
+    else {
+      StringBuffer result = new StringBuffer();
+      if (mainTail != null) {
+        result.append(mainTail);
+      }
+      if (childTail != null) {
+        result.append("\n" + LocalizedStrings.SystemMemberImpl_TAIL_OF_CHILD_LOG.toLocalizedString() + "\n");
+        result.append(childTail);
+      }
+      return result.toString();
+    }
+  }
+
+  public final java.util.Properties getLicense() {
+    GemFireVM vm = getGemFireVM();
+    if (vm == null) return null;
+    return new Properties();
+  }
+
+  public final String getVersion() {
+    GemFireVM vm = getGemFireVM();
+    if (vm == null) return null;
+    return vm.getVersionInfo();
+  }
+
+  public StatisticResource[] getStat(String statisticsTypeName) 
+  throws com.gemstone.gemfire.admin.AdminException {
+    StatisticResource[] res = new StatisticResource[0];
+    if (this.vm != null) {
+      res = getStatsImpl(this.vm.getStats(statisticsTypeName));
+    }
+    return res.length==0 ? null : res;
+  }
+
+  public StatisticResource[] getStats() 
+  throws com.gemstone.gemfire.admin.AdminException {
+    StatisticResource[] statsImpl = new StatisticResource[0];
+    if (this.vm != null) {
+      statsImpl = getStatsImpl(this.vm.getStats(null));
+    }
+    return statsImpl;
+  }
+
+  public final boolean hasCache() {
+    GemFireVM member = getGemFireVM();
+    if (member == null) {
+      return false;
+
+    } else {
+      return member.getCacheInfo() != null;
+    }
+  }
+
+  public final SystemMemberCache getCache()
+    throws com.gemstone.gemfire.admin.AdminException
+  {
+    GemFireVM vm = getGemFireVM(); // fix for bug 33505
+    if (vm == null) return null;
+    try {
+      return createSystemMemberCache(vm);
+
+    } catch (CancelException ex) {
+      return null;
+
+    } catch (CacheDoesNotExistException ex) {
+      return null;
+    }
+  }
+  
+  public void refreshConfig() 
+  throws com.gemstone.gemfire.admin.AdminException {
+    GemFireVM vm = getGemFireVM();
+    if (vm == null) return;
+    refreshConfig(vm.getConfig());
+  }
+  
+  /**
+   * Sets the value of this system member's distribution-related
+   * configuration based on the given <code>Config</code> object.
+   */
+  public final void refreshConfig(Config config) 
+  throws com.gemstone.gemfire.admin.AdminException {
+    if (config == null) {
+      throw new AdminException(LocalizedStrings.SystemMemberImpl_FAILED_TO_REFRESH_CONFIGURATION_PARAMETERS_FOR_0.toLocalizedString(new Object[] {getId()}));
+    }
+    
+    String[] names = config.getAttributeNames();
+    if (names == null || names.length < 1) {
+      throw new AdminException(LocalizedStrings.SystemMemberImpl_FAILED_TO_REFRESH_CONFIGURATION_PARAMETERS_FOR_0.toLocalizedString(new Object[] {getId()}));
+    }
+    
+    for (int i = 0; i < names.length; i++) {
+      String name = names[i];
+      Object value = config.getAttributeObject(name);
+      if (value != null) {
+        ConfigurationParameter parm = createConfigurationParameter(
+              name,                                 // name
+              config.getAttributeDescription(name), // description
+              value,      // value
+              config.getAttributeType(name),        // valueType
+              config.isAttributeModifiable(name) ); // isModifiable
+        ((ConfigurationParameterImpl) parm).addConfigurationParameterListener(this);
+        this.parms.put(name, parm);
+      }
+    }
+  }
+  
+  public final ConfigurationParameter[] getConfiguration() {
+    ConfigurationParameter[] array =
+      new ConfigurationParameter[this.parms.size()];
+    this.parms.values().toArray(array);
+    return array;
+  }
+  
+  public ConfigurationParameter[]
+    setConfiguration(ConfigurationParameter[] parms) 
+    throws AdminException {
+
+    for (int i = 0; i < parms.length; i++) {
+      ConfigurationParameter parm = parms[i];
+      this.parms.put(parm.getName(), parm);
+    }
+
+    GemFireVM vm = getGemFireVM();
+    if (vm != null) {
+      // update internal vm's config...    
+      Config config = vm.getConfig();
+      for (int i = 0; i < parms.length; i++) {
+        config.setAttributeObject(parms[i].getName(), parms[i].getValue(), ConfigSource.runtime());
+      }
+      vm.setConfig(config);
+    }
+
+    return this.getConfiguration();
+  }
+  
+  public SystemMemberType getType() {
+    return SystemMemberType.APPLICATION;
+  }
+  
+  // -------------------------------------------------------------------------
+  //   Listener callbacks
+  // -------------------------------------------------------------------------
+  
+  // -- com.gemstone.gemfire.admin.internal.ConfigurationParameterListener ---
+  public void configurationParameterValueChanged(ConfigurationParameter parm) {
+    try {
+      setConfiguration(new ConfigurationParameter[] { parm });
+    } catch (com.gemstone.gemfire.admin.AdminException e) {
+      // this shouldn't occur since this is a config listener method...
+      logger.warn(e.getMessage(), e);
+      throw new RuntimeAdminException(e);
+    } catch (java.lang.Exception e) {
+      logger.warn(e.getMessage(), e);
+    }
+//    catch (java.lang.RuntimeException e) {
+//      logWriter.warning(e);
+//      throw 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 (java.lang.Error 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();
+      logger.error(e.getMessage(), e);
+      throw e;
+    }
+  }
+  
+  // -------------------------------------------------------------------------
+  //   Overridden method(s) from java.lang.Object
+  // -------------------------------------------------------------------------
+  
+  @Override
+  public String toString() {
+    return getName();
+  }
+  
+  // -------------------------------------------------------------------------
+  //   Template methods with default behavior impl'ed.  Override if needed.
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Returns the <code>GemFireVM</code> that underlies this
+   * <code>SystemMember</code>. 
+   */
+  protected final GemFireVM getGemFireVM() {
+    return this.vm;
+  }
+
+  /**
+   * Sets the <code>GemFireVM</code> that underlies this
+   * <code>SystemMember</code>.  This method is used when a member,
+   * such as a cache server, is started by the admin API.
+   */
+  void setGemFireVM(GemFireVM vm) throws AdminException {
+    this.vm = vm;
+    if (vm != null) {
+      this.internalId = vm.getId();
+      this.id = this.internalId.toString();
+      this.name = vm.getName();
+      this.host = InetAddressUtil.toString(vm.getHost());
+    } else {
+      this.internalId = null;
+      this.id = null;
+      // leave this.name set to what it is (how come?)
+      this.host = this.getHost();
+    }
+
+    if (DistributionConfig.DEFAULT_NAME.equals(this.name)) {
+      // Fix bug 32877
+      this.name = this.id;
+    }
+
+    if (vm != null) {
+      this.refreshConfig();
+    }
+  }
+
+  /**
+   * Updates this SystemMember instance using the corresponding
+   * InternalDistributedMember
+   * 
+   * @param member
+   *          InternalDistributedMember instance to update this SystemMember
+   *          
+   * @since 6.5
+   */
+  private void updateByInternalDistributedMember(
+      InternalDistributedMember member) {
+    if (member != null) {
+      this.internalId = member;
+      this.id         = this.internalId.toString();
+      this.host       = this.internalId.getHost();
+      this.name       = this.internalId.getName();      
+      if (this.name == null || 
+          DistributionConfig.DEFAULT_NAME.equals(this.name)) { 
+        /*
+         * name could be null & referring to description of a fix for 32877
+         */
+        this.name = this.id;
+      }
+    }
+  }
+  
+  /**
+   * Template method for creating {@link StatisticResource}.
+   *
+   * @param stat  the internal stat resource to wrap with {@link StatisticResource}
+   * @return new impl instance of {@link StatisticResource}
+   */
+  protected StatisticResource createStatisticResource(StatResource stat)
+  throws com.gemstone.gemfire.admin.AdminException {
+    return new StatisticResourceImpl(stat, this);
+  }
+  
+  /**
+   * Template method for creating {@link ConfigurationParameter}.
+   *
+   * @param name            the name of this parameter which cannot change
+   * @param description     full description to use
+   * @param value           the value of this parameter
+   * @param type            the class type of the value
+   * @param userModifiable  true if this is modifiable; false if read-only
+   * @return new impl instance of {@link ConfigurationParameter}
+   */
+  protected ConfigurationParameter createConfigurationParameter(String name,
+                                                                String description,
+                                                                Object value,
+                                                                Class type,
+                                                                boolean userModifiable) {
+    return new ConfigurationParameterImpl(
+        name, description, value, type, userModifiable);
+  }
+  
+  /**
+   * Template method for creating {@link SystemMemberCache}.
+   *
+   * @param vm  the GemFire vm to retrieve cache info from
+   * @return new impl instance of {@link SystemMemberCache}
+   */
+  protected SystemMemberCache createSystemMemberCache(GemFireVM vm)
+    throws com.gemstone.gemfire.admin.AdminException
+  {
+    return new SystemMemberCacheImpl(vm);
+  }
+
+  /** Wrap the internal stats with impls of {@link StatisticResource} */
+  protected StatisticResource[] getStatsImpl(StatResource[] stats)
+  throws com.gemstone.gemfire.admin.AdminException {
+    List statList = new ArrayList();
+    for (int i = 0; i < stats.length; i++) {
+      statList.add(createStatisticResource(stats[i]));
+    }
+    return (StatisticResource[]) statList.toArray(new StatisticResource[0]);
+  }
+
+  public String[] getRoles() {
+    Set roles = this.internalId.getRoles();
+    String[] roleNames = new String[roles.size()];
+    Iterator iter = roles.iterator();
+    for (int i = 0; i < roleNames.length; i++) {
+      Role role = (Role) iter.next();
+      roleNames[i] = role.getName();
+    }
+    return roleNames;
+  }
+  
+  public DistributedMember getDistributedMember() {
+    return this.internalId;    
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberRegionEventImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberRegionEventImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberRegionEventImpl.java
new file mode 100644
index 0000000..13f845f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberRegionEventImpl.java
@@ -0,0 +1,54 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.*;
+import com.gemstone.gemfire.distributed.DistributedMember;
+import com.gemstone.gemfire.cache.Operation;
+
+/**
+ * An event that describes an operation on a region.
+ * Instances of this are delivered to a {@link SystemMemberCacheListener} when a
+ * a region comes or goes.
+ *
+ * @author Darrel Schneider
+ * @since 5.0
+ */
+public class SystemMemberRegionEventImpl
+  extends SystemMemberCacheEventImpl
+  implements SystemMemberRegionEvent
+{
+
+  /** 
+   * The path of region created/destroyed 
+   */
+  private final String regionPath;
+
+  ///////////////////////  Constructors  ///////////////////////
+
+  /**
+   * Creates a new <code>SystemMemberRegionEvent</code> for the member
+   * with the given id.
+   */
+  protected SystemMemberRegionEventImpl(DistributedMember id, Operation op, String regionPath) {
+    super(id, op);
+    this.regionPath = regionPath;
+  }
+
+  /////////////////////  Instance Methods  /////////////////////
+
+  public String getRegionPath() {
+    return this.regionPath;
+  }
+
+  @Override
+  public String toString() {
+    return super.toString() + " region=" + this.regionPath;
+  }
+
+}


[10/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExplicitConnectionSourceImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExplicitConnectionSourceImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExplicitConnectionSourceImpl.java
new file mode 100644
index 0000000..a1bdc16
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExplicitConnectionSourceImpl.java
@@ -0,0 +1,341 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException; 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.cache.util.EndpointDoesNotExistException;
+import com.gemstone.gemfire.cache.util.EndpointExistsException;
+import com.gemstone.gemfire.cache.util.EndpointInUseException;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ServerQueueStatus;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.security.GemFireSecurityException;
+
+/**
+ * A connection source where the list of endpoints is specified explicitly. 
+ * @author dsmith
+ * @since 5.7
+ * 
+ * TODO - the UnusedServerMonitor basically will force the pool to
+ * have at least one connection to each server. Maybe we need to have it
+ * create connections that are outside the pool?
+ *
+ */
+public class ExplicitConnectionSourceImpl implements ConnectionSource {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  private List serverList;
+  private int nextServerIndex = 0;
+  private int nextQueueIndex = 0;
+  private InternalPool pool;
+  
+  /**
+   * A debug flag, which can be toggled by tests to disable/enable shuffling of
+   * the endpoints list
+   */
+  private boolean DISABLE_SHUFFLING = Boolean
+      .getBoolean("gemfire.bridge.disableShufflingOfEndpoints");
+
+  public ExplicitConnectionSourceImpl(List/*<InetSocketAddress>*/contacts) {
+    ArrayList serverList = new ArrayList(contacts.size());
+    for(int i = 0; i < contacts.size(); i++) {
+      InetSocketAddress addr = (InetSocketAddress)contacts.get(i);
+      serverList.add(new ServerLocation(addr.getHostName(), addr.getPort()));
+    }
+    shuffle(serverList);
+    this.serverList = Collections.unmodifiableList(serverList);
+  }
+
+  public synchronized void start(InternalPool pool) {
+    this.pool = pool;
+    pool.getStats().setInitialContacts(serverList.size());
+  }
+  
+  public void stop() {
+    //do nothing
+  }
+
+  public ServerLocation findReplacementServer(ServerLocation currentServer, Set/*<ServerLocation>*/ excludedServers) {
+    // at this time we always try to find a server other than currentServer
+    // and if we do return it. Otherwise return null;
+    // @todo grid: We could add balancing information to the explicit source
+    // so that clients would attempt to keep the same number of connections
+    // to each server but it would be a bit of work.
+    // Plus we need to make sure it would work ok for hardware load balancers.
+    HashSet excludedPlusCurrent = new HashSet(excludedServers);
+    excludedPlusCurrent.add(currentServer);
+    return findServer(excludedPlusCurrent);
+  }
+  
+  public synchronized ServerLocation findServer(Set excludedServers) {
+    if(PoolImpl.TEST_DURABLE_IS_NET_DOWN) {
+      return null;
+    }
+    ServerLocation nextServer;
+    int startIndex = nextServerIndex;
+    do {
+      nextServer = (ServerLocation) serverList.get(nextServerIndex);
+      if(++nextServerIndex >= serverList.size()) {
+        nextServerIndex = 0;
+      }
+      if(!excludedServers.contains(nextServer)) {
+        return nextServer;
+      }
+    } while(nextServerIndex != startIndex);
+    
+    return null;
+  }
+  
+  /**
+   * TODO - this algorithm could be cleaned up. Right now we have to
+   * connect to every server in the system to find where our durable
+   * queue lives.
+   */
+  public synchronized List findServersForQueue(Set excludedServers,
+      int numServers, ClientProxyMembershipID proxyId, boolean findDurableQueue) {
+    if(PoolImpl.TEST_DURABLE_IS_NET_DOWN) {
+      return new ArrayList();
+    }
+    if(numServers == -1) {
+      numServers = Integer.MAX_VALUE;
+    }
+    if(findDurableQueue && proxyId.isDurable()) {
+      return findDurableQueues(excludedServers, numServers);
+    } else {
+      return pickQueueServers(excludedServers, numServers);
+    }
+  }
+  
+  /**
+   * Remove an endpoint from this connection source.
+   * 
+   * @param host
+   * @param port
+   * @throws EndpointDoesNotExistException if the <code>Endpoint</code> to be
+   * removed doesn't exist.
+   */
+  public synchronized void removeEndpoint(String host,int port) throws EndpointInUseException,EndpointDoesNotExistException {
+    serverList = new ArrayList(serverList);
+    Iterator it = serverList.iterator();
+    boolean found = false;
+    host = lookupHostName(host);
+    while(it.hasNext()) {
+      ServerLocation loc = (ServerLocation)it.next();
+      if(loc.getHostName().equalsIgnoreCase(host)) {
+        if(loc.getPort()==port) {
+          EndpointManager em = pool.getEndpointManager();
+          if(em.getEndpointMap().containsKey(loc)) {
+            throw new EndpointInUseException("Endpoint in use cannot be removed:"+loc);
+          } else {
+            it.remove();
+            found = true;
+          }
+        }
+      }
+    }
+    serverList = Collections.unmodifiableList(serverList);
+    if(!found) {
+      throw new EndpointDoesNotExistException("endpointlist:"+serverList,host,port);
+    }
+  }
+  
+  /**
+   * Add an endpoint to this connection source.
+   * 
+   * @param host
+   * @param port
+   * @throws EndpointExistsException if the <code>Endpoint</code> to be
+   * added already exists.
+   */
+  public synchronized void addEndpoint(String host,int port) throws EndpointExistsException {
+    Iterator it = serverList.iterator();
+    host = lookupHostName(host);
+    while(it.hasNext()) {
+      ServerLocation loc = (ServerLocation)it.next();
+      if(loc.getHostName().equalsIgnoreCase(host)) {
+        if(loc.getPort()==port) {
+          throw new EndpointExistsException("Endpoint already exists host="+host+" port="+port);
+        }
+      }
+    }
+    serverList = new ArrayList(serverList);
+    serverList.add(new ServerLocation(host,port));
+    serverList = Collections.unmodifiableList(serverList);
+  }
+ 
+  /**
+   * When we create an ExplicitConnectionSource, we convert a the hostname of an
+   * endpoint from a string to an InetAddress and back. This method duplicates
+   * that process for endpoints that are added or removed after the fact.
+   */
+  private String lookupHostName(String host) {
+    try {
+      InetAddress hostAddr = InetAddress.getByName(host);
+      host = hostAddr.getHostName();
+    } catch (UnknownHostException cause) {
+      IllegalArgumentException ex = new IllegalArgumentException("Unknown host " + host);
+      ex.initCause(cause);
+      throw ex;
+    }
+    return host;
+  } 
+
+  public boolean isBalanced() {
+    return false;
+  }
+  
+  private List pickQueueServers(Set excludedServers,
+      int numServers) {
+    
+    ArrayList result = new ArrayList();
+    ServerLocation nextQueue;
+    int startIndex = nextQueueIndex;
+    do {
+      nextQueue= (ServerLocation) serverList.get(nextQueueIndex);
+      if(++nextQueueIndex >= serverList.size()) {
+        nextQueueIndex = 0;
+      }
+      if(!excludedServers.contains(nextQueue)) {
+        result.add(nextQueue);
+      }
+    } while(nextQueueIndex != startIndex && result.size() < numServers);
+    
+    return result;
+  }
+
+  /**
+   * a "fake" operation which just extracts the queue status from the connection
+   */
+  private static class HasQueueOp implements Op {
+    public static final HasQueueOp SINGLETON = new HasQueueOp();
+    public Object attempt(Connection cnx) throws Exception {
+      ServerQueueStatus status = cnx.getQueueStatus();
+      return status.isNonRedundant() ? Boolean.FALSE : Boolean.TRUE;
+    }
+    @Override
+    public boolean useThreadLocalConnection() {
+      return false;
+    }
+  }
+  
+  private List findDurableQueues(Set excludedServers,
+      int numServers) {
+    ArrayList durableServers = new ArrayList();
+    ArrayList otherServers = new ArrayList();
+    
+    logger.debug("ExplicitConnectionSource - looking for durable queue");
+    
+    for(Iterator itr = serverList.iterator(); itr.hasNext(); ) {
+      ServerLocation server = (ServerLocation) itr.next();
+      if(excludedServers.contains(server)) {
+        continue;
+      }
+      
+      //the pool will automatically create a connection to this server
+      //and store it for future use.
+      Boolean hasQueue;
+      try {
+        hasQueue = (Boolean) pool.executeOn(server, HasQueueOp.SINGLETON);
+      } catch(GemFireSecurityException e) {
+        throw e;
+      } catch(Exception e) {
+        if(e.getCause() instanceof GemFireSecurityException) {
+          throw (GemFireSecurityException)e.getCause();
+        }
+        if(logger.isDebugEnabled()) {
+          logger.debug("Unabled to check for durable queue on server {}: {}", server, e);
+        }
+        continue;
+      }
+      if(hasQueue != null) {
+        if(hasQueue.booleanValue()) {
+          if(logger.isDebugEnabled()) {
+            logger.debug("Durable queue found on {}", server);
+          }
+          durableServers.add(server);
+        } else {
+          if(logger.isDebugEnabled()) {
+            logger.debug("Durable queue was not found on {}", server);
+          }
+          otherServers.add(server);
+        }
+      }
+    }
+
+    int remainingServers = numServers - durableServers.size();
+    if(remainingServers > otherServers.size()) {
+      remainingServers = otherServers.size();
+    }
+    //note, we're always prefering the servers in the beginning of the list
+    //but that's ok because we already shuffled the list in our constructor.
+    if(remainingServers > 0) {
+      durableServers.addAll(otherServers.subList(0, remainingServers));
+      nextQueueIndex = remainingServers % serverList.size();
+    }
+    
+    if(logger.isDebugEnabled()) {
+      logger.debug("found {} servers out of {}", durableServers.size(), numServers);
+    }
+    
+    return durableServers;
+  }
+  
+  private void shuffle(List endpoints)
+  {
+    //this check was copied from ConnectionProxyImpl
+    if (endpoints.size() < 2 || DISABLE_SHUFFLING) {
+      /*
+       * It is not safe to shuffle an ArrayList of size 1
+       * java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 at
+       * java.util.ArrayList.RangeCheck(Unknown Source) at
+       * java.util.ArrayList.get(Unknown Source) at
+       * java.util.Collections.swap(Unknown Source) at
+       * java.util.Collections.shuffle(Unknown Source)
+       */
+      return;
+    }
+    Collections.shuffle(endpoints);
+  }
+  
+  @Override
+  public String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.append("EndPoints[");
+    synchronized(this) {
+      Iterator it = serverList.iterator();
+      while(it.hasNext()) {
+        ServerLocation loc = (ServerLocation)it.next();
+        sb.append(loc.getHostName()+":"+loc.getPort());
+        if(it.hasNext()) {
+          sb.append(",");
+        }
+      }
+    }
+    sb.append("]");
+    return sb.toString();
+  }
+  
+  ArrayList<ServerLocation> getAllServers() {
+    ArrayList<ServerLocation> list = new ArrayList<ServerLocation>();
+    list.addAll(this.serverList);
+    return list;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetAllOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetAllOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetAllOp.java
new file mode 100644
index 0000000..14c55e5
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetAllOp.java
@@ -0,0 +1,233 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.ArrayList;
+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.cache.Region;
+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.Version;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+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.VersionedObjectList;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * Does a region getAll on a server
+ * @author darrel
+ * @since 5.7
+ */
+public class GetAllOp {
+  
+  private static final Logger logger = LogService.getLogger();
+  
+  /**
+   * Does a region getAll 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 getAll on
+   * @param keys list of keys to get
+   * @return the map of values found by the getAll if any
+   */
+  public static VersionedObjectList execute(ExecutablePool pool,
+                                               String region,
+                                               List keys,
+                                               Object callback)
+  {
+    AbstractOp op = new GetAllOpImpl(region, keys, callback);
+    op.initMessagePart();
+    return ((VersionedObjectList)pool.execute(op)).setKeys(keys);
+  }
+  
+  public static VersionedObjectList execute(ExecutablePool pool,
+      Region region, List keys, int retryAttempts, Object callback) {
+    AbstractOp op = new GetAllOpImpl(region.getFullPath(), keys, callback);
+    ClientMetadataService cms = ((LocalRegion)region).getCache()
+        .getClientMetadataService();
+
+    Map<ServerLocation, HashSet> serverToFilterMap = cms.getServerToFilterMap(
+        keys, region, true);
+    
+    if (serverToFilterMap == null || serverToFilterMap.isEmpty()) {
+      op.initMessagePart();
+      return ((VersionedObjectList)pool.execute(op)).setKeys(keys);
+    }
+    else {
+      VersionedObjectList result = null;
+      ServerConnectivityException se = null;
+      List retryList = new ArrayList();
+      List callableTasks = constructGetAllTasks(region.getFullPath(),
+          serverToFilterMap, (PoolImpl)pool, callback);
+      Map<ServerLocation, Object> results = SingleHopClientExecutor.submitGetAll(
+          serverToFilterMap, callableTasks, cms, (LocalRegion)region);
+      for (ServerLocation server : results.keySet()) {
+        Object serverResult = results.get(server);
+        if (serverResult instanceof ServerConnectivityException) {
+          se = (ServerConnectivityException)serverResult;
+          retryList.addAll(serverToFilterMap.get(server));
+        }
+        else {
+          if (result == null) {
+            result = (VersionedObjectList)serverResult;
+          } else {
+            result.addAll((VersionedObjectList)serverResult);
+          }
+        }
+      }
+      
+      if (se != null) {
+        if (retryAttempts == 0) {
+          throw se;
+        }
+        else {
+          VersionedObjectList retryResult = GetAllOp.execute(pool,
+              region.getFullPath(), retryList, callback);
+          if (result == null) {
+            result = retryResult;
+          } else {
+            result.addAll(retryResult);
+          }
+        }
+      }
+
+      return result;
+    }
+  }
+  
+  private GetAllOp() {
+    // no instances allowed
+  }
+  
+  static List constructGetAllTasks(String region,
+      final Map<ServerLocation, HashSet> serverToFilterMap, final PoolImpl pool, final Object callback) {
+    final List<SingleHopOperationCallable> tasks = new ArrayList<SingleHopOperationCallable>();
+    ArrayList<ServerLocation> servers = new ArrayList<ServerLocation>(
+        serverToFilterMap.keySet());
+
+    if (logger.isDebugEnabled()) {
+      logger.debug("Constructing tasks for the servers {}", servers);
+    }
+    for (ServerLocation server : servers) {
+      Set filterSet = serverToFilterMap.get(server);
+      AbstractOp getAllOp = new GetAllOpImpl(region, new ArrayList(filterSet), callback);
+
+      SingleHopOperationCallable task = new SingleHopOperationCallable(
+          new ServerLocation(server.getHostName(), server.getPort()), pool,
+          getAllOp,UserAttributes.userAttributes.get());
+      tasks.add(task);
+    }
+    return tasks;
+  }
+  
+  static class GetAllOpImpl extends AbstractOp {
+    
+    private List keyList;
+    private final Object callback;
+    
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public GetAllOpImpl(String region,
+                        List keys,
+                        Object callback)
+    {
+      super(callback != null ? MessageType.GET_ALL_WITH_CALLBACK : MessageType.GET_ALL_70, 3);
+      this.keyList = keys;
+      this.callback = callback;
+      getMessage().addStringPart(region);
+    }
+        
+    @Override
+    protected void initMessagePart() {
+      Object[] keysArray = new Object[this.keyList.size()];
+      this.keyList.toArray(keysArray);
+      getMessage().addObjPart(keysArray);
+      if (this.callback != null) {
+        getMessage().addObjPart(this.callback);
+      } else {
+        // using the old GET_ALL_70 command that expects an int saying we are not register interest
+        getMessage().addIntPart(0);
+      }
+    }
+    
+    public List getKeyList() {
+      return this.keyList;
+    }
+
+
+    @Override  
+    protected Message createResponseMessage() {
+      return new ChunkedMessage(1, Version.CURRENT);
+    }
+    
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override  
+    protected Object processResponse(Message msg, final Connection con) throws Exception {
+      final VersionedObjectList result = new VersionedObjectList(false);
+      final Exception[] exceptionRef = new Exception[1];
+      processChunkedResponse((ChunkedMessage)msg,
+                             "getAll",
+                             new ChunkHandler() {
+                               public void handle(ChunkedMessage cm) throws Exception {
+                                 Part part = cm.getPart(0);
+                                 try {
+                                   Object o = part.getObject();
+                                   if (o instanceof Throwable) {
+                                     String s = "While performing a remote getAll";
+                                     exceptionRef[0] = new ServerOperationException(s, (Throwable)o);
+                                   } else {
+                                     VersionedObjectList chunk = (VersionedObjectList)o;
+                                     chunk.replaceNullIDs(con.getEndpoint().getMemberId());
+                                     result.addAll(chunk);
+                                   }
+                                 } catch(Exception e) {
+                                   exceptionRef[0] = new ServerOperationException("Unable to deserialize value" , e);
+                                 }
+                               }
+                             });
+      if (exceptionRef[0] != null) {
+        throw exceptionRef[0];
+      } else {
+        return result;
+      }
+    }
+
+    @Override  
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.GET_ALL_DATA_ERROR;
+    }
+
+    @Override  
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startGetAll();
+    }
+    @Override  
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endGetAllSend(start, hasFailed());
+    }
+    @Override  
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endGetAll(start, hasTimedOut(), hasFailed());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetClientPRMetaDataOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetClientPRMetaDataOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetClientPRMetaDataOp.java
new file mode 100755
index 0000000..b334ea0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetClientPRMetaDataOp.java
@@ -0,0 +1,162 @@
+/*
+ * ========================================================================= 
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved. 
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ * =========================================================================
+ */
+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().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.");
+          }
+          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/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetClientPartitionAttributesOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetClientPartitionAttributesOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetClientPartitionAttributesOp.java
new file mode 100755
index 0000000..7e96f4d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetClientPartitionAttributesOp.java
@@ -0,0 +1,169 @@
+/*
+ * ========================================================================= 
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved. 
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ * =========================================================================
+ */
+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().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/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetEntryOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetEntryOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetEntryOp.java
new file mode 100644
index 0000000..9b6cd09
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetEntryOp.java
@@ -0,0 +1,73 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import com.gemstone.gemfire.internal.cache.EntrySnapshot;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.cache.tier.MessageType;
+import com.gemstone.gemfire.internal.cache.tier.sockets.Message;
+
+/**
+ * does getEntry on the server
+ * @author sbawaska
+ */
+public class GetEntryOp {
+
+  /**
+   * Does a region.getEntry on the server using the given pool
+   * @param pool
+   * @param region
+   * @param key
+   * @return an {@link EntrySnapshot} for the given key
+   */
+  public static Object execute(ExecutablePool pool, LocalRegion region,
+      Object key) {
+    AbstractOp op = new GetEntryOpImpl(region, key);
+    return pool.execute(op);
+  }
+  
+  static class GetEntryOpImpl extends AbstractOp {
+
+    private LocalRegion region;
+    private Object key;
+    public GetEntryOpImpl(LocalRegion region, Object key) {
+      super(MessageType.GET_ENTRY, 2);
+      this.region = region;
+      this.key = key;
+      getMessage().addStringPart(region.getFullPath());
+      getMessage().addStringOrObjPart(key);
+    }
+
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      EntrySnapshot snap = (EntrySnapshot) processObjResponse(msg, "getEntry");
+      if (snap != null) {
+        snap.region = region;
+      }
+      return snap;
+    }
+
+    @Override
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.REQUESTDATAERROR;
+    }
+
+    @Override  
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startGetEntry();
+    }
+    @Override  
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endGetEntrySend(start, hasFailed());
+    }
+    @Override  
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endGetEntry(start, hasTimedOut(), hasFailed());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetEventValueOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetEventValueOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetEventValueOp.java
new file mode 100755
index 0000000..e1ebe57
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetEventValueOp.java
@@ -0,0 +1,113 @@
+/*
+ * ========================================================================= 
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved. 
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ * =========================================================================
+ */
+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().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/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetFunctionAttributeOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetFunctionAttributeOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetFunctionAttributeOp.java
new file mode 100644
index 0000000..b727f4e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetFunctionAttributeOp.java
@@ -0,0 +1,75 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().send(false);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetOp.java
new file mode 100644
index 0000000..019da2e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetOp.java
@@ -0,0 +1,241 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.CacheLoaderException;
+import com.gemstone.gemfire.cache.Operation;
+import com.gemstone.gemfire.cache.client.AllConnectionsInUseException;
+import com.gemstone.gemfire.cache.client.ServerConnectivityException;
+import com.gemstone.gemfire.cache.client.ServerOperationException;
+import com.gemstone.gemfire.cache.util.BridgeWriterException;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.cache.Token;
+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.cache.versions.VersionTag;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * Does a region get on a server
+ * @author darrel
+ * @since 5.7
+ */
+public class GetOp {
+  private static final Logger logger = LogService.getLogger();
+  
+  public static final int HAS_CALLBACK_ARG = 0x01;
+  public static final int HAS_VERSION_TAG = 0x02;
+  public static final int KEY_NOT_PRESENT = 0x04;
+  public static final int VALUE_IS_INVALID = 0x08; // Token.INVALID
+
+  /**
+   * Does a region get 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 region to do the get on
+   * @param key the entry key to do the get on
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   * @param clientEvent holder for returning version information
+   * @return the entry value found by the get if any
+   */
+  public static Object execute(ExecutablePool pool, LocalRegion region,
+      Object key, Object callbackArg, boolean prSingleHopEnabled, EntryEventImpl clientEvent) {
+    ClientMetadataService cms = ((GemFireCacheImpl)region.getCache())
+        .getClientMetadataService();
+    AbstractOp op = new GetOpImpl(region, key, callbackArg,
+        prSingleHopEnabled, clientEvent);
+
+    if (logger.isDebugEnabled()) {
+      logger.debug("GetOp invoked for key {}", key);
+    }
+    if (prSingleHopEnabled) {
+      ServerLocation server = cms.getBucketServerLocation(region,
+          Operation.GET, key, null, callbackArg);
+        if (server != null) {
+          try {
+            PoolImpl poolImpl = (PoolImpl)pool;
+            boolean onlyUseExistingCnx = ((poolImpl.getMaxConnections() != -1 && poolImpl
+                .getConnectionCount() >= poolImpl.getMaxConnections()) ? true
+                : false);
+            return pool.executeOn(new ServerLocation(server.getHostName(),
+                server.getPort()), op, true, onlyUseExistingCnx);
+          }
+          catch (AllConnectionsInUseException e) {
+          }
+          catch (ServerConnectivityException e) {
+            if (e instanceof ServerOperationException) {
+              throw e; // fixed 44656
+            }
+            cms.removeBucketServerLocation(server);
+          }
+          catch (BridgeWriterException e) {
+            if (e.getCause() instanceof ServerConnectivityException)
+              cms.removeBucketServerLocation(server);
+          }
+          catch (CacheLoaderException e) {
+            if (e.getCause() instanceof ServerConnectivityException)
+              cms.removeBucketServerLocation(server);
+          }
+        }
+    }
+    return pool.execute(op);
+  }
+
+                                                               
+  private GetOp() {
+    // no instances allowed
+  }
+  
+  static class GetOpImpl extends AbstractOp {
+    
+    private LocalRegion region=null ;
+    
+    private boolean prSingleHopEnabled = false;
+
+    private Object key;
+
+    private Object callbackArg;
+
+    private EntryEventImpl clientEvent;
+    
+    public String toString() {
+      return "GetOpImpl(key="+key+")";
+    }
+    
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public GetOpImpl(LocalRegion region,
+                     Object key,
+                     Object callbackArg,
+                     boolean prSingleHopEnabled, 
+                     EntryEventImpl clientEvent) {
+      super(MessageType.REQUEST, callbackArg != null ? 3 : 2);
+      if (logger.isDebugEnabled()) {
+        logger.debug("constructing a GetOp for key {}", key/*, new Exception("stack trace")*/);
+      }
+      this.region = region ;
+      this.prSingleHopEnabled = prSingleHopEnabled;
+      this.key = key ;
+      this.callbackArg = callbackArg;
+      this.clientEvent = clientEvent;
+      getMessage().addStringPart(region.getFullPath());
+      getMessage().addStringOrObjPart(key);
+      if (callbackArg != null) {
+        getMessage().addObjPart(callbackArg);
+      }
+    }
+    
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      throw new UnsupportedOperationException(); // version tag processing requires the connection
+    }
+    
+    @Override
+    protected Object processResponse(Message msg, Connection con) throws Exception {
+      Object object = processObjResponse(msg, "get");
+      if (msg.getNumberOfParts() > 1) {
+        int partIdx = 1;
+        int flags = msg.getPart(partIdx++).getInt();
+        if ((flags & HAS_CALLBACK_ARG) != 0) {
+          msg.getPart(partIdx++).getObject(); // callbackArg
+        }
+        // if there's a version tag
+        if ((object == null)  &&  ((flags & VALUE_IS_INVALID) != 0)) {
+          object = Token.INVALID;
+        }
+        if ((flags & HAS_VERSION_TAG) != 0) {
+          VersionTag tag = (VersionTag)msg.getPart(partIdx++).getObject();
+          assert con != null; // for debugging
+          assert con.getEndpoint() != null; //for debugging
+          assert tag != null; // for debugging
+          tag.replaceNullIDs((InternalDistributedMember) con.getEndpoint().getMemberId());
+          if (this.clientEvent != null) {
+            this.clientEvent.setVersionTag(tag);
+          }
+          if ((flags & KEY_NOT_PRESENT) != 0) {
+            object = Token.TOMBSTONE;
+          }
+        }
+        if (prSingleHopEnabled && msg.getNumberOfParts() > partIdx) {
+          byte version = 0;
+          int noOfMsgParts = msg.getNumberOfParts();
+          if (noOfMsgParts == partIdx+1) {
+            Part part = msg.getPart(partIdx++);
+            if (part.isBytes()) {
+              byte[] bytesReceived = part.getSerializedForm();
+              if (bytesReceived[0] != ClientMetadataService.INITIAL_VERSION
+                  && bytesReceived.length == ClientMetadataService.SIZE_BYTES_ARRAY_RECEIVED) {
+                ClientMetadataService cms;
+                try {
+                  cms = region.getCache().getClientMetadataService();
+                  version = cms.getMetaDataVersion(region, Operation.UPDATE, key,
+                      null, callbackArg);
+                }
+                catch (CacheClosedException e) {
+                  return null;
+                }
+                if (bytesReceived[0] != version) {
+                  cms.scheduleGetPRMetaData(region, false,bytesReceived[1]);
+                }
+              }
+            }
+          }
+          else if (noOfMsgParts == partIdx+2) {
+            msg.getPart(partIdx++).getObject(); // callbackArg
+            Part part = msg.getPart(partIdx++);
+            if (part.isBytes()) {
+              byte[] bytesReceived = part.getSerializedForm();
+              if (this.region != null
+                  && bytesReceived.length == ClientMetadataService.SIZE_BYTES_ARRAY_RECEIVED) {
+                ClientMetadataService cms;
+                try {
+                  cms = region.getCache().getClientMetadataService();
+                  version = cms.getMetaDataVersion(region, Operation.UPDATE, key,
+                      null, callbackArg);
+                }
+                catch (CacheClosedException e) {
+                  return null;
+                }
+                if (bytesReceived[0] != version) {
+                  cms.scheduleGetPRMetaData(region, false,bytesReceived[1]);
+                }
+              }
+            }
+          }
+        }
+      }
+      return object;
+    }
+    @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/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXEnumByIdOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXEnumByIdOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXEnumByIdOp.java
new file mode 100644
index 0000000..c2a8f34
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXEnumByIdOp.java
@@ -0,0 +1,85 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014, Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().send(false);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXEnumsOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXEnumsOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXEnumsOp.java
new file mode 100644
index 0000000..3326733
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXEnumsOp.java
@@ -0,0 +1,103 @@
+/*=========================================================================
+ * Copyright (c) 2012 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().send(false);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXIdForEnumOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXIdForEnumOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXIdForEnumOp.java
new file mode 100644
index 0000000..4379823
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXIdForEnumOp.java
@@ -0,0 +1,106 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014, Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().send(false);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXIdForTypeOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXIdForTypeOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXIdForTypeOp.java
new file mode 100644
index 0000000..f4ea18e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXIdForTypeOp.java
@@ -0,0 +1,106 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().send(false);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXTypeByIdOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXTypeByIdOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXTypeByIdOp.java
new file mode 100644
index 0000000..6ea5e3d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXTypeByIdOp.java
@@ -0,0 +1,85 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().send(false);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXTypesOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXTypesOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXTypesOp.java
new file mode 100644
index 0000000..162cd35
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/GetPDXTypesOp.java
@@ -0,0 +1,103 @@
+/*=========================================================================
+ * Copyright (c) 2012 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().send(false);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/InstantiatorRecoveryListener.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/InstantiatorRecoveryListener.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/InstantiatorRecoveryListener.java
new file mode 100644
index 0000000..eeb8e1b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/InstantiatorRecoveryListener.java
@@ -0,0 +1,150 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.cache.client.internal.PoolImpl.PoolTask;
+import com.gemstone.gemfire.internal.InternalInstantiator;
+import com.gemstone.gemfire.internal.cache.EventID;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+
+/**
+ * A listener which will try to resend the instantiators to all servers if the
+ * entire server distributed system was lost and came back one line. This
+ * listener also takes care of sending the initial list of instantiators to the servers <br>
+ * <br> 
+ * TODO - There is a window in which all of the servers could crash and come
+ * back up and we would connect to a new server before realizing that all the
+ * servers crashed. To fix this, we would need to get some kind of birthdate of
+ * the server ds we connect and use that to decide if we need to recover
+ * instantiators. As it is, the window is not very large.
+ * 
+ * 
+ * @author dsmith
+ * 
+ */
+public class InstantiatorRecoveryListener extends EndpointManager.EndpointListenerAdapter {
+  private static final Logger logger = LogService.getLogger();
+  
+  private final AtomicInteger endpointCount = new AtomicInteger();
+  protected final InternalPool pool;
+  protected final ScheduledExecutorService background;
+  protected final long pingInterval;
+  protected final Object recoveryScheduledLock = new Object();
+  protected boolean recoveryScheduled;
+  
+  public InstantiatorRecoveryListener(ScheduledExecutorService background, InternalPool pool) {
+    this.pool = pool;
+    this.pingInterval = pool.getPingInterval();
+    this.background = background;
+  }
+  
+  @Override
+  public void endpointCrashed(Endpoint endpoint) {
+    int count = endpointCount.decrementAndGet();
+    if (logger.isDebugEnabled()) {
+      logger.debug("InstantiatorRecoveryTask - EndpointCrashed. Now have {} endpoints", count);
+    }
+  }
+
+  @Override
+  public void endpointNoLongerInUse(Endpoint endpoint) {
+    int count = endpointCount.decrementAndGet();
+    if (logger.isDebugEnabled()) {
+      logger.debug("InstantiatorRecoveryTask - EndpointNoLongerInUse. Now have {} endpoints", count);
+    }
+  }
+
+  @Override
+  public void endpointNowInUse(Endpoint endpoint) {
+    int count  = endpointCount.incrementAndGet();
+    final boolean isDebugEnabled = logger.isDebugEnabled();
+    if (isDebugEnabled) {
+      logger.debug("InstantiatorRecoveryTask - EndpointNowInUse. Now have {} endpoints", count);
+    }
+    if(count == 1) {
+      synchronized(recoveryScheduledLock) {
+        if(!recoveryScheduled) {
+          try {
+            recoveryScheduled = true;
+            background.execute(new RecoveryTask());
+            if (isDebugEnabled) {
+              logger.debug("InstantiatorRecoveryTask - Scheduled Recovery Task");
+            }
+          } catch(RejectedExecutionException e) {
+            //ignore, the timer has been cancelled, which means we're shutting down.
+          }
+        }
+      }
+    }
+  }
+  
+  protected class RecoveryTask extends PoolTask {
+
+    @Override
+    public void run2() {
+      if (pool.getCancelCriterion().cancelInProgress() != null) {
+        return;
+      }
+      synchronized(recoveryScheduledLock) {
+        recoveryScheduled = false;
+      }
+      Object[] objects = InternalInstantiator
+          .getInstantiatorsForSerialization();
+      if (objects.length == 0) {
+        return;
+      }
+      EventID eventId = InternalInstantiator.generateEventId();
+      //Fix for bug:40930
+      if (eventId == null) {
+        background.schedule(new RecoveryTask(), pingInterval,
+            TimeUnit.MILLISECONDS);
+        recoveryScheduled = true;
+      }
+      else {
+        try {
+          RegisterInstantiatorsOp.execute(pool, objects, eventId);
+        } 
+        catch (CancelException e) {
+          throw e;
+        }
+        catch (RejectedExecutionException e) {
+          // This is probably because we've started to shut down.
+          pool.getCancelCriterion().checkCancelInProgress(e);
+          throw e; // weird
+        }
+        catch(Exception e) {
+          pool.getCancelCriterion().checkCancelInProgress(e);
+          
+          // If an exception occurred on the server, don't retry
+          Throwable cause = e.getCause();
+          if (cause instanceof ClassNotFoundException) {
+            logger.warn(LocalizedMessage.create(
+                LocalizedStrings.InstantiatorRecoveryListener_INSTANTIATORRECOVERYTASK_ERROR_CLASSNOTFOUNDEXCEPTION,
+                cause.getMessage()));
+          } else {
+            logger.warn(LocalizedMessage.create(
+              LocalizedStrings.InstantiatorRecoveryListener_INSTANTIATORRECOVERYTASK_ERROR_RECOVERING_INSTANTIATORS),
+              e);
+          }
+        } finally {
+          pool.releaseThreadLocalConnection();
+        }
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/InternalPool.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/InternalPool.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/InternalPool.java
new file mode 100644
index 0000000..ce6b599
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/InternalPool.java
@@ -0,0 +1,34 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.Map;
+
+import java.util.concurrent.ScheduledExecutorService;
+import com.gemstone.gemfire.CancelCriterion;
+import com.gemstone.gemfire.cache.client.Pool;
+import com.gemstone.gemfire.internal.cache.PoolStats;
+
+/**
+ * The contract between a connection source and a connection pool.
+ * Provides methods for the connection source to access the cache
+ * and update the list of endpoints on the connection pool.
+ * @author dsmith
+ * @since 5.7
+ *
+ */
+public interface InternalPool extends Pool, ExecutablePool {
+  PoolStats getStats();
+  Map getEndpointMap();
+  EndpointManager getEndpointManager();
+  ScheduledExecutorService getBackgroundProcessor();
+  CancelCriterion getCancelCriterion();
+  boolean isDurableClient();
+  void detach();
+  String getPoolOrCacheCancelInProgress();
+}


[24/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskWriteAttributesFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskWriteAttributesFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskWriteAttributesFactory.java
new file mode 100755
index 0000000..a27ef9b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskWriteAttributesFactory.java
@@ -0,0 +1,254 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import java.util.Properties;
+
+import com.gemstone.gemfire.internal.cache.DiskWriteAttributesImpl;
+import com.gemstone.gemfire.internal.cache.xmlcache.CacheXml;
+
+/**
+ * Factory for getting DiskWriteAttribute objects
+ * 
+ * @author Mitul Bid
+ * @author Asif
+ * @since 5.1
+ * @deprecated as of 6.5 use {@link DiskStoreFactory} instead
+ */
+@Deprecated
+public final class DiskWriteAttributesFactory implements java.io.Serializable
+{
+  private static final long serialVersionUID = -4077746249663727235L;
+
+  private final Properties props = new Properties();
+
+  //////////// *** Methods to get instances of DWA *** //////////////
+
+  /**
+   * 
+   * Creates a new instance of DiskWriteAttributesFactory ready to create a
+   * <code>DiskWriteAttributes</code> with default settings. The default
+   * <code>DiskWriteAttributes</code> thus created will have following
+   * behaviour.
+   * <ul>
+   * <li>synchronous = false
+   * <li>auto-compact = true
+   * <li>allow-force-compaction = false
+   * <li>max-oplog-size = 1024 MB
+   * <li>time-interval = 1 sec
+   * <li>byte-threshold = 0 bytes
+   * 
+   * </ul>
+   */
+  public DiskWriteAttributesFactory() {
+
+  }
+
+  /**
+   * Creates a new instance of DiskWriteAttributesFactory Factory ready to
+   * create a <code>DiskWriteAttributes</code> with the same settings as those
+   * in the specified <code>DiskWriteAttributes</code>.
+   * 
+   * @param dwa
+   *          the <code>DiskWriteAttributes</code> used to initialize this
+   *          DiskWriteAttributesFactory
+   */
+  public DiskWriteAttributesFactory(DiskWriteAttributes dwa) {
+
+    this.props.setProperty(CacheXml.BYTES_THRESHOLD,
+        String.valueOf(dwa.getBytesThreshold()));
+    long maxOplogSizeInBytes = convertToBytes(dwa.getMaxOplogSize());
+    this.props.setProperty(CacheXml.MAX_OPLOG_SIZE,
+        String.valueOf(maxOplogSizeInBytes));
+    this.props.setProperty(CacheXml.ROLL_OPLOG,
+                           String.valueOf(dwa.isRollOplogs()));
+    this.props.setProperty(DiskWriteAttributesImpl.SYNCHRONOUS_PROPERTY, String
+        .valueOf(dwa.isSynchronous()));
+    if (dwa.getTimeInterval() > -1) {
+      this.props.setProperty(CacheXml.TIME_INTERVAL,
+          String.valueOf(dwa.getTimeInterval()));
+    }
+
+  }
+
+  /**
+   * Sets whether or not the writing to the disk is synchronous.
+   * 
+   * @param isSynchronous
+   *          boolean if true indicates synchronous writes
+   * @deprecated as of 6.5 use {@link AttributesFactory#setDiskSynchronous} instead
+   */
+  @Deprecated
+  public void setSynchronous(boolean isSynchronous)
+  {
+    this.props.setProperty(DiskWriteAttributesImpl.SYNCHRONOUS_PROPERTY, String
+        .valueOf(isSynchronous));
+  }
+
+  /**
+   * Sets whether or not the rolling of Oplog is enabled .
+   * 
+   * @param rollingEnabled true if oplogs are to be compacted automatically;
+   *   false if no compaction.
+   * @deprecated as of 6.5 use {@link DiskStoreFactory#setAutoCompact} instead
+   */
+  @Deprecated
+  public void setRollOplogs(boolean rollingEnabled)
+  {
+    this.props.setProperty(CacheXml.ROLL_OPLOG, String.valueOf(rollingEnabled));
+  }
+
+  /**
+   * Sets the threshold at which an oplog will become compactable. While
+   * the percentage of live records in the oplog exceeds
+   * this threshold the oplog will not be compacted.
+   * Once the percentage of live is less than or equal to the threshold
+   * the oplog can be compacted.
+   * The lower the threshold the longer the compactor will wait before compacting an oplog.
+   * The threshold is a percentage in the range 0..100.
+   * The default is 50%.
+   * <P>Examples:
+   * A threshold of 100 causes any oplog that is no longer being written to
+   * to be compactable.
+   * A threshold of 0 causes only oplogs that have no live records to be compactable
+   * in which case the compact can simply remove the oplog file.
+   * A threshold of 50 causes an oplog to become compactable when half of its
+   * live records become dead.
+   * @deprecated as of 6.5 use {@link DiskStoreFactory#setCompactionThreshold} instead
+   */
+  @Deprecated
+  public void setCompactionThreshold(int compactionThreshold) {
+    if (compactionThreshold < 0) {
+      throw new IllegalArgumentException(LocalizedStrings.DiskWriteAttributesImpl_0_HAS_TO_BE_POSITIVE_NUMBER_AND_THE_VALUE_GIVEN_1_IS_NOT_ACCEPTABLE.toLocalizedString(new Object[] {CacheXml.COMPACTION_THRESHOLD, Integer.valueOf(compactionThreshold)}));
+    } else if (compactionThreshold > 100) {
+      throw new IllegalArgumentException(LocalizedStrings.DiskWriteAttributesImpl_0_HAS_TO_BE_LESS_THAN_2_BUT_WAS_1.toLocalizedString(new Object[] {CacheXml.COMPACTION_THRESHOLD, Integer.valueOf(compactionThreshold), Integer.valueOf(100)}));
+    }
+    this.props.setProperty(CacheXml.COMPACTION_THRESHOLD,
+                           String.valueOf(compactionThreshold));
+  }
+  
+  /**
+   * Sets the maximum oplog size in bytes. When the active oplog size hits
+   * the maximum a new oplog will be created.
+   * <P>Note that this method sets the same attribute as {@link #setMaxOplogSize}.
+   * The last set of the attribute determines its value.
+   * @param maxOplogSize the maximum size of the oplog in bytes.
+   * @throws IllegalArgumentException
+   *           if the value specified is a negative number
+   * @deprecated as of 6.5 use {@link DiskStoreFactory#setMaxOplogSize} instead
+   */
+  @Deprecated
+  public void setMaxOplogSizeInBytes(long maxOplogSize)
+  {
+	
+    if (maxOplogSize < 0) {
+      throw new IllegalArgumentException(LocalizedStrings.DiskWriteAttributesFactory_MAXIMUM_OPLOG_SIZE_SPECIFIED_HAS_TO_BE_A_NONNEGATIVE_NUMBER_AND_THE_VALUE_GIVEN_0_IS_NOT_ACCEPTABLE.toLocalizedString(Long.valueOf(maxOplogSize)));
+    }
+    this.props.setProperty(CacheXml.MAX_OPLOG_SIZE,
+        String.valueOf(maxOplogSize));
+  }
+
+  /**
+   * Sets the maximum oplog size in megabytes. When the active oplog size hits
+   * the maximum a new oplog will be created.
+   * <P>Note that this method sets the same attribute as {@link #setMaxOplogSizeInBytes}.
+   * The last set of the attribute determines its value.
+   * @param maxOplogSize the maximum size of the oplog in megabytes.
+   * @throws IllegalArgumentException
+   *           if the value specified is a negative number
+   * @deprecated as of 6.5 use {@link DiskStoreFactory#setMaxOplogSize} instead
+   */
+  @Deprecated
+  public void setMaxOplogSize(int maxOplogSize)
+  {
+
+    if (maxOplogSize < 0) {
+      throw new IllegalArgumentException(LocalizedStrings.DiskWriteAttributesFactory_MAXIMUM_OPLOG_SIZE_SPECIFIED_HAS_TO_BE_A_NONNEGATIVE_NUMBER_AND_THE_VALUE_GIVEN_0_IS_NOT_ACCEPTABLE.toLocalizedString(Integer.valueOf(maxOplogSize)));
+    }
+    long maxOplogSizeInBytes = convertToBytes(maxOplogSize);
+    this.props.setProperty(CacheXml.MAX_OPLOG_SIZE, String
+        .valueOf(maxOplogSizeInBytes));
+  }
+
+  /**
+   * Takes an int which is supposed to be in megabytes
+   * and converts it to a long. This conversion takes into
+   * account that multiplication can lead to Integer.MAX_VALUE being
+   * exceeded
+   * @param megaBytes
+   * @return the converted value
+   */
+  private long convertToBytes(int megaBytes)
+  {
+    long bytes = megaBytes;
+    bytes = bytes * 1024 * 1024;
+    return bytes;
+  }
+  
+  /**
+   * Sets the number of milliseconds that can elapse before unwritten data is
+   * written to disk. It has significance only in case of asynchronous mode of
+   * writing.
+   * 
+   * @param timeInterval
+   *          Time interval in milliseconds
+   * @throws IllegalArgumentException
+   *           if the value specified is a negative number
+   * @deprecated as of 6.5 use {@link DiskStoreFactory#setTimeInterval} instead
+   */
+  @Deprecated
+  public void setTimeInterval(long timeInterval)
+  {
+    if (timeInterval < 0) {
+      throw new IllegalArgumentException(LocalizedStrings.DiskWriteAttributesFactory_TIME_INTERVAL_SPECIFIED_HAS_TO_BE_A_NONNEGATIVE_NUMBER_AND_THE_VALUE_GIVEN_0_IS_NOT_ACCEPTABLE.toLocalizedString(Long.valueOf(timeInterval)));
+    }
+
+    this.props.setProperty(CacheXml.TIME_INTERVAL,
+        String.valueOf(timeInterval));
+  }
+
+  /**
+   * Sets the number of unwritten bytes of data that can be enqueued before
+   * being written to disk. It has significance only in case of asynchronous mode
+   * of writing.
+   * 
+   * @param bytesThreshold the maximum number of bytes to enqueue before async data
+   *                       is flushed.
+   * @throws IllegalArgumentException
+   *           if the value specified is a negative number
+   * @deprecated as of 6.5 use {@link DiskStoreFactory#setQueueSize} instead
+   */
+  @Deprecated
+  public void setBytesThreshold(long bytesThreshold)
+  {
+    if (bytesThreshold < 0) {
+      throw new IllegalArgumentException(LocalizedStrings.DiskWriteAttributesFactory_QUEUE_SIZE_SPECIFIED_HAS_TO_BE_A_NONNEGATIVE_NUMBER_AND_THE_VALUE_GIVEN_0_IS_NOT_ACCEPTABLE.toLocalizedString(Long.valueOf(bytesThreshold)));
+    }
+
+    this.props.setProperty(CacheXml.BYTES_THRESHOLD,
+        String.valueOf(bytesThreshold));
+  }
+
+  /**
+   * Creates a <code>DiskWriteAttributes</code> with the current settings.
+   * 
+   * @return the newly created <code>DiskWriteAttributes</code>
+   * @throws IllegalStateException
+   *           if the current settings has compaction enabled with maximum Oplog
+   *           Size specified as infinite ( represented by 0 ) *
+   * @since 5.1
+   * @deprecated as of 6.5 use {@link DiskStoreFactory#create} instead
+   */
+  @Deprecated
+  public DiskWriteAttributes create()
+  {
+    return new DiskWriteAttributesImpl(this.props);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DuplicatePrimaryPartitionException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DuplicatePrimaryPartitionException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DuplicatePrimaryPartitionException.java
new file mode 100644
index 0000000..27d71b3
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DuplicatePrimaryPartitionException.java
@@ -0,0 +1,56 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.GemFireException;
+
+/**
+ * This exception is thrown when two nodes are defined with same primary
+ * partitions
+ * 
+ * @since 6.6
+ * @author kbachhhav
+ */
+public class DuplicatePrimaryPartitionException extends GemFireException {
+
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * Creates a new <code>DuplicatePrimaryPartitionException</code> with no
+   * detailed message.
+   */
+
+  public DuplicatePrimaryPartitionException() {
+    super();
+  }
+
+  /**
+   * Creates a new <code>DuplicatePrimaryPartitionException</code> with the
+   * given detail message.
+   */
+  public DuplicatePrimaryPartitionException(String message) {
+    super(message);
+  }
+
+  /**
+   * Creates a new <code>DuplicatePrimaryPartitionException</code> with the
+   * given cause and no detail message
+   */
+  public DuplicatePrimaryPartitionException(Throwable cause) {
+    super(cause);
+  }
+
+  /**
+   * Creates a new <code>DuplicatePrimaryPartitionException</code> with the
+   * given detail message and cause.
+   */
+  public DuplicatePrimaryPartitionException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DynamicRegionFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DynamicRegionFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DynamicRegionFactory.java
new file mode 100644
index 0000000..4922df9
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DynamicRegionFactory.java
@@ -0,0 +1,1118 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+
+import com.gemstone.gemfire.InternalGemFireError;
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.cache.client.Pool;
+import com.gemstone.gemfire.cache.client.PoolManager;
+import com.gemstone.gemfire.cache.client.internal.ServerRegionProxy;
+import com.gemstone.gemfire.cache.util.BridgeWriter;
+import com.gemstone.gemfire.cache.wan.GatewaySender;
+import com.gemstone.gemfire.distributed.DistributedMember;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.internal.Assert;
+import com.gemstone.gemfire.internal.cache.DistributedRegion;
+import com.gemstone.gemfire.internal.cache.DynamicRegionAttributes;
+import com.gemstone.gemfire.internal.cache.DynamicRegionFactoryImpl;
+import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+import com.gemstone.gemfire.internal.cache.EnumListenerEvent;
+import com.gemstone.gemfire.internal.cache.EvictionAttributesImpl;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.InitialImageOperation;
+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.RegionEventImpl;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.security.GemFireSecurityException;
+
+
+/**
+ * DynamicRegionFactory provides a distributed region creation service. 
+ * Any other member of the GemFire DistributedSystem that has created 
+ * an instance of this class will automatically instantiate regions created
+ * through the factory from anywhere else in the DistributedSystem.
+ * <p><p>
+ * Instructions for Use:<br>
+ * <ul>
+ * <li> If your application is a client in a client/server installation,
+ * either specify the pool name in the
+ * {@link DynamicRegionFactory.Config} you'll use to create a
+ * DynamicRegionFactory <i>or</i> specify it
+ * in a dynamic-region-factory element in your cache.xml.
+ *
+ * <li> Before you've created a GemFire Cache in your application, add a
+ * line of code as follows:<br>
+ * <pre><code>  DynamicRegionFactory factory = DynamicRegionFactory.get();
+ *  factory.open(config);</code></pre>
+ * <pre><code>  DynamicRegionFactory myFactoryHandle = DynamicRegionFactory.get().open(config);</code></pre>
+ * or just use a dynamic-region-factory element in the cache.xml.
+ *
+ * <li> Create the GemFire Cache.  During cache creation, the list of dynamic Regions will either be discovered
+ * by recovering
+ * their names from disk (see {@link DynamicRegionFactory.Config#persistBackup}) or from other members of the
+ * distributed system.
+ * These dynamic Regions will be created before Cache creation completes.
+ *
+ * <li> Thereafter, when you want to create dynamic distributed Regions,
+ * create them using the {@link #createDynamicRegion}.  Regions created with the factory will
+ * inherit their RegionAttributes from their parent Region, though you can override
+ * callbacks when you configure the factory.
+ *
+ * <p>All other instances of GemFire across the distributed system that
+ * instantiate and open a DynamicRegionFactory will also get the dynamic distributed Regions.
+ * 
+ * <li>Non-dynamic parent Regions should be declared in cache.xml so that they can be created before
+ * the dynamic Region factory goes active and starts creating Regions.  You will have cache creation
+ * problems if this isn't done.
+ * 
+ * <li>A DynamicRegionListener can be registered before open is called and before cache creation
+ * so that the listener will be called if dynamic Regions are created during cache creation.
+ * 
+ * </ul>
+ * <p>Saving the factory on disk:  
+ * If {@link DynamicRegionFactory.Config#persistBackup} is configured for the factory, dynamic Region information
+ * is written to disk for recovery.
+ * By default the current directory is used for this information. The {@link DynamicRegionFactory.Config#diskDir}
+ * can be used to change this default.
+ * <p>
+ * Registering interest in cache server information: The {@link DynamicRegionFactory.Config#registerInterest}
+ * setting determines whether clients will register interest in server keys or not.  You will generally want
+ * this to be turned on so that clients will see updates made to servers.  In server processes, DynamicRegionFactory
+ * forces use of NotifyBySubscription.
+ * </ul>
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>DynamicRegionFactories in non-client VMs must not be configured with a BridgeWriter.
+ * <li>If {@link #open()} is called before cache creation and the cache.xml has a dynamic-region-factory
+ * element then the cache.xml will override the open call's configuration.
+ * 
+ * <li>Since the RegionAttributes of a dynamically created Region are copied
+ * from the parent Region, any callbacks, ({@link CacheListener},
+ * {@link CacheWriter}, and {@link CacheLoader}
+ * are shared by the parent and all its dynamic children
+ * so make sure the callback is thread-safe and that its
+ * {@link CacheCallback#close} implementation does not stop it from functioning.
+ * However the products BridgeLoader, BridgeWriter, and all LRUAlgorithm instances will
+ * be cloned so that each dynamic Region has its own callback.
+ * 
+ * <li>The root Region name "DynamicRegions" is reserved. The factory creates a root Region of
+ * that name and uses it to keep track of what dynamic Regions exist. Applications should
+ * not directly access this Region; instead use the methods on this factory.
+ * </ul>
+ * @since 4.3
+ * @author Gideon Low
+ * @author Darrel Schneider
+ * @author Bruce Schuchardt
+ *
+ */
+@SuppressWarnings("deprecation")
+public abstract class DynamicRegionFactory  {
+
+  public static final String dynamicRegionListName = "__DynamicRegions";
+  private Region dynamicRegionList = null;
+  /**
+   * This controls the delay introduced to try and avoid any race conditions
+   * between propagation of newly created Dynamic Regions
+   * and the Entries put into them.
+   */
+  private static final long regionCreateSleepMillis = Long.getLong("DynamicRegionFactory.msDelay", 250).longValue();
+  private static DynamicRegionFactory singleInstance = new DynamicRegionFactoryImpl ( );
+  GemFireCacheImpl c = null;
+  Config config = null;
+
+  /** The region listeners registered on this DynamicRegionFactory */
+  private static volatile List regionListeners = Collections.EMPTY_LIST;
+  private static final Object regionListenerLock = new Object();
+
+  /**
+   * Opens the DynamicRegionFactory with default settings.
+   */
+  public void open() {
+    open(new Config());
+  }
+
+  /**
+   * Opens the factory with the given settings.
+   * This should be sent to the factory before creating a cache.  The cache
+   * will otherwise open a factory with default settings.
+   * This does not need to be sent if the cache.xml declares the use of dynamic regions.
+   * @param conf the configuration for this factory.
+   */
+  public void open(Config conf) {
+    this.config = new Config(conf);
+  }
+  /**
+   * Closes the dynamic region factory, disabling any further creation or
+   * destruction of dynamic regions in this cache.
+   */
+  protected void _close() {
+    this.config = null;
+    this.c = null;
+  }
+  /**
+   * Returns true if dynamic region factory is open; false if closed.
+   */
+  public boolean isOpen() {
+    return getConfig() != null;
+  }
+  /**
+   * Returns true if this factory is open and can produce dynamic regions.
+   * Factories are only active after their cache has been created.
+   */
+  public boolean isActive() {
+    return isOpen() && this.c != null;
+  }
+  /**
+   * Returns true if dynamic region factory is closed.
+   */
+  public boolean isClosed() {
+    return !isOpen();
+  }
+
+  /**
+   * Returns the configuration for this factory.
+   * Returns null if the factory is closed;
+   */
+  public Config getConfig() {
+    if (this.config == null)
+      return null;
+    else
+      return new Config(this.config);
+  }
+
+  public static boolean regionIsDynamicRegionList(String regionPath) {
+    return regionPath != null && regionPath.equals('/' + dynamicRegionListName);
+  }
+
+  /**
+   * The method is for internal use only. It is called implicitly during cache creation.
+   * @param theCache The GemFire <code>Cache</code>
+   * @throws CacheException
+   */
+
+  protected void _internalInit ( GemFireCacheImpl theCache ) throws CacheException
+  {
+
+    if (isClosed()) {
+      // DynamicRegions are not enabled in this vm. Just return.
+      return;
+    }
+    /**
+     * This method is called internally during cache initialization at the correct time.
+     * Initialize the factory with a GemFire Cache.  We create the metadata Region which holds all our
+     * dynamically created regions.
+     */
+    try {
+      this.c = theCache;
+      this.dynamicRegionList = theCache.getRegion(dynamicRegionListName);
+      final boolean isClient = this.config.getBridgeWriter() != null || this.config.getPoolName()!=null;
+      if (this.dynamicRegionList == null) {
+        InternalRegionArguments ira = new InternalRegionArguments()
+        .setDestroyLockFlag(true)
+        .setSnapshotInputStream(null)
+        .setImageTarget(null);
+        AttributesFactory af = new AttributesFactory ();       
+        if (this.config.getPersistBackup()) {
+          af.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
+          af.setDiskWriteAttributes(new DiskWriteAttributesFactory().create());
+          if (this.config.getDiskDir() != null) {
+            af.setDiskDirs(new File[]{this.config.getDiskDir()});
+          }
+        }
+
+        if (isClient) {
+          // BRIDGE CLIENT
+          af.setScope(Scope.LOCAL);
+          af.setDataPolicy(DataPolicy.NORMAL); //MirrorType(MirrorType.NONE);
+          af.setStatisticsEnabled(true);
+          String cpName = this.config.getPoolName();
+          if (cpName != null) {
+            Pool cp = PoolManager.find(cpName);
+            if(cp==null)   {
+              throw new IllegalStateException("Invalid pool name specified. This pool is not registered with the cache: " + cpName);
+            } else {
+              if (!cp.getSubscriptionEnabled()) {
+                throw new IllegalStateException("The client pool of a DynamicRegionFactory must be configured with queue-enabled set to true.");
+              }
+              af.setPoolName(cpName);
+            }
+          } else {
+            BridgeWriter bw = this.config.getBridgeWriter();
+            if (!bw.hasEstablishCallbackConnection()) {
+              throw new IllegalStateException(LocalizedStrings.DynamicRegionFactory_THE_CLIENT_POOL_OF_A_DYNAMICREGIONFACTORY_MUST_BE_CONFIGURED_WITH_ESTABLISHCALLBACKCONNECTION_SET_TO_TRUE.toLocalizedString());
+            }
+            af.setCacheWriter(bw);
+          }
+          ira.setInternalMetaRegion(new LocalMetaRegion(af.create(), ira));
+        } else {
+          af.setScope(Scope.DISTRIBUTED_ACK);
+          if (!this.config.getPersistBackup()) {  // if persistBackup, the data policy has already been set
+	    af.setDataPolicy(DataPolicy.REPLICATE); //setMirrorType(MirrorType.KEYS_VALUES);
+	  }
+
+          for (GatewaySender gs : c.getGatewaySenders()) {
+            if (!gs.isParallel())
+              af.addGatewaySenderId(gs.getId());
+          }
+          ira.setInternalMetaRegion(new DistributedMetaRegion(af.create())); // bug fix 35432
+        }
+    
+        try { 
+          dynamicRegionList = theCache.createVMRegion(dynamicRegionListName,  af.create(), ira);
+        }
+        catch (IOException e) {
+          // only if loading snapshot, not here
+          InternalGemFireError assErr = new InternalGemFireError(LocalizedStrings.DynamicRegionFactory_UNEXPECTED_EXCEPTION.toLocalizedString());
+          assErr.initCause(e);
+          throw assErr;
+        }
+        catch (ClassNotFoundException e) {
+          // only if loading snapshot, not here
+          InternalGemFireError assErr = new InternalGemFireError(LocalizedStrings.DynamicRegionFactory_UNEXPECTED_EXCEPTION.toLocalizedString());
+          assErr.initCause(e);
+          throw assErr;
+        }
+        if (isClient) {
+          dynamicRegionList.registerInterest("ALL_KEYS");
+        }
+        if (theCache.getLoggerI18n().fineEnabled()) {
+          theCache.getLoggerI18n().fine("Created dynamic region: " + dynamicRegionList);
+        }
+      } else {
+        if (theCache.getLoggerI18n().fineEnabled()) {
+          theCache.getLoggerI18n().fine("Retrieved dynamic region: " + dynamicRegionList);
+        }
+      }
+
+      createDefinedDynamicRegions ( );
+
+    } catch ( CacheException e ) {
+      //
+      theCache.getLoggerI18n().warning(LocalizedStrings.DynamicRegionFactory_ERROR_INITIALIZING_DYNAMICREGIONFACTORY, e);
+      throw e;
+    }
+  }
+
+  /**
+   *  This creates Dynamic Regions that already exist in other publishing processes
+   *
+   */
+  private void createDefinedDynamicRegions ( ) throws CacheException {
+    // TODO: perhaps add some logic here to avoid the possiblity of synchronization issues . . . .
+    Set s = dynamicRegionList.entrySet( false );
+
+    Iterator i = s.iterator();
+    TreeMap sorted = new TreeMap();
+
+    // sort by region name before creating (bug 35528)
+    while ( i.hasNext() ) {
+      Region.Entry e = (Region.Entry)i.next();
+      DynamicRegionAttributes dda = (DynamicRegionAttributes)e.getValue();
+      sorted.put(dda.rootRegionName + "/" + dda.name, dda);
+    }
+    i = sorted.values().iterator();
+    
+    while ( i.hasNext() ) {
+      DynamicRegionAttributes dda = (DynamicRegionAttributes)i.next();
+
+      doBeforeRegionCreated ( dda.rootRegionName, dda.name, null );
+      Region region = createDynamicRegionImpl ( dda.rootRegionName, dda.name, false );
+      doAfterRegionCreated ( region, false, false, null );
+
+    }
+
+  }
+
+  /**
+   * Returns the <code>DynamicRegionFactory</code> singleton instance.
+   * @return the <code>DynamicRegionFactory</code> singleton instance
+   */
+  public static DynamicRegionFactory get() {
+    return singleInstance;
+  }
+
+  /**
+   * Registers a <code>DynamicRegionListener</code> for callbacks.
+   * @param listener The <code>DynamicRegionListener</code> to be registered
+   */
+  public void registerDynamicRegionListener(DynamicRegionListener listener) {
+    synchronized (regionListenerLock) {
+      List oldListeners = regionListeners;
+      if (!oldListeners.contains(listener)) {
+        List newListeners = new ArrayList(oldListeners);
+        newListeners.add(listener);
+        regionListeners = newListeners;
+      }
+    }
+  }
+
+  /**
+   * Unregisters a <code>DynamicRegionListener</code> for callbacks.
+   * @param listener The <code>DynamicRegionListener</code> to be unregistered
+   */
+  public void unregisterDynamicRegionListener(DynamicRegionListener listener) {
+    synchronized (regionListenerLock) {
+      List oldListeners = regionListeners;
+      if (oldListeners.contains(listener)) {
+        List newListeners = new ArrayList(oldListeners);
+        if (newListeners.remove(listener)) {
+          regionListeners = newListeners;
+        }
+      }
+    }
+  }
+
+  private void doBeforeRegionCreated( String parentRegion, String regionName, DistributedMember mbr ) {
+    for ( Iterator i = regionListeners.iterator(); i.hasNext(); ) {
+      DynamicRegionListener listener = ( DynamicRegionListener ) i.next();
+      try {
+        listener.beforeRegionCreate( parentRegion, regionName );
+      } 
+      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();
+        this.c.getLoggerI18n().warning(LocalizedStrings.DynamicRegionFactory_DYNAMICREGIONLISTENER__0__THREW_EXCEPTION_ON_BEFOREREGIONCREATED, listener, t); 
+      }
+    }
+  }
+
+  private void doAfterRegionCreated( Region region, boolean distributed, boolean isOriginRemote, DistributedMember mbr ) {
+    RegionEvent event = new RegionEventImpl(region, Operation.REGION_CREATE, null, isOriginRemote, getMember(mbr));
+    for ( Iterator i = regionListeners.iterator(); i.hasNext(); ) {
+      DynamicRegionListener listener = ( DynamicRegionListener ) i.next();
+      try {
+        listener.afterRegionCreate( event /*region*/ );
+      } 
+      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();
+        this.c.getLoggerI18n().warning(LocalizedStrings.DynamicRegionFactory_DYNAMICREGIONLISTENER__0__THREW_EXCEPTION_ON_AFTERREGIONCREATED, listener, t);
+      }
+    }
+  }
+
+  private void doBeforeRegionDestroyed( Region region, boolean distributed, boolean isOriginRemote, boolean expiration, DistributedMember mbr ) {
+    final Operation op;
+    if (!distributed && !isOriginRemote) {
+      op = expiration? Operation.REGION_EXPIRE_LOCAL_DESTROY : Operation.REGION_LOCAL_DESTROY;
+    }
+    else {
+       op = expiration? Operation.REGION_EXPIRE_DESTROY : Operation.REGION_DESTROY;
+    }
+    RegionEvent event = new RegionEventImpl(region, op, null, isOriginRemote, getMember(mbr));
+    for ( Iterator i = regionListeners.iterator(); i.hasNext(); ) {
+      DynamicRegionListener listener = ( DynamicRegionListener ) i.next();
+      try {
+        listener.beforeRegionDestroy( event /*fullRegionName*/ );
+      }
+      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();
+        this.c.getLoggerI18n().warning(LocalizedStrings.DynamicRegionFactory_DYNAMICREGIONLISTENER__0__THREW_EXCEPTION_ON_BEFOREREGIONDESTROYED, listener, t);
+      }
+    }
+  }
+
+  private void doAfterRegionDestroyed( Region region, boolean distributed, boolean isOriginRemote, boolean expiration, DistributedMember mbr ) {
+    final Operation op;
+    if (!distributed && !isOriginRemote) {
+      op = expiration? Operation.REGION_EXPIRE_LOCAL_DESTROY : Operation.REGION_LOCAL_DESTROY;
+    }
+    else {
+       op = expiration? Operation.REGION_EXPIRE_DESTROY : Operation.REGION_DESTROY;
+    }
+    RegionEvent event = new RegionEventImpl(region, op, null, isOriginRemote, getMember(mbr));
+    for ( Iterator i = regionListeners.iterator(); i.hasNext(); ) {
+      DynamicRegionListener listener = ( DynamicRegionListener ) i.next();
+      try {
+        listener.afterRegionDestroy( event /*fullRegionName*/ );
+      } 
+      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();
+        this.c.getLoggerI18n().warning(LocalizedStrings.DynamicRegionFactory_DYNAMICREGIONLISTENER__0__THREW_EXCEPTION_ON_AFTERREGIONDESTROYED, listener, t);
+      }
+    }
+  }
+  
+  /** return the argument, or if null the DistributedMember id of this vm */
+  private DistributedMember getMember(DistributedMember mbr) {
+    if (mbr == null) {
+      return InternalDistributedSystem.getAnyInstance().getDistributedMember();
+    }
+    else {
+     return null;
+    }
+  }
+    
+
+  /**
+   * Creates the dynamic Region in the local cache and distributes the
+   * creation to other caches.
+   * 
+   * @param parentRegionName the new region is created as a subregion of the region having this path
+   * @param regionName the name of the new subregion
+   * @return the <code>Region</code> created
+   * @throws CacheException
+   */
+  public Region createDynamicRegion ( String parentRegionName, String regionName ) throws CacheException {
+    if (isClosed()) {
+      throw new IllegalStateException("Dynamic region factory is closed");
+    }
+    doBeforeRegionCreated ( parentRegionName, regionName, null );
+    Region region = createDynamicRegionImpl ( parentRegionName, regionName, true );
+    doAfterRegionCreated ( region, false, false, null );
+    return region;
+  }
+
+  /**
+   * Destroys the dynamic Region in the local cache and distributes the
+   * destruction to other caches.
+   * @param fullRegionName The full path of the <code>Region</code> to be
+   * dynamically destroyed
+   * @throws CacheException
+   * @throws RegionDestroyedException if the dynamic region was never created
+   * or has already been destroyed
+   */
+  public void destroyDynamicRegion ( String fullRegionName ) throws CacheException {    
+    if (!dynamicRegionList.containsKey(fullRegionName)) {
+      throw new RegionDestroyedException(LocalizedStrings.DynamicRegionFactory_DYNAMIC_REGION_0_HAS_NOT_BEEN_CREATED.toLocalizedString(fullRegionName), fullRegionName);
+    }
+    if (isClosed()) {
+      throw new IllegalStateException("Dynamic region factory is closed");
+    }
+
+    // Retrieve the region to destroy
+    Region region = c.getRegion( fullRegionName );
+    if (region != null) {
+      DistributedMember mbr = getMember(null);
+      doBeforeRegionDestroyed ( region, false, false, false, mbr );
+      // Locally destroy the region. Let the dynamicRegionList handle distributing
+      // the destroy.
+      region.localDestroyRegion();
+      destroyDynamicRegionImpl(fullRegionName);
+      doAfterRegionDestroyed ( region, false, false, false, mbr );
+    } else {
+      // make sure meta region is cleaned up locally and remotely
+      destroyDynamicRegionImpl(fullRegionName);
+    }
+  }
+
+  private Region createDynamicRegionImpl ( String parentRegionName, String newRegionName, boolean addEntry )
+  throws CacheException {
+
+    Region parentRegion = c.getRegion ( parentRegionName );
+    Region newRegion = null;
+
+    if ( parentRegion == null ) {
+      String errMsg = LocalizedStrings.DynamicRegionFactory_ERROR__COULD_NOT_FIND_A_REGION_NAMED___0_.toLocalizedString(parentRegionName);
+      RegionDestroyedException e = new RegionDestroyedException(errMsg, parentRegionName);
+      c.getLoggerI18n().warning(LocalizedStrings.DynamicRegionFactory_ERROR__COULD_NOT_FIND_A_REGION_NAMED___0_, parentRegionName, e);
+      throw e;
+    }
+
+    // Create RegionAttributes by inheriting from the parent
+    RegionAttributes rra = parentRegion.getAttributes();
+    RegionAttributes newRegionAttributes = null;
+
+    AttributesFactory af = new AttributesFactory( rra );
+    {
+      EvictionAttributes ev = rra.getEvictionAttributes();
+      if (ev != null && ev.getAlgorithm().isLRU()) {
+        EvictionAttributes rev = new EvictionAttributesImpl( (EvictionAttributesImpl)ev );
+        af.setEvictionAttributes( rev );
+      }
+    }
+
+    // for internal testing, until partitioned regions support subclasses or
+    // DynamicRegion implementation is redone to not inherit attrs from parent
+    // regions [bruce]
+    if (newRegionName.endsWith("_PRTEST_")) {
+      af.setPartitionAttributes((new PartitionAttributesFactory()).create());
+    }
+    
+    newRegionAttributes = af.create();
+
+    try {
+      newRegion = parentRegion.createSubregion( newRegionName, newRegionAttributes );
+      c.getLoggerI18n().fine("Created dynamic region " + newRegion);
+    } catch (RegionExistsException ex) {
+      // a race condition exists that can cause this so just fine log it
+      c.getLoggerI18n().fine("DynamicRegion " + newRegionName + " in parent " + parentRegionName + " already existed");
+      newRegion = ex.getRegion();
+//    } catch ( CacheException e ) {
+//      c.getLoggerI18n().warning ( "Error creating new Dynamic Region '" + newRegionName, e );
+//      throw e;
+    }
+
+    if (addEntry) {
+      DynamicRegionAttributes dra = new DynamicRegionAttributes ( );
+      dra.name = newRegionName;
+      dra.rootRegionName = parentRegion.getFullPath();
+      if (c.getLoggerI18n().fineEnabled()) {
+        c.getLoggerI18n().fine ("Putting entry into dynamic region list at key: " + newRegion.getFullPath());
+      }
+      dynamicRegionList.put ( newRegion.getFullPath(), dra );
+    }
+
+    if (config.getRegisterInterest()) {
+      ServerRegionProxy proxy = ((LocalRegion)newRegion).getServerProxy();
+      if (proxy != null) {
+        if (((Pool)proxy.getPool()).getSubscriptionEnabled()) {
+          try {
+            newRegion.registerInterest("ALL_KEYS");
+          }
+          catch (GemFireSecurityException ex) {
+            // Ignore security exceptions here
+            c.getSecurityLoggerI18n().warning(
+              LocalizedStrings.DynamicRegionFactory_EXCEPTION_WHEN_REGISTERING_INTEREST_FOR_ALL_KEYS_IN_DYNAMIC_REGION_0_1,  
+              new Object[] {newRegion.getFullPath(), ex});
+          }
+        }
+      }
+    }
+    
+    if (regionCreateSleepMillis > 0) {
+      try {
+        Thread.sleep( regionCreateSleepMillis );
+      } catch ( InterruptedException e ) {
+        Thread.currentThread().interrupt();
+      }
+    }
+
+    if (c.getLoggerI18n().fineEnabled()) {
+      c.getLoggerI18n().fine ( "Created Dynamic Region " + newRegion.getFullPath() );
+    }
+    return newRegion;
+  }
+
+  private void destroyDynamicRegionImpl(String fullRegionName)
+  throws CacheException {
+    // Destroy the entry in the dynamicRegionList
+    try {
+      if (c.getLoggerI18n().fineEnabled()) {
+        c.getLoggerI18n().fine ("Destroying entry from dynamic region list at key: " + fullRegionName);
+      }
+      dynamicRegionList.destroy ( fullRegionName );
+    } catch (CacheException e) {
+      c.getLoggerI18n().warning(LocalizedStrings.DynamicRegionFactory_ERROR_DESTROYING_DYNAMIC_REGION__0, fullRegionName, e);
+      throw e;
+    }
+
+    if (c.getLoggerI18n().fineEnabled()) {
+      c.getLoggerI18n().fine ( "Destroyed Dynamic Region " + fullRegionName );
+    }
+  }
+
+  /**
+   * Configuration for dynamic region factory.
+   * The default attributes are:
+   * <ul>
+   * <li>diskDir: <code>null</code>
+   * <li>bridgeWriter: <code>null</code>
+   * <li>persistBackup: <code>true</code>
+   * <li>registerInterest: <code>true</code>
+   * </ul>
+   * @since 4.3
+   */
+  public static class Config  {
+    private static final boolean DISABLE_REGISTER_INTEREST = Boolean.getBoolean("DynamicRegionFactory.disableRegisterInterest");
+    private static final boolean DISABLE_PERSIST_BACKUP = Boolean.getBoolean("DynamicRegionFactory.disablePersistence");
+
+    /** Causes the factory to be persisted on disk.  See {@link #diskDir}  */
+    public final boolean persistBackup;
+    /** The directory where the factory's {@link #persistBackup} files are placed */
+    public final File diskDir;
+    /** Causes regions created by the factory to register interest in all keys in a corresponding server cache region */
+    public final boolean registerInterest;
+    /** The {@link BridgeWriter} to be used by the factory to communicate with
+     * the factory in its server.
+     * Client factories must configure a BridgeWriter for their factory
+     * and it must be configured to establish a callback connection.
+     */
+    public final BridgeWriter bridgeWriter;
+    
+    /**
+     * The ${link Pool} to be used by the factory to communicate with 
+     * the server-side factory. Client factories may use this instead of a BridgeWriter 
+     */
+    public final String poolName;
+
+    /**
+     * Creates a configuration with the default attributes.
+     */
+    public Config() {
+      this(null, null, !DISABLE_PERSIST_BACKUP);
+    }
+    /**
+     * Creates a configuration with the given attributes and defaults for other attributes.
+     * @deprecated use a pool name instead of a bridge writer
+     */
+    @Deprecated
+    public Config(File diskDir, BridgeWriter bridgeWriter) {
+      this(diskDir, bridgeWriter, !DISABLE_PERSIST_BACKUP);
+    }
+    
+    /**
+     * Creates a configuration with the given attributes and defaults for other attributes.
+     * @deprecated use a pool name instead of a bridge writer
+     */
+    @Deprecated
+    public Config(File diskDir, BridgeWriter bridgeWriter, boolean persistBackup) {
+      this(diskDir, bridgeWriter, persistBackup, !DISABLE_REGISTER_INTEREST);
+    }
+    
+    
+    
+    /**
+     * Creates a configuration with the given attributes
+     * @deprecated use a pool name instead of a bridge writer
+     */
+    @Deprecated
+    public Config(
+      File diskDir,
+      BridgeWriter bridgeWriter,
+      boolean persistBackup,
+      boolean registerInterest)
+    {
+      this.registerInterest = registerInterest;
+      this.persistBackup = persistBackup;
+      this.diskDir = diskDir;
+      this.bridgeWriter = bridgeWriter;
+      this.poolName = null;
+    }
+    
+
+    /**
+     * Creates a configuration with the given attributes
+     */
+    public Config(
+      File diskDir,
+      String poolName,
+      boolean persistBackup,
+      boolean registerInterest)
+    {
+      this.registerInterest = registerInterest;
+      this.persistBackup = persistBackup;
+      this.diskDir = diskDir;
+      this.poolName = poolName;
+      this.bridgeWriter = null;
+    }
+
+    /**
+     * Returns true if the factory is persisted to disk; false if not.
+     */
+    public boolean getPersistBackup() {
+      return this.persistBackup;
+    }
+    
+    /**
+     * Returns true if the region will register interest in all keys of a corresponding
+     * server cache region
+     */
+    public boolean getRegisterInterest() {
+      return this.registerInterest;
+    }
+    
+    /**
+     * Returns the disk directory that the dynamic region factory data
+     * will be written to.
+     * Returns null if no directory has been specified.
+     * The diskDir is only used if <code>persistBackup</code> is true.
+     */
+    public File getDiskDir() {
+      return this.diskDir;
+    }
+    
+    /**
+     * Returns the {@link BridgeWriter} associated with the dynamic region factory.
+     * Returns null if there is no cache writer for dynamic regions.
+     * A cache writer will only exist if this is a client and the cache writer connects to a server.
+     */
+    public BridgeWriter getBridgeWriter() {
+      return this.bridgeWriter;
+    }
+    
+    /**
+     * Returns the name of the {@link Pool} associated with the dynamic region factory.
+     * Returns null if there is no connection pool for dynamic regions.
+     */
+    public String getPoolName() {
+      return this.poolName;
+    }
+    
+    /** create a new Config with settings from another one */
+    Config(Config conf) {
+      this.diskDir = conf.diskDir;
+      this.persistBackup = conf.persistBackup;
+      this.bridgeWriter = conf.bridgeWriter;
+      this.registerInterest = conf.registerInterest;
+      this.poolName = conf.poolName;
+    }
+  }
+  
+  protected void buildDynamicRegion(EntryEvent event) {
+    if (!DynamicRegionFactory.this.isOpen())
+      return;
+    
+    // Ignore the callback if it originated in this process (because the region
+    // will already have been created) and the event is not a bridge event
+    if ( !event.isOriginRemote() && !event.isBridgeEvent() ) return;
+    //
+    DynamicRegionAttributes dra = (DynamicRegionAttributes)event.getNewValue();
+    String parentRegionName = dra.rootRegionName;
+    String newRegionName = dra.name;
+
+    try {
+      doBeforeRegionCreated ( parentRegionName, newRegionName, event.getDistributedMember() );
+      Region region = createDynamicRegionImpl ( parentRegionName, newRegionName, false);
+      doAfterRegionCreated ( region, true, true, event.getDistributedMember() );
+    } catch ( Exception e ) {
+      c.getLoggerI18n().warning(LocalizedStrings.DynamicRegionFactory_ERROR_ATTEMPTING_TO_LOCALLY_CREATE_DYNAMIC_REGION__0, newRegionName, e);
+    }
+  }
+  
+  protected void razeDynamicRegion(EntryEvent event) {
+    if (!DynamicRegionFactory.this.isOpen())
+      return;
+
+    // Because CacheClientUpdater calls localDestroy we need to allow
+    // "local" events. If this is a true local then c.getRegion will return
+    // null and this code will do nothing.
+    // When bug 35644 fixed the following "if" can be uncommented.
+//     // Ignore the callback if it originated in this process (because the region
+//     // will already have been destroyed)
+//     if ( !event.isOriginRemote() && !(event instanceof BridgeEntryEventImpl)) return;
+
+    String fullRegionName = ( String ) event.getKey();
+    Region drRegion = c.getRegion( fullRegionName );
+    if (drRegion != null) {
+      try {
+        doBeforeRegionDestroyed ( drRegion, true, event.getOperation().isDistributed(), event.getOperation().isExpiration(), event.getDistributedMember() );
+        drRegion.localDestroyRegion();
+        doAfterRegionDestroyed ( drRegion, true, event.getOperation().isDistributed(), event.getOperation().isExpiration(), event.getDistributedMember() );
+      } catch ( Exception e ) {
+        c.getLoggerI18n().warning(LocalizedStrings.DynamicRegionFactory_ERROR_ATTEMPTING_TO_LOCALLY_DESTROY_DYNAMIC_REGION__0, fullRegionName, e);
+      }
+    }
+  }
+  
+//  private class DRListener implements CacheListener {
+//    public void afterCreate(EntryEvent arg0) {
+//      buildDynamicRegion(arg0);
+//    }
+//
+//    public void afterDestroy(EntryEvent arg0) {
+//      razeDynamicRegion(arg0);
+//    }
+//
+//    public void afterInvalidate(EntryEvent arg0) {
+//      // Stub, nothing to do.
+//    }
+//
+//    public void afterRegionDestroy(RegionEvent arg0) {
+//      // Stub, nothing to do.
+//    }
+//
+//    public void afterRegionInvalidate(RegionEvent arg0) {
+//      // Stub, nothing to do.
+//    }
+//
+//    public void afterUpdate(EntryEvent arg0) {
+//      // Stub, nothing to do.
+//    }
+//
+//    public void close() {
+//      // Stub, nothing to do.
+//    }
+//  }
+  
+  // Introduced to keep symmetry with DistributedMetaRegion and potentially provide improved control of
+  // the meta data
+  private class LocalMetaRegion extends LocalRegion  {
+    protected LocalMetaRegion(RegionAttributes attrs, InternalRegionArguments ira) {
+      super(dynamicRegionListName, attrs, null, DynamicRegionFactory.this.c, ira);
+      Assert.assertTrue(attrs.getScope().isLocal());
+    }
+    
+    // This is an internal uses only region
+    @Override
+    protected boolean isSecret()
+    {
+      return true;
+    }
+
+    @Override
+    protected boolean isCopyOnRead() {
+      return false;
+    }
+
+//    //@override event tracker not needed for this type of region
+//    void initEventTracker() {
+//    }
+
+    // while internal, its contents should be communicated with bridge clients 
+    @Override
+    protected boolean shouldNotifyBridgeClients()
+    {
+      return getCache().getBridgeServers().size() > 0;
+    }
+
+    // Over-ride the super behavior to perform the destruction of the dynamic region
+    @Override
+    public void invokeDestroyCallbacks(EnumListenerEvent eventType, EntryEventImpl event, boolean callDispatchEventsCallback, boolean notifyGateways )
+    {
+      Assert.assertTrue(eventType.equals(EnumListenerEvent.AFTER_DESTROY));
+      // Notify bridge clients (if this is a BridgeServer)
+      event.setEventType(eventType);
+      notifyBridgeClients(event);
+      // Notify GatewayHub (if this region participates in a Gateway)
+      if (notifyGateways) {
+        notifyGatewaySender(eventType, event);
+      }
+      // Destroy the dynamic region after the clients and gateways have been notified
+      razeDynamicRegion(event);
+    }
+
+    // Over-ride the super behavior to perform the creation of the dynamic region
+    @Override
+    protected long basicPutPart2(EntryEventImpl event, RegionEntry entry,
+        boolean isInitialized, long lastModified,
+        boolean clearConflict)  {
+    
+    boolean isCreate = event.getOperation().isCreate();
+    boolean set = false;
+    
+    if (isCreate && !event.callbacksInvoked()) {
+      // don't notify clients until all peers have created the region so that
+      // their register-interest operations will be sure to find data
+      event.callbacksInvoked(true);
+      set = true;
+    }
+    
+    long result = super.basicPutPart2(event, entry, isInitialized, lastModified, clearConflict);
+    
+    if (set) {
+      event.callbacksInvoked(false);
+    }
+    
+    if (isCreate) {
+      buildDynamicRegion(event);
+    }
+    return result;
+  }
+  
+    // The dynamic-region meta-region needs to tell clients about the event
+    // after all servers have created the region so that register-interest
+    // will work correctly
+    @Override
+    public void basicPutPart3(EntryEventImpl event, RegionEntry entry,
+        boolean isInitialized, long lastModified, boolean invokeCallbacks,
+        boolean ifNew, boolean ifOld, Object expectedOldValue,
+        boolean requireOldValue) {
+      
+      super.basicPutPart3(event, entry, isInitialized, lastModified, invokeCallbacks, ifNew, ifOld, expectedOldValue, requireOldValue);
+      
+      // this code is copied from LocalRegion.basicPutPart2
+      invokeCallbacks &= !entry.isTombstone(); // put() is creating a tombstone
+      if (invokeCallbacks) {
+        boolean doCallback = false;
+        if (isInitialized) {
+          if (event.isGenerateCallbacks()) {
+            doCallback = true;
+          }
+        }
+        if (doCallback) {
+          notifyGatewaySender(event.getOperation().isUpdate()? EnumListenerEvent.AFTER_UPDATE
+                                               : EnumListenerEvent.AFTER_CREATE, event);
+          // Notify listeners
+          if (!event.isBulkOpInProgress()) {
+            try {
+              entry.dispatchListenerEvents(event);
+            }
+            catch (InterruptedException ie) {
+              Thread.currentThread().interrupt();
+              stopper.checkCancelInProgress(null);
+            }
+          }
+        }
+      }
+    }   
+  }
+
+  // Part of the fix for bug 35432, which required a change to the 
+  // distribution and notification order on the BridgeServer
+  private class DistributedMetaRegion extends DistributedRegion  {
+    protected DistributedMetaRegion(RegionAttributes attrs) {
+      super(dynamicRegionListName, attrs, null, DynamicRegionFactory.this.c, new InternalRegionArguments());
+    }
+    // This is an internal uses only region
+    @Override
+    protected boolean isSecret()
+    {
+      return true;
+    }
+    
+//    //@override event tracker not needed for this type of region
+//    void initEventTracker() {
+//    }
+
+    @Override
+    protected boolean isCopyOnRead() {
+      return false;
+    }
+
+    // while internal, its contents should be communicated with bridge clients 
+    @Override
+    final public boolean shouldNotifyBridgeClients()
+    {
+      return getCache().getBridgeServers().size() > 0;
+    }    
+   
+    // Over-ride the super behavior to perform the destruction of the dynamic region
+    // 
+    @Override
+    public void invokeDestroyCallbacks(EnumListenerEvent eventType, EntryEventImpl event, boolean callDispatchEventsCallback, boolean notifyGateways)
+    {
+      Assert.assertTrue(eventType.equals(EnumListenerEvent.AFTER_DESTROY));
+      // Notify bridge clients (if this is a BridgeServer)
+      event.setEventType(eventType);
+      notifyBridgeClients(event);
+      // Notify GatewayHub (if this region participates in a Gateway)
+      if (notifyGateways) {
+        notifyGatewaySender(eventType, event);
+      }
+      // Destroy the dynamic region after the clients and gateways have been notified
+      razeDynamicRegion(event);
+    }
+
+    @Override
+    protected long basicPutPart2(EntryEventImpl event, RegionEntry entry,
+        boolean isInitialized, long lastModified,
+        boolean clearConflict)
+    {
+      boolean isCreate = event.getOperation().isCreate();
+      boolean set = false;
+      if (isCreate && !event.callbacksInvoked()) {
+        // don't notify clients until all peers have created the region so that
+        // their register-interest operations will be sure to find data
+        event.callbacksInvoked(true);
+        set = true;
+      }
+      
+      long result = super.basicPutPart2(event, entry, isInitialized, lastModified, clearConflict);
+      
+      if (set) {
+        event.callbacksInvoked(false);
+      }
+      
+      if (isCreate) {
+        try {
+          InitialImageOperation.setInhibitStateFlush(true); // fix for bug 36175
+          buildDynamicRegion(event);
+        }
+        finally {
+          InitialImageOperation.setInhibitStateFlush(false);
+        }
+      }
+      return result;
+    }
+    
+    // The dynamic-region meta-region needs to tell clients about the event
+    // after all servers have created the region so that register-interest
+    // will work correctly
+    @Override
+    public void basicPutPart3(EntryEventImpl event, RegionEntry entry,
+        boolean isInitialized, long lastModified, boolean invokeCallbacks,
+        boolean ifNew, boolean ifOld, Object expectedOldValue,
+        boolean requireOldValue) {
+
+      super.basicPutPart3(event, entry, isInitialized, lastModified, invokeCallbacks, ifNew, ifOld, expectedOldValue, requireOldValue);
+      
+      // this code is copied from LocalRegion.basicPutPart2
+      invokeCallbacks &= !entry.isTombstone(); // put() is creating a tombstone
+      if (invokeCallbacks) {
+        boolean doCallback = false;
+        if (isInitialized) {
+          if (event.isGenerateCallbacks()) {
+            doCallback = true;
+          }
+        }
+        if (doCallback) {
+          notifyGatewaySender(event.getOperation().isUpdate()? EnumListenerEvent.AFTER_UPDATE
+                                               : EnumListenerEvent.AFTER_CREATE, event);
+          // Notify listeners
+          if (!event.isBulkOpInProgress()) {
+            try {
+              entry.dispatchListenerEvents(event);
+            }
+            catch (InterruptedException ie) {
+              Thread.currentThread().interrupt();
+              stopper.checkCancelInProgress(null);
+            }
+          }
+        }
+      }
+    }
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DynamicRegionListener.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DynamicRegionListener.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DynamicRegionListener.java
new file mode 100644
index 0000000..968b3d0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DynamicRegionListener.java
@@ -0,0 +1,61 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/**
+ * <code>DynamicRegionListener</code> is an interface that can be
+ * implemented to handle dynamic region-related events.
+
+ * The methods on a <code>DynamicRegionListener</code> are invoked synchronously.
+ * If the listener method takes a long time to execute then it will cause the
+ * operation that caused it to be invoked to take a long time.
+ * <p>
+ * Note: It is possible to receive duplicate create events when the DynamicRegionFactory
+ * goes active due to Cache creation.
+ * <p>
+ * See {@link DynamicRegionFactory}
+ *
+ * @author Gideon Low
+ * @since 4.3
+ */
+public interface DynamicRegionListener {
+
+  /**
+   * Handles the 'before region creation' event of a dynamic region. This method
+   * is invoked before the dynamic region is created in the local VM.
+   *
+   * @param parentRegionName The name of the parent region
+   * @param regionName The name of the region being created
+   */
+  public void beforeRegionCreate(String parentRegionName, String regionName);
+
+  /**
+   * Handles the 'after region creation' event of a dynamic region. This method
+   * is invoked after the dynamic region is created in the local VM.
+   *
+   * @param event A <code>RegionEvent</code> describing the event
+   */
+  public void afterRegionCreate(RegionEvent<?,?> event);
+
+  /**
+   * Handles the 'before region destroyed' event of a dynamic region. This method
+   * is invoked before the dynamic region is destroyed in the local VM.
+   *
+   * @param event A <code>RegionEvent</code> describing the event
+   */
+  public void beforeRegionDestroy(RegionEvent<?,?> event);
+
+  /**
+   * Handles the 'after region destroyed' event of a dynamic region. This method
+   * is invoked after the dynamic region is destroyed in the local VM.
+   *
+   * @param event A <code>RegionEvent</code> describing the event
+   */
+  public void afterRegionDestroy(RegionEvent<?,?> event);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryDestroyedException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryDestroyedException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryDestroyedException.java
new file mode 100644
index 0000000..c656947
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryDestroyedException.java
@@ -0,0 +1,52 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+/**
+ * Indicates that a method was invoked on an entry that has been destroyed.
+ *
+ * @author Eric Zoerner
+ *
+ * 
+ * @see Region.Entry
+ * @since 3.0
+ */
+public class EntryDestroyedException extends CacheRuntimeException
+{
+  private static final long serialVersionUID = 831865939772672542L;
+  /** Constructs a new <code>EntryDestroyedException</code>. */ 
+  public EntryDestroyedException()
+  {
+     super();
+  }
+
+  /**
+   * Constructs a new <code>EntryDestroyedException</code> with the message.
+   * @param s the detailed message for this exception
+   */
+  public EntryDestroyedException(String s)
+  {
+    super(s);
+  }
+
+  /** Constructs a new <code>EntryDestroyedException</code> with a detailed message
+   * and a causal exception.
+   * @param s the message
+   * @param ex a causal Throwable
+   */
+  public EntryDestroyedException(String s, Throwable ex)
+  {
+    super(s, ex);
+  }
+  
+  /** Construct a <code>EntryDestroyedException</code> with a cause.
+   * @param ex the causal Throwable
+   */  
+  public EntryDestroyedException(Throwable ex) {
+    super(ex);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryEvent.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryEvent.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryEvent.java
new file mode 100644
index 0000000..2b69ac7
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryEvent.java
@@ -0,0 +1,146 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+//import java.io.*;
+
+/** Contains information about an event affecting an entry, including
+ * its identity and the the circumstances of the event.
+ * It is passed in to <code>CacheListener</code>, <code>CapacityController</code>, and <code>CacheWriter</code>.
+ *
+ * @author Eric Zoerner
+ *
+ *
+ * @see CacheListener
+ * @see CacheWriter
+ * @see RegionEvent
+ * @since 3.0
+ */
+public interface EntryEvent<K,V> extends CacheEvent<K,V> {
+
+  /** Returns the key.
+   * @return the key
+   */
+  public K 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.
+   * In certain scenarios the old value may no longer be available in which
+   * case <code>null</code> is returned.
+   * This can happen for disk regions when the old value is on disk only.
+   *
+   * @return the old value in the cache prior to this event.
+   * If the entry did not exist, was invalid, or was not available,
+   * then null is returned.
+   */
+  public V getOldValue();
+  
+  /**
+   * Returns the serialized form of the value in the cache before this event.
+   *
+   * @return the serialized form of the value in the cache before this event
+   * 
+   * @since 5.5
+   */
+  public SerializedCacheValue<V> getSerializedOldValue();
+
+  /**
+   * Returns the value in the cache after this event.
+   *
+   * @return the value in the cache after this event
+   */
+  public V getNewValue();
+  
+  /**
+   * Returns the serialized form of the value in the cache after this event.
+   *
+   * @return the serialized form of the value in the cache after this event
+   * 
+   * @since 5.5
+   */
+  public SerializedCacheValue<V> getSerializedNewValue();
+
+  // Flag query methods
+    
+  /** Returns true if this event resulted from a loader running in this cache.
+   * Note that this will be true even if the local loader called <code>netSearch</code>.
+   *
+   * If this event is for a Partitioned Region, then true will be returned if the
+   * loader ran in the same VM as where the data is hosted. If true is returned, and {@link CacheEvent#isOriginRemote}
+   * is true, it means the data is not hosted locally, but the loader was run local to the data.
+   * 
+   * @return true if this event resulted from local loader execution
+   * @deprecated as of GemFire 5.0, use {@link Operation#isLocalLoad} instead.
+   */
+  @Deprecated
+  public boolean isLocalLoad();
+  
+  /** Returns true if this event resulted from a loader running that was remote
+   * from the cache that requested it, i.e., a netLoad. Note that the cache
+   * that requested the netLoad may not be this cache in which case
+   * <code>isOriginRemote</code> will also return true.
+   * @return true if this event resulted from a netLoad
+   * @deprecated as of GemFire 5.0, use {@link Operation#isNetLoad} instead.
+   */
+  @Deprecated
+  public boolean isNetLoad();
+  
+  /** Returns true if this event resulted from a loader.
+   * @return true if isLocalLoad or isNetLoad
+   * @deprecated as of GemFire 5.0, use {@link Operation#isLoad} instead.
+   */
+  @Deprecated
+  public boolean isLoad();
+  
+  /** Returns true if this event resulted from a <code>netSearch</code>. If the <code>netSearch</code>
+   * was invoked by a loader however, this will return false and <code>isLocalLoad()</code>
+   * or <code>isNetLoad()</code> will return true instead.
+   *
+   * @return true if this event resulted from a netSearch
+   * @deprecated as of GemFire 5.0, use {@link Operation#isNetSearch} instead.
+   */
+  @Deprecated
+  public boolean isNetSearch();
+  /**
+   * Gets the TransactionId for this EntryEvent.
+   * @return the ID of the transaction that performed the operation that
+   * generated this event; null if no transaction involved.
+   * @since 4.0
+   */
+  public TransactionId getTransactionId();
+  
+  /**
+   * Returns true if this event originated on a client.
+   * 
+   * @since 5.1
+   * @return true if this event originated on a client.
+   * @deprecated as of 5.7 use {@link #hasClientOrigin} instead.
+   */
+  @Deprecated
+  public boolean isBridgeEvent();
+  /**
+   * Returns true if this event originated on a client.
+   * 
+   * @since 5.7
+   * @return true if this event originated on a client.
+   */
+  public boolean hasClientOrigin();
+  /**
+   * Returns <code>true</code> if the old value is "available".
+   * Not available means that an old value existed but it could not be obtained
+   * or it was deemed too expensive to obtain.
+   * Note that {@link #getOldValue} will return <code>null</code> when this
+   * method returns <code>false</code>.
+   * @since 6.0
+   */
+  public boolean isOldValueAvailable();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryExistsException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryExistsException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryExistsException.java
new file mode 100644
index 0000000..6978b22
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryExistsException.java
@@ -0,0 +1,53 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/** Thrown when attempting to create a <code>Region.Entry</code> that already
+ * exists in the <code>Region</code>.
+ * @author Eric Zoerner
+ *
+ * @see com.gemstone.gemfire.cache.Region#create(Object, Object)
+ * @see Region.Entry
+ * @since 3.0
+ */
+public class EntryExistsException extends CacheException {
+
+  private static final long serialVersionUID = 2925082493103537925L;
+
+  private Object oldValue;
+
+  /**
+   * Constructs an instance of <code>EntryExistsException</code> with the specified detail message.
+   * @param msg the detail message
+   * @since 6.5
+   */
+  public EntryExistsException(String msg, Object oldValue) {
+    super(msg);
+    this.oldValue = oldValue;
+  }
+
+  /**
+   * Returns the old existing value that caused this exception.
+   */
+  public Object getOldValue() {
+    return this.oldValue;
+  }
+
+  /**
+   * Sets the old existing value that caused this exception.
+   */
+  public void setOldValue(Object oldValue) {
+    this.oldValue = oldValue;
+  }
+
+  @Override
+  public String toString() {
+    return super.toString() + ", with oldValue: " + oldValue;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryNotFoundException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryNotFoundException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryNotFoundException.java
new file mode 100644
index 0000000..e1265c0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryNotFoundException.java
@@ -0,0 +1,42 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/** Thrown when an operation is invoked on <code>Region</code> for an entry that
+ * doesn't exist in the <code>Region</code>. This exception is <i>not</i>
+ * thrown by {@link com.gemstone.gemfire.cache.Region#get(Object)} or {@link Region#getEntry}.
+ *
+ * @author Eric Zoerner
+ *
+ *
+ * @see com.gemstone.gemfire.cache.Region#invalidate(Object)
+ * @see com.gemstone.gemfire.cache.Region#destroy(Object)
+ * @see Region.Entry
+ * @since 3.0
+ */
+public class EntryNotFoundException extends CacheException {
+private static final long serialVersionUID = -2404101631744605659L;
+  /**
+   * Constructs an instance of <code>EntryNotFoundException</code> with the specified detail message.
+   * @param msg the detail message
+   */
+  public EntryNotFoundException(String msg) {
+    super(msg);
+  }
+  
+  /**
+   * Constructs an instance of <code>EntryNotFoundException</code> with the specified detail message
+   * and cause.
+   * @param msg the detail message
+   * @param cause the causal Throwable
+   */
+  public EntryNotFoundException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryNotFoundInRegion.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryNotFoundInRegion.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryNotFoundInRegion.java
new file mode 100644
index 0000000..74b74c6
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryNotFoundInRegion.java
@@ -0,0 +1,41 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.GemFireException;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.InternalGemFireError;
+
+/**
+ * @deprecated this class is no longer in use
+ */
+@Deprecated
+public class EntryNotFoundInRegion extends GemFireException {
+  private static final long serialVersionUID = 5572550909947420405L;
+
+  /**
+   * Generates an {@link InternalGemFireError}
+   * @param msg the detail message
+   * @deprecated Do not create instances of this class.
+   */
+  @Deprecated
+  public EntryNotFoundInRegion(String msg) {
+    throw new InternalGemFireError(LocalizedStrings.EntryNotFoundInRegion_THIS_CLASS_IS_DEPRECATED.toLocalizedString());
+  }
+
+  /**
+   * Generates an {@link InternalGemFireError}
+   * @param msg the detail message
+   * @param cause the causal Throwable
+   * @deprecated do not create instances of this class.
+   */
+  @Deprecated
+  public EntryNotFoundInRegion(String msg, Throwable cause) {
+    throw new InternalGemFireError(LocalizedStrings.EntryNotFoundInRegion_THIS_CLASS_IS_DEPRECATED.toLocalizedString());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryOperation.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryOperation.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryOperation.java
new file mode 100755
index 0000000..5e75504
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EntryOperation.java
@@ -0,0 +1,77 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/**
+ * Gemfire Context passed to <code>PartitionedResolver</code> to compute the
+ * data location
+ * 
+ * @author Yogesh Mahajan
+ * @author Mitch Thomas
+ * 
+ * @see PartitionResolver  
+ * @since 6.0 
+ */
+public interface EntryOperation<K,V> {
+
+  /** 
+   * Returns the region to which this cached object belongs or
+   * the region that raised this event for <code>RegionEvent</code>s.
+   * @return the region associated with this object or the region that raised
+   * this event.
+   */
+  public Region<K,V> getRegion();
+
+  /**
+   * Return a description of the operation that triggered this event.
+   * It may return null and should not be used to generate routing object
+   * in {@link PartitionResolver#getRoutingObject(EntryOperation)}
+   * @return the operation that triggered this event.
+   * @since 6.0
+   * @deprecated
+   */
+  public Operation getOperation();
+
+  /** 
+   * Returns the key.
+   * @return the key
+   */
+  public K getKey();
+
+  /** Returns the callbackArgument passed to the method that generated this event.
+   * Provided primarily in case this object or region has already been
+   * destroyed. See the {@link Region} interface methods that take a
+   * callbackArgument parameter.
+   * Only fields on the key should be used when creating the routing object.
+   * @return the callbackArgument associated with this event. <code>null</code>
+   * is returned if the callback argument is not propagated to the event.
+   * This happens for events given to {@link TransactionListener}
+   * and to {@link CacheListener} on the remote side of a transaction commit.
+   */
+  public Object getCallbackArgument();
+
+  /**
+   * Returns <code>true</code> if the callback argument is "available".
+   * Not available means that the callback argument may have existed but it could
+   * not be obtained.
+   * Note that {@link #getCallbackArgument} will return <code>null</code>
+   * when this method returns <code>false</code>.
+   * @since 6.0
+   */
+  public boolean isCallbackArgumentAvailable();
+  
+  /**
+   * Returns the value but may return null and should not be used to generate 
+   * routing object in {@link PartitionResolver#getRoutingObject(EntryOperation)}.
+   *  Only fields on the key should be used when creating the routing object.
+   * @return the value.
+   * @deprecated
+   */
+  public V getNewValue();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EvictionAction.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EvictionAction.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EvictionAction.java
new file mode 100644
index 0000000..c4bb350
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EvictionAction.java
@@ -0,0 +1,105 @@
+package com.gemstone.gemfire.cache;
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+import javax.print.attribute.EnumSyntax;
+/**
+ * The action that an {@link com.gemstone.gemfire.cache.EvictionAlgorithm} takes.
+ * @author Mitch Thomas
+ * @since 5.0
+ * @see com.gemstone.gemfire.cache.EvictionAlgorithm
+ * @see com.gemstone.gemfire.internal.cache.EvictionAttributesImpl
+ */
+public final class EvictionAction extends EnumSyntax
+{
+  private static final long serialVersionUID = -98840597493242980L;
+  /** Canonical EvictionAction that represents no eviction 
+   */
+  public static final EvictionAction NONE = new EvictionAction(0);
+  
+  /** Perform a {@link com.gemstone.gemfire.cache.Region#localDestroy(Object)
+   * localDestory} on the least recently used region entry. */
+  public static final EvictionAction LOCAL_DESTROY = new EvictionAction(1);
+
+  /** Write the value of the least recently used region entry to disk
+   * and <code>null</code>-out its value in the VM to free up heap
+   * space.  Note that this action is only available when the region
+   * has been configured to access data on disk. */
+  public static final EvictionAction OVERFLOW_TO_DISK = new EvictionAction(2);
+
+  /** The default eviction action is to {@linkplain #LOCAL_DESTROY
+   * locally destroy} an Entry. */
+  public static final EvictionAction DEFAULT_EVICTION_ACTION = LOCAL_DESTROY;
+  
+  private EvictionAction(int val) { super(val); }
+  
+  private static final String[] stringTable = {
+    "none",
+    "local-destroy",
+    "overflow-to-disk",
+  };
+  
+  @Override
+  final protected String[] getStringTable() {
+    return stringTable;
+  }
+    
+  private static final EvictionAction[] enumValueTable = {
+    NONE,
+    LOCAL_DESTROY,
+    OVERFLOW_TO_DISK
+  };
+    
+  @Override
+  final protected EnumSyntax[] getEnumValueTable() {
+    return enumValueTable;
+  }
+  
+  public final boolean isLocalDestroy() {
+    return this == LOCAL_DESTROY;
+  }
+  
+  public final boolean isOverflowToDisk() {
+    return this == OVERFLOW_TO_DISK;
+  }
+  
+  public final boolean isNone() {
+    return this == NONE;
+  }
+
+  /**
+   * Returns the eviction action the corresponds to the given parameter.
+   * Returns <code>null</code> if no action corresponds.
+   * @since 6.5
+   */
+  public static EvictionAction parseValue(int v) {
+    if (v < 0 || v >= enumValueTable.length) {
+      return null;
+    } else {
+      return enumValueTable[v];
+    }
+  }
+  /** 
+   * 
+   * @param s
+   * @return the action parsed from the provided string.  If there are problems with parsing
+   * NONE is returned.
+   */
+  public static EvictionAction parseAction(String s) {
+    if (s == null)
+      return NONE;
+    if (s.length() < 1) 
+      return NONE;
+    for (int i = 0; i < stringTable.length; ++i) {
+      if (s.equals(stringTable[i])) {
+        return enumValueTable[i]; 
+      }
+    }
+    return NONE;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EvictionAlgorithm.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EvictionAlgorithm.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EvictionAlgorithm.java
new file mode 100644
index 0000000..33cca0e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EvictionAlgorithm.java
@@ -0,0 +1,141 @@
+package com.gemstone.gemfire.cache;
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+import javax.print.attribute.EnumSyntax;
+
+/** The algorithm used to determine when to perform an {@link com.gemstone.gemfire.cache.EvictionAction}
+ * 
+ * @author Mitch Thomas
+ * @since 5.0
+ * @see com.gemstone.gemfire.cache.EvictionAction
+ * @see com.gemstone.gemfire.internal.cache.EvictionAttributesImpl
+ */
+public final class EvictionAlgorithm extends EnumSyntax
+{
+  private static final long serialVersionUID = 5778669432033106789L;
+  /** 
+   * The canonical EvictionAction that represents no eviction action  
+   */
+  public static final EvictionAlgorithm NONE = new EvictionAlgorithm(0);
+  
+  /**
+   * An algorithm that considers the number of Entries in the Region before
+   * invoking its {@link EvictionAction} 
+   */
+  public static final EvictionAlgorithm LRU_ENTRY = new EvictionAlgorithm(1);
+  
+  /** 
+   * An algorithm that considers the JVM heap size before invoking its {@link EvictionAction}
+   */
+  public static final EvictionAlgorithm LRU_HEAP = new EvictionAlgorithm(2);
+  
+  /** 
+   * An algorithm that considers the amount of bytes consumed by the Region before invoking its {@link EvictionAction} 
+   */
+  public static final EvictionAlgorithm LRU_MEMORY = new EvictionAlgorithm(3);
+  
+  /**
+   * An algorithm that considers the number of Entries in the Region before
+   * invoking its {@link EvictionAction}
+   * 
+   * @deprecated
+   */
+  public static final EvictionAlgorithm LIFO_ENTRY = new EvictionAlgorithm(4);
+
+  /**
+   * An algorithm that considers the amount of bytes consumed by the Region
+   * before invoking its {@link EvictionAction}
+   * 
+   * @deprecated
+   */
+  public static final EvictionAlgorithm LIFO_MEMORY = new EvictionAlgorithm(5);
+  
+  private EvictionAlgorithm(int val) { super(val); }
+  
+  private static final String[] stringTable = {
+    "none",
+    "lru-entry-count",
+    "lru-heap-percentage",
+    "lru-memory-size",
+    "lifo-entry-count",
+    "lifo-memory-size"
+  };
+  
+  @Override
+  final protected String[] getStringTable() {
+    return stringTable;
+  }
+    
+  private static final EvictionAlgorithm[] enumValueTable = {
+    NONE,
+    LRU_ENTRY,
+    LRU_HEAP,
+    LRU_MEMORY,
+    LIFO_ENTRY,
+    LIFO_MEMORY,
+  };
+    
+  @Override
+  final protected EnumSyntax[] getEnumValueTable() {
+    return enumValueTable;
+  }
+
+  /**
+   * Returns the eviction action the corresponds to the given parameter.
+   * Returns <code>null</code> if no action corresponds.
+   * @since 6.5
+   */
+  public static EvictionAlgorithm parseValue(int v) {
+    if (v < 0 || v >= enumValueTable.length) {
+      return null;
+    } else {
+      return enumValueTable[v];
+    }
+  }
+  public static EvictionAlgorithm parseAction(String s) {
+    if (s == null)
+      return null;
+    if (s.length() < 1) 
+      return null;
+    for (int i = 0; i < stringTable.length; ++i) {
+      if (s.equals(stringTable[i])) {
+        return enumValueTable[i]; 
+      }
+    }
+    return null;
+  }
+
+    public final boolean isLRUEntry() {
+	return this == LRU_ENTRY;
+    }
+
+    public final boolean isLRUMemory() {
+	return this == LRU_MEMORY;
+    }
+    
+    public final boolean isLRUHeap() {
+	return this == LRU_HEAP;
+    }
+
+    /** returns true if this object uses a least-recently-used algorithm */
+    public boolean isLRU() {
+      return this.isLRUEntry() || this.isLRUMemory() || this.isLRUHeap();
+    }
+
+    public final boolean isNone() {
+	return this == NONE;
+    }
+
+    /**
+     * @deprecated
+     */
+    public boolean isLIFO() {
+      return this == LIFO_ENTRY || this == LIFO_MEMORY;
+    }
+}


[34/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/AgentImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/AgentImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/AgentImpl.java
new file mode 100644
index 0000000..4dfc517
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/AgentImpl.java
@@ -0,0 +1,1615 @@
+/*
+ * =========================================================================
+ *  Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ *  This product is protected by U.S. and international copyright
+ *  and intellectual property laws. Pivotal products are covered by
+ *  more patents listed at http://www.pivotal.io/patents.
+ * ========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.Notification;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.OperationsException;
+import javax.management.ReflectionException;
+import javax.management.modelmbean.ModelMBean;
+import javax.management.remote.JMXConnectionNotification;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.rmi.RMIConnectorServer;
+import javax.rmi.ssl.SslRMIClientSocketFactory;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.GemFireException;
+import com.gemstone.gemfire.GemFireIOException;
+import com.gemstone.gemfire.LogWriter;
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.admin.AdminDistributedSystem;
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.jmx.Agent;
+import com.gemstone.gemfire.admin.jmx.AgentConfig;
+import com.gemstone.gemfire.admin.jmx.AgentFactory;
+import com.gemstone.gemfire.distributed.internal.DistributionManager;
+import com.gemstone.gemfire.internal.Banner;
+import com.gemstone.gemfire.internal.GemFireVersion;
+import com.gemstone.gemfire.internal.admin.remote.TailLogResponse;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.InternalLogWriter;
+import com.gemstone.gemfire.internal.logging.LogConfig;
+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.LogMarker;
+import com.gemstone.gemfire.internal.logging.log4j.LogWriterAppender;
+import com.gemstone.gemfire.internal.logging.log4j.LogWriterAppenders;
+import com.gemstone.org.jgroups.util.StringId;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import mx4j.tools.adaptor.http.HttpAdaptor;
+
+/**
+ * The GemFire JMX Agent provides the ability to administrate one GemFire
+ * distributed system via JMX.
+ *
+ * @author    Kirk Lund
+ * @author    David Whitlock
+ * @since     3.5
+ */
+public class AgentImpl
+implements com.gemstone.gemfire.admin.jmx.Agent,
+           com.gemstone.gemfire.admin.jmx.internal.ManagedResource {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  /**
+   * MX4J HttpAdaptor only supports "basic" as an authentication method.
+   * Enabling HttpAdaptor authentication ({@link
+   * AgentConfig#HTTP_AUTHENTICATION_ENABLED_NAME}) causes the browser to
+   * require a login with username ({@link
+   * AgentConfig#HTTP_AUTHENTICATION_USER_NAME}) and password ({@link
+   * AgentConfig#HTTP_AUTHENTICATION_PASSWORD_NAME}).
+   */
+  private static final String MX4J_HTTPADAPTOR_BASIC_AUTHENTICATION = "basic";
+
+  /** JMX Service URL template for JMX/RMI Connector Server */
+  private static final String JMX_SERVICE_URL =
+                              "service:jmx:rmi://{0}:{1}/jndi/rmi://{2}:{3}{4}";
+
+  /**
+   * Set third-party logging configration: MX4J, Jakarta Commons-Logging.
+   */
+  static {
+    checkDebug();
+    String commonsLog = System.getProperty("org.apache.commons.logging.log");
+    if (commonsLog == null || commonsLog.length() == 0) {
+      System.setProperty("org.apache.commons.logging.log",
+                         "org.apache.commons.logging.impl.SimpleLog");
+    }
+  }
+
+  /** Enables mx4j tracing if Agent debugging is enabled. */
+  private static void checkDebug() {
+    try {
+      if (Boolean.getBoolean("gfAgentDebug")) {
+        mx4j.log.Log.setDefaultPriority(mx4j.log.Logger.TRACE); // .DEBUG
+      }
+    }
+    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();
+      /*ignore*/
+      }
+  }
+
+  // -------------------------------------------------------------------------
+  //   Member variables
+  // -------------------------------------------------------------------------
+
+  /** This Agent's log writer */
+  private LogWriterAppender logWriterAppender;
+  private InternalLogWriter logWriter;
+
+  /** This Agent's JMX http adaptor from MX4J */
+  private HttpAdaptor httpAdaptor;
+
+  /** This Agent's RMI Connector Server from MX4J */
+  private JMXConnectorServer rmiConnector;
+
+  /** The name of the MBean manages this resource */
+  private final String mbeanName;
+
+  /** The ObjectName of the MBean that manages this resource */
+  private final ObjectName objectName;
+
+  /** The actual ModelMBean that manages this resource */
+  private ModelMBean modelMBean;
+
+  /** The configuration for this Agent */
+  private final AgentConfigImpl agentConfig;
+
+  /** The <code>AdminDistributedSystem</code> this Agent is currently
+   * connected to or <code>null</code> */
+  private AdminDistributedSystem system;
+
+  /** The agent's configuration file */
+  private String propertyFile;
+
+  /** A lock object to guard the Connect and Disconnect calls being
+    * made on the agent for connections to the DS **/
+  private Object CONN_SYNC = new Object();
+
+  protected MemberInfoWithStatsMBean memberInfoWithStatsMBean;
+
+  private MBeanServer mBeanServer;
+
+  // -------------------------------------------------------------------------
+  //   Constructor(s)
+  // -------------------------------------------------------------------------
+
+  /**
+   * Constructs a new Agent using the specified configuration.
+   *
+   * @param agentConfig instance of configuration for Agent
+   * @throws com.gemstone.gemfire.admin.AdminException TODO-javadocs
+   * @throws IllegalArgumentException if agentConfig is null
+   */
+  public AgentImpl(AgentConfigImpl agentConfig)
+    throws AdminException, IllegalArgumentException {
+    addShutdownHook();
+    if (agentConfig == null) {
+      throw new IllegalArgumentException(LocalizedStrings.AgentImpl_AGENTCONFIG_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+    this.agentConfig = (AgentConfigImpl)agentConfig;
+    this.mbeanName   = MBEAN_NAME_PREFIX + MBeanUtil.makeCompliantMBeanNameProperty("Agent");
+
+    try {
+      this.objectName = new ObjectName(this.mbeanName);
+    } catch (MalformedObjectNameException ex) {
+      String s = LocalizedStrings.AgentImpl_WHILE_CREATING_OBJECTNAME_0.toLocalizedString(new Object[] { this.mbeanName });
+      throw new AdminException(s, ex);
+    }
+
+    this.propertyFile = this.agentConfig.getPropertyFile().getAbsolutePath();
+
+    // bind address only affects how the Agent VM connects to the system...
+    // It should be set only once in the agent lifecycle
+    this.agentConfig.setBindAddress(getBindAddress());
+
+    // LOG: create LogWriterAppender and LogWriterLogger
+    initLogWriter();
+
+    mBeanServer = MBeanUtil.start();
+
+    MBeanUtil.createMBean(this);
+
+    initializeHelperMbean();
+  }
+
+  private void initializeHelperMbean() {
+    try {
+      memberInfoWithStatsMBean = new MemberInfoWithStatsMBean(this);
+
+      MBeanServer mbs = getMBeanServer();
+      mbs.registerMBean(memberInfoWithStatsMBean, memberInfoWithStatsMBean.getObjectName());
+      /*
+       * We are not re-throwing these exceptions as failure create/register the
+       * GemFireTypesWrapper will not stop the Agent from working. But we are
+       * logging it as it could be an indication of some problem.
+       * Also not creating Localized String for the exception.
+       */
+    } catch (OperationsException e) {
+      logger.info(LocalizedMessage.create(LocalizedStrings.AgentImpl_FAILED_TO_INITIALIZE_MEMBERINFOWITHSTATSMBEAN), e);
+    } catch (MBeanRegistrationException e) {
+      logger.info(LocalizedMessage.create(LocalizedStrings.AgentImpl_FAILED_TO_INITIALIZE_MEMBERINFOWITHSTATSMBEAN), e);
+    } catch (AdminException e) {
+      logger.info(LocalizedMessage.create(LocalizedStrings.AgentImpl_FAILED_TO_INITIALIZE_MEMBERINFOWITHSTATSMBEAN), e);
+    }
+  }
+
+  // -------------------------------------------------------------------------
+  //   Public operations
+  // -------------------------------------------------------------------------
+
+  public AgentConfig getConfig() {
+    return this.agentConfig;
+  }
+
+  public AdminDistributedSystem getDistributedSystem() {
+    return this.system;
+  }
+
+  /**
+   * Persists the current Agent configuration to its property file.
+   *
+   * @throws GemFireIOException if unable to persist the configuration to props
+   * @see #getPropertyFile
+   */
+  public void saveProperties() {
+    throw new GemFireIOException("saveProperties is no longer supported for security reasons");
+  }
+
+  /**
+   * Starts the jmx agent
+   */
+  public void start() {
+    checkDebug();
+
+    this.agentConfig.validate();
+
+    if (mBeanServer == null) {
+      mBeanServer = MBeanUtil.start();
+    }
+
+    try {
+      startHttpAdaptor();
+    } catch (StartupException e) {
+      AlertAppender.getInstance().shuttingDown();
+      LogWriterAppenders.stop(LogWriterAppenders.Identifier.MAIN);
+      LogWriterAppenders.destroy(LogWriterAppenders.Identifier.MAIN);
+      throw e;
+    }
+
+    try {
+      startRMIConnectorServer();
+    } catch (StartupException e) {
+      stopHttpAdaptor();
+      AlertAppender.getInstance().shuttingDown();
+      LogWriterAppenders.stop(LogWriterAppenders.Identifier.MAIN);
+      LogWriterAppenders.destroy(LogWriterAppenders.Identifier.MAIN);
+      throw e;
+    }
+
+    try {
+      startSnmpAdaptor();
+    } catch (StartupException e) {
+      stopRMIConnectorServer();
+      stopHttpAdaptor();
+      AlertAppender.getInstance().shuttingDown();
+      LogWriterAppenders.stop(LogWriterAppenders.Identifier.MAIN);
+      LogWriterAppenders.destroy(LogWriterAppenders.Identifier.MAIN);
+      throw e;
+    }
+
+    if (this.agentConfig.getAutoConnect()) {
+      try {
+        connectToSystem();
+        /*
+         * Call Agent.stop() if connectToSystem() fails. This should clean up
+         * agent-DS connection & stop all the HTTP/RMI/SNMP adapters started
+         * earlier.
+         */
+      } catch (AdminException ex) {
+        logger.error(LocalizedMessage.create(LocalizedStrings.AgentImpl_AUTO_CONNECT_FAILED__0, ex.getMessage()));
+        this.stop();
+        throw new StartupException(ex);
+      } catch (MalformedObjectNameException ex) {
+        StringId autoConnectFailed = LocalizedStrings.AgentImpl_AUTO_CONNECT_FAILED__0;
+        logger.error(LocalizedMessage.create(autoConnectFailed, ex.getMessage()));
+        this.stop();
+        throw new StartupException(new AdminException(autoConnectFailed.toLocalizedString(new Object[] { ex.getMessage() }), ex));
+      }
+    } // getAutoConnect
+
+    logger.info(LocalizedMessage.create(LocalizedStrings.AgentImpl_GEMFIRE_JMX_AGENT_IS_RUNNING));
+    LogWriterAppenders.startupComplete(LogWriterAppenders.Identifier.MAIN);
+
+    if (memberInfoWithStatsMBean == null) {
+      initializeHelperMbean();
+    }
+  }
+
+  /**
+   * Deregisters everything this Agent registered and releases the MBeanServer.
+   */
+  public void stop() {
+    try {
+      logger.info(LocalizedMessage.create(LocalizedStrings.AgentImpl_STOPPING_JMX_AGENT));
+      AlertAppender.getInstance().shuttingDown();
+      LogWriterAppenders.stop(LogWriterAppenders.Identifier.MAIN);
+
+      // stop the GemFire Distributed System
+      stopDistributedSystem();
+
+      // stop all JMX Adaptors and Connectors...
+      stopHttpAdaptor();
+      stopRMIConnectorServer();
+      memberInfoWithStatsMBean = null;
+      stopSnmpAdaptor();
+
+      // release the MBeanServer for cleanup...
+      MBeanUtil.stop();
+      mBeanServer = null;
+
+      // remove the register shutdown hook which disconnects the Agent from the Distributed System upon JVM shutdown
+      removeShutdownHook();
+
+      logger.info(LocalizedMessage.create(LocalizedStrings.AgentImpl_AGENT_HAS_STOPPED));
+    }
+    finally {
+      LogWriterAppenders.destroy(LogWriterAppenders.Identifier.MAIN);
+      LoggingThreadGroup.cleanUpThreadGroups(); // bug35388 - logwriters accumulate, causing mem leak
+    }
+
+  }
+
+  private void stopDistributedSystem() {
+    // disconnect from the distributed system...
+    try {
+      disconnectFromSystem();
+    }
+    catch (Exception e) {
+      // disconnectFromSystem already prints any Exceptions
+    }
+    catch (VirtualMachineError err) {
+      SystemFailure.initiateFailure(err);
+      throw err;
+    }
+    catch (Error 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();
+    }
+  }
+
+  public ObjectName manageDistributedSystem()
+  throws MalformedObjectNameException {
+    synchronized (CONN_SYNC) {
+      if (isConnected()) {
+        return ((AdminDistributedSystemJmxImpl) this.system).getObjectName();
+      }
+      return null;
+    }
+  }
+
+  /**
+   * Connects to the DistributedSystem currently described by this Agent's
+   * attributes for administration and monitoring.
+   *
+   * @return the object name of the system that the Agent is now connected to
+   */
+  @SuppressFBWarnings(value="ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification="This is only a style warning.") 
+  public ObjectName connectToSystem()
+  throws AdminException, MalformedObjectNameException {
+    synchronized(CONN_SYNC) {
+      try {
+        if (isConnected()) {
+          return ((AdminDistributedSystemJmxImpl) this.system).getObjectName();
+        }
+
+        DistributionManager.isDedicatedAdminVM = true;
+
+        AdminDistributedSystemJmxImpl systemJmx =
+          (AdminDistributedSystemJmxImpl) this.system;
+        if (systemJmx == null) {
+          systemJmx = (AdminDistributedSystemJmxImpl)
+            createDistributedSystem(this.agentConfig);
+          this.system = systemJmx;
+        }
+        systemJmx.connect(this.logWriter);
+
+        return new ObjectName(systemJmx.getMBeanName());
+      } catch (AdminException e) {
+        logger.warn(e.getMessage(), e);
+        throw e;
+      } catch (RuntimeException e) {
+        logger.warn(e.getMessage(), e);
+        throw 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 (Error 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();
+        logger.error(e.getMessage(), e);
+        throw e;
+      }
+    }
+  }
+
+  /**
+   * Disconnects from the current DistributedSystem (if connected to one).
+   */
+  @SuppressFBWarnings(value="ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification="This is only a style warning.") 
+  public void disconnectFromSystem() {
+    synchronized(CONN_SYNC) {
+      try {
+        if (this.system == null || !this.system.isConnected()) {
+          return;
+        }
+        ((AdminDistributedSystemJmxImpl)this.system).disconnect();
+//         this.system = null;
+      } catch (RuntimeException e) {
+        logger.warn(e.getMessage(), e);
+        throw 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 (Error 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();
+        logger.warn(e.getMessage(), e);
+        throw e;
+      } finally {
+        DistributionManager.isDedicatedAdminVM = false;
+      }
+    }
+  }
+
+  /**
+   * Retrieves a displayable snapshot of this Agent's log.
+   *
+   * @return snapshot of the current log
+   */
+  public String getLog() {
+    String childTail = tailFile(this.logWriterAppender.getChildLogFile());
+    String mainTail = tailFile(new File(this.agentConfig.getLogFile()));
+    if (childTail == null && mainTail == null) {
+      return LocalizedStrings.AgentImpl_NO_LOG_FILE_CONFIGURED_LOG_MESSAGES_WILL_BE_DIRECTED_TO_STDOUT.toLocalizedString();
+    } else {
+      StringBuffer result = new StringBuffer();
+      if (mainTail != null) {
+        result.append(mainTail);
+      }
+      if (childTail != null) {
+        result.append("\n" + LocalizedStrings.AgentImpl_TAIL_OF_CHILD_LOG.toLocalizedString() + "\n");
+        result.append(childTail);
+      }
+      return result.toString();
+    }
+  }
+
+  /**
+   * Retrieves display-friendly GemFire version information.
+   */
+  public String getVersion() {
+    return GemFireVersion.asString();
+  }
+
+  // -------------------------------------------------------------------------
+  //   Public attribute accessors/mutators
+  // -------------------------------------------------------------------------
+
+  /** Returns true if this Agent is currently connected to a system. */
+  public boolean isConnected() {
+    boolean result = false;
+    synchronized (CONN_SYNC) {
+     result = ((this.system != null) && this.system.isConnected());
+    }
+    return result;
+  }
+
+  /**
+   * Gets the agent's property file. This is the file it will use
+   * when saving its configuration. It was also used when the agent
+   * started to initialize its configuration.
+   * @return the agent's property file
+   */
+  public String getPropertyFile() {
+    return this.propertyFile;
+  }
+
+  /**
+   * Sets the agent's property file.
+   *
+   * @param value the name of the file to save the agent properties in.
+   * @throws IllegalArgumentException if the specified file is a directory.
+   * @throws IllegalArgumentException if the specified file's parent is not an existing directory.
+   */
+  public void setPropertyFile(String value) {
+    File f = (new File(value)).getAbsoluteFile();
+    if (f.isDirectory()) {
+        throw new IllegalArgumentException(LocalizedStrings.AgentImpl_THE_FILE_0_IS_A_DIRECTORY.toLocalizedString(f));
+    }
+    File parent = f.getParentFile();
+    if (parent != null) {
+      if (!parent.isDirectory()) {
+        throw new IllegalArgumentException(LocalizedStrings.AgentImpl_THE_DIRECTORY_0_DOES_NOT_EXIST.toLocalizedString(parent));
+      }
+    }
+    this.propertyFile = f.getPath();
+  }
+
+  /**
+   * Gets the mcastAddress of the distributed system that this Agent is
+   * managing.
+   *
+   * @return   The mcastAddress value
+   */
+  public String getMcastAddress() {
+    return this.agentConfig.getMcastAddress();
+  }
+
+  /**
+   * Sets the mcastAddress of the distributed system that this Agent is
+   * managing.
+   *
+   * @param mcastAddress  The new mcastAddress value
+   */
+  public void setMcastAddress(String mcastAddress) {
+    this.agentConfig.setMcastAddress(mcastAddress);
+  }
+
+  /**
+   * Gets the mcastPort of the distributed system that this Agent is managing.
+   *
+   * @return   The mcastPort value
+   */
+  public int getMcastPort() {
+    return this.agentConfig.getMcastPort();
+  }
+
+  /**
+   * Sets the mcastPort of the distributed system that this Agent is managing.
+   *
+   * @param mcastPort  The new mcastPort value
+   */
+  public void setMcastPort(int mcastPort) {
+    this.agentConfig.setMcastPort(mcastPort);
+  }
+
+  /**
+   * Gets the locators of the distributed system that this Agent is managing.
+   * <p>
+   * Format is a comma-delimited list of "host[port]" entries.
+   *
+   * @return   The locators value
+   */
+  public String getLocators() {
+    return this.agentConfig.getLocators();
+  }
+
+  /**
+   * Sets the locators of the distributed system that this Agent is managing.
+   * <p>
+   * Format is a comma-delimited list of "host[port]" entries.
+   *
+   * @param locators  The new locators value
+   */
+  public void setLocators(String locators) {
+    this.agentConfig.setLocators(locators);
+  }
+
+  /**
+   * Gets the membership UDP port range in the distributed system that this
+   * Agent is monitoring.
+   * <p>
+   * This range is given as two numbers separated by a minus sign like "min-max"
+   *
+   * @return membership UDP port range
+   */
+  public String getMembershipPortRange() {
+    return this.agentConfig.getMembershipPortRange();
+  }
+
+  /**
+   * Sets the membership UDP port range in the distributed system that this
+   * Agent is monitoring.
+   * <p>
+   * This range is given as two numbers separated by a minus sign like "min-max"
+   *
+   * @param membershipPortRange membership UDP port range
+   */
+  public void setMembershipPortRange(String membershipPortRange) {
+    this.agentConfig.setMembershipPortRange(membershipPortRange);
+  }
+
+  /**
+   * Gets the bindAddress of the distributed system that this Agent is managing.
+   *
+   * @return   The bindAddress value
+   */
+  public String getBindAddress() {
+     return this.agentConfig.getBindAddress();
+  }
+
+  /**
+   * Sets the bindAddress of the distributed system that this Agent is managing.
+   *
+   * @param bindAddress  The new bindAddress value
+   */
+  public void setBindAddress(String bindAddress) {
+    this.agentConfig.setBindAddress(bindAddress);
+  }
+
+  /**
+   * Retrieves the command that the DistributedSystem will use to perform remote
+   * manipulation of config files and log files.
+   *
+   * @return   the remote command for DistributedSystem
+   */
+	public String getRemoteCommand() {
+		return this.agentConfig.getRemoteCommand();
+	}
+
+  /**
+   * Sets the command that the DistributedSystem will use to perform remote
+   * manipulation of config files and log files.
+   *
+   * @param remoteCommand the remote command for DistributedSystem
+   */
+	public void setRemoteCommand(String remoteCommand) {
+		this.agentConfig.setRemoteCommand(remoteCommand);
+	}
+
+  /** Returns the system identity for the DistributedSystem */
+  public String getSystemId() {
+    return this.agentConfig.getSystemId();
+  }
+
+  /** Sets the system identity for the DistributedSystem */
+  public void setSystemId(String systemId) {
+    this.agentConfig.setSystemId(systemId);
+  }
+
+  /**
+   * Gets the logFileSizeLimit in megabytes of this Agent. Zero indicates no
+   * limit.
+   *
+   * @return   The logFileSizeLimit value
+   */
+  public int getLogFileSizeLimit() {
+    return this.agentConfig.getLogFileSizeLimit();
+  }
+
+  /**
+   * Sets the logFileSizeLimit in megabytes of this Agent. Zero indicates no
+   * limit.
+   *
+   * @param logFileSizeLimit  The new logFileSizeLimit value
+   */
+  public void setLogFileSizeLimit(int logFileSizeLimit) {
+    this.agentConfig.setLogFileSizeLimit(logFileSizeLimit);
+    LogWriterAppenders.configChanged(LogWriterAppenders.Identifier.MAIN);
+  }
+
+  /**
+   * Gets the logDiskSpaceLimit in megabytes of this Agent. Zero indicates no
+   * limit.
+   *
+   * @return   The logDiskSpaceLimit value
+   */
+  public int getLogDiskSpaceLimit() {
+    return this.agentConfig.getLogDiskSpaceLimit();
+  }
+
+  /**
+   * Sets the logDiskSpaceLimit in megabytes of this Agent. Zero indicates no
+   * limit.
+   *
+   * @param logDiskSpaceLimit  The new logDiskSpaceLimit value
+   */
+  public void setLogDiskSpaceLimit(int logDiskSpaceLimit) {
+    this.agentConfig.setLogDiskSpaceLimit(logDiskSpaceLimit);
+    LogWriterAppenders.configChanged(LogWriterAppenders.Identifier.MAIN);
+  }
+
+  /**
+   * Gets the logFile name for this Agent to log to.
+   *
+   * @return   The logFile value
+   */
+  public String getLogFile() {
+    return this.agentConfig.getLogFile();
+  }
+
+  /**
+   * Sets the logFile name for this Agent to log to.
+   *
+   * @param logFile  The new logFile value
+   */
+  public void setLogFile(String logFile) {
+    this.agentConfig.setLogFile(logFile);
+    LogWriterAppenders.configChanged(LogWriterAppenders.Identifier.MAIN);
+  }
+
+  /**
+   * Gets the logLevel of this Agent.
+   *
+   * @return   The logLevel value
+   */
+  public String getLogLevel() {
+    return this.agentConfig.getLogLevel();
+  }
+
+  /**
+   * Sets the logLevel of this Agent.
+   *
+   * @param logLevel  The new logLevel value
+   */
+  public void setLogLevel(String logLevel) {
+    this.agentConfig.setLogLevel(logLevel);
+    LogWriterAppenders.configChanged(LogWriterAppenders.Identifier.MAIN);
+  }
+
+  /** Returns true if the Agent is set to auto connect to a system. */
+  public boolean getAutoConnect() {
+    return this.agentConfig.getAutoConnect();
+  }
+  /** Returns true if the Agent is set to auto connect to a system. */
+  public boolean isAutoConnect() {
+    return this.agentConfig.getAutoConnect();
+  }
+  /** Sets or unsets the option to auto connect to a system. */
+  public void setAutoConnect(boolean v) {
+    this.agentConfig.setAutoConnect(v);
+  }
+
+  /**
+   * Returns the address (URL) on which the RMI connector server runs
+   * or <code>null</code> if the RMI connector server has not been
+   * started.  This method is used primarily for testing purposes.
+   *
+   * @see JMXConnectorServer#getAddress()
+   */
+  public JMXServiceURL getRMIAddress() {
+    if (this.rmiConnector != null) {
+      return this.rmiConnector.getAddress();
+
+    } else {
+      return null;
+    }
+  }
+
+  /**
+   * Gets the configuration for this Agent.
+   *
+   * @return the configuration for this Agent
+   */
+  protected AgentConfig getAgentConfig() {
+    return this.agentConfig;
+  }
+
+  // -------------------------------------------------------------------------
+  //   Internal implementation methods
+  // -------------------------------------------------------------------------
+
+  /** Returns the tail of the system log specified by <code>File</code>. */
+  private String tailFile(File f) {
+    try {
+      return TailLogResponse.tailSystemLog(f);
+    }
+    catch (IOException ex) {
+      return LocalizedStrings.AgentImpl_COULD_NOT_TAIL_0_BECAUSE_1.toLocalizedString(new Object[] {f, ex});
+    }
+  }
+
+  /**
+   * Returns the active MBeanServer which has any GemFire MBeans registered.
+   *
+   * @return   the GemFire mbeanServer
+   */
+  public MBeanServer getMBeanServer() {
+    return mBeanServer;
+  }
+
+//  /**
+//   * Returns the active modeler Registry which has been initialized with all
+//   * the ModelMBean descriptors needed for GemFire MBeans.
+//   *
+//   * @return   the modeler registry
+//  */
+//  private Registry getRegistry() {
+//    return MBeanUtil.getRegistry();
+//  }
+
+  /**
+   * Gets the current instance of LogWriter for logging
+   *
+   * @return the logWriter
+   */
+  public LogWriter getLogWriter() {
+    return this.logWriter;
+  }
+
+  private final Thread shutdownHook =
+    new Thread(LoggingThreadGroup.createThreadGroup("Shutdown"), "Shutdown") {
+      @Override
+      public void run() {
+          disconnectFromSystem();
+      }
+    };
+    
+  /**
+   * Adds a ShutdownHook to the Agent for cleaning up any resources
+   */
+  private void addShutdownHook() {
+    if( ! Boolean.getBoolean( com.gemstone.gemfire.distributed.internal.InternalDistributedSystem.DISABLE_SHUTDOWN_HOOK_PROPERTY)) {
+      Runtime.getRuntime().addShutdownHook(shutdownHook);
+    }
+  }
+
+  private void removeShutdownHook() {
+    if( ! Boolean.getBoolean( com.gemstone.gemfire.distributed.internal.InternalDistributedSystem.DISABLE_SHUTDOWN_HOOK_PROPERTY)) {
+      Runtime.getRuntime().removeShutdownHook(shutdownHook);
+    }
+  }
+
+  /**
+   * Creates a LogWriterI18n for this Agent to use in logging.
+   */
+  @SuppressFBWarnings(value="RV_RETURN_VALUE_IGNORED_BAD_PRACTICE", justification="Return value for file delete is not important here.") 
+  private void initLogWriter() throws com.gemstone.gemfire.admin.AdminException {
+    final LogConfig logConfig = this.agentConfig.createLogConfig();
+    
+    // LOG: create logWriterAppender here
+    this.logWriterAppender = LogWriterAppenders.getOrCreateAppender(LogWriterAppenders.Identifier.MAIN, false, logConfig, false);
+
+    // LOG: look in AgentConfigImpl for existing LogWriter to use
+    InternalLogWriter existingLogWriter = this.agentConfig.getInternalLogWriter();
+    if (existingLogWriter != null) {
+      this.logWriter = existingLogWriter;
+    } else {      
+      // LOG: create LogWriterLogger
+      this.logWriter = LogWriterFactory.createLogWriterLogger(false, false, logConfig, false);
+      // LOG: changed statement from config to info
+      this.logWriter.info(Banner.getString(null));
+      // Set this log writer in AgentConfigImpl
+      this.agentConfig.setInternalLogWriter(this.logWriter);
+    }
+    
+    // LOG: create logWriter here
+    this.logWriter = LogWriterFactory.createLogWriterLogger(false, false, logConfig, false);
+
+    // Set this log writer in AgentConfig
+    this.agentConfig.setInternalLogWriter(this.logWriter);
+
+    // Print Banner information
+    logger.info(Banner.getString(this.agentConfig.getOriginalArgs()));
+
+    // LOG:CONFIG: changed next three statements from config to info
+    logger.info(LogMarker.CONFIG, LocalizedStrings.AgentImpl_AGENT_CONFIG_PROPERTY_FILE_NAME_0.toLocalizedString(AgentConfigImpl.retrievePropertyFile()));
+    logger.info(LogMarker.CONFIG, this.agentConfig.getPropertyFileDescription());
+    logger.info(LogMarker.CONFIG, this.agentConfig.toPropertiesAsString());
+  }
+
+  /**
+   * Stops the HttpAdaptor and its XsltProcessor.  Unregisters the associated
+   * MBeans.
+   */
+  private void stopHttpAdaptor() {
+    if (!this.agentConfig.isHttpEnabled()) return;
+
+    // stop the adaptor...
+    try {
+      this.httpAdaptor.stop();
+    } catch (Exception e) {
+      logger.warn(e.getMessage(), e);
+    }
+
+    try {
+      MBeanUtil.unregisterMBean(getHttpAdaptorName());
+      MBeanUtil.unregisterMBean(getXsltProcessorName());
+    } catch (MalformedObjectNameException e) {
+      logger.warn(e.getMessage(), e);
+    }
+  }
+
+  /** Stops the RMIConnectorServer and unregisters its MBean. */
+  private void stopRMIConnectorServer() {
+    if (!this.agentConfig.isRmiEnabled()) return;
+
+    // stop the RMI Connector server...
+    try {
+      this.rmiConnector.stop();
+    } catch (Exception e) {
+      logger.warn(e.getMessage(), e);
+    }
+
+    try {
+      ObjectName rmiRegistryNamingName = getRMIRegistryNamingName();
+      if (this.agentConfig.isRmiRegistryEnabled() &&
+          mBeanServer.isRegistered(rmiRegistryNamingName)) {
+        String[] empty = new String[0];
+        mBeanServer.invoke(rmiRegistryNamingName, "stop", empty, empty);
+        MBeanUtil.unregisterMBean(rmiRegistryNamingName);
+      }
+    } catch (MalformedObjectNameException e) {
+      logger.warn(e.getMessage(), e);
+    } catch (InstanceNotFoundException e) {
+      logger.warn(e.getMessage(), e);
+    } catch (ReflectionException e) {
+      logger.warn(e.getMessage(), e);
+    } catch (MBeanException e) {
+      logger.warn(e.getMessage(), e);
+    }
+
+    try {
+      ObjectName rmiConnectorServerName = getRMIConnectorServerName();
+      if (mBeanServer.isRegistered(rmiConnectorServerName)) {
+        MBeanUtil.unregisterMBean(rmiConnectorServerName);
+      }
+    } catch (MalformedObjectNameException e) {
+      logger.warn(e.getMessage(), e);
+    }
+  }
+
+  /** Stops the SnmpAdaptor and unregisters its MBean. */
+  private void stopSnmpAdaptor() {
+    if (!this.agentConfig.isSnmpEnabled()) return;
+
+    // stop the SnmpAdaptor...
+    try {
+      getMBeanServer().invoke(getSnmpAdaptorName(), "unbind",
+                              new Object[0],
+                              new String[0]);
+    } catch (Exception e) {
+      logger.warn(e.getMessage(), e);
+    }
+
+    try {
+      MBeanUtil.unregisterMBean(getSnmpAdaptorName());
+    } catch (MalformedObjectNameException e) {
+      logger.warn(e.getMessage(), e);
+    }
+  }
+
+  /** Returns the JMX ObjectName for the RMI registry Naming MBean. */
+  private ObjectName getRMIRegistryNamingName()
+  throws javax.management.MalformedObjectNameException {
+    return ObjectName.getInstance("naming:type=rmiregistry");
+  }
+
+  /** Returns the JMX ObjectName for the HttpAdaptor. */
+  private ObjectName getHttpAdaptorName()
+  throws javax.management.MalformedObjectNameException {
+    return new ObjectName("Server:name=HttpAdaptor");
+  }
+
+  /** Returns the JMX ObjectName for the RMIConnectorServer. */
+  private ObjectName getRMIConnectorServerName()
+  throws javax.management.MalformedObjectNameException {
+    return new ObjectName("connectors:protocol=rmi");
+  }
+
+  /** Returns the JMX ObjectName for the SnmpAdaptor. */
+  private ObjectName getSnmpAdaptorName()
+  throws javax.management.MalformedObjectNameException {
+    return new ObjectName("Adaptors:protocol=SNMP");
+  }
+
+  /** Returns the JMX ObjectName for the HttpAdaptor's XsltProcessor. */
+  private ObjectName getXsltProcessorName()
+  throws javax.management.MalformedObjectNameException {
+    return new ObjectName("Server:name=XSLTProcessor");
+  }
+
+  // -------------------------------------------------------------------------
+  //   Factory method for creating DistributedSystem
+  // -------------------------------------------------------------------------
+
+  /**
+   * Creates and connects to a <code>DistributedSystem</code>.
+   *
+   * @param config
+   */
+  private AdminDistributedSystem createDistributedSystem(AgentConfigImpl config)
+  throws com.gemstone.gemfire.admin.AdminException {
+    return new AdminDistributedSystemJmxImpl(config);
+  }
+
+  // -------------------------------------------------------------------------
+  //   Agent main
+  // -------------------------------------------------------------------------
+
+  /**
+   * Command-line main for running the GemFire Management Agent.
+   * <p>
+   * Accepts command-line arguments matching the options in {@link AgentConfig}
+   * and {@link com.gemstone.gemfire.admin.DistributedSystemConfig}.
+   * <p>
+   * <code>AgentConfig</code> will convert -Jarguments to System properties.
+   */
+  public static void main(String[] args) {
+    SystemFailure.loadEmergencyClasses();
+
+    AgentConfigImpl ac;
+    try {
+      ac = new AgentConfigImpl(args);
+    }
+    catch (RuntimeException ex) {
+      System.err.println(LocalizedStrings.AgentImpl_FAILED_READING_CONFIGURATION_0.toLocalizedString(ex));
+      System.exit(1);
+      return;
+    }
+
+    try {
+      Agent agent = AgentFactory.getAgent(ac);
+      agent.start();
+
+    }
+    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();
+      System.exit(1);
+    }
+  }
+
+  // -------------------------------------------------------------------------
+  //   MX4J Connectors/Adaptors
+  // -------------------------------------------------------------------------
+
+  private void createRMIRegistry() throws Exception {
+    if (!this.agentConfig.isRmiRegistryEnabled()) {
+      return;
+    }
+    MBeanServer mbs = getMBeanServer();
+    String host = this.agentConfig.getRmiBindAddress();
+    int    port = this.agentConfig.getRmiPort();
+
+    /* Register and start the rmi-registry naming MBean, which is
+     * needed by JSR 160 RMIConnectorServer */
+    ObjectName registryName = getRMIRegistryNamingName();
+    try {
+      RMIRegistryService registryNamingService = null;
+      if (host != null && !("".equals(host.trim()))) {
+        registryNamingService = new RMIRegistryService(host, port);
+      } else {
+        registryNamingService = new RMIRegistryService(port);
+      }
+      mbs.registerMBean(registryNamingService, registryName);
+    } catch (javax.management.InstanceAlreadyExistsException e) {
+      logger.info(LocalizedMessage.create(LocalizedStrings.AgentImpl_0__IS_ALREADY_REGISTERED,
+                          registryName));
+    }
+    mbs.invoke(registryName, "start", null, null);
+  }
+
+  /**
+   * Defines and starts the JMX RMIConnector and service.
+   * <p>
+   * If {@link AgentConfig#isRmiEnabled} returns false, then this adaptor will
+   * not be started.
+   */
+  private void startRMIConnectorServer() {
+    if (!this.agentConfig.isRmiEnabled()) return;
+
+    String rmiBindAddress  = this.agentConfig.getRmiBindAddress();
+
+    // Set RMI Stubs to use the given RMI Bind Address
+    // Default bindAddress is "", if none is set - ignore if not set
+    // If java.rmi.server.hostname property is specified then
+    // that override is not changed
+    String rmiStubServerNameKey = "java.rmi.server.hostname";
+    String overrideHostName     = System.getProperty(rmiStubServerNameKey);
+    if ((overrideHostName == null || overrideHostName.trim().length()==0) &&
+        (rmiBindAddress != null && rmiBindAddress.trim().length()!=0)
+       ) {
+      System.setProperty(rmiStubServerNameKey, rmiBindAddress);
+      logger.info(LocalizedMessage.create(LocalizedStrings.AgentImpl_SETTING_0,
+          new StringBuilder(rmiStubServerNameKey).append(" = ").append(rmiBindAddress)));
+    }
+
+    try {
+      createRMIRegistry();
+      ObjectName objName = getRMIConnectorServerName();
+
+      // make sure this adaptor is not already registered...
+      if (getMBeanServer().isRegistered(objName)) {
+        // dunno how we got here...
+        logger.info(LocalizedMessage.create(LocalizedStrings.AgentImpl_RMICONNECTORSERVER_ALREADY_REGISTERED_AS__0, objName));
+        return;
+      }
+
+      /*
+       * url defined as: service:jmx:protocol:sap
+       * where
+       * 1. protocol: rmi
+       * 2. sap is: [host[:port]][url-path]
+       *    where
+       *      host: rmi-binding-address
+       *      port: rmi-server-port
+       *      url-path: /jndi/rmi://<rmi-binding-address>:<rmi-port><JNDI_NAME>
+       */
+      String urlString           = null;
+      String connectorServerHost = "";
+      int    connectorServerPort = this.agentConfig.getRmiServerPort();
+      String rmiRegistryHost     = "";
+      int    rmiRegistryPort     = this.agentConfig.getRmiPort();
+
+      // Set registryHost to localhost if not specified
+      // RMI stubs would use a default IP if namingHost is left empty
+      if (rmiBindAddress == null || rmiBindAddress.trim().length()==0) {
+        connectorServerHost = "localhost";
+        rmiRegistryHost   = "";
+      } else {
+        connectorServerHost = applyRFC2732(rmiBindAddress);
+        rmiRegistryHost     = connectorServerHost;
+      }
+
+      urlString = MessageFormat.format(AgentImpl.JMX_SERVICE_URL,
+                                           connectorServerHost,
+                                           String.valueOf(connectorServerPort),
+                                           rmiRegistryHost,
+                                           String.valueOf(rmiRegistryPort),
+                                           JNDI_NAME);
+
+      logger.debug("JMX Service URL string is : \"{}\"", urlString);
+
+      // The address of the connector
+      JMXServiceURL url = new JMXServiceURL(urlString);
+
+      Map<String, Object> env = new HashMap<String, Object>();
+//      env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
+//      env.put(Context.PROVIDER_URL, "rmi://localhost:1099");
+
+      RMIServerSocketFactory ssf = new MX4JServerSocketFactory(
+            this.agentConfig.isAgentSSLEnabled(),     // true,
+            this.agentConfig.isAgentSSLRequireAuth(), // true,
+            this.agentConfig.getAgentSSLProtocols(),  // "any",
+            this.agentConfig.getAgentSSLCiphers(),    // "any",
+            this.agentConfig.getRmiBindAddress(),
+            10,  // backlog
+            this.agentConfig.getGfSecurityProperties());
+      env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf);
+
+      if (this.agentConfig.isAgentSSLEnabled()) {
+        RMIClientSocketFactory csf = new SslRMIClientSocketFactory();
+        env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf);
+      }
+
+      MBeanServer mbs = null; // will be set by registering w/ mbeanServer
+      this.rmiConnector =
+                JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
+
+      // for cleanup
+      this.rmiConnector.addNotificationListener(
+          new ConnectionNotificationAdapter(),
+          new ConnectionNotificationFilterImpl(),
+          this);
+
+      // Register the JMXConnectorServer in the MBeanServer
+      getMBeanServer().registerMBean(this.rmiConnector, objName);
+
+      // Start the JMXConnectorServer
+      this.rmiConnector.start();
+    } 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(LocalizedStrings.AgentImpl_FAILED_TO_START_RMICONNECTORSERVER, t);
+      throw new StartupException(LocalizedStrings.AgentImpl_FAILED_TO_START_RMI_SERVICE.toLocalizedString(), t);
+    }
+  }
+
+  /**
+   * Starts the optional third-party AdventNet SNMP Adaptor.
+   * <p>
+   * If {@link AgentConfig#isSnmpEnabled} returns false, then this adaptor will
+   * not be started.
+   */
+  private void startSnmpAdaptor() {
+    if (!this.agentConfig.isSnmpEnabled()) return;
+    try {
+      ObjectName objName = getSnmpAdaptorName();
+
+      // make sure this adaptor is not already registered...
+      if (getMBeanServer().isRegistered(objName)) {
+        // dunno how we got here...
+        logger.info(LocalizedMessage.create(LocalizedStrings.AgentImpl_SNMPADAPTOR_ALREADY_REGISTERED_AS__0, objName));
+        return;
+      }
+
+      String className = "com.adventnet.adaptors.snmp.snmpsupport.SmartSnmpAdaptor";
+      String snmpDir = this.agentConfig.getSnmpDirectory();
+      // ex:/merry2/users/klund/agent
+
+      // validate the directory...
+      if (snmpDir == null || snmpDir.length() == 0) {
+        throw new IllegalArgumentException(LocalizedStrings.AgentImpl_SNMPDIRECTORY_MUST_BE_SPECIFIED_BECAUSE_SNMP_IS_ENABLED.toLocalizedString());
+      }
+      File root = new File(snmpDir);
+      if (!root.exists()) {
+        throw new IllegalArgumentException(LocalizedStrings.AgentImpl_SNMPDIRECTORY_DOES_NOT_EXIST.toLocalizedString());
+      }
+
+      // create the adaptor...
+      String[] sigs = new String[] { "java.lang.String" };
+      Object[] args = new Object[] { snmpDir };
+
+      String bindAddress = this.agentConfig.getSnmpBindAddress();
+      if (bindAddress != null && bindAddress.length() > 0) {
+        sigs = new String[] { "java.lang.String", sigs[0] };
+        args = new Object[] { bindAddress, args[0] };
+      }
+
+      // go...
+      getMBeanServer().createMBean(className, objName, args, sigs);
+    } 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.AgentImpl_FAILED_TO_START_SNMPADAPTOR__0, t.getMessage()));
+      throw new StartupException(LocalizedStrings.AgentImpl_FAILED_TO_START_SNMPADAPTOR__0.toLocalizedString(t.getMessage()), t);
+    }
+  }
+
+  /**
+   * Defines and starts the JMX Http Adaptor service from MX4J.
+   * <p>
+   * If {@link AgentConfig#isHttpEnabled} returns false, then this adaptor will
+   * not be started.
+   */
+  private void startHttpAdaptor() {
+    if (!this.agentConfig.isHttpEnabled()) return;
+    try {
+      ObjectName objName = getHttpAdaptorName();
+
+      // make sure this adaptor is not already registered...
+      if (getMBeanServer().isRegistered(objName)) {
+        // dunno how we got here...
+        logger.info(LocalizedMessage.create(LocalizedStrings.AgentImpl_HTTPADAPTOR_ALREADY_REGISTERED_AS__0, objName));
+        return;
+      }
+
+      this.httpAdaptor = new HttpAdaptor();
+
+      // validate and set host and port values...
+      if (this.agentConfig.getHttpPort() > 0) {
+        this.httpAdaptor.setPort(this.agentConfig.getHttpPort());
+        logger.info(LogMarker.CONFIG, LocalizedMessage.create(LocalizedStrings.AgentImpl_HTTP_ADAPTOR_LISTENING_ON_PORT__0, this.agentConfig.getHttpPort()));
+      }
+      else {
+        logger.error(LocalizedMessage.create(LocalizedStrings.AgentImpl_INCORRECT_PORT_VALUE__0, this.agentConfig.getHttpPort()));
+      }
+
+      if (this.agentConfig.getHttpBindAddress() != null) {
+        String host = this.agentConfig.getHttpBindAddress();
+        logger.info(LogMarker.CONFIG, LocalizedMessage.create(LocalizedStrings.AgentImpl_HTTP_ADAPTOR_LISTENING_ON_ADDRESS__0, host));
+        this.httpAdaptor.setHost(host);
+      }
+      else {
+        logger.error(LocalizedMessage.create(LocalizedStrings.AgentImpl_INCORRECT_NULL_HOSTNAME));
+      }
+
+      // SSL support...
+      MX4JServerSocketFactory socketFactory =
+        new MX4JServerSocketFactory(
+            this.agentConfig.isAgentSSLEnabled(),
+            this.agentConfig.isHttpSSLRequireAuth(),
+            this.agentConfig.getAgentSSLProtocols(),
+            this.agentConfig.getAgentSSLCiphers(),
+            this.agentConfig.getGfSecurityProperties());
+      this.httpAdaptor.setSocketFactory(socketFactory);
+
+      // authentication (user login) support...
+      if (this.agentConfig.isHttpAuthEnabled()) {
+        // this pops up a login dialog from the browser...
+        this.httpAdaptor.setAuthenticationMethod(
+            MX4J_HTTPADAPTOR_BASIC_AUTHENTICATION); // only basic works
+
+        this.httpAdaptor.addAuthorization(
+            this.agentConfig.getHttpAuthUser(),
+            this.agentConfig.getHttpAuthPassword());
+      }
+
+      // add the XsltProcessor...
+      this.httpAdaptor.setProcessorName(createXsltProcessor());
+
+      // register the HttpAdaptor and snap on the XsltProcessor...
+      getMBeanServer().registerMBean(this.httpAdaptor, objName);
+      this.httpAdaptor.start();
+    } 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.AgentImpl_FAILED_TO_START_HTTPADAPTOR__0, t.getMessage()));
+      throw new StartupException(LocalizedStrings.AgentImpl_FAILED_TO_START_HTTPADAPTOR__0.toLocalizedString(t.getMessage()), t);
+    }
+  }
+
+  /**
+   * Defines and starts the Xslt Processor helper service for the Http Adaptor.
+   */
+  private ObjectName createXsltProcessor()
+  throws javax.management.JMException {
+    ObjectName objName = getXsltProcessorName();
+
+    // make sure this mbean is not already registered...
+    if (getMBeanServer().isRegistered(objName)) {
+      // dunno how we got here...
+      logger.info(LocalizedMessage.create(LocalizedStrings.AgentImpl_XSLTPROCESSOR_ALREADY_REGISTERED_AS__0, objName));
+      return objName;
+    }
+
+    getMBeanServer().registerMBean(
+      new mx4j.tools.adaptor.http.XSLTProcessor(), objName);
+    return objName;
+  }
+
+  // -------------------------------------------------------------------------
+  //   Private support methods...
+  // -------------------------------------------------------------------------
+
+//  /** Not used anymore but seems moderately useful... */
+//  private String[] parseSSLCiphers(String ciphers) {
+//    List list = new ArrayList();
+//    StringTokenizer st = new StringTokenizer(ciphers);
+//    while (st.hasMoreTokens()) {
+//      list.add(st.nextToken());
+//    }
+//    return (String[]) list.toArray(new String[list.size()]);
+//  }
+
+  // -------------------------------------------------------------------------
+  //   SSL configuration for GemFire
+  // -------------------------------------------------------------------------
+  public boolean isSSLEnabled() {
+    return this.agentConfig.isSSLEnabled();
+  }
+  public void setSSLEnabled(boolean enabled) {
+    this.agentConfig.setSSLEnabled(enabled);
+  }
+  public String getSSLProtocols() {
+    return this.agentConfig.getSSLProtocols();
+  }
+  public void setSSLProtocols(String protocols) {
+    this.agentConfig.setSSLProtocols(protocols);
+  }
+  public String getSSLCiphers() {
+    return this.agentConfig.getSSLCiphers();
+  }
+  public void setSSLCiphers(String ciphers) {
+    this.agentConfig.setSSLCiphers(ciphers);
+  }
+  public boolean isSSLAuthenticationRequired() {
+    return this.agentConfig.isSSLAuthenticationRequired();
+  }
+  public void setSSLAuthenticationRequired(boolean authRequired) {
+    this.agentConfig.setSSLAuthenticationRequired(authRequired);
+  }
+  public Properties getSSLProperties() {
+    return this.agentConfig.getSSLProperties();
+  }
+  public void setSSLProperties(Properties sslProperties) {
+    this.agentConfig.setSSLProperties(sslProperties);
+  }
+  public void addSSLProperty(String key, String value) {
+    this.agentConfig.addSSLProperty(key, value);
+  }
+  public void removeSSLProperty(String key) {
+    this.agentConfig.removeSSLProperty(key);
+  }
+
+  // -------------------------------------------------------------------------
+  //   ManagedResource implementation
+  // -------------------------------------------------------------------------
+
+	public String getMBeanName() {
+		return this.mbeanName;
+	}
+
+	public ModelMBean getModelMBean() {
+		return this.modelMBean;
+	}
+	public void setModelMBean(ModelMBean modelMBean) {
+		this.modelMBean = modelMBean;
+	}
+
+  public ObjectName getObjectName() {
+    return this.objectName;
+  }
+
+  public ManagedResourceType getManagedResourceType() {
+    return ManagedResourceType.AGENT;
+  }
+
+  public void cleanupResource() {}
+
+  static class StartupException extends GemFireException {
+    private static final long serialVersionUID = 6614145962199330348L;
+    StartupException(Throwable cause) {
+      super(cause);
+    }
+    StartupException(String reason, Throwable cause) {
+      super(reason, cause);
+    }
+  }
+
+  // -------------------------------------------------------------------------
+  //   Other Support methods
+  // -------------------------------------------------------------------------
+  /**
+   * Checks the no. of active RMI clients and updates a flag in the Admin
+   * Distributed System.
+   *
+   * @see AdminDistributedSystemJmxImpl#setRmiClientCountZero(boolean)
+   * @since 6.0
+   */
+  void updateRmiClientsCount() {
+    int noOfClientsConnected = 0;
+
+    String[] connectionIds = this.rmiConnector.getConnectionIds();
+
+    if (connectionIds != null) {
+      noOfClientsConnected = connectionIds.length;
+    }
+
+    logger.info("No. of RMI clients connected :: {}", noOfClientsConnected);
+
+    AdminDistributedSystemJmxImpl adminDSJmx =
+                                (AdminDistributedSystemJmxImpl) this.system;
+
+    adminDSJmx.setRmiClientCountZero(noOfClientsConnected == 0);
+  }
+
+  @Override
+  public String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.append("AgentImpl[");
+    sb.append("config=" + agentConfig.toProperties().toString());
+//    sb.append("; adaptor=" + httpAdaptor.toString());
+    sb.append("; mbeanName=" + mbeanName);
+    sb.append("; modelMBean=" + modelMBean);
+    sb.append("; objectName=" + objectName);
+    sb.append("; propertyFile=" + propertyFile);
+    sb.append(": rmiConnector=" + rmiConnector);
+//    sb.append("; system=" + system);)
+    sb.append("]");
+    return sb.toString();
+  }
+
+  /** Process the String form of a hostname to make it comply with Jmx URL
+   * restrictions. Namely wrap IPv6 literal address with "[", "]"
+   * @param hostname the name to safeguard.
+   * @return a string representation suitable for use in a Jmx connection URL
+   */
+  private static String applyRFC2732(String hostname) {
+    if(hostname.indexOf(":") != -1) {
+      //Assuming an IPv6 literal because of the ':'
+      return "[" + hostname + "]";
+    }
+    return hostname;
+  }
+}
+
+/**
+ * Adapter class for NotificationListener that listens to notifications of type
+ * javax.management.remote.JMXConnectionNotification
+ *
+ * @author abhishek
+ * @since 6.0
+ */
+class ConnectionNotificationAdapter implements NotificationListener {
+  private static final Logger logger = LogService.getLogger();
+
+  /**
+   * If the handback object passed is an AgentImpl, updates the JMX client count
+   *
+   * @param notification
+   *          JMXConnectionNotification for change in client connection status
+   * @param handback
+   *          An opaque object which helps the listener to associate information
+   *          regarding the MBean emitter. This object is passed to the MBean
+   *          during the addListener call and resent, without modification, to
+   *          the listener. The MBean object should not use or modify the
+   *          object. (NOTE: copied from javax.management.NotificationListener)
+   */
+  @SuppressFBWarnings(value="BC_UNCONFIRMED_CAST", justification="Only JMXConnectionNotification instances are used.") 
+  public void handleNotification(Notification notification, Object handback) {
+    if (handback instanceof AgentImpl) {
+      AgentImpl agent = (AgentImpl) handback;
+
+      JMXConnectionNotification jmxNotifn =
+        (JMXConnectionNotification) notification;
+
+      if (logger.isDebugEnabled()) {
+        logger.debug("Connection notification for connection id : '{}'", jmxNotifn.getConnectionId());
+      }
+
+      agent.updateRmiClientsCount();
+    }
+  }
+}
+
+/**
+ * Filters out the notifications of the type JMXConnectionNotification.OPENED,
+ * JMXConnectionNotification.CLOSED and JMXConnectionNotification.FAILED.
+ *
+ * @author abhishek
+ * @since 6.0
+ */
+class ConnectionNotificationFilterImpl implements NotificationFilter {
+
+  /**
+   * Default serialVersionUID
+   */
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * Invoked before sending the specified notification to the listener.
+   * Returns whether the given notification is to be sent to the listener.
+   *
+   * @param notification
+   *          The notification to be sent.
+   * @return true if the notification has to be sent to the listener, false
+   *         otherwise.
+   */
+  public boolean isNotificationEnabled(Notification notification) {
+    boolean isThisNotificationEnabled = false;
+    if (notification.getType().equals(JMXConnectionNotification.OPENED) ||
+        notification.getType().equals(JMXConnectionNotification.CLOSED) ||
+        notification.getType().equals(JMXConnectionNotification.FAILED) ) {
+      isThisNotificationEnabled = true;
+    }
+    return isThisNotificationEnabled;
+  }
+}
+


[46/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/StatisticsType.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/StatisticsType.java b/gemfire-core/src/main/java/com/gemstone/gemfire/StatisticsType.java
new file mode 100644
index 0000000..60117fe
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/StatisticsType.java
@@ -0,0 +1,63 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+//import com.gemstone.gemfire.internal.Assert;
+//import java.io.*;
+//import java.util.*;
+
+/**
+ * Used to describe a logical collection of statistics. These descriptions
+ * are used to create an instance of {@link Statistics}.
+ *
+ * <P>
+ * To get an instance of this interface use an instance of
+ * {@link StatisticsFactory}.
+ *
+ * @author Darrel Schneider
+ *
+ * @since 3.0
+ */
+public interface StatisticsType {
+
+  /**
+   * Returns the name of this statistics type
+   */
+  public String getName();
+
+  /**
+   * Returns a description of this statistics type
+   */
+  public String getDescription();
+
+  /**
+   * Returns descriptions of the statistics that this statistics type
+   * gathers together
+   */
+  public StatisticDescriptor[] getStatistics();
+
+  /**
+   * Returns the id of the statistic with the given name in this
+   * statistics instance.
+   *
+   * @throws IllegalArgumentException
+   *         No statistic named <code>name</code> exists in this
+   *         statistics instance.
+   */
+  public int nameToId(String name);
+  /**
+   * Returns the descriptor of the statistic with the given name in this
+   * statistics instance.
+   *
+   * @throws IllegalArgumentException
+   *         No statistic named <code>name</code> exists in this
+   *         statistics instance.
+   */
+  public StatisticDescriptor nameToDescriptor(String name);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/StatisticsTypeFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/StatisticsTypeFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/StatisticsTypeFactory.java
new file mode 100644
index 0000000..06025b7
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/StatisticsTypeFactory.java
@@ -0,0 +1,188 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+//import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.internal.StatArchiveFormat;
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * Instances of this interface provide methods that create instances
+ * of {@link StatisticDescriptor} and {@link StatisticsType}.
+ * Every {@link StatisticsFactory} is also a type factory.
+ *
+ * <P>
+ *
+ * A <code>StatisticsTypeFactory</code> can create a {@link
+ * StatisticDescriptor statistic} of three numeric types:
+ * <code>int</code>, <code>long</code>, and <code>double</code>.  A
+ * statistic (<code>StatisticDescriptor</code>) can either be a
+ * <I>gauge</I> meaning that its value can increase and decrease or a
+ * <I>counter</I> meaning that its value is strictly increasing.
+ * Marking a statistic as a counter allows statistic display tools
+ * to properly display a statistics whose value "wraps around" (that
+ * is, exceeds its maximum value).
+ * 
+ * <P>The following code is an example of how to create a type using XML.
+ * In this example the type has two stats whose values always increase:
+ * <pre>
+    StatisticsTypeFactory f = ...;
+    StatisticsType t = f.createType(
+        "StatSampler",
+        "Stats on the statistic sampler.",
+        new StatisticDescriptor[] {
+            f.createIntCounter("sampleCount",
+                               "Total number of samples taken by this sampler.",
+                               "samples"),
+            f.createLongCounter("sampleTime",
+                                "Total amount of time spent taking samples.",
+                                "milliseconds"),
+        }
+    );
+ * </pre>
+ * <P>The following is an example of how to create the same type using XML.
+ * The XML data:
+ * <pre>
+    &lt;?xml version="1.0" encoding="UTF-8"?&gt;
+    &lt;!DOCTYPE statistics PUBLIC
+      "-//GemStone Systems, Inc.//GemFire Statistics Type//EN"
+      "http://www.gemstone.com/dtd/statisticsType.dtd"&gt;
+    &lt;statistics&gt;
+      &lt;type name="StatSampler"&gt;
+        &lt;description&gt;Stats on the statistic sampler.&lt;/description&gt;
+        &lt;stat name="sampleCount" storage="int" counter="true"&gt;
+          &lt;description&gt;Total number of samples taken by this sampler.&lt;/description&gt;
+          &lt;unit&gt;samples&lt;/unit&gt;
+        &lt;/stat&gt;
+        &lt;stat name="sampleTime" storage="long" counter="true"&gt;
+          &lt;description&gt;Total amount of time spent taking samples.&lt;/description&gt;
+          &lt;unit&gt;milliseconds&lt;/unit&gt;
+        &lt;/stat&gt;
+      &lt;/type&gt;
+    &lt;/statistics&gt;
+ * </pre>
+ * The code to create the type:
+ * <pre>
+      StatisticsTypeFactory f = ...;
+      Reader r = new InputStreamReader("fileContainingXmlData"));
+      StatisticsType type = f.createTypesFromXml(r)[0];
+ * </pre>
+ * <P>
+ * @see <A href="package-summary.html#statistics">Package introduction</A>
+ *
+ * @author Darrel Schneider
+ *
+ * @since 3.0
+ */
+public interface StatisticsTypeFactory {
+
+  /**
+   * Creates and returns an int counter {@link StatisticDescriptor} with the given <code>name</code>, <code>description</code>, <code>units</code>,
+   * and with larger values indicating better performance.
+   */
+  public StatisticDescriptor createIntCounter(String name, String description,
+                                              String units);
+  /**
+   * Creates and returns a long counter {@link StatisticDescriptor} with the given <code>name</code>, <code>description</code>, <code>units</code>,
+   * and with larger values indicating better performance.
+   */
+  public StatisticDescriptor createLongCounter(String name, String description,
+                                               String units);
+  /**
+   * Creates and returns a double counter {@link StatisticDescriptor} with the given <code>name</code>, <code>description</code>, <code>units</code>,
+   * and with larger values indicating better performance.
+   */
+  public StatisticDescriptor createDoubleCounter(String name, String description,
+                                               String units);
+  /**
+   * Creates and returns an int gauge {@link StatisticDescriptor} with the given <code>name</code>, <code>description</code>, <code>units</code>,
+   * and with smaller values indicating better performance.
+   */
+  public StatisticDescriptor createIntGauge(String name, String description,
+                                              String units);
+  /**
+   * Creates and returns a long gauge {@link StatisticDescriptor} with the given <code>name</code>, <code>description</code>, <code>units</code>,
+   * and with smaller values indicating better performance.
+   */
+  public StatisticDescriptor createLongGauge(String name, String description,
+                                               String units);
+  /**
+   * Creates and returns a double gauge {@link StatisticDescriptor} with the given <code>name</code>, <code>description</code>, <code>units</code>,
+   * and with smaller values indicating better performance.
+   */
+  public StatisticDescriptor createDoubleGauge(String name, String description,
+                                               String units);
+
+  /**
+   * Creates and returns an int counter {@link StatisticDescriptor} with the given <code>name</code>, <code>description</code>, <code>largerBetter</code>, and <code>units</code>.
+   */
+  public StatisticDescriptor createIntCounter(String name, String description,
+                                              String units, boolean largerBetter);
+  /**
+   * Creates and returns a long counter {@link StatisticDescriptor} with the given <code>name</code>, <code>description</code>, <code>largerBetter</code>, and <code>units</code>.
+   */
+  public StatisticDescriptor createLongCounter(String name, String description,
+                                               String units, boolean largerBetter);
+  /**
+   * Creates and returns a double counter {@link StatisticDescriptor} with the given <code>name</code>, <code>description</code>, <code>largerBetter</code>, and <code>units</code>.
+   */
+  public StatisticDescriptor createDoubleCounter(String name, String description,
+                                               String units, boolean largerBetter);
+  /**
+   * Creates and returns an int gauge {@link StatisticDescriptor} with the given <code>name</code>, <code>description</code>, <code>largerBetter</code>, and <code>units</code>.
+   */
+  public StatisticDescriptor createIntGauge(String name, String description,
+                                              String units, boolean largerBetter);
+  /**
+   * Creates and returns a long gauge {@link StatisticDescriptor} with the given <code>name</code>, <code>description</code>, <code>largerBetter</code>, and <code>units</code>.
+   */
+  public StatisticDescriptor createLongGauge(String name, String description,
+                                               String units, boolean largerBetter);
+  /**
+   * Creates and returns a double gauge {@link StatisticDescriptor} with the given <code>name</code>, <code>description</code>, <code>largerBetter</code>, and <code>units</code>.
+   */
+  public StatisticDescriptor createDoubleGauge(String name, String description,
+                                               String units, boolean largerBetter);
+
+
+  /**
+   * The maximum number of descriptors a single statistics type can have.
+   * <P> Current value is: <code>254</code>
+   */
+  public final int MAX_DESCRIPTORS_PER_TYPE = StatArchiveFormat.ILLEGAL_STAT_OFFSET-1;
+
+  /**
+   * Creates or finds and returns a {@link StatisticsType} with the given <code>name</code>, <code>description</code>, and {@link StatisticDescriptor statistic descriptions}.
+   * @throws IllegalArgumentException if a type with the given <code>name</code> already exists and it differs from the given parameters.
+   */
+  public StatisticsType createType(String name, String description,
+                                   StatisticDescriptor[] stats);
+  /**
+   * Finds and returns an already created {@link StatisticsType} with the given <code>name</code>. Returns <code>null</code> if the type does not exist.
+   */
+  public StatisticsType findType(String name);
+
+  /**
+   * Creates one or more {@link StatisticsType} from the contents of the
+   * given <code>reader</code>. The created types can be found by calling
+   * {@link #findType}.
+   *
+   * @param reader
+   *        The source of the XML data which must comply with the
+   *        <code>statisticsType.dtd</code>.
+   *
+   * @throws IllegalArgumentException if a type defined in the reader
+   *  already exists
+   * @throws IOException
+   *         Something went wrong while reading from
+   *         <code>reader</code> 
+   */
+  public StatisticsType[] createTypesFromXml(Reader reader)
+    throws IOException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/SystemConnectException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/SystemConnectException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/SystemConnectException.java
new file mode 100644
index 0000000..2352c1a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/SystemConnectException.java
@@ -0,0 +1,33 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire;
+
+/**
+ * An <code>SystemConnectException</code> is thrown when a
+ * GemFire application tries to connect to an
+ * existing distributed system and is unable to contact all members of
+ * the distributed system to announce its presence.  This is usually due
+ * to resource depletion problems (low memory or too few file descriptors)
+ * in other processes.
+ */
+public class SystemConnectException extends GemFireException {
+private static final long serialVersionUID = -7378174428634468238L;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>SystemConnectException</code>.
+   */
+  public SystemConnectException(String message) {
+    super(message);
+  }
+  
+  public SystemConnectException(String message, Throwable cause) {
+    super(message, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/SystemFailure.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/SystemFailure.java b/gemfire-core/src/main/java/com/gemstone/gemfire/SystemFailure.java
new file mode 100644
index 0000000..21c6ad9
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/SystemFailure.java
@@ -0,0 +1,1215 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+/**
+ * 
+ */
+package com.gemstone.gemfire;
+
+import com.gemstone.gemfire.internal.SystemFailureTestHook;
+import com.gemstone.gemfire.internal.admin.remote.RemoteGfManagerAgent;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
+/**
+ * Catches and responds to JVM failure
+ * <p>
+ * This class represents a catastrophic failure of the system,
+ * especially the Java virtual machine.  Any class may,
+ * at any time, indicate that a system failure has occurred by calling
+ * {@link #initiateFailure(Error)} (or, less commonly,
+ * {@link #setFailure(Error)}).
+ * <p>
+ * In practice, the most common type of failure that is likely to be
+ * reported by an otherwise healthy JVM is {@link OutOfMemoryError}.  However,
+ * GemFire will report any occurrence of {@link VirtualMachineError} as
+ * a JVM failure.
+ * <p>
+ * When a failure is reported, you must assume that the JVM has <em>broken 
+ * its fundamental execution contract</em> with your application. 
+ * No programming invariant can be assumed to be true, and your 
+ * entire application must be regarded as corrupted.
+ * <h1>Failure Hooks</h1>
+ * GemFire uses this class to disable its distributed system (group
+ * communication) and any open caches.  It also provides a hook for you
+ * to respond to after GemFire disables itself.
+ * <h1>Failure WatchDog</h1>
+ * When {@link #startThreads()} is called, a "watchdog" {@link Thread} is started that 
+ * periodically checks to see if system corruption has been reported.  When 
+ * system corruption is detected, this thread proceeds to:
+ * <p>
+ * <ol>
+ * <li>
+ * <em>Close GemFire</em> -- Group communication is ceased (this cache
+ * member recuses itself from the distributed system) and the cache
+ * is further poisoned (it is pointless to try to cleanly close it at this
+ * point.).
+ * <p>
+ * After this has successfully ended, we launch a
+ * </li>
+ * <li>
+ * <em>failure action</em>, a user-defined Runnable
+ * {@link #setFailureAction(Runnable)}.
+ * By default, this Runnable performs nothing.  If you feel you need to perform
+ * an action before exiting the JVM, this hook gives you a
+ * means of attempting some action.  Whatever you attempt should be extremely
+ * simple, since your Java execution environment has been corrupted.
+ * <p>
+ * GemStone recommends that you employ 
+ * <a href="http://wrapper.tanukisoftware.org/doc/english/introduction.html">
+ * Java Service Wrapper</a> to detect when your JVM exits and to perform
+ * appropriate failure and restart actions.
+ * </li>
+ * <li>
+ * Finally, if the application has granted the watchdog permission to exit the JVM
+ * (via {@link #setExitOK(boolean)}), the watchdog calls {@link System#exit(int)} with
+ * an argument of 1.  If you have not granted this class permission to
+ * close the JVM, you are <em>strongly</em>  advised to call it in your
+ * failure action (in the previous step).
+ * </li>
+ * </ol>
+ * <p> 
+ * Each of these actions will be run exactly once in the above described
+ * order.  However, if either step throws any type of error ({@link Throwable}), 
+ * the watchdog will assume that the JVM is still under duress (esp. an 
+ * {@link OutOfMemoryError}), will wait a bit, and then retry the failed action.
+ * <p>
+ * It bears repeating that you should be very cautious of any Runnables you
+ * ask this class to run.  By definition the JVM is <em>very sick</em>
+ * when failure has been signalled.  
+ * <p>
+ * <h1>Failure Proctor</h1>
+ * In addition to the failure watchdog, {@link #startThreads()} creates a second
+ * thread (the "proctor") that monitors free memory. It does this by examining
+ * {@link Runtime#freeMemory() free memory},  
+ * {@link Runtime#totalMemory() total memory} and 
+ * {@link Runtime#maxMemory() maximum memory}.  If the amount of available 
+ * memory stays below a given 
+ * {@link #setFailureMemoryThreshold(long) threshold}, for
+ * more than {@link #WATCHDOG_WAIT} seconds, the watchdog is notified.
+ * <p>
+ * Note that the proctor can be effectively disabled by
+ * {@link SystemFailure#setFailureMemoryThreshold(long) setting} the failure memory threshold
+ * to a negative value.
+ * <p>
+ * The proctor is a second line of defense, attempting to detect 
+ * OutOfMemoryError conditions in circumstances where nothing alerted the
+ * watchdog.  For instance, a third-party jar might incorrectly handle this
+ * error and leave your virtual machine in a "stuck" state.
+ * <p>
+ * Note that the proctor does not relieve you of the obligation to
+ * follow the best practices in the next section.
+ * <h1>Best Practices</h1>
+ * <h2>Catch and Handle VirtualMachineError</h2>
+ * If you feel obliged to catch <em>either</em> {@link Error}, or 
+ * {@link Throwable}, you <em>must</em>also check for 
+ * {@link VirtualMachineError} like so:
+ * <p>
+ * <pre>
+        catch (VirtualMachineError err) {
+          SystemFailure.{@link #initiateFailure(Error) initiateFailure}(err);
+          // If this ever returns, rethrow the error.  We're poisoned
+          // now, so don't let this thread continue.
+          throw err;
+        }
+ * </pre>
+ * <h2>Periodically Check For Errors</h2>
+ * Check for serious system errors at
+ * appropriate points in your algorithms.  You may elect to use
+ * the {@link #checkFailure()} utility function, but you are
+ * not required to (you could just see if {@link SystemFailure#getFailure()}
+ * returns a non-null result).  
+ * <p>
+ * A job processing loop is a good candidate, for
+ * instance, in com.gemstone.org.jgroups.protocols.UDP#run(), 
+ * which implements {@link Thread#run}:
+ * <p>
+ * <pre>
+         for (;;)  {
+           SystemFailure.{@link #checkFailure() checkFailure}();
+           if (mcast_recv_sock == null || mcast_recv_sock.isClosed()) break;
+           if (Thread.currentThread().isInterrupted()) break;
+          ...
+ * </pre>
+ * <h2>Create Logging ThreadGroups</h2>
+ * If you create any Thread, a best practice is to catch severe errors
+ * and signal failure appropriately.  One trick to do this is to create a 
+ * ThreadGroup that handles uncaught exceptions by overriding 
+ * {@link ThreadGroup#uncaughtException(Thread, Throwable)} and to declare 
+ * your thread as a member of that {@link ThreadGroup}.  This also has a 
+ * significant side-benefit in that most uncaught exceptions 
+ * can be detected:
+ * <p>
+ * <pre>
+    ThreadGroup tg = new ThreadGroup("Worker Threads") {
+        public void uncaughtException(Thread t, Throwable e) {
+          // Do this *before* any object allocation in case of
+          // OutOfMemoryError (for instance)
+          if (e instanceof VirtualMachineError) {
+            SystemFailure.{@link #setFailure(Error) setFailure}((VirtualMachineError)e); // don't throw
+          }
+          String s = "Uncaught exception in thread " + t;
+          system.getLogWriter().severe(s, e);
+        }
+        Thread t = new Thread(myRunnable, tg, "My Thread");
+        t.start();
+      }; * </pre>
+ * <p>
+  * <h2>Catches of Error and Throwable Should Check for Failure</h2>
+  * Keep in mind that peculiar or flat-out<em>impossible</em>  exceptions may 
+  * ensue after a VirtualMachineError has been thrown <em>anywhere</em> in
+  * your virtual machine. Whenever you catch {@link Error} or {@link Throwable}, 
+  * you should also make sure that you aren't dealing with a corrupted JVM:
+  * <p>
+  * <pre>
+        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.{@link #checkFailure() checkFailure}();
+          ...
+        }
+ * </pre>
+ * @author jpenney
+ * @since 5.1
+ */
+@SuppressFBWarnings(value="DM_GC", justification="This class performs System.gc as last ditch effort during out-of-memory condition.") 
+public final class SystemFailure {
+
+  /**
+   * Preallocated error messages\
+   * LocalizedStrings may use memory (in the form of an iterator)
+   * so we must get the translated messages in advance.
+   **/
+   static final String JVM_CORRUPTION = LocalizedStrings.SystemFailure_JVM_CORRUPTION_HAS_BEEN_DETECTED.toLocalizedString();
+   static final String CALLING_SYSTEM_EXIT = LocalizedStrings.SystemFailure_SINCE_THIS_IS_A_DEDICATED_CACHE_SERVER_AND_THE_JVM_HAS_BEEN_CORRUPTED_THIS_PROCESS_WILL_NOW_TERMINATE_PERMISSION_TO_CALL_SYSTEM_EXIT_INT_WAS_GIVEN_IN_THE_FOLLOWING_CONTEXT.toLocalizedString();
+   public static final String DISTRIBUTION_HALTED_MESSAGE = LocalizedStrings.SystemFailure_DISTRIBUTION_HALTED_DUE_TO_JVM_CORRUPTION.toLocalizedString();
+   public static final String DISTRIBUTED_SYSTEM_DISCONNECTED_MESSAGE = LocalizedStrings.SystemFailure_DISTRIBUTED_SYSTEM_DISCONNECTED_DUE_TO_JVM_CORRUPTION.toLocalizedString();
+
+  /**
+   * the underlying failure
+   * 
+   * This is usually an instance of {@link VirtualMachineError}, but it
+   * is not required to be such.
+   * 
+   * @see #getFailure()
+   * @see #initiateFailure(Error)
+   */
+  protected static volatile Error failure = null;
+  
+  /**
+   * user-defined runnable to run last
+   * 
+   * @see #setFailureAction(Runnable)
+   */
+  private static volatile Runnable failureAction = new Runnable() {
+    public void run() {
+      System.err.println(JVM_CORRUPTION);
+      failure.printStackTrace();
+    }
+  };
+  
+  /**
+   * @see #setExitOK(boolean)
+   */
+  private static volatile boolean exitOK = false;
+  
+  /**
+   * If we're going to exit the JVM, I want to be accountable for who
+   * told us it was OK.
+   */
+  private static volatile Throwable exitExcuse;
+  
+  /**
+   * Indicate whether it is acceptable to call {@link System#exit(int)} after
+   * failure processing has completed.
+   * <p>
+   * This may be dynamically modified while the system is running.
+   * 
+   * @param newVal true if it is OK to exit the process
+   * @return the previous value
+   */
+  public static boolean setExitOK(boolean newVal) {
+    boolean result = exitOK;
+    exitOK = newVal;
+    if (exitOK) {
+      exitExcuse = new Throwable("SystemFailure exitOK set");
+    }
+    else {
+      exitExcuse = null;
+    }
+    return result;
+  }
+  
+  //merge42180: Added this method while merging 42180. It should have already be here through different merges or will come later
+  /**
+   * Returns true if the given Error is a fatal to the JVM and it should be shut
+   * down. Code should call {@link #initiateFailure(Error)} or
+   * {@link #setFailure(Error)} if this returns true.
+   */
+  public static boolean isJVMFailureError(Error err) {
+    // all VirtualMachineErrors are not fatal to the JVM, in particular
+    // StackOverflowError is not
+    return err instanceof OutOfMemoryError || err instanceof UnknownError;
+  }
+  /**
+   * Disallow instance creation
+   */
+  private SystemFailure() {
+    
+  }
+  
+  /**
+   * Synchronizes access to state variables, used to notify the watchdog
+   * when to run
+   * 
+   * @see #notifyWatchDog()
+   * @see #startProctor()
+   * @see #startWatchDog()
+   */
+  private static final Object failureSync = new Object();
+  
+  /**
+   * True if we have closed GemFire
+   * 
+   * @see #emergencyClose()
+   */
+  private static volatile boolean gemfireCloseCompleted = false;
+
+  /**
+   * True if we have completed the user-defined failure action
+   * 
+   * @see #setFailureAction(Runnable)
+   */
+  private static volatile  boolean failureActionCompleted = false;
+
+  /**
+   * This is a logging ThreadGroup, created only once.
+   */
+  private final static ThreadGroup tg;
+  static {
+    tg = new ThreadGroup("SystemFailure Watchdog Threads") {
+      // If the watchdog is correctly written, this will never get executed.
+      // However, there's no reason for us not to eat our own dog food
+      // (har, har) -- see the javadoc above.
+      @Override
+      public void uncaughtException(Thread t, Throwable e) {
+        // Uhhh...if the watchdog is running, we *know* there's some
+        // sort of serious error, no need to check for it here.
+        System.err.println("Internal error in SystemFailure watchdog:" + e);
+        e.printStackTrace();
+      }
+      };  
+    }
+  
+  /**
+   * This is the amount of time, in seconds, the watchdog periodically awakens
+   * to see if the system has been corrupted.
+   * <p>
+   * The watchdog will be explicitly awakened by calls to
+   * {@link #setFailure(Error)} or {@link #initiateFailure(Error)}, but
+   * it will awaken of its own accord periodically to check for failure even
+   * if the above calls do not occur.
+   * <p>
+   * This can be set with the system property 
+   * <code>gemfire.WATCHDOG_WAIT</code>. The default is 15 sec.
+   */
+  static public final int WATCHDOG_WAIT = Integer
+      .getInteger("gemfire.WATCHDOG_WAIT", 15).intValue();
+  
+  /**
+   * This is the watchdog thread
+   * 
+   * @guarded.By {@link #failureSync}
+   */
+  private static Thread watchDog;
+  
+  private static boolean isCacheClosing = false;
+
+  /**
+   * Should be invoked when GemFire cache is being created. 
+   */
+  public static void signalCacheCreate() {
+    isCacheClosing = false;
+  }
+
+  /**
+   * Should be invoked when GemFire cache is closing or closed. 
+   */
+  public static void signalCacheClose() {
+    isCacheClosing = true;
+    if (proctor != null) {
+      proctor.interrupt();
+    }
+    if (watchDog != null) {
+      watchDog.interrupt();
+    }
+  }
+
+  /**
+   * Start the watchdog thread, if it isn't already running.
+   */
+  private static void startWatchDog() {
+    if (failureActionCompleted) {
+      // Our work is done, don't restart
+      return;
+    }
+    synchronized (failureSync) {
+      if (watchDog != null && watchDog.isAlive()) {
+        return;
+      }
+      watchDog = new Thread(tg, new Runnable() {
+        public void run() {
+          runWatchDog();
+        }
+      }, "SystemFailure WatchDog");
+      watchDog.setDaemon(true);
+      watchDog.start();
+    }
+  }
+  
+  private static void stopWatchDog() {
+    synchronized (failureSync) {
+      stopping = true;
+      if (watchDog != null && watchDog.isAlive()) {
+        failureSync.notifyAll();
+        try {
+          watchDog.join(100);
+        } catch (InterruptedException ignore) {
+        }
+        if (watchDog.isAlive()) {
+          watchDog.interrupt();
+          try {
+            watchDog.join(1000);
+          } catch (InterruptedException ignore) {
+          }
+        }
+      }
+      watchDog = null;
+    }
+  }
+  
+  /**
+   * This is the run loop for the watchdog thread.
+   */
+  static protected void runWatchDog() {
+    
+    boolean warned = false;
+    
+    logFine(WATCHDOG_NAME, "Starting");
+    try {
+      basicLoadEmergencyClasses();
+    }
+    catch (ExceptionInInitializerError e) {
+      // Uhhh...are we shutting down?
+      boolean noSurprise = false;
+      Throwable cause = e.getCause();
+      if (cause != null) {
+        if (cause instanceof IllegalStateException) {
+          String msg = cause.getMessage();
+          if (msg.indexOf("Shutdown in progress") >= 0) {
+            noSurprise = true;
+          }
+        }
+      }
+      if (!noSurprise) {
+        logWarning(WATCHDOG_NAME, "Unable to load GemFire classes: ", e);
+      }
+      // In any event, we're toast
+      return;
+    }
+    catch (CancelException e) {
+      // ignore this because we are shutting down anyway
+    }
+    catch (Throwable t) {
+      logWarning(WATCHDOG_NAME, "Unable to initialize watchdog", t);
+      return;
+    }
+    for (;;) {
+      if (stopping) {
+        return;
+      }
+      try {
+        if (isCacheClosing) {
+          break;
+        }
+        // Sleep or get notified...
+        synchronized (failureSync) {
+          if (stopping) {
+            return;
+          }
+         logFine(WATCHDOG_NAME, "Waiting for disaster");
+          try {
+            failureSync.wait(WATCHDOG_WAIT * 1000); 
+          }
+          catch (InterruptedException e) {
+            // Ignore
+          }
+          if (stopping) {
+            return;
+          }
+        }
+        // Poke nose in the air, take a sniff...
+        
+        if (failureActionCompleted) {
+          // early out, for testing
+          logInfo(WATCHDOG_NAME, "all actions completed; exiting");
+        }
+        if (failure == null) {
+          // Tail wag.  Go back to sleep.
+          logFine(WATCHDOG_NAME, "no failure detected");
+          continue;
+        }
+        // BOW WOW WOW WOW WOW!  Corrupted system.
+        if (!warned ) {
+          warned = logWarning(WATCHDOG_NAME, "failure detected", failure);
+        }
+        
+        // If any of the following fail, we will go back to sleep and
+        // retry.
+        if (!gemfireCloseCompleted) {
+          logInfo(WATCHDOG_NAME, "closing GemFire");
+          try {
+            emergencyClose();
+          }
+          catch (Throwable t) {
+            logWarning(WATCHDOG_NAME, "trouble closing GemFire", t);
+            continue; // go back to sleep
+          }
+          gemfireCloseCompleted = true;
+        }
+        
+        if (!failureActionCompleted) {
+          // avoid potential race condition setting the runnable
+          Runnable r = failureAction;
+          if (r != null) {
+            logInfo(WATCHDOG_NAME, "running user's runnable");
+            try {
+              r.run();
+            }
+            catch (Throwable t) {
+              logWarning(WATCHDOG_NAME, "trouble running user's runnable", t);
+              continue; // go back to sleep
+            }
+          }
+          failureActionCompleted = true;
+        }
+        
+        stopping = true;
+        stopProctor();
+        
+        if (exitOK) {
+          logWarning(WATCHDOG_NAME,
+              // No "+" in this long message, we're out of memory!
+              CALLING_SYSTEM_EXIT,
+              exitExcuse);
+          
+          // ATTENTION: there are VERY FEW places in GemFire where it is
+          // acceptable to call System.exit.  This is one of those
+          // places...
+          System.exit(1);
+        }
+
+
+        // Our job here is done
+        logInfo(WATCHDOG_NAME, "exiting");
+        return;
+      }
+      catch (Throwable t) {
+        // We *never* give up. NEVER EVER!
+        logWarning(WATCHDOG_NAME, "thread encountered a problem: " + t, t);
+      }
+    } // for
+  }
+  
+  /**
+   * Spies on system statistics looking for low memory threshold
+   * 
+   * Well, if you're gonna have a watchdog, why not a watch CAT????
+   * 
+   * @guarded.By {@link #failureSync}
+   * @see #minimumMemoryThreshold
+   */
+  private static Thread proctor;
+
+  /**
+   * This mutex controls access to {@link #firstStarveTime} and
+   * {@link #minimumMemoryThreshold}.
+   * <p>
+   * I'm hoping that a fat lock is never created here, so that
+   * an object allocation isn't necessary to acquire this
+   * mutex.  You'd have to have A LOT of contention on this mutex
+   * in order for a fat lock to be created, which indicates IMHO
+   * a serious problem in your applications.
+   */
+  private static final Object memorySync = new Object();
+  
+  /**
+   * This is the minimum amount of memory that the proctor will
+   * tolerate before declaring a system failure.
+   * 
+   * @see #setFailureMemoryThreshold(long)
+   * @guarded.By {@link #memorySync}
+   */
+  static long minimumMemoryThreshold = Long.getLong(
+      "gemfire.SystemFailure.chronic_memory_threshold", 1048576).longValue();
+  
+  /**
+   * This is the interval, in seconds, that the proctor
+   * thread will awaken and poll system free memory.
+   * 
+   * The default is 1 sec.  This can be set using the system property
+   * <code>gemfire.SystemFailure.MEMORY_POLL_INTERVAL</code>.
+   * 
+   * @see #setFailureMemoryThreshold(long)
+   */
+  static final public long MEMORY_POLL_INTERVAL = Long.getLong(
+      "gemfire.SystemFailure.MEMORY_POLL_INTERVAL", 1).longValue();
+  
+  /**
+   * This is the maximum amount of time, in seconds, that the proctor thread
+   * will tolerate seeing free memory stay below
+   * {@link #setFailureMemoryThreshold(long)}, after which point it will 
+   * declare a system failure.
+   * 
+   * The default is 15 sec.  This can be set using the system property
+   * <code>gemfire.SystemFailure.MEMORY_MAX_WAIT</code>.
+   * 
+   * @see #setFailureMemoryThreshold(long)
+   */
+  static final public long MEMORY_MAX_WAIT = Long.getLong(
+      "gemfire.SystemFailure.MEMORY_MAX_WAIT", 15).longValue();
+  
+  /**
+   * Flag that determines whether or not we monitor memory on our own.
+   * If this flag is set, we will check freeMemory, invoke GC if free memory 
+   * gets low, and start throwing our own OutOfMemoryException if 
+   * 
+   * The default is false, so this monitoring is turned off. This monitoring has been found 
+   * to be unreliable in non-Sun VMs when the VM is under stress or behaves in unpredictable ways.
+   *
+   * @since 6.5
+   */
+  static final public boolean MONITOR_MEMORY = Boolean.getBoolean(
+      "gemfire.SystemFailure.MONITOR_MEMORY");
+  
+  /**
+   * Start the proctor thread, if it isn't already running.
+   * 
+   * @see #proctor
+   */
+  private static void startProctor() {
+    if (failure != null) {
+      // no point!
+      notifyWatchDog();
+      return;
+    }
+    synchronized (failureSync) {
+      if (proctor != null && proctor.isAlive()) {
+        return;
+      }
+      proctor = new Thread(tg, new Runnable() {
+        public void run() {
+          runProctor();
+        }
+      }, "SystemFailure Proctor");
+      proctor.setDaemon(true);
+      proctor.start();
+    }
+  }
+  
+  private static void stopProctor() {
+    synchronized (failureSync) {
+      stopping = true;
+      if (proctor != null && proctor.isAlive()) {
+        proctor.interrupt();
+        try {
+          proctor.join(1000);
+        } catch (InterruptedException ignore) {
+        }
+      }
+      proctor = null;
+    }
+  }
+  
+  /**
+   * Symbolic representation of an invalid starve time
+   */
+  static private final long NEVER_STARVED = Long.MAX_VALUE;
+  
+  /**
+   * this is the last time we saw memory starvation
+   * 
+   * @guarded.By {@link #memorySync}}}
+   */
+  static private long firstStarveTime = NEVER_STARVED;
+  
+  /**
+   * This is the previous measure of total memory.  If it changes,
+   * we reset the proctor's starve statistic.
+   */
+  static private long lastTotalMemory = 0;
+  
+  /**
+   * This is the run loop for the proctor thread (formally known
+   * as the "watchcat" (grin)
+   */
+  static protected void runProctor() {
+    // Note that the javadocs say this can return Long.MAX_VALUE.
+    // If it does, the proctor will never do its job...
+    final long maxMemory = Runtime.getRuntime().maxMemory();
+    
+    // Allocate this error in advance, since it's too late once
+    // it's been detected!
+    final OutOfMemoryError oome = new OutOfMemoryError(LocalizedStrings.SystemFailure_0_MEMORY_HAS_REMAINED_CHRONICALLY_BELOW_1_BYTES_OUT_OF_A_MAXIMUM_OF_2_FOR_3_SEC.toLocalizedString(new Object[] {PROCTOR_NAME, Long.valueOf(minimumMemoryThreshold), Long.valueOf(maxMemory), Integer.valueOf(WATCHDOG_WAIT)}));
+    
+    // Catenation, but should be OK when starting up
+    logFine(PROCTOR_NAME, "Starting, threshold = " + minimumMemoryThreshold 
+        + "; max = " + maxMemory);
+    for (;;) {
+      if (isCacheClosing) {
+        break;
+      }
+      if (stopping) {
+        return;
+      }
+
+      try {
+        //*** catnap...
+        try {
+          Thread.sleep(MEMORY_POLL_INTERVAL * 1000);
+        }
+        catch (InterruptedException e) {
+          // ignore
+        }
+        
+        if (stopping) {
+          return;
+        }
+
+        //*** Twitch ear, take a bath...
+        if (failureActionCompleted) {
+          // it's all over, we're late
+          return;
+        }
+        if (failure != null) {
+          notifyWatchDog(); // wake the dog, just in case
+          logFine(PROCTOR_NAME, "Failure has been reported, exiting");
+          return;
+        }
+        
+        if(!MONITOR_MEMORY) {
+          continue;
+        }
+
+        //*** Sit up, stretch...
+        long totalMemory = Runtime.getRuntime().totalMemory();
+        if (totalMemory < maxMemory) {
+          // We haven't finished growing the heap, so no worries...yet
+          if (DEBUG) {
+            // This message has catenation, we don't want this in
+            // production code :-)
+            logFine(PROCTOR_NAME, "totalMemory (" + totalMemory 
+                + ") < maxMemory (" + maxMemory + ")");
+          }
+          firstStarveTime = NEVER_STARVED;
+          continue;
+        }
+        if (lastTotalMemory < totalMemory) {
+          // Don't get too impatient if the heap just now grew
+          lastTotalMemory = totalMemory; // now we're maxed
+          firstStarveTime = NEVER_STARVED; // reset the clock
+          continue;
+        }
+        lastTotalMemory = totalMemory; // make a note of this
+
+        //*** Hey, is that the food bowl?
+        
+        // At this point, freeMemory really indicates how much
+        // trouble we're in.
+        long freeMemory = Runtime.getRuntime().freeMemory();
+        if(freeMemory==0) {
+          /*
+           * This is to workaround X bug #41821 in JRockit.
+           * Often, Jrockit returns 0 from Runtime.getRuntime().freeMemory()
+           * Allocating this one object and calling again seems to workaround the problem.
+           */
+          new Object();
+          freeMemory = Runtime.getRuntime().freeMemory();
+        }
+        // Grab the threshold and starve time once, under mutex, because
+        // it's publicly modifiable.
+        long curThreshold;
+        long lastStarveTime;
+        synchronized (memorySync) {
+          curThreshold = minimumMemoryThreshold;
+          lastStarveTime = firstStarveTime;
+        }
+        
+        if (freeMemory >= curThreshold /* enough memory */
+            || curThreshold == 0 /* disabled */) {
+          // Memory is FINE, reset everything
+          if (DEBUG) {
+            // This message has catenation, we don't want this in
+            // production code :-)
+            logFine(PROCTOR_NAME, "Current free memory is: " + freeMemory);
+          }
+          
+          if (lastStarveTime != NEVER_STARVED) {
+            logFine(PROCTOR_NAME, "...low memory has self-corrected.");
+          }
+          synchronized (memorySync) {
+            firstStarveTime = NEVER_STARVED;
+          }
+          continue;
+        }
+        // Memory is low
+        
+        //*** Leap to feet, nose down, tail switching...
+        long now = System.currentTimeMillis();
+        if (lastStarveTime == NEVER_STARVED) {
+          // first sighting
+          if (DEBUG) {
+            // Catenation in this message, don't put in production
+            logFine(PROCTOR_NAME, "Noting current memory " + freeMemory 
+                + " is less than threshold " + curThreshold);
+          }
+          else {
+            logWarning(
+                PROCTOR_NAME,
+                "Noting that current memory available is less than the currently designated threshold", null);
+          }
+
+          synchronized (memorySync) {
+            firstStarveTime = now;
+          }
+          System.gc(); // at least TRY...
+          continue;
+        }
+        
+        //*** squirm, wait for the right moment...wait...wait...
+        if (now - lastStarveTime < MEMORY_MAX_WAIT * 1000) {
+          // Very recent; problem may correct itself.
+          if (DEBUG) {
+            // catenation
+            logFine(PROCTOR_NAME, "...memory is still below threshold: "
+                + freeMemory);
+          }
+          else {
+            logWarning(
+                PROCTOR_NAME,
+                "Noting that current memory available is still below currently designated threshold", null);
+
+          }
+          continue;
+        }
+        
+        //*** Meow! Meow! MEOWWWW!!!!!
+        
+        // Like any smart cat, let the Dog do all the work.
+        logWarning(PROCTOR_NAME, "Memory is chronically low; setting failure!", null);
+        SystemFailure.setFailure(oome);
+        notifyWatchDog();
+        return; // we're done!
+      }
+      catch (Throwable t) {
+        logWarning(PROCTOR_NAME, "thread encountered a problem", t);
+        // We *never* give up. NEVER EVER!
+      }
+    } // for
+  }
+  
+  /**
+   * Enables some fine logging
+   */
+  static private final boolean DEBUG = false;
+  
+  /**
+   * If true, we track the progress of emergencyClose
+   * on System.err
+   */
+  static public final boolean TRACE_CLOSE = false;
+  
+  static protected final String WATCHDOG_NAME = "SystemFailure Watchdog";
+  
+  static protected final String PROCTOR_NAME = "SystemFailure Proctor";
+  
+  /**
+   * break any potential circularity in {@link #loadEmergencyClasses()}
+   */
+  private static volatile boolean emergencyClassesLoaded = false;
+  
+  /**
+   * Since it requires object memory to unpack a jar file,
+   * make sure this JVM has loaded the classes necessary for
+   * closure <em>before</em> it becomes necessary to use them.
+   * <p>
+   * Note that just touching the class in order to load it
+   * is usually sufficient, so all an implementation needs
+   * to do is to reference the same classes used in
+   * {@link #emergencyClose()}.  Just make sure to do it while
+   * you still have memory to succeed!
+   */
+  public static void loadEmergencyClasses() {
+    // This method was called to basically load this class
+    // and invoke its static initializers. Now that we don't
+    // use statics to start the threads all we need to do is
+    // call startThreads. The watchdog thread will call basicLoadEmergencyClasses.
+    startThreads();
+  }
+  private static void basicLoadEmergencyClasses() {
+    if (emergencyClassesLoaded) return;
+    emergencyClassesLoaded = true;
+    SystemFailureTestHook.loadEmergencyClasses(); // bug 50516
+    GemFireCacheImpl.loadEmergencyClasses();
+    RemoteGfManagerAgent.loadEmergencyClasses();
+  }
+  
+  /**
+   * Attempt to close any and all GemFire resources.
+   * 
+   * The contract of this method is that it should not
+   * acquire any synchronization mutexes nor create any objects.
+   * <p>
+   * The former is because the system is in an undefined state and
+   * attempting to acquire the mutex may cause a hang.
+   * <p>
+   * The latter is because the likelihood is that we are invoking
+   * this method due to memory exhaustion, so any attempt to create
+   * an object will also cause a hang.
+   * <p>
+   * This method is not meant to be called directly (but, well, I
+   * guess it could).  It is public to document the contract
+   * that is implemented by <code>emergencyClose</code> in other
+   * parts of the system.
+   */
+  public static void emergencyClose() {
+    // Make the cache (more) useless and inaccessible...
+    if (TRACE_CLOSE) {
+      System.err.println("SystemFailure: closing GemFireCache");
+    }
+    GemFireCacheImpl.emergencyClose();
+    
+    // Arcane strange DS's exist in this class:
+    if  (TRACE_CLOSE) {
+      System.err.println("SystemFailure: closing admins");
+    }
+    RemoteGfManagerAgent.emergencyClose();
+    
+    // If memory was the problem, make an explicit attempt at
+    // this point to clean up.
+    
+    System.gc(); //  This will fail if we're out of memory?/
+
+    if (TRACE_CLOSE)  {
+      System.err.println("SystemFailure: end of emergencyClose");
+    }
+  }
+
+  /**
+   * Throw the system failure.
+   * 
+   * This method does not return normally.
+   * <p>
+   * Unfortunately, attempting to create a new Throwable at this
+   * point may cause the thread to hang (instead of generating
+   * another OutOfMemoryError), so we have to make do with whatever
+   * Error we have, instead of wrapping it with one pertinent
+   * to the current context.  See bug 38394.
+   *
+   * @throws Error
+   */
+  static private void throwFailure() throws InternalGemFireError, Error {
+    // Do not return normally...
+    if (failure != null) throw failure;
+  }
+  
+  /**
+   * Notifies the watchdog thread (assumes that {@link #failure} has been set)
+   */
+  private static void notifyWatchDog() {
+    startWatchDog(); // just in case
+    synchronized (failureSync) {
+      failureSync.notifyAll();
+    }
+  }
+  
+  /**
+   * Utility function to check for failures.  If a failure is
+   * detected, this methods throws an AssertionFailure.
+   * 
+   * @see #initiateFailure(Error)
+   * @throws InternalGemFireError if the system has been corrupted
+   * @throws Error if the system has been corrupted and a thread-specific 
+   * AssertionError cannot be allocated
+   */
+  public static void checkFailure() throws InternalGemFireError, Error {
+    if (failure == null) {
+      return;
+    }
+    notifyWatchDog();
+    throwFailure();
+  }
+
+  /**
+   * Signals that a system failure has occurred and then throws an
+   * AssertionError.
+   * 
+   * @param f the failure to set
+   * @throws IllegalArgumentException if f is null
+   * @throws InternalGemFireError always; this method does not return normally.
+   * @throws Error if a thread-specific AssertionError cannot be allocated.
+   */
+  public static void initiateFailure(Error f) throws InternalGemFireError, Error {
+    SystemFailure.setFailure(f);
+    throwFailure();
+  }
+
+  /**
+   * Set the underlying system failure, if not already set.
+   * <p>
+   * This method does not generate an error, and should only be used
+   * in circumstances where execution needs to continue, such as when
+   * re-implementing {@link ThreadGroup#uncaughtException(Thread, Throwable)}.
+   * 
+   * @param failure the system failure
+   * @throws IllegalArgumentException if you attempt to set the failure to null
+   */
+  public static void setFailure(Error failure) {
+    if (failure == null) {
+      throw new IllegalArgumentException(LocalizedStrings.SystemFailure_YOU_ARE_NOT_PERMITTED_TO_UNSET_A_SYSTEM_FAILURE.toLocalizedString());
+    }
+    if (SystemFailureTestHook.errorIsExpected(failure)) {
+      return;
+    }
+    // created (OutOfMemoryError), and no stack frames are created
+    // (StackOverflowError).  There is a slight chance that the
+    // very first error may get overwritten, but this avoids the
+    // potential of object creation via a fat lock
+    SystemFailure.failure = failure;
+    notifyWatchDog();
+  }
+  
+  /**
+   * Returns the catastrophic system failure, if any.
+   * <p>
+   * This is usually (though not necessarily) an instance of
+   * {@link VirtualMachineError}.
+   * <p>
+   * A return value of null indicates that no system failure has yet been
+   * detected.
+   * <p>
+   * Object synchronization can implicitly require object creation (fat locks 
+   * in JRockit for instance), so the underlying value is not synchronized
+   * (it is a volatile). This means the return value from this call is not 
+   * necessarily the <em>first</em> failure reported by the JVM.
+   * <p>
+   * Note that even if it <em>were</em> synchronized, it would only be a 
+   * proximal indicator near the time that the JVM crashed, and may not 
+   * actually reflect the underlying root cause that generated the failure.  
+   * For instance, if your JVM is running short of memory, this Throwable is 
+   * probably an innocent victim and <em>not</em> the actual allocation (or 
+   * series of allocations) that caused your JVM to exhaust memory.
+   * <p>
+   * If this function returns a non-null value, keep in mind that the JVM is
+   * very limited.  In particular, any attempt to allocate objects may fail
+   * if the original failure was an OutOfMemoryError.  
+   * 
+   * @return the failure, if any
+   */
+  public static Error getFailure() {
+    return failure;
+  }
+
+  /**
+   * Sets a user-defined action that is run in the event
+   * that failure has been detected.
+   * <p> 
+   * This action is run <em>after</em> the GemFire cache has been shut down.
+   * If it throws any error, it will be reattempted indefinitely until it
+   * succeeds. This action may be dynamically modified while the system
+   * is running.
+   * <p>
+   * The default action prints the failure stack trace to System.err.
+   * 
+   * @see #initiateFailure(Error)
+   * @param action the Runnable to use
+   * @return the previous action
+   */
+  public static Runnable setFailureAction(Runnable action) {
+    Runnable old = SystemFailure.failureAction;
+    SystemFailure.failureAction = action;
+    return old;
+  }
+
+  /**
+   * Set the memory threshold under which system failure will be
+   * notified. 
+   * 
+   * This value may be dynamically  modified while the system
+   * is running.  The default is 1048576 bytes.  This can be set using the 
+   * system property <code>gemfire.SystemFailure.chronic_memory_threshold</code>.
+   * 
+   * @param newVal threshold in bytes
+   * @return the old threshold
+   * @see Runtime#freeMemory()
+   */
+  public static long setFailureMemoryThreshold(long newVal) {
+    long result;
+    synchronized (memorySync) {
+      result = minimumMemoryThreshold;
+      minimumMemoryThreshold = newVal;
+      firstStarveTime = NEVER_STARVED; // reset
+    }
+    startProctor(); // just in case
+    return result;
+  }
+  
+//  /**
+//   * For use by GemStone Quality Assurance Only
+//   * 
+//   * @deprecated TODO remove this
+//   */
+//  public static void reset() {
+//    System.gc();
+//    logWarning("DJP", "do not commit SystemFailure#reset", null);
+//    failure = null;
+//    failureAction = new Runnable() {
+//      public void run() {
+//        System.err.println("(SystemFailure) JVM corruption has been detected!");
+//        failure.printStackTrace();
+//      }
+//    };
+//    gemfireCloseCompleted = false;
+//    failureActionCompleted = false;
+//    synchronized (failureSync) {
+//      if (watchDog != null) {
+//        watchDog.interrupt();
+//      }
+//      watchDog = null;
+//      if (watchCat != null) {
+//        watchCat.interrupt();
+//      }
+//      watchCat = null;
+//    }
+//
+//    startWatchDog();
+//    startWatchCat();
+//  }
+  
+  static private boolean logStdErr(String kind, String name, String s, Throwable t) {
+    // As far as I can tell, this code path doesn't allocate
+    // any objects!!!!
+    try {
+      System.err.print(name);
+      System.err.print(": [");
+      System.err.print(kind);
+      System.err.print("] ");
+      System.err.println(s);
+      if (t != null) {
+        t.printStackTrace();
+      }
+      return true;
+    }
+    catch (Throwable t2) {
+      // out of luck
+      return false;
+    }
+  }
+  
+  /**
+   * Logging can require allocation of objects, so we wrap the
+   * logger so that failures are silently ignored.
+   * 
+   * @param s string to print
+   * @param t the call stack, if any
+   * @return true if the warning got printed
+   */
+  static protected boolean logWarning(String name, String s, Throwable t) {
+    return logStdErr("warning", name, s, t);
+//    if (PREFER_STDERR) {
+//      return logStdErr("warning", name, s, t);
+//    }
+//    try {
+//      log.warning(name + ": " + s, t);
+//      return true;
+//    }
+//    catch (Throwable t2) {
+//      return logStdErr("warning", name, s, t);
+//    }
+  }
+  
+  /**
+   * Logging can require allocation of objects, so we wrap the
+   * logger so that failures are silently ignored.
+   * 
+   * @param s string to print
+   */
+  static protected void logInfo(String name, String s) {
+    logStdErr("info", name, s, null);
+//    if (PREFER_STDERR) {
+//      logStdErr("info", name, s, null);
+//      return;
+//    }
+//    try {
+//      log.info(name + ": " + s);
+//    }
+//    catch (Throwable t) {
+//      logStdErr("info", name, s, t);
+//    }
+  }
+  
+  /**
+   * Logging can require allocation of objects, so we wrap the
+   * logger so that failures are silently ignored.
+   * 
+   * @param s string to print
+   */
+  static protected void logFine(String name, String s) {
+    if (DEBUG) {
+      logStdErr("fine", name, s, null);
+    }
+//    if (DEBUG && PREFER_STDERR) {
+//      logStdErr("fine", name, s, null);
+//      return;
+//    }
+//    try {
+//      log.fine(name + ": " + s);
+//    }
+//    catch (Throwable t) {
+//      if (DEBUG) {
+//        logStdErr("fine", name, s, null);
+//      }
+//    }
+  }
+  
+  private static volatile boolean stopping;
+  
+  /**
+   * This starts up the watchdog and proctor threads.
+   * This method is called when a Cache is created.
+   */
+  public static void startThreads() {
+    stopping = false;
+    startWatchDog();
+    startProctor();
+  }
+  /**
+   * This stops the threads that implement this service.
+   * This method is called when a Cache is closed.
+   */
+  public static void stopThreads() {
+    // this method fixes bug 45409
+    stopping = true;
+    stopProctor();
+    stopWatchDog();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/SystemIsRunningException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/SystemIsRunningException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/SystemIsRunningException.java
new file mode 100644
index 0000000..331f537
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/SystemIsRunningException.java
@@ -0,0 +1,37 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+/**
+ * A <code>SystemIsRunningException</code> is thrown when an operation
+ * is attempted that requires that the locator is stopped.
+ * <p>
+ * In some cases this exception may be thrown and the locator will
+ * not be running. This will happen if the locator was not stopped
+ * cleanly.
+ * <p>As of GemFire 5.0 this exception should be named LocatorIsRunningException.
+ */
+public class SystemIsRunningException extends GemFireException {
+private static final long serialVersionUID = 3516268055878767189L;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>SystemIsRunningException</code>.
+   */
+  public SystemIsRunningException() {
+    super();
+  }
+
+  /**
+   * Creates a new <code>SystemIsRunningException</code>.
+   */
+  public SystemIsRunningException(String message) {
+    super(message);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/ThreadInterruptedException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/ThreadInterruptedException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/ThreadInterruptedException.java
new file mode 100644
index 0000000..b5284a9
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/ThreadInterruptedException.java
@@ -0,0 +1,15 @@
+package com.gemstone.gemfire;
+
+/**
+ * @deprecated this class is no longer used
+ */
+
+@Deprecated
+public final class ThreadInterruptedException extends CancelException {
+private static final long serialVersionUID = 6169940883541267514L;
+  /**
+   * Do not create instances of this class
+   */
+  private ThreadInterruptedException() { }
+ 
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/ToDataException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/ToDataException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/ToDataException.java
new file mode 100644
index 0000000..b2447e8
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/ToDataException.java
@@ -0,0 +1,33 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire;
+
+/**
+ * A <code>ToDataException</code> is thrown during serialization if
+ * {@link DataSerializable#toData} throws an exception or if
+ * {@link DataSerializer#toData} is called and returns false.
+ * 
+ * @since 6.5
+ * @author darrel
+ */
+public class ToDataException extends SerializationException {
+  private static final long serialVersionUID = -2329606027453879918L;
+  /**
+   * Creates a new <code>ToDataException</code> with the given message
+   */
+  public ToDataException(String message) {
+      super(message);
+  }
+  /**
+   * Creates a new <code>ToDataException</code> with the given message
+   * and cause.
+   */
+  public ToDataException(String message, Throwable cause) {
+      super(message, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/UncreatedSystemException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/UncreatedSystemException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/UncreatedSystemException.java
new file mode 100644
index 0000000..83d4ace
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/UncreatedSystemException.java
@@ -0,0 +1,39 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire;
+
+/**
+ * An <code>UncreatedSystemException</code> is thrown when the specified
+ * locator's directory or configuration file can not be found.
+ * <p>
+ * The most likely reasons for this are:
+ * <ul>
+ * <li> The wrong locator directory was given.
+ * <li> The locator was deleted or never created.
+ * </ul>
+ * <p>As of GemFire 5.0 this exception should be named UncreatedLocatorException.
+ */
+public class UncreatedSystemException extends NoSystemException {
+private static final long serialVersionUID = 5424354567878425435L;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>UncreatedSystemException</code>.
+   */
+  public UncreatedSystemException(String message) {
+    super(message);
+  }
+  /**
+   * Creates a new <code>UncreatedSystemException</code> with the given message
+   * and cause.
+   */
+  public UncreatedSystemException(String message, Throwable cause) {
+      super(message, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/UnmodifiableException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/UnmodifiableException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/UnmodifiableException.java
new file mode 100644
index 0000000..d9141aa
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/UnmodifiableException.java
@@ -0,0 +1,27 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire;
+
+/**
+ * A <code>UnmodifiableException</code> is thrown when a
+ * an attempt is made to modify a GemFire member configuration attribute
+ * that can not currently be modified. In most cases the reason it can
+ * not be modified is that the member is active.
+ */
+public class UnmodifiableException extends GemFireException {
+private static final long serialVersionUID = -1043243260052395455L;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>UnmodifiableException</code>.
+   */
+  public UnmodifiableException(String message) {
+    super(message);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/UnstartedSystemException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/UnstartedSystemException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/UnstartedSystemException.java
new file mode 100644
index 0000000..4370021
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/UnstartedSystemException.java
@@ -0,0 +1,40 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire;
+
+/**
+ * An <code>UnstartedSystemException</code> is thrown when the specified
+ * locator exists but is not running or could not be connected to.
+ * <p>
+ * The most likely reasons for this are:
+ * <ul>
+ * <li> The locator has not completely started.
+ * <li> The locator is stopping.
+ * <li> The locator died or was killed.
+ * </ul>
+ * <p>As of GemFire 5.0 this exception should be named UnstartedLocatorException.
+ */
+public class UnstartedSystemException extends NoSystemException {
+private static final long serialVersionUID = -4285897556527521788L;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>UnstartedSystemException</code>.
+   */
+  public UnstartedSystemException(String message) {
+    super(message);
+  }
+  /**
+   * Creates a new <code>UnstartedSystemException</code> with the given message
+   * and cause.
+   */
+  public UnstartedSystemException(String message, Throwable cause) {
+      super(message, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminConfig.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminConfig.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminConfig.java
new file mode 100755
index 0000000..e2e010f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminConfig.java
@@ -0,0 +1,148 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Date;
+
+
+/**
+ * AdminConfig loads/stores the member information list. The list contains
+ * all of the members being monitored.
+ *
+ * Config must be of the format:
+ * <p>
+ * <li> Name=What you want displayed as a name for the instance
+ * <li> Type=SERVER|CLIENT
+ * <li> Host=A valid hostname or IP Address where the instance is
+ * running
+ * <li> Port=The port you are using to open the monitor port for
+ * the instance
+ * @author dpark
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public class AdminConfig
+{
+  // Name, Type, Host, Port
+  public static Entry[] loadConfig(File file) throws IOException
+  {
+
+    // Place all lines into stack
+    ArrayList entryList = new ArrayList();
+    FileReader reader = null;
+    BufferedReader fileReader = null;
+    try {
+      reader = new FileReader(file);
+      fileReader = new BufferedReader(reader);
+      // Read the first line.
+      String line = fileReader.readLine();
+
+      while (line != null) {
+        line = line.trim();
+
+        // Replace tabs with spaces
+        line = line.replace('\t', ' ');
+
+        // Skip all empty and comment lines
+          if (line.length() != 0 && line.startsWith("#") == false) {
+            try {
+              entryList.add(new Entry(line));
+            } catch (Exception ex) {
+          // ignore - drop any lines that are not valid
+        }
+          }
+          line = fileReader.readLine();
+      }
+    }
+    finally {
+      if (fileReader != null) {
+        fileReader.close();
+      }
+      if (reader != null) {
+        reader.close();
+      }
+    }
+
+    return (Entry[])entryList.toArray(new Entry[0]);
+  }
+
+  public static void storeConfig(File file, AdminConfig.Entry entries[]) throws IOException
+  {
+    FileOutputStream fos = null;
+    PrintStream ps = null;
+    try {
+      fos = new FileOutputStream(file);
+      ps = new PrintStream(fos);
+  
+      // Header
+      ps.print("#");
+      ps.println(LocalizedStrings.AdminConfig_THIS_FILE_IS_GENERATED_BY_ADMINCONSOLE_EDIT_AS_YOU_WISH_BUT_IT_WILL_BE_OVERWRITTEN_IF_IT_IS_MODIFIED_IN_ADMINCONSOLE.toLocalizedString());
+      ps.println("#");
+      ps.println(LocalizedStrings.AdminConfig_MODIFIED_0.toLocalizedString(new Date()));
+      ps.println("#");
+      ps.println("# Name, Type, Host, Port");
+      ps.println("#");
+      int len = entries.length;
+      for (int i = 0; i < len; i++) {
+        ps.println(entries[i].toString());
+      }
+      ps.flush();
+    }
+    finally {
+      if (ps != null) {
+        ps.close();
+      }
+      if (fos != null) {
+        fos.close();
+      }
+    }
+  }
+
+
+  public static class Entry
+  {
+    public String name;
+    public String type;
+    public String host;
+    public int port;
+
+    public Entry(String line)
+    {
+            // Split
+            String split[] = line.split(",");
+
+            // Convert line to parameters
+            name = split[0].trim();
+            type = split[1].trim();
+            host = split[2].trim();
+            port = Integer.parseInt(split[3]);
+    }
+
+    public Entry(String name, String type, String host, int port)
+    {
+      this.name = name;
+      this.type = type;
+      this.host = host;
+      this.port = port;
+    }
+
+    @Override // GemStoneAddition
+    public String toString()
+    {
+      return name + "," + type + "," + host + "," + port;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminDistributedSystem.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminDistributedSystem.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminDistributedSystem.java
new file mode 100755
index 0000000..be067f9
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminDistributedSystem.java
@@ -0,0 +1,479 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+import com.gemstone.gemfire.LogWriter;
+import com.gemstone.gemfire.cache.DataPolicy;
+import com.gemstone.gemfire.cache.persistence.PersistentID;
+import com.gemstone.gemfire.distributed.DistributedMember;
+
+import java.io.File;
+import java.net.InetAddress;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * Administrative interface for managing an entire GemFire distributed
+ * system.  This interface should not be confused with {@link
+ * com.gemstone.gemfire.distributed.DistributedSystem
+ * DistributedSystem} that represents a connection to a GemFire
+ * distributed system.
+ *
+ * @see AdminDistributedSystemFactory
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface AdminDistributedSystem {
+	
+  /**
+   * Retrieves the unique id for this system.
+   */
+  public String getId();
+  
+  /**
+   * Retrieves display friendly name for this system.  If this administrative
+   * VM defined an optional name for its connection to the distributed system,
+   * that name will be returned.  Otherwise the returned value will be {@link
+   * com.gemstone.gemfire.admin.AdminDistributedSystem#getId}.
+   */
+  public String getName();
+  
+  /**
+   * Retrieves the remote command and formatting this system should use to 
+   * access and/or manipulate resources on remote machines.
+   */
+  public String getRemoteCommand();
+
+  /**
+   * Sets the remote command and formatting this system should use to access 
+   * and/or manipulate resources on remote machines.
+   */
+  public void setRemoteCommand(String remoteCommand);
+
+  /**
+   * Sets the lowest level of alert that should be delivered to the
+   * {@link AlertListener}s registered on this
+   * <code>AdminDistributedSystem</code>.  The default level is {@link
+   * AlertLevel#WARNING}. 
+   */
+  public void setAlertLevel(AlertLevel level);
+
+  /**
+   * Returns the lowest level of alerts that should be delivered to
+   * the {@link AlertListener}s registered on this
+   * <code>AdminDistributedSystem</code>.
+   *
+   * @see #setAlertLevel
+   */
+  public AlertLevel getAlertLevel();
+  
+  /**
+   * Sets the lowest level of alert that should be delivered to the
+   * {@link AlertListener}s registered on this
+   * <code>AdminDistributedSystem</code>.  The default level is {@link
+   * AlertLevel#WARNING}. 
+   */
+  public void setAlertLevelAsString(String level);
+
+  /**
+   * Returns the lowest level of alerts that should be delivered to
+   * the {@link AlertListener}s registered on this
+   * <code>AdminDistributedSystem</code>.
+   *
+   * @see #setAlertLevelAsString
+   */
+  public String getAlertLevelAsString();
+
+  /**
+   * Registers an <code>AlertListener</code> that will receive all
+   * alerts that are at or above the {@linkplain #setAlertLevel alert
+   * level}. 
+   */
+  public void addAlertListener(AlertListener listener);
+
+  /**
+   * Unregisters an <code>AlertListener</code> 
+   */
+  public void removeAlertListener(AlertListener listener);
+
+  /**
+   * Retrieves the multicast address in use by this system.
+   */
+  public String getMcastAddress();
+
+  /**
+   * Retrieves the multicast port in use by this system.
+   */
+  public int getMcastPort();
+
+  /**
+   * Retrieves comma-delimited list locators to be used if multi-cast port is
+   * zero.  Format of each locators must be host[port].
+   */
+  public String getLocators();
+
+  /** 
+   * Returns true if this system is using multicast instead of locators for discovery
+   */
+  public boolean isMcastDiscovery();
+  
+  /** 
+   * Returns true if this system has enabled the use of multicast for communications
+   */
+  public boolean isMcastEnabled();
+  
+  /**
+   * Returns true if any members of this system are currently running.
+   */
+  public boolean isRunning();
+
+  /** 
+   * Returns <code>true</code> if this is currently connected to the
+   * system.
+   */
+  public boolean isConnected();
+    
+  /**
+   * Starts all managed entities that are not currently running.
+   *
+   * @throws AdminException
+   *         If a problem is encountered while starting the managed
+   *         entities.
+   */
+  public void start() throws AdminException;
+
+  /**
+   * Stops all managed entities that are currently running.
+   *
+   * @throws AdminException
+   *         If a problem is encountered while starting the managed
+   *         entities.
+   */
+  public void stop() throws AdminException;
+
+  /**
+   * Merges and returns all system logs as a single formatted log.
+   */
+  public String displayMergedLogs();
+
+  /**
+   * Retrieves the license information for this installation of GemFire.
+   *
+   * @deprecated Removed licensing in 8.0.
+   */
+  public java.util.Properties getLicense();
+
+  /**
+   * Creates a new <code>DistributionLocator</code> that is ready to
+   * {@linkplain DistributionLocator#getConfig configure} and
+   * {@linkplain #start start}.
+   *
+   * <P>
+   *
+   * It is presumed that the newly-added locator is used to discover
+   * members of the distributed system.  That is, the host/port of the
+   * new locator is appended to the {@link #getLocators locators}
+   * attribute of this <code>AdminDistributedSystem</code>.
+   */
+  public DistributionLocator addDistributionLocator();
+  
+  /** 
+   * Returns array of <code>DistributionLocator</code>s administered
+   * by this <code>AdminDistributedSystem</code>.
+   */ 
+  public DistributionLocator[] getDistributionLocators();
+  
+  /**
+   * Retrieves SystemMember instances for every
+   * application that is running and currently connection to this
+   * system.  Note that this list does not include dedicated
+   * {@linkplain #getCacheVms cache server vms}.
+   */
+  public SystemMember[] getSystemMemberApplications() 
+  throws com.gemstone.gemfire.admin.AdminException;
+
+  /**
+   * Display in readable format the latest Alert in this distributed system.
+   */
+  public String getLatestAlert();
+  
+  /**
+   * Returns an object for monitoring the health of GemFire.
+   */
+  public GemFireHealth getGemFireHealth();
+
+  /**
+   * Connects to the distributed system.  This method will return
+   * immediately after spawning a background thread that connects to
+   * the distributed system.  As a result, a
+   * <code>AdminDistributedSystem</code> can be "connected" to before
+   * any members of the system have been started or have been seen.
+   * The {@link #waitToBeConnected} method will wait for the
+   * connection to be made.
+   *
+   * @see #isConnected
+   * @see #isRunning
+   * @see #waitToBeConnected
+   */
+  public void connect();
+
+  /**
+   * Wait for up to a given number of milliseconds for the connection
+   * to the distributed system to be made.
+   *
+   * @param timeout
+   *        The number of milliseconds to wait for the connection to
+   *        to be made.
+   *
+   * @return Whether or not the connection was made.
+   *         <code>false</code>, if the method times out
+   *
+   * @throws InterruptedException
+   *         If the thread invoking this method is interrupted while
+   *         waiting. 
+   * @throws IllegalStateException
+   *         If {@link #connect} has not yet been called.
+   */
+  public boolean waitToBeConnected(long timeout)
+    throws InterruptedException;
+
+  /**
+   * Disconnects from the distributed system.
+   */
+  public void disconnect();
+
+  /** Returns this system's configuration .*/  
+  public DistributedSystemConfig getConfig();
+  
+  /**
+   * Registers a listener that receives callbacks when a member joins
+   * or leaves the distributed system.
+   */
+  public void addMembershipListener(SystemMembershipListener listener);
+
+  /**
+   * Unregisters a membership listener
+   *
+   * @see #addMembershipListener
+   */
+  public void removeMembershipListener(SystemMembershipListener listener);
+
+  /**
+   * Registers a cache event listener.
+   * Does nothing if the listener is already registered. The listeners are called
+   * in the order they are registered.
+   * @param listener the listener to register.
+    * @since 5.0
+   */
+   public void addCacheListener(SystemMemberCacheListener listener);
+
+   /**
+    * Unregisters a cache listener. Does nothing if the listener is
+    * not registered.
+    * @param listener the listener to unregister.
+    * @since 5.0
+    */
+   public void removeCacheListener(SystemMemberCacheListener listener);
+
+  /**
+   * Creates a new cache server that is ready to {@linkplain
+   * CacheServerConfig configure} and {@linkplain #start
+   * start}.
+   *
+   * @since 4.0
+   * @deprecated as of 5.7 use {@link #addCacheVm} instead.
+   */
+  @Deprecated
+  public CacheServer addCacheServer() throws AdminException;
+
+  /**
+   * Returns all of the dedicated cache server members of the
+   * distributed system.  Because they are not managed entities,
+   * application VMs that host a server cache are not included in the
+   * array.
+   *
+   * @since 4.0
+   * @deprecated as of 5.7 use {@link #getCacheVms} instead.
+   */
+  @Deprecated
+  public CacheServer[] getCacheServers() throws AdminException;
+
+  /**
+   * Returns all the cache server members of the distributed system which are
+   * hosting a client queue for the particular durable-client having the given
+   * durableClientId
+   * 
+   * @param durableClientId -
+   *                durable-id of the client
+   * @return array of CacheServer(s) having the queue for the durable client
+   * @throws AdminException
+   *
+   * @since 5.6
+   */
+  public CacheServer[] getCacheServers(String durableClientId)
+      throws AdminException;
+
+  /**
+   * Creates a new cache vm that is ready to {@linkplain
+   * CacheVmConfig configure} and {@linkplain #start
+   * start}.
+   *
+   * @since 5.7
+   */
+  public CacheVm addCacheVm() throws AdminException;
+
+  /**
+   * Returns all of the dedicated cache server vm members of the
+   * distributed system.  Because they are not managed entities,
+   * application VMs that host a server cache are not included in the
+   * array.
+   *
+   * @since 5.7
+   */
+  public CacheVm[] getCacheVms() throws AdminException;
+
+  /**
+   * Returns the administrative SystemMember specified by the {@link
+   * com.gemstone.gemfire.distributed.DistributedMember}.
+   *
+   * @param distributedMember the distributed member to lookup
+   * @return administrative SystemMember for that distributed member
+   * @since 5.0
+   */
+  public SystemMember lookupSystemMember(DistributedMember distributedMember) 
+  throws AdminException;
+
+  /**
+   * Indicate to the distributed system that persistent files have been lost.
+   * When a member recovers from a set of persistent files, it will wait for
+   * other members that were also persisting the same region to start up. If the
+   * persistent files for those other members were lost, this method can be used
+   * to tell the remaining members to stop waiting for the lost data.
+   * 
+   * @param host
+   *          The host of the member whose files were lost.
+   * @param directory
+   *          The directory where those files resided.
+   * 
+   * @throws RevokeFailedException if the persistent files are in fact
+   * currently running on one of the members of the distributed system.
+   * @since 6.5
+   * @deprecated use {@link #revokePersistentMember(UUID)} instead
+   */
+  public void revokePersistentMember(InetAddress host, String directory) throws AdminException;
+  
+  /**
+   * Indicate to the distributed system that persistent files have been lost.
+   * When a member recovers from a set of persistent files, it will wait for
+   * other members that were also persisting the same region to start up. If the
+   * persistent files for those other members were lost, this method can be used
+   * to tell the remaining members to stop waiting for the lost data.
+   * 
+   * @param diskStoreID
+   *          The unique id of the disk store which you are revoking. The unique
+   *          id can be discovered from {@link #getMissingPersistentMembers()}
+   * 
+   * @throws RevokeFailedException if the persistent files are in fact
+   * currently running on one of the members of the distributed system.
+   * @since 7.0
+   */
+  public void revokePersistentMember(UUID diskStoreID) throws AdminException;
+  
+  /**
+   * Retrieve the set of persistent files that the existing members are waiting
+   * for. See {@link AdminDistributedSystem#revokePersistentMember(InetAddress, String)}
+   * @return The persistent members that were known to the existing persistent members,
+   * when the existing members were last online.
+   * @throws AdminException
+   * @since 6.5
+   * 
+   */
+  public Set<PersistentID> getMissingPersistentMembers() throws AdminException;
+
+  /**
+   * Shuts down all the members of the distributed system with a cache that the admin 
+   * member is connected to, excluding the stand-alone locators. Calling this method
+   * will ensure that regions with the {@link DataPolicy#PERSISTENT_PARTITION} to
+   * be shutdown in a way which allows for a faster recovery when the members are 
+   * restarted.
+   * 
+   * Killing individual members can lead to inconsistencies in the members persistent
+   * data, which gemfire repairs on startup. Calling shutDownAllMembers makes sure
+   * that the persistent files are consistent on shutdown, which makes recovery faster.
+   *  
+   * This is equivalent to calling shutDownAllMembers(0);
+   * @return The set of members that were shutdown
+   * @since 6.5
+   */
+  public Set<DistributedMember> shutDownAllMembers() throws AdminException;
+  
+  /**
+   * Shuts down all the members of the distributed system with a cache that the
+   * admin member is connected to, excluding the stand-alone locators. Calling
+   * this method will ensure that regions with the
+   * {@link DataPolicy#PERSISTENT_PARTITION} to be shutdown in a way which
+   * allows for a faster recovery when the members are restarted.
+   * 
+   * Killing individual members can lead to inconsistencies in the members
+   * persistent data, which gemfire repairs on startup. Calling
+   * shutDownAllMembers makes sure that the persistent files are consistent on
+   * shutdown, which makes recovery faster.
+   * 
+   * @param timeout The amount of time to wait (in milliseconds) for the shutdown all to
+   *          complete. 
+   * @return The set of members that were shutdown, or null if the timeout is exceeded.
+   * 
+   * @since 6.5
+   */
+  public Set<DistributedMember> shutDownAllMembers(long timeout) throws AdminException;
+
+  /**
+   * Backup the persistent files for all of the members of the distributed
+   * system that the admin member is connected to. 
+   * 
+   * @param targetDir The directory where each member's backup should be placed.
+   * 
+   * @return The status of the backup, which includes the set of members
+   * that were backed up and the set of members that were known to be
+   * offline at the time of backup.
+   * @since 6.5
+   */
+  public BackupStatus backupAllMembers(File targetDir) throws AdminException;
+  
+  /**
+   * Incrementally backup the persistent files for all of the members of the distributed
+   * system that the admin member is connected to. Only new operation log files since the previous backup will be copied during this backup.
+   * The generated restore script will reference and copy operation log files from the previous backup.
+   * 
+   * @param targetDir The directory where each member's backup should be placed.
+   * @param baselineDir The directory of a previous backup.
+   * If this parameter is null or the directory does not exist (on a member by member basis)
+   * a full backup will be performed for the member. 
+   * 
+   * @return The status of the backup, which includes the set of members
+   * that were backed up and the set of members that were known to be
+   * offline at the time of backup.
+   * @since 6.5
+   */
+  public BackupStatus backupAllMembers(File targetDir,File baselineDir) throws AdminException;
+  
+  /**
+   * Compact the persistent files for all of the members of the distributed
+   * system that the admin member connected to. 
+   * 
+   * This is equivalent to calling {DiskStore#forceCompaction} on all members.
+   * 
+   * @return The set of members that compacted their disk stores.
+   * @since 6.5
+   */
+  public Map<DistributedMember, Set<PersistentID>> compactAllDiskStores() throws AdminException;
+}
+


[12/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ContainsKeyOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ContainsKeyOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ContainsKeyOp.java
new file mode 100644
index 0000000..b3fdbc0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ContainsKeyOp.java
@@ -0,0 +1,93 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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 containsKey on a server
+ * @author darrel
+ * @since 5.7
+ */
+public class ContainsKeyOp {
+  /**
+   * Does a region entry containsKey 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 containsKey on
+   * @param key the entry key to do the containsKey on
+   * @return the result of invoking containsKey on the server
+   */
+  public static boolean execute(ExecutablePool pool,
+                                String region,
+                                Object key,
+                                MODE mode)
+  {
+    AbstractOp op = new ContainsKeyOpImpl(region, key, mode);
+    Boolean result = (Boolean)pool.execute(op);
+    return result.booleanValue();
+  }
+                                                               
+  private ContainsKeyOp() {
+    // no instances allowed
+  }
+  
+  private static class ContainsKeyOpImpl extends AbstractOp {
+    
+    private String region;
+    private Object key;
+    private final MODE mode;
+    
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public ContainsKeyOpImpl(String region,
+                         Object key,
+                         MODE mode) {
+      super(MessageType.CONTAINS_KEY, 3);
+      getMessage().addStringPart(region);
+      getMessage().addStringOrObjPart(key);
+      getMessage().addIntPart(mode.ordinal());
+      this.region = region;
+      this.key = key;
+      this.mode = mode;
+    }
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      return processObjResponse(msg, "containsKey");
+    }
+    @Override
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.CONTAINS_KEY_DATA_ERROR;
+    }
+    @Override
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startContainsKey();
+    }
+    @Override
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endContainsKeySend(start, hasFailed());
+    }
+    @Override
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endContainsKey(start, hasTimedOut(), hasFailed());
+    }
+    
+    @Override
+    public String toString() {
+      return "ContainsKeyOp(region=" + region + ";key=" + key+";mode="+mode;
+    }
+  }
+  
+  public enum MODE {
+    KEY,
+    VALUE_FOR_KEY,
+    VALUE;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/DataSerializerRecoveryListener.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/DataSerializerRecoveryListener.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/DataSerializerRecoveryListener.java
new file mode 100644
index 0000000..66cf256
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/DataSerializerRecoveryListener.java
@@ -0,0 +1,144 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.cache.client.internal.PoolImpl.PoolTask;
+import com.gemstone.gemfire.internal.InternalDataSerializer;
+import com.gemstone.gemfire.internal.InternalDataSerializer.SerializerAttributesHolder;
+import com.gemstone.gemfire.internal.cache.EventID;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+
+public class DataSerializerRecoveryListener extends EndpointManager.EndpointListenerAdapter {
+  private static final Logger logger = LogService.getLogger();
+  
+  private final AtomicInteger endpointCount = new AtomicInteger();
+  protected final InternalPool pool;
+  protected final ScheduledExecutorService background;
+  protected final long pingInterval;
+  protected final Object recoveryScheduledLock = new Object();
+  protected boolean recoveryScheduled;
+  
+  public DataSerializerRecoveryListener(ScheduledExecutorService background, InternalPool pool) {
+    this.pool = pool;
+    this.pingInterval = pool.getPingInterval();
+    this.background = background;
+  }
+  
+  @Override
+  public void endpointCrashed(Endpoint endpoint) {
+    int count = endpointCount.decrementAndGet();
+    if(logger.isDebugEnabled()) {
+      logger.debug("DataSerializerRecoveryTask - EndpointCrashed. Now have {} endpoints", count);
+    }
+  }
+
+  @Override
+  public void endpointNoLongerInUse(Endpoint endpoint) {
+    int count = endpointCount.decrementAndGet();
+    if(logger.isDebugEnabled()) {
+      logger.debug("DataSerializerRecoveryTask - EndpointNoLongerInUse. Now have {} endpoints", count);
+    }
+  }
+
+  @Override
+  public void endpointNowInUse(Endpoint endpoint) {
+    int count  = endpointCount.incrementAndGet();
+    if(logger.isDebugEnabled()) {
+      logger.debug("DataSerializerRecoveryTask - EndpointNowInUse. Now have {} endpoints", count);
+    }
+    if(count == 1) {
+      synchronized(recoveryScheduledLock) {
+        if(!recoveryScheduled) {
+          try {
+            recoveryScheduled = true;
+            background.execute(new RecoveryTask());
+            logger.debug("DataSerializerRecoveryTask - Scheduled Recovery Task");
+          } catch(RejectedExecutionException e) {
+            //ignore, the timer has been cancelled, which means we're shutting down.
+          }
+        }
+      }
+    }
+  }
+  
+  protected class RecoveryTask extends PoolTask {
+
+    @Override
+    public void run2() {
+      if(pool.getCancelCriterion().cancelInProgress() != null) {
+        return;
+      }
+      synchronized(recoveryScheduledLock) {
+        recoveryScheduled = false;
+      }
+      logger.debug("DataSerializerRecoveryTask - Attempting to recover dataSerializers");
+      SerializerAttributesHolder[] holders= InternalDataSerializer.getSerializersForDistribution();
+      if(holders.length == 0) {
+        return;
+      }
+      EventID eventId = InternalDataSerializer.generateEventId();
+      //Fix for bug:40930
+      if (eventId == null) {
+        try {
+          background.schedule(new RecoveryTask(), pingInterval,
+              TimeUnit.MILLISECONDS);
+          recoveryScheduled = true;
+        } catch (RejectedExecutionException e) {
+          pool.getCancelCriterion().checkCancelInProgress(e);
+          throw e;
+        }
+      }
+      else {
+        try {
+          RegisterDataSerializersOp.execute(pool, holders, eventId);
+        } 
+        catch (CancelException e) {
+          throw e;
+        }
+        catch (RejectedExecutionException e) {
+          // This is probably because we've started to shut down.
+          pool.getCancelCriterion().checkCancelInProgress(e);
+          throw e; // weird
+        }
+        catch(Exception e) {
+          pool.getCancelCriterion().checkCancelInProgress(e);
+          
+          // If ClassNotFoundException occurred on server, don't retry
+          Throwable cause = e.getCause();
+          boolean cnfException = false;
+          if (cause instanceof ClassNotFoundException) {
+            logger.warn(LocalizedMessage.create(
+                LocalizedStrings.DataSerializerRecoveryListener_ERROR_CLASSNOTFOUNDEXCEPTION,
+                cause.getMessage()));
+            cnfException = true;
+          }
+          
+          if(!recoveryScheduled && !cnfException) {
+            logger.warn(LocalizedMessage.create(
+              LocalizedStrings.DataSerializerRecoveryListener_ERROR_RECOVERING_DATASERIALIZERS),
+              e);
+            background.schedule(new RecoveryTask(), pingInterval, TimeUnit.MILLISECONDS);
+            recoveryScheduled = true;
+          }
+        } finally {
+          pool.releaseThreadLocalConnection();
+        }
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/DestroyOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/DestroyOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/DestroyOp.java
new file mode 100644
index 0000000..7dc0eaa
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/DestroyOp.java
@@ -0,0 +1,282 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.EntryNotFoundException;
+import com.gemstone.gemfire.cache.Operation;
+import com.gemstone.gemfire.cache.client.AllConnectionsInUseException;
+import com.gemstone.gemfire.cache.client.ServerConnectivityException;
+import com.gemstone.gemfire.cache.client.ServerOperationException;
+import com.gemstone.gemfire.cache.util.BridgeWriterException;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+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.cache.versions.VersionTag;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * Does a region destroy on a server
+ * @author darrel
+ * @since 5.7
+ */
+public class DestroyOp {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  public static final int HAS_VERSION_TAG = 0x01;
+  
+  public static final int HAS_ENTRY_NOT_FOUND_PART = 0x02;
+
+  /**
+   * Does a region entry destroy 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 region to do the entry destroy on
+   * @param key the entry key to do the destroy on
+   * @param event the event for this destroy operation
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   */
+  public static Object execute(ExecutablePool pool, LocalRegion region,
+      Object key,
+      Object expectedOldValue, Operation operation,
+      EntryEventImpl event, Object callbackArg,
+      boolean prSingleHopEnabled) {
+    if (logger.isDebugEnabled()) {
+      logger.debug("Preparing DestroyOp for {} operation={}", key, operation);
+    }
+    AbstractOp op = new DestroyOpImpl(region, key, expectedOldValue,
+        operation, event, callbackArg, prSingleHopEnabled);
+    if (prSingleHopEnabled) {
+      ClientMetadataService cms = region.getCache()
+          .getClientMetadataService();
+      ServerLocation server = cms.getBucketServerLocation(region,
+          Operation.DESTROY, key, null, callbackArg);
+      if (server != null) {
+        try {
+          PoolImpl poolImpl = (PoolImpl)pool;
+          boolean onlyUseExistingCnx = ((poolImpl.getMaxConnections() != -1 && poolImpl
+              .getConnectionCount() >= poolImpl.getMaxConnections()) ? true
+              : false);
+          return pool.executeOn(server, op, true, onlyUseExistingCnx);
+        }
+        catch (AllConnectionsInUseException e) {
+        }
+        catch (ServerConnectivityException e) {
+          if (e instanceof ServerOperationException) {
+            throw e; // fixed 44656
+          }
+          cms.removeBucketServerLocation(server);
+        }
+        catch (BridgeWriterException e) {
+          if (e.getCause() instanceof ServerConnectivityException)
+            cms.removeBucketServerLocation(server);
+        }
+      }
+    }
+    return pool.execute(op);
+  }
+  
+  /**
+   * Does a region entry destroy on a server using the given connection to
+   * communicate with the server.
+   * 
+   * @param con
+   *                the connection to use to send to the server
+   * @param pool
+   *                the pool to use to communicate with the server.
+   * @param region
+   *                the region to do the entry destroy on
+   * @param key
+   *                the entry key to do the destroy on
+   * @param event
+   *                the event for this destroy operation
+   * @param callbackArg
+   *                an optional callback arg to pass to any cache callbacks
+   */
+  public static void execute(Connection con,
+                             ExecutablePool pool,
+                             String region,
+                             Object key,
+                             Object expectedOldValue,
+                             Operation operation,
+                             EntryEventImpl event,
+                             Object callbackArg)
+  {
+    AbstractOp op = new DestroyOpImpl(region, key, expectedOldValue,
+        operation, event, callbackArg);
+    pool.executeOn(con, op);
+  }
+
+  /** this is set if a response is received indicating that the entry was not found on the server */
+  public static boolean TEST_HOOK_ENTRY_NOT_FOUND;
+                                                               
+  private DestroyOp() {
+    // no instances allowed
+  }
+  
+  private static class DestroyOpImpl extends AbstractOp {
+    
+    Object key = null;
+    
+    private LocalRegion region;       
+
+    private Operation operation;
+
+    private boolean prSingleHopEnabled = false;
+    
+    private Object callbackArg;
+    
+    private EntryEventImpl event;
+    
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public DestroyOpImpl(LocalRegion region,
+                         Object key,
+                         Object expectedOldValue,
+                         Operation operation,
+                         EntryEventImpl event,
+                         Object callbackArg,
+                         boolean prSingleHopEnabled) {
+      super(MessageType.DESTROY, callbackArg != null ? 6 : 5);
+      this.key = key;
+      this.region = region ;
+      this.operation = operation;
+      this.prSingleHopEnabled = prSingleHopEnabled;
+      this.callbackArg = callbackArg ;
+      this.event = event;
+      getMessage().addStringPart(region.getFullPath());
+      getMessage().addStringOrObjPart(key);
+      getMessage().addObjPart(expectedOldValue);
+      getMessage().addObjPart(operation==Operation.DESTROY? null : operation); // server interprets null as DESTROY
+      getMessage().addBytesPart(event.getEventId().calcBytes());
+      if (callbackArg != null) {
+        getMessage().addObjPart(callbackArg);
+      }
+    }
+
+
+    public DestroyOpImpl(String region, Object key, Object expectedOldValue,
+        Operation operation, EntryEventImpl event, 
+        Object callbackArg) {
+      super(MessageType.DESTROY, callbackArg != null ? 6 : 5);
+      this.key = key;
+      this.event = event;
+      getMessage().addStringPart(region);
+      getMessage().addStringOrObjPart(key);
+      getMessage().addObjPart(expectedOldValue);
+      getMessage().addObjPart(operation==Operation.DESTROY? null : operation); // server interprets null as DESTROY
+      getMessage().addBytesPart(event.getEventId().calcBytes());
+      if (callbackArg != null) {
+        getMessage().addObjPart(callbackArg);
+      }
+    }
+    
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      throw new UnsupportedOperationException();
+    }
+    
+    
+    @Override
+    protected Object processResponse(Message msg, Connection con) throws Exception {
+      processAck(msg, "destroy");
+      boolean isReply = (msg.getMessageType() == MessageType.REPLY);
+      int partIdx = 0;
+      int flags = 0;
+      if (isReply) {
+        flags = msg.getPart(partIdx++).getInt();
+        if ((flags & HAS_VERSION_TAG) != 0) {
+          VersionTag tag = (VersionTag)msg.getPart(partIdx++).getObject();
+          // we use the client's ID since we apparently don't track the server's ID in connections
+          tag.replaceNullIDs((InternalDistributedMember) con.getEndpoint().getMemberId());
+          this.event.setVersionTag(tag);
+          if (logger.isDebugEnabled()) {
+            logger.debug("received Destroy response with {}", tag);
+            }
+        } else if (logger.isDebugEnabled()) {
+          logger.debug("received Destroy response with no version tag");
+        }
+      }
+      if (prSingleHopEnabled) {
+        byte version = 0 ;
+//        if (log.fineEnabled()) {
+//          log.fine("reading prSingleHop part #" + (partIdx+1));
+//        }
+        Part part = msg.getPart(partIdx++);
+        byte[] bytesReceived = part.getSerializedForm();
+        if (bytesReceived[0] != ClientMetadataService.INITIAL_VERSION
+            && bytesReceived.length == ClientMetadataService.SIZE_BYTES_ARRAY_RECEIVED) {
+          if (this.region != null) {
+            ClientMetadataService cms = null;
+            try {
+              cms = region.getCache().getClientMetadataService();
+              version = cms.getMetaDataVersion(region, Operation.UPDATE,
+                  key, null, callbackArg);
+            }
+            catch (CacheClosedException e) {
+              return null;
+            }
+            if (bytesReceived[0] != version) {
+              cms.scheduleGetPRMetaData(region, false,bytesReceived[1]);
+            }
+          }
+        }
+      } else {
+        partIdx++; // skip OK byte
+      }
+      boolean entryNotFound = false;
+      if (msg.getMessageType() == MessageType.REPLY && (flags & HAS_ENTRY_NOT_FOUND_PART) != 0) {
+        entryNotFound = (msg.getPart(partIdx++).getInt() == 1);
+        if (logger.isDebugEnabled() && (flags & HAS_ENTRY_NOT_FOUND_PART) != 0) {
+          logger.debug("destroy response has entryNotFound={}", entryNotFound);
+        }
+        if (entryNotFound) {
+          TEST_HOOK_ENTRY_NOT_FOUND = true;
+        }
+      }
+      if (this.operation == Operation.REMOVE && entryNotFound) {
+        if (logger.isDebugEnabled()) {
+          logger.debug("received REMOVE response from server with entryNotFound={}", entryNotFound);
+        }
+        return new EntryNotFoundException(LocalizedStrings.AbstractRegionMap_ENTRY_NOT_FOUND_WITH_EXPECTED_VALUE.toLocalizedString());
+      }
+      return null;
+    }
+
+    @Override
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.DESTROY_DATA_ERROR;
+    }
+
+    @Override
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startDestroy();
+    }
+    @Override
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endDestroySend(start, hasFailed());
+    }
+    @Override
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endDestroy(start, hasTimedOut(), hasFailed());
+    }
+    @Override
+    public String toString() {
+      return "DestroyOp:"+key;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/DestroyRegionOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/DestroyRegionOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/DestroyRegionOp.java
new file mode 100644
index 0000000..f1e3cd9
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/DestroyRegionOp.java
@@ -0,0 +1,95 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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.internal.cache.EventID;
+
+/**
+ * Does a region destroyRegion (or create) on a server
+ * @author darrel
+ * @since 5.7
+ */
+public class DestroyRegionOp {
+  /**
+   * Does a region destroyRegion 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 destroyRegion on
+   * @param eventId the event id for this destroyRegion
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   */
+  public static void execute(ExecutablePool pool,
+                             String region,
+                             EventID eventId,
+                             Object callbackArg)
+  {
+    AbstractOp op = new DestroyRegionOpImpl(region, eventId, callbackArg);
+    pool.execute(op);
+  }
+  /**
+   * Does a region destroyRegion on a server using the given connection
+   * to communicate with the server.
+   * @param con the connection to use to send to the server
+   * @param pool the pool to use to communicate with the server.
+   * @param region the name of the region to do the destroyRegion on
+   * @param eventId the event id for this destroyRegion
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   */
+  public static void execute(Connection con,
+                             ExecutablePool pool,
+                             String region,
+                             EventID eventId,
+                             Object callbackArg)
+  {
+    AbstractOp op = new DestroyRegionOpImpl(region, eventId, callbackArg);
+    pool.executeOn(con, op);
+  }
+                                                               
+  private DestroyRegionOp() {
+    // no instances allowed
+  }
+  
+  private static class DestroyRegionOpImpl extends AbstractOp {
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public DestroyRegionOpImpl(String region,
+                     EventID eventId,
+                     Object callbackArg) {
+      super(MessageType.DESTROY_REGION, callbackArg != null ? 3 : 2);
+      getMessage().addStringPart(region);
+      getMessage().addBytesPart(eventId.calcBytes());
+      if (callbackArg != null) {
+        getMessage().addObjPart(callbackArg);
+      }
+    }
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      processAck(msg, "destroyRegion");
+      return null;
+    }
+    @Override
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.DESTROY_REGION_DATA_ERROR;
+    }
+    @Override
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startDestroyRegion();
+    }
+    @Override
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endDestroyRegionSend(start, hasFailed());
+    }
+    @Override
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endDestroyRegion(start, hasTimedOut(), hasFailed());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/Endpoint.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/Endpoint.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/Endpoint.java
new file mode 100644
index 0000000..25518a3
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/Endpoint.java
@@ -0,0 +1,102 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import com.gemstone.gemfire.distributed.DistributedMember;
+import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+
+/**
+ * Represents a server. Keeps track of information about the specific server
+ * @author dsmith
+ * @since 5.7
+ *
+ */
+public class Endpoint {
+  
+  private AtomicLong lastExecute = new AtomicLong();
+  private AtomicInteger references = new AtomicInteger();
+  private final ServerLocation location;
+  private final ConnectionStats stats;
+  private final EndpointManagerImpl manager;
+  private final DistributedMember memberId;
+  private volatile boolean closed;
+  
+  Endpoint(EndpointManagerImpl endpointManager, DistributedSystem ds,
+      ServerLocation location, ConnectionStats stats,
+      DistributedMember memberId) {
+    this.manager =endpointManager;
+    this.location = location;
+    this.stats = stats;
+    this.memberId = memberId;
+    updateLastExecute();
+  }
+
+  public void updateLastExecute() {
+    this.lastExecute.set(System.nanoTime());
+  }
+
+  private long getLastExecute() {
+    return lastExecute.get();
+  }
+
+  public boolean timeToPing(long pingIntervalNanos) {
+    long now = System.nanoTime();
+    return getLastExecute() <= (now - pingIntervalNanos);
+  }
+  
+  public void close() {
+    if(!closed) {
+      closed = true;
+    }
+  }
+  
+  public boolean isClosed() {
+    return closed == true;
+  }
+
+  public ConnectionStats getStats() {
+    return stats;
+  }
+
+  void addReference() {
+    references.incrementAndGet();
+  }
+
+  /**
+   * @return true if this was the last reference to the endpoint
+   */
+  public boolean removeReference() {
+    boolean lastReference = (references.decrementAndGet() <= 0);
+    if(lastReference) {
+      manager.endpointNotInUse(this);
+    }
+    return lastReference;
+  }
+
+  /**
+   * @return the location of this server
+   */
+  public ServerLocation getLocation() {
+    return location;
+  }
+
+  @Override
+  public String toString() {
+    return location.toString();
+  }
+  
+  public DistributedMember getMemberId() {
+    return memberId;
+  }
+  
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/EndpointManager.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/EndpointManager.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/EndpointManager.java
new file mode 100644
index 0000000..5d4a1f2
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/EndpointManager.java
@@ -0,0 +1,91 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.Map;
+
+import com.gemstone.gemfire.distributed.DistributedMember;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+
+/**
+ * The endpoint manager keeps track of which servers we 
+ * are connected to. Other parts of the client code can register
+ * listeners that will be notified about when endpoints are created
+ * or died. For example the connection manager registers a listener
+ * to be notified if a server dies and closes all of it's connections.
+ * @author dsmith
+ *
+ */
+public interface EndpointManager {
+  /**
+   * Get the endpoint for this server and create it if it does not already exist.
+   * This increments the reference count for the endpoint,
+   *  so you should call {@link Endpoint#removeReference()} after
+   *  the endpoint is no longer in use.
+   */
+  Endpoint referenceEndpoint(ServerLocation server, DistributedMember memberId);
+
+  /**
+   * Indicate that a particular server has crashed. All of the listeners will be notified
+   * that the server has crashed.
+   * @param endpoint
+   */
+  void serverCrashed(Endpoint endpoint);
+
+  /**
+   * Get the map of all endpoints currently in use.
+   * @return a map for ServerLocation->Endpoint
+   */
+  Map<ServerLocation, Endpoint> getEndpointMap();
+
+  void close();
+
+  /** Add a listener which will be notified when the state of
+   * an endpoint changes.
+   */
+  void addListener(EndpointManager.EndpointListener listener);
+
+  /**
+   * Remove a listener. 
+   */
+  void removeListener(EndpointManager.EndpointListener listener);
+  
+  /**
+   * Get the stats for all of the servers we ever connected too.
+   * @return a map of ServerLocation-> ConnectionStats
+   */
+  public Map getAllStats();
+
+  /**
+   * Test hook that returns the number of servers we currently have connections to.
+   */
+  public int getConnectedServerCount();
+
+  public static interface EndpointListener {
+    
+    void endpointNoLongerInUse(Endpoint endpoint);
+    
+    void endpointCrashed(Endpoint endpoint);
+    
+    void endpointNowInUse(Endpoint endpoint);
+  }
+
+  public static class EndpointListenerAdapter implements EndpointListener {
+  
+    public void endpointCrashed(Endpoint endpoint) {
+    }
+  
+    public void endpointNoLongerInUse(Endpoint endpoint) {
+    }
+  
+    public void endpointNowInUse(Endpoint endpoint) {
+    }
+  }
+
+  public String getPoolName();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/EndpointManagerImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/EndpointManagerImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/EndpointManagerImpl.java
new file mode 100644
index 0000000..5bf3a48
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/EndpointManagerImpl.java
@@ -0,0 +1,301 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.ArrayList;
+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 org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.CancelCriterion;
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.client.PoolManager;
+import com.gemstone.gemfire.distributed.DistributedMember;
+import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.DummyStatisticsFactory;
+import com.gemstone.gemfire.internal.cache.PoolStats;
+import com.gemstone.gemfire.internal.cache.execute.TransactionFunctionService;
+import com.gemstone.gemfire.internal.cache.tier.InternalBridgeMembership;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * @author dsmith
+ *
+ */
+public class EndpointManagerImpl implements EndpointManager {
+  private static final Logger logger = LogService.getLogger();
+  
+  private volatile Map<ServerLocation, Endpoint> endpointMap = Collections.emptyMap();
+  private final Map/*<ServerLocation, ConnectionStats>*/<ServerLocation, ConnectionStats> statMap = new HashMap<ServerLocation, ConnectionStats>();
+  private final DistributedSystem ds;
+  private final String poolName;
+  private final EndpointListenerBroadcaster listener = new EndpointListenerBroadcaster();
+  protected final CancelCriterion cancelCriterion;
+  private final PoolStats poolStats;
+  
+  public EndpointManagerImpl(String poolName, DistributedSystem ds,CancelCriterion cancelCriterion, PoolStats poolStats) {
+    this.ds = ds;
+    this.poolName = poolName;
+    this.cancelCriterion = cancelCriterion;
+    this.poolStats = poolStats;
+    listener.addListener(new EndpointListenerForBridgeMembership());
+    listener.addListener(new TransactionFunctionService.ListenerForTransactionFunctionService());
+  }
+  
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.EndpointManager#referenceEndpoint(com.gemstone.gemfire.distributed.internal.ServerLocation)
+   */
+  public Endpoint referenceEndpoint(ServerLocation server, DistributedMember memberId) {
+    //logger.warn("REFENDPOINT server:"+server+" memberId:"+memberId);
+    Endpoint endpoint = endpointMap.get(server);
+    boolean addedEndpoint = false;
+    if(endpoint == null || endpoint.isClosed()) {
+      synchronized(this) {
+        endpoint = endpointMap.get(server);
+        if(endpoint == null || endpoint.isClosed()) {
+          ConnectionStats stats  = getStats(server);
+          Map<ServerLocation, Endpoint> endpointMapTemp = new HashMap<ServerLocation, Endpoint>(endpointMap);
+          endpoint = new Endpoint(this, ds, server, stats, memberId);
+          endpointMapTemp.put(server, endpoint);
+          endpointMap = Collections.unmodifiableMap(endpointMapTemp);
+          addedEndpoint = true;
+          poolStats.setServerCount(endpointMap.size());
+        }
+      }
+    }
+    
+    endpoint.addReference();
+    
+    if(addedEndpoint) {
+      //logger.warn("EMANFIRE2:JOIN:"+endpoint.getLocation()+" mid:"+endpoint.getMemberId());
+      listener.endpointNowInUse(endpoint);
+    } else {
+      //logger.warn("EMANFIRE33:NOJOIN:"+endpoint.getLocation()+" mid:"+endpoint.getMemberId());
+    }
+    
+    return endpoint;
+  }
+  
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.EndpointManager#serverCrashed(com.gemstone.gemfire.cache.client.internal.Endpoint)
+   */
+  public void serverCrashed(Endpoint endpoint) {
+    removeEndpoint(endpoint, true);
+  }
+  
+  void endpointNotInUse(Endpoint endpoint) {
+    removeEndpoint(endpoint, false);
+  }
+  
+  /** Used by Endpoint only, when the reference count for this endpoint reaches 0 */
+  private void removeEndpoint(Endpoint endpoint, boolean crashed) {
+    endpoint.close();
+    boolean removedEndpoint = false;
+    synchronized(this) {
+      Map<ServerLocation, Endpoint> endpointMapTemp = new HashMap<ServerLocation, Endpoint>(endpointMap);
+      endpoint = endpointMapTemp.remove(endpoint.getLocation());
+      if(endpoint != null) {
+        endpointMap = Collections.unmodifiableMap(endpointMapTemp);
+        removedEndpoint = true;
+      }
+      poolStats.setServerCount(endpointMap.size());
+    }
+    if(removedEndpoint) {
+      PoolImpl pool = (PoolImpl)PoolManager.find(this.poolName);
+      if (pool != null && pool.getMultiuserAuthentication()) {
+        int size = 0;
+        ArrayList<ProxyCache> proxyCaches = pool.getProxyCacheList();
+        synchronized (proxyCaches) {
+        for (ProxyCache proxyCache : proxyCaches) {
+          try {
+            Long userId = proxyCache.getUserAttributes().getServerToId().remove(
+                endpoint.getLocation());
+            if (userId != null) {
+              ++size;
+            }
+          } catch (CacheClosedException cce) {
+            // If this call is triggered by a Cache.close(), then this can be
+            // expected.
+          }
+        }
+        if (logger.isDebugEnabled()) {
+          logger.debug("EndpointManagerImpl.removeEndpoint() Removed server {} from {} user's ProxyCache", endpoint.getLocation(), size);
+        }
+        }
+        UserAttributes ua = UserAttributes.userAttributes.get();
+        if (ua != null) {
+          Long userId = ua.getServerToId().remove(endpoint.getLocation());
+          if (userId != null && logger.isDebugEnabled()) {
+            logger.debug("EndpointManagerImpl.removeEndpoint() Removed server {} from thread local variable", endpoint.getLocation());
+          }
+        }
+      } else if (pool != null && !pool.getMultiuserAuthentication()) {
+        endpoint.getLocation().setUserId(-1);
+      }
+      if(crashed) {
+        listener.endpointCrashed(endpoint);
+      }
+      else {
+        listener.endpointNoLongerInUse(endpoint);
+      }
+    }
+  }
+  
+  
+
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.EndpointManager#getEndpointMap()
+   */
+  public Map<ServerLocation, Endpoint> getEndpointMap() {
+    return endpointMap;
+  }
+
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.EndpointManager#close()
+   */
+  public synchronized void close() {
+    for(Iterator<ConnectionStats> itr = statMap.values().iterator(); itr.hasNext(); ) {
+      ConnectionStats stats = itr.next();
+      stats.close();
+    }
+    
+    statMap.clear();
+    endpointMap = Collections.emptyMap();
+    listener.clear();
+  }
+  
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.EndpointManager#addListener(com.gemstone.gemfire.cache.client.internal.EndpointManagerImpl.EndpointListener)
+   */
+  public void addListener(EndpointManager.EndpointListener listener) {
+    this.listener.addListener(listener);
+  }
+  
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.EndpointManager#removeListener(com.gemstone.gemfire.cache.client.internal.EndpointManagerImpl.EndpointListener)
+   */
+  public void removeListener(EndpointManager.EndpointListener listener) {
+    this.listener.removeListener(listener);
+  }
+  
+  private synchronized ConnectionStats getStats(ServerLocation location) {
+    ConnectionStats stats = statMap.get(location);
+    if(stats == null) {
+      String statName = poolName + "-" + location.toString();
+      PoolImpl pool = (PoolImpl)PoolManager.find(this.poolName);
+      if (pool != null) {
+        if (pool.getGatewaySender() != null) {
+          stats = new ConnectionStats(new DummyStatisticsFactory(), statName,
+              this.poolStats/*, this.gatewayStats*/);
+        }
+      }
+      if (stats == null) {
+        stats = new ConnectionStats(ds, statName, this.poolStats/*,
+            this.gatewayStats*/);
+      }
+      statMap.put(location, stats);
+    }
+    
+    return stats;
+  }
+  
+  public synchronized Map<ServerLocation, ConnectionStats> getAllStats() {
+    return new HashMap<ServerLocation, ConnectionStats>(statMap);
+  }
+
+  public int getConnectedServerCount() {
+    return getEndpointMap().size();
+  }
+  
+  public static void loadEmergencyClasses() {
+    //do nothing
+  }
+  
+  protected static class EndpointListenerBroadcaster implements EndpointManager.EndpointListener {
+  
+    private volatile Set/*<EndpointListener>*/<EndpointListener> endpointListeners = Collections.emptySet();
+    
+    public synchronized void addListener(EndpointManager.EndpointListener listener) {
+      HashSet<EndpointListener> tmpListeners = new HashSet<EndpointListener>(endpointListeners);
+      tmpListeners.add(listener);
+      endpointListeners = Collections.unmodifiableSet(tmpListeners);
+    }
+
+    public synchronized void clear() {
+      endpointListeners = Collections.emptySet();
+    }
+
+    public void removeListener(EndpointManager.EndpointListener listener) {
+      HashSet<EndpointListener> tmpListeners = new HashSet<EndpointListener>(endpointListeners);
+      tmpListeners.remove(listener);
+      endpointListeners = Collections.unmodifiableSet(tmpListeners);
+    }
+
+    public void endpointCrashed(Endpoint endpoint) {
+      for(Iterator<EndpointListener> itr = endpointListeners.iterator(); itr.hasNext(); ) {
+        EndpointManager.EndpointListener listener = itr.next();
+        listener.endpointCrashed(endpoint);
+      }
+    }
+
+    public void endpointNoLongerInUse(Endpoint endpoint) {
+      for(Iterator<EndpointListener> itr = endpointListeners.iterator(); itr.hasNext(); ) {
+        EndpointManager.EndpointListener listener = itr.next();
+        listener.endpointNoLongerInUse(endpoint);
+      }
+    }
+
+    public void endpointNowInUse(Endpoint endpoint) {
+      //logger.warn("HIGHUP:JOIN:"+endpoint.getLocation());
+      for(Iterator<EndpointListener> itr = endpointListeners.iterator(); itr.hasNext(); ) {
+        EndpointManager.EndpointListener listener = itr.next();
+        listener.endpointNowInUse(endpoint);
+      }
+    }
+  }
+  
+  
+  
+  public class EndpointListenerForBridgeMembership implements EndpointManager.EndpointListener {
+    
+    public void endpointCrashed(Endpoint endpoint) {
+      if(endpoint.getMemberId()==null || cancelCriterion.cancelInProgress()!=null) {
+        return;
+      }
+      //logger.warn("EMANFIRE:CRASH:"+endpoint.getLocation());
+      InternalBridgeMembership.notifyCrashed(endpoint.getMemberId(), false);
+    }
+
+    public void endpointNoLongerInUse(Endpoint endpoint) {
+      if(endpoint.getMemberId()==null || cancelCriterion.cancelInProgress()!=null) {
+        return;
+      }
+      //logger.warn("EMANFIRE:LEFT:"+endpoint.getLocation());
+      InternalBridgeMembership.notifyLeft(endpoint.getMemberId(), false);
+    }
+
+    public void endpointNowInUse(Endpoint endpoint) {
+      if(cancelCriterion.cancelInProgress()!=null) {
+        return;
+      }
+      //logger.warn("EMANFIRE:JOIN:"+endpoint.getLocation()+" mid:"+endpoint.getMemberId(),new Exception());
+      InternalBridgeMembership.notifyJoined(endpoint.getMemberId(), false);
+    }
+  }
+
+  public String getPoolName() {
+    return poolName;
+  }  
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecutablePool.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecutablePool.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecutablePool.java
new file mode 100644
index 0000000..1477a7e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecutablePool.java
@@ -0,0 +1,141 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+
+import com.gemstone.gemfire.cache.NoSubscriptionServersAvailableException;
+import com.gemstone.gemfire.cache.client.SubscriptionNotEnabledException;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+
+/**
+ * Provides methods to execute AbstractOp instances on a client pool.
+ * @author darrel
+ * @since 5.7
+ */
+public interface ExecutablePool {
+  /**
+   * Execute the given op on the servers that this pool connects to.
+   * This method is responsible for retrying the op if an attempt fails.
+   * It will only execute it once and on one server.
+   * @param op the operation to execute
+   * @return the result of execution if any; null if not
+   * @since 5.7
+   */
+  public Object execute(Op op);
+  
+  /**
+   * Execute the given op on the servers that this pool connects to.
+   * This method is responsible for retrying the op if an attempt fails.
+   * It will only execute it once and on one server.
+   * @param op the operation to execute
+   * @return the result of execution if any; null if not
+   * @since 5.7
+   */
+  public Object execute(Op op, int retryAttempts);
+  
+  /**
+   * Execute the given op on all the servers that have server-to-client queues
+   * for this pool The last exception from any server will be thrown if the op fails.
+   * The op is executed with the primary first, followed by the backups.
+   * 
+   * @param op
+   *                the operation to execute.
+   * @throws NoSubscriptionServersAvailableException if we have no queue server
+   * @throws SubscriptionNotEnabledException If the pool does not have queues enabled
+   */
+  public void executeOnAllQueueServers(Op op) throws NoSubscriptionServersAvailableException, SubscriptionNotEnabledException;
+  /**
+   * Execute the given op on all the servers that have server-to-client queues
+   * for this pool. The op will be executed on all backups, and then the primary.
+   * This method will block until a primary is available.
+   * 
+   * @param op
+   *                the operation to execute
+   * @return The result from the primary server.
+   * @throws NoSubscriptionServersAvailableException if we have no queue server
+   * @throws SubscriptionNotEnabledException If the pool does not have queues enabled
+   * @since 5.7
+   */
+  public Object executeOnQueuesAndReturnPrimaryResult(Op op)  throws NoSubscriptionServersAvailableException, SubscriptionNotEnabledException;
+  /**
+   * Execute the given op on the given server.
+   * @param server the server to do the execution on
+   * @param op the operation to execute
+   * @return the result of execution if any; null if not
+   */
+  public Object executeOn(ServerLocation server, Op op);
+  /**
+   * Execute the given op on the given server.
+   * @param server the server to do the execution on
+   * @param op the operation to execute
+   * @param accessed true if the connection is accessed by this execute
+   * @return the result of execution if any; null if not
+   */
+  public Object executeOn(ServerLocation server, Op op, boolean accessed,boolean onlyUseExistingCnx);
+  /**
+   * Execute the given op on the given connection.
+   * @param con the connection to do the execution on
+   * @param op the operation to execute
+   * @return the result of execution if any; null if not
+   */
+  public Object executeOn(Connection con, Op op);
+  /**
+   * Execute the given op on the given connection.
+   * @param con the connection to do the execution on
+   * @param op the operation to execute
+   * @param timeoutFatal true if a timeout exception should be treated as a fatal one
+   * @return the result of execution if any; null if not
+   */
+  public Object executeOn(Connection con, Op op, boolean timeoutFatal);
+  /**
+   * Execute the given op on the current primary server.
+   * @param op the operation to execute
+   * @return the result of execution if any; null if not
+   */
+  public Object executeOnPrimary(Op op);
+  public RegisterInterestTracker getRITracker();
+  
+  /**
+   * Release the connection held by the calling
+   * thread if we're using thread local connections
+   */
+  void releaseThreadLocalConnection();
+  
+  /**
+   * The calling thread will connect to only one server for
+   * executing all ops until it calls {@link #releaseServerAffinity()}
+   * @param allowFailover true if we want to failover to another
+   * server when the first server is unreachable. Affinity to the
+   * new server will be maintained
+   * @since 6.6
+   */
+  public void setupServerAffinity(boolean allowFailover);
+  
+  /**
+   * Release the server affinity established
+   * by {@link #setupServerAffinity(boolean)}
+   * @since 6.6
+   */
+  public void releaseServerAffinity();
+  
+  /**
+   * When server affinity is enabled by this thread, returns the server against which all ops in this thread are performed 
+   * @return location of the affinity server
+   * @since 6.6
+   * @see ExecutablePool#setupServerAffinity(boolean) 
+   */
+  public ServerLocation getServerAffinityLocation();
+  
+  /**
+   * All subsequent operations by this thread will be performed on
+   * the given ServerLocation. Used for resuming suspended transactions.
+   * @param serverLocation
+   * @since 6.6
+   */
+  public void setServerAffinityLocation(ServerLocation serverLocation);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteFunctionHelper.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteFunctionHelper.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteFunctionHelper.java
new file mode 100644
index 0000000..bced6de
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteFunctionHelper.java
@@ -0,0 +1,21 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+public class ExecuteFunctionHelper {
+
+  public final static byte BUCKETS_AS_FILTER_MASK = 0x02;
+  public final static byte IS_REXECUTE_MASK = 0x01;
+  
+  static byte createFlags(boolean executeOnBucketSet, byte isReExecute) {
+    byte flags = executeOnBucketSet ? 
+        (byte)(0x00 | BUCKETS_AS_FILTER_MASK) : 0x00;
+    flags = isReExecute == 1? (byte)(flags | IS_REXECUTE_MASK) : flags;      
+    return flags;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteFunctionNoAckOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteFunctionNoAckOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteFunctionNoAckOp.java
new file mode 100755
index 0000000..706e8c4
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteFunctionNoAckOp.java
@@ -0,0 +1,234 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.InternalGemFireError;
+import com.gemstone.gemfire.cache.execute.Function;
+import com.gemstone.gemfire.cache.execute.FunctionException;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.cache.execute.AbstractExecution;
+import com.gemstone.gemfire.internal.cache.execute.MemberMappedArgument;
+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;
+import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+
+/**
+ * Does a Execution of function on server (possibly without region/cache) 
+ * It does not get the resulf from the server (follows Fire&Forget approch)
+ * @author Suranjan Kumar
+ * @since 5.8Beta
+ */
+public class ExecuteFunctionNoAckOp {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  private ExecuteFunctionNoAckOp() {
+    // no instances allowed
+  }
+
+  /**
+   * Does a execute Function 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 function
+   *                of the function to be executed
+   * @param args
+   *                specified arguments to the application function
+   */
+  public static void execute(PoolImpl pool, Function function,
+      Object args, MemberMappedArgument memberMappedArg,
+      boolean allServers, byte hasResult, boolean isFnSerializationReqd, String[] groups) {
+    List servers = null;
+    AbstractOp op = new ExecuteFunctionNoAckOpImpl(function, args, memberMappedArg,
+        hasResult, isFnSerializationReqd, groups, allServers);
+    try {
+      // In case of allServers getCurrentServers and call
+      // executeOn(ServerLocation server, Op op)
+      if (allServers && groups.length == 0) {
+        if (logger.isDebugEnabled()) {
+          logger.debug("ExecuteFunctionNoAckOp#execute : Sending Function Execution Message:" + op.getMessage() + " to all servers using pool: " +pool);
+        }
+        servers = pool.getCurrentServers();
+        Iterator i = servers.iterator();
+        while (i.hasNext()) {          
+          pool.executeOn((ServerLocation)i.next(), op);
+        }
+      }
+      else { 
+        if (logger.isDebugEnabled()) {
+          logger.debug("ExecuteFunctionNoAckOp#execute : Sending Function Execution Message:" + op.getMessage() + " to server using pool: " + pool + " with groups:" + Arrays.toString(groups) + " all members:" + allServers);
+        }
+        pool.execute(op,0);       
+      }
+    }
+    catch (Exception ex) {
+      if (logger.isDebugEnabled()) {
+        logger.debug("ExecuteFunctionNoAckOp#execute : Exception occured while Sending Function Execution Message:" + op.getMessage() + " to server using pool: " +pool, ex);
+      }
+      if (ex.getMessage() != null)
+        throw new FunctionException(ex.getMessage(), ex);
+      else
+        throw new FunctionException(
+            "Unexpected exception during function execution:", ex);
+    }
+  }
+
+  public static void execute(PoolImpl pool, String functionId,
+      Object args, MemberMappedArgument memberMappedArg,
+      boolean allServers, byte hasResult, boolean isFnSerializationReqd, boolean isHA, boolean optimizeForWrite, String[] groups) {
+    List servers = null;
+    AbstractOp op = new ExecuteFunctionNoAckOpImpl(functionId, args, memberMappedArg,
+        hasResult, isFnSerializationReqd, isHA, optimizeForWrite, groups, allServers);
+    try {
+      // In case of allServers getCurrentServers and call
+      // executeOn(ServerLocation server, Op op)
+      if (allServers && groups.length == 0) {
+        if (logger.isDebugEnabled()) {
+          logger.debug("ExecuteFunctionNoAckOp#execute : Sending Function Execution Message:" + op.getMessage() + " to all servers using pool: " +pool);
+        }
+        servers = pool.getCurrentServers();
+        Iterator i = servers.iterator();
+        while (i.hasNext()) {          
+          pool.executeOn((ServerLocation)i.next(), op);
+        }
+      }
+      else {        
+        if (logger.isDebugEnabled()) {
+          logger.debug("ExecuteFunctionNoAckOp#execute : Sending Function Execution Message:" + op.getMessage() + " to server using pool: " + pool + " with groups:" + Arrays.toString(groups) + " all members:" + allServers);
+        }
+        pool.execute(op,0);       
+      }
+    }
+    catch (Exception ex) {
+      if (logger.isDebugEnabled()) {
+        logger.debug("ExecuteFunctionNoAckOp#execute : Exception occured while Sending Function Execution Message:" + op.getMessage() + " to server using pool: " +pool, ex);
+      }
+      if (ex.getMessage() != null)
+        throw new FunctionException(ex.getMessage(), ex);
+      else
+        throw new FunctionException(
+            "Unexpected exception during function execution:", ex);
+    }
+  }
+  
+  private static class ExecuteFunctionNoAckOpImpl extends AbstractOp {
+
+    /**
+     * number of parts in the request message
+     */
+    private static final int MSG_PARTS = 6;
+
+    /**
+     * @throws com.gemstone.gemfire.SerializationException
+     *                 if serialization fails
+     */
+    public ExecuteFunctionNoAckOpImpl(Function function, Object args,
+        MemberMappedArgument memberMappedArg, byte hasResult,
+        boolean isFnSerializationReqd, String[] groups, boolean allMembers) {
+      super(MessageType.EXECUTE_FUNCTION, MSG_PARTS);
+      byte functionState = AbstractExecution.getFunctionState(function.isHA(),
+          function.hasResult(), function.optimizeForWrite());
+      getMessage().addBytesPart(new byte[]{functionState});
+      if(isFnSerializationReqd){
+        getMessage().addStringOrObjPart(function); 
+      }
+      else{
+        getMessage().addStringOrObjPart(function.getId()); 
+      }
+      getMessage().addObjPart(args);
+      getMessage().addObjPart(memberMappedArg);
+      getMessage().addObjPart(groups);
+      getMessage().addBytesPart(ExecuteFunctionOp.getByteArrayForFlags(allMembers));
+    }
+
+    /**
+     * @param functionId
+     * @param args
+     * @param memberMappedArg
+     * @param hasResult
+     * @param isFnSerializationReqd
+     * @param isHA
+     * @param optimizeForWrite
+     */
+    public ExecuteFunctionNoAckOpImpl(String functionId, Object args,
+        MemberMappedArgument memberMappedArg, byte hasResult,
+        boolean isFnSerializationReqd, boolean isHA, boolean optimizeForWrite,
+        String[] groups, boolean allMembers) {
+      super(MessageType.EXECUTE_FUNCTION, MSG_PARTS);
+      getMessage().addBytesPart(
+          new byte[] { AbstractExecution.getFunctionState(isHA,
+              hasResult == (byte)1 ? true : false, optimizeForWrite) });
+      getMessage().addStringOrObjPart(functionId);
+      getMessage().addObjPart(args);
+      getMessage().addObjPart(memberMappedArg);
+      getMessage().addObjPart(groups);
+      getMessage().addBytesPart(ExecuteFunctionOp.getByteArrayForFlags(allMembers));
+    }
+
+    @Override  
+    protected Object processResponse(Message msg) throws Exception {
+      final int msgType = msg.getMessageType();
+      if (msgType == MessageType.REPLY) {
+        return null;
+      }
+      else {
+        Part part = msg.getPart(0);
+        if (msgType == MessageType.EXCEPTION) {
+          Throwable t = (Throwable)part.getObject();
+          logger.warn(LocalizedMessage.create(LocalizedStrings.EXECUTE_FUNCTION_NO_HAS_RESULT_RECEIVED_EXCEPTION), t);
+        }
+        else if (isErrorResponse(msgType)) {
+          logger.warn(LocalizedMessage.create(LocalizedStrings.EXECUTE_FUNCTION_NO_HAS_RESULT_RECEIVED_EXCEPTION)); // TODO:LOG:FIXED: was ", part.getString());" which makes no sense
+        }
+        else {
+          throw new InternalGemFireError("Unexpected message type "
+              + MessageType.getString(msgType));
+        }
+        return null;
+      }
+    }
+
+    @Override  
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.EXECUTE_FUNCTION_ERROR;
+    }
+
+    @Override  
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startExecuteFunction();
+    }
+
+    @Override  
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endExecuteFunctionSend(start, hasFailed());
+    }
+
+    @Override  
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endExecuteFunction(start, hasTimedOut(), hasFailed());
+    }
+
+    @Override  
+    protected Message createResponseMessage() {
+      return new Message(1, Version.CURRENT);
+    }
+  }
+
+}


[49/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-assembly/src/main/dist/bin/gfsh-completion.bash
----------------------------------------------------------------------
diff --git a/gemfire-assembly/src/main/dist/bin/gfsh-completion.bash b/gemfire-assembly/src/main/dist/bin/gfsh-completion.bash
new file mode 100755
index 0000000..6db7ef1
--- /dev/null
+++ b/gemfire-assembly/src/main/dist/bin/gfsh-completion.bash
@@ -0,0 +1,88 @@
+#!/usr/bin/env bash
+#
+# Auto completion script for GemFire's gfsh script
+#
+# Either explicitly source it into your shell enviroment, set it up in your
+# .bashrc or .bash_profile or copy it to /etc/bash_completion.d
+#
+
+_gfsh() {
+    # The main verbs gfsh understands
+    declare -r VERBS="compact describe encrypt help run start status stop validate version"
+
+    # The nouns relevant to the verbs
+    declare -r N_compact="offline-disk-store"
+    declare -r N_describe="offline-disk-store"
+    declare -r N_encrypt="password"
+    declare -r N_help="$VERBS"
+    declare -r N_start="jconsole jvisualvm locator pulse server vsd"
+    declare -r N_status="locator server"
+    declare -r N_stop="locator server"
+    declare -r N_validate="offline-disk-store"
+
+    # The options relevant to each verb-noun combination
+    declare -r OPT_compact_offline_disk_store="--name --disk-dirs --max-oplog-size --J"
+    declare -r OPT_describe_offline_disk_store="--name=value --disk-dirs --region"
+    declare -r OPT_encrypt_password="--password"
+    declare -r OPT_run="--file --quiet --continue-on-error"
+    declare -r OPT_start_jconsole="--interval --notile --pluginpath --version --J"
+    declare -r OPT_start_jvisualvm="--J"
+    declare -r OPT_start_locator="--name --bind-address --force --group \
+        --hostname-for-clients --locators --log-level --mcast-address \
+        --mcast-port --port --dir --properties-file --security-properties-file \
+        --initial-heap --max-heap --J --connect --enable-cluster-configuration \
+        --load-cluster-configuration-from-dir"
+    declare -r OPT_start_pulse="--url"
+    declare -r OPT_start_server="--name --assign-buckets --bind-address \
+        --cache-xml-file --classpath --disable-default-server \
+        --disable-exit-when-out-of-memory --enable-time-statistics --force \
+        --properties-file --security-properties-file --group \
+        --locators \
+        --log-level --mcast-address --mcast-port --name --memcached-port \
+        --memcached-protocol --rebalance --server-bind-address --server-port \
+        --spring-xml-location --statistic-archive-file --dir --initial-heap \
+        --max-heap --use-cluster-configuration --J --critical-heap-percentage \
+        --eviction-heap-percentage --hostname-for-clients --max-connections \
+        --message-time-to-live --max-message-count --max-threads --socket-buffer-size"
+    declare -r OPT_start_vsd="--file"
+    declare -r OPT_status_locator="--name --host --port --pid --dir"
+    declare -r OPT_status_server="--name --pid --dir"
+    declare -r OPT_stop_locator="--name --pid --dir"
+    declare -r OPT_stop_server="--name --pid --dir"
+    declare -r OPT_validate_offline_disk_store="--name --disk-dirs"
+    declare -r OPT_version="--full"
+
+    local cur=${COMP_WORDS[COMP_CWORD]}
+    local use="VERBS"
+
+    local verb=${COMP_WORDS[1]}
+    local noun=${COMP_WORDS[2]}
+
+    # Ignore potential options
+    noun=${noun##-*}
+
+    # Because variable names can't have dashes
+    noun=${noun//-/_}
+
+    if [[ -n "$noun" ]]; then
+        use="OPT_${verb}_${noun}"
+        if [[ -z "${!use}" ]]; then
+            use="N_$verb"
+        fi
+    elif [[ -n "$verb" ]]; then
+        # Special handling for these as they don't have associated nouns
+        if [[ "$verb" = "run" || "$verb" = "version" ]]; then
+            use="OPT_$verb"
+        else
+            use="N_$verb"
+            if [[ -z "${!use}" ]]; then
+                use="VERBS"
+            fi
+        fi
+    fi
+
+    COMPREPLY=( $( compgen -W "${!use}" -- "$cur" ) )
+}
+
+complete -F _gfsh gfsh
+    

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-assembly/src/main/dist/bin/gfsh.bat
----------------------------------------------------------------------
diff --git a/gemfire-assembly/src/main/dist/bin/gfsh.bat b/gemfire-assembly/src/main/dist/bin/gfsh.bat
new file mode 100755
index 0000000..c4a9480
--- /dev/null
+++ b/gemfire-assembly/src/main/dist/bin/gfsh.bat
@@ -0,0 +1,73 @@
+@echo off
+
+REM
+REM Environment variables:
+REM
+REM GF_JAVA - java executable path. 
+REM
+REM JAVA_ARGS - java arguments, i.e., -Xms1024m -Xmx1024m ... 
+REM
+REM GEMFIRE - GemFire product Directory
+REM
+REM
+
+@setlocal enableextensions
+@set scriptdir=%~dp0
+@set gf=%scriptdir:\bin\=%
+REM echo %gf%
+REM echo %scriptdir%
+@if exist "%gf%\lib\gemfire-core-dependencies.jar" @goto gfok
+@echo Could not determine GEMFIRE location
+@verify other 2>nul
+@goto done
+:gfok
+@set GEMFIRE=%gf%
+
+@set GEMFIRE_JARS=%GEMFIRE%\lib\gfsh-dependencies.jar
+@if defined CLASSPATH (
+@set GEMFIRE_JARS=%GEMFIRE_JARS%;%CLASSPATH%
+)
+
+@if not defined GF_JAVA (
+@REM %GF_JAVA% is not defined, assume it is on the PATH
+@if defined JAVA_HOME (
+@set GF_JAVA=%JAVA_HOME%\bin\java.exe
+) else (
+@set GF_JAVA=java
+)
+) 
+
+REM
+REM GFSH_JARS
+REM
+@set GFSH_JARS=;%GEMFIRE%\lib\gfsh-dependencies.jar
+@set CLASSPATH=%GFSH_JARS%;%GEMFIRE_JARS%
+
+REM
+REM Copy default .gfshrc to the home directory. Uncomment if needed.
+REM
+REM @if not exist "%USERPROFILE%\.gemfire\.gfsh2rc" (
+REM @xcopy /q "%GEMFIRE%\defaultConfigs\.gfsh2rc" "%USERPROFILE%\.gemfire"
+REM )
+
+REM
+REM Make dir if .gemfire does not exist. Uncomment if needed.
+REM
+REM @if not exist "%USERPROFILE%\.gemfire" (
+REM @mkdir "%USERPROFILE%\.gemfire"
+REM )
+
+REM  Consider java is from JDK
+@set TOOLS_JAR=%JAVA_HOME%\lib\tools.jar
+@IF EXIST "%TOOLS_JAR%" (
+    @set CLASSPATH=%CLASSPATH%;%TOOLS_JAR%
+) ELSE (
+    set TOOLS_JAR=
+)
+
+@set LAUNCHER=com.gemstone.gemfire.management.internal.cli.Launcher
+@if defined JAVA_ARGS (
+@set JAVA_ARGS="%JAVA_ARGS%"
+)
+@"%GF_JAVA%" -Dgfsh=true -Dlog4j.configurationFile=/com/gemstone/gemfire/internal/logging/log4j/log4j2-cli.xml %JAVA_ARGS% %LAUNCHER% %*
+:done

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/build.gradle
----------------------------------------------------------------------
diff --git a/gemfire-core/build.gradle b/gemfire-core/build.gradle
new file mode 100755
index 0000000..7639aa4
--- /dev/null
+++ b/gemfire-core/build.gradle
@@ -0,0 +1,133 @@
+sourceSets {
+  jca {
+    compileClasspath += configurations.compile
+    runtimeClasspath += configurations.runtime
+  }
+}
+
+configurations {
+  //declaring new configuration that will be used to associate with artifacts
+  archives
+}
+
+dependencies {
+  provided files("${System.getProperty('java.home')}/../lib/tools.jar")
+  compile 'antlr:antlr:2.7.7'
+  compile 'com.fasterxml.jackson.core:jackson-annotations:2.2.0'
+  compile 'com.fasterxml.jackson.core:jackson-core:2.2.0'
+  compile 'com.fasterxml.jackson.core:jackson-databind:2.2.0'
+  compile 'com.google.code.findbugs:annotations:3.0.0'
+  compile 'commons-io:commons-io:2.3'
+  compile 'commons-logging:commons-logging:1.1.1'
+  compile 'commons-modeler:commons-modeler:2.0'
+  compile 'it.unimi.dsi:fastutil:6.6.2'
+  compile 'javax.activation:activation:1.1.1'
+  compile 'javax.mail:javax.mail-api:1.4.5'
+  compile 'javax.resource:javax.resource-api:1.7'
+  compile 'javax.servlet:javax.servlet-api:3.1.0'
+  compile 'javax.transaction:javax.transaction-api:1.2'
+  compile 'mx4j:mx4j:3.0.1'
+  compile 'mx4j:mx4j-remote:3.0.1'
+  compile 'mx4j:mx4j-tools:3.0.1'
+  compile 'net.java.dev.jna:jna:4.0.0'
+  compile 'net.sourceforge.jline:jline:1.0.S2-B'
+  compile 'org.eclipse.jetty:jetty-http:9.2.3.v20140905'
+  compile 'org.eclipse.jetty:jetty-io:9.2.3.v20140905'
+  compile 'org.eclipse.jetty:jetty-security:9.2.3.v20140905'
+  compile 'org.eclipse.jetty:jetty-server:9.2.3.v20140905'
+  compile 'org.eclipse.jetty:jetty-servlet:9.2.3.v20140905'
+  compile 'org.eclipse.jetty:jetty-util:9.2.3.v20140905'
+  compile 'org.eclipse.jetty:jetty-webapp:9.2.3.v20140905'
+  compile 'org.eclipse.jetty:jetty-xml:9.2.3.v20140905'
+  compile 'org.fusesource.jansi:jansi:1.8'
+  compile 'org.apache.logging.log4j:log4j-api:2.1'
+  compile 'org.apache.logging.log4j:log4j-core:2.1'
+  compile 'org.apache.logging.log4j:log4j-slf4j-impl:2.1'
+  compile 'org.apache.logging.log4j:log4j-jcl:2.1'
+  compile 'org.slf4j:slf4j-api:1.7.7'
+  compile 'org.springframework.data:spring-data-commons:1.9.1.RELEASE'
+  compile 'org.springframework.data:spring-data-gemfire:1.5.1.RELEASE'
+  compile 'org.springframework:spring-tx:3.2.12.RELEASE'
+  compile 'org.springframework.shell:spring-shell:1.0.0.RELEASE'
+  compile 'org.xerial.snappy:snappy-java:1.1.1.6'
+
+  compile project(':gemfire-jgroups')
+  compile project(':gemfire-joptsimple')
+  compile project(':gemfire-json')
+  
+  testCompile 'org.apache.bcel:bcel:5.2'
+
+  jcaCompile sourceSets.main.output
+
+  provided project(path: ':gemfire-junit', configuration: 'testOutput')
+}
+
+// Creates the version properties file and writes it to the classes dir
+task createVersionPropertiesFile << {
+  ext.gitBranch = 'master'
+  ext.commitId = '1366ff2d4fcbf54bfad684e9ba9822db2a2b0ff5'
+  ext.sourceDate = '2015-04-06 14:54:51 -0700'
+  
+  ext.osArch = System.getProperty('os.arch')
+  ext.osName = System.getProperty('os.name')
+  ext.osVersion = System.getProperty('os.version')
+  ext.buildDate = new Date().format('yyyy-MM-dd HH:mm:ss Z')
+  ext.buildNumber = new Date().format('MMddyy')
+  ext.jdkVersion = System.getProperty('java.version')
+
+  def props = [
+    "Product-Name"      : "Pivotal GemFire",
+    "Product-Version"   : version,
+    "Build-Id"          : System.env.USER + ' ' + ext.buildNumber,
+    "Build-Date"        : ext.buildDate,
+    "Build-Platform"    : ext.osName + ' ' + ext.osVersion + ' ' + ext.osArch,
+    "Build-Java-Version": ext.jdkVersion,
+    "Source-Date"       : ext.sourceDate,
+    "Source-Revision"   : ext.commitId,
+    "Source-Repository" : ext.gitBranch
+  ] as Properties
+
+  new FileOutputStream(file("$buildDir/classes/main/com/gemstone/gemfire/internal/GemFireVersion.properties")).withStream { fos ->
+    props.store(fos, '')
+  }
+}
+
+jar {
+
+  from sourceSets.main.output
+  from sourceSets.jca.output
+  
+  exclude 'com/gemstone/gemfire/management/internal/web/**'
+  exclude 'com/gemstone/gemfire/internal/i18n/StringIdResourceBundle_ja.txt'
+  exclude 'com/gemstone/gemfire/admin/doc-files/ds4_0.dtd'
+}
+
+task webJar (type: Jar, dependsOn: classes) {
+  description 'Assembles the jar archive containing the gemfire management web classes.'
+  from sourceSets.main.output
+  baseName 'gemfire-web'
+  include 'com/gemstone/gemfire/management/internal/web/**'
+}
+
+task raJar (type: Jar, dependsOn: classes) {
+  description 'Assembles the jar archive that contains the JCA classes'
+  from sourceSets.jca.output
+  exclude 'com/gemstone/gemfire/ra/**'
+  archiveName 'ra.jar'
+}
+
+task jcaJar (type: Jar, dependsOn: raJar) {
+  description 'Assembles the jar archive that contains the JCA bundle'
+  baseName 'gemfire-jca'
+  extension 'rar'
+  metaInf { from 'src/jca/ra.xml' }
+  from raJar.archivePath
+}
+
+artifacts {
+  archives webJar, raJar, jcaJar
+}
+
+compileJava.doLast {
+    tasks.createVersionPropertiesFile.execute()
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/GFConnectionFactoryImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/GFConnectionFactoryImpl.java b/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/GFConnectionFactoryImpl.java
new file mode 100644
index 0000000..0453cf7
--- /dev/null
+++ b/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/GFConnectionFactoryImpl.java
@@ -0,0 +1,57 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.internal.ra;
+
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionManager;
+import javax.resource.spi.ManagedConnectionFactory;
+
+import com.gemstone.gemfire.ra.GFConnectionFactory;
+/**
+ * 
+ * @author asif
+ *
+ */
+public class GFConnectionFactoryImpl implements GFConnectionFactory
+{
+  final private ConnectionManager cm;
+
+  final private ManagedConnectionFactory mcf;
+
+  private Reference ref;
+
+  public GFConnectionFactoryImpl(ManagedConnectionFactory mcf) {
+    this.cm = null;
+    this.mcf = mcf;
+  }
+
+  public GFConnectionFactoryImpl(ConnectionManager cm,
+      ManagedConnectionFactory mcf) {
+    this.cm = cm;
+    this.mcf = mcf;
+  }
+
+  public GFConnectionImpl getConnection() throws ResourceException
+  {
+    return (GFConnectionImpl)cm.allocateConnection(mcf, null);
+  }
+
+  public void setReference(Reference ref)
+  {
+    this.ref = ref;
+
+  }
+
+  public Reference getReference() throws NamingException
+  {
+    return this.ref;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/GFConnectionImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/GFConnectionImpl.java b/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/GFConnectionImpl.java
new file mode 100644
index 0000000..095fe9f
--- /dev/null
+++ b/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/GFConnectionImpl.java
@@ -0,0 +1,62 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.internal.ra;
+
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.resource.ResourceException;
+
+import com.gemstone.gemfire.internal.ra.spi.JCAManagedConnection;
+import com.gemstone.gemfire.ra.GFConnection;
+
+/**
+ * 
+ * @author asif
+ *
+ */
+public class GFConnectionImpl implements GFConnection
+{
+  private JCAManagedConnection mc;
+
+  private Reference ref;
+
+  public GFConnectionImpl(JCAManagedConnection mc) {
+    this.mc = mc;
+  }
+
+  public void resetManagedConnection(JCAManagedConnection mc)
+  {
+    this.mc = mc;
+  }
+
+  public void close() throws ResourceException
+  {
+    // Check if the connection is associated with a JTA. If yes, then
+    // we should throw an exception on close being invoked.
+    if (this.mc != null) {
+      this.mc.onClose(this);
+    }
+  }
+
+  public void invalidate()
+  {
+    this.mc = null;
+  }
+
+  public void setReference(Reference ref)
+  {
+    this.ref = ref;
+
+  }
+
+  public Reference getReference() throws NamingException
+  {
+    return this.ref;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/spi/JCALocalTransaction.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/spi/JCALocalTransaction.java b/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/spi/JCALocalTransaction.java
new file mode 100644
index 0000000..1d1a61b
--- /dev/null
+++ b/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/spi/JCALocalTransaction.java
@@ -0,0 +1,227 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.internal.ra.spi;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.LocalTransaction;
+import javax.resource.spi.LocalTransactionException;
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+
+import com.gemstone.gemfire.LogWriter;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.TransactionId;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.TXStateProxy;
+
+import com.gemstone.gemfire.internal.cache.TXManagerImpl;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+/**
+ * 
+ * @author asif
+ *
+ */
+public class JCALocalTransaction implements LocalTransaction
+{
+  private volatile GemFireCacheImpl cache;
+
+  private volatile TXManagerImpl gfTxMgr;
+
+  private volatile TransactionId tid;
+
+  private static final boolean DEBUG = false;
+
+  private volatile boolean initDone = false;
+
+  JCALocalTransaction(GemFireCacheImpl cache, TXManagerImpl tm) {
+    this.cache = cache;
+    this.gfTxMgr = tm;
+    this.initDone = true;
+    // System.out.println("Asif:JCALocalTransaction:Param contrcutr for tx ="+
+    // this );
+  }
+
+  JCALocalTransaction() {
+    this.cache = null;
+    this.gfTxMgr = null;
+    this.initDone = false;
+    // System.out.println("Asif:JCALocalTransaction:Empty constructor for tx ="+
+    // this );
+  }
+
+  public void begin() throws ResourceException
+  {
+    if (DEBUG) {
+      try {
+        throw new NullPointerException("Asif:JCALocalTransaction:begin");
+      }
+      catch (NullPointerException npe) {
+        npe.printStackTrace();
+      }
+    }
+    try {
+      if (!initDone || this.cache.isClosed()) {
+        this.init();
+      }
+      // System.out.println("JCALocalTransaction:Asif: cache is ="+cache +
+      // " for tx ="+this);
+      LogWriter logger = cache.getLogger();
+      if (logger.fineEnabled()) {
+        logger.fine("JCALocalTransaction::begin:");
+      }
+      TransactionManager tm = cache.getJTATransactionManager();
+      if (this.tid != null) {
+        throw new LocalTransactionException(
+            " A transaction is already in progress");
+      }
+      if (tm != null && tm.getTransaction() != null) {
+        if (logger.fineEnabled()) {
+          logger.fine("JCAManagedConnection: JTA transaction is on");
+        }
+        // This is having a JTA transaction. Assuming ignore jta flag is true,
+        // explicitly being a gemfire transaction.
+        TXStateProxy tsp = this.gfTxMgr.getTXState();
+        if (tsp == null) {
+          this.gfTxMgr.begin();
+          tsp = this.gfTxMgr.getTXState();
+          tsp.setJCATransaction();
+          this.tid = tsp.getTransactionId();
+          if (logger.fineEnabled()) {
+            logger.fine("JCALocalTransaction:begun GFE transaction");
+          }
+        }
+        else {
+          throw new LocalTransactionException(
+              "GemFire is already associated with a transaction");
+        }
+      }
+      else {
+        if (logger.fineEnabled()) {
+          logger.fine("JCAManagedConnection: JTA Transaction does not exist.");
+        }
+      }
+    }
+    catch (SystemException e) {
+      // this.onError();
+      throw new ResourceException(e);
+    }
+    // Not to be invoked for local transactions managed by the container
+    // Iterator<ConnectionEventListener> itr = this.listeners.iterator();
+    // ConnectionEvent ce = new ConnectionEvent(this,
+    // ConnectionEvent.LOCAL_TRANSACTION_STARTED);
+    // while (itr.hasNext()) {
+    // itr.next().localTransactionStarted(ce);
+    // }
+
+  }
+
+  public void commit() throws ResourceException
+  {
+    if (DEBUG) {
+      try {
+        throw new NullPointerException("Asif:JCALocalTransaction:commit");
+      }
+      catch (NullPointerException npe) {
+        npe.printStackTrace();
+      }
+    }
+    LogWriter logger = cache.getLogger();
+    if (logger.fineEnabled()) {
+      logger.fine("JCALocalTransaction:invoked commit");
+    }
+    TXStateProxy tsp = this.gfTxMgr.getTXState();
+    if (tsp != null && this.tid != tsp.getTransactionId()) {
+      throw new IllegalStateException(
+          "Local Transaction associated with Tid = " + this.tid
+              + " attempting to commit a different transaction");
+    }
+    try {
+      this.gfTxMgr.commit();
+      this.tid = null;
+    }
+    catch (Exception e) {
+      throw new LocalTransactionException(e.toString());
+    }
+    // Iterator<ConnectionEventListener> itr = this.listeners.iterator();
+    // ConnectionEvent ce = new
+    // ConnectionEvent(this,ConnectionEvent.LOCAL_TRANSACTION_COMMITTED);
+    // while( itr.hasNext()) {
+    // itr.next().localTransactionCommitted(ce);
+    // }
+
+  }
+
+  public void rollback() throws ResourceException
+  {
+    if (DEBUG) {
+      try {
+        throw new NullPointerException("Asif:JJCALocalTransaction:rollback");
+      }
+      catch (NullPointerException npe) {
+        npe.printStackTrace();
+      }
+    }
+    TXStateProxy tsp = this.gfTxMgr.getTXState();
+    if (tsp != null && this.tid != tsp.getTransactionId()) {
+      throw new IllegalStateException(
+          "Local Transaction associated with Tid = " + this.tid
+              + " attempting to commit a different transaction");
+    }
+    LogWriter logger = cache.getLogger();
+    if (logger.fineEnabled()) {
+      logger.fine("JCALocalTransaction:invoked rollback");
+    }
+    try {
+      this.gfTxMgr.rollback();
+    }
+    catch (IllegalStateException ise) {
+      // It is possible that the GFE transaction has already been rolled back.
+      if (ise
+          .getMessage()
+          .equals(
+              LocalizedStrings.TXManagerImpl_THREAD_DOES_NOT_HAVE_AN_ACTIVE_TRANSACTION
+                  .toLocalizedString())) {
+        // /ignore;
+      }
+      else {
+        throw new ResourceException(ise);
+      }
+    }
+    catch (Exception e) {
+      throw new ResourceException(e);
+    }
+    finally {
+      this.tid = null;
+    }
+    // Iterator<ConnectionEventListener> itr = this.listeners.iterator();
+    // ConnectionEvent ce = new ConnectionEvent(this,
+    // ConnectionEvent.LOCAL_TRANSACTION_ROLLEDBACK);
+    // while (itr.hasNext()) {
+    // itr.next().localTransactionRolledback(ce);
+    // }
+
+  }
+
+  private void init() throws SystemException
+  {
+    this.cache = (GemFireCacheImpl)CacheFactory.getAnyInstance();
+    LogWriter logger = this.cache.getLogger();
+    if (logger.fineEnabled()) {
+      logger.fine("JCAManagedConnection:init. Inside init");
+    }
+    gfTxMgr = cache.getTxManager();
+    this.initDone = true;
+  }
+
+  boolean transactionInProgress()
+  {
+    return this.tid != null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/spi/JCAManagedConnection.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/spi/JCAManagedConnection.java b/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/spi/JCAManagedConnection.java
new file mode 100644
index 0000000..9b54c33
--- /dev/null
+++ b/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/spi/JCAManagedConnection.java
@@ -0,0 +1,290 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.internal.ra.spi;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.resource.NotSupportedException;
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionEvent;
+import javax.resource.spi.ConnectionEventListener;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.LocalTransaction;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionMetaData;
+import javax.security.auth.Subject;
+import javax.transaction.SystemException;
+import javax.transaction.xa.XAResource;
+
+import com.gemstone.gemfire.LogWriter;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.TXManagerImpl;
+import com.gemstone.gemfire.internal.ra.GFConnectionImpl;
+
+/**
+ * 
+ * @author asif
+ *
+ */
+public class JCAManagedConnection implements ManagedConnection
+
+{
+  private final List<ConnectionEventListener> listeners;
+
+  private volatile TXManagerImpl gfTxMgr;
+
+  // private volatile TransactionId currentTxID;
+  private volatile GemFireCacheImpl cache;
+
+  private volatile boolean initDone = false;
+
+  private volatile PrintWriter logger;
+
+  private JCAManagedConnectionFactory factory;
+
+  private volatile Set<GFConnectionImpl> connections;
+
+  private volatile JCALocalTransaction localTran;
+
+  private final static boolean DEBUG = false;
+
+  public JCAManagedConnection(JCAManagedConnectionFactory fact) {
+    this.factory = fact;
+    this.listeners = Collections
+        .<ConnectionEventListener> synchronizedList(new ArrayList<ConnectionEventListener>());
+    this.localTran = new JCALocalTransaction();
+    this.connections = Collections
+        .<GFConnectionImpl> synchronizedSet(new HashSet<GFConnectionImpl>());
+  }
+
+  public void addConnectionEventListener(ConnectionEventListener listener)
+  {
+    this.listeners.add(listener);
+
+  }
+
+  public void associateConnection(Object conn) throws ResourceException
+  {
+    if (!(conn instanceof GFConnectionImpl)) {
+      throw new ResourceException("Connection is not of type GFConnection");
+    }
+
+    ((GFConnectionImpl)conn).resetManagedConnection(this);
+    this.connections.add((GFConnectionImpl)conn);
+  }
+
+  public void cleanup() throws ResourceException
+  {
+    if (DEBUG) {
+      try {
+        throw new NullPointerException("Asif:JCAManagedConnection:cleanup");
+      }
+      catch (NullPointerException npe) {
+        npe.printStackTrace();
+      }
+    }
+    synchronized (this.connections) {
+      Iterator<GFConnectionImpl> connsItr = this.connections.iterator();
+      while (connsItr.hasNext()) {
+        GFConnectionImpl conn = connsItr.next();
+        conn.invalidate();
+        connsItr.remove();
+      }
+    }
+    if (this.localTran == null || this.localTran.transactionInProgress()) {
+      if (this.initDone && !this.cache.isClosed()) {
+        this.localTran = new JCALocalTransaction(cache, gfTxMgr);
+      }
+      else {
+        this.localTran = new JCALocalTransaction();
+      }
+    }
+
+  }
+
+  public void destroy() throws ResourceException
+  {
+    if (DEBUG) {
+      try {
+        throw new NullPointerException("Asif:JCAManagedConnection:destroy");
+      }
+      catch (NullPointerException npe) {
+        npe.printStackTrace();
+      }
+    }
+    synchronized (this.connections) {
+      Iterator<GFConnectionImpl> connsItr = this.connections.iterator();
+      while (connsItr.hasNext()) {
+        GFConnectionImpl conn = connsItr.next();
+        conn.invalidate();
+        connsItr.remove();
+      }
+    }
+    this.gfTxMgr = null;
+    this.cache = null;
+    this.localTran = null;
+    this.listeners.clear();
+  }
+
+  public Object getConnection(Subject arg0, ConnectionRequestInfo arg1)
+      throws ResourceException
+  {
+    if (DEBUG) {
+      try {
+        throw new NullPointerException(
+            "Asif:JCAManagedConnection:getConnection");
+      }
+      catch (NullPointerException npe) {
+        npe.printStackTrace();
+      }
+    }
+    try {
+      if (!this.initDone || this.cache.isClosed()) {
+        init();
+      }
+      LogWriter logger = this.cache.getLogger();
+      if (logger.fineEnabled()) {
+        logger
+            .fine("JCAManagedConnection:getConnection. Returning new Connection");
+      }
+
+      GFConnectionImpl conn = new GFConnectionImpl(this);
+      this.connections.add(conn);
+      return conn;
+    }
+    catch (SystemException e) {
+      this.onError(e);
+      throw new ResourceException("GemFire Resource unavailable", e);
+    }
+  }
+
+  private void init() throws SystemException
+  {
+    this.cache = (GemFireCacheImpl)CacheFactory.getAnyInstance();
+    LogWriter logger = this.cache.getLogger();
+    if (logger.fineEnabled()) {
+      logger.fine("JCAManagedConnection:init. Inside init");
+    }
+    gfTxMgr = cache.getTxManager();
+    this.initDone = true;
+  }
+
+  public LocalTransaction getLocalTransaction() throws ResourceException
+  {
+    if (DEBUG) {
+      try {
+        throw new NullPointerException(
+            "Asif:JCAManagedConnection:getLocalTransaction");
+      }
+      catch (NullPointerException npe) {
+        npe.printStackTrace();
+      }
+    }
+
+    return this.localTran;
+  }
+
+  public PrintWriter getLogWriter() throws ResourceException
+  {
+    return this.logger;
+  }
+
+  public ManagedConnectionMetaData getMetaData() throws ResourceException
+  {
+    if (DEBUG) {
+      try {
+        throw new NullPointerException("Asif:JCAManagedConnection:getMetaData");
+      }
+      catch (NullPointerException npe) {
+        npe.printStackTrace();
+      }
+    }
+    if (this.initDone && !this.cache.isClosed()) {
+      LogWriter logger = this.cache.getLogger();
+      if (logger.fineEnabled()) {
+        logger.fine("JCAManagedConnection:getMetaData");
+      }
+    }
+    return new JCAManagedConnectionMetaData(this.factory.getProductName(),
+        this.factory.getVersion(), this.factory.getUserName());
+  }
+
+  public XAResource getXAResource() throws ResourceException
+  {
+    throw new NotSupportedException("XA Transaction not supported");
+  }
+
+  public void removeConnectionEventListener(ConnectionEventListener arg0)
+  {
+    this.listeners.remove(arg0);
+
+  }
+
+  public void setLogWriter(PrintWriter logger) throws ResourceException
+  {
+    this.logger = logger;
+  }
+
+  private void onError(Exception e)
+  {
+
+    this.localTran = null;
+
+    synchronized (this.connections) {
+      Iterator<GFConnectionImpl> connsItr = this.connections.iterator();
+      while (connsItr.hasNext()) {
+        GFConnectionImpl conn = connsItr.next();
+        conn.invalidate();
+        synchronized (this.listeners) {
+          Iterator<ConnectionEventListener> itr = this.listeners.iterator();
+          ConnectionEvent ce = new ConnectionEvent(this,
+              ConnectionEvent.CONNECTION_ERROR_OCCURRED, e);
+          ce.setConnectionHandle(conn);
+          while (itr.hasNext()) {
+            itr.next().connectionErrorOccurred(ce);
+          }
+        }
+        connsItr.remove();
+      }
+    }
+
+  }
+
+  public void onClose(GFConnectionImpl conn) throws ResourceException
+  {
+    conn.invalidate();
+    this.connections.remove(conn);
+    synchronized (this.listeners) {
+      Iterator<ConnectionEventListener> itr = this.listeners.iterator();
+      ConnectionEvent ce = new ConnectionEvent(this,
+          ConnectionEvent.CONNECTION_CLOSED);
+      ce.setConnectionHandle(conn);
+      while (itr.hasNext()) {
+        itr.next().connectionClosed(ce);
+      }
+    }
+    if (this.connections.isEmpty()) {
+      // safe to dissociate this managedconnection so that it can go to pool
+      if (this.initDone && !this.cache.isClosed()) {
+        this.localTran = new JCALocalTransaction(this.cache, this.gfTxMgr);
+      }
+      else {
+        this.localTran = new JCALocalTransaction();
+      }
+    }
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/spi/JCAManagedConnectionFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/spi/JCAManagedConnectionFactory.java b/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/spi/JCAManagedConnectionFactory.java
new file mode 100644
index 0000000..8f6784d
--- /dev/null
+++ b/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/spi/JCAManagedConnectionFactory.java
@@ -0,0 +1,136 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.internal.ra.spi;
+
+import java.io.PrintWriter;
+import java.util.Set;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionManager;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.security.auth.Subject;
+
+import com.gemstone.gemfire.internal.ra.GFConnectionFactoryImpl;
+/**
+ * 
+ * @author asif
+ *
+ */
+public class JCAManagedConnectionFactory implements ManagedConnectionFactory
+{
+  private String productName;
+
+  private String version;
+
+  private String user;
+
+  private PrintWriter logger;
+
+  public Object createConnectionFactory() throws ResourceException
+  {
+
+    return new GFConnectionFactoryImpl(this);
+  }
+
+  public Object createConnectionFactory(ConnectionManager cm)
+      throws ResourceException
+  {
+
+    return new GFConnectionFactoryImpl(cm, this);
+  }
+
+  public ManagedConnection createManagedConnection(Subject arg0,
+      ConnectionRequestInfo arg1) throws ResourceException
+  {
+    return new JCAManagedConnection(this);
+
+  }
+
+  public PrintWriter getLogWriter() throws ResourceException
+  {
+
+    return this.logger;
+  }
+
+  public ManagedConnection matchManagedConnections(Set arg0, Subject arg1,
+      ConnectionRequestInfo arg2) throws ResourceException
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  public void setLogWriter(PrintWriter logger) throws ResourceException
+  {
+    this.logger = logger;
+
+  }
+
+  public boolean equals(Object obj)
+  {
+    if (obj instanceof JCAManagedConnectionFactory) {
+      return true;
+    }
+    else {
+      return false;
+    }
+  }
+
+  public int hashCode()
+  {
+    return 0;
+  }
+
+  public void setUserName(String user)
+  {
+
+    if (this.logger != null) {
+      logger.println("JCAManagedConnectionFactory::setUserName:. user name is="
+          + user);
+    }
+    this.user = user;
+  }
+
+  public String getUserName()
+  {
+    return this.user;
+  }
+
+  public void setProductName(String name)
+  {
+
+    if (this.logger != null) {
+      logger
+          .println("JCAManagedConnectionFactory::setProductName:. Product name is="
+              + name);
+    }
+    this.productName = name;
+  }
+
+  public String getProductName()
+  {
+    return this.productName;
+  }
+
+  public void setVersion(String version)
+  {
+
+    if (this.logger != null) {
+      logger.println("JCAManagedConnectionFactory::setVersion:. version is="
+          + version);
+    }
+    this.version = version;
+  }
+
+  public String getVersion()
+  {
+    return this.version;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/spi/JCAManagedConnectionMetaData.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/spi/JCAManagedConnectionMetaData.java b/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/spi/JCAManagedConnectionMetaData.java
new file mode 100644
index 0000000..dec4729
--- /dev/null
+++ b/gemfire-core/src/jca/java/com/gemstone/gemfire/internal/ra/spi/JCAManagedConnectionMetaData.java
@@ -0,0 +1,58 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.internal.ra.spi;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ManagedConnectionMetaData;
+/**
+ * 
+ * @author asif
+ *
+ */
+public class JCAManagedConnectionMetaData implements ManagedConnectionMetaData
+{
+  private final String prodName;
+
+  private final String version;
+
+  private final String user;
+
+  public JCAManagedConnectionMetaData(String prodName, String version,
+      String user) {
+    this.prodName = prodName;
+    this.version = version;
+    this.user = user;
+  }
+
+  
+  public String getEISProductName() throws ResourceException
+  {
+    return this.prodName;
+  }
+
+  
+  public String getEISProductVersion() throws ResourceException
+  {
+
+    return this.version;
+  }
+
+  
+  public int getMaxConnections() throws ResourceException
+  {
+
+    return 0;
+  }
+
+  
+  public String getUserName() throws ResourceException
+  {
+    return this.user;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/jca/ra.xml
----------------------------------------------------------------------
diff --git a/gemfire-core/src/jca/ra.xml b/gemfire-core/src/jca/ra.xml
new file mode 100644
index 0000000..85c90b8
--- /dev/null
+++ b/gemfire-core/src/jca/ra.xml
@@ -0,0 +1,37 @@
+
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE connector PUBLIC '-//Sun Microsystems, Inc.//DTD Connector 1.0//EN' 'http://java.sun.com/j2ee/dtds/connector_1_0.dtd'>
+
+<connector>
+    <display-name>GFE JCA Adaptor</display-name>
+    <vendor-name>Pivotal Software</vendor-name>
+    <spec-version>1.5</spec-version>
+    <eis-type>GFE JCA</eis-type>
+    <version>1.5</version>
+    <resourceadapter>
+        <managedconnectionfactory-class>com.gemstone.gemfire.internal.ra.spi.JCAManagedConnectionFactory</managedconnectionfactory-class>
+                <config-property>
+                    <config-property-name>ProductName</config-property-name>
+                    <config-property-type>java.lang.String</config-property-type>
+                    <config-property-value>GemFire</config-property-value>
+                </config-property>
+                <config-property>
+                    <config-property-name>UserName</config-property-name>
+                    <config-property-type>java.lang.String</config-property-type>
+                    <config-property-value/>
+                </config-property>
+                <config-property>
+                    <config-property-name>Version</config-property-name>
+                    <config-property-type>java.lang.String</config-property-type>
+                    <config-property-value>8.0</config-property-value>
+                </config-property>
+        
+        <connectionfactory-interface>com.gemstone.gemfire.ra.GFConnectionFactory</connectionfactory-interface>
+        <connectionfactory-impl-class>com.gemstone.gemfire.internal.ra.GFConnectionFactoryImpl</connectionfactory-impl-class>
+        <connection-interface>com.gemstone.gemfire.ra.GFConnection</connection-interface>
+        <connection-impl-class>com.gemstone.gemfire.internal.ra.GFConnectionImpl</connection-impl-class>
+        <transaction-support>LocalTransaction</transaction-support>
+        <reauthentication-support>false</reauthentication-support> 
+    </resourceadapter>
+</connector>

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/CancelCriterion.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/CancelCriterion.java b/gemfire-core/src/main/java/com/gemstone/gemfire/CancelCriterion.java
new file mode 100644
index 0000000..fedbd49
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/CancelCriterion.java
@@ -0,0 +1,100 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+/**
+ * Abstract cancellation proxy for cancelling an operation, esp. a thread.
+ * 
+ * Creators of services or threads should implement a subclass of CancelCriterion,
+ * and implement the two methods - cancelInProgress, and generateCancelledException(e).
+ * 
+ * Code inside the service can check to see if the service is cancelled by calling
+ * {@link #checkCancelInProgress(Throwable)}. Generally the pattern is to check
+ * before performing an operation, check if the service is canceled before propgrating 
+ * an exception futher up the stack, and check for cancelation inside a long loop.
+ * Eg.
+ * 
+ * <code>
+ * while(true) {
+ *   c.checkCancelInProgress(null);
+ *   try {
+ *      dispatchEvents();
+ *   } catch(IOException e) {
+ *     c.checkCancelInProgress(e);
+ *     throw e;
+ *   }
+ * }
+ * </code>
+ * 
+ * @author jpenney
+ * @see CancelException
+ * @since 5.1
+ */
+public abstract class CancelCriterion
+{
+  /**
+   * Indicate if the service is in the progress of being cancelled.  The
+   * typical use of this is to indicate, in the case of an {@link InterruptedException},
+   * that the current operation should be cancelled.
+   * @return null if the service is not shutting down, or a message that can be used to
+   * construct an exception indicating the service is shut down.
+   */
+  public abstract String cancelInProgress();
+//import com.gemstone.gemfire.distributed.internal.DistributionManager;
+//    * <p>
+//    * In particular, a {@link DistributionManager} returns a non-null result if
+//    * message distribution has been terminated.
+  
+  /**
+   * Use this utility  function in your implementation of cancelInProgress()
+   * and cancelled() to indicate a system failure
+   * 
+   * @return failure string if system failure has occurred
+   */
+  protected final String checkFailure() {
+    Throwable tilt = SystemFailure.getFailure();
+    if (tilt != null) {
+      // Allocate no objects here!
+      return SystemFailure.JVM_CORRUPTION;
+    }
+    return null;
+  }
+
+  /**
+   * See if the current operation is being cancelled.  If so, it either
+   * throws a {@link RuntimeException} (usually a {@link CancelException}).
+   * 
+   * @param e an underlying exception or null if there is no exception 
+   * that triggered this check
+   * @see #cancelInProgress()
+   */
+  public final void checkCancelInProgress(Throwable e) {
+    SystemFailure.checkFailure();
+    String reason = cancelInProgress();
+    if (reason == null) {
+      return;
+    }
+    throw generateCancelledException(e);
+  }
+
+  /**
+   * Template factory method for generating the exception to be thrown by
+   * {@link #checkCancelInProgress(Throwable)}. Override this to specify
+   * different exception for checkCancelInProgress() to throw.
+   * 
+   * This method should wrap the exception in a service specific 
+   * CancelationException (eg CacheClosedException). 
+   * or return null if the service is not being canceled.
+   * 
+   * @param e
+   *          an underlying exception, if any
+   * @return RuntimeException to be thrown by checkCancelInProgress(), null if
+   *         the receiver has not been cancelled.
+   */
+  abstract public RuntimeException generateCancelledException(Throwable e);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/CancelException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/CancelException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/CancelException.java
new file mode 100644
index 0000000..5148825
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/CancelException.java
@@ -0,0 +1,55 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+/**
+ * 
+ */
+package com.gemstone.gemfire;
+
+import com.gemstone.gemfire.cache.CacheRuntimeException;
+
+/**
+ * Abstract root class of all GemFire exceptions representing system
+ * cancellation
+ * 
+ * @author jpenney
+ * @since 6.0
+ */
+public abstract class CancelException extends CacheRuntimeException {
+
+  /**
+   * for serialization
+   */
+  public CancelException() {
+  }
+
+  /**
+   * Create instance with given message
+   * @param message the message
+   */
+  public CancelException(String message) {
+    super(message);
+  }
+
+  /**
+   * Create instance with given message and cause
+   * @param message the message
+   * @param cause the cause
+   */
+  public CancelException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Create instance with empty message and given cause
+   * @param cause the cause
+   */
+  public CancelException(Throwable cause) {
+    super(cause);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/CanonicalInstantiator.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/CanonicalInstantiator.java b/gemfire-core/src/main/java/com/gemstone/gemfire/CanonicalInstantiator.java
new file mode 100644
index 0000000..4c5568b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/CanonicalInstantiator.java
@@ -0,0 +1,77 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+import java.io.*;
+
+/**
+ * <code>CanonicalInstantiator</code> is much like its parent
+ * <code>Instantiator</code> except that instead of
+ * needing to implement <code>newInstance()</code>
+ * you now must implement <code>newInstance(DataInput)</code>.
+ * The addition of the <code>DataInput</code> parameter allows the instance
+ * creator to optionally read data from the data input stream and use it to
+ * decide the instance to create. This allows a value that represents a
+ * canonical instance to be written by a class's {@link DataSerializer#toData}
+ * and then be read by <code>newInstance(DataInput)</code>
+ * and map it back to a canonical instance.
+ * <p>
+ * Note that {@link DataSerializer#fromData} is always called on the instance
+ * returned from <code>newInstance(DataInput)</code>.
+ *
+ * @author darrel
+ * @since 5.1
+ */
+public abstract class CanonicalInstantiator extends Instantiator {
+  /**
+   * Creates a new <code>CanonicalInstantiator</code> that instantiates a given
+   * class.
+   *
+   * @param c
+   *        The <code>DataSerializable</code> class to register.  This
+   *        class must have a static initializer that registers this
+   *        <code>Instantiator</code>. 
+   * @param classId
+   *        A unique id for class <code>c</code>.  The
+   *        <code>classId</code> must not be zero.
+   *        This has been an <code>int</code> since dsPhase1.
+   *
+   * @throws IllegalArgumentException
+   *         If <code>c</code> does not implement
+   *         <code>DataSerializable</code>, <code>classId</code> is
+   *         less than or equal to zero.
+   * @throws NullPointerException
+   *         If <code>c</code> is <code>null</code>
+   */
+  public CanonicalInstantiator(Class<? extends DataSerializable> c, int classId) {
+    super(c, classId);
+  }
+  
+  /**
+   * This method is not supported and if called will
+   * throw UnsupportedOperationException.
+   * Use {@link #newInstance(DataInput)} instead.
+   * 
+   * @throws UnsupportedOperationException in all cases
+   */
+  @Override
+  public final DataSerializable newInstance() {
+    throw new UnsupportedOperationException();
+  }
+  /**
+   * Creates a new "empty" instance of a <Code>DataSerializable</code>
+   * class whose state will be filled in by invoking its 
+   * {@link DataSerializable#fromData fromData} method.
+   * @param in the data input that can be read to decide what instance to create.
+   * @return the new "empty" instance.
+   * @throws IOException if a read from <code>in</code> fails.
+   * @since 5.1
+   */
+  public abstract DataSerializable newInstance(DataInput in)
+    throws IOException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/CopyException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/CopyException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/CopyException.java
new file mode 100644
index 0000000..3a28298
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/CopyException.java
@@ -0,0 +1,58 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire;
+
+/**
+ * Indicates a failure to copy an object.
+ *
+ * @author Darrel Schneider
+ *
+ *
+ * @see CopyHelper#copy
+ * @since 4.0
+ */
+public class CopyException extends GemFireException {
+private static final long serialVersionUID = -1143711608610323585L;
+  
+  /**
+   * Constructs a new <code>CopyException</code>.
+   */
+  public CopyException() {
+    super();
+  }
+  
+  /**
+   * Constructs a new <code>CopyException</code> with a message string.
+   *
+   * @param msg a message string
+   */
+  public CopyException(String msg) {
+    super(msg);
+  }
+  
+  /**
+   * Constructs a new <code>CopyException</code> with a message string
+   * and a cause.
+   *
+   * @param msg the message string
+   * @param cause a causal Throwable
+   */
+  public CopyException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+  
+  /**
+   * Constructs a new <code>CopyException</code> with a cause.
+   *
+   * @param cause a causal Throwable
+   */
+  public CopyException(Throwable cause) {
+    super(cause);
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/CopyHelper.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/CopyHelper.java b/gemfire-core/src/main/java/com/gemstone/gemfire/CopyHelper.java
new file mode 100644
index 0000000..cd21c4c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/CopyHelper.java
@@ -0,0 +1,259 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.UUID;
+
+import com.gemstone.gemfire.internal.HeapDataOutputStream;
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.cache.CachedDeserializable;
+import com.gemstone.gemfire.internal.cache.Token;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.pdx.PdxInstance;
+import com.gemstone.gemfire.pdx.WritablePdxInstance;
+import com.gemstone.gemfire.pdx.internal.PdxUnreadData;
+
+/**
+ * A static helper for optimally creating copies.  Creating copies
+ * of cache values provides improved concurrency as well as isolation.
+ * For transactions, creating a copy is the guaranteed way to enforce
+ * "Read Committed" isolation on changes to cache
+ * <code>Entries</code>.
+
+ * <p>Here is a simple example of how to use <code>CopyHelper.copy</code>
+ *  <pre>
+ *    Object o = r.get("stringBuf");
+ *    StringBuffer s = (StringBuffer) CopyHelper.copy(o);
+ *    s.append("... and they lived happily ever after.  The End.");
+ *    r.put("stringBuf", s);
+ *  </pre>
+ *
+ * @see Cloneable
+ * @see Serializable
+ * @see DataSerializer
+ * @see com.gemstone.gemfire.cache.Cache#setCopyOnRead
+ * @see com.gemstone.gemfire.cache.CacheTransactionManager
+ *
+ * @author Mitch Thomas
+ * @since 4.0
+ */
+
+public final class CopyHelper {
+
+  // no instances allowed
+  private CopyHelper() {
+  }
+
+  /**
+   * Return true if the given object is an instance of a well known
+   * immutable class.
+   * The well known classes are:
+   * <ul>
+   * <li>String
+   * <li>Byte
+   * <li>Character
+   * <li>Short
+   * <li>Integer
+   * <li>Long
+   * <li>Float
+   * <li>Double
+   * <li>BigInteger
+   * <li>BigDecimal
+   * <li>UUID
+   * <li>PdxInstance but not WritablePdxInstance
+   * </ul>
+   * @param o the object to check
+   * @return true if o is an instance of a well known immutable class.
+   * @since 6.6.2
+   */
+  public static boolean isWellKnownImmutableInstance(Object o) {
+    if (o instanceof String) {
+      return true;
+    }
+    if (o instanceof Number) {
+      if (o instanceof Integer) return true;
+      if (o instanceof Long) return true;
+      if (o instanceof Byte) return true;
+      if (o instanceof Short) return true;
+      if (o instanceof Float) return true;
+      if (o instanceof Double) return true;
+      // subclasses of non-final classes may be mutable
+      if (o.getClass().equals(BigInteger.class)) return true;
+      if (o.getClass().equals(BigDecimal.class)) return true;
+    }
+    if (o instanceof PdxInstance && !(o instanceof WritablePdxInstance)) {
+      // no need to copy since it is immutable
+      return true;
+    }
+    if (o instanceof Character) return true;
+    if (o instanceof UUID) return true;
+    return false;
+  }
+  /**
+   * <p>Makes a copy of the specified object. The object returned is not guaranteed
+   * to be a deep copy of the original object, as explained below.
+   * 
+   * <p>Copies can only be made if the original is a <tt>Cloneable</tt> or serializable by 
+   * GemFire.
+   * If o is a {@link #isWellKnownImmutableInstance(Object) well known immutable instance}
+   * then it will be returned without copying it.
+   * 
+   * <p>If the argument o is an instance of {@link java.lang.Cloneable}, a copy is
+   * made by invoking <tt>clone</tt> on it. Note that not all implementations of <tt>clone</tt> 
+   * make deep copies (e.g. {@link java.util.HashMap#clone HashMap.clone}). Otherwise, if the
+   * argument is not an instance of <tt>Cloneable</tt>, a copy is made using serialization: if 
+   * GemFire serialization is implemented, it is used; otherwise, java serialization is used.
+   * 
+   * <p> The difference between this method and {@link #deepCopy(Object) deepCopy}, is that
+   * this method uses <tt>clone</tt> if available, whereas <tt>deepCopy</tt> does not. As a
+   * result, for <tt>Cloneable</tt> objects copied using this method, how deep a copy the 
+   * returned object is depends on its implementation of <tt>clone</tt>. 
+   * 
+   * @param o the original object that a copy is needed of
+   * @return the new instance that is a copy of of the original
+   * @throws CopyException if copying fails because a class could not
+   * be found or could not be serialized.
+   * @see #deepCopy(Object)
+   * @since 4.0
+   */
+  @SuppressWarnings("unchecked")
+  public static <T> T copy(T o) {
+    T copy = null;
+    try {
+      if (o == null) {
+        return null;
+      } else if (o instanceof Token) {
+        return o;
+      } else {
+        if (isWellKnownImmutableInstance(o)) return o;
+        if (o instanceof Cloneable) {
+          try {
+            // Note that Object.clone is protected so we need to use reflection
+            // to call clone even though this guy implements Cloneable
+            Class<?> c = o.getClass();
+            // By convention, the user should make the clone method public.
+            // But even if they don't, let's go ahead and use it.
+            // The other problem is that if the class is private, we still
+            // need to make the method accessible even if the method is public,
+            // because Object.clone is protected.
+            Method m = c.getDeclaredMethod("clone", new Class[0]);
+            m.setAccessible(true);
+            copy = (T)m.invoke(o, new Object[0]);
+            return copy;
+          } catch (NoSuchMethodException ignore) {
+            // try using Serialization
+          } catch (IllegalAccessException ignore) {
+            // try using Serialization
+          } catch (SecurityException ignore) {
+            // try using Serialization
+          } catch (InvocationTargetException ex) {
+            Throwable cause = ex.getTargetException();
+            if (cause instanceof CloneNotSupportedException) {
+              // try using Serialization
+            } else {
+              throw new CopyException(LocalizedStrings.CopyHelper_CLONE_FAILED.toLocalizedString(), cause != null ? cause : ex);
+            }
+          }
+        } else if (o instanceof CachedDeserializable) {
+          copy = (T) ((CachedDeserializable) o).getDeserializedWritableCopy(null, null);
+          return copy;
+        } else if (o.getClass().isArray() && o.getClass().getComponentType().isPrimitive()) {
+          if (o instanceof byte[]) {
+            byte[] a = (byte[])o;
+            copy = (T) Arrays.copyOf(a, a.length);
+          } else if (o instanceof boolean[]) {
+            boolean[] a = (boolean[])o;
+            copy = (T) Arrays.copyOf(a, a.length);
+          } else if (o instanceof char[]) {
+            char[] a = (char[])o;
+            copy = (T) Arrays.copyOf(a, a.length);
+          } else if (o instanceof int[]) {
+            int[] a = (int[])o;
+            copy = (T) Arrays.copyOf(a, a.length);
+          } else if (o instanceof long[]) {
+            long[] a = (long[])o;
+            copy = (T) Arrays.copyOf(a, a.length);
+          } else if (o instanceof short[]) {
+            short[] a = (short[])o;
+            copy = (T) Arrays.copyOf(a, a.length);
+          } else if (o instanceof float[]) {
+            float[] a = (float[])o;
+            copy = (T) Arrays.copyOf(a, a.length);
+          } else if (o instanceof double[]) {
+            double[] a = (double[])o;
+            copy = (T) Arrays.copyOf(a, a.length);
+          }
+          return copy;
+        }
+        // Copy using serialization
+        copy = doDeepCopy(o);
+        return copy;
+      }
+    } finally {
+      if (copy != null) {
+        PdxUnreadData.copy(o, copy);
+      }
+    }
+  }
+
+  /**
+   * Makes a deep copy of the specified object o using serialization, so the object
+   * has to be serializable by GemFire. 
+   * 
+   * <p>If o is a {@link #isWellKnownImmutableInstance(Object) well known immutable 
+   * instance} then it will be returned without copying it.
+   * 
+   * <p>The passed in object is serialized in memory, and then deserialized into 
+   * a new instance, which is returned. If GemFire serialization is implemented 
+   * for the object, it is used; otherwise, java serialization is used.  
+   * 
+   * @param o the original object to be copied
+   * @return the new instance that is a copy of the original
+   * @throws CopyException if copying fails because a class could not
+   * be found or could not be serialized
+   * @see #copy(Object)
+   */
+  public static <T> T deepCopy(T o) {
+    T copy = null;
+    try {
+      if (o == null) {
+        return null;
+      } else if (o instanceof Token || isWellKnownImmutableInstance(o)) {
+        return o;
+      } else {
+        copy = doDeepCopy(o);
+        return copy;
+      }
+    } finally {
+      if (copy != null) {
+        PdxUnreadData.copy(o, copy);
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  private static<T> T doDeepCopy(T o) {
+    try {
+      HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
+      DataSerializer.writeObject(o, hdos);
+      return (T)DataSerializer.readObject(new DataInputStream(hdos.getInputStream()));
+    } catch (ClassNotFoundException ex) {
+      throw new CopyException(LocalizedStrings.CopyHelper_COPY_FAILED_ON_INSTANCE_OF_0.toLocalizedString(o.getClass()), ex);
+    } catch (IOException ex) {
+      throw new CopyException(LocalizedStrings.CopyHelper_COPY_FAILED_ON_INSTANCE_OF_0.toLocalizedString(o.getClass()), ex);
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/DataSerializable.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/DataSerializable.java b/gemfire-core/src/main/java/com/gemstone/gemfire/DataSerializable.java
new file mode 100644
index 0000000..034b8ff
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/DataSerializable.java
@@ -0,0 +1,131 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+import java.io.*;
+
+/**
+ * An interface for objects whose state can be written/read as
+ * primitive types and strings ("data").  That is, instead of
+ * serializing itself to an {@link java.io.ObjectOutputStream}, a
+ * <code>DataSerializable</code> can serialize itself to a {@link
+ * DataOutput}.  By implementing this interface, objects can be
+ * serialized faster and in a more compact format than standard Java
+ * serialization.  The {@link DataSerializer} class contains a number
+ * of static methods that may be helpful to implementations of
+ * <code>DataSerializable</code>.
+ *
+ * <P>
+ *
+ * When possible, GemFire respects the <code>DataSerializable</code>
+ * contract to provide optimal object serialization.  For instance, if
+ * a <code>DataSerializable</code> object is 
+ * {@linkplain com.gemstone.gemfire.cache.Region#put(Object, Object) placed} into a distributed
+ * cache region, its <code>toData</code> method will be used to
+ * serialize it when it is sent to another member of the distributed
+ * system.
+ *
+ * <P>
+ *
+ * To avoid the overhead of Java reflection,
+ * <code>DataSerializable</code> classes may register an {@link
+ * Instantiator} to be used during deserialization.  Alternatively,
+ * classes that implement <code>DataSerializable</code> can provide a
+ * zero-argument constructor that will be invoked when they are read
+ * with {@link DataSerializer#readObject}.
+ *
+ * <P>
+ *
+ * Some classes (especially third-party classes that you may not have
+ * the source code to) cannot be modified to implement
+ * <code>DataSerializable</code>.  These classes can be data
+ * serialized by an instance of {@link DataSerializer}.
+ *
+ * <P>
+ *
+ * <code>DataSerializable</code> offers improved performance over
+ * standard Java serialization, but does not offer all of the features
+ * of standard Java serialization.  In particular, data serialization
+ * does not attempt to maintain referential integrity among the
+ * objects it is writing or reading.  As a result, data serialization
+ * should not be used with complex object graphs.  Attempting to data
+ * serialize graphs that contain object cycles will result in infinite
+ * recursion and a {@link StackOverflowError}.  Attempting to
+ * deserialize an object graph that contains multiple reference
+ * paths to the same object will result in multiple copies of the
+ * objects that are referred to through multiple paths.
+ *
+ * <P>
+ *
+ * <CENTER>
+ * <IMG src="doc-files/data-serialization-exceptions.gif" 
+ *      HEIGHT="219" WIDTH="698">
+ * </CENTER>
+ *
+ * @see java.io.Serializable
+ * @see DataSerializer
+ * @see Instantiator
+ *
+ * @author David Whitlock
+ * @since 3.5 */
+public interface DataSerializable extends Serializable {
+
+  /**
+   * Writes the state of this object as primitive data to the given
+   * <code>DataOutput</code>.
+   * <p>
+   * Since 5.7 it is possible for any method call to the specified
+   * <code>DataOutput</code> to throw {@link GemFireRethrowable}.
+   * It should <em>not</em> be caught by user code.
+   * If it is it <em>must</em> be rethrown.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   */
+  public void toData(DataOutput out) throws IOException;
+
+  /**
+   * Reads the state of this object as primitive data from the given
+   * <code>DataInput</code>. 
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         A class could not be loaded while reading from
+   *         <code>in</code> 
+   */
+  public void fromData(DataInput in)
+    throws IOException, ClassNotFoundException;
+
+  ////////////////////////  Inner Classes  ////////////////////////
+
+  /**
+   * <code>Replaceable</code> allows an object to write an alternative
+   * version of itself to a <code>DataOutput</code>.  It is similar to
+   * the <code>writeReplace</code> method of standard Java
+   * {@linkplain java.io.Serializable serialization}.  
+   *
+   * <P>
+   *
+   * Note that if a <code>Replaceable</code> is also
+   * <code>DataSerializable</code>, its <code>toData</code> method
+   * will <B>not</B> be invoked.  Instead, its replacement object will
+   * be written to the stream using {@link DataSerializer#writeObject(Object, DataOutput)}. 
+   *
+   * @see DataSerializer#writeObject(Object, DataOutput)
+   */
+  public interface Replaceable {
+
+    /**
+     * Replaces this object with another in the "output stream"
+     * written by {@link DataSerializer#writeObject(Object, DataOutput)}.
+     */
+    public Object replace() throws IOException;
+  }
+
+}


[06/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueManagerImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueManagerImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueManagerImpl.java
new file mode 100644
index 0000000..71357e3
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueManagerImpl.java
@@ -0,0 +1,1478 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.ArrayList;
+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.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.GemFireException;
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.cache.InterestResultPolicy;
+import com.gemstone.gemfire.cache.NoSubscriptionServersAvailableException;
+import com.gemstone.gemfire.cache.client.ServerConnectivityException;
+import com.gemstone.gemfire.cache.client.internal.PoolImpl.PoolTask;
+import com.gemstone.gemfire.cache.client.internal.RegisterInterestTracker.RegionInterestEntry;
+import com.gemstone.gemfire.cache.client.internal.ServerBlackList.BlackListListener;
+import com.gemstone.gemfire.cache.client.internal.ServerBlackList.BlackListListenerAdapter;
+import com.gemstone.gemfire.cache.client.internal.ServerBlackList.FailureTracker;
+import com.gemstone.gemfire.cache.query.internal.CqStateImpl;
+import com.gemstone.gemfire.cache.query.internal.DefaultQueryService;
+import com.gemstone.gemfire.cache.query.internal.cq.ClientCQ;
+import com.gemstone.gemfire.cache.query.internal.cq.CqService;
+import com.gemstone.gemfire.cache.query.internal.cq.InternalCqQuery;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.Assert;
+import com.gemstone.gemfire.internal.cache.BridgeObserver;
+import com.gemstone.gemfire.internal.cache.BridgeObserverHolder;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.cache.tier.InterestType;
+import com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientUpdater;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ServerQueueStatus;
+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.log4j.LocalizedMessage;
+import com.gemstone.gemfire.security.GemFireSecurityException;
+import com.gemstone.org.jgroups.util.StringId;
+
+/**
+ * Manages Client Queues. Responsible for creating callback connections and
+ * satisfying redundancy requirements.
+ * 
+ * @author dsmith
+ * @since 5.7
+ * 
+ */
+public class QueueManagerImpl implements QueueManager {
+  private static final Logger logger = LogService.getLogger();
+
+//  private static final long SERVER_LOCATION_TIMEOUT = Long.getLong(
+//      "gemfire.QueueManagerImpl.SERVER_LOCATION_TIMEOUT", 120000).longValue();
+  private static final Comparator QSIZE_COMPARATOR = new QSizeComparator();
+
+  protected final long redundancyRetryInterval;
+  private final EndpointManager endpointManager;
+  private final EndpointManager.EndpointListenerAdapter endpointListener;
+  private final ConnectionSource source;
+  private final int redundancyLevel;
+  protected final ConnectionFactory factory;
+  private final InternalLogWriter securityLogger;
+  private final ClientProxyMembershipID proxyId;
+  protected final InternalPool pool;
+  private final QueueStateImpl state;
+  private boolean printPrimaryNotFoundError;
+  private boolean printRedundancyNotSatisfiedError;
+  private boolean printRecoveringPrimary;
+  private boolean printRecoveringRedundant;
+  protected final ServerBlackList blackList;
+  // Lock which guards updates to queueConnections.
+  // Also threads calling getAllConnections will wait on this
+  // lock until there is a primary.
+  protected final Object lock = new Object();
+  
+  protected final CountDownLatch initializedLatch = new CountDownLatch(1);
+
+  private ScheduledThreadPoolExecutor recoveryThread;
+  private volatile boolean sentClientReady;
+
+  // queueConnections in maintained by using copy-on-write
+  protected volatile ConnectionList queueConnections = new ConnectionList();
+  protected volatile RedundancySatisfierTask redundancySatisfierTask = null;
+  private volatile boolean shuttingDown;
+
+  public QueueManagerImpl(
+      InternalPool pool, 
+      EndpointManager endpointManager,
+      ConnectionSource source, 
+      ConnectionFactory factory,
+      int queueRedundancyLevel, 
+      long redundancyRetryInterval, 
+      InternalLogWriter securityLogger,
+      ClientProxyMembershipID proxyId) {
+    this.printPrimaryNotFoundError = true;
+    this.printRedundancyNotSatisfiedError = true;
+    this.printRecoveringRedundant = true;
+    this.printRecoveringPrimary = true;
+    this.pool = pool;
+    this.endpointManager = endpointManager;
+    this.source = source;
+    this.factory = factory;
+    this.redundancyLevel = queueRedundancyLevel;
+    this.securityLogger = securityLogger;
+    this.proxyId = proxyId;
+    this.redundancyRetryInterval = redundancyRetryInterval;
+    blackList = new ServerBlackList(redundancyRetryInterval);
+    
+    
+    this.endpointListener = new EndpointManager.EndpointListenerAdapter() {
+      @Override
+      public void endpointCrashed(Endpoint endpoint) {
+        QueueManagerImpl.this.endpointCrashed(endpoint);
+      }
+    };
+    
+    this.state = new QueueStateImpl(this);
+  }
+
+  public InternalPool getPool() {
+    return pool;
+  }
+
+  public boolean isPrimaryUpdaterAlive() {
+    boolean result = false;
+    QueueConnectionImpl primary = (QueueConnectionImpl)
+      queueConnections.getPrimary();
+    if (primary != null) {
+      ClientUpdater cu = primary.getUpdater();
+      if (cu != null) {
+        result = ((CacheClientUpdater)cu).isAlive();
+      }
+    }
+    return result;
+  }
+  
+  public QueueConnections getAllConnectionsNoWait() {
+      return queueConnections;
+  }
+  
+  public QueueConnections getAllConnections() {
+
+    ConnectionList snapshot = queueConnections;
+    if (snapshot.getPrimary() == null) {
+      // wait for a new primary to become available.
+      synchronized (lock) {
+        snapshot = queueConnections;
+        while (snapshot.getPrimary() == null
+            && !snapshot.primaryDiscoveryFailed() && !shuttingDown && pool.getPoolOrCacheCancelInProgress()==null) {
+          try {
+            lock.wait();
+          } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            break;
+          }
+          snapshot = queueConnections;
+        }
+      }
+    }
+    
+    if (snapshot.getPrimary() == null) {
+      pool.getCancelCriterion().checkCancelInProgress(null);
+      GemFireException exception  = snapshot.getPrimaryDiscoveryException();
+      if(exception == null || exception instanceof NoSubscriptionServersAvailableException) {
+        exception = new NoSubscriptionServersAvailableException(exception);
+      }
+      else { 
+        exception = new ServerConnectivityException(exception.getMessage(), exception);
+      }
+      throw exception;
+    }
+
+    return snapshot;
+  }
+
+  public InternalLogWriter getSecurityLogger() {
+    return securityLogger;
+  }
+
+  public void close(boolean keepAlive) {
+    endpointManager.removeListener(endpointListener);
+    synchronized (lock) {
+      shuttingDown = true;
+      if (redundancySatisfierTask != null) {
+        redundancySatisfierTask.cancel();
+      }
+      lock.notifyAll();
+    }
+    if (recoveryThread != null) {
+      // it will be null if we never called start
+      recoveryThread.shutdown();
+    }
+    if (recoveryThread != null) {
+      try {
+        if(!recoveryThread.awaitTermination(PoolImpl.SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS)) {
+          logger.warn(LocalizedMessage.create(LocalizedStrings.QueueManagerImpl_TIMEOUT_WAITING_FOR_RECOVERY_THREAD_TO_COMPLETE));
+        }
+      } catch (InterruptedException e1) {
+        Thread.currentThread().interrupt();
+        logger.debug("Interrupted waiting for recovery thread termination");
+      }
+    }
+    
+    QueueConnectionImpl primary = (QueueConnectionImpl) queueConnections
+        .getPrimary();
+    if(logger.isDebugEnabled()) {
+      logger.debug("QueueManagerImpl - closing connections with keepAlive={}", keepAlive);
+    }
+    if (primary != null) {
+      try {
+        if(logger.isDebugEnabled()) {
+          logger.debug("QueueManagerImpl - closing primary {}", primary);
+        }
+        primary.internalClose(keepAlive);
+      } catch (Exception e) {
+        logger.warn(LocalizedMessage.create(
+          LocalizedStrings.QueueManagerImpl_ERROR_CLOSING_PRIMARY_CONNECTION_TO_0,
+          primary.getEndpoint()), e);
+      }
+    }
+
+    List backups = queueConnections.getBackups();
+    for (Iterator itr = backups.iterator(); itr.hasNext();) {
+      QueueConnectionImpl backup = (QueueConnectionImpl) itr.next();
+      if (backup != null) {
+        try {
+          if(logger.isDebugEnabled()) {
+            logger.debug("QueueManagerImpl - closing backup {}", backup);
+          }
+          backup.internalClose(keepAlive);
+        } catch (Exception e) {
+          logger.warn(LocalizedMessage.create(
+              LocalizedStrings.QueueManagerImpl_ERROR_CLOSING_BACKUP_CONNECTION_TO_0,
+              backup.getEndpoint()), e);
+        }
+      }
+    }
+  }
+  
+  
+  public void emergencyClose() {
+    shuttingDown = true;
+    queueConnections.getPrimary().emergencyClose();
+    List backups = queueConnections.getBackups();
+    for(int i = 0; i < backups.size(); i++) {
+      Connection backup = (Connection) backups.get(i);
+      backup.emergencyClose();
+    }
+  }
+
+  public void start(ScheduledExecutorService background) {
+    try {
+      blackList.start(background);
+      endpointManager.addListener(endpointListener);
+
+      // Use a separate timer for queue management tasks
+      // We don't want primary recovery (and therefore user threads) to wait for
+      // things like pinging connections for health checks.
+      // this.background = background;
+      final String name = "queueTimer-" + this.pool.getName();
+      this.recoveryThread = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
+
+        public Thread newThread(Runnable r) {
+          Thread result = new Thread(r, name);
+          result.setDaemon(true);
+          return result;
+        }
+
+
+      });
+      recoveryThread.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+
+//    TODO - use yet another Timer or the like for these tasks? We know
+      //we don't want them in the recoveryThread, because the ThreadIdToSequenceIdExpiryTask
+      //will wait for primary recovery.
+      getState().start(background, getPool().getSubscriptionAckInterval());
+
+      // initialize connections
+      initializeConnections();
+
+      scheduleRedundancySatisfierIfNeeded(redundancyRetryInterval);
+
+      //When a server is removed from the blacklist, try again
+      //to establish redundancy (if we need to)
+      BlackListListener blackListListener = new BlackListListenerAdapter() {
+        @Override
+        public void serverRemoved(ServerLocation location) {
+          QueueManagerImpl.this.scheduleRedundancySatisfierIfNeeded(0);
+        }
+      };
+
+      blackList.addListener(blackListListener);
+      factory.getBlackList().addListener(blackListListener);
+    } finally {
+      initializedLatch.countDown();
+    }
+  }
+  
+  
+
+  public void readyForEvents(InternalDistributedSystem system) {
+    synchronized(lock) {
+      this.sentClientReady = true;
+    }
+
+    QueueConnectionImpl primary = null;
+    while (primary == null) {
+      try {
+        primary = (QueueConnectionImpl) getAllConnections().getPrimary();
+      } catch(NoSubscriptionServersAvailableException e) {
+        primary = null;
+        break;
+      }
+      if(primary.sendClientReady()) {
+        try {
+          logger.info(LocalizedMessage.create(
+            LocalizedStrings.QueueManagerImpl_SENDING_READY_FOR_EVENTS_TO_PRIMARY_0,
+            primary));
+          ReadyForEventsOp.execute(pool, primary); 
+        } catch(Exception e) {
+          if(logger.isDebugEnabled()) {
+            logger.debug("Error sending ready for events to {}", primary, e);
+          }
+          primary.destroy();
+          primary = null;
+        }
+      }
+    }
+  }
+  
+  public void readyForEventsAfterFailover(QueueConnectionImpl primary) {
+    try {
+      logger.info(LocalizedMessage.create(
+        LocalizedStrings.QueueManagerImpl_SENDING_READY_FOR_EVENTS_TO_PRIMARY_0, primary));
+      ReadyForEventsOp.execute(pool, primary);
+    } catch(Exception e) {
+      if(logger.isDebugEnabled()) {
+        logger.debug("Error sending ready for events to {}", primary, e);
+      }
+      primary.destroy();
+    }
+  }
+
+  void connectionCrashed(Connection con) {
+    // the endpoint has not crashed but this method does all the work
+    // we need to do
+    endpointCrashed(con.getEndpoint());
+  }
+  
+  void endpointCrashed(Endpoint endpoint) {
+    QueueConnectionImpl deadConnection = null;
+    //We must be synchronized while checking to see if we have a queue connection for the endpoint,
+    //because when we need to prevent a race between adding a queue connection to the map
+    //and the endpoint for that connection crashing.
+    synchronized (lock) {
+      deadConnection = queueConnections.getConnection(endpoint);
+      if (deadConnection != null) {
+        queueConnections = queueConnections.removeConnection(deadConnection);
+      }
+    }
+    if (deadConnection != null) {
+      logger.info(LocalizedMessage.create(LocalizedStrings.QueueManagerImpl_SUBSCRIPTION_ENDPOINT_CRASHED_SCHEDULING_RECOVERY, 
+                        new Object[]{deadConnection.getUpdater() != null ?(deadConnection.getUpdater().isPrimary()? "Primary" : "Redundant") : "Queue", endpoint}));
+      scheduleRedundancySatisfierIfNeeded(0);
+      deadConnection.internalDestroy();
+    } else {
+      if (logger.isDebugEnabled()) {
+        logger.debug("Ignoring crashed endpoint {} it does not have a queue.", endpoint);
+      }
+    }
+  }
+  /**
+   * This method checks whether queue connection exist on this endpoint or not.
+   *  if its there then it just destroys connection as clientUpdate thread is not there to read that connection.
+   */
+  public void checkEndpoint(ClientUpdater ccu, Endpoint endpoint)
+  {
+    QueueConnectionImpl deadConnection = null;
+    
+    synchronized (lock) {
+      if(shuttingDown)
+        return;
+      //if same client updater then only remove as we don't know whether it has created new updater/connection on same endpoint or not..
+      deadConnection = queueConnections.getConnection(endpoint);
+      if (deadConnection != null && ccu.equals(deadConnection.getUpdater())) {
+        queueConnections = queueConnections.removeConnection(deadConnection);        
+        deadConnection.internalDestroy();
+      }      
+    }    
+    
+    logger.info(LocalizedMessage.create(LocalizedStrings.QueueManagerImpl_CACHE_CLIENT_UPDATER_FOR_ON_ENDPOINT_EXITING_SCHEDULING_RECOVERY,
+                new Object[]{(deadConnection != null && deadConnection.getUpdater() != null)?(deadConnection.getUpdater().isPrimary()? "Primary" : "Redundant"): "Queue", endpoint}));
+    scheduleRedundancySatisfierIfNeeded(0);//one more chance
+  }
+
+  private void initializeConnections() {
+    final boolean isDebugEnabled = logger.isDebugEnabled();
+    if (isDebugEnabled) {
+      logger.debug("SubscriptionManager - intitializing connections");
+    }
+    
+    int queuesNeeded = redundancyLevel == -1 ? -1 : redundancyLevel + 1;
+    Set excludedServers = new HashSet(blackList.getBadServers());
+    List servers = findQueueServers(excludedServers, queuesNeeded, true, false, null);
+
+    if (servers == null || servers.isEmpty()) {
+      logger.warn(
+        LocalizedStrings.QueueManagerImpl_COULD_NOT_CREATE_A_QUEUE_NO_QUEUE_SERVERS_AVAILABLE);
+      scheduleRedundancySatisfierIfNeeded(redundancyRetryInterval);
+      synchronized (lock) {
+        queueConnections = queueConnections.setPrimaryDiscoveryFailed(null);
+        lock.notifyAll();
+      }
+      return;
+    }
+
+    if (isDebugEnabled) {
+      logger.debug("SubscriptionManager - discovered subscription servers {}", servers);
+    }
+
+    SortedMap/* <ServerQueueStatus,Connection> */oldQueueServers = new TreeMap(
+        QSIZE_COMPARATOR);
+    List nonRedundantServers = new ArrayList();
+
+    for (Iterator itr = servers.iterator(); itr.hasNext();) {
+      ServerLocation server = (ServerLocation) itr.next();
+      Connection connection = null;
+      try {
+        connection = factory.createClientToServerConnection(server, true);
+      } catch(GemFireSecurityException e) {
+        throw e;
+      } catch (Exception e) {
+        if (isDebugEnabled) {
+          logger.debug("SubscriptionManager - Error connected to server: {}", server, e);
+        }
+      }
+      if (connection != null) {
+        ServerQueueStatus status = connection.getQueueStatus();
+        if (status.isRedundant() || status.isPrimary()) {
+          oldQueueServers.put(status, connection);
+        } else {
+          nonRedundantServers.add(connection);
+        }
+      }
+    }
+
+    // This ordering was determined from the old ConnectionProxyImpl code
+    //
+    // initialization order of the new redundant and primary server is
+    // old redundant w/ second largest queue
+    // old redundant w/ third largest queue
+    // ...
+    // old primary
+    // non redundants in no particular order
+    //
+    // The primary is then chosen as
+    // redundant with the largest queue
+    // primary if there are no redundants
+    // a non redundant
+
+    // if the redundant with the largest queue fails, then we go and
+    // make a new server a primary.
+
+    Connection newPrimary = null;
+    if (!oldQueueServers.isEmpty()) {
+      newPrimary = (Connection) oldQueueServers.remove(oldQueueServers
+          .lastKey());
+    } else if (!nonRedundantServers.isEmpty()) {
+      newPrimary = (Connection) nonRedundantServers.remove(0);
+    }
+    
+    nonRedundantServers.addAll(0, oldQueueServers.values());
+
+    for (Iterator itr = nonRedundantServers.iterator(); itr.hasNext();) {
+      Connection connection = (Connection) itr.next();
+      QueueConnectionImpl queueConnection = initializeQueueConnection(
+          connection, false, null);
+      if (queueConnection != null) {
+        addToConnectionList(queueConnection, false);
+      }
+    }
+
+    QueueConnectionImpl primaryQueue = null;
+    if (newPrimary != null) {
+      primaryQueue = initializeQueueConnection(newPrimary, true, null);
+      if (primaryQueue == null) {
+        newPrimary.destroy();
+      } else {
+        if(!addToConnectionList(primaryQueue, true)) {
+          primaryQueue = null;
+        }
+      }
+    }
+
+
+    excludedServers.addAll(servers);
+
+    // Make sure we have enough redundant copies. Some of the connections may
+    // have failed
+    // above.
+    if (redundancyLevel != -1 && getCurrentRedundancy() < redundancyLevel) {
+      if (isDebugEnabled) {
+        logger.debug("SubscriptionManager - Some initial connections failed. Trying to create redundant queues");
+      }
+      recoverRedundancy(excludedServers, false);
+    }
+
+    if (redundancyLevel != -1 && primaryQueue == null) {
+      if (isDebugEnabled) {
+        logger.debug("SubscriptionManager - Intial primary creation failed. Trying to create a new primary");
+      }
+      while(primaryQueue == null) { 
+        primaryQueue = createNewPrimary(excludedServers);
+        if(primaryQueue == null) {
+          //couldn't find a server to make primary
+          break;
+        }
+        if(!addToConnectionList(primaryQueue, true)) {
+          excludedServers.add(primaryQueue.getServer());
+          primaryQueue = null;
+        }
+      }
+    }
+
+    if (primaryQueue == null) {
+      if (isDebugEnabled) {
+        logger.debug("SubscriptionManager - Unable to create a new primary queue, using one of the redundant queues");
+      }
+      while(primaryQueue == null) {
+        primaryQueue = promoteBackupToPrimary(queueConnections.getBackups());
+        if(primaryQueue == null) {
+          //no backup servers available
+          break;
+        }
+        if(!addToConnectionList(primaryQueue, true)) {
+          synchronized(lock) {
+            //make sure we don't retry this same connection.
+            queueConnections = queueConnections.removeConnection(primaryQueue);
+          }
+          primaryQueue = null;
+        }
+      }
+    }
+
+    if (primaryQueue == null) {
+      logger.error(LocalizedMessage.create(
+          LocalizedStrings.QueueManagerImpl_COULD_NOT_INITIALIZE_A_PRIMARY_QUEUE_ON_STARTUP_NO_QUEUE_SERVERS_AVAILABLE));
+      synchronized (lock) {
+        queueConnections = queueConnections.setPrimaryDiscoveryFailed(
+            new NoSubscriptionServersAvailableException(LocalizedStrings.QueueManagerImpl_COULD_NOT_INITIALIZE_A_PRIMARY_QUEUE_ON_STARTUP_NO_QUEUE_SERVERS_AVAILABLE.toLocalizedString()));
+        lock.notifyAll();
+      }
+      cqsDisconnected();
+    }
+    else {
+      cqsConnected();
+    }
+
+    if (getCurrentRedundancy() < redundancyLevel) {
+      logger.warn(LocalizedMessage.create(
+          LocalizedStrings.QueueManagerImpl_UNABLE_TO_INITIALIZE_ENOUGH_REDUNDANT_QUEUES_ON_STARTUP_THE_REDUNDANCY_COUNT_IS_CURRENTLY_0,  
+          getCurrentRedundancy()));
+    }
+  }
+
+  private void cqsConnected() {
+    GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+    if(cache != null) {
+      CqService cqService = cache.getCqService();
+    //Primary queue was found, alert the affected cqs if necessary
+      cqService.cqsConnected(pool);
+    }
+  }
+
+  private void cqsDisconnected() {
+    //No primary queue was found, alert the affected cqs if necessary
+    GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+    if(cache != null) {
+      CqService cqService = cache.getCqService();
+      cqService.cqsDisconnected(pool);
+    }
+  }
+
+  private int getCurrentRedundancy() {
+    return queueConnections.getBackups().size();
+  }
+  
+  /**
+   * Make sure that we have enough backup servers.
+   * 
+   * Add any servers we fail to connect to to the excluded servers list.
+   */
+  protected boolean recoverRedundancy(Set excludedServers, boolean recoverInterest) {
+    if(pool.getPoolOrCacheCancelInProgress() != null) {
+      return true;
+    }
+    int additionalBackups;
+    while (pool.getPoolOrCacheCancelInProgress()==null && ((additionalBackups = redundancyLevel - getCurrentRedundancy()) > 0
+        || redundancyLevel == -1))  {
+
+      
+      if(redundancyLevel != -1 && printRecoveringRedundant) {
+        logger.info(LocalizedMessage.create(LocalizedStrings.QueueManagerImpl_SUBSCRIPTION_MANAGER_REDUNDANCY_SATISFIER_REDUNDANT_ENDPOINT_HAS_BEEN_LOST_ATTEMPTIMG_TO_RECOVER));
+        printRecoveringRedundant = false;
+       }
+      
+      List servers = findQueueServers(excludedServers, redundancyLevel == -1 ? -1 : additionalBackups, false, 
+                            (redundancyLevel == -1 ? false : printRedundancyNotSatisfiedError),
+                                    LocalizedStrings.QueueManagerImpl_COULD_NOT_FIND_SERVER_TO_CREATE_REDUNDANT_CLIENT_QUEUE);
+
+      if (servers == null || servers.isEmpty()) {
+        if (redundancyLevel != -1) {
+          
+          if(printRedundancyNotSatisfiedError) {
+          logger.info(LocalizedMessage.create(
+            LocalizedStrings.QueueManagerImpl_REDUNDANCY_LEVEL_0_IS_NOT_SATISFIED_BUT_THERE_ARE_NO_MORE_SERVERS_AVAILABLE_REDUNDANCY_IS_CURRENTLY_1,
+            new Object[] { Integer.valueOf(redundancyLevel), Integer.valueOf(getCurrentRedundancy())}));
+          }          
+        }
+        printRedundancyNotSatisfiedError = false;//printed above
+        return false;
+      }
+      excludedServers.addAll(servers);
+
+      final boolean isDebugEnabled = logger.isDebugEnabled();
+      for (Iterator itr = servers.iterator(); itr.hasNext();) {
+        ServerLocation server = (ServerLocation) itr.next();
+        Connection connection = null;
+        try {
+          connection = factory.createClientToServerConnection(server, true);
+        } catch(GemFireSecurityException e) {
+          throw e;
+        } catch (Exception e) {
+          if (isDebugEnabled) {
+            logger.debug("SubscriptionManager - Error connecting to server: ()", server, e);
+          }
+        }
+        if (connection == null) {
+          continue;
+        }
+
+        QueueConnectionImpl queueConnection = initializeQueueConnection(
+            connection, false, null);
+        if (queueConnection != null) {
+          boolean isFirstNewConnection = false;
+          synchronized (lock) {
+            if (recoverInterest && queueConnections.getPrimary() == null
+                && queueConnections.getBackups().isEmpty()) {
+              //  we lost our queue at some point. We Need to recover
+              // interest. This server will be made primary after this method
+              // finishes
+              // because whoever killed the primary when this method started
+              // should
+              // have scheduled a task to recover the primary.
+              isFirstNewConnection = true;
+              // TODO - Actually, we need a better check than the above. There's
+              // still a chance
+              // that we haven't realized that the primary has died but it is
+              // already gone. We should
+              // get some information from the queue server about whether it was
+              // able to copy the
+              // queue from another server and decide if we need to recover our
+              // interest based on
+              // that information.
+            }
+          }
+          boolean promotionFailed = false;
+          if (isFirstNewConnection) {
+            if (!promoteBackupCnxToPrimary(queueConnection)) {
+              promotionFailed = true;
+            }
+          }
+          if (!promotionFailed) {
+            if (addToConnectionList(queueConnection, isFirstNewConnection)) {
+              //redundancy satisfied
+              printRedundancyNotSatisfiedError = true;
+              printRecoveringRedundant = true;
+              if (logger.isDebugEnabled()) {
+                logger.debug("SubscriptionManager redundancy satisfier - created a queue on server {}", queueConnection.getEndpoint());
+              }
+              // Even though the new redundant queue will usually recover
+              // subscription information (see bug #39014) from its initial
+              // image provider, in bug #42280 we found that this is not always
+              // the case, so clients must always register interest with the new
+              // redundant server.
+              if(recoverInterest) {
+                recoverInterest(queueConnection, isFirstNewConnection);
+              }
+            }
+          } 
+        }
+      } 
+    }    
+    return true;
+  }
+
+  private QueueConnectionImpl promoteBackupToPrimary(List backups) {
+    QueueConnectionImpl primary = null;
+    for (int i = 0; primary == null && i < backups.size(); i++) {
+      QueueConnectionImpl lastConnection = (QueueConnectionImpl) backups.get(i);
+      if (promoteBackupCnxToPrimary(lastConnection)) {
+        primary = lastConnection;
+      }
+    }
+    return primary;
+  }
+
+  private boolean promoteBackupCnxToPrimary(QueueConnectionImpl cnx) {
+    boolean result = false;
+    if (PoolImpl.BEFORE_PRIMARY_IDENTIFICATION_FROM_BACKUP_CALLBACK_FLAG) {
+      BridgeObserver bo = BridgeObserverHolder.getInstance();
+      bo.beforePrimaryIdentificationFromBackup();
+    }
+    try {
+      boolean haveSentClientReady = this.sentClientReady;
+      if(haveSentClientReady) {
+        cnx.sendClientReady();
+      }
+      ClientUpdater updater = cnx.getUpdater();
+      if(updater == null) {
+        if (logger.isDebugEnabled()) {
+          logger.debug("backup connection was destroyed before it could become the primary.");
+        }
+        Assert.assertTrue(cnx.isDestroyed());
+      } else {
+        updater.setFailedUpdater(queueConnections.getFailedUpdater());
+        MakePrimaryOp.execute(pool, cnx, haveSentClientReady);
+        result = true;
+        if (PoolImpl.AFTER_PRIMARY_IDENTIFICATION_FROM_BACKUP_CALLBACK_FLAG) {
+          BridgeObserver bo = BridgeObserverHolder.getInstance();
+          bo.afterPrimaryIdentificationFromBackup(cnx.getServer());
+        }
+      }
+    } catch (Exception e) {
+      if(pool.getPoolOrCacheCancelInProgress() == null && logger.isDebugEnabled()) {
+        logger.debug("Error making a backup server the primary server for client subscriptions", e);
+      }
+    }
+    return result;
+  }
+  /**
+   * Create a new primary server from a non-redundant server.
+   * 
+   * Add any failed servers to the excludedServers set.
+   */
+  private QueueConnectionImpl createNewPrimary(Set excludedServers) {
+    QueueConnectionImpl primary = null;
+    while (primary == null && pool.getPoolOrCacheCancelInProgress()==null) {
+      List servers = findQueueServers(excludedServers, 1, false, 
+                                       printPrimaryNotFoundError,
+                                       LocalizedStrings.QueueManagerImpl_COULD_NOT_FIND_SERVER_TO_CREATE_PRIMARY_CLIENT_QUEUE);
+      printPrimaryNotFoundError = false; //printed above
+      if (servers == null || servers.isEmpty()) {
+        break;
+      }
+
+      Connection connection = null;
+      try {
+        connection = factory
+          .createClientToServerConnection((ServerLocation) servers.get(0), true);
+      } catch (GemFireSecurityException e) {
+        throw e;
+      } catch(Exception e) {
+        if(logger.isDebugEnabled()) {
+          logger.debug("SubscriptionManagerImpl - error creating a connection to server {}", servers.get(0));
+        }
+      }
+      if (connection != null) {
+        primary = initializeQueueConnection(connection, true, queueConnections.getFailedUpdater());
+      }
+      excludedServers.addAll(servers);
+    }
+    
+    if(primary != null && sentClientReady && primary.sendClientReady()) {
+      readyForEventsAfterFailover(primary);
+    }
+    return primary;
+  }
+
+  private List findQueueServers(Set excludedServers, int count,
+      boolean findDurable, boolean printErrorMessage, StringId msgId) {
+    List servers = null;
+    Exception ex = null;
+    try {
+      if(pool.getPoolOrCacheCancelInProgress()!=null) {
+        return null;
+      }
+      servers = source.findServersForQueue(excludedServers, count, proxyId, findDurable);
+    } catch(GemFireSecurityException e) {
+      //propagate the security exception immediately.
+      throw e;
+    } catch (Exception e) {
+      /*logger
+          .warning(
+              LocalizedStrings.QueueManagerImpl_COULD_NOT_RETRIEVE_LIST_OF_SERVERS_FOR_SUBSCRIPTION_0,
+              new Object[] { e.getMessage() });*/
+      ex = e;
+      if (logger.isDebugEnabled()) {
+        logger.debug("SubscriptionManager - Error getting the list of servers: {}", e);
+      }
+    }
+    
+    if(printErrorMessage)
+    {
+      if(servers == null || servers.isEmpty())
+      {
+        logger.error(LocalizedMessage.create(msgId, 
+          new Object[]{ (excludedServers!= null?excludedServers.size(): 0), (ex != null?ex.getMessage(): "no exception")}));
+      }
+    }
+    return servers;
+  }
+
+  /**
+   * Find a new primary, adding any failed servers we encounter to the excluded
+   * servers list
+   * 
+   * First we try to make a backup server the primary, but if run out of backup
+   * servers we will try to find a new server.
+   */
+  protected void recoverPrimary(Set excludedServers) {
+    if(pool.getPoolOrCacheCancelInProgress() != null) {
+      return;
+    }
+    final boolean isDebugEnabled = logger.isDebugEnabled();
+    if (queueConnections.getPrimary() != null) {
+      if (isDebugEnabled) {
+        logger.debug("Primary recovery not needed");
+      }
+      return;
+    }
+
+    if (isDebugEnabled) {
+      logger.debug("SubscriptionManager redundancy satisfier - primary endpoint has been lost. Attempting to recover");
+    }
+
+    if(printRecoveringPrimary) {
+     logger.info(LocalizedMessage.create(LocalizedStrings.QueueManagerImpl_SUBSCRIPTION_MANAGER_REDUNDANCY_SATISFIER_PRIMARY_ENDPOINT_HAS_BEEN_LOST_ATTEMPTIMG_TO_RECOVER));
+     printRecoveringPrimary = false;
+    }
+    
+    QueueConnectionImpl newPrimary = null;
+    while(newPrimary == null && pool.getPoolOrCacheCancelInProgress()==null) {
+      List backups = queueConnections.getBackups();
+      newPrimary = promoteBackupToPrimary(backups);
+      //Hitesh now lets say that server crashed
+      if(newPrimary == null) {
+        //could not find a backup to promote
+        break;
+      }
+      if(!addToConnectionList(newPrimary, true)) {
+        synchronized(lock) {
+          //make sure we don't retry the same backup server
+          queueConnections = queueConnections.removeConnection(newPrimary);
+        }
+        newPrimary = null;
+      }
+
+    }
+    
+    if(newPrimary != null) {
+      if (isDebugEnabled) {
+        logger.debug("SubscriptionManager redundancy satisfier - Switched backup server to primary: {}", newPrimary.getEndpoint());
+      }
+      if (PoolImpl.AFTER_PRIMARY_RECOVERED_CALLBACK_FLAG) {
+        BridgeObserver bo = BridgeObserverHolder.getInstance();
+        bo.afterPrimaryRecovered(newPrimary.getServer());
+      }
+     
+      //new primary from back up server was found, alert affected cqs if necessary
+      cqsConnected();
+      printPrimaryNotFoundError = true;
+      printRecoveringPrimary =true;
+      return;
+    }
+
+    while(newPrimary == null) {
+      newPrimary = createNewPrimary(excludedServers);
+      if(newPrimary == null) {
+        //could not find a new primary to create
+        break;
+      }
+      if(!addToConnectionList(newPrimary, true)) {
+        excludedServers.add(newPrimary.getServer());
+        newPrimary = null;
+      }
+      
+      if (newPrimary != null) {
+        if (isDebugEnabled) {
+          logger.debug("SubscriptionManager redundancy satisfier - Non backup server was made primary. Recovering interest {}", newPrimary.getEndpoint());
+        }
+
+        if(!recoverInterest(newPrimary, true)) {
+          excludedServers.add(newPrimary.getServer());
+          newPrimary = null;
+        }
+        //New primary queue was found from a non backup, alert the affected cqs
+        cqsConnected();
+      }
+
+      if (newPrimary != null && PoolImpl.AFTER_PRIMARY_RECOVERED_CALLBACK_FLAG) {
+        BridgeObserver bo = BridgeObserverHolder.getInstance();
+        bo.afterPrimaryRecovered(newPrimary.getServer());
+      }
+      printPrimaryNotFoundError = true;
+      printRecoveringPrimary = true;
+      return;
+    }
+    //No primary queue was found, alert the affected cqs
+    cqsDisconnected();
+    if (isDebugEnabled) {
+      logger.debug("SubscriptionManager redundancy satisfier - Could not recover a new primary");
+    }
+    synchronized (lock) {
+      queueConnections = queueConnections.setPrimaryDiscoveryFailed(null);
+      lock.notifyAll();
+    }
+  }
+
+  private QueueConnectionImpl initializeQueueConnection(Connection connection,
+      boolean isPrimary, ClientUpdater failedUpdater) {
+    QueueConnectionImpl queueConnection = null;
+    FailureTracker failureTracker = blackList.getFailureTracker(connection.getServer());
+    try {
+      ClientUpdater updater = factory.createServerToClientConnection(connection
+          .getEndpoint(), this, isPrimary, failedUpdater);
+      if (updater != null) {
+        queueConnection = new QueueConnectionImpl(this, connection, updater, failureTracker);
+      } else {
+        logger.warn(LocalizedMessage.create(
+            LocalizedStrings.QueueManagerImpl_UNABLE_TO_CREATE_A_SUBSCRIPTION_CONNECTION_TO_SERVER_0,
+            connection.getEndpoint()));
+      }
+    } catch (Exception e) {
+      if (logger.isDebugEnabled()) {
+        logger.debug("error creating subscription connection to server {}", connection.getEndpoint(), e);
+      }
+    }
+    if (queueConnection == null) {
+      failureTracker.addFailure();
+      connection.destroy();
+    }
+    return queueConnection;
+  }
+  //need flag whether primary is created from backup
+  // for backuup queue lets assume before we add connection, endpoint crashed, now we put in connection but CCU may died as endpoint closed....
+  // so before putting connection need to see if something(crash) happen we should be able to recover from it
+  private boolean addToConnectionList(QueueConnectionImpl connection, boolean isPrimary) {
+    boolean isBadConnection;
+    synchronized(lock) {
+      ClientUpdater cu = connection.getUpdater();
+      if(cu == null || (! cu.isAlive() ) || (!cu.isProcessing()) )
+        return false;//don't add
+      //now still CCU can died but then it will execute Checkendpoint with lock it will remove connection connection and it will reschedule it.
+      if(connection.getEndpoint().isClosed() || shuttingDown || pool.getPoolOrCacheCancelInProgress()!=null) {
+        isBadConnection = true;
+      } else {
+        isBadConnection = false;
+        if(isPrimary) {
+          queueConnections = queueConnections.setPrimary(connection);
+          lock.notifyAll();
+        } else {          
+          queueConnections = queueConnections.addBackup(connection);
+        }
+      }
+    }
+    
+    if(isBadConnection) {
+      if(logger.isDebugEnabled()) {
+        logger.debug("Endpoint {} crashed while creating a connection. The connection will be destroyed", connection.getEndpoint());
+      }
+      connection.internalDestroy();
+    }
+    
+    return !isBadConnection;
+  }
+
+  protected void scheduleRedundancySatisfierIfNeeded(long delay) {
+    if(shuttingDown) {
+      return;
+    }
+    
+    synchronized (lock) {
+      if(shuttingDown) {
+        return;
+      }
+      if (queueConnections.getPrimary() == null
+          || getCurrentRedundancy() < redundancyLevel || redundancyLevel == -1
+          || queueConnections.primaryDiscoveryFailed()) {
+        if (redundancySatisfierTask != null) {
+          if (redundancySatisfierTask.getRemainingDelay() > delay) {
+            redundancySatisfierTask.cancel();
+          } else {
+            return;
+          }
+        }
+
+        redundancySatisfierTask = new RedundancySatisfierTask();
+        try {
+        ScheduledFuture future = recoveryThread.schedule(redundancySatisfierTask,
+            delay, TimeUnit.MILLISECONDS);
+        redundancySatisfierTask.setFuture(future);
+        } catch(RejectedExecutionException e) {
+          //ignore, the timer has been cancelled, which means we're shutting down.
+        }
+      }
+    }
+  }
+  
+
+  private boolean recoverInterest(final QueueConnectionImpl newConnection,
+      final boolean isFirstNewConnection) {
+    
+    if(pool.getPoolOrCacheCancelInProgress() != null) {
+      return true;
+    }
+    
+    // recover interest
+    try {
+      recoverAllInterestTypes(newConnection, isFirstNewConnection);
+      newConnection.getFailureTracker().reset();
+      return true;
+    } 
+    catch (CancelException ignore) {
+      return true;
+      // ok to ignore we are being shutdown
+    } 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) {
+      SystemFailure.checkFailure();
+      pool.getCancelCriterion().checkCancelInProgress(t);
+      logger.warn(LocalizedMessage.create(
+        LocalizedStrings.QueueManagerImpl_QUEUEMANAGERIMPL_FAILED_TO_RECOVER_INTEREST_TO_SERVER_0,
+        newConnection.getServer()), t);
+      newConnection.getFailureTracker().addFailure();
+      newConnection.destroy();
+      return false;
+    }
+  }
+
+  public QueueState getState() {
+    return this.state;
+  }
+
+  private void recoverSingleList(int interestType, Connection recoveredConnection,
+      boolean isDurable, boolean receiveValues, boolean isFirstNewConnection) {
+    Iterator i = this.getPool().getRITracker()
+    .getRegionToInterestsMap(interestType, isDurable, !receiveValues).values().iterator();
+    while (i.hasNext()) { // restore a region
+      RegionInterestEntry e = (RegionInterestEntry) i.next();
+      recoverSingleRegion(e.getRegion(), e.getInterests(), interestType,
+          recoveredConnection, isDurable, receiveValues, isFirstNewConnection);
+    } // restore a region
+  }
+
+  private void recoverCqs(Connection recoveredConnection, boolean isDurable) {
+    Map cqs = this.getPool().getRITracker().getCqsMap();
+    Iterator i = cqs.entrySet().iterator();
+    while(i.hasNext()) {
+      Map.Entry e = (Map.Entry)i.next();
+      ClientCQ cqi = (ClientCQ)e.getKey();
+      String name = cqi.getName();
+      if (this.pool.getMultiuserAuthentication()) {
+        UserAttributes.userAttributes.set(((DefaultQueryService)this.pool
+            .getQueryService()).getUserAttributes(name));
+      }
+      try {
+        if (((CqStateImpl)cqi.getState()).getState() != CqStateImpl.INIT) {
+          cqi.createOn(recoveredConnection, isDurable);
+        }
+      } finally {
+        UserAttributes.userAttributes.set(null);
+      }
+    }
+  }
+  
+  // TODO this is distressingly similar to LocalRegion#processSingleInterest
+  private void recoverSingleRegion(LocalRegion r, Map keys, int interestType,
+      Connection recoveredConnection, boolean isDurable,
+      boolean receiveValues, boolean isFirstNewConnection) {
+
+    if (logger.isDebugEnabled()) {
+      logger.debug("{}.recoverSingleRegion starting kind={} region={}: {}", this, InterestType.getString(interestType), r.getFullPath(), keys);
+    }
+    
+    // build a HashMap, key is policy, value is list
+    HashMap policyMap = new HashMap();
+    Iterator keysIter = keys.entrySet().iterator();
+    while (keysIter.hasNext()) { // restore and commit an interest
+      Map.Entry me = (Map.Entry) keysIter.next();
+      Object key = me.getKey();
+      InterestResultPolicy pol = (InterestResultPolicy) me.getValue();
+      
+      if (interestType == InterestType.KEY) {
+    	// Gester: we only consolidate the key into list for InterestType.KEY
+        LinkedList keyList = (LinkedList)policyMap.get(pol);
+        if (keyList == null) {
+          
+          keyList = new LinkedList();
+        }
+        keyList.add(key);
+        policyMap.put(pol, keyList);
+      } else {
+        // for other Interest type, do it one by one
+    	recoverSingleKey(r, key, pol, interestType, recoveredConnection,
+    	    isDurable, receiveValues, isFirstNewConnection);
+      }
+    }
+    
+    // Process InterestType.KEY: Iterator list for each each policy
+    Iterator polIter = policyMap.entrySet().iterator();
+    while (polIter.hasNext()) {
+      Map.Entry me = (Map.Entry) polIter.next();
+      LinkedList keyList = (LinkedList)me.getValue();
+      InterestResultPolicy pol = (InterestResultPolicy)me.getKey();
+      recoverSingleKey(r, keyList, pol, interestType, recoveredConnection,
+          isDurable, receiveValues, isFirstNewConnection);
+    }
+  }
+
+  private void recoverSingleKey(LocalRegion r, Object keys,
+      InterestResultPolicy policy, int interestType, Connection recoveredConnection,
+      boolean isDurable, boolean receiveValues, boolean isFirstNewConnection) {
+    r.startRegisterInterest();
+    try {
+      // Remove all matching values from local cache
+      if (isFirstNewConnection) { // only if this recoveredEP
+        // becomes primaryEndpoint
+        r.clearKeysOfInterest(keys, interestType, policy);
+        if (logger.isDebugEnabled()) {
+          logger.debug("{}.recoverSingleRegion :Endpoint recovered is primary so clearing the keys of interest starting kind={} region={}: {}", this, InterestType.getString(interestType), r.getFullPath(), keys);
+        }
+      }
+      // Register interest, get new values back
+      List serverKeys;
+      if (policy != InterestResultPolicy.KEYS_VALUES) {
+      serverKeys = r.getServerProxy().registerInterestOn(recoveredConnection,
+          keys, interestType, policy, isDurable, !receiveValues,
+          r.getAttributes().getDataPolicy().ordinal);
+      // Restore keys based on server's response
+      if (isFirstNewConnection) {
+        // only if this recoveredEP becomes primaryEndpoint
+        r.refreshEntriesFromServerKeys(recoveredConnection, serverKeys, policy);
+      }
+      } else {
+        if (!isFirstNewConnection) {
+          // InterestResultPolicy.KEYS_VALUES now fetches values in
+          // RegisterInterestOp's response itself and in this case
+          // refreshEntriesFromServerKeys(...) does not explicitly fetch values
+          // but only updates keys-values to region. To not fetch values, we
+          // need to use policy NONE or KEYS.
+          serverKeys = r.getServerProxy().registerInterestOn(recoveredConnection,
+              keys, interestType, InterestResultPolicy.NONE, isDurable, !receiveValues,
+              r.getAttributes().getDataPolicy().ordinal);
+        } else {
+          serverKeys = r.getServerProxy().registerInterestOn(recoveredConnection,
+              keys, interestType, policy, isDurable, !receiveValues,
+              r.getAttributes().getDataPolicy().ordinal);
+          r.refreshEntriesFromServerKeys(recoveredConnection, serverKeys, policy);
+        }
+      }
+    } finally {
+      r.finishRegisterInterest();
+    }
+  }
+
+  private void recoverInterestList(final Connection recoveredConnection,
+      boolean durable, boolean receiveValues, boolean isFirstNewConnection) {
+    recoverSingleList(InterestType.KEY, recoveredConnection, durable, receiveValues, isFirstNewConnection);
+    recoverSingleList(InterestType.REGULAR_EXPRESSION, recoveredConnection, durable, receiveValues, isFirstNewConnection);
+    recoverSingleList(InterestType.FILTER_CLASS, recoveredConnection, durable, receiveValues, isFirstNewConnection);
+    recoverSingleList(InterestType.OQL_QUERY, recoveredConnection, durable, receiveValues, isFirstNewConnection);
+    // VJR: Recover CQs moved to recoverAllInterestTypes() to avoid multiple
+    // calls for receiveValues flag being true and false.
+    //recoverCqs(recoveredConnection, durable);
+    //recoverSingleList(InterestType.CQ, recoveredConnection, durable,isFirstNewConnection);
+  }
+
+  protected void recoverAllInterestTypes(final Connection recoveredConnection,
+      boolean isFirstNewConnection) {
+    if (PoolImpl.BEFORE_RECOVER_INTERST_CALLBACK_FLAG) {
+      BridgeObserver bo = BridgeObserverHolder.getInstance();
+      bo.beforeInterestRecovery();
+    }
+    recoverInterestList(recoveredConnection, false, true, isFirstNewConnection);
+    recoverInterestList(recoveredConnection, false, false, isFirstNewConnection);
+    recoverCqs(recoveredConnection, false);
+    if ( getPool().isDurableClient()) {
+      recoverInterestList(recoveredConnection, true, true, isFirstNewConnection);
+      recoverInterestList(recoveredConnection, true, false, isFirstNewConnection);
+      recoverCqs(recoveredConnection, true);
+    }
+  }
+
+  
+  /**
+   * A comparator which sorts queue elements in the order of primary first
+   * redundant with smallest queue size ... redundant with largest queue size
+   * 
+   * @author dsmith
+   * 
+   */
+  protected static class QSizeComparator implements java.util.Comparator {
+    public int compare(Object o1, Object o2) {
+      ServerQueueStatus s1 = (ServerQueueStatus) o1;
+      ServerQueueStatus s2 = (ServerQueueStatus) o2;
+      // sort primaries to the front of the list
+      if (s1.isPrimary() && !s2.isPrimary()) {
+        return -1;
+      } else if (!s1.isPrimary() && s2.isPrimary()) {
+        return 1;
+      } else {
+        int diff =  s1.getServerQueueSize() - s2.getServerQueueSize();
+        if(diff != 0) {
+          return diff;
+        } else {
+          return s1.getMemberId().compareTo(s2.getMemberId());
+        }
+      }
+    }
+  }
+
+  /**
+   * A data structure for holding the current set of connections the
+   * queueConnections reference should be maintained by making a copy of this
+   * data structure for each change.
+   * 
+   * Note the the order of the backups is significant. The first backup in the
+   * list is the first server that will be become primary after the primary
+   * fails, etc.
+   * 
+   * The order of backups in this list is the reverse of the order or endpoints
+   * from the old ConnectionProxyImpl .
+   */
+  public class ConnectionList implements QueueConnections {
+    private final QueueConnectionImpl primary;
+    private final Map/* <Endpoint, QueueConnection> */connectionMap;
+    private final List/* <QueueConnection> */backups;
+    /**
+     * The primaryDiscoveryException flag is stronger than just not having any
+     * queue connections It also means we tried all of the possible queue
+     * servers and we'ren't able to connect.
+     */
+    private final GemFireException primaryDiscoveryException;
+    private final QueueConnectionImpl failedPrimary;
+
+    public ConnectionList() {
+      primary = null;
+      connectionMap = Collections.EMPTY_MAP;
+      backups = Collections.EMPTY_LIST;
+      primaryDiscoveryException = null;
+      failedPrimary = null;
+    }
+
+    private ConnectionList(QueueConnectionImpl primary, List backups,
+        GemFireException discoveryException, QueueConnectionImpl failedPrimary) {
+      this.primary = primary;
+      Map allConnectionsTmp = new HashMap();
+      for (Iterator itr = backups.iterator(); itr.hasNext();) {
+        QueueConnectionImpl nextConnection = (QueueConnectionImpl) itr.next();
+        allConnectionsTmp.put(nextConnection.getEndpoint(), nextConnection);
+      }
+      if (primary != null) {
+        allConnectionsTmp.put(primary.getEndpoint(), primary);
+      }
+      this.connectionMap = Collections.unmodifiableMap(allConnectionsTmp);
+      this.backups = Collections.unmodifiableList(new ArrayList(backups));
+      pool.getStats().setSubscriptionCount(connectionMap.size());
+      this.primaryDiscoveryException = discoveryException;
+      this.failedPrimary = failedPrimary;
+    }
+
+    public ConnectionList setPrimary(QueueConnectionImpl newPrimary) {
+      List newBackups = backups;
+      if (backups.contains(newPrimary)) {
+        newBackups = new ArrayList(backups);
+        newBackups.remove(newPrimary);
+      }
+      return new ConnectionList(newPrimary, newBackups, null, null);
+    }
+
+    public ConnectionList setPrimaryDiscoveryFailed(
+        GemFireException p_discoveryException) {
+      GemFireException discoveryException = p_discoveryException;
+      if(discoveryException == null) {
+        discoveryException = new NoSubscriptionServersAvailableException("Primary discovery failed.");
+      }
+      return new ConnectionList(primary, backups, discoveryException, failedPrimary);
+    }
+
+    public ConnectionList addBackup(QueueConnectionImpl queueConnection) {
+      ArrayList newBackups = new ArrayList(backups);
+      newBackups.add(queueConnection);
+      return new ConnectionList(primary, newBackups, primaryDiscoveryException, failedPrimary);
+    }
+
+    public ConnectionList removeConnection(QueueConnectionImpl connection) {
+      if (primary == connection) {
+        return new ConnectionList(null, backups, primaryDiscoveryException, primary);
+      } else {
+        ArrayList newBackups = new ArrayList(backups);
+        newBackups.remove(connection);
+        return new ConnectionList(primary, newBackups, primaryDiscoveryException, failedPrimary);
+      }
+    }
+
+    public Connection getPrimary() {
+      return primary;
+    }
+
+    public List/* <QueueConnection> */getBackups() {
+      return backups;
+    }
+    
+    /**
+     * Return the cache client updater from the previously
+     * failed primary
+     * @return the previous updater or null if there is no previous updater
+     */
+    public ClientUpdater getFailedUpdater() {
+      if(failedPrimary != null) {
+        return failedPrimary.getUpdater();
+      } else {
+        return null;
+      }
+    }
+
+    public boolean primaryDiscoveryFailed() {
+      return primaryDiscoveryException != null;
+    }
+    
+    public GemFireException getPrimaryDiscoveryException() {
+      return primaryDiscoveryException;
+    }
+
+    public QueueConnectionImpl getConnection(Endpoint endpoint) {
+      return (QueueConnectionImpl) connectionMap.get(endpoint);
+    }
+
+    /** return a copy of the list of all server locations */
+    public Set/* <ServerLocation> */getAllLocations() {
+      HashSet locations = new HashSet();
+      for (Iterator itr = connectionMap.keySet().iterator(); itr.hasNext();) {
+        com.gemstone.gemfire.cache.client.internal.Endpoint endpoint = (com.gemstone.gemfire.cache.client.internal.Endpoint) itr.next();
+        locations.add(endpoint.getLocation());
+      }
+
+      return locations;
+    }
+  }
+  
+  protected void logError(StringId message, Throwable t) {
+    if(t instanceof GemFireSecurityException) {
+      securityLogger.error(message, t);
+    } else { 
+      logger.error(message, t);
+    }
+  }
+
+  /**
+   * Asynchronous task which tries to restablish a primary connection and
+   * satisfy redundant requirements.
+   * 
+   * This task should only be running in a single thread at a time. This task is
+   * the only way that new queue servers will be added, and the only way that a
+   * backup server can transistion to a primary server.
+   * 
+   */
+  protected class RedundancySatisfierTask extends PoolTask {
+    private boolean isCancelled;
+    private ScheduledFuture future;
+
+    public void setFuture(ScheduledFuture future) {
+      this.future = future;
+    }
+
+    public long getRemainingDelay() {
+      return future.getDelay(TimeUnit.MILLISECONDS);
+    }
+
+    @Override
+    public void run2() {
+      try {
+        initializedLatch.await();
+        synchronized (lock) {
+          if (isCancelled) {
+            return;
+          } else {
+            redundancySatisfierTask = null;
+          }
+          if(pool.getPoolOrCacheCancelInProgress()!=null) {
+	    /* wake up waiters so they can detect cancel */
+	    lock.notifyAll();
+            return;
+          }
+        }
+        Set excludedServers = queueConnections.getAllLocations();
+        excludedServers.addAll(blackList.getBadServers());
+        excludedServers.addAll(factory.getBlackList().getBadServers());
+        recoverPrimary(excludedServers);
+        recoverRedundancy(excludedServers, true);
+      } 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 (CancelException e) {
+        throw e;
+      } 
+      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();
+        synchronized (lock) {
+          if(t instanceof GemFireSecurityException) {
+            queueConnections = queueConnections.setPrimaryDiscoveryFailed((GemFireSecurityException) t);
+          } else {
+            queueConnections = queueConnections.setPrimaryDiscoveryFailed(null);
+          }
+          lock.notifyAll();
+          pool.getCancelCriterion().checkCancelInProgress(t);
+          logError(LocalizedStrings.QueueManagerImpl_ERROR_IN_REDUNDANCY_SATISFIER, t);
+        }
+      }
+
+      scheduleRedundancySatisfierIfNeeded(redundancyRetryInterval);
+    }
+
+    public boolean cancel() {
+      synchronized (lock) {
+        if(isCancelled) {
+          return false;
+        }
+        isCancelled = true;
+        future.cancel(false);
+        redundancySatisfierTask = null;
+        return true;
+      }
+    }
+
+  }
+
+  public static void loadEmergencyClasses() {
+    QueueConnectionImpl.loadEmergencyClasses();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueState.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueState.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueState.java
new file mode 100755
index 0000000..e4df40a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueState.java
@@ -0,0 +1,17 @@
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.concurrent.ScheduledExecutorService;
+import com.gemstone.gemfire.internal.cache.EventID;
+
+public interface QueueState {
+
+  public void processMarker();
+  public boolean getProcessedMarker();
+  public void incrementInvalidatedStats();
+  public boolean verifyIfDuplicate(EventID eventId, boolean addToMap);
+  public boolean verifyIfDuplicate(EventID eventId);
+  /** test hook
+   */
+  public java.util.Map getThreadIdToSequenceIdMap();
+  public void start(ScheduledExecutorService timer, int interval);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueStateImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueStateImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueStateImpl.java
new file mode 100755
index 0000000..3dda60b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/QueueStateImpl.java
@@ -0,0 +1,440 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionDestroyedException;
+import com.gemstone.gemfire.cache.client.internal.PoolImpl.PoolTask;
+import com.gemstone.gemfire.internal.cache.BridgeObserver;
+import com.gemstone.gemfire.internal.cache.BridgeObserverHolder;
+import com.gemstone.gemfire.internal.cache.EventID;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.cache.ha.ThreadIdentifier;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+public class QueueStateImpl implements QueueState {
+  private static final Logger logger = LogService.getLogger();
+
+  protected QueueManager qManager = null;
+  private boolean processedMarker = false;
+  private final AtomicInteger invalidateCount = new AtomicInteger();
+
+  /**
+   * This will store the ThreadId to latest received sequence Id
+   * 
+   * Keys are instances of {@link ThreadIdentifier} Values are instances of
+   * {@link SequenceIdAndExpirationObject}
+   */
+  protected final Map threadIdToSequenceId = new LinkedHashMap();
+
+  public QueueStateImpl(QueueManager qm) {
+    this.qManager = qm;
+  }
+
+  public void processMarker() {
+    if (!this.processedMarker) {     
+      handleMarker();
+      this.processedMarker = true;
+    } else {
+      if (logger.isDebugEnabled()) {
+        logger.debug("{}: extra marker received", this);
+      }
+    }
+  }
+
+  public boolean getProcessedMarker() {
+    return this.processedMarker;
+  }
+
+  public void handleMarker() {
+    ArrayList regions = new ArrayList();
+    Cache cache = GemFireCacheImpl.getInstance();
+    if (cache == null) {
+      return;
+    }
+
+    Set rootRegions = cache.rootRegions();
+
+    
+    for (Iterator iter1 = rootRegions.iterator(); iter1.hasNext();) {
+      Region rootRegion = (Region) iter1.next();
+      regions.add(rootRegion);
+      try {
+        Set subRegions = rootRegion.subregions(true); // throws RDE
+        for (Iterator iter2 = subRegions.iterator(); iter2.hasNext();) {
+          regions.add(iter2.next());
+        }
+      } catch (RegionDestroyedException e) {
+        continue; // region is gone go to the next one bug 38705
+      }
+    }
+
+    for (Iterator iter = regions.iterator(); iter.hasNext();) {
+      LocalRegion region = (LocalRegion) iter.next();
+      try {
+        if (region.getAttributes().getPoolName()!=null && region.getAttributes().getPoolName().equals(qManager.getPool().getName())) {
+          region.handleMarker(); // can this throw RDE??
+        }
+      }
+      catch (RegionDestroyedException e) {
+        continue; // region is gone go to the next one bug 38705
+      }
+    }
+  }
+
+  public void incrementInvalidatedStats() {
+    this.invalidateCount.incrementAndGet();
+
+  }
+  public int getInvalidateCount() {
+    return this.invalidateCount.get();
+  }
+  
+  /** test hook
+   */
+  public Map getThreadIdToSequenceIdMap() {
+    return this.threadIdToSequenceId;
+  }
+  
+  public boolean verifyIfDuplicate(EventID eid) {
+    return verifyIfDuplicate(eid, true);  
+  }
+  
+  public boolean verifyIfDuplicate(EventID eid, boolean addToMap) {
+    ThreadIdentifier tid = new ThreadIdentifier(eid.getMembershipID(), eid
+        .getThreadID());
+    long seqId = eid.getSequenceID();
+    SequenceIdAndExpirationObject seo = null;
+
+    // Fix 36930: save the max sequence id for each non-putAll operation's thread
+    // There're totally 3 cases to consider:
+    // check the tid:
+    // 1) if duplicated, (both putall or non-putall): reject
+    // 2) if not duplicate
+    //    2.1)if putAll, check via real thread id again, 
+    //        if duplicate, reject (because one non-putall operation with bigger 
+    //        seqno has happened) 
+    //        otherwise save the putAllSeqno for real thread id 
+    //        and save seqno for tid
+    //    2.2) if not putAll, 
+    //        check putAllSequenceId with real thread id
+    //        if request's seqno is smaller, reject (because one putAll operation
+    //         with bigger seqno has happened)
+    //        otherwise, update the seqno for tid
+    // lock taken to avoid concurrentModification
+    // while the objects are being expired
+    synchronized (this.threadIdToSequenceId) {
+      seo = (SequenceIdAndExpirationObject) this.threadIdToSequenceId.get(tid);
+      if (seo != null && seo.getSequenceId() >= seqId) {
+        if (logger.isDebugEnabled()) {
+          logger.debug(" got a duplicate entry with EventId {}. Ignoring the entry", eid);
+        }
+        seo.setAckSend(false); // bug #41289: send ack to this server since it's sending old events
+        // this.threadIdToSequenceId.put(tid, new SequenceIdAndExpirationObject(
+        // seo.getSequenceId()));
+        return true;
+      }
+      else if (addToMap) {
+        ThreadIdentifier real_tid = new ThreadIdentifier(eid.getMembershipID(), 
+            ThreadIdentifier.getRealThreadIDIncludingWan(eid.getThreadID()));
+        if  (ThreadIdentifier.isPutAllFakeThreadID(eid.getThreadID())) {
+          // it's a putAll
+          seo = (SequenceIdAndExpirationObject) this.threadIdToSequenceId.get(real_tid);
+          if (seo != null && seo.getSequenceId() >= seqId) {
+            if (logger.isDebugEnabled()) {
+              logger.debug("got a duplicate putAll entry with eventId {}. Other operation with same thread id and bigger seqno {} has happened. Ignoring the entry", eid, seo.getSequenceId());
+            }
+            seo.setAckSend(false); // bug #41289: send ack to servers that send old events
+            return true;
+          }
+          else {
+            // save the seqno for real thread id into a putAllSequenceId 
+            this.threadIdToSequenceId.remove(real_tid);
+            this.threadIdToSequenceId.put(real_tid, seo == null? 
+                new SequenceIdAndExpirationObject(-1, seqId): 
+                new SequenceIdAndExpirationObject(seo.getSequenceId(), seqId));
+            // save seqno for tid
+            // here tid!=real_tid, for fake tid, putAllSeqno should be 0
+            this.threadIdToSequenceId.remove(tid);
+            this.threadIdToSequenceId.put(tid, new SequenceIdAndExpirationObject(seqId, -1));
+          }
+        } else {
+          // non-putAll operation:
+          // check putAllSeqno for real thread id
+          // if request's seqno is smaller, reject
+          // otherwise, update the seqno for tid
+          seo = (SequenceIdAndExpirationObject) this.threadIdToSequenceId.get(real_tid);
+          if (seo != null && seo.getPutAllSequenceId() >= seqId) {
+            if (logger.isDebugEnabled()) {
+              logger.debug("got a duplicate non-putAll entry with eventId {}. One putAll operation with same real thread id and bigger seqno {} has happened. Ignoring the entry", eid, seo.getPutAllSequenceId());
+            }
+            seo.setAckSend(false); // bug #41289: send ack to servers that send old events
+            return true;
+          }
+          else {
+            // here tid==real_tid
+            this.threadIdToSequenceId.remove(tid);
+            this.threadIdToSequenceId.put(tid, seo == null? 
+                new SequenceIdAndExpirationObject(seqId, -1):
+                new SequenceIdAndExpirationObject(seqId, seo.getPutAllSequenceId()));
+          }
+        }
+      }
+    }
+    return false;
+  }
+  public void start(ScheduledExecutorService timer, int interval) {
+    timer.scheduleWithFixedDelay(new ThreadIdToSequenceIdExpiryTask(),
+                              interval, interval, TimeUnit.MILLISECONDS);
+  }
+  
+  /**
+   * 
+   * Thread which will iterate over threadIdToSequenceId map
+   * 
+   * 1)It will send an ack primary server for all threadIds for which it has not
+   * send an ack. 2)It will expire the entries which have exceeded the specified
+   * expiry time and for which ack has been alerady sent.
+   * 
+   * @author darrel
+   * @author Mitul Bid
+   * @author Suyog Bhokare
+   * @since 5.1
+   * 
+   */
+
+  private class ThreadIdToSequenceIdExpiryTask extends PoolTask {
+    /**
+     * The expiry time of the entries in the map
+     */
+    private final long expiryTime;
+
+    /**
+     * The peridic ack interval for client
+     */
+//     private final long ackTime;
+//       ackTime = QueueStateImpl.this.qManager.getPool().getQueueAckInterval();
+
+//     /**
+//      * boolean to specify if the thread should continue running
+//      */
+//     private volatile boolean continueRunning = true;
+
+    /**
+     * constructs the Thread and initializes the expiry time
+     * 
+     */
+    public ThreadIdToSequenceIdExpiryTask() {
+      expiryTime = QueueStateImpl.this.qManager.getPool()
+          .getSubscriptionMessageTrackingTimeout();
+    }
+    
+    @Override
+    public void run2() {
+      SystemFailure.checkFailure();
+      if (qManager.getPool().getCancelCriterion().cancelInProgress() != null) {
+        return;
+      }
+      if (PoolImpl.BEFORE_SENDING_CLIENT_ACK_CALLBACK_FLAG) {
+        BridgeObserver bo = BridgeObserverHolder.getInstance();
+        bo.beforeSendingClientAck();
+      }
+      //if ((qManager.getPool().getSubscriptionRedundancy() != 0) || (qManager.getPool().isDurableClient())) {
+        sendPeriodicAck();
+      //}
+      checkForExpiry();
+    }
+
+//     void shutdown() {
+//       synchronized (this) {
+//         continueRunning = false;
+//         this.notify();
+//         // Since the wait is timed, it is not necessary to interrupt
+//         // the thread; it will wake up of its own accord.
+//         // this.interrupt();
+//       }
+//       try {
+//         this.join();
+//       } catch (InterruptedException e) {
+//         Thread.currentThread().interrupt();
+//         // TODO:
+//       }
+//     }
+
+    void checkForExpiry() {
+      synchronized (threadIdToSequenceId) {
+        Iterator iterator = threadIdToSequenceId.entrySet().iterator();
+        long currentTime = System.currentTimeMillis();
+        Map.Entry entry;
+        SequenceIdAndExpirationObject seo;
+
+        while (iterator.hasNext()) {
+          entry = (Map.Entry) iterator.next();
+          seo = (SequenceIdAndExpirationObject) entry.getValue();
+          if ((currentTime - seo.getCreationTime() > this.expiryTime)) {
+            if (seo.getAckSend()
+                || (qManager.getPool().getSubscriptionRedundancy() == 0 && !qManager.getPool().isDurableClient())) {
+              iterator.remove();
+            }
+          } else {
+            break;
+          }
+        }
+      }
+    }
+
+    /**
+     * Sends Periodic ack to the primary server for all threadIds for which it
+     * has not send an ack.
+     */
+    void sendPeriodicAck() {
+      List events = new ArrayList();
+      boolean success = false;
+      synchronized (threadIdToSequenceId) {
+        Iterator iterator = threadIdToSequenceId.entrySet().iterator();
+        while (iterator.hasNext()) {
+          Map.Entry entry = (Map.Entry) iterator.next();
+          SequenceIdAndExpirationObject seo = (SequenceIdAndExpirationObject) entry
+              .getValue();
+          if (!seo.getAckSend()) {
+            ThreadIdentifier tid = (ThreadIdentifier) entry.getKey();
+            events.add(new EventID(tid.getMembershipID(), tid.getThreadID(),
+                seo.getSequenceId()));
+            seo.setAckSend(true);
+            // entry.setValue(entry);
+          }// if ends
+        }// while ends
+      }// synchronized ends
+
+      if (events.size() > 0) {
+        try {
+          PrimaryAckOp.execute(qManager.getAllConnections().getPrimary(), qManager.getPool(), events);
+          success = true;
+        } catch (Exception ex) {
+          if (logger.isDebugEnabled())
+            logger.debug("Exception while sending an ack to the primary server: {}", ex);
+        } finally {
+          if (!success) {
+            Iterator iter = events.iterator();
+            while (iter.hasNext()) {
+              EventID eid = (EventID) iter.next();
+              ThreadIdentifier tid = new ThreadIdentifier(
+                  eid.getMembershipID(), eid.getThreadID());
+              synchronized (threadIdToSequenceId) {
+                SequenceIdAndExpirationObject seo = (SequenceIdAndExpirationObject) threadIdToSequenceId
+                    .get(tid);
+                if (seo != null && seo.getAckSend()) {
+                  seo = (SequenceIdAndExpirationObject) threadIdToSequenceId
+                      .remove(tid);
+                  if (seo != null) {
+                    // put back the old seqId with a new time stamp
+                    SequenceIdAndExpirationObject siaeo = new SequenceIdAndExpirationObject(
+                        seo.getSequenceId(), seo.getPutAllSequenceId());
+                    threadIdToSequenceId.put(tid, siaeo);
+                  }
+                }// if ends
+              }// synchronized ends
+            }// while ends
+          }// if(!success) ends
+        }// finally ends
+      }// if(events.size() > 0)ends
+    }// method ends
+  }
+
+  /**
+   * A class to store sequenceId and the creation time of the object to be used
+   * for expiring the entry
+   * 
+   * @author Mitul Bid
+   * @since 5.1
+   * 
+   */
+  public static class SequenceIdAndExpirationObject {
+    /** The sequence Id of the entry * */
+    private final long sequenceId;
+    /** The sequence Id of the putAll operations * */
+    private final long putAllSequenceId;
+    /** The time of creation of the object* */
+    private final long creationTime;
+    /** Client ack is send to server or not* */
+    private boolean ackSend;
+
+    SequenceIdAndExpirationObject(long sequenceId, long putAllSequenceId) {
+      this.sequenceId = sequenceId;
+      this.putAllSequenceId = putAllSequenceId;
+      this.creationTime = System.currentTimeMillis();
+      this.ackSend = false;
+    }
+
+    /**
+     * @return Returns the creationTime.
+     */
+    public final long getCreationTime() {
+      return creationTime;
+    }
+
+    /**
+     * @return Returns the sequenceId.
+     */
+    public final long getSequenceId() {
+      return sequenceId;
+    }
+
+    /**
+     * @return Returns the putAllSequenceId.
+     */
+    public final long getPutAllSequenceId() {
+      return putAllSequenceId;
+    }
+
+    /**
+     * 
+     * @return Returns the ackSend
+     */
+    public boolean getAckSend() {
+      return ackSend;
+    }
+
+    /**
+     * Sets the ackSend
+     * 
+     * @param ackSend
+     */
+    public void setAckSend(boolean ackSend) {
+      this.ackSend = ackSend;
+    }
+
+    @Override
+    public String toString() {
+      StringBuffer sb = new StringBuffer();
+      sb.append("SequenceIdAndExpirationObject[");
+      sb.append("ackSend = " + this.ackSend);
+      sb.append("; creation = " + creationTime);
+      sb.append("; seq = " + sequenceId);
+      sb.append("; putAll seq = " + putAllSequenceId);
+      sb.append("]");
+      return sb.toString();
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ReadyForEventsOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ReadyForEventsOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ReadyForEventsOp.java
new file mode 100644
index 0000000..8d598d1
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ReadyForEventsOp.java
@@ -0,0 +1,82 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().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/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterDataSerializersOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterDataSerializersOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterDataSerializersOp.java
new file mode 100644
index 0000000..c3ab84b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterDataSerializersOp.java
@@ -0,0 +1,129 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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.BridgeObserver;
+import com.gemstone.gemfire.internal.cache.BridgeObserverHolder;
+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) {
+        BridgeObserver bo = BridgeObserverHolder.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) {
+        BridgeObserver bo = BridgeObserverHolder.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().send(false);
+    }
+  }
+}


[41/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/BackupStatusImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/BackupStatusImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/BackupStatusImpl.java
new file mode 100644
index 0000000..60e078d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/BackupStatusImpl.java
@@ -0,0 +1,53 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
+
+import com.gemstone.gemfire.admin.BackupStatus;
+import com.gemstone.gemfire.cache.persistence.PersistentID;
+import com.gemstone.gemfire.distributed.DistributedMember;
+
+/**
+ * Holds the result of a backup operation.
+ * 
+ * @author dsmith
+ *
+ */
+public class BackupStatusImpl implements BackupStatus, Serializable {
+  private static final long serialVersionUID = 3704162840296921840L;
+  
+  private Map<DistributedMember, Set<PersistentID>> backedUpDiskStores;
+  private Set<PersistentID> offlineDiskStores;
+  
+  public BackupStatusImpl(
+      Map<DistributedMember, Set<PersistentID>> backedUpDiskStores,
+      Set<PersistentID> offlineDiskStores) {
+    super();
+    this.backedUpDiskStores = backedUpDiskStores;
+    this.offlineDiskStores = offlineDiskStores;
+  }
+
+  public Map<DistributedMember, Set<PersistentID>> getBackedUpDiskStores() {
+    return backedUpDiskStores;
+  }
+
+  public Set<PersistentID> getOfflineDiskStores() {
+    return offlineDiskStores;
+  }
+
+  @Override
+  public String toString() {
+    return "BackupStatus[backedUpDiskStores=" + backedUpDiskStores + ", offlineDiskStores=" + offlineDiskStores + "]"; 
+  }
+  
+  
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/CacheHealthConfigImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/CacheHealthConfigImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/CacheHealthConfigImpl.java
new file mode 100644
index 0000000..d06dee7
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/CacheHealthConfigImpl.java
@@ -0,0 +1,83 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.*;
+
+/**
+ * The implementation of <code>CacheHealthConfig</code>
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ */
+public abstract class CacheHealthConfigImpl
+  extends MemberHealthConfigImpl implements CacheHealthConfig {
+
+  /** The maximum number of milliseconds a
+   * <code>netSearch</code> operation can take before the cache member
+   * is considered to be unhealthy. */
+  private long maxNetSearchTime = DEFAULT_MAX_NET_SEARCH_TIME;
+
+  /** The maximum mumber of milliseconds a cache
+   * <code>load</code> operation can take before the cache member is
+   * considered to be unhealthy. */
+  private long maxLoadTime = DEFAULT_MAX_LOAD_TIME;
+
+  /** The minimum hit ratio of a healthy cache member. */
+  private double minHitRatio = DEFAULT_MIN_HIT_RATIO;
+
+  /** The maximum number of entries in the event delivery queue
+   * of a healthy cache member. */
+  private long maxEventQueueSize = DEFAULT_MAX_EVENT_QUEUE_SIZE;
+
+  ///////////////////////  Constructors  ///////////////////////
+
+  /**
+   * Creates a new <code>CacheHealthConfigImpl</code> with the default
+   * configuration.
+   */
+  CacheHealthConfigImpl() {
+
+  }
+
+  //////////////////////  Instance Methods  /////////////////////
+
+  public long getMaxNetSearchTime() {
+    return this.maxNetSearchTime;
+  }
+
+  public void setMaxNetSearchTime(long maxNetSearchTime) {
+    this.maxNetSearchTime = maxNetSearchTime;
+  }
+
+  public long getMaxLoadTime() {
+    return this.maxLoadTime;
+  }
+
+  public void setMaxLoadTime(long maxLoadTime) {
+    this.maxLoadTime = maxLoadTime;
+  }
+
+  public double getMinHitRatio() {
+    return this.minHitRatio;
+  }
+
+  public void setMinHitRatio(double minHitRatio) {
+    this.minHitRatio = minHitRatio;
+  }
+
+  public long getMaxEventQueueSize() {
+    return this.maxEventQueueSize;
+  }
+
+  public void setMaxEventQueueSize(long maxEventQueueSize) {
+    this.maxEventQueueSize = maxEventQueueSize;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/CacheHealthEvaluator.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/CacheHealthEvaluator.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/CacheHealthEvaluator.java
new file mode 100644
index 0000000..e9b89e0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/CacheHealthEvaluator.java
@@ -0,0 +1,315 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.util.List;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.admin.CacheHealthConfig;
+import com.gemstone.gemfire.admin.GemFireHealthConfig;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.distributed.internal.DM;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.internal.OSProcess;
+import com.gemstone.gemfire.internal.cache.CacheLifecycleListener;
+import com.gemstone.gemfire.internal.cache.CachePerfStats;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * Contains the logic for evaluating the health of a GemFire
+ * <code>Cache</code> instance according to the thresholds provided in
+ * a {@link CacheHealthConfig}.
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ */
+class CacheHealthEvaluator extends AbstractHealthEvaluator 
+  implements CacheLifecycleListener {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  /** The config from which we get the evaulation criteria */
+  private CacheHealthConfig config;
+
+  /** The description of the cache being evaluated */
+  private String description;
+
+  /** Statistics about the <code>Cache</code> instance.  If no cache
+   * has been created in this VM, this field will be <code>null</code>
+   */
+  private CachePerfStats cacheStats;
+
+  /** The previous value of the netsearchTime stat (in nanoseconds) */
+  private long prevNetsearchTime;
+
+  /** The previous value of the netsearchedCompleted stat */
+  private long prevNetsearchesCompleted;
+
+  /** The previous value of the loadTime stat (in nanoseconds) */
+  private long prevLoadTime;
+
+  /** The previous value of the loadedCompleted stat */
+  private long prevLoadsCompleted;
+
+  /** The previous value of the gets stat */
+  private long prevGets;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>CacheHealthEvaluator</code>
+   */
+  CacheHealthEvaluator(GemFireHealthConfig config,
+                       DM dm) {
+    super(config, dm);
+
+    this.config = config;
+    InternalDistributedSystem system = dm.getSystem();
+    GemFireCacheImpl cache;
+    try {
+      cache = (GemFireCacheImpl) CacheFactory.getInstance(system);
+
+    } catch (CancelException ex) {
+      // No cache in this VM
+      cache = null;
+    }
+
+    initialize(cache, dm);
+    GemFireCacheImpl.addCacheLifecycleListener(this);
+  }
+
+  ////////////////////  Instance Methods  ////////////////////
+
+  @Override
+  protected String getDescription() {
+    return this.description;
+  }
+
+  /**
+   * Initializes the state of this evaluator based on the given cache
+   * instance. 
+   */
+  private void initialize(GemFireCacheImpl cache, DM dm) {
+    StringBuffer sb = new StringBuffer();
+    if (cache != null) {
+      this.cacheStats = cache.getCachePerfStats();
+
+      sb.append("Cache \"");
+      sb.append(cache.getName());
+      sb.append("\"");
+
+    } else {
+      sb.append("No Cache");
+    }
+
+    sb.append(" in member ");
+    sb.append(dm.getId());
+    int pid = OSProcess.getId();
+    if (pid != 0) {
+      sb.append(" with pid ");
+      sb.append(pid);
+    }
+    this.description = sb.toString();
+  }
+
+  public void cacheCreated(GemFireCacheImpl cache) {
+    InternalDistributedSystem system =
+      (InternalDistributedSystem) cache.getDistributedSystem();
+    DM dm = system.getDistributionManager();
+    initialize(cache, dm);
+  }
+
+  /**
+   * Checks to make sure that the average <code>netSearch</code> time
+   * during the previous health check interval is less than the
+   * {@linkplain CacheHealthConfig#getMaxNetSearchTime threshold}.  If
+   * not, the status is "okay" health.
+   *
+   * @see CachePerfStats#getNetsearchTime
+   * @see CachePerfStats#getNetsearchesCompleted
+   */
+  void checkNetSearchTime(List status) {
+    if (this.cacheStats == null || isFirstEvaluation() ||
+        this.cacheStats.isClosed()) {
+      return;
+    }
+
+    long deltaNetsearchTime =
+      this.cacheStats.getNetsearchTime() - this.prevNetsearchTime;
+    long deltaNetsearchesCompleted =
+      this.cacheStats.getNetsearchesCompleted() -
+      this.prevNetsearchesCompleted;
+
+    if (deltaNetsearchesCompleted != 0) {
+      long ratio = deltaNetsearchTime / deltaNetsearchesCompleted;
+      ratio /= 1000000;
+      long threshold = this.config.getMaxNetSearchTime();
+        
+      if (ratio > threshold) {
+        String s = LocalizedStrings.CacheHealthEvaluator_THE_AVERAGE_DURATION_OF_A_CACHE_NETSEARCH_0_MS_EXCEEDS_THE_THRESHOLD_1_MS.toLocalizedString(new Object[] { ratio, threshold });
+        status.add(okayHealth(s));
+      }
+    }
+  }
+
+  /**
+   * Checks to make sure that the average <code>load</code> time
+   * during the previous health check interval is less than the
+   * {@linkplain CacheHealthConfig#getMaxLoadTime threshold}.  If
+   * not, the status is "okay" health.
+   *
+   * @see CachePerfStats#getLoadTime
+   * @see CachePerfStats#getLoadsCompleted
+   */
+  void checkLoadTime(List status) {
+    if (this.cacheStats == null || isFirstEvaluation() ||
+        this.cacheStats.isClosed()) {
+      return;
+    }
+
+    if (!isFirstEvaluation()) {
+      long deltaLoadTime =
+        this.cacheStats.getLoadTime() - this.prevLoadTime;
+      long deltaLoadsCompleted =
+        this.cacheStats.getLoadsCompleted() -
+        this.prevLoadsCompleted;
+
+      if (logger.isDebugEnabled()) {
+        logger.debug("Completed {} loads in {} ms", deltaLoadsCompleted, (deltaLoadTime / 1000000));
+      }
+
+      if (deltaLoadsCompleted != 0) {
+        long ratio = deltaLoadTime / deltaLoadsCompleted;
+        ratio /= 1000000;
+        long threshold = this.config.getMaxLoadTime();
+        
+        if (ratio > threshold) {
+          String s = LocalizedStrings.CacheHealthEvaluator_THE_AVERAGE_DURATION_OF_A_CACHE_LOAD_0_MS_EXCEEDS_THE_THRESHOLD_1_MS.toLocalizedString(new Object[] { ratio, threshold });
+          if (logger.isDebugEnabled()) {
+            logger.debug(s);
+          }
+          status.add(okayHealth(s));
+        }
+      }
+    }
+  }
+
+  /**
+   * Checks to make sure that the cache hit ratio during the previous
+   * health check interval is less than the {@linkplain
+   * CacheHealthConfig#getMinHitRatio threshold}.  If not, the status
+   * is "okay" health.
+   *
+   * <P>
+   *
+   * The following formula is used to compute the hit ratio:
+   *
+   * <PRE>
+   * hitRatio = (gets - (loadsCompleted + netsearchesCompleted)) / (gets)
+   * </PRE>
+   *
+   *
+   * @see CachePerfStats#getGets
+   * @see CachePerfStats#getLoadsCompleted
+   * @see CachePerfStats#getNetsearchesCompleted
+   */
+  void checkHitRatio(List status) {
+    if (this.cacheStats == null || isFirstEvaluation() ||
+        this.cacheStats.isClosed()) {
+      return;
+    }
+
+    long deltaGets = this.cacheStats.getGets() - this.prevGets;
+    if (deltaGets != 0) {
+      long deltaLoadsCompleted =
+        this.cacheStats.getLoadsCompleted() - this.prevLoadsCompleted;
+      long deltaNetsearchesCompleted =
+        this.cacheStats.getNetsearchesCompleted() -
+        this.prevNetsearchesCompleted;
+
+      double hits =
+        (deltaGets -
+                (deltaLoadsCompleted + deltaNetsearchesCompleted));
+      double hitRatio = hits / deltaGets;
+      double threshold = this.config.getMinHitRatio();
+      if (hitRatio < threshold) {
+        String s = "The hit ratio of this Cache (" + hitRatio +
+          ") is below the threshold (" + threshold + ")";
+        status.add(okayHealth(s));
+      }
+    }
+  }
+
+  /**
+   * Checks to make sure that the {@linkplain
+   * CachePerfStats#getEventQueueSize cache event queue size} does
+   * not exceed the {@linkplain CacheHealthConfig#getMaxEventQueueSize
+   * threshold}.  If it does, the status is "okay" health.
+   */
+  void checkEventQueueSize(List status) {
+    if (this.cacheStats == null || isFirstEvaluation() ||
+        this.cacheStats.isClosed()) {
+      return;
+    }
+
+    long eventQueueSize = this.cacheStats.getEventQueueSize();
+    long threshold = this.config.getMaxEventQueueSize();
+    if (eventQueueSize > threshold) {
+      String s = LocalizedStrings.CacheHealthEvaluator_THE_SIZE_OF_THE_CACHE_EVENT_QUEUE_0_MS_EXCEEDS_THE_THRESHOLD_1_MS.toLocalizedString(new Object[] { Long.valueOf(eventQueueSize), Long.valueOf(threshold) });
+      status.add(okayHealth(s));
+    }
+  }
+
+
+  /**
+   * Updates the previous values of statistics
+   */
+  private void updatePrevious() {
+    if (this.cacheStats != null && !this.cacheStats.isClosed()) {
+      this.prevLoadTime = this.cacheStats.getLoadTime();
+      this.prevLoadsCompleted = this.cacheStats.getLoadsCompleted();
+      this.prevNetsearchTime = this.cacheStats.getNetsearchTime();
+      this.prevNetsearchesCompleted =
+        this.cacheStats.getNetsearchesCompleted();
+      this.prevGets = this.cacheStats.getGets();
+
+    } else {
+      this.prevLoadTime = 0L;
+      this.prevLoadsCompleted = 0L;
+      this.prevNetsearchTime = 0L;
+      this.prevNetsearchesCompleted = 0L;
+      this.prevGets = 0L;
+    }
+  }
+
+  @Override
+  protected void check(List status) {
+
+    checkNetSearchTime(status);
+    checkLoadTime(status);
+    checkHitRatio(status);
+    checkEventQueueSize(status);
+
+    updatePrevious();
+  }
+
+  @Override
+  public void close() {
+    GemFireCacheImpl.removeCacheLifecycleListener(this);
+  }
+
+  @Override
+  public void cacheClosed(GemFireCacheImpl cache) {
+    // do nothing
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/CacheServerConfigImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/CacheServerConfigImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/CacheServerConfigImpl.java
new file mode 100644
index 0000000..4e4e6b1
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/CacheServerConfigImpl.java
@@ -0,0 +1,127 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.CacheServerConfig;
+import com.gemstone.gemfire.admin.CacheVmConfig;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.internal.admin.GemFireVM;
+
+/**
+ * An implementation of <code>CacheVmConfig</code>
+ *
+ * @author David Whitlock
+ * @since 4.0
+ */
+public class CacheServerConfigImpl extends ManagedEntityConfigImpl 
+  implements CacheVmConfig, CacheServerConfig {
+
+  /** Declarative caching XML file that is used to initialize the
+   * Cache in the cache server. */
+  private String cacheXMLFile;
+
+  /** Extra classpath for the cache server */
+  private String classpath;
+
+  ///////////////////////  Constructors  ///////////////////////
+
+  /**
+   * Creates a new <code>CacheServerConfigImpl</code> with the default
+   * configuration settings.
+   */
+  public CacheServerConfigImpl() {
+    this.cacheXMLFile = null;
+    this.classpath = null;
+  }
+
+  /**
+   * Creates a new <code>CacheServerConfigImpl</code> for a running
+   * cache server.
+   */
+  public CacheServerConfigImpl(GemFireVM vm) {
+    super(vm);
+
+    String name = DistributionConfig.CACHE_XML_FILE_NAME;
+    this.cacheXMLFile = vm.getConfig().getAttribute(name);
+    this.classpath = null;
+  }
+
+  /**
+   * Copy constructor
+   */
+  public CacheServerConfigImpl(CacheServerConfig other) {
+    super(other);
+    this.cacheXMLFile = other.getCacheXMLFile();
+    this.classpath = other.getClassPath();
+  }
+
+  /**
+   * Copy constructor
+   */
+  public CacheServerConfigImpl(CacheVmConfig other) {
+    super(other);
+    this.cacheXMLFile = other.getCacheXMLFile();
+    this.classpath = other.getClassPath();
+  }
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  public String getCacheXMLFile() {
+    return this.cacheXMLFile;
+  }
+
+  public void setCacheXMLFile(String cacheXMLFile) {
+    checkReadOnly();
+    this.cacheXMLFile = cacheXMLFile;
+    configChanged();
+  }
+
+  public String getClassPath() {
+    return this.classpath;
+  }
+
+  public void setClassPath(String classpath) {
+    checkReadOnly();
+    this.classpath = classpath;
+    configChanged();
+  }
+
+  @Override
+  public void validate() {
+    super.validate();
+
+    // Nothing to validate really.  Cache.xml file could live on
+    // different file system.
+  }
+
+  /**
+   * Currently, listeners are not supported on the locator config.
+   */
+  @Override
+  protected void configChanged() {
+
+  }
+
+  @Override
+  public Object clone() throws CloneNotSupportedException {
+    return new CacheServerConfigImpl((CacheVmConfig)this);
+  }
+
+  @Override
+  public String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.append(super.toString());
+    sb.append(" cacheXMLFile=");
+    sb.append(this.getCacheXMLFile());
+    sb.append(" classPath=");
+    sb.append(this.getClassPath());
+
+    return sb.toString();    
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/CacheServerImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/CacheServerImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/CacheServerImpl.java
new file mode 100644
index 0000000..00f2b5b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/CacheServerImpl.java
@@ -0,0 +1,190 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.*;
+import com.gemstone.gemfire.distributed.internal.DM;
+import com.gemstone.gemfire.distributed.internal.DistributionManager;
+import com.gemstone.gemfire.internal.admin.GemFireVM;
+import com.gemstone.gemfire.internal.admin.remote.RemoteApplicationVM;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+/**
+ * Implements the administrative interface to a cache server.
+ *
+ * @author David Whitlock
+ * @since 3.5
+ */
+public class CacheServerImpl extends ManagedSystemMemberImpl
+  implements CacheVm, CacheServer {
+
+  /** How many new <code>CacheServer</code>s have been created? */
+  private static int newCacheServers = 0;
+
+  ///////////////////////  Instance Fields  ///////////////////////
+
+  /** The configuration object for this cache server */
+  private final CacheServerConfigImpl config;
+
+  /////////////////////////  Constructors  ////////////////////////
+
+  /**
+   * Creates a new <code>CacheServerImpl</code> that represents a
+   * non-existsing (unstarted) cache server in a given distributed
+   * system.
+   */
+  public CacheServerImpl(AdminDistributedSystemImpl system,
+                         CacheVmConfig config) 
+    throws AdminException {
+
+    super(system, config);
+
+    this.config = (CacheServerConfigImpl) config;
+    this.config.setManagedEntity(this);
+  }
+
+  /**
+   * Creates a new <code>CacheServerImpl</code> that represents an
+   * existing dedicated cache server in a given distributed system.
+   */
+  public CacheServerImpl(AdminDistributedSystemImpl system,
+                         GemFireVM vm) 
+    throws AdminException {
+
+    super(system, vm);
+    this.config = new CacheServerConfigImpl(vm);
+  }
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  @Override
+  public SystemMemberType getType() {
+    return SystemMemberType.CACHE_VM;
+  }
+
+  public String getNewId() {
+    synchronized (CacheServerImpl.class) {
+      return "CacheVm" + (++newCacheServers);
+    }
+  }
+
+  public void start() throws AdminException {
+    if (!needToStart()) {
+      return;
+    }
+
+    this.config.validate();
+    this.controller.start(this);
+    this.config.setManagedEntity(this);
+  }
+
+  public void stop() {
+    if (!needToStop()) {
+      return;
+    }
+
+    this.controller.stop(this);
+    // NOTE: DistributedSystem nodeLeft will then set this.manager to null
+    this.config.setManagedEntity(null);
+  }
+  
+  public boolean isRunning() {
+    DM dm = ((AdminDistributedSystemImpl)getDistributedSystem()).getDistributionManager();
+    if(dm == null) {
+      try {
+        return this.controller.isRunning(this);
+      }
+      catch (IllegalStateException e) {
+        return false;
+      }
+    }
+    return ((DistributionManager)dm).getDistributionManagerIdsIncludingAdmin().contains(getDistributedMember());
+  }
+
+  public CacheServerConfig getConfig() {
+    return this.config;
+  }
+
+  public CacheVmConfig getVmConfig() {
+    return this.config;
+  }
+
+  ////////////////////////  Command execution  ////////////////////////
+
+  public ManagedEntityConfig getEntityConfig() {
+    return this.getConfig();
+  }
+
+  public String getEntityType() {
+    // Fix bug 32564
+    return "Cache Vm";
+  }
+
+  public String getStartCommand() {
+    StringBuffer sb = new StringBuffer();
+    sb.append(this.controller.getProductExecutable(this, "cacheserver"));
+    sb.append(" start -dir=");
+    sb.append(this.getConfig().getWorkingDirectory());
+
+    String file = this.getConfig().getCacheXMLFile();
+    if (file != null && file.length() > 0) {
+      sb.append(" ");
+      sb.append(com.gemstone.gemfire.distributed.internal.DistributionConfig.CACHE_XML_FILE_NAME);
+      sb.append("=");
+      sb.append(file);
+    }
+
+    String classpath = this.getConfig().getClassPath();
+    if (classpath != null && classpath.length() > 0) {
+      sb.append(" -classpath=");
+      sb.append(classpath);
+    }
+
+    appendConfiguration(sb);
+
+    return sb.toString().trim();
+  }
+
+  public String getStopCommand() {
+    StringBuffer sb = new StringBuffer();
+    sb.append(this.controller.getProductExecutable(this, "cacheserver"));
+    sb.append(" stop -dir=");
+    sb.append(this.getConfig().getWorkingDirectory());
+
+    return sb.toString().trim();
+  }
+
+  public String getIsRunningCommand() {
+    StringBuffer sb = new StringBuffer();
+    sb.append(this.controller.getProductExecutable(this, "cacheserver"));
+    sb.append(" status -dir=");
+    sb.append(this.getConfig().getWorkingDirectory());
+
+    return sb.toString().trim();
+  }
+
+  /**
+   * Find whether this server is primary for given client (durableClientId)
+   * 
+   * @param durableClientId -
+   *                durable-id of the client
+   * @return true if the server is primary for given client
+   * 
+   * @since 5.6
+   */
+  public boolean isPrimaryForDurableClient(String durableClientId)
+  {
+    RemoteApplicationVM vm = (RemoteApplicationVM)this.getGemFireVM();
+    boolean isPrimary = false;
+    if (vm != null) {
+      isPrimary = vm.isPrimaryForDurableClient(durableClientId);
+}
+    return isPrimary;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ConfigurationParameterImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ConfigurationParameterImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ConfigurationParameterImpl.java
new file mode 100755
index 0000000..4ce4c4e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ConfigurationParameterImpl.java
@@ -0,0 +1,272 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.ConfigurationParameter;
+import com.gemstone.gemfire.admin.UnmodifiableConfigurationException;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import java.io.File;
+//import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A single configuration parameter of a system member.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ */
+public class ConfigurationParameterImpl
+implements com.gemstone.gemfire.admin.ConfigurationParameter {
+  
+  /** Identifying name of this configuration parameter */
+  protected String name;
+  /** Full description of this configuration parameter */
+  protected String description;
+  /** The current value */
+  protected Object value;
+  /** Class type of the value */
+  protected Class type;
+  /** True if this is modifiable; false if read-only */
+  protected boolean userModifiable;
+  /** List of listeners to notify when value changes */
+  private final List listeners = new ArrayList();
+  
+  // -------------------------------------------------------------------------
+  //   Constructor(s)
+  // -------------------------------------------------------------------------
+  
+  /** 
+   * Constructs new <code>ConfigurationParameterImpl</code>.
+   *
+   * @param name            the name of this parameter which cannot change
+   * @param description     full description to use
+   * @param value           the value of this parameter
+   * @param type            the class type of the value
+   * @param userModifiable  true if this is modifiable; false if read-only
+   */
+  protected ConfigurationParameterImpl(String name,
+                                       String description,
+                                       Object value,
+                                       Class type,
+                                       boolean userModifiable) {
+    if (name == null || name.length() == 0) {
+      throw new IllegalArgumentException(LocalizedStrings.ConfigurationParameterImpl_CONFIGURATIONPARAMETER_NAME_MUST_BE_SPECIFIED.toLocalizedString());
+    }
+    
+    this.name = name;
+    setInternalState(description, value, type, userModifiable);
+  }
+  
+  /** 
+   * Constructs new <code>ConfigurationParameterImpl</code>.
+   *
+   * @param name            the name of this parameter which cannot change
+   * @param value           the value of this parameter
+   */
+  protected ConfigurationParameterImpl(String name,
+                                       Object value) {
+    if (name == null || name.length() == 0) {
+      throw new IllegalArgumentException(LocalizedStrings.ConfigurationParameterImpl_CONFIGURATIONPARAMETER_NAME_MUST_BE_SPECIFIED.toLocalizedString());
+    }
+    
+    this.name = name;
+    setInternalState(name, value, value.getClass(), true);
+  }
+  
+  /** Constructor to allow serialization by subclass */
+  protected ConfigurationParameterImpl() {}
+  
+  // -------------------------------------------------------------------------
+  //   Attribute accessors and mutators
+  // -------------------------------------------------------------------------
+
+  public String getName() {
+    return this.name;
+  }
+  
+  public String getDescription() {
+    return this.description;
+  }
+  
+  public Object getValue() {
+    return this.value;
+  }
+  
+  public String getValueAsString() {
+    if (isString()) {
+      return (String) this.value;
+    }
+    else if (isInetAddress()) {
+      return InetAddressUtil.toString(this.value);
+    }
+    else if (isFile()) {
+      return this.value.toString();
+    }
+    else if (isOctal()) {
+      String strVal = Integer.toOctalString(((Integer) this.value).intValue());
+      if (!strVal.startsWith("0")) {
+        strVal = "0" + strVal;
+      }
+      return strVal;
+    }
+    else if (isArray()) {
+      List list = Arrays.asList((Object[]) this.value);
+      return list.toString();
+    }
+    else {
+      return this.value.toString();
+    }
+  }
+  
+  public Class getValueType() {
+    return this.type;
+  }
+  
+  public boolean isModifiable() {
+    return this.userModifiable;
+  }
+  
+  public boolean isArray() {
+    return "manager-parameters".equals(this.name) || 
+           "manager-classpaths".equals(this.name);
+  }
+  public boolean isInetAddress() {
+    return java.net.InetAddress.class.isAssignableFrom(this.type);
+  }
+  public boolean isFile() {
+    return java.io.File.class.equals(this.type);
+  }
+  public boolean isOctal() {
+    return "shared-memory-permissions".equals(this.name);
+  }
+  public boolean isString() {
+    return java.lang.String.class.equals(this.type);
+  }
+  
+  public void setValue(Object value) throws UnmodifiableConfigurationException {
+    if (!isModifiable()) {
+      throw new UnmodifiableConfigurationException(LocalizedStrings.ConfigurationParameterImpl_0_IS_NOT_A_MODIFIABLE_CONFIGURATION_PARAMETER.toLocalizedString(getName()));
+    }
+    if (value == null) {
+      throw new IllegalArgumentException(LocalizedStrings.ConfigurationParameterImpl_UNABLE_TO_SET_0_TO_NULL_VALUE.toLocalizedString(getName()));
+    }
+    if (!getValueType().equals(value.getClass())) {
+      throw new IllegalArgumentException(LocalizedStrings.ConfigurationParameterImpl_UNABLE_TO_SET_TYPE_0_WITH_TYPE_1.toLocalizedString(new Object[] {getValueType().getName(), value.getClass().getName()}));
+    }
+    
+    if (value instanceof String && !isString()) {
+      // we need to check what the type should be and convert to it...
+      setValueFromString((String) value);
+    }
+    else {
+      this.value = value;
+    }
+    fireConfigurationParameterValueChanged(this);
+  }
+  
+  // -------------------------------------------------------------------------
+  //   Operations for handling the registration of listeners
+  //     Note: this is only for use within impl pkg and subclass pkgs
+  // -------------------------------------------------------------------------
+  
+  /** Adds the listener for any changes to this configuration parameter. */
+  public void addConfigurationParameterListener(ConfigurationParameterListener listener) {
+    if (!this.listeners.contains(listener)) {
+      this.listeners.add(listener);
+    }
+  }
+  
+  /** Removes the listener if it's currently registered. */
+  public void removeConfigurationParameterListener(ConfigurationParameterListener listener) {
+    if (this.listeners.contains(listener)) {
+      this.listeners.remove(listener);
+    }
+  }
+
+  // -------------------------------------------------------------------------
+  //   Implementation methods
+  // -------------------------------------------------------------------------
+
+  protected void setValueFromString(String newValue) {
+    if (newValue == null) {
+      throw new IllegalArgumentException(LocalizedStrings.ConfigurationParameterImpl_UNABLE_TO_SET_0_TO_NULL_VALUE.toLocalizedString(getName()));
+    }
+
+    if (isInetAddress()) {
+      this.value = InetAddressUtil.toInetAddress(newValue);
+    }
+    else if (isFile()) {
+      this.value = new File(newValue);
+    }
+    else if (isOctal()) {
+      if (!newValue.startsWith("0")) {
+        newValue = "0" + newValue;
+      }
+      this.value = Integer.valueOf(Integer.parseInt(newValue, 8));
+    }
+    else if (isArray()) {
+      // parse it TODO
+      throw new IllegalArgumentException(LocalizedStrings.ConfigurationParameterImpl_SETTING_ARRAY_VALUE_FROM_DELIMITED_STRING_IS_NOT_SUPPORTED.toLocalizedString());
+    }
+    else {
+      this.value = newValue;
+    }
+  }
+  
+  /**
+   * Fires changed configuration parameter to registered listeners.
+   *
+   * @param parm  the configuration parameter the changed 
+   */
+  protected void fireConfigurationParameterValueChanged(ConfigurationParameter parm)  {
+    ConfigurationParameterListener[] listeners = 
+        (ConfigurationParameterListener[]) this.listeners.toArray(
+            new ConfigurationParameterListener[0]);
+    for (int i = 0; i < listeners.length; i++) {
+      listeners[i].configurationParameterValueChanged(parm);
+    }
+  }  
+  
+  /**
+   * Sets the internal state of this configuration parameter.  
+   *
+   * @param description     full description to use
+   * @param value           the value of this parameter
+   * @param type            the class type of the value
+   * @param userModifiable  true if this is modifiable; false if read-only
+   */
+  protected void setInternalState(String description,
+                                  Object value,
+                                  Class type,
+                                  boolean userModifiable) {
+    if (description == null || description.length() == 0) {
+      throw new IllegalArgumentException(LocalizedStrings.ConfigurationParameterImpl_CONFIGURATIONPARAMETER_DESCRIPTION_MUST_BE_SPECIFIED.toLocalizedString());
+    }
+    this.description = description;
+    this.type = type;
+    this.userModifiable = userModifiable;
+
+    if (value == null) {
+      throw new IllegalArgumentException(LocalizedStrings.ConfigurationParameterImpl_UNABLE_TO_SET_0_TO_NULL_VALUE.toLocalizedString(getName()));
+    }
+
+    this.value = value;
+  }
+  
+  @Override
+  public String toString() {
+    return this.name;
+  }
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ConfigurationParameterListener.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ConfigurationParameterListener.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ConfigurationParameterListener.java
new file mode 100755
index 0000000..0720465
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ConfigurationParameterListener.java
@@ -0,0 +1,26 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.ConfigurationParameter;
+
+/**
+ * Listens to value changes of a 
+ * {@link com.gemstone.gemfire.admin.ConfigurationParameter}.  This is for 
+ * internal use only to allow a {@link SystemMemberImpl} to keep track of 
+ * configuration changes made through 
+ * {@link ConfigurationParameterImpl#setValue}.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ */
+public interface ConfigurationParameterListener {
+  public void configurationParameterValueChanged(ConfigurationParameter parm);
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DisabledManagedEntityController.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DisabledManagedEntityController.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DisabledManagedEntityController.java
new file mode 100755
index 0000000..2af37a3
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DisabledManagedEntityController.java
@@ -0,0 +1,83 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.admin.DistributedSystemConfig;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
+
+/**
+ * This is a disabled implementation of ManagedEntityController for bug #47909.
+ *
+ * The old ManagedEntityController was a concrete class which has been renamed
+ * to ManagedEntityControllerImpl. The build.xml now skips building
+ * ManagedEntityControllerImpl. If ManagedEntityControllerImpl is not found
+ * in the classpath then the code uses DisabledManagedEntityController as a
+ * place holder.
+ *
+ * @author Kirk Lund
+ */
+class DisabledManagedEntityController implements ManagedEntityController {
+
+  private static final Logger logger = LogService.getLogger();
+
+  private static final String EXCEPTION_MESSAGE = "Local and remote OS command invocations are disabled for the Admin API.";
+  
+  DisabledManagedEntityController() {
+  }
+  
+  @Override
+  public void start(InternalManagedEntity entity) {
+    if (logger.isTraceEnabled(LogMarker.MANAGED_ENTITY)){
+      logger.warn(LogMarker.MANAGED_ENTITY, "DisabledManagedEntityController#start {}", EXCEPTION_MESSAGE);
+    }
+    throw new UnsupportedOperationException(EXCEPTION_MESSAGE);
+  }
+
+  @Override
+  public void stop(InternalManagedEntity entity) {
+    if (logger.isTraceEnabled(LogMarker.MANAGED_ENTITY)){
+      logger.warn(LogMarker.MANAGED_ENTITY, "DisabledManagedEntityController#stop {}", EXCEPTION_MESSAGE);
+    }
+    throw new UnsupportedOperationException(EXCEPTION_MESSAGE);
+  }
+
+  @Override
+  public boolean isRunning(InternalManagedEntity entity) {
+    if (logger.isTraceEnabled(LogMarker.MANAGED_ENTITY)){
+      logger.warn(LogMarker.MANAGED_ENTITY, "DisabledManagedEntityController#isRunning {}", EXCEPTION_MESSAGE);
+    }
+    throw new UnsupportedOperationException(EXCEPTION_MESSAGE);
+  }
+
+  @Override
+  public String getLog(DistributionLocatorImpl locator) {
+    if (logger.isTraceEnabled(LogMarker.MANAGED_ENTITY)){
+      logger.warn(LogMarker.MANAGED_ENTITY, "DisabledManagedEntityController#getLog {}", EXCEPTION_MESSAGE);
+    }
+    throw new UnsupportedOperationException(EXCEPTION_MESSAGE);
+  }
+
+  @Override
+  public String buildSSLArguments(DistributedSystemConfig config) {
+    if (logger.isTraceEnabled(LogMarker.MANAGED_ENTITY)){
+      logger.warn(LogMarker.MANAGED_ENTITY, "DisabledManagedEntityController#buildSSLArguments {}", EXCEPTION_MESSAGE);
+    }
+    throw new UnsupportedOperationException(EXCEPTION_MESSAGE);
+  }
+
+  @Override
+  public String getProductExecutable(InternalManagedEntity entity, String executable) {
+    if (logger.isTraceEnabled(LogMarker.MANAGED_ENTITY)){
+      logger.warn(LogMarker.MANAGED_ENTITY, "DisabledManagedEntityController#getProductExecutable {}", EXCEPTION_MESSAGE);
+    }
+    throw new UnsupportedOperationException(EXCEPTION_MESSAGE);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributedSystemConfigImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributedSystemConfigImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributedSystemConfigImpl.java
new file mode 100755
index 0000000..4918e29
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributedSystemConfigImpl.java
@@ -0,0 +1,1095 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.GemFireIOException;
+import com.gemstone.gemfire.admin.AdminXmlException;
+import com.gemstone.gemfire.admin.CacheServerConfig;
+import com.gemstone.gemfire.admin.CacheVmConfig;
+import com.gemstone.gemfire.admin.DistributedSystemConfig;
+import com.gemstone.gemfire.admin.DistributionLocator;
+import com.gemstone.gemfire.admin.DistributionLocatorConfig;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.distributed.internal.DistributionConfigImpl;
+import com.gemstone.gemfire.internal.Banner;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.InternalLogWriter;
+import com.gemstone.gemfire.internal.logging.LocalLogWriter;
+import com.gemstone.gemfire.internal.logging.LogConfig;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.LogWriterFactory;
+import com.gemstone.gemfire.internal.logging.LogWriterImpl;
+import com.gemstone.gemfire.internal.logging.ManagerLogWriter;
+import com.gemstone.gemfire.internal.logging.log4j.LogWriterAppender;
+import com.gemstone.org.jgroups.util.StringId;
+
+/**
+ * An implementation of the configuration object for an
+ * <code>AdminDistributedSystem</code>.  After a config has been used
+ * to create an <code>AdminDistributedSystem</code> most of the
+ * configuration attributes cannot be changed.  However, some
+ * operations (such as getting information about GemFire managers and
+ * distribution locators) are "passed through" to the
+ * <code>AdminDistributedSystem</code> associated with this
+ * configuration object.
+ *
+ * @since 3.5
+ */
+public class DistributedSystemConfigImpl 
+  implements DistributedSystemConfig {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  private String entityConfigXMLFile = DEFAULT_ENTITY_CONFIG_XML_FILE;
+  private String systemId = DEFAULT_SYSTEM_ID;
+  private String mcastAddress = DEFAULT_MCAST_ADDRESS;
+  private int mcastPort = DEFAULT_MCAST_PORT;
+  private int ackWaitThreshold = DEFAULT_ACK_WAIT_THRESHOLD;
+  private int ackSevereAlertThreshold = DEFAULT_ACK_SEVERE_ALERT_THRESHOLD;
+  private String locators = DEFAULT_LOCATORS;
+  private String bindAddress = DEFAULT_BIND_ADDRESS;
+  private String serverBindAddress = DEFAULT_BIND_ADDRESS;
+  private String remoteCommand = DEFAULT_REMOTE_COMMAND;
+  private boolean disableTcp = DEFAULT_DISABLE_TCP;
+  private boolean enableNetworkPartitionDetection = DEFAULT_ENABLE_NETWORK_PARTITION_DETECTION;
+  private boolean disableAutoReconnect = DEFAULT_DISABLE_AUTO_RECONNECT;
+  private int memberTimeout = DEFAULT_MEMBER_TIMEOUT;
+  private String membershipPortRange = getMembershipPortRangeString(DEFAULT_MEMBERSHIP_PORT_RANGE);
+  private int tcpPort = DEFAULT_TCP_PORT;
+  
+
+  private String logFile = DEFAULT_LOG_FILE;
+  private String logLevel = DEFAULT_LOG_LEVEL;
+  private int logDiskSpaceLimit = DEFAULT_LOG_DISK_SPACE_LIMIT;
+  private int logFileSizeLimit = DEFAULT_LOG_FILE_SIZE_LIMIT;
+  private int refreshInterval = DEFAULT_REFRESH_INTERVAL;
+  private Properties gfSecurityProperties = new Properties();
+
+  /** Listeners to notify when this DistributedSystemConfig changes */
+  private Set listeners = new HashSet();
+  
+  /** Configs for CacheServers that this system config is aware of */
+  private Set cacheServerConfigs = new HashSet();
+
+  /** Configs for the managed distribution locators in the distributed
+   * system */
+  private Set locatorConfigs = new HashSet();
+  
+  /** The display name of this distributed system */
+  private String systemName = DEFAULT_NAME;
+
+  /** The admin distributed system object that is configured by this
+   * config object. 
+   *
+   * @since 4.0 */
+  private AdminDistributedSystemImpl system;
+
+  /** The GemFire log writer used by the distributed system */
+  private InternalLogWriter logWriter;
+
+  
+  ///////////////////////  Static Methods  ///////////////////////
+
+  /**
+   * Filters out all properties that are unique to the admin
+   * <code>DistributedSystemConfig</code> that are not present in the
+   * internal <code>DistributionConfig</code>.
+   *
+   * @since 4.0
+   */
+  private static Properties
+    filterOutAdminProperties(Properties props) { 
+
+    Properties props2 = new Properties();
+    for (Enumeration names = props.propertyNames();
+         names.hasMoreElements(); ) {
+      String name = (String) names.nextElement();
+      if (!(ENTITY_CONFIG_XML_FILE_NAME.equals(name) ||
+            REFRESH_INTERVAL_NAME.equals(name) ||
+            REMOTE_COMMAND_NAME.equals(name)
+           )
+         ) {
+        String value = props.getProperty(name);
+        if ((name != null) && (value != null)) {
+          props2.setProperty(name, value);
+        }
+      }
+    }
+
+    return props2;
+  }
+
+  ////////////////////////  Constructors  ////////////////////////
+
+  /**
+   * Creates a new <code>DistributedSystemConfigImpl</code> based on
+   * the configuration stored in a <code>DistributedSystem</code>'s
+   * <code>DistributionConfig</code>. 
+   */
+  public DistributedSystemConfigImpl(DistributionConfig distConfig,
+                                     String remoteCommand) {
+    if (distConfig == null) {
+      throw new IllegalArgumentException(LocalizedStrings.DistributedSystemConfigImpl_DISTRIBUTIONCONFIG_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+
+    this.mcastAddress = InetAddressUtil.toString(distConfig.getMcastAddress());
+    this.mcastPort = distConfig.getMcastPort();
+    this.locators = distConfig.getLocators();
+    this.membershipPortRange = 
+                  getMembershipPortRangeString(distConfig.getMembershipPortRange());
+
+    this.systemName = distConfig.getName();
+    
+    this.sslEnabled = distConfig.getSSLEnabled();
+    this.sslCiphers = distConfig.getSSLCiphers();
+    this.sslProtocols = distConfig.getSSLProtocols();
+    this.sslAuthenticationRequired = distConfig.getSSLRequireAuthentication();
+
+    this.logFile = distConfig.getLogFile().getPath();
+    this.logLevel =
+      LogWriterImpl.levelToString(distConfig.getLogLevel());
+    this.logDiskSpaceLimit = distConfig.getLogDiskSpaceLimit();
+    this.logFileSizeLimit = distConfig.getLogFileSizeLimit();
+    
+    basicSetBindAddress(distConfig.getBindAddress());
+    this.tcpPort = distConfig.getTcpPort();
+    
+    this.disableTcp = distConfig.getDisableTcp();
+
+    this.remoteCommand = remoteCommand;
+    this.serverBindAddress = distConfig.getServerBindAddress();
+    this.enableNetworkPartitionDetection = distConfig.getEnableNetworkPartitionDetection();
+    this.memberTimeout = distConfig.getMemberTimeout();
+    this.refreshInterval = DistributedSystemConfig.DEFAULT_REFRESH_INTERVAL;
+    this.gfSecurityProperties = (Properties) distConfig.getSSLProperties().clone();
+  }
+
+  /**
+   * Zero-argument constructor to be used only by subclasses.
+   *
+   * @since 4.0
+   */
+  protected DistributedSystemConfigImpl() {
+
+  }
+  
+  /**
+   * Creates a new <code>DistributedSystemConifgImpl</code> whose
+   * configuration is specified by the given <code>Properties</code>
+   * object.
+   */
+  protected DistributedSystemConfigImpl(Properties props) {
+    this(props, false);
+  }
+
+  /**
+   * Creates a new <code>DistributedSystemConifgImpl</code> whose configuration
+   * is specified by the given <code>Properties</code> object.
+   * 
+   * @param props
+   *          The configuration properties specified by the caller
+   * @param ignoreGemFirePropsFile
+   *          whether to skip loading distributed system properties from
+   *          gemfire.properties file
+   *          
+   * @since 6.5
+   */
+  protected DistributedSystemConfigImpl(Properties props, 
+                                        boolean ignoreGemFirePropsFile) {
+    this(new DistributionConfigImpl(
+        filterOutAdminProperties(props), ignoreGemFirePropsFile), 
+        DEFAULT_REMOTE_COMMAND);
+    String remoteCommand = props.getProperty(REMOTE_COMMAND_NAME);
+    if (remoteCommand != null) {
+      this.remoteCommand = remoteCommand;
+    }
+
+    String entityConfigXMLFile =
+      props.getProperty(ENTITY_CONFIG_XML_FILE_NAME);
+    if (entityConfigXMLFile != null) {
+      this.entityConfigXMLFile = entityConfigXMLFile;
+    }
+
+    String refreshInterval =
+      props.getProperty(REFRESH_INTERVAL_NAME);
+    if (refreshInterval != null) {
+      try {
+       this.refreshInterval = Integer.parseInt(refreshInterval);
+      } catch (NumberFormatException nfEx) {
+        throw new IllegalArgumentException(LocalizedStrings.DistributedSystemConfigImpl_0_IS_NOT_A_VALID_INTEGER_1.toLocalizedString(new Object[] { refreshInterval, REFRESH_INTERVAL_NAME }));
+      }
+    }
+  }
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  /**
+   * Returns the <code>LogWriterI18n</code> to be used when administering
+   * the distributed system. Returns null if nothing has been provided via
+   * <code>setInternalLogWriter</code>.
+   *
+   * @since 4.0
+   */
+  public InternalLogWriter getInternalLogWriter() {
+    // LOG: used only for sharing between IDS, AdminDSImpl and AgentImpl -- to prevent multiple banners, etc.
+    synchronized (this) {
+      return this.logWriter;
+    }
+  }
+
+  /**
+   * Sets the <code>LogWriterI18n</code> to be used when administering the
+   * distributed system.
+   */
+  public void setInternalLogWriter(InternalLogWriter logWriter) {
+    // LOG: used only for sharing between IDS, AdminDSImpl and AgentImpl -- to prevent multiple banners, etc.
+    synchronized (this) {
+      this.logWriter = logWriter;
+    }    
+  }
+  
+  public LogConfig createLogConfig() {
+    return new LogConfig() {
+        @Override
+        public int getLogLevel() {
+          return LogWriterImpl.levelNameToCode(DistributedSystemConfigImpl.this.getLogLevel());
+        }
+        @Override
+        public File getLogFile() {
+          return new File(DistributedSystemConfigImpl.this.getLogFile());
+        }
+        @Override
+        public int getLogFileSizeLimit() {
+          return DistributedSystemConfigImpl.this.getLogFileSizeLimit();
+        }
+        @Override
+        public int getLogDiskSpaceLimit() {
+          return DistributedSystemConfigImpl.this.getLogDiskSpaceLimit();
+        }
+        @Override
+        public String getName() {
+          return DistributedSystemConfigImpl.this.getSystemName();
+        }
+        @Override
+        public String toLoggerString() {
+          return DistributedSystemConfigImpl.this.toString();
+        }
+      };
+  }
+
+  /**
+   * Marks this config object as "read only".  Attempts to modify a
+   * config object will result in a {@link IllegalStateException}
+   * being thrown.
+   *
+   * @since 4.0
+   */
+  void setDistributedSystem(AdminDistributedSystemImpl system) {
+    this.system = system;
+  }
+
+  /**
+   * Checks to see if this config object is "read only".  If it is,
+   * then an {@link IllegalStateException} is thrown.
+   *
+   * @since 4.0
+   */
+  protected void checkReadOnly() {
+    if (this.system != null) {
+      throw new IllegalStateException(LocalizedStrings.DistributedSystemConfigImpl_A_DISTRIBUTEDSYSTEMCONFIG_OBJECT_CANNOT_BE_MODIFIED_AFTER_IT_HAS_BEEN_USED_TO_CREATE_AN_ADMINDISTRIBUTEDSYSTEM.toLocalizedString());
+    }
+  }
+
+  public String getEntityConfigXMLFile() {
+    return this.entityConfigXMLFile;
+  }
+
+  public void setEntityConfigXMLFile(String xmlFile) {
+    checkReadOnly();
+    this.entityConfigXMLFile = xmlFile;
+    configChanged();
+  }
+
+  /**
+   * Parses the XML configuration file that describes managed
+   * entities.
+   *
+   * @throws AdminXmlException
+   *         If a problem is encountered while parsing the XML file.
+   */
+  private void parseEntityConfigXMLFile() {
+    String fileName = this.entityConfigXMLFile;
+    File xmlFile = new File(fileName);
+    if (!xmlFile.exists()) {
+      if (DEFAULT_ENTITY_CONFIG_XML_FILE.equals(fileName)) {
+        // Default doesn't exist, no big deal
+        return;
+      } else {
+        throw new AdminXmlException(LocalizedStrings.DistributedSystemConfigImpl_ENTITY_CONFIGURATION_XML_FILE_0_DOES_NOT_EXIST.toLocalizedString(fileName));
+      }
+    }
+
+    try {
+      InputStream is = new FileInputStream(xmlFile);
+      try {
+        ManagedEntityConfigXmlParser.parse(is, this);
+      }
+      finally {
+        is.close();
+      }
+    } 
+    catch (IOException ex) {
+      throw new AdminXmlException(LocalizedStrings.DistributedSystemConfigImpl_WHILE_PARSING_0.toLocalizedString(fileName), ex);
+    }
+  }
+
+  public String getSystemId() {
+    return this.systemId;
+  }
+
+  public void setSystemId(String systemId) {
+    checkReadOnly();
+    this.systemId = systemId;
+    configChanged();
+  }
+  
+  /** Returns the multicast address for the system */
+  public String getMcastAddress() {
+    return this.mcastAddress;
+  }
+  
+  public void setMcastAddress(String mcastAddress) {
+    checkReadOnly();
+    this.mcastAddress = mcastAddress;
+    configChanged();
+  }
+
+  /** Returns the multicast port for the system */
+  public int getMcastPort() {
+    return this.mcastPort;
+  }
+  
+  public void setMcastPort(int mcastPort) {
+    checkReadOnly();
+    this.mcastPort = mcastPort;
+    configChanged();
+  }
+
+  public int getAckWaitThreshold() {
+    return this.ackWaitThreshold;
+  }
+  
+  public void setAckWaitThreshold(int seconds) {
+    checkReadOnly();
+    this.ackWaitThreshold = seconds;
+    configChanged();
+  }
+
+  public int getAckSevereAlertThreshold() {
+    return this.ackSevereAlertThreshold;
+  }
+  
+  public void setAckSevereAlertThreshold(int seconds) {
+    checkReadOnly();
+    this.ackSevereAlertThreshold = seconds;
+    configChanged();
+  }
+
+  /** Returns the comma-delimited list of locators for the system */
+  public String getLocators() {
+    return this.locators;
+  }
+
+  public void setLocators(String locators) {
+    checkReadOnly();
+    if (locators == null) {
+      this.locators = "";
+    }
+    else {
+      this.locators = locators;
+    }
+    configChanged();
+  }
+  
+  /**
+   * Returns the value for membership-port-range
+   * 
+   * @return the value for the Distributed System property membership-port-range 
+   */
+  public String getMembershipPortRange() {
+    return this.membershipPortRange;
+  }
+
+  /**
+   * Sets the Distributed System property membership-port-range
+   * 
+   * @param membershipPortRangeStr
+   *          the value for membership-port-range given as two numbers separated 
+   *          by a minus sign.
+   */
+  public void setMembershipPortRange(String membershipPortRangeStr) {
+    /*
+     * FIXME: Setting attributes in DistributedSystemConfig has no effect on
+     * DistributionConfig which is actually used for connection with DS. This is
+     * true for all such attributes. Should be addressed in the Admin Revamp if 
+     * we want these 'set' calls to affect anything. Then we can use the 
+     * validation code in DistributionConfigImpl code.
+     */
+    checkReadOnly();
+    if (membershipPortRangeStr == null) {
+      this.membershipPortRange = getMembershipPortRangeString(DEFAULT_MEMBERSHIP_PORT_RANGE);
+    } else {
+      try {
+        if (validateMembershipRange(membershipPortRangeStr)) {
+          this.membershipPortRange = membershipPortRangeStr;
+        } else {
+          throw new IllegalArgumentException(
+              LocalizedStrings.DistributedSystemConfigImpl_INVALID_VALUE_FOR_MEMBERSHIP_PORT_RANGE
+                  .toLocalizedString(new Object[] {membershipPortRangeStr, 
+                                                   MEMBERSHIP_PORT_RANGE_NAME}));
+        }
+      } catch (Exception e) {
+        if (logger.isDebugEnabled()) {
+          logger.debug(e.getMessage(), e);
+        }
+      }
+    }
+  }
+  
+  public void setTcpPort(int port) {
+    checkReadOnly();
+    this.tcpPort = port;
+    configChanged();
+  }
+  
+  public int getTcpPort() {
+    return this.tcpPort;
+  }
+
+  /**
+   * Validates the given string - which is expected in the format as two numbers
+   * separated by a minus sign - in to an integer array of length 2 with first
+   * element as lower end & second element as upper end of the range.
+   * 
+   * @param membershipPortRange
+   *          membership-port-range given as two numbers separated by a minus
+   *          sign.
+   * @return true if the membership-port-range string is valid, false otherwise
+   */
+  private boolean validateMembershipRange(String membershipPortRange) {
+    int[] range = null;
+    if (membershipPortRange != null && membershipPortRange.trim().length() > 0) {
+      String[] splitted = membershipPortRange.split("-");
+      range = new int[2];
+      range[0] = Integer.parseInt(splitted[0].trim());
+      range[1] = Integer.parseInt(splitted[1].trim());
+      //NumberFormatException if any could be thrown
+      
+      if (range[0] < 0 || range[0] >= range[1] || 
+          range[1] < 0 || range[1] > 65535) {
+        range = null;
+      }
+    }
+    return range != null;
+  }  
+  
+  /**
+   * @return the String representation of membershipPortRange with lower & upper
+   *         limits of the port range separated by '-' e.g. 1-65535
+   */
+  private static String getMembershipPortRangeString(int[] membershipPortRange) {
+    String membershipPortRangeString = "";
+    if (membershipPortRange != null && 
+        membershipPortRange.length == 2) {
+      membershipPortRangeString = membershipPortRange[0] + "-" + 
+                                  membershipPortRange[1];
+    }
+    
+    return membershipPortRangeString;
+  }
+
+  public String getBindAddress() {
+    return this.bindAddress;
+  }
+
+  public void setBindAddress(String bindAddress) {
+    checkReadOnly();
+    basicSetBindAddress(bindAddress);
+    configChanged();
+  }
+  
+  public String getServerBindAddress() {
+    return this.serverBindAddress;
+  }
+
+  public void setServerBindAddress(String bindAddress) {
+    checkReadOnly();
+    basicSetServerBindAddress(bindAddress);
+    configChanged();
+  }
+  
+  public boolean getDisableTcp() {
+    return this.disableTcp;
+  }
+  
+  public void setDisableTcp(boolean flag) {
+    checkReadOnly();
+    disableTcp = flag;
+    configChanged();
+  }
+
+  public void setEnableNetworkPartitionDetection(boolean newValue) {
+    checkReadOnly();
+    this.enableNetworkPartitionDetection = newValue;
+    configChanged();
+  }
+  public boolean getEnableNetworkPartitionDetection() {
+    return this.enableNetworkPartitionDetection;
+  }
+  public void setDisableAutoReconnect(boolean newValue) {
+    checkReadOnly();
+    this.disableAutoReconnect = newValue;
+    configChanged();
+  }
+  public boolean getDisableAutoReconnect() {
+    return this.disableAutoReconnect;
+  }
+  public int getMemberTimeout() {
+   return this.memberTimeout;
+  }
+  public void setMemberTimeout(int value) {
+    checkReadOnly();
+    this.memberTimeout = value;
+    configChanged();
+  }
+
+  private void basicSetBindAddress(String bindAddress) {
+    if (!validateBindAddress(bindAddress)) {
+      throw new IllegalArgumentException(LocalizedStrings.DistributedSystemConfigImpl_INVALID_BIND_ADDRESS_0.toLocalizedString(bindAddress));
+    }
+    this.bindAddress = bindAddress;
+  }
+  
+  private void basicSetServerBindAddress(String bindAddress) {
+    if (!validateBindAddress(bindAddress)) {
+      throw new IllegalArgumentException(LocalizedStrings.DistributedSystemConfigImpl_INVALID_BIND_ADDRESS_0.toLocalizedString(bindAddress));
+    }
+    this.serverBindAddress = bindAddress;
+  }
+  
+  /** Returns the remote command setting to use for remote administration */
+  public String getRemoteCommand() {
+    return this.remoteCommand;
+  }
+  
+  /**
+   * Sets the remote command for this config object.  This attribute
+   * may be modified after this config object has been used to create
+   * an admin distributed system.
+   */
+  public void setRemoteCommand(String remoteCommand) {
+    if (!ALLOW_ALL_REMOTE_COMMANDS) {
+      checkRemoteCommand(remoteCommand);
+    }
+    this.remoteCommand = remoteCommand;
+    configChanged();
+  }
+  
+  private static final boolean ALLOW_ALL_REMOTE_COMMANDS = Boolean.getBoolean("gemfire.admin.ALLOW_ALL_REMOTE_COMMANDS");
+  private static final String[] LEGAL_REMOTE_COMMANDS = { "rsh", "ssh" };
+  private static final String ILLEGAL_REMOTE_COMMAND_RSH_OR_SSH = "Allowed remote commands include \"rsh {HOST} {CMD}\" or \"ssh {HOST} {CMD}\" with valid rsh or ssh switches. Invalid: ";
+  private final void checkRemoteCommand(final String remoteCommand) {
+    if (remoteCommand == null || remoteCommand.isEmpty()) {
+      return;
+    }
+    final String command = remoteCommand.toLowerCase().trim();
+    if (!command.contains("{host}") || !command.contains("{cmd}")) {
+      throw new IllegalArgumentException(ILLEGAL_REMOTE_COMMAND_RSH_OR_SSH + remoteCommand);
+    }
+    
+    final StringTokenizer tokenizer = new StringTokenizer(command, " ");
+    final ArrayList<String> array = new ArrayList<String>(); 
+    for (int i = 0; tokenizer.hasMoreTokens(); i++) {
+      String string = tokenizer.nextToken();
+      if (i == 0) {
+        // first element must be rsh or ssh
+        boolean found = false;
+        for (int j = 0; j < LEGAL_REMOTE_COMMANDS.length; j++) {
+          if (string.contains(LEGAL_REMOTE_COMMANDS[j])) {
+            // verify command is at end of string
+            if (!(string.endsWith(LEGAL_REMOTE_COMMANDS[j]) || string.endsWith(LEGAL_REMOTE_COMMANDS[j]+".exe"))) {
+              throw new IllegalArgumentException(ILLEGAL_REMOTE_COMMAND_RSH_OR_SSH + remoteCommand);
+            }
+            found = true;
+          }
+        }
+        if (!found) {
+          throw new IllegalArgumentException(ILLEGAL_REMOTE_COMMAND_RSH_OR_SSH + remoteCommand);
+        }
+      } else {
+        final boolean isSwitch = string.startsWith("-");
+        final boolean isHostOrCmd = string.equals("{host}") || string.equals("{cmd}");
+        
+        // additional elements must be switches or values-for-switches or {host} or user@{host} or {cmd}
+        if (!isSwitch && !isHostOrCmd) {
+          final String previous = (array == null || array.isEmpty()) ? null : array.get(array.size()-1);
+          final boolean isValueForSwitch = previous != null && previous.startsWith("-");
+          final boolean isHostWithUser = string.contains("@") && string.endsWith("{host}");
+          
+          if (!(isValueForSwitch || isHostWithUser)) {
+            throw new IllegalArgumentException(ILLEGAL_REMOTE_COMMAND_RSH_OR_SSH + remoteCommand);
+          }
+        }
+      }
+      array.add(string);
+    }
+  }
+  
+	public String getSystemName() {
+		return this.systemName;
+	}
+  
+	public void setSystemName(final String systemName) {
+          checkReadOnly();
+		this.systemName = systemName;
+    configChanged();
+	}
+  
+  /** 
+   * Returns an array of configurations for statically known
+   * CacheServers
+   *
+   * @since 4.0
+   */ 
+  public CacheServerConfig[] getCacheServerConfigs() {
+    return (CacheServerConfig[]) this.cacheServerConfigs.toArray(
+        new CacheServerConfig[this.cacheServerConfigs.size()]);
+  }
+  public CacheVmConfig[] getCacheVmConfigs() {
+    return (CacheVmConfig[]) this.cacheServerConfigs.toArray(new CacheVmConfig[this.cacheServerConfigs.size()]);
+  }
+  
+  
+  /** 
+   * Creates the configuration for a CacheServer
+   *
+   * @since 4.0
+   */
+  public CacheServerConfig createCacheServerConfig() {
+    CacheServerConfig config = new CacheServerConfigImpl();
+    addCacheServerConfig(config);
+    return config;
+  }
+  public CacheVmConfig createCacheVmConfig() {
+    return (CacheVmConfig)createCacheServerConfig();
+  }
+  
+  /** 
+   * Adds the configuration for a CacheServer
+   *
+   * @since 4.0
+   */
+  private void addCacheServerConfig(CacheServerConfig managerConfig) {
+    checkReadOnly();
+
+    if (managerConfig == null) return;
+    for (Iterator iter = this.cacheServerConfigs.iterator(); iter.hasNext();) {
+      CacheServerConfigImpl impl = (CacheServerConfigImpl) iter.next();
+      if (impl.equals(managerConfig)) {
+        return;
+      }
+    }
+    this.cacheServerConfigs.add(managerConfig);
+    configChanged();
+  }
+  
+  /** 
+   * Removes the configuration for a CacheServer
+   *
+   * @since 4.0
+   */
+  public void removeCacheServerConfig(CacheServerConfig managerConfig) {
+    removeCacheVmConfig((CacheVmConfig)managerConfig);
+  }
+  public void removeCacheVmConfig(CacheVmConfig managerConfig) {
+    checkReadOnly();
+    this.cacheServerConfigs.remove(managerConfig);
+    configChanged();
+  }
+
+  /** 
+   * Returns the configurations of all managed distribution locators
+   */
+  public DistributionLocatorConfig[] getDistributionLocatorConfigs() {
+    if (this.system != null) {
+      DistributionLocator[] locators =
+        this.system.getDistributionLocators(); 
+      DistributionLocatorConfig[] configs =
+        new DistributionLocatorConfig[locators.length];
+      for (int i = 0; i < locators.length; i++) {
+        configs[i] = locators[i].getConfig();
+      }
+      return configs;
+
+    } else {
+      Object[] array =
+        new DistributionLocatorConfig[this.locatorConfigs.size()];
+      return (DistributionLocatorConfig[]) this.locatorConfigs.toArray(array);
+    }
+  }
+  
+  /** Creates the configuration for a DistributionLocator */
+  public DistributionLocatorConfig createDistributionLocatorConfig() {
+    checkReadOnly();
+    DistributionLocatorConfig config = new DistributionLocatorConfigImpl();
+    addDistributionLocatorConfig(config);
+    return config;
+  }
+  
+  /** Adds the configuration for a DistributionLocator */
+  private void addDistributionLocatorConfig(DistributionLocatorConfig config) {
+    checkReadOnly();
+    this.locatorConfigs.add(config);
+    configChanged();
+  }
+  
+  /** 
+   * Removes the configuration for a DistributionLocator
+   */
+  public void removeDistributionLocatorConfig(DistributionLocatorConfig config) {
+    checkReadOnly();
+    this.locatorConfigs.remove(config);
+    configChanged();
+  }
+
+  /** 
+   * Validates the bind address.  The address may be a host name or IP address,
+   * but it must not be empty and must be usable for creating an InetAddress.
+   * Cannot have a leading '/' (which InetAddress.toString() produces).
+   *
+   * @param bindAddress host name or IP address to validate
+   */
+  public static boolean validateBindAddress(String bindAddress) {
+    if (bindAddress == null || bindAddress.length() == 0) return true;
+    if (InetAddressUtil.validateHost(bindAddress) == null) return false;
+    return true;
+  }
+  
+  public synchronized void configChanged() {
+    ConfigListener[] clients = null;
+    synchronized(this.listeners) {
+      clients = (ConfigListener[]) 
+          listeners.toArray(new ConfigListener[this.listeners.size()]);
+    }
+    for (int i = 0; i < clients.length; i++) {
+      try {
+        clients[i].configChanged(this);
+      } catch (Exception e) {
+        logger.warn(e.getMessage(), e);
+      }
+    }
+  }
+  
+  /** Registers listener for notification of changes in this config. */
+  public void addListener(ConfigListener listener) {
+    synchronized(this.listeners) {
+      this.listeners.add(listener);
+    }
+  }
+  
+  /** Removes previously registered listener of this config. */
+  public void removeListener(ConfigListener listener) {
+    synchronized(this.listeners) {
+      this.listeners.remove(listener);
+    }
+  }
+  
+  // -------------------------------------------------------------------------
+  //   SSL support...
+  // -------------------------------------------------------------------------
+  private boolean sslEnabled = 
+      DistributionConfig.DEFAULT_SSL_ENABLED;
+  private String sslProtocols = 
+      DistributionConfig.DEFAULT_SSL_PROTOCOLS;
+  private String sslCiphers = 
+      DistributionConfig.DEFAULT_SSL_CIPHERS;
+  private boolean sslAuthenticationRequired = 
+      DistributionConfig.DEFAULT_SSL_REQUIRE_AUTHENTICATION;
+  private Properties sslProperties = new Properties();
+  
+  public boolean isSSLEnabled() {
+    return this.sslEnabled;
+  }
+  public void setSSLEnabled(boolean enabled) {
+    checkReadOnly();
+    this.sslEnabled = enabled;
+    configChanged();
+  }
+  public String getSSLProtocols() {
+    return this.sslProtocols;
+  }
+  public void setSSLProtocols(String protocols) {
+    checkReadOnly();
+    this.sslProtocols = protocols;
+    configChanged();
+  }
+  public String getSSLCiphers() {
+    return this.sslCiphers;
+  }
+  public void setSSLCiphers(String ciphers) {
+    checkReadOnly();
+    this.sslCiphers = ciphers;
+    configChanged();
+  }
+  public boolean isSSLAuthenticationRequired() {
+    return this.sslAuthenticationRequired;
+  }
+  public void setSSLAuthenticationRequired(boolean authRequired) {
+    checkReadOnly();
+    this.sslAuthenticationRequired = authRequired;
+    configChanged();
+  }
+  public Properties getSSLProperties() {
+    return this.sslProperties;
+  }
+
+  public void setSSLProperties(Properties sslProperties) {
+    checkReadOnly();
+    this.sslProperties = sslProperties;
+    if (this.sslProperties == null) {
+      this.sslProperties = new Properties();
+    }
+    configChanged();
+  }
+  
+  public void addSSLProperty(String key, String value) {
+    checkReadOnly();
+    this.sslProperties.put(key, value);
+    configChanged();
+  }
+
+  public void removeSSLProperty(String key) {
+    checkReadOnly();
+    this.sslProperties.remove(key);
+    configChanged();
+  }
+  
+  /**
+   * 
+   * 
+   * @return the gfSecurityProperties
+   * @since 6.6.3
+   */
+  public Properties getGfSecurityProperties() {
+    return gfSecurityProperties;
+  }
+
+  public String getLogFile() {
+    return this.logFile;
+  }
+
+  public void setLogFile(String logFile) {
+    checkReadOnly();
+    this.logFile = logFile;
+    configChanged();
+  }
+
+  public String getLogLevel() {
+    return this.logLevel;
+  }
+
+  public void setLogLevel(String logLevel) {
+    checkReadOnly();
+    this.logLevel = logLevel;
+    configChanged();
+  }
+
+  public int getLogDiskSpaceLimit() {
+    return this.logDiskSpaceLimit;
+  }
+
+  public void setLogDiskSpaceLimit(int limit) {
+    checkReadOnly();
+    this.logDiskSpaceLimit = limit;
+    configChanged();
+  }
+
+  public int getLogFileSizeLimit() {
+    return this.logFileSizeLimit;
+  }
+
+  public void setLogFileSizeLimit(int limit) {
+    checkReadOnly();
+    this.logFileSizeLimit = limit;
+    configChanged();
+  }
+
+  /**
+   * Returns the refreshInterval in seconds
+   */
+  public int getRefreshInterval() {
+    return this.refreshInterval;
+  }
+
+  /**
+   * Sets the refreshInterval in seconds
+   */
+  public void setRefreshInterval(int timeInSecs) {
+    checkReadOnly();
+    this.refreshInterval = timeInSecs;
+    configChanged();
+  }
+
+
+  /**
+   * Makes sure that the mcast port and locators are correct and
+   * consistent.
+   *
+   * @throws IllegalArgumentException
+   *         If configuration is not valid
+   */
+  public void validate() {
+    if (this.getMcastPort() < MIN_MCAST_PORT ||
+        this.getMcastPort() > MAX_MCAST_PORT) {
+      throw new IllegalArgumentException(LocalizedStrings.DistributedSystemConfigImpl_MCASTPORT_MUST_BE_AN_INTEGER_INCLUSIVELY_BETWEEN_0_AND_1.toLocalizedString(new Object[] {Integer.valueOf(MIN_MCAST_PORT), Integer.valueOf(MAX_MCAST_PORT)}));
+    }
+
+    // disabled in 5.1 - multicast and locators can be used together
+    //if (!DEFAULT_LOCATORS.equals(this.getLocators()) &&
+    //    this.mcastPort > 0) { 
+    //  throw new IllegalArgumentException(
+    //    "mcastPort must be zero when locators are specified");
+    //}
+
+    LogWriterImpl.levelNameToCode(this.logLevel);
+
+    if (this.logFileSizeLimit < MIN_LOG_FILE_SIZE_LIMIT || 
+        this.logFileSizeLimit > MAX_LOG_FILE_SIZE_LIMIT) {
+      throw new IllegalArgumentException(LocalizedStrings.DistributedSystemConfigImpl_LOGFILESIZELIMIT_MUST_BE_AN_INTEGER_BETWEEN_0_AND_1.toLocalizedString(new Object[] {Integer.valueOf(MIN_LOG_FILE_SIZE_LIMIT), Integer.valueOf(MAX_LOG_FILE_SIZE_LIMIT)}));
+    }
+
+    if (this.logDiskSpaceLimit < MIN_LOG_DISK_SPACE_LIMIT || 
+        this.logDiskSpaceLimit > MAX_LOG_DISK_SPACE_LIMIT) {
+      throw new IllegalArgumentException(LocalizedStrings.DistributedSystemConfigImpl_LOGDISKSPACELIMIT_MUST_BE_AN_INTEGER_BETWEEN_0_AND_1.toLocalizedString(new Object[] {Integer.valueOf(MIN_LOG_DISK_SPACE_LIMIT), Integer.valueOf(MAX_LOG_DISK_SPACE_LIMIT)}));
+    }
+
+    parseEntityConfigXMLFile();
+  }
+
+  /**
+   * Makes a deep copy of this config object.
+   */
+  @Override
+  public Object clone() throws CloneNotSupportedException {
+    DistributedSystemConfigImpl other =
+      (DistributedSystemConfigImpl) super.clone();
+    other.system = null;
+    other.cacheServerConfigs = new HashSet();
+    other.locatorConfigs = new HashSet();
+
+    DistributionLocatorConfig[] myLocators =
+      this.getDistributionLocatorConfigs();
+    for (int i = 0; i < myLocators.length; i++) {
+      DistributionLocatorConfig locator = myLocators[i];
+      other.addDistributionLocatorConfig((DistributionLocatorConfig) locator.clone());
+    }
+
+    CacheServerConfig[] myCacheServers = this.getCacheServerConfigs();
+    for (int i = 0; i < myCacheServers.length; i++) {
+      CacheServerConfig locator = myCacheServers[i];
+      other.addCacheServerConfig((CacheServerConfig) locator.clone());
+    }
+
+    return other;
+  }
+  
+  @Override
+  public String toString() {
+    StringBuffer buf = new StringBuffer(1000);
+    String lf = System.getProperty("line.separator");
+    if (lf == null) lf = ",";
+    
+    buf.append("DistributedSystemConfig(");
+    buf.append(lf);
+    buf.append("  system-name=");
+    buf.append(String.valueOf(this.systemName));
+    buf.append(lf);
+    buf.append("  "+MCAST_ADDRESS_NAME+"=");
+    buf.append(String.valueOf(this.mcastAddress));
+    buf.append(lf);
+    buf.append("  "+MCAST_PORT_NAME+"=");
+    buf.append(String.valueOf(this.mcastPort));
+    buf.append(lf);
+    buf.append("  "+LOCATORS_NAME+"=");
+    buf.append(String.valueOf(this.locators));
+    buf.append(lf);
+    buf.append("  "+MEMBERSHIP_PORT_RANGE_NAME+"=");
+    buf.append(getMembershipPortRange());
+    buf.append(lf);
+    buf.append("  "+BIND_ADDRESS_NAME+"=");
+    buf.append(String.valueOf(this.bindAddress));
+    buf.append(lf);
+    buf.append("  "+TCP_PORT_NAME+"="+this.tcpPort);
+    buf.append(lf);
+    buf.append("  "+DistributionConfig.DISABLE_TCP_NAME+"=");
+    buf.append(String.valueOf(this.disableTcp));
+    buf.append(lf);
+    buf.append("  "+DistributionConfig.DISABLE_AUTO_RECONNECT_NAME+"=");
+    buf.append(String.valueOf(this.disableAutoReconnect));
+    buf.append(lf);
+    buf.append("  "+REMOTE_COMMAND_NAME+"=");
+    buf.append(String.valueOf(this.remoteCommand));
+    buf.append(lf);
+    buf.append("  "+SSL_ENABLED_NAME+"=");
+    buf.append(String.valueOf(this.sslEnabled));
+    buf.append(lf);
+    buf.append("  "+SSL_CIPHERS_NAME+"=");
+    buf.append(String.valueOf(this.sslCiphers));
+    buf.append(lf);
+    buf.append("  "+SSL_PROTOCOLS_NAME+"=");
+    buf.append(String.valueOf(this.sslProtocols));
+    buf.append(lf);
+    buf.append("  "+SSL_REQUIRE_AUTHENTICATION_NAME+"=");
+    buf.append(String.valueOf(this.sslAuthenticationRequired));
+    buf.append(lf);
+    buf.append("  "+LOG_FILE_NAME+"=");
+    buf.append(String.valueOf(this.logFile));
+    buf.append(lf);
+    buf.append("  "+LOG_LEVEL_NAME+"=");
+    buf.append(String.valueOf(this.logLevel));
+    buf.append(lf);
+    buf.append("  "+LOG_DISK_SPACE_LIMIT_NAME+"=");
+    buf.append(String.valueOf(this.logDiskSpaceLimit));
+    buf.append(lf);
+    buf.append("  "+LOG_FILE_SIZE_LIMIT_NAME+"=");
+    buf.append(String.valueOf(this.logFileSizeLimit));
+    buf.append(lf);
+    buf.append("  "+REFRESH_INTERVAL_NAME+"=");
+    buf.append(String.valueOf(this.refreshInterval));
+    buf.append(")");
+    return buf.toString();
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributedSystemHealthConfigImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributedSystemHealthConfigImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributedSystemHealthConfigImpl.java
new file mode 100644
index 0000000..3b633f2
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributedSystemHealthConfigImpl.java
@@ -0,0 +1,50 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.*;
+
+/**
+ * The implementation of <code>DistributedSystemHealthConfig</code>.
+ * Note that because it never leaves the management VM, it is not
+ * <code>Serializable</code> and is not part of the {@link
+ * GemFireHealthConfigImpl} class hierarchy.
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ */
+public class DistributedSystemHealthConfigImpl
+  implements DistributedSystemHealthConfig {
+
+  /** The maximum number of application members that can
+   * unexceptedly leave a healthy the distributed system. */
+  private long maxDepartedApplications =
+    DEFAULT_MAX_DEPARTED_APPLICATIONS;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>DistributedSystemHealthConfigImpl</code> with
+   * the default configuration.
+   */
+  protected DistributedSystemHealthConfigImpl() {
+
+  }
+
+  /////////////////////  Instance Methods  /////////////////////
+
+  public long getMaxDepartedApplications() {
+    return this.maxDepartedApplications;
+  }
+
+  public void setMaxDepartedApplications(long maxDepartedApplications)
+  {
+    this.maxDepartedApplications = maxDepartedApplications;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributedSystemHealthEvaluator.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributedSystemHealthEvaluator.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributedSystemHealthEvaluator.java
new file mode 100644
index 0000000..a131670
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributedSystemHealthEvaluator.java
@@ -0,0 +1,163 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.DistributedSystemHealthConfig;
+import com.gemstone.gemfire.distributed.internal.DistributionManager;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.distributed.internal.DM;
+import com.gemstone.gemfire.distributed.internal.MembershipListener;
+import java.util.*;
+
+import com.gemstone.gemfire.distributed.internal.membership.*;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+/**
+ * Contains the logic for evaluating the health of an entire GemFire
+ * distributed system according to the thresholds provided in a {@link
+ * DistributedSystemHealthConfig}.
+ *
+ * <P>
+ *
+ * Note that unlike other evaluators, the
+ * <code>DistributedSystemHealthEvaluator</code> resides in the
+ * "administrator" VM and not in the member VMs.  This is because
+ * there only needs to be one
+ * <code>DistributedSystemHealthEvaluator</code> per distributed
+ * system.
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ * */
+class DistributedSystemHealthEvaluator
+  extends AbstractHealthEvaluator implements MembershipListener {
+
+  /** The config from which we get the evaluation criteria */
+  private DistributedSystemHealthConfig config;
+
+  /** The distribution manager with which this MembershipListener is
+   * registered */
+  private DM dm;
+
+  /** The description of the distributed system being evaluated */
+  private String description;
+
+  /** The number of application members that have unexpectedly left
+   * since the previous evaluation */
+  private int crashedApplications;
+
+  ///////////////////////  Constructors  ///////////////////////
+
+  /**
+   * Creates a new <code>DistributedSystemHealthEvaluator</code>
+   */
+  DistributedSystemHealthEvaluator(DistributedSystemHealthConfig config,
+                                   DM dm) {
+    super(null, dm);
+
+    this.config = config;
+    this.dm = dm;
+    this.dm.addMembershipListener(this);
+
+    StringBuffer sb = new StringBuffer();
+    sb.append("Distributed System ");
+
+    String desc = null;
+    if (dm instanceof DistributionManager) {
+      desc = 
+        ((DistributionManager) dm).getDistributionConfigDescription();
+    } 
+
+    if (desc != null) {
+      sb.append(desc);
+
+    } else {
+      DistributionConfig dsc = dm.getSystem().getConfig();
+      String locators = dsc.getLocators();
+      if (locators == null || locators.equals("")) {
+        sb.append("using multicast ");
+        sb.append(dsc.getMcastAddress());
+        sb.append(":");
+        sb.append(dsc.getMcastPort());
+
+      } else {
+        sb.append("using locators ");
+        sb.append(locators);
+      }
+    }
+
+    this.description = sb.toString();
+  }
+
+  ////////////////////  Instance Methods  ////////////////////
+
+  @Override
+  protected String getDescription() {
+    return this.description;
+  }
+
+  /**  
+   * Checks to make sure that the number of application members of
+   * the distributed system that have left unexpected since the last
+   * evaluation is less than the {@linkplain
+   * DistributedSystemHealthConfig#getMaxDepartedApplications
+   * threshold}.  If not, the status is "poor" health.
+   */
+  void checkDepartedApplications(List status) {
+    synchronized (this) {
+      long threshold = this.config.getMaxDepartedApplications();
+      if (this.crashedApplications > threshold) {
+        String s = LocalizedStrings.DistributedSystemHealth_THE_NUMBER_OF_APPLICATIONS_THAT_HAVE_LEFT_THE_DISTRIBUTED_SYSTEM_0_EXCEEDS_THE_THRESHOLD_1.toLocalizedString(new Object[] { Long.valueOf(this.crashedApplications), Long.valueOf(threshold)});
+        status.add(poorHealth(s));
+      }
+      this.crashedApplications = 0;
+    }
+  }
+
+  @Override
+  protected void check(List status) {
+    checkDepartedApplications(status);
+  }
+
+  @Override
+  void close() {
+    this.dm.removeMembershipListener(this);
+  }
+
+  public void memberJoined(InternalDistributedMember id) {
+
+  }
+
+  /**
+   * Keeps track of which members depart unexpectedly
+   */
+  public void memberDeparted(InternalDistributedMember id, boolean crashed) {
+    if (!crashed)
+      return;
+    synchronized (this) {
+        int kind = id.getVmKind();
+        switch (kind) {
+        case DistributionManager.LOCATOR_DM_TYPE:
+        case DistributionManager.NORMAL_DM_TYPE:
+          this.crashedApplications++;
+          break;
+        default:
+          break;
+        }
+    } // synchronized
+  }
+
+  public void quorumLost(Set<InternalDistributedMember> failures, List<InternalDistributedMember> remaining) {
+  }
+
+  public void memberSuspect(InternalDistributedMember id,
+      InternalDistributedMember whoSuspected) {
+  }
+  
+}


[40/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributedSystemHealthMonitor.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributedSystemHealthMonitor.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributedSystemHealthMonitor.java
new file mode 100644
index 0000000..ca7f067
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributedSystemHealthMonitor.java
@@ -0,0 +1,428 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.GemFireHealth;
+import com.gemstone.gemfire.admin.GemFireHealthConfig;
+import com.gemstone.gemfire.admin.GemFireMemberStatus;
+import com.gemstone.gemfire.admin.RegionSubRegionSnapshot;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionAttributes;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.internal.Assert;
+import com.gemstone.gemfire.internal.Config;
+import com.gemstone.gemfire.internal.SocketCreator;
+import com.gemstone.gemfire.internal.admin.AdminBridgeServer;
+import com.gemstone.gemfire.internal.admin.CacheInfo;
+import com.gemstone.gemfire.internal.admin.DLockInfo;
+import com.gemstone.gemfire.internal.admin.GemFireVM;
+import com.gemstone.gemfire.internal.admin.GfManagerAgent;
+import com.gemstone.gemfire.internal.admin.HealthListener;
+import com.gemstone.gemfire.internal.admin.Stat;
+import com.gemstone.gemfire.internal.admin.StatAlertDefinition;
+import com.gemstone.gemfire.internal.admin.StatListener;
+import com.gemstone.gemfire.internal.admin.StatResource;
+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;
+
+/**
+ * A thread that monitors the health of the distributed system.  It is
+ * kind of like a {@link
+ * com.gemstone.gemfire.distributed.internal.HealthMonitorImpl}.  In
+ * order to get it to place nice with the rest of the health
+ * monitoring APIs, this class pretends that it is a
+ * <code>GemFireVM</code>.  Kind of hokey, but it beats a bunch of
+ * special-case code.
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ * */
+class DistributedSystemHealthMonitor implements Runnable, GemFireVM {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  /** Evaluates the health of the distributed system */
+  private DistributedSystemHealthEvaluator eval;
+
+  /** Notified when the health of the distributed system changes */
+  private GemFireHealthImpl healthImpl;
+
+  /** The number of seconds between health checks */
+  private int interval;
+
+  /** The thread in which the monitoring occurs */
+  private Thread thread;
+
+  /** Has this monitor been asked to stop? */
+  private volatile boolean stopRequested = false;
+
+  /** The health of the distributed system the last time we checked. */
+  private GemFireHealth.Health prevHealth = GemFireHealth.GOOD_HEALTH;
+
+  /** The most recent <code>OKAY_HEALTH</code> diagnoses of the
+   * GemFire system */
+  private List okayDiagnoses;
+
+  /** The most recent <code>POOR_HEALTH</code> diagnoses of the
+   * GemFire system */
+  private List poorDiagnoses;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>DistributedSystemHealthMonitor</code> that
+   * evaluates the health of the distributed system against the given
+   * thresholds once every <code>interval</code> seconds.
+   *
+   * @param eval
+   *        Used to evaluate the health of the distributed system
+   * @param healthImpl
+   *        Receives callbacks when the health of the distributed
+   *        system changes
+   * @param interval
+   *        How often the health is checked
+   */
+  DistributedSystemHealthMonitor(DistributedSystemHealthEvaluator eval,
+                                 GemFireHealthImpl healthImpl,
+                                 int interval) {
+    this.eval = eval;
+    this.healthImpl = healthImpl;
+    this.interval = interval;
+    this.okayDiagnoses = new ArrayList();
+    this.poorDiagnoses = new ArrayList();
+
+    ThreadGroup group =
+      LoggingThreadGroup.createThreadGroup(LocalizedStrings.DistributedSystemHealthMonitor_HEALTH_MONITORS.toLocalizedString(), logger);
+    String name = LocalizedStrings.DistributedSystemHealthMonitor_HEALTH_MONITOR_FOR_0.toLocalizedString(eval.getDescription());
+    this.thread = new Thread(group, this, name);
+    this.thread.setDaemon(true);
+  }
+
+  /**
+   * Does the work of monitoring the health of the distributed
+   * system. 
+   */
+  public void run() {
+    if (logger.isDebugEnabled()) {
+      logger.debug("Monitoring health of {} every {} seconds", this.eval.getDescription(), interval);
+    }
+
+    while (!this.stopRequested) {
+      SystemFailure.checkFailure();
+      try {
+        Thread.sleep(interval * 1000);
+        List status = new ArrayList();
+        eval.evaluate(status);
+
+        GemFireHealth.Health overallHealth = GemFireHealth.GOOD_HEALTH;
+        this.okayDiagnoses.clear();
+        this.poorDiagnoses.clear();
+
+        for (Iterator iter = status.iterator(); iter.hasNext(); ) {
+          AbstractHealthEvaluator.HealthStatus health =
+            (AbstractHealthEvaluator.HealthStatus) iter.next();
+          if (overallHealth == GemFireHealth.GOOD_HEALTH) {
+            if ((health.getHealthCode() != GemFireHealth.GOOD_HEALTH)) {
+              overallHealth = health.getHealthCode();
+            }
+
+          } else if (overallHealth == GemFireHealth.OKAY_HEALTH) {
+            if (health.getHealthCode() == GemFireHealth.POOR_HEALTH) {
+              overallHealth = GemFireHealth.POOR_HEALTH;
+            }
+          }
+
+          GemFireHealth.Health healthCode = health.getHealthCode();
+          if (healthCode == GemFireHealth.OKAY_HEALTH) {
+            this.okayDiagnoses.add(health.getDiagnosis());
+
+          } else if (healthCode == GemFireHealth.POOR_HEALTH) {
+            this.poorDiagnoses.add(health.getDiagnosis());
+            break;
+          }
+        }
+        
+        if (overallHealth != prevHealth) {
+          healthImpl.healthChanged(this, overallHealth);
+          this.prevHealth = overallHealth;
+        }
+        
+      } catch (InterruptedException ex) {
+        // We're all done
+        // No need to reset the interrupted flag, since we're going to exit.
+        break;
+      }
+    }
+
+    eval.close();
+    if (logger.isDebugEnabled()) {
+      logger.debug("Stopped checking for distributed system health");
+    }
+  }
+
+  /**
+   * Starts this <code>DistributedSystemHealthMonitor</code>
+   */
+  void start(){
+    this.thread.start();
+  }
+
+  /**
+   * Stops this <code>DistributedSystemHealthMonitor</code>
+   */
+  void stop() {
+    if (this.thread.isAlive()) {
+      this.stopRequested = true;
+      this.thread.interrupt();
+      this.healthImpl.nodeLeft(null, this);
+
+      try {
+        this.thread.join();
+      } 
+      catch (InterruptedException ex) {
+        Thread.currentThread().interrupt();
+        logger.warn(LocalizedMessage.create(LocalizedStrings.DistributedSystemHealthMonitor_INTERRUPTED_WHILE_STOPPING_HEALTH_MONITOR_THREAD), ex);
+      }
+    }
+  }
+
+  //////////////////////  GemFireVM Methods  //////////////////////
+
+  public java.net.InetAddress getHost() {
+    try {
+      return SocketCreator.getLocalHost();
+
+    } catch (Exception ex) {
+      throw new com.gemstone.gemfire.InternalGemFireException(LocalizedStrings.DistributedSystemHealthMonitor_COULD_NOT_GET_LOCALHOST.toLocalizedString());
+    }
+  }
+  
+  public String getName() {
+//    return getId().toString();
+    throw new UnsupportedOperationException("Not a real GemFireVM");
+  }
+
+  public java.io.File getWorkingDirectory() {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public java.io.File getGemFireDir() {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+  
+  public java.util.Date getBirthDate() {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public Properties getLicenseInfo(){
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public GemFireMemberStatus getSnapshot() {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public RegionSubRegionSnapshot getRegionSnapshot() {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public StatResource[] getStats(String statisticsTypeName){
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public StatResource[] getAllStats(){
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+   
+  public DLockInfo[] getDistributedLockInfo(){
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public void addStatListener(StatListener observer,
+                              StatResource observedResource,
+                              Stat observedStat){
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+  
+  public void removeStatListener(StatListener observer){
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }  
+
+  public void addHealthListener(HealthListener observer,
+                                GemFireHealthConfig cfg){
+
+  }
+  
+  public void removeHealthListener(){
+
+  }
+
+  public void resetHealthStatus(){
+    this.prevHealth = GemFireHealth.GOOD_HEALTH;
+  }
+
+  public String[] getHealthDiagnosis(GemFireHealth.Health healthCode){
+    if (healthCode == GemFireHealth.GOOD_HEALTH) {
+      return new String[0];
+
+    } else if (healthCode == GemFireHealth.OKAY_HEALTH) {
+      String[] array = new String[this.okayDiagnoses.size()];
+      this.okayDiagnoses.toArray(array);
+      return array;
+
+    } else {
+      Assert.assertTrue(healthCode == GemFireHealth.POOR_HEALTH);
+      String[] array = new String[this.poorDiagnoses.size()];
+      this.poorDiagnoses.toArray(array);
+      return array;
+    }
+  }
+
+  public Config getConfig(){
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public void setConfig(Config cfg){
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public GfManagerAgent getManagerAgent(){
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+  
+  public String[] getSystemLogs(){
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public void setInspectionClasspath(String classpath){
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+  
+  public String getInspectionClasspath(){
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+  
+  public Region[] getRootRegions(){
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public Region getRegion(CacheInfo c, String path) {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public Region createVMRootRegion(CacheInfo c, String name,
+                                   RegionAttributes attrs) {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public Region createSubregion(CacheInfo c, String parentPath,
+                                String name, RegionAttributes attrs) {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public void setCacheInspectionMode(int mode) {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public int getCacheInspectionMode(){
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public void takeRegionSnapshot(String regionName, int snapshotId){
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public InternalDistributedMember getId() {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public CacheInfo getCacheInfo() {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public String getVersionInfo() {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public CacheInfo setCacheLockTimeout(CacheInfo c, int v) {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public CacheInfo setCacheLockLease(CacheInfo c, int v) {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public CacheInfo setCacheSearchTimeout(CacheInfo c, int v) {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public AdminBridgeServer addBridgeServer(CacheInfo cache)
+    throws AdminException {
+
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public AdminBridgeServer getBridgeInfo(CacheInfo cache, 
+                                         int id)
+    throws AdminException {
+
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public AdminBridgeServer startBridgeServer(CacheInfo cache,
+                                             AdminBridgeServer bridge)
+    throws AdminException {
+
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  public AdminBridgeServer stopBridgeServer(CacheInfo cache,
+                                            AdminBridgeServer bridge)
+    throws AdminException {
+
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  /**
+   * This operation is not supported for this object. Will throw 
+   * UnsupportedOperationException if invoked.
+   */
+  public void setAlertsManager(StatAlertDefinition[] alertDefs, 
+      long refreshInterval, boolean setRemotely) {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  /**
+   * This operation is not supported for this object. Will throw 
+   * UnsupportedOperationException if invoked.
+   */
+  public void setRefreshInterval(long refreshInterval) {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+
+  /**
+   * This operation is not supported for this object. Will throw 
+   * UnsupportedOperationException if invoked.
+   */
+  public void updateAlertDefinitions(StatAlertDefinition[] alertDefs,
+      int actionCode) {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributedSystemHealthMonitor_NOT_A_REAL_GEMFIREVM.toLocalizedString());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributionLocatorConfigImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributionLocatorConfigImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributionLocatorConfigImpl.java
new file mode 100644
index 0000000..1e3e7e8
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributionLocatorConfigImpl.java
@@ -0,0 +1,183 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.DistributionLocator;
+import com.gemstone.gemfire.admin.DistributionLocatorConfig;
+import com.gemstone.gemfire.distributed.internal.InternalLocator;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import java.net.InetAddress;
+import java.util.Properties;
+
+/**
+ * Provides an implementation of
+ * <code>DistributionLocatorConfig</code>.
+ *
+ * @author David Whitlock
+ * @since 4.0
+ */
+public class DistributionLocatorConfigImpl 
+  extends ManagedEntityConfigImpl 
+  implements DistributionLocatorConfig {
+
+  /** The minimum networking port (0) */
+  public static final int MIN_PORT = 0;
+
+  /** The maximum networking port (65535) */
+  public static final int MAX_PORT = 65535;
+  
+  //////////////////////  Instance Fields  //////////////////////
+
+  /** The port on which this locator listens */
+  private int port;
+
+  /** The address to bind to on a multi-homed host */
+  private String bindAddress;
+  
+  /** The properties used to configure the DistributionLocator's
+      DistributedSystem */
+  private Properties dsProperties;
+
+  /** The DistributionLocator that was created with this config */
+  private DistributionLocator locator;
+
+  //////////////////////  Static Methods  //////////////////////
+
+  /**
+   * Contacts a distribution locator on the given host and port and
+   * creates a <code>DistributionLocatorConfig</code> for it.
+   *
+   * @see InternalLocator#getLocatorInfo
+   *
+   * @return <code>null</code> if the locator cannot be contacted
+   */
+  static DistributionLocatorConfig
+    createConfigFor(String host, int port, InetAddress bindAddress) {
+
+    String[] info = null;
+    if (bindAddress != null) {
+      info = InternalLocator.getLocatorInfo(bindAddress, port);
+    }
+    else {
+      info = InternalLocator.getLocatorInfo(InetAddressUtil.toInetAddress(host), port);
+    }
+    if (info == null) {
+      return null;
+    }
+
+    DistributionLocatorConfigImpl config =
+      new DistributionLocatorConfigImpl();
+    config.setHost(host);
+    config.setPort(port);
+    if (bindAddress != null) {
+      config.setBindAddress(bindAddress.getHostAddress());
+    }
+    config.setWorkingDirectory(info[0]);
+    config.setProductDirectory(info[1]);
+
+    return config;
+  }
+
+  ///////////////////////  Constructors  ///////////////////////
+
+  /**
+   * Creates a new <code>DistributionLocatorConfigImpl</code> with the
+   * default settings.
+   */
+  public DistributionLocatorConfigImpl() {
+    this.port = 0;
+    this.bindAddress = null;
+    this.locator = null;
+    this.dsProperties = new java.util.Properties();
+    this.dsProperties.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
+  }
+
+  /////////////////////  Instance Methods  /////////////////////
+
+  /**
+   * Sets the locator that was configured with this
+   * <Code>DistributionLocatorConfigImpl</code>. 
+   */
+  void setLocator(DistributionLocator locator) {
+    this.locator = locator;
+  }
+
+  @Override
+  protected boolean isReadOnly() {
+    return this.locator != null && this.locator.isRunning();
+  }
+
+  public int getPort() {
+    return this.port;
+  }
+
+  public void setPort(int port) {
+    checkReadOnly();
+    this.port = port;
+    configChanged();
+  }
+
+  public String getBindAddress() {
+    return this.bindAddress;
+  }
+
+  public void setBindAddress(String bindAddress) {
+    checkReadOnly();
+    this.bindAddress = bindAddress;
+    configChanged();
+  }
+  
+  public void setDistributedSystemProperties(Properties props) {
+    this.dsProperties = props;
+  }
+  
+  public Properties getDistributedSystemProperties() {
+    return this.dsProperties;
+  }
+
+  @Override
+  public void validate() {
+    super.validate();
+
+    if (port < MIN_PORT || port > MAX_PORT) {
+      throw new IllegalArgumentException(LocalizedStrings.DistributionLocatorConfigImpl_PORT_0_MUST_BE_AN_INTEGER_BETWEEN_1_AND_2.toLocalizedString(new Object[] {Integer.valueOf(port), Integer.valueOf(MIN_PORT), Integer.valueOf(MAX_PORT)}));
+    }
+
+    if (this.bindAddress != null &&
+        InetAddressUtil.validateHost(this.bindAddress) == null) {
+      throw new IllegalArgumentException(LocalizedStrings.DistributionLocatorConfigImpl_INVALID_HOST_0.toLocalizedString(this.bindAddress));
+    }
+  }
+
+  /**
+   * Currently, listeners are not supported on the locator config.
+   */
+  @Override
+  protected void configChanged() {
+
+  }
+
+  @Override
+  public Object clone() throws CloneNotSupportedException {
+    DistributionLocatorConfigImpl clone =
+      (DistributionLocatorConfigImpl) super.clone();
+    clone.locator = null;
+    return clone;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+    sb.append("DistributionLocatorConfig: host=").append(getHost());
+    sb.append(", bindAddress=").append(getBindAddress());
+    sb.append(", port=").append(getPort());
+    return sb.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributionLocatorImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributionLocatorImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributionLocatorImpl.java
new file mode 100755
index 0000000..d970816
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/DistributionLocatorImpl.java
@@ -0,0 +1,322 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.admin.internal;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.admin.AdminDistributedSystem;
+import com.gemstone.gemfire.admin.DistributionLocator;
+import com.gemstone.gemfire.admin.DistributionLocatorConfig;
+import com.gemstone.gemfire.admin.ManagedEntityConfig;
+import com.gemstone.gemfire.distributed.internal.DM;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.internal.admin.remote.DistributionLocatorId;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+
+/**
+ * Default administrative implementation of a DistributionLocator.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ */
+public class DistributionLocatorImpl
+  implements DistributionLocator, InternalManagedEntity {
+  
+  private static final Logger logger = LogService.getLogger();
+  
+  /** How many new <code>DistributionLocator</code>s have been created? */
+  private static int newLocators = 0;
+
+  ////////////////////  Instance Fields  ////////////////////
+
+  /** The configuration object for this locator */
+  private final DistributionLocatorConfigImpl config;
+
+  /** The id of this distribution locator */
+  private final String id;
+  
+  /** Used to control the actual DistributionLocator service */
+  private ManagedEntityController controller;
+
+  /** The system that this locator is a part of */
+  private AdminDistributedSystemImpl system;
+
+  // -------------------------------------------------------------------------
+  //   constructor(s)...
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Constructs new instance of <code>DistributionLocatorImpl</code>
+   * that is a member of the given distributed system.
+   */
+  public DistributionLocatorImpl(DistributionLocatorConfig config,
+                                 AdminDistributedSystemImpl system) {
+    this.config = (DistributionLocatorConfigImpl) config;
+    this.config.validate();
+    this.config.setManagedEntity(this);
+    this.id = getNewId();
+    this.controller = system.getEntityController();
+    this.system = system;
+  }
+  
+  // -------------------------------------------------------------------------
+  //   Attribute accessors/mutators...
+  // -------------------------------------------------------------------------
+  
+        public String getId() {
+                return this.id;
+        }
+
+  public String getNewId() {
+    synchronized (DistributionLocatorImpl.class) {
+      return "Locator" + (++newLocators);
+    }
+  }
+
+  /**
+   * Returns the configuration object for this locator.
+   *
+   * @since 4.0
+   */
+  public DistributionLocatorConfig getConfig() {
+    return this.config;
+  }
+
+  public AdminDistributedSystem getDistributedSystem() {
+    return this.system;
+  }
+
+  /**
+   * Unfortunately, it doesn't make much sense to maintain the state
+   * of a locator.  The admin API does not receive notification when
+   * the locator actually starts and stops.  If we try to guess, we'll
+   * just end up with race conditions galore.  So, we can't fix bug
+   * 32455 for locators.
+   */
+  public int setState(int state) {
+    throw new UnsupportedOperationException(LocalizedStrings.DistributionLocatorImpl_CAN_NOT_SET_THE_STATE_OF_A_LOCATOR.toLocalizedString());
+  }
+
+  // -------------------------------------------------------------------------
+  //   Operations...
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Polls to determine whether or not this managed entity has
+   * started.
+   */
+  public boolean waitToStart(long timeout) 
+    throws InterruptedException {
+
+    if (Thread.interrupted()) throw new InterruptedException();
+    
+    long start = System.currentTimeMillis();
+    while (System.currentTimeMillis() - start < timeout) {
+      if (this.isRunning()) {
+        return true;
+
+      } else {
+        Thread.sleep(100);
+      }
+    }
+
+    logger.info(LocalizedMessage.create(
+      LocalizedStrings.DistributionLocatorImpl_DONE_WAITING_FOR_LOCATOR));
+    return this.isRunning();
+  }
+
+  /**
+   * Polls to determine whether or not this managed entity has
+   * stopped.
+   */
+  public boolean waitToStop(long timeout) 
+    throws InterruptedException {
+
+    if (Thread.interrupted()) throw new InterruptedException();
+    
+    long start = System.currentTimeMillis();
+    while (System.currentTimeMillis() - start < timeout) {
+      if (!this.isRunning()) {
+        return true;
+
+      } else {
+        Thread.sleep(100);
+      }
+    }
+
+    return !this.isRunning();
+  }
+
+  public boolean isRunning() {
+    DM dm = ((AdminDistributedSystemImpl)getDistributedSystem()).getDistributionManager();
+    if(dm == null) {
+      try {
+        return this.controller.isRunning(this);
+      }
+      catch (IllegalStateException e) {
+        return false;
+      }
+    }
+    
+    String host = getConfig().getHost();
+    int port = getConfig().getPort();
+    String bindAddress = getConfig().getBindAddress();
+    
+    boolean found = false;
+    Map<InternalDistributedMember, Collection<String>> hostedLocators = dm.getAllHostedLocators();
+    for (Iterator<InternalDistributedMember> memberIter = hostedLocators.keySet().iterator(); memberIter.hasNext();) {
+      for (Iterator<String> locatorIter = hostedLocators.get(memberIter.next()).iterator(); locatorIter.hasNext();) {
+        DistributionLocatorId locator = new DistributionLocatorId(locatorIter.next());
+        found = found || locator.getHost().getHostAddress().equals(host);
+        found = found || locator.getHost().getHostName().equals(host);
+        if (!found && !host.contains(".")) {
+          try {
+            InetAddress inetAddr = InetAddress.getByName(host);
+            found = locator.getHost().getHostName().equals(inetAddr.getHostName());
+            if (!found) {
+              found = locator.getHost().getHostAddress().equals(inetAddr.getHostAddress());
+            }
+          }
+          catch (UnknownHostException e) {
+            // try config host as if it is an IP address instead of host name
+          }
+        }
+        if (locator.getBindAddress() != null && !locator.getBindAddress().isEmpty()
+            && bindAddress != null && !bindAddress.isEmpty()) {
+          found = found && locator.getBindAddress().equals(bindAddress);
+        }
+        found = found && locator.getPort() == port;
+        if (found) {
+          return true;
+        }
+      }
+    }
+    return found;
+  }
+  
+  public void start() {
+    this.config.validate();
+    this.controller.start(this);
+    this.config.setLocator(this);
+    this.system.updateLocatorsString();
+  }
+  
+  public void stop() {
+    this.controller.stop(this);
+    this.config.setLocator(null);
+  }
+  
+  public String getLog() {
+    return this.controller.getLog(this);
+  }
+  
+	/**
+	 * Returns a string representation of the object.
+	 * 
+	 * @return a string representation of the object
+	 */
+  @Override
+	public String toString() {
+		return "DistributionLocator " + getId();
+	}
+
+  ////////////////////////  Command execution  ////////////////////////
+
+  public ManagedEntityConfig getEntityConfig() {
+    return this.getConfig();
+  }
+
+  public String getEntityType() {
+    return "Locator";
+  }
+
+  public String getStartCommand() {
+    StringBuffer sb = new StringBuffer();
+    sb.append(this.controller.getProductExecutable(this, "gemfire"));
+    sb.append(" start-locator -q -dir=");
+    sb.append(this.getConfig().getWorkingDirectory());
+    sb.append(" -port=");
+    sb.append(this.getConfig().getPort());
+    Properties props = config.getDistributedSystemProperties();
+    Enumeration en = props.propertyNames();
+    while (en.hasMoreElements()) {
+      String pn = (String)en.nextElement();
+      sb.append(" -Dgemfire." + pn + "=" + props.getProperty(pn));
+    }
+
+    String bindAddress = this.getConfig().getBindAddress();
+    if (bindAddress != null && bindAddress.length() > 0) {
+      sb.append(" -address=");
+      sb.append(this.getConfig().getBindAddress());
+    }
+    sb.append(" ");
+
+    String sslArgs =
+      this.controller.buildSSLArguments(this.system.getConfig());
+    if (sslArgs != null) {
+      sb.append(sslArgs);
+    }
+
+    return sb.toString().trim();
+  }
+
+  public String getStopCommand() {
+    StringBuffer sb = new StringBuffer();
+    sb.append(this.controller.getProductExecutable(this, "gemfire"));
+    sb.append(" stop-locator -q -dir=");
+    sb.append(this.getConfig().getWorkingDirectory());
+    sb.append(" -port=");
+    sb.append(this.getConfig().getPort());
+
+    String bindAddress = this.getConfig().getBindAddress();
+    if (bindAddress != null && bindAddress.length() > 0) {
+      sb.append(" -address=");
+      sb.append(this.getConfig().getBindAddress());
+    }
+    sb.append(" ");
+
+    String sslArgs =
+      this.controller.buildSSLArguments(this.system.getConfig());
+    if (sslArgs != null) {
+      sb.append(sslArgs);
+    }
+
+    return sb.toString().trim();
+  }
+
+  public String getIsRunningCommand() {
+    StringBuffer sb = new StringBuffer();
+    sb.append(this.controller.getProductExecutable(this, "gemfire"));
+    sb.append(" status-locator -dir=");
+    sb.append(this.getConfig().getWorkingDirectory());
+
+    return sb.toString().trim();
+  }
+
+  public String getLogCommand() {
+    StringBuffer sb = new StringBuffer();
+    sb.append(this.controller.getProductExecutable(this, "gemfire"));
+    sb.append(" tail-locator-log -dir=");
+    sb.append(this.getConfig().getWorkingDirectory());
+
+    return sb.toString().trim();
+  }
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/EnabledManagedEntityController.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/EnabledManagedEntityController.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/EnabledManagedEntityController.java
new file mode 100755
index 0000000..8555f96
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/EnabledManagedEntityController.java
@@ -0,0 +1,403 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Properties;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.admin.AdminDistributedSystem;
+import com.gemstone.gemfire.admin.DistributedSystemConfig;
+import com.gemstone.gemfire.admin.ManagedEntity;
+import com.gemstone.gemfire.admin.ManagedEntityConfig;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.internal.ProcessOutputReader;
+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;
+
+/**
+ * Implements the actual administration (starting, stopping, etc.) of
+ * GemFire {@link ManagedEntity}s.  It {@link Runtime#exec(java.lang.String) executes}
+ * commands to administer the entities based on information provided
+ * by the {@link InternalManagedEntity} object.  Note that it does not
+ * use <code>SystemAdmin</code> to manage "local" entities; it always
+ * execs the scripts.
+ *
+ * <P>
+ *
+ * This class is a refactoring of <code>Systemcontroller</code>,
+ * <code>RemoteCommand</code>, and <code>LocatorRemoteCommand</code>.
+ *
+ * @author David Whitlock
+ * @author Kirk Lund (original SystemController)
+ * @since 4.0
+ */
+class EnabledManagedEntityController implements ManagedEntityController {
+  private static final Logger logger = LogService.getLogger();
+
+//  /** A lock to ensure that only entity is managed at a time.  See bug
+//   * 31374. */
+//  private static Object startStopLock = new Object();
+
+  /** Known strings found in output indicating error. */
+  private static final String[] ERROR_OUTPUTS = new String[] {
+    "No such file or directory",
+    "The system cannot find the file specified.",
+    "Access is denied.",
+    "cannot open",
+    "ERROR"
+  };
+
+  /** Token in command prefix to be replaced with actual HOST */
+  private static final String HOST = "{HOST}";
+
+  /** Token in command prefix to be replaced with actual execution CMD */
+  private static final String CMD = "{CMD}";
+
+  //////////////////////  Instance Fields  //////////////////////
+
+  /** The thread group in which threads launched by this system
+   * controller reside. */
+  private final ThreadGroup threadGroup;
+
+  /** System to which the managed entities belong */
+  private final AdminDistributedSystem system;
+
+  ///////////////////////  Constructors  ///////////////////////
+
+  /**
+   * Creates a new <code>ManagedEntityController</code> for entities
+   * in the given distributed system.
+   */
+  EnabledManagedEntityController(AdminDistributedSystem system) {
+    this.system = system;
+    this.threadGroup =
+      LoggingThreadGroup.createThreadGroup("ManagedEntityController threads", logger);
+  }
+
+  /////////////////////  Instance Methods  /////////////////////
+
+  /**
+   * Returns <code>true</code> if the <code>output</code> string
+   * contains a known error message.
+   */
+  private boolean outputIsError(String output) {
+    if (output == null) return false;
+    boolean error = false;
+    for (int i = 0; i < ERROR_OUTPUTS.length; i++) {
+      error = output.indexOf(ERROR_OUTPUTS[i]) > -1;
+      if (error) return error;
+    }
+    return error;
+  }
+
+  /**
+   * Executes a command using {@link Runtime#exec(java.lang.String)}.
+   *
+   * @param command
+   *        The full command to remotely execute
+   *
+   * @return Output from the command that was executed or
+   *         <code>null</code> if the executing the command failed.
+   */
+  protected String execute(String command,
+                         InternalManagedEntity entity) {
+    /* TODO: this is getting ugly... clients of this method really need to
+       have the ability to do their own parsing/checking of 'output' */
+    if (command == null || command.length() == 0) {
+      throw new IllegalArgumentException(LocalizedStrings.ManagedEntityController_EXECUTION_COMMAND_IS_EMPTY.toLocalizedString());
+    }
+
+    File workingDir =
+      new File(entity.getEntityConfig().getWorkingDirectory());
+    logger.info(LocalizedMessage.create(LocalizedStrings.ManagedEntityController_EXECUTING_REMOTE_COMMAND_0_IN_DIRECTORY_1, new Object[] {command, workingDir}));
+    Process p = null;
+    try {
+      p = Runtime.getRuntime().exec(command, null /* env */,
+                                    workingDir);
+
+    } catch (java.io.IOException e) {
+      logger.fatal(LocalizedMessage.create(LocalizedStrings.ManagedEntityController_WHILE_EXECUTING_0, command), e);
+      return null;
+    }
+
+    final ProcessOutputReader pos = new ProcessOutputReader(p);
+    int retCode = pos.getExitCode();
+    final String output = pos.getOutput();
+    logger.info(LocalizedMessage.create(LocalizedStrings.ManagedEntityController_RESULT_OF_EXECUTING_0_IS_1, new Object[] {command, Integer.valueOf(retCode)}));
+    logger.info(LocalizedMessage.create(LocalizedStrings.ManagedEntityController_OUTPUT_OF_0_IS_1, new Object[] {command, output}));
+
+    if (retCode != 0 || outputIsError(output)) {
+      logger.warn(LocalizedMessage.create(LocalizedStrings.ManagedEntityController_REMOTE_EXECUTION_OF_0_FAILED, command));
+      return null;
+    }
+
+    return output;
+  }
+
+  /** Returns true if the path ends with a path separator. */
+  private boolean endsWithSeparator(String path) {
+    return path.endsWith("/") || path.endsWith("\\");
+  }
+
+  /** Translates the path between Windows and UNIX. */
+  private String getOSPath(String path) {
+    if (pathIsWindows(path)) {
+      return path.replace('/', '\\');
+    } else {
+      return path.replace('\\', '/');
+    }
+  }
+
+//  /** Returns true if the path is on Windows. */
+//  private boolean pathIsWindows(File path) {
+//    return pathIsWindows(path.toString());
+//  }
+
+  /** Returns true if the path is on Windows. */
+  private boolean pathIsWindows(String path) {
+    if (path != null && path.length() > 1) {
+      return (Character.isLetter(path.charAt(0)) && path.charAt(1) == ':') ||
+        (path.startsWith("//") || path.startsWith("\\\\"));
+    }
+    return false;
+  }
+
+  /**
+   * If the managed entity resides on a remote host, then
+   * <code>command</code> is munged to take the remote command into account.
+   *
+   * @throws IllegalStateException
+   *        If a remote command is required, but one has not been
+   *        specified.
+   */
+  private String arrangeRemoteCommand(InternalManagedEntity entity,
+                                      String cmd) {
+
+    String host = entity.getEntityConfig().getHost();
+    if (InetAddressUtil.isLocalHost(host)) {
+      // No arranging necessary
+      return cmd;
+    }
+
+    String prefix = entity.getEntityConfig().getRemoteCommand();
+    if (prefix == null || prefix.length() <= 0) {
+      prefix = entity.getDistributedSystem().getRemoteCommand();
+    }
+
+    if (prefix == null || prefix.length() <= 0) {
+      throw new IllegalStateException(LocalizedStrings.ManagedEntityController_A_REMOTE_COMMAND_MUST_BE_SPECIFIED_TO_OPERATE_ON_A_MANAGED_ENTITY_ON_HOST_0
+          .toLocalizedString(host));
+    }
+
+    int hostIdx = prefix.indexOf(HOST);
+    int cmdIdx = prefix.indexOf(CMD);
+    if (hostIdx == -1 && cmdIdx == -1) {
+      return prefix + " " + host + " " + cmd;
+    }
+
+    if (hostIdx >= 0) {
+      String start = prefix.substring(0, hostIdx);
+      String end = null;
+      if (hostIdx + HOST.length() >= prefix.length()) {
+        end = "";
+      } else {
+        end = prefix.substring(hostIdx + HOST.length());
+      }
+      prefix = start + host + end;
+      cmdIdx = prefix.indexOf(CMD); //recalculate;
+    }
+
+    if (cmdIdx >= 0) {
+      String start = prefix.substring(0, cmdIdx);
+      String end = null;
+      if (cmdIdx + CMD.length() >= prefix.length()) {
+        end = "";
+      } else {
+        end = prefix.substring(cmdIdx + CMD.length());
+      }
+      prefix = start + cmd + end;
+    }
+    return prefix;
+  }
+
+  /**
+   * Returns the full path to the executable in
+   * <code>$GEMFIRE/bin</code> taking into account the {@linkplain
+   * ManagedEntityConfig#getProductDirectory product directory} and the
+   * platform's file separator.
+   *
+   * <P>
+   *
+   * Note: we should probably do a better job of determine whether or
+   * not the machine on which the entity runs is Windows or Linux.
+   *
+   * @param executable
+   *        The name of the executable that resides in
+   *        <code>$GEMFIRE/bin</code>.
+   */
+  public String getProductExecutable(InternalManagedEntity entity,
+                                     String executable) {
+    String productDirectory =
+      entity.getEntityConfig().getProductDirectory();
+    String path = null;
+    File productDir = new File(productDirectory);
+//    if (productDir != null) (cannot be null)
+    {
+      path = productDir.getPath();
+      if (!endsWithSeparator(path)) {
+        path += File.separator;
+      }
+      path += "bin" + File.separator;
+    }
+//    else {
+//      path = "";
+//    }
+
+    String bat = "";
+    if (pathIsWindows(path)) {
+      bat = ".bat";
+    }
+    return getOSPath(path) + executable + bat;
+  }
+
+  /**
+   * Builds optional SSL command-line arguments.  Returns null if SSL is not
+   * enabled for the distributed system.
+   */
+  public String buildSSLArguments(DistributedSystemConfig config) {
+    Properties sslProps = buildSSLProperties(config, true);
+    if (sslProps == null) return null;
+
+    StringBuffer sb = new StringBuffer();
+    for (Iterator iter = sslProps.keySet().iterator(); iter.hasNext();) {
+      String key = (String) iter.next();
+      String value = sslProps.getProperty(key);
+      sb.append(" -J-D" + key + "=" + value);
+    }
+
+    return sb.toString();
+  }
+
+  /**
+   * Builds optional SSL properties for DistributionLocator. Returns null if SSL
+   * is not enabled for the distributed system.
+   *
+   * @param forCommandLine
+   *                true indicates that
+   *                {@link DistributionConfig#GEMFIRE_PREFIX} should be
+   *                prepended so the argument will become -Dgemfire.xxxx
+   */
+  private Properties buildSSLProperties(DistributedSystemConfig config,
+                                        boolean forCommandLine) {
+    if (!config.isSSLEnabled()) return null;
+
+    String prefix = "";
+    if (forCommandLine) prefix = DistributionConfig.GEMFIRE_PREFIX;
+
+    Properties sslProps = (Properties) config.getSSLProperties().clone();
+    // add ssl-enabled, etc...
+    sslProps.setProperty(prefix +
+                         DistributionConfig.MCAST_PORT_NAME,
+                         "0");
+    sslProps.setProperty(prefix +
+                         DistributionConfig.SSL_ENABLED_NAME,
+                         String.valueOf(config.isSSLEnabled()));
+    sslProps.setProperty(prefix +
+                         DistributionConfig.SSL_CIPHERS_NAME,
+                         config.getSSLCiphers());
+    sslProps.setProperty(prefix +
+                         DistributionConfig.SSL_PROTOCOLS_NAME,
+                         config.getSSLProtocols());
+    sslProps.setProperty(prefix +
+                         DistributionConfig.SSL_REQUIRE_AUTHENTICATION_NAME,
+                         String.valueOf(config.isSSLAuthenticationRequired()));
+    return sslProps;
+  }
+
+
+  /**
+   * Starts a managed entity.
+   */
+  public void start(final InternalManagedEntity entity) {
+    final String command =
+      arrangeRemoteCommand(entity, entity.getStartCommand());
+    Thread start = new Thread(this.threadGroup, new Runnable() {
+        public void run() {
+          execute(command, entity);
+        }
+      }, "Start " + entity.getEntityType());
+    start.start();
+  }
+
+  /**
+   * Stops a managed entity.
+   */
+  public void stop(final InternalManagedEntity entity) {
+    final String command =
+      arrangeRemoteCommand(entity, entity.getStopCommand());
+    Thread stop = new Thread(this.threadGroup, new Runnable() {
+        public void run() {
+          execute(command, entity);
+        }
+      }, "Stop " + entity.getEntityType());
+    stop.start();
+  }
+
+  /**
+   * Returns whether or not a managed entity is running
+   */
+  public boolean isRunning(InternalManagedEntity entity) {
+    final String command =
+      arrangeRemoteCommand(entity, entity.getIsRunningCommand());
+    String output = execute(command, entity);
+
+    if (output == null ||
+        (output.indexOf("stop" /* "ing" "ped" */) != -1) ||
+        (output.indexOf("killed") != -1) ||
+        (output.indexOf("starting") != -1)) {
+      return false;
+
+    } else if (output.indexOf("running") != -1) {
+      return true;
+
+    } else {
+      throw new IllegalStateException(LocalizedStrings.ManagedEntityController_COULD_NOT_DETERMINE_IF_MANAGED_ENTITY_WAS_RUNNING_0
+          .toLocalizedString(output));
+    }
+  }
+
+  /**
+   * Returns the contents of a locator's log file.  Other APIs are
+   * used to get the log file of managed entities that are also system
+   * members.
+   */
+  public String getLog(DistributionLocatorImpl locator) {
+    String command =
+      arrangeRemoteCommand(locator, locator.getLogCommand());
+    return execute(command, locator);
+  }
+
+  /**
+   * Returns the contents of the given directory using the given
+   * managed entity to determine the host and remote command.
+   */
+  private String listDirectory(InternalManagedEntity entity,
+                               String dir) {
+    ManagedEntityConfig config = entity.getEntityConfig();
+    String listFile =
+        pathIsWindows(config.getProductDirectory()) ? "dir " : "ls ";
+    String command =
+      arrangeRemoteCommand(entity, listFile + dir);
+    return execute(command, entity);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/FinishBackupRequest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/FinishBackupRequest.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/FinishBackupRequest.java
new file mode 100644
index 0000000..c464a75
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/FinishBackupRequest.java
@@ -0,0 +1,159 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.persistence.PersistentID;
+import com.gemstone.gemfire.distributed.DistributedMember;
+import com.gemstone.gemfire.distributed.internal.DM;
+import com.gemstone.gemfire.distributed.internal.DistributionManager;
+import com.gemstone.gemfire.distributed.internal.DistributionMessage;
+import com.gemstone.gemfire.distributed.internal.ReplyException;
+import com.gemstone.gemfire.internal.admin.remote.AdminFailureResponse;
+import com.gemstone.gemfire.internal.admin.remote.AdminMultipleReplyProcessor;
+import com.gemstone.gemfire.internal.admin.remote.AdminResponse;
+import com.gemstone.gemfire.internal.admin.remote.CliLegacyMessage;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+
+/**
+ * A request send from an admin VM to all of the peers to indicate
+ * that that should complete the backup operation.
+ * 
+ * @author dsmith
+ *
+ */
+public class FinishBackupRequest  extends CliLegacyMessage {
+  private static final Logger logger = LogService.getLogger();
+  
+  private File targetDir;
+  private File baselineDir;
+  
+  public FinishBackupRequest() {
+    super();
+  }
+
+  public FinishBackupRequest(File targetDir,File baselineDir) {
+    this.targetDir = targetDir;
+    this.baselineDir = baselineDir;
+  }
+  
+  public static Map<DistributedMember, Set<PersistentID>> send(DM dm, Set recipients, File targetDir, File baselineDir) {
+    FinishBackupRequest request = new FinishBackupRequest(targetDir,baselineDir);
+    request.setRecipients(recipients);
+
+    FinishBackupReplyProcessor replyProcessor = new FinishBackupReplyProcessor(dm, recipients);
+    request.msgId = replyProcessor.getProcessorId();
+    dm.putOutgoing(request);
+    try {
+      replyProcessor.waitForReplies();
+    } catch (ReplyException e) {
+      if(!(e.getCause() instanceof CancelException)) {
+        throw e;
+      }
+    } catch (InterruptedException e) {
+      e.printStackTrace();
+    }
+    AdminResponse response = request.createResponse((DistributionManager)dm);
+    response.setSender(dm.getDistributionManagerId());
+    replyProcessor.process(response);
+    return replyProcessor.results;
+  }
+  
+  @Override
+  protected AdminResponse createResponse(DistributionManager dm) {
+    GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+    HashSet<PersistentID> persistentIds;
+    if(cache == null) {
+      persistentIds = new HashSet<PersistentID>();
+    } else {
+      try {
+        persistentIds = cache.getBackupManager().finishBackup(targetDir, baselineDir);
+      } catch (IOException e) {
+        logger.error(LocalizedMessage.create(LocalizedStrings.CliLegacyMessage_ERROR, this.getClass()), e);
+        return AdminFailureResponse.create(dm, getSender(), e);
+      }
+    }
+    
+    return new FinishBackupResponse(this.getSender(), persistentIds);
+  }
+
+  public int getDSFID() {
+    return FINISH_BACKUP_REQUEST;
+  }
+  
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    super.fromData(in);
+    targetDir = DataSerializer.readFile(in);
+    baselineDir = DataSerializer.readFile(in);
+  }
+
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    super.toData(out);
+    DataSerializer.writeFile(targetDir, out);
+    DataSerializer.writeFile(baselineDir, out);
+  }
+
+  private static class FinishBackupReplyProcessor extends AdminMultipleReplyProcessor {
+    Map<DistributedMember, Set<PersistentID>> results = Collections.synchronizedMap(new HashMap<DistributedMember, Set<PersistentID>>());
+    public FinishBackupReplyProcessor(DM dm, Collection initMembers) {
+      super(dm, initMembers);
+    }
+    
+    @Override
+    protected boolean stopBecauseOfExceptions() {
+      return false;
+    }
+
+    
+    
+    @Override
+    protected int getAckWaitThreshold() {
+      //Disable the 15 second warning if the backup is taking a long time
+      return 0;
+    }
+
+    @Override
+    public long getAckSevereAlertThresholdMS() {
+      //Don't log severe alerts for backups either
+      return Long.MAX_VALUE;
+    }
+
+    @Override
+    protected void process(DistributionMessage msg, boolean warn) {
+      if(msg instanceof FinishBackupResponse) {
+        final HashSet<PersistentID> persistentIds = ((FinishBackupResponse) msg).getPersistentIds();
+        if(persistentIds != null && !persistentIds.isEmpty()) {
+          results.put(msg.getSender(), persistentIds);
+        }
+      }
+      super.process(msg, warn);
+    }
+    
+    
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/FinishBackupResponse.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/FinishBackupResponse.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/FinishBackupResponse.java
new file mode 100644
index 0000000..998c0c3
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/FinishBackupResponse.java
@@ -0,0 +1,70 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.HashSet;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.persistence.PersistentID;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.internal.admin.remote.AdminResponse;
+
+/**
+ * The reply for a {@link FinishBackupRequest}. The
+ * reply contains the persistent ids of the disk stores
+ * that were backed up on this member.
+ * 
+ * @author dsmith
+ *
+ */
+public class FinishBackupResponse extends AdminResponse {
+  
+  private HashSet<PersistentID> persistentIds;
+  
+  public FinishBackupResponse() {
+    super();
+  }
+
+  public FinishBackupResponse(InternalDistributedMember sender, HashSet<PersistentID> persistentIds) {
+    this.setRecipient(sender);
+    this.persistentIds = persistentIds;
+  }
+  
+  public HashSet<PersistentID> getPersistentIds() {
+    return persistentIds;
+  }
+
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    super.fromData(in);
+    persistentIds = DataSerializer.readHashSet(in);
+  }
+
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    super.toData(out);
+    DataSerializer.writeHashSet(persistentIds, out);
+  }
+
+  @Override
+  protected Object clone() throws CloneNotSupportedException {
+    return super.clone();
+  }
+
+  public int getDSFID() {
+    return FINISH_BACKUP_RESPONSE;
+  }
+  
+  @Override
+  public String toString() {
+    return getClass().getName() + ": " + persistentIds;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/FlushToDiskRequest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/FlushToDiskRequest.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/FlushToDiskRequest.java
new file mode 100644
index 0000000..3336aa2
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/FlushToDiskRequest.java
@@ -0,0 +1,89 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.cache.persistence.PersistentID;
+import com.gemstone.gemfire.distributed.internal.DM;
+import com.gemstone.gemfire.distributed.internal.DistributionManager;
+import com.gemstone.gemfire.distributed.internal.ReplyException;
+import com.gemstone.gemfire.internal.admin.remote.AdminMultipleReplyProcessor;
+import com.gemstone.gemfire.internal.admin.remote.AdminResponse;
+import com.gemstone.gemfire.internal.admin.remote.CliLegacyMessage;
+import com.gemstone.gemfire.internal.cache.DiskStoreImpl;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+
+/**
+ * A request to from an admin VM to all non admin members
+ * to start a backup. In the prepare phase of the backup,
+ * the members will suspend bucket destroys to make sure
+ * buckets aren't missed during the backup.
+ * 
+ * @author dsmith
+ *
+ */
+public class FlushToDiskRequest  extends CliLegacyMessage {
+  
+  public FlushToDiskRequest() {
+    
+  }
+  
+  public static void send(DM dm, Set recipients) {
+    FlushToDiskRequest request = new FlushToDiskRequest();
+    request.setRecipients(recipients);
+
+    FlushToDiskProcessor replyProcessor = new FlushToDiskProcessor(dm, recipients);
+    request.msgId = replyProcessor.getProcessorId();
+    dm.putOutgoing(request);
+    try {
+      replyProcessor.waitForReplies();
+    } catch (ReplyException e) {
+      if(!(e.getCause() instanceof CancelException)) {
+        throw e;
+      }
+    } catch (InterruptedException e) {
+      e.printStackTrace();
+    }
+    AdminResponse response = request.createResponse((DistributionManager)dm);
+    response.setSender(dm.getDistributionManagerId());
+    replyProcessor.process(response);
+  }
+  
+  @Override
+  protected AdminResponse createResponse(DistributionManager dm) {
+    GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+    HashSet<PersistentID> persistentIds;
+    if(cache != null) {
+      Collection<DiskStoreImpl> diskStores = cache.listDiskStoresIncludingRegionOwned();
+      for(DiskStoreImpl store : diskStores) {
+        store.flush();
+      }
+    }
+    
+    return new FlushToDiskResponse(this.getSender());
+  }
+
+  public int getDSFID() {
+    return FLUSH_TO_DISK_REQUEST;
+  }
+  
+  private static class FlushToDiskProcessor extends AdminMultipleReplyProcessor {
+    public FlushToDiskProcessor(DM dm, Collection initMembers) {
+      super(dm, initMembers);
+    }
+    
+    @Override
+    protected boolean stopBecauseOfExceptions() {
+      return false;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/FlushToDiskResponse.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/FlushToDiskResponse.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/FlushToDiskResponse.java
new file mode 100644
index 0000000..b08b133
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/FlushToDiskResponse.java
@@ -0,0 +1,37 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.internal.admin.remote.AdminResponse;
+
+/**
+ * The response to the {@link FlushToDiskRequest}
+ * 
+ * @author dsmith
+ *
+ */
+public class FlushToDiskResponse extends AdminResponse {
+
+  public FlushToDiskResponse() {
+    super();
+  }
+
+  public FlushToDiskResponse(InternalDistributedMember sender) {
+    this.setRecipient(sender);
+  }
+  
+  public int getDSFID() {
+    return FLUSH_TO_DISK_RESPONSE;
+  }
+  
+  @Override
+  public String toString() {
+    return getClass().getName();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/GemFireHealthConfigImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/GemFireHealthConfigImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/GemFireHealthConfigImpl.java
new file mode 100644
index 0000000..61e5022
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/GemFireHealthConfigImpl.java
@@ -0,0 +1,75 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.*;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+// @todo davidw Delegate to a "parent" config for properties that are not overridden.
+// This will be made easier with a special <code>HealthConfigAttribute</code> class.
+/**
+ * The implementation of <code>GemFireHealthConfig</code>
+ *
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ */
+public class GemFireHealthConfigImpl
+  extends CacheHealthConfigImpl
+  implements GemFireHealthConfig {
+
+  private static final long serialVersionUID = -6797673296902808018L;
+
+  /** The name of the host to which this configuration applies. */
+  private String hostName;
+
+  /** The number of seconds to wait between evaluating the health of
+   * GemFire. */
+  private int interval = DEFAULT_HEALTH_EVALUATION_INTERVAL;
+
+  ////////////////////////  Constructors  ////////////////////////
+
+  /**
+   * Creates a new <code>GemFireHealthConfigImpl</code> that applies
+   * to the host with the given name.
+   *
+   * @param hostName
+   *        The name of the host to which this configuration applies.
+   *        If <code>null</code>, then this is the "default"
+   *        configuration. 
+   */
+  public GemFireHealthConfigImpl(String hostName) {
+    this.hostName = hostName;
+  }
+
+  ///////////////////////  Instance Methods  ///////////////////////
+
+  public String getHostName() {
+    return this.hostName;
+  }
+
+  public void setHealthEvaluationInterval(int interval) {
+    this.interval = interval;
+  }
+
+  public int getHealthEvaluationInterval() {
+    return this.interval;
+  }
+
+  @Override
+  public String toString() {
+    if (this.hostName == null) {
+      return LocalizedStrings.GemFireHealthConfigImpl_DEFAULT_GEMFIRE_HEALTH_CONFIGURATION.toLocalizedString();
+
+    } else {
+      return LocalizedStrings.GemFireHealthConfigImpl_GEMFIRE_HEALTH_CONFIGURATION_FOR_HOST_0.toLocalizedString(this.hostName);
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/GemFireHealthEvaluator.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/GemFireHealthEvaluator.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/GemFireHealthEvaluator.java
new file mode 100644
index 0000000..f5647a9
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/GemFireHealthEvaluator.java
@@ -0,0 +1,179 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.admin.GemFireHealth;
+import com.gemstone.gemfire.admin.GemFireHealthConfig;
+import com.gemstone.gemfire.distributed.internal.DistributionManager;
+import com.gemstone.gemfire.internal.Assert;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * Evaluates the health of various GemFire components in the VM
+ * according to a {@link GemFireHealthConfig}.
+ *
+ * <P>
+ *
+ * Note that evaluators never reside in the administration VM, they
+ * only in member VMs.  They are not <code>Serializable</code> and
+ * aren't meant to be.
+ *
+ * @see MemberHealthEvaluator
+ * @see CacheHealthEvaluator
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ */
+public class GemFireHealthEvaluator {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  /** Determines how the health of GemFire is determined */
+  private GemFireHealthConfig config;
+
+  /** Evaluates the health of this member of the distributed system */
+  private MemberHealthEvaluator memberHealth;
+
+  /** Evaluates the health of the Cache hosted in this VM */
+  private CacheHealthEvaluator cacheHealth;
+
+  /** The most recent <code>OKAY_HEALTH</code> diagnoses of the
+   * GemFire system */
+  private List okayDiagnoses;
+
+  /** The most recent <code>POOR_HEALTH</code> diagnoses of the
+   * GemFire system */
+  private List poorDiagnoses;
+
+  ///////////////////////  Constructors  ///////////////////////
+
+  /**
+   * Creates a new <code>GemFireHealthEvaluator</code>
+   *
+   * @param config
+   *        The configuration that determines whether or GemFire is
+   *        healthy 
+   * @param dm
+   *        The distribution manager 
+   */
+  public GemFireHealthEvaluator(GemFireHealthConfig config,
+                                DistributionManager dm) {
+    if (config == null) {
+      throw new NullPointerException(LocalizedStrings.GemFireHealthEvaluator_NULL_GEMFIREHEALTHCONFIG.toLocalizedString());
+    }
+
+    this.config = config;
+    this.memberHealth = new MemberHealthEvaluator(config, dm);
+    this.cacheHealth = new CacheHealthEvaluator(config, dm);
+    this.okayDiagnoses = new ArrayList();
+    this.poorDiagnoses = new ArrayList();
+  }
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  /**
+   * Evaluates the health of the GemFire components in this VM.
+   *
+   * @return The aggregate health code (such as {@link
+   *         GemFireHealth#OKAY_HEALTH}) of the GemFire components.
+   */
+  public GemFireHealth.Health evaluate() {
+    List status = new ArrayList();
+    this.memberHealth.evaluate(status);
+    this.cacheHealth.evaluate(status);
+
+    GemFireHealth.Health overallHealth = GemFireHealth.GOOD_HEALTH;
+    this.okayDiagnoses.clear();
+    this.poorDiagnoses.clear();
+
+    for (Iterator iter = status.iterator(); iter.hasNext(); ) {
+      AbstractHealthEvaluator.HealthStatus health =
+        (AbstractHealthEvaluator.HealthStatus) iter.next();
+      if (overallHealth == GemFireHealth.GOOD_HEALTH) {
+        if ((health.getHealthCode() != GemFireHealth.GOOD_HEALTH)) {
+          overallHealth = health.getHealthCode();
+        }
+
+      } else if (overallHealth == GemFireHealth.OKAY_HEALTH) {
+        if (health.getHealthCode() == GemFireHealth.POOR_HEALTH) {
+          overallHealth = GemFireHealth.POOR_HEALTH;
+        }
+      }
+
+      GemFireHealth.Health healthCode = health.getHealthCode();
+      if (healthCode == GemFireHealth.OKAY_HEALTH) {
+        this.okayDiagnoses.add(health.getDiagnosis());
+
+      } else if (healthCode == GemFireHealth.POOR_HEALTH) {
+        this.poorDiagnoses.add(health.getDiagnosis());
+      }
+    }
+
+    if (logger.isDebugEnabled()) {
+      logger.debug("Evaluated health to be {}", overallHealth);
+    }
+    return overallHealth;
+  }
+
+  /**
+   * Returns detailed information explaining the current health status.
+   * Each array element is a different cause for the current status.
+   * An empty array will be returned if the current status is {@link
+   * GemFireHealth#GOOD_HEALTH}. 
+   */
+  public String[] getDiagnosis(GemFireHealth.Health healthCode) {
+    if (healthCode == GemFireHealth.GOOD_HEALTH) {
+      return new String[0];
+
+    } else if (healthCode == GemFireHealth.OKAY_HEALTH) {
+      String[] array = new String[this.okayDiagnoses.size()];
+      this.okayDiagnoses.toArray(array);
+      return array;
+
+    } else {
+      Assert.assertTrue(healthCode == GemFireHealth.POOR_HEALTH);
+      String[] array = new String[this.poorDiagnoses.size()];
+      this.poorDiagnoses.toArray(array);
+      return array;
+    }
+  }
+
+  /**
+   * Resets the state of this evaluator
+   */
+  public void reset() {
+    this.okayDiagnoses.clear();
+    this.poorDiagnoses.clear();
+  }
+
+  /**
+   * Returns the heath evaluation interval, in seconds.
+   *
+   * @see GemFireHealthConfig#getHealthEvaluationInterval
+   */
+  public int getEvaluationInterval() {
+    return this.config.getHealthEvaluationInterval();
+  }
+
+  /**
+   * Closes this evaluator and releases all of its resources
+   */
+  public void close() {
+    this.memberHealth.close();
+    this.cacheHealth.close();
+  }
+
+}


[25/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheTransactionManager.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheTransactionManager.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheTransactionManager.java
new file mode 100644
index 0000000..0c666fa
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheTransactionManager.java
@@ -0,0 +1,322 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import java.util.concurrent.TimeUnit;
+
+
+/** <p>The CacheTransactionManager interface allows applications to manage
+ * transactions on a per {@link Cache} basis.  
+ * 
+ * <p>The life cycle of a GemFire transaction starts with a begin
+ * operation. The life cycle ends with either a commit or rollback
+ * operation.  Between the begin and the commit/rollback are typically
+ * {@link Region} operations.  In general, those that either create,
+ * destroy, invalidate or update {@link Region.Entry} are considered
+ * transactional, that is they modify transactional state.
+ * 
+ * <p>A GemFire transaction may involve operations on multiple regions,
+ * each of which may have different attributes.
+ * 
+ * <p>While a GemFire transaction and its operations are invoked in
+ * the local VM, the resulting transaction state is distributed to
+ * other VM's at commit time as per the attributes of each
+ * participant Region.
+ * 
+ * <p>A transaction can have no more than one thread associated with
+ * it and conversely a thread can only operate on one transaction at
+ * any given time. Child threads will not inherit the existing
+ * transaction.
+ *
+ * <p>Each of the following methods operate on the current thread.  All
+ * methods throw {@link CacheClosedException} if the Cache is closed.
+ * 
+ * <p>GemFire Transactions currently only support Read Committed
+ * isolation.  In addition, they are optimistic transactions in that
+ * write locking and conflict checks are performed as part of the
+ * commit operation.
+ *
+ * <p>For guaranteed Read Committed isolation, avoid making "in place"
+ * changes, because such changes will be "seen" by other transactions
+ * and break the Read Committed isolation guarantee. e.g.
+ *
+ *  <pre>
+ *    CacheTransactionManager txMgr = cache.getCacheTransactionManager();
+ *    txMgr.begin();
+ *    StringBuffer s = (StringBuffer) r.get("stringBuf");
+ *    s.append("Changes seen before commit. NOT Read Committed!");
+ *    r.put("stringBuf", s);
+ *    txMgr.commit();
+ *  </pre>
+ * 
+ *  <p>To aid in creating copies, the "copy on read"
+ *  <code>Cache</code> attribute and the {@link
+ *  com.gemstone.gemfire.CopyHelper#copy} method are provided.
+ *  The following is a Read Committed safe example using the
+ *  <code>CopyHelper.copy</code> method.
+ * 
+ *  <pre>
+ *    CacheTransactionManager txMgr = cache.getCacheTransactionManager();
+ *    txMgr.begin();
+ *    Object o = r.get("stringBuf");
+ *    StringBuffer s = (StringBuffer) CopyHelper.copy(o);
+ *    s.append("Changes unseen before commit. Read Committed.");
+ *    r.put("stringBuf", s);
+ *    txMgr.commit();
+ *  </pre>
+ *
+ *  <p>Its important to note that creating copies can negatively
+ *  impact both performance and memory consumption.
+ *
+ * <p>Partitioned Regions, Distributed No Ack and Distributed Ack Regions are supported
+ * (see {@link AttributesFactory} for Scope).  For both scopes, a
+ * consistent configuration (per VM) is enforced.
+ * 
+ * <p>Global Regions, client Regions (see {@link com.gemstone.gemfire.cache.client})
+ * and persistent Regions (see {@link DiskWriteAttributes}) do not
+ * support transactions.
+ * 
+ * <p>When PartitionedRegions are involved in a transaction, all data in the 
+ * transaction must be colocated together on one data node. See the GemFire 
+ * Developer Guide for details on using transactions with Partitioned Regions.
+ * 
+ * @author Mitch Thomas
+ * 
+ * @since 4.0
+ * 
+ * @see Cache
+ * 
+ */
+public interface CacheTransactionManager {
+    /** Creates a new transaction and associates it with the current thread.
+     *
+     * @throws IllegalStateException if the thread is already associated with a transaction
+     *
+     * @since 4.0
+     */
+    public void begin();
+
+    /** Commit the transaction associated with the current thread. If
+     *  the commit operation fails due to a conflict it will destroy
+     *  the transaction state and throw a {@link
+     *  CommitConflictException}.  If the commit operation succeeds,
+     *  it returns after the transaction state has been merged with
+     *  committed state.  When this method completes, the thread is no
+     *  longer associated with a transaction.
+     *
+     * @throws IllegalStateException if the thread is not associated with a transaction
+     * 
+     * @throws CommitConflictException if the commit operation fails due to
+     *   a write conflict.
+     * 
+     * @throws TransactionDataNodeHasDepartedException if the node hosting the
+     * transaction data has departed. This is only relevant for transaction that
+     * involve PartitionedRegions.
+     * 
+     * @throws TransactionDataNotColocatedException if at commit time, the data
+     * involved in the transaction has moved away from the transaction hosting 
+     * node. This can only happen if rebalancing/recovery happens during a 
+     * transaction that involves a PartitionedRegion. 
+     *   
+     * @throws TransactionInDoubtException when GemFire cannot tell which nodes
+     * have applied the transaction and which have not. This only occurs if nodes
+     * fail mid-commit, and only then in very rare circumstances.
+     */
+    public void commit() throws CommitConflictException;
+
+    /** Roll back the transaction associated with the current thread. When
+     *  this method completes, the thread is no longer associated with a
+     *  transaction and the transaction context is destroyed.
+     *
+     * @since 4.0
+     * 
+     * @throws IllegalStateException if the thread is not associated with a transaction
+     */
+    public void rollback();
+
+  /**
+   * Suspends the transaction on the current thread. All subsequent operations
+   * performed by this thread will be non-transactional. The suspended
+   * transaction can be resumed by calling {@link #resume(TransactionId)}
+   * 
+   * @return the transaction identifier of the suspended transaction or null if
+   *         the thread was not associated with a transaction
+   * @since 6.6.2
+   */
+  public TransactionId suspend();
+
+  /**
+   * On the current thread, resumes a transaction that was previously suspended
+   * using {@link #suspend()}
+   * 
+   * @param transactionId
+   *          the transaction to resume
+   * @throws IllegalStateException
+   *           if the thread is associated with a transaction or if
+   *           {@link #isSuspended(TransactionId)} would return false for the
+   *           given transactionId
+   * @since 6.6.2
+   * @see #tryResume(TransactionId)
+   */
+  public void resume(TransactionId transactionId);
+
+  /**
+   * This method can be used to determine if a transaction with the given
+   * transaction identifier is currently suspended locally. This method does not
+   * check other members for transaction status.
+   * 
+   * @param transactionId
+   * @return true if the transaction is in suspended state, false otherwise
+   * @since 6.6.2
+   * @see #exists(TransactionId)
+   */
+  public boolean isSuspended(TransactionId transactionId);
+
+  /**
+   * On the current thread, resumes a transaction that was previously suspended
+   * using {@link #suspend()}.
+   * 
+   * This method is equivalent to
+   * <pre>
+   * if (isSuspended(txId)) {
+   *   resume(txId);
+   * }
+   * </pre>
+   * except that this action is performed atomically
+   * 
+   * @param transactionId
+   *          the transaction to resume
+   * @return true if the transaction was resumed, false otherwise
+   * @since 6.6.2
+   */
+  public boolean tryResume(TransactionId transactionId);
+
+  /**
+   * On the current thread, resumes a transaction that was previously suspended
+   * using {@link #suspend()}, or waits for the specified timeout interval if
+   * the transaction has not been suspended. This method will return if:
+   * <ul>
+   * <li>Another thread suspends the transaction</li>
+   * <li>Another thread calls commit/rollback on the transaction</li>
+   * <li>This thread has waited for the specified timeout</li>
+   * </ul>
+   * 
+   * This method returns immediately if {@link #exists(TransactionId)} returns false.
+   * 
+   * @param transactionId
+   *          the transaction to resume
+   * @param time
+   *          the maximum time to wait
+   * @param unit
+   *          the time unit of the <code>time</code> argument
+   * @return true if the transaction was resumed, false otherwise
+   * @since 6.6.2
+   * @see #tryResume(TransactionId)
+   */
+  public boolean tryResume(TransactionId transactionId, long time, TimeUnit unit);
+
+  /**
+   * Reports the existence of a transaction for the given transactionId. This
+   * method can be used to determine if a transaction with the given transaction
+   * identifier is currently in progress locally.
+   * 
+   * @param transactionId
+   *          the given transaction identifier
+   * @return true if the transaction is in progress, false otherwise.
+   * @since 6.6.2
+   * @see #isSuspended(TransactionId)
+   */
+  public boolean exists(TransactionId transactionId);
+  
+    /** Reports the existence of a Transaction for this thread
+     *
+     * @return true if a transaction exists, false otherwise
+     *
+     * @since 4.0
+     */
+    public boolean exists();
+
+    /** Returns the transaction identifier for the current thread
+     *
+     * @return the transaction identifier or null if no transaction exists
+     *
+     * @since 4.0
+     */
+    public TransactionId getTransactionId();
+
+    /**
+     * Gets the transaction listener for this Cache.
+     *
+     * @return The TransactionListener instance or null if no listener.
+     * @throws IllegalStateException if more than one listener exists on this cache
+     * @deprecated as of GemFire 5.0, use {@link #getListeners} instead
+     */
+    @Deprecated
+    public TransactionListener getListener();
+
+    /** Returns an array of all the transaction listeners on this cache.
+     * Modifications to the returned array will not effect what listeners are on this cache.
+     * @return the cache's <code>TransactionListener</code>s; an empty array if no listeners
+     * @since 5.0
+     */
+    public TransactionListener[] getListeners();
+
+    /**
+     * Sets the transaction listener for this Cache.
+     *
+     * @param newListener the TransactionListener to register with the Cache.
+     *   Use a <code>null</code> to deregister the current listener without
+     *   registering a new one.
+     * @return the previous TransactionListener
+     * @throws IllegalStateException if more than one listener exists on this cache
+     * @deprecated as of GemFire 5.0, use {@link #addListener} or {@link #initListeners} instead.
+     */
+    @Deprecated
+    public TransactionListener setListener(TransactionListener newListener);
+    /**
+     * Adds a transaction listener to the end of the list of transaction listeners on this cache.
+     * @param aListener the user defined transaction listener to add to the cache.
+     * @throws IllegalArgumentException if <code>aListener</code> is null
+     * @since 5.0
+     */
+    public void addListener(TransactionListener aListener);
+    /**
+     * Removes a transaction listener from the list of transaction listeners on this cache.
+     * Does nothing if the specified listener has not been added.
+     * If the specified listener has been added then {@link CacheCallback#close} will
+     * be called on it; otherwise does nothing.
+     * @param aListener the transaction listener to remove from the cache.
+     * @throws IllegalArgumentException if <code>aListener</code> is null
+     * @since 5.0
+     */
+    public void removeListener(TransactionListener aListener);
+    /**
+     * Removes all transaction listeners, calling {@link CacheCallback#close} on each of them, and then adds each listener in the specified array.
+     * @param newListeners a possibly null or empty array of listeners to add to this cache.
+     * @throws IllegalArgumentException if the <code>newListeners</code> array has a null element
+     * @since 5.0
+     */
+    public void initListeners(TransactionListener[] newListeners);
+
+    /**
+     * Set the TransactionWriter for the cache
+     * @param writer
+     * @see TransactionWriter
+     * @since 6.5
+     */
+    public void setWriter(TransactionWriter writer);
+
+    /**
+     * Returns the current {@link TransactionWriter}
+     * @see CacheTransactionManager#setWriter(TransactionWriter)
+     * @return the current {@link TransactionWriter}
+     * @since 6.5
+     */
+    public TransactionWriter getWriter();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheWriter.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheWriter.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheWriter.java
new file mode 100644
index 0000000..5f3ca0c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheWriter.java
@@ -0,0 +1,142 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/** A user-defined object defined in the {@link RegionAttributes} that is
+ * called synchronously before a region or entry in the cache is
+ * modified. The typical use for a <code>CacheWriter</code> is to update a database.
+ * Application writers should implement these methods to execute
+ * application-specific behavior before the cache is modified.
+ *
+ * <p>Before the region is updated via a put, create, or destroy operation,
+ * GemFire will call a <code>CacheWriter</code> that is installed anywhere in any
+ * participating cache for that region, preferring a local <code>CacheWriter</code>
+ * if there is one. Usually there will be only one <code>CacheWriter</code> in
+ * the distributed system. If there are multiple <code>CacheWriter</code>s
+ * available in the distributed system, the GemFire
+ * implementation always prefers one that is stored locally, or else picks one
+ * arbitrarily; in any case only one <code>CacheWriter</code> will be invoked.
+ *
+ * <p>The <code>CacheWriter</code> is capable of aborting the update to the cache by throwing
+ * a <code>CacheWriterException</code>. This exception or any runtime exception
+ * thrown by the <code>CacheWriter</code> will abort the operation and the
+ * exception will be propagated to the initiator of the operation, regardless
+ * of whether the initiator is in the same VM as the <code>CacheWriter</code>.
+ *
+ * @author Eric Zoerner
+ *
+ * @see AttributesFactory#setCacheWriter
+ * @see RegionAttributes#getCacheWriter
+ * @see AttributesMutator#setCacheWriter
+ * @since 3.0
+ */
+public interface CacheWriter<K,V> extends CacheCallback {
+
+  /**
+   * Called before an entry is updated. The entry update is initiated by a <code>put</code>
+   * or a <code>get</code> that causes the loader to update an existing entry.
+   * The entry previously existed in the cache where the operation was
+   * initiated, although the old value may have been null. The entry being
+   * updated may or may not exist in the local cache where the CacheWriter is
+   * installed.
+   *
+   * @param event an EntryEvent that provides information about the operation in progress
+   * @throws CacheWriterException if thrown will abort the operation in progress,
+   *         and the exception will be propagated back to caller that initiated
+   *         the operation
+   * @see Region#put(Object, Object)
+   * @see Region#get(Object)
+   */
+  public void beforeUpdate(EntryEvent<K,V> event)
+  throws CacheWriterException;
+
+  /** Called before an entry is created. Entry creation is initiated by a
+   * <code>create</code>, a <code>put</code>, or a <code>get</code>.
+   * The <code>CacheWriter</code> can determine whether this value comes from a
+   * <code>get</code> or not by evaluating the {@link CacheEvent#getOperation() Operation}'s {@link Operation#isLoad()} method.
+   * The entry being created may already exist in the local cache where this <code>CacheWriter</code>
+   * is installed, but it does not yet exist in the cache where the operation was initiated.
+   * @param event an EntryEvent that provides information about the operation in progress
+   * @throws CacheWriterException if thrown will abort the operation in progress,
+   *         and the exception will be propagated back to caller that initiated
+   *         the operation
+   * @see Region#create(Object, Object)
+   * @see Region#put(Object, Object)
+   * @see Region#get(Object)
+   */
+  public void beforeCreate(EntryEvent<K,V> event)
+  throws CacheWriterException;
+
+  /**
+   * Called before an entry is destroyed. The entry being destroyed may or may
+   * not exist in the local cache where the CacheWriter is installed. This method
+   * is <em>not</em> called as a result of expiration or 
+   * {@link Region#localDestroy(Object)}.
+   *
+   * @param event an EntryEvent that provides information about the operation in progress
+   * @throws CacheWriterException if thrown will abort the operation in progress,
+   *         and the exception will be propagated back to caller that initiated
+   *         the operation
+   *
+   * @see Region#destroy(Object)
+   */
+  public void beforeDestroy(EntryEvent<K,V> event)
+  throws CacheWriterException;
+
+  /**
+   * Called before a region is destroyed. The <code>CacheWriter</code>
+   * will not additionally be called for each entry that is destroyed
+   * in the region as a result of a region destroy. If the region's
+   * subregions have <code>CacheWriter</code>s installed, then they
+   * will be called for the cascading subregion destroys.
+   * This method is <em>not</em> called as a result of
+   * {@link Region#close}, {@link Cache#close}, or {@link Region#localDestroyRegion()}.  However, the
+   * {@link Region#close} method is invoked regardless of whether a
+   * region is destroyed locally.  A non-local region destroy results
+   * in an invocation of {@link #beforeRegionDestroy} followed by an
+   * invocation of {@link Region#close}.
+   *<p>
+   * WARNING: This method should not destroy or create any regions itself or a
+   * deadlock will occur.
+   *
+   * @param event
+   *        a RegionEvent that provides information about the operation
+   *
+   * @throws CacheWriterException
+   *         if thrown, will abort the operation in progress, and the
+   *         exception will be propagated back to the caller that
+   *         initiated the operation
+   *
+   * @see Region#destroyRegion()
+   */
+  public void beforeRegionDestroy(RegionEvent<K,V> event)
+  throws CacheWriterException;
+
+  /**
+   * Called before a region is cleared. The <code>CacheWriter</code>
+   * will not additionally be called for each entry that is cleared
+   * in the region as a result of a region clear. 
+   * 
+   *<p>
+   * WARNING: This method should not clear/destroy any regions 
+   * 
+   *
+   * @param event
+   *        a RegionEvent that provides information about the operation
+   *
+   * @throws CacheWriterException
+   *         if thrown, will abort the operation in progress, and the
+   *         exception will be propagated back to the caller that
+   *         initiated the operation
+   *
+   * @see Region#clear
+   */
+  public void beforeRegionClear(RegionEvent<K,V> event)
+  throws CacheWriterException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheWriterException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheWriterException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheWriterException.java
new file mode 100644
index 0000000..11437c1
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheWriterException.java
@@ -0,0 +1,61 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/**
+ * An exception thrown by a <code>CacheWriter</code> method. This exception
+ * is propagated back to the caller that initiated modification of the
+ * cache, even if the caller is not in the same cache VM.
+ *
+ * @author Eric Zoerner
+ *
+ * @see CacheWriter
+ * @see com.gemstone.gemfire.cache.Region#put(Object, Object)
+ * @see com.gemstone.gemfire.cache.Region#destroy(Object)
+ * @see com.gemstone.gemfire.cache.Region#create(Object, Object)
+ * @see com.gemstone.gemfire.cache.Region#destroyRegion()
+ * @see com.gemstone.gemfire.cache.Region#get(Object)
+ * @since 3.0
+ */
+public class CacheWriterException extends OperationAbortedException {
+private static final long serialVersionUID = -2872212342970454458L;
+  
+  /**
+   * Creates a new instance of <code>CacheWriterException</code>.
+   */
+  public CacheWriterException() {
+  }
+  
+  
+  /**
+   * Constructs an instance of <code>CacheWriterException</code> with the specified detail message.
+   * @param msg the detail message
+   */
+  public CacheWriterException(String msg) {
+    super(msg);
+  }
+  
+  /**
+   * Constructs an instance of <code>CacheWriterException</code> with the specified detail message
+   * and cause.
+   * @param msg the detail message
+   * @param cause the causal Throwable
+   */
+  public CacheWriterException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+  
+  /**
+   * Constructs an instance of <code>CacheWriterException</code> with the specified cause.
+   * @param cause the causal Throwable
+   */
+  public CacheWriterException(Throwable cause) {
+    super(cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheXmlException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheXmlException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheXmlException.java
new file mode 100644
index 0000000..a88c5ff
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheXmlException.java
@@ -0,0 +1,41 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * Thrown when a problem is encountered while parsing a <A
+ * href="package-summary.html#declarative">declarative caching XML
+ * file</A>.  Examples of such problems are a malformed XML file or
+ * the inability to load a {@link Declarable} class.
+ *
+ * @see CacheFactory#create
+ *
+ * @author David Whitlock
+ *
+ * @since 3.0
+ */
+public class CacheXmlException extends CacheRuntimeException {
+private static final long serialVersionUID = -4343870964883131754L;
+
+  /**
+   * Creates a new <code>CacheXmlException</code> with the given
+   * description and cause.
+   */
+  public CacheXmlException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Creates a new <code>CacheXmlException</code> with the given
+   * description.
+   */
+  public CacheXmlException(String message) {
+    super(message);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ClientSession.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ClientSession.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ClientSession.java
new file mode 100755
index 0000000..cea178f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ClientSession.java
@@ -0,0 +1,189 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/**
+ * Class <code>ClientSession</code> represents a client connection on the
+ * server. <code>ClientSessions</code> can be used from the cache server to
+ * perform interest registrations and unregistrations on behalf of clients.
+ * <code>ClientSessions</code> are only available on the cache server.
+ * 
+ * <p>
+ * The ClientSession is often used in conjunction with a callback
+ * <code>EntryEvent</code> as shown below.
+ * 
+ * <pre>
+ * String durableClientId = ...; // Some part of the event's key or value would contain this id
+ * Cache cache = CacheFactory.getAnyInstance();
+ * CacheServer cacheServer = (CacheServer) cache.getCacheServers().iterator().next();
+ * ClientSession clientSession = cacheServer.getClientSession(durableClientId);
+ * clientSession.registerInterest(event.getRegion().getFullPath(), event.getKey(), InterestResultPolicy.KEYS_VALUES, true);
+ * </pre>
+ * 
+ * @author Barry Oglesby
+ * @since 6.0
+ * @see com.gemstone.gemfire.cache.server.CacheServer#getClientSession(String)
+ *      getClientSession
+ * @see com.gemstone.gemfire.cache.server.CacheServer#getClientSession(com.gemstone.gemfire.distributed.DistributedMember)
+ *      getClientSession
+ *
+ */
+public interface ClientSession {
+
+  /**
+   * Registers interest in a particular region and key
+   * 
+   * @param regionName
+   *          The name of the region in which to register interest
+   * @param keyOfInterest
+   *          The key on which to register interest
+   * @param policy
+   *          The {@link com.gemstone.gemfire.cache.InterestResultPolicy}. Note:
+   *          For the special token 'ALL_KEYS' and lists of keys, values are not
+   *          pushed to the client.
+   * @param isDurable
+   *          Whether the interest is durable
+   * @throws IllegalStateException
+   *           if this is not the primary server for the given client
+   */
+  public void registerInterest(String regionName, Object keyOfInterest,
+      InterestResultPolicy policy, boolean isDurable);
+
+  /**
+   * Registers interest in a particular region and key
+   *
+   * @param regionName
+   *          The name of the region in which to register interest
+   * @param keyOfInterest
+   *          The key to on which to register interest
+   * @param policy
+   *          The {@link com.gemstone.gemfire.cache.InterestResultPolicy}. Note:
+   *          For the special token 'ALL_KEYS' and lists of keys, values are not
+   *          pushed to the client.
+   * @param isDurable
+   *          Whether the interest is durable
+   * @param receiveValues
+   *          Whether to receive create or update events as invalidates similar
+   *          to notify-by-subscription false. The default is true.
+   * @throws IllegalStateException
+   *          if this is not the primary server for the given client
+   * @since 6.5
+   */
+  public void registerInterest(String regionName, Object keyOfInterest,
+      InterestResultPolicy policy, boolean isDurable, boolean receiveValues);
+  
+  /**
+   * Registers interest in a particular region and regular expression
+   *
+   * @param regionName
+   *          The name of the region in which to register interest
+   * @param regex
+   *          The regular expression on which to register interest
+   * @param isDurable
+   *          Whether the interest is durable
+   * @throws IllegalStateException
+   *          if this is not the primary server for the given client
+   */
+  public void registerInterestRegex(String regionName, String regex,
+      boolean isDurable);
+  
+  /**
+   * Registers interest in a particular region and regular expression
+   * 
+   * @param regionName
+   *          The name of the region in which to register interest
+   * @param regex
+   *          The regular expression to on which to register interest
+   * @param isDurable
+   *          Whether the interest is durable
+   * @param receiveValues
+   *          Whether to receive create or update events as invalidates similar
+   *          to notify-by-subscription false. The default is true.
+   * @throws IllegalStateException
+   *           if this is not the primary server for the given client
+   * @since 6.5
+   */
+  public void registerInterestRegex(String regionName, String regex,
+      boolean isDurable, boolean receiveValues);
+
+  /**
+   * Unregisters interest in a particular region and key
+   * 
+   * @param regionName
+   *          The name of the region in which to unregister interest
+   * @param keyOfInterest
+   *          The key on which to unregister interest
+   * @param isDurable
+   *          Whether the interest is durable
+   * @throws IllegalStateException
+   *           if this is not the primary server for the given client
+   */
+  public void unregisterInterest(String regionName, Object keyOfInterest,
+      boolean isDurable);
+  
+  /**
+   * Unregisters interest in a particular region and key
+   * 
+   * @param regionName
+   *          The name of the region in which to unregister interest
+   * @param keyOfInterest
+   *          The key on which to unregister interest
+   * @param isDurable
+   *          Whether the interest is durable
+   * @param receiveValues
+   *          Whether to receive create or update events as invalidates similar
+   *          to notify-by-subscription false. The default is true.
+   * @throws IllegalStateException
+   *           if this is not the primary server for the given client
+   * @since 6.5
+   */
+  public void unregisterInterest(String regionName, Object keyOfInterest,
+      boolean isDurable, boolean receiveValues);
+
+  /**
+   * Unregisters interest in a particular region and regular expression
+   * 
+   * @param regionName
+   *          The name of the region in which to unregister interest
+   * @param regex
+   *          The regular expression on which to unregister interest
+   * @param isDurable
+   *          Whether the interest is durable
+   * @throws IllegalStateException
+   *           if this is not the primary server for the given client
+   */
+  public void unregisterInterestRegex(String regionName, String regex,
+      boolean isDurable);
+
+  /**
+   * Unregisters interest in a particular region and regular expression
+   * 
+   * @param regionName
+   *          The name of the region in which to unregister interest
+   * @param regex
+   *          The regular expression on which to unregister interest
+   * @param isDurable
+   *          Whether the interest is durable
+   * @param receiveValues
+   *          Whether to receive create or update events as invalidates similar
+   *          to notify-by-subscription false. The default is true.
+   * @throws IllegalStateException
+   *           if this is not the primary server for the given client
+   * @since 6.5
+   */
+  public void unregisterInterestRegex(String regionName, String regex,
+      boolean isDurable, boolean receiveValues);
+
+  /**
+   * Returns whether this server is the primary for this client
+   *
+   * @return whether this server is the primary for this client
+   */
+  public boolean isPrimary();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CommitConflictException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CommitConflictException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CommitConflictException.java
new file mode 100644
index 0000000..a957ebc
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CommitConflictException.java
@@ -0,0 +1,48 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/** Thrown when a commit fails due to a write conflict.
+ *
+ * @author Darrel Schneider
+ *
+ * @see CacheTransactionManager#commit
+ * @since 4.0
+ */
+public class CommitConflictException extends TransactionException {
+  private static final long serialVersionUID = -1491184174802596675L;
+
+  /**
+   * Constructs an instance of <code>CommitConflictException</code> with the specified detail message.
+   * @param msg the detail message
+   */
+  public CommitConflictException(String msg) {
+    super(msg);
+  }
+  
+  /**
+   * Constructs an instance of <code>CommitConflictException</code> with the specified detail message
+   * and cause.
+   * @param msg the detail message
+   * @param cause the causal Throwable
+   */
+  public CommitConflictException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+  
+  /**
+   * Constructs an instance of <code>CommitConflictException</code> with the specified cause.
+   * @param cause the causal Throwable
+   * @since 6.5
+   */
+  public CommitConflictException(Throwable cause) {
+    super(cause);
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CommitDistributionException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CommitDistributionException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CommitDistributionException.java
new file mode 100755
index 0000000..7763f54
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CommitDistributionException.java
@@ -0,0 +1,72 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import java.util.*;
+
+/**
+ * Indicates that an attempt to notify required participants of a transaction 
+ * involving one or more regions that are configured with {@link 
+ * MembershipAttributes} may have failed. The commit itself was completed but
+ * one or more regions affected by the transaction have one or more required
+ * roles that were not successfully notified. Failure may be caused by 
+ * departure of one or more required roles while sending the operation to
+ * them. This exception will contain one {@link RegionDistributionException}
+ * for every region that had a reliability failure. Details of the failed
+ * {@link MembershipAttributes#getRequiredRoles required roles} are provided
+ *  in each RegionDistributionException.
+ *
+ * @author Kirk Lund
+ * @since 5.0
+ */
+public class CommitDistributionException extends TransactionException {
+  private static final long serialVersionUID = -3517820638706581823L;
+  /** 
+   * The RegionDistributionExceptions for every region that had a reliability
+   * failure during distribution of the operation.
+   */
+  private Set regionDistributionExceptions = Collections.EMPTY_SET;
+  
+  /** 
+   * Constructs a <code>CommitDistributionException</code> with a message.
+   *
+   * @param s the String message
+   */
+  public CommitDistributionException(String s) {
+    super(s);
+  }
+  
+  /** 
+   * Constructs a <code>CommitDistributionException</code> with a message and
+   * a cause.
+   *
+   * @param s the String message
+   * @param regionDistributionExceptions set of RegionDistributionExceptions
+   * for each region that had a reliability failure
+   */
+  public CommitDistributionException(String s, Set regionDistributionExceptions) {
+    super(s);
+    this.regionDistributionExceptions = regionDistributionExceptions;
+    if (this.regionDistributionExceptions == null) {
+      this.regionDistributionExceptions = Collections.EMPTY_SET;
+    }
+  }
+  
+  /** 
+   * Returns set of RegionDistributionExceptions for each region that had a 
+   * reliability failure during distribution of the operation.
+   *
+   * @return set of RegionDistributionExceptions for each region that had a 
+   * reliability failure during distribution of the operation
+   */
+  public Set getRegionDistributionExceptions() {
+    return this.regionDistributionExceptions;
+  }
+  
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CommitIncompleteException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CommitIncompleteException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CommitIncompleteException.java
new file mode 100644
index 0000000..f0aa031
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CommitIncompleteException.java
@@ -0,0 +1,15 @@
+package com.gemstone.gemfire.cache;
+
+/**
+ * Thrown when a commit fails to complete due to errors
+ * @author Mitch Thomas
+ * @since 5.7
+ */
+public class CommitIncompleteException extends TransactionException {
+private static final long serialVersionUID = 1017741483744420800L;
+
+  public CommitIncompleteException(String message) {
+    super(message);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CustomExpiry.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CustomExpiry.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CustomExpiry.java
new file mode 100644
index 0000000..fbcf398
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CustomExpiry.java
@@ -0,0 +1,33 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/**
+ * This is the contract that a <code>custom-expiry</code> element must honor.
+ * It determines the expiration characteristics for a specific entry in a region.
+ * <p>Note that if you wish to refer to an implementation of this interface in XML,
+ * the implementation must also implement the Declarable interface.
+ * 
+ * @author jpenney
+ *
+ */
+public interface CustomExpiry<K,V> extends CacheCallback {
+
+  /**
+   * Calculate the expiration for a given entry.
+   * Returning null indicates that the
+   * default for the region should be used.
+   * <p>
+   * The entry parameter should not be used after this method invocation completes.
+   * @param entry the entry to calculate the expiration for
+   * @return the expiration to be used, null if the region's defaults should be
+   * used.
+   */
+  public ExpirationAttributes getExpiry(Region.Entry<K,V> entry);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DataPolicy.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DataPolicy.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DataPolicy.java
new file mode 100644
index 0000000..fdf9a12
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DataPolicy.java
@@ -0,0 +1,246 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+
+package com.gemstone.gemfire.cache;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import java.io.*;
+
+/**
+ * Enumerated type for region data policy.
+ * The data policy specifies how this local cache will handle the data for a region.
+ * <ol>
+ * <li><code>EMPTY</code> causes data to never be stored in local memory. The region will always appear empty. It can be used to for zero footprint producers that only want to distribute their data to others and for zero footprint consumers that only want to see events.
+ * <li><code>NORMAL</code> causes data that this region is interested in to be stored in local memory. It allows the contents in this cache to differ from other caches.
+ * <li><code>PARTITION</code> causes data that this region holds to be spread across processes.  The amount of data held in this cache is configured in {@link PartitionAttributes} with a {@link PartitionAttributesFactory}.
+ * <li><code>PERSISTENT_PARTITION</code> in addition to <code>PARTITION</code> also causes data to be stored to disk. The region initialization uses the data stored on disk.
+ * <li><code>REPLICATE</code> causes data that this region is interested in to be stored in local memory. A distributed region will be initialized with the data from other caches. On distributed region operations that would cause the contents to differ with other caches are not allowed. This policy is allowed on local scope region but it behaves the same as <code>NORMAL</code>.
+ * <li><code>PERSISTENT_REPLICATE</code> in addition to <code>REPLICATE</code> also causes data to be stored to disk. The region initialization uses the data stored on disk. Note that the persistence applies to both local scope and distributed scope.
+ * </ol>
+ *
+ * @author Darrel Schneider
+ *
+ *
+ * @see AttributesFactory#setDataPolicy
+ * @see RegionAttributes#getDataPolicy
+ *
+ * @since 5.0
+ */
+public class DataPolicy implements java.io.Serializable {
+  private static final long serialVersionUID = 2095573273889467233L;
+
+  private static final DataPolicy[] VALUES = new DataPolicy[10];
+
+  /**
+   * Data is never stored in local memory.
+   * The region will always be empty locally.
+   * It can be used to for zero footprint producers that only want to distribute
+   * their data to others
+   * and for zero footprint consumers that only want to see events.
+   */
+  public static final DataPolicy EMPTY = new DataPolicy(0, "EMPTY");
+
+  /**
+   * Allows the contents in this cache to differ from other caches.<p>
+   * Data that this region is interested in is stored in local memory.
+   */
+  public static final DataPolicy NORMAL = new DataPolicy(1, "NORMAL");
+
+  /**
+   * The region will be initialized with the data from other caches and accepts
+   * any new entries created in other caches.<p>
+   * Operations that would cause the contents to differ with other caches
+   * are not allowed.<p>
+   * Data that this region is interested in is stored in local memory.
+   */
+  public static final DataPolicy REPLICATE = new DataPolicy(2, "REPLICATE");
+
+  /**
+   * In addition to <code>REPLICATE</code> also causes data to be stored to
+   * disk. The region initialization may use the data stored on disk.
+   */
+  public static final DataPolicy PERSISTENT_REPLICATE = new DataPolicy(3, "PERSISTENT_REPLICATE");
+  
+  
+  /**
+   * Data in this region may be spread across a number of processes.  This is
+   * further configured with {@link PartitionAttributes partitioning attributes}
+   */
+  public static final DataPolicy PARTITION = new DataPolicy(4, "PARTITION");
+
+  /**
+  * In addition to <code>NORMAL</code>, contents inside of this cache are
+  * (partially) initialized with data from other caches, if available.
+  */
+  public static final DataPolicy PRELOADED = new DataPolicy(5, "PRELOADED");
+
+  /**
+   * In addition to <code>PARTITION</code> also causes data to be stored to
+   * disk. The region initialization may use the data stored on disk.
+   * @since 6.5
+   */
+  public static final DataPolicy PERSISTENT_PARTITION = new DataPolicy(6, "PERSISTENT_PARTITION");
+  
+   /**
+   * The data policy used by default; it is {@link #NORMAL}.
+   */
+  public static final DataPolicy DEFAULT = NORMAL;
+
+    
+  /** The name of this mirror type. */
+  private final transient String name;
+    
+  /** used as ordinal to represent this DataPolicy */
+  public final byte ordinal;
+
+  private Object readResolve() throws ObjectStreamException {
+    return VALUES[ordinal];  // Canonicalize
+  }
+    
+    
+  /** Creates a new instance of DataPolicy. */
+  private DataPolicy(int ordinal, String name) {
+    if (ordinal >= VALUES.length) {
+      throw new IllegalArgumentException(LocalizedStrings.DataPolicy_ONLY_0_DATAPOLICIES_MAY_BE_DEFINED.toLocalizedString(Integer.valueOf(VALUES.length+1)));
+    }
+    if (VALUES[ordinal] != null) {
+      throw new IllegalArgumentException(LocalizedStrings.DataPolicy_ORDINAL_0_IS_ALREADY_DEFINED_BY_1.toLocalizedString(new Object[] {Integer.valueOf(ordinal), VALUES[ordinal]}));
+    }
+    this.name = name;
+    this.ordinal = (byte)(ordinal & 0xff);
+    VALUES[this.ordinal] = this;
+  }
+    
+  /** Return the DataPolicy represented by specified ordinal */
+  public static DataPolicy fromOrdinal(byte ordinal) {
+    return VALUES[ordinal];
+  }
+    
+    
+  /** Return true if regions with this policy store data locally.<p>
+   * Although DataPolicy {@link #PARTITION} will return true to this query,
+   * it is possible to turn off local storage with
+   * {@link PartitionAttributesFactory#setLocalMaxMemory(int)} by setting
+   * localMaxMemory to zero. 
+   * @return true if regions with this policy store data locally.
+   * @see #NORMAL
+   * @see #PRELOADED
+   * @see #REPLICATE
+   * @see #PERSISTENT_REPLICATE
+   * @see #PARTITION
+   * @see #PERSISTENT_PARTITION
+   */
+  public boolean withStorage() {
+    return this != EMPTY;
+  }
+
+  /** Return whether this policy does replication.
+   * @return true if this policy does replication.
+   * @see #REPLICATE
+   * @see #PERSISTENT_REPLICATE
+   */
+  public boolean withReplication() {
+    return this == REPLICATE || this == PERSISTENT_REPLICATE;
+  }
+  
+  /** Return whether this policy does persistence.
+   * @return true if this policy does persistence.
+   * @see #PERSISTENT_PARTITION
+   * @see #PERSISTENT_REPLICATE
+   * @since 6.5
+   */
+  public boolean withPersistence() {
+    return this == PERSISTENT_PARTITION || this == PERSISTENT_REPLICATE;
+  }
+
+  /** Return whether this policy does partitioning.
+   * @return true if this policy does partitioning
+   * @see #PARTITION
+   * @see #PERSISTENT_PARTITION
+   * @since 6.5
+   */
+  public boolean withPartitioning() {
+    return this == PARTITION || this == PERSISTENT_PARTITION;
+  }
+
+  /** Return whether this policy does preloaded.
+   * @return true if this policy does preloaded.
+   * @see #PRELOADED
+   * @since 6.5
+   */
+  public boolean withPreloaded() {
+    return this == PRELOADED;
+  }
+
+  /**
+   * Return true if this policy is {@link #EMPTY}.
+   * @return true if this policy is {@link #EMPTY}.
+   * @deprecated from version 6.5 forward please use withStorage()
+   */
+  public boolean isEmpty() {
+    return this == EMPTY;
+  }
+  /**
+   * Return true if this policy is {@link #NORMAL}.
+   * @return true if this policy is {@link #NORMAL}.
+   * @deprecated from version 6.5 forward please use an identity comparison instead of this method
+   */
+  public boolean isNormal() {
+    return this == NORMAL;
+  }
+  /**
+   * Return true if this policy is {@link #PRELOADED}.
+   * @return true if this policy is {@link #PRELOADED}
+   * @deprecated from version 6.5 forward please use withPreloaded()
+   */
+  public boolean isPreloaded() {
+    return this == PRELOADED;
+  }
+  /**
+   * Return true if this policy is the default.
+   * @return true if this policy is the default.
+   * @deprecated from version 6.5 forward please use an identity comparison instead of this method
+   */
+  public boolean isDefault() {
+    return this == DEFAULT;
+  }
+  /**
+   * Return true if this policy is {@link #REPLICATE}.
+   * @return true if this policy is {@link #REPLICATE}.
+   * @deprecated from version 6.5 forward please use withReplication()
+   */
+  public boolean isReplicate() {
+    return this == REPLICATE;
+  }
+  /**
+   * Return true if this policy is {@link #PERSISTENT_REPLICATE}.
+   * @return true if this policy is {@link #PERSISTENT_REPLICATE}.
+   * @deprecated from version 6.5 forward please use withPersistence() and withReplication()
+   */
+  public boolean isPersistentReplicate() {
+    return this == PERSISTENT_REPLICATE;
+  }
+  
+  /**
+   * Return true if this policy is {@link #PARTITION}.
+   * @return true if this policy is {@link #PARTITION}
+   * @deprecated from version 6.5 forward please use withPartitioning()
+   */
+  public boolean isPartition() {
+    return this == PARTITION;
+  }
+  
+  /** Returns a string representation for this data policy.
+     * @return the name of this data policy.
+     */
+  @Override
+  public String toString() {
+    return this.name;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Declarable.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Declarable.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Declarable.java
new file mode 100644
index 0000000..4f2633d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Declarable.java
@@ -0,0 +1,68 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import java.util.Properties;
+
+/** 
+ * An object that can be described in a declarative caching XML file.
+ *
+ * <p>
+ *
+ * Any user-defined object in the declarative caching xml file
+ * should implement this interface in order to be constructed.
+ *
+ * <p>
+ *
+ * For example, the user can declare a <code>CacheLoader</code> in a declarative
+ * XML file as follows:
+ *
+ * <pre>
+ *        &lt;cache-loader&gt;
+ *          &lt;class-name&gt;com.company.app.DBLoader&lt;/class-name&gt;
+ *          &lt;parameter name="URL"&gt;
+ *            &lt;string&gt;jdbc://12.34.56.78/mydb&lt;/string&gt;
+ *          &lt;/parameter&gt;
+ *        &lt;/cache-loader&gt;
+ * </pre>
+ *
+ * <p>
+ *
+ * In this case, <code>com.company.app.DBLoader</code> must 
+ * implement both the {@link CacheLoader} and <code>Declarable</code>
+ * interfaces. The cache service will construct a
+ * <code>com.company.app.DBLoader</code> object by invoking the loader's
+ * zero-argument constructor and then calling the {@link #init} method
+ * to pass in the parameters.
+ *
+ * <P>
+ *
+ * See <a href="package-summary.html#declarative">package introduction</a>.
+ *
+ * @author Darrel Schneider
+ *
+ * 
+ * @since 2.0
+ */
+public interface Declarable {
+
+  /**
+   * Initializes a user-defined object using the given properties.
+   * Note that any uncaught exception thrown by this method will cause
+   * the <code>Cache</code> initialization to fail.
+   *
+   * @param props 
+   *        Contains the parameters declared in the declarative xml
+   *        file.
+   *
+   * @throws IllegalArgumentException
+   *         If one of the configuration options in <code>props</code>
+   *         is illegal or malformed.
+   */
+  public void init(Properties props);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskAccessException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskAccessException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskAccessException.java
new file mode 100644
index 0000000..c3ce541
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskAccessException.java
@@ -0,0 +1,132 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import java.io.IOException;
+
+/**
+ * Indicates that an <code>IOException</code> during a disk region operation.
+ *
+ * @author Darrel Schneider
+ *
+ *
+ * @since 3.2
+ */
+public class DiskAccessException extends CacheRuntimeException {
+  private static final long serialVersionUID = 5799100281147167888L;
+
+  private transient boolean isRemote;
+  
+  /**
+   * Constructs a new <code>DiskAccessException</code>.
+   */
+  public DiskAccessException() {
+    super();
+  }
+  
+  /**
+   * Constructs a new <code>DiskAccessException</code> with a message string.
+   *
+   * @param msg a message string
+   * @param r The Region for which the disk operation failed
+   */
+  public DiskAccessException(String msg, Region r) {
+    this(msg, null, r == null ? null : r.getFullPath());
+  }
+  
+  /**
+   * Constructs a new <code>DiskAccessException</code> with a message string.
+   *
+   * @param msg a message string
+   * @param regionName The name of the Region for which the disk operation failed
+   * @since 6.5
+   */
+  public DiskAccessException(String msg, String regionName) {
+    this(msg, null, regionName);
+  }
+
+  /**
+   * Constructs a new <code>DiskAccessException</code> with a message string.
+   *
+   * @param msg a message string
+   * @param ds The disk store for which the disk operation failed
+   * @since 6.5
+   */
+  public DiskAccessException(String msg, DiskStore ds) {
+    this(msg, null, ds);
+  }
+  
+  /**
+   * Constructs a new <code>DiskAccessException</code> with a message string
+   * and a cause.
+   *
+   * @param msg the message string
+   * @param cause a causal Throwable
+   * @param regionName The name of the Region for which the disk operation failed
+   * @since 6.5
+   */
+  public DiskAccessException(String msg, Throwable cause, String regionName) {
+    super((regionName!=null ? "For Region: " + regionName + ": " : "") + msg, cause);
+  }
+
+  /**
+   * Constructs a new <code>DiskAccessException</code> with a message string
+   * and a cause.
+   *
+   * @param msg the message string
+   * @param cause a causal Throwable
+   * @param ds The disk store for which the disk operation failed
+   * @since 6.5
+   */
+  public DiskAccessException(String msg, Throwable cause, DiskStore ds) {
+    super((ds!=null ? "For DiskStore: " + ds.getName() + ": " : "") + msg, cause);
+  }
+  
+  /**
+   * Constructs a new <code>DiskAccessException</code> with a cause.
+   *
+   * @param cause a causal Throwable
+   */
+  public DiskAccessException(Throwable cause) {
+    super(cause);
+  }
+  
+  /**
+   * Constructs a new <code>DiskAccessException</code> with a message string
+   * and a cause.
+   *
+   * @param msg the message string
+   * @param cause a causal Throwable
+   * @since gemfire 8.0
+   */
+  public DiskAccessException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+  
+  /**
+   * Returns true if this exception originated from a remote node.
+   */
+  public final boolean isRemote() {
+    return this.isRemote;
+  }
+
+  // Overrides to set "isRemote" flag after deserialization
+
+  private synchronized void writeObject(final java.io.ObjectOutputStream out)
+      throws IOException {
+    getStackTrace(); // Ensure that stackTrace field is initialized.
+    out.defaultWriteObject();
+  }
+
+  private void readObject(final java.io.ObjectInputStream in)
+      throws IOException, ClassNotFoundException {
+    in.defaultReadObject();
+    this.isRemote = true;
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskStore.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskStore.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskStore.java
new file mode 100644
index 0000000..fe2056c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskStore.java
@@ -0,0 +1,207 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import java.io.File;
+import java.util.UUID;
+
+/**
+ * Provides disk storage for one or more regions. The regions in the same disk store will
+ * share the same disk persistence attributes. A region without a disk store name
+ * belongs to the default disk store.
+ * <p>Instances of this interface are created using
+ * {@link DiskStoreFactory#create}. So to create a <code>DiskStore</code> named <code>myDiskStore</code> do this:
+ * <PRE>
+ *   new DiskStoreFactory().create("myDiskStore");
+ * </PRE>
+ * <p>Existing DiskStore instances can be found using {@link Cache#findDiskStore(String)}
+ *
+ * @author Gester
+ * @since 6.5
+ *
+ */
+public interface DiskStore {
+
+  /**
+   * Get the name of the DiskStore
+   *
+   * @return the name of the DiskStore
+   * @see DiskStoreFactory#create
+   */
+  public String getName();
+
+  /**
+   * Returns true if the disk files are to be automatically compacted.
+   *
+   * @return Returns true if the disk files are to be automatically compacted;
+   *         false if automatic compaction is turned off
+   */
+  public boolean getAutoCompact();
+
+  /**
+   * Returns the threshold at which an oplog will become compactable. Until it reaches
+   * this threshold the oplog will not be compacted.
+   * The threshold is a percentage in the range 0..100.
+   * @return the threshold, as a percentage, at which an oplog is considered compactable.
+   */
+  public int getCompactionThreshold();
+
+  /**
+   * Returns true if manual compaction of disk files is allowed on this region.
+   * Manual compaction is done be calling {@link #forceCompaction}.
+   * <p>Note that calls to {@link #forceCompaction} will also be allowed if {@link #getAutoCompact automatic compaction} is enabled.
+   *
+   * @return Returns true if manual compaction of disk files is allowed on this region.
+   */
+  public boolean getAllowForceCompaction();
+
+  /**
+   * Get the maximum size in megabytes a single oplog (operation log) file should be
+   *
+   * @return the maximum size in megabyte the operations log file can be
+   */
+  public long getMaxOplogSize();
+
+  /**
+   * Returns the number of milliseconds that can elapse before
+   * unwritten data is written to disk.
+   *
+   * @return Returns the time interval in milliseconds that can elapse between two writes to disk
+   */
+  public long getTimeInterval();
+
+  /**
+   * Returns the size of the write buffer that this disk store will use when
+   * writing data to disk. Larger values may increase performance but will use
+   * more memory.
+   * The disk store will allocate one direct memory buffer of this size.
+   *
+   * @return Returns the size of the write buffer.
+   */
+  public int getWriteBufferSize();
+
+  /**
+   * Returns the directories to which the region's data are written.  If
+   * multiple directories are used, GemFire will attempt to distribute the
+   * data evenly amongst them.
+   *
+   */
+  public File[] getDiskDirs();
+
+  /**
+   * Returns the sizes of the disk directories in megabytes
+   */
+  public int[] getDiskDirSizes();
+
+  /**
+   * Returns the universally unique identifier for the Disk Store across the GemFire distributed system.
+   * </p>
+   * @return a UUID uniquely identifying this Disk Store in the GemFire distributed system.
+   * @see java.util.UUID
+   */
+  public UUID getDiskStoreUUID();
+
+  /**
+   * Returns the maximum number of operations that can be asynchronously
+   * queued to be written to disk. When this limit is reached, it will cause
+   * operations to block until they can be put in the queue.
+   * If this <code>DiskStore</code> configures synchronous writing, then
+   * <code>queueSize</code> is ignored.
+   *
+   * @return the maxinum number of entries that can be queued concurrently
+   * for asynchronous writting to disk.
+   *
+   */
+  public int getQueueSize();
+
+  /**
+   * Causes any data that is currently in the asynchronous queue to be written
+   * to disk. Does not return until the flush is complete.
+   *
+   * @throws DiskAccessException
+   *         If problems are encounter while writing to disk
+   */
+  public void flush();
+
+  /**
+   * Asks the disk store to start writing to a new oplog.
+   * The old oplog will be asynchronously compressed if compaction is set to true.
+   * The new oplog will be created in the next available directory with free space.
+   * If there is no directory with free space available and compaction is set to false,
+   * then a <code>DiskAccessException</code> saying that the disk is full will be
+   * thrown.
+   * If compaction is true then the application will wait for the other oplogs
+   * to be compacted and more space to be created.
+   *
+   * @throws DiskAccessException
+   */
+  public void forceRoll();
+
+   /**
+    * Allows a disk compaction to be forced on this disk store. The compaction
+    * is done even if automatic compaction is not configured.
+    * If the current active oplog has had data written to it and it is
+    * compactable then an implicit call to {@link #forceRoll} will be made
+    * so that the active oplog can be compacted.
+    * <P>This method will block until the compaction completes.
+    * @return <code>true</code> if one or more oplogs were compacted;
+    * <code>false</code> indicates that no oplogs were ready
+    * to be compacted or that a compaction was already in progress.
+    * @see #getAllowForceCompaction
+    */
+  public boolean forceCompaction();
+  
+  /**
+   * Destroys this disk store. Removes the disk store from the cache,
+   * and removes all files related to the disk store from disk.
+   * 
+   * If there are any currently open regions in the disk store
+   * this method will throw an exception. If there are any closed regions that 
+   * are persisted in this disk store, the data for those regions 
+   * will be destroyed. 
+   *
+   * @throws IllegalStateException if the disk store is currently
+   * in use by any regions, gateway senders, or a PDX type registry.
+   * 
+   * @since 8.0
+   */
+  public void destroy();
+  
+
+  /**
+   * Returns the warning threshold for disk usage as a percentage of the total 
+   * disk volume.
+   * 
+   * @return the warning percent
+   * @since 8.0
+   */
+  public float getDiskUsageWarningPercentage();
+
+  /**
+   * Returns the critical threshold for disk usage as a percentage of the total 
+   * disk volume.
+   * 
+   * @return the critical percent
+   * @since 8.0
+   */
+  public float getDiskUsageCriticalPercentage();
+  
+  /**
+   * Sets the value of the disk usage warning percentage.
+   * 
+   * @param warningPercent the warning percent
+   */
+  public void setDiskUsageWarningPercentage(float warningPercent);
+  
+  /**
+   * Sets the value of the disk usage critical percentage.
+   * 
+   * @param criticalPercent the critical percent
+   */
+  public void setDiskUsageCriticalPercentage(float criticalPercent);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskStoreFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskStoreFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskStoreFactory.java
new file mode 100755
index 0000000..ab67c75
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskStoreFactory.java
@@ -0,0 +1,234 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+
+import java.io.File;
+
+/**
+ * Factory for creating instances of {@link DiskStore}.
+ * To get an instance of this factory call {@link Cache#createDiskStoreFactory}.
+ * If all you want to do is find an existing disk store see {@link Cache#findDiskStore}.
+ * <P>
+ * To use this factory configure it with the <code>set</code> methods and then
+ * call {@link #create} to produce a disk store instance.
+ * 
+ * @author Gester
+ * @since 6.5
+ */
+public interface DiskStoreFactory
+{
+  /**
+   * The name of the default disk store is "DEFAULT".
+   * This name can be used to redefine the default disk store.
+   * Regions that have not had their disk-store-name set will
+   * use this disk store.
+   */
+  public static final String DEFAULT_DISK_STORE_NAME = "DEFAULT";
+  /**
+   * The default setting for auto compaction. 
+   * <p>Current value: <code>true</code>.
+   */
+  public static final boolean DEFAULT_AUTO_COMPACT = true;
+  
+  /**
+   * The default compaction threshold.
+   * <p>Current value: <code>50</code>.
+   */
+  public static final int DEFAULT_COMPACTION_THRESHOLD = 50;
+
+  /**
+   * The default value of the allow force compaction attribute.
+   * <p>Current value: <code>false</code>.
+   */
+  public static final boolean DEFAULT_ALLOW_FORCE_COMPACTION = false;
+
+  /**
+   * The default maximum oplog file size in megabytes.
+   * <p>Current value: <code>1024</code> which is one gigabyte.
+   */
+  public static final long DEFAULT_MAX_OPLOG_SIZE = Long.getLong("gemfire.DEFAULT_MAX_OPLOG_SIZE", 1024L).longValue(); // 1024 == 1 GB; // sys prop used by dunit and junit
+
+  /**
+   * The default time interval in milliseconds.
+   * <p>Current value: <code>1000</code>.
+   */
+  public static final long DEFAULT_TIME_INTERVAL = 1000; // 1 sec;
+  
+  /**
+   * The default write buffer size.
+   * <p>Current value: <code>32768</code>.
+   */
+  public static final int DEFAULT_WRITE_BUFFER_SIZE = 32 * 1024;
+
+  /**
+   * The default maximum number of operations that can be asynchronously queued.
+   * <p>Current value: <code>0</code>.
+   */
+  public static final int DEFAULT_QUEUE_SIZE = 0;
+  
+  /**
+   * The default disk directories.
+   * <p>Current value: <code>current directory</code>.
+   */
+  public static final File[] DEFAULT_DISK_DIRS = new File[] { new File(".") };
+  
+  /**
+   * The default disk directory size in megabytes.
+   * <p>Current value: <code>2,147,483,647</code> which is two petabytes.
+   */
+  public static final int DEFAULT_DISK_DIR_SIZE = Integer.MAX_VALUE; // unlimited for bug 41863
+  
+  /**
+   * The default disk directory sizes.
+   * <p>Current value: {@link #DEFAULT_DISK_DIR_SIZE} which is two petabytes each.
+   */
+  public static final int[] DEFAULT_DISK_DIR_SIZES = new int[] {DEFAULT_DISK_DIR_SIZE};
+
+  /**
+   * The default disk usage warning percentage.
+   * <p>Current value: <code>90</code>.
+   */
+  public static final float DEFAULT_DISK_USAGE_WARNING_PERCENTAGE = 90;
+  
+  /**
+   * The default disk usage critical percentage.
+   * <p>Current value: <code>99</code>.
+   */
+  public static final float DEFAULT_DISK_USAGE_CRITICAL_PERCENTAGE = 99;
+  
+  /** 
+   * Set to <code>true</code> to cause the disk files to be automatically compacted.
+   * Set to <code>false</code> if no compaction is needed or manual compaction will be used.
+   * @param isAutoCompact if true then use auto compaction
+   * @return a reference to <code>this</code>
+   */
+  public DiskStoreFactory setAutoCompact(boolean isAutoCompact);
+
+  /**
+   * Sets the threshold at which an oplog will become compactable. Until it reaches
+   * this threshold the oplog will not be compacted.
+   * The threshold is a percentage in the range 0..100.
+   * When the amount of garbage in an oplog exceeds this percentage then when a compaction
+   * is done this garbage will be cleaned up freeing up disk space. Garbage is created by
+   * entry destroys, entry updates, and region destroys.
+   * @param compactionThreshold the threshold percentage at which an oplog is compactable
+   * @return a reference to <code>this</code>
+   */
+  public DiskStoreFactory setCompactionThreshold(int compactionThreshold);
+
+  /** 
+   * Set to <code>true</code> to allow {@link DiskStore#forceCompaction} to be called
+   * on regions using this disk store.
+   *
+   * @param allowForceCompaction if true then allow force compaction.
+   * @return a reference to <code>this</code>
+   */
+  public DiskStoreFactory setAllowForceCompaction(boolean allowForceCompaction);
+
+  /** 
+   * Sets the maximum size in megabytes a single oplog (operation log) is allowed to be.
+   * When an oplog is created this amount of file space will be immediately reserved.
+   * 
+   * @param maxOplogSize maximum size in megabytes for one single oplog file.
+   * @return a reference to <code>this</code>
+   */
+  public DiskStoreFactory setMaxOplogSize(long maxOplogSize);
+
+  /**
+   * Sets the number of milliseconds that can elapse before
+   * data written asynchronously is flushed to disk.
+   * <p>For how to configure a region to be asynchronous see: {@link AttributesFactory#setDiskSynchronous}.
+   * 
+   * @param timeInterval number of milliseconds that can elapse before
+   * async data is flushed to disk.
+   * @return a reference to <code>this</code>
+   */
+  public DiskStoreFactory setTimeInterval(long timeInterval);
+
+  /**
+   * Sets the write buffer size in bytes.
+   * 
+   * @param writeBufferSize write buffer size in bytes.
+   * @return a reference to <code>this</code>
+   */
+  public DiskStoreFactory setWriteBufferSize(int writeBufferSize);
+
+  /**
+   * Sets the maximum number of operations that can be asynchronously queued.
+   * Once this many pending async operations have been queued async ops will
+   * begin blocking until some of the queued ops have been flushed to disk.
+   * <p>
+   * For how to configure a region to be asynchronous see:
+   * {@link AttributesFactory#setDiskSynchronous}.
+   * 
+   * @param queueSize
+   *          number of operations that can be asynchronously queued. If 0, the
+   *          queue will be unlimited.
+   * @return a reference to <code>this</code>
+   */
+  public DiskStoreFactory setQueueSize(int queueSize);
+
+  /**
+   * Sets the directories to which this disk store's data is written. If multiple
+   * directories are used, GemFire will attempt to distribute the data evenly
+   * amongst them.
+   * The size of each directory will be set to the default of {@link #DEFAULT_DISK_DIR_SIZE}.
+   * 
+   * @param diskDirs directories to put the oplog files.
+   * @return a reference to <code>this</code>
+   * 
+   * @throws GemfireIOException if a directory cannot be created
+   */
+  public DiskStoreFactory setDiskDirs(File[] diskDirs);
+
+  /**
+   * Sets the directories to which this disk store's data is written
+   * and also set the sizes in megabytes of each directory.
+   * 
+   * @param diskDirs directories to put the oplog files.
+   * @param diskDirSizes sizes of disk directories in megabytes
+   * @return a reference to <code>this</code>
+   * 
+   * @throws IllegalArgumentException if length of the size array
+   * does not match to the length of the dir array
+   * @throws GemfireIOException if a directory cannot be created
+   */
+  public DiskStoreFactory setDiskDirsAndSizes(File[] diskDirs,int[] diskDirSizes);
+
+  /**
+   * Sets the warning threshold for disk usage as a percentage of the total disk
+   * volume.
+   * 
+   * @param warningPercent warning percent of disk usage
+   * @return a reference to <code>this</code>
+   * @since 8.0
+   */
+  public DiskStoreFactory setDiskUsageWarningPercentage(float warningPercent);
+
+  /**
+   * Sets the critical threshold for disk usage as a percentage of the total disk
+   * volume.
+   * 
+   * @param criticalPercent critical percent of disk usage
+   * @return a reference to <code>this</code>
+   * @since 8.0
+   */
+  public DiskStoreFactory setDiskUsageCriticalPercentage(float criticalPercent);
+
+  /**
+   * Create a new disk store or find an existing one. In either case the returned disk store's
+   * configuration will be the same as this factory's configuration.
+   * 
+   * @param name the name of the DiskStore
+   * @return the newly created DiskStore.
+   * @throws IllegalStateException if a disk store with the given name already exists
+   * and its configuration is not consistent with this factory.
+   */
+  public DiskStore create(String name);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskWriteAttributes.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskWriteAttributes.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskWriteAttributes.java
new file mode 100644
index 0000000..a7067b9
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/DiskWriteAttributes.java
@@ -0,0 +1,99 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * Immutable parameter object for describing how {@linkplain
+ * Region.Entry region entries} should be written to disk.
+ *
+ * @see DiskWriteAttributesFactory
+ * @see AttributesFactory#setDiskWriteAttributes
+ * @see RegionAttributes#getDiskWriteAttributes
+ * @see Region#writeToDisk
+ *
+ * @author David Whitlock
+ * @author Mitul Bid
+ *
+ * @since 3.2
+ * @deprecated as of 6.5 use {@link DiskStore} instead
+ */
+@Deprecated
+public interface DiskWriteAttributes
+  extends java.io.Serializable {
+
+
+
+  //////////////////////  Instance Methods  //////////////////////
+
+ 
+
+  /**
+   * Returns true if this <code>DiskWriteAttributes</code> object
+   * configures synchronous writes.
+   * 
+   * @return Returns true if writes to disk are synchronous and false otherwise
+   * @deprecated as of 6.5 use {@link RegionAttributes#isDiskSynchronous} instead.
+   */
+  @Deprecated
+  public boolean isSynchronous();
+  
+  
+  /** 
+   * Returns true if the oplogs is to be rolled to a more condensed format (on disk)
+   * 
+   * @return Returns true if the oplogs is to be rolled or false otherwise
+   */
+  public boolean isRollOplogs();
+
+  /** 
+   * Get the maximum size in megabytes a single oplog (operation log) file should be 
+   * 
+   * @return the maximum size the operations log file can be
+   * @deprecated as of 6.5 use {@link DiskStore#getMaxOplogSize()} 
+   * instead.
+   */
+  @Deprecated
+  public int getMaxOplogSize();
+
+  /**
+   * Returns the number of milliseconds that can elapse before
+   * unwritten data is written to disk.  If this
+   * <code>DiskWriteAttributes</code> configures synchronous writing,
+   * then <code>timeInterval</code> has no meaning.
+   * 
+   * @return Returns the time interval in milliseconds that can elapse between two writes to disk
+   * @deprecated as of 6.5 use {@link DiskStore#getTimeInterval()} 
+   * instead.
+   */
+  @Deprecated
+  public long getTimeInterval();
+
+  /**
+   * Returns the number of unwritten bytes of data that can be
+   * enqueued before being written to disk.  If this
+   * <code>DiskWriteAttributes</code> configures synchronous writing,
+   * then <code>bytesThreshold</code> has no meaning.
+   * 
+   * @return Returns the number of bytes that can be buffered before being written to disk
+   * @deprecated as of 6.5 use {@link DiskStore#getQueueSize()} 
+   * instead.
+   */
+  @Deprecated
+  public long getBytesThreshold();
+
+  /**
+   * Two <code>DiskWriteAttributes</code> are equal if the both
+   * specify the synchronous writes, or they both specify asynchronous
+   * writes with the same time interval, bytes threshold, maxOplogSize and
+   * compaction values
+   * 
+   * @return true if o is equal else false
+   */
+  public boolean equals(Object o);
+
+}


[28/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/package.html
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/package.html b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/package.html
new file mode 100755
index 0000000..266cfa6
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/package.html
@@ -0,0 +1,150 @@
+<HTML>
+<BODY>
+
+<P>Contains the implementation of the external JMX APIs from {@link
+com.gemstone.gemfire.admin.jmx}.</P>
+
+<H2>JMX Support in GemFire</H2>
+
+Our goal was to provide JMX administrative support in GemFire.  The design was influenced by these important factors:
+<p>
+<ul>
+<li/>1) Requirement to not impact performance of the product
+<li/>2) Desire to introduce JMX without altering the existing product or the management console
+<li/>3) Similar functionality already existed in the console and the internal.admin pkg which the console uses
+<li/>4) Requirement to also introduce a simple and usable Admin API which or may not be related to JMX
+</ul>
+
+From a functional stand point, the JMX support was supposed to provide most of the same administrative and operational monitoring that the console already provides.  In some cases we limited the functionality due to security concerns and in others because it was hard to express the features as JMX beans.  The JMX Agent also provides some functionality (such as Health monitoring) that is not currently in the console.
+<p>
+The Agent communicates with the distributed system using the same distribution manager {@link com.gemstone.gemfire.distributed.internal.DistributionManager} as the console uses and thus has the same requirements that determine what distributed system it can manage.  Although the Console currently supports managing multiple distributed systems, we decided that a given Agent should only be able to manage a single system.  We have not tested the use of more than one Agent for the same system, however nothing currently prohibits this. 
+<p>
+We decided to develop a simple public Admin API which in essence wraps the internal.admin API that the Console currently uses extensively.  The Admin API also contains implementations of new functionality not in internal.admin.  Our JMX support is an extension to this Admin API.  In an overly simplified view, the GemFire JMX MBeans are ModelMBeans that manage instances of the Admin API objects housed in the Agent's MBeanServer.
+<p>
+The selected architecture consists of a Daemon Agent, which exists in a separate VM that GemFire does not depend on.  This Agent hosts an MBeanServer, instances of any and all MBeans registered for managing a GemFire distributed system, and server connectors/adaptors that various types of clients can connect to.
+<p>
+The two server connectors we selected are the HttpAdaptor and the RMI Connector.  The HttpAdaptor provides an HTML user interface of all MBeans in the MBeanServer.  Although this generic UI is not as rich as an RMI client (or the GemFire Console) could be, it provides a functional and easy to use UI with no development required.  The JMX Remote specification details the standard connectors.  Although the HttpAdaptor is not required by this Sun spec. it is included in some form with all JMX implementations that I investigated.  It should be noted that our JMX Agent currently starts up the HttpAdaptor, but not the RMI Connector.  The latter is deferred as later work since some form of client must be developed for testing.  Further research may also uncover a generic, configurable open-source RMI client for JMX.  The GemFire Console could in theory be reworked as an RMI Connector client, but this is not currently planned.
+<p>
+Two open-source JMX implementations made it to our final review for consideration: <a href="http://www.xmojo.org">XMOJO</a> and <a href="http://www.mx4j.org">MX4J</a>.  The decision to go with MX4J was based mainly on our perceptions of MX4J being more active and widespread in use.  Additionally, XMOJO is associated with <a href="http://www.adventnet.com/">AdventNet</a> which produces commercial products.  This made MX4J seem more true to open-source and safer from corporate tampering.
+<p>
+ModelMBeans are very dynamic and capable of managing aggregate resources.  Use of a ModelMBean entails specifying meta-data to an instance of javax.management.modelmbean.RequiredModelMBean.  This meta-data identifies the manageble resource(s) which can consist of a single object, or many objects, including those in one VM or in any number of distributed VMs.  We decided to subclass classes in the Admin API in order to massage them a little and make them easier to use as a managed resource by the ModelMBean.  For example, com.gemstone.gemfire.admin.GemFireManager represents a type of member in a GemFire system which manages shared memory.  When an MBean is registered for managing the GemFireManager, the JMX Agent instantiates a "JMX friendlier" subclass: com.gemstone.gemfire.admin.jmx.internal.GemFireMangerJmxImpl.  Comparison of this class with the non-JMX super class com.gemstone.gemfire.admin.internal.GemFireManagerImpl will illustrate what "JMX friendly" means better than trying 
 to explain it here...
+<p>
+One standard approach to defining a ModelMBean is to programmatically
+build the necessary meta-data.  The folks on the Tomcat approach
+developed a better solution... an XML definition file which Jakarta
+Commons-Modeler parses to create the meta-data objects required to
+definie the ModelMBean.  We currently have our XML descriptor file at
+com.gemstone.gemfire.admin.jmx.mbeans-descriptors.xml.
+Commons-Modeler can be found at <A href="http://jakarta.apache.org/commons/modeler">http://jakarta.apache.org/commons/modeler/</A>
+<p>
+Here's a quick run-down of the Admin and JMX pkgs in GemFire...
+<p>
+<b>com.gemstone.gemfire.admin</b>
+<ul>
+<li/>interfaces describing GemFire entities and resources for managing or monitoring
+</ul>
+<p>
+<b>com.gemstone.gemfire.admin.internal</b>
+<ul>
+<li/>implementations of the admin pkg which could be used to managing GemFire
+<li/>recommendation is to create one set on non-JMX unit tests for these and then wrap that unit test within another test that is specific to its use in JMX
+</ul>
+<p>
+<b>com.gemstone.gemfire.admin.jmx</b>
+<ul>
+<li/>Commons-Modeler descriptor file mbeans-descriptors.xml
+<li/>AgentMBean - non-required interface that simply represents a public documentation of what the Agent does
+<li/>VersionMBean and Version - unused (but functional) examples of a standard MBean (other MBeans as defined in mbeans-descriptors.xml also provide version info)
+</ul>
+<p>
+<b>com.gemstone.gemfire.admin.jmx.internal</b>
+<ul>
+<li/>subclasses of com.gemstone.gemfire.admin.internal classes that use JMX services, implement ManagedResource, register ModelMBeans to manage themselves, and other JMX related details
+<li/>ManagedResource - simple interface we use to create a more uniform approach in using JMX
+<li/>Agent - application with main, registers HttpAdaptor, acts as a factory to DistributedSystemJmxImpl (which is the entry point to using JMX with a GemFire system)
+<li/>AgentConfig - configuration for Agent that reads/writes to a properties file
+<li/>MBeanUtil - utility class with static methods for defining MBeans, registering for timer-based refresh notifications, and lots of other JMX stuff
+<li/>StatisticAttributeInfo and ConfigAttributeInfo - these are the results of refactoring common code from some of the JmxImpl classes that required runtime dynamic (ie, not known at design time) MBean attributes
+<li/>SpecManagedBean - subclass of part of Commons-Modeler, this class acts as a workaround for a bug in Commons-Modeler (I hope to remove this after working with Jakarta-Commons to correct the bug)
+<li/>AgentPrintStream - this is a hack workaround for suppressing warnings from Xalan that derive from a purported incompatibility between the XSLT sheets in MX4J and the version of Xalan in JDK1.4.2 - experts with Xalan recommend upgrading to the very latest version of Xalan which is not currently desired for GemFire
+</ul>
+<p>
+<h3>Some caveats, workarounds, and GemFire bugs to be aware of:</h3>
+<p>
+1) MX4J uses XSLT style sheets that are intended to work with the latest version of Xalan.  JDK1.4.2 bundles an older version of Xalan which generates warnings.
+<p>
+2) MX4J's implementation of javax.management.modelmbean.RequiredModelMBean contains a bug such that any return type defined as an array of some object results in it attempting to Class.forName the class name with the "[]" still in the name of the class.  Our current workaround is to return java.lang.Object where we'd like to return an array of some non-primitive type.  I hope to look at this closer and work with MX4J to correct it (unless that latest code base at MX4J already has a fix).
+<p>
+3) Our MBeans currently have some return types of Admin interfaces and GemFire MBean types.  This is not recommended.  The correct approach is to return javax.management.ObjectName or an array of ObjectName so that remotability is not broken.  We have a bug filed to correct this in GemFire.
+<p>
+4) Commons-Modeler provides a simple, incomplete implementation of ModelMBean called org.apache.commons.modeler.BaseModelMBean. We decided to use the standard RequiredModelMBean which all JMX implementations are required to supply.  The JMX spec details several "managed resource types" that a ModelMBean can support.  ObjectReference is the type that both MX4J's RequiredModelMBean and Modeler's BaseModelMBean support.  However, MX4J is more strict in it's interpretation of the spec which spells it out as "ObjectReference".  Modeler's BaseModelMBean performs no enforcement and simply assumes it is managing type ObjectReference.  Modeler has a bug in org.apache.commons.modeler.ManagedBean because it specifies "objectReference" which is the incorrect case in comparison to the specification.  I intend to work with the Jakarta-Commons folks to change this to comply with the spec.  The Modeler will use BaseModelMBean by default even though it is actually depending on a JMX implementation s
 uch as MX4J or XMOJO.  com.gemstone.gemfire.admin.jmx.internal.MBeanUtil tells Modeler to use RequiredModelMBean instead and also uses com.gemstone.gemfire.admin.jmx.internal.SpecManagedBean as a workaround to the whole "objectReference" issue.  You could feasibly use org.apache.commons.modeler.BaseModelMBean or RequiredModelMBean.
+<p>
+
+<h3>Capabilities currently supported in GemFire via JMX:</h3>
+<ul>
+<li/>1) View overall system and its settings and start/stop all members
+<li/>2) View all managers and applications
+<li/>3) View and modify config (includes optional use of JMX Timer service to auto-refresh)
+<li/>4) View any statistics (includes optional use of JMX Timer service to auto-refresh)
+<li/>5) View member's cache and its statistics
+<li/>6) View a cache's region and its attributes, statistics, but not the data
+<li/>7) Health monitoring (ask David W. for more info... I haven't had a chance to look at this yet)
+<li/>8) Create, start, and stop managers
+</ul>
+<p>
+<h3>TODO:</h3>
+<ul>
+<li/>1) Creation and control of Locators
+<li/>2) Enable the RMI Connector and build tests
+<li/>3) Bind Address support (bug 30898)
+<li/>4) SSL Configuration support
+<li/>5) JMX Connector security
+<li/>6) more thorough automated tests!!
+<li/>7) Documentation of use w/ built-in Connectors (RMI and HTTP)
+<li/>8) Documentation of use w/ AdventNet SNMP Adaptor
+<li/>9) Documentation of use w/ selected commercial management products
+<li/>10) Determine high-availability requirements if any (mentioned by Jags)
+</ul>
+See also <a href="#deferred_ops">deferred backlog from Hardening/Operations sprint</a>
+<p>
+It's very easy to use the JMX Monitor service to monitor an MBean's attribute and fire JMX Notifications.  Statistics and Config Parameters are "MBean attributes".
+
+<p>
+<h3>Using Third Party Management Consoles/Tools</h3>
+There is information on <a href="http://www.adventnet.com/">AdventNet's website</a> detailing the use of their <a href="http://www.adventnet.com/products/snmpadaptor/index.html">SNMP Adaptor</a> to enable connectivity to <a href="http://www.openview.hp.com/">HP OpenView</a>, <a href="http://www.ibm.com/software/tivoli/">IBM Tivoli</a>, <a href="http://www3.ca.com/solutions/solution.asp?id=315">CA Unicenter</a>, and other SNMP managers.
+<p>
+Aside from using AdventNet's SNMP Adaptor, HPOpenView is the first I've seen of the big players offering what appears to be a way to plug our JMX support into their product for management of GemFire.  I haven't had a chance to look at it yet.  Most likely their <a href="http://www.openview.hp.com/products/spi/">SPI</a> supports writing a small amount of glue code to have their console become an RMI client to our JMX VM (which is essentially an MBeanServer "server" that hosts our MBeans).  I think it's unlikely that such vendors would want to support hosting of third party MBeans and the classpath/versioning headaches involved in that.  The JMX Remote specification really is meant to cover how such console's would perform the remote connections to custom MBeans in external VMs/products.  It is likely that the other management tool vendors such as Tivoli have a similar SPI available or in the works.
+<p>
+See HP Dev Resource Central's page on <a href="http://devresource.hp.com/jmx.htm">JMX</a> for info and links on using JMX to integrate with HP OpenView.  You can also sign up for <a href="http://www.hpdev.com/.docs/pg/5">HP Developer News</a>
+<p>
+<h3><a name="deferred_ops">Deferred Backlog from Hardening/Operations Sprint</a></h3>
+Note: some of these tasks may no longer be worded properly or even needed...
+<ul>
+<li/>Provide a consolidated view of all cache Regions via JMX
+<li/>Send an alert upon system failure, communication failure, etc.
+<li/>Monitor cache system failures, comm failures, loader failures, etc via JMX
+<li/>Detect/handle stuck shared memory locks via JMX
+<li/>Provide a "combination view" (distributed system-wide) of certain statistics via JMX
+<li/>Integrate with Tivoli and produce a document
+<li/>Test managing caches via JMX with a large number of Regions, Entries, etc.
+<li/>Create XDoclet module to auto-generate mbeans-descriptors.xml (Note: we're using JavaDoc 1.4.2 which is incompatible with XDoclet; Sun intends to restore compatibility in the next version of JavaDoc)
+<li/>Investigate AdventNet's JMX administration console
+<li/>View percentage of VM memory used by a Cache via JMX
+<li/>Investigate modifying the GemFire Console to use JMX
+<li/>Investigate providing secure management via JMX
+<li/>Document security usage for JMX management
+<li/>Investigate managing GemFire via BMC Patrol
+<li/>Investigate managing GemFire via HP OpenView
+<li/>Investigate managing GemFire via UniCenter
+<li/>Submit fix to Jakrta Commons-Modeler for ObjectReference fix in ManagedBean
+<li/>Submit fix to MX4J for classload error in RequiredModelMBean
+<li/>Enable the RMI Connector (currently commented out in Agent)
+<li/>Create tests for RMI Connector
+<li/>Document and JavaDoc usage of the RMI Connector
+<li/>Add support to MBeanUtil to determine which MBeanServer the Agent is in
+<li/>Correlate information from GemFire MBeans with MBeans from other products
+<li/>Test deploying GemFire MBeans into other products' MBean containers
+</ul>
+
+</BODY>
+</HTML>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/package.html
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/package.html b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/package.html
new file mode 100755
index 0000000..c637d23
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/package.html
@@ -0,0 +1,12 @@
+<HTML>
+<BODY>
+
+<P>Provides administrative access to a GemFire distributed system via
+the Java Management Extensions (JMX).</P>
+
+<P>Click <A href="doc-files/mbeans-descriptions.html">here</A> for a
+description of the attributes, operations, and notifications of the
+GemFire JMX MBeans.</P>
+
+</BODY>
+</HTML>

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/package.html
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/package.html b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/package.html
new file mode 100644
index 0000000..172e1b6
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/package.html
@@ -0,0 +1,62 @@
+<HTML>
+<BODY>
+
+<P>Provides an API for administering various GemFire components such
+as a GemFire distributed
+system, and processes that host GemFire Caches.</P>
+
+<H3>Administration of a GemFire Distributed System</H3>
+
+The Admin API provides interfaces for administrative control, 
+monitoring, and custom management of a GemFire system.
+<P>
+The {@link com.gemstone.gemfire.admin.AdminDistributedSystemFactory}
+is the starting point.  It creates an instance of
+<code>AdminDistributedSystem</code> that administers the distributed
+system to which a VM is {@linkplain
+com.gemstone.gemfire.distributed.DistributedSystem connected}.
+<P>
+<pre><code>
+DistributedSystem connection = DistributedSystem.connect(new Properties());
+AdminDistributedSystem system = 
+    AdminDistributedSystemFactory.getDistributedSystem(connection);
+system.connect(new File("admin.log"), "info");
+</code></pre>
+<P>
+This {@link com.gemstone.gemfire.admin.AdminDistributedSystem}
+interface exposes methods for such tasks as connecting to the system,
+merging system logs, getting administrative interfaces to 
+applications that host GemFire Caches.
+
+<H3>Monitoring the Health of GemFire</H3>
+
+<P>The {@link com.gemstone.gemfire.admin.GemFireHealth} interface
+allows the overall health of GemFire to be monitored.
+<code>GemFireHealth</code> monitors the behavior the members of a
+distributed system namely 
+application VMs that may host {@link com.gemstone.gemfire.cache.Cache
+cache} instances.  There are three levels of health: {@linkplain
+com.gemstone.gemfire.admin.GemFireHealth#GOOD_HEALTH good health} that
+indicates that all GemFire components are behaving reasonably,
+{@linkplain com.gemstone.gemfire.admin.GemFireHealth#OKAY_HEALTH okay
+health} that indicates that one or more GemFire components is slightly
+unhealthy and may need some attention, and {@linkplain
+com.gemstone.gemfire.admin.GemFireHealth#POOR_HEALTH poor health} that
+indicates that a GemFire component is unhealthy and needs immediate
+attention.</P>
+
+<P>Because each GemFire application has its own definition of what it
+means to be "healthy", the metrics that are used to determine health
+are configurable.  {@link
+com.gemstone.gemfire.admin.GemFireHealthConfig} provides methods for
+configuring how the health of {@linkplain
+com.gemstone.gemfire.admin.DistributedSystemHealthConfig the
+distributed system},
+{@linkplain com.gemstone.gemfire.admin.CacheHealthConfig members that
+host Cache instances}, and {@linkplain
+com.gemstone.gemfire.admin.MemberHealthConfig individual members} of
+the distributed system.  <code>GemFireHealthConfig</code> also allows
+you to configure how often GemFire's health is evaluated.</P>
+
+</BODY>
+</HTML>


[18/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/AsyncEventQueueFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/AsyncEventQueueFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/AsyncEventQueueFactory.java
new file mode 100644
index 0000000..3316ac7
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/AsyncEventQueueFactory.java
@@ -0,0 +1,182 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.asyncqueue;
+
+import java.util.List;
+
+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.cache.wan.GatewaySenderFactory;
+
+/**
+ * Factory to create the <code>AsyncEventQueue</code>. 
+ * Below example illustrates how to get the instance of factory and create the 
+ * <code>AsyncEventQueue</code>.
+<PRE>
+  Cache c = new CacheFactory().create();
+  // get AsyncEventQueueFactory from cache
+  AsyncEventQueueFactory factory = cache.createAsyncEventQueueFactory();
+  
+  // set the attributes on factory
+  factory.setBatchSize(batchSize);
+  factory.setBatchConflationEnabled(isConflation);
+  factory.setMaximumQueueMemory(maxMemory);
+  factory.setParallel(isParallel);
+             .
+             .
+  // create instance of AsyncEventListener           
+  AsyncEventListener asyncEventListener = new <AsyncEventListener class>;
+  // create AsyncEventQueue by providing the id and instance of AsyncEventListener
+  AsyncEventQueue asyncQueue = factory.create(asyncQueueId, asyncEventListener);
+</PRE>
+ * 
+ * @author pdeole
+ * @since 7.0
+ */
+public interface AsyncEventQueueFactory {
+
+  /**
+   * Sets the disk store name for overflow or persistence.
+   * 
+   * @param name
+   */
+  public AsyncEventQueueFactory setDiskStoreName(String name);
+
+  /**
+   * Sets the maximum amount of memory (in MB) for an
+   * <code>AsyncEventQueue</code>'s queue.
+   * Default is 100 MB.
+   * 
+   * @param memory
+   *          The maximum amount of memory (in MB) for an
+   *          <code>AsyncEventQueue</code>'s queue
+   */
+  public AsyncEventQueueFactory setMaximumQueueMemory(int memory);
+  
+  /**
+   * Sets whether or not the writing to the disk is synchronous.
+   * Default is true.
+   * 
+   * @param isSynchronous
+   *          boolean if true indicates synchronous writes
+   *  
+   */
+  public AsyncEventQueueFactory setDiskSynchronous(boolean isSynchronous);
+
+  /**
+   * Sets the batch size for an <code>AsyncEventQueue</code>'s queue.
+   * Default is 100.
+   * 
+   * @param size
+   *          The size of batches sent to its <code>AsyncEventListener</code>
+   */
+  public AsyncEventQueueFactory setBatchSize(int size);
+  
+  /**
+   * Sets the batch time interval (in milliseconds) for a <code>AsyncEventQueue</code>.
+   * Default is 5 ms.
+   * 
+   * @param interval
+   *          The maximum time interval that can elapse before a partial batch
+   *          is sent from a <code>AsyncEventQueue</code>.
+   */
+  public AsyncEventQueueFactory setBatchTimeInterval(int interval);
+
+  /**
+   * Sets whether the <code>AsyncEventQueue</code> is persistent or not.
+   * Default is false.
+   * 
+   * @param isPersistent
+   *          Whether to enable persistence for an <code>AsyncEventQueue</code>.
+   */
+  public AsyncEventQueueFactory setPersistent(boolean isPersistent);
+
+  /**
+   * Indicates whether all VMs need to distribute events to remote site. In this
+   * case only the events originating in a particular VM will be in dispatched
+   * in order.
+   * Default is false.
+   * 
+   * @param isParallel
+   *          boolean to indicate whether distribution policy is parallel
+   */
+
+  public AsyncEventQueueFactory setParallel(boolean isParallel);
+  
+  /**
+   * Sets whether to enable batch conflation for <code>AsyncEventQueue</code>.
+   * Default is false.
+   * 
+   * @param     isConflation        
+   *              Whether or not to enable batch conflation for batches sent from a 
+   *              <code>AsyncEventQueue</code>
+   */
+  public AsyncEventQueueFactory setBatchConflationEnabled(boolean isConflation);
+  
+  /**
+   * Sets the number of dispatcher thread.
+   * Default is 5.
+   * 
+   * @param numThreads
+   */
+  public AsyncEventQueueFactory setDispatcherThreads(int numThreads);
+
+  /**
+   * Removes a <code>GatewayEventFilter</code> to the attributes of
+   * AsyncEventQueue being created by factory.
+   * 
+   * @param filter
+   *          GatewayEventFilter
+   */
+  public AsyncEventQueueFactory addGatewayEventFilter(GatewayEventFilter filter);
+
+  /**
+   * Removes the provided <code>GatewayEventFilter</code> from the attributes of
+   * AsyncEventQueue being created by factory.
+   * 
+   * @param filter
+   */
+  public AsyncEventQueueFactory removeGatewayEventFilter(
+      GatewayEventFilter filter);
+  
+  /**
+   * Sets the order policy for multiple dispatchers.
+   * Default is KEY.
+   * 
+   * @param policy
+   */
+  public AsyncEventQueueFactory setOrderPolicy(OrderPolicy policy);
+  
+  /**
+   * Sets the <code>GatewayEventSubstitutionFilter</code>.
+   * 
+   * @param filter
+   *          The <code>GatewayEventSubstitutionFilter</code>
+   */
+  public AsyncEventQueueFactory setGatewayEventSubstitutionListener(
+      GatewayEventSubstitutionFilter filter);
+
+
+  /**
+   * Creates the <code>AsyncEventQueue</code>. It accepts Id of AsyncEventQueue
+   * and instance of AsyncEventListener. Multiple queues can be created using
+   * Same listener instance. So, the instance of <code>AsyncEventListener</code>
+   * should be thread safe in that case. The <code>AsyncEventListener</code>
+   * will start receiving events when the <code>AsyncEventQueue</code> is
+   * created.
+   * 
+   * 
+   * @param id
+   *          Id of AsyncEventQueue
+   * @param listener
+   *          <code>AsyncEventListener</code> to be added to the regions that
+   *          are configured to use this queue.
+   */
+  public AsyncEventQueue create(String id, AsyncEventListener listener);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/AsyncEventQueueFactoryImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/AsyncEventQueueFactoryImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/AsyncEventQueueFactoryImpl.java
new file mode 100644
index 0000000..203c444
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/AsyncEventQueueFactoryImpl.java
@@ -0,0 +1,279 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.asyncqueue.internal;
+
+import com.gemstone.gemfire.internal.cache.wan.AsyncEventQueueConfigurationException;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.asyncqueue.AsyncEventListener;
+import com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueue;
+import com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueueFactory;
+import com.gemstone.gemfire.cache.wan.GatewayEventFilter;
+import com.gemstone.gemfire.cache.wan.GatewayEventSubstitutionFilter;
+import com.gemstone.gemfire.cache.wan.GatewaySender;
+import com.gemstone.gemfire.cache.wan.GatewaySender.OrderPolicy;
+import com.gemstone.gemfire.cache.wan.GatewaySenderFactory;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.wan.GatewaySenderAttributes;
+import com.gemstone.gemfire.internal.cache.xmlcache.AsyncEventQueueCreation;
+import com.gemstone.gemfire.internal.cache.xmlcache.CacheCreation;
+import com.gemstone.gemfire.internal.cache.xmlcache.ParallelAsyncEventQueueCreation;
+import com.gemstone.gemfire.internal.cache.xmlcache.ParallelGatewaySenderCreation;
+import com.gemstone.gemfire.internal.cache.xmlcache.SerialAsyncEventQueueCreation;
+import com.gemstone.gemfire.internal.cache.xmlcache.SerialGatewaySenderCreation;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+public class AsyncEventQueueFactoryImpl implements AsyncEventQueueFactory {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  /**
+   * Used internally to pass the attributes from this factory to the real
+   * GatewaySender it is creating.
+   */
+  private GatewaySenderAttributes attrs = new GatewaySenderAttributes();
+
+  private Cache cache;
+  
+  /**
+   * The default batchTimeInterval for AsyncEventQueue in milliseconds.
+   */
+  public static final int DEFAULT_BATCH_TIME_INTERVAL = 5;
+  
+  
+  public AsyncEventQueueFactoryImpl(Cache cache) {
+    this.cache = cache;
+    this.attrs = new GatewaySenderAttributes();
+    // set a different default for batchTimeInterval for AsyncEventQueue
+    this.attrs.batchTimeInterval = DEFAULT_BATCH_TIME_INTERVAL;
+  }
+  
+  @Override
+  public AsyncEventQueueFactory setBatchSize(int size) {
+    this.attrs.batchSize = size;
+    return this;
+  }
+  public AsyncEventQueueFactory setPersistent(boolean isPersistent) {
+    this.attrs.isPersistenceEnabled = isPersistent;
+    return this;
+  }
+  
+  @Override
+  public AsyncEventQueueFactory setDiskStoreName(String name) {
+    this.attrs.diskStoreName = name;
+    return this;
+  }
+
+  @Override
+  public AsyncEventQueueFactory setMaximumQueueMemory(int memory) {
+    this.attrs.maximumQueueMemory = memory;
+    return this;
+  }
+  
+  @Override
+  public AsyncEventQueueFactory setDiskSynchronous(boolean isSynchronous) {
+    this.attrs.isDiskSynchronous = isSynchronous;
+    return this;
+  }
+  
+  @Override
+  public AsyncEventQueueFactory setBatchTimeInterval(int batchTimeInterval) {
+    this.attrs.batchTimeInterval = batchTimeInterval;
+    return this;
+  }
+  
+  @Override
+  public AsyncEventQueueFactory setBatchConflationEnabled(boolean isConflation) {
+    this.attrs.isBatchConflationEnabled = isConflation;
+    return this;
+  }
+  
+  @Override
+  public AsyncEventQueueFactory setDispatcherThreads(int numThreads) {
+    this.attrs.dispatcherThreads = numThreads;
+    return this;
+  }
+  
+  @Override
+  public AsyncEventQueueFactory setOrderPolicy(OrderPolicy policy) {
+    this.attrs.policy = policy;
+    return this;
+  }
+  
+  @Override
+  public AsyncEventQueueFactory addGatewayEventFilter(GatewayEventFilter filter) {
+    this.attrs.addGatewayEventFilter(filter);
+    return this;
+  }
+
+  @Override
+  public AsyncEventQueueFactory removeGatewayEventFilter(
+      GatewayEventFilter filter) {
+    this.attrs.eventFilters.remove(filter);
+    return this;
+  }
+  @Override
+  public AsyncEventQueueFactory setGatewayEventSubstitutionListener(
+      GatewayEventSubstitutionFilter filter) {
+    this.attrs.eventSubstitutionFilter = filter;
+    return this;
+  }
+  
+  public AsyncEventQueueFactory removeGatewayEventAlternateValueProvider(
+      GatewayEventSubstitutionFilter provider) {
+    return this;
+  }
+  
+  public AsyncEventQueueFactory addAsyncEventListener(
+      AsyncEventListener listener) {
+    this.attrs.addAsyncEventListener(listener);
+    return this;
+  }
+
+  public AsyncEventQueue create(String asyncQueueId, AsyncEventListener listener) {
+    if (listener == null) {
+      throw new IllegalArgumentException(
+          LocalizedStrings.AsyncEventQueue_ASYNC_EVENT_LISTENER_CANNOT_BE_NULL.toLocalizedString());
+    }
+    
+    AsyncEventQueue asyncEventQueue = null;
+    if (this.cache instanceof GemFireCacheImpl) {
+      if (logger.isDebugEnabled()) {
+        logger.debug("Creating GatewaySender that underlies the AsyncEventQueue");
+      }
+      
+      //TODO: Suranjan .separate asynceventqueue from gatewaysender
+      //GatewaySenderFactory senderFactory = this.cache.createGatewaySenderFactory();
+      //senderFactory.setMaximumQueueMemory(attrs.getMaximumQueueMemory());
+      //senderFactory.setBatchSize(attrs.getBatchSize());
+      //senderFactory.setBatchTimeInterval(attrs.getBatchTimeInterval());
+      //if (attrs.isPersistenceEnabled()) {
+        //senderFactory.setPersistenceEnabled(true);
+      //}
+      //senderFactory.setDiskStoreName(attrs.getDiskStoreName());
+      //senderFactory.setDiskSynchronous(attrs.isDiskSynchronous());
+      //senderFactory.setBatchConflationEnabled(attrs.isBatchConflationEnabled());
+      //senderFactory.setParallel(attrs.isParallel());
+      //senderFactory.setDispatcherThreads(attrs.getDispatcherThreads());
+      //if OrderPolicy is not null, set it, otherwise, let the default OrderPolicy take the charge
+      //if (attrs.getOrderPolicy() != null) {
+    	//senderFactory.setOrderPolicy(attrs.getOrderPolicy());
+      //}
+      //for (GatewayEventFilter filter : attrs.eventFilters) {
+        //senderFactory.addGatewayEventFilter(filter);
+      //}
+      //senderFactory.setGatewayEventSubstitutionFilter(attrs.getGatewayEventSubstitutionFilter());
+      //Type cast to GatewaySenderFactory implementation impl to add the async event listener 
+      //and set the isForInternalUse to true. These methods are not exposed on GatewaySenderFactory
+      //GatewaySenderFactory factoryImpl = (GatewaySenderFactoryImpl) senderFactory;
+      //senderFactory.setForInternalUse(true);
+      //senderFactory.addAsyncEventListener(listener);
+      //senderFactory.setBucketSorted(attrs.isBucketSorted());
+      // add member id to differentiate between this region and the redundant bucket 
+      // region created for this queue. 
+      //GatewaySender sender = 
+        //  senderFactory.create(
+          //  AsyncEventQueueImpl.getSenderIdFromAsyncEventQueueId(asyncQueueId));
+      addAsyncEventListener(listener);
+      GatewaySender sender = create(AsyncEventQueueImpl.getSenderIdFromAsyncEventQueueId(asyncQueueId));
+      asyncEventQueue = new AsyncEventQueueImpl(sender, listener);
+      ((GemFireCacheImpl) cache).addAsyncEventQueue(asyncEventQueue);
+    } else if (this.cache instanceof CacheCreation) {
+      asyncEventQueue = new AsyncEventQueueCreation(asyncQueueId, attrs, listener);
+      ((CacheCreation) cache).addAsyncEventQueue(asyncEventQueue);
+    }
+    if (logger.isDebugEnabled()) {
+      logger.debug("Returning AsyncEventQueue" + asyncEventQueue);
+    }
+    return asyncEventQueue;
+  }
+  
+  private GatewaySender create(String id) {
+    this.attrs.id = id;
+    GatewaySender sender = null;
+
+    if(this.attrs.getDispatcherThreads() <= 0) {
+      throw new AsyncEventQueueConfigurationException(
+          LocalizedStrings.AsyncEventQueue_0_CANNOT_HAVE_DISPATCHER_THREADS_LESS_THAN_1
+              .toLocalizedString(id));
+    }
+    
+    if (this.attrs.isParallel()) {
+      if ((this.attrs.getOrderPolicy() != null)
+          && this.attrs.getOrderPolicy().equals(OrderPolicy.THREAD)) {
+        throw new AsyncEventQueueConfigurationException(
+            LocalizedStrings.AsyncEventQueue_0_CANNOT_BE_CREATED_WITH_ORDER_POLICY_1
+                .toLocalizedString(id, this.attrs.getOrderPolicy()));
+      }
+      
+      if (this.cache instanceof GemFireCacheImpl) {
+        sender = new ParallelAsyncEventQueueImpl(this.cache, this.attrs);
+        ((GemFireCacheImpl)this.cache).addGatewaySender(sender);
+        if (!this.attrs.isManualStart()) {
+          sender.start();
+        }
+      }
+      else if (this.cache instanceof CacheCreation) {
+        sender = new ParallelAsyncEventQueueCreation(this.cache, this.attrs);
+        ((CacheCreation)this.cache).addGatewaySender(sender);
+      }
+    }
+    else {
+//      if (this.attrs.getOrderPolicy() != null) {
+//        if (this.attrs.getDispatcherThreads() == GatewaySender.DEFAULT_DISPATCHER_THREADS) {
+//          throw new AsyncEventQueueConfigurationException(
+//              LocalizedStrings.AsyncEventQueue_INVALID_ORDER_POLICY_CONCURRENCY_0
+//                  .toLocalizedString(id));
+//        }
+//      }
+      if (this.attrs.getOrderPolicy() == null && this.attrs.getDispatcherThreads() > 1) {
+         this.attrs.policy = GatewaySender.DEFAULT_ORDER_POLICY;
+      }
+      if (this.cache instanceof GemFireCacheImpl) {
+        sender = new SerialAsyncEventQueueImpl(this.cache, this.attrs);
+        ((GemFireCacheImpl)this.cache).addGatewaySender(sender);
+        if (!this.attrs.isManualStart()) {
+          sender.start();
+        }
+      }
+      else if (this.cache instanceof CacheCreation) {
+        sender = new SerialAsyncEventQueueCreation(this.cache, this.attrs);
+        ((CacheCreation)this.cache).addGatewaySender(sender);
+      }
+    }
+    return sender;
+  }
+  
+  public void configureAsyncEventQueue(AsyncEventQueue asyncQueueCreation) {
+    this.attrs.batchSize = asyncQueueCreation.getBatchSize();
+    this.attrs.batchTimeInterval = asyncQueueCreation.getBatchTimeInterval();
+    this.attrs.isBatchConflationEnabled = asyncQueueCreation.isBatchConflationEnabled();
+    this.attrs.isPersistenceEnabled = asyncQueueCreation.isPersistent();
+    this.attrs.diskStoreName = asyncQueueCreation.getDiskStoreName();
+    this.attrs.isDiskSynchronous = asyncQueueCreation.isDiskSynchronous();
+    this.attrs.maximumQueueMemory = asyncQueueCreation.getMaximumQueueMemory();
+    this.attrs.isParallel = asyncQueueCreation.isParallel();
+    this.attrs.isBucketSorted = ((AsyncEventQueueCreation)asyncQueueCreation).isBucketSorted();
+    this.attrs.dispatcherThreads = asyncQueueCreation.getDispatcherThreads();
+    this.attrs.policy = asyncQueueCreation.getOrderPolicy();
+    this.attrs.eventFilters = asyncQueueCreation.getGatewayEventFilters();
+    this.attrs.eventSubstitutionFilter = asyncQueueCreation.getGatewayEventSubstitutionFilter();
+  }
+
+  public AsyncEventQueueFactory setParallel(boolean isParallel) {
+    this.attrs.isParallel = isParallel;
+    return this;
+  }
+  public AsyncEventQueueFactory setBucketSorted(boolean isbucketSorted) {
+    this.attrs.isBucketSorted = isbucketSorted;
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/AsyncEventQueueImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/AsyncEventQueueImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/AsyncEventQueueImpl.java
new file mode 100644
index 0000000..5e621f1
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/AsyncEventQueueImpl.java
@@ -0,0 +1,188 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.asyncqueue.internal;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+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;
+import com.gemstone.gemfire.cache.wan.GatewaySender.OrderPolicy;
+import com.gemstone.gemfire.internal.cache.RegionQueue;
+import com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySender;
+import com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySenderEventProcessor;
+import com.gemstone.gemfire.internal.cache.wan.serial.ConcurrentSerialGatewaySenderEventProcessor;
+
+public class AsyncEventQueueImpl implements AsyncEventQueue {
+
+  private GatewaySender sender = null;
+  
+  private AsyncEventListener asyncEventListener = null;
+  
+  public static final String ASYNC_EVENT_QUEUE_PREFIX = "AsyncEventQueue_";
+  
+  public AsyncEventQueueImpl(GatewaySender sender, AsyncEventListener eventListener) {
+    this.sender = sender;
+    this.asyncEventListener = eventListener;
+  }
+ 
+  @Override
+  public String getId() {
+    return getAsyncEventQueueIdFromSenderId(this.sender.getId());
+  }
+  
+  @Override
+  public AsyncEventListener getAsyncEventListener() {
+    return asyncEventListener;
+  }
+  
+  @Override
+  public List<GatewayEventFilter> getGatewayEventFilters() {
+    return sender.getGatewayEventFilters();
+  }
+
+  @Override
+  public GatewayEventSubstitutionFilter getGatewayEventSubstitutionFilter() {
+    return sender.getGatewayEventSubstitutionFilter();
+  }
+
+  @Override
+  public int getBatchSize() {
+    return sender.getBatchSize();
+  }
+
+  @Override
+  public String getDiskStoreName() {
+    return sender.getDiskStoreName();
+  }
+  
+  @Override
+  public int getBatchTimeInterval() {
+    return sender.getBatchTimeInterval();
+  }
+  
+  @Override
+  public boolean isBatchConflationEnabled() {
+    return sender.isBatchConflationEnabled();
+  }
+
+  @Override
+  public int getMaximumQueueMemory() {
+    return sender.getMaximumQueueMemory();
+  }
+
+  @Override
+  public boolean isPersistent() {
+    return sender.isPersistenceEnabled();
+  }
+
+  @Override
+  public boolean isDiskSynchronous() {
+    return sender.isDiskSynchronous();
+  }
+  
+  @Override
+  public int getDispatcherThreads() {
+    return sender.getDispatcherThreads();
+  }
+  
+  @Override
+  public OrderPolicy getOrderPolicy() {
+    return sender.getOrderPolicy();
+  }
+  
+  @Override
+  public boolean isPrimary() {
+    return ((AbstractGatewaySender) sender).isPrimary();
+  }
+  
+  @Override
+  public int size() {
+	AbstractGatewaySenderEventProcessor eventProcessor = 
+	  ((AbstractGatewaySender) sender).getEventProcessor();
+	    
+	int size = 0;
+	if (eventProcessor instanceof ConcurrentSerialGatewaySenderEventProcessor) {
+	  Set<RegionQueue> queues = 
+		((ConcurrentSerialGatewaySenderEventProcessor) eventProcessor).getQueues();
+	  Iterator<RegionQueue> itr = queues.iterator();
+	  while (itr.hasNext()) {
+		size = size + itr.next().size();
+	  }
+	} else {
+	  size = eventProcessor.getQueue().size();
+	}
+	return size;
+  }
+  
+  public GatewaySender getSender() {
+    return this.sender;
+  }
+  
+  public AsyncEventQueueStats getStatistics() {
+     AbstractGatewaySender abstractSender =  (AbstractGatewaySender) this.sender;
+     return ((AsyncEventQueueStats) abstractSender.getStatistics());
+  }
+  
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == null) {
+      return false;
+    }
+    if (this == obj) {
+      return true;
+    }
+    if (!(obj instanceof AsyncEventQueue)) {
+      return false;
+    }
+    AsyncEventQueueImpl asyncEventQueue = (AsyncEventQueueImpl) obj;
+    if (asyncEventQueue.getId().equals(this.getId())) {
+      return true;
+    }
+    return false;
+  }
+  
+  @Override
+  public int hashCode() {
+    return getId().hashCode();
+  }
+
+  public static String getSenderIdFromAsyncEventQueueId(String asyncQueueId) {
+    StringBuilder builder = new StringBuilder();
+    builder.append(ASYNC_EVENT_QUEUE_PREFIX);
+    builder.append(asyncQueueId);
+    return builder.toString();
+  }
+
+  public static String getAsyncEventQueueIdFromSenderId(String senderId) {
+    if (!senderId.startsWith(ASYNC_EVENT_QUEUE_PREFIX)) {
+      return senderId;
+    }
+    else {
+      return senderId.substring(ASYNC_EVENT_QUEUE_PREFIX.length());
+    }
+  }
+
+  public static boolean isAsyncEventQueue(String senderId) {
+    return senderId.startsWith(ASYNC_EVENT_QUEUE_PREFIX);
+  }
+
+  public boolean isParallel() {
+    return sender.isParallel();
+  }
+
+   public boolean isBucketSorted() {
+    // TODO Auto-generated method stub
+    return false;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/AsyncEventQueueStats.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/AsyncEventQueueStats.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/AsyncEventQueueStats.java
new file mode 100644
index 0000000..3f0c7a0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/AsyncEventQueueStats.java
@@ -0,0 +1,177 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.asyncqueue.internal;
+
+import com.gemstone.gemfire.StatisticDescriptor;
+import com.gemstone.gemfire.StatisticsFactory;
+import com.gemstone.gemfire.StatisticsType;
+import com.gemstone.gemfire.StatisticsTypeFactory;
+import com.gemstone.gemfire.internal.StatisticsTypeFactoryImpl;
+import com.gemstone.gemfire.internal.cache.wan.GatewaySenderStats;
+
+public class AsyncEventQueueStats extends GatewaySenderStats {
+
+  public static final String typeName = "AsyncEventQueueStatistics";
+  
+  /** The <code>StatisticsType</code> of the statistics */
+  private static final StatisticsType type;
+  
+  
+  static {
+
+  StatisticsTypeFactory f = StatisticsTypeFactoryImpl.singleton();
+
+  type = f.createType(typeName, "Stats for activity in the AsyncEventQueue",
+     new StatisticDescriptor[] {
+      f.createIntCounter
+      (EVENTS_RECEIVED,
+       "Number of events received by this queue.",
+       "operations"),
+      f.createIntCounter
+      (EVENTS_QUEUED,
+       "Number of events added to the event queue.",
+       "operations"),
+      f.createLongCounter
+       (EVENT_QUEUE_TIME,
+        "Total time spent queueing events.",
+        "nanoseconds"),
+      f.createIntGauge
+       (EVENT_QUEUE_SIZE,
+        "Size of the event queue.",
+        "operations", false),
+      f.createIntGauge
+        (TMP_EVENT_QUEUE_SIZE,
+         "Size of the temporary events queue.",
+         "operations", false),
+      f.createIntCounter
+       (EVENTS_NOT_QUEUED_CONFLATED,
+        "Number of events received but not added to the event queue because the queue already contains an event with the event's key.",
+        "operations"),
+      f.createIntCounter
+        (EVENTS_CONFLATED_FROM_BATCHES,
+         "Number of events conflated from batches.",
+         "operations"),
+      f.createIntCounter
+       (EVENTS_DISTRIBUTED,
+        "Number of events removed from the event queue and sent.",
+        "operations"),
+      f.createIntCounter
+       (EVENTS_EXCEEDING_ALERT_THRESHOLD,
+        "Number of events exceeding the alert threshold.",
+        "operations", false),
+      f.createLongCounter
+       (BATCH_DISTRIBUTION_TIME,
+        "Total time spent distributing batches of events to receivers.",
+        "nanoseconds"),
+      f.createIntCounter
+       (BATCHES_DISTRIBUTED,
+        "Number of batches of events removed from the event queue and sent.",
+        "operations"),
+      f.createIntCounter
+       (BATCHES_REDISTRIBUTED,
+        "Number of batches of events removed from the event queue and resent.",
+        "operations", false),
+      f.createIntCounter
+       (UNPROCESSED_TOKENS_ADDED_BY_PRIMARY,
+        "Number of tokens added to the secondary's unprocessed token map by the primary (though a listener).",
+        "tokens"),
+      f.createIntCounter
+       (UNPROCESSED_EVENTS_ADDED_BY_SECONDARY,
+        "Number of events added to the secondary's unprocessed event map by the secondary.",
+        "events"),
+      f.createIntCounter
+       (UNPROCESSED_EVENTS_REMOVED_BY_PRIMARY,
+        "Number of events removed from the secondary's unprocessed event map by the primary (though a listener).",
+        "events"),
+      f.createIntCounter
+       (UNPROCESSED_TOKENS_REMOVED_BY_SECONDARY,
+        "Number of tokens removed from the secondary's unprocessed token map by the secondary.",
+        "tokens"),
+      f.createIntCounter
+       (UNPROCESSED_EVENTS_REMOVED_BY_TIMEOUT,
+        "Number of events removed from the secondary's unprocessed event map by a timeout.",
+        "events"),
+      f.createIntCounter
+       (UNPROCESSED_TOKENS_REMOVED_BY_TIMEOUT,
+        "Number of tokens removed from the secondary's unprocessed token map by a timeout.",
+        "tokens"),
+      f.createIntGauge
+       (UNPROCESSED_EVENT_MAP_SIZE,
+        "Current number of entries in the secondary's unprocessed event map.",
+        "events", false),
+      f.createIntGauge
+       (UNPROCESSED_TOKEN_MAP_SIZE,
+        "Current number of entries in the secondary's unprocessed token map.",
+        "tokens", false),
+      f.createIntGauge
+       (CONFLATION_INDEXES_MAP_SIZE,
+        "Current number of entries in the conflation indexes map.",
+        "events"),
+      f.createIntCounter
+        (NOT_QUEUED_EVENTS,
+         "Number of events not added to queue.",
+         "events"),
+      f.createIntCounter
+        (EVENTS_FILTERED,
+         "Number of events filtered through GatewayEventFilter.",
+         "events"),
+      f.createIntCounter
+        (LOAD_BALANCES_COMPLETED,
+         "Number of load balances completed",
+         "operations"),
+      f.createIntGauge
+        (LOAD_BALANCES_IN_PROGRESS,
+         "Number of load balances in progress",
+         "operations"),
+      f.createLongCounter
+        (LOAD_BALANCE_TIME,
+         "Total time spent load balancing this sender",
+         "nanoseconds"),
+  });
+
+  // Initialize id fields
+  eventsReceivedId = type.nameToId(EVENTS_RECEIVED);
+  eventsQueuedId = type.nameToId(EVENTS_QUEUED);
+  eventsNotQueuedConflatedId = type.nameToId(EVENTS_NOT_QUEUED_CONFLATED);
+  eventQueueTimeId = type.nameToId(EVENT_QUEUE_TIME);
+  eventQueueSizeId = type.nameToId(EVENT_QUEUE_SIZE);
+  eventTmpQueueSizeId = type.nameToId(TMP_EVENT_QUEUE_SIZE);
+  eventsDistributedId = type.nameToId(EVENTS_DISTRIBUTED);
+  eventsExceedingAlertThresholdId = type.nameToId(EVENTS_EXCEEDING_ALERT_THRESHOLD);
+  batchDistributionTimeId = type.nameToId(BATCH_DISTRIBUTION_TIME);
+  batchesDistributedId = type.nameToId(BATCHES_DISTRIBUTED);
+  batchesRedistributedId = type.nameToId(BATCHES_REDISTRIBUTED);
+  unprocessedTokensAddedByPrimaryId = type.nameToId(UNPROCESSED_TOKENS_ADDED_BY_PRIMARY);
+  unprocessedEventsAddedBySecondaryId = type.nameToId(UNPROCESSED_EVENTS_ADDED_BY_SECONDARY);
+  unprocessedEventsRemovedByPrimaryId = type.nameToId(UNPROCESSED_EVENTS_REMOVED_BY_PRIMARY);
+  unprocessedTokensRemovedBySecondaryId = type.nameToId(UNPROCESSED_TOKENS_REMOVED_BY_SECONDARY);
+  unprocessedEventsRemovedByTimeoutId = type.nameToId(UNPROCESSED_EVENTS_REMOVED_BY_TIMEOUT);
+  unprocessedTokensRemovedByTimeoutId = type.nameToId(UNPROCESSED_TOKENS_REMOVED_BY_TIMEOUT);
+  unprocessedEventMapSizeId = type.nameToId(UNPROCESSED_EVENT_MAP_SIZE);
+  unprocessedTokenMapSizeId = type.nameToId(UNPROCESSED_TOKEN_MAP_SIZE); 
+  conflationIndexesMapSizeId = type.nameToId(CONFLATION_INDEXES_MAP_SIZE); 
+  notQueuedEventsId = type.nameToId(NOT_QUEUED_EVENTS);
+  eventsFilteredId = type.nameToId(EVENTS_FILTERED);
+  eventsConflatedFromBatchesId = type.nameToId(EVENTS_CONFLATED_FROM_BATCHES);
+  loadBalancesCompletedId = type.nameToId(LOAD_BALANCES_COMPLETED);
+  loadBalancesInProgressId = type.nameToId(LOAD_BALANCES_IN_PROGRESS);
+  loadBalanceTimeId = type.nameToId(LOAD_BALANCE_TIME);
+  }
+  
+  /**
+   * Constructor.
+   *
+   * @param f The <code>StatisticsFactory</code> which creates the
+   * <code>Statistics</code> instance
+   * @param asyncQueueId The id of the <code>AsyncEventQueue</code> used to
+   * generate the name of the <code>Statistics</code>
+   */
+  public AsyncEventQueueStats(StatisticsFactory f, String asyncQueueId) {
+    super(f, asyncQueueId, type);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/ParallelAsyncEventQueueImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/ParallelAsyncEventQueueImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/ParallelAsyncEventQueueImpl.java
new file mode 100644
index 0000000..74a8ef5
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/ParallelAsyncEventQueueImpl.java
@@ -0,0 +1,244 @@
+package com.gemstone.gemfire.cache.asyncqueue.internal;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.EntryOperation;
+import com.gemstone.gemfire.cache.asyncqueue.AsyncEventListener;
+import com.gemstone.gemfire.cache.wan.GatewayTransportFilter;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.distributed.internal.ResourceEvent;
+import com.gemstone.gemfire.distributed.internal.DistributionAdvisor.Profile;
+import com.gemstone.gemfire.internal.cache.DistributedRegion;
+import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+import com.gemstone.gemfire.internal.cache.EventID;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.PartitionedRegionHelper;
+import com.gemstone.gemfire.internal.cache.UpdateAttributesProcessor;
+import com.gemstone.gemfire.internal.cache.ha.ThreadIdentifier;
+import com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySender;
+import com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySenderEventProcessor;
+import com.gemstone.gemfire.internal.cache.wan.GatewaySenderAttributes;
+import com.gemstone.gemfire.internal.cache.wan.parallel.ConcurrentParallelGatewaySenderEventProcessor;
+import com.gemstone.gemfire.internal.cache.wan.parallel.ConcurrentParallelGatewaySenderQueue;
+import com.gemstone.gemfire.internal.cache.wan.GatewaySenderAdvisor.GatewaySenderProfile;
+import com.gemstone.gemfire.internal.cache.xmlcache.CacheCreation;
+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;
+
+public class ParallelAsyncEventQueueImpl extends AbstractGatewaySender {
+  
+  private static final Logger logger = LogService.getLogger();
+  
+  final ThreadGroup loggerGroup = LoggingThreadGroup.createThreadGroup(
+      "Remote Site Discovery Logger Group", logger);
+  
+  public ParallelAsyncEventQueueImpl(){
+    super();
+    this.isParallel = true;
+  }
+  
+  public ParallelAsyncEventQueueImpl(Cache cache, GatewaySenderAttributes attrs) {
+    super(cache, attrs);
+    if (!(this.cache instanceof CacheCreation)) {
+      // this sender lies underneath the AsyncEventQueue. Need to have
+      // AsyncEventQueueStats
+        this.statistics = new AsyncEventQueueStats(
+            cache.getDistributedSystem(), AsyncEventQueueImpl
+                .getAsyncEventQueueIdFromSenderId(id));
+      }  
+    this.isForInternalUse = true;
+  }
+  
+  @Override
+  public void start() {
+    this.lifeCycleLock.writeLock().lock(); 
+    try {
+      if (isRunning()) {
+        logger.warn(LocalizedMessage.create(LocalizedStrings.GatewaySender_SENDER_0_IS_ALREADY_RUNNING, this.getId()));
+        return;
+      }
+
+      if (this.remoteDSId != DEFAULT_DISTRIBUTED_SYSTEM_ID) {
+        String locators = ((GemFireCacheImpl)this.cache).getDistributedSystem()
+            .getConfig().getLocators();
+        if (locators.length() == 0) {
+          throw new IllegalStateException(
+              LocalizedStrings.AbstractGatewaySender_LOCATOR_SHOULD_BE_CONFIGURED_BEFORE_STARTING_GATEWAY_SENDER
+                  .toLocalizedString());
+        }
+      }
+      /*
+       * Now onwards all processing will happen through "ConcurrentParallelGatewaySenderEventProcessor"
+       * we have made "ParallelGatewaySenderEventProcessor" and "ParallelGatewaySenderQueue" as a
+       * utility classes of Concurrent version of processor and queue.
+       */
+      eventProcessor = new ConcurrentParallelGatewaySenderEventProcessor(this);
+      /*if (getDispatcherThreads() > 1) {
+        eventProcessor = new ConcurrentParallelGatewaySenderEventProcessor(this);
+      } else {
+        eventProcessor = new ParallelGatewaySenderEventProcessor(this);
+      }*/
+      
+      eventProcessor.start();
+      waitForRunningStatus();
+      //Only notify the type registry if this is a WAN gateway queue
+      if(!isAsyncEventQueue()) {
+        ((GemFireCacheImpl) getCache()).getPdxRegistry().gatewaySenderStarted(this);
+      }
+      new UpdateAttributesProcessor(this).distribute(false);
+     
+      InternalDistributedSystem system = (InternalDistributedSystem) this.cache
+          .getDistributedSystem();
+      system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_START, this);
+      
+      logger.info(LocalizedMessage.create(LocalizedStrings.ParallelGatewaySenderImpl_STARTED__0, this));
+      
+      if (!tmpQueuedEvents.isEmpty()) {
+        enqueTempEvents();
+      }
+    }
+    finally {
+      this.lifeCycleLock.writeLock().unlock();
+    }
+  }
+  
+//  /**
+//   * The sender is not started but only the message queue i.e. shadowPR is created on the node.
+//   * @param targetPr
+//   */
+//  private void createMessageQueueOnAccessorNode(PartitionedRegion targetPr) {
+//    eventProcessor = new ParallelGatewaySenderEventProcessor(this, targetPr);
+//  }
+  
+
+  @Override
+  public void stop() {
+    this.lifeCycleLock.writeLock().lock(); 
+    try {
+      if (!this.isRunning()) {
+        return;
+      }
+      // Stop the dispatcher
+      AbstractGatewaySenderEventProcessor ev = this.eventProcessor;
+      if (ev != null && !ev.isStopped()) {
+        ev.stopProcessing();
+      }
+
+      // Stop the proxy (after the dispatcher, so the socket is still
+      // alive until after the dispatcher has stopped)
+      stompProxyDead();
+
+      // Close the listeners
+      for (AsyncEventListener listener : this.listeners) {
+        listener.close();
+      }
+      //stop the running threads, open sockets if any
+      ((ConcurrentParallelGatewaySenderQueue)this.eventProcessor.getQueue()).cleanUp();
+
+      logger.info(LocalizedMessage.create(LocalizedStrings.GatewayImpl_STOPPED__0, this));
+      
+      InternalDistributedSystem system = (InternalDistributedSystem) this.cache
+      .getDistributedSystem();
+      system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_STOP, this);
+      
+      clearTempEventsAfterSenderStopped();
+    }
+    finally {
+      this.lifeCycleLock.writeLock().unlock();
+    }
+  }
+  
+  @Override
+  public String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.append("ParallelGatewaySender{");
+    sb.append("id=" + getId());
+    sb.append(",remoteDsId="+ getRemoteDSId());
+    sb.append(",isRunning ="+ isRunning());
+    sb.append("}");
+    return sb.toString();
+  }
+
+  public void fillInProfile(Profile profile) {
+    assert profile instanceof GatewaySenderProfile;
+    GatewaySenderProfile pf = (GatewaySenderProfile)profile;
+    pf.Id = getId();
+    pf.remoteDSId = getRemoteDSId();
+    pf.isRunning = isRunning();
+    pf.isPrimary = isPrimary();
+    pf.isParallel = true;
+    pf.isBatchConflationEnabled = isBatchConflationEnabled();
+    pf.isPersistenceEnabled = isPersistenceEnabled();
+    pf.alertThreshold = getAlertThreshold();
+    pf.manualStart = isManualStart();
+    pf.dispatcherThreads = getDispatcherThreads();
+    pf.orderPolicy = getOrderPolicy();
+    for (com.gemstone.gemfire.cache.wan.GatewayEventFilter filter : getGatewayEventFilters()) {
+      pf.eventFiltersClassNames.add(filter.getClass().getName());
+    }
+    for (GatewayTransportFilter filter : getGatewayTransportFilters()) {
+      pf.transFiltersClassNames.add(filter.getClass().getName());
+    }
+    for (AsyncEventListener listener : getAsyncEventListeners()) {
+      pf.senderEventListenerClassNames.add(listener.getClass().getName());
+    }
+    pf.isDiskSynchronous = isDiskSynchronous();
+  }
+
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySender#setModifiedEventId(com.gemstone.gemfire.internal.cache.EntryEventImpl)
+   */
+  @Override
+  protected void setModifiedEventId(EntryEventImpl clonedEvent) {
+    int bucketId = -1;
+    //merged from 42004
+    if (clonedEvent.getRegion() instanceof DistributedRegion) {
+//      if (getOrderPolicy() == OrderPolicy.THREAD) {
+//        bucketId = PartitionedRegionHelper.getHashKey(
+//            ((EntryEventImpl)clonedEvent).getEventId().getThreadID(),
+//            getMaxParallelismForReplicatedRegion());
+//      }
+//      else
+        bucketId = PartitionedRegionHelper.getHashKey(clonedEvent.getKey(),
+            getMaxParallelismForReplicatedRegion());
+    }
+    else {
+      bucketId = PartitionedRegionHelper
+          .getHashKey((EntryOperation)clonedEvent);
+    }
+    EventID originalEventId = clonedEvent.getEventId();
+    long originatingThreadId = ThreadIdentifier.getRealThreadID(originalEventId.getThreadID());
+
+    long newThreadId = ThreadIdentifier
+    .createFakeThreadIDForParallelGSPrimaryBucket(bucketId,
+        originatingThreadId, getEventIdIndex());
+    
+    // In case of parallel as all events go through primary buckets
+    // we don't neet to generate different threadId for secondary buckets
+    // as they will be rejected if seen at PR level itself
+    
+//    boolean isPrimary = ((PartitionedRegion)getQueue().getRegion())
+//    .getRegionAdvisor().getBucketAdvisor(bucketId).isPrimary();
+//    if (isPrimary) {
+//      newThreadId = ThreadIdentifier
+//          .createFakeThreadIDForParallelGSPrimaryBucket(bucketId,
+//              originatingThreadId);
+//    } else {
+//      newThreadId = ThreadIdentifier
+//          .createFakeThreadIDForParallelGSSecondaryBucket(bucketId,
+//              originatingThreadId);
+//    }
+
+    EventID newEventId = new EventID(originalEventId.getMembershipID(),
+        newThreadId, originalEventId.getSequenceID(), bucketId);
+    if (logger.isDebugEnabled()) {
+      logger.debug("{}: Generated event id for event with key={}, bucketId={}, original event id={}, threadId={}, new event id={}, newThreadId={}",
+          this, clonedEvent.getKey(), bucketId, originalEventId, originatingThreadId, newEventId, newThreadId);
+    }
+    clonedEvent.setEventId(newEventId);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/SerialAsyncEventQueueImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/SerialAsyncEventQueueImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/SerialAsyncEventQueueImpl.java
new file mode 100644
index 0000000..90b41ac
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/internal/SerialAsyncEventQueueImpl.java
@@ -0,0 +1,241 @@
+package com.gemstone.gemfire.cache.asyncqueue.internal;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.asyncqueue.AsyncEventListener;
+import com.gemstone.gemfire.cache.wan.GatewayTransportFilter;
+import com.gemstone.gemfire.distributed.DistributedLockService;
+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.internal.cache.EntryEventImpl;
+import com.gemstone.gemfire.internal.cache.EventID;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.RegionQueue;
+import com.gemstone.gemfire.internal.cache.UpdateAttributesProcessor;
+import com.gemstone.gemfire.internal.cache.ha.ThreadIdentifier;
+import com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySender;
+import com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySenderEventProcessor;
+import com.gemstone.gemfire.internal.cache.wan.GatewaySenderAdvisor.GatewaySenderProfile;
+import com.gemstone.gemfire.internal.cache.wan.GatewaySenderAttributes;
+import com.gemstone.gemfire.internal.cache.wan.GatewaySenderConfigurationException;
+import com.gemstone.gemfire.internal.cache.wan.serial.ConcurrentSerialGatewaySenderEventProcessor;
+import com.gemstone.gemfire.internal.cache.wan.serial.SerialGatewaySenderEventProcessor;
+import com.gemstone.gemfire.internal.cache.wan.serial.SerialGatewaySenderQueue;
+import com.gemstone.gemfire.internal.cache.xmlcache.CacheCreation;
+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;
+
+public class SerialAsyncEventQueueImpl extends AbstractGatewaySender {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  final ThreadGroup loggerGroup = LoggingThreadGroup.createThreadGroup(
+      "Remote Site Discovery Logger Group", logger);
+
+  public SerialAsyncEventQueueImpl(){
+    super();
+    this.isParallel = false;
+  }
+  public SerialAsyncEventQueueImpl(Cache cache,
+      GatewaySenderAttributes attrs) {
+    super(cache, attrs);
+    if (!(this.cache instanceof CacheCreation)) {
+      // this sender lies underneath the AsyncEventQueue. Need to have
+      // AsyncEventQueueStats
+        this.statistics = new AsyncEventQueueStats(
+            cache.getDistributedSystem(), AsyncEventQueueImpl
+                .getAsyncEventQueueIdFromSenderId(id));
+      }
+  }
+  
+  @Override
+  public void start() {
+    if (logger.isDebugEnabled()) {
+      logger.debug("Starting gatewaySender : {}", this);
+    }
+    
+    this.lifeCycleLock.writeLock().lock();
+    try {
+      if (isRunning()) {
+        logger.warn(LocalizedMessage.create(LocalizedStrings.GatewaySender_SENDER_0_IS_ALREADY_RUNNING, this.getId()));
+        return;
+      }
+      if (this.remoteDSId != DEFAULT_DISTRIBUTED_SYSTEM_ID) {
+        String locators = ((GemFireCacheImpl)this.cache).getDistributedSystem()
+            .getConfig().getLocators();
+        if (locators.length() == 0) {
+          throw new GatewaySenderConfigurationException(
+              LocalizedStrings.AbstractGatewaySender_LOCATOR_SHOULD_BE_CONFIGURED_BEFORE_STARTING_GATEWAY_SENDER
+                  .toLocalizedString());
+        }
+      }
+      getSenderAdvisor().initDLockService();
+      if (!isPrimary()) {
+        if (getSenderAdvisor().volunteerForPrimary()) {
+          getSenderAdvisor().makePrimary();
+        } else {
+          getSenderAdvisor().makeSecondary();
+        }
+      }
+      if (getDispatcherThreads() > 1) {
+        eventProcessor = new ConcurrentSerialGatewaySenderEventProcessor(
+            SerialAsyncEventQueueImpl.this);
+      } else {
+        eventProcessor = new SerialGatewaySenderEventProcessor(
+            SerialAsyncEventQueueImpl.this, getId());
+      }
+      eventProcessor.start();
+      waitForRunningStatus();
+      this.startTime = System.currentTimeMillis();
+      
+      //Only notify the type registry if this is a WAN gateway queue
+      if(!isAsyncEventQueue()) {
+        ((GemFireCacheImpl) getCache()).getPdxRegistry().gatewaySenderStarted(this);
+      }
+      new UpdateAttributesProcessor(this).distribute(false);
+
+      
+      InternalDistributedSystem system = (InternalDistributedSystem) this.cache
+          .getDistributedSystem();
+      system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_START, this);
+      
+      logger.info(LocalizedMessage.create(LocalizedStrings.SerialGatewaySenderImpl_STARTED__0, this));
+  
+      enqueTempEvents();
+    } finally {
+      this.lifeCycleLock.writeLock().unlock();
+    }
+  }
+  
+  @Override
+  public void stop() {
+    if (logger.isDebugEnabled()) {
+      logger.debug("Stopping Gateway Sender : {}", this);
+    }
+    this.lifeCycleLock.writeLock().lock();
+    try {
+      // Stop the dispatcher
+      AbstractGatewaySenderEventProcessor ev = this.eventProcessor;
+      if (ev != null && !ev.isStopped()) {
+        ev.stopProcessing();
+      }
+
+      // Stop the proxy (after the dispatcher, so the socket is still
+      // alive until after the dispatcher has stopped)
+      stompProxyDead();
+
+      // Close the listeners
+      for (AsyncEventListener listener : this.listeners) {
+        listener.close();
+      }
+      logger.info(LocalizedMessage.create(LocalizedStrings.GatewayImpl_STOPPED__0, this));
+      
+      clearTempEventsAfterSenderStopped();
+    } finally {
+      this.lifeCycleLock.writeLock().unlock();
+    }
+    if (this.isPrimary()) {
+      try {
+        DistributedLockService
+            .destroy(getSenderAdvisor().getDLockServiceName());
+      } catch (IllegalArgumentException e) {
+        // service not found... ignore
+      }
+    }
+    if (getQueues() != null && !getQueues().isEmpty()) {
+      for (RegionQueue q : getQueues()) {
+        ((SerialGatewaySenderQueue)q).cleanUp();
+      }
+    }
+    this.setIsPrimary(false);
+    new UpdateAttributesProcessor(this).distribute(false);
+    Thread lockObtainingThread = getSenderAdvisor().getLockObtainingThread();
+    if (lockObtainingThread != null && lockObtainingThread.isAlive()) {
+      // wait a while for thread to terminate
+      try {
+        lockObtainingThread.join(3000);
+      } catch (InterruptedException ex) {
+        // we allowed our join to be canceled
+        // reset interrupt bit so this thread knows it has been interrupted
+        Thread.currentThread().interrupt();
+      }
+      if (lockObtainingThread.isAlive()) {
+        logger.info(LocalizedMessage.create(LocalizedStrings.GatewaySender_COULD_NOT_STOP_LOCK_OBTAINING_THREAD_DURING_GATEWAY_SENDER_STOP));
+      }
+    }
+    
+    InternalDistributedSystem system = (InternalDistributedSystem) this.cache
+        .getDistributedSystem();
+    system.handleResourceEvent(ResourceEvent.GATEWAYSENDER_STOP, this);
+  }
+  
+  @Override
+  public String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.append("SerialGatewaySender{");
+    sb.append("id=" + getId());
+    sb.append(",remoteDsId="+ getRemoteDSId());
+    sb.append(",isRunning ="+ isRunning());
+    sb.append(",isPrimary ="+ isPrimary());
+    sb.append("}");
+    return sb.toString();
+  }
+ 
+  @Override
+  public void fillInProfile(Profile profile) {
+    assert profile instanceof GatewaySenderProfile;
+    GatewaySenderProfile pf = (GatewaySenderProfile)profile;
+    pf.Id = getId();
+    pf.startTime = getStartTime();
+    pf.remoteDSId = getRemoteDSId();
+    pf.isRunning = isRunning();
+    pf.isPrimary = isPrimary();
+    pf.isParallel = false;
+    pf.isBatchConflationEnabled = isBatchConflationEnabled();
+    pf.isPersistenceEnabled = isPersistenceEnabled();
+    pf.alertThreshold = getAlertThreshold();
+    pf.manualStart = isManualStart();
+    for (com.gemstone.gemfire.cache.wan.GatewayEventFilter filter : getGatewayEventFilters()) {
+      pf.eventFiltersClassNames.add(filter.getClass().getName());
+    }
+    for (GatewayTransportFilter filter : getGatewayTransportFilters()) {
+      pf.transFiltersClassNames.add(filter.getClass().getName());
+    }
+    for (AsyncEventListener listener : getAsyncEventListeners()) {
+      pf.senderEventListenerClassNames.add(listener.getClass().getName());
+    }
+    pf.isDiskSynchronous = isDiskSynchronous();
+    pf.dispatcherThreads = getDispatcherThreads();
+    pf.orderPolicy = getOrderPolicy();
+    pf.serverLocation = this.getServerLocation(); 
+  }
+
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.internal.cache.wan.AbstractGatewaySender#setModifiedEventId(com.gemstone.gemfire.internal.cache.EntryEventImpl)
+   */
+  @Override
+  protected void setModifiedEventId(EntryEventImpl clonedEvent) {
+    EventID originalEventId = clonedEvent.getEventId();
+    long originalThreadId = originalEventId.getThreadID();
+    long newThreadId = originalThreadId;
+    if (ThreadIdentifier.isWanTypeThreadID(newThreadId)) {
+      // This thread id has already been converted. Do nothing.
+    } else {
+      newThreadId = ThreadIdentifier
+        .createFakeThreadIDForParallelGSPrimaryBucket(0, originalThreadId,
+            getEventIdIndex());
+    }
+    EventID newEventId = new EventID(originalEventId.getMembershipID(),
+        newThreadId, originalEventId.getSequenceID());
+    if (logger.isDebugEnabled()) {
+      logger.debug("{}: Generated event id for event with key={}, original event id={}, originalThreadId={}, new event id={}, newThreadId={}",
+          this, clonedEvent.getKey(), originalEventId, originalThreadId, newEventId, newThreadId);
+    }
+    clonedEvent.setEventId(newEventId);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/AllConnectionsInUseException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/AllConnectionsInUseException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/AllConnectionsInUseException.java
new file mode 100644
index 0000000..95c86f0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/AllConnectionsInUseException.java
@@ -0,0 +1,52 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client;
+
+
+/**
+ * Indicates that the connection pool is at its maximum size and
+ * all connections are in use.
+ * @author dsmith
+ * @since 5.7
+ */
+public class AllConnectionsInUseException extends ServerConnectivityException {
+
+  private static final long serialVersionUID = 7304243507881787071L;
+
+  /**
+   * Create a new instance of AllConnectionsInUseException without a detail message or cause.
+   */
+  public AllConnectionsInUseException() {
+  }
+
+  /**
+   * Create a new instance of AllConnectionsInUseException with a detail message
+   * @param message the detail message
+   */
+  public AllConnectionsInUseException(String message) {
+    super(message);
+  }
+  
+  /**
+   * Create a new instance of AllConnectionsInUseException with a cause
+   * @param cause the cause
+   */
+  public AllConnectionsInUseException(Throwable cause) {
+    super(cause);
+  }
+  
+  /**
+   * Create a new instance of AllConnectionsInUseException with a detail message and cause
+   * @param message the detail message
+   * @param cause the cause
+   */
+  public AllConnectionsInUseException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientCache.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientCache.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientCache.java
new file mode 100644
index 0000000..7582da9
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientCache.java
@@ -0,0 +1,159 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache.client;
+
+import java.net.InetSocketAddress;
+import java.util.Properties;
+import java.util.Set;
+
+import com.gemstone.gemfire.cache.*;
+import com.gemstone.gemfire.cache.query.QueryService;
+
+/**
+ * A ClientCache instance controls the life cycle of the local singleton cache in a client. 
+ * <p>A ClientCache is created using {@link ClientCacheFactory#create}.
+ * See {@link ClientCacheFactory} for common usage patterns for creating the client cache instance.
+ * <p>ClientCache provides
+ * access to functionality when a member connects as a client to GemFire servers.
+ * It provides the following services:
+ <ul>
+ * <li> Access to existing regions (see {@link #getRegion} and {@link #rootRegions}).
+ * <li> Creation of regions (see {@link #createClientRegionFactory(ClientRegionShortcut)} and {@link #createClientRegionFactory(String)}).
+ * <li> Access the query service (see {@link #getQueryService} and {@link #getLocalQueryService}).</li>
+ * <li> Access the GemFire logger (see {@link #getLogger}).</li>
+ * <li> Access the GemFire distributed system (see {@link #getDistributedSystem}).</li>
+ * <li> Access the GemFire resource manager (see {@link #getResourceManager}).</li>
+ * <li> Manages local disk stores for this cache instance (see {@link #createDiskStoreFactory}).</li>
+ * <li> Creation of authenticated cache views that support multiple users (see {@link #createAuthenticatedView}).
+ </ul>
+ * <p>A ClientCache connects to a server using a {@link Pool}. This pool can be
+ * configured in the ClientCacheFactory (by default GemFire tries to create a pool
+ * which tries to connect to a server on the localhost on port 40404). This default pool
+ * is used by {@link Region}s (created using {@link ClientRegionFactory}) to talk to
+ * regions on the server.
+ * <p>More pools can be created using {@link PoolManager} or by declaring them in cache.xml.
+ * @since 6.5
+ * @author darrel
+ */
+public interface ClientCache extends GemFireCache {
+  /**
+   * Return the QueryService for the named pool.
+   * The query operations performed
+   * using this QueryService will be executed on the servers that are associated
+   * with this pool.
+   */
+  public QueryService getQueryService(String poolName);
+  
+  /**
+   * Return a QueryService that queries the local state in the client cache.
+   * These queries will not be sent to a server.
+   */
+  public QueryService getLocalQueryService();
+  
+  /**
+   * Terminates this object cache and releases all the resources.
+   * Calls {@link Region#close} on each region in the cache.
+   * After this cache is closed, any further
+   * method call on this cache or any region object will throw
+   * {@link CacheClosedException}, unless otherwise noted.
+   * @param keepalive whether the server should keep the durable client's queues alive for the timeout period
+   * @throws CacheClosedException if the cache is already closed.
+   */
+  public void close(boolean keepalive);  
+
+  /**
+   * Create and return a client region factory that is initialized to create
+   * a region using the given predefined region attributes.
+   * @param shortcut the predefined region attributes to initialize the factory with.
+   * @return a factory that will produce a client region.
+   */
+  public <K,V> ClientRegionFactory<K,V> createClientRegionFactory(ClientRegionShortcut shortcut);
+
+  /**
+   * Create and return a client region factory that is initialized to create
+   * a region using the given named region attributes.
+   * <p>Named region attributes are defined in cache.xml by setting the name as
+   * the value of the <code>id</code> attribute on a <code>region-attributes</code> element.
+   * @param regionAttributesId the named region attributes to initialize the factory with.
+   * @throws IllegalStateException if named region attributes has not been defined.
+   * @return a factory that will produce a client region.
+   */
+  public <K,V> ClientRegionFactory<K,V> createClientRegionFactory(String regionAttributesId);
+
+  /**
+   * Notifies the server that this durable client is ready to receive updates.
+   * This method is used by durable clients to notify servers that they
+   * are ready to receive updates. As soon as the server receives this message, 
+   * it will forward updates to this client (if necessary).
+   * <p>
+   * Durable clients must call this method after they are done creating regions
+   * and issuing interest registration requests.If it is called before then events
+   * will be lost.Any time a new {@link Pool} is created and regions have been 
+   * added to it then this method needs to be called again.
+   * <p>
+   *
+   * @throws IllegalStateException if called by a non-durable client
+   */
+  public void readyForEvents();
+
+  /**
+   * Creates an authenticated cache view using the given user security properties
+   * on the client cache's default pool.
+   * Multiple views with different user properties can be created on a
+   * single client cache.
+   * 
+   * Requires that {@link ClientCacheFactory#setPoolMultiuserAuthentication(boolean) multiuser-authentication}
+   * to be set to true on the default pool.
+
+   * Applications must use this instance to do operations, when
+   * multiuser-authentication is set to true.
+   *
+   * <p>
+   * Authenticated cache views are only allows to access {@link ClientRegionShortcut#PROXY proxy} regions.
+   * The {@link RegionService#getRegion} method will throw IllegalStateException
+   * if an attempt is made to get a region that has local storage.
+   *
+   * @throws UnsupportedOperationException
+   *           when invoked with multiuser-authentication as false.
+   * @param userSecurityProperties
+   *          the security properties of a user.
+   * @return the {@link RegionService} instance associated with a user and the given
+   *         properties.
+   */
+  public RegionService createAuthenticatedView(Properties userSecurityProperties);
+  
+  /**
+   * Creates an authenticated cache view using the given user security properties
+   * using the given pool to connect to servers.
+   * Requires that {@link PoolFactory#setMultiuserAuthentication(boolean) multiuser-authentication} to be set to true
+   * on the given pool.
+   * <p>See {@link #createAuthenticatedView(Properties)} for more information
+   * on the returned cache view.
+   * @param userSecurityProperties the security properties of a user.
+   * @param poolName - the pool that the users should be authenticated against.
+   * @return the {@link RegionService} instance associated with a user and the given
+   *         properties.
+   */
+  public RegionService createAuthenticatedView(Properties userSecurityProperties, String poolName);
+  
+  /**
+   * Returns a set of the servers to which this client is currently connected.
+   * @since 6.6
+   */
+  public Set<InetSocketAddress> getCurrentServers();
+  
+  /**
+   * Returns the default server pool. If one or more non-default pools were
+   * configured, this may return null.
+   * @since 7.0
+   * @see com.gemstone.gemfire.cache.client.Pool
+   */
+  public Pool getDefaultPool();
+  
+}


[05/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInstantiatorsOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInstantiatorsOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInstantiatorsOp.java
new file mode 100644
index 0000000..f3c9f03
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInstantiatorsOp.java
@@ -0,0 +1,171 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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.BridgeObserver;
+import com.gemstone.gemfire.internal.cache.BridgeObserverHolder;
+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) {
+        BridgeObserver bo = BridgeObserverHolder.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) {
+        BridgeObserver bo = BridgeObserverHolder.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().send(false);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInterestListOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInterestListOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInterestListOp.java
new file mode 100644
index 0000000..873f3d6
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInterestListOp.java
@@ -0,0 +1,138 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.List;
+
+import com.gemstone.gemfire.cache.InterestResultPolicy;
+import com.gemstone.gemfire.cache.client.internal.RegisterInterestOp.RegisterInterestOpImpl;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.cache.tier.MessageType;
+
+/**
+ * Does a region registerInterestList on a server
+ * @author darrel
+ * @since 5.7
+ */
+public class RegisterInterestListOp {
+  /**
+   * Does a region registerInterestList 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 registerInterestList on
+   * @param keys list of keys we are interested in
+   * @param policy the interest result policy for this registration
+   * @param isDurable true if this registration is durable
+   * @param regionDataPolicy the data policy ordinal of the region
+   * @return list of keys
+   */
+  public static List execute(ExecutablePool pool,
+                             String region,
+                             List keys,
+                             InterestResultPolicy policy,
+                             boolean isDurable,
+                             boolean receiveUpdatesAsInvalidates,
+                             byte regionDataPolicy)
+  {
+    AbstractOp op = new RegisterInterestListOpImpl(region, keys, policy,
+        isDurable, receiveUpdatesAsInvalidates, regionDataPolicy);
+    return (List) pool.executeOnQueuesAndReturnPrimaryResult(op);
+  }
+                                                               
+  private RegisterInterestListOp() {
+    // no instances allowed
+  }
+  /**
+   * Does a region registerInterestList on a server using connections from the given pool
+   * to communicate with the given server location.
+   * @param sl the server to do the register interest on.
+   * @param pool the pool to use to communicate with the server.
+   * @param region the name of the region to do the registerInterest on
+   * @param keys describes what we are interested in
+   * @param policy the interest result policy for this registration
+   * @param isDurable true if this registration is durable
+   * @param regionDataPolicy the data policy ordinal of the region
+   * @return list of keys
+   */
+  public static List executeOn(ServerLocation sl,
+                               ExecutablePool pool,
+                               String region,
+                               List keys,
+                               InterestResultPolicy policy,
+                               boolean isDurable,
+                               boolean receiveUpdatesAsInvalidates,
+                               byte regionDataPolicy)
+  { 
+    AbstractOp op = new RegisterInterestListOpImpl(region, keys, policy,
+        isDurable, receiveUpdatesAsInvalidates, regionDataPolicy);
+    return  (List) pool.executeOn(sl, op);
+  }
+
+  
+  /**
+   * Does a region registerInterestList on a server using connections from the given pool
+   * to communicate with the given server location.
+   * @param conn the connection to do the register interest on.
+   * @param pool the pool to use to communicate with the server.
+   * @param region the name of the region to do the registerInterest on
+   * @param keys describes what we are interested in
+   * @param policy the interest result policy for this registration
+   * @param isDurable true if this registration is durable
+   * @param regionDataPolicy the data policy ordinal of the region
+   * @return list of keys
+   */
+  public static List executeOn(Connection conn,
+                               ExecutablePool pool,
+                               String region,
+                               List keys,
+                               InterestResultPolicy policy,
+                               boolean isDurable,
+                               boolean receiveUpdatesAsInvalidates,
+                               byte regionDataPolicy)
+  {
+    AbstractOp op = new RegisterInterestListOpImpl(region, keys, policy,
+        isDurable, receiveUpdatesAsInvalidates, regionDataPolicy);
+    return  (List) pool.executeOn(conn, op);
+  }
+  
+  private static class RegisterInterestListOpImpl extends RegisterInterestOpImpl {
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public RegisterInterestListOpImpl(String region,
+                                      List keys,
+                                      InterestResultPolicy policy,
+                                      boolean isDurable,
+                                      boolean receiveUpdatesAsInvalidates,
+                                      byte regionDataPolicy) {
+      super(region, MessageType.REGISTER_INTEREST_LIST, 6);
+      getMessage().addStringPart(region);
+      getMessage().addObjPart(policy);
+      {
+        byte durableByte = (byte)(isDurable ? 0x01 : 0x00);
+        getMessage().addBytesPart(new byte[] {durableByte});
+      }      
+      //Set chunk size of HDOS for keys      
+      getMessage().setChunkSize(keys.size()*16);
+      getMessage().addObjPart(keys);
+      
+      byte notifyByte = (byte)(receiveUpdatesAsInvalidates ? 0x01 : 0x00);
+      getMessage().addBytesPart(new byte[] {notifyByte});
+
+      // The second byte '1' below tells server to serialize values in VersionObjectList.
+      // Java clients always expect serializeValues to be true in VersionObjectList unlike Native clients.
+      // This was being sent as part of GetAllOp prior to fixing #43684.
+      getMessage().addBytesPart(new byte[] {regionDataPolicy, (byte)0x01});
+    }
+    @Override
+    protected String getOpName() {
+      return "registerInterestList";
+    }
+    // note we reuse the same stats used by RegisterInterestOpImpl
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInterestOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInterestOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInterestOp.java
new file mode 100644
index 0000000..db0a47f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInterestOp.java
@@ -0,0 +1,287 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+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.ChunkedMessage;
+import com.gemstone.gemfire.internal.cache.tier.sockets.Part;
+import com.gemstone.gemfire.internal.cache.tier.sockets.VersionedObjectList;
+import com.gemstone.gemfire.InternalGemFireError;
+import com.gemstone.gemfire.internal.cache.tier.InterestType;
+import com.gemstone.gemfire.cache.InterestResultPolicy;
+import com.gemstone.gemfire.cache.client.ServerOperationException;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+
+import java.util.ArrayList;
+import java.util.List;
+/**
+ * Does a region registerInterest on a server
+ * @author darrel
+ * @since 5.7
+ */
+public class RegisterInterestOp {
+  /**
+   * Does a region registerInterest 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 registerInterest on
+   * @param key describes what we are interested in
+   * @param interestType the {@link InterestType} for this registration
+   * @param policy the interest result policy for this registration
+   * @param isDurable true if this registration is durable
+   * @param regionDataPolicy the data policy ordinal of the region
+   * @return list of keys
+   */
+  public static List execute(ExecutablePool pool,
+                             String region,
+                             Object key,
+                             int interestType,
+                             InterestResultPolicy policy,
+                             boolean isDurable,
+                             boolean receiveUpdatesAsInvalidates,
+                             byte regionDataPolicy)
+  {
+    AbstractOp op = new RegisterInterestOpImpl(region, key,
+        interestType, policy, isDurable, receiveUpdatesAsInvalidates, regionDataPolicy);
+    return  (List) pool.executeOnQueuesAndReturnPrimaryResult(op);
+  }
+                                                               
+  /**
+   * Does a region registerInterest on a server using connections from the given pool
+   * to communicate with the given server location.
+   * @param sl the server to do the register interest on.
+   * @param pool the pool to use to communicate with the server.
+   * @param region the name of the region to do the registerInterest on
+   * @param key describes what we are interested in
+   * @param interestType the {@link InterestType} for this registration
+   * @param policy the interest result policy for this registration
+   * @param isDurable true if this registration is durable
+   * @param regionDataPolicy the data policy ordinal of the region
+   * @return list of keys
+   */
+  public static List executeOn(ServerLocation sl,
+                               ExecutablePool pool,
+                               String region,
+                               Object key,
+                               int interestType,
+                               InterestResultPolicy policy,
+                               boolean isDurable,
+                               boolean receiveUpdatesAsInvalidates,
+                               byte regionDataPolicy)
+  {
+    AbstractOp op = new RegisterInterestOpImpl(region, key,
+        interestType, policy, isDurable, receiveUpdatesAsInvalidates, regionDataPolicy);
+    return  (List) pool.executeOn(sl, op);
+  }
+
+  
+  /**
+   * Does a region registerInterest on a server using connections from the given pool
+   * to communicate with the given server location.
+   * @param conn the connection to do the register interest on.
+   * @param pool the pool to use to communicate with the server.
+   * @param region the name of the region to do the registerInterest on
+   * @param key describes what we are interested in
+   * @param interestType the {@link InterestType} for this registration
+   * @param policy the interest result policy for this registration
+   * @param isDurable true if this registration is durable
+   * @param regionDataPolicy the data policy ordinal of the region
+   * @return list of keys
+   */
+  public static List executeOn(Connection conn,
+                               ExecutablePool pool,
+                               String region,
+                               Object key,
+                               int interestType,
+                               InterestResultPolicy policy,
+                               boolean isDurable,
+                               boolean receiveUpdatesAsInvalidates,
+                               byte regionDataPolicy)
+  {
+    AbstractOp op = new RegisterInterestOpImpl(region, key,
+        interestType, policy, isDurable, receiveUpdatesAsInvalidates, regionDataPolicy);
+    return  (List) pool.executeOn(conn, op);
+  }
+
+  
+  private RegisterInterestOp() {
+    // no instances allowed
+  }
+
+  protected static class RegisterInterestOpImpl extends AbstractOp {
+    protected String region;
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public RegisterInterestOpImpl(String region,
+                                  Object key,
+                                  int interestType,
+                                  InterestResultPolicy policy,
+                                  boolean isDurable,
+                                  boolean receiveUpdatesAsInvalidates,
+                                  byte regionDataPolicy) {
+      super(MessageType.REGISTER_INTEREST, 7);
+      this.region = region;
+      getMessage().addStringPart(region);
+      getMessage().addIntPart(interestType);
+      getMessage().addObjPart(policy);
+      {
+        byte durableByte = (byte)(isDurable ? 0x01 : 0x00);
+        getMessage().addBytesPart(new byte[] {durableByte});
+      }
+      getMessage().addStringOrObjPart(key);
+      byte notifyByte = (byte)(receiveUpdatesAsInvalidates ? 0x01 : 0x00);
+      getMessage().addBytesPart(new byte[] {notifyByte});
+
+      // The second byte '1' below tells server to serialize values in VersionObjectList.
+      // Java clients always expect serializeValues to be true in VersionObjectList unlike Native clients.
+      // This was being sent as part of GetAllOp prior to fixing #43684.
+      getMessage().addBytesPart(new byte[] {regionDataPolicy, (byte)0x01});
+    }
+    /**
+     * This constructor is used by our subclass CreateCQWithIROpImpl
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    protected RegisterInterestOpImpl(String region, int msgType, int numParts) {
+      super(msgType, numParts);
+      this.region = region;
+    }
+
+    @Override  
+    protected Message createResponseMessage() {
+      return new ChunkedMessage(1, Version.CURRENT);
+    }
+    
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override  
+    protected Object processResponse(Message m, Connection con) throws Exception {
+      ChunkedMessage msg = (ChunkedMessage)m;
+      msg.readHeader();
+      switch (msg.getMessageType()) {
+      case MessageType.RESPONSE_FROM_PRIMARY: {
+        ArrayList serverKeys = new ArrayList();
+        VersionedObjectList serverEntries = null;
+        LocalRegion r = null;
+        
+        try {
+          r = (LocalRegion)GemFireCacheImpl.getInstance().getRegion(this.region);
+        }catch(Exception ex) {
+		//ignore but read message
+	//	GemFireCacheImpl.getInstance().getLogger().config("hitesh error " + ex.getClass());
+        }
+        
+        ArrayList list = new ArrayList();
+        ArrayList listOfList = new ArrayList();
+        listOfList.add(list);
+
+        // Process the chunks
+        do {
+          // Read the chunk
+          msg.receiveChunk();
+
+          // Deserialize the result
+          Part part = msg.getPart(0);
+
+          Object partObj = part.getObject();
+          if (partObj instanceof Throwable) {
+            String s = "While performing a remote " + getOpName();
+            throw new ServerOperationException(s, (Throwable)partObj);
+            // Get the exception toString part.
+            // This was added for c++ thin client and not used in java
+            //Part exceptionToStringPart = msg.getPart(1);
+          }
+          else {
+            if (partObj instanceof VersionedObjectList) {
+              if (serverEntries == null) {
+                serverEntries = new VersionedObjectList(true);
+              }
+              ((VersionedObjectList)partObj).replaceNullIDs(con.getEndpoint().getMemberId());
+              // serverEntries.addAll((VersionedObjectList)partObj);
+              list.clear();
+              list.add(partObj);
+
+	      if(r != null) {
+		try {      
+                  r.refreshEntriesFromServerKeys(con, listOfList, InterestResultPolicy.KEYS_VALUES);
+		}catch(Exception ex) {
+	//	  GemFireCacheImpl.getInstance().getLogger().config("hitesh error2 " + ex.getClass());
+		}
+	      }
+            } else {
+              // Add the result to the list of results
+              serverKeys.add((List)partObj);
+            }
+          }
+
+        } while (!msg.isLastChunk());
+        if (serverEntries != null) {
+          list.clear();
+          list.add(serverEntries); // serverEntries will always be empty.
+          return listOfList;
+        }
+        return serverKeys;
+      }
+      case MessageType.RESPONSE_FROM_SECONDARY:
+        // Read the chunk
+        msg.receiveChunk();
+        return null;
+      case MessageType.EXCEPTION:
+        // Read the chunk
+        msg.receiveChunk();
+        // Deserialize the result
+        Part part = msg.getPart(0);
+        // Get the exception toString part.
+        // This was added for c++ thin client and not used in java
+        //Part exceptionToStringPart = msg.getPart(1);
+        Object obj = part.getObject();
+        {
+          String s = this + ": While performing a remote " + getOpName();
+          throw new ServerOperationException(s, (Throwable) obj);
+        }
+      case MessageType.REGISTER_INTEREST_DATA_ERROR:
+        // Read the chunk
+        msg.receiveChunk();
+
+        // Deserialize the result
+        String errorMessage = msg.getPart(0).getString();
+        String s = this + ": While performing a remote " + getOpName() + ": ";
+        throw new ServerOperationException(s + errorMessage);
+      default:
+        throw new InternalGemFireError("Unknown message type "
+                                       + msg.getMessageType());
+      }
+    }
+    protected String getOpName() {
+      return "registerInterest";
+    }
+    @Override  
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.REGISTER_INTEREST_DATA_ERROR;
+    }
+    @Override  
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startRegisterInterest();
+    }
+    @Override  
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endRegisterInterestSend(start, hasFailed());
+    }
+    @Override  
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endRegisterInterest(start, hasTimedOut(), hasFailed());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInterestTracker.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInterestTracker.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInterestTracker.java
new file mode 100644
index 0000000..9d67251
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RegisterInterestTracker.java
@@ -0,0 +1,410 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.ArrayList;
+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.InternalGemFireError;
+import com.gemstone.gemfire.cache.InterestResultPolicy;
+import com.gemstone.gemfire.cache.query.internal.cq.InternalCqQuery;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.cache.tier.InterestType;
+import com.gemstone.gemfire.internal.cache.tier.sockets.UnregisterAllInterest;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+
+/**
+ * Used to keep track of what interest a client has registered.
+ * This code was extracted from the old ConnectionProxyImpl.
+ * @author darrel
+ * @since 5.7
+ */
+public class RegisterInterestTracker {
+  private static final Logger logger = LogService.getLogger();
+  
+  public final static int interestListIndex = 0;
+  public final static int durableInterestListIndex = 1;
+  public final static int interestListIndexForUpdatesAsInvalidates = 2;
+  public final static int durableInterestListIndexForUpdatesAsInvalidates = 3;
+  
+  private final FailoverInterestList[] fils = new FailoverInterestList[4];
+  
+  /** Manages CQs */
+  private final ConcurrentMap cqs /* <CqQuery,Boolean> */= new ConcurrentHashMap();
+  
+  public RegisterInterestTracker() {
+    this.fils[interestListIndex] = new FailoverInterestList();
+    this.fils[interestListIndexForUpdatesAsInvalidates] = new FailoverInterestList();
+    this.fils[durableInterestListIndex] = new FailoverInterestList();
+    this.fils[durableInterestListIndexForUpdatesAsInvalidates] = new FailoverInterestList();
+  }
+  
+  public static int getInterestLookupIndex(boolean isDurable, boolean receiveUpdatesAsInvalidates) {
+    if (isDurable) {
+      if (receiveUpdatesAsInvalidates) {
+        return durableInterestListIndexForUpdatesAsInvalidates;
+      } else {
+        return durableInterestListIndex;
+      }
+    } else {
+      if (receiveUpdatesAsInvalidates) {
+        return interestListIndexForUpdatesAsInvalidates;
+      } else {
+        return interestListIndex;
+      }
+    }
+  }
+  
+  public List getInterestList(String regionName, int interestType)
+  {
+    RegionInterestEntry rie1 = readRegionInterests(regionName, interestType, false, false);
+    RegionInterestEntry rie2 = readRegionInterests(regionName, interestType, false, true);
+    RegionInterestEntry rie3 = readRegionInterests(regionName, interestType, true, false);
+    RegionInterestEntry rie4 = readRegionInterests(regionName, interestType, true, true);
+    
+    ArrayList result = new ArrayList();
+    
+    if (rie1 != null) {
+      result.addAll(rie1.getInterests().keySet());
+    }
+    
+    if (rie2 != null) {
+      result.addAll(rie2.getInterests().keySet());
+    }
+    
+    if (rie3 != null) {
+      result.addAll(rie3.getInterests().keySet());
+    }
+    
+    if (rie4 != null) {
+      result.addAll(rie4.getInterests().keySet());
+    }
+    
+    return result;
+  }
+
+  public void addSingleInterest(LocalRegion r, Object key, int interestType,
+      InterestResultPolicy pol, boolean isDurable, boolean receiveUpdatesAsInvalidates)
+  {
+    RegionInterestEntry rie = getRegionInterests(r, interestType, false,
+        isDurable, receiveUpdatesAsInvalidates);
+    rie.getInterests().put(key, pol);
+  }
+
+  public boolean removeSingleInterest(LocalRegion r, Object key,
+      int interestType, boolean isDurable, boolean receiveUpdatesAsInvalidates)
+  {
+    RegionInterestEntry rie = getRegionInterests(r, interestType, true,
+        isDurable, receiveUpdatesAsInvalidates);
+    if (rie == null) {
+      return false;
+    }
+    if (logger.isDebugEnabled()) {
+      logger.debug("removeSingleInterest region={} key={}", r.getFullPath(), key);
+    }
+    Object interest = rie.getInterests().remove(key);
+    if (interest == null) {
+      logger.warn(LocalizedMessage.create(LocalizedStrings.RegisterInterestTracker_REMOVESINGLEINTEREST_KEY_0_NOT_REGISTERED_IN_THE_CLIENT, key));
+      return false;
+    }
+    else {
+      return true;
+    }
+    //return rie.getInterests().remove(key) != null;
+  }
+
+  public void addInterestList(LocalRegion r, List keys,
+      InterestResultPolicy pol, boolean isDurable, boolean receiveUpdatesAsInvalidates)
+  {
+    RegionInterestEntry rie = getRegionInterests(r, InterestType.KEY, false,
+        isDurable, receiveUpdatesAsInvalidates);
+    for (int i = 0; i < keys.size(); i++) {
+      rie.getInterests().put(keys.get(i), pol);
+    }
+  }
+
+  public void addCq(InternalCqQuery cqi, boolean isDurable)
+  {
+    this.cqs.put(cqi, Boolean.valueOf(isDurable));
+    /*
+    RegionInterestEntry rie = getRegionInterests(r, InterestType.CQ, false, isDurable);
+      rie.getInterests().put(cqi.getName(), cqi);
+      */
+  }
+  
+  public void removeCq(InternalCqQuery cqi, boolean isDurable)
+  {
+    this.cqs.remove(cqi);
+    /*
+    RegionInterestEntry rie = getRegionInterests(r, InterestType.CQ, false, isDurable);
+      rie.getInterests().remove(cqi.getName());
+      */
+  }
+
+  public Map getCqsMap(){
+    return this.cqs;
+  }
+  
+  /**
+   * Unregisters everything registered on the given region name
+   */
+  public void unregisterRegion(ServerRegionProxy srp,
+                               boolean keepalive) {
+    removeAllInterests(srp, InterestType.KEY, false, keepalive, false);
+    removeAllInterests(srp, InterestType.FILTER_CLASS, false, keepalive, false);
+    removeAllInterests(srp, InterestType.OQL_QUERY, false, keepalive, false);
+    removeAllInterests(srp, InterestType.REGULAR_EXPRESSION, false, keepalive, false);
+    removeAllInterests(srp, InterestType.KEY, false, keepalive, true);
+    removeAllInterests(srp, InterestType.FILTER_CLASS, false, keepalive, true);
+    removeAllInterests(srp, InterestType.OQL_QUERY, false, keepalive, true);
+    removeAllInterests(srp, InterestType.REGULAR_EXPRESSION, false, keepalive, true);
+    //durable
+    if (srp.getPool().isDurableClient()) {
+      removeAllInterests(srp, InterestType.KEY, true, keepalive, true);
+      removeAllInterests(srp, InterestType.FILTER_CLASS, true, keepalive, true);
+      removeAllInterests(srp, InterestType.OQL_QUERY, true, keepalive, true);
+      removeAllInterests(srp, InterestType.REGULAR_EXPRESSION, true, keepalive, true);
+      removeAllInterests(srp, InterestType.KEY, true, keepalive, false);
+      removeAllInterests(srp, InterestType.FILTER_CLASS, true, keepalive, false);
+      removeAllInterests(srp, InterestType.OQL_QUERY, true, keepalive, false);
+      removeAllInterests(srp, InterestType.REGULAR_EXPRESSION, true, keepalive, false);
+    }
+  }
+  
+  /**
+   * Remove all interests of a given type on the given proxy's region.
+   * @param interestType
+   *          the interest type
+   * @param durable
+   *          a boolean stating whether to remove durable or non-durable registrations
+   */
+  private void removeAllInterests(ServerRegionProxy srp, int interestType,
+      boolean durable, boolean keepAlive, boolean receiveUpdatesAsInvalidates)
+  {
+    String regName = srp.getRegionName();
+    ConcurrentMap allInterests = getRegionToInterestsMap(interestType, durable, receiveUpdatesAsInvalidates);
+    if (allInterests.remove(regName) != null) {
+      if (logger.isDebugEnabled()) {
+        logger.debug("removeAllInterests region={} type={}", regName, InterestType.getString(interestType));
+      }
+      try {
+        // fix bug 35680 by using a UnregisterAllInterest token
+        Object key = UnregisterAllInterest.singleton();
+        // we have already cleaned up the tracker so send the op directly
+        UnregisterInterestOp.execute(srp.getPool(), regName, key, interestType,
+                                     true/*isClosing*/, keepAlive);
+      }
+      catch (Exception e) {
+        if(srp.getPool().getCancelCriterion().cancelInProgress() == null) {
+          logger.warn(LocalizedMessage.create(
+              LocalizedStrings.RegisterInterestTracker_PROBLEM_REMOVING_ALL_INTEREST_ON_REGION_0_INTERESTTYPE_1_2,
+              new Object[] {regName, InterestType.getString(interestType), e.getLocalizedMessage()}));
+        }
+      }
+    }
+  }
+
+  public boolean removeInterestList(LocalRegion r, List keys, boolean isDurable,
+      boolean receiveUpdatesAsInvalidates)
+  {
+    RegionInterestEntry rie = getRegionInterests(r, InterestType.KEY, true,
+        isDurable, receiveUpdatesAsInvalidates);
+    if (rie == null) {
+      return false;
+    }
+    if (logger.isDebugEnabled()) {
+      logger.debug("removeInterestList region={} keys={}", r.getFullPath(), keys);
+    }
+    int removeCount = 0;
+    for (int i = 0; i < keys.size(); i++) {
+      Object key = keys.get(i);
+      Object interest = rie.getInterests().remove(key);
+      if (interest != null) {
+        removeCount++;
+      }
+      else {
+        logger.warn(LocalizedMessage.create(
+            LocalizedStrings.RegisterInterestTracker_REMOVEINTERESTLIST_KEY_0_NOT_REGISTERED_IN_THE_CLIENT,
+            key));
+      }
+    }
+    return removeCount != 0;
+  }
+
+  /**
+   * Return keys of interest for a given region. The keys in this Map are the
+   * full names of the regions. The values are instances of RegionInterestEntry.
+   *
+   * @param interestType
+   *          the type to return
+   * @return the map
+   */
+  public ConcurrentMap getRegionToInterestsMap(int interestType, boolean isDurable,
+      boolean receiveUpdatesAsInvalidates)
+  {
+    FailoverInterestList fil =
+      this.fils[getInterestLookupIndex(isDurable, receiveUpdatesAsInvalidates)];
+    
+    ConcurrentMap mapOfInterest = null;
+    
+    switch (interestType) {
+    case InterestType.KEY:
+      mapOfInterest = fil.keysOfInterest;
+      break;
+    case InterestType.REGULAR_EXPRESSION:
+      mapOfInterest = fil.regexOfInterest;
+      break;
+    case InterestType.FILTER_CLASS:
+      mapOfInterest = fil.filtersOfInterest;
+      break;
+    case InterestType.CQ:
+      mapOfInterest = fil.cqsOfInterest;
+      break;
+    case InterestType.OQL_QUERY:
+      mapOfInterest = fil.queriesOfInterest;
+      break;
+    default:
+      throw new InternalGemFireError("Unknown interestType");
+    }
+    return mapOfInterest;
+  }
+
+  /**
+   * Return the RegionInterestEntry for the given region. Create one if none
+   * exists and forRemoval is false.
+   *
+   * @param r
+   *          specified region
+   * @param interestType
+   *          desired interest type
+   * @param forRemoval
+   *          true if calls wants one for removal
+   * @return the entry or null if none exists and forRemoval is true.
+   */
+  private RegionInterestEntry getRegionInterests(LocalRegion r,
+                                                 int interestType,
+                                                 boolean forRemoval,
+                                                 boolean isDurable,
+                                                 boolean receiveUpdatesAsInvalidates)
+  {
+    final String regionName = r.getFullPath();
+    ConcurrentMap mapOfInterest = getRegionToInterestsMap(interestType, isDurable, receiveUpdatesAsInvalidates);
+    RegionInterestEntry result = (RegionInterestEntry)
+      mapOfInterest.get(regionName);
+    if (result == null && !forRemoval) {
+      RegionInterestEntry rie = new RegionInterestEntry(r);
+      result = (RegionInterestEntry)mapOfInterest.putIfAbsent(regionName, rie);
+      if (result == null) {
+        result = rie;
+      }
+    }
+    return result;
+  }
+  private RegionInterestEntry readRegionInterests(String regionName,
+                                                  int interestType,
+                                                  boolean isDurable,
+                                                  boolean receiveUpdatesAsInvalidates)
+  {
+    ConcurrentMap mapOfInterest = getRegionToInterestsMap(interestType, isDurable, receiveUpdatesAsInvalidates);
+    return (RegionInterestEntry)mapOfInterest.get(regionName);
+  }
+
+  /**
+   * A Holder object for client's register interest, this is required when 
+   * a client fails over to another server and does register interest based on 
+   * this Data structure 
+   * 
+   * @author Yogesh Mahajan
+   * @since 5.5
+   *
+   */
+   static protected class FailoverInterestList {
+    /**
+     * Record of enumerated keys of interest.
+     *
+     * This list is maintained here in case an endpoint (server) bounces. In that
+     * case, a message will be sent to the endpoint as soon as it has restarted.
+     *
+     * The keys in this Map are the full names of the regions. The values are
+     * instances of {@link RegionInterestEntry}.
+     */
+    final ConcurrentMap keysOfInterest = new ConcurrentHashMap();
+
+    /**
+     * Record of regular expression keys of interest.
+     *
+     * This list is maintained here in case an endpoint (server) bounces. In that
+     * case, a message will be sent to the endpoint as soon as it has restarted.
+     *
+     * The keys in this Map are the full names of the regions. The values are
+     * instances of {@link RegionInterestEntry}.
+     */
+     final ConcurrentMap regexOfInterest = new ConcurrentHashMap();
+
+    /**
+     * Record of filtered keys of interest.
+     *
+     * This list is maintained here in case an endpoint (server) bounces. In that
+     * case, a message will be sent to the endpoint as soon as it has restarted.
+     *
+     * The keys in this Map are the full names of the regions. The values are
+     * instances of {@link RegionInterestEntry}.
+     */
+     final ConcurrentMap filtersOfInterest = new ConcurrentHashMap();
+
+    /**
+     * Record of QOL keys of interest.
+     *
+     * This list is maintained here in case an endpoint (server) bounces. In that
+     * case, a message will be sent to the endpoint as soon as it has restarted.
+     *
+     * The keys in this Map are the full names of the regions. The values are
+     * instances of {@link RegionInterestEntry}.
+     */
+     final ConcurrentMap queriesOfInterest = new ConcurrentHashMap();
+     
+     /**
+      * Record of registered CQs
+      *
+      */
+      final ConcurrentMap cqsOfInterest = new ConcurrentHashMap();
+  }
+
+  /**
+   * Description of the interests of a particular region.
+   *
+   * @author jpenney
+   *
+   */
+  static public class RegionInterestEntry
+  {
+    private final LocalRegion region;
+
+    private final ConcurrentMap interests;
+
+    RegionInterestEntry(LocalRegion r) {
+      this.region = r;
+      this.interests = new ConcurrentHashMap();
+    }
+
+    public LocalRegion getRegion() {
+      return this.region;
+    }
+
+    public ConcurrentMap getInterests() {
+      return this.interests;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RemoveAllOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RemoveAllOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RemoveAllOp.java
new file mode 100644
index 0000000..b4bf64d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RemoveAllOp.java
@@ -0,0 +1,382 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.DataPolicy;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.client.ServerOperationException;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.cache.EventID;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.cache.PutAllPartialResultException;
+import com.gemstone.gemfire.internal.cache.PutAllPartialResultException.PutAllPartialResult;
+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.VersionedObjectList;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * Does a region removeAll on a server
+ * @author darrel
+ * @since 8.1
+ */
+public class RemoveAllOp {
+  
+  public static final Logger logger = LogService.getLogger();
+  
+  public static final int FLAG_EMPTY = 0x01;
+  public static final int FLAG_CONCURRENCY_CHECKS = 0x02;
+
+  
+  /**
+   * Does a region removeAll 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 removeAll on
+   * @param keys Collection of keys to remove
+   * @param eventId the event id for this op
+   */
+  public static VersionedObjectList execute(ExecutablePool pool,
+                             Region region,
+                             Collection<Object> keys,
+                             EventID eventId,
+                             boolean isRetry, Object callbackArg)
+  {
+    RemoveAllOpImpl op = new RemoveAllOpImpl(region, keys,
+        eventId, ((PoolImpl)pool).getPRSingleHopEnabled(), callbackArg);
+    op.initMessagePart();
+    if(isRetry) {
+      op.getMessage().setIsRetry();
+    }
+    return (VersionedObjectList)pool.execute(op);
+  }
+  
+  /**
+   * Does a region put 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 removeAll on
+   * @param keys the Collection of keys to remove
+   * @param eventId the event id for this removeAll
+   */
+  public static VersionedObjectList execute(ExecutablePool pool,
+                             Region region,
+                             Collection<Object> keys,
+                             EventID eventId, 
+                             int retryAttempts, Object callbackArg)
+  {
+    final boolean isDebugEnabled = logger.isDebugEnabled();
+    ClientMetadataService cms = ((LocalRegion)region).getCache()
+        .getClientMetadataService();
+
+    Map<ServerLocation, HashSet> serverToFilterMap = cms.getServerToFilterMap(
+        keys, region, true);
+
+    if (serverToFilterMap == null || serverToFilterMap.isEmpty()) {
+      AbstractOp op = new RemoveAllOpImpl(region, keys,
+          eventId, ((PoolImpl)pool).getPRSingleHopEnabled(), callbackArg);
+      op.initMessagePart();
+      return (VersionedObjectList)pool.execute(op);
+    }
+
+    List callableTasks = constructAndGetRemoveAllTasks(region,
+        eventId, serverToFilterMap, (PoolImpl)pool, callbackArg);
+
+    if (isDebugEnabled) {
+      logger.debug("RemoveAllOp#execute : Number of removeAll tasks is :{}", callableTasks.size());
+    }
+    HashMap<ServerLocation, RuntimeException> failedServers = new HashMap<ServerLocation,RuntimeException>();
+    PutAllPartialResult result = new PutAllPartialResult(keys.size());
+    try {
+      Map<ServerLocation, Object> results = SingleHopClientExecutor
+          .submitBulkOp(callableTasks, cms, (LocalRegion)region, failedServers);
+      for (Map.Entry<ServerLocation, Object> entry: results.entrySet()) {
+        Object value = entry.getValue();
+        if (value instanceof PutAllPartialResultException) {
+          PutAllPartialResultException pap = (PutAllPartialResultException)value;
+          if (isDebugEnabled) {
+            logger.debug("RemoveAll SingleHop encountered BulkOpPartialResultException exception: {}, failedServers are {}", pap, failedServers.keySet());
+          }
+          result.consolidate(pap.getResult());
+        } else {
+          if (value != null) {
+            VersionedObjectList list = (VersionedObjectList)value;
+            result.addKeysAndVersions(list);
+          }
+        }
+      }
+    } catch (RuntimeException ex) {
+      logger.debug("single-hop removeAll encountered unexpected exception: {}",ex);
+        throw ex;
+      }
+
+    if (!failedServers.isEmpty()) {
+      if (retryAttempts == 0) {
+        throw failedServers.values().iterator().next();
+      }
+
+      // if the partial result set doesn't already have keys (for tracking version tags)
+      // then we need to gather up the keys that we know have succeeded so far and
+      // add them to the partial result set
+      if (result.getSucceededKeysAndVersions().size() == 0) {
+        // if there're failed servers, we need to save the succeed keys in submitRemoveAll
+        // if retry succeeded, everything is ok, otherwise, the saved "succeeded
+        // keys" should be consolidated into PutAllPartialResultException
+      // succeedKeySet is used to send back to client in PartialResult case
+      // so it's not a must to use LinkedHashSet
+      Set succeedKeySet = new LinkedHashSet();
+      Set<ServerLocation> serverSet = serverToFilterMap.keySet();
+      for (ServerLocation server : serverSet) {
+        if (!failedServers.containsKey(server)) {
+          succeedKeySet.addAll(serverToFilterMap.get(server));
+        }
+      }
+  
+      // save succeedKeys, but if retries all succeeded, discard the PutAllPartialResult
+        result.addKeys(succeedKeySet);
+      }
+      
+      // send maps for the failed servers one by one instead of merging 
+      // them into one big map. The reason is, we have to keep the same event
+      // ids for each sub map. There is a unit test in PutAllCSDUnitTest for
+      // the otherwise case.
+      boolean oneSubMapRetryFailed = false;
+      Set<ServerLocation> failedServerSet = failedServers.keySet();
+      for (ServerLocation failedServer : failedServerSet) {
+        //        Throwable failedServers.values().iterator().next();
+        RuntimeException savedRTE = failedServers.get(failedServer);
+        if (savedRTE instanceof PutAllPartialResultException) {
+          // will not retry for BulkOpPartialResultException
+          // but it means at least one sub map ever failed 
+          oneSubMapRetryFailed = true;
+          continue;
+        }
+        Collection<Object> newKeys = serverToFilterMap.get(failedServer);
+        try {
+          VersionedObjectList v = RemoveAllOp.execute(pool, region, newKeys, eventId, true, callbackArg);
+          if (v == null) {
+            result.addKeys(newKeys);
+          } else {
+            result.addKeysAndVersions(v);
+          }
+        } catch (PutAllPartialResultException pre) {
+          oneSubMapRetryFailed = true;
+          logger.debug("Retry failed with BulkOpPartialResultException: {} Before retry: {}", pre, result.getKeyListString());
+          result.consolidate(pre.getResult());
+        } catch (Exception rte) {
+          oneSubMapRetryFailed = true;
+          Object firstKey = newKeys.iterator().next();
+          result.saveFailedKey(firstKey, rte);
+        }
+      } // for failedServer
+
+      // If all retries succeeded, the PRE in first tries can be ignored
+      if (oneSubMapRetryFailed && result.hasFailure()) {
+        PutAllPartialResultException pre = new PutAllPartialResultException(result);
+        throw pre;
+      }
+    } // failedServers!=null
+
+    return result.getSucceededKeysAndVersions();
+  }
+  
+  private RemoveAllOp() {
+    // no instances allowed
+  }
+  
+  
+  static List constructAndGetRemoveAllTasks(Region region,
+      final EventID eventId, 
+      final Map<ServerLocation, HashSet> serverToFilterMap,
+      final PoolImpl pool, Object callbackArg) {
+    final List<SingleHopOperationCallable> tasks = new ArrayList<SingleHopOperationCallable>();
+    ArrayList<ServerLocation> servers = new ArrayList<ServerLocation>(
+        serverToFilterMap.keySet());
+
+    if (logger.isDebugEnabled()) {
+      logger.debug("Constructing tasks for the servers{}", servers);
+    }
+    for (ServerLocation server : servers) {
+      AbstractOp RemoveAllOp = new RemoveAllOpImpl(region,
+          serverToFilterMap.get(server), eventId, true, callbackArg);
+
+      SingleHopOperationCallable task = new SingleHopOperationCallable(
+          new ServerLocation(server.getHostName(), server.getPort()), pool,
+          RemoveAllOp,UserAttributes.userAttributes.get());
+      tasks.add(task);
+    }
+    return tasks;
+  }
+
+  private static class RemoveAllOpImpl extends AbstractOp {
+    
+    private boolean prSingleHopEnabled = false;
+    
+    private LocalRegion region = null;
+    
+    private Collection<Object> keys = null;
+    private final Object callbackArg;
+    
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public RemoveAllOpImpl(Region region, Collection<Object> keys,
+        EventID eventId, boolean prSingleHopEnabled, Object callbackArg) {
+      super(MessageType.REMOVE_ALL, 5 + keys.size());
+      this.prSingleHopEnabled = prSingleHopEnabled;
+      this.region = (LocalRegion)region;
+      getMessage().addStringPart(region.getFullPath());
+      getMessage().addBytesPart(eventId.calcBytes());
+      this.keys = keys;
+      this.callbackArg = callbackArg;
+    }
+    
+    @Override
+    protected void initMessagePart() {
+      int size = keys.size();
+      int flags = 0;
+      if (region.getDataPolicy() == DataPolicy.EMPTY) {
+        flags |= FLAG_EMPTY;
+      }
+      if (region.getConcurrencyChecksEnabled()) {
+        flags |= FLAG_CONCURRENCY_CHECKS;
+      }
+      getMessage().addIntPart(flags);
+      getMessage().addObjPart(this.callbackArg);
+      getMessage().addIntPart(size);
+
+      for (Object key: this.keys) {
+        getMessage().addStringOrObjPart(key);
+      }      
+    }
+    @Override  
+    protected Message createResponseMessage() {
+      return new ChunkedMessage(2, Version.CURRENT);
+    }
+    
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      throw new UnsupportedOperationException();
+    }
+    
+    @Override
+    protected Object processResponse(final Message msg, final Connection con) throws Exception {
+      final VersionedObjectList result = new VersionedObjectList();
+      final Exception[] exceptionRef = new Exception[1];
+      final boolean isDebugEnabled = logger.isDebugEnabled();
+      try {
+        processChunkedResponse((ChunkedMessage)msg,
+                             "removeAll",
+                             new ChunkHandler() {
+                               public void handle(ChunkedMessage cm) throws Exception {
+                                 int numParts = msg.getNumberOfParts();
+                                 if (isDebugEnabled) {
+                                   logger.debug("RemoveAllOp.processChunkedResponse processing message with {} parts", numParts);
+                                 }
+                                 for (int partNo=0; partNo < numParts; partNo++) {
+                                   Part part = cm.getPart(partNo);
+                                   try {
+                                     Object o = part.getObject();
+                                     if (isDebugEnabled) {
+                                       logger.debug("part({}) contained {}", partNo, o);
+                                     }
+                                     if (o == null) {
+                                       // no response is an okay response
+                                     } else if (o instanceof byte[]) {
+                                       if (prSingleHopEnabled) {
+                                         byte[] bytesReceived = part.getSerializedForm();
+                                         if (/*bytesReceived.length==1 &&*/ bytesReceived[0] != ClientMetadataService.INITIAL_VERSION) { // nw hop
+                                           if (region != null) {
+                                             ClientMetadataService cms;
+                                             try {
+                                               cms = region.getCache().getClientMetadataService();
+                                               cms.scheduleGetPRMetaData(region, false,bytesReceived[1]);
+                                             }
+                                             catch (CacheClosedException e) {
+                                             }
+                                           }
+                                         }
+                                       }
+                                     } else if (o instanceof Throwable) {
+                                       String s = "While performing a remote removeAll";
+                                       exceptionRef[0] = new ServerOperationException(s, (Throwable)o);
+                                     } else {
+                                       VersionedObjectList chunk = (VersionedObjectList)o;
+                                       chunk.replaceNullIDs(con.getEndpoint().getMemberId());
+                                       result.addAll(chunk);
+                                     }
+                                   } catch(Exception e) {
+                                     exceptionRef[0] = new ServerOperationException("Unable to deserialize value" , e);
+                                   }
+                                 }
+                               }
+                             });
+      } catch (ServerOperationException e) {
+        if (e.getCause() instanceof PutAllPartialResultException) {
+          PutAllPartialResultException cause = (PutAllPartialResultException)e.getCause(); 
+          cause.getSucceededKeysAndVersions().replaceNullIDs(con.getEndpoint().getMemberId());
+          throw cause;
+        } else {
+          throw e;
+        }
+      }
+      if (exceptionRef[0] != null) {
+        throw exceptionRef[0];
+      } else {
+        // v7.0.1: fill in the keys
+        if (result.hasVersions() && result.getKeys().isEmpty()) {
+          if (logger.isTraceEnabled()) {
+            logger.trace("setting keys of response to {}", this.keys);
+          }
+          ArrayList<Object> tmpKeys;
+          if (this.keys instanceof ArrayList) {
+            tmpKeys = (ArrayList<Object>) this.keys;
+          } else {
+            tmpKeys = new ArrayList<Object>(this.keys);
+          }
+          result.setKeys(tmpKeys);
+        }
+      }
+      return result;
+    }
+    
+    @Override
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.PUT_DATA_ERROR;
+    }
+
+    @Override
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startRemoveAll();
+    }
+    @Override
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endRemoveAllSend(start, hasFailed());
+    }
+    @Override
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endRemoveAll(start, hasTimedOut(), hasFailed());
+    }
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RollbackOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RollbackOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RollbackOp.java
new file mode 100644
index 0000000..35c4494
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/RollbackOp.java
@@ -0,0 +1,90 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().send(false);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ServerBlackList.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ServerBlackList.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ServerBlackList.java
new file mode 100644
index 0000000..aec202d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ServerBlackList.java
@@ -0,0 +1,179 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.cache.client.internal.PoolImpl.PoolTask;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * This class is designed to prevent the client from spinning
+ * and reconnected to the same failed server over and over.
+ * We've removed the old dead server monitor code because
+ * the locator is supposed to keep track of what servers are
+ * alive or dead. However, there is still the possibility that the locator
+ * may tell us a server is alive but we are unable to reach it. 
+ * 
+ * This class keeps track of the number of consecutive failures
+ * that happen to on each server. If the number of failures exceeds the limit,
+ * the server is added to a blacklist for a certain period of time. After
+ * the time is expired, the server comes off the blacklist, but the next
+ * failure will put the server back on the list for a longer period of time.
+ * 
+ * @author dsmith
+ *
+ */
+public class ServerBlackList {
+  
+  private static final Logger logger = LogService.getLogger();
+  
+  private final Map/*<ServerLocation, AI>*/ failureTrackerMap = new HashMap();
+  protected final Set blacklist = new CopyOnWriteArraySet();
+  private final Set unmodifiableBlacklist = Collections.unmodifiableSet(blacklist);
+  protected ScheduledExecutorService background;
+  protected final ListenerBroadcaster broadcaster = new ListenerBroadcaster();
+  
+  //not final for tests.
+  static int THRESHOLD = Integer.getInteger("gemfire.ServerBlackList.THRESHOLD", 3).intValue();
+  protected final long pingInterval;
+  
+  public ServerBlackList(long pingInterval) {
+    this.pingInterval = pingInterval;
+  }
+  
+  public void start(ScheduledExecutorService background) {
+    this.background = background;
+  }
+  
+  FailureTracker getFailureTracker(ServerLocation location) {
+    FailureTracker failureTracker;
+    synchronized(failureTrackerMap) {
+      failureTracker = (FailureTracker) failureTrackerMap.get(location);
+      if(failureTracker == null) {
+        failureTracker = new FailureTracker(location);
+        failureTrackerMap.put(location, failureTracker);
+      }
+    }
+    
+    return failureTracker;
+  }
+  
+  public Set getBadServers() {
+    return unmodifiableBlacklist;
+  }
+  
+  public class FailureTracker {
+    private final AtomicInteger consecutiveFailures = new AtomicInteger();
+    private final ServerLocation location;
+    
+    public FailureTracker(ServerLocation location) {
+      this.location = location;
+    }
+    
+    public void reset() {
+      consecutiveFailures.set(0);
+    }
+    
+    public void addFailure() {
+      if(blacklist.contains(location)) {
+        //A second failure must have happened before we added
+        //this server to the blacklist. Don't count that failure.
+        return;
+      }
+      long failures = consecutiveFailures.incrementAndGet();
+      if(failures >= THRESHOLD) {
+        if(logger.isDebugEnabled()) {
+          logger.debug("Blacklisting server {} for {}ms because it had {} consecutive failures", location, pingInterval, failures);
+        }
+        blacklist.add(location);
+        broadcaster.serverAdded(location);
+        try {
+          background.schedule(new ExpireBlackListTask(location), pingInterval, TimeUnit.MILLISECONDS);
+        } catch(RejectedExecutionException e) {
+          //ignore, the timer has been cancelled, which means we're shutting down.
+        }
+        
+      }
+    }
+  }
+  
+  public void addListener(BlackListListener blackListListener) {
+    broadcaster.listeners.add(blackListListener);
+  }
+  
+  public void removeListener(BlackListListener blackListListener) {
+    broadcaster.listeners.remove(blackListListener);
+  }
+  
+
+  
+  private class ExpireBlackListTask extends PoolTask {
+    private ServerLocation location;
+
+    public ExpireBlackListTask(ServerLocation location) {
+      this.location = location;
+    }
+    
+    @Override
+    public void run2() {
+      if(logger.isDebugEnabled()) {
+        logger.debug("{} is no longer blacklisted", location);
+      }
+      blacklist.remove(location);
+      broadcaster.serverRemoved(location);
+    }
+  }
+  
+  public static interface BlackListListener { 
+    public void serverAdded(ServerLocation location);
+    
+    public void serverRemoved(ServerLocation location);
+  }
+  
+  public static class BlackListListenerAdapter implements BlackListListener {
+    public void serverAdded(ServerLocation location) {
+      //do nothing
+    }
+
+    public void serverRemoved(ServerLocation location) {
+      //do nothing      
+    }
+  }
+  
+  protected static class ListenerBroadcaster implements BlackListListener {
+    
+    protected Set listeners = new CopyOnWriteArraySet();
+
+    public void serverAdded(ServerLocation location) {
+      for(Iterator itr = listeners.iterator(); itr.hasNext(); ) {
+        BlackListListener listener = (BlackListListener) itr.next();
+        listener.serverAdded(location);
+      }
+    }
+
+    public void serverRemoved(ServerLocation location) {
+      for(Iterator itr = listeners.iterator(); itr.hasNext(); ) {
+        BlackListListener listener = (BlackListListener) itr.next();
+        listener.serverRemoved(location);
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ServerProxy.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ServerProxy.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ServerProxy.java
new file mode 100644
index 0000000..a428e01
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ServerProxy.java
@@ -0,0 +1,60 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.List;
+
+import com.gemstone.gemfire.cache.query.SelectResults;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+
+/**
+ * Used to send operations from a client to a server.
+ * @author darrel
+ * @since 5.7
+ */
+public class ServerProxy {
+  protected final InternalPool pool;
+  /**
+   * Creates a server proxy for the given pool.
+   * @param pool the pool that this proxy will use to communicate with servers
+   */
+  public ServerProxy(InternalPool pool) {
+    this.pool = pool;
+  }
+  /**
+   * Returns the pool the proxy is using.
+   */
+  public InternalPool getPool() {
+    return this.pool;
+  }
+  /**
+   * Release use of this pool
+   */
+  public void detach() {
+    this.pool.detach();
+  }
+
+  /**
+   * Ping the specified server to see if it is still alive
+   * @param server the server to do the execution on
+   */
+  public void ping(ServerLocation server) {
+    PingOp.execute(this.pool, server);
+  }
+  /**
+   * Does a query on a server
+   * @param queryPredicate A query language boolean query predicate
+   * @return  A <code>SelectResults</code> containing the values
+   *            that match the <code>queryPredicate</code>.
+   */
+  public SelectResults query(String queryPredicate, Object[] queryParams)
+  {
+    return QueryOp.execute(this.pool, queryPredicate, queryParams);
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ServerRegionDataAccess.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ServerRegionDataAccess.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ServerRegionDataAccess.java
new file mode 100644
index 0000000..0787a03
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ServerRegionDataAccess.java
@@ -0,0 +1,134 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.gemstone.gemfire.cache.Operation;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.Region.Entry;
+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.tier.sockets.VersionedObjectList;
+import com.gemstone.gemfire.internal.cache.tx.TransactionalOperation;
+
+public interface ServerRegionDataAccess {
+
+  /**
+   * Does a get on the server
+   * @param key the entry key to do the get on
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   * @param clientEvent the client event, if any, for version propagation
+   * @return the entry value found by the get if any
+   */
+  public abstract Object get(Object key, Object callbackArg, EntryEventImpl clientEvent);
+
+  /**
+   * Does a region put on the server
+   * @param key the entry key to do the put on
+   * @param value the entry value to put
+   * @param clientEvent the client event, if any, for eventID and version tag propagation
+   * @param op the operation type of this event
+   * @param requireOldValue
+   * @param expectedOldValue
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   * @param isCreateFwd
+   */
+  public abstract Object put(Object key, Object value, byte[] deltaBytes, EntryEventImpl clientEvent,
+      Operation op, boolean requireOldValue, Object expectedOldValue,
+      Object callbackArg, boolean isCreateFwd);
+
+
+  /**
+   * Does a region entry destroy on the server
+   * @param key the entry key to do the destroy on
+   * @param expectedOldValue the value that must be associated with the entry, or null
+   * @param operation the operation being performed (Operation.DESTROY, Operation.REMOVE)
+   * @param clientEvent the client event, if any, for version propagation
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   */
+  public abstract Object destroy(Object key, Object expectedOldValue,
+      Operation operation, EntryEventImpl clientEvent, Object callbackArg);
+
+  
+  /**
+   * Does a region entry invalidate on the server
+   * @param event the entryEventImpl that represents the invalidate
+   */
+  public abstract void invalidate(EntryEventImpl event);
+  
+  
+  /**
+   * Does a region clear on the server
+   * @param eventId the event id for this clear
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   */
+  public abstract void clear(EventID eventId, Object callbackArg);
+
+
+  /**
+   * Does a region containsKey on a server
+   * @param key the entry key to do the containsKey on
+   */
+  public abstract boolean containsKey(Object key);
+
+  /**
+   * Does a region containsKey on a server
+   * @param key the entry key to do the containsKey on
+   */
+  public abstract boolean containsValueForKey(Object key);
+  
+  
+  /**
+   * Does a region containsValue on a server
+   * @param value the entry value to search for
+   */
+  public boolean containsValue(Object value);
+
+  
+  /**
+   * Does a region keySet on a server
+   */
+  public abstract Set keySet();
+
+  public abstract VersionedObjectList putAll(Map map, EventID eventId, boolean skipCallbacks, Object callbackArg);
+
+  public abstract VersionedObjectList removeAll(Collection<Object> keys, EventID eventId, Object callbackArg);
+
+  public abstract VersionedObjectList getAll(List keys, Object callback);
+  
+  public int size();
+
+  /**
+   * gets an entry from the server, does not invoke loaders
+   * @param key
+   * @return an {@link EntrySnapshot} for the given key
+   */
+  public Entry getEntry(Object key);
+//  public boolean containsValue(Object value);
+//  public Set entries(boolean recursive) {
+//  public void invalidate(Object key) throws TimeoutException,
+//  public int size()
+
+  /**
+   * returns the name of the region to which this interface provides access
+   */
+  public String getRegionName();
+  
+  /**
+   * returns the region to which this interface provides access.  This may be
+   * null in an admin system
+   */
+  public Region getRegion();
+
+
+}
\ No newline at end of file


[11/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteFunctionOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteFunctionOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteFunctionOp.java
new file mode 100755
index 0000000..deefb4c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteFunctionOp.java
@@ -0,0 +1,644 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import com.gemstone.gemfire.InternalGemFireError;
+import com.gemstone.gemfire.cache.client.ServerConnectivityException;
+import com.gemstone.gemfire.cache.client.ServerOperationException;
+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.distributed.DistributedMember;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.execute.AbstractExecution;
+import com.gemstone.gemfire.internal.cache.execute.FunctionStats;
+import com.gemstone.gemfire.internal.cache.execute.InternalFunctionException;
+import com.gemstone.gemfire.internal.cache.execute.InternalFunctionInvocationTargetException;
+import com.gemstone.gemfire.internal.cache.execute.MemberMappedArgument;
+import com.gemstone.gemfire.internal.cache.execute.ServerFunctionExecutor;
+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.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.logging.log4j.Logger;
+
+/**
+ * Executes the function on server (possibly without region/cache).<br> 
+ * Also gets the result back from the server
+ * @author Suranjan Kumar
+ * @since 5.8
+ */
+
+public class ExecuteFunctionOp {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  /** index of allMembers in flags[] */
+  public static final int ALL_MEMBERS_INDEX = 0;
+  /** index of ignoreFailedMembers in flags[] */
+  public static final int IGNORE_FAILED_MEMBERS_INDEX = 1;
+
+  private ExecuteFunctionOp() {
+    // no instances allowed
+  }
+  
+  /**
+   * Does a execute Function 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 function of the function to be executed
+   * @param args specified arguments to the application function
+   */
+  public static void execute(final PoolImpl pool, Function function,
+      ServerFunctionExecutor executor, Object args,
+      MemberMappedArgument memberMappedArg, boolean allServers, byte hasResult,
+      ResultCollector rc, boolean isFnSerializationReqd,
+      UserAttributes attributes, String[] groups) {
+    final AbstractOp op = new ExecuteFunctionOpImpl(function, args,
+        memberMappedArg, hasResult, rc, isFnSerializationReqd, (byte)0, groups, allServers, executor.isIgnoreDepartedMembers());
+
+    if (allServers && groups.length == 0) {
+      if (logger.isDebugEnabled()) {
+        logger.debug("ExecuteFunctionOp#execute : Sending Function Execution Message:{} to all servers using pool: {}", op.getMessage(), pool);
+      }
+      List callableTasks = constructAndGetFunctionTasks(pool, function, args,
+          memberMappedArg, hasResult, rc, isFnSerializationReqd, attributes);
+
+      SingleHopClientExecutor.submitAll(callableTasks);
+    } else {
+      boolean reexecuteForServ = false;
+      AbstractOp reexecOp = null;
+      int retryAttempts = 0;
+      boolean reexecute = false;
+      int maxRetryAttempts = 0;
+      if(function.isHA())
+        maxRetryAttempts = pool.getRetryAttempts();
+      
+      final boolean isDebugEnabled = logger.isDebugEnabled();
+      do {
+        try {
+          if (reexecuteForServ) {
+            if (isDebugEnabled) {
+              logger.debug("ExecuteFunctionOp#execute.reexecuteForServ : Sending Function Execution Message:{} to server using pool: {} with groups:{} all members:{} ignoreFailedMembers:{}", op.getMessage(), pool, Arrays.toString(groups), allServers, executor.isIgnoreDepartedMembers());
+            }
+            reexecOp = new ExecuteFunctionOpImpl(function, args,
+                memberMappedArg, hasResult, rc, isFnSerializationReqd,
+                (byte)1/* isReExecute */, groups, allServers, executor.isIgnoreDepartedMembers());
+            pool.execute(reexecOp, 0);
+          } else {
+            if (isDebugEnabled) {
+              logger.debug("ExecuteFunctionOp#execute : Sending Function Execution Message:{} to server using pool: {} with groups:{} all members:{} ignoreFailedMembers:{}", op.getMessage(), pool, Arrays.toString(groups), allServers, executor.isIgnoreDepartedMembers());
+            }
+
+            pool.execute(op, 0);
+          }
+          reexecute = false;
+          reexecuteForServ = false;
+        } catch (InternalFunctionInvocationTargetException e) {
+          if (isDebugEnabled) {
+            logger.debug("ExecuteFunctionOp#execute : Received InternalFunctionInvocationTargetException. The failed node is {}", e.getFailedNodeSet());
+          }
+          reexecute = true;
+          rc.clearResults();
+        } catch (ServerConnectivityException se) {
+          retryAttempts++;
+
+          if (isDebugEnabled) {
+            logger.debug("ExecuteFunctionOp#execute : Received ServerConnectivityException. The exception is {} The retryAttempt is : {} maxRetryAttempts  {}", se, retryAttempts, maxRetryAttempts);
+          }
+          if (se instanceof ServerOperationException) {
+            throw se;
+          }
+          if ((retryAttempts > maxRetryAttempts && maxRetryAttempts != -1))
+            throw se;
+
+          reexecuteForServ = true;
+          rc.clearResults();
+        }
+      } while (reexecuteForServ);
+
+      if (reexecute && function.isHA()) {
+        ExecuteFunctionOp.reexecute(pool, function,
+            executor, rc, hasResult, isFnSerializationReqd, maxRetryAttempts - 1, groups, allServers);
+      }
+    }
+  }
+  
+  public static void execute(final PoolImpl pool, String functionId,
+      ServerFunctionExecutor executor, Object args,
+      MemberMappedArgument memberMappedArg, boolean allServers, byte hasResult,
+      ResultCollector rc, boolean isFnSerializationReqd, boolean isHA,
+      boolean optimizeForWrite, UserAttributes properties, String[] groups) {
+    final AbstractOp op = new ExecuteFunctionOpImpl(functionId, args,
+        memberMappedArg, hasResult, rc, isFnSerializationReqd, isHA,
+        optimizeForWrite, (byte)0, groups, allServers, executor.isIgnoreDepartedMembers());
+    if (allServers && groups.length == 0) {
+      if (logger.isDebugEnabled()) {
+        logger.debug("ExecuteFunctionOp#execute : Sending Function Execution Message:{} to all servers using pool: {}", op.getMessage(), pool);
+      }
+      List callableTasks = constructAndGetFunctionTasks(pool, functionId, args,
+          memberMappedArg, hasResult, rc, isFnSerializationReqd, isHA,
+          optimizeForWrite, properties);
+
+      SingleHopClientExecutor.submitAll(callableTasks);
+    } else {
+      boolean reexecuteForServ = false;
+      AbstractOp reexecOp = null;
+      int retryAttempts = 0;
+      boolean reexecute = false;
+      int maxRetryAttempts = 0;
+      if(isHA){
+        maxRetryAttempts = pool.getRetryAttempts();
+      }
+      
+      final boolean isDebugEnabled = logger.isDebugEnabled();
+      do {
+        try {
+          if (reexecuteForServ) {
+            reexecOp = new ExecuteFunctionOpImpl(functionId, args,
+                memberMappedArg, hasResult, rc, isFnSerializationReqd, isHA,
+                optimizeForWrite, (byte)1, groups, allServers, executor.isIgnoreDepartedMembers());
+            pool.execute(reexecOp, 0);
+          } else {
+            if (isDebugEnabled) {
+              logger.debug("ExecuteFunctionOp#execute : Sending Function Execution Message:{} to server using pool:{} with groups:{} all members:{} ignoreFailedMembers:{}", op.getMessage(), pool, Arrays.toString(groups), allServers, executor.isIgnoreDepartedMembers());
+            }
+            pool.execute(op, 0);
+          }
+          reexecute = false;
+          reexecuteForServ = false;
+        } catch (InternalFunctionInvocationTargetException e) {
+          if (isDebugEnabled) {
+            logger.debug("ExecuteFunctionOp#execute : Received InternalFunctionInvocationTargetException. The failed node is {}", e.getFailedNodeSet());
+          }
+          reexecute = true;
+          rc.clearResults();
+        } catch (ServerConnectivityException se) {
+          retryAttempts++;
+
+          if (isDebugEnabled) {
+            logger.debug("ExecuteFunctionOp#execute : Received ServerConnectivityException. The exception is {} The retryAttempt is : {} maxRetryAttempts {}", se, retryAttempts, maxRetryAttempts);
+          }
+          if (se instanceof ServerOperationException) {
+            throw se;
+          }
+          if ((retryAttempts > maxRetryAttempts && maxRetryAttempts != -1))
+            throw se;
+
+          reexecuteForServ = true;
+          rc.clearResults();
+        }
+      } while (reexecuteForServ);
+
+      if (reexecute && isHA) {
+        ExecuteFunctionOp.reexecute(pool, functionId, executor, rc, hasResult,
+            isFnSerializationReqd, maxRetryAttempts - 1, args, isHA,
+            optimizeForWrite, groups, allServers);
+      }
+    }
+  }
+  
+  public static void reexecute(ExecutablePool pool, Function function,
+      ServerFunctionExecutor serverExecutor, ResultCollector resultCollector,
+      byte hasResult, boolean isFnSerializationReqd, int maxRetryAttempts, String[] groups, boolean allMembers) {
+    boolean reexecute = true;
+    int retryAttempts = 0;
+    final boolean isDebugEnabled = logger.isDebugEnabled();
+    do {
+      reexecute = false;
+      AbstractOp reExecuteOp = new ExecuteFunctionOpImpl(function, serverExecutor.getArguments(),
+          serverExecutor.getMemberMappedArgument(), hasResult, resultCollector, isFnSerializationReqd, (byte)1, groups, allMembers, serverExecutor.isIgnoreDepartedMembers());
+      if (isDebugEnabled) {
+        logger.debug("ExecuteFunction#reexecute : Sending Function Execution Message:{} to Server using pool:{} with groups:{} all members:{} ignoreFailedMembers:{}", reExecuteOp.getMessage(), pool, Arrays.toString(groups), allMembers, serverExecutor.isIgnoreDepartedMembers());
+      }
+      try {
+          pool.execute(reExecuteOp,0);
+      }
+      catch (InternalFunctionInvocationTargetException e) {
+        if (isDebugEnabled) {
+          logger.debug("ExecuteFunctionOp#reexecute : Recieved InternalFunctionInvocationTargetException. The failed nodes are {}", e.getFailedNodeSet());
+        }
+        reexecute = true;
+        resultCollector.clearResults();
+      }
+      catch (ServerConnectivityException se) {
+        if (isDebugEnabled) {
+          logger.debug("ExecuteFunctionOp#reexecute : Received ServerConnectivity Exception.");
+        }
+        
+        if(se instanceof ServerOperationException){
+          throw se;
+        }
+        retryAttempts++;
+        if (retryAttempts > maxRetryAttempts && maxRetryAttempts != -2) 
+          throw se;
+
+        reexecute = true;
+        resultCollector.clearResults();
+      }
+    } while (reexecute);
+  }
+  
+  public static void reexecute(ExecutablePool pool, String functionId,
+      ServerFunctionExecutor serverExecutor, ResultCollector resultCollector,
+      byte hasResult, boolean isFnSerializationReqd, int maxRetryAttempts,
+      Object args, boolean isHA, boolean optimizeForWrite, String[] groups, boolean allMembers) {
+    boolean reexecute = true;
+    int retryAttempts = 0;
+    final boolean isDebugEnabled = logger.isDebugEnabled();
+    do {
+      reexecute = false;
+      
+      final AbstractOp op = new ExecuteFunctionOpImpl(functionId, args,
+          serverExecutor.getMemberMappedArgument(), hasResult, resultCollector, isFnSerializationReqd, isHA, optimizeForWrite, (byte)1, groups, allMembers, serverExecutor.isIgnoreDepartedMembers());
+      
+      if (isDebugEnabled) {
+        logger.debug("ExecuteFunction#reexecute : Sending Function Execution Message:{} to Server using pool:{} with groups:{} all members:{} ignoreFailedMembers:{}", op.getMessage(), pool, Arrays.toString(groups), allMembers, serverExecutor.isIgnoreDepartedMembers());
+      }
+      try {
+          pool.execute(op,0);
+      }
+      catch (InternalFunctionInvocationTargetException e) {
+        if (isDebugEnabled) {
+          logger.debug("ExecuteFunctionOp#reexecute : Recieved InternalFunctionInvocationTargetException. The failed nodes are {}", e.getFailedNodeSet());
+        }
+        reexecute = true;
+        resultCollector.clearResults();
+      }
+      catch (ServerConnectivityException se) {
+        if (isDebugEnabled) {
+          logger.debug("ExecuteFunctionOp#reexecute : Received ServerConnectivity Exception.");
+        }
+        
+        if(se instanceof ServerOperationException){
+          throw se;
+        }
+        retryAttempts++;
+        if (retryAttempts > maxRetryAttempts && maxRetryAttempts != -2) 
+          throw se;
+
+        reexecute = true;
+        resultCollector.clearResults();
+      }
+    } while (reexecute);
+  }
+
+  static List constructAndGetFunctionTasks(final PoolImpl pool,
+      final Function function, Object args,
+      MemberMappedArgument memberMappedArg, byte hasResult, ResultCollector rc,
+      boolean isFnSerializationReqd, UserAttributes attributes) {
+    final List<SingleHopOperationCallable> tasks = new ArrayList<SingleHopOperationCallable>();
+    ArrayList<ServerLocation> servers = null;
+    if (pool.getLocators() == null || pool.getLocators().isEmpty()) { 
+      servers = ((ExplicitConnectionSourceImpl)pool.getConnectionSource())
+          .getAllServers();
+    }
+    else {
+      servers = ((AutoConnectionSourceImpl)pool.getConnectionSource())
+          .findAllServers(); // n/w call on locator
+    }
+
+    for (ServerLocation server : servers) {
+      final AbstractOp op = new ExecuteFunctionOpImpl(function,
+          args, memberMappedArg, hasResult, rc, isFnSerializationReqd, (byte)0, null/*onGroups does not use single-hop for now*/, false, false);
+      SingleHopOperationCallable task = new SingleHopOperationCallable(server, pool, op, attributes);
+      tasks.add(task);
+    }
+    return tasks;
+  }
+      
+  static List constructAndGetFunctionTasks(final PoolImpl pool,
+      final String functionId, Object args,
+      MemberMappedArgument memberMappedArg, byte hasResult, ResultCollector rc,
+      boolean isFnSerializationReqd, boolean isHA, boolean optimizeForWrite, UserAttributes properties) {
+    final List<SingleHopOperationCallable> tasks = new ArrayList<SingleHopOperationCallable>();
+    ArrayList<ServerLocation> servers = null;
+    if (pool.getLocators() == null || pool.getLocators().isEmpty()) { 
+      servers = ((ExplicitConnectionSourceImpl)pool.getConnectionSource())
+          .getAllServers();
+    }
+    else {
+      servers = ((AutoConnectionSourceImpl)pool.getConnectionSource())
+          .findAllServers(); // n/w call on locator
+    }
+
+    for (ServerLocation server : servers) {
+      final AbstractOp op = new ExecuteFunctionOpImpl(functionId,
+          args, memberMappedArg, hasResult, rc, isFnSerializationReqd, isHA, optimizeForWrite, (byte)0,null/*onGroups does not use single-hop for now*/, false, false);
+      SingleHopOperationCallable task = new SingleHopOperationCallable(server, pool, op, properties);
+      tasks.add(task);
+    }
+    return tasks;
+  }
+  
+  static byte[] getByteArrayForFlags(boolean... flags) {
+    byte[] retVal = null;
+    if (flags.length > 0) {
+      retVal = new byte[flags.length];
+      for (int i=0; i<flags.length; i++) {
+        if (flags[i]) {
+          retVal[i] = 1;
+        } else {
+          retVal[i] = 0;
+        }
+      }
+    }
+    return retVal;
+  }
+
+  static class ExecuteFunctionOpImpl extends AbstractOp {
+
+    private ResultCollector resultCollector;
+    
+   //To get the instance of the Function Statistics we need the function name or instance
+    private String functionId;
+
+    private Function function;
+
+    private Object args;
+
+    private MemberMappedArgument memberMappedArg;
+
+    private byte hasResult;
+
+    private boolean isFnSerializationReqd;
+
+    private String[] groups;
+
+    /**
+     * [0] = allMembers
+     * [1] = ignoreFailedMembers
+     */
+    private byte[] flags;
+
+    /**
+     * number of parts in the request message
+     */
+    private static final int MSG_PARTS = 6;
+
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public ExecuteFunctionOpImpl(Function function, Object args,
+        MemberMappedArgument memberMappedArg, byte hasResult,
+        ResultCollector rc, boolean isFnSerializationReqd, byte isReexecute, String[] groups, boolean allMembers, boolean ignoreFailedMembers) {
+      super(MessageType.EXECUTE_FUNCTION, MSG_PARTS);
+      byte fnState = AbstractExecution.getFunctionState(function.isHA(),
+          function.hasResult(), function.optimizeForWrite());
+
+      addBytes(isReexecute, fnState);
+      if(isFnSerializationReqd){
+        getMessage().addStringOrObjPart(function); 
+      }
+      else{
+        getMessage().addStringOrObjPart(function.getId()); 
+      }
+      getMessage().addObjPart(args);
+      getMessage().addObjPart(memberMappedArg);
+      getMessage().addObjPart(groups);
+      this.flags = getByteArrayForFlags(allMembers, ignoreFailedMembers);
+      getMessage().addBytesPart(this.flags);
+      resultCollector = rc;
+      if(isReexecute == 1) {
+        resultCollector.clearResults();
+      }
+      this.functionId = function.getId();
+      this.function = function;
+      this.args = args;
+      this.memberMappedArg = memberMappedArg;
+      this.hasResult = fnState;
+      this.isFnSerializationReqd = isFnSerializationReqd;
+      this.groups = groups;
+    }
+
+    public ExecuteFunctionOpImpl(String functionId, Object args2,
+        MemberMappedArgument memberMappedArg, byte hasResult,
+        ResultCollector rc, boolean isFnSerializationReqd, boolean isHA,
+        boolean optimizeForWrite, byte isReexecute, String[] groups, boolean allMembers, boolean ignoreFailedMembers) {
+      super(MessageType.EXECUTE_FUNCTION, MSG_PARTS);
+      byte fnState = AbstractExecution.getFunctionState(isHA,
+          hasResult == (byte)1 ? true : false, optimizeForWrite);
+
+      addBytes(isReexecute, fnState);
+      getMessage().addStringOrObjPart(functionId);
+      getMessage().addObjPart(args2);
+      getMessage().addObjPart(memberMappedArg);
+      getMessage().addObjPart(groups);
+      this.flags = getByteArrayForFlags(allMembers, ignoreFailedMembers);
+      getMessage().addBytesPart(this.flags);
+      resultCollector = rc;
+      if(isReexecute == 1) {
+        resultCollector.clearResults();
+      } 
+      this.functionId = functionId;
+      this.args = args2;
+      this.memberMappedArg = memberMappedArg;
+      this.hasResult = fnState;
+      this.isFnSerializationReqd = isFnSerializationReqd;
+      this.groups = groups;
+    }
+
+    public ExecuteFunctionOpImpl(ExecuteFunctionOpImpl op, byte isReexecute) {
+      super(MessageType.EXECUTE_FUNCTION, MSG_PARTS);
+      this.resultCollector = op.resultCollector;
+      this.function = op.function;
+      this.functionId = op.functionId;
+      this.hasResult = op.hasResult;
+      this.args = op.args;
+      this.memberMappedArg = op.memberMappedArg;
+      this.isFnSerializationReqd = op.isFnSerializationReqd;
+      this.groups = op.groups;
+      this.flags = op.flags;
+      
+      addBytes(isReexecute, this.hasResult);
+      if(this.isFnSerializationReqd){
+        getMessage().addStringOrObjPart(function); 
+      }
+      else{
+        getMessage().addStringOrObjPart(function.getId()); 
+      }
+      getMessage().addObjPart(this.args);
+      getMessage().addObjPart(this.memberMappedArg);
+      getMessage().addObjPart(this.groups);
+      getMessage().addBytesPart(this.flags);
+      if(isReexecute == 1) {
+        resultCollector.clearResults();
+      }
+    }
+
+    private void addBytes(byte isReexecute, byte fnStateOrHasResult) {
+      if (GemFireCacheImpl.getClientFunctionTimeout() == GemFireCacheImpl.DEFAULT_CLIENT_FUNCTION_TIMEOUT) {
+        if (isReexecute == 1) {
+          getMessage().addBytesPart(new byte[] { AbstractExecution.getReexecuteFunctionState(fnStateOrHasResult) });
+        } else {
+          getMessage().addBytesPart(new byte[] { fnStateOrHasResult });
+        }
+      } else {
+        byte[] bytes = new byte[5];
+        if (isReexecute == 1) {
+          bytes[0] = AbstractExecution.getReexecuteFunctionState(fnStateOrHasResult);
+        } else {
+          bytes[0] = fnStateOrHasResult;
+        }
+        Part.encodeInt(GemFireCacheImpl.getClientFunctionTimeout(), bytes, 1);
+        getMessage().addBytesPart(bytes);
+      }
+    }
+
+    /**
+     * ignoreFaileMember flag is at index 1
+     */
+    private boolean getIgnoreFailedMembers() {
+      boolean ignoreFailedMembers = false;
+      if (this.flags != null && this.flags.length > 1) {
+        if (this.flags[IGNORE_FAILED_MEMBERS_INDEX] == 1) {
+          ignoreFailedMembers = true;
+        }
+      }
+      return ignoreFailedMembers;
+    }
+
+    @Override  
+    protected Object processResponse(Message msg) throws Exception {      
+      ChunkedMessage executeFunctionResponseMsg = (ChunkedMessage)msg;
+      try {
+        // Read the header which describes the type of message following
+        executeFunctionResponseMsg.readHeader();
+        switch (executeFunctionResponseMsg.getMessageType()) {
+          case MessageType.EXECUTE_FUNCTION_RESULT:
+            if (logger.isDebugEnabled()) {
+              logger.debug("ExecuteFunctionOpImpl#processResponse: received message of type EXECUTE_FUNCTION_RESULT.");
+            }
+            // Read the chunk
+            do{
+              executeFunctionResponseMsg.receiveChunk();
+              Object resultResponse = executeFunctionResponseMsg.getPart(0)
+                  .getObject();
+              Object result;
+              if (resultResponse instanceof ArrayList) {
+                result = ((ArrayList)resultResponse).get(0);
+              }
+              else {
+                result = resultResponse;
+              }
+              if (result instanceof FunctionException) {
+                //String s = "While performing a remote " + getOpName();
+                FunctionException ex = ((FunctionException)result);
+                if (ex instanceof InternalFunctionException || getIgnoreFailedMembers()) {
+                  Throwable cause = ex.getCause() == null ? ex : ex.getCause();
+                  DistributedMember memberID = (DistributedMember)((ArrayList)resultResponse)
+                      .get(1);
+                  this.resultCollector.addResult(memberID, cause);
+                  FunctionStats.getFunctionStats(this.functionId, null)
+                      .incResultsReceived();
+                  continue;
+                }
+                else {
+                  throw ex;
+                }
+              }else if (result instanceof Throwable) {
+                String s = "While performing a remote " + getOpName();
+                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 {
+                DistributedMember memberID = (DistributedMember)((ArrayList)resultResponse)
+                    .get(1);
+                synchronized (resultCollector) {
+                  resultCollector.addResult(memberID, result);                    
+                }
+                FunctionStats.getFunctionStats(this.functionId, null)
+                    .incResultsReceived();
+              }
+            }while(!executeFunctionResponseMsg.isLastChunk());
+            if (logger.isDebugEnabled()) {
+              logger.debug("ExecuteFunctionOpImpl#processResponse: received all the results from server successfully.");
+            }
+            return null;          
+          case MessageType.EXCEPTION:
+            if (logger.isDebugEnabled()) {
+              logger.debug("ExecuteFunctionOpImpl#processResponse: received message of type EXCEPTION");
+            }
+            // Read the chunk
+            executeFunctionResponseMsg.receiveChunk();
+            Part part0 = executeFunctionResponseMsg.getPart(0);
+            Object obj = part0.getObject();
+            if (obj instanceof FunctionException) {
+              FunctionException ex = ((FunctionException)obj);
+              throw ex;
+            }
+            else {
+              String s = ": While performing a remote execute Function" + ((Throwable)obj).getMessage();
+              throw new ServerOperationException(s, (Throwable)obj);              
+            }
+          case MessageType.EXECUTE_FUNCTION_ERROR:
+            if (logger.isDebugEnabled()) {
+              logger.debug("ExecuteFunctionOpImpl#processResponse: received message of type EXECUTE_FUNCTION_ERROR");
+            }
+            // Read the chunk
+            executeFunctionResponseMsg.receiveChunk();
+            String errorMessage = executeFunctionResponseMsg.getPart(0)
+                .getString();
+            throw new ServerOperationException(errorMessage);
+          default:
+            throw new InternalGemFireError(
+                LocalizedStrings.Op_UNKNOWN_MESSAGE_TYPE_0
+                  .toLocalizedString(
+                     Integer.valueOf(executeFunctionResponseMsg.getMessageType())));
+        }
+      }
+      finally {
+        executeFunctionResponseMsg.clear();
+      }      
+    }
+
+    @Override  
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.EXECUTE_FUNCTION_ERROR;
+    }
+
+    @Override  
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startExecuteFunction();
+    }
+    
+    protected String getOpName() {
+      return "executeFunction";
+    }
+
+    @Override  
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endExecuteFunctionSend(start, hasFailed());
+    }
+
+    @Override  
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endExecuteFunction(start, hasTimedOut(), hasFailed());
+    }
+
+    @Override  
+    protected Message createResponseMessage() {
+      return new ChunkedMessage(1, Version.CURRENT);
+    }
+  }
+  
+  public static final int MAX_FE_THREADS = Integer.getInteger(
+      "DistributionManager.MAX_FE_THREADS",
+      Math.max(Runtime.getRuntime().availableProcessors() * 4, 16)).intValue();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteRegionFunctionNoAckOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteRegionFunctionNoAckOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteRegionFunctionNoAckOp.java
new file mode 100755
index 0000000..76840ce
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteRegionFunctionNoAckOp.java
@@ -0,0 +1,218 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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.execute.Function;
+import com.gemstone.gemfire.cache.execute.FunctionException;
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.cache.execute.AbstractExecution;
+import com.gemstone.gemfire.internal.cache.execute.MemberMappedArgument;
+import com.gemstone.gemfire.internal.cache.execute.ServerRegionFunctionExecutor;
+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;
+import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+
+/**
+ * Does a Execution of function on server region
+ * It does not get the resul from the server (follows Fire&Forget approch)
+ * @author Kishor Bachhav
+ * @since 5.8Beta
+ */
+public class ExecuteRegionFunctionNoAckOp {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  private ExecuteRegionFunctionNoAckOp() {
+    // no instances allowed
+  }
+
+  /**
+   * Does a execute Function 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 put on
+   * @param function to be executed
+   * @param serverRegionExecutor which will return argument and filter
+   */
+  public static void execute(ExecutablePool pool, String region,
+      Function function, ServerRegionFunctionExecutor serverRegionExecutor,
+      byte hasResult) {
+    AbstractOp op = new ExecuteRegionFunctionNoAckOpImpl(region, function,
+        serverRegionExecutor, hasResult);
+    try {
+      if (logger.isDebugEnabled()) {
+        logger.debug("ExecuteRegionFunctionNoAckOp#execute : Sending Function Execution Message: {} to Server using pool: {}", op.getMessage(), pool);
+      }
+      pool.execute(op);
+    }
+    catch (Exception ex) {
+      if (logger.isDebugEnabled()) {
+        logger.debug("ExecuteRegionFunctionNoAckOp#execute : Exception occured while Sending Function Execution Message: {} to server using pool: {}", op.getMessage(), pool, ex);
+      }
+      if (ex.getMessage() != null)
+        throw new FunctionException(ex.getMessage(), ex);
+      else
+        throw new FunctionException(
+            "Unexpected exception during function execution:", ex);
+    }
+  }
+
+  public static void execute(ExecutablePool pool, String region,
+      String functionId, ServerRegionFunctionExecutor serverRegionExecutor,
+      byte hasResult, boolean isHA, boolean optimizeForWrite) {
+    AbstractOp op = new ExecuteRegionFunctionNoAckOpImpl(region, functionId,
+        serverRegionExecutor, hasResult, isHA, optimizeForWrite);
+    try {
+      if (logger.isDebugEnabled()) {
+        logger.debug("ExecuteRegionFunctionNoAckOp#execute : Sending Function Execution Message: {} to Server using pool: {}", op.getMessage(), pool);
+      }
+      pool.execute(op);
+    }
+    catch (Exception ex) {
+      if (logger.isDebugEnabled()) {
+        logger.debug("ExecuteRegionFunctionNoAckOp#execute : Exception occured while Sending Function Execution Message: {} to server using pool: {}", op.getMessage(), pool, ex);
+      }
+      if (ex.getMessage() != null)
+        throw new FunctionException(ex.getMessage(), ex);
+      else
+        throw new FunctionException(
+            "Unexpected exception during function execution:", ex);
+    }
+  }
+  
+  private static class ExecuteRegionFunctionNoAckOpImpl extends AbstractOp {
+    private final boolean executeOnBucketSet ;
+    
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public ExecuteRegionFunctionNoAckOpImpl(String region, Function function,
+        ServerRegionFunctionExecutor serverRegionExecutor, byte hasResult) {
+      super(MessageType.EXECUTE_REGION_FUNCTION, 8 + serverRegionExecutor
+          .getFilter().size());
+      byte isReExecute = 0;
+      int removedNodesSize = 0;
+      byte functionState = AbstractExecution.getFunctionState(function.isHA(),
+          function.hasResult(), function.optimizeForWrite());
+      Set routingObjects = serverRegionExecutor.getFilter();
+      Object args = serverRegionExecutor.getArguments();
+      MemberMappedArgument memberMappedArg = serverRegionExecutor.getMemberMappedArgument();
+      getMessage().addBytesPart(new byte[]{functionState});
+      getMessage().addStringPart(region);
+      if(serverRegionExecutor.isFnSerializationReqd()){
+        getMessage().addStringOrObjPart(function); 
+      }
+      else{
+        getMessage().addStringOrObjPart(function.getId()); 
+      }
+      getMessage().addObjPart(args);
+      getMessage().addObjPart(memberMappedArg);
+      
+      this.executeOnBucketSet = serverRegionExecutor.getExecuteOnBucketSetFlag(); 
+//      byte flags = this.executeOnBucketSet ?
+//          (byte)(0x00 | Op.BUCKETS_AS_FILTER_MASK) : 0x00;
+//      flags = isReExecute == 1? (byte)(flags | Op.IS_REXECUTE_MASK) : flags;
+      byte flags = ExecuteFunctionHelper.createFlags(executeOnBucketSet, isReExecute);
+
+      getMessage().addBytesPart(new byte[]{flags});
+      getMessage().addIntPart(routingObjects.size());
+      for (Object key : routingObjects) {
+        getMessage().addStringOrObjPart(key);
+      }
+      getMessage().addIntPart(removedNodesSize);
+    }
+
+    public ExecuteRegionFunctionNoAckOpImpl(String region, String functionId,
+        ServerRegionFunctionExecutor serverRegionExecutor, byte hasResult, boolean isHA, boolean optimizeForWrite) {
+      super(MessageType.EXECUTE_REGION_FUNCTION, 8 + serverRegionExecutor
+          .getFilter().size());
+      byte isReExecute = 0;
+      int removedNodesSize = 0;
+      byte functionState = AbstractExecution.getFunctionState(isHA,
+          hasResult==(byte)1?true:false, optimizeForWrite);
+      
+      Set routingObjects = serverRegionExecutor.getFilter();
+      Object args = serverRegionExecutor.getArguments();
+      MemberMappedArgument memberMappedArg = serverRegionExecutor.getMemberMappedArgument();
+      getMessage().addBytesPart(new byte[]{functionState});
+      getMessage().addStringPart(region);
+      getMessage().addStringOrObjPart(functionId); 
+      getMessage().addObjPart(args);
+      getMessage().addObjPart(memberMappedArg);
+      this.executeOnBucketSet = serverRegionExecutor.getExecuteOnBucketSetFlag(); 
+//      byte flags = this.executeOnBucketSet ?
+//          (byte)(0x00 | Op.BUCKETS_AS_FILTER_MASK) : 0x00;
+//      flags = isReExecute == 1? (byte)(flags | Op.IS_REXECUTE_MASK) : flags;
+      byte flags = ExecuteFunctionHelper.createFlags(executeOnBucketSet, isReExecute);
+
+      getMessage().addBytesPart(new byte[]{flags});
+      getMessage().addIntPart(routingObjects.size());
+      for (Object key : routingObjects) {
+        getMessage().addStringOrObjPart(key);
+      }
+      getMessage().addIntPart(removedNodesSize);
+    }
+    
+    @Override  
+    protected Object processResponse(Message msg) throws Exception {
+      final int msgType = msg.getMessageType();
+      if (msgType == MessageType.REPLY) {
+      return null;
+    }
+      else {
+        Part part = msg.getPart(0);
+        if (msgType == MessageType.EXCEPTION) {
+          Throwable t = (Throwable)part.getObject();
+          logger.warn(LocalizedMessage.create(LocalizedStrings.EXECUTE_FUNCTION_NO_HAS_RESULT_RECEIVED_EXCEPTION), t);
+        }
+        else if (isErrorResponse(msgType)) {
+          logger.warn(LocalizedMessage.create(LocalizedStrings.EXECUTE_FUNCTION_NO_HAS_RESULT_RECEIVED_EXCEPTION)); // TODO:LOG:FIXED: used to include part.getString()); but it wouldn't have been printed
+        }
+        else {
+          throw new InternalGemFireError("Unexpected message type "
+              + MessageType.getString(msgType));
+        }
+        return null;
+      }
+    
+    }
+
+    @Override  
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.EXECUTE_REGION_FUNCTION_ERROR;
+    }
+
+    @Override  
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startExecuteFunction();
+    }
+
+    @Override  
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endExecuteFunctionSend(start, hasFailed());
+    }
+
+    @Override  
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endExecuteFunction(start, hasTimedOut(), hasFailed());
+    }
+
+    @Override  
+    protected Message createResponseMessage() {
+      return new Message(1, Version.CURRENT);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteRegionFunctionOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteRegionFunctionOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteRegionFunctionOp.java
new file mode 100755
index 0000000..199e11a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteRegionFunctionOp.java
@@ -0,0 +1,615 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+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.cache.client.internal.ExecuteRegionFunctionSingleHopOp.ExecuteRegionFunctionSingleHopOpImpl;
+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.distributed.DistributedMember;
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.execute.AbstractExecution;
+import com.gemstone.gemfire.internal.cache.execute.FunctionStats;
+import com.gemstone.gemfire.internal.cache.execute.InternalFunctionException;
+import com.gemstone.gemfire.internal.cache.execute.MemberMappedArgument;
+import com.gemstone.gemfire.internal.cache.execute.InternalFunctionInvocationTargetException;
+import com.gemstone.gemfire.internal.cache.execute.ServerRegionFunctionExecutor;
+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.logging.LogService;
+
+/**
+ * Does a Execution of function on server region.<br>
+ * It alos gets result from the server
+ * @author Kishor Bachhav
+ * @since 5.8Beta
+ */
+public class ExecuteRegionFunctionOp {
+
+  private static final Logger logger = LogService.getLogger();
+  private ExecuteRegionFunctionOp() {
+    // no instances allowed
+  }
+
+  /**
+   * Does a execute Function 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 put on
+   * @param function to be executed
+   * @param serverRegionExecutor which will return argument and filter
+   * @param resultCollector is used to collect the results from the Server
+   */
+  public static void execute(ExecutablePool pool, String region,
+      Function function, ServerRegionFunctionExecutor serverRegionExecutor,
+      ResultCollector resultCollector, byte hasResult, int mRetryAttempts) {
+    AbstractOp op = new ExecuteRegionFunctionOpImpl(region, function, serverRegionExecutor,
+        resultCollector, hasResult, new HashSet<String>());
+
+    int retryAttempts = 0;
+    boolean reexecute = false;
+    boolean reexecuteForServ = false;
+    Set<String> failedNodes = new HashSet<String>();
+    AbstractOp reexecOp = null; 
+    int maxRetryAttempts = 0;
+    if (function.isHA()) {
+      maxRetryAttempts = mRetryAttempts;
+    }
+    
+    final boolean isDebugEnabled =logger.isDebugEnabled();
+    do {
+    try {
+        if (reexecuteForServ) {
+          reexecOp = new ExecuteRegionFunctionOpImpl(
+              (ExecuteRegionFunctionOpImpl)op, (byte)1/* isReExecute */,
+              failedNodes);
+          pool.execute(reexecOp, 0);
+        }
+        else {
+          pool.execute(op, 0);
+        }
+        reexecute = false;
+        reexecuteForServ = false;
+      }
+    catch (InternalFunctionInvocationTargetException e) {
+      if (isDebugEnabled) {
+        logger.debug("ExecuteRegionFunctionOp#execute : Received InternalFunctionInvocationTargetException. The failed nodes are {}", e.getFailedNodeSet());
+      }
+      reexecute = true;
+      resultCollector.clearResults();
+      Set<String> failedNodesIds = e.getFailedNodeSet();
+      failedNodes.clear();
+      if (failedNodesIds != null) {
+        failedNodes.addAll(failedNodesIds);
+      }
+    }
+    catch (ServerConnectivityException se) {
+      retryAttempts++;
+      if (isDebugEnabled) {
+        logger.debug("ExecuteRegionFunctionOp#execute : Received ServerConnectivityException. The exception is {} The retryattempt is : {} maxRetryAttempts {}", se, retryAttempts, maxRetryAttempts );
+      }
+      if(se instanceof ServerOperationException){
+        throw se;
+      }
+      if ((retryAttempts > maxRetryAttempts && maxRetryAttempts !=-1) /*|| !function.isHA()*/)
+        throw se;
+
+      reexecuteForServ = true;
+      resultCollector.clearResults();
+      failedNodes.clear();
+    }
+    }
+    while(reexecuteForServ);
+
+    if ( reexecute && function.isHA()) {
+      ExecuteRegionFunctionOp.reexecute(pool, region, function,
+          serverRegionExecutor, resultCollector, hasResult, failedNodes,
+          maxRetryAttempts - 1);
+    }
+  }
+  
+  public static void execute(ExecutablePool pool, String region,
+      String function, ServerRegionFunctionExecutor serverRegionExecutor,
+      ResultCollector resultCollector, byte hasResult, int mRetryAttempts, boolean isHA, boolean optimizeForWrite) {
+    AbstractOp op = new ExecuteRegionFunctionOpImpl(region, function, serverRegionExecutor,
+        resultCollector, hasResult, new HashSet<String>(), isHA, optimizeForWrite, true);
+
+    int retryAttempts = 0;
+    boolean reexecute = false;
+    boolean reexecuteForServ = false;
+    Set<String> failedNodes = new HashSet<String>();
+    AbstractOp reexecOp = null; 
+    int maxRetryAttempts = 0;
+    if (isHA) {
+      maxRetryAttempts = mRetryAttempts;
+    }
+    final boolean isDebugEnabled = logger.isDebugEnabled();
+    do{
+    try {
+      if (reexecuteForServ) {
+        reexecOp = new ExecuteRegionFunctionOpImpl(
+            (ExecuteRegionFunctionOpImpl)op, (byte)1/* isReExecute */,
+            failedNodes);
+        pool.execute(reexecOp, 0);
+      }
+      else {
+        pool.execute(op, 0);
+      }
+      reexecute = false;
+      reexecuteForServ = false;
+    }
+    catch (InternalFunctionInvocationTargetException e) {
+      if (isDebugEnabled) {
+        logger.debug("ExecuteRegionFunctionOp#execute : Received InternalFunctionInvocationTargetException. The failed nodes are {}", e.getFailedNodeSet());
+      }
+      reexecute = true;
+      resultCollector.clearResults();
+      Set<String> failedNodesIds = e.getFailedNodeSet();
+      failedNodes.clear();
+      if (failedNodesIds != null) {
+        failedNodes.addAll(failedNodesIds);
+      }
+    }
+    catch (ServerConnectivityException se) {
+      if (isDebugEnabled) {
+        logger.debug("ExecuteRegionFunctionOp#execute : Received ServerConnectivityException. The exception is {} The retryattempt is : {} maxRetryAttempts {}", se, retryAttempts, maxRetryAttempts);
+      }
+      if(se instanceof ServerOperationException){
+        throw se;
+      }
+      retryAttempts++;
+      if ((retryAttempts >  maxRetryAttempts && maxRetryAttempts != -1) /*|| !isHA*/)
+        throw se;
+
+      reexecute = true;
+      resultCollector.clearResults();
+      failedNodes.clear();
+    }
+  }
+  while(reexecuteForServ);
+  
+    if ( reexecute && isHA) {
+      ExecuteRegionFunctionOp.reexecute(pool, region, function,
+          serverRegionExecutor, resultCollector, hasResult, failedNodes,
+          maxRetryAttempts - 1, isHA, optimizeForWrite);
+    }
+  }
+  
+  public static void reexecute(ExecutablePool pool, String region,
+      Function function, ServerRegionFunctionExecutor serverRegionExecutor,
+      ResultCollector resultCollector, byte hasResult, Set<String> failedNodes, int maxRetryAttempts) {
+    AbstractOp op = new ExecuteRegionFunctionOpImpl(region, function, serverRegionExecutor,
+        resultCollector, hasResult, new HashSet<String>());
+
+    boolean reexecute = true;
+    int retryAttempts = 0;
+    final boolean isDebugEnabled = logger.isDebugEnabled();
+    do {
+      reexecute = false;
+     AbstractOp reExecuteOp = new ExecuteRegionFunctionOpImpl(
+          (ExecuteRegionFunctionOpImpl)op, (byte)1/*isReExecute*/, failedNodes);
+      if (isDebugEnabled) {
+        logger.debug("ExecuteRegionFunction#reexecute: Sending Function Execution Message: {} to Server using pool: {} with failed nodes: {}", reExecuteOp.getMessage(), pool, failedNodes);
+      }
+      try {
+          pool.execute(reExecuteOp,0);
+      }
+      catch (InternalFunctionInvocationTargetException e) {
+        if (isDebugEnabled) {
+          logger.debug("ExecuteRegionFunctionOp#reexecute : Received InternalFunctionInvocationTargetException. The failed nodes are {}", e.getFailedNodeSet());
+        }
+        reexecute = true;
+        resultCollector.clearResults();
+        Set<String> failedNodesIds = e.getFailedNodeSet();
+        failedNodes.clear();
+        if (failedNodesIds != null) {
+          failedNodes.addAll(failedNodesIds);
+        }
+      }
+      catch (ServerConnectivityException se) {
+        if (isDebugEnabled) {
+          logger.debug("ExecuteRegionFunctionOp#reexecute : Received ServerConnectivity Exception.");
+        }
+        
+        if(se instanceof ServerOperationException){
+          throw se;
+        }
+        retryAttempts++;
+        if (retryAttempts > maxRetryAttempts && maxRetryAttempts != -2) 
+          throw se;
+
+        reexecute = true;
+        resultCollector.clearResults();
+        failedNodes.clear();
+      }
+    } while (reexecute);
+  }
+  
+  public static void reexecute(ExecutablePool pool, String region,
+      String function, ServerRegionFunctionExecutor serverRegionExecutor,
+      ResultCollector resultCollector, byte hasResult, Set<String> failedNodes, int maxRetryAttempts, boolean isHA, boolean optimizeForWrite) {
+    AbstractOp op = new ExecuteRegionFunctionOpImpl(region, function, serverRegionExecutor,
+        resultCollector, hasResult, new HashSet<String>(), isHA, optimizeForWrite, true);
+
+    boolean reexecute = true;
+    int retryAttempts = 0;
+    final boolean isDebugEnabled = logger.isDebugEnabled();
+    do {
+      reexecute = false;
+      
+      AbstractOp reExecuteOp = new ExecuteRegionFunctionOpImpl(
+          (ExecuteRegionFunctionOpImpl)op, (byte)1/*isReExecute*/, failedNodes);
+      if (isDebugEnabled) {
+        logger.debug("ExecuteRegionFunction#reexecute : Sending Function Execution Message: {} to Server using pool: {}", reExecuteOp.getMessage(), pool);
+      }
+      try {
+          pool.execute(reExecuteOp,0);
+      }
+      catch (InternalFunctionInvocationTargetException e) {
+        if (isDebugEnabled) {
+          logger.debug("ExecuteRegionFunctionOp#reexecute : Received InternalFunctionInvocationTargetException. The failed nodes are {}", e.getFailedNodeSet());
+        }
+        reexecute = true;
+        resultCollector.clearResults();
+        Set<String> failedNodesIds = e.getFailedNodeSet();
+        failedNodes.clear();
+        if (failedNodesIds != null) {
+          failedNodes.addAll(failedNodesIds);
+        }
+      }
+      catch (ServerConnectivityException se) {
+        if (isDebugEnabled) { 
+          logger.debug("ExecuteRegionFunctionOp#reexecute : Received ServerConnectivityException. The exception is {} The retryattempt is : {} maxRetryAttempts {}", se, retryAttempts, maxRetryAttempts);
+        }
+        if(se instanceof ServerOperationException){
+          throw se;
+        }
+        retryAttempts++;
+        if (retryAttempts > maxRetryAttempts && maxRetryAttempts != -2) 
+          throw se;
+
+        reexecute = true;
+        resultCollector.clearResults();
+        failedNodes.clear();
+      }
+    } while (reexecute);
+  }
+  static class ExecuteRegionFunctionOpImpl extends AbstractOp {
+
+    // To collect the results from the server
+    private final ResultCollector resultCollector;
+
+    //To get the instance of the Function Statistics we need the function name or instance
+    private Function function;
+
+    private byte isReExecute = 0;
+
+    private final String regionName;
+
+    private final ServerRegionFunctionExecutor executor;
+
+    private final byte hasResult;
+
+    private Set<String> failedNodes = new HashSet<String>();
+
+    private final String functionId;
+    private final boolean executeOnBucketSet;
+
+    /**
+     * @param removedNodes TODO
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public ExecuteRegionFunctionOpImpl(String region, Function function,
+        ServerRegionFunctionExecutor serverRegionExecutor, ResultCollector rc,
+        byte hasResult, Set<String> removedNodes) {
+      super(MessageType.EXECUTE_REGION_FUNCTION, 8
+          + serverRegionExecutor.getFilter().size() + removedNodes.size());
+      Set routingObjects = serverRegionExecutor.getFilter();
+      Object args = serverRegionExecutor.getArguments();
+      byte functionState = AbstractExecution.getFunctionState(function.isHA(),
+          function.hasResult(), function.optimizeForWrite());
+      MemberMappedArgument memberMappedArg = serverRegionExecutor
+          .getMemberMappedArgument();
+
+      addBytes(functionState);
+      getMessage().addStringPart(region);
+      if (serverRegionExecutor.isFnSerializationReqd()) {
+        getMessage().addStringOrObjPart(function);
+      }
+      else {
+        getMessage().addStringOrObjPart(function.getId());
+      }
+      getMessage().addObjPart(args);
+      getMessage().addObjPart(memberMappedArg);
+      this.executeOnBucketSet = serverRegionExecutor.getExecuteOnBucketSetFlag(); 
+      byte flags = ExecuteFunctionHelper.createFlags(executeOnBucketSet, isReExecute);
+
+      getMessage().addBytesPart(new byte[] {flags});
+      getMessage().addIntPart(routingObjects.size());
+      for (Object key : routingObjects) {
+        getMessage().addStringOrObjPart(key);
+      }
+      getMessage().addIntPart(removedNodes.size());
+      for (Object nodes : removedNodes) {
+        getMessage().addStringOrObjPart(nodes);
+      }
+
+      this.resultCollector = rc;
+      this.regionName = region;
+      this.function = function;
+      this.functionId = function.getId();
+      this.executor = serverRegionExecutor;
+      this.hasResult = functionState;
+      this.failedNodes = removedNodes;
+    }
+    
+    public ExecuteRegionFunctionOpImpl(String region, String function,
+        ServerRegionFunctionExecutor serverRegionExecutor, ResultCollector rc,
+        byte hasResult, Set<String> removedNodes, boolean isHA, boolean optimizeForWrite, boolean calculateFnState ) {
+      super(MessageType.EXECUTE_REGION_FUNCTION, 8
+          + serverRegionExecutor.getFilter().size() + removedNodes.size());
+      Set routingObjects = serverRegionExecutor.getFilter();
+      byte functionState = hasResult;
+      if(calculateFnState){
+         functionState = AbstractExecution.getFunctionState(isHA,
+          hasResult == (byte)1 ? true : false, optimizeForWrite);
+      }
+      Object args = serverRegionExecutor.getArguments();
+      MemberMappedArgument memberMappedArg = serverRegionExecutor
+          .getMemberMappedArgument();
+      addBytes(functionState);
+      getMessage().addStringPart(region);
+      getMessage().addStringOrObjPart(function);
+      getMessage().addObjPart(args);
+      getMessage().addObjPart(memberMappedArg);
+      
+      this.executeOnBucketSet = serverRegionExecutor.getExecuteOnBucketSetFlag(); 
+//      byte flags = this.executeOnBucketSet ? 
+//          (byte)(0x00 | ExecuteFunctionHelper.BUCKETS_AS_FILTER_MASK) : 0x00;
+//      flags = isReExecute == 1? (byte)(flags | ExecuteFunctionHelper.IS_REXECUTE_MASK) : flags;
+      byte flags = ExecuteFunctionHelper.createFlags(executeOnBucketSet, isReExecute);
+      
+      getMessage().addBytesPart(new byte[] { flags });
+      getMessage().addIntPart(routingObjects.size());
+      for (Object key : routingObjects) {
+        getMessage().addStringOrObjPart(key);
+      }
+      getMessage().addIntPart(removedNodes.size());
+      for (Object nodes : removedNodes) {
+        getMessage().addStringOrObjPart(nodes);
+      }
+
+      this.resultCollector = rc;
+      this.regionName = region;
+      this.functionId = function;
+      this.executor = serverRegionExecutor;
+      this.hasResult = functionState;
+      this.failedNodes = removedNodes;
+    }
+
+    public ExecuteRegionFunctionOpImpl(
+        ExecuteRegionFunctionSingleHopOpImpl newop) {
+      this(newop.getRegionName(), newop.getFunctionId(), newop.getExecutor(),
+          newop.getResultCollector(), newop.getHasResult(),
+          new HashSet<String>(), newop.isHA(), newop
+              .optimizeForWrite(), false);
+    }
+
+    public ExecuteRegionFunctionOpImpl(ExecuteRegionFunctionOpImpl op,
+        byte isReExecute, Set<String> removedNodes) {
+      super(MessageType.EXECUTE_REGION_FUNCTION, 8
+          + op.executor.getFilter().size() + removedNodes.size());
+      this.isReExecute = isReExecute;
+      this.resultCollector = op.resultCollector;
+      this.function = op.function;
+      this.functionId = op.functionId;
+      this.regionName = op.regionName;
+      this.executor = op.executor;
+      this.hasResult = op.hasResult;
+      this.failedNodes = op.failedNodes;
+      this.executeOnBucketSet = op.executeOnBucketSet;
+      if (isReExecute == 1) {
+        this.resultCollector.endResults();
+        this.resultCollector.clearResults();
+      }
+
+      Set routingObjects = executor.getFilter();
+      Object args = executor.getArguments();
+      MemberMappedArgument memberMappedArg = executor.getMemberMappedArgument();
+      getMessage().clear();
+      addBytes(this.hasResult);
+      getMessage().addStringPart(this.regionName);
+      if (executor.isFnSerializationReqd()) {
+        getMessage().addStringOrObjPart(function);
+      }
+      else {
+        getMessage().addStringOrObjPart(functionId);
+      }
+      getMessage().addObjPart(args);
+      getMessage().addObjPart(memberMappedArg);
+//      byte flags = this.executeOnBucketSet ?
+//          (byte)(0x00 | Op.BUCKETS_AS_FILTER_MASK) : 0x00;
+//      flags = isReExecute == 1? (byte)(flags | Op.IS_REXECUTE_MASK) : flags;
+      byte flags = ExecuteFunctionHelper.createFlags(executeOnBucketSet, isReExecute);
+
+      getMessage().addBytesPart(new byte[] {flags });
+      getMessage().addIntPart(routingObjects.size());
+      for (Object key : routingObjects) {
+        getMessage().addStringOrObjPart(key);
+      }
+      getMessage().addIntPart(removedNodes.size());
+      for (Object nodes : removedNodes) {
+        getMessage().addStringOrObjPart(nodes);
+      }
+    }
+
+    private void addBytes(byte functionStateOrHasResult) {
+      if (GemFireCacheImpl.getClientFunctionTimeout() == GemFireCacheImpl.DEFAULT_CLIENT_FUNCTION_TIMEOUT) {
+        getMessage().addBytesPart(new byte[] { functionStateOrHasResult });
+      } else {
+        byte[] bytes = new byte[5];
+        bytes[0] = functionStateOrHasResult;
+        Part.encodeInt(GemFireCacheImpl.getClientFunctionTimeout(), bytes, 1);
+        getMessage().addBytesPart(bytes);
+      }
+    }
+
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      ChunkedMessage executeFunctionResponseMsg = (ChunkedMessage)msg;
+      // Read the header which describes the type of message following
+      try {
+        executeFunctionResponseMsg.readHeader();
+        switch (executeFunctionResponseMsg.getMessageType()) {
+          case MessageType.EXECUTE_REGION_FUNCTION_RESULT:
+            final boolean isDebugEnabled = logger.isDebugEnabled();
+            if (isDebugEnabled) {
+              logger.debug("ExecuteRegionFunctionOpImpl#processResponse: received message of type EXECUTE_REGION_FUNCTION_RESULT. The number of parts are : {}", executeFunctionResponseMsg.getNumberOfParts());
+            }
+            // Read the chunk
+            do {
+              executeFunctionResponseMsg.receiveChunk();
+              Object resultResponse = executeFunctionResponseMsg.getPart(0)
+                  .getObject();
+              Object result;
+              if (resultResponse instanceof ArrayList) {
+                result = ((ArrayList)resultResponse).get(0);
+              }
+              else {
+                result = resultResponse;
+              }
+              if (result instanceof FunctionException) {
+                FunctionException ex = ((FunctionException)result);
+                if (ex instanceof InternalFunctionException) {
+                  Throwable cause = ex.getCause();
+                  DistributedMember memberID = (DistributedMember)((ArrayList)resultResponse)
+                      .get(1);
+                  this.resultCollector
+                      .addResult(memberID, cause);
+                  FunctionStats.getFunctionStats(this.functionId,
+                      this.executor.getRegion().getSystem())
+                      .incResultsReceived();
+                  continue;
+                }
+                else if (((FunctionException)result).getCause() instanceof InternalFunctionInvocationTargetException) {
+                  InternalFunctionInvocationTargetException ifite = (InternalFunctionInvocationTargetException)ex
+                      .getCause();
+                  this.failedNodes.addAll(ifite.getFailedNodeSet());
+                }
+                executeFunctionResponseMsg.clear();
+                throw ex;
+              }
+              else if (result instanceof Throwable) {
+                String s = "While performing a remote " + getOpName();
+                executeFunctionResponseMsg.clear();
+                throw new ServerOperationException(s, (Throwable)result);
+              }
+              else {
+                DistributedMember memberID = (DistributedMember)((ArrayList)resultResponse)
+                    .get(1);
+                this.resultCollector.addResult(memberID, result);
+                FunctionStats.getFunctionStats(this.functionId,
+                    this.executor.getRegion().getSystem()).incResultsReceived();
+              }
+            } while (!executeFunctionResponseMsg.isLastChunk());
+            if (isDebugEnabled) {
+              logger.debug("ExecuteRegionFunctionOpImpl#processResponse: received all the results from server successfully.");
+            }
+            this.resultCollector.endResults();
+            return null;
+
+          case MessageType.EXCEPTION:
+            if (logger.isDebugEnabled()) {
+              logger.debug("ExecuteRegionFunctionOpImpl#processResponse: received message of type EXCEPTION. The number of parts are : {}", executeFunctionResponseMsg.getNumberOfParts());
+            }
+
+            // Read the chunk
+            executeFunctionResponseMsg.receiveChunk();
+            Part part0 = executeFunctionResponseMsg.getPart(0);
+            Object obj = part0.getObject();
+            if (obj instanceof FunctionException) {
+              FunctionException ex = ((FunctionException)obj);
+              if (((FunctionException)obj).getCause() instanceof InternalFunctionInvocationTargetException) {
+                InternalFunctionInvocationTargetException ifite = (InternalFunctionInvocationTargetException)ex
+                    .getCause();
+                this.failedNodes.addAll(ifite.getFailedNodeSet());
+              }
+              executeFunctionResponseMsg.clear();
+              throw ex;
+            }
+            else if (obj instanceof Throwable) {
+              executeFunctionResponseMsg.clear();
+              String s = "While performing a remote " + getOpName();
+              throw new ServerOperationException(s, (Throwable)obj);
+            }
+            break;
+          case MessageType.EXECUTE_REGION_FUNCTION_ERROR:
+            if (logger.isDebugEnabled()) {
+              logger.debug("ExecuteRegionFunctionOpImpl#processResponse: received message of type EXECUTE_REGION_FUNCTION_ERROR");
+            }
+            // Read the chunk
+            executeFunctionResponseMsg.receiveChunk();
+            String errorMessage = executeFunctionResponseMsg.getPart(0)
+                .getString();
+            executeFunctionResponseMsg.clear();
+            throw new ServerOperationException(errorMessage);
+          default:
+            throw new InternalGemFireError("Unknown message type "
+                + executeFunctionResponseMsg.getMessageType());
+        }
+      }
+      finally {
+        executeFunctionResponseMsg.clear();
+      }
+      return null;
+    }
+
+    @Override
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.EXECUTE_REGION_FUNCTION_ERROR;
+    }
+
+    @Override
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startExecuteFunction();
+    }
+
+    protected String getOpName() {
+      return "executeRegionFunction";
+    }
+
+    @Override
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endExecuteFunctionSend(start, hasFailed());
+    }
+
+    @Override
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endExecuteFunction(start, hasTimedOut(), hasFailed());
+    }
+
+    @Override
+    protected Message createResponseMessage() {
+      return new ChunkedMessage(1, Version.CURRENT);
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteRegionFunctionSingleHopOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteRegionFunctionSingleHopOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteRegionFunctionSingleHopOp.java
new file mode 100644
index 0000000..5ea03f8
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ExecuteRegionFunctionSingleHopOp.java
@@ -0,0 +1,491 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.ArrayList;
+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.InternalGemFireError;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.client.ServerOperationException;
+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.distributed.DistributedMember;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.cache.execute.AbstractExecution;
+import com.gemstone.gemfire.internal.cache.execute.FunctionStats;
+import com.gemstone.gemfire.internal.cache.execute.InternalFunctionException;
+import com.gemstone.gemfire.internal.cache.execute.InternalFunctionInvocationTargetException;
+import com.gemstone.gemfire.internal.cache.execute.MemberMappedArgument;
+import com.gemstone.gemfire.internal.cache.execute.ServerRegionFunctionExecutor;
+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.logging.LogService;
+
+/**
+ * @author skumar
+ * @since 6.5
+ */
+public class ExecuteRegionFunctionSingleHopOp {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  private ExecuteRegionFunctionSingleHopOp() {
+  }
+
+  public static void execute(ExecutablePool pool, Region region,
+      Function function, ServerRegionFunctionExecutor serverRegionExecutor,
+      ResultCollector resultCollector, byte hasResult,
+      Map<ServerLocation, ? extends HashSet> serverToFilterMap, int mRetryAttempts, boolean allBuckets) {
+
+    boolean reexecute = false;
+    Set<String> failedNodes = new HashSet<String>();
+    int maxRetryAttempts = 0;
+    if (function.isHA()) {
+      maxRetryAttempts = mRetryAttempts;
+    }
+    ClientMetadataService cms = ((GemFireCacheImpl)region.getCache())
+        .getClientMetadataService();
+
+    final boolean isDebugEnabled = logger.isDebugEnabled();
+    if (isDebugEnabled) {
+      logger.debug("ExecuteRegionFunctionSingleHopOp#execute : The serverToFilterMap is : {}", serverToFilterMap);
+    }
+    List<SingleHopOperationCallable> callableTasks = constructAndGetExecuteFunctionTasks(region.getFullPath(),
+        serverRegionExecutor, serverToFilterMap, (PoolImpl)pool, function,
+        hasResult, resultCollector, cms, allBuckets);
+
+    reexecute = SingleHopClientExecutor.submitAllHA(callableTasks,
+        (LocalRegion)region, resultCollector, failedNodes);
+
+    if (isDebugEnabled) {
+      logger.debug("ExecuteRegionFunctionSingleHopOp#execute : The size of callableTask is : {}", callableTasks.size());
+    }
+
+    if (reexecute ) {
+      resultCollector.clearResults();
+      if(function.isHA()) {
+      ExecuteRegionFunctionOp.reexecute(pool, region.getFullPath(), function,
+          serverRegionExecutor, resultCollector, hasResult, failedNodes,
+          maxRetryAttempts - 1);
+      }
+      else {
+        ExecuteRegionFunctionOp.execute(pool, region.getFullPath(), function,
+            serverRegionExecutor, resultCollector, hasResult,
+            maxRetryAttempts - 1);
+      }
+    }
+
+    resultCollector.endResults();
+  }
+
+  public static void execute(ExecutablePool pool, Region region,
+      String functionId, ServerRegionFunctionExecutor serverRegionExecutor,
+      ResultCollector resultCollector, byte hasResult,
+      Map<ServerLocation, ? extends HashSet> serverToFilterMap,
+      int mRetryAttempts, boolean allBuckets, boolean isHA,
+      boolean optimizeForWrite) {
+
+    boolean reexecute = false;
+    Set<String> failedNodes = new HashSet<String>();
+    int maxRetryAttempts = 0;
+    if (isHA) {
+      maxRetryAttempts = mRetryAttempts;
+    }
+    ClientMetadataService cms = ((GemFireCacheImpl)region.getCache())
+        .getClientMetadataService();
+
+    final boolean isDebugEnabled = logger.isDebugEnabled();
+    if (isDebugEnabled) {
+      logger.debug("ExecuteRegionFunctionSingleHopOp#execute : The serverToFilterMap is : {}", serverToFilterMap);
+    }
+    List<SingleHopOperationCallable> callableTasks = constructAndGetExecuteFunctionTasks(region.getFullPath(),
+        serverRegionExecutor, serverToFilterMap, (PoolImpl)pool, functionId,
+        hasResult, resultCollector, cms, allBuckets, isHA,optimizeForWrite);
+
+    reexecute = SingleHopClientExecutor.submitAllHA(callableTasks,
+        (LocalRegion)region, resultCollector, failedNodes);
+
+    if (isDebugEnabled) {
+      logger.debug("ExecuteRegionFunctionSingleHopOp#execute : The size of callableTask is: {}, reexecute={}", callableTasks.size(), reexecute);
+    }
+
+    if (reexecute) {
+      resultCollector.clearResults();
+      if (isHA) {
+        ExecuteRegionFunctionOp.reexecute(pool, region.getFullPath(),
+            functionId, serverRegionExecutor, resultCollector, hasResult,
+            failedNodes, maxRetryAttempts - 1, isHA, optimizeForWrite);
+      }
+      else {
+        ExecuteRegionFunctionOp.execute(pool, region.getFullPath(), functionId,
+            serverRegionExecutor, resultCollector, hasResult,
+            maxRetryAttempts - 1, isHA, optimizeForWrite);
+      }
+    }
+
+    resultCollector.endResults();
+  }
+
+  
+  static List<SingleHopOperationCallable> constructAndGetExecuteFunctionTasks(String region,
+      ServerRegionFunctionExecutor serverRegionExecutor,
+      final Map<ServerLocation, ? extends HashSet> serverToFilterMap,
+      final PoolImpl pool, final Function function, byte hasResult,
+      ResultCollector rc, ClientMetadataService cms, boolean allBucket) {
+    final List<SingleHopOperationCallable> tasks = new ArrayList<SingleHopOperationCallable>();
+    ArrayList<ServerLocation> servers = new ArrayList<ServerLocation>(
+        serverToFilterMap.keySet());
+
+    if (logger.isDebugEnabled()) {
+      logger.debug("Constructing tasks for the servers {}", servers);
+    }
+    for (ServerLocation server : servers) {
+      ServerRegionFunctionExecutor executor = (ServerRegionFunctionExecutor)serverRegionExecutor
+          .withFilter(serverToFilterMap.get(server));
+
+      AbstractOp op = new ExecuteRegionFunctionSingleHopOpImpl(region, function, executor, rc, hasResult, new HashSet<String>(),
+          allBucket);
+      SingleHopOperationCallable task = new SingleHopOperationCallable(
+          new ServerLocation(server.getHostName(), server.getPort()), pool, op, UserAttributes.userAttributes.get());
+      tasks.add(task);
+    }
+    return tasks;
+  }
+
+  static List<SingleHopOperationCallable> constructAndGetExecuteFunctionTasks(String region,
+      ServerRegionFunctionExecutor serverRegionExecutor,
+      final Map<ServerLocation, ? extends HashSet> serverToFilterMap,
+      final PoolImpl pool, final String functionId, byte hasResult,
+      ResultCollector rc, ClientMetadataService cms, boolean allBucket, boolean isHA, boolean optimizeForWrite) {
+    final List<SingleHopOperationCallable> tasks = new ArrayList<SingleHopOperationCallable>();
+    ArrayList<ServerLocation> servers = new ArrayList<ServerLocation>(
+        serverToFilterMap.keySet());
+
+    if (logger.isDebugEnabled()) {
+      logger.debug("Constructing tasks for the servers {}", servers);
+    }
+    for (ServerLocation server : servers) {
+      ServerRegionFunctionExecutor executor = (ServerRegionFunctionExecutor)serverRegionExecutor
+          .withFilter(serverToFilterMap.get(server));
+
+      AbstractOp op = new ExecuteRegionFunctionSingleHopOpImpl(region, functionId, executor, rc, hasResult, new HashSet<String>(),
+          allBucket, isHA, optimizeForWrite);
+      SingleHopOperationCallable task = new SingleHopOperationCallable(
+          new ServerLocation(server.getHostName(), server.getPort()), pool, op, UserAttributes.userAttributes.get());
+      tasks.add(task);
+    }
+    return tasks;
+  }
+  
+  static class ExecuteRegionFunctionSingleHopOpImpl extends AbstractOp {
+
+    private final ResultCollector resultCollector;
+
+    private final String functionId;
+
+    private final String regionName;
+
+    private final ServerRegionFunctionExecutor executor;
+
+    private final byte hasResult;
+
+    private Set<String> failedNodes = new HashSet<String>();
+
+    private boolean isHA; 
+    
+    private boolean optimizeForWrite;
+
+    public ExecuteRegionFunctionSingleHopOpImpl(String region,
+        Function function, ServerRegionFunctionExecutor serverRegionExecutor,
+        ResultCollector rc, byte hasResult,
+        Set<String> removedNodes, boolean allBuckets) {
+      // What is this 8 that is getting added to filter and removednode sizes?
+      // It should have been used as a constant and documented
+      super(MessageType.EXECUTE_REGION_FUNCTION_SINGLE_HOP, 8
+          + serverRegionExecutor.getFilter().size() + removedNodes.size());
+      this.isHA = function.isHA();
+      this.optimizeForWrite = function.optimizeForWrite();
+      byte functionState = AbstractExecution.getFunctionState(function.isHA(),
+          function.hasResult() , function.optimizeForWrite());
+      Set routingObjects = serverRegionExecutor.getFilter();
+      Object args = serverRegionExecutor.getArguments();
+      MemberMappedArgument memberMappedArg = serverRegionExecutor
+          .getMemberMappedArgument();
+      addBytes(functionState);
+      getMessage().addStringPart(region);
+      if (serverRegionExecutor.isFnSerializationReqd()) {
+        getMessage().addStringOrObjPart(function);
+      }
+      else {
+        getMessage().addStringOrObjPart(function.getId());
+      }
+      getMessage().addObjPart(args);
+      getMessage().addObjPart(memberMappedArg);
+      getMessage().addBytesPart(new byte[] { allBuckets ? (byte)1 : (byte)0 });
+      getMessage().addIntPart(routingObjects.size());
+      for (Object key : routingObjects) {
+        if(allBuckets){
+          getMessage().addIntPart((Integer)key);
+        }
+        else {
+          getMessage().addStringOrObjPart(key);
+        }
+      }
+      getMessage().addIntPart(removedNodes.size());
+      for (Object nodes : removedNodes) {
+        getMessage().addStringOrObjPart(nodes);
+      }
+
+      this.resultCollector = rc;
+      this.regionName = region;
+      this.functionId = function.getId();
+      this.executor = serverRegionExecutor;
+      this.hasResult = functionState;
+      this.failedNodes = removedNodes;
+    }
+
+    public ExecuteRegionFunctionSingleHopOpImpl(String region,
+        String functionId, ServerRegionFunctionExecutor serverRegionExecutor,
+        ResultCollector rc, byte hasResult,
+        Set<String> removedNodes, boolean allBuckets, boolean isHA, boolean optimizeForWrite) {
+      // What is this 8 that is getting added to filter and removednode sizes?
+      // It should have been used as a constant and documented
+      super(MessageType.EXECUTE_REGION_FUNCTION_SINGLE_HOP, 8
+          + serverRegionExecutor.getFilter().size() + removedNodes.size());
+      this.isHA = isHA;
+      this.optimizeForWrite = optimizeForWrite;
+      Set routingObjects = serverRegionExecutor.getFilter();
+      Object args = serverRegionExecutor.getArguments();
+      byte functionState = AbstractExecution.getFunctionState(isHA,
+          hasResult == (byte)1 ? true : false, optimizeForWrite);
+      MemberMappedArgument memberMappedArg = serverRegionExecutor
+          .getMemberMappedArgument();
+      addBytes(functionState);
+      getMessage().addStringPart(region);
+      getMessage().addStringOrObjPart(functionId);
+      getMessage().addObjPart(args);
+      getMessage().addObjPart(memberMappedArg);
+      getMessage().addBytesPart(new byte[] { allBuckets ? (byte)1 : (byte)0 });
+      getMessage().addIntPart(routingObjects.size());
+      for (Object key : routingObjects) {
+        if(allBuckets){
+          getMessage().addIntPart((Integer)key);
+        }
+        else {
+          getMessage().addStringOrObjPart(key);
+        }
+      }
+      getMessage().addIntPart(removedNodes.size());
+      for (Object nodes : removedNodes) {
+        getMessage().addStringOrObjPart(nodes);
+      }
+
+      this.resultCollector = rc;
+      this.regionName = region;
+      this.functionId = functionId;
+      this.executor = serverRegionExecutor;
+      this.hasResult = functionState;
+      this.failedNodes = removedNodes;
+    }
+
+    private void addBytes(byte functionState) {
+      if (GemFireCacheImpl.getClientFunctionTimeout() == GemFireCacheImpl.DEFAULT_CLIENT_FUNCTION_TIMEOUT) {
+        getMessage().addBytesPart(new byte[] { functionState });
+      } else {
+        byte[] bytes = new byte[5];
+        bytes[0] = functionState;
+        Part.encodeInt(GemFireCacheImpl.getClientFunctionTimeout(), bytes, 1);
+        getMessage().addBytesPart(bytes);
+      }
+    }
+
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      ChunkedMessage executeFunctionResponseMsg = (ChunkedMessage)msg;
+      try {
+        executeFunctionResponseMsg.readHeader();
+        switch (executeFunctionResponseMsg.getMessageType()) {
+          case MessageType.EXECUTE_REGION_FUNCTION_RESULT:
+            final boolean isDebugEnabled = logger.isDebugEnabled();
+            if (isDebugEnabled) {
+              logger.debug("ExecuteRegionFunctionSingleHopOpImpl#processResponse: received message of type EXECUTE_REGION_FUNCTION_RESULT.");
+            }
+            do {
+              executeFunctionResponseMsg.receiveChunk();
+              Object resultResponse = executeFunctionResponseMsg.getPart(0)
+                  .getObject();
+              Object result;
+              if (resultResponse instanceof ArrayList) {
+                result = ((ArrayList)resultResponse).get(0);
+              }
+              else {
+                result = resultResponse;
+              }
+
+              if (result instanceof FunctionException) {
+                FunctionException ex = ((FunctionException)result);
+                if (isDebugEnabled) {
+                  logger.debug("ExecuteRegionFunctionSingleHopOpImpl#processResponse: received Exception. {}", ex.getCause());
+                }
+                if (ex instanceof InternalFunctionException) {
+                  Throwable cause = ex.getCause();
+                  DistributedMember memberID = (DistributedMember)((ArrayList)resultResponse)
+                      .get(1);
+                  this.resultCollector
+                      .addResult(memberID, cause);
+                  FunctionStats.getFunctionStats(this.functionId,
+                      this.executor.getRegion().getSystem())
+                      .incResultsReceived();
+                  continue;
+                }
+                else if (((FunctionException)result).getCause() instanceof InternalFunctionInvocationTargetException) {
+                  InternalFunctionInvocationTargetException ifite = (InternalFunctionInvocationTargetException)ex
+                      .getCause();
+                  this.failedNodes.addAll(ifite.getFailedNodeSet());
+                }
+                if (!ex.getMessage().equals("Buckets are null"))
+                  throw ex;
+
+                return null;
+              }
+              else if (result instanceof Throwable) {
+                String s = "While performing a remote " + getOpName();
+                throw new ServerOperationException(s, (Throwable)result);
+              }
+              else {
+                DistributedMember memberID = (DistributedMember)((ArrayList)resultResponse)
+                    .get(1);
+                synchronized (this.resultCollector) {
+                  this.resultCollector
+                      .addResult(memberID, result);
+                }
+                FunctionStats.getFunctionStats(this.functionId,
+                    this.executor.getRegion().getSystem()).incResultsReceived();
+              }
+            } while (!executeFunctionResponseMsg.isLastChunk());
+            if (isDebugEnabled) {
+              logger.debug("ExecuteRegionFunctionSingleHopOpImpl#processResponse: received all the results from server successfully.");
+            }
+            return null;
+            
+          case MessageType.EXCEPTION:
+            if (logger.isDebugEnabled()) {
+              logger.debug("ExecuteRegionFunctionSingleHopOpImpl#processResponse: received message of type EXCEPTION");
+            }
+            executeFunctionResponseMsg.receiveChunk();
+            Part part0 = executeFunctionResponseMsg.getPart(0);
+            Object obj = part0.getObject();
+
+            if (obj instanceof FunctionException) {
+              FunctionException ex = ((FunctionException)obj);
+              if (((FunctionException)obj).getCause() instanceof InternalFunctionInvocationTargetException) {
+                InternalFunctionInvocationTargetException ifite = (InternalFunctionInvocationTargetException)ex
+                    .getCause();
+                this.failedNodes.addAll(ifite.getFailedNodeSet());
+              }
+              if (!ex.getMessage().equals("Buckets are null")) {
+                throw ex;
+              }
+              return null;
+            }
+            else if (obj instanceof Throwable) {
+              String s = "While performing a remote " + getOpName();
+              throw new ServerOperationException(s, (Throwable)obj);
+            }
+            break;
+          case MessageType.EXECUTE_REGION_FUNCTION_ERROR:
+            if (logger.isDebugEnabled()) {
+              logger.debug("ExecuteRegionFunctionSingleHopOpImpl#processResponse: received message of type EXECUTE_REGION_FUNCTION_ERROR");
+            }
+            executeFunctionResponseMsg.receiveChunk();
+            String errorMessage = executeFunctionResponseMsg.getPart(0)
+                .getString();
+            throw new ServerOperationException(errorMessage);
+            
+          default:
+            throw new InternalGemFireError("Unknown message type "
+                + executeFunctionResponseMsg.getMessageType());
+        }
+      }
+      finally {
+        executeFunctionResponseMsg.clear();
+      }
+      return null;
+    }
+
+    ResultCollector getResultCollector() {
+      return this.resultCollector;
+    }
+
+    String getFunctionId() {
+      return this.functionId;
+    }
+
+    String getRegionName() {
+      return this.regionName;
+    }
+
+    ServerRegionFunctionExecutor getExecutor() {
+      return this.executor;
+    }
+
+    byte getHasResult() {
+      return this.hasResult;
+    }
+
+    boolean isHA() {
+      return this.isHA;
+    }
+
+     boolean optimizeForWrite() {
+      return this.optimizeForWrite;
+    }
+    
+    @Override
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.EXECUTE_REGION_FUNCTION_ERROR;
+    }
+
+    @Override
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startExecuteFunction();
+    }
+
+    protected String getOpName() {
+      return "executeRegionFunctionSingleHop";
+    }
+
+    @Override
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endExecuteFunctionSend(start, hasFailed());
+    }
+
+    @Override
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endExecuteFunction(start, hasTimedOut(), hasFailed());
+    }
+
+    @Override
+    protected Message createResponseMessage() {
+      return new ChunkedMessage(1, Version.CURRENT);
+    }
+
+  }
+}


[48/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/DataSerializer.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/DataSerializer.java b/gemfire-core/src/main/java/com/gemstone/gemfire/DataSerializer.java
new file mode 100644
index 0000000..e677593
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/DataSerializer.java
@@ -0,0 +1,3542 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+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.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Stack;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Vector;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.admin.RegionNotFoundException;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheFactory;
+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.ObjToByteArraySerializer;
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.cache.CachedDeserializable;
+import com.gemstone.gemfire.internal.cache.EventID;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+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.LogMarker;
+import com.gemstone.gemfire.pdx.PdxInstance;
+
+/**
+ * Provides static helper methods for reading and writing
+ * non-primitive data when working with a {@link DataSerializable}.
+ * For instance, classes that implement <code>DataSerializable</code>
+ * can use the <code>DataSerializer</code> in their
+ * <code>toData</code> and <code>fromData</code> methods:
+ *
+ * <!--
+ * The source code for the Employee class resides in
+ *         tests/com/examples/ds/Employee.java
+ * Please keep the below code snippet in sync with that file.
+ * -->
+ *
+ * <PRE>
+public class Employee implements DataSerializable {
+  private int id;
+  private String name;
+  private Date birthday;
+  private Company employer;
+
+  public void toData(DataOutput out) throws IOException {
+    out.writeInt(this.id);
+    out.writeUTF(this.name);
+    DataSerializer.writeDate(this.birthday, out);
+    DataSerializer.writeObject(this.employer, out);
+  }
+
+  public void fromData(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    this.id = in.readInt();
+    this.name = in.readUTF();
+    this.birthday = DataSerializer.readDate(in);
+    this.employer = (Company) DataSerializer.readObject(in);
+  }
+}
+
+ * </PRE>
+ *
+ * <P>
+ *
+ * Instances of <code>DataSerializer</code> are used to data serialize
+ * objects (such as instances of standard Java classes or third-party
+ * classes for which the source code is not available) that do not
+ * implement the <code>DataSerializable</code> interface.
+ *
+ * <P>
+ *
+ * The following <code>DataSerializer</code> data serializes instances
+ * of <code>Company</code>.  In order for the data serialization
+ * framework to consult this custom serializer, it must be {@linkplain
+ * #register(Class) registered} with the framework.
+ *
+ * <!--
+ * The source code for the CompanySerializer class resides in
+ *         tests/com/examples/ds/CompanySerializer.java
+ * Please keep the below code snippet in sync with that file.
+ * -->
+ *
+ * <PRE>
+public class CompanySerializer extends DataSerializer {
+
+  static {
+    DataSerializer.register(CompanySerializer.class);
+  }
+
+  &#47;**
+   * May be invoked reflectively if instances of Company are
+   * distributed to other VMs.
+   *&#47;
+  public CompanySerializer() {
+
+  }
+
+  public Class[] getSupportedClasses() {
+    return new Class[] { Company.class };
+  }
+  public int getId() {
+    return 42;
+  }
+
+  public boolean toData(Object o, DataOutput out)
+    throws IOException {
+    if (o instanceof Company) {
+      Company company = (Company) o;
+      out.writeUTF(company.getName());
+
+      // Let's assume that Address is java.io.Serializable
+      Address address = company.getAddress();
+      writeObject(address, out);
+      return true;
+
+    } else {
+      return false;
+    }
+  }
+
+  public Object fromData(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    String name = in.readUTF();
+    Address address = (Address) readObject(in);
+    return new Company(name, address);
+  }
+}
+ * </PRE>
+ *
+ * Just like {@link Instantiator}s, a <code>DataSerializer</code> may
+ * be sent to other members of the distributed system when it is
+ * {@linkplain #register(Class) registered}.  The data serialization
+ * framework does not require that a <code>DataSerializer</code> be
+ * {@link Serializable}, but it does require that it provide a
+ * {@linkplain #DataSerializer() zero-argument constructor}.
+ *
+ * @see #writeObject(Object, DataOutput)
+ * @see #readObject
+ *
+ * @author David Whitlock
+ * @since 3.5 */
+public abstract class DataSerializer {
+  
+  private static final Logger logger = LogService.getLogger();
+  
+  /** The eventId of this <code>DataSerializer</code> */
+  private EventID eventId;
+
+  /** The originator of this <code>DataSerializer</code> */
+  private ClientProxyMembershipID context;
+
+  protected static final boolean TRACE_SERIALIZABLE =
+    Boolean.getBoolean("DataSerializer.TRACE_SERIALIZABLE");
+
+  /* Used to prevent standard Java serialization when sending data to a non-Java client */
+  protected static final ThreadLocal<Boolean> DISALLOW_JAVA_SERIALIZATION = new ThreadLocal<Boolean>();
+
+  //////////////////////  Instance Fields  /////////////////////
+
+  //////////////////////  Static Methods  //////////////////////
+
+  /**
+   * Writes an instance of <code>Class</code> to a
+   * <code>DataOutput</code>.
+   * This method will handle a
+   * <code>null</code> value and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readClass
+   */
+  public static void writeClass(Class<?> c, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Class {}", c);
+    }
+
+    if (c == null || c.isPrimitive()) {
+      InternalDataSerializer.writePrimitiveClass(c, out);
+    }
+    else {
+      // non-primitive classes have a second CLASS byte
+      // if readObject/writeObject is called:
+      // the first CLASS byte indicates it's a Class, the second
+      // one indicates it's a non-primitive Class
+      out.writeByte(DSCODE.CLASS);
+      String cname = c.getName();
+      cname = swizzleClassNameForWrite(cname);
+      writeString(cname, out);
+    }
+  }
+
+  /**
+   * Writes class name to a <code>DataOutput</code>. This method will handle a
+   * <code>null</code> value and not throw a <code>NullPointerException</code>.
+   * 
+   * @throws IOException
+   *           A problem occurs while writing to <code>out</code>
+   * 
+   * @see #readNonPrimitiveClassName(DataInput)
+   */
+  public static void writeNonPrimitiveClassName(String className, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Class name {}", className);
+    }
+
+    writeString(swizzleClassNameForWrite(className), out);
+  }
+
+  /**
+   * Reads an instance of <code>Class</code> from a
+   * <code>DataInput</code>.  The class will be loaded using the
+   * {@linkplain Thread#getContextClassLoader current content class
+   * loader}.
+   * The return value may be <code>null</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class cannot be loaded
+   */
+  public static Class<?> readClass(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    byte typeCode = in.readByte();
+    if (typeCode == DSCODE.CLASS) {
+      String className = readString(in);
+      className = swizzleClassNameForRead(className);
+      Class<?> c = InternalDataSerializer.getCachedClass(className); // fix for bug 41206
+      return c;
+    }
+    else {
+      return InternalDataSerializer.decodePrimitiveClass(typeCode);
+    }
+  }
+  
+  /**
+   * For backward compatibility we must swizzle the package of
+   * some classes that had to be moved when GemFire was open-
+   * sourced.  This preserves backward-compatibility.
+   * 
+   * @param name the fully qualified class name
+   * @return the name of the class in this implementation
+   */
+  private static String swizzleClassNameForRead(String name) {
+    String oldPackage = "com.gemstone.org.jgroups.stack.tcpserver";
+    String newPackage = "com.gemstone.gemfire.distributed.internal.tcpserver";
+    String result = name;
+    if (name.startsWith(oldPackage)) {
+      result = newPackage + name.substring(oldPackage.length());
+    }
+    return result;
+  }
+  
+  /**
+   * For backward compatibility we must swizzle the package of
+   * some classes that had to be moved when GemFire was open-
+   * sourced.  This preserves backward-compatibility.
+   * 
+   * @param name the fully qualified class name
+   * @return the name of the class in this implementation
+   */
+  private static String swizzleClassNameForWrite(String name) {
+    String oldPackage = "com.gemstone.org.jgroups.stack.tcpserver";
+    String newPackage = "com.gemstone.gemfire.distributed.internal.tcpserver";
+    String result = name;
+    if (name.startsWith(newPackage)) {
+      result = oldPackage + name.substring(newPackage.length());
+    }
+    return result;
+  }
+  
+  /**
+   * Reads name of an instance of <code>Class</code> from a
+   * <code>DataInput</code>.
+   * 
+   * The return value may be <code>null</code>.
+   * 
+   * @throws IOException
+   *           A problem occurs while reading from <code>in</code>
+   * @see #writeNonPrimitiveClassName(String, DataOutput)
+   */
+  public static String readNonPrimitiveClassName(DataInput in)
+      throws IOException {
+
+    InternalDataSerializer.checkIn(in);
+
+    return swizzleClassNameForRead(readString(in));
+  }
+
+  /**
+   * Writes an instance of Region. A Region is serialized as just a reference
+   * to a full path only. It will be recreated on the other end by calling
+   * {@link CacheFactory#getAnyInstance} and then calling
+   * <code>getRegion</code> on it.
+   * This method will handle a
+   * <code>null</code> value and not throw a
+   * <code>NullPointerException</code>.
+   */
+  public static void writeRegion(Region<?,?> rgn, DataOutput out)
+  throws IOException {
+    writeString((rgn != null) ? rgn.getFullPath() : null, out);
+  }
+
+  /**
+   * Reads an instance of Region. A Region is serialized as a reference to a
+   * full path only. It is recreated on the other end by calling
+   * {@link CacheFactory#getAnyInstance} and then calling
+   * <code>getRegion</code> on it.
+   * The return value may be <code>null</code>.
+   *
+   * @param in the input stream
+   * @return the Region instance
+   * @throws com.gemstone.gemfire.cache.CacheClosedException if a cache has not been created or the only
+   * created one is closed.
+   * @throws RegionNotFoundException if there is no region by this name
+   * in the Cache
+   */
+  public static <K,V> Region<K,V> readRegion(DataInput in)
+  throws IOException, ClassNotFoundException {
+    String fullPath = readString(in);
+    Region<K,V> rgn = null;
+    if (fullPath != null) {
+      // use getExisting to fix bug 43151
+      rgn = ((Cache)GemFireCacheImpl.getExisting("Needed cache to find region.")).getRegion(fullPath);
+      if (rgn == null) {
+      throw new RegionNotFoundException(LocalizedStrings.DataSerializer_REGION_0_COULD_NOT_BE_FOUND_WHILE_READING_A_DATASERIALIZER_STREAM.toLocalizedString(fullPath));
+      }
+    }
+    return rgn;
+  }
+
+
+  /**
+   * Writes an instance of <code>Date</code> to a
+   * <code>DataOutput</code>.  Note that even though <code>date</code>
+   * may be an instance of a subclass of <code>Date</code>,
+   * <code>readDate</code> will always return an instance of
+   * <code>Date</code>, <B>not</B> an instance of the subclass.  To
+   * preserve the class type of <code>date</code>,\
+   * {@link #writeObject(Object, DataOutput)} should be used for data serialization.
+   * This method will handle a
+   * <code>null</code> value and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readDate
+   */
+  public static void writeDate(Date date, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Date {}", date);
+    }
+
+    long v;
+    if (date == null) {
+      v = -1L;
+    } else {
+      v = date.getTime();
+      if (v == -1L) {
+        throw new IllegalArgumentException("Dates whose getTime returns -1 can not be DataSerialized.");
+      }
+    }
+    out.writeLong(v);
+  }
+
+  /**
+   * Reads an instance of <code>Date</code> from a
+   * <code>DataInput</code>.
+   * The return value may be <code>null</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Date readDate(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    long time = in.readLong();
+    Date date = null;
+    if (time != -1L) {
+      date = new Date(time);
+    }
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Date {}", date);
+    }
+
+    return date;
+  }
+
+  /**
+   * Writes an instance of <code>File</code> to a
+   * <code>DataOutput</code>.  Note that even though <code>file</code>
+   * may be an instance of a subclass of <code>File</code>,
+   * <code>readFile</code> will always return an instance of
+   * <code>File</code>, <B>not</B> an instance of the subclass.  To
+   * preserve the class type of <code>file</code>,
+   * {@link #writeObject(Object, DataOutput)} should be used for data serialization.
+   * This method will handle a
+   * <code>null</code> value and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readFile
+   * @see File#getCanonicalPath
+   */
+  public static void writeFile(File file, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing File {}", file);
+    }
+
+    writeString((file != null) ? file.getCanonicalPath() : null, out);
+  }
+
+  /**
+   * Reads an instance of <code>File</code> from a
+   * <code>DataInput</code>.
+   * The return value may be <code>null</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static File readFile(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    String s = readString(in);
+    File file = null;
+    if (s != null) {
+      file = new File(s);
+    }
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read File {}", file);
+    }
+
+    return file;
+  }
+
+  /**
+   * Writes an instance of <code>InetAddress</code> to a
+   * <code>DataOutput</code>.  The <code>InetAddress</code> is data
+   * serialized by writing its {@link InetAddress#getAddress byte}
+   * representation to the <code>DataOutput</code>.  {@link
+   * #readInetAddress} converts the <code>byte</code> representation
+   * to an instance of <code>InetAddress</code> using {@link
+   * InetAddress#getAddress}.  As a result, if <code>address</code>
+   * is an instance of a user-defined subclass of
+   * <code>InetAddress</code> (that is, not an instance of one of the
+   * subclasses from the <code>java.net</code> package), its class
+   * will not be preserved.  In order to be able to read an instance
+   * of the user-defined class, {@link #writeObject(Object, DataOutput)} should be used.
+   * This method will handle a
+   * <code>null</code> value and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readInetAddress
+   */
+  public static void writeInetAddress(InetAddress address,
+                                      DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing InetAddress {}", address);
+    }
+
+    writeByteArray((address != null) ? address.getAddress() : null, out);
+  }
+
+  /**
+   * Reads an instance of <code>InetAddress</code> from a
+   * <code>DataInput</code>.
+   * The return value may be <code>null</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *         or the address read from <code>in</code> is unknown
+   *
+   * @see InetAddress#getAddress
+   */
+  public static InetAddress readInetAddress(DataInput in)
+    throws IOException {
+
+    InternalDataSerializer.checkIn(in);
+
+    byte[] address = readByteArray(in);
+    if (address == null) {
+      return null;
+    }
+
+    try {
+      InetAddress addr = InetAddress.getByAddress(address);
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read InetAddress {}", addr);
+      }
+      return addr;
+    } catch (UnknownHostException ex) {
+      IOException ex2 = new IOException(LocalizedStrings.DataSerializer_WHILE_READING_AN_INETADDRESS.toLocalizedString());
+      ex2.initCause(ex);
+      throw ex2;
+    }
+
+  }
+
+  /**
+   * Writes an instance of <code>String</code> to a
+   * <code>DataOutput</code>.
+   * This method will handle a
+   * <code>null</code> value and not throw a
+   * <code>NullPointerException</code>.
+   * <p>As of 5.7 strings longer than 0xFFFF can be serialized.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readString
+   */
+  public static void writeString(String value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    final boolean isDebugEnabled = logger.isTraceEnabled(LogMarker.SERIALIZER);
+    if (isDebugEnabled) {
+      logger.trace(LogMarker.SERIALIZER, "Writing String \"{}\"", value);
+    }
+
+    if (value == null) {
+      if (isDebugEnabled) {
+        logger.trace(LogMarker.SERIALIZER, "Writing NULL_STRING");
+      }
+      out.writeByte(DSCODE.NULL_STRING);
+
+    } else {
+      // [bruce] writeUTF is expensive - it creates a char[] to fetch
+      // the string's contents, iterates over the array to compute the
+      // encoded length, creates a byte[] to hold the encoded bytes,
+      // iterates over the char[] again to create the encode bytes,
+      // then writes the bytes.  Since we usually deal with ISO-8859-1
+      // strings, we can accelerate this by accessing chars directly
+      // with charAt and fill a single-byte buffer.  If we run into
+      // a multibyte char, we revert to using writeUTF()
+      int len = value.length();
+      int utfLen = len; // added for bug 40932
+      for (int i=0; i<len; i++) {
+        char c = value.charAt(i);
+        if ((c <= 0x007F) && (c >= 0x0001)) {
+          // nothing needed
+        } else if (c > 0x07FF) {
+          utfLen += 2;
+        } else {
+          utfLen += 1;
+        }
+        // Note we no longer have an early out when we detect the first
+        // non-ascii char because we need to compute the utfLen for bug 40932.
+        // This is not a performance problem because most strings are ascii
+        // and they never did the early out.
+      }
+      boolean writeUTF = utfLen > len;
+      if (writeUTF) {
+        if (utfLen > 0xFFFF) {
+          if (isDebugEnabled) {
+            logger.trace(LogMarker.SERIALIZER, "Writing utf HUGE_STRING of len={}", len);
+          }
+          out.writeByte(DSCODE.HUGE_STRING);
+          out.writeInt(len);
+          out.writeChars(value);
+        } else {
+          if (isDebugEnabled) {
+            logger.trace(LogMarker.SERIALIZER, "Writing utf STRING of len={}", len);
+          }
+          out.writeByte(DSCODE.STRING);
+          out.writeUTF(value);
+        }
+      }
+      else {
+        if (len > 0xFFFF) {
+          if (isDebugEnabled) {
+            logger.trace(LogMarker.SERIALIZER, "Writing HUGE_STRING_BYTES of len={}", len);
+          }
+          out.writeByte(DSCODE.HUGE_STRING_BYTES);
+          out.writeInt(len);
+          out.writeBytes(value);
+        } else {
+          if (isDebugEnabled) {
+            logger.trace(LogMarker.SERIALIZER, "Writing STRING_BYTES of len={}", len);
+          }
+          out.writeByte(DSCODE.STRING_BYTES);
+          out.writeShort(len);
+          out.writeBytes(value);
+        }
+      }
+    }
+  }
+
+  /**
+   * Reads an instance of <code>String</code> from a
+   * <code>DataInput</code>.  The return value may be
+   * <code>null</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeString
+   */
+  public static String readString(DataInput in) throws IOException {
+    return InternalDataSerializer.readString(in, in.readByte());
+  }
+
+  /**
+   * Writes an instance of <code>Boolean</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   * @throws NullPointerException if value is null.
+   *
+   * @see #readBoolean
+   */
+  public static void writeBoolean(Boolean value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Boolean {}", value);
+    }
+
+    out.writeBoolean(value.booleanValue());
+  }
+
+  /**
+   * Reads an instance of <code>Boolean</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Boolean readBoolean(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    Boolean value = Boolean.valueOf(in.readBoolean());
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Boolean {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes an instance of <code>Character</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   * @throws NullPointerException if value is null.
+   *
+   * @see #readCharacter
+   */
+  public static void writeCharacter(Character value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Character {}", value);
+    }
+
+    out.writeChar(value.charValue());
+  }
+
+  /**
+   * Reads an instance of <code>Character</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Character readCharacter(DataInput in)
+    throws IOException {
+
+    InternalDataSerializer.checkIn(in);
+
+    Character value = Character.valueOf(in.readChar());
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Character {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes an instance of <code>Byte</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   * @throws NullPointerException if value is null.
+   *
+   * @see #readByte
+   */
+  public static void writeByte(Byte value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Byte {}", value);
+    }
+
+    out.writeByte(value.byteValue());
+  }
+
+  /**
+   * Reads an instance of <code>Byte</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Byte readByte(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    Byte value = Byte.valueOf(in.readByte());
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Byte {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes an instance of <code>Short</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   * @throws NullPointerException if value is null.
+   *
+   * @see #readShort
+   */
+  public static void writeShort(Short value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Short {}", value);
+    }
+
+    out.writeShort(value.shortValue());
+  }
+
+  /**
+   * Reads an instance of <code>Short</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Short readShort(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    Short value = Short.valueOf(in.readShort());
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Short {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes an instance of <code>Integer</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   * @throws NullPointerException if value is null.
+   *
+   * @see #readInteger
+   */
+  public static void writeInteger(Integer value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Integer {}", value);
+    }
+
+    out.writeInt(value.intValue());
+  }
+
+  /**
+   * Reads an instance of <code>Integer</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Integer readInteger(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    Integer value = Integer.valueOf(in.readInt());
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Integer {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes an instance of <code>Long</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   * @throws NullPointerException if value is null.
+   *
+   * @see #readLong
+   */
+  public static void writeLong(Long value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Long {}", value);
+    }
+
+    out.writeLong(value.longValue());
+  }
+
+  /**
+   * Reads an instance of <code>Long</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Long readLong(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    Long value = Long.valueOf(in.readLong());
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Long {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes an instance of <code>Float</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   * @throws NullPointerException if value is null.
+   *
+   * @see #readFloat
+   */
+  public static void writeFloat(Float value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Float {}", value);
+    }
+
+    out.writeFloat(value.floatValue());
+  }
+
+  /**
+   * Reads an instance of <code>Float</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Float readFloat(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    Float value = Float.valueOf(in.readFloat());
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Float {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes an instance of <code>Double</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   * @throws NullPointerException if value is null.
+   *
+   * @see #readDouble
+   */
+  public static void writeDouble(Double value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Double {}", value);
+    }
+
+    out.writeDouble(value.doubleValue());
+  }
+
+  /**
+   * Reads an instance of <code>Double</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static Double readDouble(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    Double value = Double.valueOf(in.readDouble());
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Double {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive <code>boolean</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeBoolean
+   * @since 5.1
+   */
+  public static void writePrimitiveBoolean(boolean value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Boolean {}", value);
+    }
+
+    out.writeBoolean(value);
+  }
+
+  /**
+   * Reads a primitive <code>boolean</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @see DataInput#readBoolean
+   * @since 5.1
+   */
+  public static boolean readPrimitiveBoolean(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    boolean value = in.readBoolean();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Boolean {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive <code>byte</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeByte
+   * @since 5.1
+   */
+  public static void writePrimitiveByte(byte value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Byte {}", value);
+    }
+
+    out.writeByte(value);
+  }
+
+  /**
+   * Reads a primitive <code>byte</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @see DataInput#readByte
+   * @since 5.1
+   */
+  public static byte readPrimitiveByte(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    byte value = in.readByte();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Byte {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive  <code>char</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeChar
+   * @since 5.1
+   */
+  public static void writePrimitiveChar(char value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Char {}", value);
+    }
+
+    out.writeChar(value);
+  }
+
+  /**
+   * Reads a primitive <code>char</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @see DataInput#readChar
+   * @since 5.1
+   */
+  public static char readPrimitiveChar(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    char value = in.readChar();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Char {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive <code>short</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeShort
+   * @since 5.1
+   */
+  public static void writePrimitiveShort(short value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Short {}", value);
+    }
+
+    out.writeShort(value);
+  }
+
+  /**
+   * Reads a primitive <code>short</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @see DataInput#readShort
+   * @since 5.1
+   */
+  public static short readPrimitiveShort(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    short value = in.readShort();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Short {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive <code>int</code> as an unsigned byte to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeByte
+   * @see DataInput#readUnsignedByte
+   * @since 5.1
+   */
+  public static void writeUnsignedByte(int value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Unsigned Byte {}", value);
+    }
+
+    out.writeByte(value);
+  }
+
+  /**
+   * Reads a primitive <code>int</code> as an unsigned byte from a
+   * <code>DataInput</code> using {@link DataInput#readUnsignedByte}.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @since 5.1
+   */
+  public static int readUnsignedByte(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    int value = in.readUnsignedByte();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Unsigned Byte {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive <code>int</code> as an unsigned short to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeShort
+   * @see DataInput#readUnsignedShort
+   * @since 5.1
+   */
+  public static void writeUnsignedShort(int value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Unsigned Short {}", value);
+    }
+
+    out.writeShort(value);
+  }
+
+  /**
+   * Reads a primitive <code>int</code> as an unsigned short from a
+   * <code>DataInput</code> using {@link DataInput#readUnsignedShort}.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @since 5.1
+   */
+  public static int readUnsignedShort(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    int value = in.readUnsignedShort();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Unsigned Short {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive <code>int</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeInt
+   */
+  public static void writePrimitiveInt(int value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Integer {}", value);
+    }
+
+    out.writeInt(value);
+  }
+
+  /**
+   * Reads a primitive <code>int</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @see DataInput#readInt
+   * @since 5.1
+   */
+  public static int readPrimitiveInt(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    int value = in.readInt();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Integer {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive <code>long</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeLong
+   * @since 5.1
+   */
+  public static void writePrimitiveLong(long value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Long {}", value);
+    }
+
+    out.writeLong(value);
+  }
+
+  /**
+   * Reads a primitive <code>long</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @see DataInput#readLong
+   * @since 5.1
+   */
+  public static long readPrimitiveLong(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    long value = in.readLong();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Long {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primitive <code>float</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeFloat
+   * @since 5.1
+   */
+  public static void writePrimitiveFloat(float value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Float {}", value);
+    }
+
+    out.writeFloat(value);
+  }
+
+  /**
+   * Reads a primitive <code>float</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @see DataInput#readFloat
+   * @since 5.1
+   */
+  public static float readPrimitiveFloat(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    float value = in.readFloat();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Float {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes a primtive <code>double</code> to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see DataOutput#writeDouble
+   * @since 5.1
+   */
+  public static void writePrimitiveDouble(double value, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Double {}", value);
+    }
+
+    out.writeDouble(value);
+  }
+
+  /**
+   * Reads a primitive <code>double</code> from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @see DataInput#readDouble
+   * @since 5.1
+   */
+  public static double readPrimitiveDouble(DataInput in) throws IOException {
+    InternalDataSerializer.checkIn(in);
+
+    double value = in.readDouble();
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Read Double {}", value);
+    }
+    return value;
+  }
+
+  /**
+   * Writes an array of <code>byte</code>s to a
+   * <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readByteArray
+   */
+  public static void writeByteArray(byte[] array, DataOutput out)
+    throws IOException {
+    int len = 0;
+    if (array != null) {
+      len = array.length;
+    }
+    writeByteArray(array, len, out);
+  }
+
+  /**
+   * Writes the first <code>len</code> elements
+   * of an array of <code>byte</code>s to a
+   * <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @param len the actual number of entries to write. If len is greater
+   * than then length of the array then the entire array is written.
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readByteArray
+   */
+  public static void writeByteArray(byte[] array, int len, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int length = len; // to avoid warnings about parameter assignment
+    
+    if (array == null) {
+      length = -1;
+    } else {
+      if (length > array.length) {
+        length = array.length;
+      }
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing byte array of length {}", length);
+    }
+    if (length > 0) {
+      out.write(array, 0, length);
+    }
+  }
+  /**
+   * Serialize the given object <code>obj</code> into a byte array
+   * using {@link #writeObject(Object, DataOutput)} and then writes the byte array
+   * to the given data output <code>out</code> in the same format
+   * {@link #writeByteArray(byte[], DataOutput)} does.
+   * This method will serialize a
+   * <code>null</code> obj and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @param obj the object to serialize and write
+   * @param out the data output to write the byte array to
+   * @throws IllegalArgumentException
+   *         if a problem occurs while serialize <code>obj</code>
+   * @throws IOException
+   *         if a problem occurs while writing to <code>out</code>
+   *
+   * @see #readByteArray
+   * @since 5.0.2
+   */
+  public static void writeObjectAsByteArray(Object obj, DataOutput out)
+    throws IOException {
+    Object object = obj;
+    if (obj instanceof CachedDeserializable) {
+      object = ((CachedDeserializable) obj).getSerializedValue();
+    }
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      if (object == null) {
+        logger.trace(LogMarker.SERIALIZER, "writeObjectAsByteArray null");
+      } else {
+        logger.trace(LogMarker.SERIALIZER, "writeObjectAsByteArray obj.getClass={}", object.getClass());
+      }
+    }
+    if (object instanceof byte[] || object == null) {
+      writeByteArray((byte[])object, out);
+    } else if (out instanceof ObjToByteArraySerializer) {
+      ((ObjToByteArraySerializer)out).writeAsSerializedByteArray(object);
+    } else {
+      HeapDataOutputStream hdos;
+      if (object instanceof HeapDataOutputStream) {
+        hdos = (HeapDataOutputStream)object;
+      } else {
+        Version v = InternalDataSerializer.getVersionForDataStreamOrNull(out);
+        if (v == null) {
+          v = Version.CURRENT;
+        }
+        hdos = new HeapDataOutputStream(v);
+        try {
+          DataSerializer.writeObject(object, hdos);
+        } catch (IOException e) {
+          RuntimeException e2 = new IllegalArgumentException(LocalizedStrings.DataSerializer_PROBELM_WHILE_SERIALIZING.toLocalizedString());
+          e2.initCause(e);
+          throw e2;
+        }
+      }
+      InternalDataSerializer.writeArrayLength(hdos.size(), out);
+      hdos.sendTo(out);
+    }
+  }
+
+  /**
+   * Reads an array of <code>byte</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeByteArray(byte[], DataOutput)
+   */
+  public static byte[] readByteArray(DataInput in)
+    throws IOException {
+
+      InternalDataSerializer.checkIn(in);
+
+      int length = InternalDataSerializer.readArrayLength(in);
+      if (length == -1) {
+        return null;
+      } else {
+        byte[] array = new byte[length];
+        in.readFully(array, 0, length);
+
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+          logger.trace(LogMarker.SERIALIZER, "Read byte array of length {}", length);
+        }
+
+        return array;
+      }
+    }
+
+  /**
+   * Writes an array of <code>String</code>s to a
+   * <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readStringArray
+   * @see #writeString
+   */
+  public static void writeStringArray(String[] array, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int length;
+    if (array == null) {
+      length = -1;
+    } else {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing String array of length {}", length);
+    }
+    if (length > 0) {
+      for (int i = 0; i < length; i++) {
+        writeString(array[i], out);
+      }
+    }
+  }
+
+  /**
+   * Reads an array of <code>String</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeStringArray
+   */
+  public static String[] readStringArray(DataInput in)
+    throws IOException {
+
+      InternalDataSerializer.checkIn(in);
+
+      int length = InternalDataSerializer.readArrayLength(in);
+      if (length == -1) {
+        return null;
+      } else {
+        String[] array = new String[length];
+        for (int i = 0; i < length; i++) {
+          array[i] = readString(in);
+        }
+
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+          logger.trace(LogMarker.SERIALIZER, "Read String array of length {}", length);
+        }
+
+        return array;
+      }
+    }
+
+  /**
+   * Writes an array of <code>short</code>s to a
+   * <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readShortArray
+   */
+  public static void writeShortArray(short[] array, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int length;
+    if (array == null) {
+      length = -1;
+    } else {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing short array of length {}", length);
+    }
+    if (length > 0) {
+      for (int i = 0; i < length; i++) {
+        out.writeShort(array[i]);
+      }
+    }
+  }
+
+  /**
+   * Reads an array of <code>short</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeShortArray
+   */
+  public static short[] readShortArray(DataInput in)
+    throws IOException {
+
+      InternalDataSerializer.checkIn(in);
+
+      int length = InternalDataSerializer.readArrayLength(in);
+      if (length == -1) {
+        return null;
+      } else {
+        short[] array = new short[length];
+        for (int i = 0; i < length; i++) {
+          array[i] = in.readShort();
+        }
+
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+          logger.trace(LogMarker.SERIALIZER, "Read short array of length {}", length);
+        }
+
+        return array;
+      }
+    }
+
+  /**
+   * Writes an array of <code>char</code>s to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readCharArray
+   * @since 5.7
+   */
+  public static void writeCharArray(char[] array, DataOutput out)
+      throws IOException {
+
+    InternalDataSerializer.writeCharArray(array, array != null ? array.length
+        : -1, out);
+  }
+
+  /**
+   * Reads an array of <code>char</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeCharArray
+   * @since 5.7 
+   */
+  public static char[] readCharArray(DataInput in)
+    throws IOException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int length = InternalDataSerializer.readArrayLength(in);
+    if (length == -1) {
+      return null;
+    } else {
+      char[] array = new char[length];
+      for (int i = 0; i < length; i++) {
+        array[i] = in.readChar();
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read char array of length {}", length);
+      }
+
+      return array;
+    }
+  }
+  /**
+   * Writes an array of <code>boolean</code>s to a
+   * <code>DataOutput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readBooleanArray
+   * @since 5.7
+   */
+  public static void writeBooleanArray(boolean[] array, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int length;
+    if (array == null) {
+      length = -1;
+    } else {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing boolean array of length {}", length);
+    }
+    if (length > 0) {
+      for (int i = 0; i < length; i++) {
+        out.writeBoolean(array[i]);
+      }
+    }
+  }
+
+  /**
+   * Reads an array of <code>boolean</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeBooleanArray
+   * @since 5.7
+   */
+  public static boolean[] readBooleanArray(DataInput in)
+    throws IOException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int length = InternalDataSerializer.readArrayLength(in);
+    if (length == -1) {
+      return null;
+    } else {
+      boolean[] array = new boolean[length];
+      for (int i = 0; i < length; i++) {
+        array[i] = in.readBoolean();
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read boolean array of length {}", length);
+      }
+
+      return array;
+    }
+  }
+  /**
+   * Writes an <code>int</code> array to a <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readIntArray
+   */
+  public static void writeIntArray(int[] array, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int length;
+    if (array == null) {
+      length = -1;
+    } else {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing int array of length {}", length);
+    }
+    if (length > 0) {
+      for (int i = 0; i < length; i++) {
+        out.writeInt(array[i]);
+      }
+    }
+  }
+
+  /**
+   * Reads an <code>int</code> array from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeIntArray
+   */
+  public static int[] readIntArray(DataInput in)
+    throws IOException {
+
+      InternalDataSerializer.checkIn(in);
+
+      int length = InternalDataSerializer.readArrayLength(in);
+      if (length == -1) {
+        return null;
+      } else {
+        int[] array = new int[length];
+        for (int i = 0; i < length; i++) {
+          array[i] = in.readInt();
+        }
+
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+          logger.trace(LogMarker.SERIALIZER, "Read int array of length {}", length);
+        }
+
+        return array;
+      }
+    }
+
+  /**
+   * Writes an array of <code>long</code>s to a
+   * <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readLongArray
+   */
+  public static void writeLongArray(long[] array, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int length;
+    if (array == null) {
+      length = -1;
+    } else {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing long array of length {}", length);
+    }
+    if (length > 0) {
+      for (int i = 0; i < length; i++) {
+        out.writeLong(array[i]);
+      }
+    }
+  }
+
+  /**
+   * Reads an array of <code>long</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeLongArray
+   */
+  public static long[] readLongArray(DataInput in)
+    throws IOException {
+
+      InternalDataSerializer.checkIn(in);
+
+      int length = InternalDataSerializer.readArrayLength(in);
+      if (length == -1) {
+        return null;
+      } else {
+        long[] array = new long[length];
+        for (int i = 0; i < length; i++) {
+          array[i] = in.readLong();
+        }
+
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+          logger.trace(LogMarker.SERIALIZER, "Read long array of length {}", length);
+        }
+
+        return array;
+      }
+    }
+
+  /**
+   * Writes an array of <code>float</code>s to a
+   * <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readFloatArray
+   */
+  public static void writeFloatArray(float[] array, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int length;
+    if (array == null) {
+      length = -1;
+    } else {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing float array of length {}", length);
+    }
+    if (length > 0) {
+      for (int i = 0; i < length; i++) {
+        out.writeFloat(array[i]);
+      }
+    }
+  }
+
+  /**
+   * Reads an array of <code>float</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeFloatArray
+   */
+  public static float[] readFloatArray(DataInput in)
+    throws IOException {
+
+      InternalDataSerializer.checkIn(in);
+
+      int length = InternalDataSerializer.readArrayLength(in);
+      if (length == -1) {
+        return null;
+      } else {
+        float[] array = new float[length];
+        for (int i = 0; i < length; i++) {
+          array[i] = in.readFloat();
+        }
+
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+          logger.trace(LogMarker.SERIALIZER, "Read float array of length {}", length);
+        }
+
+        return array;
+      }
+    }
+
+  /**
+   * Writes an array of <code>double</code>s to a
+   * <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readDoubleArray
+   */
+  public static void writeDoubleArray(double[] array, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int length;
+    if (array == null) {
+      length = -1;
+    } else {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing double array of length {}", length);
+    }
+    if (length > 0) {
+      for (int i = 0; i < length; i++) {
+        out.writeDouble(array[i]);
+      }
+    }
+  }
+
+  /**
+   * Reads an array of <code>double</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeDoubleArray
+   */
+  public static double[] readDoubleArray(DataInput in)
+    throws IOException {
+
+      InternalDataSerializer.checkIn(in);
+
+      int length = InternalDataSerializer.readArrayLength(in);
+      if (length == -1) {
+        return null;
+      } else {
+        double[] array = new double[length];
+        for (int i = 0; i < length; i++) {
+          array[i] = in.readDouble();
+        }
+
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+          logger.trace(LogMarker.SERIALIZER, "Read double array of length {}", length);
+        }
+
+        return array;
+      }
+    }
+
+  /**
+   * Writes an array of <code>Object</code>s to a
+   * <code>DataOutput</code>.
+   * This method will serialize a
+   * <code>null</code> array and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readObjectArray
+   * @see #writeObject(Object, DataOutput)
+   */
+  public static void writeObjectArray(Object[] array, DataOutput out)
+    throws IOException {
+    InternalDataSerializer.writeObjectArray(array, out, false);
+  }
+  
+  /**
+   * Reads an array of <code>Object</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   *
+   * @see #writeObjectArray
+   * @see #readObject
+   */
+  public static Object[] readObjectArray(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+      InternalDataSerializer.checkIn(in);
+
+      int length = InternalDataSerializer.readArrayLength(in);
+      if (length == -1) {
+        return null;
+      } else {
+        Class<?> c = null;
+        byte typeCode = in.readByte();
+        String typeString = null;
+        if (typeCode == DSCODE.CLASS) {
+          typeString = readString(in);
+        }
+        
+        GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+        boolean lookForPdxInstance = false;
+        ClassNotFoundException cnfEx = null;
+        if (typeCode == DSCODE.CLASS
+            && cache != null && cache.getPdxReadSerializedByAnyGemFireServices()) {
+          try {
+            c = InternalDataSerializer.getCachedClass(typeString);
+            lookForPdxInstance = true;
+          } catch (ClassNotFoundException ignore) {
+            c = Object.class;
+            cnfEx = ignore;
+          }
+        } else {
+          if (typeCode == DSCODE.CLASS) {
+            c = InternalDataSerializer.getCachedClass(typeString);
+          } else {
+            c = InternalDataSerializer.decodePrimitiveClass(typeCode);
+          }
+        }
+        Object o = null;
+        if (length > 0) {
+          o = readObject(in);
+          if (lookForPdxInstance && o instanceof PdxInstance) {
+            lookForPdxInstance = false;
+            c = Object.class;
+          }
+        }
+        Object[] array = (Object[]) Array.newInstance(c, length);
+        if (length > 0) {
+          array[0] = o;
+        }
+        for (int i = 1; i < length; i++) {
+          o = readObject(in);
+          if (lookForPdxInstance && o instanceof PdxInstance) {
+            // create an Object[] and copy all the entries we already did into it
+            lookForPdxInstance = false;
+            c = Object.class;
+            Object[] newArray = (Object[])Array.newInstance(c, length);
+            System.arraycopy(array, 0, newArray, 0, i);
+            array = newArray;
+          }
+          array[i] = o;
+        }
+        if (lookForPdxInstance && cnfEx != null && length > 0) {
+          // We have a non-empty array and didn't find any
+          // PdxInstances in it. So we should have been able
+          // to load the element type.
+          // Note that empty arrays in this case will deserialize
+          // as an Object[] since we can't tell if the element
+          // type is a pdx one.
+          throw cnfEx;
+        }
+
+        if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+          logger.trace(LogMarker.SERIALIZER, "Read Object array of length {}", length);
+        }
+
+        return array;
+      }
+    }
+  
+  /**
+   * Writes an array of <tt>byte[]</tt> to a <tt>DataOutput</tt>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <tt>out</tt>.
+   *
+   */
+  public static void writeArrayOfByteArrays(byte[][] array, DataOutput out)
+  throws IOException {    
+    
+    InternalDataSerializer.checkOut(out);
+    int length;
+    if (array == null) {
+      length = -1;
+    }
+    else {
+      length = array.length;
+    }
+    InternalDataSerializer.writeArrayLength(length, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing byte[][] of length {}", length);
+    }
+    if (length >= 0) {
+      for (int i = 0; i < length; i++) {
+        writeByteArray(array[i], out);
+      }
+    }
+  }
+  
+  /**
+   * Reads an array of <code>byte[]</code>s from a
+   * <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   */
+  public static byte[][] readArrayOfByteArrays(DataInput in)
+  throws IOException, ClassNotFoundException {
+    
+    InternalDataSerializer.checkIn(in);
+    
+    int length = InternalDataSerializer.readArrayLength(in);
+    if (length == -1) {
+      return null;
+    } else {
+      byte[][] array = new byte[length][];
+      for (int i = 0; i < length; i++) {
+        array[i] = readByteArray(in);
+      }
+      
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read byte[][] of length {}", length);
+      }
+      
+      return array;
+    }
+  }
+  
+  
+  /**
+   * Writes an <code>ArrayList</code> to a <code>DataOutput</code>.
+   * Note that even though <code>list</code> may be an instance of a
+   * subclass of <code>ArrayList</code>, <code>readArrayList</code>
+   * will always return an instance of <code>ArrayList</code>,
+   * <B>not</B> an instance of the subclass.  To preserve the class
+   * type of <code>list</code>, {@link #writeObject(Object, DataOutput)} should be used
+   * for data serialization.
+   * This method will serialize a
+   * <code>null</code> list and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readArrayList
+   */
+  public static void writeArrayList(ArrayList<?> list, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int size;
+    if (list == null) {
+      size = -1;
+    } else {
+      size = list.size();
+    }
+    InternalDataSerializer.writeArrayLength(size, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing ArrayList with {} elements: {}", size, list);
+    }
+    if (size > 0) {
+      for (int i=0; i < size; i++) {
+        writeObject(list.get(i), out);
+      }
+    }
+  }
+  
+  
+
+  /**
+   * Reads an <code>ArrayList</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>ArrayList</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeArrayList
+   */
+  public static <E> ArrayList<E> readArrayList(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      ArrayList<E> list = new ArrayList<E>(size);
+      for (int i = 0; i < size; i++) {
+        E element = DataSerializer.<E>readObject(in);
+        list.add(element);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read ArrayList with {} elements: {}", size, list);
+      }
+
+      return list;
+    }
+  }
+
+  /**
+   * Writes an <code>Vector</code> to a <code>DataOutput</code>.
+   * Note that even though <code>list</code> may be an instance of a
+   * subclass of <code>Vector</code>, <code>readVector</code>
+   * will always return an instance of <code>Vector</code>,
+   * <B>not</B> an instance of the subclass.  To preserve the class
+   * type of <code>list</code>, {@link #writeObject(Object, DataOutput)} should be used
+   * for data serialization.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readVector
+   * @since 5.7
+   */
+  public static void writeVector(Vector<?> list, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int size;
+    if (list == null) {
+      size = -1;
+    } else {
+      size = list.size();
+    }
+    InternalDataSerializer.writeArrayLength(size, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Vector with {} elements: {}", size, list);
+    }
+    if (size > 0) {
+      for (int i=0; i < size; i++) {
+        writeObject(list.get(i), out);
+      }
+    }
+  }
+
+  /**
+   * Reads an <code>Vector</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>Vector</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeVector
+   * @since 5.7
+   */
+  public static <E> Vector<E> readVector(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      Vector<E> list = new Vector<E>(size);
+      for (int i = 0; i < size; i++) {
+        E element = DataSerializer.<E>readObject(in);
+        list.add(element);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read Vector with {} elements: {}", size, list);
+      }
+
+      return list;
+    }
+  }
+
+  /**
+   * Writes an <code>Stack</code> to a <code>DataOutput</code>.
+   * Note that even though <code>list</code> may be an instance of a
+   * subclass of <code>Stack</code>, <code>readStack</code>
+   * will always return an instance of <code>Stack</code>,
+   * <B>not</B> an instance of the subclass.  To preserve the class
+   * type of <code>list</code>, {@link #writeObject(Object, DataOutput)} should be used
+   * for data serialization.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readStack
+   * @since 5.7
+   */
+  public static void writeStack(Stack<?> list, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int size;
+    if (list == null) {
+      size = -1;
+    } else {
+      size = list.size();
+    }
+    InternalDataSerializer.writeArrayLength(size, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Stack with {} elements: {}", size, list);
+    }
+    if (size > 0) {
+      for (int i=0; i < size; i++) {
+        writeObject(list.get(i), out);
+      }
+    }
+  }
+
+  /**
+   * Reads an <code>Stack</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>Stack</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeStack
+   * @since 5.7
+   */
+  public static <E> Stack<E> readStack(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      Stack<E> list = new Stack<E>();
+      for (int i = 0; i < size; i++) {
+        E element = DataSerializer.<E>readObject(in);
+        list.add(element);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read Stack with {} elements: {}", size, list);
+      }
+
+      return list;
+    }
+  }
+
+  /**
+   * Writes an <code>LinkedList</code> to a <code>DataOutput</code>.
+   * Note that even though <code>list</code> may be an instance of a
+   * subclass of <code>LinkedList</code>, <code>readLinkedList</code>
+   * will always return an instance of <code>LinkedList</code>,
+   * <B>not</B> an instance of the subclass.  To preserve the class
+   * type of <code>list</code>, {@link #writeObject(Object, DataOutput)} should be used
+   * for data serialization.
+   * This method will serialize a
+   * <code>null</code> list and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readLinkedList
+   */
+  public static void writeLinkedList(LinkedList<?> list, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int size;
+    if (list == null) {
+      size = -1;
+    } else {
+      size = list.size();
+    }
+    InternalDataSerializer.writeArrayLength(size, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing LinkedList with {} elements: {}", size, list);
+    }
+    if (size > 0) {
+      for (Object e: list) {
+        writeObject(e, out);
+      }
+    }
+  }
+
+  /**
+   * Reads an <code>LinkedList</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>LinkedList</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeLinkedList
+   */
+  public static <E> LinkedList<E> readLinkedList(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      LinkedList<E> list = new LinkedList<E>();
+      for (int i = 0; i < size; i++) {
+        E element = DataSerializer.<E>readObject(in);
+        list.add(element);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read LinkedList with {} elements: {}", size, list);
+      }
+
+      return list;
+    }
+  }
+
+  /**
+   * Writes a <code>HashSet</code> to a <code>DataOutput</code>.  Note
+   * that even though <code>set</code> may be an instance of a
+   * subclass of <code>HashSet</code>, <code>readHashSet</code> will
+   * always return an instance of <code>HashSet</code>, <B>not</B> an
+   * instance of the subclass.  To preserve the class type of
+   * <code>set</code>, {@link #writeObject(Object, DataOutput)} should be used for data
+   * serialization.
+   * This method will serialize a
+   * <code>null</code> set and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readHashSet
+   */
+  public static void writeHashSet(HashSet<?> set, DataOutput out)
+    throws IOException {
+    InternalDataSerializer.writeSet(set, out);
+  }
+
+  /**
+   * Reads a <code>HashSet</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>HashSet</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeHashSet
+   */
+  public static <E> HashSet<E> readHashSet(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      HashSet<E> set = new HashSet<E>(size);
+      for (int i = 0; i < size; i++) {
+        E element = DataSerializer.<E>readObject(in);
+        set.add(element);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read HashSet with {} elements: {}", size, set);
+      }
+
+      return set;
+    }
+  }
+
+  /**
+   * Writes a <code>LinkedHashSet</code> to a <code>DataOutput</code>.  Note
+   * that even though <code>set</code> may be an instance of a
+   * subclass of <code>LinkedHashSet</code>, <code>readLinkedHashSet</code> will
+   * always return an instance of <code>LinkedHashSet</code>, <B>not</B> an
+   * instance of the subclass.  To preserve the class type of
+   * <code>set</code>, {@link #writeObject(Object, DataOutput)} should be used for data
+   * serialization.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readLinkedHashSet
+   * @since 5.7
+   */
+  public static void writeLinkedHashSet(LinkedHashSet<?> set, DataOutput out)
+    throws IOException {
+    InternalDataSerializer.writeSet(set, out);
+  }
+
+  /**
+   * Reads a <code>LinkedHashSet</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>LinkedHashSet</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeLinkedHashSet
+   * @since 5.7
+   */
+  public static <E> LinkedHashSet<E> readLinkedHashSet(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      LinkedHashSet<E> set = new LinkedHashSet<E>(size);
+      for (int i = 0; i < size; i++) {
+        E element = DataSerializer.<E>readObject(in);
+        set.add(element);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read LinkedHashSet with {} elements: {}", size, set);
+      }
+
+      return set;
+    }
+  }
+
+  /**
+   * Writes a <code>HashMap</code> to a <code>DataOutput</code>.  Note
+   * that even though <code>map</code> may be an instance of a
+   * subclass of <code>HashMap</code>, <code>readHashMap</code> will
+   * always return an instance of <code>HashMap</code>, <B>not</B> an
+   * instance of the subclass.  To preserve the class type of
+   * <code>map</code>, {@link #writeObject(Object, DataOutput)} should be used for data
+   * serialization.
+   * This method will serialize a
+   * <code>null</code> map and not throw a
+   * <code>NullPointerException</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readHashMap
+   */
+  public static void writeHashMap(HashMap<?,?> map, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int size;
+    if (map == null) {
+      size = -1;
+    } else {
+      size = map.size();
+    }
+    InternalDataSerializer.writeArrayLength(size, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing HashMap with {} elements: {}", size, map);
+    }
+    if (size > 0) {
+      for (Map.Entry<?,?> entry: map.entrySet()) {
+        writeObject(entry.getKey(), out);
+        writeObject(entry.getValue(), out);
+      }
+    }
+  }
+
+  /**
+   * Reads a <code>HashMap</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>HashMap</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeHashMap
+   */
+  public static <K,V> HashMap<K,V> readHashMap(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      HashMap<K,V> map = new HashMap<K,V>(size);
+      for (int i = 0; i < size; i++) {
+        K key = DataSerializer.<K>readObject(in);
+        V value = DataSerializer.<V>readObject(in);
+        map.put(key, value);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read HashMap with {} elements: {}", size, map);
+      }
+
+      return map;
+    }
+  }
+
+  /**
+   * Writes a <code>IdentityHashMap</code> to a <code>DataOutput</code>.  Note
+   * that even though <code>map</code> may be an instance of a
+   * subclass of <code>IdentityHashMap</code>, <code>readIdentityHashMap</code> will
+   * always return an instance of <code>IdentityHashMap</code>, <B>not</B> an
+   * instance of the subclass.  To preserve the class type of
+   * <code>map</code>, {@link #writeObject(Object, DataOutput)} should be used for data
+   * serialization.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readIdentityHashMap
+   */
+  public static void writeIdentityHashMap(IdentityHashMap<?,?> map, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int size;
+    if (map == null) {
+      size = -1;
+    } else {
+      size = map.size();
+    }
+    InternalDataSerializer.writeArrayLength(size, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing IdentityHashMap with {} elements: {}", size, map);
+    }
+    if (size > 0) {
+      for (Map.Entry<?,?> entry: map.entrySet()){
+        writeObject(entry.getKey(), out);
+        writeObject(entry.getValue(), out);
+      }
+    }
+  }
+
+  /**
+   * Reads a <code>IdentityHashMap</code> from a <code>DataInput</code>.
+   * Note that key identity is not preserved unless the keys belong to a class
+   * whose serialization preserves identity.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>IdentityHashMap</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeIdentityHashMap
+   */
+  public static <K,V> IdentityHashMap<K,V> readIdentityHashMap(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      IdentityHashMap<K,V> map = new IdentityHashMap<K,V>(size);
+      for (int i = 0; i < size; i++) {
+        K key = DataSerializer.<K>readObject(in);
+        V value = DataSerializer.<V>readObject(in);
+        map.put(key, value);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read IdentityHashMap with {} elements: {}", size, map);
+      }
+
+      return map;
+    }
+  }
+
+  /**
+   * Writes a <code>ConcurrentHashMap</code> to a <code>DataOutput</code>.  Note
+   * that even though <code>map</code> may be an instance of a
+   * subclass of <code>ConcurrentHashMap</code>, <code>readConcurrentHashMap</code> will
+   * always return an instance of <code>ConcurrentHashMap</code>, <B>not</B> an
+   * instance of the subclass.  To preserve the class type of
+   * <code>map</code>, {@link #writeObject(Object, DataOutput)} should be used for data
+   * serialization.
+   * <P>At this time if {@link #writeObject(Object, DataOutput)} is called with an instance
+   * of ConcurrentHashMap then it will be serialized with normal java.io Serialization. So
+   * if you want the keys and values of a ConcurrentHashMap to take advantage of GemFire serialization
+   * it must be serialized with this method.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readConcurrentHashMap
+   * @since 6.6
+   */
+  public static void writeConcurrentHashMap(ConcurrentHashMap<?,?> map, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int size;
+    Collection<Map.Entry<?,?>> entrySnapshot = null;
+    if (map == null) {
+      size = -1;
+    } else {
+      // take a snapshot to fix bug 44562
+      entrySnapshot = new ArrayList<Map.Entry<?,?>>(map.entrySet());
+      size = entrySnapshot.size();
+    }
+    InternalDataSerializer.writeArrayLength(size, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing ConcurrentHashMap with {} elements: {}", size, entrySnapshot);
+    }
+    if (size > 0) {
+      for (Map.Entry<?,?> entry: entrySnapshot) {
+        writeObject(entry.getKey(), out);
+        writeObject(entry.getValue(), out);
+      }
+    }
+  }
+
+  /**
+   * Reads a <code>ConcurrentHashMap</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>ConcurrentHashMap</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeConcurrentHashMap
+   * @since 6.6
+   */
+  public static <K,V> ConcurrentHashMap<K,V> readConcurrentHashMap(DataInput in)
+    throws IOException, ClassNotFoundException {
+
+    InternalDataSerializer.checkIn(in);
+
+    int size = InternalDataSerializer.readArrayLength(in);
+    if (size == -1) {
+      return null;
+    } else {
+      ConcurrentHashMap<K,V> map = new ConcurrentHashMap<K,V>(size);
+      for (int i = 0; i < size; i++) {
+        K key = DataSerializer.<K>readObject(in);
+        V value = DataSerializer.<V>readObject(in);
+        map.put(key, value);
+      }
+
+      if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+        logger.trace(LogMarker.SERIALIZER, "Read ConcurrentHashMap with {} elements: {}", size, map);
+      }
+
+      return map;
+    }
+  }
+
+  /**
+   * Writes a <code>Hashtable</code> to a <code>DataOutput</code>.  Note
+   * that even though <code>map</code> may be an instance of a
+   * subclass of <code>Hashtable</code>, <code>readHashtable</code> will
+   * always return an instance of <code>Hashtable</code>, <B>not</B> an
+   * instance of the subclass.  To preserve the class type of
+   * <code>map</code>, {@link #writeObject(Object, DataOutput)} should be used for data
+   * serialization.
+   *
+   * @throws IOException
+   *         A problem occurs while writing to <code>out</code>
+   *
+   * @see #readHashtable
+   * @since 5.7
+   */
+  public static void writeHashtable(Hashtable<?,?> map, DataOutput out)
+    throws IOException {
+
+    InternalDataSerializer.checkOut(out);
+
+    int size;
+    if (map == null) {
+      size = -1;
+    } else {
+      size = map.size();
+    }
+    InternalDataSerializer.writeArrayLength(size, out);
+    if (logger.isTraceEnabled(LogMarker.SERIALIZER)) {
+      logger.trace(LogMarker.SERIALIZER, "Writing Hashtable with {} elements: {}", size, map);
+    }
+    if (size > 0) {
+      for (Map.Entry<?,?> entry: map.entrySet()) {
+        writeObject(entry.getKey(), out);
+        writeObject(entry.getValue(), out);
+      }
+    }
+  }
+
+  /**
+   * Reads a <code>Hashtable</code> from a <code>DataInput</code>.
+   *
+   * @throws IOException
+   *         A problem occurs while reading from <code>in</code>
+   * @throws ClassNotFoundException
+   *         The class of one of the <Code>Hashtable</code>'s
+   *         elements cannot be found.
+   *
+   * @see #writeHashtable
+   * @since 5.7
+   */
+  public static <K,V> Hashtable<K,V> readHashtable(DataInput in)

<TRUNCATED>

[04/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ServerRegionProxy.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ServerRegionProxy.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ServerRegionProxy.java
new file mode 100644
index 0000000..a1cf4ba
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ServerRegionProxy.java
@@ -0,0 +1,894 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.Collection;
+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.cache.CacheLoader;
+import com.gemstone.gemfire.cache.CacheWriter;
+import com.gemstone.gemfire.cache.DataPolicy;
+import com.gemstone.gemfire.cache.InterestResultPolicy;
+import com.gemstone.gemfire.cache.Operation;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.Region.Entry;
+import com.gemstone.gemfire.cache.client.PoolManager;
+import com.gemstone.gemfire.cache.client.internal.ContainsKeyOp.MODE;
+import com.gemstone.gemfire.cache.execute.Function;
+import com.gemstone.gemfire.cache.execute.ResultCollector;
+import com.gemstone.gemfire.cache.util.BridgeClient;
+import com.gemstone.gemfire.cache.util.BridgeLoader;
+import com.gemstone.gemfire.cache.util.BridgeWriter;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.cache.AbstractRegion;
+import com.gemstone.gemfire.internal.cache.BridgeObserver;
+import com.gemstone.gemfire.internal.cache.BridgeObserverHolder;
+import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+import com.gemstone.gemfire.internal.cache.EventID;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+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.execute.ServerRegionFunctionExecutor;
+import com.gemstone.gemfire.internal.cache.tier.InterestType;
+import com.gemstone.gemfire.internal.cache.tier.sockets.VersionedObjectList;
+import com.gemstone.gemfire.internal.cache.tier.sockets.VersionedObjectList.Iterator;
+import com.gemstone.gemfire.internal.cache.tx.ClientTXStateStub;
+import com.gemstone.gemfire.internal.cache.tx.TransactionalOperation.ServerRegionOperation;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+
+/**
+ * Used to send region operations from a client to a server
+ * @author darrel
+ * @since 5.7
+ */
+@SuppressWarnings("deprecation")
+public class ServerRegionProxy extends ServerProxy implements ServerRegionDataAccess {
+  private static final Logger logger = LogService.getLogger();
+  
+  private final LocalRegion region;
+  private final String regionName;
+
+  
+  /**
+   * Creates a server region proxy for the given region.
+   * @param r the region
+   * @throws IllegalStateException if the region does not have a pool
+   */
+  public ServerRegionProxy(Region r) {
+    super(calcPool(r));
+    assert r instanceof LocalRegion;
+    this.region = (LocalRegion)r;
+    this.regionName = r.getFullPath();
+  }
+  /**
+   * Used by tests to create proxies for "fake" regions.
+   * Also, used by ClientStatsManager for admin region.
+   */
+  public ServerRegionProxy(String regionName, PoolImpl pool) {
+    super(pool);
+    this.region = null;
+    this.regionName = regionName;
+  }
+  
+  private static InternalPool calcPool(Region r) {
+    String poolName = r.getAttributes().getPoolName();
+    if (poolName == null || "".equals(poolName)) {
+      final CacheLoader cl = r.getAttributes().getCacheLoader();
+      final CacheWriter cw = r.getAttributes().getCacheWriter();
+      if (AbstractRegion.isBridgeLoader(cl) || AbstractRegion.isBridgeWriter(cw)) {
+        Object loaderPool = null;
+        Object writerPool = null;
+        if (AbstractRegion.isBridgeLoader(cl)) {
+          if (cl instanceof BridgeLoader) {
+            loaderPool = ((BridgeLoader)cl).getConnectionProxy();
+          } else {
+            loaderPool = ((BridgeClient)cl).getConnectionProxy();
+          }
+        }
+        if (AbstractRegion.isBridgeWriter(cw)) {
+          writerPool = ((BridgeWriter)cw).getConnectionProxy();
+        }
+        if (loaderPool != writerPool && loaderPool != null && writerPool != null) {
+          throw new IllegalStateException("The region " + r.getFullPath()
+                                          + " has a BridgeLoader and a BridgeWriter/BridgeClient "
+                                          + " that are configured with different connection pools. "
+                                          + " This is not allowed. Instead create a single BridgeClient and install it as both the loader and the writer."
+                                          + " loaderPool="+loaderPool + " writerPool=" + writerPool);
+        }
+        InternalPool result = (InternalPool)loaderPool;
+        if (result == null) {
+          result = (InternalPool)writerPool;
+        }
+        return result;
+      } else {
+        throw new IllegalStateException("The region " + r.getFullPath()
+                                        + " did not have a client pool configured.");
+      }
+    } else {
+      InternalPool pool = (InternalPool)PoolManager.find(poolName);
+      if (pool == null) {
+        throw new IllegalStateException("The pool " + poolName
+                                        + " does not exist.");
+      }
+      return pool;
+    }
+  }
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.ServerRegionDataAccess#get(java.lang.Object, java.lang.Object)
+   */
+  public Object get(Object key, Object callbackArg, EntryEventImpl clientEvent) {
+    recordTXOperation(ServerRegionOperation.GET, key, callbackArg);
+    return GetOp.execute(this.pool, this.region, key, callbackArg, this.pool.getPRSingleHopEnabled(), clientEvent);
+  }
+
+  
+  
+  public int size() {
+    return SizeOp.execute(this.pool, this.regionName);
+  }
+  
+  /**
+   * Do not call this method if the value is Delta instance. Exclicitly passing
+   * <code>Operation.CREATE</code> to the <code>PutOp.execute()</code>
+   * method as the caller of this method does not put Delta instances as value.
+   * 
+   * @param key
+   * @param value
+   * @param event
+   * @param callbackArg
+   */
+  public Object putForMetaRegion(Object key,
+                  Object value,
+                  byte[] deltaBytes,
+                  EntryEventImpl event,
+                  Object callbackArg,
+                  boolean isMetaRegionPutOp)
+  {
+    if (this.region == null) {
+      return PutOp.execute(this.pool, this.regionName, key, value, deltaBytes, event,
+          Operation.CREATE,
+          false, null,
+          callbackArg, this.pool.getPRSingleHopEnabled(),
+          isMetaRegionPutOp);
+    } else {
+      return PutOp.execute(this.pool, this.region, key, value, deltaBytes,
+          event, Operation.CREATE, false, null, callbackArg, this.pool
+              .getPRSingleHopEnabled());
+    }
+  }
+
+  public Object put(Object key,
+                  Object value,
+                  byte[] deltaBytes,
+                  EntryEventImpl event,
+                  Operation op,
+                  boolean requireOldValue, Object expectedOldValue,
+                  Object callbackArg,
+                  boolean isCreate)
+  {
+    recordTXOperation(ServerRegionOperation.PUT, key, value, deltaBytes,
+        event.getEventId(), op, Boolean.valueOf(requireOldValue), expectedOldValue,
+        callbackArg, Boolean.valueOf(isCreate));
+    Operation operation = op;
+    if (!isCreate && this.region.getDataPolicy() == DataPolicy.EMPTY
+        && op.isCreate() && op != Operation.PUT_IF_ABSENT) {
+      operation = Operation.UPDATE;
+    }
+
+    if (this.region == null) {
+      return PutOp.execute(this.pool, this.regionName, key, value, deltaBytes,
+          event, operation, requireOldValue, expectedOldValue, callbackArg,
+          this.pool.getPRSingleHopEnabled(), false);
+    }
+    else {
+      return PutOp.execute(this.pool, this.region, key, value, deltaBytes,
+          event, operation, requireOldValue, expectedOldValue, callbackArg,
+          this.pool.getPRSingleHopEnabled());
+    }
+  }
+  
+  
+  /**
+   * Does a region put on the server using the given connection.
+   * @param con the connection to use to send to the server
+   * @param key the entry key to do the put on
+   * @param value the entry value to put
+   * @param eventId the event ID for this put
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   */
+  public void putOnForTestsOnly(Connection con,
+                    Object key,
+                    Object value,
+                    EventID eventId,
+                    Object callbackArg)
+  {
+    EntryEventImpl event = new EntryEventImpl(eventId);
+    PutOp.execute(con, this.pool, this.regionName, key, value, event, callbackArg, this.pool.getPRSingleHopEnabled());
+  }
+  
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.ServerRegionDataAccess#destroy(java.lang.Object, java.lang.Object, com.gemstone.gemfire.cache.Operation, com.gemstone.gemfire.internal.cache.EventID, java.lang.Object)
+   */
+  public Object destroy(Object key,
+                      Object expectedOldValue,
+                      Operation operation,
+                      EntryEventImpl event,
+                      Object callbackArg)
+  {
+    if (event.isBulkOpInProgress()) {
+      // this is a removeAll, ignore this!
+      return null;
+    }
+    recordTXOperation(ServerRegionOperation.DESTROY, key, expectedOldValue, operation, event.getEventId(), callbackArg);
+    return DestroyOp.execute(this.pool, this.region, key, expectedOldValue,
+        operation, event, callbackArg, this.pool.getPRSingleHopEnabled());
+    }
+  
+  
+  public void invalidate(EntryEventImpl event) {
+    recordTXOperation(ServerRegionOperation.INVALIDATE, event.getKey(), event);
+    InvalidateOp.execute(this.pool, this.region.getFullPath(),
+        event);
+  }
+  
+  
+  /**
+   * Does a region entry destroy on the server using the given connection.
+   * @param con the connection to use to send to the server
+   * @param key the entry key to do the destroy on
+   * @param expectedOldValue the value that the entry must have to perform the operation, or null
+   * @param operation the operation being performed (Operation.DESTROY, Operation.REMOVE)
+   * @param event the event for this destroy operation
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   */
+  public void destroyOnForTestsOnly(Connection con,
+                        Object key,
+                        Object expectedOldValue,
+                        Operation operation,
+                        EntryEventImpl event,
+                        Object callbackArg)
+  {
+    DestroyOp.execute(con, this.pool, this.regionName, key, 
+        expectedOldValue, operation, event, callbackArg);
+  }
+  /**
+   * Does a region destroy on the server
+   * @param eventId the event id for this destroy
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   */
+  public void destroyRegion(EventID eventId,
+                            Object callbackArg)
+  {
+    DestroyRegionOp.execute(this.pool, this.regionName, eventId, callbackArg);
+  }
+  /**
+   * Does a region destroy on the server using the given connection.
+   * @param con the connection to use to send to the server
+   * @param eventId the event id for this destroy
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   */
+  public void destroyRegionOnForTestsOnly(Connection con,
+                              EventID eventId,
+                              Object callbackArg)
+  {
+    DestroyRegionOp.execute(con, this.pool, this.regionName, eventId, callbackArg);
+  }
+  
+  public TXCommitMessage commit(int txId) {
+    TXCommitMessage tx = CommitOp.execute(this.pool,txId);
+    return tx;
+  }
+
+  public void rollback(int txId) {
+    RollbackOp.execute(this.pool, txId);
+  }
+  
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.ServerRegionDataAccess#clear(com.gemstone.gemfire.internal.cache.EventID, java.lang.Object)
+   */
+  public void clear(EventID eventId,
+                    Object callbackArg)
+  {
+    ClearOp.execute(this.pool, this.regionName, eventId, callbackArg);
+  }
+  
+  /**
+   * Does a region clear on the server using the given connection.
+   * @param con the connection to use to send to the server
+   * @param eventId the event id for this clear
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   */
+  public void clearOnForTestsOnly(Connection con,
+                      EventID eventId,
+                      Object callbackArg)
+  {
+    ClearOp.execute(con, this.pool, this.regionName, eventId, callbackArg);
+  }
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.ServerRegionDataAccess#containsKey(java.lang.Object)
+   */
+  public boolean containsKey(Object key) {
+    recordTXOperation(ServerRegionOperation.CONTAINS_KEY, key);
+    return ContainsKeyOp.execute(this.pool, this.regionName, key,MODE.KEY);
+  }
+  
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.ServerRegionDataAccess#containsKey(java.lang.Object)
+   */
+  public boolean containsValueForKey(Object key) {
+    recordTXOperation(ServerRegionOperation.CONTAINS_VALUE_FOR_KEY, key);
+    return ContainsKeyOp.execute(this.pool, this.regionName, key,MODE.VALUE_FOR_KEY);
+  }
+  
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.ServerRegionDataAccess#containsKey(java.lang.Object)
+   */
+  public boolean containsValue(Object value) {
+    recordTXOperation(ServerRegionOperation.CONTAINS_VALUE, null, value);
+    return ContainsKeyOp.execute(this.pool, this.regionName, value,MODE.VALUE);
+  }
+  
+  /* (non-Javadoc)
+   * @see com.gemstone.gemfire.cache.client.internal.ServerRegionDataAccess#keySet()
+   */
+  public Set keySet() {
+    recordTXOperation(ServerRegionOperation.KEY_SET, null);
+    return KeySetOp.execute(this.pool, this.regionName);
+  }
+  
+  /**
+   * Does a region registerInterest on a server
+   * @param key describes what we are interested in
+   * @param interestType the {@link InterestType} for this registration
+   * @param policy the interest result policy for this registration
+   * @param isDurable true if this registration is durable
+   * @param regionDataPolicy the data policy ordinal of the region
+   * @return list of keys
+   */
+  public List registerInterest(final Object key,
+                               final int interestType,
+                               final InterestResultPolicy policy,
+                               final boolean isDurable,
+                               final byte regionDataPolicy)
+  {
+    return registerInterest(key, interestType, policy, isDurable, false, regionDataPolicy);
+  }
+  
+  /**
+   * Does a region registerInterest on a server
+   * @param key describes what we are interested in
+   * @param interestType the {@link InterestType} for this registration
+   * @param policy the interest result policy for this registration
+   * @param isDurable true if this registration is durable
+   * @param receiveUpdatesAsInvalidates whether to act like notify-by-subscription is false.
+   * @param regionDataPolicy the data policy ordinal of the region
+   * @return list of keys
+   */
+  public List registerInterest(final Object key,
+                               final int interestType,
+                               final InterestResultPolicy policy,
+                               final boolean isDurable,
+                               final boolean receiveUpdatesAsInvalidates,
+                               final byte regionDataPolicy)
+  {
+    if (interestType == InterestType.KEY
+        && key instanceof List) {
+      return registerInterestList((List)key, policy, isDurable, receiveUpdatesAsInvalidates, regionDataPolicy);
+    } else {
+      
+      final RegisterInterestTracker rit = this.pool.getRITracker();
+      List result = null;
+      boolean finished = false;
+      try {
+        // register with the tracker early
+        rit.addSingleInterest(this.region, key, interestType, policy, isDurable, receiveUpdatesAsInvalidates);
+        result = RegisterInterestOp.execute(this.pool, this.regionName, key,
+            interestType, policy, isDurable, receiveUpdatesAsInvalidates, regionDataPolicy);
+        //////// TEST PURPOSE ONLY ///////////
+        if (PoolImpl.AFTER_REGISTER_CALLBACK_FLAG) {
+          BridgeObserver bo = BridgeObserverHolder.getInstance();
+          bo.afterInterestRegistration();
+        }
+        /////////////////////////////////////////
+        finished = true;
+        return result;
+      }
+      finally {
+        if (!finished) {
+          rit.removeSingleInterest(this.region, key, interestType,
+              isDurable, receiveUpdatesAsInvalidates);
+        }
+      }
+    }
+  }
+  /**
+   * Support for server-side interest registration
+   */
+  public void addSingleInterest(Object key, int interestType,
+      InterestResultPolicy pol, boolean isDurable, boolean receiveUpdatesAsInvalidates) {
+    RegisterInterestTracker rit = this.pool.getRITracker();
+    boolean finished = false;
+    try {
+      rit.addSingleInterest(this.region, key, interestType, pol,
+          isDurable, receiveUpdatesAsInvalidates);
+      finished = true;
+    }
+    finally {
+      if (!finished) {
+        rit.removeSingleInterest(this.region, key, interestType,
+            isDurable, receiveUpdatesAsInvalidates);
+      }
+    }
+  }
+  
+  public void addListInterest(List keys, InterestResultPolicy pol,
+      boolean isDurable, boolean receiveUpdatesAsInvalidates) {
+    RegisterInterestTracker rit = this.pool.getRITracker();
+    boolean finished = false;
+    try {
+      rit.addInterestList(this.region, keys, pol, isDurable,
+          receiveUpdatesAsInvalidates);
+      finished = true;
+    }
+    finally {
+      if (!finished) {
+        rit.removeInterestList(this.region, keys, isDurable,
+            receiveUpdatesAsInvalidates);
+      }
+    }
+  }
+
+  /**
+   * Support for server-side interest registration
+   */
+  public void removeSingleInterest(Object key, int interestType,
+      boolean isDurable, boolean receiveUpdatesAsInvalidates) {
+    this.pool.getRITracker()
+      .removeSingleInterest(this.region, key, interestType,
+          isDurable, receiveUpdatesAsInvalidates);
+  }
+  
+  public void removeListInterest(List keys, boolean isDurable,
+      boolean receiveUpdatesAsInvalidates) {
+    this.pool.getRITracker().removeInterestList(this.region, keys, isDurable,
+        receiveUpdatesAsInvalidates);
+  }
+  
+  /**
+   * Does a region registerInterest on a server described by the given server location
+   * <p>Note that this call by-passes the RegisterInterestTracker.
+   * @param sl the server to do the register interest on.
+   * @param key describes what we are interested in
+   * @param interestType the {@link InterestType} for this registration
+   * @param policy the interest result policy for this registration
+   * @param isDurable true if this registration is durable
+   * @param regionDataPolicy the data policy ordinal of the region
+   * @return list of keys
+   */
+  public List registerInterestOn(ServerLocation sl,
+                                 final Object key,
+                                 final int interestType,
+                                 final InterestResultPolicy policy,
+                                 final boolean isDurable,
+                                 final byte regionDataPolicy)
+  {
+    return registerInterestOn(sl, key, interestType, policy, isDurable, false, regionDataPolicy);
+  }
+  /**
+   * Does a region registerInterest on a server described by the given server location
+   * <p>Note that this call by-passes the RegisterInterestTracker.
+   * @param sl the server to do the register interest on.
+   * @param key describes what we are interested in
+   * @param interestType the {@link InterestType} for this registration
+   * @param policy the interest result policy for this registration
+   * @param isDurable true if this registration is durable
+   * @param receiveUpdatesAsInvalidates whether to act like notify-by-subscription is false.
+   * @param regionDataPolicy the data policy ordinal of the region
+   * @return list of keys
+   */
+  public List registerInterestOn(ServerLocation sl,
+                                 final Object key,
+                                 final int interestType,
+                                 final InterestResultPolicy policy,
+                                 final boolean isDurable,
+                                 final boolean receiveUpdatesAsInvalidates,
+                                 final byte regionDataPolicy)
+  {
+    if (interestType == InterestType.KEY
+        && key instanceof List) {
+      return RegisterInterestListOp.executeOn(sl, this.pool, this.regionName,
+          (List)key, policy, isDurable, receiveUpdatesAsInvalidates, regionDataPolicy);
+    } else {
+      return RegisterInterestOp.executeOn(sl, this.pool, this.regionName, key,
+          interestType, policy, isDurable, receiveUpdatesAsInvalidates, regionDataPolicy);
+    }
+  }
+  
+  /**
+   * Does a region registerInterest on a server described by the given connection
+   * <p>Note that this call by-passes the RegisterInterestTracker.
+   * @param conn the connection to do the register interest on.
+   * @param key describes what we are interested in
+   * @param interestType the {@link InterestType} for this registration
+   * @param policy the interest result policy for this registration
+   * @param isDurable true if this registration is durable
+   * @param regionDataPolicy the data policy ordinal of the region
+   * @return list of keys
+   */
+  public List registerInterestOn(Connection conn,
+                                 final Object key,
+                                 final int interestType,
+                                 final InterestResultPolicy policy,
+                                 final boolean isDurable,
+                                 final byte regionDataPolicy)
+  {
+    return registerInterestOn(conn, key, interestType, policy, isDurable, false, regionDataPolicy); 
+  }
+  /**
+   * Does a region registerInterest on a server described by the given connection
+   * <p>Note that this call by-passes the RegisterInterestTracker.
+   * @param conn the connection to do the register interest on.
+   * @param key describes what we are interested in
+   * @param interestType the {@link InterestType} for this registration
+   * @param policy the interest result policy for this registration
+   * @param isDurable true if this registration is durable
+   * @param receiveUpdatesAsInvalidates whether to act like notify-by-subscription is false.
+   * @param regionDataPolicy the data policy ordinal of the region
+   * @return list of keys
+   */
+  public List registerInterestOn(Connection conn,
+                                 final Object key,
+                                 final int interestType,
+                                 final InterestResultPolicy policy,
+                                 final boolean isDurable,
+                                 final boolean receiveUpdatesAsInvalidates,
+                                 final byte regionDataPolicy)
+  {
+    if (interestType == InterestType.KEY
+        && key instanceof List) {
+      return RegisterInterestListOp.executeOn(conn, this.pool, this.regionName,
+          (List)key, policy, isDurable, receiveUpdatesAsInvalidates, regionDataPolicy);
+    } else {
+      return RegisterInterestOp.executeOn(conn, this.pool, this.regionName,
+          key, interestType, policy, isDurable, receiveUpdatesAsInvalidates, regionDataPolicy);
+    }
+  }
+    
+  
+  
+  /**
+   * Does a region registerInterestList on a server
+   * @param keys list of keys we are interested in
+   * @param policy the interest result policy for this registration
+   * @param isDurable true if this registration is durable
+   * @param regionDataPolicy the data policy ordinal of the region
+   * @return list of keys
+   */
+  public List registerInterestList(List keys,
+                                   InterestResultPolicy policy,
+                                   boolean isDurable,
+                                   boolean receiveUpdatesAsInvalidates,
+                                   final byte regionDataPolicy)
+  {
+    final RegisterInterestTracker rit = this.pool.getRITracker();
+    List result = null;
+    boolean finished = false;
+    try {
+      // register with the tracker early
+      rit.addInterestList(this.region, keys, policy, isDurable, receiveUpdatesAsInvalidates);
+      result = RegisterInterestListOp.execute(this.pool, this.regionName, keys, policy, isDurable, receiveUpdatesAsInvalidates, regionDataPolicy);
+      finished = true;
+      //////// TEST PURPOSE ONLY ///////////
+      if (PoolImpl.AFTER_REGISTER_CALLBACK_FLAG) {
+        BridgeObserver bo = BridgeObserverHolder.getInstance();
+        bo.afterInterestRegistration();
+      }
+      /////////////////////////////////////////
+      return result;
+    }
+    finally {
+      if (!finished) {
+        rit.removeInterestList(this.region, keys, isDurable, receiveUpdatesAsInvalidates);
+      }
+    }
+  }
+  /**
+   * Does a region unregisterInterest on a server
+   * @param key describes what we are no longer interested in
+   * @param interestType the {@link InterestType} for this unregister
+   * @param isClosing true if this unregister is done by a close
+   * @param keepAlive true if this unregister should not undo a durable registration
+   */
+  public void unregisterInterest(Object key,
+                                 int interestType,
+                                 boolean isClosing,
+                                 boolean keepAlive)
+  {
+    if (interestType == InterestType.KEY
+        && key instanceof List) {
+      unregisterInterestList((List)key, isClosing, keepAlive);
+    } else {
+      RegisterInterestTracker rit = this.pool.getRITracker();
+      boolean removed =
+        rit.removeSingleInterest(this.region, key, interestType, false, false) ||
+        rit.removeSingleInterest(this.region, key, interestType, true, false) ||
+        rit.removeSingleInterest(this.region, key, interestType, false, true) ||
+        rit.removeSingleInterest(this.region, key, interestType, true, true);
+      if (removed) {
+        UnregisterInterestOp.execute(this.pool, this.regionName, key, interestType, isClosing, keepAlive);
+      }
+    }
+  }
+  /**
+   * Does a region unregisterInterestList on a server
+   * @param keys list of keys we are interested in
+   * @param isClosing true if this unregister is done by a close
+   * @param keepAlive true if this unregister should not undo a durable registration
+   */
+  public void unregisterInterestList(List keys,
+                                     boolean isClosing,
+                                     boolean keepAlive)
+  {
+    RegisterInterestTracker rit = this.pool.getRITracker();
+    boolean removed =
+      rit.removeInterestList(this.region, keys, false, true) ||
+      rit.removeInterestList(this.region, keys, false, false) ||
+      rit.removeInterestList(this.region, keys, true, true) ||
+      rit.removeInterestList(this.region, keys, true, false);
+    if (removed) {
+      UnregisterInterestListOp.execute(this.pool, this.regionName, keys, isClosing, keepAlive);
+    }
+  }
+  public List getInterestList(int interestType) {
+    return this.pool.getRITracker().getInterestList(this.regionName,
+                                                    interestType);
+  }
+
+  @Override
+  public VersionedObjectList putAll(Map map, EventID eventId, boolean skipCallbacks, Object callbackArg) {
+    recordTXOperation(ServerRegionOperation.PUT_ALL, null, map, eventId);
+    int txID = TXManagerImpl.getCurrentTXUniqueId();
+    if (this.pool.getPRSingleHopEnabled() && (txID == TXManagerImpl.NOTX)) {
+      return PutAllOp.execute(this.pool, this.region, map, eventId, skipCallbacks, this.pool.getRetryAttempts(), callbackArg);
+    }
+    else {
+      return PutAllOp.execute(this.pool, this.region, map, eventId, skipCallbacks, false, callbackArg);
+    }
+  }
+  
+  @Override
+  public VersionedObjectList removeAll(Collection<Object> keys, EventID eventId, Object callbackArg) {
+    recordTXOperation(ServerRegionOperation.REMOVE_ALL, null, keys, eventId);
+    int txID = TXManagerImpl.getCurrentTXUniqueId();
+    if (this.pool.getPRSingleHopEnabled() && (txID == TXManagerImpl.NOTX)) {
+      return RemoveAllOp.execute(this.pool, this.region, keys, eventId, this.pool.getRetryAttempts(), callbackArg);
+    }
+    else {
+      return RemoveAllOp.execute(this.pool, this.region, keys, eventId, false, callbackArg);
+    }
+  }
+  
+  
+  @Override
+  public VersionedObjectList getAll(List keys, Object callback) {
+    recordTXOperation(ServerRegionOperation.GET_ALL, null, keys);
+    int txID = TXManagerImpl.getCurrentTXUniqueId();
+    VersionedObjectList result;
+    if (this.pool.getPRSingleHopEnabled() && (txID == TXManagerImpl.NOTX)) {
+      result = GetAllOp.execute(this.pool, this.region, keys,this.pool.getRetryAttempts(), callback);
+    }
+    else {
+      result = GetAllOp.execute(this.pool, this.regionName, keys, callback);
+    }
+    if (result != null) {
+      for (Iterator it=result.iterator(); it.hasNext(); ) {
+        VersionedObjectList.Entry entry = it.next();
+        Object key = entry.getKey();
+        Object value = entry.getValue();
+        boolean isOnServer = entry.isKeyNotOnServer();
+        if (!isOnServer) {
+          if (value instanceof Throwable) {
+            logger.warn(LocalizedMessage.create(
+                    LocalizedStrings.GetAll_0_CAUGHT_THE_FOLLOWING_EXCEPTION_ATTEMPTING_TO_GET_VALUE_FOR_KEY_1,
+                    new Object[]{value, key}), (Throwable)value);
+          } 
+        }
+      }
+    }
+    return result;
+  }
+    
+  /**
+   * Release use of this pool
+   */
+  public void detach(boolean keepalive) {
+    this.pool.getRITracker().unregisterRegion(this, keepalive);
+    super.detach();
+  }
+  public String getRegionName() {
+    return this.regionName;
+  }
+  
+  public Region getRegion() {
+    return this.region;
+  }
+    
+  public void executeFunction(String rgnName, Function function,
+      ServerRegionFunctionExecutor serverRegionExecutor,
+      ResultCollector resultCollector, byte hasResult, boolean replaying) {
+    
+    recordTXOperation(ServerRegionOperation.EXECUTE_FUNCTION, null, Integer.valueOf(1),
+          function, serverRegionExecutor, resultCollector,
+          Byte.valueOf(hasResult));
+
+    int retryAttempts = pool.getRetryAttempts();
+
+    if (this.pool.getPRSingleHopEnabled()) {
+      ClientMetadataService cms = region.getCache()
+      .getClientMetadataService();
+      if (serverRegionExecutor.getFilter().isEmpty()) {
+        HashMap<ServerLocation, HashSet<Integer>> serverToBuckets = cms
+        .groupByServerToAllBuckets(this.region, function.optimizeForWrite());
+        if (serverToBuckets == null || serverToBuckets.isEmpty()) {
+          ExecuteRegionFunctionOp.execute(this.pool, rgnName, function,
+              serverRegionExecutor, resultCollector, hasResult, retryAttempts);
+          cms.scheduleGetPRMetaData(region, false);
+        }
+        else {
+          ExecuteRegionFunctionSingleHopOp.execute(this.pool, this.region,
+              function, serverRegionExecutor, resultCollector, hasResult,
+              serverToBuckets, retryAttempts, true);
+        }
+      }
+      else {
+        boolean isBucketFilter = serverRegionExecutor.getExecuteOnBucketSetFlag();
+        Map<ServerLocation, HashSet> serverToFilterMap = cms
+        .getServerToFilterMap(serverRegionExecutor.getFilter(), region,
+            function.optimizeForWrite(), isBucketFilter);
+        if (serverToFilterMap == null || serverToFilterMap.isEmpty()) {         
+          ExecuteRegionFunctionOp.execute(this.pool, rgnName, function,
+              serverRegionExecutor, resultCollector, hasResult, retryAttempts);
+            cms.scheduleGetPRMetaData(region, false);          
+        }
+        else {
+          //Asif: In case of withBucketFilter , the serverToFilterMap is nothing but
+          // serverToBucketsMap, so allBuckets flag should be true in that case 
+          // so allBuckets flag is governed by isBucketFilter flag
+          ExecuteRegionFunctionSingleHopOp.execute(this.pool, this.region,
+              function, serverRegionExecutor, resultCollector, hasResult,
+              serverToFilterMap, retryAttempts, isBucketFilter);
+          
+         
+        }
+      }
+    }
+    else {
+      ExecuteRegionFunctionOp.execute(this.pool, rgnName, function,
+          serverRegionExecutor, resultCollector, hasResult, retryAttempts);
+    }
+  }
+
+
+  public void executeFunction(String rgnName, String functionId,
+      ServerRegionFunctionExecutor serverRegionExecutor,
+      ResultCollector resultCollector, byte hasResult, boolean isHA, boolean optimizeForWrite,
+      boolean replaying) {
+
+    recordTXOperation(ServerRegionOperation.EXECUTE_FUNCTION, null, Integer.valueOf(2), 
+          functionId, serverRegionExecutor, resultCollector, Byte.valueOf(hasResult),
+          Boolean.valueOf(isHA), Boolean.valueOf(optimizeForWrite));
+    
+    int retryAttempts = pool.getRetryAttempts();
+
+    if (this.pool.getPRSingleHopEnabled()) {
+      ClientMetadataService cms = this.region.getCache()
+      .getClientMetadataService();
+      if (serverRegionExecutor.getFilter().isEmpty()) {
+        HashMap<ServerLocation, HashSet<Integer>> serverToBuckets = cms
+        .groupByServerToAllBuckets(this.region, optimizeForWrite);
+        if (serverToBuckets == null || serverToBuckets.isEmpty()) {
+          ExecuteRegionFunctionOp.execute(this.pool, rgnName, functionId,
+              serverRegionExecutor, resultCollector, hasResult, retryAttempts, isHA, optimizeForWrite);
+          cms.scheduleGetPRMetaData(this.region, false);
+        }
+        else {
+          ExecuteRegionFunctionSingleHopOp.execute(this.pool, this.region,
+              functionId, serverRegionExecutor, resultCollector, hasResult,
+              serverToBuckets, retryAttempts, true, isHA, optimizeForWrite);
+        }
+      }
+      else {
+        boolean isBucketsAsFilter = serverRegionExecutor.getExecuteOnBucketSetFlag();
+        Map<ServerLocation, HashSet> serverToFilterMap = cms
+        .getServerToFilterMap(serverRegionExecutor.getFilter(), region,
+            optimizeForWrite, isBucketsAsFilter);
+        if (serverToFilterMap == null || serverToFilterMap.isEmpty()) {         
+          ExecuteRegionFunctionOp.execute(this.pool, rgnName, functionId,
+              serverRegionExecutor, resultCollector, hasResult, retryAttempts, isHA, optimizeForWrite);
+            cms.scheduleGetPRMetaData(region, false);          
+        }
+        else {
+          ExecuteRegionFunctionSingleHopOp.execute(this.pool, this.region,
+              functionId, serverRegionExecutor, resultCollector, hasResult,
+              serverToFilterMap, retryAttempts, false, isHA, optimizeForWrite);
+        }
+      }
+    }
+    else {
+      ExecuteRegionFunctionOp.execute(this.pool, rgnName, functionId,
+          serverRegionExecutor, resultCollector, hasResult, retryAttempts, isHA, optimizeForWrite);
+    }
+  }
+
+  
+  public void executeFunctionNoAck(String rgnName, Function function,
+      ServerRegionFunctionExecutor serverRegionExecutor, byte hasResult, boolean replaying) {
+    recordTXOperation(ServerRegionOperation.EXECUTE_FUNCTION, null, Integer.valueOf(3),
+          function, serverRegionExecutor, Byte.valueOf(hasResult));
+    ExecuteRegionFunctionNoAckOp.execute(this.pool, rgnName, function,
+        serverRegionExecutor, hasResult);
+  }    
+  
+  public void executeFunctionNoAck(String rgnName, String functionId,
+      ServerRegionFunctionExecutor serverRegionExecutor, byte hasResult,
+      boolean isHA, boolean optimizeForWrite, boolean replaying) {
+    recordTXOperation(ServerRegionOperation.EXECUTE_FUNCTION, null, Integer.valueOf(4),
+          functionId, serverRegionExecutor, Byte.valueOf(hasResult));
+    ExecuteRegionFunctionNoAckOp.execute(this.pool, rgnName, functionId,
+        serverRegionExecutor, hasResult, isHA,  optimizeForWrite);
+  } 
+
+  public Entry getEntry(Object key) {
+    recordTXOperation(ServerRegionOperation.GET_ENTRY, key);
+    return (Entry) GetEntryOp.execute(pool, region, key);
+  }
+
+  
+  /**
+   * Transaction synchronization notification to the servers
+   * @see com.gemstone.gemfire.internal.cache.tx.ClientTXStateStub#beforeCompletion()
+   */
+  public void beforeCompletion(int txId) {
+    TXSynchronizationOp.execute(pool, 0, txId, TXSynchronizationOp.CompletionType.BEFORE_COMPLETION);
+  }
+  
+  /**
+   * Transaction synchronization notification to the servers
+   * @param status
+   * @return the server's TXCommitMessage
+   * @see com.gemstone.gemfire.internal.cache.tx.ClientTXStateStub#afterCompletion(int)
+   */
+  public TXCommitMessage afterCompletion(int status, int txId) {
+    return TXSynchronizationOp.execute(pool, status, txId, TXSynchronizationOp.CompletionType.AFTER_COMPLETION);
+  }
+
+  public byte[] getFunctionAttributes(String functionId){
+    return (byte[])GetFunctionAttributeOp.execute(this.pool, functionId);
+  }
+  
+  /** test hook */
+  private void recordTXOperation(ServerRegionOperation op, Object key, Object... arguments) {
+    if (ClientTXStateStub.transactionRecordingEnabled()) {
+      TXStateProxy tx = TXManagerImpl.getCurrentTXState();
+      if (tx == null) {
+        return;
+      }
+      tx.recordTXOperation(this, op, key, arguments);
+    }
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/SingleHopClientExecutor.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/SingleHopClientExecutor.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/SingleHopClientExecutor.java
new file mode 100644
index 0000000..ada3ab2
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/SingleHopClientExecutor.java
@@ -0,0 +1,387 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+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.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.InternalGemFireException;
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.client.ServerConnectivityException;
+import com.gemstone.gemfire.cache.client.ServerOperationException;
+import com.gemstone.gemfire.cache.client.internal.GetAllOp.GetAllOpImpl;
+import com.gemstone.gemfire.cache.execute.FunctionException;
+import com.gemstone.gemfire.cache.execute.ResultCollector;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.cache.PutAllPartialResultException;
+import com.gemstone.gemfire.internal.cache.execute.InternalFunctionInvocationTargetException;
+import com.gemstone.gemfire.internal.cache.tier.sockets.VersionedObjectList;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+
+public class SingleHopClientExecutor {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  static final ExecutorService execService = Executors
+      .newCachedThreadPool(new ThreadFactory() {
+        AtomicInteger threadNum = new AtomicInteger();
+
+        public Thread newThread(final Runnable r) {
+          Thread result = new Thread(r, "Function Execution Thread-"
+              + threadNum.incrementAndGet());
+          result.setDaemon(true);
+          return result;
+        }
+      });
+
+  static void submitAll(List callableTasks) {
+    if (callableTasks != null && !callableTasks.isEmpty()) {
+      List futures = null;
+      try {
+        futures = execService.invokeAll(callableTasks);
+      }
+      catch (RejectedExecutionException rejectedExecutionEx) {
+        throw rejectedExecutionEx;
+      }
+      catch (InterruptedException e) {
+        throw new InternalGemFireException(e.getMessage());
+      }
+      if (futures != null) {
+        Iterator itr = futures.iterator();
+        while (itr.hasNext() && !execService.isShutdown()
+            && !execService.isTerminated()) {
+          Future fut = (Future)itr.next();
+          try {
+            fut.get();
+          }
+          catch (InterruptedException e) {
+            throw new InternalGemFireException(e.getMessage());
+          }
+          catch (ExecutionException ee) {
+            if (ee.getCause() instanceof FunctionException) {
+              throw (FunctionException)ee.getCause();
+            }
+            else if (ee.getCause() instanceof ServerOperationException) {
+              throw (ServerOperationException)ee.getCause();
+            }
+            else if (ee.getCause() instanceof ServerConnectivityException) {
+              throw (ServerConnectivityException)ee.getCause();
+            }
+            else {
+              throw executionThrowable(ee.getCause());
+            }
+          }
+        }
+      }
+    }
+  }
+
+  static boolean submitAllHA(List callableTasks, LocalRegion region,
+      ResultCollector rc, Set<String> failedNodes) {
+
+    ClientMetadataService cms = region.getCache()
+        .getClientMetadataService();
+    boolean reexecute = false;
+
+    if (callableTasks != null && !callableTasks.isEmpty()) {
+      List futures = null;
+      try {
+        futures = execService.invokeAll(callableTasks);
+      }
+      catch (RejectedExecutionException rejectedExecutionEx) {
+        throw rejectedExecutionEx;
+      }
+      catch (InterruptedException e) {
+        throw new InternalGemFireException(e.getMessage());
+      }
+      if (futures != null) {
+        Iterator futureItr = futures.iterator();
+        Iterator taskItr = callableTasks.iterator();
+        final boolean isDebugEnabled = logger.isDebugEnabled();
+        while (futureItr.hasNext() && !execService.isShutdown()
+            && !execService.isTerminated()) {
+          Future fut = (Future)futureItr.next();
+          SingleHopOperationCallable task = (SingleHopOperationCallable)taskItr.next();
+          ServerLocation server = task.getServer();
+          try {
+            fut.get();
+            if (isDebugEnabled) {
+              logger.debug("ExecuteRegionFunctionSingleHopOp#got result from {}", server);
+            }
+          }
+          catch (InterruptedException e) {
+            throw new InternalGemFireException(e.getMessage());
+          }
+          catch (ExecutionException ee) {
+            if (ee.getCause() instanceof InternalFunctionInvocationTargetException) {
+              if (isDebugEnabled) {
+                logger.debug("ExecuteRegionFunctionSingleHopOp#ExecutionException.InternalFunctionInvocationTargetException : Caused by :{}", ee.getCause());
+              }
+              try {
+                cms = region.getCache().getClientMetadataService();
+              }
+              catch (CacheClosedException e) {
+                return false;
+              }
+              cms.scheduleGetPRMetaData(region, false);
+              cms.removeBucketServerLocation(server);
+              reexecute = true;
+              failedNodes.addAll(((InternalFunctionInvocationTargetException)ee
+                  .getCause()).getFailedNodeSet());
+              rc.clearResults();
+            }
+            else if (ee.getCause() instanceof FunctionException) {
+              if (isDebugEnabled) {
+                logger.debug("ExecuteRegionFunctionSingleHopOp#ExecutionException.FunctionException : Caused by :{}", ee.getCause());
+              }
+              throw (FunctionException)ee.getCause();
+            }
+            else if (ee.getCause() instanceof ServerOperationException) {
+              if (isDebugEnabled) {
+                logger.debug("ExecuteRegionFunctionSingleHopOp#ExecutionException.ServerOperationException : Caused by :{}", ee.getCause());
+              }
+              throw (ServerOperationException)ee.getCause();
+            }
+            else if (ee.getCause() instanceof ServerConnectivityException) {
+              if (isDebugEnabled) {
+                logger.debug("ExecuteRegionFunctionSingleHopOp#ExecutionException.ServerConnectivityException : Caused by :{} The failed server is: {}", ee.getCause(), server);
+              }
+              try {
+                cms = region.getCache().getClientMetadataService();
+              }
+              catch (CacheClosedException e) {
+                return false;
+              }
+              cms.removeBucketServerLocation(server);
+              cms.scheduleGetPRMetaData(region, false);
+              reexecute = true;
+              rc.clearResults();
+            }
+            else {
+              throw executionThrowable(ee.getCause());
+            }
+          }
+        }
+      }
+    }
+    return reexecute;
+  }
+  
+  /**
+   * execute bulk op (putAll or removeAll) on multiple PR servers, returning a map of the results.
+   * Results are either a VersionedObjectList or a BulkOpPartialResultsException
+   * @param callableTasks
+   * @param cms
+   * @param region
+   * @param failedServers
+   * @return the per-server results
+   */
+  static Map<ServerLocation, Object> submitBulkOp(List callableTasks, ClientMetadataService cms, 
+      LocalRegion region, Map<ServerLocation,RuntimeException> failedServers) {
+    if (callableTasks != null && !callableTasks.isEmpty()) {
+      Map<ServerLocation, Object> resultMap = new HashMap<ServerLocation, Object>();
+      boolean anyPartialResults = false;
+      List futures = null;
+      try {
+        futures = execService.invokeAll(callableTasks);
+      }
+      catch (RejectedExecutionException rejectedExecutionEx) {
+        throw rejectedExecutionEx;
+      }
+      catch (InterruptedException e) {
+        throw new InternalGemFireException(e.getMessage());
+      }
+      if (futures != null) {
+        Iterator futureItr = futures.iterator();
+        Iterator taskItr = callableTasks.iterator();
+        RuntimeException rte = null;
+        final boolean isDebugEnabled = logger.isDebugEnabled();
+        while (futureItr.hasNext() && !execService.isShutdown()
+            && !execService.isTerminated()) {
+          Future fut = (Future)futureItr.next();
+          SingleHopOperationCallable task = (SingleHopOperationCallable)taskItr
+              .next();
+          ServerLocation server = task.getServer();
+          try {
+            VersionedObjectList versions = (VersionedObjectList)fut.get();
+            if (logger.isDebugEnabled()) {
+              logger.debug("submitBulkOp#got result from {}:{}",
+                  server, versions);
+            }
+            resultMap.put(server, versions);
+          }
+          catch (InterruptedException e) {
+            InternalGemFireException ige = new InternalGemFireException(e);
+            // only to make this server as failed server, not to throw right now
+            failedServers.put(server,  ige);
+            if (rte == null) {
+              rte = ige;
+            }
+          }
+          catch (ExecutionException ee) {
+            if (ee.getCause() instanceof ServerOperationException) {
+              if (logger.isDebugEnabled()) {
+                logger.debug("submitBulkOp#ExecutionException from server {}", server, ee);
+              }
+              ServerOperationException soe = (ServerOperationException)ee.getCause();
+              // only to make this server as failed server, not to throw right now
+              failedServers.put(server, soe);
+              if (rte == null) {
+                rte = soe;
+              }
+            }
+            else if (ee.getCause() instanceof ServerConnectivityException) {
+              if (logger.isDebugEnabled()) {
+                logger.debug("submitBulkOp#ExecutionException for server {}", server, ee);
+              }
+              cms = region.getCache().getClientMetadataService();
+              cms.removeBucketServerLocation(server);
+              cms.scheduleGetPRMetaData(region, false);
+              failedServers.put(server, (ServerConnectivityException)ee.getCause());
+            }
+            else {
+              Throwable t = ee.getCause();
+              if (t instanceof PutAllPartialResultException) {
+                resultMap.put(server, t);
+                anyPartialResults = true;
+                failedServers.put(server, (PutAllPartialResultException)t);
+              } else {
+                RuntimeException other_rte = executionThrowable(ee.getCause());
+                failedServers.put(server, other_rte);
+                if (rte == null) {
+                  rte = other_rte;
+                }
+              }
+            }
+          } // catch
+        } // while
+        // if there are any partial results we suppress throwing an exception
+        // so the partial results can be processed
+        if (rte != null && !anyPartialResults) {
+          throw rte;
+        }
+      }
+      return resultMap;
+    }
+    return null;
+  }
+  
+  static Map<ServerLocation, Object> submitGetAll(
+      Map<ServerLocation, HashSet> serverToFilterMap, List callableTasks,
+      ClientMetadataService cms, LocalRegion region) {
+
+    if (callableTasks != null && !callableTasks.isEmpty()) {
+      Map<ServerLocation, Object> resultMap = new HashMap<ServerLocation, Object>();
+      List futures = null;
+      try {
+        futures = execService.invokeAll(callableTasks);
+      }
+      catch (RejectedExecutionException rejectedExecutionEx) {
+        throw rejectedExecutionEx;
+      }
+      catch (InterruptedException e) {
+        throw new InternalGemFireException(e.getMessage());
+      }
+      if (futures != null) {
+        Iterator futureItr = futures.iterator();
+        Iterator taskItr = callableTasks.iterator();
+        while (futureItr.hasNext() && !execService.isShutdown()
+            && !execService.isTerminated()) {
+          Future fut = (Future)futureItr.next();
+          SingleHopOperationCallable task = (SingleHopOperationCallable)taskItr
+              .next();
+          List keys = ((GetAllOpImpl)task.getOperation()).getKeyList();
+          ServerLocation server = task.getServer();
+          try {
+
+            VersionedObjectList valuesFromServer = (VersionedObjectList)fut.get();
+            valuesFromServer.setKeys(keys);
+
+            for (VersionedObjectList.Iterator it=valuesFromServer.iterator(); it.hasNext(); ) {
+              VersionedObjectList.Entry entry = it.next();
+              Object key = entry.getKey();
+              Object value = entry.getValue();
+              if (!entry.isKeyNotOnServer()) {
+                if (value instanceof Throwable) {
+                  logger.warn(LocalizedMessage.create(
+                    LocalizedStrings.GetAll_0_CAUGHT_THE_FOLLOWING_EXCEPTION_ATTEMPTING_TO_GET_VALUE_FOR_KEY_1,
+                    new Object[]{value, key}), (Throwable)value);
+                } 
+              }
+            }
+            if (logger.isDebugEnabled()) {
+              logger.debug("GetAllOp#got result from {}: {}", server, valuesFromServer);
+            }
+            resultMap.put(server, valuesFromServer);
+          }
+          catch (InterruptedException e) {
+            throw new InternalGemFireException(e.getMessage());
+          }
+          catch (ExecutionException ee) {
+            if (ee.getCause() instanceof ServerOperationException) {
+              if (logger.isDebugEnabled()) {
+                logger.debug("GetAllOp#ExecutionException.ServerOperationException : Caused by :{}", ee.getCause());
+              }
+              throw (ServerOperationException)ee.getCause();
+            }
+            else if (ee.getCause() instanceof ServerConnectivityException) {
+              if (logger.isDebugEnabled()) {
+                logger.debug("GetAllOp#ExecutionException.ServerConnectivityException : Caused by :{} The failed server is: {}", ee.getCause(), server);
+              }
+              try {
+                cms = region.getCache()
+                    .getClientMetadataService();
+              }
+              catch (CacheClosedException e) {
+                return null;
+              }
+              cms.removeBucketServerLocation(server);
+              cms.scheduleGetPRMetaData((LocalRegion)region, false);
+              resultMap.put(server, ee.getCause());
+            }
+            else {
+              throw executionThrowable(ee.getCause());
+            }
+          }
+        }
+        return resultMap;
+      }
+    }
+    return null;
+  }
+  
+  static void submitTask(Runnable task) {
+    execService.submit(task);
+  }
+
+  // Find out what exception to throw?
+  private static RuntimeException executionThrowable(Throwable t) {
+    if (t instanceof RuntimeException)
+      return (RuntimeException)t;
+    else if (t instanceof Error)
+      throw (Error)t;
+    else
+      throw new IllegalStateException("Don't know", t);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/SingleHopOperationCallable.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/SingleHopOperationCallable.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/SingleHopOperationCallable.java
new file mode 100644
index 0000000..18de8b7
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/SingleHopOperationCallable.java
@@ -0,0 +1,74 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.concurrent.Callable;
+
+import com.gemstone.gemfire.cache.client.AllConnectionsInUseException;
+import com.gemstone.gemfire.cache.client.internal.ExecuteRegionFunctionOp.ExecuteRegionFunctionOpImpl;
+import com.gemstone.gemfire.cache.client.internal.ExecuteRegionFunctionSingleHopOp.ExecuteRegionFunctionSingleHopOpImpl;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+/**
+ * 
+ * @author ymahajan
+ *
+ */
+public class SingleHopOperationCallable implements Callable {
+
+  final private ServerLocation server;
+
+  final private PoolImpl pool;
+
+  final private AbstractOp op;
+
+  final private UserAttributes securityAttributes;
+
+  public SingleHopOperationCallable(ServerLocation server, PoolImpl pool,
+      AbstractOp op, UserAttributes securityAttributes) {
+    this.server = server;
+    this.pool = pool;
+    this.op = op;
+    this.securityAttributes = securityAttributes;
+  }
+
+  public Object call() throws Exception {
+    op.initMessagePart();
+    Object result = null;
+    boolean onlyUseExistingCnx = ((pool.getMaxConnections() != -1 && pool
+        .getConnectionCount() >= pool.getMaxConnections()) ? true : false);
+    try {
+      UserAttributes.userAttributes.set(securityAttributes);
+      result = this.pool.executeOn(server, op, true, onlyUseExistingCnx);
+    }
+    catch (AllConnectionsInUseException ex) {
+      // if we reached connection limit and don't have available connection to
+      // that server,then execute function on one of the connections available
+      // from other servers instead of creating new connection to the original
+      // server
+      if (op instanceof ExecuteRegionFunctionSingleHopOpImpl){
+        ExecuteRegionFunctionSingleHopOpImpl newop = (ExecuteRegionFunctionSingleHopOpImpl)op;
+        result = this.pool.execute(new ExecuteRegionFunctionOpImpl(newop));
+      }else {
+        result = this.pool.execute(this.op);
+      }
+    }
+    finally {
+      UserAttributes.userAttributes.set(null);
+    }
+    return result;
+  }
+  
+  public ServerLocation getServer() {
+    return this.server;
+  }
+  
+  public AbstractOp getOperation() {
+    return this.op;
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/SizeOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/SizeOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/SizeOp.java
new file mode 100644
index 0000000..2c446d8
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/SizeOp.java
@@ -0,0 +1,83 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().send(false);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/TXFailoverOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/TXFailoverOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/TXFailoverOp.java
new file mode 100644
index 0000000..417d32c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/TXFailoverOp.java
@@ -0,0 +1,84 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().send(false);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/TXSynchronizationOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/TXSynchronizationOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/TXSynchronizationOp.java
new file mode 100644
index 0000000..092e6ce
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/TXSynchronizationOp.java
@@ -0,0 +1,154 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+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().send(false);
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/UnregisterInterestListOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/UnregisterInterestListOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/UnregisterInterestListOp.java
new file mode 100644
index 0000000..4c30f6c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/UnregisterInterestListOp.java
@@ -0,0 +1,91 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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;
+
+/**
+ * Does a region unregisterInterestList on a server
+ * @author darrel
+ * @since 5.7
+ */
+public class UnregisterInterestListOp {
+  /**
+   * Does a region unregisterInterestList 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 unregisterInterestList on
+   * @param keys list of keys we are interested in
+   * @param isClosing true if this unregister is done by a close
+   * @param keepAlive true if this unregister should not undo a durable registration
+   */
+  public static void execute(ExecutablePool pool,
+                             String region,
+                             List keys,
+                             boolean isClosing,
+                             boolean keepAlive)
+  {
+    AbstractOp op = new UnregisterInterestListOpImpl(region, keys, isClosing, keepAlive);
+    pool.executeOnAllQueueServers(op);
+  }
+                                                               
+  private UnregisterInterestListOp() {
+    // no instances allowed
+  }
+  
+  private static class UnregisterInterestListOpImpl extends AbstractOp {
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public UnregisterInterestListOpImpl(String region,
+                                        List keys,
+                                        boolean isClosing,
+                                        boolean keepAlive) {
+      super(MessageType.UNREGISTER_INTEREST_LIST, 4+keys.size());
+      getMessage().addStringPart(region);
+      {
+        byte closingByte = (byte)(isClosing ? 0x01 : 0x00);
+        getMessage().addBytesPart(new byte[] {closingByte});
+      }
+      {
+        byte keepAliveByte = (byte)(keepAlive ? 0x01 : 0x00);
+        getMessage().addBytesPart(new byte[] {keepAliveByte});
+      }
+      getMessage().addIntPart(keys.size());
+      for (Iterator i = keys.iterator(); i.hasNext();) {
+        getMessage().addStringOrObjPart(i.next());
+      }
+    }
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      processAck(msg, "unregisterInterestList");
+      return null;
+    }
+    @Override
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.UNREGISTER_INTEREST_DATA_ERROR;
+    }
+    // using UnregisterInterest stats
+    @Override
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startUnregisterInterest();
+    }
+    @Override
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endUnregisterInterestSend(start, hasFailed());
+    }
+    @Override
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endUnregisterInterest(start, hasTimedOut(), hasFailed());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/UnregisterInterestOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/UnregisterInterestOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/UnregisterInterestOp.java
new file mode 100644
index 0000000..1e89b13
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/UnregisterInterestOp.java
@@ -0,0 +1,89 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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.internal.cache.tier.InterestType;
+
+/**
+ * Does a region unregisterInterest on a server
+ * @author darrel
+ * @since 5.7
+ */
+public class UnregisterInterestOp {
+  /**
+   * Does a region unregisterInterest 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 unregisterInterest on
+   * @param key describes what we are no longer interested in
+   * @param interestType the {@link InterestType} for this unregister
+   * @param isClosing true if this unregister is done by a close
+   * @param keepAlive true if this unregister should not undo a durable registration
+   */
+  public static void execute(ExecutablePool pool,
+                             String region,
+                             Object key,
+                             int interestType,
+                             boolean isClosing,
+                             boolean keepAlive)
+  {
+    AbstractOp op = new UnregisterInterestOpImpl(region, key, interestType, isClosing, keepAlive);
+    pool.executeOnAllQueueServers(op);
+  }
+                                                               
+  private UnregisterInterestOp() {
+    // no instances allowed
+  }
+  
+  private static class UnregisterInterestOpImpl extends AbstractOp {
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public UnregisterInterestOpImpl(String region,
+                                    Object key,
+                                    int interestType,
+                                    boolean isClosing,
+                                    boolean keepAlive) {
+      super(MessageType.UNREGISTER_INTEREST, 5);
+      getMessage().addStringPart(region);
+      getMessage().addIntPart(interestType);
+      getMessage().addStringOrObjPart(key);
+      {
+        byte closingByte = (byte)(isClosing ? 0x01 : 0x00);
+        getMessage().addBytesPart(new byte[] {closingByte});
+      }
+      {
+        byte keepAliveByte = (byte)(keepAlive ? 0x01 : 0x00);
+        getMessage().addBytesPart(new byte[] {keepAliveByte});
+      }
+    }
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      processAck(msg, "unregisterInterest");
+      return null;
+    }
+    @Override
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.UNREGISTER_INTEREST_DATA_ERROR;
+    }
+    @Override
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startUnregisterInterest();
+    }
+    @Override
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endUnregisterInterestSend(start, hasFailed());
+    }
+    @Override
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endUnregisterInterest(start, hasTimedOut(), hasFailed());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/UserAttributes.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/UserAttributes.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/UserAttributes.java
new file mode 100755
index 0000000..5c959e9
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/UserAttributes.java
@@ -0,0 +1,50 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.gemstone.gemfire.cache.client.Pool;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+
+public class UserAttributes {
+
+  private Properties credentials;
+  // Update this whenever we lose/add a server.
+  private ConcurrentHashMap<ServerLocation, Long> serverToId = new ConcurrentHashMap<ServerLocation, Long>();
+
+  private Pool pool;
+
+  public static final ThreadLocal<UserAttributes> userAttributes = new ThreadLocal<UserAttributes>();
+
+  public UserAttributes(Properties credentials, Pool pool) {
+    this.credentials = credentials;
+    this.pool = pool;
+  }
+
+  public void setCredentials(Properties credentials) {
+    this.credentials = credentials;
+  }
+
+  public Properties getCredentials() {
+    return credentials;
+  }
+
+  public void setServerToId(ServerLocation server, Long uniqueId) {
+    serverToId.put(server, uniqueId);
+  }
+
+  public ConcurrentHashMap<ServerLocation, Long> getServerToId() {
+    return serverToId;
+  }
+
+  public Pool getPool() {
+    return pool;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/ConnectionManagerImpl.dia
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/ConnectionManagerImpl.dia b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/ConnectionManagerImpl.dia
new file mode 100644
index 0000000..39d8f3d
Binary files /dev/null and b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/ConnectionManagerImpl.dia differ

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/ConnectionManagerImpl.png
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/ConnectionManagerImpl.png b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/ConnectionManagerImpl.png
new file mode 100644
index 0000000..773fabe
Binary files /dev/null and b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/ConnectionManagerImpl.png differ

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/PoolImpl.dia
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/PoolImpl.dia b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/PoolImpl.dia
new file mode 100644
index 0000000..731aeb0
Binary files /dev/null and b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/PoolImpl.dia differ

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/QueueManagerImpl.dia
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/QueueManagerImpl.dia b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/QueueManagerImpl.dia
new file mode 100644
index 0000000..8cc7d0e
Binary files /dev/null and b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/QueueManagerImpl.dia differ

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/QueueManagerImpl.png
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/QueueManagerImpl.png b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/QueueManagerImpl.png
new file mode 100644
index 0000000..d48bbf6
Binary files /dev/null and b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/QueueManagerImpl.png differ

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/client_static_diagram.png
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/client_static_diagram.png b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/client_static_diagram.png
new file mode 100644
index 0000000..afbeaa4
Binary files /dev/null and b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/doc-files/client_static_diagram.png differ

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ClientConnectionRequest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ClientConnectionRequest.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ClientConnectionRequest.java
new file mode 100644
index 0000000..6c6c04b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ClientConnectionRequest.java
@@ -0,0 +1,59 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Set;
+
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+
+/**
+ * A request from a client to the locator asking for a
+ * server to connect to for client to server traffic.
+ * @author dsmith
+ *
+ */
+public class ClientConnectionRequest extends ServerLocationRequest {
+  Set/*<ServerLocation>*/ excludedServers;
+  
+  public ClientConnectionRequest() {
+    
+  }
+
+  public ClientConnectionRequest(Set/*<ServerLocation>*/ excludedServers, String serverGroup) {
+    super(serverGroup);
+    this.excludedServers = excludedServers;
+  }
+
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    super.fromData(in);
+    this.excludedServers = SerializationHelper.readServerLocationSet(in);
+  }
+
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    super.toData(out);
+    SerializationHelper.writeServerLocationSet(this.excludedServers, out);
+  }
+
+  public Set getExcludedServers() {
+    return excludedServers;
+  }
+  
+  @Override
+  public String toString() {
+    return "ClientConnectionRequest{group=" + getServerGroup() + ", excluded=" + getExcludedServers() + "}";
+  }
+
+  public int getDSFID() {
+    return DataSerializableFixedID.CLIENT_CONNECTION_REQUEST;
+  }
+}


[36/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/AdminDistributedSystemJmxImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/AdminDistributedSystemJmxImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/AdminDistributedSystemJmxImpl.java
new file mode 100755
index 0000000..9728640
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/AdminDistributedSystemJmxImpl.java
@@ -0,0 +1,2332 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TimerTask;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.management.MBeanException;
+import javax.management.MalformedObjectNameException;
+import javax.management.Notification;
+import javax.management.ObjectName;
+import javax.management.RuntimeMBeanException;
+import javax.management.RuntimeOperationsException;
+import javax.management.modelmbean.ModelMBean;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.CacheServer;
+import com.gemstone.gemfire.admin.CacheServerConfig;
+import com.gemstone.gemfire.admin.CacheVm;
+import com.gemstone.gemfire.admin.CacheVmConfig;
+import com.gemstone.gemfire.admin.DistributedSystemConfig;
+import com.gemstone.gemfire.admin.DistributionLocator;
+import com.gemstone.gemfire.admin.DistributionLocatorConfig;
+import com.gemstone.gemfire.admin.GemFireHealth;
+import com.gemstone.gemfire.admin.SystemMember;
+import com.gemstone.gemfire.admin.SystemMemberCacheEvent;
+import com.gemstone.gemfire.admin.SystemMemberCacheListener;
+import com.gemstone.gemfire.admin.SystemMemberRegionEvent;
+import com.gemstone.gemfire.admin.SystemMemberType;
+import com.gemstone.gemfire.admin.internal.AdminDistributedSystemImpl;
+import com.gemstone.gemfire.admin.internal.CacheServerConfigImpl;
+import com.gemstone.gemfire.admin.internal.DistributionLocatorImpl;
+import com.gemstone.gemfire.cache.persistence.PersistentID;
+import com.gemstone.gemfire.distributed.DistributedMember;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.internal.Assert;
+import com.gemstone.gemfire.internal.admin.Alert;
+import com.gemstone.gemfire.internal.admin.ApplicationVM;
+import com.gemstone.gemfire.internal.admin.ClientMembershipMessage;
+import com.gemstone.gemfire.internal.admin.GemFireVM;
+import com.gemstone.gemfire.internal.admin.GfManagerAgent;
+import com.gemstone.gemfire.internal.admin.StatAlert;
+import com.gemstone.gemfire.internal.admin.StatAlertDefinition;
+import com.gemstone.gemfire.internal.admin.remote.UpdateAlertDefinitionMessage;
+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.log4j.LocalizedMessage;
+
+/**
+ * Provides MBean support for managing a GemFire distributed system.
+ * <p>
+ * TODO: refactor to implement DistributedSystem and delegate to instance of
+ * DistributedSystemImpl. Wrap all delegate calls w/ e.printStackTrace() since 
+ * the HttpAdaptor devours them (what to do w/ template methods then?)
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ */
+public class AdminDistributedSystemJmxImpl 
+              extends AdminDistributedSystemImpl
+              implements ManagedResource, DistributedSystemConfig, StatAlertsAggregator {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  private Properties mailProps;
+
+  // The file name where the StatAlertDefinitions would be serialized
+  private String statAlertDefnSerFile = System.getProperty("user.dir");
+  
+  /** 
+   * Simple counter incrementing on each notification.  This this currently 
+   * resets at every restart of Agent
+   */
+  private final AtomicInteger notificationSequenceNumber = new AtomicInteger();
+
+  /**
+   * Variable to indicate if there are no Rmi clients connected.
+   */
+  private volatile boolean isRmiClientCountZero;
+
+  /**
+   * Variable to indicate if Statistics Alert definitions could be persisted 
+   * across runs/sessions.
+   */
+  private volatile boolean canPersistStatAlertDefs = true;
+
+  /** Cache Listener to listen to Cache & Region create/destroy events */
+  private CacheAndRegionListenerImpl cacheRegionListener;
+
+  // -------------------------------------------------------------------------
+  //   Constructor(s)
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Constructs new DistributedSystemJmxImpl and registers an MBean to represent
+   * it.
+   * 
+   * @param config
+   *          configuration defining the JMX agent.
+   */
+  public AdminDistributedSystemJmxImpl(AgentConfigImpl config)
+      throws com.gemstone.gemfire.admin.AdminException {
+    super(config);
+    this.mbeanName = "GemFire:type=AdminDistributedSystem,id="
+        + MBeanUtil.makeCompliantMBeanNameProperty(getId());
+    this.objectName = MBeanUtil.createMBean(this);
+    isEmailNotificationEnabled = config.isEmailNotificationEnabled();
+    if (isEmailNotificationEnabled) {
+      initMailProps(config);
+    }
+    // Init file name for StatAlertDefns
+    initStateSaveFile(config);
+    Assert.assertTrue(this.objectName != null);
+
+    cacheRegionListener = new CacheAndRegionListenerImpl(this);
+  }
+
+  private void initMailProps(AgentConfigImpl config) {
+    mailProps = new Properties();
+    mailProps.put(MailManager.PROPERTY_MAIL_FROM, 
+                    config.getEmailNotificationFrom());
+    mailProps.put(MailManager.PROPERTY_MAIL_HOST, 
+                    config.getEmailNotificationHost());
+    mailProps.put(MailManager.PROPERTY_MAIL_TO_LIST, 
+                    config.getEmailNotificationToList());
+  }
+
+  private void initStateSaveFile(AgentConfigImpl agentConfig) {
+    // Init file name for StatAlertDefns
+    AgentConfigImpl impl = (AgentConfigImpl) agentConfig;
+    File propFile = impl.getPropertyFile();
+
+    if (propFile!=null) {
+     if (propFile.isDirectory()) {
+       statAlertDefnSerFile = propFile.getAbsolutePath();
+     } else if (propFile.getParentFile()!=null) {
+       statAlertDefnSerFile = propFile.getParentFile().getAbsolutePath();
+     }
+    }
+
+    statAlertDefnSerFile = statAlertDefnSerFile + File.separator + agentConfig.getStateSaveFile();
+  }
+  
+  // -------------------------------------------------------------------------
+  //   MBean operations
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Registers the MBeans for monitoring the health of GemFire 
+   *
+   * @see com.gemstone.gemfire.admin.internal.AdminDistributedSystemImpl#getGemFireHealth
+   */
+  public ObjectName monitorGemFireHealth() throws MalformedObjectNameException {
+    GemFireHealthJmxImpl health = (GemFireHealthJmxImpl) getGemFireHealth();
+    health.ensureMBeansAreRegistered();
+    return health.getObjectName();
+  }
+
+  /**
+   * Creates a new DistributionLocator for this system and registers an MBean
+   * for managing it.
+   * <p>
+   * If the Locator already exists, then this will simply register an MBean
+   * for it.
+   *
+   * @param host              the host name or IP address of the locator
+   * @param port              the port the locator service listens on
+   * @param workingDirectory  directory path for the locator and its log
+   * @param productDirectory  directory path to the GemFire product to use 
+   */
+  public ObjectName createDistributionLocator(String host,
+                                              int port,
+                                              String workingDirectory,
+                                              String productDirectory) 
+                                       throws MalformedObjectNameException {
+    return createDistributionLocator(
+        host, port, workingDirectory, productDirectory, getRemoteCommand());
+  }
+  
+  /**
+   * Creates a new DistributionLocator for this system and registers an MBean
+   * for managing it.
+   * <p>
+   * If the Locator already exists, then this will simply register an MBean
+   * for it.
+   *
+   * @param host              the host name or IP address of the locator
+   * @param port              the port the locator service listens on
+   * @param workingDirectory  directory path for the locator and its log
+   * @param productDirectory  directory path to the GemFire product to use 
+   * @param remoteCommand     formatted remote command to control remotely
+   */
+  public ObjectName createDistributionLocator(String host,
+                                              int port,
+                                              String workingDirectory,
+                                              String productDirectory,
+                                              String remoteCommand) 
+                                       throws MalformedObjectNameException {
+    try {
+      DistributionLocatorJmxImpl locator =
+        (DistributionLocatorJmxImpl) addDistributionLocator();
+      
+      DistributionLocatorConfig config = locator.getConfig();
+      config.setHost(host);
+      config.setPort(port);
+      config.setWorkingDirectory(workingDirectory);
+      config.setProductDirectory(productDirectory);
+      config.setRemoteCommand(remoteCommand);
+
+      return new ObjectName(locator.getMBeanName());
+    } catch (RuntimeException e) {
+      logger.warn(e.getMessage(), e);
+      throw 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 (Error 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();
+      logger.error(e.getMessage(), e);
+      throw e;
+    }
+  }
+  
+  // -------------------------------------------------------------------------
+  //   Template methods overriden from superclass...
+  // -------------------------------------------------------------------------
+  
+  /** Override createSystemMember by instantiating SystemMemberJmxImpl */
+  @Override
+  protected SystemMember createSystemMember(ApplicationVM app)
+  throws com.gemstone.gemfire.admin.AdminException {
+    return new SystemMemberJmxImpl(this, app);
+  }
+
+  /**
+   * Constructs & returns a SystemMember instance using the corresponding
+   * InternalDistributedMember object.
+   * 
+   * @param member
+   *          InternalDistributedMember instance for which a SystemMember
+   *          instance is to be constructed.
+   * @return constructed SystemMember instance
+   * @throws com.gemstone.gemfire.admin.AdminException
+   *           if construction of SystemMember instance fails
+   *
+   * @since 6.5
+   */
+  protected SystemMember createSystemMember(InternalDistributedMember member)
+      throws com.gemstone.gemfire.admin.AdminException {
+    return new SystemMemberJmxImpl(this, member);
+  }
+  
+
+  @Override
+  protected CacheServer createCacheServer(ApplicationVM member) 
+    throws AdminException {
+
+    return new CacheServerJmxImpl(this, member);
+  }
+
+  @Override
+  protected CacheServer createCacheServer(CacheServerConfigImpl config) 
+    throws AdminException {
+
+    return new CacheServerJmxImpl(this, config);
+  }
+
+  /** Override createGemFireHealth by instantiating GemFireHealthJmxImpl */
+  @Override
+  protected GemFireHealth createGemFireHealth(GfManagerAgent system) 
+    throws com.gemstone.gemfire.admin.AdminException {
+    if (system == null) {
+      throw new IllegalStateException(LocalizedStrings.AdminDistributedSystemJmxImpl_GFMANAGERAGENT_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+    return new GemFireHealthJmxImpl(system, this);
+  }
+  
+  /** Template-method for creating a DistributionLocatorImpl instance. */
+  @Override
+  protected DistributionLocatorImpl 
+    createDistributionLocatorImpl(DistributionLocatorConfig config) {
+    return new DistributionLocatorJmxImpl(config, this);
+  }
+
+  // -------------------------------------------------------------------------
+  //   Internal Admin listeners and JMX Notifications
+  // -------------------------------------------------------------------------
+  
+  /** Notification type for indicating system member joined */
+  public static final String NOTIF_MEMBER_JOINED = 
+                             "gemfire.distributedsystem.member.joined";
+  /** Notification type for indicating system member left */
+  public static final String NOTIF_MEMBER_LEFT = 
+                             "gemfire.distributedsystem.member.left";
+  /** Notification type for indicating system member crashed */
+  public static final String NOTIF_MEMBER_CRASHED = 
+                             "gemfire.distributedsystem.member.crashed";
+  /** Notification type for sending GemFire alerts as JMX notifications */
+  public static final String NOTIF_ALERT = 
+                             "gemfire.distributedsystem.alert";
+  /** Notification type for sending GemFire StatAlerts as JMX notifications */
+  public static final String NOTIF_STAT_ALERT = 
+    "gemfire.distributedsystem.statalert";
+  /** Notification type for indicating abnormal disconnection from the distributed system */
+  public static final String NOTIF_ADMIN_SYSTEM_DISCONNECT = 
+    "gemfire.distributedsystem.disconnect";
+  
+  
+  private static final String EML_SUBJ_PRFX_GFE_ALERT = "[GemFire Alert] ";
+  private static final String EML_SUBJ_PRFX_GFE_NOTFY = "[GemFire Notification] ";
+  private static final String EML_SUBJ_ITEM_GFE_DS = "Distributed System: ";
+
+  // --------- com.gemstone.gemfire.internal.admin.JoinLeaveListener ---------
+  /** 
+   * Listener callback for when a member has joined this DistributedSystem.
+   * <p>
+   * React by creating an MBean for managing the SystemMember and then fire
+   * a Notification with the internal Id of the member VM.
+   *
+   * @param source  the distributed system that fired nodeJoined
+   * @param joined  the VM that joined
+   * @see com.gemstone.gemfire.internal.admin.JoinLeaveListener#nodeJoined
+   */
+  @Override
+  public void nodeJoined(GfManagerAgent source, GemFireVM joined) {
+    try {
+      super.nodeJoined(source, joined);
+      
+      /* super.nodeJoined results in creation of a new SystemMember which 
+       * registers itself as an MBean, so now we try to find it...
+       */
+      SystemMember member = findSystemMember(joined);
+      
+      if(null == member) {
+        if (logger.isDebugEnabled()) {
+          logger.debug("AdminDistributedSystemJmxImpl.nodeJoined(), Could not find SystemMember for VM {}", joined);
+        }
+        return;
+      }
+      
+      try {
+        if (logger.isDebugEnabled()) {
+          logger.debug("Processing node joined for: {}", member);
+          logger.debug("RemoteGemFireVM.nodeJoined(), setting alerts manager *************");
+        }
+        setAlertsManager(joined);
+        
+        this.modelMBean.sendNotification(new Notification(
+            NOTIF_MEMBER_JOINED,
+            ((ManagedResource)member).getObjectName(), // Pass the ObjName of the Source Member
+            notificationSequenceNumber.addAndGet(1),
+            joined.getId().toString()));
+
+//      String mess = "Gemfire AlertNotification: System Member Joined, System member Id: " + joined.getId().toString();
+//      sendEmail("Gemfire AlertNotification: Member Joined, ID: " + joined.getId().toString(), mess);
+        if (isEmailNotificationEnabled) {
+          String mess = LocalizedStrings.AdminDistributedSystemJmxImpl_MEMBER_JOINED_THE_DISTRIBUTED_SYSTEM_MEMBER_ID_0.toLocalizedString(new Object[] {joined.getId().toString()} );
+        	sendEmail(
+        	    EML_SUBJ_PRFX_GFE_NOTFY + EML_SUBJ_ITEM_GFE_DS + getName() + " <" 
+        	    + LocalizedStrings.AdminDistributedSystemJmxImpl_MEMBER_JOINED.toLocalizedString() +">", 
+        	    mess);
+        }
+      } catch (javax.management.MBeanException e) {
+        logger.warn(e.getMessage(), e);
+      }
+    } catch (RuntimeException e) {
+      logger.warn(e.getMessage(), e);
+      throw 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 (Error 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();
+      logger.error(e.getMessage(), e);
+      throw e;
+    }
+  }
+  
+  /** 
+   * Listener callback for when a member has left this DistributedSystem.
+   * <p>
+   * React by removing the member's MBean.
+   * Also fire a Notification with the internal Id of the member VM.
+   *
+   * @param source  the distributed system that fired nodeLeft
+   * @param left    the VM that left
+   * @see com.gemstone.gemfire.internal.admin.JoinLeaveListener#nodeLeft
+   */
+  @Override
+  public void nodeLeft(GfManagerAgent source, GemFireVM left) {
+    try {
+      SystemMember member = findSystemMember(left, false);
+      super.nodeLeft(source, left);
+      if (logger.isDebugEnabled()) {
+        logger.debug("Processing node left for: {}", member);
+      }
+      try {
+        this.modelMBean.sendNotification(new Notification(
+            NOTIF_MEMBER_LEFT,
+            ((ManagedResource)member).getObjectName(), // Pass the ObjName of the Source Member
+            notificationSequenceNumber.addAndGet(1),
+            left.getId().toString()));
+
+//        String mess = "Gemfire AlertNotification: System Member Left the system, System member Id: " + left.getId().toString();
+//        sendEmail("Gemfire AlertNotification: Member Left, ID: " + left.getId().toString(), mess);
+        if (isEmailNotificationEnabled) {
+          String mess = LocalizedStrings.AdminDistributedSystemJmxImpl_MEMBER_LEFT_THE_DISTRIBUTED_SYSTEM_MEMBER_ID_0.toLocalizedString(new Object[] {left.getId().toString()} );
+        	sendEmail( 
+        	    EML_SUBJ_PRFX_GFE_NOTFY + EML_SUBJ_ITEM_GFE_DS + getName() + " <" 
+        	    + LocalizedStrings.AdminDistributedSystemJmxImpl_MEMBER_LEFT.toLocalizedString() +">", 
+        	    mess);
+        }
+      } catch (javax.management.MBeanException e) { 
+        logger.warn(e.getMessage(), e);
+      }
+      
+      SystemMemberType memberType = member.getType();  
+      if (/* member != null && */ memberType.isApplication() || memberType.isCacheVm()) {
+        // automatically unregister the MBean...
+        MBeanUtil.unregisterMBean((ManagedResource) member);
+      }
+    } catch (RuntimeException e) {
+      logger.warn(e.getMessage(), e);
+      throw 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 (Error 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();
+      logger.error(e.getMessage(), e);
+      throw e;
+    }
+  }
+  
+  /** 
+   * Listener callback for when a member of this DistributedSystem has crashed.
+   * <p>
+   * Also fires a Notification with the internal Id of the member VM.
+   *
+   * @param source  the distributed system that fired nodeCrashed
+   * @param crashed the VM that crashed
+   * @see com.gemstone.gemfire.internal.admin.JoinLeaveListener#nodeCrashed
+   */
+  @Override
+  public void nodeCrashed(GfManagerAgent source, GemFireVM crashed) {
+    try {
+      // SystemMember application has left...
+      SystemMember member = findSystemMember(crashed, false);
+      super.nodeCrashed(source, crashed);
+      if (logger.isDebugEnabled()) {
+        logger.debug("Processing node crash for: {}", member);
+      }
+      
+      try {
+        this.modelMBean.sendNotification(new Notification(
+            NOTIF_MEMBER_CRASHED,
+            ((ManagedResource)member).getObjectName(), // Pass the ObjName of the Source Member
+            notificationSequenceNumber.addAndGet(1),
+            crashed.getId().toString()));
+        
+//        String mess = "Gemfire AlertNotification: System Member Crashed, System member Id: " + crashed.getId().toString();
+//        sendEmail("Gemfire AlertNotification: Member Crashed, ID: " + crashed.getId().toString(), mess);
+        if (isEmailNotificationEnabled) {
+          String mess = LocalizedStrings.AdminDistributedSystemJmxImpl_MEMBER_CRASHED_IN_THE_DISTRIBUTED_SYSTEM_MEMBER_ID_0.toLocalizedString(new Object[] {crashed.getId().toString()} );
+        	sendEmail(
+        	    EML_SUBJ_PRFX_GFE_ALERT + EML_SUBJ_ITEM_GFE_DS + getName() + " <" 
+        	    + LocalizedStrings.AdminDistributedSystemJmxImpl_MEMBER_CRASHED.toLocalizedString() +">", 
+        	    mess);
+        }
+      } catch (javax.management.MBeanException e) {
+        logger.warn(e.getMessage(), e);
+      }
+
+      SystemMemberType memberType = member.getType();
+      if (/* member != null && */ memberType.isApplication() || memberType.isCacheVm()) {
+        // automatically unregister the MBean...
+        MBeanUtil.unregisterMBean((ManagedResource) member);
+      }
+    } catch (RuntimeException e) {
+      logger.warn(e.getMessage(), e);
+      throw 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 (Error 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();
+      logger.error(e.getMessage(), e);
+      throw e;
+    }
+  }
+
+  // ----------- com.gemstone.gemfire.internal.admin.AlertListener -----------
+  /** 
+   * Listener callback for when a SystemMember of this DistributedSystem has 
+   * crashed.
+   * <p>
+   * Fires a Notification with the information from the alert.
+   *
+   * @param alert the gemfire alert to broadcast as a notification
+   * @see com.gemstone.gemfire.internal.admin.AlertListener#alert
+   */
+  @Override
+  public void alert(Alert alert) {
+    try {
+      super.alert(alert);
+      try {
+        String strAlert = alert.toString();
+        this.modelMBean.sendNotification(new Notification(
+            NOTIF_ALERT,
+            this.mbeanName,
+            notificationSequenceNumber.addAndGet(1),
+            strAlert));
+        
+//        String mess = "Gemfire AlertNotification: System Alert :" + alert.toString();
+//        sendEmail("Gemfire AlertNotification: System Alert", mess);
+        if (isEmailNotificationEnabled) {
+          String mess = LocalizedStrings.AdminDistributedSystemJmxImpl_SYSTEM_ALERT_FROM_DISTRIBUTED_SYSTEM_0.toLocalizedString(strAlert);
+        	sendEmail( EML_SUBJ_PRFX_GFE_ALERT + EML_SUBJ_ITEM_GFE_DS + getName() + " <System Alert>", mess);
+        }
+      } catch (javax.management.MBeanException e) {
+        logger.warn(e.getMessage(), e);
+      }
+    } catch (RuntimeException e) {
+      logger.warn(e.getMessage(), e);
+      throw 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 (Error 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();
+      logger.error(e.getMessage(), e);
+      throw e;
+    }
+  }
+  
+  @Override
+  public void onDisconnect(InternalDistributedSystem sys) {
+    if (logger.isDebugEnabled()) {
+      this.logger.debug("Calling AdminDistributedSystemJmxImpl#onDisconnect");
+    }
+  	try {
+  		super.onDisconnect(sys);
+  		
+  		try {
+  			this.modelMBean.sendNotification(new Notification(
+  			        NOTIF_ADMIN_SYSTEM_DISCONNECT,
+  			        this.mbeanName,
+  			        notificationSequenceNumber.addAndGet(1),
+  			        null));
+  		} catch (MBeanException e) {
+  		  logger.warn(e.getMessage(), e);	
+  		}
+  	} catch (RuntimeException e) {
+  	  logger.warn(e.getMessage(), e);
+  	  throw 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 (Error 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();
+  	  logger.error(e.getMessage(), e);
+  	  throw e;
+  	}
+  	if (logger.isDebugEnabled()) {
+  	  this.logger.debug("Completed AdminDistributedSystemJmxImpl#onDisconnect");
+  	}
+  }
+  
+  // -------------------------------------------------------------------------
+  //   ManagedResource implementation
+  // -------------------------------------------------------------------------
+  
+  /** The name of the MBean that will manage this resource */
+  private String mbeanName;
+
+  /** The remotable ObjectName that the  MBean is registered under */
+  final private ObjectName objectName;
+  
+  /** The ModelMBean that is configured to manage this resource */
+  private ModelMBean modelMBean;
+  
+	public String getMBeanName() {
+		return this.mbeanName;
+	}
+  
+	public ModelMBean getModelMBean() {
+		return this.modelMBean;
+	}
+	public void setModelMBean(ModelMBean modelMBean) {
+		this.modelMBean = modelMBean;
+	}
+
+  public ObjectName getObjectName() {
+    return this.objectName;
+  }
+
+  public ManagedResourceType getManagedResourceType() {
+    return ManagedResourceType.DISTRIBUTED_SYSTEM;
+  }
+  
+  // -------------------------------------------------------------------------
+  //   Error traps added to overridden methods...
+  // -------------------------------------------------------------------------
+  
+  @Override
+  public boolean isRunning() {
+    try {
+      return super.isRunning();
+    } catch (java.lang.RuntimeException e) {
+      logger.warn(e.getMessage(), e);
+      throw 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 (java.lang.Error 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();
+      logger.error(e.getMessage(), e);
+      throw e;
+    }
+  }
+
+  @Override
+  public void start() throws AdminException {
+    try {
+      super.start();
+    } catch (java.lang.RuntimeException e) {
+      logger.warn(e.getMessage(), e);
+      throw 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 (java.lang.Error 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();
+      logger.error(e.getMessage(), e);
+      throw e;
+    }
+  }
+  
+  @Override
+  public void stop() throws AdminException {
+    try {
+      super.stop();
+    } catch (java.lang.RuntimeException e) {
+      logger.warn(e.getMessage(), e);
+      throw 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 (java.lang.Error 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();
+      logger.error(e.getMessage(), e);
+      throw e;
+    }
+  }
+
+  @Override
+  public boolean waitToBeConnected(long timeout)
+    throws InterruptedException {
+
+    if (Thread.interrupted()) throw new InterruptedException();
+    try {
+      return super.waitToBeConnected(timeout);
+    } catch (java.lang.RuntimeException e) {
+      logger.warn(e.getMessage(), e);
+      throw 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 (java.lang.Error 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();
+      logger.error(e.getMessage(), e);
+      throw e;
+    }
+  }
+
+  @Override
+  public String displayMergedLogs() {
+    try {
+      return super.displayMergedLogs();
+    } catch (java.lang.RuntimeException e) {
+      logger.warn(e.getMessage(), e);
+      throw 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 (java.lang.Error 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();
+      logger.error(e.getMessage(), e);
+      throw e;
+    }
+  }
+
+  public ObjectName manageDistributionLocator()
+    throws MalformedObjectNameException {
+
+    try {
+      return new ObjectName(((ManagedResource) addDistributionLocator()).getMBeanName());
+    }
+//     catch (AdminException e) { logger.warn(e.getMessage(), e); throw e; }
+    catch (RuntimeException e) {
+      logger.warn(e.getMessage(), e);
+      throw 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 (Error 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();
+      logger.error(e.getMessage(), e);
+      throw e;
+    }
+  }
+
+  public ObjectName[] manageDistributionLocators() 
+  throws MalformedObjectNameException {
+    try {
+      DistributionLocator[] locs = getDistributionLocators();
+      ObjectName[] onames = new javax.management.ObjectName[locs.length];
+      for (int i = 0; i < locs.length; i++) {
+        DistributionLocatorJmxImpl loc = (DistributionLocatorJmxImpl) locs[i];
+        onames[i] = new ObjectName(loc.getMBeanName());
+      }
+      return onames;
+    }
+    //catch (AdminException e) { logger.warn(e.getMessage(), e); throw e; }
+    catch (RuntimeException e) { 
+      logger.warn(e.getMessage(), e); 
+      throw 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 (Error 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();
+      logger.error(e.getMessage(), e); 
+      throw e; 
+    }
+  }
+    
+  /**
+   * @deprecated as of 5.7 use {@link #manageCacheVm} instead.
+   */
+  @Deprecated
+  public ObjectName manageCacheServer()
+  throws AdminException, MalformedObjectNameException {
+    return manageCacheVm();
+  }
+  public ObjectName manageCacheVm()
+  throws AdminException, MalformedObjectNameException {
+    try {
+      return new ObjectName(((ManagedResource) addCacheVm()).getMBeanName());
+    } catch (AdminException e) { 
+      logger.warn(e.getMessage(), e); 
+      throw e; 
+    } catch (RuntimeException e) { 
+      logger.warn(e.getMessage(), e); 
+      throw 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 (Error 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();
+      logger.warn(e.getMessage(), e);
+      throw e; 
+    }
+  }
+
+  /**
+   * @deprecated as of 5.7 use {@link #manageCacheVms} instead.
+   */
+  @Deprecated
+  public ObjectName[] manageCacheServers()
+  throws AdminException, MalformedObjectNameException {
+    return manageCacheVms();
+  }
+
+  public ObjectName[] manageCacheVms()
+  throws AdminException, MalformedObjectNameException {
+    try {
+      CacheVm[] mgrs = getCacheVms();
+      ObjectName[] onames = new javax.management.ObjectName[mgrs.length];
+      for (int i = 0; i < mgrs.length; i++) {
+        CacheServerJmxImpl mgr = (CacheServerJmxImpl) mgrs[i];
+        onames[i] = new ObjectName(mgr.getMBeanName());
+      }
+      return onames;
+    } catch (AdminException e) { 
+      logger.warn(e.getMessage(), e); 
+      throw e; 
+    } catch (RuntimeException e) { 
+      logger.warn(e.getMessage(), e); 
+      throw 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 (Error 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();
+      logger.error(e.getMessage(), e);
+      throw e; 
+    }
+  }
+
+  public ObjectName[] manageSystemMemberApplications()
+  throws AdminException, MalformedObjectNameException {
+    try {
+      SystemMember[] apps = getSystemMemberApplications();
+      ObjectName[] onames = new javax.management.ObjectName[apps.length];
+      for (int i = 0; i < apps.length; i++) {
+        SystemMemberJmxImpl app = (SystemMemberJmxImpl) apps[i];
+        onames[i] = new ObjectName(app.getMBeanName());
+      }
+      return onames;
+    } catch (AdminException e) { 
+      logger.warn(e.getMessage(), e); 
+      throw e; 
+    } catch (RuntimeException e) { 
+      logger.warn(e.getMessage(), e); 
+      throw 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 (Error 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();
+      logger.error(e.getMessage(), e);
+      throw e; 
+    }
+  }
+  
+  /**
+   * Return the ObjectName for the SystemMemberMBean representing the
+   * specified distributed member or null if the member is not found.
+   *
+   * @param distributedMember the distributed member to manage
+   * @return the ObjectName for the SystemMemberMBean
+   */
+  public ObjectName manageSystemMember(DistributedMember distributedMember)
+  throws AdminException, MalformedObjectNameException {
+    try {
+      SystemMember member = lookupSystemMember(distributedMember);
+      if (member == null) return null;
+      SystemMemberJmxImpl jmx = (SystemMemberJmxImpl) member;
+      ObjectName oname = new ObjectName(jmx.getMBeanName());
+      return oname;
+    } catch (AdminException e) { 
+      logger.warn(e.getMessage(), e); 
+      throw e; 
+    } catch (RuntimeException e) { 
+      logger.warn(e.getMessage(), e); 
+      throw 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 (Error 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();
+      logger.error(e.getMessage(), e);
+      throw e; 
+    }
+  }
+  
+  @Override
+  public void connect(InternalLogWriter logWriter) {
+    try {
+      // LOG: passes the AdminDistributedSystemImpl LogWriterLogger into GfManagerAgentConfig
+      super.connect(logWriter);
+      
+      // Load existing StatAlert Definitions
+      readAlertDefinitionsAsSerializedObjects();
+
+      /* Add Cache Listener to listen to Cache & Region create/destroy events */
+      if (logger.isDebugEnabled()) {
+        logger.debug("Adding CacheAndRegionListener .... ");
+      }
+      addCacheListener(cacheRegionListener);
+    } catch (RuntimeException e) { 
+      logger.warn(e.getMessage(), e);
+      throw 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 (Error 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();
+      logger.error(e.getMessage(), e);
+      throw e; 
+    }
+  }
+  
+  @Override
+  public void disconnect() {
+    try {
+      super.disconnect();
+      
+      // Save existing StatAlert Definitions
+      saveAlertDefinitionsAsSerializedObjects();
+
+      /* Remove Cache Listener to listen to Cache & Region create/destroy events */
+      if (logger.isDebugEnabled()) {
+        logger.debug("Removing CacheAndRegionListener .... ");
+      }
+      removeCacheListener(cacheRegionListener);      
+    } catch (RuntimeException e) { 
+      logger.warn(e.getMessage(), e);
+      throw e;
+    } catch (VirtualMachineError err) {
+      SystemFailure.initiateFailure(err);
+      // If this ever returns, re-throw the error.  We're poisoned
+      // now, so don't let this thread continue.
+      throw err;
+    } catch (Error 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();
+      logger.error(e.getMessage(), e);
+      throw e;
+    }
+  }
+
+  public void cleanupResource() {
+    disconnect();
+  }
+  
+  /**
+   * @return the isRmiClientCountZero
+   * @since 6.0
+   */
+  public boolean isRmiClientCountZero() {
+    return isRmiClientCountZero;
+  }
+
+  /**
+   * @param isRmiClientCountZero the isJmxClientCountZero to set
+   * @since 6.0
+   */
+  void setRmiClientCountZero(boolean isRmiClientCountZero) {
+    this.isRmiClientCountZero = isRmiClientCountZero;
+    
+    if (isRmiClientCountZero) {
+      logger.info(LocalizedStrings.AdminDistributedSystemJmxImpl_JMX_CLIENT_COUNT_HAS_DROPPED_TO_ZERO);
+    }
+  }
+
+
+  ///////////////////////  Configuration  ///////////////////////
+
+  public String getEntityConfigXMLFile() {
+    return this.getConfig().getEntityConfigXMLFile();
+  }
+
+  public void setEntityConfigXMLFile(String xmlFile) {
+    this.getConfig().setEntityConfigXMLFile(xmlFile);
+  }
+
+  public String getSystemId() {
+    return this.getConfig().getSystemId();
+  }
+
+  public void setSystemId(String systemId) {
+    this.getConfig().setSystemId(systemId);
+  }
+
+  @Override
+  public String getSystemName() {
+    return this.getConfig().getSystemName();
+  }
+
+  public void setSystemName(final String name) {
+    this.getConfig().setSystemName(name);
+  }
+    
+  @Override
+  public boolean getDisableTcp() {
+    return this.getConfig().getDisableTcp();
+  }
+
+  public void setEnableNetworkPartitionDetection(boolean newValue) {
+    getConfig().setEnableNetworkPartitionDetection(newValue);
+  }
+  public boolean getEnableNetworkPartitionDetection() {
+    return getConfig().getEnableNetworkPartitionDetection();
+  }
+  public int getMemberTimeout() {
+   return getConfig().getMemberTimeout();
+  }
+  public void setMemberTimeout(int value) {
+    getConfig().setMemberTimeout(value);
+  }
+  
+  @Override
+  public String getMcastAddress() {
+    return this.getConfig().getMcastAddress();
+  }
+
+  public void setMcastAddress(String mcastAddress) {
+    this.getConfig().setMcastAddress(mcastAddress);
+  }
+
+  @Override
+  public int getMcastPort() {
+    return this.getConfig().getMcastPort();
+  }
+  
+  public void setMcastPort(int mcastPort) {
+    this.getConfig().setMcastPort(mcastPort);
+  }
+
+  public int getAckWaitThreshold() {
+    return getConfig().getAckWaitThreshold();
+  }
+  
+  public void setAckWaitThreshold(int seconds) {
+    getConfig().setAckWaitThreshold(seconds);
+  }
+
+  public int getAckSevereAlertThreshold() {
+    return getConfig().getAckSevereAlertThreshold();
+  }
+  
+  public void setAckSevereAlertThreshold(int seconds) {
+    getConfig().setAckSevereAlertThreshold(seconds);
+  }
+
+  @Override
+  public String getLocators() {
+    return this.getConfig().getLocators();
+  }
+
+  @Override
+  public void setLocators(String locators) {
+    this.getConfig().setLocators(locators);
+  }
+  
+  /* Note that the getter & setter for membership port range are referred from 
+   * the super class AdminDistributedSystemImpl */
+
+  public String getBindAddress() {
+    return this.getConfig().getBindAddress();
+  }
+
+  public void setBindAddress(String bindAddress) {
+    this.getConfig().setBindAddress(bindAddress);
+  }
+  
+  public String getServerBindAddress() {
+    return this.getConfig().getServerBindAddress();
+  }
+
+  public void setServerBindAddress(String bindAddress) {
+    this.getConfig().setServerBindAddress(bindAddress);
+  }
+
+  @Override
+  public String getRemoteCommand() {
+    return this.getConfig().getRemoteCommand();
+  }
+
+  @Override
+  public void setRemoteCommand(String command) {
+    this.getConfig().setRemoteCommand(command);
+  }
+
+  public boolean isSSLEnabled() {
+    return this.getConfig().isSSLEnabled();
+  }
+
+  public void setSSLEnabled(boolean enabled) {
+    this.getConfig().setSSLEnabled(enabled);
+  }
+
+  public String getSSLProtocols() {
+    return this.getConfig().getSSLProtocols();
+  }
+
+  public void setSSLProtocols(String protocols) {
+    this.getConfig().setSSLProtocols(protocols);
+  }
+
+  public String getSSLCiphers() {
+    return this.getConfig().getSSLCiphers();
+  }
+
+  public void setSSLCiphers(String ciphers) {
+    this.getConfig().setSSLCiphers(ciphers);
+  }
+
+  public boolean isSSLAuthenticationRequired() {
+    return this.getConfig().isSSLAuthenticationRequired();
+  }
+
+  public void setSSLAuthenticationRequired(boolean authRequired) {
+    this.getConfig().setSSLAuthenticationRequired(authRequired);
+  }
+  
+  public Properties getSSLProperties() {
+    return this.getConfig().getSSLProperties();
+  }
+
+  public void setSSLProperties(Properties sslProperties) {
+    this.getConfig().setSSLProperties(sslProperties);
+  }
+
+  public void addSSLProperty(String key, String value) {
+    this.getConfig().addSSLProperty(key, value);
+  }
+
+  public void removeSSLProperty(String key) {
+    this.getConfig().removeSSLProperty(key);
+  }
+  
+  public String getLogFile() {
+    return this.getConfig().getLogFile();
+  }
+
+  public void setLogFile(String logFile) {
+    this.getConfig().setLogFile(logFile);
+  }
+
+  public String getLogLevel() {
+    return this.getConfig().getLogLevel();
+  }
+
+  public void setLogLevel(String logLevel) {
+    this.getConfig().setLogLevel(logLevel);
+  }
+
+  public int getLogDiskSpaceLimit() {
+    return this.getConfig().getLogDiskSpaceLimit();
+  }
+
+  public void setLogDiskSpaceLimit(int limit) {
+    this.getConfig().setLogDiskSpaceLimit(limit);
+  }
+
+  public int getLogFileSizeLimit() {
+    return this.getConfig().getLogFileSizeLimit();
+  }
+
+  public void setLogFileSizeLimit(int limit) {
+    this.getConfig().setLogFileSizeLimit(limit);
+  }
+
+  public void setDisableTcp(boolean flag) {
+    this.getConfig().setDisableTcp(flag);
+  }
+
+  public int getRefreshInterval() {
+    return this.getConfig().getRefreshInterval();
+  }
+
+  /*
+   * The interval (in seconds) between auto-polling for updating
+   * AdminDistributedSystem constituents including SystemMember,
+   * SystemMemberCache and StatisticResource. This applies only to the default
+   * interval set when the resource is created. Changes to this interval will
+   * not get propagated to existing resources but will apply to all new
+   * resources
+   */
+  public void setRefreshInterval(int interval) {
+    this.getConfig().setRefreshInterval(interval);
+  }
+
+  public CacheServerConfig[] getCacheServerConfigs() {
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+
+  public CacheServerConfig createCacheServerConfig() {
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+
+  public void removeCacheServerConfig(CacheServerConfig config) {
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+
+  public CacheVmConfig[] getCacheVmConfigs() {
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+
+  public CacheVmConfig createCacheVmConfig() {
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+
+  public void removeCacheVmConfig(CacheVmConfig config) {
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+
+  public DistributionLocatorConfig[] getDistributionLocatorConfigs() {
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+  
+  public DistributionLocatorConfig createDistributionLocatorConfig() {
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+
+  public void removeDistributionLocatorConfig(DistributionLocatorConfig config) 
+{
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+
+  public void addListener(ConfigListener listener) {
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+
+  public void removeListener(ConfigListener listener) {
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+
+  public void validate() {
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+
+  @Override
+  public Object clone() throws CloneNotSupportedException {
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+  
+
+  private static final String[] PERSISTENT_ID_FIELDS = new String[] {"host", "directory", "uuid"};
+  private static final String[] PERSISTENT_ID_DESCRIPTIONS = new String[] {"The host that was persisting the missing files", "The directory where the files were persisted", "The unique id for the persistent files"};
+  private final CompositeType PERSISTENT_ID_TYPE;
+  private final TabularType PERSISTENT_ID_TABLE_TYPE;
+  
+  { 
+    try {
+      PERSISTENT_ID_TYPE = new CompositeType(PersistentID.class.getCanonicalName(), "A single member's a set of persistent files for a region", PERSISTENT_ID_FIELDS, PERSISTENT_ID_DESCRIPTIONS, new OpenType[] {SimpleType.STRING, SimpleType.STRING, SimpleType.STRING});
+      PERSISTENT_ID_TABLE_TYPE = new TabularType("TABLE_" + PERSISTENT_ID_TYPE.getTypeName(), "A table of persistent member ids", PERSISTENT_ID_TYPE, PERSISTENT_ID_FIELDS);
+    } catch (OpenDataException e) {
+      throw new ExceptionInInitializerError(e);
+    }
+  }
+  
+  public TabularData getMissingPersistentMembersJMX() throws AdminException {
+    
+    try {
+      Set<PersistentID> members = super.getMissingPersistentMembers();
+      TabularData results = new TabularDataSupport(PERSISTENT_ID_TABLE_TYPE);
+      int index = 0;
+      for(PersistentID id : members) {
+        CompositeData idData = new CompositeDataSupport(PERSISTENT_ID_TYPE, PERSISTENT_ID_FIELDS, new Object[] {id.getHost().toString(), id.getDirectory(), id.getUUID().toString()});
+        results.put(idData);
+        index++;
+      }
+      return results;
+    } catch( OpenDataException e) {
+      logger.warn("Exception occurred while getting missing persistent members.", e);
+      throw new AdminException(e);
+    }
+  }
+
+  public void revokePersistentMember(String host,
+      String directory) throws AdminException, UnknownHostException {
+    super.revokePersistentMember(InetAddress.getByName(host), directory);
+  }
+  
+  public void revokePersistentMember(String uuid) throws AdminException, UnknownHostException {
+    super.revokePersistentMember(UUID.fromString(uuid));
+  }
+
+  /* ********************************************************************* */
+  /* ************** Implementing StatAlertsAggregator interface ********** */
+  /* ********************************************************************* */
+  
+  /* Map to store admin stat alert definitions */
+  private final Map ALERT_DEFINITIONS = new Hashtable();
+  
+  /* Refresh interval for all stat alerts managers in seconds */
+  private int refreshIntervalForStatAlerts = 20;
+
+  /* 
+   * This map contains list of stat alerts as a value for alert def ID as a key  
+   */
+  private final HashMap alertsStore = new HashMap();
+  
+  //TODO: yet to set the timer task
+//  private SystemTimer systemwideAlertNotificationScheduler = new SystemTimer();
+  
+  private MailManager mailManager = null;
+  private final boolean isEmailNotificationEnabled;
+  
+  /**
+   * Convenience method to retrieve admin stat alert definition.
+   * 
+   * @param alertDefinitionId id of a stat alert definition 
+   * @return StatAlertDefinition reference to an instance of StatAlertDefinition
+   * @since 5.7
+   */
+  private StatAlertDefinition getAlertDefinition(int alertDefinitionId) {
+    synchronized(ALERT_DEFINITIONS) {
+      return (StatAlertDefinition)ALERT_DEFINITIONS.get(Integer.valueOf(alertDefinitionId));
+    }
+  }
+  
+/*  private void setAlertDefinition(StatAlertDefinition alertDefinition) {
+    ALERT_DEFINITIONS.put(Integer.valueOf(alertDefinition.getId()), alertDefinition);
+  }*/
+
+  /** 
+   * This method can be used to get an alert definition. 
+   * 
+   * @param alertDefinition StatAlertDefinition to retrieve
+   * @return StatAlertDefinition 
+   * @since 5.7
+   */
+  public StatAlertDefinition getAlertDefinition(StatAlertDefinition alertDefinition) {
+    return getAlertDefinition(alertDefinition.getId());
+  }
+  
+  /**
+   * This method is used to write existing StatAlertDefinitions 
+   * to a file
+   */
+  protected void readAlertDefinitionsAsSerializedObjects() {
+    StatAlertDefinition[] defns = new StatAlertDefinition[0];
+
+    File serFile = null;
+    FileInputStream foStr = null;
+    DataInputStream ooStr = null;
+
+    try {
+      serFile = new File(statAlertDefnSerFile);
+      
+      if (!canWriteToFile(serFile)) {/* can not write a file */
+        canPersistStatAlertDefs = false;
+      }
+      if (!serFile.exists()) {/* file does not exist */
+        return;
+      }
+      
+      if (logger.isDebugEnabled()) {
+        logger.debug("AdminDistributedSystemJmxImpl.readAlertDefinitionsAsSerializedObjects: File: {}", serFile.getPath());
+      }
+
+      foStr = new FileInputStream(serFile);
+      ooStr = new DataInputStream(foStr);
+      defns = (StatAlertDefinition[])DataSerializer.readObjectArray(ooStr);
+    } catch (ClassNotFoundException cnfEx) {
+      logger.error(LocalizedMessage.create(
+          LocalizedStrings.AdminDistributedSystem_ENCOUNTERED_A_0_WHILE_LOADING_STATALERTDEFINITIONS_1,
+          new Object[] {cnfEx.getClass().getName(), statAlertDefnSerFile}), cnfEx);
+      canPersistStatAlertDefs = false;
+    } catch (IOException ex) {
+      logger.error(LocalizedMessage.create(
+          LocalizedStrings.AdminDistributedSystem_ENCOUNTERED_A_0_WHILE_LOADING_STATALERTDEFINITIONS_1_LOADING_ABORTED,
+          new Object[] {ex.getClass().getName(), statAlertDefnSerFile}), ex);
+      canPersistStatAlertDefs = false;
+    } finally {
+      if (foStr!=null) {
+        try {
+          foStr.close();
+        } catch (IOException ex) {
+          ;
+        }
+      }
+      if (ooStr!=null) { 
+        try {
+          ooStr.close();
+        } catch (IOException ex) {
+          ;
+        }
+      }
+    }
+    
+    for (int i=0; i<defns.length; i++) {
+      updateAlertDefinition(defns[i]);
+    }
+  }
+
+  /**
+   * This method is used to write existing StatAlertDefinitions 
+   * to a file
+   */
+  public void saveAlertDefinitionsAsSerializedObjects() {
+    File serFile = null;
+    FileOutputStream foStr = null;
+    DataOutputStream ooStr = null;
+    try {
+      serFile = new File(statAlertDefnSerFile);
+      
+  
+      if (logger.isDebugEnabled()) {
+        logger.debug("AdminDistributedSystemJmxImpl.saveAlertDefinitionsAsSerializedObjects: File: {}", serFile.getPath());
+      }
+      
+      if (!canWriteToFile(serFile)) {
+        return;
+      }
+      
+      foStr = new FileOutputStream(serFile);
+      ooStr = new DataOutputStream(foStr);
+      
+      int numOfAlerts = 0;
+      StatAlertDefinition[] defs = null;
+
+      synchronized (ALERT_DEFINITIONS) {
+        numOfAlerts = ALERT_DEFINITIONS.size();
+        defs = new StatAlertDefinition[numOfAlerts];
+        
+        int i = 0;
+        for (Iterator iter=ALERT_DEFINITIONS.keySet().iterator(); iter.hasNext() ;) {
+          Integer key = (Integer) iter.next();
+          StatAlertDefinition readDefn = (StatAlertDefinition) ALERT_DEFINITIONS.get(key);
+          defs[i] = readDefn;
+          i++; 
+        }
+      }
+
+      DataSerializer.writeObjectArray(defs, ooStr);
+    } catch (IOException ex) {
+      logger.error(LocalizedMessage.create(
+          LocalizedStrings.AdminDistributedSystem_ENCOUNTERED_A_0_WHILE_SAVING_STATALERTDEFINITIONS_1,
+          new Object[] {ex.getClass().getName(), statAlertDefnSerFile}), ex);
+    } finally {
+      if (foStr!=null) 
+        try {
+          foStr.close();
+        } catch (IOException ex) {
+          ;
+        }
+      if (ooStr!=null) 
+        try {
+          ooStr.close();
+        } catch (IOException ex) {
+          ;
+        }
+    }
+  }
+
+  /**
+   * Checks if the given file is writable.
+   * 
+   * @param file
+   *          file to check write permissions for
+   * @return true if file is writable, false otherwise
+   */
+  private boolean canWriteToFile(File file) {
+    boolean fileIsWritable = true;
+    // Fix for BUG40360 : When the user does not have write permissions for
+    // saving the stat-alert definitions, then appropriate warning message is 
+    // logged and the operation is aborted. In case the file doesn't exist, then 
+    // it attempts to create a file. If the attempt fails then it logs 
+    // appropriate warning and the operation is aborted. File.canWrite check for
+    // a directory sometimes fails on Windows platform. Hence file creation is 
+    // necessary.
+    if (file.exists()) {
+      if (!file.canWrite()) {
+        logger.warn(LocalizedMessage.create(
+            LocalizedStrings.AdminDistributedSystemJmxImpl_READONLY_STAT_ALERT_DEF_FILE_0,
+            new Object[] { file }));
+        fileIsWritable = false;
+      }
+    } else {
+      try {
+        file.createNewFile();
+      } catch (IOException e) {
+        logger.warn(LocalizedMessage.create(
+            LocalizedStrings.AdminDistributedSystemJmxImpl_FAILED_TO_CREATE_STAT_ALERT_DEF_FILE_0,
+            new Object[] { file }), e);
+        fileIsWritable = false;
+      } finally {
+        // Since we had created this file only for testing purpose, delete the
+        // same.
+        if ((file.exists() && !file.delete()) && logger.isDebugEnabled()) {
+          logger.debug("Could not delete file :'{}' which is created for checking permissions.", file.getAbsolutePath());
+        }
+      }
+    }
+    return fileIsWritable;
+  }
+
+  /** 
+   * This method can be used to update alert definition for the Stat mentioned.
+   * This method should update the collection maintained at the aggregator and 
+   * should notify members for the newly added alert definitions.
+   * A new alert definition will be created if matching one not found.
+   * 
+   * @param alertDefinition alertDefinition to be updated 
+   * @since 5.7
+   */  
+  public void updateAlertDefinition(StatAlertDefinition alertDefinition) {
+    if (logger.isDebugEnabled()) {
+      logger.debug("Entered AdminDistributedSystemJmxImpl.updateAlertDefinition(StatAlertDefinition) *****");
+    }
+    /*
+     * What to update in the alert definition? There should be another argument 
+     * or arguments in a map.
+     * 1. Need to update the list/map of alert definitions across members.   
+     */
+    synchronized (ALERT_DEFINITIONS) {
+      ALERT_DEFINITIONS.put(Integer.valueOf(alertDefinition.getId()), alertDefinition);
+      
+      if (logger.isDebugEnabled()) {
+        logger.debug("AdminDistributedSystemJmxImpl.updateAlertDefinition : alertDefinition :: id={} :: {}", alertDefinition.getId(), alertDefinition.getStringRepresentation());
+      }
+      
+      /* TODO: add code to retry on failure */
+      notifyMembersForAlertDefinitionChange(alertDefinition);
+    }
+    if (logger.isDebugEnabled()) {
+      logger.debug("Exiting AdminDistributedSystemJmxImpl.updateAlertDefinition(StatAlertDefinition) *****");
+    }
+  }
+
+  /** 
+   * This method can be used to remove alert definition for the Stat 
+   * mentioned. 
+   * This method should update the collection maintained at the aggregator and 
+   * should notify members for the newly added alert definitions. 
+   * 
+   * @param defId id of the alert definition to be removed
+   * @since 5.7
+   */  
+  public void removeAlertDefinition(Integer defId) {
+    if (logger.isDebugEnabled()) {
+      logger.debug("Entered AdminDistributedSystemJmxImpl.removeAlertDefinition id *****");
+    }
+    /*
+     * alert passed to be deleted from the list/map of alerts on JMX MBean 
+     * & all Member MBeans
+     */
+    synchronized (ALERT_DEFINITIONS) {
+      StatAlertDefinition alertDefinition = (StatAlertDefinition)ALERT_DEFINITIONS.get(defId);
+  	  if (alertDefinition != null) {
+    		ALERT_DEFINITIONS.remove(defId);
+    		synchronized (alertsStore) {
+    		  alertsStore.remove(defId);
+    		}
+    		/* TODO: add code to retry on failure */
+    		notifyMembersForAlertDefinitionRemoval(alertDefinition);
+  	  }      
+    }
+    if (logger.isDebugEnabled()) {
+      logger.debug("Exiting AdminDistributedSystemJmxImpl.removeAlertDefinition() *****");
+    }
+  }
+
+  /** 
+   * Convenience method to check whether an alert definition is created.
+   * 
+   * @param alertDefinition alert definition to check whether already created
+   * @return true if the alert definition is already created, false 
+   *         otherwise 
+   * @since 5.7
+   */
+  public boolean isAlertDefinitionCreated(StatAlertDefinition alertDefinition) {
+    /*
+     * Need to maintain a map of stat against the StatAlertDefinitions.
+     * check in that map whether the alert definition is there for the given 
+     * alert
+     * 
+     * TODO: optimize to use Map.containsKey - DONE
+     */
+    synchronized(ALERT_DEFINITIONS) {
+      return ALERT_DEFINITIONS.containsKey(Integer.valueOf(alertDefinition.getId()));
+    }
+  }
+
+  /**
+   * Returns the refresh interval for the Stats in seconds.
+   * 
+   * @return refresh interval for the Stats(in seconds)
+   * @since 5.7
+   */
+  public synchronized int getRefreshIntervalForStatAlerts() {
+    /*
+     * state to store the refresh interval set by the user/GFMon client 
+     */
+    return refreshIntervalForStatAlerts;
+  }
+
+  /**
+   * This method is used to set the refresh interval for the Stats in 
+   * seconds 
+   * 
+   * @param refreshIntervalForStatAlerts refresh interval for the Stats(in seconds)
+   * @since 5.7
+   */
+  public synchronized void setRefreshIntervalForStatAlerts(int refreshIntervalForStatAlerts) {
+    /*
+     * change the state refresh interval here. 
+     */
+    this.refreshIntervalForStatAlerts = refreshIntervalForStatAlerts;
+    notifyMembersForRefreshIntervalChange(this.refreshIntervalForStatAlerts*1000l);
+  }
+
+  /**
+   * Returns whether Statistics Alert definitions could be persisted across 
+   * runs/sessions
+   * 
+   * @return value of canPersistStatAlertDefs.
+   * @since 6.5
+   */
+  public boolean canPersistStatAlertDefs() {
+    return canPersistStatAlertDefs;
+  }
+
+  /**
+   * An intermediate method to notify all members for change in refresh interval.
+   * 
+   * @param newInterval refresh interval to be set for members(in milliseconds)
+   */
+  private void notifyMembersForRefreshIntervalChange(long newInterval) {
+    GfManagerAgent  agent = getGfManagerAgent();
+    ApplicationVM[] VMs   = agent.listApplications();    
+    //TODO: is there any other way to get all VMs?
+    
+    for (int i = 0; i < VMs.length; i++) {
+      VMs[i].setRefreshInterval(newInterval);
+    }
+  }
+  
+  /**
+   * An intermediate method to notify all members for change in stat alert 
+   * definition.
+   * 
+   * @param alertDef stat alert definition that got changed
+   */  
+  private void notifyMembersForAlertDefinitionChange(StatAlertDefinition alertDef) {
+    if (logger.isDebugEnabled()) {
+      logger.debug("Entered AdminDistributedSystemJmxImpl.notifyMembersForAlertDefinitionChange(StatAlertDefinition) *****");
+    }
+    GfManagerAgent        agent     = getGfManagerAgent();
+    StatAlertDefinition[] alertDefs = new StatAlertDefinition[] {alertDef};
+    ApplicationVM[]       VMs       = agent.listApplications();
+    
+    for (int i = 0; i < VMs.length; i++) {
+      VMs[i].updateAlertDefinitions(alertDefs, 
+          UpdateAlertDefinitionMessage.UPDATE_ALERT_DEFINITION);
+    }
+
+    if (logger.isDebugEnabled()) {
+      logger.debug("Exiting AdminDistributedSystemJmxImpl.notifyMembersForAlertDefinitionChange(StatAlertDefinition) "
+    		    + VMs.length+" members notified.*****");
+    }
+  }
+
+  /**
+   * An intermediate method to notify all members for removal of stat alert 
+   * definition.
+   * 
+   * @param alertDef stat alert definition to be removed
+   */
+  private void notifyMembersForAlertDefinitionRemoval(StatAlertDefinition alertDef) {
+    GfManagerAgent        agent     = getGfManagerAgent();
+    StatAlertDefinition[] alertDefs = new StatAlertDefinition[] {alertDef};
+    ApplicationVM[]       VMs       = agent.listApplications();
+    
+    for (int i = 0; i < VMs.length; i++) {
+      VMs[i].updateAlertDefinitions(alertDefs, 
+          UpdateAlertDefinitionMessage.REMOVE_ALERT_DEFINITION);
+    }
+  }
+
+  /**
+   * This method can be used to set the AlertsManager for the newly joined     
+   * member VM.
+   * 
+   * @param memberVM Member VM to set AlertsManager for
+   * @since 5.7
+   */
+  public synchronized void setAlertsManager(GemFireVM memberVM) {
+    /*
+     * 1. Who'll call this method? Who gets notified when a member joins? 
+     *    I think that's AdminDistributedSystemJmxImpl.nodeCreated()
+     * 2. Is the argument GemFireVM correct? Need to modify this interface to 
+     *    add method to set an interface. Need to see how it can be passed to 
+     *    the RemoteGemFireVM implementation. Also need to check whetherother 
+     *    implementors (like DistributedSystemHealthMonitor) of GemFireVM even 
+     *    need to have the AlertsManager
+     * 3. Would the alerts manager be set by aggregator or a JMXAgent i.e. AdminDistributedSystemJmxImpl
+     * 4. Setting the list of available alert definitions & refresh interval at 
+     *    this moment only would be better/easier.
+     * 5. Need to know Alerts Manager creation/construction. Need to decide how 
+     *    the object would be set & sent across to the Agent VM.
+     */
+    if (logger.isDebugEnabled()) {
+      logger.debug("Entered AdminDistributedSystemJmxImpl.setAlertsManager(GemFireVM) *****");
+    }
+    
+    // creating an array of stat alert definition objects
+    StatAlertDefinition[] alertDefs = new StatAlertDefinition[0];
+    
+    Collection alertDefsCollection = null;
+    synchronized(ALERT_DEFINITIONS) {
+      alertDefsCollection = ALERT_DEFINITIONS.values();
+    }
+    
+    alertDefs = (StatAlertDefinition[])alertDefsCollection.toArray(alertDefs);
+    
+    memberVM.setAlertsManager(alertDefs, getRefreshIntervalForStatAlerts()*1000l, true);
+    
+    if (logger.isDebugEnabled()) {
+      logger.debug("Exiting AdminDistributedSystemJmxImpl.setAlertsManager(GemFireVM) *****");
+    }
+  }
+
+  /** 
+   * This method can be used to retrieve all available stat alert definitions. 
+   * Returns empty array if there are no stat alert definitions defined.
+   * 
+   * @return An array of all available StatAlertDefinition objects 
+   * @since 5.7
+   */
+  public StatAlertDefinition[] getAllStatAlertDefinitions() {
+    if (logger.isDebugEnabled()) {
+      logger.debug("Entered AdminDistributedSystemJmxImpl.getAllStatAlertDefinitions() *****");
+    }
+    
+    Collection alertDefs = null;
+    synchronized(ALERT_DEFINITIONS) {
+      alertDefs = ALERT_DEFINITIONS.values();
+    }
+    
+    StatAlertDefinition[] alertDefsArr = null;
+    
+    if (alertDefs != null) {
+      alertDefsArr = new StatAlertDefinition[alertDefs.size()];
+      alertDefsArr = (StatAlertDefinition[])alertDefs.toArray(alertDefsArr);
+    } else {
+      alertDefsArr = new StatAlertDefinition[0];
+    }
+    
+    if (logger.isDebugEnabled()) {
+      logger.debug("Exiting AdminDistributedSystemJmxImpl.getAllStatAlertDefinitions() *****");
+    }
+    
+    return alertDefsArr;
+  }
+
+
+  /**
+   * This method can be used to process the notifications sent by the 
+   * member(s). Actual aggregation of stats can occur here. The array contains 
+   * alert objects with alert def. ID & value. AlertHelper class can be used to 
+   * retrieve the corresponding alert definition.
+   * 
+   * @param alerts array of Alert class(contains alert def. ID & value)
+   * @param remoteVM Remote Member VM that sent Stat Alerts for processing the
+   *                 notifications to the clients
+   */  
+  public void processNotifications(StatAlert[] alerts, GemFireVM remoteVM) {
+    if (logger.isDebugEnabled()) {
+      logger.debug("Entered AdminDistributedSystemJmxImpl.processNotifications(StatAlert[{}], GemFireVM) *************", alerts.length);
+    }
+    
+    /* 
+     * Notifications can not be processed if the remote VM is not available.
+     * NOTE: Should this method get the required GemFireVM information instead 
+     * of its reference so that even if the member leaves we still have the 
+     * information collected earlier to process the notification?
+     */
+    if (remoteVM == null) {
+      if (logger.isDebugEnabled()) {
+        logger.debug("Could not process stat alert notifications as given GemFireVM is null.");
+      }
+      return;
+    }
+    
+    /*
+     * 1. The implementation idea is yet not clear.
+     * 2. The StatAlert array would received directly or from a request object. 
+     */
+    ArrayList notificationObjects = new ArrayList();
+    
+    String memberId = remoteVM.getId().getId();
+
+    final boolean isSystemWide = false;
+    
+    StatAlert alert = null;
+    Integer   defId = null;
+//    Number[]  values = null;
+    for (int i = 0; i < alerts.length; i++) {
+      alert = alerts[i];
+      
+//      defId = Integer.valueOf(alert.getDefinitionId());
+      if (getAlertDefinition(alert.getDefinitionId())==null)
+        continue; // Ignore any removed AlertDefns 
+//      values = alert.getValues();
+      
+//      StatAlertDefinition statAlertDef = (StatAlertDefinition)ALERT_DEFINITIONS.get(defId);
+      
+      /*
+       * 1. check if it's system-wide.
+       * 2. if system-wide keep, it in a collection (that should get cleared on 
+       *    timeout). Process all alerts when notifications from all members are 
+       *    received. Need to check if the member leaves meanwhile. 
+       * 
+       * 1. Check if function evaluation is required?
+       * 2. If it's not required, the notification should directly be sent to 
+       *    clients.
+       */
+      
+      //if (statAlertDef.getFunctionId() != 0) {
+        /*
+         * StatAlert with alert definitions having functions
+         * assigned will get evaluated at manager side only.
+         * 
+         * Is combination of systemwide alerts with function valid? It should 
+         * be & hence such evaluation should be skipped on manager side. Or is 
+         * it to be evaluated at manager as well as aggragator?
+         */
+      //}
+      
+      //TODO: is this object required? Or earlier canbe resused?
+      StatAlertNotification alertNotification = new StatAlertNotification(alert, memberId);
+      
+      /*
+       * variable isSystemWide is created only for convienience, there
+       * should be an indication for the same in the alert definition. 
+       * Currently there is no systemWide definition
+       * 
+       * Evaluating system wide alerts:
+       *   1. It'll take time for aggregator to gather alerts from all members.
+       *      Member might keep joining & leaving in between. The member for whom 
+       *      the stat-alert value was taken might have left & new ones might 
+       *      have joined leave until all the calculations are complete. 
+       *      A disclaimer to be put that these are not exact values.
+       *   2. How would the aggregator know that it has received alerts from all 
+       *      the managers? Is the concept of system-wide alerts valid? 
+       *      System-wide stats might be!
+       *      
+       */
+      if (!isSystemWide) {
+        notificationObjects.add(alertNotification);
+        continue;
+      }
+      HashSet accumulatedAlertValues;
+      synchronized (alertsStore) {
+        accumulatedAlertValues = (HashSet)alertsStore.get(defId);
+        
+        if (accumulatedAlertValues == null) {
+          accumulatedAlertValues = new HashSet();
+          alertsStore.put(defId, accumulatedAlertValues);
+        }
+      }
+      synchronized (accumulatedAlertValues) {
+        accumulatedAlertValues.add(alertNotification);
+      }
+    } //for ends
+    
+    if (!notificationObjects.isEmpty()) {
+      /* TODO: should ths method send & forget or be fail-safe? */
+      sendNotifications(notificationObjects, getObjectName());
+    }
+    
+    if (logger.isDebugEnabled()) {
+      logger.debug("Exiting AdminDistributedSystemJmxImpl.processNotifications(StatAlert[], GemFireVM) *************");
+    }
+  }
+
+  private byte[] convertNotificationsDataToByteArray(ArrayList notificationObjects) {
+    if (logger.isDebugEnabled()) {
+      logger.debug("AdminDistributedSystemJmxImpl#convertNotificationsDataToByteArray: {} notifications", notificationObjects.size());
+    }
+
+    byte[] arr = null;
+
+    try {
+      ByteArrayOutputStream byteArrStr = new ByteArrayOutputStream();
+      DataOutputStream str = new DataOutputStream(byteArrStr);
+      DataSerializer.writeArrayList(notificationObjects, str);
+      str.flush();
+      arr = byteArrStr.toByteArray();
+    } catch(IOException ex) {
+      logger.warn(LocalizedMessage.create(
+          LocalizedStrings.AdminDistributedSystem_ENCOUNTERED_AN_IOEXCEPTION_0,
+          ex.getLocalizedMessage()));
+    }
+
+    return arr;
+  }
+
+  /**
+   * An intermediate method to send notifications to the clients.
+   * 
+   * @param notificationObjects list of StatAlertNotification objects
+   */
+  private void sendNotifications(ArrayList notificationObjects, 
+      ObjectName objName) {
+    try {
+      if (logger.isDebugEnabled()) {
+        logger.debug("AdminDistributedSystemJmxImpl#sendNotifications: sending {} notifications", notificationObjects.size());
+      }
+      
+      byte[] notifBytes = convertNotificationsDataToByteArray(notificationObjects);
+      if (notifBytes!=null) {
+        Notification notif = new Notification(NOTIF_STAT_ALERT,  
+            objName, // Pass the StatNotifications
+            notificationSequenceNumber.addAndGet(1), "StatAlert Notifications");
+        notif.setUserData(notifBytes);
+        this.modelMBean.sendNotification(notif);
+      } // IOException handled and logged in convertNotificationsDataToByteArray
+
+      StringBuffer buf = new StringBuffer();
+      for (int i = 0; i < notificationObjects.size(); i ++) {
+        StatAlertNotification not = (StatAlertNotification)
+            notificationObjects.get(i);
+        buf.append(not.toString(getAlertDefinition(not.getDefinitionId())));
+      }
+//      sendEmail("Gemfire AlertNotification on Member:" + objName, buf.toString());
+      if (isEmailNotificationEnabled) {
+        String mess = LocalizedStrings.AdminDistributedSystemJmxImpl_STATISTICS_ALERT_FROM_DISTRIBUTED_SYSTEM_MEMBER_0_STATISTICS_1.toLocalizedString(new Object[] {objName.getCanonicalName(), buf.toString()} );
+        sendEmail(
+            EML_SUBJ_PRFX_GFE_ALERT + EML_SUBJ_ITEM_GFE_DS + getName() 
+            + " <"+LocalizedStrings.AdminDistributedSystemJmxImpl_STATISTICS_ALERT_FOR_MEMBER.toLocalizedString()+">", 
+            mess);
+      }
+    } catch (javax.management.MBeanException e) {
+      logger.error(e.getMessage(), e);
+    } catch (RuntimeException e) {
+      logger.error(e.getMessage(), e);
+      throw 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 (Error 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();
+      logger.error(e.getMessage(), e);
+      throw e;
+    }
+  }
+  
+  /**
+   * Sends an email to the configured recipients using configured email server.
+   * The given message will be the email body. NOTE: the check whether email
+   * notfication is enabled or not should done using
+   * {@link #isEmailNotificationEnabled} before calling this method.
+   * 
+   * @param subject
+   *          subject of the email
+   * @param message
+   *          message body of the email
+   */
+  private void sendEmail(String subject, String message) {
+	  if (mailManager == null) {
+	    mailManager = new MailManager(mailProps);
+	  }
+    this.mailManager.sendEmail(subject, message);
+  }
+
+  public void processSystemwideNotifications() {
+  }
+
+  public String getId() {
+    String myId = super.getId();
+    return MBeanUtil.makeCompliantMBeanNameProperty(myId);
+  }
+
+  /**
+   * This method is used to process ClientMembership events sent for
+   * BridgeMembership by bridge servers to all admin members.
+   * 
+   * @param senderId
+   *          id of the member that sent the ClientMembership changes for
+   *          processing (could be null)
+   * @param clientId
+   *          id of a client for which the notification was sent
+   * @param clientHost
+   *          host on which the client is/was running
+   * @param eventType
+   *          denotes whether the client Joined/Left/Crashed should be one of
+   *          ClientMembershipMessage#JOINED, ClientMembershipMessage#LEFT,
+   *          ClientMembershipMessage#CRASHED
+   */
+  @Override
+  public void processClientMembership(String senderId, String clientId,
+      String clientHost, int eventType) {
+    logger.info(LocalizedMessage.create(LocalizedStrings.AdminDistributedSystemJmxImpl_PROCESSING_CLIENT_MEMBERSHIP_EVENT_0_FROM_1_FOR_2_RUNNING_ON_3, new String[] {ClientMembershipMessage.getEventTypeString(eventType), senderId, clientId, clientHost}));
+    try {
+      SystemMemberJmx systemMemberJmx = null;
+      CacheVm[] cacheVms = getCacheVms();
+      
+      for (CacheVm cacheVm : cacheVms) {
+        if (cacheVm.getId().equals(senderId) && 
+            cacheVm instanceof CacheServerJmxImpl) {
+          systemMemberJmx = (CacheServerJmxImpl) cacheVm;
+          break;
+        }
+      }
+      
+      if (systemMemberJmx == null) {
+        SystemMember[] appVms = getSystemMemberApplications();
+        
+        for (SystemMember appVm : appVms) {
+          if (appVm.getId().equals(senderId) && 
+              appVm instanceof SystemMemberJmxImpl) {
+            systemMemberJmx = (SystemMemberJmxImpl) appVm;
+            break;
+          }
+        }
+        
+      }
+
+      if (systemMemberJmx != null) {
+        systemMemberJmx.handleClientMembership(clientId, eventType);
+      }
+    } catch (AdminException e) {
+      logger.error(LocalizedMessage.create(
+          LocalizedStrings.AdminDistributedSystemJmxImpl_FAILED_TO_PROCESS_CLIENT_MEMBERSHIP_FROM_0_FOR_1,
+              new Object[] { senderId, clientId }), e);
+      return;
+    } catch (RuntimeOperationsException e) {
+      logger.warn(e.getMessage(), e);//failed to send notification
+    }
+  }
+
+  public String getAlertLevelAsString() {
+    return super.getAlertLevelAsString();
+  }
+  
+  public void setAlertLevelAsString(String level) {
+    String newLevel = level != null ? level.trim() : null;
+    try {
+      super.setAlertLevelAsString(newLevel);
+    } catch (IllegalArgumentException e) {
+      throw new RuntimeMBeanException(e, e.getMessage());
+    }
+  }
+
+  /**
+   * Finds the member as per details in the given event object and passes on
+   * this event for handling the cache creation.
+   * 
+   * @param event
+   *          event object corresponding to the creation of the cache
+   */
+  public void handleCacheCreateEvent(SystemMemberCacheEvent event) {
+    String memberId = event.getMemberId();
+    SystemMemberJmx systemMemberJmx = (SystemMemberJmx) findCacheOrAppVmById(memberId);
+    
+    if (systemMemberJmx != null) {
+      systemMemberJmx.handleCacheCreate(event);
+    }
+    
+  }
+
+  /**
+   * Finds the member as per details in the given event object and passes on
+   * this event for handling the cache closure.
+   * 
+   * @param event
+   *          event object corresponding to the closure of the cache
+   */
+  public void handleCacheCloseEvent(SystemMemberCacheEvent event) {
+    String memberId = event.getMemberId();
+    SystemMemberJmx systemMemberJmx = (SystemMemberJmx) findCacheOrAppVmById(memberId);
+    
+    if (systemMemberJmx != null) {
+      systemMemberJmx.handleCacheClose(event);
+    }
+    
+  }
+
+  /**
+   * Finds the member as per details in the given event object and passes on
+   * this event for handling the region creation.
+   * 
+   * @param event
+   *          event object corresponding to the creation of a region
+   */
+  public void handleRegionCreateEvent(SystemMemberRegionEvent event) {
+    String memberId = event.getMemberId();
+    SystemMemberJmx systemMemberJmx = (SystemMemberJmx) findCacheOrAppVmById(memberId);
+    
+    if (systemMemberJmx != null) {
+      systemMemberJmx.handleRegionCreate(event);
+    }
+  }  
+  
+  /**
+   * Finds the member as per details in the given event object and passes on 
+   * this event for handling the region loss.
+   * 
+   * @param event
+   *          event object corresponding to the loss of a region
+   */
+  public void handleRegionLossEvent(SystemMemberRegionEvent event) {
+    String memberId = event.getMemberId();
+    SystemMemberJmx systemMemberJmx = (SystemMemberJmx) findCacheOrAppVmById(memberId);
+    
+    if (systemMemberJmx != null) {
+      systemMemberJmx.handleRegionLoss(event);
+    }
+  }
+
+  @Override
+  public void setDisableAutoReconnect(boolean newValue) {
+    getConfig().setDisableAutoReconnect(newValue);
+  }
+
+  @Override
+  public boolean getDisableAutoReconnect() {
+    return getConfig().getDisableAutoReconnect();
+  }  
+  
+}
+
+class ProcessSystemwideStatAlertsNotification extends TimerTask {
+  private StatAlertsAggregator aggregator;
+  
+  ProcessSystemwideStatAlertsNotification(StatAlertsAggregator aggregator) {
+    this.aggregator = aggregator;
+  }
+  
+  @Override
+  public void run() {
+    aggregator.processSystemwideNotifications();
+  }
+  
+}
+
+/**
+ * Implementation of SystemMemberCacheListener used for listening to events:
+ * <ol> <li> Cache Created </li>
+ * <li> Cache Closed </li>
+ * <li> Region Created </li>
+ * <li> Region Loss </li>
+ * </ol>
+ * 
+ * @author abhishek
+ */
+class CacheAndRegionListenerImpl implements SystemMemberCacheListener {
+  private AdminDistributedSystemJmxImpl adminDS;
+
+  /**
+   * Csontructor to create CacheAndRegionListenerImpl
+   * 
+   * @param adminDSResource
+   *          instance of AdminDistributedSystemJmxImpl
+   */
+  CacheAndRegionListenerImpl(AdminDistributedSystemJmxImpl adminDSResource) {
+    this.adminDS = adminDSResource;
+  }
+  
+  /**
+   * See SystemMemberCacheListener#afterCacheClose(SystemMemberCacheEvent)
+   */
+  public void afterCacheClose(SystemMemberCacheEvent event) {
+    adminDS.handleCacheCloseEvent(event);
+  }
+  
+  /**
+   * See SystemMemberCacheListener#afterCacheCreate(SystemMemberCacheEvent)
+   */
+  public void afterCacheCreate(SystemMemberCacheEvent event) {
+    adminDS.handleCacheCreateEvent(event);
+  }
+  
+  /**
+   * See SystemMemberCacheListener#afterRegionCreate(SystemMemberCacheEvent)
+   */
+  public void afterRegionCreate(SystemMemberRegionEvent event) {
+    adminDS.handleRegionCreateEvent(event);    
+  }
+  
+  /**
+   * See SystemMemberCacheListener#afterRegionLoss(SystemMemberCacheEvent)
+   */
+  public void afterRegionLoss(SystemMemberRegionEvent event) {
+    adminDS.handleRegionLossEvent(event);
+  }  
+}
+


[43/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberCacheServer.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberCacheServer.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberCacheServer.java
new file mode 100755
index 0000000..d9fd01e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberCacheServer.java
@@ -0,0 +1,300 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+import com.gemstone.gemfire.cache.server.ServerLoadProbe;
+
+/**
+ * Administrative interface that represents a {@link
+ * com.gemstone.gemfire.cache.server.CacheServer CacheServer} that
+ * serves the contents of a system member's cache to clients. 
+ *
+ * @see SystemMemberCache#addCacheServer
+ *
+ * @author darrel
+ * @since 5.7
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface SystemMemberCacheServer {
+
+  /** 
+   * Returns the port on which this cache server listens for
+   * clients to connect.
+   */
+  public int getPort();
+
+  /**
+   * Sets the port on which this cache server listens for
+   * clients to connect.
+   *
+   * @throws AdminException
+   *         If this cache server is running
+   */
+  public void setPort(int port) throws AdminException;
+
+  /**
+   * Starts this cache server.  Once the server is running, its
+   * configuration cannot be changed.
+   *
+   * @throws AdminException
+   *         If an error occurs while starting the cache server
+   */
+  public void start() throws AdminException;
+
+  /** 
+   * Returns whether or not this cache server is running
+   */
+  public boolean isRunning();
+
+  /**
+   * Stops this cache server.  Note that the
+   * <code>CacheServer</code> can be reconfigured and restarted if
+   * desired.
+   */
+  public void stop() throws AdminException;
+
+  /**
+   * Updates the information about this cache server.
+   */
+  public void refresh();
+
+  /**
+   * Returns a string representing the ip address or host name that this server
+   * will listen on.
+   * @return the ip address or host name that this server is to listen on
+   * @since 5.7
+   */
+  public String getBindAddress();
+  /**
+   * Sets the ip address or host name that this server is to listen on for
+   * client connections.
+   * <p>Setting a specific bind address will cause the cache server to always
+   * use this address and ignore any address specified by "server-bind-address"
+   * or "bind-address" in the <code>gemfire.properties</code> file
+   * (see {@link com.gemstone.gemfire.distributed.DistributedSystem}
+   * for a description of these properties).
+   * <p> A <code>null</code> value will be treated the same as the default "".
+   * <p> The default value does not override the gemfire.properties. If you wish to
+   * override the properties and want to have your server bind to all local
+   * addresses then use this string <code>"0.0.0.0"</code>.
+   * @param address the ip address or host name that this server is to listen on
+   * @throws AdminException if this cache server is running
+   * @since 5.7
+   */
+  public void setBindAddress(String address) throws AdminException;
+  /**
+   * Returns a string representing the ip address or host name that server locators
+   * will tell clients that this server is listening on.
+   * @return the ip address or host name to give to clients so they can connect
+   *         to this server
+   * @since 5.7
+   */
+  public String getHostnameForClients();
+  /**
+   * Sets the ip address or host name that this server is to listen on for
+   * client connections.
+   * <p>Setting a specific hostname-for-clients will cause server locators
+   * to use this value when telling clients how to connect to this server.
+   * <p> The default value causes the bind-address to be given to clients
+   * <p> A <code>null</code> value will be treated the same as the default "".
+   * @param name the ip address or host name that will be given to clients
+   *   so they can connect to this server
+   * @throws AdminException if this cache server is running
+   * @since 5.7
+   */
+  public void setHostnameForClients(String name) throws AdminException;
+  /**
+   * Sets whether or not this cache server should notify clients based on
+   * key subscription.
+   *
+   * If false, then an update to any key on the server causes an update to
+   * be sent to all clients. This update does not push the actual data to the
+   * clients. Instead, it causes the client to locally invalidate or destroy
+   * the corresponding entry. The next time the client requests the key, it
+   * goes to the cache server for the value.
+   *
+   * If true, then an update to any key on the server causes an update to be
+   * sent to only those clients who have registered interest in that key. Other
+   * clients are not notified of the change. In addition, the actual value is
+   * pushed to the client. The client does not need to request the new value
+   * from the cache server.
+   * @throws AdminException if this cache server is running
+   * @since 5.7
+   */
+  public void setNotifyBySubscription(boolean b) throws AdminException;
+
+  /**
+   * Answers whether or not this cache server should notify clients based on
+   * key subscription.
+   * @since 5.7
+   */
+  public boolean getNotifyBySubscription();
+
+  /**
+   * Sets the buffer size in bytes of the socket connection for this
+   * <code>CacheServer</code>. The default is 32768 bytes.
+   *
+   * @param socketBufferSize The size in bytes of the socket buffer
+   * @throws AdminException if this cache server is running
+   * @since 5.7
+   */
+  public void setSocketBufferSize(int socketBufferSize) throws AdminException;
+
+  /**
+   * Returns the configured buffer size of the socket connection for this
+   * <code>CacheServer</code>. The default is 32768 bytes.
+   * @return the configured buffer size of the socket connection for this
+   * <code>CacheServer</code>
+   * @since 5.7
+   */
+  public int getSocketBufferSize();
+
+  /**
+   * Sets the maximum amount of time between client pings. This value is
+   * used by the <code>ClientHealthMonitor</code> to determine the health
+   * of this <code>CacheServer</code>'s clients. The default is 60000 ms.
+   *
+   * @param maximumTimeBetweenPings The maximum amount of time between client
+   * pings
+   * @throws AdminException if this cache server is running
+   * @since 5.7
+   */
+  public void setMaximumTimeBetweenPings(int maximumTimeBetweenPings) throws AdminException;
+
+  /**
+   * Returns the maximum amount of time between client pings. This value is
+   * used by the <code>ClientHealthMonitor</code> to determine the health
+   * of this <code>CacheServer</code>'s clients. The default is 60000 ms.
+   * @return the maximum amount of time between client pings.
+   * @since 5.7
+   */
+  public int getMaximumTimeBetweenPings();
+
+  /** 
+   *  Returns the maximum allowed client connections
+   * @since 5.7
+   */
+  public int getMaxConnections();
+
+  /**
+   * Sets the maxium number of client connections allowed.
+   * When the maximum is reached the server will stop accepting
+   * connections.
+   * @throws AdminException if this cache server is running
+   * @since 5.7
+   */
+  public void setMaxConnections(int maxCons) throws AdminException;
+
+  /** 
+   * Returns the maxium number of threads allowed in this server to service
+   * client requests.
+   * The default of <code>0</code> causes the server to dedicate a thread for
+   * every client connection.
+   * @since 5.7
+   */
+  public int getMaxThreads();
+
+  /**
+   * Sets the maxium number of threads allowed in this server to service
+   * client requests.
+   * The default of <code>0</code> causes the server to dedicate a thread for
+   * every client connection.
+   * @throws AdminException if this cache server is running
+   * @since 5.7
+   */
+  public void setMaxThreads(int maxThreads) throws AdminException;
+
+  /**
+   * Returns the maximum number of messages that can be enqueued in a
+   * client-queue.
+   * @since 5.7
+   */
+  public int getMaximumMessageCount();
+
+  /**
+   * Sets maximum number of messages that can be enqueued in a client-queue.
+   * @throws AdminException if this cache server is running
+   * @since 5.7
+   */
+  public void setMaximumMessageCount(int maxMessageCount) throws AdminException;
+  
+  /**
+   * Returns the time (in seconds ) after which a message in the client queue
+   * will expire.
+   * @since 5.7
+   */
+  public int getMessageTimeToLive();
+
+  /**
+   * Sets the time (in seconds ) after which a message in the client queue
+   * will expire.
+   * @throws AdminException if this cache server is running
+   * @since 5.7
+   */
+  public void setMessageTimeToLive(int messageTimeToLive) throws AdminException;
+  /**
+   * Sets the list of server groups this cache server will belong to.
+   * By default cache servers belong to the default global server group
+   * which all cache servers always belong to.
+   * @param groups possibly empty array of <code>String</code> where each string
+   * is a server groups that this cache server will be a member of.
+   * @throws AdminException if this cache server is running
+   * @since 5.7
+   */
+  public void setGroups(String[] groups) throws AdminException;
+  /**
+   * Returns the list of server groups that this cache server belongs to.
+   * @return a possibly empty array of <code>String</code>s where
+   * each string is a server group. Modifying this array will not change the
+   * server groups that this cache server belongs to.
+   * @since 5.7
+   */
+  public String[] getGroups();
+  
+  /**
+   * Get a description of the load probe for this cache server.
+   * {@link ServerLoadProbe} for details on the load probe.
+   * @return the load probe used by this cache
+   * server.
+   * @since 5.7
+   */
+  public String getLoadProbe();
+
+  /**
+   * Set the load probe for this cache server. See
+   * {@link ServerLoadProbe} for details on how to implement
+   * a load probe.
+   * 
+   * The load probe should implement DataSerializable if 
+   * it is used with this interface, because it will be sent to the remote
+   * VM.
+   * @param loadProbe the load probe to use for
+   * this cache server.
+   * @throws AdminException  if the cache server is running
+   * @since 5.7
+   */
+  public void setLoadProbe(ServerLoadProbe loadProbe) throws AdminException;
+
+  /**
+   * Get the frequency in milliseconds to poll the load probe on this cache
+   * server.
+   * 
+   * @return the frequency in milliseconds that we will poll the load probe.
+   */
+  public long getLoadPollInterval();
+
+  /**
+   * Set the frequency in milliseconds to poll the load probe on this cache
+   * server
+   * @param loadPollInterval the frequency in milliseconds to poll
+   * the load probe. Must be greater than 0.
+   * @throws AdminException if the cache server is running
+   */
+  public void setLoadPollInterval(long loadPollInterval) throws AdminException;
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberRegion.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberRegion.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberRegion.java
new file mode 100644
index 0000000..19be33a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberRegion.java
@@ -0,0 +1,313 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+import com.gemstone.gemfire.cache.*;
+import java.io.File;
+
+/**
+ * Administrative interface that represent's the {@link
+ * SystemMember}'s view of one of its cache's {@link
+ * com.gemstone.gemfire.cache.Region}s.  If the region in the remote
+ * system member is closed or destroyed, the methods of
+ * <code>SystemMemberRegion</code> will throw {@link
+ * RegionNotFoundException}.
+ *
+ * @author    Darrel Schneider
+ * @since 3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface SystemMemberRegion {
+  // attributes
+  /**
+   * Returns the name that identifies this region in its cache.
+   *
+   * @see com.gemstone.gemfire.cache.Region#getName
+   */
+  public String getName();
+  
+  /**
+   * Returns the full path name that identifies this region in its
+   * cache.
+   *
+   * @see com.gemstone.gemfire.cache.Region#getFullPath
+   */
+  public String getFullPath();
+
+  /**
+   * Returns the names of all the subregions of this region.
+   */
+  public java.util.Set getSubregionNames();
+
+  /**
+   * Returns the full path of each of the subregions of this region.
+   * These paths are suitable for use with {@link
+   * SystemMemberCache#getRegion}.
+   */
+  public java.util.Set getSubregionFullPaths();
+
+  /**
+   * Returns a description of any user attribute associated with this
+   * region.  The description includes the classname of the user
+   * attribute object as well as its <code>toString</code>
+   * representation.
+   */
+  public String getUserAttribute();
+
+  /**
+   * Returns a description of any CacheLoader associated with this region.
+   */
+  public String getCacheLoader();
+  /**
+   * Returns a description of any CacheWriter associated with this region.
+   */
+  public String getCacheWriter();
+
+  /**
+   * Returns the <code>EvictionAttributes</code> that configure how
+   * entries in the the region are evicted 
+   */
+  public EvictionAttributes getEvictionAttributes();
+
+  /**
+   * Returns a description of the CacheListener in this region's attributes. If
+   * there is more than 1 CacheListener defined for a region this method will
+   * return the description of the 1st CacheListener returned from
+   * {@link #getCacheListeners}
+   * 
+   * @deprecated as of 6.0 use getCacheListeners() instead
+   */
+  @Deprecated
+  public String getCacheListener();
+
+  /**
+   * This method will return an empty array if there are no CacheListeners
+   * defined on the region. If there are one or more than 1 CacheListeners
+   * defined, this method will return an array which has the names of all the
+   * CacheListeners
+   * 
+   * @return String[] the region's <code>CacheListeners</code> as a String array
+   * @since 6.0
+   */
+  public String[] getCacheListeners();
+
+  /**
+   * Returns the KeyConstraint in this region's attributes.
+   */
+  public String getKeyConstraint();
+
+  /**
+   * Returns the ValueConstraint in this region's attributes.
+   */
+  public String getValueConstraint();
+
+  /**
+   * Returns the RegionTimeToLive time limit in this region's attributes.
+   */
+  public int getRegionTimeToLiveTimeLimit();
+
+  /**
+   * Returns the RegionTimeToLive action in this region's attributes.
+   */
+  public ExpirationAction getRegionTimeToLiveAction();
+
+  /**
+   * Returns the EntryTimeToLive time limit in this region's attributes.
+   */
+  public int getEntryTimeToLiveTimeLimit();
+
+  /**
+   * Returns the EntryTimeToLive action in this region's attributes.
+   */
+  public ExpirationAction getEntryTimeToLiveAction();
+
+  /**
+   * string describing the CustomExpiry for entry-time-to-live
+   * @return the CustomExpiry for entry-time-to-live
+   */
+  public String getCustomEntryTimeToLive();
+  
+  /**
+   * Returns the RegionIdleTimeout time limit in this region's attributes.
+   */
+  public int getRegionIdleTimeoutTimeLimit();
+
+  /**
+   * Returns the RegionIdleTimeout action in this region's attributes.
+   */
+  public ExpirationAction getRegionIdleTimeoutAction();
+
+  /**
+   * Returns the EntryIdleTimeout time limit in this region's attributes.
+   */
+  public int getEntryIdleTimeoutTimeLimit();
+
+  /**
+   * Returns the EntryIdleTimeout action in this region's attributes.
+   */
+  public ExpirationAction getEntryIdleTimeoutAction();
+  
+  /**
+   * string describing the CustomExpiry for entry-idle-timeout
+   * @return the CustomExpiry for entry-idle-timeout
+   */
+  public String getCustomEntryIdleTimeout();
+  
+  /**
+   * Returns the MirrorType in this region's attributes.
+   * @deprecated as of 5.0, you should use getDataPolicy instead
+   */
+  @Deprecated
+  public MirrorType getMirrorType();
+  
+  /**
+   * Returns the DataPolicy in this region's attributes.
+   */
+  public DataPolicy getDataPolicy();
+  
+  /**
+  
+  /**
+   * Returns the Scope in this region's attributes.
+   */
+  public Scope getScope();
+
+  /**
+   * Returns the InitialCapacity in this region's attributes.
+   */
+  public int getInitialCapacity();
+
+  /**
+   * Returns the LoadFactor in this region's attributes.
+   */
+  public float getLoadFactor();
+
+  /**
+   * Returns the ConcurrencyLevel in this region's attributes.
+   */
+  public int getConcurrencyLevel();
+
+  /**
+   * Returns whether or not conflicting concurrent operations on this region
+   * are prevented 
+   */
+  public boolean getConcurrencyChecksEnabled();
+
+  /**
+   * Returns the StatisticsEnabled in this region's attributes.
+   */
+  public boolean getStatisticsEnabled();
+
+  /**
+   * Returns whether or not a persistent backup should be made of the
+   * region (as opposed to just writing the overflow data to disk).
+   */
+  public boolean getPersistBackup();
+
+  /**
+   * Returns the <code>DiskWriteAttributes</code> that configure how
+   * the region is written to disk.
+   */
+  public DiskWriteAttributes getDiskWriteAttributes();
+
+  /**
+   * Returns the directories to which the region's data are written.  If
+   * multiple directories are used, GemFire will attempt to distribute the
+   * data evenly amongst them.
+   */
+  public File[] getDiskDirs();
+
+  /**
+   * Returns the number of entries currently in this region.
+   */
+  public int getEntryCount();
+  
+  /**
+   * Returns the number of subregions currently in this region.
+   */
+  public int getSubregionCount();
+
+  /**
+   * Returns the LastModifiedTime obtained from this region's statistics.
+   */
+  public long getLastModifiedTime();
+
+  /**
+   * Returns the LastAccessedTime obtained from this region's statistics.
+   */
+  public long getLastAccessedTime();
+
+  /**
+   * Returns the HitCount obtained from this region's statistics.
+   */
+  public long getHitCount();
+
+  /**
+   * Returns the MissCount obtained from this region's statistics.
+   */
+  public long getMissCount();
+
+  /**
+   * Returns the HitRatio obtained from this region's statistics.
+   */
+  public float getHitRatio();
+
+  /**
+   * Returns whether or not acks are sent after an update is processed.
+   * @return False if acks are sent after updates are processed;
+   *         true if acks are sent before updates are processed.
+   *
+   * @since 4.1
+   */
+  public boolean getEarlyAck();
+
+  // operations
+  /**
+   * Updates the state of this region instance. Note that once a cache
+   * instance is closed refresh will never change the state of its regions.
+   */
+  public void refresh();
+
+  /**
+   * Creates a subregion of this region.
+   *
+   * @param name
+   *        The name of the region to create
+   * @param attrs
+   *        The attributes of the root region
+   *
+   * @throws AdminException
+   *         If the region cannot be created
+   *
+   * @since 4.0
+   */
+  public SystemMemberRegion createSubregion(String name,
+                                            RegionAttributes attrs)
+    throws AdminException;
+
+  /**
+   * Returns the <code>MembershipAttributes</code> that configure required
+   * roles for reliable access to the region.
+   * @since 5.0
+   */
+  public MembershipAttributes getMembershipAttributes();
+  
+  /**
+   * Returns the <code>SubscriptionAttributes</code> for the region.
+   * @since 5.0
+   */
+  public SubscriptionAttributes getSubscriptionAttributes();
+  
+  /**
+   * Returns the <code>PartitionAttributes</code> for the region.
+   * @since 5.7
+   */
+  public PartitionAttributes getPartitionAttributes();
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberRegionEvent.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberRegionEvent.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberRegionEvent.java
new file mode 100644
index 0000000..d2267ba
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberRegionEvent.java
@@ -0,0 +1,17 @@
+package com.gemstone.gemfire.admin;
+
+/**
+ * An event that describes an operation on a region.
+ * Instances of this are delivered to a {@link SystemMemberCacheListener} when a
+ * a region comes or goes.
+ *
+ * @author Darrel Schneider
+ * @since 5.0
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface SystemMemberRegionEvent extends SystemMemberCacheEvent {
+  /**
+   * Returns the full path of the region the event was done on.
+   */
+  public String getRegionPath();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberType.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberType.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberType.java
new file mode 100755
index 0000000..4001d96
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberType.java
@@ -0,0 +1,137 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+//import java.io.*;
+
+/**
+ * Type-safe definition for system members.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public class SystemMemberType implements java.io.Serializable {
+  private static final long serialVersionUID = 3284366994485749302L;
+    
+  /** GemFire shared-memory manager connected to the distributed system */
+  public static final SystemMemberType MANAGER = 
+      new SystemMemberType("GemFireManager");
+
+  /** Application connected to the distributed system */
+  public static final SystemMemberType APPLICATION = 
+      new SystemMemberType("Application");
+
+  /** GemFire Cache VM connected to the distributed system */
+  public static final SystemMemberType CACHE_VM =
+    new SystemMemberType("CacheVm");
+
+  /** GemFire Cache Server connected to the distributed system
+   * @deprecated as of 5.7 use {@link #CACHE_VM} instead.
+   */
+  @Deprecated
+  public static final SystemMemberType CACHE_SERVER = CACHE_VM;
+
+
+  /** The display-friendly name of this system member type. */
+  private final transient String name;
+  
+  // The 4 declarations below are necessary for serialization
+  /** int used as ordinal to represent this Scope */
+  public final int ordinal = nextOrdinal++;
+
+  private static int nextOrdinal = 0;
+  
+  private static final SystemMemberType[] VALUES =
+    { MANAGER, APPLICATION, CACHE_VM };
+
+  private Object readResolve() throws java.io.ObjectStreamException {
+    return VALUES[ordinal];  // Canonicalize
+  }
+  
+  /** Creates a new instance of SystemMemberType. */
+  private SystemMemberType(String name) {
+    this.name = name;
+  }
+    
+  /** Return the SystemMemberType represented by specified ordinal */
+  public static SystemMemberType fromOrdinal(int ordinal) {
+    return VALUES[ordinal];
+  }
+
+  public String getName() {
+    return this.name;
+  }
+  
+  /** Return whether this is <code>MANAGER</code>. */
+  public boolean isManager() {
+    return this.equals(MANAGER);
+  }
+    
+  /** Return whether this is <code>APPLICATION</code>. */
+  public boolean isApplication() {
+    return this.equals(APPLICATION);
+  }
+
+  /** Return whether this is <code>CACHE_SERVER</code>.
+   * @deprecated as of 5.7 use {@link #isCacheVm} instead.
+   */
+  @Deprecated
+  public boolean isCacheServer() {
+    return isCacheVm();
+  }
+  /** Return whether this is <code>CACHE_VM</code>.
+   */
+  public boolean isCacheVm() {
+    return this.equals(CACHE_VM);
+  }
+    
+  /** 
+   * Returns a string representation for this system member type.
+   *
+   * @return the name of this system member type
+   */
+  @Override
+  public String toString() {
+      return this.name;
+  }
+
+	/**
+	 * Indicates whether some other object is "equal to" this one.
+	 *
+	 * @param  other  the reference object with which to compare.
+	 * @return true if this object is the same as the obj argument;
+	 *         false otherwise.
+	 */
+  @Override
+	public boolean equals(Object other) {
+		if (other == this) return true;
+		if (other == null) return false;
+		if (!(other instanceof SystemMemberType)) return  false;
+		final SystemMemberType that = (SystemMemberType) other;
+		if (this.ordinal != that.ordinal) return false;
+		return true;
+	}
+
+	/**
+	 * Returns a hash code for the object. This method is supported for the
+	 * benefit of hashtables such as those provided by java.util.Hashtable.
+	 *
+	 * @return the integer 0 if description is null; otherwise a unique integer.
+	 */
+  @Override
+	public int hashCode() {
+		int result = 17;
+		final int mult = 37;
+		result = mult * result + this.ordinal;
+		return result;
+	}
+  
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMembershipEvent.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMembershipEvent.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMembershipEvent.java
new file mode 100644
index 0000000..c81319f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMembershipEvent.java
@@ -0,0 +1,32 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+import com.gemstone.gemfire.distributed.DistributedMember;
+/**
+ * An event that describes the distributed member originated this event.
+ * Instances of this are delivered to a {@link SystemMembershipListener} when a
+ * member has joined or left the distributed system.
+ *
+ * @author Darrel Schneider
+ * @since 3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface SystemMembershipEvent {
+  /**
+   * Returns the distributed member as a String.
+   */
+  public String getMemberId();
+
+  /**
+   * Returns the {@link DistributedMember} that this event originated in.
+   * @return the member that performed the operation that originated this event.
+   * @since 5.0
+   */
+  public DistributedMember getDistributedMember();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMembershipListener.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMembershipListener.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMembershipListener.java
new file mode 100644
index 0000000..027c032
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMembershipListener.java
@@ -0,0 +1,53 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+/**
+ * A listener whose callback methods are invoked when members join or
+ * leave the GemFire distributed system.
+ *
+ * @see AdminDistributedSystem#addMembershipListener
+ *
+ * @author David Whitlock
+ * @since 3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface SystemMembershipListener {
+
+  /**
+   * Invoked when a member has joined the distributed system
+   */
+  public void memberJoined(SystemMembershipEvent event);
+
+  /**
+   * Invoked when a member has gracefully left the distributed system.  This
+   * occurs when the member took action to remove itself from the distributed
+   * system.
+   */
+  public void memberLeft(SystemMembershipEvent event);
+
+  /**
+   * Invoked when a member has unexpectedly left the distributed
+   * system.  This occurs when a member is forcibly removed from the
+   * distributed system by another process, such as from
+   * <a href=../distributed/DistributedSystem.html#member-timeout> failure detection</a>, or
+   * <a href=../distributed/DistributedSystem.html#enable-network-partition-detection>
+   * network partition detection</a> processing.
+   */
+  public void memberCrashed(SystemMembershipEvent event);
+
+//   /**
+//    * Invoked when a member broadcasts an informational message.
+//    *
+//    * @see com.gemstone.gemfire.distributed.DistributedSystem#fireInfoEvent
+//    *
+//    * @since 4.0
+//    */
+//   public void memberInfo(SystemMembershipEvent event);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/UnmodifiableConfigurationException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/UnmodifiableConfigurationException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/UnmodifiableConfigurationException.java
new file mode 100755
index 0000000..6df86cd
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/UnmodifiableConfigurationException.java
@@ -0,0 +1,80 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+   
+package com.gemstone.gemfire.admin;
+
+/**
+ * An <code>UnmodifiableConfigurationException</code> is thrown when an attempt
+ * is made to modify the value of an unmodifiable 
+ * {@link ConfigurationParameter}.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public class UnmodifiableConfigurationException extends AdminException {
+private static final long serialVersionUID = -7653547392992060646L;
+
+  /**
+   * Constructs a new exception with <code>null</code> as its detail message.
+   * The cause is not initialized, and may subsequently be initialized by a
+   * call to {@link Throwable#initCause}.
+   */
+  public UnmodifiableConfigurationException() {
+    super();
+  }
+
+  /**
+   * Constructs a new exception with the specified detail message.  The
+   * cause is not initialized, and may subsequently be initialized by
+   * a call to {@link Throwable#initCause}.
+   *
+   * @param   message   the detail message. The detail message is saved for 
+   *          later retrieval by the {@link #getMessage()} method.
+   */
+  public UnmodifiableConfigurationException(String message) {
+    super(message);
+  }
+
+  /**
+   * Constructs a new exception with the specified detail message and
+   * cause.  <p>Note that the detail message associated with
+   * <code>cause</code> is <i>not</i> automatically incorporated in
+   * this exception's detail message.
+   *
+   * @param  message the detail message (which is saved for later retrieval
+   *         by the {@link #getMessage()} method).
+   * @param  cause the cause (which is saved for later retrieval by the
+   *         {@link #getCause()} method).  (A <tt>null</tt> value is
+   *         permitted, and indicates that the cause is nonexistent or
+   *         unknown.)
+   */
+  public UnmodifiableConfigurationException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Constructs a new exception with the specified cause and a detail
+   * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+   * typically contains the class and detail message of <tt>cause</tt>).
+   * This constructor is useful for exceptions that are little more than
+   * wrappers for other throwables (for example, {@link
+   * java.security.PrivilegedActionException}).
+   *
+   * @param  cause the cause (which is saved for later retrieval by the
+   *         {@link #getCause()} method).  (A <tt>null</tt> value is
+   *         permitted, and indicates that the cause is nonexistent or
+   *         unknown.)
+   */
+  public UnmodifiableConfigurationException(Throwable cause) {
+    super(cause);
+  }
+    
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/AbstractHealthEvaluator.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/AbstractHealthEvaluator.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/AbstractHealthEvaluator.java
new file mode 100644
index 0000000..7fa9424
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/AbstractHealthEvaluator.java
@@ -0,0 +1,176 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.util.List;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.admin.GemFireHealth;
+import com.gemstone.gemfire.admin.GemFireHealthConfig;
+import com.gemstone.gemfire.distributed.internal.DM;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+
+/**
+ * The abstract superclass of all GemFire health evaluators.
+ * Basically, this class specifies what the health evaluators need and
+ * what they should do.
+ *
+ * <P>
+ *
+ * Note that evaluators never reside in the administration VM, they
+ * only in member VMs.  They are not <code>Serializable</code> and
+ * aren't meant to be.
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ * */
+public abstract class AbstractHealthEvaluator  {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  /** The number of times this evaluator has been evaluated.  Certain
+   * checks are not made the first time an evaluation occurs.  */
+  private int numEvaluations;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>AbstractHealthEvaluator</code> with the given
+   * <code>GemFireHealthConfig</code> and
+   * <code>DistributionManager</code>.  
+   *
+   * Originally, this method took an
+   * <code>InternalDistributedSystem</code>, but we found there were
+   * race conditions during initialization.  Namely, that a
+   * <code>DistributionMessage</code> can be processed before the
+   * <code>InternalDistributedSystem</code>'s
+   * <code>DistributionManager</code> is set.
+   */
+  protected AbstractHealthEvaluator(GemFireHealthConfig config,
+                                    DM dm)
+  {
+    this.numEvaluations = 0;
+  }
+
+  /////////////////////  Instance Methods  /////////////////////
+
+  /**
+   * Evaluates the health of a component of a GemFire distributed
+   * system. 
+   *
+   * @param status
+   *        A list of {@link AbstractHealthEvaluator.HealthStatus
+   *        HealthStatus} objects that is populated when ill health is
+   *        detected.
+   */
+  public final void evaluate(List status) {
+    this.numEvaluations++;
+    check(status);
+  }
+
+  /**
+   * Checks the health of a component of a GemFire distributed
+   * system. 
+   *
+   * @see #evaluate
+   */
+  protected abstract void check(List status);
+
+  /**
+   * Returns whether or not this is the first evaluation
+   */
+  protected final boolean isFirstEvaluation() {
+    return this.numEvaluations <= 1;
+  }
+
+  /**
+   * A factory method that creates a {@link
+   * AbstractHealthEvaluator.HealthStatus HealthStats} with
+   * {@linkplain GemFireHealth#OKAY_HEALTH okay} status.
+   */
+  protected HealthStatus okayHealth(String diagnosis) {
+    logger.info(LocalizedMessage.create(LocalizedStrings.AbstractHealthEvaluator_OKAY_HEALTH__0, diagnosis));
+    return new HealthStatus(GemFireHealth.OKAY_HEALTH, diagnosis);
+  }
+
+  /**
+   * A factory method that creates a {@link
+   * AbstractHealthEvaluator.HealthStatus HealthStats} with
+   * {@linkplain GemFireHealth#POOR_HEALTH poor} status.
+   */
+  protected HealthStatus poorHealth(String diagnosis) {
+    logger.info(LocalizedMessage.create(LocalizedStrings.AbstractHealthEvaluator_POOR_HEALTH__0, diagnosis));
+    return new HealthStatus(GemFireHealth.POOR_HEALTH, diagnosis);
+  }
+
+  /**
+   * Returns a <code>String</code> describing the component whose
+   * health is evaluated by this evaluator.
+   */
+  protected abstract String getDescription();
+
+  /**
+   * Closes this evaluator and releases all of its resources
+   */
+  abstract void close();
+
+  ///////////////////////  Inner Classes  //////////////////////
+
+  /**
+   * Represents the health of a GemFire component.
+   */
+  public class HealthStatus  {
+    /** The health of a GemFire component */
+    private GemFireHealth.Health healthCode;
+
+    /** The diagnosis of the illness */
+    private String diagnosis;
+
+    //////////////////////  Constructors  //////////////////////
+
+    /**
+     * Creates a new <code>HealthStatus</code> with the give
+     * <code>health</code> code and <code>dianosis</code> message.
+     *
+     * @see GemFireHealth#OKAY_HEALTH
+     * @see GemFireHealth#POOR_HEALTH
+     */
+    HealthStatus(GemFireHealth.Health healthCode, String diagnosis) {
+      this.healthCode = healthCode;
+      this.diagnosis =
+        "[" + AbstractHealthEvaluator.this.getDescription() + "] " +
+        diagnosis;
+    }
+
+    /////////////////////  Instance Methods  /////////////////////
+
+    /**
+     * Returns the health code
+     *
+     * @see GemFireHealth#OKAY_HEALTH
+     * @see GemFireHealth#POOR_HEALTH
+     */
+    public GemFireHealth.Health getHealthCode() {
+      return this.healthCode;
+    }
+
+    /**
+     * Returns the diagnosis prepended with a description of the
+     * component that is ill.
+     */
+    public String getDiagnosis() {
+      return this.diagnosis;
+    }
+
+  }
+
+}


[21/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Region.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Region.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Region.java
new file mode 100644
index 0000000..9c02030
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Region.java
@@ -0,0 +1,2385 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.locks.Lock;
+
+import com.gemstone.gemfire.cache.client.ClientRegionFactory;
+import com.gemstone.gemfire.cache.client.Pool;
+import com.gemstone.gemfire.cache.client.SubscriptionNotEnabledException;
+import com.gemstone.gemfire.cache.query.FunctionDomainException;
+import com.gemstone.gemfire.cache.query.NameResolutionException;
+import com.gemstone.gemfire.cache.query.QueryInvalidException;
+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.snapshot.RegionSnapshotService;
+
+/** Manages subregions and cached data. Each region
+ * can contain multiple subregions and entries for data.
+ * Regions provide a hierarchical name space
+ * within the cache. Also, a region can be used to group cached
+ * objects for management purposes.
+ * <p>
+ *
+ * The Region interface basically contains two set of APIs: Region management
+ * APIs; and (potentially) distributed operations on entries. Non-distributed
+ * operations on entries
+ * are provided by the inner interface, {@link com.gemstone.gemfire.cache.Region.Entry}.
+ * <p>
+ *
+ * Each {@link com.gemstone.gemfire.cache.Cache} defines a single top region called the root region.
+ * User applications can use the root region to create subregions
+ * for isolated name space and object grouping.
+ * <p>
+ *
+ * A region's name can be any String except that it should not contain
+ * the region name separator, a forward slash (/).
+ *
+ * <code>Region</code>s can be referenced by a relative path name from any region
+ * higher in the hierarchy in {@link #getSubregion}. You can get the relative
+ * path from the root region with {@link #getFullPath}. The name separator
+ * is used to concatenate all the region names together from the root, starting
+ * with the root's subregions.
+ * <p>
+ * Relative region names can provide a convenient
+ * method to locate a subregion directly from some higher region. For example,
+ * a region structure is as follows:
+ * a region named <i>3rd_level_region</i> has parent region <i>2nd_level_region</i>; region
+ * <i>2nd_level_region</i> in turn has parent region  <i>1st_level_region</i>; and region
+ *  <i>1st_level_region</i> is a child of the root region. Then,the user can get the region
+ *  <i>3rd_level_region</i> from the root region by issuing:
+ *  <pre>
+ *  <code>
+ *  region3 = root.getSubregion("1st_level_region/2nd_level_region/3rd_level_region");
+ *  </code>
+ *  </pre>
+ *  or the user can get the region <i>3rd_level_region</i> from region <i>1st_level_region</i>
+ *  by issuing
+ *  <pre>
+ *  <code>
+ *  region3 = region1.getSubregion("2nd_level_region/3rd_level_region");
+ *  </code>
+ *  </pre>
+ * <p>
+ * Region entries are identified by their key. Any Object can be used as a key
+ * as long as the key Object
+ * is region-wide unique and implements both the equals and
+ * hashCode methods. For regions with distributed scope, the key must also be Serializable.
+ * <p>
+ * Regions and their entries can be locked. The <code>Lock</code>
+ * obtained from {@link #getRegionDistributedLock} is a distributed lock on the
+ * entire Region, and the <code>Lock</code> obtained from
+ * {@link Region#getDistributedLock} is a distributed lock on the individual
+ * entry.
+ *
+ * <p>If the scope is <code>Scope.GLOBAL</code>, the methods
+ * that modify, destroy, or invalidate the entries in this region will also get a
+ * distributed lock. See the documentations for {@link #getDistributedLock} and
+ * {@link #getRegionDistributedLock} for details on the implicit locking that
+ * occurs for regions with <code>Scope.GLOBAL</code>.
+ *<p>
+ * Unless otherwise specified, all of these methods throw a
+ * <code>CacheClosedException</code> if the Cache is closed at the time of
+ * invocation, or a <code>RegionDestroyedException</code> if this region has been
+ * destroyed.
+ * Serializability Requirements for arguments: Several methods in the region API
+ * take parameters such as key, value and callback parameters.All of these parameters
+ * are typed as objects.
+ * For distributed regions, keys, values and callback parameters have to be serializable
+ * Failure to meet these serialization requirements
+ * causes API methods to throw IllegalArgumentException.
+ * <p>
+ * Implementation of the java.util.concurrent.ConcurrentMap interface was added
+ * in version 6.5.  These methods give various levels
+ * of concurrency guarantees based on the scope and data policy of the region.
+ * They are implemented in the peer cache and client/server cache but are
+ * disallowed in peer Regions having NORMAL or EMPTY data policies.
+ * <p>
+ * The semantics of the ConcurrentMap methods on a Partitioned Region are
+ * consistent with those expected on a ConcurrentMap. In particular
+ * multiple writers in different JVMs of the same key in the same
+ * Partitioned Region will be done atomically.
+ * <p>
+ * The same is true for a region with GLOBAL scope. All operations will be
+ * done atomically since a distributed lock will be held while the
+ * operation is done.
+ * <p>
+ * The same is true for a region with LOCAL scope. All ops will be done 
+ * atomically since the underlying map is a concurrent hash map and no 
+ * distribution is involved.
+ * <p>
+ * For peer REPLICATE and PRELOADED regions atomicity is limited to
+ * threads in the JVM the operation starts in.  There is no coordination with
+ * other members of the system unless the operation is performed in a
+ * transaction.
+ *<p> 
+ * For client server regions the atomicity is determined by the scope and 
+ * data policy of the server region as described above. The operation is 
+ * actually performed on the server as described above. Clients will
+ * always send the ConcurrentMap operation to the server and the result 
+ * returned by the ConcurrentMap method in client will reflect what was 
+ * done on the server. Same goes for any CacheListener called on the
+ * client. Any local state on the client will be updated to be consistent 
+ * with the state change made on the server.
+ *<p> 
+ * @see RegionAttributes
+ * @see AttributesFactory
+ * @see AttributesMutator
+ * @see Region.Entry
+ * @since 2.0
+ */
+
+public interface Region<K,V>  extends ConcurrentMap<K, V> {
+  /** The region name separator character. */
+  public static final char SEPARATOR_CHAR = '/';
+
+  /** The region name separator character, represented as a string for convenience. */
+  public static final String SEPARATOR = "/";
+
+  /** Returns the name of this region. A region's name
+   * can be any non-empty String providing it does not
+   * contain the name separator, a forward slash (/).
+   * If this is the root region, returns "root".
+   * <p>
+   * Does not throw a <code>CacheClosedException</code> or a
+   * <code>RegionDestroyedException</code>.
+   *
+   * @return the name of this region
+   */
+  public String getName();
+
+  /**
+   * Returns the full path of this region starting with a forward slash, followed
+   * by the root, including every subregion in the path to this region.
+   * The path separator is a forward slash.
+   * <p>
+   * Does not throw a <code>CacheClosedException</code> or a
+   * <code>RegionDestroyedException</code>.
+   *
+   * @return the full path of this region
+   */
+  public String getFullPath();
+
+  /**
+   * Gets the parent region of this region. If
+   * this region is a root region, returns null.
+   * <p>
+   * Does not throw a <code>CacheClosedException</code> or a
+   * <code>RegionDestroyedException</code>.
+   *
+   * @return the parent region which contains this region;
+   * null, if this region is the root region
+   * @see Region#createSubregion(String, RegionAttributes) createSubregion
+   */
+  public <PK, PV> Region<PK, PV> getParentRegion();
+
+  /** Returns the <code>RegionAttributes</code> for this region.
+   * This object is backed by this region, so if attributes
+   * are modified using this region's <code>AttributesMutator</code>,
+   * this <code>RegionAttributes</code> object will immediately reflect the change.
+   * <p>
+   * Does not throw a <code>CacheClosedException</code> or a
+   * <code>RegionDestroyedException</code>.
+   *
+   * @return the <code>RegionAttributes</code> of this region
+   * @see Region#createSubregion(String, RegionAttributes)
+   * @see AttributesMutator
+   * @see AttributesFactory
+   * @see #getAttributesMutator
+   */
+  public RegionAttributes<K, V> getAttributes();
+
+
+  /** Returns a mutator object used for modifying this region's attributes
+   *  after region creation.
+   * Note that some attributes are immutable after region creation.
+   *
+   * @return the <code>AttributesMutator</code> object
+   * @see #getAttributes
+   */
+  public AttributesMutator<K,V> getAttributesMutator();
+
+  /** Returns the <code>CacheStatistics</code> for this region.
+   *
+   * @return the <code>CacheStatistics</code> of this region
+   * @throws StatisticsDisabledException if statistics have been disabled for this region
+   * @throws UnsupportedOperationException If the region is a partitioned region
+   */
+  public CacheStatistics getStatistics() throws StatisticsDisabledException;
+
+  /** Invalidates this region. Invalidation cascades to
+   * all entries and subregions. After
+   * the <code>invalidateRegion</code>, this region and the entries in it still
+   * exist. To remove all the entries and this region,
+   * <code>destroyRegion</code> should be used. The region invalidate will be distributed
+   * to other caches if the scope is not <code>Scope.LOCAL</code>.
+   * <p>
+   * Does not update any <code>CacheStatistics</code>.
+   *
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out getting distributed lock for <code>Scope.GLOBAL</code>
+   * @see CacheListener#afterRegionInvalidate
+   */
+  public void invalidateRegion() throws TimeoutException;
+
+  /** Invalidates this region. The invalidation will cascade to
+   * all the subregions and cached entries. After
+   * the <code>invalidateRegion</code>, the region and the entries in it still
+   * exist. In order to remove all the entries and the region,
+   * <code>destroyRegion</code> should be used. The region invalidate will be distributed
+   * to other caches if the scope is not <code>Scope.LOCAL</code>.
+   * <p>
+   * Does not update any <code>CacheStatistics</code>.
+   * @param aCallbackArgument a user-defined parameter to pass to callback events
+   *        triggered by this method. Can be null. Should be serializable.
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for <code>Scope.GLOBAL</code>
+   * @throws TimeoutException if timed out getting distributed lock for <code>Scope.GLOBAL</code>
+   * @throws IllegalArgumentException if aCallbackArgument is not serializable
+   * @see CacheListener#afterRegionInvalidate
+   */
+  public void invalidateRegion(Object aCallbackArgument) throws TimeoutException;
+
+
+
+  /** Invalidates this region in the local cache only. Invalidation
+   * cascades to all entries and subregions. After
+   * the <code>invalidateRegion</code>, this region and the entries in it still
+   * exist. To remove all the entries and this region,
+   * destroyRegion should be used.
+   *
+   * Does not update any <code>CacheStatistics</code>.
+   *
+   * @throws IllegalStateException if this region is distributed and
+   * {@link DataPolicy#withReplication replicated}
+   * @throws UnsupportedOperationException If the region is a partitioned region
+   * @see CacheListener#afterRegionInvalidate
+   */
+  public void localInvalidateRegion();
+
+  /** Invalidates this region in the local cache only,
+   * and provides a user-defined argument to the <code>CacheListener</code>.
+   * The invalidation will cascade to
+   * all the subregions and cached entries. After
+   * the <code>invalidateRegion</code>, the region and the entries in it still
+   * exist. In order to remove all the entries and the region,
+   * destroyRegion should be used.
+   *
+   * Does not update any <code>CacheStatistics</code>.
+   * @param aCallbackArgument a user-defined parameter to pass to callback events
+   *        triggered by this method. Can be null.
+   * @throws IllegalStateException if the region is distributed and
+   * {@link DataPolicy#withReplication replicated}
+   * @throws UnsupportedOperationException If the region is a partitioned region
+   * @see CacheListener#afterRegionInvalidate
+   */
+
+  public void localInvalidateRegion(Object aCallbackArgument);
+
+
+  /** Destroys the whole region.
+   * Destroy cascades to all entries
+   * and subregions. After the destroy, this
+   * region object can not be used any more and any attempt to use this region
+   * object will get <code>RegionDestroyedException</code>.
+   * The region destroy will be distributed to other caches if the scope is
+   * not <code>Scope.LOCAL</code>.
+   * <p>
+   * Does not update any <code>CacheStatistics</code>.
+   *
+   * @throws CacheWriterException if a CacheWriter aborts the operation; if this
+   *         occurs some subregions may have already been successfully destroyed.
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out getting distributed lock for Scope.GLOBAL
+   * @see CacheListener#afterRegionDestroy
+   * @see CacheWriter#beforeRegionDestroy
+   */
+  public void destroyRegion() throws CacheWriterException, TimeoutException;
+
+  /** Destroys the whole region and provides a user-defined parameter
+   * object to any <code>CacheWriter</code> invoked in the process.
+   * Destroy cascades to all entries
+   * and subregions. After the destroy, this region object can not be used
+   * any more. Any attempt to use this region object will get a
+   * <code>RegionDestroyedException</code> exception. The region destroy is
+   * distributed to other caches if the scope is not <code>Scope.LOCAL</code>.
+   * <p>
+   * Does not update any <code>CacheStatistics</code>.
+   *
+   * @param aCallbackArgument a user-defined parameter to pass to callback events
+   *        triggered by this method. Can be null. Should be serializable.
+   * @throws CacheWriterException if a CacheWriter aborts the operation; if this
+   *         occurs some subregions may have already been successfully destroyed.
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out getting distributed lock for Scope.GLOBAL
+   * @throws IllegalArgumentException if aCallbackArgument is not serializable
+   * @see CacheListener#afterRegionDestroy
+   * @see CacheWriter#beforeRegionDestroy
+   */
+  public void destroyRegion(Object aCallbackArgument) throws CacheWriterException, TimeoutException;
+
+  /** Destroys the whole region in the local cache only. No <code>CacheWriter</code>
+   * is invoked.
+   * Destroy cascades to all entries and subregions.
+   * After the destroy, this region object can not be used
+   * any more and any attempt to use this region object will get
+   * {@link RegionDestroyedException} exception.
+   * This operation is not distributed to any other cache.
+   * <p>
+   * Does not update any <code>CacheStatistics</code>.
+   *
+   * @see CacheListener#afterRegionDestroy
+   */
+  public void localDestroyRegion();
+
+  /** Destroys the whole region in the local cache only, and provides a
+   * user-defined argument to a <code>CacheListener</code>  if any.
+   *
+   * No <code>CacheWriter</code> is invoked.
+   * Destroy will cascade to all the entries
+   * and subregions. After the destroy, this region object can not be used
+   * any more. Any attempt to use this region object will get
+   * {@link RegionDestroyedException} exception.
+   * <p>
+   * Does not update any <code>CacheStatistics</code>.
+   * @param aCallbackArgument a user-defined parameter to pass to callback events
+   *        triggered by this call. Can be null.
+   * @see CacheListener#afterRegionDestroy
+   */
+  public void localDestroyRegion(Object aCallbackArgument);
+
+  /**
+   * Does a localDestroyRegion, but leaves behind the disk files if this
+   * is a region with persistBackup set to true.
+   * Calls {@link CacheListener#afterRegionDestroy} on each cache listener
+   * on the closed region(s).
+   * Also calls {@link CacheCallback#close} on each callback on the closed
+   * region(s).
+   * <p>
+   * Does not update any <code>CacheStatistics</code>.
+   *
+   * @see Region#localDestroyRegion()
+   * @see CacheListener#afterRegionDestroy
+   */
+  public void close();
+
+  /**
+   * Obtains the snapshot service to allow the cache data to be imported
+   * or exported.
+   * 
+   * @return the snapshot service for the region
+   */
+  public RegionSnapshotService<K, V> getSnapshotService();
+  
+  /**
+   * Saves the data in this region in a snapshot file. The data is a
+   * "concurrent" snapshot in that modifications to the region
+   * while the snapshot is being written are not guaranteed to be included
+   * or excluded from the snapshot. In other words, if there are concurrent
+   * modifications to the region while the snapshot is being written, the
+   * snapshot may not reflect a consistent state of the entire region at any
+   * moment in time.
+   *
+   * @param outputStream the output stream to write to
+   * @throws IOException if encountered while writing the file
+   * @throws UnsupportedOperationException If the region is a partitioned region
+   * @see #loadSnapshot
+   * 
+   * @deprecated as of 7.0 use {@link #getSnapshotService()}
+   */
+  public void saveSnapshot(OutputStream outputStream) throws IOException;
+
+  /**
+   * Loads data from a file that was previously created with the saveSnapshot
+   * method. This method essentially destroys the region and automatically
+   * recreates it with the data in the snapshot. Any current data in the region
+   * is lost, replaced with the data in the snapshot file.
+   * Causes this region and all other regions with the same
+   * name in remote caches in this distributed system to be reinitialized:
+   * remote regions are cleared of all data and distributed {@link DataPolicy#withReplication replicated} remote regions will do
+   * a new getInitialImage operation to get the data from this snapshot. Any
+   * existing references to this region or any region that is reinitialized in
+   * this manner become unusable in that any subsequent methods invoked on those
+   * references will throw a RegionReinitializedException (which is a subclass
+   * of RegionDestroyedException).<p>
+   *
+   * In order to continue working with this region, a new reference needs to be
+   * acquired using Cache#getRegion or Region#getSubregion (which will block until
+   * reinitialization is complete).<p>
+   *
+   * NOTE: SUBREGIONS ARE DESTROYED.
+   * Since loading a snapshot effectively destroys the region and recreates
+   * it, all subregions of this region in this cache as well as other remote
+   * caches in the same distributed system are destroyed.<p>
+   *
+   * If any error occurs while loading the snapshot, this region is destroyed
+   * and threads in remote caches that are attempting to get a reference to this
+   * region will get null instead of a region reference.
+   *
+   * The only callbacks that are invoked are called for the destroyRegion
+   * operation, i.e. the CacheWriter and the close methods on callbacks.
+   * CacheListeners and other callback objects have their close() methods called
+   * when the region is destroyed, and then those same callback objects will
+   * be reinstalled on the new region. Therefore, the callback objects should
+   * be able to handle a close() followed by events associated with the newly
+   * created region.
+   *
+   * @param inputStream the inputStream to load the snapshot from
+   * @throws ClassNotFoundException if a class cannot be found while loading
+   *         data
+   * @throws IOException if error encountered while reading file.
+   * @throws CacheWriterException if a CacheWriter aborts the destroyRegion
+   *         operation; if this occurs some subregions may have already been
+   *         successfully destroyed.
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out getting distributed lock for Scope.GLOBAL
+   * @throws UnsupportedOperationException If the region is a partitioned region
+   *
+   * @see RegionReinitializedException
+   * 
+   * @deprecated as of 7.0 use {@link #getSnapshotService()}
+   */
+  public void loadSnapshot(InputStream inputStream)
+  throws IOException, ClassNotFoundException, CacheWriterException, TimeoutException;
+
+  /** Returns a subregion with the specified name or null if doesn't exist. The
+   * name is relative from this region, so it can be either a simple region name
+   * or a relative region path. If <code>regionName</code> is the empty string, then this
+   * region itself is returned.
+   *
+   * @param path the path to the subregion
+   * @return a subregion with the specified relative path from this region,
+   * or null if it doesn't exist
+   * @throws IllegalArgumentException if path starts with a forward slash or
+   * @see Region Region
+   * @see Region#getFullPath
+   */
+  public <SK, SV> Region<SK, SV> getSubregion(String path);
+
+
+  /** Creates a subregion with the specified name and <code>RegionAttributes</code>.
+   * The name must not contain a region name separator.
+   * If the subregion is a distributed {@link DataPolicy#withReplication replicated} region, it
+   * will be initialized with data from all other caches in this
+   * distributed system that have the same region.
+   *
+   * <p>Updates the {@link CacheStatistics#getLastAccessedTime} and
+   * {@link CacheStatistics#getLastModifiedTime} for this region.
+   *
+   * @param subregionName the subregion name
+   * @param aRegionAttributes the RegionAttributes to be used for the subregion
+   * @return a subregion with the specified name
+   * @throws IllegalArgumentException if aRegionAttributes is null or if
+   * regionName is null, the empty string, or contains a '/'
+   * @throws IllegalStateException If the supplied RegionAttributes violate the
+   *         <a href="AttributesFactory.html#creationConstraints">region creation constraints</a>
+   *         with a region of the same name in another cache in the distributed system
+   *         or with this (parent) region.
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out getting distributed lock for Scope.GLOBAL
+   * @throws RegionExistsException if a subregion by the specified name already exists
+   * @throws UnsupportedOperationException If the region is a partitioned region
+   * @see AttributesFactory
+   * @see Region#getFullPath
+   * @deprecated as of 7.0 use {@link RegionFactory#createSubregion(Region, String)} or {@link ClientRegionFactory#createSubregion(Region, String)}.
+   */
+  public <SK,SV> Region<SK,SV> createSubregion(String subregionName, RegionAttributes<SK,SV> aRegionAttributes)
+  throws RegionExistsException, TimeoutException;
+
+  /** Returns a Set of all subregions. If the recursive parameter is
+   * set to true, this call will recursively collect all subregions
+   * contained in this region. Otherwise, this call will only
+   * return the Set of direct subregions.
+   *
+   *<p>This <code>Set</code> is unmodifiable. It is
+   * backed by this region. Synchronization is not necessary to access or
+   * iterate over this set. No <code>ConcurrentModificationException</code>s
+   * will be thrown, but subregions may be added or removed while a thread is
+   * iterating. Iterators are intended to be used by one thread at a time.
+   * If a stable "snapshot" view of the set is required, then call
+   * one of the toArray methods on the set and iterate over the array.
+   *
+   * @param recursive if false, collects direct subregions only; if true,
+   *      collects all subregions recursively
+   * @return a Set of subregions
+   */
+  public Set<Region<?, ?>> subregions(boolean recursive);
+
+
+  /** Returns the <code>Region.Entry</code> for the specified key, or null if it doesn't
+   * exist.
+   *
+   * @param key the key corresponding to the Entry to return
+   * @return the Region.Entry for the specified key or null if not found in this
+   *         region
+   * @throws NullPointerException if key is null
+   */
+  public Entry<K,V> getEntry(Object key);
+
+  /** Returns the value associated with the specified key. If the value
+   * is not present locally for this entry, a netSearch and/or a CacheLoader
+   * may be invoked to get the value, depending on the scope of this region.
+   * A netSearch looks for a value in every node of the system that defines
+   * this region. A netLoad invokes remote loaders one at a time until one
+   * returns a value or throws an exception.
+   * If any of these methods successfully retrieves a value than the value
+   * is immediately returned.
+   *<p>
+   * For local scope, a local CacheLoader will be invoked if there is one.
+   * For global scope, the order is netSearch, localLoad, netLoad.
+   * For any other distributed scope, the order is localLoad, netSearch, netLoad.
+   *<p>
+   * netSearch and netLoad are never performed more than once, so if a loader
+   * attempts to do a netSearch and one was already done, then another one will
+   * not be done.
+   *<p>
+   * The value returned by get is not copied, so multi-threaded applications
+   * should not modify the value directly, but should use the update methods.
+   *<p>
+   * Updates the {@link CacheStatistics#getLastAccessedTime},
+   * {@link CacheStatistics#getHitCount}, {@link CacheStatistics#getMissCount},
+   * and {@link CacheStatistics#getLastModifiedTime} (if a new value is loaded)
+   * for this region and the entry.
+   *<p>
+   *
+   * If the <code>CacheWriter</code> throws a
+   * <code>CacheWriterException</code> when a new value is retrieved
+   * from a loader, the value will not be put into the cache (a new
+   * entry will not be created) but the get will return the value and
+   * not propagate the exception.
+   *
+   * @param key whose associated value is to be returned. The key Object must
+   * implement the equals and hashCode methods. Note that even though key is typed as "Object"
+   * if a CacheLoader is used then make sure you only pass instances of "K" in this parameter.
+   * @return the value with specified key, or null if the value
+   * is not found and can't be loaded
+   * @throws NullPointerException if the key is null
+   * @throws IllegalArgumentException if the key does not meet
+   *         the serializability requirements
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out doing a {@link Cache#getSearchTimeout search} for distributed or getting a distributed lock for Scope.GLOBAL
+   * @throws CacheLoaderException if a cache loader throws an exception, or if
+   *         the cache loader returns an object that is not serializable and this
+   *         is a distributed region
+   * @throws PartitionedRegionStorageException for a partitioned region fails to invoke a {@link CacheLoader}
+   * @see CacheLoader#load
+   * @see CacheListener#afterCreate
+   * @see CacheListener#afterUpdate
+   * @see CacheWriter#beforeCreate
+   * @see CacheWriter#beforeUpdate
+   */
+  public V get(Object key) throws CacheLoaderException, TimeoutException;
+
+  /** Returns the value associated with the specified key, passing the callback
+   * argument to any cache loaders or cache writers that are invoked in the
+   * operation. If the value
+   * is not present locally for this entry, a netSearch and/or a CacheLoader
+   * may be invoked to get the value, depending on the scope of this region.
+   * A netSearch looks for a value in every node of the system that defines
+   * this region. A netLoad invokes remote loaders one at a time until one
+   * returns a value or throws an exception.
+   * If any of these methods successfully retrieves a value than the value
+   * is immediately returned.
+   *<p>
+   * For local scope, a local CacheLoader will be invoked if there is one.
+   * For global scope, the order is netSearch, localLoad, netLoad.
+   * For any other distributed scope, the order is localLoad, netSearch, netLoad.
+   *<p>
+   * netSearch and netLoad are never performed more than once, so if a loader
+   * attempts to do a netSearch and one was already done, then another one will
+   * not be done.
+   *<p>
+   * The value returned by get is not copied, so multi-threaded applications
+   * should not modify the value directly, but should use the update methods.
+   *<p>
+   * Updates the {@link CacheStatistics#getLastAccessedTime},
+   * {@link CacheStatistics#getHitCount}, {@link CacheStatistics#getMissCount},
+   * and {@link CacheStatistics#getLastModifiedTime} (if a new value is loaded)
+   * for this region and the entry.
+   *
+   * If the <code>CacheWriter</code>
+   * throws a <code>CacheWriterException</code> when
+   * a new value is retrieved from a loader,  then the value will not be put
+   * into the cache (a new entry will not be created) but the get will return
+   * the value and not propagate the exception.
+   *
+   * @param key whose associated value is to be returned. The key Object must
+   * implement the equals and hashCode methods. Note that even though key is typed as "Object"
+   * if a CacheLoader is used then make sure you only pass instances of "K" in this parameter.
+   * @param aCallbackArgument an argument passed into the CacheLoader if
+   * loader is used. This same argument will also be subsequently passed
+   * to a CacheWriter if the loader returns a non-null value to be placed in
+   * the cache. Modifications to this argument made in the CacheLoader will
+   * be visible to the CacheWriter even if the loader and the writer are
+   * installed in different cache VMs. It will also be passed to any other
+   * callback events triggered by this method.
+   * May be null. Should be serializable.
+   * @return the value with specified key, or null if the value
+   * is not found and can't be loaded
+   * @throws NullPointerException if key is null
+   * @throws IllegalArgumentException if aCallbackArgument is not serializable
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out doing a {@link Cache#getSearchTimeout search} for distributed or getting a distributed lock for Scope.GLOBAL
+   * @throws CacheLoaderException if a cache loader throws an exception, or if
+   *         the cache loader returns an object that is not serializable and this
+   *         is a distributed region
+   * @throws PartitionedRegionStorageException for a partitioned region fails to invoke a {@link CacheLoader}
+   * @see RegionAttributes
+   * @see CacheLoader#load
+   * @see CacheListener#afterCreate
+   * @see CacheListener#afterUpdate
+   * @see CacheWriter#beforeCreate
+   * @see CacheWriter#beforeUpdate
+   */
+  public V get(Object key, Object aCallbackArgument)
+  throws TimeoutException, CacheLoaderException;
+
+  /** Places a new value into an entry in this region with the specified key.
+   * If there is already an entry associated with the specified key in this region,
+   * the entry's previous value is overwritten.
+   *
+   * <p>Updates the {@link CacheStatistics#getLastAccessedTime} and
+   * {@link CacheStatistics#getLastModifiedTime} for this region and the entry.
+   *
+   * @param key a key associated with the value to be put into this region.
+   * The key object must implement the equals and hashCode methods.
+   * @param value the value to be put into the cache
+   * @return the previous value stored locally for the key.
+   *         If the entry did not exist then <code>null</code> is returned.
+   *         If the entry was "invalid" then <code>null</code> is returned.
+   *         In some cases <code>null</code> may be returned even
+   *         if a previous value exists.
+   *         If the region is a client proxy then <code>null</code> is returned.
+   *         If the region is partitioned and the put is done on a non-primary then <code>null</code> is returned.
+   *         If the value is not currently stored in memory but is on disk
+   *         and if the region does not have cqs
+   *         then <code>null</code> is returned.
+   * @throws NullPointerException if key is null or if value
+   *         is null (use invalidate instead), or if the key or value do not
+   *         meet serializability requirements
+   * @throws ClassCastException if key does not satisfy the keyConstraint
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out getting distributed lock for Scope.GLOBAL
+   * @throws CacheWriterException if a CacheWriter aborts the operation
+   * @throws PartitionedRegionStorageException if the operation could not be completed on a partitioned region.
+   * @throws LowMemoryException if a low memory condition is detected.
+   * @see #invalidate(Object)
+   * @see CacheLoader#load
+   * @see CacheListener#afterCreate
+   * @see CacheListener#afterUpdate
+   * @see CacheWriter#beforeCreate
+   * @see CacheWriter#beforeUpdate
+   */
+  public V put(K key, V value)
+  throws TimeoutException, CacheWriterException;
+
+
+  /** Places a new value into an entry in this region with the specified key,
+   * providing a user-defined parameter
+   * object to any <code>CacheWriter</code> invoked in the process.
+   * If there is already an entry associated with the specified key in this region,
+   * the entry's previous value is overwritten.
+   *
+   * <p>Updates the {@link CacheStatistics#getLastAccessedTime} and
+   * {@link CacheStatistics#getLastModifiedTime} for this region and the entry.
+   *
+   * @param key a key associated with the value to be put into this region.
+   * The key object must implement the equals and hashCode methods.
+   * @param value the value to be put into the cache
+   * @param aCallbackArgument a user-defined parameter to pass to callback events
+   *        triggered by this method. Can be null. Should be serializable.
+   * @return the previous value stored locally for the key.
+   *         If the entry did not exist then <code>null</code> is returned.
+   *         If the entry was "invalid" then <code>null</code> is returned.
+   *         In some cases <code>null</code> may be returned even
+   *         if a previous value exists.
+   *         If the region is a client proxy then <code>null</code> is returned.
+   *         If the region is partitioned and the put is done on a non-primary then <code>null</code> is returned.
+   *         If the value is not currently stored in memory but is on disk
+   *         and if the region does not have cqs
+   *         then <code>null</code> is returned.
+   * @throws NullPointerException if key is null
+   * @throws IllegalArgumentException if key, value, or
+   *         aCallbackArgument do not meet serializability requirements
+   * @throws ClassCastException if key does not satisfy the keyConstraint
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out getting distributed lock for Scope.GLOBAL
+   * @throws CacheWriterException if a CacheWriter aborts the operation
+   * @throws PartitionedRegionStorageException if the operation could not be completed on a partitioned region.
+   * @throws LowMemoryException if a low memory condition is detected.
+   * @see #invalidate(Object)
+   * @see CacheLoader#load
+   * @see CacheListener#afterCreate
+   * @see CacheListener#afterUpdate
+   * @see CacheWriter#beforeCreate
+   * @see CacheWriter#beforeUpdate
+   */
+  public V put(K key, V value, Object aCallbackArgument)
+  throws TimeoutException, CacheWriterException;
+
+  /** Creates a new entry in this region with the specified key and value.
+   *
+   * <p>Updates the {@link CacheStatistics#getLastAccessedTime} and
+   * {@link CacheStatistics#getLastModifiedTime} for this region and the entry.
+   *<p>
+   * If this region has a distributed scope, this operation
+   * may cause update events in caches that already have
+   * this region with this entry, and it will cause create events in other caches
+   * that have {@link InterestPolicy#ALL all events} configured.
+   *<p>
+   * This operation gets a distributed lock on the entry if the scope is
+   * <code>Scope.GLOBAL</code>.
+   *
+   * @param key the key for which to create the entry in this region
+   * @param value the value for the new entry, which may be null meaning
+   *              the new entry starts as if it had been locally invalidated
+   * @throws NullPointerException if key is null
+   * @throws IllegalArgumentException if the key or value
+   *         is not serializable and this is a distributed region
+   * @throws ClassCastException if key does not satisfy the keyConstraint
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out getting distributed lock for <code>Scope.GLOBAL</code>
+   * @throws EntryExistsException if an entry with this key already exists
+   * @throws CacheWriterException if a CacheWriter aborts the operation
+   * @throws PartitionedRegionStorageException if the operation could not be completed on a partitioned region.
+   * @throws LowMemoryException if a low memory condition is detected.
+   * @see CacheListener#afterCreate
+   * @see CacheListener#afterUpdate
+   * @see CacheWriter#beforeCreate
+   * @see CacheWriter#beforeUpdate
+   */
+  public void create(K key, V value)
+  throws TimeoutException, EntryExistsException, CacheWriterException;
+
+  /** Creates a new entry in this region with the specified key and value,
+   * providing a user-defined parameter
+   * object to any <code>CacheWriter</code> invoked in the process.
+   * If this region has a distributed scope, then the value may be updated
+   * subsequently if other caches update the value.
+   *
+   * <p>Updates the {@link CacheStatistics#getLastAccessedTime} and
+   * {@link CacheStatistics#getLastModifiedTime} for this region and the entry.
+   * <p>
+   * If this region has a distributed scope, this operation
+   * may cause update events in caches that already have
+   * this region with this entry, and it will cause create events in other caches
+   * that have {@link InterestPolicy#ALL all events} configured.
+   *
+   * @param key the key for which to create the entry in this region
+   * @param value the value for the new entry, which may be null meaning
+   *              the new entry starts as if it had been locally invalidated.
+   * @param aCallbackArgument a user-defined parameter to pass to callback events
+   *        triggered by this method. Can be null. Should be serializable.
+   * @throws NullPointerException if key is null
+   * @throws IllegalArgumentException if the key, value, or
+   *         aCallbackArgument do not meet serializability requirements
+   * @throws ClassCastException if key does not satisfy the keyConstraint
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out getting distributed lock for <code>Scope.GLOBAL</code>
+   * @throws EntryExistsException if an entry with this key already exists
+   * @throws CacheWriterException if a CacheWriter aborts the operation
+   * @throws PartitionedRegionStorageException if the operation could not be completed on a partitioned region.
+   * @throws LowMemoryException if a low memory condition is detected.
+   * @see CacheListener#afterCreate
+   * @see CacheListener#afterUpdate
+   * @see CacheWriter#beforeCreate
+   * @see CacheWriter#beforeUpdate
+   */
+  public void create(K key, V value, Object aCallbackArgument)
+  throws TimeoutException, EntryExistsException, CacheWriterException;
+
+  /** Invalidates the entry with the specified key. Invalidate
+   * only removes the value from the entry, the key is kept intact.
+   * To completely remove the entry, destroy should be used.
+   * The invalidate will be distributed to other caches if
+   * the scope is not Scope.LOCAL.
+   *
+   * <p>
+   * Does not update any <code>CacheStatistics</code>.
+   *
+   * @param key the key of the value to be invalidated
+   * @throws NullPointerException if key is null
+   * @throws IllegalArgumentException if the key does not
+   *         meet serializability requirements
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out getting distributed lock for <code>Scope.GLOBAL</code>
+   * @throws EntryNotFoundException if the entry does not exist in this region
+   * @see CacheListener#afterInvalidate
+   */
+  public void invalidate(Object key)
+  throws TimeoutException, EntryNotFoundException;
+
+  /** Invalidates the entry with the specified key,
+   * and provides a user-defined argument to the <code>CacheListener</code>.
+   * Invalidate only removes the value from the entry, the key is kept intact.
+   * To completely remove the entry, destroy should be used.
+   *
+   * <p>
+   * Does not update any <code>CacheStatistics</code>.
+   *
+   * @param key the key of the value to be invalidated
+   * @param aCallbackArgument a user-defined parameter to pass to callback events
+   *        triggered by this method. Can be null. Should be serializable.
+   * @throws NullPointerException if key is null
+   * @throws IllegalArgumentException if the key or the
+   *         aCallbackArgument do not meet serializability requirements
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for <code>Scope.GLOBAL</code>
+   * @throws TimeoutException if timed out getting distributed lock for <code>Scope.GLOBAL</code>
+   * @throws EntryNotFoundException if this entry does not exist in this region
+   * @see CacheListener#afterInvalidate
+   */
+
+  public void invalidate(Object key, Object aCallbackArgument)
+  throws TimeoutException, EntryNotFoundException;
+
+  /** Invalidates the value with the specified key in the local cache only.
+   * Invalidate will only remove the value from the entry, the key will be kept intact.
+   * In order to completely remove the key, entry and value, destroy should
+   * be called.
+   *
+   * <p>
+   * Does not update any <code>CacheStatistics</code>.
+   *
+   * @param key the key of the value to be invalidated
+   * @throws NullPointerException if key is null
+   * @throws IllegalArgumentException if the key
+   *         does not meet serializability requirements
+   * @throws IllegalStateException if this region is distributed and
+   * {@link DataPolicy#withReplication replicated}
+   * @throws EntryNotFoundException if the entry does not exist in this region locally
+   * @throws UnsupportedOperationException If the region is a partitioned region
+   * @throws UnsupportedOperationInTransactionException If called in a transactional context
+   * @see CacheListener#afterInvalidate
+   */
+  public void localInvalidate(Object key) throws EntryNotFoundException;
+
+  /** Invalidates the value with the specified key in the local cache only,
+   * and provides a user-defined argument to the <code>CacheListener</code>.
+   * Invalidate will only remove the value from the entry, the key will be kept intact.
+   * In order to completely remove the key, entry and value, destroy should
+   * be called.
+   *
+   * <p>
+   * Does not update any <code>CacheStatistics</code>.
+   *
+   * @param key the key of the value to be invalidated
+   * @param aCallbackArgument a user-defined parameter to pass to callback events
+   *        triggered by this method. Can be null.
+   * @throws NullPointerException if key is null
+   * @throws IllegalStateException if this region is distributed and
+   * {@link DataPolicy#withReplication replicated}
+   * @throws EntryNotFoundException if this entry does not exist in this region locally
+   * @throws UnsupportedOperationException If the region is a partitioned region
+   * @throws UnsupportedOperationInTransactionException If called in a transactional context
+   * @see CacheListener#afterInvalidate
+   */
+  public void localInvalidate(Object key, Object aCallbackArgument)
+  throws EntryNotFoundException;
+
+
+  /** Destroys the entry with the specified key. Destroy removes
+   * not only the value but also the key and entry from this region.
+   * Destroy will be distributed to other caches if the scope
+   * is not <code>Scope.LOCAL</code>.
+   * <p>
+   * Does not update any <code>CacheStatistics</code>.
+   *
+   * @param key the key of the entry
+   * @return the previous value stored locally for the key.
+   *         If the entry was "invalid" then <code>null</code> is returned.
+   *         In some cases <code>null</code> may be returned even
+   *         if a previous value exists.
+   *         If the region is a client proxy then <code>null</code> is returned.
+   *         If the region is partitioned and the destroy is done on a non-primary then <code>null</code> is returned.
+   *         If the value is not currently stored in memory but is on disk
+   *         and if the region does not have cqs
+   *         then <code>null</code> is returned.
+   * @throws NullPointerException if key is null
+   * @throws IllegalArgumentException if key does not meet
+   *         serializability requirements
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out getting distributed lock for Scope.GLOBAL
+   * @throws EntryNotFoundException if the entry does not exist in this region
+   * @throws CacheWriterException if a CacheWriter aborts the operation
+   * @see CacheListener#afterDestroy
+   * @see CacheWriter#beforeDestroy
+   */
+  public V destroy(Object key)
+  throws TimeoutException, EntryNotFoundException, CacheWriterException;
+
+
+  /** Destroys the entry with the specified key, and provides a user-defined
+   * parameter object to any <code>CacheWriter</code> invoked in the process.
+   * Destroy removes
+   * not only the value but also the key and entry from this region.
+   * Destroy will be distributed to other caches if the scope is not
+   * <code>Scope.LOCAL</code>.
+   * <p>
+   * Does not update any <code>CacheStatistics</code>.
+   *
+   * @param key the key of the entry to destroy
+   * @param aCallbackArgument a user-defined parameter to pass to callback events
+   *        triggered by this method. Can be null. Should be serializable.
+   * @return the previous value stored locally for the key.
+   *         If the entry was "invalid" then <code>null</code> is returned.
+   *         In some cases <code>null</code> may be returned even
+   *         if a previous value exists.
+   *         If the region is a client proxy then <code>null</code> is returned.
+   *         If the region is partitioned and the destroy is done on a non-primary then <code>null</code> is returned.
+   *         If the value is not currently stored in memory but is on disk
+   *         and if the region does not have cqs
+   *         then <code>null</code> is returned.
+   * @throws NullPointerException if key is null
+   * @throws IllegalArgumentException if the key or aCallbackArgument
+   *         do not meet serializability requirements
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out getting distributed lock for Scope.GLOBAL
+   * @throws EntryNotFoundException if the entry does not exist in this region
+   * @throws CacheWriterException if a CacheWriter aborts the operation
+   * @see CacheListener#afterDestroy
+   * @see CacheWriter#beforeDestroy
+   */
+  public V destroy(Object key, Object aCallbackArgument)
+  throws TimeoutException, EntryNotFoundException, CacheWriterException;
+
+  /** Destroys the value with the specified key in the local cache only,
+   * No <code>CacheWriter</code> is
+   * invoked. Destroy removes not only the value but also the key and entry
+   * from this region.
+   * <p>
+   * Does not update any <code>CacheStatistics</code>.
+   *
+   * @param key the key of the entry to destroy
+   * @throws NullPointerException if key is null
+   * @throws IllegalStateException if this region is distributed and
+   * {@link DataPolicy#withReplication replicated}
+   * @throws EntryNotFoundException if the entry does not exist in this region locally
+   * @throws UnsupportedOperationException If the region is a partitioned region
+   * @throws UnsupportedOperationInTransactionException If called in a transactional context
+   * @see CacheListener#afterDestroy
+   */
+  public void localDestroy(Object key) throws EntryNotFoundException;
+
+  /**
+   * Destroys the value with the specified key in the local cache
+   * only, and provides a user-defined
+   * parameter object to the <code>CacheListener</code>, if any. No <code>CacheWriter</code> is
+   * invoked. Destroy removes
+   * not only the value but also the key and entry from this region.
+   * <p>
+   * Does not update any <code>CacheStatistics</code>.
+   *
+   * @param key the key of the entry to destroy
+   * @param aCallbackArgument a user-defined parameter to pass to callback events
+   *        triggered by this method. Can be null.
+   * @throws NullPointerException if key is null
+   * @throws IllegalStateException if this region is distributed and
+   * {@link DataPolicy#withReplication replicated}
+   * @throws EntryNotFoundException if the entry does not exist in this region locally
+   * @throws UnsupportedOperationException If the region is a partitioned region
+   * @throws UnsupportedOperationInTransactionException If called in a transactional context
+   * @see CacheListener#afterDestroy
+   */
+  public void localDestroy(Object key, Object aCallbackArgument) throws EntryNotFoundException;
+
+  /** Returns a set of keys in the region.
+   *
+   *<p>This <code>Set</code> is unmodifiable. It is
+   * backed by this region. Synchronization is not necessary to access or
+   * iterate over this set. No <code>ConcurrentModificationException</code>s
+   * will be thrown, but keys may be added or removed to this set while a thread
+   * is iterating. Iterators are intended to be used by one thread at a time.
+   * If a stable "snapshot" view of the set is required, then call
+   * one of the toArray methods on the set and iterate over the array.
+   * If you need to lock down the region so this set is not modified while
+   * it is being accessed, use global scope with a distributed lock.
+   *
+   *@deprecated Use <code>keySet</code> instead;
+   *
+   * @return a Set of all the keys
+   */
+  @Deprecated
+  public Set<K> keys();
+
+
+  /** Returns a set of keys in the region.
+   *
+   *<p>This <code>Set</code> is unmodifiable. It is
+   * backed by this region. Synchronization is not necessary to access or
+   * iterate over this set. No <code>ConcurrentModificationException</code>s
+   * will be thrown, but keys may be added or removed to this set while a thread
+   * is iterating. Iterators are intended to be used by one thread at a time.
+   * If a stable "snapshot" view of the set is required, then call
+   * one of the toArray methods on the set and iterate over the array.
+   * If you need to lock down the region so this set is not modified while
+   * it is being accessed, use global scope with a distributed lock.
+   *
+   *
+   * @return a Set of all the keys
+   */
+  public Set<K> keySet();
+
+  /** Returns a Collection of values in this region.
+   *
+   *<p>This <code>Collection</code> is unmodifiable. It is
+   * backed by this region. Synchronization is not necessary to access or
+   * iterate over this collection. No <code>ConcurrentModificationException</code>s
+   * will be thrown, but values may be added or removed to this collection while a thread
+   * is iterating. Iterators are intended to be used by one thread at a time.
+   * If a stable "snapshot" view of the collection is required, then call
+   * one of the toArray methods on the collection and iterate over the array.
+   * If you need to lock down the region so this set is not modified while
+   * it is being accessed, use global scope with a distributed lock on the
+   * region.
+   *
+   * <p>Null values are not included in the result collection.
+   * @return a Collection of all the objects cached in this region
+   */
+  public Collection<V> values();
+
+  /** Returns the <code>Set</code> of <code>Region.Entry</code> objects in this region.
+   * If the recursive parameter is set to true, this call will
+   * recursively collect all the entries
+   * in this region and its subregions and return them in the Set; if false,
+   * it only returns entries directly contained in this region.
+   *
+   *<p>This <code>Set</code> is unmodifiable. It is
+   * backed by this region. Synchronization is not necessary to access or
+   * iterate over this set. No <code>ConcurrentModificationException</code>s
+   * will be thrown, but entries may be added or removed to this set while a thread
+   * is iterating. Iterators are intended to be used by one thread at a time.
+   * If a stable "snapshot" view of the set is required, then call
+   * one of the toArray methods on the set and iterate over the array.
+   * If you need to lock down the region so this set is not modified while
+   * it is being accessed, use global scope with a distributed lock.
+   *
+   * @param recursive if true, this call recursively collects all the
+   * entries in this region and its subregions; if false, it only returns
+   * the entries directly contained in this region
+   * @return a List of all the cached objects
+   *
+   * @deprecated Use <code>entrySet(boolean recursive)</code> instead.
+   * @see Region.Entry
+   */
+  @Deprecated
+  public Set<Region.Entry<?,?>> entries(boolean recursive);
+
+  /** Returns the <code>Set</code> of <code>Region.Entry</code> objects in this region.
+   * If the recursive parameter is set to true, this call will
+   * recursively collect all the entries
+   * in this region and its subregions and return them in the Set; if false,
+   * it only returns entries directly contained in this region.
+   *
+   *<p>This <code>Set</code> is unmodifiable. It is
+   * backed by this region. Synchronization is not necessary to access or
+   * iterate over this set. No <code>ConcurrentModificationException</code>s
+   * will be thrown, but entries may be added or removed to this set while a thread
+   * is iterating. Iterators are intended to be used by one thread at a time.
+   * If a stable "snapshot" view of the set is required, then call
+   * one of the toArray methods on the set and iterate over the array.
+   * If you need to lock down the region so this set is not modified while
+   * it is being accessed, use global scope with a distributed lock.
+   *
+   * @param recursive if true, this call recursively collects all the
+   * entries in this region and its subregions; if false, it only returns
+   * the entries directly contained in this region
+   * @return a Set of all the cached objects
+   * @see Region.Entry
+   */
+  public Set<Region.Entry<?,?>> entrySet(boolean recursive);
+
+  /** Returns the <code>Cache</code> associated with this region.
+   *  <p>Does not throw a <code>CacheClosedException</code> if the Cache is closed.
+   * @return the Cache
+   * @deprecated as of 6.5 use {@link #getRegionService()} instead.
+   */
+  public Cache getCache();
+
+  /**
+   * Returns the <code>cache</code> associated with this region.
+   *  <p>Does not throw a <code>CacheClosedException</code> if the cache is closed.
+   * @return the cache
+   * @since 6.5
+   */
+  public RegionService getRegionService();
+  
+  /**
+   * Returns the application-defined object associated with this region.
+   * GemFire does not use this object for any purpose.
+   *
+   * @return the user attribute object or null if it has not been set
+   */
+  public Object getUserAttribute();
+
+  /** Sets the application-defined object associated with this region.
+   * GemFire does not use this object for any purpose.
+   * @param value the application-defined object
+   */
+  public void setUserAttribute(Object value);
+
+  /** Returns whether this region has been destroyed.
+   *
+   * <p>Does not throw a <code>RegionDestroyedException</code> if this region
+   * has been destroyed.
+   * @return true if this region has been destroyed
+   */
+  public boolean isDestroyed();
+
+  /** Returns whether there is a valid (non-null) value present for the specified
+   * key. This method is equivalent to:
+   * <pre>
+   * Entry e = getEntry(key);
+   * return e != null && e.getValue() != null;
+   * </pre>
+   *
+   * @param key the key to check for a valid value
+   * @return true if there is an entry in this region for the specified key
+   * and it has a valid value
+   */
+  public boolean containsValueForKey(Object key);
+
+  /** Returns whether the specified key currently exists in this region.
+   * This method is equivalent to <code>getEntry(key) != null</code>.
+   *
+   * @param key the key to check for an existing entry
+   * @return true if there is an entry in this region for the specified key
+   */
+  public boolean containsKey(Object key);
+
+
+  /** For {@link Scope#GLOBAL} regions, gets a <em>distributed</em>
+   * lock on this whole region. This region lock
+   * cannot be acquired until all other caches release both region locks and any
+   * entry locks they hold in this region. Likewise, new entry locks cannot be
+   * acquired until outstanding region locks are released.
+   * The only place that a region distributed lock is acquired automatically
+   * is during region creation for distributed {@link DataPolicy#withReplication replicated}
+   * regions when they acquire their initial data.
+   * <p>
+   * The operations invalidateRegion and destroyRegion do <em>not</em>
+   * automatically acquire a distributed lock at all, so it is possible for these
+   * operations to cause an entry to be invalidated or the region to be destroyed
+   * even if a distributed lock is held on an entry. If an application requires
+   * all entry level locks to be released when a region is destroyed or
+   * invalidated as a whole, then it can call this method explicitly to get
+   * a ock on the entire region before calling invalidateRegion or destroyRegion.
+   * <p>
+   * See
+   * {@link #getDistributedLock} for the list of operations that automatically
+   * acquire distributed entry locks for regions with global scope.
+   * <p>
+   * Note that Region locks are potentially very expensive to acquire.
+   *
+   * @return a <code>Lock</code> used for acquiring a distributed lock on the entire region
+   * @throws IllegalStateException if the scope of this region is not global
+   * @throws UnsupportedOperationException If the region is a partitioned region
+   */
+  public Lock getRegionDistributedLock() throws IllegalStateException;
+
+  /** For {@link Scope#GLOBAL} regions, gets a <em>distributed</em>
+   * lock on the entry with the specified key.
+   * Use of this <code>Lock</code> enables an application to synchronize
+   * operations on entries at a higher level than provided for by
+   * {@link Scope#GLOBAL}. This is the same lock that GemFire uses internally
+   * for operations that modify the cache with global scope, so this lock can
+   * be used for high-level synchronization with other caches that have
+   * this region with global scope. For example, if an application needs to
+   * get two values out of a region with global scope and guarantee that the
+   * first value is not modified before the second value is retrieved,
+   * it can use this lock in the following manner:
+   * <pre>
+   * Lock entry1Lock = myRegion.getDistributedLock(key1);
+   * Lock entry2Lock = myRegion.getDistributedLock(key2);
+   * entry1Lock.lock();
+   * entry2Lock.lock();
+   * try {
+   *   Object val1 = myRegion.get(key1);
+   *   Object val2 = myRegion.get(key2);
+   *   // do something with val1 and val2
+   * }
+   * finally {
+   *   entry2Lock.unlock();
+   *   entry1Lock.unlock();
+   * }
+   * </pre>
+   *
+   * You can also get a lock on an entry that does not exist in the local
+   * cache. Doing so guarantees that no other cache with the same
+   * region using global scope or using the same lock will create or update
+   * that entry while you have the lock.
+   *
+   * When a region has global scope, the following operations automatically
+   * acquire a distributed lock on an entry: <code>create</code>,
+   * <code>put</code>, <code>destroy</code>, <code>invalidate</code>,
+   * and <code>get</code> that causes a loader to be invoked.
+   * @return a <code>Lock</code> used for acquiring a distributed lock on an
+   * entry
+   * @throws IllegalStateException if the scope of this region is not global
+   * @throws NullPointerException if key is null
+   * @throws UnsupportedOperationException If the region is a partitioned region
+   */
+  public Lock getDistributedLock(Object key) throws IllegalStateException;
+
+  /**
+   * Initiates a flush to asynchronously write unwritten region entries to disk.
+   *
+   * @throws IllegalStateException
+   *         If this region is not configured to write to disk
+   * @throws DiskAccessException
+   *         If problems are encounter while writing to disk
+   * @throws UnsupportedOperationException If the region is a partitioned region
+   * @see AttributesFactory#setPersistBackup
+   * @since 3.2
+   * @deprecated use {@link DiskStore#flush} instead.
+   */
+  @Deprecated
+  public void writeToDisk();
+
+  /**
+   * Determines whether there is a value in this <code>Region</code>
+   * that matches the given <code>queryPredicate</code>.  Filters the
+   * values of this region using the predicate given as a string with
+   * the syntax of the <code>WHERE</code> clause of the query
+   * language.  The predefined variable <code>this</code> may be used
+   * inside the predicate to denote the current value being filtered.
+   *
+   * @param queryPredicate
+   *            A query language boolean query predicate.
+   *
+   * @return <code>true</code> if there is a value in region that
+   *         matches the predicate, otherwise <code>false</code>.
+   *
+   * @throws QueryInvalidException
+   *         If predicate does not correspond to valid query language
+   *         syntax.
+   *
+   * @see QueryService
+   *
+   * @since 4.0
+   */
+  public boolean existsValue(String queryPredicate)
+  throws FunctionDomainException, TypeMismatchException, NameResolutionException,
+         QueryInvocationTargetException;
+  /**
+   * Filters the values of this region using the <code>queryPredicate</code>.
+   * The queryPredicate should follow the syntax of query WHERE clause.
+   *
+   * When executed from a client, this method always runs on the server.
+   * However application should use QueryService to execute queries.
+   *
+   * When executed from a client, this method always runs on the server. 
+   * However application should use QueryService to execute queries.
+   *
+   * @see Pool#getQueryService
+   * @see Cache#getQueryService()
+   *
+   * @param queryPredicate
+   *            A query language boolean query predicate.
+   *
+   * @return  A <code>SelectResults</code> containing the values of this
+   *            <code>Region</code> that match the
+   *            <code>predicate</code>.
+   *
+   * @throws QueryInvalidException
+   *         If exception occurs during query compilation or processing.
+   *
+   * @see QueryService
+   *
+   * @since 4.0
+   */
+  public <E> SelectResults<E> query(String queryPredicate)
+  throws FunctionDomainException, TypeMismatchException, NameResolutionException,
+         QueryInvocationTargetException;
+
+  /**
+   * Selects the single value in this <code>Region</code> that matches
+   * the given query <code>predicate</code>.
+   * Filters the values of this region using the predicate given as a string
+   * with the syntax of the where clause of the query language.
+   * The predefined variable <code>this</code> may be used inside the predicate
+   * to denote the element currently being filtered.
+   *
+   * @param queryPredicate
+   *            A query language boolean query predicate.
+   *
+   * @return The single element that evaluates to true for the
+   *         predicate. If no value in this <code>Region</code>
+   *         matches the predicate, <code>null</code> is returned.
+   *
+   * @throws QueryInvalidException
+   *         If predicate does not correspond to valid query language
+   *         syntax.
+   * @throws FunctionDomainException
+   *         If more than one element evaluates to true.
+   *
+   * @see QueryService
+   * @since 4.0
+   */
+  public Object selectValue(String queryPredicate)
+  throws FunctionDomainException, TypeMismatchException, NameResolutionException,
+         QueryInvocationTargetException;
+
+  /**
+   * Asks the region to start writing to a new oplog (if persistence/overflow
+   * is turned on). The old one will be asynchronously compressed if compaction is set to true. If the region
+   * is not persistent/overflow no change in the region will be reflected. The new log will
+   * be created in the next available directory with free space. If there is no directory with free space
+   * available and compaction is set to false, then a <code>DiskAccessException</code> saying that the disk is full will be
+   * thrown. If compaction is true, the application will wait for the other oplogs to be compressed and more
+   * space to be created.
+   *
+   * @since 5.1
+   * @throws DiskAccessException
+   * @deprecated use {@link DiskStore#forceRoll} instead.
+   */
+  @Deprecated
+  public void forceRolling();
+  
+  /**
+   * Specifies this member to become the grantor for this region's lock
+   * service.  The grantor will be the lock authority which is responsible
+   * for handling all lock requests for this service.  Other members will
+   * request locks from this member. Locking for this member will be optimal
+   * as it will not require messaging to acquire a given lock.
+   * <p>
+   * Calls to this method will block until grantor authority has been
+   * transferred to this member.
+   * <p>
+   * If another member later calls <code>becomeLockGrantor</code>, that
+   * member will transfer grantor authority from this member to itself.
+   * Multiple calls to this operation will have no effect unless another
+   * member has transferred grantor authority, in which case, this member will
+   * transfer grantor authority back to itself.
+   * <p>
+   * This region's scope must be <code>Scope.GLOBAL</code> to become a lock
+   * grantor.
+   * <p>
+   * This operation should not be invoked repeatedly in an application. It is
+   * possible to create a lock service and have two or more members endlessly
+   * calling becomeLockGrantor to transfer grantorship back and forth.
+   *
+   * @throws IllegalStateException if scope is not GLOBAL
+   * @throws UnsupportedOperationException If the region is a partitioned region
+   *
+   * @since 4.0
+   */
+  public void becomeLockGrantor();
+
+  /**
+   * Removes all local entries from this region. This is not a distributed operation.
+   * This operation is not allowed on replicated regions.
+   *
+   * @since 5.0
+   * @throws UnsupportedOperationException  If the region is a replicated region
+   * @throws UnsupportedOperationException  If the region is a partitioned region
+   * @see CacheListener#afterRegionClear
+   *
+   */
+  public void localClear();
+
+////// Map API's ////
+  /**
+   * Removes all entries from this region. Clear will be distributed to other caches if the scope
+   * is not <code>Scope.LOCAL</code>.
+   * <p>
+   * @since 5.0
+   * @see java.util.Map#clear()
+   * @see CacheListener#afterRegionClear
+   * @see CacheWriter#beforeRegionClear
+   * @throws UnsupportedOperationException If the region is a partitioned region
+   */
+  public void clear();
+
+  /**
+   * Returns true if this region maps one or more keys to the specified value.
+   * More formally, returns true if and only if this region contains at least one
+   * entry to a value v such that (value==null ? v==null : value.equals(v)).
+   * This operation is not distributed and only the current region will be
+   * checked for this value.
+   *
+   * @since 5.0
+   * @see java.util.Map#containsValue(Object)
+   */
+  public boolean containsValue(Object value);
+
+  /**
+   * Returns the <code>Set</code> of <code>Region.Entry</code> objects in this region.
+   *
+   *<p>This <code>Set</code> is unmodifiable. It is
+   * backed by this region. Synchronization is not necessary to access or
+   * iterate over this set. No <code>ConcurrentModificationException</code>s
+   * will be thrown, but entries may be added or removed to this set while a thread
+   * is iterating. Iterators are intended to be used by one thread at a time.
+   * If a stable "snapshot" view of the set is required, then call
+   * one of the toArray methods on the set and iterate over the array.
+   * If you need to lock down the region so this set is not modified while
+   * it is being accessed, use global scope with a distributed lock.
+   *
+   * A remove called on an entry via the iterator will result in an UnsupportedOperationException
+   *
+   *  The Region.Entry obtained via the iterator is backed by the region. If a setValue on
+   *  that entry is called, it will be similar in effect as calling a put on that key.
+   *
+   * @return a Set of all the Region.Entry instances in this region locally
+   * @since 5.0
+   * @see java.util.Map#entrySet()
+   */
+  public Set<Map.Entry<K,V>> entrySet(); //@todo darrel: should be Region.Entry
+
+  /**
+   * Returns true if this region contains no entries.
+   *@since 5.0
+   * @see java.util.Map#isEmpty()
+   * @return true if this region contains no entries.
+   */
+  public boolean isEmpty();
+
+  /**
+   * Copies all of the entries from the specified map to this region.
+   * The effect of this call is equivalent to that of calling {@link #put(Object, Object)} on
+   * this region once for each entry in the specified map.
+   * This operation will be distributed to other caches if the scope
+   * is not <code>Scope.LOCAL</code>.
+   * @param map the key/value pairs to put in this region.
+   * @since 5.0
+   * @see java.util.Map#putAll(Map map)
+   * @throws LowMemoryException if a low memory condition is detected.
+   */
+  public void putAll(Map<? extends K, ? extends V> map);
+
+  /**
+   * Copies all of the entries from the specified map to this region.
+   * The effect of this call is equivalent to that of calling {@link #put(Object, Object, Object)} on
+   * this region once for each entry in the specified map.
+   * This operation will be distributed to other caches if the scope
+   * is not <code>Scope.LOCAL</code>.
+   * @param map the key/value pairs to put in this region.
+   * @param aCallbackArgument a user-defined parameter to pass to callback events
+   *        triggered by this method. May be null. Must be serializable if this operation is distributed.
+   * @since 8.1
+   * @see java.util.Map#putAll(Map map)
+   * @throws LowMemoryException if a low memory condition is detected.
+   */
+  public void putAll(Map<? extends K, ? extends V> map, Object aCallbackArgument);
+
+  /**
+   * Removes all of the entries for the specified keys from this region.
+   * The effect of this call is equivalent to that of calling {@link #destroy(Object)} on
+   * this region once for each key in the specified collection.
+   * If an entry does not exist that key is skipped; EntryNotFoundException is not thrown.
+   * This operation will be distributed to other caches if the scope
+   * is not <code>Scope.LOCAL</code>.
+   * @param keys the keys to remove from this region.
+   * @since 8.1
+   * @see Region#destroy(Object)
+   */
+  public void removeAll(Collection<? extends K> keys);
+  /**
+   * Removes all of the entries for the specified keys from this region.
+   * The effect of this call is equivalent to that of calling {@link #destroy(Object, Object)} on
+   * this region once for each key in the specified collection.
+   * If an entry does not exist that key is skipped; EntryNotFoundException is not thrown.
+   * This operation will be distributed to other caches if the scope
+   * is not <code>Scope.LOCAL</code>.
+   * @param keys the keys to remove from this region.
+   * @param aCallbackArgument a user-defined parameter to pass to callback events
+   *        triggered by this method. May be null. Must be serializable if this operation is distributed.
+   * @since 8.1
+   * @see Region#destroy(Object, Object)
+   */
+  public void removeAll(Collection<? extends K> keys, Object aCallbackArgument);
+  
+  /**
+   * Gets values for all the keys in the input Collection.
+   * If a given key does not exist in the region then that key's value in the
+   * returned map will be <code>null</code>.
+   * <p>
+   * Note that the keys collection should extend K since a load may be done and the
+   * key in that case will be stored in the region. The keys parameter was not changed
+   * to extend K for backwards compatibility.
+   * @param keys A Collection of keys
+   * @return A Map of values for the input keys
+   *
+   * @since 5.7
+   */
+  public Map<K, V> getAll(Collection<?> keys);
+  /**
+   * Gets and returns values for all the keys in the input Collection.
+   * If a given key does not exist in the region then that key's value in the
+   * returned map will be <code>null</code>.
+   * @param <T> the type of the keys passed to getAll
+   * @param keys A Collection of keys
+   * @param aCallbackArgument an argument passed into the CacheLoader if
+   * a loader is used. This same argument will also be subsequently passed
+   * to a CacheWriter if the loader returns a non-null value to be placed in
+   * the cache. Modifications to this argument made in the CacheLoader will
+   * be visible to the CacheWriter even if the loader and the writer are
+   * installed in different cache VMs. It will also be passed to any other
+   * callback events triggered by this method.
+   * May be null. Must be serializable if this operation is distributed.
+   * @return A Map of values for the input keys
+   *
+   * @since 8.1
+   */
+  public <T extends K> Map<T, V> getAll(Collection<T> keys, Object aCallbackArgument);
+
+
+  /**
+   * Removes the entry with the specified key. The operation removes
+   * not only the value but also the key and entry from this region.
+   * Remove will be distributed to other caches if the scope
+   * is not <code>Scope.LOCAL</code>.
+   * <p>
+   * Does not update any <code>CacheStatistics</code>.
+   *
+   * @param key the key of the entry
+   * @return <code>null</code> is returned if an entry for key does not exist
+   *         otherwise the value that was stored locally for the removed entry is returned.
+   *         If the entry was "invalid" then <code>null</code> is returned.
+   *         In some cases <code>null</code> may be returned even
+   *         if a previous value exists. 
+   *         If the region is a client proxy then <code>null</code> is returned.
+   *         If the region is partitioned and the remove is done on a non-primary then <code>null</code> is returned.
+   *         If the value is not currently stored in memory but is on disk
+   *         and if the region does not have cqs
+   *         then <code>null</code> is returned.
+   * @throws NullPointerException if key is null
+   * @throws IllegalArgumentException if key does not meet
+   *         serializability requirements
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out getting distributed lock for Scope.GLOBAL
+   * @throws CacheWriterException if a CacheWriter aborts the operation
+   * @see Region#destroy(Object)
+   * @see CacheListener#afterDestroy
+   * @see CacheWriter#beforeDestroy
+   * @see java.util.Map#remove(Object)
+   *
+   * @since 5.0
+   */
+  public V remove(Object key);
+
+  /**
+   * Returns the number of entries present in this region.
+   * 
+   * For {@link DataPolicy#PARTITION}, this is a distributed operation that
+   * returns the number of entries present in entire region.
+   * 
+   * For all other types of regions, it returns the number of entries present
+   * locally, and it is not a distributed operation.
+   * 
+   * @since 5.0
+   * @see java.util.Map#size()
+   * @return int the number of entries present in this region
+   */
+  public int size();
+  /**
+   *
+   * Compares the specified object with this region for equality.
+   * Regions are only equal to themselves (identity based) so {@link Object#equals} is used.
+   * Note that some other class that implements <code>Map</code> may say that
+   * it is equal to an instance of Region (since Region implements Map)
+   * even though Region will never say that it is equal to that instance.
+   *
+   * @param other Object object to be compared against the this
+   * @return <tt>true</tt> if the specified object is equal to this region.
+   * @see Object#equals
+   */
+  public boolean equals(Object other);
+  /**
+   * Returns the hash code value for this region.  The hash code of a region is
+   * based on identity and uses {@link Object#hashCode}.
+   * @return the hash code value for this region.
+   * @see Object#hashCode()
+   */
+  public int hashCode();
+
+  /**
+   * Sends a request to the CacheServer to register interest in a key for
+   * this client. Updates to this key by other clients will be pushed to
+   * this client by the CacheServer. This method is currently supported
+   * only on clients in a client server topology. This key is first
+   * locally cleared from the client and current value for this
+   * key is inserted into the local cache before this call returns.
+   *
+   * @param key The key on which to register interest. If the key is a
+   * <code>List</code>, then all the keys in the <code>List</code> will
+   * be registered. The key can also be the special token 'ALL_KEYS', which
+   * will register interest in all keys in the region. In effect, this will
+   * cause an update to any key in this region in the CacheServer to be pushed
+   * to the client.
+   *
+   * <p>This method uses the default <code>InterestResultPolicy</code>.</p>
+   *
+   * <p><i>Using 'ALL_KEYS' is the same as calling {@link #registerInterestRegex(String)}
+   * with ".*" as the argument.  This means that all keys any type are
+   * pushed to the client and inserted into the local cache.</i></p>
+   * 
+   * <p>If you locally-destroy a key and your region has concurrency-checks-enabled 
+   * turned off you will not receive invalidation events from your interest subscription 
+   * for that key.  When concurrency-checks-enabled is turned on GemFire will accept 
+   * invalidation and deliver these events to your client cache.</p>
+   * 
+   * @see InterestResultPolicy
+   *
+   * @since 4.2
+   *
+   * @throws UnsupportedOperationException if the region is not configured with a pool name.
+   * @throws SubscriptionNotEnabledException if the region's pool does not have subscriptions enabled.
+   * @throws UnsupportedOperationException if the region is a replicate with distributed scope.
+   */
+  public void registerInterest(K key);
+
+  /**
+   * Sends a request to the CacheServer to register interest in a key for
+   * this client. Updates to this key by other clients will be pushed to
+   * this client by the CacheServer. This method is currently supported
+   * only on clients in a client server topology. This key is first
+   * locally cleared from the client and current value for this
+   * key is inserted into the local cache before this call returns. (if
+   * requested).
+   * 
+   * <p>If you locally-destroy a key and your region has concurrency-checks-enabled 
+   * turned off you will not receive invalidation events from your interest subscription 
+   * for that key.  When concurrency-checks-enabled is turned on GemFire will accept 
+   * invalidation and deliver these events to your client cache.</p>
+   *
+   * @param key The key on which to register interest. If the key is a
+   * <code>List</code>, then all the keys in the <code>List</code> will
+   * be registered. The key can also be the special token 'ALL_KEYS', which
+   * will register interest in all keys in the region. In effect, this will
+   * cause an update to any key in this region in the CacheServer to be pushed
+   * to the client.
+   *
+   * <p><i>Using 'ALL_KEYS' is the same as calling {@link #registerInterestRegex(String)}
+   * with ".*" as the argument.  This means that all keys of any type are
+   * pushed to the client and inserted into the local cache.</i></p>
+   *
+   * @param policy The interest result policy. This can be one of:
+   * <ul>
+   * <li>InterestResultPolicy.NONE - does not initialize the local cache</li>
+   * <li>InterestResultPolicy.KEYS - initializes the local cache with the
+   * keys satisfying the request</li>
+   * <li>InterestResultPolicy.KEYS_VALUES - initializes the local cache with
+   * the keys and current values satisfying the request</li>
+   * </ul>
+   * @throws UnsupportedOperationException if the region is not configured with a pool name.
+   * @throws SubscriptionNotEnabledException if the region's pool does not have subcriptions enabled.
+   * @throws UnsupportedOperationException if the region is a replicate with distributed scope.
+   *
+   * @see InterestResultPolicy
+   *
+   * @since 4.2.3
+   */
+  public void registerInterest(K key, InterestResultPolicy policy);
+
+  /**
+   * Sends a request to the CacheServer to register interest in a regular
+   * expression pattern for this client. Updates to any keys of type {@link String}
+   * satisfying this regular expression by other clients will be pushed to
+   * this client by the CacheServer. This method is currently supported only
+   * on clients in a client server topology. These keys are first
+   * locally cleared from the client and the current values for keys of type  {@link String}
+   * that satisfy the regular expression are inserted into the local cache before this call returns.
+   *
+   * <p>Note that if the <code>regex</code> is <code>".*"</code> then all keys of any type will be pushed to the client.
+   * <p>This method uses the default <code>InterestResultPolicy</code>.</p>
+   *
+   * <p>The regular expression string is compiled using the {@link java.util.regex.Pattern} class.</p>
+   * 
+   * <p>If you locally-destroy a key and your region has concurrency-checks-enabled 
+   * turned off you will not receive invalidation events from your interest subscription 
+   * for that key.  When concurrency-checks-enabled is turned on GemFire will accept 
+   * invalidation and deliver these events to your client cache.</p>
+   *
+   * @param regex The regular expression on which to register interest.
+   *
+   * @throws UnsupportedOperationException if the region is not configured with a pool name.
+   * @throws SubscriptionNotEnabledException if the region's pool does not have subscriptions enabled.
+   * @throws UnsupportedOperationException if the region is a replicate with distributed scope.
+   * @see InterestResultPolicy
+   * @see java.util.regex.Pattern
+   *
+   * @since 4.2.3
+   */
+  public void registerInterestRegex(String regex);
+
+  /**
+   * Sends a request to the CacheServer to register interest in a regular
+   * expression pattern for this client. Updates to any keys of type {@link String}
+   * satisfying this regular expression by other clients will be pushed to
+   * this client by the CacheServer. This method is currently supported only
+   * on clients in a client server topology. These keys are first
+   * locally cleared from the client and the current values for keys of type  {@link String}
+   * that satisfy the regular expression are inserted into the local cache before this call returns.
+   *
+   * <p>The regular expression string is compiled using the {@link java.util.regex.Pattern} class.</p>
+   *
+   * <p>If you locally-destroy a key and your region has concurrency-checks-enabled 
+   * turned off you will not receive invalidation events from your interest subscription 
+   * for that key.  When concurrency-checks-enabled is turned on GemFire will accept 
+   * invalidation and deliver these events to your client cache.</p>
+   *
+   * @param regex The regular expression on which to register interest.
+   * @param policy The interest result policy. This can be one of:
+   * <ul>
+   * <li>InterestResultPolicy.NONE - does not initialize the local cache</li>
+   * <li>InterestResultPolicy.KEYS - initializes the local cache with the
+   * keys satisfying the request</li>
+   * <li>InterestResultPolicy.KEYS_VALUES - initializes the local cache with
+   * the keys and current values satisfying the request</li>
+   * </ul>
+   * @throws UnsupportedOperationException if the region is not configured with a pool name.
+   * @throws SubscriptionNotEnabledException if the region's pool does not have subscriptions enabled.
+   * @throws UnsupportedOperationException if the region is a replicate with distributed scope.
+   *
+   * @see InterestResultPolicy
+   * @see java.util.regex.Pattern
+   *
+   * @since 4.2.3
+   */
+  public void registerInterestRegex(String regex, InterestResultPolicy policy);
+
+  /**
+   * Sends a request to the CacheServer to unregister interest in a key for
+   * this client. Updates to this key by other clients will be no longer be
+   * pushed to this client by the CacheServer. This method is currently
+   * supported only on clients in a client server topology.
+   *
+   * @param key The key on which to register interest. If the key is a
+   * <code>List</code>, then all the keys in the <code>List</code> will
+   * be unregistered.
+   * @throws UnsupportedOperationException if the region is not configured with a pool name.
+   *
+   * @since 4.2
+   */
+  public void unregisterInterest(K key);
+
+  /**
+   * Sends a request to the CacheServer to unregister interest in a regular
+   * expression pattern for this client. Updates to any keys satisfying this
+   * regular expression by other clients will no longer be pushed to this client
+   * by the CacheServer. This method is currently supported only on clients in a
+   * client server topology.
+   *
+   * @param regex The regular expression on which to unregister i

<TRUNCATED>

[23/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EvictionAttributes.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EvictionAttributes.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EvictionAttributes.java
new file mode 100644
index 0000000..04a70aa
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EvictionAttributes.java
@@ -0,0 +1,486 @@
+/*
+ * =========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ * ========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.cache.control.ResourceManager;
+import com.gemstone.gemfire.cache.util.ObjectSizer;
+import com.gemstone.gemfire.internal.cache.EvictionAttributesImpl;
+
+/**
+ * <p>Attributes that describe how a <code>Region</code>'s size is managed through an eviction controller. Eviction
+ * controllers are defined by an {@link com.gemstone.gemfire.cache.EvictionAlgorithm} and a {@link
+ * com.gemstone.gemfire.cache.EvictionAction}. Once a <code>Region</code> is created with an eviction controller, it can
+ * not be removed, however it can be changed through an {@link com.gemstone.gemfire.cache.EvictionAttributesMutator}.
+ *
+ * @author Mitch Thomas
+ * @see com.gemstone.gemfire.cache.AttributesFactory#setEvictionAttributes(EvictionAttributes)
+ * @see com.gemstone.gemfire.cache.AttributesMutator
+ * @since 5.0
+ */
+@SuppressWarnings("serial")
+public abstract class EvictionAttributes implements DataSerializable {
+  /**
+   * The default maximum for {@linkplain EvictionAlgorithm#LRU_ENTRY entry LRU}. Currently <code>900</code> entries.
+   */
+  public static final int DEFAULT_ENTRIES_MAXIMUM = 900;
+  /**
+   * The default maximum for {@linkplain EvictionAlgorithm#LRU_MEMORY memory LRU}. Currently <code>10</code> megabytes.
+   */
+  public static final int DEFAULT_MEMORY_MAXIMUM = 10;
+
+  /**
+   * Creates and returns {@linkplain EvictionAlgorithm#LRU_ENTRY entry LRU} eviction attributes
+   * with default {@linkplain EvictionAction#DEFAULT_EVICTION_ACTION action}
+   * and default {@linkplain #DEFAULT_ENTRIES_MAXIMUM maximum}. 
+   * <p/>
+   * {@link EvictionAttributes} cause regions to evict the least recently used (LRU)
+   * entry once the region reaches a maximum capacity. The entry is either locally destroyed or its value overflows
+   * to disk when evicted.
+   * <p/>
+   * <p/>
+   * This is not supported when replication is enabled.
+   * <p/>
+   * <p/>
+   * For a region with {@link DataPolicy#PARTITION}, the EvictionAttribute <code>maximum</code>, indicates the number of
+   * entries allowed in the region, collectively for its primary buckets and redundant copies for this JVM. Once there
+   * are <code>maximum</code> entries in the region's primary buckets and redundant copies for this JVM, the least
+   * recently used entry will be evicted from the bucket in which the subsequent put takes place.
+   * <p/>
+   * <p/>
+   * If you are using a <code>cache.xml</code> file to create a Cache Region declaratively, you can include the
+   * following to configure a region for eviction
+   * <p/>
+   * <pre>
+   *         &lt;region-attributes&gt;
+   *            &lt;eviction-attributes&gt;
+   *               &lt;lru-entry-count maximum=&quot;900&quot; action=&quot;local-destroy&quot;/&gt;
+   *            &lt;/eviction-attributes&gt;
+   *         &lt;/region-attributes&gt;
+   * </pre>
+   *
+   * @return {@linkplain EvictionAlgorithm#LRU_ENTRY entry LRU} eviction attributes
+   * with default {@linkplain EvictionAction#DEFAULT_EVICTION_ACTION action}
+   * and default {@linkplain #DEFAULT_ENTRIES_MAXIMUM maximum}
+   */
+  public static EvictionAttributes createLRUEntryAttributes() {
+    return new EvictionAttributesImpl().setAlgorithm(
+      EvictionAlgorithm.LRU_ENTRY).setAction(
+      EvictionAction.DEFAULT_EVICTION_ACTION).internalSetMaximum(
+      DEFAULT_ENTRIES_MAXIMUM);
+  }
+
+  /**
+   * Creates and returns {@linkplain EvictionAlgorithm#LRU_ENTRY entry LRU} eviction attributes
+   * with default {@linkplain EvictionAction#DEFAULT_EVICTION_ACTION action}
+   * and given <code>maximumEntries</code>.
+   *
+   * @param maximumEntries the number of entries to keep in the Region
+   * @return {@linkplain EvictionAlgorithm#LRU_ENTRY entry LRU} eviction attributes
+   * with default {@linkplain EvictionAction#DEFAULT_EVICTION_ACTION action}
+   * and <code>maximumEntries</code>
+   * @see #createLRUEntryAttributes()
+   */
+  public static EvictionAttributes createLRUEntryAttributes(int maximumEntries) {
+    return new EvictionAttributesImpl().setAlgorithm(EvictionAlgorithm.LRU_ENTRY).setAction(
+      EvictionAction.DEFAULT_EVICTION_ACTION).internalSetMaximum(maximumEntries);
+  }
+  
+  /**
+   * Creates and returns {@linkplain EvictionAlgorithm#LRU_ENTRY entry LRU} eviction attributes
+   * with default {@linkplain #DEFAULT_ENTRIES_MAXIMUM maximum}
+   * and given <code>evictionAction</code>.
+   *
+   * @param evictionAction the action to perform when evicting an entry
+   * @return {@linkplain EvictionAlgorithm#LRU_ENTRY entry LRU} eviction attributes
+   * with default {@linkplain #DEFAULT_ENTRIES_MAXIMUM maximum}
+   * and given <code>evictionAction</code>
+   * @see #createLRUEntryAttributes()
+   * @since 8.1
+   */
+  public static EvictionAttributes createLRUEntryAttributes(EvictionAction evictionAction) {
+    return new EvictionAttributesImpl().setAlgorithm(EvictionAlgorithm.LRU_ENTRY).setAction(evictionAction)
+      .internalSetMaximum(DEFAULT_ENTRIES_MAXIMUM);
+  }
+
+  /**
+   * Creates and returns {@linkplain EvictionAlgorithm#LRU_ENTRY entry LRU} eviction attributes
+   * with given <code>evictionAction</code>
+   * and given <code>maximumEntries</code>.
+   *
+   * @param maximumEntries the number of entries to keep in the Region
+   * @param evictionAction the action to perform when evicting an entry
+   * @return {@linkplain EvictionAlgorithm#LRU_ENTRY entry LRU} eviction attributes
+   * with given <code>evictionAction</code>
+   * and given <code>maximumEntries</code>
+   * @see #createLRUEntryAttributes()
+   */
+  public static EvictionAttributes createLRUEntryAttributes(int maximumEntries, EvictionAction evictionAction) {
+    return new EvictionAttributesImpl().setAlgorithm(EvictionAlgorithm.LRU_ENTRY).setAction(evictionAction)
+      .internalSetMaximum(maximumEntries);
+  }
+
+  /**
+   * Creates and returns {@linkplain EvictionAlgorithm#LRU_HEAP heap LRU} eviction attributes
+   * with default {@linkplain EvictionAction#DEFAULT_EVICTION_ACTION action}
+   * and default {@linkplain ObjectSizer#DEFAULT sizer}.
+   * <p/>
+   * Heap LRU EvictionAttributes evict the least recently used {@link Region.Entry} when heap usage exceeds the
+   * {@link ResourceManager} eviction heap threshold. If the eviction heap threshold is exceeded the least recently used
+   * {@link Region.Entry}s are evicted.
+   * <p/>
+   * <p/>
+   * With other LRU-based eviction controllers, only cache actions (such as {@link Region#put(Object, Object) puts} and
+   * {@link Region#get(Object) gets}) cause the LRU entry to be evicted. However, with heap LRU, because the JVM's heap may be effected
+   * by more than just the GemFire cache operations, a daemon thread will perform the eviction if no operations are being done
+   * on the region.
+   * <p/>
+   * The eviction attribute's {@linkplain ObjectSizer sizer} is used to estimate how much the heap will be reduced by an
+   * eviction. 
+   * <p/>
+   * When using Heap LRU, the JVM must be launched with the <code>-Xmx</code> and <code>-Xms</code> switches set to the
+   * same values. Many virtual machine implementations have additional JVM switches to control the behavior of the
+   * garbage collector. We suggest that you investigate tuning the garbage collector when using this type of eviction
+   * controller.  A collector that frequently collects is needed to keep our heap usage up to date. In particular, on
+   * the Sun <A href="http://java.sun.com/docs/hotspot/gc/index.html">HotSpot</a> JVM, the
+   * <code>-XX:+UseConcMarkSweepGC</code> flag needs to be set, and <code>-XX:CMSInitiatingOccupancyFraction=N</code>
+   * should be set with N being a percentage that is less than the {@link ResourceManager} eviction heap threshold.
+   * <p/>
+   * The JRockit JVM has similar flags, <code>-Xgc:gencon</code> and <code>-XXgcTrigger:N</code>, which are required if
+   * using this LRU algorithm. Please Note: the JRockit gcTrigger flag is based on heap free, not heap in use like the
+   * GemFire parameter. This means you need to set gcTrigger to 100-N. for example, if your eviction threshold is 30
+   * percent, you will need to set gcTrigger to 70 percent.
+   * <p/>
+   * On the IBM JVM, the flag to get a similar collector is <code>-Xgcpolicy:gencon</code>, but there is no corollary to
+   * the gcTrigger/CMSInitiatingOccupancyFraction flags, so when using this feature with an IBM JVM, the heap usage
+   * statistics might lag the true memory usage of the JVM, and thresholds may need to be set sufficiently high that the
+   * JVM will initiate GC before the thresholds are crossed.
+   * <p/>
+   * If you are using a <code>cache.xml</code> file to create a Cache Region declaratively, you can include the
+   * following to create an LRU heap eviction controller:
+   * <p/>
+   * <pre>
+   *         &lt;region-attributes&gt;
+   *            &lt;eviction-attributes&gt;
+   *               &lt;lru-heap-percentage action=&quot;local-destroy&quot;
+   *            &lt;/eviction-attributes&gt;
+   *         &lt;/region-attributes&gt;
+   * </pre>
+   * <p/>
+   *
+   * @return {@linkplain EvictionAlgorithm#LRU_HEAP heap LRU} eviction attributes
+   * with default {@linkplain EvictionAction#DEFAULT_EVICTION_ACTION action}
+   * and default {@linkplain ObjectSizer#DEFAULT sizer}
+   */
+  public static EvictionAttributes createLRUHeapAttributes() {
+    return new EvictionAttributesImpl()
+      .setAlgorithm(EvictionAlgorithm.LRU_HEAP)
+      .setAction(EvictionAction.DEFAULT_EVICTION_ACTION)
+      .setObjectSizer(ObjectSizer.DEFAULT);
+  }
+
+  /**
+   * Creates and returns {@linkplain EvictionAlgorithm#LRU_HEAP heap LRU} eviction attributes
+   * with default {@linkplain EvictionAction#DEFAULT_EVICTION_ACTION action}
+   * and the given <code>sizer</code>.
+   *
+   * @param sizer the sizer implementation used to determine the size of each entry in this region
+   * @return {@linkplain EvictionAlgorithm#LRU_HEAP heap LRU} eviction attributes
+   * with default {@linkplain EvictionAction#DEFAULT_EVICTION_ACTION action}
+   * and the given <code>sizer</code>
+   * @see #createLRUHeapAttributes()
+   */
+  public static EvictionAttributes createLRUHeapAttributes(final ObjectSizer sizer) {
+    return new EvictionAttributesImpl()
+      .setAlgorithm(EvictionAlgorithm.LRU_HEAP)
+      .setAction(EvictionAction.DEFAULT_EVICTION_ACTION)
+      .setObjectSizer(sizer);
+  }
+
+  /**
+   * Creates and returns {@linkplain EvictionAlgorithm#LRU_HEAP heap LRU} eviction attributes
+   * with the given <code>evictionAction</code>
+   * and given <code>sizer</code>.
+   *
+   * @param sizer the sizer implementation used to determine the size of each entry in this region
+   * @param evictionAction the way in which entries should be evicted
+   * @return {@linkplain EvictionAlgorithm#LRU_HEAP heap LRU} eviction attributes
+   * with the given <code>evictionAction</code>
+   * and given <code>sizer</code>
+   * @see #createLRUHeapAttributes()
+   */
+  public static EvictionAttributes createLRUHeapAttributes(final ObjectSizer sizer, final EvictionAction evictionAction) {
+    return new EvictionAttributesImpl()
+      .setAlgorithm(EvictionAlgorithm.LRU_HEAP)
+      .setAction(evictionAction)
+      .setObjectSizer(sizer);
+  }
+
+  /**
+   * Creates and returns {@linkplain EvictionAlgorithm#LRU_MEMORY memory LRU} eviction attributes
+   * with default {@linkplain EvictionAction#DEFAULT_EVICTION_ACTION action},
+   * default {@linkplain ObjectSizer#DEFAULT sizer},
+   * and default {@linkplain #DEFAULT_MEMORY_MAXIMUM maximum}. 
+   * <p/>
+   * Creates EvictionAttributes for an eviction controller that will remove the least recently used (LRU) entry from a
+   * region once the region reaches a certain byte capacity. Capacity is determined by monitoring the size of entries
+   * added and evicted. Capacity is specified in terms of megabytes. GemFire uses an efficient algorithm to determine
+   * the amount of space a region entry occupies in the JVM. However, this algorithm may not yield optimal results for
+   * all kinds of data. The user may provide his or her own algorithm for determining the size of objects by
+   * implementing an {@link ObjectSizer}.
+   * <p/>
+   * <p/>
+   * For a region with {@link DataPolicy#PARTITION}, the EvictionAttribute <code>maximum</code>, is always equal to
+   * {@link  PartitionAttributesFactory#setLocalMaxMemory(int)  " local max memory "} specified for the {@link
+   * PartitionAttributes}. It signifies the amount of memory allowed in the region, collectively for its primary buckets
+   * and redundant copies for this JVM. It can be different for the same region in different JVMs.
+   * <p/>
+   * If you are using a <code>cache.xml</code> file to create a Cache Region declaratively, you can include the
+   * following to create an LRU memory eviction controller:
+   * <p/>
+   * <pre>
+   *          &lt;region-attributes&gt;
+   *            &lt;eviction-attributes&gt;
+   *               &lt;lru-memory-size maximum=&quot;10&quot; action=&quot;local-destroy&quot;&gt;
+   *                  &lt;class-name&gt;com.foo.MySizer&lt;/class-name&gt;
+   *                  &lt;parameter name=&quot;name&quot;&gt;
+   *                     &lt;string&gt;Super Sizer&lt;/string&gt;
+   *                  &lt;/parameter&gt;
+   *               &lt;/lru-memory-size&gt;
+   *            &lt;/eviction-attributes&gt;
+   *         &lt;/region-attributes&gt;
+   * </pre>
+   *
+   * @return {@linkplain EvictionAlgorithm#LRU_MEMORY memory LRU} eviction attributes
+   * with default {@linkplain EvictionAction#DEFAULT_EVICTION_ACTION action},
+   * default {@linkplain ObjectSizer#DEFAULT sizer},
+   * and default {@linkplain #DEFAULT_MEMORY_MAXIMUM maximum}
+   */
+  public static EvictionAttributes createLRUMemoryAttributes() {
+    return new EvictionAttributesImpl().setAlgorithm(EvictionAlgorithm.LRU_MEMORY).setAction(
+      EvictionAction.DEFAULT_EVICTION_ACTION).internalSetMaximum(DEFAULT_MEMORY_MAXIMUM)
+        .setObjectSizer(ObjectSizer.DEFAULT);
+  }
+
+  /**
+   * Creates and returns {@linkplain EvictionAlgorithm#LRU_MEMORY memory LRU} eviction attributes
+   * with default {@linkplain EvictionAction#DEFAULT_EVICTION_ACTION action},
+   * default {@linkplain ObjectSizer#DEFAULT sizer},
+   * and given <code>maximumMegabytes</code>.
+   * <p/>
+   * <p/>
+   * For a region with {@link DataPolicy#PARTITION}, even if maximumMegabytes are supplied, the EvictionAttribute
+   * <code>maximum</code>, is always set to {@link PartitionAttributesFactory#setLocalMaxMemory(int) " local max memory
+   * "} specified for the {@link PartitionAttributes}.
+   * <p/>
+   *
+   * @param maximumMegabytes the maximum allowed bytes in the Region
+   * @return {@linkplain EvictionAlgorithm#LRU_MEMORY memory LRU} eviction attributes
+   * with default {@linkplain EvictionAction#DEFAULT_EVICTION_ACTION action},
+   * default {@linkplain ObjectSizer#DEFAULT sizer},
+   * and given <code>maximumMegabytes</code>
+   * @see #createLRUMemoryAttributes()
+   */
+  public static EvictionAttributes createLRUMemoryAttributes(int maximumMegabytes) {
+    return new EvictionAttributesImpl().setAlgorithm(EvictionAlgorithm.LRU_MEMORY).setAction(
+      EvictionAction.DEFAULT_EVICTION_ACTION).internalSetMaximum(maximumMegabytes).setObjectSizer(null);
+  }
+
+  /**
+   * Creates and returns {@linkplain EvictionAlgorithm#LRU_MEMORY memory LRU} eviction attributes
+   * with default {@linkplain EvictionAction#DEFAULT_EVICTION_ACTION action},
+   * given <code>sizer</code>,
+   * and given <code>maximumMegabytes</code>.
+   * <p/>
+   * <p>For a region with {@link DataPolicy#PARTITION}, even if maximumMegabytes are supplied, the EvictionAttribute
+   * <code>maximum</code>, is always set to {@link  PartitionAttributesFactory#setLocalMaxMemory(int)  " local max
+   * memory "} specified for the {@link PartitionAttributes}.
+   *
+   * @param maximumMegabytes the maximum allowed bytes in the Region
+   * @param sizer calculates the size in bytes of the key and value for an entry.
+   * @return {@linkplain EvictionAlgorithm#LRU_MEMORY memory LRU} eviction attributes
+   * with default {@linkplain EvictionAction#DEFAULT_EVICTION_ACTION action},
+   * given <code>sizer</code>,
+   * and given <code>maximumMegabytes</code>
+   * @see #createLRUMemoryAttributes()
+   */
+  public static EvictionAttributes createLRUMemoryAttributes(int maximumMegabytes, ObjectSizer sizer) {
+    return new EvictionAttributesImpl().setAlgorithm(EvictionAlgorithm.LRU_MEMORY).setAction(
+      EvictionAction.DEFAULT_EVICTION_ACTION).internalSetMaximum(maximumMegabytes).setObjectSizer(sizer);
+  }
+
+  /**
+   * Creates and returns {@linkplain EvictionAlgorithm#LRU_MEMORY memory LRU} eviction attributes
+   * with the given <code>evictionAction</code>,
+   * given <code>sizer</code>,
+   * and given <code>maximumMegabytes</code>.
+   * <p/>
+   * <p>For a region with {@link DataPolicy#PARTITION}, even if maximumMegabytes are supplied, the EvictionAttribute
+   * <code>maximum</code>, is always set to {@link  PartitionAttributesFactory#setLocalMaxMemory(int)  " local max
+   * memory "} specified for the {@link PartitionAttributes}.
+   *
+   * @param maximumMegabytes the maximum allowed bytes in the Region
+   * @param sizer calculates the size in bytes of the key and value for an entry.
+   * @param evictionAction the action to take when the maximum has been reached.
+   * @return {@linkplain EvictionAlgorithm#LRU_MEMORY memory LRU} eviction attributes
+   * with the given <code>evictionAction</code>,
+   * given <code>sizer</code>,
+   * and given <code>maximumMegabytes</code>
+   * @see #createLRUMemoryAttributes()
+   */
+  public static EvictionAttributes createLRUMemoryAttributes(int maximumMegabytes, ObjectSizer sizer, EvictionAction evictionAction) {
+    return new EvictionAttributesImpl().setAlgorithm(EvictionAlgorithm.LRU_MEMORY).setAction(evictionAction)
+      .internalSetMaximum(maximumMegabytes).setObjectSizer(sizer);
+  }
+
+  /**
+   * Creates and returns {@linkplain EvictionAlgorithm#LRU_MEMORY memory LRU} eviction attributes
+   * with default {@linkplain EvictionAction#DEFAULT_EVICTION_ACTION action},
+   * given <code>sizer</code>,
+   * and default {@linkplain #DEFAULT_MEMORY_MAXIMUM maximum}. 
+   * <p/>
+   * <p>For a region with {@link DataPolicy#PARTITION}, even if maximumMegabytes are supplied, the EvictionAttribute
+   * <code>maximum</code>, is always set to {@link  PartitionAttributesFactory#setLocalMaxMemory(int)  " local max
+   * memory "} specified for the {@link PartitionAttributes}.
+   *
+   * @param sizer calculates the size in bytes of the key and value for an entry.
+   * @return {@linkplain EvictionAlgorithm#LRU_MEMORY memory LRU} eviction attributes
+   * with default {@linkplain EvictionAction#DEFAULT_EVICTION_ACTION action},
+   * given <code>sizer</code>,
+   * and default {@linkplain #DEFAULT_MEMORY_MAXIMUM maximum}
+   * @see #createLRUMemoryAttributes()
+   * @since 6.0
+   */
+  public static EvictionAttributes createLRUMemoryAttributes(ObjectSizer sizer) {
+    return new EvictionAttributesImpl().setAlgorithm(EvictionAlgorithm.LRU_MEMORY).setAction(
+      EvictionAction.DEFAULT_EVICTION_ACTION).setObjectSizer(sizer).internalSetMaximum(
+          DEFAULT_MEMORY_MAXIMUM);
+  }
+
+  /**
+   * Creates and returns {@linkplain EvictionAlgorithm#LRU_MEMORY memory LRU} eviction attributes
+   * with given <code>evictionAction</code>,
+   * given <code>sizer</code>,
+   * and default {@linkplain #DEFAULT_MEMORY_MAXIMUM maximum}. 
+   * <p/>
+   * <p>For a region with {@link DataPolicy#PARTITION}, even if maximumMegabytes are supplied, the EvictionAttribute
+   * <code>maximum</code>, is always set to {@link  PartitionAttributesFactory#setLocalMaxMemory(int)  " local max
+   * memory "} specified for the {@link PartitionAttributes}.
+   *
+   * @param sizer calculates the size in bytes of the key and value for an entry.
+   * @param evictionAction the action to take when the maximum has been reached.
+   * @return {@linkplain EvictionAlgorithm#LRU_MEMORY memory LRU} eviction attributes
+   * with given <code>evictionAction</code>,
+   * given <code>sizer</code>,
+   * and default {@linkplain #DEFAULT_MEMORY_MAXIMUM maximum}
+   * @see #createLRUMemoryAttributes()
+   * @since 6.0
+   */
+  public static EvictionAttributes createLRUMemoryAttributes(ObjectSizer sizer, EvictionAction evictionAction) {
+    return new EvictionAttributesImpl().setAlgorithm(EvictionAlgorithm.LRU_MEMORY).setAction(evictionAction)
+      .setObjectSizer(sizer).internalSetMaximum(DEFAULT_MEMORY_MAXIMUM);
+  }
+
+  /**
+   * An {@link ObjectSizer} is used by the {@link EvictionAlgorithm#LRU_MEMORY} algorithm to measure the size of each
+   * Entry as it is entered into a Region. A default implementation is provided, see {@link
+   * #createLRUMemoryAttributes()} for more.
+   * An {@link ObjectSizer} is used by {@link EvictionAlgorithm#LRU_HEAP} to estimate how much heap will be saved
+   * when evicting a region entry.
+   *
+   * @return the sizer used by {@link EvictionAlgorithm#LRU_MEMORY} or {@link EvictionAlgorithm#LRU_HEAP}, for all other algorithms null is returned.
+   */
+  public abstract ObjectSizer getObjectSizer();
+
+  /**
+   * The algorithm is used to identify entries that will be evicted.
+   *
+   * @return a non-null EvictionAlgorithm instance reflecting the configured value or NONE when no eviction controller
+   *         has been configured.
+   */
+  public abstract EvictionAlgorithm getAlgorithm();
+
+  /**
+   * The unit of this value is determined by the definition of the {@link EvictionAlgorithm} set by one of the creation
+   * methods e.g. {@link EvictionAttributes#createLRUEntryAttributes()}
+   *
+   * @return maximum value used by the {@link EvictionAlgorithm} which determines when the {@link EvictionAction} is
+   *         performed.
+   */
+  public abstract int getMaximum();
+
+  /** @return action that the {@link EvictionAlgorithm} takes when the maximum value is reached. */
+  public abstract EvictionAction getAction();
+
+  @Override
+  public final boolean equals(final Object obj) {
+    if (obj == this) {
+      return true;
+    }
+    if (!(obj instanceof EvictionAttributes)) {
+      return false;
+    }
+    final EvictionAttributes other = (EvictionAttributes) obj;
+    if (!this.getAlgorithm().equals(other.getAlgorithm()) ||
+        !this.getAction().equals(other.getAction())) {
+      return false;
+    }
+    // LRUHeap doesn't support maximum
+    if (!this.getAlgorithm().isLRUHeap() &&
+        this.getMaximum() != other.getMaximum()) {
+      return false;
+    }
+    return true;
+  }
+
+  @Override
+  public final int hashCode() {
+    if (getAlgorithm().isLRUHeap()) {
+      return getAlgorithm().hashCode();
+    } else {
+      return this.getAlgorithm().hashCode() ^ this.getMaximum();
+    }
+  }
+
+  @Override
+  public String toString() {
+    final StringBuilder buffer = new StringBuilder(128);
+    buffer.append(" algorithm=").append(this.getAlgorithm());
+    if (!this.getAlgorithm().isNone()) {
+      buffer.append("; action=").append(this.getAction());
+      if (!getAlgorithm().isLRUHeap()) {
+        buffer.append("; maximum=").append(this.getMaximum());
+      }
+      if (this.getObjectSizer() != null) {
+        buffer.append("; sizer=").append(this.getObjectSizer());
+      }
+    }
+    return buffer.toString();
+  }
+
+  /**
+   * @return an EvictionAttributes for the  LIFOCapacityController
+   * @since 5.7
+   */
+  public static EvictionAttributes createLIFOEntryAttributes(int maximumEntries, EvictionAction evictionAction) {
+    return new EvictionAttributesImpl().setAlgorithm(EvictionAlgorithm.LIFO_ENTRY).setAction(evictionAction)
+      .internalSetMaximum(maximumEntries);
+  }
+
+  /**
+   * @return an EvictionAttributes for the MemLIFOCapacityController
+   * @since 5.7
+   */
+  public static EvictionAttributes createLIFOMemoryAttributes(int maximumMegabytes, EvictionAction evictionAction) {
+    return new EvictionAttributesImpl().setAlgorithm(EvictionAlgorithm.LIFO_MEMORY).setAction(evictionAction)
+      .internalSetMaximum(maximumMegabytes).setObjectSizer(null);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EvictionAttributesMutator.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EvictionAttributesMutator.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EvictionAttributesMutator.java
new file mode 100644
index 0000000..bb0fbfc
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/EvictionAttributesMutator.java
@@ -0,0 +1,31 @@
+package com.gemstone.gemfire.cache;
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+import com.gemstone.gemfire.internal.cache.EvictionAttributesImpl;
+
+/**
+ * The EvictionAttributesMutator allows changes to be made to a 
+ * {@link com.gemstone.gemfire.cache.EvictionAttributes}. It is returned
+ * by {@link com.gemstone.gemfire.cache.AttributesMutator#getEvictionAttributesMutator()}
+ * @author Mitch Thomas
+ * @since 5.0
+ */
+public interface EvictionAttributesMutator
+{
+  /**
+   * Sets the maximum value on the {@link EvictionAttributesImpl} that the given
+   * {@link EvictionAlgorithm} uses to determine when to perform its
+   * {@link EvictionAction}. The unit of the maximum value is determined by the
+   * {@link EvictionAlgorithm}
+   * 
+   * @param maximum
+   *          value used by the {@link EvictionAlgorithm}
+   */
+  public void setMaximum(int maximum);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ExpirationAction.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ExpirationAction.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ExpirationAction.java
new file mode 100644
index 0000000..f2245f4
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ExpirationAction.java
@@ -0,0 +1,114 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+
+package com.gemstone.gemfire.cache;
+
+import java.io.*;
+
+/**
+ * Enumerated type for expiration actions.
+ *
+ * @author Eric Zoerner
+ *
+ *
+ * @see ExpirationAttributes
+ * @since 3.0
+ */
+public class ExpirationAction implements Serializable {
+    private static final long serialVersionUID = 658925707882047900L;
+    
+    /** When the region or cached object expires, it is invalidated. */
+    public final static ExpirationAction INVALIDATE = new ExpirationAction("INVALIDATE");
+    /** When expired, invalidated locally only. Not supported for partitioned regions. */
+    public final static ExpirationAction LOCAL_INVALIDATE = new ExpirationAction("LOCAL_INVALIDATE");
+    
+    /** When the region or cached object expires, it is destroyed. */
+    public final static ExpirationAction DESTROY = new ExpirationAction("DESTROY");
+    /** When expired, destroyed locally only. Not supported for partitioned regions. Use DESTROY instead. */
+    public final static ExpirationAction LOCAL_DESTROY = new ExpirationAction("LOCAL_DESTROY");
+    
+    /** The name of this action */
+    private final transient String name;
+    
+    /** Creates a new instance of ExpirationAction.
+     * 
+     * @param name the name of the expiration action
+     * @see #toString
+     */
+    private ExpirationAction(String name) {
+        this.name = name;
+    }
+    
+    /**
+     * Returns whether this is the action for distributed invalidate.
+     * @return true if this in INVALIDATE
+     */
+    public boolean isInvalidate() {
+      return this == INVALIDATE;
+    }
+    
+    /**
+     * Returns whether this is the action for local invalidate.
+     * @return true if this is LOCAL_INVALIDATE
+     */
+    public boolean isLocalInvalidate() {
+      return this == LOCAL_INVALIDATE;
+    }
+    
+    /** Returns whether this is the action for distributed destroy.
+     * @return true if this is DESTROY
+     */
+    public boolean isDestroy() {
+      return this == DESTROY;
+    }
+    
+    /** Returns whether this is the action for local destroy.
+     * @return true if thisis LOCAL_DESTROY
+     */
+    public boolean isLocalDestroy() {
+      return this == LOCAL_DESTROY;
+    }
+    
+    /** Returns whether this action is local.
+     * @return true if this is LOCAL_INVALIDATE or LOCAL_DESTROY
+     */
+    public boolean isLocal() {
+      return this == LOCAL_INVALIDATE || this == LOCAL_DESTROY;
+    }
+    
+    /** Returns whether this action is distributed.
+     * @return true if this is INVALIDATE or DESTROY
+     */
+    public boolean isDistributed() {
+      return !isLocal();
+    }    
+        
+    /** Returns a string representation for this action
+     * @return the name of this action
+     */
+    @Override
+    public String toString() {
+        return this.name;
+    }
+
+    // The 4 declarations below are necessary for serialization
+    private static int nextOrdinal = 0;
+    public final int ordinal = nextOrdinal++;
+    private static final ExpirationAction[] VALUES =
+      { INVALIDATE, LOCAL_INVALIDATE, DESTROY, LOCAL_DESTROY};
+    private Object readResolve() throws ObjectStreamException {
+      return fromOrdinal(ordinal);  // Canonicalize
+    }
+
+    /** Return the ExpirationAction represented by specified ordinal */
+    public static ExpirationAction fromOrdinal(int ordinal) {
+      return VALUES[ordinal];
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ExpirationAttributes.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ExpirationAttributes.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ExpirationAttributes.java
new file mode 100644
index 0000000..1b64c70
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ExpirationAttributes.java
@@ -0,0 +1,135 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.internal.InternalDataSerializer;
+
+/** Immutable parameter object for accessing and setting the attributes associated with 
+ * <code>timeToLive</code> and <code>idleTimeout</code>. If the expiration
+ * action is not specified, it defaults to <code>ExpirationAction.INVALIDATE</code>.
+ * If the timeout is not specified, it defaults to zero (which means to never timeout).
+ *
+ * @author Eric Zoerner
+ *
+ *
+ * @see AttributesFactory
+ * @see RegionAttributes
+ * @see AttributesMutator
+ * @since 3.0
+ */
+public class ExpirationAttributes implements DataSerializable { 
+  private static final long serialVersionUID = 5956885652945706394L;
+  /** convenience constant for a default instance */
+  public static final ExpirationAttributes DEFAULT = new ExpirationAttributes();
+  
+  /** The number of seconds since this value or region was created before it expires. */  
+  private  int timeout;
+  
+  /** The action that should take place when this object or region expires.
+   */  
+  private  ExpirationAction action;
+
+  /** Constructs a default <code>ExpirationAttributes</code>, which indicates no expiration
+   * will take place.
+   */
+  public ExpirationAttributes() {
+    this.timeout = 0;
+    this.action = ExpirationAction.INVALIDATE;
+  }
+  
+  /** Constructs an <code>ExpirationAttributes</code> with the specified expiration time
+   * and the default expiration action <code>ExpirationAction.INVALIDATE</code>.
+   * @param expirationTime The number of seconds before expiration
+   * @throws IllegalArgumentException if expirationTime is nonpositive
+   */
+  public ExpirationAttributes(int expirationTime) {
+    this.timeout = expirationTime;
+    this.action = ExpirationAction.INVALIDATE;
+  }
+  
+  /** Constructs an <code>ExpirationAttributes</code> with the specified expiration time and
+   * expiration action.
+   * @param expirationTime The number of seconds for a value to live before it expires
+   * @param expirationAction the action to take when the value expires
+   * @throws IllegalArgumentException if expirationTime is nonpositive
+   */
+  public ExpirationAttributes(int expirationTime, ExpirationAction expirationAction) {
+    this.timeout = expirationTime;
+    this.action = expirationAction;
+  }
+  
+
+  /** Returns the number of seconds before a region or value expires.
+   *
+   * @return the relative number of seconds before a region or value expires
+   * or zero if it will never expire
+   */  
+  public int getTimeout() {
+    return this.timeout;
+  }
+  
+  /** Returns the action that should take place when this value or region expires.
+   * 
+   * @return the action to take when expiring
+   */  
+  public ExpirationAction getAction() {
+    return this.action;
+  }
+  
+  @Override
+  public boolean equals(Object obj) {
+    if (!(obj instanceof ExpirationAttributes)) {
+      return false;
+    }
+    ExpirationAttributes ea = (ExpirationAttributes)obj;
+    return this.timeout == ea.timeout && this.action == ea.action;
+  }
+  
+  @Override
+  public int hashCode() {
+    return this.timeout ^ this.action.hashCode();
+  }
+  
+  /** Returns a string representation of this <code>ExpirationAttributes</code>. If the timeout
+   * is zero, returns <code>"NO EXPIRATION"</code>.
+   * @return the String representation of this expiration attribute
+   */
+  @Override
+  public String toString() {
+    if (this.timeout == 0) {
+      return "NO EXPIRATION";
+    }
+    return "timeout: " + this.timeout +  ";action: " + this.action;
+  }
+  
+  public static ExpirationAttributes createFromData(DataInput in)
+      throws IOException, ClassNotFoundException {
+    ExpirationAttributes result = new ExpirationAttributes();
+    InternalDataSerializer.invokeFromData(result, in);
+    return result;
+  }
+
+
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.timeout = in.readInt();
+    this.action = (ExpirationAction)DataSerializer.readObject(in);
+
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    out.writeInt(this.timeout);
+    DataSerializer.writeObject(this.action, out);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/FailedSynchronizationException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/FailedSynchronizationException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/FailedSynchronizationException.java
new file mode 100644
index 0000000..5697e3c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/FailedSynchronizationException.java
@@ -0,0 +1,46 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/** 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
+ * @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);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/FixedPartitionAttributes.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/FixedPartitionAttributes.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/FixedPartitionAttributes.java
new file mode 100644
index 0000000..25bc41f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/FixedPartitionAttributes.java
@@ -0,0 +1,106 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.internal.cache.FixedPartitionAttributesImpl;
+
+/**
+ * Composite date type used to distribute the attributes for a fixed partition.
+ * </p>
+ * 
+ * {@link com.gemstone.gemfire.cache.PartitionAttributes#getFixedPartitionAttributes()}
+ * returns all fixed partitions in Partitioned Region attributes. </p>
+ * {@link com.gemstone.gemfire.cache.PartitionAttributesFactory#addFixedPartitionAttributes(FixedPartitionAttributes)}
+ * configures <code>FixedPartitionAttributes</Code> in
+ * <code>PartitionedRegionAttributes</code> </p>
+ * 
+ * @see com.gemstone.gemfire.cache.PartitionAttributes
+ * @see com.gemstone.gemfire.cache.PartitionAttributesFactory
+ * 
+ * @author kbachhav
+ * @since 6.6
+ */
+
+public abstract class FixedPartitionAttributes {
+  
+  private final static boolean DEFAULT_PRIMARY_STATUS = false;
+  
+  private final static int DEFAULT_NUM_BUCKETS = 1;
+
+  /**
+   * Creates an instance of <code>FixedPartitionAttributes</code>.
+   * 
+   * @param name
+   *          Name of the fixed partition.
+   */
+  final public static FixedPartitionAttributes createFixedPartition(String name) {
+    return new FixedPartitionAttributesImpl().setPartitionName(name).isPrimary(
+        DEFAULT_PRIMARY_STATUS).setNumBuckets(DEFAULT_NUM_BUCKETS);
+  }
+
+  /**
+   * Creates an instance of <code>FixedPartitionAttributes</code>.
+   * 
+   * @param name
+   *          Name of the fixed partition.
+   * @param isPrimary
+   *          True if this member is the primary for the partition.
+   */
+  final public static FixedPartitionAttributes createFixedPartition(
+      String name, boolean isPrimary) {
+    return new FixedPartitionAttributesImpl().setPartitionName(name).isPrimary(
+        isPrimary).setNumBuckets(DEFAULT_NUM_BUCKETS);
+  }
+
+  /**
+   * Creates an instance of <code>FixedPartitionAttributes</code>.
+   * 
+   * @param name
+   *          Name of the fixed partition.
+   * @param isPrimary
+   *          True if this member is the primary for the partition.
+   * @param numBuckets
+   *          Number of buckets allowed for the partition.
+   */
+  final public static FixedPartitionAttributes createFixedPartition(
+      String name, boolean isPrimary, int numBuckets) {
+    return new FixedPartitionAttributesImpl().setPartitionName(name).isPrimary(
+        isPrimary).setNumBuckets(numBuckets);
+  }
+
+  /**
+   * Creates an instance of <code>FixedPartitionAttributes</code>.
+   * 
+   * @param name
+   *          Name of the fixed partition.
+   * @param numBuckets
+   *          Number of buckets allowed for the partition.
+   */
+  final public static FixedPartitionAttributes createFixedPartition(
+      String name, int numBuckets) {
+    return new FixedPartitionAttributesImpl().setPartitionName(name).isPrimary(
+        DEFAULT_PRIMARY_STATUS).setNumBuckets(numBuckets);
+  }
+
+  /**
+   * Returns the name of the fixed partition.
+   */
+  public abstract String getPartitionName();
+
+  /**
+   * Returns whether this member is the primary for the partition.
+   * 
+   * @return True if this member is the primary, false otherwise.
+   */
+  public abstract boolean isPrimary();
+
+  /**
+   * Returns the number of buckets allowed for the partition.
+   */
+  public abstract int getNumBuckets();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/FixedPartitionResolver.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/FixedPartitionResolver.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/FixedPartitionResolver.java
new file mode 100644
index 0000000..4864ccc
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/FixedPartitionResolver.java
@@ -0,0 +1,71 @@
+/*
+ * ========================================================================= 
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved. 
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ * =========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import java.util.Set;
+
+/**
+ * Implementers of interface <code>FixedPartitionResolver</code> helps to
+ * achieve explicit mapping of a "user defined" partition to a data member node.
+ * <p>
+ * GemFire uses the partition name returned by {@link FixedPartitionResolver#getPartitionName(EntryOperation, Set)} to determine on
+ * which member the data is being managed. Say, for example, you want to
+ * partition all Trades according to quarters. You can implement
+ * FixedPartitionResolver to get the name of the quarter based on the date given
+ * as part of {@link com.gemstone.gemfire.cache.EntryOperation}.
+ * </p>
+ * 
+ * public class QuarterPartitionResolver implements FixedPartitionResolver{<br>
+ * &nbsp &nbsp public String getPartitionName(EntryOperation opDetails, Set
+ * allAvailablePartitions) {<br>
+ * &nbsp &nbsp Date date = sdf.parse((String)opDetails.getKey());<br>
+ * &nbsp &nbsp Calendar cal = Calendar.getInstance();<br>
+ * &nbsp &nbsp cal.setTime(date);<br>
+ * &nbsp &nbsp int month = cal.get(Calendar.MONTH);<br>
+ * &nbsp &nbsp if (month == 0 || month == 1 || month == 2) {<br>
+ * &nbsp &nbsp &nbsp return "Quarter1";<br>
+ * &nbsp &nbsp }<br>
+ * &nbsp &nbsp else if (month == 3 || month == 4 || month == 5) {<br>
+ * &nbsp &nbsp &nbsp return "Quarter2";<br>
+ * &nbsp &nbsp }<br>
+ * &nbsp &nbsp else if (month == 6 || month == 7 || month == 8) {<br>
+ * &nbsp &nbsp &nbsp return "Quarter3";<br>
+ * &nbsp &nbsp }<br>
+ * &nbsp &nbsp else if (month == 9 || month == 10 || month == 11) {<br>
+ * &nbsp &nbsp &nbsp return "Quarter4";<br>
+ * &nbsp &nbsp }<br>
+ * &nbsp &nbsp else {<br>
+ * &nbsp &nbsp &nbsp return "Invalid Quarter";<br>
+ * &nbsp &nbsp }<br>
+ * &nbsp }<br>
+ *
+ * @see PartitionResolver
+ * @author kbachhav
+ * @since 6.6
+ *
+ * 
+ */
+public interface FixedPartitionResolver<K, V> extends PartitionResolver<K, V> {
+
+  /**
+   * This method is used to get the name of the partition for the given entry
+   * operation.
+   * 
+   * @param opDetails
+   *          the details of the entry operation e.g. {@link Region#get(Object)}
+   * @param targetPartitions
+   *           Avoid using this parameter.This set is deprecated from 8.0 and same will be removed in future release.
+   *           Represents all the available primary partitions on the nodes.
+   * 
+   * @return partition-name associated with node which allows mapping of given
+   *         data to user defined partition
+   */
+  public String getPartitionName(EntryOperation<K, V> opDetails,
+      @Deprecated Set<String> targetPartitions);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/GatewayConfigurationException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/GatewayConfigurationException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/GatewayConfigurationException.java
new file mode 100644
index 0000000..e0c0d80
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/GatewayConfigurationException.java
@@ -0,0 +1,36 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+
+/**
+ * An exception indicating that a gateway configuration
+ * will not work with the remote side of the gateway's configuration.
+ * @since 6.6
+ */
+public class GatewayConfigurationException extends GatewayException {
+
+  public GatewayConfigurationException() {
+    super();
+  }
+
+  public GatewayConfigurationException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+
+  public GatewayConfigurationException(String msg) {
+    super(msg);
+  }
+
+  public GatewayConfigurationException(Throwable cause) {
+    super(cause);
+  }
+
+  
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/GatewayException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/GatewayException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/GatewayException.java
new file mode 100755
index 0000000..1ae62da
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/GatewayException.java
@@ -0,0 +1,59 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/**
+ * An exception thrown by a <code>Gateway</code>.
+ *
+ * @author Barry Oglesby
+ *
+ * @since 4.2
+ */
+public class GatewayException extends OperationAbortedException {
+private static final long serialVersionUID = 8090143153569084886L;
+
+  /**
+   * Constructor.
+   * Creates a new instance of <code>GatewayException</code>.
+   */
+  public GatewayException() {
+  }
+
+  /**
+   * Constructor.
+   * Creates an instance of <code>GatewayException</code> with the
+   * specified detail message.
+   * @param msg the detail message
+   */
+  public GatewayException(String msg) {
+    super(msg);
+  }
+
+  /**
+   * Constructor.
+   * Creates an instance of <code>GatewayException</code> with the
+   * specified detail message
+   * and cause.
+   * @param msg the detail message
+   * @param cause the causal Throwable
+   */
+  public GatewayException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+
+  /**
+   * Constructor.
+   * Creates an instance of <code>GatewayException</code> with the
+   * specified cause.
+   * @param cause the causal Throwable
+   */
+  public GatewayException(Throwable cause) {
+    super(cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/GemFireCache.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/GemFireCache.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/GemFireCache.java
new file mode 100644
index 0000000..4ed4dfb
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/GemFireCache.java
@@ -0,0 +1,254 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.naming.Context;
+
+import com.gemstone.gemfire.LogWriter;
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.client.ClientCacheFactory;
+import com.gemstone.gemfire.cache.control.ResourceManager;
+import com.gemstone.gemfire.cache.wan.GatewaySenderFactory;
+import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.pdx.PdxSerializer;
+
+/**
+ * GemFireCache represents the singleton cache that must be created
+ * in order to use GemFire in a Java virtual machine.
+ * Users must create either a {@link Cache} for a peer/server JVM
+ * or a {@link ClientCache} for a client JVM.
+ * Instances of this interface are created using one of the following methods:
+ * <ul>
+ * <li> {@link CacheFactory#create()} creates a peer/server instance of {@link Cache}.
+ * <li> {@link ClientCacheFactory#create()} creates a client instance of {@link ClientCache}.
+ * </ul>
+ *
+ * @since 6.5
+ * @author darrel
+ */
+public interface GemFireCache extends RegionService {
+  /** Returns the name of this cache.
+   * This method does not throw
+   * <code>CacheClosedException</code> if the cache is closed.
+   * @return the String name of this cache
+   */
+  public String getName();
+  /**
+   * Returns the distributed system used by this cache.
+   * This method does not throw
+   * <code>CacheClosedException</code> if the cache is closed.
+   */
+  public DistributedSystem getDistributedSystem();
+  /**
+   * Returns the <code>ResourceManager</code> for managing this cache's 
+   * resources.
+   * 
+   * @return <code>ResourceManager</code> for managing this cache's resources
+   * @since 6.0
+   */
+  public ResourceManager getResourceManager();
+
+  /**
+   * Sets the "copy on read" feature for cache read operations.
+   *
+   * @since 4.0
+   */
+  public void setCopyOnRead(boolean copyOnRead);
+
+  /**
+   * Indicates whether the "copy on read" is enabled for this cache.
+   * 
+   * @return true if "copy on read" is enabled, false otherwise.
+   *
+   * @since 4.0
+   */
+  public boolean getCopyOnRead();
+
+  /**
+   * Returns the <code>RegionAttributes</code> with the given
+   * <code>id</code> or <code>null</code> if no
+   * <code>RegionAttributes</code> with that id exists.
+   *
+   * @see #setRegionAttributes
+   *
+   * @since 4.1
+   */
+  public <K,V> RegionAttributes<K,V> getRegionAttributes(String id);
+
+  /**
+   * Sets the <code>id</code> of the given
+   * <code>RegionAttributes</code>.  If a region attributes named
+   * <code>name</code> already exists, the mapping will be overwritten
+   * with <code>attrs</code>.  However, changing the mapping will not
+   * effect existing regions.
+   *
+   * @param id
+   *        The id of the region attributes
+   * @param attrs
+   *        The attributes to associate with <code>id</code>.  If
+   *        <code>attrs</code> is <code>null</code>, any existing
+   *        <code>RegionAttributes</code> associated with
+   *        <code>id</code> will be removed.
+   *
+   * @see #getRegionAttributes
+   *
+   * @since 4.1
+   */
+  public <K,V> void setRegionAttributes(String id, RegionAttributes<K,V> attrs);
+
+  /**
+   * Returns an unmodifiable mapping of ids to region attributes.  The
+   * keys of the map are {@link String}s and the values of the map are
+   * {@link RegionAttributes}.
+   *
+   * @since 4.1
+   */
+  public <K,V> Map<String, RegionAttributes<K,V>> listRegionAttributes();
+
+  /**
+   * Loads the cache configuration described in a <a
+   * href="package-summary.html#declarative">declarative caching XML
+   * file</a> into this cache.  If the XML describes a region that
+   * already exists, any mutable region attributes, indexes, and
+   * region entries that are defined in the XML are updated/added.
+   *
+   * <P>
+   *
+   * Because this method may perform a {@link Region#put(Object, Object) put} on a
+   * <code>Region</code>, it declares that it throws a
+   * <code>TimeoutException</code>, <code>CacheWriterException</code>,
+   * <code>GatewayException</code>,
+   * or <code>RegionExistsException</code>.
+   *
+   * @throws CacheXmlException
+   *         If the XML read from <code>is</code> does not conform to
+   *         the dtd or if an <code>IOException</code> occurs while
+   *         reading the XML.
+   *
+   * @since 4.1
+   */
+  public void loadCacheXml(InputStream is) 
+    throws TimeoutException, CacheWriterException,
+           GatewayException,
+           RegionExistsException;
+
+  /**
+   * Gets the logging object for GemFire.
+   * This method does not throw
+   * <code>CacheClosedException</code> if the cache is closed.
+   * @return the logging object
+   */
+  public LogWriter getLogger();
+
+  /**
+   * Gets the security logging object for GemFire.
+   * This method does not throw
+   * <code>CacheClosedException</code> if the cache is closed.
+   * @return the security logging object
+   */
+  public LogWriter getSecurityLogger();
+
+  /**
+   * Returns the DiskStore by name or <code>null</code> if no disk store is found.
+   * @param name the name of the disk store to find. If <code>null</code> then the
+   * default disk store, if it exists, is returned.
+   * @since 6.5
+   */
+  public DiskStore findDiskStore(String name);
+  
+  /**
+   * create diskstore factory 
+   * 
+   * @since 6.5
+   */
+  public DiskStoreFactory createDiskStoreFactory();
+  
+  public GatewaySenderFactory createGatewaySenderFactory();
+  
+  /**
+   * Returns whether { @link PdxInstance} is preferred for PDX types instead of Java object.
+   * @see com.gemstone.gemfire.cache.CacheFactory#setPdxReadSerialized(boolean)
+   * @see com.gemstone.gemfire.cache.client.ClientCacheFactory#setPdxReadSerialized(boolean)
+   * 
+   * @since 6.6
+   */
+  public boolean getPdxReadSerialized();
+  
+  /**
+   * Returns the PdxSerializer used by this cache, or null
+   * if no PDX serializer is defined.
+   * 
+   * @since 6.6
+   * @see CacheFactory#setPdxSerializer(PdxSerializer)
+   * @see ClientCacheFactory#setPdxSerializer(PdxSerializer)
+   */
+  public PdxSerializer getPdxSerializer();
+  
+  /**
+   * Returns the disk store used for PDX meta data
+   * @since 6.6
+   * @see CacheFactory#setPdxDiskStore(String)
+   * @see ClientCacheFactory#setPdxDiskStore(String)
+   */
+  public String getPdxDiskStore();
+  
+  /**
+   * Returns true if the PDX metadata for this
+   * cache is persistent
+   * @since 6.6
+   * @see CacheFactory#setPdxPersistent(boolean)
+   * @see ClientCacheFactory#setPdxPersistent(boolean)
+   */
+  public boolean getPdxPersistent();
+  /**
+   * Returns true if fields that are not read during PDX deserialization
+   * should be ignored during the PDX serialization.
+   * @since 6.6
+   * @see CacheFactory#setPdxIgnoreUnreadFields(boolean)
+   * @see ClientCacheFactory#setPdxIgnoreUnreadFields(boolean)
+   */
+  public boolean getPdxIgnoreUnreadFields();
+  /**
+   * Get the CacheTransactionManager instance for this Cache.
+   *
+   * @return The CacheTransactionManager instance.
+   *
+   * @throws CacheClosedException if the cache is closed.
+   *
+   * @since 4.0
+   */
+  public CacheTransactionManager getCacheTransactionManager();
+  /**
+   * Returns the JNDI context associated with the Cache.
+   * @return javax.naming.Context
+   * Added as part of providing JTA implementation in Gemfire.
+   *
+   * @since 4.0
+   */
+  public Context getJNDIContext();
+
+  /**
+   * Returns the Declarable used to initialize this cache or <code>null</code>
+   * if it does not have an initializer.
+   * @since 6.6
+   */
+  public Declarable getInitializer();
+
+  /**
+   * Returns the Properties used to initialize the cache initializer or
+   * <code>null</code> if no initializer properties exist.
+   * @since 6.6
+   */
+  public Properties getInitializerProps();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/IncompatibleVersionException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/IncompatibleVersionException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/IncompatibleVersionException.java
new file mode 100755
index 0000000..27bdb25
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/IncompatibleVersionException.java
@@ -0,0 +1,39 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * An <code>IncompatibleVersionException</code> that the client version
+ * was not compatible with the server version.
+ *
+ * @since 5.7
+ */
+public class IncompatibleVersionException extends VersionException {
+private static final long serialVersionUID = 668812986092856749L;
+
+  /**
+   * Constructs a new <code>IncompatibleVersionException</code>.
+   *
+   * @param clientVersion The client <code>Version</code>
+   * @param serverVersion The server <code>Version</code>
+   */
+  public IncompatibleVersionException(Object/*Version*/ clientVersion,
+      Object/*Version*/ serverVersion) {
+    this("Client version " + clientVersion
+        + " is incompatible with server version " + serverVersion);
+  }
+
+  /**
+   * Constructs a new <code>IncompatibleVersionException</code>.
+   *
+   * @param message The exception message
+   */
+  public IncompatibleVersionException(String message) {
+    super(message);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/InterestPolicy.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/InterestPolicy.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/InterestPolicy.java
new file mode 100644
index 0000000..f066c82
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/InterestPolicy.java
@@ -0,0 +1,140 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+
+package com.gemstone.gemfire.cache;
+import java.io.*;
+
+/**
+ * Enumerated type for region subscription interest policy.
+ * The interest policy specifies what data a subscriber is interested in having
+ * in it's region.
+ *
+ * @author Darrel Schneider
+ *
+ *
+ * @see SubscriptionAttributes
+ *
+ * @since 5.0
+ */
+public class InterestPolicy implements java.io.Serializable {
+  private static final long serialVersionUID = 1567179436331385968L;
+
+  private static byte nextOrdinal = 0;
+    
+  private static final InterestPolicy[] VALUES = new InterestPolicy[2];
+
+  /**
+   * This subscriber is interested in all data.
+   * More specifically operations done in this cache and
+   * distributed operations done in remote caches.
+   * <p>
+   * When combined with {@link DataPolicy#EMPTY} this region will receive
+   * events for every distributed operation but will not store the data.
+   * <p>
+   * When combined with {@link DataPolicy#NORMAL} or
+   * {@link DataPolicy#PRELOADED} this region will accept
+   * {@link Region#create(Object, Object)} operations done remotely. Without
+   * the <code>ALL</code> interest policy, <code>NORMAL</code> and
+   * <code>PRELOADED</code> ignore <code>creates</code> that the region
+   * does  not have an existing entry for.
+   * <p>
+   * When combined with the {@link DataPolicy#withReplication replication
+   * policies} this interest has no effect.
+   * <p>
+   * When combined with {@link DataPolicy#PARTITION} this interest policy
+   * causes cache listeners to be notified of changes regardless of the
+   * physical location of the data affected.  That is, a listener in a VM
+   * using this policy will receive notification of all changes to the
+   * partitioned region.
+   */
+  public static final InterestPolicy ALL = new InterestPolicy("ALL");
+
+  /**
+   * This subscriber is interested in data that is already in its cache.
+   * More specifically operations done in this cache and
+   * distributed operations done in remote caches.
+   * <p>
+   * When combined with {@link DataPolicy#EMPTY} this region will never
+   * receive events for distributed operations since its content is always
+   * empty.  It will continue to get events for operations done locally.
+   * <p>
+   * When combined with {@link DataPolicy#NORMAL} or
+   * {@link DataPolicy#PRELOADED} this region will accept remote operations
+   * done to entries it already has in its cache.
+   * <p>
+   * When combined with the {@link DataPolicy#withReplication replication
+   * policies} * this interest has no effect.
+   * <p>
+   * When combined with {@link DataPolicy#PARTITION} this interest policy
+   * causes cache listeners to be notified in the VM holding the affected data.
+   *  That is, listeners are only notified if the affected* key-value pair is
+   * in the same process as the listener.
+   */
+  public static final InterestPolicy CACHE_CONTENT = new InterestPolicy("CACHE_CONTENT");
+
+  /**
+   * The interest policy used by default; it is {@link #CACHE_CONTENT}.
+   */
+  public static final InterestPolicy DEFAULT = CACHE_CONTENT;
+
+    
+  /** The name of this mirror type. */
+  private final transient String name;
+    
+  /** used as ordinal to represent this InterestPolicy */
+  public final byte ordinal;
+
+  private Object readResolve() throws ObjectStreamException {
+    return VALUES[ordinal];  // Canonicalize
+  }
+    
+    
+  /** Creates a new instance of InterestPolicy. */
+  private InterestPolicy(String name) {
+    this.name = name;
+    this.ordinal = nextOrdinal++;
+    VALUES[this.ordinal] = this;
+  }
+    
+  /** Return the InterestPolicy represented by specified ordinal */
+  public static InterestPolicy fromOrdinal(byte ordinal) {
+    return VALUES[ordinal];
+  }
+    
+    
+  /**
+   * Return true if this policy is {@link #ALL}.
+   * @return true if this policy is {@link #ALL}.
+   */
+  public boolean isAll() {
+    return this == ALL;
+  }
+  /**
+   * Return true if this policy is {@link #CACHE_CONTENT}.
+   * @return true if this policy is {@link #CACHE_CONTENT}.
+   */
+  public boolean isCacheContent() {
+    return this == CACHE_CONTENT;
+  }
+  /**
+   * Return true if this policy is the default.
+   * @return true if this policy is the default.
+   */
+  public boolean isDefault() {
+    return this == DEFAULT;
+  }
+  
+  /** Returns a string representation for this interest policy.
+     * @return the name of this interest policy.
+     */
+  @Override
+  public String toString() {
+    return this.name;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/InterestRegistrationEvent.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/InterestRegistrationEvent.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/InterestRegistrationEvent.java
new file mode 100755
index 0000000..187bc33
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/InterestRegistrationEvent.java
@@ -0,0 +1,83 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import java.util.Set;
+
+import com.gemstone.gemfire.internal.cache.tier.InterestType;
+
+/**
+ * Interface <code>InterestRegistrationEvent</code> encapsulated interest
+ * event information like region and keys of interest.
+ *
+ * @author Barry Oglesby
+ * @since 6.0
+ */
+public interface InterestRegistrationEvent {
+
+  /**
+   * Returns the name of the region to which this interest event belongs.
+   *
+   * @return the name of the region to which this interest event belongs
+   */
+  public String getRegionName();
+  
+  /**
+   * Returns the region to which this interest belongs.
+   * 
+   * @return the region to which this interest belongs
+   */
+  public Region<?,?> getRegion(); 
+
+  /**
+   * Returns a <code>Set</code> of keys of interest.
+   * 
+   * @return a <code>Set</code> of keys of interest
+   */
+  public Set<?> getKeysOfInterest();
+
+  /**
+   * Returns this event's interest type.
+   *
+   * @return this event's interest type
+   */
+  public int getInterestType();
+
+  /**
+   * Returns whether this event represents a register interest.
+   *
+   * @return whether this event represents a register interest
+   */
+  public boolean isRegister();
+
+  /**
+   * Returns whether this event's interest type is
+   * {@link InterestType#KEY}.
+   *
+   * @return whether this event's interest type is
+   *         {@link InterestType#KEY}
+   */
+  public boolean isKey();
+
+  /**
+   * Returns whether this event's interest type is
+   * {@link InterestType#REGULAR_EXPRESSION}.
+   *
+   * @return whether this event's interest type is
+   *         {@link InterestType#REGULAR_EXPRESSION}
+   */
+  public boolean isRegularExpression();
+  
+  /** 
+   * Returns the {@link ClientSession} that initiated this event 
+   *  
+   * @return the {@link ClientSession} that initiated this event 
+   */ 
+  public ClientSession getClientSession(); 
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/InterestRegistrationListener.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/InterestRegistrationListener.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/InterestRegistrationListener.java
new file mode 100755
index 0000000..3a0f509
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/InterestRegistrationListener.java
@@ -0,0 +1,75 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/**
+ * Interface <code>InterestRegisterationListener</code> provides the ability for
+ * applications to be notified of interest registration and unregistration
+ * events. Instances must be implemented by applications and registered in
+ * <code>CacheServer</code> VMs using the
+ * {@link com.gemstone.gemfire.cache.server.CacheServer#registerInterestRegistrationListener
+ * registerInterestRegistrationListener} API. The methods on an
+ * <code>InterestRegisterationListener</code> are invoked synchronously with the
+ * interest event in any <code>CacheServer</code> VM hosting the requesting
+ * client's subscriptions.
+ *
+ * <p>Shown below is an example implementation.
+ *
+ * <pre>
+ *import com.gemstone.gemfire.cache.InterestRegistrationEvent;
+ *import com.gemstone.gemfire.cache.InterestRegistrationListener;
+ *
+ *public class TestInterestRegistrationListener implements InterestRegistrationListener {
+ *
+ *  public void afterRegisterInterest(InterestRegistrationEvent event) {
+ *    System.out.println("afterRegisterInterest: " + event.getRegionName() + " -> " + event.getKeysOfInterest());
+ *  }
+
+ *  public void afterUnregisterInterest(InterestRegistrationEvent event) {
+ *    System.out.println("afterUnregisterInterest: " + event.getRegionName() + " -> " + event.getKeysOfInterest());
+ *  }
+ *
+ *  public void close() {}
+ *}
+ * </pre>
+ *
+ * Shown below is an example registration.
+ *
+ * <pre>
+ *private void registerInterestRegistrationListener() {
+ *  Cache cache = ...;
+ *  CacheServer cs = cache.getCacheServers().iterator().next();
+ *  InterestRegistrationListener listener = new TestInterestRegistrationListener();
+ *  cs.registerInterestRegistrationListener(listener);
+ *}
+ * </pre>
+ *
+ * @author Barry Oglesby
+ *
+ * @since 6.0
+ * 
+ * @see com.gemstone.gemfire.cache.server.CacheServer#registerInterestRegistrationListener registerInterestRegistrationListener
+ * @see com.gemstone.gemfire.cache.server.CacheServer#unregisterInterestRegistrationListener unregisterInterestRegistrationListener
+ */
+public interface InterestRegistrationListener extends CacheCallback {
+
+  /**
+   * Handles an after register interest event.
+   *
+   * @param event the InterestRegistrationEvent
+   */
+  public void afterRegisterInterest(InterestRegistrationEvent event);
+
+  /**
+   * Handles an after unregister interest event.
+   *
+   * @param event the InterestRegistrationEvent
+   */
+  public void afterUnregisterInterest(InterestRegistrationEvent event);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/InterestResultPolicy.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/InterestResultPolicy.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/InterestResultPolicy.java
new file mode 100755
index 0000000..38bf314
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/InterestResultPolicy.java
@@ -0,0 +1,113 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.internal.cache.tier.sockets.InterestResultPolicyImpl;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+/**
+ * Class <code>InterestResultPolicy</code> is an enumerated type for a
+ * register interest result. The result of a call to Region.registerInterest
+ * can be the keys and current values, just the keys or nothing.
+ *
+ * @author Barry Oglesby
+ *
+ * @see com.gemstone.gemfire.cache.Region#registerInterest(Object)
+ * @see com.gemstone.gemfire.cache.Region#registerInterestRegex(String)
+ *
+ * @since 4.2.3
+ */
+public class InterestResultPolicy implements Serializable {
+  private static final long serialVersionUID = -4993765891973030160L;
+
+  private static byte nextOrdinal = 0;
+
+  private static final InterestResultPolicy[] VALUES = new InterestResultPolicy[3];
+
+  public static final InterestResultPolicy NONE = new InterestResultPolicyImpl("NONE");
+  public static final InterestResultPolicy KEYS = new InterestResultPolicyImpl("KEYS");
+  public static final InterestResultPolicy KEYS_VALUES = new InterestResultPolicyImpl("KEYS_VALUES");
+
+  /**
+   * The <code>InterestResultPolicy</code> used by default; it is {@link #KEYS_VALUES}.
+   */
+  public static final InterestResultPolicy DEFAULT = KEYS_VALUES;
+
+
+  /** The name of this <code>InterestResultPolicy</code>. */
+  private final transient String name;
+
+  /** The ordinal representing this <code>InterestResultPolicy</code>. */
+  public final byte ordinal;
+
+  protected Object readResolve() throws ObjectStreamException {
+    return VALUES[ordinal];  // Canonicalize
+  }
+
+
+  /** should only be called from InterestResultPolicyImpl */
+  protected InterestResultPolicy(String name) {
+    this.name = name;
+    this.ordinal = nextOrdinal++;
+    VALUES[this.ordinal] = this;
+  }
+
+  /** Returns the <code>InterestResultPolicy</code> represented by specified ordinal */
+  public static InterestResultPolicy fromOrdinal(byte ordinal) {
+    return VALUES[ordinal];
+  }
+  /** Returns the ordinal value.
+   * @since 5.0
+   */
+  public byte getOrdinal() {
+    return this.ordinal;
+  }
+
+  /**
+   * Returns true if this <code>InterestResultPolicy</code> is {@link #NONE}.
+   * @return true if this <code>InterestResultPolicy</code> is {@link #NONE}.
+   */
+  public boolean isNone() {
+    return this == NONE;
+  }
+
+  /**
+   * Returns true if this <code>InterestResultPolicy</code> is {@link #KEYS}.
+   * @return true if this <code>InterestResultPolicy</code> is {@link #KEYS}.
+   */
+  public boolean isKeys() {
+    return this == KEYS;
+  }
+
+  /**
+   * Returns true if this <code>InterestResultPolicy</code> is {@link #KEYS_VALUES}.
+   * @return true if this <code>InterestResultPolicy</code> is {@link #KEYS_VALUES}.
+   */
+  public boolean isKeysValues() {
+    return this == KEYS_VALUES;
+  }
+
+  /**
+   * Returns true if this <code>InterestResultPolicy</code> is the default.
+   * @return true if this <code>InterestResultPolicy</code> is the default.
+   */
+  public boolean isDefault() {
+    return this == DEFAULT;
+  }
+
+  /** Returns a string representation for this <code>InterestResultPolicy</code>.
+   * @return the name of this data policy.
+   */
+  @Override // GemStoneAddition
+  public String toString() {
+    return this.name;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/LoaderHelper.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/LoaderHelper.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/LoaderHelper.java
new file mode 100644
index 0000000..b2cdb2f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/LoaderHelper.java
@@ -0,0 +1,72 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/** Provides a set of APIs to help the
+ * implementation of the <code>CacheLoader</code> load method. An instance of <code>LoaderHelper</code>
+ * is only valid within the {@link CacheLoader#load(LoaderHelper) load}
+ * method.
+ *
+ * @author Dave Monnie
+ *
+ * @see CacheLoader#load(LoaderHelper) load
+ * @since 2.0
+ */
+public interface LoaderHelper<K,V>
+{
+  /** Searches other caches for the value to be loaded. If the cache
+   * is part of a distributed caching system, <code>netSearch</code>
+   * will try to locate the requested value in any other cache within
+   * the system.  If the search is successful, a reference to a local
+   * copy of the value is returned. If there is no value for this
+   * entry present in the system, and doNetLoad is true, GemFire looks
+   * for and invokes <code>CacheLoaders</code> in other nodes in the
+   * system.  The net load will invoke one loader at a time until a
+   * loader either returns a non-null value or throws an exception.
+   * If the object is not found, <code>null</code> is returned.
+   *
+   * @param doNetLoad 
+   *        if true, and there is no valid value found for this entry
+   *        in the system, then look for and invoke loaders on other
+   *        nodes
+   *
+   * @return the requested value or null if not found
+   *
+   * @throws TimeoutException if the netSearch times out before
+   *         getting a response from another cache
+   * @throws CacheLoaderException
+   *         If <code>netSearch</code> is attempted on a {@linkplain
+   *         com.gemstone.gemfire.cache.Scope#LOCAL local} region. 
+   */
+  public V netSearch(boolean doNetLoad)
+    throws CacheLoaderException, TimeoutException;
+
+  /**
+   * Returns the key for the value being loaded.
+   *
+   * @return the name Object for the object being loaded
+   * @see CacheLoader#load(LoaderHelper) load
+   */
+  public K getKey();
+
+  /**
+   * Returns the region to which the entry belongs.
+   *
+   * @return the name of the region for the object being loaded
+   * @see CacheLoader#load(LoaderHelper) load
+   */
+  public Region<K,V> getRegion();
+
+  /** Return the argument object for the load method that was passed in from
+   * application code. This object is passed in as <i>aLoaderArgument</i> in
+   * {@link Region#get(Object, Object) get}.
+   * @return the argument or null if one was not supplied
+   */
+  public Object getArgument();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/LossAction.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/LossAction.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/LossAction.java
new file mode 100755
index 0000000..79e51da
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/LossAction.java
@@ -0,0 +1,140 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Specifies how access to the region is affected when one or more required
+ * roles are lost. A role is lost when it is are offline and no longer
+ * present in the system membership.
+ * The <code>LossAction</code> is specified when configuring a region's
+ * {@link com.gemstone.gemfire.cache.MembershipAttributes}.
+ * 
+ * @author Kirk Lund
+ * @since 5.0
+ */
+public class LossAction implements Serializable {
+  private static final long serialVersionUID = -832035480397447797L;
+
+  // NOTE: to change/add these files are impacted:
+  //   LossAction, package.html
+  
+  /**
+   * The region is unavailable when required roles are missing. All operations
+   * including read and write access are denied.  All read and write operations
+   * on the region will result in {@link RegionAccessException} while any 
+   * required roles are absent.  Basic administration of the region is allowed,
+   * including {@linkplain Region#close close} and 
+   * {@linkplain Region#localDestroyRegion() localDestroyRegion}.
+   */
+  public static final LossAction NO_ACCESS = 
+      new LossAction("NO_ACCESS");
+
+  /** 
+   * Only local access to the region is allowed when required roles are 
+   * missing.  All distributed write operations on the region will throw 
+   * {@link RegionAccessException} while any required roles are absent.
+   * Reads which result in a netSearch behave normally, while any attempt
+   * to invoke a netLoad is not allowed.
+   */
+  public static final LossAction LIMITED_ACCESS = 
+      new LossAction("LIMITED_ACCESS");
+
+  /** 
+   * Access to the region is unaffected when required roles are missing. 
+   */
+  public static final LossAction FULL_ACCESS = 
+      new LossAction("FULL_ACCESS");
+
+  /** 
+   * Loss of required roles causes the entire cache to be closed. In addition,
+   * this process will disconnect from the DistributedSystem and then
+   * reconnect. Attempting to use any existing references to the regions
+   * or cache will throw a {@link CacheClosedException}.
+   */
+  public static final LossAction RECONNECT = 
+      new LossAction("RECONNECT");
+
+  /** The name of this mirror type. */
+  private final transient String name;
+
+  // The 4 declarations below are necessary for serialization
+  /** byte used as ordinal to represent this Scope */
+  public final byte ordinal = nextOrdinal++;
+
+  private static byte nextOrdinal = 0;
+  
+  private static final LossAction[] PRIVATE_VALUES =
+    { NO_ACCESS, LIMITED_ACCESS, FULL_ACCESS, RECONNECT };
+  
+  /** List of all LossAction values */
+  public static final List VALUES = 
+    Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));
+
+  private Object readResolve() throws ObjectStreamException {
+    return PRIVATE_VALUES[ordinal];  // Canonicalize
+  }
+  
+  /** Creates a new instance of LossAction. */
+  private LossAction(String name) {
+      this.name = name;
+  }
+  
+  /** Return the LossAction represented by specified ordinal */
+  public static LossAction fromOrdinal(byte ordinal) {
+    return PRIVATE_VALUES[ordinal];
+  }
+  
+  /** Return the LossAction specified by name */
+  public static LossAction fromName(String name) {
+    if (name == null || name.length() == 0) {
+      throw new IllegalArgumentException(LocalizedStrings.LossAction_INVALID_LOSSACTION_NAME_0.toLocalizedString(name));
+    }
+    for (int i = 0; i < PRIVATE_VALUES.length; i++) {
+      if (name.equals(PRIVATE_VALUES[i].name)) {
+        return PRIVATE_VALUES[i];
+      }
+    }
+    throw new IllegalArgumentException(LocalizedStrings.LossAction_INVALID_LOSSACTION_NAME_0.toLocalizedString(name));
+  }
+  
+  /** Returns true if this is <code>NO_ACCESS</code>. */
+  public boolean isNoAccess() {
+    return this == NO_ACCESS;
+  }
+  
+  /** Returns true if this is <code>LIMITED_ACCESS</code>. */
+  public boolean isLimitedAccess() {
+    return this == LIMITED_ACCESS;
+  }
+  
+  /** Returns true if this is <code>FULL_ACCESS</code>. */
+  public boolean isAllAccess() {
+    return this == FULL_ACCESS;
+  }
+  
+  /** Returns true if this is <code>RECONNECT</code>. */
+  public boolean isReconnect() {
+    return this == RECONNECT;
+  }
+  
+  /** 
+   * Returns a string representation for this loss action.
+   * @return the name of this loss action
+   */
+  @Override
+  public String toString() {
+      return this.name;
+  }
+  
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/LowMemoryException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/LowMemoryException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/LowMemoryException.java
new file mode 100644
index 0000000..6bd1101
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/LowMemoryException.java
@@ -0,0 +1,58 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.gemstone.gemfire.cache.control.ResourceManager;
+import com.gemstone.gemfire.distributed.DistributedMember;
+
+/**
+ * Indicates a low memory condition either on the local or a remote {@link Cache}.
+ * The {@link ResourceManager} monitors local tenured memory consumption and determines when operations are rejected.
+ * 
+ * @see ResourceManager#setCriticalHeapPercentage(float)
+ * @see Region#put(Object, Object)
+ * 
+ * @author sbawaska
+ * @since 6.0
+ */
+public class LowMemoryException extends ResourceException {
+
+  private static final long serialVersionUID = 6585765466722883168L;
+  private final Set<DistributedMember> critMems;
+
+  /**
+   * Creates a new instance of <code>LowMemoryException</code>.
+   */
+  public LowMemoryException() {
+    this.critMems = Collections.emptySet();
+  }
+
+  /**
+   * Constructs an instance of <code>LowMemoryException</code> with the specified detail message.
+   * @param msg the detail message
+   * @param criticalMembers the member(s) which are/were in a critical state
+   */
+  public LowMemoryException(String msg, final Set<DistributedMember> criticalMembers) {
+    super(msg);
+    this.critMems = Collections.unmodifiableSet(criticalMembers);
+  }
+
+  /**
+   * Get a read-only set of members in a critical state at the time this
+   * exception was constructed.
+   * @return the critical members
+   */
+  public Set<DistributedMember> getCriticalMembers() {
+    return this.critMems;
+  }
+}


[47/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/Delta.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/Delta.java b/gemfire-core/src/main/java/com/gemstone/gemfire/Delta.java
new file mode 100755
index 0000000..5d44249
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/Delta.java
@@ -0,0 +1,57 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+
+/**
+ * This interface defines a contract between the application and GemFire that
+ * allows GemFire to determine whether an application object contains a delta,
+ * allows GemFire to extract the delta from an application object, and generate
+ * a new application object by applying a delta to an existing application
+ * object. The difference in object state is contained in the {@link DataOutput}
+ * and {@link DataInput} parameters.
+ * 
+ * @since 6.1
+ * 
+ */
+public interface Delta {
+
+  /**
+   * Returns true if this object has pending changes it can write out.
+   */
+  boolean hasDelta();
+
+  /**
+   * This method is invoked on an application object at the delta sender, if
+   * GemFire determines the presence of a delta by calling
+   * {@link Delta#hasDelta()} on the object. The delta is written to the
+   * {@link DataOutput} object provided by GemFire.
+   * 
+   * Any delta state should be reset in this method.
+   * 
+   * @throws IOException
+   */
+  void toDelta(DataOutput out) throws IOException;
+
+
+  /**
+   * This method is invoked on an existing application object when an update is
+   * received as a delta. This method throws an {@link InvalidDeltaException}
+   * when the delta in the {@link DataInput} cannot be applied to the object.
+   * GemFire automatically handles an {@link InvalidDeltaException} by
+   * reattempting the update by sending the full application object.
+   * 
+   * @throws IOException
+   * @throws InvalidDeltaException
+   */
+  void fromDelta(DataInput in) throws IOException, InvalidDeltaException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/DeltaSerializationException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/DeltaSerializationException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/DeltaSerializationException.java
new file mode 100644
index 0000000..5476939
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/DeltaSerializationException.java
@@ -0,0 +1,50 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+/**
+ * 
+ */
+package com.gemstone.gemfire;
+
+/**
+ * This exception wraps any checked exception encountered during invocation of
+ * {@link Delta#fromDelta(java.io.DataInput)} or
+ * {@link Delta#toDelta(java.io.DataOutput)} in GemFire.
+ * 
+ * @since 6.5
+ */
+public class DeltaSerializationException extends RuntimeException {
+
+  /**
+   * Default constructor
+   */
+  public DeltaSerializationException() {
+  }
+
+  /**
+   * @param message
+   */
+  public DeltaSerializationException(String message) {
+    super(message);
+  }
+
+  /**
+   * @param cause
+   */
+  public DeltaSerializationException(Throwable cause) {
+    super(cause);
+  }
+
+  /**
+   * @param message
+   * @param cause
+   */
+  public DeltaSerializationException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/ForcedDisconnectException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/ForcedDisconnectException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/ForcedDisconnectException.java
new file mode 100755
index 0000000..8618d63
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/ForcedDisconnectException.java
@@ -0,0 +1,32 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire;
+
+/**
+ * An <code>ForcedDisconnectException</code> is thrown when a GemFire
+ * application is removed from the distributed system due to membership
+ * constraints such as network partition detection.
+ * 
+ * @since 5.7
+ */
+public class ForcedDisconnectException extends CancelException {
+private static final long serialVersionUID = 4977003259880566257L;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>SystemConnectException</code>.
+   */
+  public ForcedDisconnectException(String message) {
+    super(message);
+  }
+  
+  public ForcedDisconnectException(String message, Throwable cause) {
+    super(message, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireCacheException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireCacheException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireCacheException.java
new file mode 100644
index 0000000..aca728a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireCacheException.java
@@ -0,0 +1,41 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+import com.gemstone.gemfire.cache.CacheException;
+
+/**
+ * An <code>GemFireCacheException</code> is used to wrap a
+ * {@link CacheException}. This is needed in contexts that can
+ * not throw the cache exception directly because of it being
+ * a typed exception.
+ */
+public class GemFireCacheException extends GemFireException {
+private static final long serialVersionUID = -2844020916351682908L;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>GemFireCacheException</code>.
+   */
+  public GemFireCacheException(String message, CacheException ex) {
+    super(message, ex);
+  }
+  /**
+   * Creates a new <code>GemFireCacheException</code>.
+   */
+  public GemFireCacheException(CacheException ex) {
+    super(ex);
+  }
+  /**
+   * Gets the wrapped {@link CacheException}
+   */
+  public CacheException getCacheException() {
+    return (CacheException)getCause();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireCheckedException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireCheckedException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireCheckedException.java
new file mode 100644
index 0000000..50dbfa4
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireCheckedException.java
@@ -0,0 +1,81 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+   
+package com.gemstone.gemfire;
+
+/**
+ * This is the abstract superclass of exceptions that are thrown and
+ * declared.
+ * <p>
+ * This class ought to be called <em>GemFireException</em>, but that name
+ * is reserved for an older class that extends {@link java.lang.RuntimeException}.
+ * 
+ * @see com.gemstone.gemfire.GemFireException
+ * @since 5.1
+ */
+public abstract class GemFireCheckedException extends Exception {
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>GemFireException</code> with no detailed message.
+   */
+  public GemFireCheckedException() {
+    super();
+  }
+
+  /**
+   * Creates a new <code>GemFireCheckedException</code> with the given detail
+   * message.
+   */
+  public GemFireCheckedException(String message) {
+    super(message);
+  }
+
+  /**
+   * Creates a new <code>GemFireException</code> with the given detail
+   * message and cause.
+   */
+  public GemFireCheckedException(String message, Throwable cause) {
+    super(message);
+    this.initCause(cause);
+  }
+  
+  /**
+   * Creates a new <code>GemFireCheckedException</code> with the given cause and
+   * no detail message
+   */
+  public GemFireCheckedException(Throwable cause) {
+    super();
+    this.initCause(cause);
+  }
+
+  ////////////////////  Instance Methods  ////////////////////
+
+  /**
+   * Returns the root cause of this <code>GemFireCheckedException</code> or
+   * <code>null</code> if the cause is nonexistent or unknown.
+   */
+  public Throwable getRootCause() {
+      if ( this.getCause() == null ) return null;
+      Throwable root = this.getCause();
+      while ( root != null ) {
+//          if ( ! ( root instanceof GemFireCheckedException )) {
+//              break;
+//          }
+//          GemFireCheckedException tmp = (GemFireCheckedException) root;
+          if ( root.getCause() == null ) {
+              break;
+          } else {
+              root = root.getCause();
+          }
+      }
+      return root;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireConfigException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireConfigException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireConfigException.java
new file mode 100644
index 0000000..5678eb7
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireConfigException.java
@@ -0,0 +1,33 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+   
+package com.gemstone.gemfire;
+
+/**
+ * A <code>GemFireConfigException</code> is used for failures
+ * while processing a GemFire configuration XML file.
+ */
+public class GemFireConfigException extends GemFireException {
+private static final long serialVersionUID = 7791789785331120991L;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>GemFireConfigException</code>.
+   */
+  public GemFireConfigException(String message) {
+    super(message);
+  }
+
+  /**
+   * Creates a new <code>GemFireConfigException</code>.
+   */
+  public GemFireConfigException(String message, Throwable cause) {
+    super(message, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireException.java
new file mode 100644
index 0000000..0a1087a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireException.java
@@ -0,0 +1,140 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+   
+package com.gemstone.gemfire;
+
+/**
+ * This is the abstract superclass of exceptions that are thrown to
+ * indicate incorrect usage of GemFire.
+ *
+ * Since these exceptions are unchecked, this class really
+ * <em>ought</em> to be called <code>GemFireRuntimeException</code>;
+ * however, the current name is retained for compatibility's sake.
+ * 
+ * @author David Whitlock
+ * @see com.gemstone.gemfire.GemFireCheckedException
+ * @see com.gemstone.gemfire.cache.CacheRuntimeException
+ */
+// Implementation note: This class is abstract so that we are forced
+// to have more specific exception types.  We want to avoid using
+// GemFireException to describe an arbitrary error condition (think
+// GsError).
+public abstract class GemFireException extends RuntimeException {
+
+  /** The cause of this <code>GemFireException</code> */
+//  private Throwable cause;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>GemFireException</code> with no detailed message.
+   */
+  public GemFireException() {
+    super();
+  }
+
+  /**
+   * Creates a new <code>GemFireException</code> with the given detail
+   * message.
+   */
+  public GemFireException(String message) {
+    super(message);
+  }
+
+  /**
+   * Creates a new <code>GemFireException</code> with the given detail
+   * message and cause.
+   */
+  public GemFireException(String message, Throwable cause) {
+    super(message, cause);
+//    this.cause = cause;
+  }
+  
+  /**
+   * Creates a new <code>GemFireException</code> with the given cause and
+   * no detail message
+   */
+  public GemFireException(Throwable cause) {
+    super(cause);
+//    this.cause = cause;
+  }
+
+  ////////////////////  Instance Methods  ////////////////////
+
+  /**
+   * Returns the cause of this <code>GemFireException</code> or
+   * <code>null</code> if the cause is nonexistent or unknown.
+   */
+//  public Throwable getCause() {
+//    return this.cause;
+//  }
+
+  /**
+   * Returns the root cause of this <code>GemFireException</code> or
+   * <code>null</code> if the cause is nonexistent or unknown.
+   */
+  public Throwable getRootCause() {
+    if ( this.getCause() == null ) {
+      return null;
+    }
+    Throwable root = this.getCause();
+    while ( root.getCause() != null ) {
+      root = root.getCause();
+    }
+    return root;
+  }
+  
+//  public void printStackTrace() {
+//    super.printStackTrace();
+//    if (this.cause != null) {
+//      System.err.println("Caused by:");
+//      this.cause.printStackTrace();
+//    }
+//  }
+  
+//  public void printStackTrace(java.io.PrintWriter pw) {
+//    super.printStackTrace(pw);
+//
+//    if (this.cause != null) {
+//      pw.println("Caused by:");
+//      this.cause.printStackTrace(pw);
+//    }
+//  }
+//  
+//  public String getMessage() {
+//    if (this.cause != null) {
+//      String ourMsg = super.getMessage();
+//      if (ourMsg == null || ourMsg.length() == 0) {
+//        //ourMsg = super.toString(); //causes inifinite recursion
+//        ourMsg = "";
+//      }
+//      StringBuffer sb = new StringBuffer(ourMsg);
+//      sb.append(" Caused by: ");
+//      String causeMsg = this.cause.getMessage();
+//      if (causeMsg == null || causeMsg.length() == 0) {
+//        causeMsg = this.cause.toString();
+//      }
+//      sb.append(causeMsg);
+//      return sb.toString();
+//    } else {
+//      return super.getMessage();
+//    }
+//  }
+
+  /**
+   * Represent the receiver as well as the cause
+   */
+//  public String toString() {
+//    String result = super.toString();
+//    if (cause != null) {
+//      result = result + ", caused by " + cause.toString();
+//    }
+//    return result;
+//  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireIOException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireIOException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireIOException.java
new file mode 100644
index 0000000..545675a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireIOException.java
@@ -0,0 +1,32 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+   
+package com.gemstone.gemfire;
+
+/**
+ * A <code>GemFireIOException</code> is thrown when a 
+ * GemFire operation failure is caused by an <code>IOException</code>.
+ *
+ * @author David Whitlock
+ *
+ */
+public class GemFireIOException extends GemFireException {
+private static final long serialVersionUID = 5694009444435264497L;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>GemFireIOException</code>.
+   */
+  public GemFireIOException(String message, Throwable cause) {
+    super(message, cause);
+  }
+  public GemFireIOException(String message) {
+    super(message);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireRethrowable.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireRethrowable.java b/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireRethrowable.java
new file mode 100644
index 0000000..7499e90
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/GemFireRethrowable.java
@@ -0,0 +1,38 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+/**
+ * This error is used by GemFire for internal purposes.
+ * It does not indicate an error condition.
+ * For this reason it is named "Rethrowable" instead of the standard "Error".
+ * It was made an <code>Error</code> to make it easier for user code that typically would
+ * catch <code>Exception</code> to not accidently catch this exception.
+ * <p> Note: if user code catches this error (or its subclasses) then it <em>must</em>
+ * be rethrown.
+ * 
+ * @author darrel
+ * @since 5.7
+ */
+public class GemFireRethrowable extends Error {
+  private static final long serialVersionUID = 8349791552668922571L;
+
+  /**
+   * Create a GemFireRethrowable.
+   */
+  public GemFireRethrowable() {
+  }
+
+  /**
+   * Create a GemFireRethrowable with the specified message.
+   * @param message
+   */
+  public GemFireRethrowable(String message) {
+    super(message);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/IncompatibleSystemException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/IncompatibleSystemException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/IncompatibleSystemException.java
new file mode 100644
index 0000000..98aebf4
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/IncompatibleSystemException.java
@@ -0,0 +1,29 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire;
+
+/**
+ * An <code>IncompatibleSystemException</code> is thrown when a
+ * new GemFire process tries to connect to an
+ * existing distributed system and its version is not the same as
+ * that of the distributed system. In this case the new member is
+ * not allowed to connect to the distributed system.
+ * <p>As of GemFire 5.0 this exception should be named IncompatibleDistributedSystemException
+ */
+public class IncompatibleSystemException extends GemFireException {
+private static final long serialVersionUID = -6852188720149734350L;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>IncompatibleSystemException</code>.
+   */
+  public IncompatibleSystemException(String message) {
+    super(message);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/Instantiator.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/Instantiator.java b/gemfire-core/src/main/java/com/gemstone/gemfire/Instantiator.java
new file mode 100644
index 0000000..90ec175
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/Instantiator.java
@@ -0,0 +1,303 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+import com.gemstone.gemfire.internal.InternalInstantiator;
+import com.gemstone.gemfire.internal.cache.EventID;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+/**
+ * <code>Instantiator</code> allows classes that implement {@link
+ * DataSerializable} to be registered with the data serialization
+ * framework.  Knowledge of <code>DataSerializable</code> classes
+ * allows the framework to optimize how instances of those classes are
+ * data serialized.
+ *
+ * <P>
+ *
+ * Ordinarily, when a <code>DataSerializable</code> object is written
+ * using {@link DataSerializer#writeObject(Object, java.io.DataOutput)}, a special marker class id
+ * is written to the stream followed by the class name of the
+ * <code>DataSerializable</code> object.  After the marker class id is
+ * read by {@link DataSerializer#readObject} it performs the following
+ * operations,
+ *
+ * <OL>
+ *
+ * <LI>The class name is read</LI>
+ *
+ * <LI>The class is loaded using {@link Class#forName(java.lang.String)}</LI>
+ *
+ * <LI>An instance of the class is created using reflection</LI>
+ *
+ * <LI>{@link DataSerializable#fromData} is invoked on the
+ * newly-created object</LI>
+ *
+ * </OL>
+ *
+ * However, if a <code>DataSerializable</code> class is {@linkplain
+ * #register(Instantiator) registered} with the data serialization framework and
+ * assigned a unique class id, an important optimization can be
+ * performed that avoid the expense of using reflection to instantiate
+ * the <code>DataSerializable</code> class.  When the object is
+ * written using {@link DataSerializer#writeObject(Object, java.io.DataOutput)}, the object's
+ * registered class id is written to the stream.  Consequently, when
+ * the data is read from the stream, the {@link #newInstance} method
+ * of the appropriate <code>Instantiator</code> instance is invoked to
+ * create an "empty" instance of the <code>DataSerializable</code>
+ * instead of using reflection to create the new instance.
+ *
+ * <P>
+ *
+ * Commonly, a <code>DataSerializable</code> class will register
+ * itself with the <code>Instantiator</code> in a static initializer
+ * as shown in the below example code.
+ *
+ * <!-- 
+ * The source code for the CompanySerializer class resides in 
+ *         tests/com/examples/ds/User.java
+ * Please keep the below code snippet in sync with that file.
+ * -->
+ *
+ * <PRE>
+public class User implements DataSerializable {
+  private String name;
+  private int userId;
+
+  static {
+    Instantiator.register(new Instantiator(User.class, 45) {
+        public DataSerializable newInstance() {
+          return new User();
+        }
+      });
+  }
+
+  public User(String name, int userId) {
+    this.name = name;
+    this.userId = userId;
+  }
+
+  &#47;**
+   * Creates an "empty" User whose contents are filled in by
+   * invoking its toData() method
+   *&#47;
+  private User() {
+
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    out.writeUTF(this.name);
+    out.writeInt(this.userId);
+  }
+
+  public void fromData(DataInput in)
+    throws IOException, ClassNotFoundException {
+    this.name = in.readUTF();
+    this.userId = in.readInt();
+  }
+}
+ * </PRE>
+ *
+ * <code>Instantiator</code>s may be distributed to other members of
+ * the distributed system when they are registered.  Consider the
+ * following scenario in which VM1 and VM2 are members of the same
+ * distributed system.  Both VMs define the sameRegion and VM2's
+ * region replicates the contents of VM1's using replication.
+ * VM1 puts an instance of the above <code>User</code> class into the
+ * region.  The act of instantiating <code>User</code> will load the
+ * <code>User</code> class and invoke its static initializer, thus
+ * registering the <code>Instantiator</code> with the data
+ * serialization framework.  Because the region is a replicate, the
+ * <code>User</code> will be data serialized and sent to VM2.
+ * However, when VM2 attempts to data deserialize the
+ * <code>User</code>, its <code>Instantiator</code> will not
+ * necessarily be registered because <code>User</code>'s static
+ * initializer may not have been invoked yet.  As a result, an
+ * exception would be logged while deserializing the <code>User</code>
+ * and the replicate would not appear to have the new value.  So, in
+ * order to ensure that the <code>Instantiator</code> is registered in
+ * VM2, the data serialization framework distributes a message to each
+ * member when an <code>Instantiator</code> is {@linkplain #register(Instantiator)
+ * registered}.  <p>Note that the framework does not require that an
+ * <code>Instantiator</code> be {@link java.io.Serializable}, but it
+ * does require that it provide
+ * a {@linkplain #Instantiator(Class, int)
+ * two-argument constructor}.
+ *
+ * @see #register(Instantiator)
+ * @see #newInstance
+ *
+ * @author David Whitlock
+ * @since 3.5 */
+public abstract class Instantiator {
+
+  /** The class associated with this instantiator.  Used mainly for
+   * debugging purposes and error messages. */
+  private Class<? extends DataSerializable> clazz;
+
+  /** The id of this <code>Instantiator</code> */
+  private int id;
+  
+  /** The eventId of this <code>Instantiator</code> */
+  private EventID eventId;
+  
+  /** The originator of this <code>Instantiator</code> */
+  private ClientProxyMembershipID context;
+
+
+  ///////////////////////  Static Methods  ///////////////////////
+
+  /**
+   * Registers a <code>DataSerializable</code> class with the data
+   * serialization framework.  This method is usually invoked from the
+   * static initializer of a class that implements
+   * <code>DataSerializable</code>. 
+   *
+   * @param instantiator
+   *        An <code>Instantiator</code> whose {@link #newInstance}
+   *        method is invoked when an object is data deserialized.
+   *
+   * @throws IllegalStateException
+   *         If class <code>c</code> is
+   *         already registered with a different class id, or another
+   *         class has already been registered with id
+   *         <code>classId</code>
+   * @throws NullPointerException
+   *         If <code>instantiator</code> is <code>null</code>.
+   */
+  public static synchronized void register(Instantiator instantiator) {
+    InternalInstantiator.register(instantiator, true);
+  }
+
+  /**
+   * Registers a <code>DataSerializable</code> class with the data
+   * serialization framework.  This method is usually invoked from the
+   * static initializer of a class that implements
+   * <code>DataSerializable</code>. 
+   *
+   * @param instantiator
+   *        An <code>Instantiator</code> whose {@link #newInstance}
+   *        method is invoked when an object is data deserialized.
+   *
+   * @param distribute
+   *        True if the registered <code>DataSerializer</code> has to be
+   *        distributed to other members of the distributed system.
+   *
+   * @throws IllegalArgumentException
+   *         If class <code>c</code> is
+   *         already registered with a different class id, or another
+   *         class has already been registered with id
+   *         <code>classId</code>
+   * @throws NullPointerException
+   *         If <code>instantiator</code> is <code>null</code>.
+   */
+  public static synchronized void register(Instantiator instantiator,
+      boolean distribute) {
+    InternalInstantiator.register(instantiator, distribute);
+  }
+
+  ////////////////////////  Constructors  ////////////////////////
+
+  /**
+   * Creates a new <code>Instantiator</code> that instantiates a given
+   * class.
+   *
+   * @param c
+   *        The <code>DataSerializable</code> class to register.  This
+   *        class must have a static initializer that registers this
+   *        <code>Instantiator</code>. 
+   * @param classId
+   *        A unique id for class <code>c</code>.  The
+   *        <code>classId</code> must not be zero.
+   *        This has been an <code>int</code> since dsPhase1.
+   *
+   * @throws IllegalArgumentException
+   *         If <code>c</code> does not implement
+   *         <code>DataSerializable</code>, <code>classId</code> is
+   *         less than or equal to zero.
+   * @throws NullPointerException
+   *         If <code>c</code> is <code>null</code>
+   */
+  public Instantiator(Class<? extends DataSerializable> c, int classId) {
+    if (c == null) {
+      throw new NullPointerException(LocalizedStrings.Instantiator_CANNOT_REGISTER_A_NULL_CLASS.toLocalizedString());
+    }
+
+    if (!DataSerializable.class.isAssignableFrom(c)) {
+      throw new IllegalArgumentException(LocalizedStrings.Instantiator_CLASS_0_DOES_NOT_IMPLEMENT_DATASERIALIZABLE.toLocalizedString(c.getName()));
+    }
+
+    if (classId == 0) {
+      throw new IllegalArgumentException(LocalizedStrings.Instantiator_CLASS_ID_0_MUST_NOT_BE_0.toLocalizedString(Integer.valueOf(classId)));
+    }
+
+    this.clazz = c;
+    this.id = classId;
+  }
+  
+  //////////////////////  Instance Methods  //////////////////////
+
+  /**
+   * Creates a new "empty" instance of a <Code>DataSerializable</code>
+   * class whose state will be filled in by invoking its {@link
+   * DataSerializable#fromData fromData} method.
+   *
+   * @see DataSerializer#readObject
+   */
+  public abstract DataSerializable newInstance();
+
+  /**
+   * Returns the <code>DataSerializable</code> class that is
+   * instantiated by this <code>Instantiator</code>.
+   */
+  public final Class<? extends DataSerializable> getInstantiatedClass() {
+    return this.clazz;
+  }
+
+  /**
+   * Returns the unique <code>id</code> of this
+   * <code>Instantiator</code>.
+   */
+  public final int getId() {
+    return this.id;
+  }
+  /**
+   * sets the unique <code>eventId</code> of this
+   * <code>Instantiator</code>. For internal use only.
+   */
+  public final void setEventId(Object/*EventID*/ eventId) {
+    this.eventId = (EventID)eventId;
+  }
+  
+  /**
+   * Returns the unique <code>eventId</code> of this
+   * <code>Instantiator</code>. For internal use only.
+   */
+  public final Object/*EventID*/ getEventId() {
+    return this.eventId;
+  }
+  
+  /**
+   * sets the context of this
+   * <code>Instantiator</code>. For internal use only.
+   */
+  public final void setContext(Object/*ClientProxyMembershipID*/ context) {
+    this.context = (ClientProxyMembershipID)context;
+  }
+  
+  /**
+   * Returns the context of this
+   * <code>Instantiator</code>. For internal use only.
+   */
+  public final Object/*ClientProxyMembershipID*/ getContext() {
+    return this.context;
+  }
+  
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/InternalGemFireError.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/InternalGemFireError.java b/gemfire-core/src/main/java/com/gemstone/gemfire/InternalGemFireError.java
new file mode 100644
index 0000000..3e13588
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/InternalGemFireError.java
@@ -0,0 +1,145 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+/**
+ * 
+ */
+package com.gemstone.gemfire;
+
+/**
+ * Indicates that serious error has occurred within the GemFire system.
+ * 
+ * This is similar to {@link AssertionError}, but these errors are always
+ * enabled in a GemFire system.
+ * 
+ * @author jpenney
+ * @since 5.5
+ * @see AssertionError
+ */
+public class InternalGemFireError extends Error {
+  private static final long serialVersionUID = 6390043490679349593L;
+
+  /**
+   * 
+   */
+  public InternalGemFireError() {
+    // TODO Auto-generated constructor stub
+  }
+
+  /**
+   * @param message
+   */
+  public InternalGemFireError(String message) {
+    super(message);
+  }
+
+  /**
+   * @param cause
+   */
+  public InternalGemFireError(Throwable cause) {
+    super(cause);
+  }
+
+  /**
+   * @param message
+   * @param cause
+   */
+  public InternalGemFireError(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Constructs an AssertionError with its detail message derived
+   * from the specified object, which is converted to a string as
+   * defined in <i>The Java Language Specification, Second
+   * Edition</i>, Section 15.18.1.1.
+   *<p>
+   * If the specified object is an instance of <tt>Throwable</tt>, it
+   * becomes the <i>cause</i> of the newly constructed assertion error.
+   *
+   * @param detailMessage value to be used in constructing detail message
+   * @see   Throwable#getCause()
+   */
+  public InternalGemFireError(Object detailMessage) {
+      this("" +  detailMessage);
+      if (detailMessage instanceof Throwable)
+          initCause((Throwable) detailMessage);
+  }
+
+  /**
+   * Constructs an AssertionError with its detail message derived
+   * from the specified <code>boolean</code>, which is converted to
+   * a string as defined in <i>The Java Language Specification,
+   * Second Edition</i>, Section 15.18.1.1.
+   *
+   * @param detailMessage value to be used in constructing detail message
+   */
+  public InternalGemFireError(boolean detailMessage) {
+      this("" +  detailMessage);
+  }
+
+  /**
+   * Constructs an AssertionError with its detail message derived
+   * from the specified <code>char</code>, which is converted to a
+   * string as defined in <i>The Java Language Specification, Second
+   * Edition</i>, Section 15.18.1.1.
+   *
+   * @param detailMessage value to be used in constructing detail message
+   */
+  public InternalGemFireError(char detailMessage) {
+      this("" +  detailMessage);
+  }
+
+  /**
+   * Constructs an AssertionError with its detail message derived
+   * from the specified <code>int</code>, which is converted to a
+   * string as defined in <i>The Java Language Specification, Second
+   * Edition</i>, Section 15.18.1.1.
+   *
+   * @param detailMessage value to be used in constructing detail message
+   */
+  public InternalGemFireError(int detailMessage) {
+      this("" +  detailMessage);
+  }
+
+  /**
+   * Constructs an AssertionError with its detail message derived
+   * from the specified <code>long</code>, which is converted to a
+   * string as defined in <i>The Java Language Specification, Second
+   * Edition</i>, Section 15.18.1.1.
+   *
+   * @param detailMessage value to be used in constructing detail message
+   */
+  public InternalGemFireError(long detailMessage) {
+      this("" +  detailMessage);
+  }
+
+  /**
+   * Constructs an AssertionError with its detail message derived
+   * from the specified <code>float</code>, which is converted to a
+   * string as defined in <i>The Java Language Specification, Second
+   * Edition</i>, Section 15.18.1.1.
+   *
+   * @param detailMessage value to be used in constructing detail message
+   */
+  public InternalGemFireError(float detailMessage) {
+      this("" +  detailMessage);
+  }
+
+  /**
+   * Constructs an AssertionError with its detail message derived
+   * from the specified <code>double</code>, which is converted to a
+   * string as defined in <i>The Java Language Specification, Second
+   * Edition</i>, Section 15.18.1.1.
+   *
+   * @param detailMessage value to be used in constructing detail message
+   */
+  public InternalGemFireError(double detailMessage) {
+      this("" +  detailMessage);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/InternalGemFireException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/InternalGemFireException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/InternalGemFireException.java
new file mode 100644
index 0000000..ddea8b9
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/InternalGemFireException.java
@@ -0,0 +1,47 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+   
+package com.gemstone.gemfire;
+
+/**
+ * An <code>InternalGemFireException</code> is thrown when
+ * a low level, internal, operation fails due to no fault of
+ * the user. The message often contains an operating system
+ * error code.
+ *
+ * @author David Whitlock
+ *
+ */
+public class InternalGemFireException extends GemFireException {
+private static final long serialVersionUID = -6912843691545178619L;
+
+  //////////////////////  Constructors  //////////////////////
+
+  public InternalGemFireException() {
+    super();
+  }
+
+  public InternalGemFireException(Throwable cause) {
+    super(cause);
+  }
+
+  /**
+   * Creates a new <code>InternalGemFireException</code>.
+   */
+  public InternalGemFireException(String message) {
+    super(message);
+  }
+
+  /**
+   * Creates a new <code>InternalGemFireException</code> that was
+   * caused by a given exception
+   */
+  public InternalGemFireException(String message, Throwable thr) {
+    super(message, thr);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/InvalidDeltaException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/InvalidDeltaException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/InvalidDeltaException.java
new file mode 100755
index 0000000..3f191c2
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/InvalidDeltaException.java
@@ -0,0 +1,54 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+import java.io.DataInput;
+
+/**
+ * An <code>InvalidDeltaException</code> is thrown when a delta cannot be
+ * successfully applied by the receiving peer/client. The class implementing
+ * {@link Delta} may also choose to throw this in
+ * {@link Delta#fromDelta(DataInput in)}. GemFire, on encountering this
+ * exception distributes the full application object.
+ * 
+ * @since 6.1
+ */
+public class InvalidDeltaException extends GemFireException {
+
+  /**
+   * Creates a new <code>InvalidDeltaException</code>. 
+   */
+  public InvalidDeltaException() {
+  }
+
+  /**
+   * Creates a new <code>InvalidDeltaException</code>. 
+   * @param msg String explaining the exception
+   */
+  public InvalidDeltaException(String msg) {
+    super(msg);
+  }
+
+  /**
+   * Creates a new <code>InvalidDeltaException</code>. 
+   * @param e Throwable
+   */
+  public InvalidDeltaException(Throwable e) {
+    super(e);
+  }
+
+  /**
+   * Creates a new <code>InvalidDeltaException</code>. 
+   * @param msg String explaining the exception
+   * @param e Throwable
+   */
+  public InvalidDeltaException(String msg, Throwable e) {
+    super(msg, e);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/InvalidValueException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/InvalidValueException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/InvalidValueException.java
new file mode 100644
index 0000000..0e6ac8a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/InvalidValueException.java
@@ -0,0 +1,33 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire;
+
+/**
+ * An <code>InvalidValueException</code> is thrown when an attempt is
+ * made to set a configuration attribute to an invalid value is made.
+ * Values are considered invalid when they are
+ * not compatible with the attribute's type.
+ */
+public class InvalidValueException extends GemFireException {
+private static final long serialVersionUID = 6186767885369527709L;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>InvalidValueException</code>.
+   */
+  public InvalidValueException(String message) {
+    super(message);
+  }
+  /**
+   * Creates a new <code>InvalidValueException</code>.
+   */
+  public InvalidValueException(String message, Throwable ex) {
+    super(message, ex);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/InvalidVersionException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/InvalidVersionException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/InvalidVersionException.java
new file mode 100644
index 0000000..c2d1ddd
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/InvalidVersionException.java
@@ -0,0 +1,9 @@
+package com.gemstone.gemfire;
+
+public class InvalidVersionException extends GemFireException {
+  private static final long serialVersionUID = 6342040462194322698L;
+
+  public InvalidVersionException(String msg) {
+    super(msg);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/LicenseException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/LicenseException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/LicenseException.java
new file mode 100644
index 0000000..527c9b7
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/LicenseException.java
@@ -0,0 +1,45 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+   
+package com.gemstone.gemfire;
+
+/**
+ * A <code>LicenseException</code> is thrown when
+ * the license check fails.
+ *
+ * @deprecated Licensing is not supported as of 8.0.
+ */
+@Deprecated
+public class LicenseException extends GemFireException {
+private static final long serialVersionUID = -1178557127300465801L;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>LicenseException</code>.
+   */
+  public LicenseException(String message) {
+    super(message);
+  }
+
+  /**
+   * Creates a new <code>LicenseException</code> that was
+   * caused by a given exception
+   */
+  public LicenseException(String message, Throwable thr) {
+    super(message, thr);
+  }
+
+  /**
+   * Creates a new <code>LicenseException</code> that was
+   * caused by a given exception
+   */
+  public LicenseException(Throwable thr) {
+    super(thr.getMessage(), thr);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/LogWriter.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/LogWriter.java b/gemfire-core/src/main/java/com/gemstone/gemfire/LogWriter.java
new file mode 100644
index 0000000..0555b75
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/LogWriter.java
@@ -0,0 +1,292 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.  
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire;
+
+import java.util.logging.Handler;
+
+import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.i18n.LogWriterI18n;
+
+/**
+  * Defines methods available to clients that want to write a log message
+  * to their GemFire distributed system log file.
+  * <p>
+  * Instances of this interface can be obtained by calling
+  * {@link DistributedSystem#getLogWriter}.
+  * <p>
+  * For any logged message the log file will contain:
+  * <ul>
+  * <li> The message's level.
+  * <li> The time the message was logged.
+  * <li> The id of the thread that logged the message.
+  * <li> The message itself which can be a string and/or an exception
+  *      including the exception's stack trace.
+  * </ul>
+  * <p>
+  * A message always has a level.
+  * Logging levels are ordered. Enabling logging at a given level also
+  * enables logging at higher levels. The higher the level the more
+  * important and urgent the message.
+  * <p>
+  * The levels, in descending order, are:
+  * <ul>
+  * <li> <code>severe</code>  (highest value) is a message level indicating a serious failure.
+  *   In general <code>severe</code> messages should describe events that
+  *   are of considerable importance and which will prevent normal program
+  *   execution. They should be reasonably intelligible to end users and
+  *   to information managers.
+  * <li> <code>error</code>  
+  *   In general <code>error</code> messages should describe events that
+  *   are of considerable importance but will not prevent normal program
+  *   execution. They should be reasonably intelligible to end users and
+  *   to information managers. They are weaker than <code>severe</code> and
+  *   stronger than <code>warning</code>.
+  * <li> <code>warning</code> is a message level indicating a potential problem.
+  *   In general <code>warning</code> messages should describe events that
+  *   will be of interest to end users or information managers, or which indicate
+  *   potential problems.
+  * <li> <code>info</code> is a message level for informational messages.
+  *   Typically <code>info</code> messages should be reasonably significant
+  *   and should make sense to end users and system administrators.
+  * <li> <code>config</code> is a message level for static configuration messages.
+  *   <code>config</code> messages are intended to provide a variety of static
+  *   configuration information, to assist in debugging problems that may be
+  *   associated with particular configurations.
+  * <li> <code>fine</code> is a message level providing tracing information.
+  *   In general the <code>fine</code> level should be used for information
+  *   that will be broadly interesting to developers. This level is for
+  *   the lowest volume, and most important, tracing messages.
+  * <li> <code>finer</code> indicates a fairly detailed tracing message.
+  *   Logging calls for entering, returning, or throwing an exception
+  *   are traced at the <code>finer</code> level.
+  * <li> <code>finest</code> (lowest value) indicates a highly detailed tracing message.
+  *   In general the <code>finest</code> level should be used for the most
+  *   voluminous detailed tracing messages.
+  * </ul>
+  * <p>
+  * For each level methods exist that will request a message, at that
+  * level, to be logged. These methods are all named after their level.
+  * <p>
+  * For each level a method exists that returns a boolean indicating
+  * if messages at that level will currently be logged. The names
+  * of these methods are of the form: <em>level</em><code>Enabled</code>.
+  *
+  * @author      darrel
+  */
+public interface LogWriter {
+  
+    /**
+     * Returns true if "severe" log messages are enabled.
+     * Returns false if "severe" log messages are disabled.
+     */
+    public boolean severeEnabled();
+    /**
+     * Writes both a message and exception to this writer.
+     * The message level is "severe".
+     */
+    public void severe(String msg, Throwable ex);
+    /**
+     * Writes a message to this writer.
+     * The message level is "severe".
+     */
+    public void severe(String msg);
+    /**
+     * Writes an exception to this writer.
+     * The exception level is "severe".
+     */
+    public void severe(Throwable ex);
+    /**
+     * Returns true if "error" log messages are enabled.
+     * Returns false if "error" log messages are disabled.
+     */
+    public boolean errorEnabled();
+    /**
+     * Writes both a message and exception to this writer.
+     * The message level is "error".
+     */
+    public void error(String msg, Throwable ex);
+    /**
+     * Writes a message to this writer.
+     * The message level is "error".
+     */
+    public void error(String msg);
+    /**
+     * Writes an exception to this writer.
+     * The exception level is "error".
+     */
+    public void error(Throwable ex);
+    /**
+     * Returns true if "warning" log messages are enabled.
+     * Returns false if "warning" log messages are disabled.
+     */
+    public boolean warningEnabled();
+    /**
+     * Writes both a message and exception to this writer.
+     * The message level is "warning".
+     */
+    public void warning(String msg, Throwable ex);
+    /**
+     * Writes a message to this writer.
+     * The message level is "warning".
+     */
+    public void warning(String msg);
+    /**
+     * Writes an exception to this writer.
+     * The exception level is "warning".
+     */
+    public void warning(Throwable ex);
+    /**
+     * Returns true if "info" log messages are enabled.
+     * Returns false if "info" log messages are disabled.
+     */
+    public boolean infoEnabled();
+    /**
+     * Writes both a message and exception to this writer.
+     * The message level is "information".
+     */
+    public void info(String msg, Throwable ex);
+    /**
+     * Writes a message to this writer.
+     * The message level is "information".
+     */
+    public void info(String msg);
+    /**
+     * Writes an exception to this writer.
+     * The exception level is "information".
+     */
+    public void info(Throwable ex);
+    /**
+     * Returns true if "config" log messages are enabled.
+     * Returns false if "config" log messages are disabled.
+     */
+    public boolean configEnabled();
+    /**
+     * Writes both a message and exception to this writer.
+     * The message level is "config".
+     */
+    public void config(String msg, Throwable ex);
+    /**
+     * Writes a message to this writer.
+     * The message level is "config".
+     */
+    public void config(String msg);
+    /**
+     * Writes an exception to this writer.
+     * The exception level is "config".
+     */
+    public void config(Throwable ex);
+    /**
+     * Returns true if "fine" log messages are enabled.
+     * Returns false if "fine" log messages are disabled.
+     */
+    public boolean fineEnabled();
+    /**
+     * Writes both a message and exception to this writer.
+     * The message level is "fine".
+     */
+    public void fine(String msg, Throwable ex);
+    /**
+     * Writes a message to this writer.
+     * The message level is "fine".
+     */
+    public void fine(String msg);
+    /**
+     * Writes an exception to this writer.
+     * The exception level is "fine".
+     */
+    public void fine(Throwable ex);
+    /**
+     * Returns true if "finer" log messages are enabled.
+     * Returns false if "finer" log messages are disabled.
+     */
+    public boolean finerEnabled();
+    /**
+     * Writes both a message and exception to this writer.
+     * The message level is "finer".
+     */
+    public void finer(String msg, Throwable ex);
+    /**
+     * Writes a message to this writer.
+     * The message level is "finer".
+     */
+    public void finer(String msg);
+    /**
+     * Writes an exception to this writer.
+     * The exception level is "finer".
+     */
+    public void finer(Throwable ex);
+    /**
+     * Log a method entry.
+     * <p>The logging is done using the <code>finer</code> level.
+     * The string message will start with <code>"ENTRY"</code> and
+     * include the class and method names.
+     * @param sourceClass Name of class that issued the logging request.
+     * @param sourceMethod Name of the method that issued the logging request.
+     */
+    public void entering(String sourceClass, String sourceMethod);
+    /**
+     * Log a method return.
+     * <p>The logging is done using the <code>finer</code> level.
+     * The string message will start with <code>"RETURN"</code> and
+     * include the class and method names.
+     * @param sourceClass Name of class that issued the logging request.
+     * @param sourceMethod Name of the method that issued the logging request.
+     */
+    public void exiting(String sourceClass, String sourceMethod);
+    /**
+     * Log throwing an exception.
+     * <p> Use to log that a method is
+     * terminating by throwing an exception. The logging is done using
+     * the <code>finer</code> level.
+     * <p> This is a convenience method that could be done
+     * instead by calling {@link #finer(String, Throwable)}.
+     * The string message will start with <code>"THROW"</code> and
+     * include the class and method names.
+     * @param sourceClass Name of class that issued the logging request.
+     * @param sourceMethod Name of the method that issued the logging request.
+     * @param thrown The Throwable that is being thrown.
+     */
+    public void throwing(String sourceClass, String sourceMethod,
+			 Throwable thrown);
+    /**
+     * Returns true if "finest" log messages are enabled.
+     * Returns false if "finest" log messages are disabled.
+     */
+    public boolean finestEnabled();
+    /**
+     * Writes both a message and exception to this writer.
+     * The message level is "finest".
+     */
+    public void finest(String msg, Throwable ex);
+    /**
+     * Writes a message to this writer.
+     * The message level is "finest".
+     */
+    public void finest(String msg);
+    /**
+     * Writes an exception to this writer.
+     * The exception level is "finest".
+     */
+    public void finest(Throwable ex);
+
+    /**
+     * Returns a 1.4 logging handler that can be used to direct application
+     * output to this GemFire logger using the standard JDK logger APIs.
+     * Each time this method is called it creates a new instance of a
+     * Handler so care should be taken to not call this method too often.
+     */
+    public Handler getHandler();
+    
+    /**
+     * A mechanism for accessing the abstraction layer used for 
+     * internationalization.
+     * @return LogWriterI18n
+     */
+    public LogWriterI18n convertToLogWriterI18n();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/NoSystemException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/NoSystemException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/NoSystemException.java
new file mode 100644
index 0000000..3dd292c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/NoSystemException.java
@@ -0,0 +1,39 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire;
+
+/**
+ * A <code>NoSystemException</code> is thrown when a
+ * locator can not be found or connected to.
+ * In most cases one of the following subclasses is used instead
+ * of <code>NoSystemException</code>:
+ * <ul>
+ * <li> {@link UncreatedSystemException}
+ * <li> {@link UnstartedSystemException}
+ * </ul>
+ * <p>As of GemFire 5.0 this exception should be named NoLocatorException.
+ */
+public class NoSystemException extends GemFireException {
+private static final long serialVersionUID = -101890149467219630L;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>NoSystemException</code>.
+   */
+  public NoSystemException(String message) {
+    super(message);
+  }
+  /**
+   * Creates a new <code>NoSystemException</code> with the given message
+   * and cause.
+   */
+  public NoSystemException(String message, Throwable cause) {
+      super(message, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/SerializationException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/SerializationException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/SerializationException.java
new file mode 100644
index 0000000..fd95e5d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/SerializationException.java
@@ -0,0 +1,36 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+import com.gemstone.gemfire.GemFireIOException;
+
+/**
+ * An exception indicating that a serialization or deserialization failed.
+ * @author darrel
+ * @since 5.7
+ */
+public class SerializationException extends GemFireIOException {
+private static final long serialVersionUID = 7783018024920098997L;
+  /**
+   * 
+   * Create a new instance of SerializationException with a detail message
+   * @param message the detail message
+   */
+  public SerializationException(String message) {
+    super(message);
+  }
+
+  /**
+   * Create a new instance of SerializationException with a detail message and cause
+   * @param message the detail message
+   * @param cause the cause
+   */
+  public SerializationException(String message, Throwable cause) {
+    super(message, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/StatisticDescriptor.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/StatisticDescriptor.java b/gemfire-core/src/main/java/com/gemstone/gemfire/StatisticDescriptor.java
new file mode 100644
index 0000000..38b0129
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/StatisticDescriptor.java
@@ -0,0 +1,73 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+//import com.gemstone.gemfire.internal.Assert;
+//import com.gemstone.gemfire.internal.FieldInfo;
+
+/**
+ * Describes an individual statistic whose value is updated by an
+ * application and may be archived by GemFire.  These descriptions are
+ * gathered together in a {@link StatisticsType}.
+ *
+ * <P>
+ * To get an instance of this interface use an instance of
+ * {@link StatisticsFactory}.
+ * <P>
+ * <code>StatisticDescriptor</code>s are naturally ordered by their name.
+ *
+ * @author David Whitlock
+ * @author Darrel Schneider
+ *
+ * @since 3.0
+ */
+public interface StatisticDescriptor extends Comparable<StatisticDescriptor> {
+
+  ////////////////////  Instance Methods  ////////////////////
+
+  /**
+   * Returns the id of this statistic in a {@link StatisticsType
+   * statistics type}.  The id is initialized when its statistics
+   * type is created.
+   *
+   * @throws IllegalStateException
+   *         The id has not been initialized yet
+   */
+  public int getId();
+
+  /**
+   * Returns the name of this statistic
+   */
+  public String getName();
+
+  /**
+   * Returns a description of this statistic
+   */
+  public String getDescription();
+
+  /**
+   * Returns the type of this statistic
+   */
+  public Class<?> getType();
+
+  /**
+   * Returns true if this statistic is a counter; false if its a gauge.
+   * Counter statistics have values that always increase.
+   * Gauge statistics have unconstrained values.
+   */
+  public boolean isCounter();
+
+  /**
+   * Returns true if a larger statistic value indicates better performance.
+   */
+  public boolean isLargerBetter();
+  /**
+   * Returns the unit in which this statistic is measured
+   */
+  public String getUnit();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/Statistics.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/Statistics.java b/gemfire-core/src/main/java/com/gemstone/gemfire/Statistics.java
new file mode 100644
index 0000000..3b74113
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/Statistics.java
@@ -0,0 +1,437 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+//import com.gemstone.gemfire.distributed.DistributedSystem;
+
+/**
+ * Instances of this interface maintain the values of various application-defined
+ * statistics.  The statistics themselves are described by an instance
+ * of {@link StatisticsType}.
+ *
+ * <P>
+ * To get an instance of this interface use an instance of
+ * {@link StatisticsFactory}.
+ * <P>
+ *
+ * For improved performance, each statistic may be referred to by
+ * its {@link #nameToDescriptor descriptor}.
+ * <P>
+ * For optimal performance, each statistic may be referred to by
+ * its {@link #nameToId id} in the statistics object. Note that
+ * ids can not be mapped back to their name and methods that take ids
+ * are unsafe. It is important to call the correct type of method
+ * for the given id. For example if your stat is a long then incLong
+ * must be called instead of incInt.
+ * <p>Note that as of the 5.1 release the <code>incInt</code>,
+ * <code>incLong</code>, and <code>incDouble</code> methods no longer
+ * return the new value of the statistic. They now return <code>void</code>.
+ * This incompatible change was made
+ * to allow for a more efficient concurrent increment implementation.
+ * <P>
+ *
+ * @see <A href="package-summary.html#statistics">Package introduction</A>
+ *
+ * @author David Whitlock
+ * @author Darrel Schneider
+ *
+ * @since 3.0
+ *
+ */
+public interface Statistics {
+
+  /**
+   * Closes these statistics.  After statistics have been closed, they
+   * are no longer archived.
+   * A value access on a closed statistics always results in zero.
+   * A value modification on a closed statistics is ignored.
+   */
+  public void close();
+
+  ////////////////////////  accessor Methods  ///////////////////////
+
+  /**
+   * Returns the id of the statistic with the given name in this
+   * statistics instance.
+   *
+   * @throws IllegalArgumentException
+   *         No statistic named <code>name</code> exists in this
+   *         statistics instance.
+   *
+   * @see StatisticsType#nameToId
+   */
+  public int nameToId(String name);
+
+  
+  /**
+   * Returns the descriptor of the statistic with the given name in this
+   * statistics instance.
+   *
+   * @throws IllegalArgumentException
+   *         No statistic named <code>name</code> exists in this
+   *         statistics instance.
+   *
+   * @see StatisticsType#nameToDescriptor
+   */
+  public StatisticDescriptor nameToDescriptor(String name);
+
+  /**
+   * Gets a value that uniquely identifies this statistics.
+   */
+  public long getUniqueId();
+
+  /**
+   * Gets the {@link StatisticsType} of this instance.
+   */
+  public StatisticsType getType();
+  /**
+   * Gets the text associated with this instance that helps identify it.
+   */
+  public String getTextId();
+  /**
+   * Gets the number associated with this instance that helps identify it.
+   */
+  public long getNumericId();
+  /**
+   * Returns true if modifications are atomic. This means that multiple threads,
+   * can safely modify this instance without extra synchronization.
+   * <p>
+   * Returns false if modifications are not atomic. This means that modifications
+   * to this instance are cheaper but not thread safe.
+   */
+  public boolean isAtomic();
+  /**
+   * Returns true if the instance has been {@link #close closed}.
+   */
+  public boolean isClosed();
+  
+  ////////////////////////  set() Methods  ///////////////////////
+
+  /**
+   * Sets the value of a statistic with the given <code>id</code>
+   * whose type is <code>int</code>.
+   * @param id a statistic id obtained with {@link #nameToId}
+   * or {@link StatisticsType#nameToId}.
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   *         If the id is invalid.
+   */
+  public void setInt(int id, int value);
+
+  /**
+   * Sets the value of a named statistic of type <code>int</code>
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists named <code>name</code> or
+   *         if the statistic with name <code>name</code> is not of
+   *         type <code>int</code>.
+   */
+  public void setInt(String name, int value);
+
+  /**
+   * Sets the value of a described statistic of type <code>int</code>
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists for the given <code>descriptor</code> or
+   *         if the described statistic is not of
+   *         type <code>int</code>.
+   */
+  public void setInt(StatisticDescriptor descriptor, int value);
+
+  /**
+   * Sets the value of a statistic with the given <code>id</code>
+   * whose type is <code>long</code>.
+   * @param id a statistic id obtained with {@link #nameToId}
+   * or {@link StatisticsType#nameToId}.
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   *         If the id is invalid.
+   */
+  public void setLong(int id, long value);
+
+  /**
+   * Sets the value of a described statistic of type <code>long</code>
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists for the given <code>descriptor</code> or
+   *         if the described statistic is not of
+   *         type <code>long</code>.
+   */
+  public void setLong(StatisticDescriptor descriptor, long value);
+
+  /**
+   * Sets the value of a named statistic of type <code>long</code>.
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists named <code>name</code> or
+   *         if the statistic with name <code>name</code> is not of
+   *         type <code>long</code>.
+   */
+  public void setLong(String name, long value);
+
+  /**
+   * Sets the value of a statistic with the given <code>id</code>
+   * whose type is <code>double</code>.
+   * @param id a statistic id obtained with {@link #nameToId}
+   * or {@link StatisticsType#nameToId}.
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   *         If the id is invalid.
+   */
+  public void setDouble(int id, double value);
+
+  /**
+   * Sets the value of a described statistic of type <code>double</code>
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists for the given <code>descriptor</code> or
+   *         if the described statistic is not of
+   *         type <code>double</code>.
+   */
+  public void setDouble(StatisticDescriptor descriptor, double value);
+  /**
+   * Sets the value of a named statistic of type <code>double</code>.
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists named <code>name</code> or
+   *         if the statistic with name <code>name</code> is not of
+   *         type <code>double</code>.
+   */
+  public void setDouble(String name, double value);
+
+  ///////////////////////  get() Methods  ///////////////////////
+
+  /**
+   * Returns the value of the identified statistic of type <code>int</code>.
+   *
+   * @param id a statistic id obtained with {@link #nameToId}
+   * or {@link StatisticsType#nameToId}.
+   * @throws ArrayIndexOutOfBoundsException
+   *         If the id is invalid.
+   */
+  public int getInt(int id);
+
+  /**
+   * Returns the value of the described statistic of type <code>int</code>.
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists with the specified <code>descriptor</code> or
+   *         if the described statistic is not of
+   *         type <code>int</code>.
+   */
+  public int getInt(StatisticDescriptor descriptor);
+  /**
+   * Returns the value of the statistic of type <code>int</code> at
+   * the given name.
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists with name <code>name</code> or
+   *         if the statistic named <code>name</code> is not of
+   *         type <code>int</code>.
+   */
+  public int getInt(String name);
+
+  /**
+   * Returns the value of the identified statistic of type <code>long</code>.
+   *
+   * @param id a statistic id obtained with {@link #nameToId}
+   * or {@link StatisticsType#nameToId}.
+   * @throws ArrayIndexOutOfBoundsException
+   *         If the id is invalid.
+   */
+  public long getLong(int id);
+
+
+  /**
+   * Returns the value of the described statistic of type <code>long</code>.
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists with the specified <code>descriptor</code> or
+   *         if the described statistic is not of
+   *         type <code>long</code>.
+   */
+  public long getLong(StatisticDescriptor descriptor);
+  /**
+   * Returns the value of the statistic of type <code>long</code> at
+   * the given name.
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists with name <code>name</code> or
+   *         if the statistic named <code>name</code> is not of
+   *         type <code>long</code>.
+   */
+  public long getLong(String name);
+
+  /**
+   * Returns the value of the identified statistic of type <code>double</code>.
+   *
+   * @param id a statistic id obtained with {@link #nameToId}
+   * or {@link StatisticsType#nameToId}.
+   * @throws ArrayIndexOutOfBoundsException
+   *         If the id is invalid.
+   */
+  public double getDouble(int id);
+
+  /**
+   * Returns the value of the described statistic of type <code>double</code>.
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists with the specified <code>descriptor</code> or
+   *         if the described statistic is not of
+   *         type <code>double</code>.
+   */
+  public double getDouble(StatisticDescriptor descriptor);
+  /**
+   * Returns the value of the statistic of type <code>double</code> at
+   * the given name.
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists with name <code>name</code> or
+   *         if the statistic named <code>name</code> is not of
+   *         type <code>double</code>.
+   */
+  public double getDouble(String name);
+
+  /**
+   * Returns the value of the identified statistic.
+   *
+   * @param descriptor a statistic descriptor obtained with {@link #nameToDescriptor}
+   * or {@link StatisticsType#nameToDescriptor}.
+   * @throws IllegalArgumentException
+   *         If the described statistic does not exist
+   */
+  public Number get(StatisticDescriptor descriptor);
+
+  /**
+   * Returns the value of the named statistic.
+   *
+   * @throws IllegalArgumentException
+   *         If the named statistic does not exist
+   */
+  public Number get(String name);
+
+  /**
+   * Returns the bits that represent the raw value of the described statistic.
+   *
+   * @param descriptor a statistic descriptor obtained with {@link #nameToDescriptor}
+   * or {@link StatisticsType#nameToDescriptor}.
+   * @throws IllegalArgumentException
+   *         If the described statistic does not exist
+   */
+  public long getRawBits(StatisticDescriptor descriptor);
+
+  /**
+   * Returns the bits that represent the raw value of the named statistic.
+   *
+   * @throws IllegalArgumentException
+   *         If the named statistic does not exist
+   */
+  public long getRawBits(String name);
+
+  ////////////////////////  inc() Methods  ////////////////////////
+
+  /**
+   * Increments the value of the identified statistic of type <code>int</code>
+   * by the given amount.
+   *
+   * @param id a statistic id obtained with {@link #nameToId}
+   * or {@link StatisticsType#nameToId}.
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   *         If the id is invalid.
+   */
+  public void incInt(int id, int delta);
+
+  /**
+   * Increments the value of the described statistic of type <code>int</code>
+   * by the given amount.
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists with the given <code>descriptor</code> or
+   *         if the described statistic is not of
+   *         type <code>int</code>.
+   */
+  public void incInt(StatisticDescriptor descriptor, int delta);
+
+  /**
+   * Increments the value of the statistic of type <code>int</code> with
+   * the given name by a given amount.
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists with name <code>name</code> or
+   *         if the statistic named <code>name</code> is not of
+   *         type <code>int</code>.
+   */
+  public void incInt(String name, int delta);
+
+  /**
+   * Increments the value of the identified statistic of type <code>long</code>
+   * by the given amount.
+   *
+   * @param id a statistic id obtained with {@link #nameToId}
+   * or {@link StatisticsType#nameToId}.
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   *         If the id is invalid.
+   */
+  public void incLong(int id, long delta);
+
+  /**
+   * Increments the value of the described statistic of type <code>long</code>
+   * by the given amount.
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists with the given <code>descriptor</code> or
+   *         if the described statistic is not of
+   *         type <code>long</code>.
+   */
+  public void incLong(StatisticDescriptor descriptor, long delta);
+  /**
+   * Increments the value of the statistic of type <code>long</code> with
+   * the given name by a given amount.
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists with name <code>name</code> or
+   *         if the statistic named <code>name</code> is not of
+   *         type <code>long</code>.
+   */
+  public void incLong(String name, long delta);
+
+  /**
+   * Increments the value of the identified statistic of type <code>double</code>
+   * by the given amount.
+   *
+   * @param id a statistic id obtained with {@link #nameToId}
+   * or {@link StatisticsType#nameToId}.
+   *
+   * @throws ArrayIndexOutOfBoundsException
+   *         If the id is invalid.
+   */
+  public void incDouble(int id, double delta);
+
+  /**
+   * Increments the value of the described statistic of type <code>double</code>
+   * by the given amount.
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists with the given <code>descriptor</code> or
+   *         if the described statistic is not of
+   *         type <code>double</code>.
+   */
+  public void incDouble(StatisticDescriptor descriptor, double delta);
+  /**
+   * Increments the value of the statistic of type <code>double</code> with
+   * the given name by a given amount.
+   *
+   * @throws IllegalArgumentException
+   *         If no statistic exists with name <code>name</code> or
+   *         if the statistic named <code>name</code> is not of
+   *         type <code>double</code>.
+   */
+  public void incDouble(String name, double delta);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/StatisticsFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/StatisticsFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/StatisticsFactory.java
new file mode 100644
index 0000000..3e239a0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/StatisticsFactory.java
@@ -0,0 +1,145 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire;
+
+//import com.gemstone.gemfire.distributed.DistributedSystem;
+//import com.gemstone.gemfire.internal.StatArchiveFormat;
+//import java.io.IOException;
+//import java.io.Reader;
+
+/**
+ * Instances of this interface provide methods that create instances
+ * of {@link Statistics}.
+ * It can also be used to create instances of {@link StatisticDescriptor}
+ * and {@link StatisticsType} because it implements {@link StatisticsTypeFactory}.
+ * {@link
+ * com.gemstone.gemfire.distributed.DistributedSystem} is the only
+ * instance of this interface.
+ *
+ * <P>
+ *
+ * A <code>StatisticsFactory</code> can create a {@link
+ * StatisticDescriptor statistic} of three numeric types:
+ * <code>int</code>, <code>long</code>, and <code>double</code>.  A
+ * statistic (<code>StatisticDescriptor</code>) can either be a
+ * <I>gauge</I> meaning that its value can increase and decrease or a
+ * <I>counter</I> meaning that its value is strictly increasing.
+ * Marking a statistic as a counter allows statistic display tools
+ * to properly display a statistics whose value "wraps around" (that
+ * is, exceeds its maximum value).
+ * 
+ * <P>The following code is an example of how to create a type using the api.
+ * In this example the type has two stats whose values always increase:
+ * <pre>
+    StatisticsFactory f = ...;
+    StatisticsType t = f.createType(
+        "StatSampler",
+        "Stats on the statistic sampler.",
+        new StatisticDescriptor[] {
+            f.createIntCounter("sampleCount",
+                               "Total number of samples taken by this sampler.",
+                               "samples"),
+            f.createLongCounter("sampleTime",
+                                "Total amount of time spent taking samples.",
+                                "milliseconds"),
+        }
+    );
+    this.samplerStats = f.createStatistics(t, "statSampler");
+    this.sampleCountId = this.samplerStats.nameToId("sampleCount");
+    this.sampleTimeId = this.samplerStats.nameToId("sampleTime");
+ * </pre>
+ * Later on the stat ids can be used to increment the stats:
+ * <pre>
+    this.samplerStats.incInt(this.sampleCountId, 1);
+    this.samplerStats.incLong(this.sampleTimeId, nanosSpentWorking / 1000000);
+ * </pre>
+ * <P>The following is an example of how to create the same type using XML.
+ * The XML data:
+ * <pre>
+    &lt;?xml version="1.0" encoding="UTF-8"?&gt;
+    &lt;!DOCTYPE statistics PUBLIC
+      "-//GemStone Systems, Inc.//GemFire Statistics Type//EN"
+      "http://www.gemstone.com/dtd/statisticsType.dtd"&gt;
+    &lt;statistics&gt;
+      &lt;type name="StatSampler"&gt;
+        &lt;description&gt;Stats on the statistic sampler.&lt;/description&gt;
+        &lt;stat name="sampleCount" storage="int" counter="true"&gt;
+          &lt;description&gt;Total number of samples taken by this sampler.&lt;/description&gt;
+          &lt;unit&gt;samples&lt;/unit&gt;
+        &lt;/stat&gt;
+        &lt;stat name="sampleTime" storage="long" counter="true"&gt;
+          &lt;description&gt;Total amount of time spent taking samples.&lt;/description&gt;
+          &lt;unit&gt;milliseconds&lt;/unit&gt;
+        &lt;/stat&gt;
+      &lt;/type&gt;
+    &lt;/statistics&gt;
+ * </pre>
+ * The code to create the type:
+ * <pre>
+      StatisticsFactory f = ...;
+      Reader r = new InputStreamReader("fileContainingXmlData"));
+      StatisticsType type = f.createTypesFromXml(r)[0];
+ * </pre>
+ * <P>
+ * @see <A href="package-summary.html#statistics">Package introduction</A>
+ *
+ * @author Darrel Schneider
+ *
+ * @since 3.0
+ */
+public interface StatisticsFactory extends StatisticsTypeFactory {
+  /**
+   * Creates and returns a {@link Statistics} instance of the given {@link StatisticsType type} with default ids.
+   * <p>
+   * The created instance may not be {@link Statistics#isAtomic atomic}.
+   */
+  public Statistics createStatistics(StatisticsType type);
+  /**
+   * Creates and returns a {@link Statistics} instance of the given {@link StatisticsType type}, <code>textId</code>, and with a default numeric id.
+   * <p>
+   * The created instance may not be {@link Statistics#isAtomic atomic}.
+   */
+  public Statistics createStatistics(StatisticsType type, String textId);
+  /**
+   * Creates and returns a {@link Statistics} instance of the given {@link StatisticsType type}, <code>textId</code>, and <code>numericId</code>.
+   * <p>
+   * The created instance may not be {@link Statistics#isAtomic atomic}.
+   */
+  public Statistics createStatistics(StatisticsType type, String textId, long numericId);
+
+  /**
+   * Creates and returns a {@link Statistics} instance of the given {@link StatisticsType type} with default ids.
+   * <p>
+   * The created instance will be {@link Statistics#isAtomic atomic}.
+   */
+  public Statistics createAtomicStatistics(StatisticsType type);
+  /**
+   * Creates and returns a {@link Statistics} instance of the given {@link StatisticsType type}, <code>textId</code>, and with a default numeric id.
+   * <p>
+   * The created instance will be {@link Statistics#isAtomic atomic}.
+   */
+  public Statistics createAtomicStatistics(StatisticsType type, String textId);
+  /**
+   * Creates and returns a {@link Statistics} instance of the given {@link StatisticsType type}, <code>textId</code>, and <code>numericId</code>.
+   * <p>
+   * The created instance will be {@link Statistics#isAtomic atomic}.
+   */
+  public Statistics createAtomicStatistics(StatisticsType type, String textId, long numericId);
+  /**
+   * Returns an array of all the existing statistics of the given type.
+   */
+  public Statistics[] findStatisticsByType(StatisticsType type);
+  /**
+   * Returns an array of all the existing statistics with the given textId.
+   */
+  public Statistics[] findStatisticsByTextId(String textId);
+  /**
+   * Returns an array of all the existing statistics with the given numericId.
+   */
+  public Statistics[] findStatisticsByNumericId(long numericId);
+}


[50/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9e31b3b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,19 @@
+# This file should contain patterns all developers want to ignore
+# If you have workspace specific files, add them 
+# to .git/info/exclude.
+#
+# see git help gitignore for more details
+build/
+.gradle/
+.classpath
+.project
+.settings/
+build-eclipse/
+/tags
+
+*.iml
+*.ipr
+*.iws
+*.swp
+# bruce: my synch settings for windows->linux transfers
+transferhost.txt

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/COMPILING.txt
----------------------------------------------------------------------
diff --git a/COMPILING.txt b/COMPILING.txt
new file mode 100644
index 0000000..89f44f4
--- /dev/null
+++ b/COMPILING.txt
@@ -0,0 +1,13 @@
+To build with gradle, just run
+
+./gradlew build
+
+To create a distribution run
+
+./gradlew distTar
+
+or
+
+./gradlew distZip
+
+the distribution archives will be located in gemfire-assembly/build/distributions/.

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/LICENSE.txt
----------------------------------------------------------------------
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 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.

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/NOTICE
----------------------------------------------------------------------
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..a63dcd5
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,339 @@
+Apache Geode (incubating) 
+Copyright 2015 The Apache Software Foundation.
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+The following is a listing of the open source components detailed in
+this document. This list is provided for your convenience; please read
+further if you wish to review the copyright notice(s) and the full text
+of the license associated with each component.
+
+SECTION 1: BSD-STYLE, MIT-STYLE, OR SIMILAR STYLE LICENSES
+
+   >>> dom4j-1.6.1
+   >>> jopt-simple-4.4
+   >>> json-none
+   >>> spymemcached-2.9.0
+
+
+
+SECTION 2: Apache License, V2.0
+
+   >>> fastutil-6.6.1
+   >>> hadoop-common-2.4.0
+   >>> swagger-ui-2.0.17
+
+
+
+SECTION 3: GNU Lesser General Public License, V2.1
+
+   >>> jgroups-2.2.9
+
+
+
+APPENDIX. Standard License Files
+
+   >>> Apache License, V2.0
+
+   >>> GNU Lesser General Public License, V2.1
+
+
+
+
+--------------- SECTION 1:  BSD-STYLE, MIT-STYLE, OR SIMILAR STYLE LICENSES ----------
+
+BSD-STYLE, MIT-STYLE, OR SIMILAR STYLE LICENSES are applicable to the following component(s).
+
+
+>>> dom4j-1.6.1
+
+Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
+
+Redistribution and use of this software and associated documentation
+("Software"), with or without modification, are permitted provided
+that the following conditions are met:
+
+1. Redistributions of source code must retain copyright
+   statements and notices.  Redistributions must also contain a
+   copy of this document.
+ 
+2. Redistributions in binary form must reproduce the
+   above copyright notice, this list of conditions and the
+   following disclaimer in the documentation and/or other
+   materials provided with the distribution.
+ 
+3. The name "DOM4J" must not be used to endorse or promote
+   products derived from this Software without prior written
+   permission of MetaStuff, Ltd.  For written permission,
+   please contact dom4j-info@metastuff.com.
+ 
+4. Products derived from this Software may not be called "DOM4J"
+   nor may "DOM4J" appear in their names without prior written
+   permission of MetaStuff, Ltd. DOM4J is a registered
+   trademark of MetaStuff, Ltd.
+ 
+5. Due credit should be given to the DOM4J Project - 
+   http://www.dom4j.org
+ 
+THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+>>> jopt-simple-4.4
+
+The MIT License
+
+ Copyright (c) 2004-2011 Paul R. Holser, Jr.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ADDITIONAL LICENSE INFORMATION:
+
+> Apache 2.0
+
+pholser-jopt-simple-jopt-simple-4.3-11-gdf866e0.zip\pholser-jopt-simple-df866e0\src\site\resources\scripts\prettify.js
+
+Copyright (C) 2006 Google 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.
+
+
+>>> json-none
+
+Copyright (c) 2002 JSON.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+The Software shall be used for Good, not Evil.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+>>> spymemcached-2.9.0
+
+Copyright (C) 2006-2009 Dustin Sallings
+ * Copyright (C) 2009-2011 Couchbase, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING
+ * IN THE SOFTWARE.
+
+
+--------------- SECTION 2: Apache License, V2.0 ----------
+
+Apache License, V2.0 is applicable to the following component(s).
+
+
+>>> fastutil-6.6.1
+
+* Copyright (C) 2002-2014 Sebastiano Vigna 
+ *
+ * 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.
+
+
+>>> hadoop-common-2.4.0
+
+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. See accompanying LICENSE file.
+
+
+>>> swagger-ui-2.0.17
+
+License: Apache 2.0
+
+
+
+ADDITIONAL LICENSE INFORMATION:
+
+
+> MIT
+
+
+swagger-ui-2.0.17.jar/ META-INF/ resources/ webjars/ swagger-ui/ 2.0.17/ lib/ jquery.ba-bbq.min.js
+
+
+[PLEASE NOTE:  WE ELECT TO USE AND DISTRIBUTE THIS COMPONENT UNDER THE TERMS OF THE MIT LICENSE.  THE ORIGINAL LICENSE TERMS ARE REPRODUCED BELOW ONLY AS A REFERENCE.]
+
+
+
+jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010
+ * http://benalman.com/projects/jquery-bbq-plugin/
+ * 
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+
+
+--------------- SECTION 3: GNU Lesser General Public License, V2.1 ----------
+
+GNU Lesser General Public License, V2.1 is applicable to the following component(s).
+
+
+>>> jgroups-2.2.9
+
+License: LGPL 2.1
+
+
+ADDITIONAL LICENSE INFORMATION:
+
+
+> Apache 1.1
+
+JGroups-2.2.9.src.zip\JGroups-2.2.9.src\lib\commons-logging.jar\META-INF\LICENSE.txt
+
+
+The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+
+
+ant-optional.jar
+ant.jar
+
+
+> MIT
+
+JGroups-2.2.9.src.zip/ JGroups-2.2.9.src/ lib/bcprov-jdk14-117.jar/ org/ bouncycastle/ LICENSE.class
+	
+
+
+Copyright (c) 2000 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)  GH line.separator IJ^
+
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,subject to the following conditions:The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE [LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..7941ea4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,90 @@
+# Overview
+
+Geode is a data management platform that provides real-time, consistent access to data-intensive applications throughout widely distributed cloud architectures.  
+
+Geode pools memory, CPU, network resources, and optionally local disk across multiple processes to manage application objects and behavior. It uses dynamic replication and data partitioning techniques to implement high availability, improved performance, scalability, and fault tolerance. In addition to being a distributed data container, Geode is an in-memory data management system that provides reliable asynchronous event notifications and guaranteed message delivery.
+
+Geode is an extremely mature and robust product that can trace its legacy all the way back to one of the first Object Databases for Smalltalk: GemStone. Geode (as GemFireâ„¢) was first deployed in the financial sector as the transactional, low-latency data engine used by multiple Wall Street trading platforms.  Today Geode is used by over 600 enterprise customers for high-scale, 24x7 business critical applications. An example deployment includes [China National Railways](http://pivotal.io/big-data/case-study/scaling-online-sales-for-the-largest-railway-in-the-world-china-railway-corporation) that uses Geode to run railway ticketing for the entire country of China with a 10 node cluster that manages 2 gigabytes of "hot data" in memory, and 10 backup nodes for high availability and elastic scale.
+
+# Main Concepts and Components
+
+_Caches_ are an abstraction that describe a node in a Geode distributed system.
+
+Within each cache, you define data _regions_. Data regions are analogous to tables in a relational database and manage data in a distributed fashion as name/value pairs. A _replicated_ region stores identical copies of the data on each cache member of a distributed system. A _partitioned_ region spreads the data among cache members. After the system is configured, client applications can access the distributed data in regions without knowledge of the underlying system architecture. You can define listeners to receive notifications when data has changed, and you can define expiration criteria to delete obsolete data in a region.
+
+_Locators_ provide both discovery and load balancing services. You configure clients with a list of locator services and the locators maintain a dynamic list of member servers. By default, Geode clients and servers use port 40404 and multicast to discover each other.
+
+Geode includes the following features:
+* Combines redundancy, replication, and a "shared nothing" persistence architecture to deliver fail-safe reliability and performance.
+* Horizontally scalable to thousands of cache members, with multiple cache topologies to meet different enterprise needs. The cache can be distributed across multiple computers.
+* Asynchronous and synchronous cache update propagation.
+* Delta propagation distributes only the difference between old and new versions of an object (delta) instead of the entire object, resulting in significant distribution cost savings.
+* Reliable asynchronous event notifications and guaranteed message delivery through optimized, low latency distribution layer.
+* Applications run 4 to 40 times faster with no additional hardware.
+* Data awareness and real-time business intelligence. If data changes as you retrieve it, you see the changes immediately.
+* Integration with Spring Framework to speed and simplify the development of scalable, transactional enterprise applications.
+* JTA compliant transaction support.
+* Cluster-wide configurations that can be persisted and exported to other clusters.
+* Remote cluster management through HTTP.
+* REST APIs for REST-enabled application development.
+* Rolling upgrade between major version releases.
+
+# Geode in 5 minutes
+
+Obtain the source archive from Pivotal.  Extract and build from source (note: currently Geode supports jdk1.7.75):
+
+    $ cd geode
+    $ ./gradlew build installDist
+
+Start a locator and server:
+
+    $ cd gemfire-assembly/build/install/geode
+    $ ./bin/gfsh
+    gfsh> start locator --name=locator
+    gfsh> start server --name=server
+
+Create a region:
+
+    gfsh> create region --name=region --type=REPLICATE
+
+Write a client application:
+
+_HelloWorld.java_
+
+    import java.util.Map;
+    import com.gemstone.gemfire.cache.Region;
+    import com.gemstone.gemfire.cache.client.*;
+    
+    public class HelloWorld {
+      public static void main(String[] args) throws Exception {
+        ClientCache cache = new ClientCacheFactory()
+          .addPoolLocator("localhost", 10334)
+          .create();
+        Region<String, String> region = cache
+          .<String, String>createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY)
+          .create("region");
+    
+        region.put("1", "Hello");
+        region.put("2", "World");
+        
+        for (Map.Entry<String, String>  entry : region.entrySet()) {
+          System.out.format("key = %s, value = %s\n", entry.getKey(), entry.getValue());
+        }
+        cache.close();
+      }
+    }
+
+Compile and run `HelloWorld.java`.  The classpath should include `gemfire-core-dependencies.jar`.
+
+    javac -cp /some/path/geode/gemfire-assembly/build/install/geode/lib/gemfire-core-dependencies.jar HelloWorld.java
+    java -cp .:/some/path/geode/gemfire-assembly/build/install/geode/lib/gemfire-core-dependencies.jar HelloWorld
+
+#Application Development
+
+Geode applications can be written in a number of client technologies:
+
+* Java using the Geode client API or embedded using the Geode peer API
+* [Spring Data GemFire](http://projects.spring.io/spring-data-gemfire/) or [Spring Cache](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html)
+* [Python](https://github.com/gemfire/py-gemfire-rest)
+* REST
+* [[memcached|Moving from memcached to gemcached]]

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/RUNNING.txt
----------------------------------------------------------------------
diff --git a/RUNNING.txt b/RUNNING.txt
new file mode 100644
index 0000000..ebb0ae7
--- /dev/null
+++ b/RUNNING.txt
@@ -0,0 +1,23 @@
+Create a distribution archive using
+
+./gradlew distTar
+
+Unpack the archive found in gemfire-assembly/build/distributions and run the gfsh shell
+
+cd apache-gemfire-*
+bin/gfsh
+
+OR
+
+Unpack the archive using Gradle task
+
+./gradlew installDist
+
+cd build/install/gemfire
+bin/gfsh
+
+From the gfsh shell you can start a locator and a server using
+
+gfsh> start locator --name=locator
+gfsh> start server --name=server
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/build.gradle
----------------------------------------------------------------------
diff --git a/build.gradle b/build.gradle
new file mode 100755
index 0000000..01a62df
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,267 @@
+apply plugin: 'wrapper'
+
+allprojects {
+  // We want to see all test results.  This is equivalatent to setting --continue
+  // on the command line.
+  gradle.startParameter.continueOnFailure = true
+  
+  repositories {
+    mavenLocal()
+    mavenCentral()
+    maven { url "http://repo.spring.io/release" }
+    maven { url "http://repo.spring.io/milestone" }
+    maven { url "http://repo.spring.io/snapshot" }
+    maven { url "http://repo.spring.io/libs-release" }
+    maven { url "http://repo.spring.io/ext-release-local" }
+    maven { url "http://dist.gemstone.com/maven/release" }
+  }
+
+  group = "io.pivotal.gemfire"
+
+  apply plugin: 'idea'
+  apply plugin: 'eclipse'
+  
+  buildRoot = buildRoot.trim()
+  if (!buildRoot.isEmpty()) {
+    buildDir = buildRoot + project.path.replace(":", "/") + "/build"
+  }
+}
+
+def testResultsDir(def parent, def name) {
+  new File(parent, name)
+}
+
+def writeTestProperties(def parent, def name) {
+  def availablePortFinder = AvailablePortFinder.createPrivate()
+  
+  def props = new Properties()
+  props.setProperty('mcast-port', Integer.toString(availablePortFinder.nextAvailable))
+  props.setProperty('log-level', 'config')
+  def propsFile = new File(testResultsDir(parent, name), 'gemfire.properties')
+  def writer = propsFile.newWriter()
+  props.store(writer, 'Autogenerated Gemfire properties')
+
+}
+
+subprojects {
+  apply plugin: 'java'
+
+  // apply compiler options
+  gradle.taskGraph.whenReady( { graph ->
+    tasks.withType(JavaCompile).each { javac ->
+      javac.configure {
+        sourceCompatibility '1.7'
+        targetCompatibility '1.7'
+        options.encoding = 'UTF-8'
+      }
+    }
+  })
+  
+  // apply default manifest
+  gradle.taskGraph.whenReady( { graph ->
+    tasks.withType(Jar).each { jar ->
+      jar.doFirst {
+        manifest {
+          attributes(
+            "Manifest-Version"  : "1.0",
+            "Created-By"        : System.getProperty("user.name"),
+            "Title"             : rootProject.name,
+            "Version"           : version,
+            "Vendor"            : "Pivotal Software, Inc."
+          )
+        }
+      }
+    }
+  })
+
+  configurations {
+    provided {
+      description 'a dependency that is provided externally at runtime'
+      visible true
+    }
+    
+    testOutput {
+      extendsFrom testCompile
+      description  'a dependency that exposes test artifacts'
+    }
+  }
+
+  // Here we want to disable all transitive dependencies on external artifacts.  This
+  // allows us to lock down library versions.  However, we want project dependencies to
+  // be transitive such that the libraries of a dependent project are automatically included.
+  configurations.all {
+    dependencies.all { dep ->
+      if (dep instanceof ModuleDependency && !(dep instanceof ProjectDependency)) {
+        dep.transitive = false
+      }
+    }
+  }
+  
+  eclipse {
+    classpath {
+      defaultOutputDir = file('build-eclipse')
+      downloadSources = true
+      plusConfigurations += [ configurations.provided ]     
+    }
+    // Several files have UTF-8 encoding and Eclipse running on Windows
+    // will have trouble unless we tell it to use UTF-8 encoding.
+    // This setting needs to go into the core.resources.prefs file,
+    // which the JDT script isn't set up to configure
+    eclipseJdt << {
+      File f = file('.settings/org.eclipse.core.resources.prefs')
+      f.write('eclipse.preferences.version=1\n')
+      f.append('encoding/<project>=utf-8')
+    }
+  }
+  
+  cleanEclipse << {
+    delete '.settings/org.eclipse.core.resources.prefs'
+  }
+
+  idea {
+    module {
+      downloadSources = true
+      scopes.PROVIDED.plus += [ configurations.provided ]
+    }
+  }
+    
+  task jarTest (type: Jar, dependsOn: testClasses) {
+    description 'Assembles a jar archive of test classes.'
+    from sourceSets.test.output
+    classifier 'test'
+  }
+
+  artifacts {
+    testOutput jarTest
+  }
+
+  sourceSets {
+    main.compileClasspath += configurations.provided
+    main.runtimeClasspath -= configurations.provided
+    test.compileClasspath += configurations.provided
+    test.runtimeClasspath += configurations.provided
+  }
+
+  javadoc.classpath += configurations.provided
+  
+  dependencies {
+    compile 'org.springframework:spring-aop:3.2.12.RELEASE'
+    compile 'org.springframework:spring-beans:3.2.12.RELEASE'
+    compile 'org.springframework:spring-context:3.2.12.RELEASE'
+    compile 'org.springframework:spring-context-support:3.2.12.RELEASE'
+    compile 'org.springframework:spring-core:3.2.12.RELEASE'
+    compile 'org.springframework:spring-expression:3.2.12.RELEASE'
+    compile 'org.springframework:spring-web:3.2.12.RELEASE'
+    compile 'org.springframework:spring-webmvc:3.2.12.RELEASE'
+    
+    testCompile 'junit:junit:4.11'
+    testCompile 'org.hamcrest:hamcrest-core:1.1'
+    testCompile 'org.hamcrest:hamcrest-library:1.1'
+    testCompile 'org.jmock:jmock:2.5.1'
+    testCompile 'org.jmock:jmock-legacy:2.5.1'
+    testCompile 'edu.umd.cs.mtc:multithreadedtc:1.01'
+    testRuntime 'cglib:cglib-nodep:2.1_3'
+    testRuntime 'org.objenesis:objenesis:1.0'
+  }
+
+  test {
+    include '**/*JUnitTest.class'
+    useJUnit {
+      includeCategories 'com.gemstone.junit.UnitTest'
+      excludeCategories 'com.gemstone.junit.IntegrationTest'
+      excludeCategories 'com.gemstone.junit.DistributedTest'
+    }    
+    
+    // run each test in its own vm to avoid interference issues if a test doesn't clean up
+    // state
+    //forkEvery 1
+    
+    doFirst {
+      writeTestProperties(buildDir, name)
+    }
+  }
+
+  task integrationTest(type:Test) {
+    include '**/*JUnitTest.class'
+    useJUnit {
+      excludeCategories 'com.gemstone.junit.UnitTest'
+      includeCategories 'com.gemstone.junit.IntegrationTest'
+      excludeCategories 'com.gemstone.junit.DistributedTest'
+    }    
+
+    forkEvery 1
+
+    doFirst {
+      writeTestProperties(buildDir, name)
+    }
+  }
+  
+  task distributedTest(type:Test) {
+    include '**/*DUnitTest.class'
+    
+// TODO add @Category(DistributedTest.class) to dunit tests
+//    useJUnit {
+//      excludeCategories 'com.gemstone.junit.UnitTest'
+//      excludeCategories 'com.gemstone.junit.IntegrationTest'
+//      includeCategories 'com.gemstone.junit.DistributedTest'
+//    }    
+    
+    //I'm hoping this might deal with SOME OOMEs I've seen
+    forkEvery 30
+  }
+
+  // apply common test configuration
+  gradle.taskGraph.whenReady( { graph ->
+    tasks.withType(Test).each { test ->
+      check.dependsOn test
+      test.configure {
+        onlyIf { ! Boolean.getBoolean('skip.tests') }
+    
+        def resultsDir = testResultsDir(buildDir, test.name)
+        workingDir resultsDir.absolutePath
+        
+        reports.html.destination = file "$buildDir/reports/$name"
+        testLogging {
+          exceptionFormat = 'full'
+        }
+        
+        maxHeapSize '768m'
+        jvmArgs = ['-XX:+HeapDumpOnOutOfMemoryError', '-XX:MaxPermSize=256M', '-ea']
+
+        systemProperties = [
+          'gemfire.DEFAULT_MAX_OPLOG_SIZE' : '10',
+          'gemfire.disallowMcastDefaults'  : 'true',
+          'jline.terminal'                 : 'jline.UnsupportedTerminal',
+        ]
+
+        def eol = System.getProperty('line.separator')
+        def progress = new File(resultsDir, "$test.name-progress.txt")
+        beforeTest { desc ->
+          def now = new Date().format('yyyy-MM-dd HH:mm:ss.SSS Z')
+          progress << "$now Starting test $desc.className $desc.name$eol"
+        }
+        afterTest { desc, result ->
+          def now = new Date().format('yyyy-MM-dd HH:mm:ss.SSS Z')
+          progress << "$now Completed test $desc.className $desc.name with result: ${result.resultType}$eol"
+        }
+        
+        doFirst {
+          resultsDir.deleteDir()
+          resultsDir.mkdirs()
+        }
+      }
+    }
+  })
+  
+  check.dependsOn integrationTest
+  check.dependsOn distributedTest
+}
+
+task combineReports(type: TestReport) {
+  description 'Combines the test reports.'
+  destinationDir = file "$buildDir/reports/combined"
+}
+
+gradle.taskGraph.whenReady({ graph ->
+  tasks.getByName('combineReports').reportOn rootProject.subprojects.collect{ it.tasks.withType(Test) }.flatten()
+})

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/etc/eclipseFormatterProfile.xml
----------------------------------------------------------------------
diff --git a/etc/eclipseFormatterProfile.xml b/etc/eclipseFormatterProfile.xml
new file mode 100755
index 0000000..1043611
--- /dev/null
+++ b/etc/eclipseFormatterProfile.xml
@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<profiles version="11">
+<profile kind="CodeFormatterProfile" name="GemFire" version="11">
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.compiler.source" value="1.5"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.5"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.5"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
+</profile>
+</profiles>

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/etc/intellijIdeaCodeStyle.xml
----------------------------------------------------------------------
diff --git a/etc/intellijIdeaCodeStyle.xml b/etc/intellijIdeaCodeStyle.xml
new file mode 100755
index 0000000..eb88ace
--- /dev/null
+++ b/etc/intellijIdeaCodeStyle.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<code_scheme name="gemstoneCodeStyleScheme">
+  <option name="OTHER_INDENT_OPTIONS">
+    <value>
+      <option name="INDENT_SIZE" value="2" />
+      <option name="CONTINUATION_INDENT_SIZE" value="2" />
+      <option name="TAB_SIZE" value="2" />
+      <option name="USE_TAB_CHARACTER" value="false" />
+      <option name="SMART_TABS" value="false" />
+      <option name="LABEL_INDENT_SIZE" value="0" />
+      <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+      <option name="USE_RELATIVE_INDENTS" value="false" />
+    </value>
+  </option>
+  <option name="LINE_SEPARATOR" value="&#10;" />
+  <option name="GENERATE_FINAL_LOCALS" value="true" />
+  <option name="GENERATE_FINAL_PARAMETERS" value="true" />
+  <option name="INSERT_INNER_CLASS_IMPORTS" value="true" />
+  <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="1000" />
+  <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="1" />
+  <option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
+    <value />
+  </option>
+  <option name="IMPORT_LAYOUT_TABLE">
+    <value>
+      <package name="" withSubpackages="true" static="true" />
+      <emptyLine />
+      <package name="java" withSubpackages="true" static="false" />
+      <package name="javax" withSubpackages="true" static="false" />
+      <emptyLine />
+      <package name="junit" withSubpackages="true" static="false" />
+      <package name="jmock" withSubpackages="true" static="false" />
+      <emptyLine />
+      <package name="com" withSubpackages="true" static="false" />
+      <emptyLine />
+      <package name="edu" withSubpackages="true" static="false" />
+      <emptyLine />
+      <package name="net" withSubpackages="true" static="false" />
+      <emptyLine />
+      <package name="org" withSubpackages="true" static="false" />
+      <emptyLine />
+      <package name="" withSubpackages="true" static="false" />
+    </value>
+  </option>
+  <option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
+  <option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
+  <option name="JD_ADD_BLANK_AFTER_DESCRIPTION" value="false" />
+  <option name="JD_KEEP_INVALID_TAGS" value="false" />
+  <option name="JD_PRESERVE_LINE_FEEDS" value="true" />
+  <option name="HTML_ATTRIBUTE_WRAP" value="0" />
+  <option name="HTML_ALIGN_TEXT" value="true" />
+  <option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
+  <option name="BLOCK_COMMENT_AT_FIRST_COLUMN" value="false" />
+  <XML>
+    <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
+  </XML>
+  <codeStyleSettings language="Groovy">
+    <indentOptions>
+      <option name="INDENT_SIZE" value="2" />
+      <option name="CONTINUATION_INDENT_SIZE" value="2" />
+      <option name="TAB_SIZE" value="2" />
+    </indentOptions>
+  </codeStyleSettings>
+  <codeStyleSettings language="JAVA">
+    <option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
+    <option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
+    <option name="BLANK_LINES_BEFORE_PACKAGE" value="1" />
+    <option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
+    <option name="CLASS_BRACE_STYLE" value="5" />
+    <option name="METHOD_BRACE_STYLE" value="5" />
+    <option name="ELSE_ON_NEW_LINE" value="true" />
+    <option name="WHILE_ON_NEW_LINE" value="true" />
+    <option name="CATCH_ON_NEW_LINE" value="true" />
+    <option name="FINALLY_ON_NEW_LINE" value="true" />
+    <option name="SPACE_WITHIN_ARRAY_INITIALIZER_BRACES" value="true" />
+    <option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
+    <option name="CALL_PARAMETERS_WRAP" value="1" />
+    <option name="PREFER_PARAMETERS_WRAP" value="true" />
+    <option name="METHOD_PARAMETERS_WRAP" value="5" />
+    <option name="EXTENDS_KEYWORD_WRAP" value="1" />
+    <option name="THROWS_KEYWORD_WRAP" value="1" />
+    <option name="METHOD_CALL_CHAIN_WRAP" value="1" />
+    <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
+    <option name="ARRAY_INITIALIZER_WRAP" value="5" />
+    <option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true" />
+    <option name="ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE" value="true" />
+    <option name="IF_BRACE_FORCE" value="3" />
+    <option name="DOWHILE_BRACE_FORCE" value="3" />
+    <option name="WHILE_BRACE_FORCE" value="3" />
+    <option name="FOR_BRACE_FORCE" value="3" />
+    <option name="METHOD_ANNOTATION_WRAP" value="5" />
+    <option name="CLASS_ANNOTATION_WRAP" value="5" />
+    <option name="FIELD_ANNOTATION_WRAP" value="5" />
+    <option name="VARIABLE_ANNOTATION_WRAP" value="5" />
+    <indentOptions>
+      <option name="INDENT_SIZE" value="2" />
+      <option name="CONTINUATION_INDENT_SIZE" value="2" />
+      <option name="TAB_SIZE" value="2" />
+    </indentOptions>
+  </codeStyleSettings>
+  <codeStyleSettings language="XML">
+    <indentOptions>
+      <option name="INDENT_SIZE" value="2" />
+      <option name="CONTINUATION_INDENT_SIZE" value="2" />
+      <option name="TAB_SIZE" value="2" />
+    </indentOptions>
+  </codeStyleSettings>
+</code_scheme>
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-assembly/build.gradle
----------------------------------------------------------------------
diff --git a/gemfire-assembly/build.gradle b/gemfire-assembly/build.gradle
new file mode 100755
index 0000000..6e816d1
--- /dev/null
+++ b/gemfire-assembly/build.gradle
@@ -0,0 +1,171 @@
+apply plugin: 'distribution'
+
+jar.enabled = false
+
+configurations {
+  archives
+}
+
+dependencies {
+  provided project(':gemfire-core')
+  
+  archives project(':gemfire-json')  
+  archives project(':gemfire-joptsimple')  
+  archives project(':gemfire-jgroups')  
+  archives project(':gemfire-core')  
+  archives project(':gemfire-web')
+  archives project(':gemfire-web-api')
+}
+
+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
+  classpath += files "$buildDir/install/${distributions.main.baseName}/lib/gemfire-core-dependencies.jar"
+}
+
+task defaultDistributionConfig(type: JavaExec, dependsOn: classes) {
+  outputs.file file("$buildDir/gemfire.properties")
+  main 'com.gemstone.gemfire.distributed.internal.DistributionConfigImpl'
+  classpath project(':gemfire-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(':gemfire-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 = {
+  configurations.archives.dependencies.collect { it.dependencyProject }
+    .findAll { !it.name.contains('web') }
+    .collect { it.jar.archiveName }
+    .join(' ') + ' ' +
+    project(':gemfire-core').configurations.runtime.collect { it.getName() }.findAll {
+      it.contains('antlr') ||
+      it.contains('commons-io') ||
+      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-slf4j-impl') ||
+      it.contains('slf4j-api') ||
+      it.contains('spring-core') ||
+      it.contains('spring-shell') ||
+      it.contains('snappy-java')
+    }.join(' ') 
+}
+
+task depsJar (type: Jar, dependsOn: ':gemfire-core:classes') {
+  description 'Assembles the jar archive that defines the gemfire classpath.'
+  archiveName 'gemfire-core-dependencies.jar'
+  doFirst {
+    manifest { 
+      attributes("Class-Path": cp())
+    }
+  }
+}
+
+task gfshDepsJar (type: Jar, dependsOn: ':gemfire-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(':gemfire-core').webJar.archiveName +
+        ' ' + springWeb
+      )
+    }
+  }
+}
+
+distributions {
+  main {
+    baseName = 'geode' //TODO rootProject.name
+    contents {
+      duplicatesStrategy 'exclude'
+      
+      into ('config') {
+        from defaultCacheConfig
+        from defaultDistributionConfig
+
+        from (project(':gemfire-core').sourceSets.main.resources.files.find { 
+          it.name == 'log4j2-default.xml' 
+        }) {
+          rename 'log4j2-default.xml', 'log4j2.xml'
+        }
+      }
+      
+      into ('lib') {
+        exclude 'annotation*.jar'
+        from project(":gemfire-jgroups").configurations.runtime
+        from project(":gemfire-jgroups").configurations.archives.allArtifacts.files
+
+        from project(":gemfire-json").configurations.runtime
+        from project(":gemfire-json").configurations.archives.allArtifacts.files
+
+        from project(":gemfire-joptsimple").configurations.runtime
+        from project(":gemfire-joptsimple").configurations.archives.allArtifacts.files
+
+        from project(":gemfire-core").configurations.runtime
+        from project(":gemfire-core").configurations.archives.allArtifacts.files
+
+        // include this jar        
+        from project(":gemfire-web-api").jar.outputs.files.getFiles()
+        
+        // dependency jars
+        from depsJar
+        from gfshDepsJar
+      }
+
+      into ('tools/Extensions') {
+        from (project(":gemfire-web").configurations.archives.allArtifacts.files) {
+          exclude '*.jar'
+        }
+        from (project(":gemfire-web-api").configurations.archives.allArtifacts.files) {
+          exclude '*.jar'
+        }
+      }
+    }
+  }
+}
+
+artifacts {
+  archives depsJar, gfshDepsJar
+}
+ 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-assembly/src/main/dist/bin/gfsh
----------------------------------------------------------------------
diff --git a/gemfire-assembly/src/main/dist/bin/gfsh b/gemfire-assembly/src/main/dist/bin/gfsh
new file mode 100755
index 0000000..e700aae
--- /dev/null
+++ b/gemfire-assembly/src/main/dist/bin/gfsh
@@ -0,0 +1,138 @@
+#!/bin/bash
+
+#
+# Environment variables:
+#
+# GF_JAVA - java executable path. 
+#
+# JAVA_ARGS - java arguments, i.e., -Xms1024m -Xmx1024m ...
+#
+# GEMFIRE - GemFire product directory  
+#
+#
+
+if [ -t 0 -a -t 1 ]; then
+  export COLUMNS=`tput cols`
+fi
+
+# Is the file a symbolic link?
+if [ -L $0 ]; then
+    LINK=$( ls -la $0 | awk '{print $NF}' )
+    # Is the link an absolute path?
+    if [[ $(echo $LINK | grep '^/') ]]; then
+        GFSCRIPT=$LINK
+    else
+        GFSCRIPT=$( dirname $0 )/$LINK
+    fi
+    GFPATH=$( cd $(dirname $GFSCRIPT)/..; pwd )
+else
+    GFPATH=$( cd $(dirname $0)/..; pwd )
+fi
+
+# Set GEMFIRE to the product toplevel directory
+GEMFIRE=$GFPATH
+
+UNAME=$( uname )
+if [[ "$UNAME" == CYGWIN* ]]; then
+  UNAME="cygwin"
+else
+  if [[ "$UNAME" == Darwin* ]]; then
+    UNAME="darwin"
+  fi
+fi
+
+if [ "x$WINDIR" != "x" ]; then
+  if [ "${UNAME}" = "cygwin" ]; then
+#	Added for making backspace work under cygwin
+	JLINE_TERMINAL="-Djline.terminal=com.gemstone.gemfire.management.internal.cli.shell.jline.CygwinMinttyTerminal"
+  else
+    echo "ERROR: The variable WINDIR is set indicating this script is running in a Windows OS, please use the .bat file version instead."
+    exit 1
+  fi
+fi
+
+if [ ! -f $GEMFIRE/lib/gemfire-core-dependencies.jar ]; then
+  echo "ERROR: Could not determine GEMFIRE location."
+  exit 1
+fi
+export GEMFIRE
+
+GEMFIRE_JARS=$GEMFIRE/lib/gfsh-dependencies.jar
+if [ "x$CLASSPATH" != "x" ]; then
+  GEMFIRE_JARS=$GEMFIRE_JARS:$CLASSPATH
+fi
+CLASSPATH=$GEMFIRE_JARS
+
+#
+# Copy default .gfshrc to the home directory. Uncomment if needed.
+#
+#if [ ! -f $HOME/.gemfire/.gfsh2rc ]; then
+#  cp $GEMFIRE/defaultConfigs/.gemfire/.gfsh2rc $HOME
+#fi
+
+#
+# Make dirs and copy etc files if .gemfire does not exist. Uncomment if needed.
+#
+#if [ ! -d $HOME/.gemfire ]; then
+#  mkdir -p $HOME/.gemfire/gfsh
+#fi
+
+LAUNCHER=com.gemstone.gemfire.management.internal.cli.Launcher
+
+if [ "x$JAVA_ARGS" != "x" ]; then
+  JAVA_ARGS="$JAVA_ARGS"
+fi
+
+if [ "x$GF_JAVA" == "x" ]; then 
+    if [ "x$JAVA_HOME" != "x" ]; then
+        GF_JAVA=$JAVA_HOME/bin/java
+    fi
+fi
+
+GF_JAVA=${GF_JAVA:-java}
+
+GF_JAVA_PATH=`which "$GF_JAVA"`
+if [ "x$GF_JAVA_PATH" == "x" ]; then
+  echo "ERROR: Could not find java executable in the path. Please set JAVA_HOME to point to the JDK directory or point GF_JAVA to java executable from JDK."
+  exit 1
+fi
+GF_JAVA_PARENT=`dirname "$GF_JAVA_PATH"`
+GF_JAVA_PARENT=`dirname "$GF_JAVA_PARENT"`
+TOOLS_JAR="$GF_JAVA_PARENT/lib/tools.jar"
+if [ ! -f "$TOOLS_JAR" ]; then
+    # Now consider java is from JRE in JDK 
+    TOOLS_JAR="$GF_JAVA_PARENT/../lib/tools.jar"
+    if [ ! -f "$TOOLS_JAR" ]; then
+        TOOLS_JAR=
+        if [ "${UNAME}" = "darwin" ]; then
+            # For MacOS, try default path
+            TOOLS_JAR="/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Classes/classes.jar"
+            if [ ! -f "$TOOLS_JAR" ]; then
+              TOOLS_JAR=
+            fi
+        fi
+    fi
+fi
+
+if [ "x$TOOLS_JAR" != "x" ]; then
+  CLASSPATH="$CLASSPATH:$TOOLS_JAR"
+fi
+
+if [ "${UNAME}" = "cygwin" ]; then
+  CLASSPATH=$( cygpath -w -p "$CLASSPATH" )
+  if [ -t 0 -a -t 1 ]; then
+    stty -icanon min 1 -echo
+  fi
+fi
+
+# Set our trap handler to clean up the terminal in case bad things happen
+# Only when running attached to terminal
+if [ -t 0 -a -t 1 ]; then
+  trap "stty icanon echo" SIGCHLD
+fi
+
+# This enables job control and monitoring, effectively switching on the trap
+# handler to run when the java exe exits, regardless of how (even if killed).
+set -bm
+"$GF_JAVA" -Dgfsh=true -Dlog4j.configurationFile=/com/gemstone/gemfire/internal/logging/log4j/log4j2-cli.xml ${JLINE_TERMINAL} -classpath "${CLASSPATH}" $JAVA_ARGS $LAUNCHER  "$@"
+exit $?


[33/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/AgentLauncher.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/AgentLauncher.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/AgentLauncher.java
new file mode 100644
index 0000000..b6bc44f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/AgentLauncher.java
@@ -0,0 +1,880 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+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.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.SortedMap;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.GemFireException;
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.jmx.Agent;
+import com.gemstone.gemfire.admin.jmx.AgentConfig;
+import com.gemstone.gemfire.admin.jmx.AgentFactory;
+import com.gemstone.gemfire.distributed.internal.DistributionManager;
+import com.gemstone.gemfire.internal.OSProcess;
+import com.gemstone.gemfire.internal.PureJavaMode;
+import com.gemstone.gemfire.internal.SocketCreator;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.util.IOUtils;
+import com.gemstone.gemfire.internal.util.JavaCommandBuilder;
+
+/**
+ * A command line utility inspired by the <code>CacheServerLauncher</code> that is responsible for administering
+ * a stand-along GemFire JMX {@link Agent}.
+ * <p/>
+ * @author David Whitlock
+ * @since 3.5
+ */
+public class AgentLauncher {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  /** Should the launch command be printed? */
+  public static final boolean PRINT_LAUNCH_COMMAND = Boolean.getBoolean(AgentLauncher.class.getSimpleName()
+      + ".PRINT_LAUNCH_COMMAND");
+
+  /* constants used to define state */
+  static final int SHUTDOWN = 0;
+  static final int STARTING = 1;
+  static final int RUNNING = 2;
+  static final int SHUTDOWN_PENDING = 3;
+  static final int SHUTDOWN_PENDING_AFTER_FAILED_STARTUP = 4;
+  static final int UNKNOWN = 6;
+
+  /** Agent configuration options */
+  static final String AGENT_PROPS = "agent-props";
+
+  /** A flag to indicate if the current log file should be kept. Used only when 'start' is used to fork off the 'server' */
+  static final String APPENDTO_LOG_FILE = "appendto-log-file";
+
+  /** optional and additional classpath entries */
+  static final String CLASSPATH = "classpath";
+
+  /** The directory argument */
+  static final String DIR = "dir";
+
+  /** Extra VM arguments */
+  static final String VMARGS = "vmargs";
+
+  /** The directory in which the agent's output resides */
+  private File workingDirectory = null;
+
+  /** The Status object for the agent */
+  private Status status = null;
+
+  /** base name for the agent to be launched */
+  private final String basename;
+
+  /** The name for the start up log file */
+  private final String startLogFileName;
+
+  /** The name of the status file */
+  private final String statusFileName;
+
+  /**
+   * Instantiates an AgentLauncher for execution and control of the GemFire JMX Agent process.  This constructor is
+   * package private to prevent direct instantiation or subclassing by classes outside this package, but does allow
+   * the class to be tested as needed.
+   * <p/>
+   * @param basename base name for the application to be launched
+   */
+  AgentLauncher(final String basename) {
+    assert basename != null : "The base name used by the AgentLauncher to create files cannot be null!";
+    this.basename = basename;
+    final String formattedBasename = this.basename.toLowerCase().replace(" ", "");
+    this.startLogFileName = "start_" + formattedBasename + ".log";
+    this.statusFileName = "." + formattedBasename + ".ser";
+  }
+
+  /**
+   * Prints information about the agent configuration options
+   */
+  public void configHelp() {
+    PrintStream out = System.out;
+
+    Properties props = AgentConfigImpl.getDefaultValuesForAllProperties();
+
+    out.println("\n");
+    out.println(LocalizedStrings.AgentLauncher_AGENT_CONFIGURATION_PROPERTIES.toString());
+
+    SortedMap<String, String> map = new TreeMap<String, String>();
+
+    int maxLength = 0;
+    for (Iterator<Object> iter = props.keySet().iterator(); iter.hasNext(); ) {
+      String prop = (String) iter.next();
+      int length = prop.length();
+      if (length > maxLength) {
+        maxLength = length;
+      }
+
+      map.put(prop, AgentConfigImpl.getPropertyDescription(prop) +
+              " (" + LocalizedStrings.AgentLauncher_DEFAULT.toLocalizedString() + "  \"" + props.getProperty(prop) + "\")");
+    }
+
+    Iterator<Entry<String, String>> entries = map.entrySet().iterator();
+    while (entries.hasNext()) {
+      Entry<String, String> entry = entries.next();
+      String prop = entry.getKey();
+      out.print("  ");
+      out.println(prop);
+
+      String description = entry.getValue();
+      StringTokenizer st = new StringTokenizer(description, " ");
+      out.print("    ");
+      int printed = 6;
+      while (st.hasMoreTokens()) {
+        String word = st.nextToken();
+        if (printed + word.length() > 72) {
+          out.print("\n    ");
+          printed = 6;
+        }
+        out.print(word);
+        out.print(" ");
+        printed += word.length() + 1;
+      }
+      out.println("");
+    }
+    out.println("");
+
+    System.exit(1);
+  }
+
+  /**
+   * Returns a map that maps the name of the start options 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(final String[] args) throws Exception {
+    final Map<String, Object> options = new HashMap<String, Object>();
+
+    options.put(APPENDTO_LOG_FILE, "false");
+    options.put(DIR, IOUtils.tryGetCanonicalFileElseGetAbsoluteFile(new File(".")));
+
+    final List<String> vmArgs = new ArrayList<String>();
+    options.put(VMARGS, vmArgs);
+
+    final Properties agentProps = new Properties();
+    options.put(AGENT_PROPS, agentProps);
+
+    for (final String arg : args) {
+      if (arg.startsWith("-classpath=")) {
+        options.put(CLASSPATH, arg.substring("-classpath=".length()));
+      }
+      else if (arg.startsWith("-dir=")) {
+        final File workingDirectory = processDirOption(options, arg.substring("-dir=".length()));
+        System.setProperty(AgentConfigImpl.AGENT_PROPSFILE_PROPERTY_NAME,
+          new File(workingDirectory, AgentConfig.DEFAULT_PROPERTY_FILE).getPath());
+      }
+      else if (arg.startsWith("-J")) {
+        vmArgs.add(arg.substring(2));
+      }
+      else if (arg.contains("=")) {
+        final int index = arg.indexOf("=");
+        final String prop = arg.substring(0, index);
+        final String value = arg.substring(index + 1);
+
+        // if appendto-log-file is set, put it in options;  it is not set as an agent prop
+        if (prop.equals(APPENDTO_LOG_FILE)) {
+          options.put(APPENDTO_LOG_FILE, value);
+          continue;
+        }
+
+        // verify the property is valid
+        AgentConfigImpl.getPropertyDescription(prop);
+
+        // Note, the gfAgentPropertyFile System property is ultimately read in the constructor of the AgentImpl class
+        // in order to make any properties defined in this file not only accessible to the DistributedSystem but to
+        // the GemFire Agent as well.
+        if (AgentConfigImpl.PROPERTY_FILE_NAME.equals(prop)) {
+          System.setProperty(AgentConfigImpl.AGENT_PROPSFILE_PROPERTY_NAME, value);
+        }
+
+        // The Agent properties file (specified with the command-line key=value) is used to pass configuration settings
+        // to the GemFire DistributedSystem.  A property file can be passed using the property-file command-line switch
+        // is a large number of properties are specified, or the properties maybe individually specified on the
+        // command-line as property=value arguments.
+        agentProps.setProperty(prop, value);
+      }
+    }
+
+    return options;
+  }
+
+  /**
+   * After parsing the command line arguments, spawn the Java VM that will host the GemFire JMX Agent.
+   */
+  public void start(final String[] args) throws Exception {
+    final Map<String, Object> options = getStartOptions(args);
+
+    workingDirectory = IOUtils.tryGetCanonicalFileElseGetAbsoluteFile((File) options.get(DIR));
+
+    // verify that any GemFire JMX Agent process has been properly shutdown and delete any remaining status files...
+    verifyAndClearStatus();
+
+    // start the GemFire JMX Agent process...
+    runCommandLine(options, buildCommandLine(options));
+
+    // wait for the GemFire JMX Agent process to complete startup and begin running...
+    // it is also possible the Agent process may fail to start, so this should not wait indefinitely unless
+    // the status file was not successfully written to
+    pollAgentUntilRunning();
+
+    System.exit(0);
+  }
+
+  private void verifyAndClearStatus() throws Exception {
+    final Status status = getStatus();
+
+    if (status != null && status.state != SHUTDOWN) {
+      throw new IllegalStateException(LocalizedStrings.AgentLauncher_JMX_AGENT_EXISTS_BUT_WAS_NOT_SHUTDOWN.toLocalizedString());
+    }
+
+    deleteStatus();
+  }
+
+  private String[] buildCommandLine(final Map<String, Object> options) {
+    final List<String> commands = JavaCommandBuilder.buildCommand(AgentLauncher.class.getName(), (String) options.get(CLASSPATH), null,
+      (List<String>) options.get(VMARGS));
+
+    commands.add("server");
+    commands.add("-dir=" + workingDirectory);
+
+    final Properties agentProps = (Properties) options.get(AGENT_PROPS);
+
+    for (final Object key : agentProps.keySet()) {
+      commands.add(key + "=" + agentProps.get(key.toString()));
+    }
+
+    return commands.toArray(new String[commands.size()]);
+  }
+
+  private void printCommandLine(final String[] commandLine) {
+    if (PRINT_LAUNCH_COMMAND) {
+      System.out.print("Starting " + this.basename + " with command:\n");
+      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 IOException {
+    // initialize the startup log starting with a fresh log file (where all startup messages are printed)
+    final File startLogFile = IOUtils.tryGetCanonicalFileElseGetAbsoluteFile(
+      new File(workingDirectory, startLogFileName));
+
+    if (startLogFile.exists() && !startLogFile.delete()) {
+      throw new IOException(LocalizedStrings.AgentLauncher_UNABLE_TO_DELETE_FILE_0.toLocalizedString(
+        startLogFile.getAbsolutePath()));
+    }
+
+    Map<String, String> env = new HashMap<String, String>();
+    // read the passwords from command line
+    SocketCreator.readSSLProperties(env, true);
+
+    printCommandLine(commandLine);
+
+    final int pid = OSProcess.bgexec(commandLine, workingDirectory, startLogFile, false, env);
+
+    System.out.println(LocalizedStrings.AgentLauncher_STARTING_JMX_AGENT_WITH_PID_0.toLocalizedString(pid));
+
+    return pid;
+  }
+
+  private void pollAgentUntilRunning() throws Exception {
+    Status status = spinReadStatus();
+
+    // TODO this loop could recurse indefinitely if the GemFire JMX Agent's state never changes from STARTING
+    // to something else (like RUNNING), which could happen if server process fails to startup correctly
+    // and did not or could not write to the status file!
+    // TODO should we really allow the InterruptedException from the Thread.sleep call to break this loop (yeah, I
+    // think so given the fact this could loop indefinitely)?
+    while (status != null && status.state == STARTING) {
+      Thread.sleep(500);
+      status = spinReadStatus();
+    }
+
+    if (status == null) {
+      // TODO throw a more appropriate Exception here!
+      throw new Exception(LocalizedStrings.AgentLauncher_NO_AVAILABLE_STATUS.toLocalizedString());
+    }
+    else {
+      System.out.println(status);
+    }
+  }
+
+  /**
+   * Starts the GemFire JMX Agent "server" process with the given command line arguments.
+   */
+  public void server(final String[] args) throws Exception {
+    final Map<String, Object> options = getStartOptions(args);
+
+    workingDirectory = IOUtils.tryGetCanonicalFileElseGetAbsoluteFile((File) options.get(DIR));
+
+    writeStatus(createStatus(this.basename, STARTING, OSProcess.getId()));
+
+    final Agent agent = createAgent((Properties) options.get(AGENT_PROPS));
+
+    final Thread thread = createAgentProcessThread(createAgentProcessThreadGroup(), agent);
+    thread.setDaemon(true);
+    thread.start();
+
+    // periodically check and see if the JMX Agent has been told to stop
+    pollAgentForPendingShutdown(agent);
+  }
+
+  private Agent createAgent(final Properties props) throws IOException, AdminException {
+    DistributionManager.isDedicatedAdminVM = true;
+    SystemFailure.setExitOK(true);
+
+    final AgentConfigImpl config = new AgentConfigImpl(props);
+
+    // see bug 43760
+    if (config.getLogFile() == null || "".equals(config.getLogFile().trim())) {
+      config.setLogFile(AgentConfigImpl.DEFAULT_LOG_FILE);
+    }
+
+    // LOG:TODO: redirectOutput called here
+    OSProcess.redirectOutput(new File(config.getLogFile())); // redirect output to the configured log file
+
+    return AgentFactory.getAgent(config);
+  }
+
+  private ThreadGroup createAgentProcessThreadGroup() {
+    return new ThreadGroup(LocalizedStrings.AgentLauncher_STARTING_AGENT.toLocalizedString()) {
+        @Override
+        public void uncaughtException(final Thread t, final Throwable e) {
+          if (e instanceof VirtualMachineError) {
+            SystemFailure.setFailure((VirtualMachineError) e);
+          }
+          setServerError(LocalizedStrings.AgentLauncher_UNCAUGHT_EXCEPTION_IN_THREAD_0.toLocalizedString(t.getName()), e);
+        }
+      };
+  }
+
+  private Thread createAgentProcessThread(final ThreadGroup group, final Agent agent) {
+    return new Thread(group, createAgentProcessRunnable(agent), "Start agent");
+  }
+
+  private Runnable createAgentProcessRunnable(final Agent agent) {
+    return new Runnable() {
+      public void run() {
+        try {
+          agent.start();
+          writeStatus(createStatus(AgentLauncher.this.basename, RUNNING, OSProcess.getId()));
+        }
+        catch (IOException e) {
+          e.printStackTrace();
+        }
+        catch (GemFireException e) {
+          e.printStackTrace();
+          handleGemFireException(e);
+        }
+      }
+
+      private void handleGemFireException(final GemFireException e) {
+        String message = LocalizedStrings.AgentLauncher_SERVER_FAILED_TO_START_0.toLocalizedString(e.getMessage());
+
+        if (e.getCause() != null) {
+          if (e.getCause().getCause() != null) {
+            message += ", " + e.getCause().getCause().getMessage();
+          }
+        }
+
+        setServerError(null, new Exception(message));
+      }
+    };
+  }
+
+
+  /**
+   * Notes that an error has occurred in the agent and that it has shut down because of it.
+   */
+  private void setServerError(final String message, final Throwable cause) {
+    try {
+      writeStatus(createStatus(this.basename, SHUTDOWN_PENDING_AFTER_FAILED_STARTUP, OSProcess.getId(), message, cause));
+    }
+    catch (Exception e) {
+      logger.fatal(e.getMessage(), e);
+      System.exit(1);
+    }
+  }
+
+  private void pollAgentForPendingShutdown(final Agent agent) throws Exception {
+    while (true) {
+      pause(500);
+      spinReadStatus();
+
+      if (isStatus(SHUTDOWN_PENDING, SHUTDOWN_PENDING_AFTER_FAILED_STARTUP)) {
+        agent.stop();
+        final int exitCode = (isStatus(SHUTDOWN_PENDING_AFTER_FAILED_STARTUP) ? 1 : 0);
+        writeStatus(createStatus(this.status, SHUTDOWN));
+        System.exit(exitCode);
+      }
+    }
+  }
+
+  /**
+   * Extracts configuration information for stopping a agent based on the
+   * contents of the command line.  This method can also be used with getting
+   * the status of a agent.
+   */
+  protected Map<String, Object> getStopOptions(final String[] args) throws Exception {
+    final Map<String, Object> options = new HashMap<String, Object>();
+
+    options.put(DIR, IOUtils.tryGetCanonicalFileElseGetAbsoluteFile(new File(".")));
+
+    for (final String arg : args) {
+      if (arg.equals("stop") || arg.equals("status")) {
+        // expected
+      }
+      else if (arg.startsWith("-dir=")) {
+        processDirOption(options, arg.substring("-dir=".length()));
+      }
+      else {
+        throw new Exception(LocalizedStrings.AgentLauncher_UNKNOWN_ARGUMENT_0.toLocalizedString(arg));
+      }
+    }
+
+    return options;
+  }
+
+  /**
+   * Stops a running JMX Agent by setting the status to "shutdown pending".
+   */
+  public void stop(final String[] args) throws Exception {
+    final Map<String, Object> options = getStopOptions(args);
+
+    workingDirectory = IOUtils.tryGetCanonicalFileElseGetAbsoluteFile((File) options.get(DIR));
+
+    int exitStatus = 1;
+
+    if (new File(workingDirectory, statusFileName).exists()) {
+      spinReadStatus();
+
+      if (!isStatus(SHUTDOWN)) {
+        writeStatus(createStatus(this.basename, SHUTDOWN_PENDING, status.pid));
+      }
+
+      pollAgentForShutdown();
+
+      if (isStatus(SHUTDOWN)) {
+        System.out.println(LocalizedStrings.AgentLauncher_0_HAS_STOPPED.toLocalizedString(this.basename));
+        deleteStatus();
+        exitStatus = 0;
+      }
+      else {
+        System.out.println(LocalizedStrings.AgentLauncher_TIMEOUT_WAITING_FOR_0_TO_SHUTDOWN_STATUS_IS_1
+          .toLocalizedString(this.basename, status));
+      }
+    }
+    else {
+      System.out.println(LocalizedStrings.AgentLauncher_THE_SPECIFIED_WORKING_DIRECTORY_0_CONTAINS_NO_STATUS_FILE
+        .toLocalizedString(workingDirectory));
+    }
+
+    System.exit(exitStatus);
+  }
+
+  private void pollAgentForShutdown() throws InterruptedException {
+    final long endTime = (System.currentTimeMillis() + 20000);
+    long clock = 0;
+
+    while (clock < endTime && !isStatus(SHUTDOWN)) {
+      pause(500);
+      spinReadStatus();
+      clock = System.currentTimeMillis();
+    }
+  }
+
+  /**
+   * Prints the status of the GemFire JMX Agent running in the configured working directory.
+   */
+  public void status(final String[] args) throws Exception {
+    this.workingDirectory = IOUtils.tryGetCanonicalFileElseGetAbsoluteFile((File) getStopOptions(args).get(DIR));
+    System.out.println(getStatus());
+    System.exit(0);
+  }
+
+  /**
+   * Returns the <code>Status</code> of the GemFire JMX Agent in the <code>workingDirectory</code>.
+   */
+  protected Status getStatus() throws Exception {
+    Status status;
+
+    if (new File(workingDirectory, statusFileName).exists()) {
+      status = spinReadStatus();
+    }
+    else {
+      status = createStatus(this.basename, SHUTDOWN, 0, LocalizedStrings.AgentLauncher_0_IS_NOT_RUNNING_IN_SPECIFIED_WORKING_DIRECTORY_1
+        .toLocalizedString(this.basename, this.workingDirectory), null);
+    }
+
+    return status;
+  }
+
+  /**
+   * Determines if the Status.state is one of the specified states in the given array of states.  Note, the status
+   * of the Agent, as indicated in the .agent.ser status file, should never have a written value of UNKNOWN.
+   * <p/>
+   * @param states an array of possible acceptable states satisfying the condition of the Agent's status.
+   * @return a boolean value indicating whether the Agent's status satisfies one of the specified states.
+   */
+  private boolean isStatus(final Integer... states) {
+    return (this.status != null && Arrays.asList(defaultToUnknownStateIfNull(states)).contains(this.status.state));
+  }
+
+  /**
+   * Removes an agent's status file
+   */
+  protected void deleteStatus() throws IOException {
+    final File statusFile = new File(workingDirectory, statusFileName);
+
+    if (statusFile.exists() && !statusFile.delete()) {
+      throw new IOException("Could not delete status file (" + statusFile.getAbsolutePath() + ")");
+    }
+  }
+
+  /**
+   * Reads the GemFire JMX Agent's status from the status file (.agent.ser) in it's working directory.
+   * <p/>
+   * @return a Status object containing the state persisted to the .agent.ser file in the working directory
+   * and representing the status of the Agent
+   * @throws IOException if the status file was unable to be read.
+   * @throws RuntimeException if the class of the object written to the .agent.ser file is not of type Status.
+   */
+  protected Status readStatus() throws IOException {
+    FileInputStream fileIn = null;
+    ObjectInputStream objectIn = null;
+
+    try {
+      fileIn = new FileInputStream(new File(workingDirectory, statusFileName));
+      objectIn = new ObjectInputStream(fileIn);
+      this.status = (Status) objectIn.readObject();
+      return this.status;
+    }
+    catch (ClassNotFoundException e) {
+      throw new RuntimeException(e);
+    }
+    finally {
+      IOUtils.close(objectIn);
+      IOUtils.close(fileIn);
+    }
+  }
+
+  /**
+   * A wrapper method for the readStatus method to make one last check for the GemFire JMX Agent process if running
+   * with the native libraries.
+   * @return the Status object as returned from readStatus unless running in native mode and a determination is made
+   * such that the Agent process is not running.
+   * @throws IOException if the state of the Agent process could not be read from the .agent.ser status file.
+   * @see #readStatus()
+   */
+  protected Status nativeReadStatus() throws IOException {
+    Status status = readStatus();
+
+    // @see Bug #32760 - the bug is still possible in pure Java mode
+    if (status != null && !PureJavaMode.isPure() && !OSProcess.exists(status.pid)) {
+      status = createStatus(status, SHUTDOWN);
+    }
+
+    return status;
+  }
+
+  /**
+   * Reads the JMX Agent's status from the .agent.ser status file.  If the status file cannot be read due
+   * to I/O problems, the method will keep attempting to read the file for up to 20 seconds.
+   * <p/>
+   * @return the Status of the GemFire JMX Agent as determined by the .agent.ser status file, or natively
+   * based on the presence/absence of the Agent process.
+   */
+  protected Status spinReadStatus() {
+    Status status = null;
+
+    final long endTime = (System.currentTimeMillis() + 20000);
+    long clock = 0;
+
+    while (status == null && clock < endTime) {
+      try {
+        status = nativeReadStatus();
+      }
+      catch (Exception ignore) {
+        // see bug 31575
+        // see bug 36998
+        // try again after a short delay... the status file might have been read prematurely before it existed
+        // or while the server was trying to write to it resulting in a possible EOFException, or other IOException.
+        pause(500);
+      }
+      finally {
+        clock = System.currentTimeMillis();
+      }
+    }
+
+    return status;
+  }
+
+  /**
+   * Sets the status of the GemFire JMX Agent by serializing a <code>Status</code> object to a status file
+   * in the Agent's working directory.
+   * <p/>
+   * @param status the Status object representing the state of the Agent process to persist to disk.
+   * @return the written Status object.
+   * @throws IOException if the Status could not be successfully persisted to disk.
+   */
+  public Status writeStatus(final Status status) throws IOException {
+    FileOutputStream fileOut = null;
+    ObjectOutputStream objectOut = null;
+
+    try {
+      fileOut = new FileOutputStream(new File(workingDirectory, statusFileName));
+      objectOut = new ObjectOutputStream(fileOut);
+      objectOut.writeObject(status);
+      objectOut.flush();
+      this.status = status;
+      return this.status;
+    }
+    finally {
+      IOUtils.close(objectOut);
+      IOUtils.close(fileOut);
+    }
+  }
+
+  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;
+  }
+
+  protected static Status createStatus(final Status status, final int state) {
+    assert status != null : "The status to clone cannot be null!";
+    return createStatus(status.baseName, state, status.pid, status.msg, status.exception);
+  }
+
+  protected static Integer[] defaultToUnknownStateIfNull(final Integer... states) {
+    return (states != null ? states : new Integer[] { UNKNOWN });
+  }
+
+  protected static boolean pause(final int milliseconds) {
+    try {
+      Thread.sleep(milliseconds);
+      return true;
+    }
+    catch (InterruptedException e) {
+      Thread.currentThread().interrupt();
+      return false;
+    }
+  }
+
+  protected static File processDirOption(final Map<String, Object> options, final String dirValue) throws FileNotFoundException {
+    final File workingDirectory = new File(dirValue);
+
+    if (!workingDirectory.exists()) {
+      throw new FileNotFoundException(LocalizedStrings.AgentLauncher_THE_INPUT_WORKING_DIRECTORY_DOES_NOT_EXIST_0
+        .toLocalizedString(dirValue));
+    }
+
+    options.put(DIR, workingDirectory);
+
+    return workingDirectory;
+  }
+
+  /**
+   * Prints usage information for the AgentLauncher to the command line.
+   * <p/>
+   * @param message a String to output to the command line indicating the user error.
+   */
+  private static void usage(final String message) {
+    final PrintStream out = System.out;
+
+    out.println("\n** " + message + "\n");
+
+    out.println("agent start [-J<vmarg>]* [-dir=<dir>] [prop=value]*");
+    out.println(LocalizedStrings.AgentLauncher_STARTS_THE_GEMFIRE_JMX_AGENT.toLocalizedString());
+    out.println("\t" + LocalizedStrings.AgentLauncher_VMARG.toLocalizedString() );
+    out.println("\t" + LocalizedStrings.AgentLauncher_DIR.toLocalizedString());
+    out.println("\t" + LocalizedStrings.AgentLauncher_PROP.toLocalizedString());
+    out.println("\t" + LocalizedStrings.AgentLauncher_SEE_HELP_CONFIG.toLocalizedString());
+    out.println();
+
+    out.println("agent stop [-dir=<dir>]");
+    out.println(LocalizedStrings.AgentLauncher_STOPS_A_GEMFIRE_JMX_AGENT.toLocalizedString());
+    out.println("\t" + LocalizedStrings.AgentLauncher_DIR.toLocalizedString());
+    out.println("");
+    out.println("agent status [-dir=<dir>]");
+    out.println(LocalizedStrings.AgentLauncher_REPORTS_THE_STATUS_AND_THE_PROCESS_ID_OF_A_GEMFIRE_JMX_AGENT.toLocalizedString());
+    out.println("\t" + LocalizedStrings.AgentLauncher_DIR.toLocalizedString());
+    out.println();
+
+    System.exit(1);
+  }
+
+  /**
+   * Bootstrap method to launch the GemFire JMX Agent process to monitor and manage a GemFire Distributed System/Cache.
+   * Main will read the arguments passed on the command line and dispatch the command to the appropriate handler.
+   */
+  public static void main(final String[] args) {
+    if (args.length < 1) {
+      usage(LocalizedStrings.AgentLauncher_MISSING_COMMAND.toLocalizedString());
+    }
+
+    // TODO is this only needed on 'agent server'?  'agent {start|stop|status}' technically do no run any GemFire Cache
+    // or DS code inside the current process.
+    SystemFailure.loadEmergencyClasses();
+
+    final AgentLauncher launcher = new AgentLauncher("Agent");
+
+    try {
+      final String command = args[0];
+
+      if (command.equalsIgnoreCase("start")) {
+        launcher.start(args);
+      }
+      else if (command.equalsIgnoreCase("server")) {
+        launcher.server(args);
+      }
+      else if (command.equalsIgnoreCase("stop")) {
+        launcher.stop(args);
+      }
+      else if (command.equalsIgnoreCase("status")) {
+        launcher.status(args);
+      }
+      else if (command.toLowerCase().matches("-{0,2}help")) {
+        if (args.length > 1) {
+          final String topic = args[1];
+
+          if (topic.equals("config")) {
+            launcher.configHelp();
+          }
+          else {
+            usage(LocalizedStrings.AgentLauncher_NO_HELP_AVAILABLE_FOR_0.toLocalizedString(topic));
+          }
+        }
+
+        usage(LocalizedStrings.AgentLauncher_AGENT_HELP.toLocalizedString());
+      }
+      else {
+        usage(LocalizedStrings.AgentLauncher_UNKNOWN_COMMAND_0.toLocalizedString(command));
+      }
+    }
+    catch (VirtualMachineError e) {
+      SystemFailure.initiateFailure(e);
+      throw e;
+    }
+    catch (Throwable t) {
+      SystemFailure.checkFailure();
+      t.printStackTrace();
+      System.err.println(LocalizedStrings.AgentLauncher_ERROR_0.toLocalizedString(t.getLocalizedMessage()));
+      System.exit(1);
+    }
+  }
+
+  /**
+   * A class representing the current state of the GemFire JMX Agent process.  Instances of this class are serialized
+   * to a {@linkplain #statusFileName file} on disk in the specified working directory {@linkplain #workingDirectory}.
+   * <p/>
+   * @see #SHUTDOWN
+   * @see #STARTING
+   * @see #RUNNING
+   * @see #SHUTDOWN_PENDING
+   * @see #SHUTDOWN_PENDING_AFTER_FAILED_STARTUP
+   */
+  // TODO refactor this class and internalize the state
+  // TODO refactor the class and make immutable
+  static class Status implements Serializable {
+
+    private static final long serialVersionUID = -7758402454664266174L;
+
+    int pid = 0;
+    int state = 0;
+
+    final String baseName;
+    String msg;
+
+    Throwable exception;
+
+    public Status(final String baseName) {
+      this.baseName = baseName;
+    }
+
+    @Override
+    public String toString() {
+      final StringBuilder buffer = new StringBuilder();
+
+      if (pid == Integer.MIN_VALUE && state == SHUTDOWN && msg != null) {
+        buffer.append(msg);
+      }
+      else {
+        buffer.append(LocalizedStrings.AgentLauncher_0_PID_1_STATUS.toLocalizedString(this.baseName, pid));
+
+        switch (state) {
+          case SHUTDOWN:
+            buffer.append(LocalizedStrings.AgentLauncher_SHUTDOWN.toLocalizedString());
+            break;
+          case STARTING:
+            buffer.append(LocalizedStrings.AgentLauncher_STARTING.toLocalizedString());
+            break;
+          case RUNNING:
+            buffer.append(LocalizedStrings.AgentLauncher_RUNNING.toLocalizedString());
+            break;
+          case SHUTDOWN_PENDING:
+            buffer.append(LocalizedStrings.AgentLauncher_SHUTDOWN_PENDING.toLocalizedString());
+            break;
+          case SHUTDOWN_PENDING_AFTER_FAILED_STARTUP:
+            buffer.append(LocalizedStrings.AgentLauncher_SHUTDOWN_PENDING_AFTER_FAILED_STARTUP.toLocalizedString());
+            break;
+          default:
+            buffer.append(LocalizedStrings.AgentLauncher_UNKNOWN.toLocalizedString());
+            break;
+        }
+
+        if (exception != null) {
+          if (msg != null) {
+            buffer.append("\n").append(msg).append(" - ");
+          }
+          else {
+            buffer.append("\n " + LocalizedStrings.AgentLauncher_EXCEPTION_IN_0_1
+              .toLocalizedString(this.baseName, exception.getMessage()) + " - ");
+          }
+          buffer.append(LocalizedStrings.AgentLauncher_SEE_LOG_FILE_FOR_DETAILS.toLocalizedString());
+        }
+      }
+
+      return buffer.toString();
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/CacheServerJmxImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/CacheServerJmxImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/CacheServerJmxImpl.java
new file mode 100644
index 0000000..78d868b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/CacheServerJmxImpl.java
@@ -0,0 +1,633 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+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 java.util.Map.Entry;
+import java.util.Set;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.Notification;
+import javax.management.ObjectName;
+import javax.management.modelmbean.ModelMBean;
+import javax.naming.OperationNotSupportedException;
+
+import org.apache.commons.modeler.ManagedBean;
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.CacheServerConfig;
+import com.gemstone.gemfire.admin.CacheVmConfig;
+import com.gemstone.gemfire.admin.ConfigurationParameter;
+import com.gemstone.gemfire.admin.StatisticResource;
+import com.gemstone.gemfire.admin.SystemMemberCache;
+import com.gemstone.gemfire.admin.SystemMemberCacheEvent;
+import com.gemstone.gemfire.admin.SystemMemberRegionEvent;
+import com.gemstone.gemfire.admin.internal.CacheServerImpl;
+import com.gemstone.gemfire.admin.internal.ConfigurationParameterImpl;
+import com.gemstone.gemfire.internal.admin.ClientMembershipMessage;
+import com.gemstone.gemfire.internal.admin.GemFireVM;
+import com.gemstone.gemfire.internal.admin.StatResource;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * MBean representation of a {@link
+ * com.gemstone.gemfire.admin.CacheVm}. 
+ *
+ * @author David Whitlock
+ * @since 4.0
+ */
+public class CacheServerJmxImpl extends CacheServerImpl
+  implements ManagedResource, CacheVmConfig, CacheServerConfig, SystemMemberJmx {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  /** 
+   * Interval in seconds between refreshes. Value less than one results in no 
+   * refreshing 
+   */
+  private int refreshInterval = 0;
+
+  /** The object name of this managed resource */
+  private ObjectName objectName;
+
+  /** The name of the MBean that will manage this resource */
+  private String mbeanName;
+
+  /** The ModelMBean that is configured to manage this resource */
+  private ModelMBean modelMBean;
+
+  /** Reference to the cache MBean representing a Cache in the Cache VM Member */
+  private SystemMemberCacheJmxImpl managedSystemMemberCache;
+  
+  /** collection to collect all the resources created for this member */
+  private Map<StatResource, StatisticResourceJmxImpl> managedStatisticsResourcesMap = new HashMap<StatResource, StatisticResourceJmxImpl>();
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>CacheServerJmxImpl</code> for an existing
+   * cache server.
+   */
+  CacheServerJmxImpl(AdminDistributedSystemJmxImpl system,
+                     GemFireVM vm)
+    throws AdminException {
+
+    super(system, vm);
+    initializeMBean();
+  }
+
+  /**
+   * Creates a new <code>CacheServerJmxImpl</code> for an
+   * newly-created cache server.
+   */
+  CacheServerJmxImpl(AdminDistributedSystemJmxImpl system,
+                     CacheVmConfig config)
+    throws AdminException {
+
+    super(system, config);
+    initializeMBean();
+  }
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  /** 
+   * Creates and registers the MBean to manage this resource
+   */
+  private void initializeMBean()
+    throws AdminException {
+    //initialize Managed Resources for stats & cache first.
+//    initializeManagedResources();
+    
+    this.mbeanName = new StringBuffer("GemFire.CacheVm:")
+        .append("id=")
+        .append(MBeanUtil.makeCompliantMBeanNameProperty(getId()))
+        .append(",type=")
+        .append(MBeanUtil.makeCompliantMBeanNameProperty(getType().getName()))
+        .toString();
+
+    this.objectName = MBeanUtil.createMBean(this, 
+        addDynamicAttributes(MBeanUtil.lookupManagedBean(this)));
+
+    // Refresh Interval
+    AdminDistributedSystemJmxImpl sysJmx = (AdminDistributedSystemJmxImpl)system;
+    if (sysJmx.getRefreshInterval()>0)
+      this.refreshInterval = sysJmx.getRefreshInterval();
+  }
+
+  public String getMBeanName() {
+    return this.mbeanName;
+  }
+  
+  public ModelMBean getModelMBean() {
+    return this.modelMBean;
+  }
+  public void setModelMBean(ModelMBean modelMBean) {
+    this.modelMBean = modelMBean;
+  }
+  
+  public ObjectName getObjectName() {
+    return this.objectName;
+  }
+
+  public ManagedResourceType getManagedResourceType() {
+    return ManagedResourceType.CACHE_VM;
+  }
+  
+  /**
+   * Un-registers all the statistics & cache managed resource created for this 
+   * member. After un-registering the resource MBean instances, clears 
+   * managedStatisticsResourcesMap collection & sets managedSystemMemberCache 
+   * to null.
+   * 
+   * Creates ConfigurationParameterJmxImpl, StatisticResourceJmxImpl and 
+   * SystemMemberCacheJmxImpl. But cleans up only StatisticResourceJmxImpl and 
+   * SystemMemberCacheJmxImpl which are of type ManagedResource.
+   */
+  public void cleanupResource() {    
+    synchronized (this.managedStatisticsResourcesMap) {
+      ConfigurationParameter[] names = getConfiguration();
+      if (names != null) {
+        for (int i = 0; i < names.length; i++) {
+          ConfigurationParameter parm = names[i];
+          ((ConfigurationParameterImpl) parm).removeConfigurationParameterListener(this);
+        }
+      }
+      this.parms.clear();
+      
+      Collection<StatisticResourceJmxImpl> statisticResources = managedStatisticsResourcesMap.values();
+      
+      for (StatisticResourceJmxImpl statisticResource : statisticResources) {
+        MBeanUtil.unregisterMBean(statisticResource);
+      }
+        
+      this.managedStatisticsResourcesMap.clear();
+    }
+    
+    MBeanUtil.unregisterMBean(this.managedSystemMemberCache);
+    this.managedSystemMemberCache = null;
+  }
+
+  ///////////////////////  Configuration  ///////////////////////
+
+  @Override
+  public String getHost() {
+    return this.getConfig().getHost();
+  }
+
+  public void setHost(String host) {
+    this.getConfig().setHost(host);
+  }
+
+  @Override
+  public String getWorkingDirectory() {
+    return this.getConfig().getWorkingDirectory();
+  }
+
+  @Override
+  public void setWorkingDirectory(String dir) {
+    this.getConfig().setWorkingDirectory(dir);
+  }
+
+  @Override
+  public String getProductDirectory() {
+    return this.getConfig().getProductDirectory();
+  }
+
+  @Override
+  public void setProductDirectory(String dir) {
+    this.getConfig().setProductDirectory(dir);
+  }
+
+  public String getRemoteCommand() {
+    return this.getConfig().getRemoteCommand();
+  }
+
+  public void setRemoteCommand(String remoteCommand) {
+    this.getConfig().setRemoteCommand(remoteCommand);
+  }
+
+  public void validate() {
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+
+  @Override
+  public Object clone() throws CloneNotSupportedException {
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+
+  public String getCacheXMLFile() {
+    return this.getConfig().getCacheXMLFile();
+  }
+
+  public void setCacheXMLFile(String cacheXMLFile) {
+    this.getConfig().setCacheXMLFile(cacheXMLFile);
+  }
+
+  public String getClassPath() {
+    return this.getConfig().getClassPath();
+  }
+
+  public void setClassPath(String classpath) {
+    this.getConfig().setClassPath(classpath);
+  }
+
+  // -------------------------------------------------------------------------
+  //   MBean attribute accessors/mutators
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Gets the interval in seconds between config refreshes
+   *
+   * @return the current refresh interval in seconds
+   */
+  public int getRefreshInterval() {
+    return this.refreshInterval;
+  }
+  
+   /**
+   * Sets interval in seconds between cache config refreshes; zero or less turns 
+   * off auto refreshing.  Manual refreshing has no effect on when the next
+   * scheduled refresh will occur.
+   *
+   * @param refreshInterval  the new refresh interval in seconds
+   */  
+  public void _setRefreshInterval(int refreshInterval) {
+    boolean isRegistered = MBeanUtil.isRefreshNotificationRegistered(this,
+        RefreshNotificationType.SYSTEM_MEMBER_CONFIG);
+
+    if (isRegistered && (getRefreshInterval() == refreshInterval))
+      return;
+
+    this.refreshInterval = Helper.setAndReturnRefreshInterval(this, refreshInterval);
+  }
+
+  /**
+   * RefreshInterval is now set only through the AdminDistributedSystem property
+   * refreshInterval. Attempt to set refreshInterval on CacheServerJmx MBean
+   * would result in an OperationNotSupportedException Auto-refresh is enabled
+   * on demand when a call to refreshConfig is made
+   * 
+   * @param refreshInterval
+   *          the new refresh interval in seconds
+   * @deprecated since 6.0 use DistributedSystemConfig.refreshInterval instead
+   */
+  @Deprecated
+  public void setRefreshInterval(int refreshInterval)
+      throws OperationNotSupportedException {
+    throw new OperationNotSupportedException(
+        LocalizedStrings.MANAGED_RESOURCE_REFRESH_INTERVAL_CANT_BE_SET_DIRECTLY.toLocalizedString());
+  }  
+  
+  // -------------------------------------------------------------------------
+  //   MBean Operations
+  // -------------------------------------------------------------------------
+
+  public void refreshConfig()
+    throws com.gemstone.gemfire.admin.AdminException {
+    // 1st call to refreshConfig would trigger 
+    // the auto-refresh if an interval is set
+    if (this.refreshInterval>0) {
+      this._setRefreshInterval(this.refreshInterval);
+    }
+
+    super.refreshConfig();
+  }
+
+  /**
+   * Initializes Cache & Statistics managed resources.
+   * 
+   * @throws AdminException
+   *           if initialization of managed resources fails
+   */
+//  private void initializeManagedResources() throws AdminException {
+//    try {
+//      manageCache();
+//    } catch (MalformedObjectNameException e) {
+//      throw new AdminException(LocalizedStrings.SystemMemberJmxImpl_EXCEPTION_OCCURRED_WHILE_INITIALIZING_0_MBEANS_FOR_1.toLocalizedString(
+//              new Object[] {"Cache", getId()}), 
+//              e);
+//    } catch (AdminException ae) {
+//      if (LocalizedStrings.SystemMemberJmx_THIS_SYSTEM_MEMBER_DOES_NOT_HAVE_A_CACHE.toLocalizedString().equals(ae.getMessage())) {
+//        //ignore this exception for a cache-less peer 
+//      } else {
+//        throw ae;
+//      }
+//    }
+//    try {
+//      manageStats();
+//    } catch (MalformedObjectNameException e) {
+//      throw new AdminException(LocalizedStrings.SystemMemberJmxImpl_EXCEPTION_OCCURRED_WHILE_INITIALIZING_0_MBEANS_FOR_1.toLocalizedString(
+//          new Object[] {"Statistics", getId()}), 
+//          e);
+//    }
+//  }
+  
+  /** 
+   * Gets this member's cache.
+   *
+   * @return array of ObjectName for this member's cache
+   */
+  public ObjectName manageCache() 
+  throws AdminException, MalformedObjectNameException {
+    return Helper.manageCache(this);
+  }
+
+  /** 
+   * Gets all active StatisticResources for this manager.
+   *
+   * @return array of ObjectName instances
+   */
+  public ObjectName[] manageStats() 
+  throws AdminException, MalformedObjectNameException {
+    return Helper.manageStats(this);
+  }
+
+  /** 
+   * Gets the active StatisticResources for this manager, based on the
+   * typeName as the key
+   *
+   * @return ObjectName of StatisticResourceJMX instance
+   */
+  public ObjectName[] manageStat(String statisticsTypeName) 
+    throws AdminException, MalformedObjectNameException {
+    
+    return Helper.manageStat(this, statisticsTypeName);
+  }
+
+  // -------------------------------------------------------------------------
+  //   JMX Notification listener
+  // -------------------------------------------------------------------------
+
+  /**
+   * Handles notification to refresh. Reacts by refreshing the values of this
+   * GemFireManager's ConfigurationParamaters. Any other notification is
+   * ignored. Given notification is handled only if there is any JMX client
+   * connected to the system.
+   * 
+   * @param notification
+   *          the JMX notification being received
+   * @param hb
+   *          handback object is unused
+   */
+  public void handleNotification(Notification notification, Object hb) {
+    AdminDistributedSystemJmxImpl systemJmx = 
+                                  (AdminDistributedSystemJmxImpl) this.system;
+
+    if (!systemJmx.isRmiClientCountZero()) {
+      Helper.handleNotification(this, notification, hb);
+    }
+  }
+
+  // -------------------------------------------------------------------------
+  //   Template methods overriden from superclass...
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Template method for creating instance of ConfigurationParameter.  
+   * Overridden to return ConfigurationParameterJmxImpl.
+   */
+  @Override
+  protected ConfigurationParameter createConfigurationParameter(String name,
+                                                                String description,
+                                                                Object value,
+                                                                Class type,
+                                                                boolean userModifiable) {
+    return new ConfigurationParameterJmxImpl(
+        name, description, value, type, userModifiable);
+  }
+  
+
+
+  /**
+   * Override createStatisticResource by instantiating StatisticResourceJmxImpl 
+   * if it was not created earlier otherwise returns the same instance.
+   * 
+   * @param stat
+   *         StatResource reference for which this JMX resource is to be created
+   * @return StatisticResourceJmxImpl - JMX Implementation of StatisticResource
+   * @throws AdminException
+   *           if constructing StatisticResourceJmxImpl instance fails
+   */
+  @Override
+  protected StatisticResource createStatisticResource(StatResource stat)
+    throws com.gemstone.gemfire.admin.AdminException {
+    StatisticResourceJmxImpl managedStatisticResource = null;
+    
+    synchronized (this.managedStatisticsResourcesMap) {
+      /* 
+       * Ensuring that a single instance of Statistic Resource is created per 
+       * StatResource.
+       */
+      StatisticResourceJmxImpl statisticResourceJmxImpl = managedStatisticsResourcesMap.get(stat);
+      if (statisticResourceJmxImpl != null) {
+        managedStatisticResource = statisticResourceJmxImpl;
+      } else {
+        managedStatisticResource = new StatisticResourceJmxImpl(stat, this);
+        managedStatisticResource.getStatistics();//inits timer
+        managedStatisticsResourcesMap.put(stat, managedStatisticResource);
+      }
+    }
+    return managedStatisticResource;
+  }
+
+  /**
+   * Override createSystemMemberCache by instantiating SystemMemberCacheJmxImpl 
+   * if it was not created earlier.
+   * 
+   * @param vm
+   *          GemFireVM reference for which this JMX resource is to be created
+   * @return SystemMemberCacheJmxImpl - JMX Implementation of SystemMemberCache
+   * @throws AdminException
+   *           if constructing SystemMemberCacheJmxImpl instance fails
+   */
+  @Override
+  protected SystemMemberCache createSystemMemberCache(GemFireVM vm)
+    throws com.gemstone.gemfire.admin.AdminException {
+    if (managedSystemMemberCache == null) {
+      managedSystemMemberCache = new SystemMemberCacheJmxImpl(vm);
+    }
+    return managedSystemMemberCache;
+  }
+  
+  // -------------------------------------------------------------------------
+  //   Create MBean attributes for each ConfigurationParameter
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Add MBean attribute definitions for each ConfigurationParameter.
+   *
+   * @param managed the mbean definition to add attributes to
+   * @return a new instance of ManagedBean copied from <code>managed</code> but 
+   *         with the new attributes added
+   */
+  public ManagedBean addDynamicAttributes(ManagedBean managed) 
+  throws com.gemstone.gemfire.admin.AdminException {
+    return Helper.addDynamicAttributes(this, managed);
+  }
+
+  /**
+   * Cleans up Managed Resources created for the client that was connected to
+   * the server represented by this class.
+   * 
+   * @param clientId
+   *          id of the client to be removed
+   * @return List of ManagedResources associated with the client of given client
+   *         id
+   */
+  /*
+   * This clean up is for the clients. The clients are started with a loner DM.
+   * Hence the clientId is not supposed to contain '/' as per 
+   * InternalDistributedMember.toString().
+   */
+  public List<ManagedResource> cleanupBridgeClientResources(String clientId) {
+    List<ManagedResource> returnedResources = new ArrayList<ManagedResource>();
+
+    String compatibleId = "id_"+MBeanUtil.makeCompliantMBeanNameProperty(clientId);
+    synchronized (this.managedStatisticsResourcesMap) {
+      Set<Entry<StatResource, StatisticResourceJmxImpl>> entrySet = this.managedStatisticsResourcesMap.entrySet();
+      
+      for (Iterator<Entry<StatResource, StatisticResourceJmxImpl>> it = entrySet.iterator(); it.hasNext();) {
+        Entry<StatResource, StatisticResourceJmxImpl> entry = it.next();
+        StatisticResourceJmxImpl resource = entry.getValue();
+        if (resource.getMBeanName().contains(compatibleId)) {
+          it.remove(); //remove matching entry
+          returnedResources.add(resource);
+        }
+      }
+    }
+    return returnedResources;
+  }
+  
+  /**
+   * Implementation handles client membership changes.
+   * 
+   * @param clientId
+   *          id of the client for whom membership change happened
+   * @param eventType
+   *          membership change type; one of
+   *          {@link ClientMembershipMessage#JOINED},
+   *          {@link ClientMembershipMessage#LEFT}, 
+   *          {@link ClientMembershipMessage#CRASHED}
+   */
+  public void handleClientMembership(String clientId, int eventType) {
+    String notifType                = null;
+    List<ManagedResource> cleanedUp = null;
+    
+    if (eventType == ClientMembershipMessage.LEFT) {
+      notifType = NOTIF_CLIENT_LEFT;
+      cleanedUp = cleanupBridgeClientResources(clientId);
+    } else if (eventType == ClientMembershipMessage.CRASHED) {
+      notifType = NOTIF_CLIENT_CRASHED;
+      cleanedUp = cleanupBridgeClientResources(clientId);
+    } else if (eventType == ClientMembershipMessage.JOINED) {
+      notifType = NOTIF_CLIENT_JOINED;
+    }
+    
+    if (cleanedUp != null) {
+      for (ManagedResource resource : cleanedUp) {
+        MBeanUtil.unregisterMBean(resource);
+      }
+    }
+
+    Helper.sendNotification(this, 
+        new Notification(notifType, this.modelMBean, 
+        Helper.getNextNotificationSequenceNumber(),
+        clientId));
+  }
+  
+  /**
+   * Implementation handles creation of cache by extracting the details from the 
+   * given event object and sending the 
+   * {@link SystemMemberJmx#NOTIF_CACHE_CREATED} notification to the connected 
+   * JMX Clients.
+   * 
+   * @param event
+   *          event object corresponding to the creation of the cache
+   */
+  public void handleCacheCreate(SystemMemberCacheEvent event) {
+    Helper.sendNotification(this, 
+      new Notification(NOTIF_CACHE_CREATED, this.modelMBean, 
+      Helper.getNextNotificationSequenceNumber(),
+      Helper.getCacheEventDetails(event)));
+  }  
+
+  /**
+   * Implementation handles closure of cache by extracting the details from the 
+   * given event object and sending the
+   * {@link SystemMemberJmx#NOTIF_CACHE_CLOSED} notification to the connected 
+   * JMX Clients. 
+   * 
+   * @param event
+   *          event object corresponding to the closure of the cache
+   */
+  public void handleCacheClose(SystemMemberCacheEvent event) {
+    Helper.sendNotification(this, 
+        new Notification(NOTIF_CACHE_CLOSED, this.modelMBean, 
+        Helper.getNextNotificationSequenceNumber(),
+        Helper.getCacheEventDetails(event)));
+  }
+
+  /**
+   * Implementation handles creation of region by extracting the details from 
+   * the given event object and sending the
+   * {@link SystemMemberJmx#NOTIF_REGION_CREATED} notification to the connected 
+   * JMX Clients. Region Path is set as User Data in Notification. 
+   * 
+   * @param event
+   *          event object corresponding to the creation of a region
+   */
+  public void handleRegionCreate(SystemMemberRegionEvent event) {
+    Notification notification = new Notification(NOTIF_REGION_CREATED, 
+                                    this.modelMBean, 
+                                    Helper.getNextNotificationSequenceNumber(),
+                                    Helper.getRegionEventDetails(event));
+    
+    notification.setUserData(event.getRegionPath());
+
+    Helper.sendNotification(this, notification);
+  }
+
+  /**
+   * Implementation should handle loss of region by extracting the details from 
+   * the given event object and sending the
+   * {@link SystemMemberJmx#NOTIF_REGION_LOST} notification to the connected 
+   * JMX Clients. Region Path is set as User Data in Notification. Additionally, 
+   * it also clears the ManagedResources created for the region that is lost. 
+   * 
+   * @param event
+   *          event object corresponding to the loss of a region
+   */
+  public void handleRegionLoss(SystemMemberRegionEvent event) {
+    SystemMemberCacheJmxImpl cacheResource = this.managedSystemMemberCache;
+    
+    if (cacheResource != null) {
+      ManagedResource cleanedUp = 
+                cacheResource.cleanupRegionResources(event.getRegionPath());
+      
+      if (cleanedUp != null) {
+        MBeanUtil.unregisterMBean(cleanedUp);
+      }
+    }
+
+    Notification notification = new Notification(NOTIF_REGION_LOST, 
+                                    this.modelMBean, 
+                                    Helper.getNextNotificationSequenceNumber(),
+                                    Helper.getRegionEventDetails(event));
+    
+    notification.setUserData(event.getRegionPath());
+
+    Helper.sendNotification(this, notification);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/ConfigAttributeInfo.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/ConfigAttributeInfo.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/ConfigAttributeInfo.java
new file mode 100755
index 0000000..6b11710
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/ConfigAttributeInfo.java
@@ -0,0 +1,69 @@
+/*
+ *  =========================================================================
+ *  Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *  ========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+//import com.gemstone.gemfire.admin.ConfigurationParameter;
+import com.gemstone.gemfire.internal.Assert;
+
+import javax.management.Descriptor;
+import javax.management.modelmbean.DescriptorSupport;
+import javax.management.modelmbean.ModelMBeanAttributeInfo;
+
+/** 
+ * Subclass of AttributeInfo with {@link 
+ * com.gemstone.gemfire.admin.ConfigurationParameter} added for use as the 
+ * {@link javax.management.modelmbean.ModelMBeanAttributeInfo} descriptor's 
+ * <i>targetObject</i> value.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ */
+class ConfigAttributeInfo extends org.apache.commons.modeler.AttributeInfo {
+  private static final long serialVersionUID = -1918437700841687078L;
+  
+  private final ConfigurationParameterJmxImpl config;
+  
+  public ConfigAttributeInfo(ConfigurationParameterJmxImpl config) {
+    super();
+    this.config = config;
+  }
+  
+  public ConfigurationParameterJmxImpl getConfig() {
+    return this.config;
+  }
+
+  @Override
+  public ModelMBeanAttributeInfo createAttributeInfo() {
+    Descriptor desc = new DescriptorSupport(
+        new String[] {
+        "name=" + this.displayName,
+        "descriptorType=attribute",
+        "currencyTimeLimit=-1", // always stale
+        "displayName=" + this.displayName,
+        "getMethod=getJmxValue",
+        "setMethod=setJmxValue" 
+        });
+        
+    Assert.assertTrue(this.config != null, "Config target object is null!");
+    desc.setField("targetObject", this.config);
+
+    ModelMBeanAttributeInfo info = new ModelMBeanAttributeInfo(
+        this.displayName, // name
+        this.type,        // type
+        this.description, // description
+        this.readable,    // isReadable
+        this.writeable,   // isWritable
+        this.is,          // isIs
+        desc);
+        
+    return info;
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/ConfigurationParameterJmxImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/ConfigurationParameterJmxImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/ConfigurationParameterJmxImpl.java
new file mode 100755
index 0000000..e75fa02
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/ConfigurationParameterJmxImpl.java
@@ -0,0 +1,161 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.apache.logging.log4j.Level;
+
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.admin.UnmodifiableConfigurationException;
+import com.gemstone.gemfire.internal.Assert;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+/**
+ * Provides MBean support for managing accessing a ConfigurationParameter.
+ * <p>
+ * Implements java.io.Serializable because several MBeans have attributes of
+ * type ConfigurationParameter. This means that calls to getMBeanInfo which
+ * may be serialized for remote clients will be broken unless those attributes
+ * support serialization.
+ * <p>
+ * TODO: refactor to implement ConfigurationParameter and delegate to 
+ * ConfigurationParameterImpl. Wrap all delegate calls w/ e.printStackTrace()
+ * since the HttpAdaptor devours them
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ */
+public class ConfigurationParameterJmxImpl
+extends com.gemstone.gemfire.admin.internal.ConfigurationParameterImpl
+implements Serializable {
+
+  private static final long serialVersionUID = -7822171853906772375L;
+  private boolean deserialized = false;
+  
+  // -------------------------------------------------------------------------
+  //   Constructor(s)
+  // -------------------------------------------------------------------------
+  
+  protected ConfigurationParameterJmxImpl(String name,
+                                          String description,
+                                          Object value,
+                                          Class type,
+                                          boolean userModifiable) {
+    super(name, description, value, type, userModifiable);
+  }
+  
+  protected ConfigurationParameterJmxImpl(String name,
+                                          Object value) {
+    super(name, value);
+  }
+  
+  /** Constructor to allow serialization */
+  protected ConfigurationParameterJmxImpl() { super(); }
+  
+  @Override
+  public void setValue(Object value) throws UnmodifiableConfigurationException {
+    if (deserialized) {
+      throw new UnsupportedOperationException(LocalizedStrings.ConfigurationParameterJmxImpl_REMOTE_MUTATION_OF_CONFIGURATIONPARAMETER_IS_CURRENTLY_UNSUPPORTED.toLocalizedString());
+    }
+    try {
+      super.setValue(value);
+    } catch (UnmodifiableConfigurationException e) {
+      MBeanUtil.logStackTrace(Level.WARN, e);
+      throw e;
+    } catch (java.lang.RuntimeException e) {
+      MBeanUtil.logStackTrace(Level.WARN, e);
+      throw 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 (java.lang.Error 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();
+      MBeanUtil.logStackTrace(Level.ERROR, e);
+      throw e;
+    }
+  }
+  
+  // -------------------------------------------------------------------------
+  //   HACK
+  // -------------------------------------------------------------------------
+  public void setJmxValue(Integer value) throws UnmodifiableConfigurationException {
+    setValue(value);
+  }
+  public void setJmxValue(String value) throws UnmodifiableConfigurationException {
+    setValue(value);
+  }
+  public void setJmxValue(java.io.File value) throws UnmodifiableConfigurationException {
+    setValue(value);
+  }
+  public void setJmxValue(Boolean value) throws UnmodifiableConfigurationException {
+    setValue(value);
+  }
+  
+  public Class getJmxValueType() {
+    if (isInetAddress() || isFile() || isOctal()) {
+      return java.lang.String.class;
+    }
+    return getValueType();
+  }
+  
+  public Object getJmxValue() {
+    if (isInetAddress() || isFile() || isOctal()) {
+      return getValueAsString();
+    }
+    return getValue();
+  }
+  
+  /** 
+   * Override writeObject which is used in serialization. This class is
+   * serialized when JMX client acquires MBeanInfo for ConfigurationParameter
+   * MBean. Super class is not serializable.
+   */
+  private void writeObject(java.io.ObjectOutputStream out)
+  throws IOException {
+    out.writeObject(this.name);
+    out.writeObject(this.description);
+    out.writeObject(this.value);
+    out.writeObject(this.type);
+    out.writeBoolean(this.userModifiable);
+  }
+  
+  /** 
+   * Override readObject which is used in serialization. Customize 
+   * serialization of this exception to avoid escape of InternalRole
+   * which is not Serializable. 
+   */
+  private void readObject(java.io.ObjectInputStream in)
+  throws IOException, ClassNotFoundException {
+    String inName = (String) in.readObject();
+    String inDescription = (String) in.readObject();
+    Object inValue = in.readObject();
+    Class inClass = (Class) in.readObject();
+    boolean inUserModifiable = in.readBoolean();
+    
+    Assert.assertTrue(inName != null);
+    Assert.assertTrue(inDescription != null);
+    Assert.assertTrue(inValue != null);
+    Assert.assertTrue(inClass != null);
+    
+    this.deserialized = true;
+    this.name = inName;
+    setInternalState(inDescription, inValue, inClass, inUserModifiable);
+  }
+     
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/DistributedSystemHealthConfigJmxImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/DistributedSystemHealthConfigJmxImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/DistributedSystemHealthConfigJmxImpl.java
new file mode 100644
index 0000000..1326aa1
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/DistributedSystemHealthConfigJmxImpl.java
@@ -0,0 +1,99 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import com.gemstone.gemfire.admin.*;
+import com.gemstone.gemfire.admin.internal.*;
+//import com.gemstone.gemfire.internal.admin.*;
+import javax.management.*;
+import javax.management.modelmbean.*;
+//import org.apache.commons.modeler.ManagedBean;
+
+/**
+ * The JMX "managed resource" that represents the configuration for
+ * the health of a distributed system.  Basically, it provides the
+ * behavior of <code>DistributedSystemHealthConfigImpl</code>, but
+ * does some JMX stuff like registering beans with the agent.
+ *
+ * @see GemFireHealthJmxImpl#createDistributedSystemHealthConfig
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ */
+public class DistributedSystemHealthConfigJmxImpl
+  extends DistributedSystemHealthConfigImpl 
+  implements ManagedResource {
+
+  /** The <code>GemFireHealth</code> that we help configure */
+  private GemFireHealth health;
+
+  /** The name of the MBean that will manage this resource */
+  private String mbeanName;
+
+  /** The ModelMBean that is configured to manage this resource */
+  private ModelMBean modelMBean;
+
+  /** The JMX object name of the MBean for this managed resource */
+  private final ObjectName objectName;
+
+  ///////////////////////  Constructors  ///////////////////////
+
+  /**
+   * Creates a new <code>DistributedSystemHealthCOnfigJmxImpl</code>
+   * that configures the health of the distributed system monitored by
+   * <code>health</code>.
+   */
+  DistributedSystemHealthConfigJmxImpl(GemFireHealthJmxImpl health)
+    throws AdminException {
+
+    super();
+    this.health = health;
+    this.mbeanName = new StringBuffer()
+      .append(MBEAN_NAME_PREFIX)
+      .append("DistributedSystemHealthConfig,id=")
+      .append(MBeanUtil.makeCompliantMBeanNameProperty(health.getDistributedSystem().getId()))
+      .toString();
+    this.objectName = MBeanUtil.createMBean(this);
+  }
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  /**
+   * Applies the changes made to this config back to the health
+   * monitor.
+   *
+   * @see GemFireHealth#setDistributedSystemHealthConfig
+   */
+  public void applyChanges() {
+    this.health.setDistributedSystemHealthConfig(this);
+  }
+
+  public String getMBeanName() {
+    return this.mbeanName;
+  }
+  
+  public ModelMBean getModelMBean() {
+    return this.modelMBean;
+  }
+
+  public void setModelMBean(ModelMBean modelMBean) {
+    this.modelMBean = modelMBean;
+  }
+
+  public ManagedResourceType getManagedResourceType() {
+    return ManagedResourceType.DISTRIBUTED_SYSTEM_HEALTH_CONFIG;
+  }
+
+  public ObjectName getObjectName() {
+    return this.objectName;
+  }
+
+  public void cleanupResource() {}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/DistributionLocatorJmxImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/DistributionLocatorJmxImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/DistributionLocatorJmxImpl.java
new file mode 100755
index 0000000..d3800d0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/DistributionLocatorJmxImpl.java
@@ -0,0 +1,178 @@
+/*=========================================================================
+ *Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *All Rights Reserved.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+//import com.gemstone.gemfire.admin.AdminException;
+//import com.gemstone.gemfire.admin.DistributionLocator;
+import com.gemstone.gemfire.admin.DistributionLocatorConfig;
+import com.gemstone.gemfire.admin.internal.AdminDistributedSystemImpl;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+//import com.gemstone.gemfire.internal.Assert;
+
+//import org.apache.commons.modeler.ManagedBean;
+//import org.apache.commons.modeler.AttributeInfo;
+
+//import java.util.Date;
+//import java.util.Set;
+
+//import javax.management.Attribute;
+//import javax.management.AttributeList;
+//import javax.management.Descriptor;
+//import javax.management.JMException;
+//import javax.management.MBeanServer;
+//import javax.management.MalformedObjectNameException;
+//import javax.management.Notification;
+//import javax.management.NotificationListener;
+import javax.management.ObjectName;
+//import javax.management.modelmbean.DescriptorSupport;
+import javax.management.modelmbean.ModelMBean;
+//import javax.management.modelmbean.ModelMBeanAttributeInfo;
+
+/**
+ * Provides MBean support for managing a distribution locator.
+ *
+ * @author    Kirk Lund
+ */
+public class DistributionLocatorJmxImpl 
+extends com.gemstone.gemfire.admin.internal.DistributionLocatorImpl
+implements com.gemstone.gemfire.admin.jmx.internal.ManagedResource,
+           DistributionLocatorConfig {
+
+  /** The JMX object name of this managed resource */
+  private ObjectName objectName;
+
+  // -------------------------------------------------------------------------
+  //   Constructor(s)
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Constructs new instance of DistributionLocatorJmxImpl for managing a
+   * distribution locator service via JMX.
+   */
+  public DistributionLocatorJmxImpl(DistributionLocatorConfig config,
+                                    AdminDistributedSystemImpl system) {
+    super(config, system);
+    initializeMBean();
+  }
+
+  /** Create and register the MBean to manage this resource */
+  private void initializeMBean() {
+    this.mbeanName = "GemFire:type=DistributionLocator,id=" + MBeanUtil.makeCompliantMBeanNameProperty(getId());
+    this.objectName =
+        MBeanUtil.createMBean(this, MBeanUtil.lookupManagedBean(this));
+  }
+
+  ////////////////////////  Configuration  ////////////////////////
+
+  public String getHost() {
+    return this.getConfig().getHost();
+  }
+
+  public void setHost(String host) {
+    this.getConfig().setHost(host);
+  }
+
+  public String getWorkingDirectory() {
+    return this.getConfig().getWorkingDirectory();
+  }
+
+  public void setWorkingDirectory(String dir) {
+    this.getConfig().setWorkingDirectory(dir);
+  }
+
+  public String getProductDirectory() {
+    return this.getConfig().getProductDirectory();
+  }
+
+  public void setProductDirectory(String dir) {
+    this.getConfig().setProductDirectory(dir);
+  }
+
+  public String getRemoteCommand() {
+    return this.getConfig().getRemoteCommand();
+  }
+
+  public void setRemoteCommand(String remoteCommand) {
+    this.getConfig().setRemoteCommand(remoteCommand);
+  }
+
+  public java.util.Properties getDistributedSystemProperties() {
+    return this.getConfig().getDistributedSystemProperties();
+  }
+  
+  public void setDistributedSystemProperties(java.util.Properties props) {
+    this.getConfig().setDistributedSystemProperties(props);
+  }
+
+  public void validate() {
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+
+  @Override
+  public Object clone() throws CloneNotSupportedException {
+    throw new UnsupportedOperationException(LocalizedStrings.SHOULDNT_INVOKE.toLocalizedString());
+  }
+
+  public int getPort() {
+    return this.getConfig().getPort();
+  }
+
+  public void setPort(int port) {
+    this.getConfig().setPort(port);
+  }
+
+  public String getBindAddress() {
+    return this.getConfig().getBindAddress();
+  }
+
+  public void setBindAddress(String bindAddress) {
+    this.getConfig().setBindAddress(bindAddress);
+  }
+
+  // -------------------------------------------------------------------------
+  //   MBean attributes - accessors/mutators
+  // -------------------------------------------------------------------------
+  
+  // -------------------------------------------------------------------------
+  //   JMX Notification listener
+  // -------------------------------------------------------------------------
+
+  // -------------------------------------------------------------------------
+  //   ManagedResource implementation
+  // -------------------------------------------------------------------------
+  
+  /** The name of the MBean that will manage this resource */
+  private String mbeanName;
+
+  /** The ModelMBean that is configured to manage this resource */
+  private ModelMBean modelMBean;
+  
+	public String getMBeanName() {
+		return this.mbeanName;
+	}
+  
+	public ModelMBean getModelMBean() {
+		return this.modelMBean;
+	}
+	public void setModelMBean(ModelMBean modelMBean) {
+		this.modelMBean = modelMBean;
+	}
+  
+  public ObjectName getObjectName() {
+    return this.objectName;
+  }
+
+  public ManagedResourceType getManagedResourceType() {
+    return ManagedResourceType.DISTRIBUTION_LOCATOR;
+  }
+  
+  public void cleanupResource() {}
+  
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/DynamicManagedBean.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/DynamicManagedBean.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/DynamicManagedBean.java
new file mode 100755
index 0000000..a54d11a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/DynamicManagedBean.java
@@ -0,0 +1,134 @@
+/*
+ *  =========================================================================
+ *  Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *  ========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.modeler.AttributeInfo;
+import org.apache.commons.modeler.OperationInfo;
+import org.apache.commons.modeler.ManagedBean;
+
+/**
+ * Extends ManagedBean to allow for dynamically creating new instances of
+ * ManagedBean based on an existing instance of ManagedBean.
+ * 
+ * @author  Kirk Lund
+ * @since 5.0.1
+ */
+public class DynamicManagedBean extends org.apache.commons.modeler.ManagedBean {
+  private static final long serialVersionUID = 4051924500150228160L;
+  
+  public DynamicManagedBean(ManagedBean managed) {
+    super();
+    
+    this.attributes = managed.getAttributes();
+    this.className = managed.getClassName();
+    this.constructors = managed.getConstructors();
+    this.description = managed.getDescription();
+    this.domain = managed.getDomain();
+    this.group = managed.getGroup();
+    this.name = managed.getName();
+    this.fields = managed.getFields();
+    this.notifications = managed.getNotifications();
+    this.operations = managed.getOperations();
+    this.type = managed.getType();
+    
+    /* we don't use modelerType and it's nice to remove it to keep the list of 
+       attributes cleaned up...*/
+    removeAttribute("modelerType");
+  }
+
+  /**
+   * Removes an attribute from this ManagedBean's attribute descriptor list.
+   *
+   * @param name the attribute to be removed
+   */
+  public void removeAttribute(String name) {
+    if (name == null || name.length() < 1) {
+      return;
+    }
+    synchronized (this.attributes) {
+      List attributesList = new ArrayList(this.attributes.length);
+      for (int i = 0; i < this.attributes.length; i++) {
+        if (!name.equals(this.attributes[i].getName())) {
+          attributesList.add(this.attributes[i]);
+        }
+      }
+      this.attributes = (AttributeInfo[]) 
+          attributesList.toArray(new AttributeInfo[attributesList.size()]);
+      
+      /* super.info should be nulled out anytime the structure is changed,
+       * such as altering the attributes, operations, or notifications
+       *
+       * however super.info is private, so we need the following hack to cause
+       * the super class to null it out for us...
+       */
+      setType(this.type); // causes this in super: "this.info = null;"
+    }
+  }
+
+  /**
+   * Removes the operation with the given name from thie
+   * <code>ManageBean</code>'s operation descriptor list.
+   *
+   * @since 4.0
+   */
+  public void removeOperation(String name) {
+    if (name == null || name.length() < 1) {
+      return;
+    }
+
+    synchronized (operations) {
+      List operationsList = new ArrayList(this.operations.length);
+      for (int i = 0; i < this.operations.length; i++) {
+        if (!name.equals(this.operations[i].getName())) {
+          operationsList.add(this.operations[i]);
+        }
+      }
+      this.operations = (OperationInfo[]) 
+          operationsList.toArray(new OperationInfo[operationsList.size()]);
+      
+      /* super.info should be nulled out anytime the structure is changed,
+       * such as altering the operations, operations, or notifications
+       *
+       * however super.info is private, so we need the following hack to cause
+       * the super class to null it out for us...
+       */
+      setType(this.type); // causes this in super: "this.info = null;"
+    }
+  }
+
+  /**
+   * Return a string representation of this managed bean.
+   */
+  @Override
+  public String toString() {
+    StringBuffer sb = new StringBuffer("DynamicManagedBean[");
+    sb.append("name=");
+    sb.append(name);
+    sb.append(", className=");
+    sb.append(className);
+    sb.append(", description=");
+    sb.append(description);
+    if (group != null) {
+      sb.append(", group=");
+      sb.append(group);
+    }
+    sb.append(", type=");
+    sb.append(type);
+    sb.append(", attributes=");
+    sb.append(Arrays.asList(attributes));
+    sb.append("]");
+    return (sb.toString());
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/GemFireHealthConfigJmxImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/GemFireHealthConfigJmxImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/GemFireHealthConfigJmxImpl.java
new file mode 100644
index 0000000..478d344
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/GemFireHealthConfigJmxImpl.java
@@ -0,0 +1,214 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import com.gemstone.gemfire.admin.*;
+import com.gemstone.gemfire.admin.internal.*;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
+import javax.management.*;
+import javax.management.modelmbean.*;
+
+/**
+ * The JMX "managed resource" that represents the configuration for
+ * the health of GemFire.  Basically, it provides the behavior of
+ * <code>GemFireHealthConfigImpl</code>, but does some JMX stuff like
+ * registering beans with the agent.
+ *
+ * <P>
+ *
+ * Unlike other <code>ManagedResource</code>s this class cannot simply
+ * subclass <code>GemFireHealthImpl</code> because it instances are
+ * serialized and sent to other VMs.  This is problematic because the
+ * other VMs most likely do not have JMX classes like
+ * <code>ModelMBean</code> on their classpaths.  So, instead we
+ * delegate all of the <code>GemFireHealthConfig</code> behavior to
+ * another object which IS serialized.
+ *
+ * @see GemFireHealthJmxImpl#createDistributedSystemHealthConfig
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ */
+@SuppressFBWarnings(justification="This class is deprecated. Also, any further changes so close to the release is inadvisable.") 
+public class GemFireHealthConfigJmxImpl
+  implements GemFireHealthConfig, ManagedResource, java.io.Serializable {
+
+  private static final long serialVersionUID = 1482719647163239953L;
+
+  /** The <code>GemFireHealth</code> that we help configure */
+  private GemFireHealth health;
+
+  /** The name of the MBean that will manage this resource */
+  private String mbeanName;
+
+  /** The ModelMBean that is configured to manage this resource */
+  private ModelMBean modelMBean;
+
+  /** The delegate that contains the real config state */
+  private GemFireHealthConfig delegate;
+
+  /** The object name of this managed resource */
+  private ObjectName objectName;
+
+  ///////////////////////  Constructors  ///////////////////////
+
+  /**
+   * Creates a new <code>GemFireHealthConfigJmxImpl</code> that
+   * configures the health monitoring of components running on the
+   * given host.
+   */
+  GemFireHealthConfigJmxImpl(GemFireHealthJmxImpl health,
+                             String hostName)
+    throws AdminException {
+
+    this.delegate = new GemFireHealthConfigImpl(hostName);
+    this.health = health;
+    this.mbeanName = new StringBuffer()
+      .append(MBEAN_NAME_PREFIX)
+      .append("GemFireHealthConfig,id=")
+      .append(MBeanUtil.makeCompliantMBeanNameProperty(health.getDistributedSystem().getId()))
+      .append(",host=") 
+      .append((hostName == null ? "default" : MBeanUtil.makeCompliantMBeanNameProperty(hostName)))
+      .toString(); 
+    this.objectName = MBeanUtil.createMBean(this);
+  }
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  /**
+   * Applies the changes made to this config back to the health
+   * monitor.
+   *
+   * @see GemFireHealth#setDistributedSystemHealthConfig
+   */
+  public void applyChanges() {
+    String hostName = this.getHostName();
+    if (hostName == null) {
+      this.health.setDefaultGemFireHealthConfig(this);
+
+    } else {
+      this.health.setGemFireHealthConfig(hostName, this);
+    }
+  }
+
+  public String getMBeanName() {
+    return this.mbeanName;
+  }
+  
+  public ModelMBean getModelMBean() {
+    return this.modelMBean;
+  }
+
+  public ObjectName getObjectName() {
+    return this.objectName;
+  }
+
+  public void setModelMBean(ModelMBean modelMBean) {
+    this.modelMBean = modelMBean;
+  }
+
+  public ManagedResourceType getManagedResourceType() {
+    return ManagedResourceType.GEMFIRE_HEALTH_CONFIG;
+  }
+
+  /**
+   * Replace this object with the delegate that can be properly
+   * serialized. 
+   */
+  public Object writeReplace() {
+    return this.delegate;
+  }
+
+  //////////////////////  MemberHealthConfig  //////////////////////
+
+  public long getMaxVMProcessSize() {
+    return delegate.getMaxVMProcessSize();
+  }
+
+  public void setMaxVMProcessSize(long size) {
+    delegate.setMaxVMProcessSize(size);
+  }
+
+  public long getMaxMessageQueueSize() {
+    return delegate.getMaxMessageQueueSize();
+  }
+
+  public void setMaxMessageQueueSize(long maxMessageQueueSize) {
+    delegate.setMaxMessageQueueSize(maxMessageQueueSize);
+  }
+
+  public long getMaxReplyTimeouts() {
+    return delegate.getMaxReplyTimeouts();
+  }
+
+  public void setMaxReplyTimeouts(long maxReplyTimeouts) {
+    delegate.setMaxReplyTimeouts(maxReplyTimeouts);
+  }
+
+  public double getMaxRetransmissionRatio() {
+    return delegate.getMaxRetransmissionRatio();
+  }
+  
+  public void setMaxRetransmissionRatio(double ratio) {
+    delegate.setMaxRetransmissionRatio(ratio);
+  }
+
+  //////////////////////  CacheHealthConfig  //////////////////////
+
+    public long getMaxNetSearchTime() {
+    return delegate.getMaxNetSearchTime();
+  }
+
+  public void setMaxNetSearchTime(long maxNetSearchTime) {
+    delegate.setMaxNetSearchTime(maxNetSearchTime);
+  }
+
+  public long getMaxLoadTime() {
+    return delegate.getMaxLoadTime();
+  }
+
+  public void setMaxLoadTime(long maxLoadTime) {
+    delegate.setMaxLoadTime(maxLoadTime);
+  }
+
+  public double getMinHitRatio() {
+    return delegate.getMinHitRatio();
+  }
+
+  public void setMinHitRatio(double minHitRatio) {
+    delegate.setMinHitRatio(minHitRatio);
+  }
+
+  public long getMaxEventQueueSize() {
+    return delegate.getMaxEventQueueSize();
+  }
+
+  public void setMaxEventQueueSize(long maxEventQueueSize) {
+    delegate.setMaxEventQueueSize(maxEventQueueSize);
+  }
+
+  //////////////////////  GemFireHealthConfig  //////////////////////
+
+  public String getHostName() {
+    return delegate.getHostName();
+  }
+
+  public void setHealthEvaluationInterval(int interval) {
+    delegate.setHealthEvaluationInterval(interval);
+  }
+
+  public int getHealthEvaluationInterval() {
+    return delegate.getHealthEvaluationInterval();
+  }
+
+  public void cleanupResource() {}
+  
+}


[15/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClientMetadataService.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClientMetadataService.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClientMetadataService.java
new file mode 100755
index 0000000..f3c17b5
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClientMetadataService.java
@@ -0,0 +1,835 @@
+/*
+ * ========================================================================= 
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved. 
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ * =========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.EntryOperation;
+import com.gemstone.gemfire.cache.FixedPartitionResolver;
+import com.gemstone.gemfire.cache.Operation;
+import com.gemstone.gemfire.cache.PartitionResolver;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.cache.BucketServerLocation66;
+import com.gemstone.gemfire.internal.cache.EntryOperationImpl;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.cache.PartitionedRegionHelper;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * Maintains {@link ClientPartitionAdvisor} for Partitioned Regions on servers
+ * Client operations will consult this service to identify the server locations
+ * on which the data for the client operation is residing
+ * 
+ * @author Suranjan Kumar
+ * @author Yogesh Mahajan
+ * 
+ * @since 6.5
+ * 
+ */
+public final class ClientMetadataService {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  private final Cache cache;
+  
+  private final Set<String> nonPRs = new HashSet<String>();
+
+  private boolean HONOUR_SERVER_GROUP_IN_PR_SINGLE_HOP = Boolean.getBoolean("gemfire.PoolImpl.honourServerGroupsInPRSingleHop");
+
+  public static final int SIZE_BYTES_ARRAY_RECEIVED = 2;
+  
+  public static final int INITIAL_VERSION = 0;
+  
+  /** random number generator used in pruning */
+  private final Random rand = new Random();
+  
+  public ClientMetadataService(Cache cache) {
+    this.cache = cache;
+  }
+
+  private final Map<String, ClientPartitionAdvisor> clientPRAdvisors = new ConcurrentHashMap<String, ClientPartitionAdvisor>();
+  private final Map<String, Set<ClientPartitionAdvisor>> colocatedPRAdvisors = new ConcurrentHashMap<String, Set<ClientPartitionAdvisor>>();
+  
+  private PartitionResolver getResolver(Region r, Object key,
+      Object callbackArgument) {
+    // First choice is one associated with the region
+    final String regionFullPath = r.getFullPath();
+    ClientPartitionAdvisor advisor = this
+        .getClientPartitionAdvisor(regionFullPath);
+    PartitionResolver result = null;
+    if (advisor != null) {
+      result = advisor.getPartitionResolver();
+    }
+    
+    if (result != null) {
+      return result;
+    }
+
+    // Second is the key
+    if (key != null && key instanceof PartitionResolver) {
+      return (PartitionResolver)key;
+    }
+
+    // Third is the callback argument
+    if (callbackArgument != null
+        && callbackArgument instanceof PartitionResolver) {
+      return (PartitionResolver)callbackArgument;
+    }
+    // There is no resolver.
+    return null;
+  }
+
+  public ServerLocation getBucketServerLocation(Region region,
+      Operation operation, Object key, Object value, Object callbackArg) {
+    ClientPartitionAdvisor prAdvisor  = this.getClientPartitionAdvisor(region.getFullPath());
+    if (prAdvisor == null) {
+      return null;
+    }
+    int totalNumberOfBuckets = prAdvisor.getTotalNumBuckets();
+
+    final PartitionResolver resolver = getResolver(region, key, callbackArg);
+    Object resolveKey;
+    EntryOperation entryOp = null;
+    if (resolver == null) {
+      // client has not registered PartitionResolver
+      // Assuming even PR at server side is not using PartitionResolver
+      resolveKey = key;
+    }
+    else {
+      entryOp = new EntryOperationImpl(region, operation, key,
+          value, callbackArg);
+      resolveKey = resolver.getRoutingObject(entryOp);
+      if (resolveKey == null) {
+        throw new IllegalStateException(
+            LocalizedStrings.PartitionedRegionHelper_THE_ROUTINGOBJECT_RETURNED_BY_PARTITIONRESOLVER_IS_NULL
+                .toLocalizedString());
+      }
+    }
+    int bucketId;
+    if (resolver instanceof FixedPartitionResolver) {
+      if (entryOp == null) {
+        entryOp = new EntryOperationImpl(region,
+            Operation.FUNCTION_EXECUTION, key, null, null);
+      }
+      String partition = ((FixedPartitionResolver)resolver).getPartitionName(
+          entryOp, prAdvisor.getFixedPartitionNames());
+      if (partition == null) {
+        Object[] prms = new Object[] { region.getName(), resolver };
+        throw new IllegalStateException(
+            LocalizedStrings.PartitionedRegionHelper_FOR_REGION_0_PARTITIONRESOLVER_1_RETURNED_PARTITION_NAME_NULL
+                .toLocalizedString(prms));
+      }
+      else {
+        bucketId = prAdvisor.assignFixedBucketId(region, partition, resolveKey);
+        if (bucketId == -1) {
+          // scheduleGetPRMetaData((LocalRegion)region);
+          return null;
+        }
+
+      }
+    }else {
+      bucketId = PartitionedRegionHelper.getHashKey(resolveKey, totalNumberOfBuckets);
+    }
+    
+    ServerLocation bucketServerLocation = getServerLocation(region, operation,
+        bucketId);
+    ServerLocation location = null;
+    if (bucketServerLocation != null)
+      location = new ServerLocation(bucketServerLocation.getHostName(),
+          bucketServerLocation.getPort());
+    return location;
+  }
+
+  private ServerLocation getServerLocation(Region region, Operation operation,
+      int bucketId) {
+    final String regionFullPath = region.getFullPath();
+    ClientPartitionAdvisor prAdvisor = this.getClientPartitionAdvisor(regionFullPath);
+    if (prAdvisor == null) {
+      if (logger.isDebugEnabled()) {
+        logger.debug("ClientMetadataService#getServerLocation : Region {} prAdvisor does not exist.", regionFullPath);
+      }
+      return null;
+    }
+    
+//    if (prAdvisor.getColocatedWith() != null) {
+//      prAdvisor = this.getClientPartitionAdvisor(prAdvisor.getColocatedWith());
+//      if (prAdvisor == null) {
+//        if (this.logger.fineEnabled()) {
+//          this.logger.fine(
+//              "ClientMetadataService#getServerLocation : Region "
+//                  + regionFullPath + "prAdvisor does not exist.");
+//        }
+//        return null;
+//      }
+//    }
+    
+    if (operation.isGet()) {
+      return prAdvisor.adviseServerLocation(bucketId);
+    }
+    else {
+      return prAdvisor.advisePrimaryServerLocation(bucketId);
+    }
+  }
+
+  public Map<ServerLocation, HashSet> getServerToFilterMap(
+	      final Collection routingKeys, final Region region, boolean primaryMembersNeeded
+	     ) {
+	  return getServerToFilterMap(routingKeys, region, primaryMembersNeeded, false);
+  }
+  
+  public Map<ServerLocation, HashSet> getServerToFilterMap(
+      final Collection routingKeys, final Region region, boolean primaryMembersNeeded,
+      boolean bucketsAsFilter) {
+    final String regionFullPath = region.getFullPath();
+    ClientPartitionAdvisor prAdvisor = this.getClientPartitionAdvisor(regionFullPath);
+    if (prAdvisor == null || prAdvisor.adviseRandomServerLocation() == null) {
+      scheduleGetPRMetaData((LocalRegion)region, false);
+      return null;
+    }
+    HashMap<Integer, HashSet> bucketToKeysMap = groupByBucketOnClientSide(
+        region, prAdvisor, routingKeys, bucketsAsFilter);
+
+    HashMap<ServerLocation, HashSet> serverToKeysMap = new HashMap<ServerLocation, HashSet>();
+    HashMap<ServerLocation, HashSet<Integer>> serverToBuckets = groupByServerToBuckets(
+        prAdvisor, bucketToKeysMap.keySet(), primaryMembersNeeded);
+    
+    if(serverToBuckets == null){
+      return null;
+    }
+    
+    for (Map.Entry entry : serverToBuckets.entrySet()) {
+      ServerLocation server = (ServerLocation)entry.getKey();
+      HashSet<Integer> buckets = (HashSet)entry.getValue();
+      for (Integer bucket : buckets) {
+        // use LinkedHashSet to maintain the order of keys
+        // the keys will be iterated several times
+        LinkedHashSet keys = (LinkedHashSet)serverToKeysMap.get(server);
+        if (keys == null) {
+          keys = new LinkedHashSet();
+        }
+        keys.addAll(bucketToKeysMap.get(bucket));
+        serverToKeysMap.put(server, keys);
+      }
+    }
+    if (logger.isDebugEnabled()) {
+      logger.debug("Returning server to keys map : {}", serverToKeysMap);
+    }
+
+    return serverToKeysMap;
+  }
+  
+  public HashMap<ServerLocation, HashSet<Integer>> groupByServerToAllBuckets(Region region, boolean primaryOnly){
+    final String regionFullPath = region.getFullPath();
+    ClientPartitionAdvisor prAdvisor = this.getClientPartitionAdvisor(regionFullPath);
+    if (prAdvisor == null || prAdvisor.adviseRandomServerLocation() == null) {
+      scheduleGetPRMetaData((LocalRegion)region, false);
+      return null;
+    }
+    int totalNumberOfBuckets = prAdvisor.getTotalNumBuckets();
+    HashSet<Integer> allBucketIds = new HashSet<Integer>();
+    for(int i =0; i < totalNumberOfBuckets; i++){
+      allBucketIds.add(i);
+    }
+    return groupByServerToBuckets(prAdvisor, allBucketIds, primaryOnly);
+  }
+  /**
+   * This function should make a map of server to buckets it is hosting.
+   * If for some bucket servers are not available due to mismatch in metadata
+   * it should fill up a random server for it.
+   */
+  private HashMap<ServerLocation, HashSet<Integer>> groupByServerToBuckets(
+      ClientPartitionAdvisor prAdvisor, Set<Integer> bucketSet,
+      boolean primaryOnly) {
+    if (primaryOnly) {
+      Set<Integer> bucketsWithoutServer = new HashSet<Integer>();
+      HashMap<ServerLocation, HashSet<Integer>> serverToBucketsMap = new HashMap<ServerLocation, HashSet<Integer>>();
+      for (Integer bucketId : bucketSet) {
+        ServerLocation server = prAdvisor.advisePrimaryServerLocation(bucketId);
+        if (server == null) {
+          bucketsWithoutServer.add(bucketId);          
+          continue;
+        }
+        HashSet<Integer> buckets = serverToBucketsMap.get(server);
+        if (buckets == null) {
+          buckets = new HashSet<Integer>(); // faster if this was an ArrayList
+          serverToBucketsMap.put(server, buckets);
+        }
+        buckets.add(bucketId);
+      }
+
+      if (!serverToBucketsMap.isEmpty() ) {
+        serverToBucketsMap.entrySet().iterator().next().getValue().addAll(
+            bucketsWithoutServer);
+      }
+      
+      if (logger.isDebugEnabled()) {
+        logger.debug("ClientMetadataService: The server to bucket map is : {}", serverToBucketsMap);
+      }
+
+      return serverToBucketsMap;
+    }
+    else {
+      return pruneNodes(prAdvisor, bucketSet);
+    }
+  }
+  
+  
+  private HashMap<ServerLocation, HashSet<Integer>> pruneNodes(
+      ClientPartitionAdvisor prAdvisor, Set<Integer> buckets) {
+    
+    final boolean isDebugEnabled = logger.isDebugEnabled();
+    if (isDebugEnabled) {
+      logger.debug("ClientMetadataService: The buckets to be pruned are: {}", buckets);
+    }
+    Set<Integer> bucketSetWithoutServer =  new HashSet<Integer>();
+    HashMap<ServerLocation, HashSet<Integer>> serverToBucketsMap = new HashMap<ServerLocation, HashSet<Integer>>();
+    HashMap<ServerLocation, HashSet<Integer>> prunedServerToBucketsMap = new HashMap<ServerLocation, HashSet<Integer>>();
+
+    for (Integer bucketId : buckets) {
+      List<BucketServerLocation66> serversList = prAdvisor
+          .adviseServerLocations(bucketId);
+      if (isDebugEnabled) {
+        logger.debug("ClientMetadataService: For bucketId {} the server list is {}", bucketId, serversList);
+      }
+      if ((serversList == null || serversList.size() == 0) ) {       
+        bucketSetWithoutServer.add(bucketId);        
+        continue;
+      }
+      
+      if (isDebugEnabled) {
+        logger.debug("ClientMetadataService: The buckets owners of the bucket: {} are: {}", bucketId, serversList);
+      }
+      
+      for (ServerLocation server : serversList) {
+        if (serverToBucketsMap.get(server) == null) {
+          HashSet<Integer> bucketSet = new HashSet<Integer>();
+          bucketSet.add(bucketId);
+          serverToBucketsMap.put(server, bucketSet);
+        }
+        else {
+          HashSet<Integer> bucketSet = serverToBucketsMap.get(server);
+          bucketSet.add(bucketId);
+          serverToBucketsMap.put(server, bucketSet);
+        }
+      }
+    }
+    if (isDebugEnabled) {
+      logger.debug("ClientMetadataService: The server to buckets map is : {}", serverToBucketsMap);
+    }
+
+    HashSet<Integer> currentBucketSet = new HashSet<Integer>();
+    // ServerLocation randomFirstServer =
+    // prAdvisor.adviseRandomServerLocation(); // get a random server here
+    ServerLocation randomFirstServer = null;
+    if (serverToBucketsMap.isEmpty()) {
+      return null;
+    }
+    else {
+      int size = serverToBucketsMap.size();
+      randomFirstServer = (ServerLocation)serverToBucketsMap.keySet().toArray()[rand.nextInt(size)];
+    }
+    HashSet<Integer> bucketSet = serverToBucketsMap.get(randomFirstServer);
+    if (isDebugEnabled) {
+      logger.debug("ClientMetadataService: Adding the server : {} which is random and buckets {} to prunedMap", randomFirstServer, bucketSet);
+    }
+    currentBucketSet.addAll(bucketSet);
+    prunedServerToBucketsMap.put(randomFirstServer, bucketSet);
+    serverToBucketsMap.remove(randomFirstServer);
+
+    while (!currentBucketSet.equals(buckets)) {
+      ServerLocation server = findNextServer(serverToBucketsMap.entrySet(),
+          currentBucketSet);
+      if (server == null) {
+//        HashSet<Integer> rBuckets = prunedServerToBucketsMap
+//            .get(randomFirstServer);
+//        HashSet<Integer> remainingBuckets = new HashSet<Integer>(buckets);
+//        remainingBuckets.removeAll(currentBucketSet);
+//        rBuckets.addAll(remainingBuckets);
+//        prunedServerToBucketsMap.put(randomFirstServer, rBuckets);
+        break;
+      }
+      
+      HashSet<Integer> bucketSet2 = serverToBucketsMap.get(server);
+      bucketSet2.removeAll(currentBucketSet);
+      if(bucketSet2.isEmpty()) {
+        serverToBucketsMap.remove(server);
+        continue;
+      }
+      currentBucketSet.addAll(bucketSet2);
+      prunedServerToBucketsMap.put(server, bucketSet2);
+      if (isDebugEnabled) {
+        logger.debug("ClientMetadataService: Adding the server : {} and buckets {} to prunedServer.", server, bucketSet2);
+      }
+      serverToBucketsMap.remove(server);
+    }
+    prunedServerToBucketsMap.entrySet().iterator().next().getValue().addAll(
+        bucketSetWithoutServer);
+    
+    
+    if (isDebugEnabled) {
+      logger.debug("ClientMetadataService: The final prunedServerToBucket calculated is : {}", prunedServerToBucketsMap);
+    }
+    
+    return prunedServerToBucketsMap;
+  }
+  
+  
+  private ServerLocation findNextServer(
+      Set<Map.Entry<ServerLocation, HashSet<Integer>>> entrySet,
+      HashSet<Integer> currentBucketSet) {
+   
+    ServerLocation server = null;
+    int max = -1;
+    ArrayList<ServerLocation> nodesOfEqualSize = new ArrayList<ServerLocation>(); 
+    for (Map.Entry<ServerLocation, HashSet<Integer>> entry : entrySet) {
+      HashSet<Integer> buckets = new HashSet<Integer>();
+      buckets.addAll(entry.getValue());
+      buckets.removeAll(currentBucketSet);
+
+      if (max < buckets.size()) {
+        max = buckets.size();
+        server = entry.getKey();
+        nodesOfEqualSize.clear();
+        nodesOfEqualSize.add(server);
+      }
+      else if (max == buckets.size()){
+        nodesOfEqualSize.add(server);
+      }
+    }
+    
+    //return node;
+    Random r = new Random();
+    if(nodesOfEqualSize.size() > 0)
+      return nodesOfEqualSize.get(r.nextInt(nodesOfEqualSize.size()));
+    
+    return null; 
+  }
+  
+  private HashMap<Integer, HashSet> groupByBucketOnClientSide(Region region,
+      ClientPartitionAdvisor prAdvisor, Collection routingKeys, boolean bucketsAsFilter) {
+    
+    HashMap<Integer, HashSet> bucketToKeysMap = new HashMap();
+    int totalNumberOfBuckets = prAdvisor.getTotalNumBuckets();
+    Iterator i = routingKeys.iterator();
+    while (i.hasNext()) {
+      Object key = i.next();      
+      int bucketId = bucketsAsFilter ? ((Integer)key).intValue() :
+        extractBucketID(region, prAdvisor, totalNumberOfBuckets, key);
+      HashSet bucketKeys = bucketToKeysMap.get(bucketId);
+      if (bucketKeys == null) {
+        bucketKeys = new HashSet(); // faster if this was an ArrayList
+        bucketToKeysMap.put(bucketId, bucketKeys);
+      }
+      bucketKeys.add(key);
+    }
+    if (logger.isDebugEnabled()) {
+      logger.debug("Bucket to keys map : {}", bucketToKeysMap);
+    }
+    return bucketToKeysMap;
+  }
+
+  private int extractBucketID(Region region, ClientPartitionAdvisor prAdvisor,
+      int totalNumberOfBuckets, Object key) {
+    int bucketId = -1;
+    final PartitionResolver resolver = getResolver(region, key, null);
+    Object resolveKey;
+    EntryOperation entryOp = null;
+    if (resolver == null) {
+      // client has not registered PartitionResolver
+      // Assuming even PR at server side is not using PartitionResolver
+      resolveKey = key;
+    }
+    else {
+      entryOp = new EntryOperationImpl(region,
+          Operation.FUNCTION_EXECUTION, key, null, null);
+      resolveKey = resolver.getRoutingObject(entryOp);
+      if (resolveKey == null) {
+        throw new IllegalStateException(
+            LocalizedStrings.PartitionedRegionHelper_THE_ROUTINGOBJECT_RETURNED_BY_PARTITIONRESOLVER_IS_NULL
+                .toLocalizedString());
+      }
+    }
+   
+    if (resolver instanceof FixedPartitionResolver) {
+      if (entryOp == null) {
+        entryOp = new EntryOperationImpl(region,
+            Operation.FUNCTION_EXECUTION, key, null, null);
+      }
+      String partition = ((FixedPartitionResolver)resolver).getPartitionName(
+          entryOp, prAdvisor.getFixedPartitionNames());
+      if (partition == null) {
+        Object[] prms = new Object[] { region.getName(), resolver };
+        throw new IllegalStateException(
+            LocalizedStrings.PartitionedRegionHelper_FOR_REGION_0_PARTITIONRESOLVER_1_RETURNED_PARTITION_NAME_NULL
+                .toLocalizedString(prms));
+      }
+      else {
+        bucketId =  prAdvisor.assignFixedBucketId(region, partition, resolveKey);
+        // This bucketid can be -1 in some circumstances where we don't have information about 
+        // all the partition on the server.
+        // Do proactive scheduling of metadata fetch
+        if(bucketId == -1) {
+          scheduleGetPRMetaData((LocalRegion)region, true);
+        }
+      }
+    }else{
+      bucketId = PartitionedRegionHelper.getHashKey(resolveKey, totalNumberOfBuckets);
+    }
+    return bucketId;
+  }
+  
+  
+
+  public void scheduleGetPRMetaData(final LocalRegion region,
+      final boolean isRecursive) {
+    if(this.nonPRs.contains(region.getFullPath())){
+      return;
+    }
+    region.getCachePerfStats().incNonSingleHopsCount();
+    if (isRecursive) {
+      try {
+        getClientPRMetadata(region);
+      }
+      catch (VirtualMachineError e) {
+        SystemFailure.initiateFailure(e);
+        throw e;
+      }
+      catch (Throwable e) {
+        SystemFailure.checkFailure();
+        if (logger.isDebugEnabled()) {
+          logger.debug("An exception occurred while fetching metadata", e);
+        }
+      }
+    }
+    else {
+      Runnable fetchTask = new Runnable() {
+        @SuppressWarnings("synthetic-access")
+        public void run() {
+          try {
+            getClientPRMetadata(region);
+          }
+          catch (VirtualMachineError e) {
+            SystemFailure.initiateFailure(e);
+            throw e;
+          }
+          catch (Throwable e) {
+            SystemFailure.checkFailure();
+            if (logger.isDebugEnabled()) {
+              logger.debug("An exception occurred while fetching metadata", e);
+            }
+          }
+        }
+      };
+      SingleHopClientExecutor.submitTask(fetchTask);
+    }
+  }
+  
+  public final void getClientPRMetadata(LocalRegion region) {
+    final String regionFullPath = region.getFullPath();
+    ClientPartitionAdvisor advisor = null;
+    InternalPool pool = region.getServerProxy().getPool();
+    // Acquires lock only if it is free, else a request to fetch meta data is in
+    // progress, so just return 
+    if (region.clientMetaDataLock.tryLock()) {
+      try {
+        advisor = this.getClientPartitionAdvisor(regionFullPath);
+        if (advisor==null) {
+          advisor = GetClientPartitionAttributesOp
+              .execute(pool, regionFullPath);
+          if(advisor == null){
+            this.nonPRs.add(regionFullPath);
+            return;
+          }
+          addClientPartitionAdvisor(regionFullPath, advisor);
+        }
+        else {
+          if(advisor.getFixedPAMap() != null && !advisor.isFPAAttrsComplete()) {
+            ClientPartitionAdvisor newAdvisor = GetClientPartitionAttributesOp
+            .execute(pool, regionFullPath);
+            advisor.updateFixedPAMap(newAdvisor.getFixedPAMap());
+          }
+        }
+        String colocatedWith = advisor.getColocatedWith();
+        if (colocatedWith == null) {
+          isMetadataRefreshed_TEST_ONLY = true;
+          GetClientPRMetaDataOp.execute(pool, regionFullPath, this);
+          region.getCachePerfStats().incMetaDataRefreshCount();
+        }
+        else {
+          ClientPartitionAdvisor colocatedAdvisor = this.getClientPartitionAdvisor(colocatedWith);
+          LocalRegion leaderRegion = (LocalRegion)region.getCache()
+          .getRegion(colocatedWith);
+          if (colocatedAdvisor == null) {
+            scheduleGetPRMetaData(leaderRegion, true);
+            return;
+          }
+          else {
+            isMetadataRefreshed_TEST_ONLY = true;
+            GetClientPRMetaDataOp.execute(pool, colocatedWith, this);
+            leaderRegion.getCachePerfStats().incMetaDataRefreshCount();
+          }
+        }
+      }
+      finally {
+        region.clientMetaDataLock.unlock();
+      }
+    }
+  }
+  
+  public void scheduleGetPRMetaData(final LocalRegion region,
+      final boolean isRecursive, byte nwHopType) {
+    if(this.nonPRs.contains(region.getFullPath())){
+      return;
+    }
+    ClientPartitionAdvisor advisor = this.getClientPartitionAdvisor(region.getFullPath());
+    if(advisor!= null && advisor.getServerGroup().length()!= 0 && HONOUR_SERVER_GROUP_IN_PR_SINGLE_HOP){
+      if (logger.isDebugEnabled()) {
+        logger.debug("Scheduling metadata refresh : {}", nwHopType);
+      }
+      if(nwHopType == (byte)2){
+        return;
+      }
+    }
+    region.getCachePerfStats().incNonSingleHopsCount();
+    if (isRecursive) {
+      try {
+        getClientPRMetadata(region);
+      } catch (VirtualMachineError e) {
+        SystemFailure.initiateFailure(e);
+        throw e;
+      } catch (Throwable e) {
+        SystemFailure.checkFailure();
+        if (logger.isDebugEnabled()) {
+          logger.debug("An exception occurred while fetching metadata", e);
+        }
+      }
+    } else {
+      Runnable fetchTask = new Runnable() {
+        @SuppressWarnings("synthetic-access")
+        public void run() {
+          try {
+            getClientPRMetadata(region);
+          } catch (VirtualMachineError e) {
+            SystemFailure.initiateFailure(e);
+            throw e;
+          } catch (Throwable e) {
+            SystemFailure.checkFailure();
+            if (logger.isDebugEnabled()) {
+              logger.debug("An exception occurred while fetching metadata", e);
+            }
+          }
+        }
+      };
+      SingleHopClientExecutor.submitTask(fetchTask);
+    }
+  }
+
+  public void removeBucketServerLocation(ServerLocation serverLocation) {
+    Set<String> keys = getAllRegionFullPaths();
+    final boolean isDebugEnabled = logger.isDebugEnabled();
+    if (isDebugEnabled) {
+      logger.debug("ClientMetadataService removing a ServerLocation :{}{}", serverLocation, keys);
+    }
+    if (keys != null) {
+      for (String regionPath : keys) {
+        ClientPartitionAdvisor prAdvisor = this
+            .getClientPartitionAdvisor(regionPath);
+        if (isDebugEnabled) {
+          logger.debug("ClientMetadataService removing from {}{}", regionPath, prAdvisor);
+        }
+        if (prAdvisor != null) {
+          prAdvisor.removeBucketServerLocation(serverLocation);
+        }
+      }
+    }
+  }
+  
+  public byte getMetaDataVersion(Region region, Operation operation,
+      Object key, Object value, Object callbackArg) {
+    ClientPartitionAdvisor prAdvisor = this.getClientPartitionAdvisor(region
+        .getFullPath());
+    if (prAdvisor == null) {
+      return 0;
+    }
+
+    int totalNumberOfBuckets = prAdvisor.getTotalNumBuckets();
+
+    final PartitionResolver resolver = getResolver(region, key, callbackArg);
+    Object resolveKey;
+    EntryOperation entryOp = null;
+    if (resolver == null) {
+      // client has not registered PartitionResolver
+      // Assuming even PR at server side is not using PartitionResolver
+      resolveKey = key;
+    }
+    else {
+      entryOp = new EntryOperationImpl(region, operation, key,
+          value, callbackArg);
+      resolveKey = resolver.getRoutingObject(entryOp);
+      if (resolveKey == null) {
+        throw new IllegalStateException(
+            LocalizedStrings.PartitionedRegionHelper_THE_ROUTINGOBJECT_RETURNED_BY_PARTITIONRESOLVER_IS_NULL
+                .toLocalizedString());
+      }
+    }
+    
+    int bucketId;
+    if (resolver instanceof FixedPartitionResolver) {
+      if (entryOp == null) {
+        entryOp = new EntryOperationImpl(region,
+            Operation.FUNCTION_EXECUTION, key, null, null);
+      }
+      String partition = ((FixedPartitionResolver)resolver).getPartitionName(
+          entryOp, prAdvisor.getFixedPartitionNames());
+      if (partition == null) {
+        Object[] prms = new Object[] { region.getName(), resolver };
+        throw new IllegalStateException(
+            LocalizedStrings.PartitionedRegionHelper_FOR_REGION_0_PARTITIONRESOLVER_1_RETURNED_PARTITION_NAME_NULL
+                .toLocalizedString(prms));
+      }
+      else {
+        bucketId =  prAdvisor.assignFixedBucketId(region, partition, resolveKey);
+      }
+    }else {
+      bucketId = PartitionedRegionHelper.getHashKey(resolveKey, totalNumberOfBuckets);
+    }
+    
+    BucketServerLocation66 bsl = (BucketServerLocation66)getPrimaryServerLocation(
+        region, bucketId);
+    if (bsl == null) {
+      return 0;
+    }
+    return bsl.getVersion();
+  }
+
+  private ServerLocation getPrimaryServerLocation(Region region, int bucketId) {
+    final String regionFullPath = region.getFullPath();
+    ClientPartitionAdvisor prAdvisor = this.getClientPartitionAdvisor(regionFullPath);
+    if (prAdvisor == null) {
+      if (logger.isDebugEnabled()) {
+        logger.debug("ClientMetadataService#getServerLocation : Region {} prAdvisor does not exist.", regionFullPath);
+      }
+      return null;
+    }
+
+    if (prAdvisor.getColocatedWith() != null) {
+      prAdvisor = this.getClientPartitionAdvisor(prAdvisor.getColocatedWith());
+      if (prAdvisor == null) {
+        if (logger.isDebugEnabled()) {
+          logger.debug("ClientMetadataService#getServerLocation : Region {} prAdvisor does not exist.", regionFullPath);
+        }
+        return null;
+      }
+    }
+    return prAdvisor.advisePrimaryServerLocation(bucketId);
+  }
+  
+  private void addClientPartitionAdvisor(String regionFullPath,
+      ClientPartitionAdvisor advisor) {
+    if (this.cache.isClosed() || this.clientPRAdvisors == null) {
+      return;
+    }
+    try {
+      this.clientPRAdvisors.put(regionFullPath, advisor);
+      if (advisor.getColocatedWith() != null) {
+        String parentRegionPath = advisor.getColocatedWith();
+        Set<ClientPartitionAdvisor> colocatedAdvisors = this.colocatedPRAdvisors.get(parentRegionPath);
+        if(colocatedAdvisors == null){
+          colocatedAdvisors = new CopyOnWriteArraySet<ClientPartitionAdvisor>();
+          this.colocatedPRAdvisors.put(parentRegionPath, colocatedAdvisors);
+        }
+        colocatedAdvisors.add(advisor);
+      }
+    }
+    catch (Exception npe) {
+      // ignore, shutdown case
+    }
+    
+  }
+
+  public ClientPartitionAdvisor getClientPartitionAdvisor(String regionFullPath) {
+    if (this.cache.isClosed() || this.clientPRAdvisors == null) {
+      return null;
+    }
+    ClientPartitionAdvisor prAdvisor = null;
+    try {
+      prAdvisor = this.clientPRAdvisors.get(regionFullPath);
+    }
+    catch (Exception npe) {
+      return null;
+    }
+    return prAdvisor;
+  }
+  
+  public Set<ClientPartitionAdvisor> getColocatedClientPartitionAdvisor(String regionFullPath) {
+    if (this.cache.isClosed() || this.clientPRAdvisors == null || this.colocatedPRAdvisors == null) {
+      return null;
+    }
+    return this.colocatedPRAdvisors.get(regionFullPath);
+  }
+  
+  private Set<String> getAllRegionFullPaths() {
+    if (this.cache.isClosed() || this.clientPRAdvisors == null) {
+      return null;
+    }
+    Set<String> keys  = null;
+    try {
+      keys = this.clientPRAdvisors.keySet();
+    }
+    catch (Exception npe) {
+      return null;
+    }
+    return keys;
+  }
+
+  public void close() {
+    this.clientPRAdvisors.clear();
+    this.colocatedPRAdvisors.clear();
+  }
+  
+  public boolean isRefreshMetadataTestOnly() {
+    return isMetadataRefreshed_TEST_ONLY;
+  }
+
+  public void satisfyRefreshMetadata_TEST_ONLY(boolean isRefreshMetadataTestOnly) {
+    isMetadataRefreshed_TEST_ONLY = isRefreshMetadataTestOnly;
+  }
+
+  public Map<String, ClientPartitionAdvisor> getClientPRMetadata_TEST_ONLY() {
+    return clientPRAdvisors;
+  }
+
+  public Map<String, ClientPartitionAdvisor> getClientPartitionAttributesMap() {
+    return clientPRAdvisors;
+  }
+
+  public boolean honourServerGroup(){
+    return HONOUR_SERVER_GROUP_IN_PR_SINGLE_HOP;
+  }
+  
+  private boolean isMetadataRefreshed_TEST_ONLY = false;
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClientPartitionAdvisor.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClientPartitionAdvisor.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClientPartitionAdvisor.java
new file mode 100755
index 0000000..f060b7a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClientPartitionAdvisor.java
@@ -0,0 +1,279 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import com.gemstone.gemfire.InternalGemFireException;
+import com.gemstone.gemfire.cache.FixedPartitionAttributes;
+import com.gemstone.gemfire.internal.cache.BucketServerLocation66;
+import com.gemstone.gemfire.cache.PartitionResolver;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.ClassPathLoader;
+import com.gemstone.gemfire.internal.cache.BucketServerLocation;
+import com.gemstone.gemfire.internal.cache.FixedPartitionAttributesImpl;
+import com.gemstone.gemfire.internal.cache.BucketServerLocation66;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+/**
+ * Stores the information such as partition attributes and meta data details
+ * 
+ * @author Suranjan Kumar
+ * @author Yogesh Mahajan
+ * 
+ * @since 6.5
+ * 
+ */
+public class ClientPartitionAdvisor {
+
+  private final ConcurrentMap<Integer, List<BucketServerLocation66>> bucketServerLocationsMap 
+  = new ConcurrentHashMap<Integer, List<BucketServerLocation66>>();
+
+  private final int totalNumBuckets;
+
+  private String serverGroup = "";
+  
+  private final String colocatedWith;
+
+  private PartitionResolver partitionResolver = null;
+  
+  private Map<String, List<Integer>> fixedPAMap = null;
+
+  private boolean fpaAttrsCompletes = false;
+
+  @SuppressWarnings("unchecked")
+  public ClientPartitionAdvisor(int totalNumBuckets, String colocatedWith,
+      String partitionResolverName, Set<FixedPartitionAttributes> fpaSet) {
+
+    this.totalNumBuckets = totalNumBuckets;
+    this.colocatedWith = colocatedWith;
+    try {
+      if (partitionResolverName != null) {
+        this.partitionResolver = (PartitionResolver)
+            ClassPathLoader.getLatest().forName(partitionResolverName).newInstance();
+      }
+    }
+    catch (Exception e) {
+      e.printStackTrace();
+      throw new InternalGemFireException(LocalizedStrings.ClientPartitionAdvisor_CANNOT_CREATE_AN_INSTANCE_OF_PARTITION_RESOLVER_0.toLocalizedString(partitionResolverName));
+    }
+    if (fpaSet != null) {
+      fixedPAMap = new ConcurrentHashMap<String, List<Integer>>();
+      int totalFPABuckets = 0;
+      for (FixedPartitionAttributes fpa : fpaSet) {
+        List attrList = new ArrayList();
+        totalFPABuckets+=fpa.getNumBuckets();
+        attrList.add(fpa.getNumBuckets());
+        attrList.add(((FixedPartitionAttributesImpl)fpa).getStartingBucketID());
+        fixedPAMap.put(fpa.getPartitionName(), attrList);
+      }
+      if(totalFPABuckets == this.totalNumBuckets) {
+        this.fpaAttrsCompletes = true;
+      }
+    }
+  }
+
+  public ServerLocation adviseServerLocation(int bucketId) {
+    if (this.bucketServerLocationsMap.containsKey(bucketId)) {
+      List<BucketServerLocation66> locations = this.bucketServerLocationsMap
+          .get(bucketId);
+      List<BucketServerLocation66> locationsCopy = new ArrayList<BucketServerLocation66>(
+          locations);
+      // TODO: We need to consider Load Balancing Policy
+      if (locationsCopy.isEmpty()) {
+        return null;
+      }
+      if (locationsCopy.size() == 1) {
+        return locationsCopy.get(0);
+      }
+      int index = new Random().nextInt(locationsCopy.size() - 1);
+      return locationsCopy.get(index);
+    }
+    return null;
+  }
+
+  public ServerLocation adviseRandomServerLocation() {
+    ArrayList<Integer> bucketList = new ArrayList<Integer>(
+        this.bucketServerLocationsMap.keySet());
+
+    if (bucketList.size() > 0) {
+      Collections.shuffle(bucketList);
+      List<BucketServerLocation66> locations = this.bucketServerLocationsMap
+          .get(bucketList.get(0));
+
+      if (locations != null) {
+        List<BucketServerLocation66> serverList = new ArrayList<BucketServerLocation66>(
+            locations);
+        if (serverList.size() == 0)
+          return null;
+        return serverList.get(0);
+      }
+    }
+    return null;
+  }
+  
+  public List<BucketServerLocation66> adviseServerLocations(int bucketId) {
+    if (this.bucketServerLocationsMap.containsKey(bucketId)) {
+      List<BucketServerLocation66> locationsCopy = new ArrayList<BucketServerLocation66>(
+          this.bucketServerLocationsMap.get(bucketId));
+      return locationsCopy;
+    }
+    return null;
+  }
+  
+  public ServerLocation advisePrimaryServerLocation(int bucketId) {
+    if (this.bucketServerLocationsMap.containsKey(bucketId)) {
+      List<BucketServerLocation66> locations = this.bucketServerLocationsMap
+          .get(bucketId);
+      List<BucketServerLocation66> locationsCopy = new ArrayList<BucketServerLocation66>(
+          locations);
+      for (BucketServerLocation66 loc : locationsCopy) {
+        if (loc.isPrimary()) {
+          return loc;
+        }
+      }
+    }
+    return null;
+  }
+
+  public void updateBucketServerLocations(int bucketId,
+    List<BucketServerLocation66> bucketServerLocations, ClientMetadataService cms) {
+    List<BucketServerLocation66> locationCopy = new ArrayList<BucketServerLocation66>();
+    List<BucketServerLocation66> locations;
+    
+    boolean honourSeverGroup = cms.honourServerGroup();
+
+    if (this.serverGroup.length() != 0 && honourSeverGroup) {
+      for (BucketServerLocation66 s : bucketServerLocations) {
+        String[] groups = s.getServerGroups();
+        if (groups.length > 0) {
+          for (String str : groups) {
+            if (str.equals(this.serverGroup)) {
+              locationCopy.add(s);
+              break;
+            }
+          }
+        } else {
+          locationCopy.add(s);
+        }
+      }
+      locations = Collections.unmodifiableList(locationCopy);
+    } else {
+      locations = Collections.unmodifiableList(bucketServerLocations);
+    }
+    
+    this.bucketServerLocationsMap.put(bucketId, locations);
+  }
+
+  public void removeBucketServerLocation(ServerLocation serverLocation) {
+    Iterator<Map.Entry<Integer, List<BucketServerLocation66>>> iter = this.bucketServerLocationsMap
+        .entrySet().iterator();
+    while (iter.hasNext()) {
+      Map.Entry<Integer, List<BucketServerLocation66>> entry = iter.next();
+      Integer key = entry.getKey();
+      List<BucketServerLocation66> oldLocations = entry.getValue();
+      List<BucketServerLocation66> newLocations = new ArrayList<BucketServerLocation66>(
+          oldLocations);
+      // if this serverLocation contains in the list the remove the
+      // serverLocation and update the map with new List
+      while (newLocations.remove(serverLocation)
+          && !this.bucketServerLocationsMap.replace(key, oldLocations,
+              newLocations)) {
+        oldLocations = this.bucketServerLocationsMap.get(key);
+        newLocations = new ArrayList<BucketServerLocation66>(oldLocations);
+      }
+    }
+  }
+
+  public Map<Integer, List<BucketServerLocation66>> getBucketServerLocationsMap_TEST_ONLY() {
+    return this.bucketServerLocationsMap;
+  }
+
+  /**
+   * This method returns total number of buckets for a PartitionedRegion.
+   * 
+   * @return total number of buckets for a PartitionedRegion.
+   */
+  
+  public int getTotalNumBuckets() {
+    return this.totalNumBuckets;
+  }
+
+  /**
+   * @return the serverGroup
+   */
+  public String getServerGroup() {
+    return this.serverGroup;
+  }
+   
+
+  public void setServerGroup(String group) {
+    this.serverGroup = group;
+  }
+
+  /**
+   * Returns name of the colocated PartitionedRegion on CacheServer
+   */
+  public String getColocatedWith() {
+    return this.colocatedWith;
+  }
+
+  /**
+   * Returns the PartitionResolver set for custom partitioning
+   * 
+   * @return <code>PartitionResolver</code> for the PartitionedRegion
+   */
+  public PartitionResolver getPartitionResolver() {
+    return this.partitionResolver;
+  }
+
+  public Set<String> getFixedPartitionNames() {
+    return this.fixedPAMap.keySet();
+  }
+
+  public int assignFixedBucketId(Region region, String partition,
+      Object resolveKey) {
+    if (this.fixedPAMap.containsKey(partition)) {
+      List<Integer> attList = this.fixedPAMap.get(partition);
+      int hc = resolveKey.hashCode();
+      int bucketId = Math.abs(hc % (attList.get(0)));
+      int partitionBucketID = bucketId + attList.get(1);
+      return partitionBucketID;
+    }
+    else {
+      // We don't know as we might not have got the all FPAttributes
+      // from the FPR, So don't throw the exception but send the request
+      // to the server and update the FPA attributes
+      // This exception should be thrown from the server as we will
+      // not be sure of partition not available unless we contact the server.
+      return -1;
+    }
+  }
+  
+  public Map<String, List<Integer>> getFixedPAMap(){
+    return this.fixedPAMap;
+  }
+  
+  public void updateFixedPAMap(Map<String, List<Integer>> map) {
+    this.fixedPAMap.putAll(map);
+  }
+
+  public boolean isFPAAttrsComplete() {
+    return this.fpaAttrsCompletes;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClientRegionFactoryImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClientRegionFactoryImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClientRegionFactoryImpl.java
new file mode 100644
index 0000000..7526ff7
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClientRegionFactoryImpl.java
@@ -0,0 +1,262 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import com.gemstone.gemfire.cache.AttributesFactory;
+import com.gemstone.gemfire.cache.CacheListener;
+import com.gemstone.gemfire.cache.CustomExpiry;
+import com.gemstone.gemfire.cache.EvictionAttributes;
+import com.gemstone.gemfire.cache.ExpirationAttributes;
+import com.gemstone.gemfire.cache.InterestPolicy;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionAttributes;
+import com.gemstone.gemfire.cache.RegionExistsException;
+import com.gemstone.gemfire.cache.Scope;
+import com.gemstone.gemfire.cache.SubscriptionAttributes;
+import com.gemstone.gemfire.cache.client.ClientRegionFactory;
+import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
+import com.gemstone.gemfire.cache.client.Pool;
+import com.gemstone.gemfire.compression.Compressor;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.cache.UserSpecifiedRegionAttributes;
+
+/**
+ * The distributed system will always default to a loner on a client.
+ * 
+ * @author darrel
+ * @since 6.5
+ */
+
+public class ClientRegionFactoryImpl<K,V> implements ClientRegionFactory<K,V>
+{
+  private final AttributesFactory<K,V> attrsFactory;
+  private final GemFireCacheImpl cache;
+
+  /**
+   * Constructs a ClientRegionFactory by creating a DistributedSystem and a Cache. If
+   * no DistributedSystem exists it creates a loner DistributedSystem,
+   * otherwise it uses the existing DistributedSystem.
+   * A default pool will be used unless ...
+   * The Region
+   * configuration is initialized using the given region shortcut.
+   *
+   * @param pra
+   *          the region shortcut to use
+   */
+  public ClientRegionFactoryImpl(GemFireCacheImpl cache, ClientRegionShortcut pra) {
+    this.cache = cache;
+    RegionAttributes ra = cache.getRegionAttributes(pra.toString());
+    if (ra == null) {
+      throw new IllegalStateException("The region shortcut " + pra
+                                      + " has been removed.");
+    }
+    this.attrsFactory = new AttributesFactory<K,V>(ra);
+    initAttributeFactoryDefaults();
+  }
+
+  /**
+   * Constructs a ClientRegionFactory by creating a DistributedSystem and a Cache. If
+   * no DistributedSystem exists it creates a loner DistributedSystem,
+   * otherwise it uses the existing DistributedSystem.
+   * A default pool will be used unless ...
+   * The region configuration is initialized using a region attributes
+   * whose name was given as the refid.
+   *
+   * @param refid
+   *          the name of the region attributes to use
+   */
+  public ClientRegionFactoryImpl(GemFireCacheImpl cache, String refid) {
+    this.cache = cache;
+    RegionAttributes ra = cache.getRegionAttributes(refid);
+    if (ra == null) {
+      throw new IllegalStateException("The named region attributes \"" + refid
+                                      + "\" has not been defined.");
+    }
+    this.attrsFactory = new AttributesFactory<K,V>(ra);
+    initAttributeFactoryDefaults();
+  }
+
+  private void initAttributeFactoryDefaults() {
+    this.attrsFactory.setScope(Scope.LOCAL);
+    this.attrsFactory.setSubscriptionAttributes(new SubscriptionAttributes(InterestPolicy.ALL));
+//    this.attrsFactory.setIgnoreJTA(true);  in 6.6 and later releases client regions support JTA
+  }
+  
+  /**
+   * Returns the cache used by this factory.
+   */
+  private GemFireCacheImpl getCache() {
+    return this.cache;
+  }
+
+  private Pool getDefaultPool() {
+    return getCache().getDefaultPool();
+  }
+
+  public ClientRegionFactory<K,V> addCacheListener(CacheListener<K,V> aListener)
+  {
+    this.attrsFactory.addCacheListener(aListener);
+    return this;
+  }
+
+  public ClientRegionFactory<K,V> initCacheListeners(CacheListener<K,V>[] newListeners)
+  {
+    this.attrsFactory.initCacheListeners(newListeners);
+    return this;
+  }
+
+  public ClientRegionFactory<K,V> setEvictionAttributes(EvictionAttributes evictionAttributes) {
+    this.attrsFactory.setEvictionAttributes(evictionAttributes);
+    return this;
+  }
+
+  public ClientRegionFactory<K,V> setEntryIdleTimeout(ExpirationAttributes idleTimeout)
+  {
+    this.attrsFactory.setEntryIdleTimeout(idleTimeout);
+    return this;
+  }
+
+  public ClientRegionFactory<K,V> setCustomEntryIdleTimeout(CustomExpiry<K,V> custom) {
+    this.attrsFactory.setCustomEntryIdleTimeout(custom);
+    return this;
+  }
+  
+  public ClientRegionFactory<K,V> setEntryTimeToLive(ExpirationAttributes timeToLive)
+  {
+    this.attrsFactory.setEntryTimeToLive(timeToLive);
+    return this;
+  }
+
+  public ClientRegionFactory<K,V> setCustomEntryTimeToLive(CustomExpiry<K,V> custom) {
+    this.attrsFactory.setCustomEntryTimeToLive(custom);
+    return this;
+  }
+  
+  public ClientRegionFactory<K,V> setRegionIdleTimeout(ExpirationAttributes idleTimeout)
+  {
+    this.attrsFactory.setRegionIdleTimeout(idleTimeout);
+    return this;
+  }
+
+  public ClientRegionFactory<K,V> setRegionTimeToLive(ExpirationAttributes timeToLive)
+  {
+    this.attrsFactory.setRegionTimeToLive(timeToLive);
+    return this;
+  }
+
+  public ClientRegionFactory<K,V> setKeyConstraint(Class<K> keyConstraint)
+  {
+    this.attrsFactory.setKeyConstraint(keyConstraint);
+    return this;
+  }
+
+  public ClientRegionFactory<K,V> setValueConstraint(Class<V> valueConstraint)
+  {
+    this.attrsFactory.setValueConstraint(valueConstraint);
+    return this;
+  }
+
+  public ClientRegionFactory<K,V> setInitialCapacity(int initialCapacity)
+  {
+    this.attrsFactory.setInitialCapacity(initialCapacity);
+    return this;
+  }
+
+  public ClientRegionFactory<K,V> setLoadFactor(float loadFactor)
+  {
+    this.attrsFactory.setLoadFactor(loadFactor);
+    return this;
+  }
+
+  public ClientRegionFactory<K,V> setConcurrencyLevel(int concurrencyLevel)
+  {
+    this.attrsFactory.setConcurrencyLevel(concurrencyLevel);
+    return this;
+  }
+
+  public void setConcurrencyChecksEnabled(boolean concurrencyChecksEnabled) {
+    this.attrsFactory.setConcurrencyChecksEnabled(concurrencyChecksEnabled);
+  }
+
+  public ClientRegionFactory<K,V> setDiskStoreName(String name) {
+    this.attrsFactory.setDiskStoreName(name);
+    return this;
+  }
+  
+  public ClientRegionFactory<K,V> setDiskSynchronous(boolean isSynchronous)
+  {
+    this.attrsFactory.setDiskSynchronous(isSynchronous);
+    return this;
+  }
+
+  public ClientRegionFactory<K,V> setStatisticsEnabled(boolean statisticsEnabled)
+  {
+    this.attrsFactory.setStatisticsEnabled(statisticsEnabled);
+    return this;
+  }
+
+  public ClientRegionFactory<K,V> setCloningEnabled(boolean cloningEnable) {
+    this.attrsFactory.setCloningEnabled(cloningEnable);
+    return this;
+  }
+
+  public ClientRegionFactory<K,V> setPoolName(String poolName) {
+    this.attrsFactory.setPoolName(poolName);
+    return this;
+  }  
+  
+  @Override
+  public ClientRegionFactory<K, V> setCompressor(Compressor compressor) {
+    this.attrsFactory.setCompressor(compressor);
+    return this;
+  }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public Region<K,V> create(String name) throws RegionExistsException {
+    return getCache().basicCreateRegion(name, createRegionAttributes());
+  }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public Region<K,V> createSubregion(Region<?,?> parent, String name) throws RegionExistsException {
+    return ((LocalRegion)parent).createSubregion(name, createRegionAttributes());
+  }
+  
+  @SuppressWarnings("deprecation")
+  private RegionAttributes<K,V> createRegionAttributes() {
+    RegionAttributes<K,V> ra = this.attrsFactory.create();
+    if (ra.getPoolName() == null || "".equals(ra.getPoolName())) {
+      UserSpecifiedRegionAttributes<K, V> ura = (UserSpecifiedRegionAttributes<K, V>)ra;
+      if (ura.requiresPoolName) {
+        Pool dp = getDefaultPool();
+        if (dp != null) {
+          this.attrsFactory.setPoolName(dp.getName());
+          ra = this.attrsFactory.create();
+        } else {
+          throw new IllegalStateException("The poolName must be set on a client.");
+        }
+      }
+    }
+    return ra;
+  }
+
+  //  public ClientRegionFactory<K, V> addParallelGatewaySenderId(
+//      String parallelGatewaySenderId) {
+//    this.attrsFactory.addParallelGatewaySenderId(parallelGatewaySenderId);
+//    return this;
+//  }
+//
+//  public ClientRegionFactory<K, V> addSerialGatewaySenderId(
+//      String serialGatewaySenderId) {
+//    this.attrsFactory.addSerialGatewaySenderId(serialGatewaySenderId);
+//    return this;
+//  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClientUpdater.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClientUpdater.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClientUpdater.java
new file mode 100644
index 0000000..4333768
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClientUpdater.java
@@ -0,0 +1,27 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+/**
+ * @author dsmith
+ *
+ */
+public interface ClientUpdater {
+
+  void close();
+  
+  boolean isAlive();
+
+  void join(long wait) throws InterruptedException;
+  
+  public void setFailedUpdater(ClientUpdater failedUpdater);
+  
+  public boolean isProcessing();
+  
+  public boolean isPrimary();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/CloseConnectionOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/CloseConnectionOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/CloseConnectionOp.java
new file mode 100644
index 0000000..269a354
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/CloseConnectionOp.java
@@ -0,0 +1,86 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().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/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/CommitOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/CommitOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/CommitOp.java
new file mode 100644
index 0000000..0b2cc6c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/CommitOp.java
@@ -0,0 +1,100 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().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/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/Connection.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/Connection.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/Connection.java
new file mode 100644
index 0000000..99bf77f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/Connection.java
@@ -0,0 +1,75 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ServerQueueStatus;
+
+/**
+ * Represents a connection from a client to a server.
+ * Instances are created, kept, and used by {@link PoolImpl}.
+ * @author darrel
+ * @since 5.7
+ */
+public interface Connection {
+  public static final long DEFAULT_CONNECTION_ID = 26739;
+  
+  public Socket getSocket();
+  public ByteBuffer getCommBuffer();
+  public ConnectionStats getStats();
+  /**
+   * Forcefully close the resources used by this connection.
+   * This should be called if the connection or the server dies.
+   */
+  public void destroy();
+
+  /**
+   * Return true if this connection has been destroyed
+   */
+  public boolean isDestroyed();
+
+  /**
+   * Gracefully close the connection by notifying 
+   * the server. It is not necessary to call destroy
+   * after closing the connection.
+   * @param keepAlive What do do this server to
+   * client connection proxy on this server. 
+   * @throws Exception if there was an error notifying the server.
+   * The connection will still be destroyed.
+   */
+  public void close(boolean keepAlive) throws Exception;
+  
+  public ServerLocation getServer();
+  
+  public Endpoint getEndpoint();
+  
+  public ServerQueueStatus getQueueStatus();
+  
+  public Object execute(Op op) throws Exception;
+
+  public void emergencyClose();
+  
+  public short getWanSiteVersion();
+   
+  public void setWanSiteVersion(short wanSiteVersion);
+  
+  public int getDistributedSystemId();
+  
+  public OutputStream getOutputStream();
+  
+  public InputStream getInputStream();
+
+  public void setConnectionID(long id);
+
+  public long getConnectionID();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionFactory.java
new file mode 100644
index 0000000..390db3a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionFactory.java
@@ -0,0 +1,59 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.Set;
+
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.security.GemFireSecurityException;
+
+/**
+ * A factory for creating new connections.
+ * @author dsmith
+ * @since 5.7
+ *
+ */
+public interface ConnectionFactory {
+
+  /**
+   * Create a client to server connection to the given server
+   * @param location the server to connection
+   * @return a connection to that server, or null if 
+   * a connection could not be established.
+   * @throws GemFireSecurityException if there was a security exception 
+   * while trying to establish a connections.
+   */
+  Connection createClientToServerConnection(ServerLocation location, boolean forQueue)
+    throws GemFireSecurityException;
+
+  /**
+   * Returns the best server for this client to connect to.
+   * Returns null if no servers exist.
+   * @param currentServer if non-null then we are trying to replace a connection
+   *                      that we have to this server.
+   * @param excludedServers the list of servers
+   * to skip over when finding a server to connect to
+   */
+  ServerLocation findBestServer(ServerLocation currentServer, Set excludedServers);
+
+  /**
+   * Create a client to server connection to any server
+   * that is not in the excluded list.
+   * @param excludedServers the list of servers
+   * to skip over when finding a server to connect to
+   * @return a connection or null if 
+   * a connection could not be established.
+   * @throws GemFireSecurityException if there was a security exception
+   * trying to establish a connection.
+   */
+  Connection createClientToServerConnection(Set excludedServers) throws GemFireSecurityException;
+  
+  ClientUpdater createServerToClientConnection(Endpoint endpoint, QueueManager qManager, boolean isPrimary, ClientUpdater failedUpdater);
+  
+  ServerBlackList getBlackList();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionFactoryImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionFactoryImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionFactoryImpl.java
new file mode 100644
index 0000000..ae4b851
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionFactoryImpl.java
@@ -0,0 +1,305 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.CancelCriterion;
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.cache.GatewayConfigurationException;
+import com.gemstone.gemfire.cache.client.ServerRefusedConnectionException;
+import com.gemstone.gemfire.cache.client.internal.ServerBlackList.FailureTracker;
+import com.gemstone.gemfire.cache.wan.GatewaySender;
+import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.distributed.PoolCancelledException;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.cache.PoolManagerImpl;
+import com.gemstone.gemfire.internal.cache.tier.Acceptor;
+import com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientUpdater;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
+import com.gemstone.gemfire.internal.cache.tier.sockets.HandShake;
+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.security.GemFireSecurityException;
+
+/**
+ * Creates connections, using a connection source to determine
+ * which server to connect to.
+ * @author dsmith
+ * @since 5.7
+ * 
+ */
+public class ConnectionFactoryImpl implements ConnectionFactory {
+  
+  private static final Logger logger = LogService.getLogger();
+  
+  //TODO  - the handshake holds state. It seems like the code depends 
+  //on all of the handshake operations happening in a single thread. I don't think we
+  //want that, need to refactor.
+  private final HandShake handshake;
+  private final int socketBufferSize;
+  private final int handShakeTimeout;
+  private final boolean usedByGateway;
+  private final ServerBlackList blackList;
+  private final CancelCriterion cancelCriterion;
+  private ConnectionSource source;
+  private int readTimeout;
+  private DistributedSystem ds;
+  private EndpointManager endpointManager;
+  private GatewaySender gatewaySender;
+  private PoolImpl pool;
+  
+  /**
+   * Test hook for client version support
+   * @since 5.7
+   */
+  
+  public static boolean testFailedConnectionToServer = false;
+    
+  public ConnectionFactoryImpl(ConnectionSource source,
+      EndpointManager endpointManager, DistributedSystem sys,
+      int socketBufferSize, int handShakeTimeout, int readTimeout,
+      ClientProxyMembershipID proxyId, CancelCriterion cancelCriterion,
+      boolean usedByGateway, GatewaySender sender,long pingInterval,
+      boolean multiuserSecureMode, PoolImpl pool) {
+    this.handshake = new HandShake(proxyId, sys);
+    this.handshake.setClientReadTimeout(readTimeout);
+    this.source = source;
+    this.endpointManager = endpointManager;
+    this.ds = sys;
+    this.socketBufferSize = socketBufferSize;
+    this.handShakeTimeout = handShakeTimeout;
+    this.handshake.setMultiuserSecureMode(multiuserSecureMode);
+    this.readTimeout = readTimeout;
+    this.usedByGateway = usedByGateway;
+    this.gatewaySender = sender;
+    this.blackList = new ServerBlackList(pingInterval);
+    this.cancelCriterion = cancelCriterion;
+    this.pool = pool;
+  }
+  
+  public void start(ScheduledExecutorService background) {
+    blackList.start(background);
+  }
+
+  private byte getCommMode(boolean forQueue) {
+    if (this.usedByGateway || (this.gatewaySender != null)) {
+      return Acceptor.GATEWAY_TO_GATEWAY;
+    } else if(forQueue) {
+      return Acceptor.CLIENT_TO_SERVER_FOR_QUEUE;
+    } else {
+      return Acceptor.CLIENT_TO_SERVER;
+    }
+  }
+  
+  public ServerBlackList getBlackList() { 
+    return blackList;
+  }
+  
+  public Connection createClientToServerConnection(ServerLocation location, boolean forQueue)  throws GemFireSecurityException {
+    ConnectionImpl connection = new ConnectionImpl(this.ds, this.cancelCriterion);
+    FailureTracker failureTracker = blackList.getFailureTracker(location);
+    
+    boolean initialized = false;
+    
+    try {
+      HandShake connHandShake = new HandShake(handshake);
+      connection.connect(endpointManager, location, connHandShake,
+                         socketBufferSize, handShakeTimeout, readTimeout, getCommMode(forQueue), this.gatewaySender);
+      failureTracker.reset();
+      connection.setHandShake(connHandShake);
+      authenticateIfRequired(connection);
+      initialized = true;
+    } catch(CancelException e) {
+      //propagate this up, don't retry
+      throw e;
+    } catch(GemFireSecurityException e) {
+      //propagate this up, don't retry
+      throw e;
+    } catch(GatewayConfigurationException e) {
+    //propagate this up, don't retry
+      throw e;
+    } catch(ServerRefusedConnectionException src) {
+      //propagate this up, don't retry      	
+      logger.warn(LocalizedMessage.create(LocalizedStrings.AutoConnectionSourceImpl_COULD_NOT_CREATE_A_NEW_CONNECTION_TO_SERVER_0, src.getMessage()));
+      testFailedConnectionToServer = true;
+      throw src;
+    } catch (Exception e) {
+      if (e.getMessage() != null &&
+          (e.getMessage().equals("Connection refused")
+           || e.getMessage().equals("Connection reset"))) { // this is the most common case, so don't print an exception
+        if (logger.isDebugEnabled()) {
+          logger.debug("Unable to connect to {}: connection refused", location);
+        }
+      } else {//print a warning with the exception stack trace
+        logger.warn(LocalizedMessage.create(LocalizedStrings.ConnectException_COULD_NOT_CONNECT_TO_0, location), e);
+      }
+      testFailedConnectionToServer = true;
+    } finally {
+      if(!initialized) {
+        connection.destroy();
+        failureTracker.addFailure();
+        connection = null;
+      }
+    }
+    
+    return connection;
+  }
+
+  private void authenticateIfRequired(Connection conn) {
+    cancelCriterion.checkCancelInProgress(null);
+    if (!pool.isUsedByGateway() && !pool.getMultiuserAuthentication()) {
+      if (conn.getServer().getRequiresCredentials()) {
+        if (conn.getServer().getUserId() == -1) {
+          Long uniqueID = (Long)AuthenticateUserOp.executeOn(conn, pool);
+          conn.getServer().setUserId(uniqueID);
+          if (logger.isDebugEnabled()) {
+            logger.debug("CFI.authenticateIfRequired() Completed authentication on {}", conn);
+          }
+        }
+      }
+    }
+  }
+
+  public ServerLocation findBestServer(ServerLocation currentServer, Set excludedServers) {
+    if (currentServer != null && source.isBalanced()) {
+      return currentServer;
+    }
+    final Set origExcludedServers = excludedServers;
+    excludedServers = new HashSet(excludedServers);
+    Set blackListedServers = blackList.getBadServers();  
+    excludedServers.addAll(blackListedServers);
+    ServerLocation server = source.findReplacementServer(currentServer, excludedServers);
+    if (server == null) {
+      // Nothing worked! Let's try without the blacklist.
+      if (excludedServers.size() > origExcludedServers.size()) {
+        // We had some guys black listed so lets give this another whirl.
+        server = source.findReplacementServer(currentServer, origExcludedServers);
+      }
+    }
+    if (server == null && logger.isDebugEnabled()) {
+      logger.debug("Source was unable to findForReplacement any servers");
+    }
+    return server;
+  }
+  
+  public Connection createClientToServerConnection(Set excludedServers) throws GemFireSecurityException {
+    final Set origExcludedServers = excludedServers;
+    excludedServers = new HashSet(excludedServers);
+    Set blackListedServers = blackList.getBadServers();  
+    excludedServers.addAll(blackListedServers);
+    Connection conn = null;
+//    long startTime = System.currentTimeMillis();
+    RuntimeException fatalException = null;
+    boolean tryBlackList = true;
+    
+    do {
+      ServerLocation server = source.findServer(excludedServers);
+      if(server == null) {
+        
+        if(tryBlackList) {
+          // Nothing worked! Let's try without the blacklist.
+          tryBlackList = false;
+          int size = excludedServers.size();
+          excludedServers.removeAll(blackListedServers);
+          // make sure we didn't remove any of the ones that the caller set not to use
+          excludedServers.addAll(origExcludedServers);
+          if(excludedServers.size()<size) {
+            // We are able to remove some exclusions, so lets give this another whirl.
+            continue;
+          }
+        }
+        if (logger.isDebugEnabled()) {
+          logger.debug("Source was unable to locate any servers");
+        }
+        if(fatalException!=null) {
+          throw fatalException;
+        }
+        return null;
+      }
+    
+      try {
+        conn = createClientToServerConnection(server, false);
+      } catch(CancelException e) {
+      //propagate this up immediately
+        throw e;
+      } catch(GemFireSecurityException e) {
+        //propagate this up immediately
+        throw e; 
+      } catch(GatewayConfigurationException e) {
+        //propagate this up immediately
+        throw e;
+      } catch(ServerRefusedConnectionException srce) {
+        fatalException = srce;
+        if (logger.isDebugEnabled()) {
+          logger.debug("ServerRefusedConnectionException attempting to connect to {}", server , srce);
+        }
+      } catch (Exception e) {
+        logger.warn(LocalizedMessage.create(LocalizedStrings.ConnectException_COULD_NOT_CONNECT_TO_0, server), e);
+      }
+      
+      excludedServers.add(server);
+    } while(conn == null);
+      
+//    if(conn == null) {
+//      logger.fine("Unable to create a connection in the allowed time.");
+//      
+//      if(fatalException!=null) {
+//        throw fatalException;
+//      }
+//    }
+    return conn;
+  }
+  
+  public ClientUpdater createServerToClientConnection(Endpoint endpoint,
+      QueueManager qManager, boolean isPrimary, ClientUpdater failedUpdater) {
+    String clientUpdateName = CacheClientUpdater.CLIENT_UPDATER_THREAD_NAME
+    + " on " + endpoint.getMemberId() + " port " + endpoint.getLocation().getPort();
+    if (logger.isDebugEnabled()) {
+      logger.debug("Establishing: {}", clientUpdateName);
+    }
+//  Launch the thread
+    CacheClientUpdater updater = new CacheClientUpdater(clientUpdateName,
+        endpoint.getLocation(), isPrimary, ds, new HandShake(this.handshake), qManager,
+        endpointManager, endpoint, handShakeTimeout);
+    
+    if(!updater.isConnected()) {
+      return null;
+    }
+    
+    updater.setFailedUpdater(failedUpdater);
+    updater.start();
+
+//  Wait for the client update thread to be ready
+//    if (!updater.waitForInitialization()) {
+      // Yogesh : This doesn't wait for notify if the updater
+      // thread exits from the run in case of Exception in CCU thread
+      // Yogesh : fix for 36690
+      // because when CCU thread gets a ConnectException, it comes out of run method
+      // and when a thread is no more running it notifies all the waiting threads on the thread object.
+      // so above wait will come out irrelevant of notify from CCU thread, when CCU thread has got an exception
+      // To avoid this problem we check isAlive before returning from this method.
+//      if (logger != null && logger.infoEnabled()) {
+//        logger.info(LocalizedStrings.AutoConnectionSourceImpl_0_NOT_STARTED_1, new Object[] {this, clientUpdateName});
+//      }
+//      return null;
+//    }else {
+//      if (logger != null && logger.infoEnabled()) {
+//        logger.info(LocalizedStrings.AutoConnectionSourceImpl_0_STARTED_1, new Object[] {this, clientUpdateName});
+//      }
+//    }
+    return updater;
+  }
+}
+
+


[19/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionShortcut.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionShortcut.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionShortcut.java
new file mode 100644
index 0000000..5000032
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionShortcut.java
@@ -0,0 +1,229 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/**
+ * Each enum represents a predefined {@link RegionAttributes} in a {@link Cache}.
+ * These enum values can be used to create regions using a {@link RegionFactory}
+ * obtained by calling {@link Cache#createRegionFactory(RegionShortcut)}.
+ * <p>Another way to use predefined region attributes is in cache.xml by setting
+ * the refid attribute on a region element or region-attributes element to the
+ * string of each value.
+ * @since 6.5
+ * @author darrel
+ */
+public enum RegionShortcut {
+  /**
+   * A PARTITION has local state that is partitioned across each peer member
+   * that created the region.
+   * The actual RegionAttributes for a PARTITION region set the {@link DataPolicy} to {@link DataPolicy#PARTITION}.
+   */
+  PARTITION,
+  /**
+   * A PARTITION_REDUNDANT has local state that is partitioned across each peer member
+   * that created the region.
+   * In addition an extra copy of the data is kept in memory.
+   * The actual RegionAttributes for a PARTITION_REDUNDANT region set the {@link DataPolicy} to {@link DataPolicy#PARTITION} and the redundant-copies to 1.
+   */
+  PARTITION_REDUNDANT,
+  /**
+   * A PARTITION_PERSISTENT has local state that is partitioned across each peer member
+   * that created the region.
+   * In addition its state is written to disk and recovered from disk when the region
+   * is created.
+   * The actual RegionAttributes for a PARTITION_PERSISTENT region set the {@link DataPolicy} to {@link DataPolicy#PERSISTENT_PARTITION}.
+   */
+  PARTITION_PERSISTENT,
+  /**
+   * A PARTITION_REDUNDANT_PERSISTENT has local state that is partitioned across each peer member
+   * that created the region.
+   * In addition its state is written to disk and recovered from disk when the region
+   * is created.
+   * In addition an extra copy of the data is kept in memory.
+   * The actual RegionAttributes for a PARTITION_REDUNDANT_PERSISTENT region set the {@link DataPolicy} to {@link DataPolicy#PERSISTENT_PARTITION} and the redundant-copies to 1.
+   */
+  PARTITION_REDUNDANT_PERSISTENT,
+  /**
+   * A PARTITION_OVERFLOW has local state that is partitioned across each peer member
+   * that created the region.
+   * It will also move the values of entries to disk once it detects that the
+   * java vm is running low of memory.
+   * The actual RegionAttributes for a PARTITION_OVERFLOW region set the {@link DataPolicy} to {@link DataPolicy#PARTITION}.
+   * and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+   * with {@link EvictionAction#OVERFLOW_TO_DISK}.
+   */
+  PARTITION_OVERFLOW,
+  /**
+   * A PARTITION_REDUNDANT_OVERFLOW has local state that is partitioned across each peer member
+   * that created the region.
+   * In addition an extra copy of the data is kept in memory.
+   * It will also move the values of entries to disk once it detects that the
+   * java vm is running low of memory.
+   * The actual RegionAttributes for a PARTITION_REDUNDANT_OVERFLOW region set the {@link DataPolicy} to {@link DataPolicy#PARTITION}, the redundant-copies to 1,
+   * and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+   * with {@link EvictionAction#OVERFLOW_TO_DISK}.
+   */
+  PARTITION_REDUNDANT_OVERFLOW,
+  /**
+   * A PARTITION_PERSISTENT_OVERFLOW has local state that is partitioned across each peer member
+   * that created the region.
+   * In addition its state is written to disk and recovered from disk when the region
+   * is created.
+   * It will also remove the values of entries from memory once it detects that the
+   * java vm is running low of memory.
+   * The actual RegionAttributes for a PARTITION_PERSISTENT_OVERFLOW region set the {@link DataPolicy} to {@link DataPolicy#PERSISTENT_PARTITION}
+   * and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+   * with {@link EvictionAction#OVERFLOW_TO_DISK}.
+   */
+  PARTITION_PERSISTENT_OVERFLOW,
+  /**
+   * A PARTITION_REDUNDANT_PERSISTENT_OVERFLOW has local state that is partitioned across each peer member
+   * that created the region.
+   * In addition its state is written to disk and recovered from disk when the region
+   * is created.
+   * In addition an extra copy of the data is kept in memory.
+   * It will also remove the values of entries from memory once it detects that the
+   * java vm is running low of memory.
+   * The actual RegionAttributes for a PARTITION_REDUNDANT_PERSISTENT_OVERFLOW region set the {@link DataPolicy} to {@link DataPolicy#PERSISTENT_PARTITION}, the redundant-copies to 1,
+   * and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+   * with {@link EvictionAction#OVERFLOW_TO_DISK}.
+   */
+  PARTITION_REDUNDANT_PERSISTENT_OVERFLOW,
+  /**
+   * A PARTITION_HEAP_LRU has local state that is partitioned across each peer member
+   * that created the region.
+   * It will also destroy entries once it detects that the java vm is running low
+   * of memory.
+   * The actual RegionAttributes for a PARTITION_HEAP_LRU region set the {@link DataPolicy} to {@link DataPolicy#PARTITION}
+   * and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+   * with {@link EvictionAction#LOCAL_DESTROY}.
+   */
+  PARTITION_HEAP_LRU,
+  /**
+   * A PARTITION_REDUNDANT_HEAP_LRU has local state that is partitioned across each peer member
+   * that created the region.
+   * In addition an extra copy of the data is kept in memory.
+   * It will also destroy entries once it detects that the java vm is running low
+   * of memory.
+   * The actual RegionAttributes for a PARTITION_REDUNDANT_HEAP_LRU region set the {@link DataPolicy} to {@link DataPolicy#PARTITION}, the redundant-copies to 1,
+   * and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+   * with {@link EvictionAction#LOCAL_DESTROY}.
+   */
+  PARTITION_REDUNDANT_HEAP_LRU,
+
+  /**
+   * A REPLICATE has local state that is kept in sync with all other replicate
+   * regions that exist in its peers.
+   * The actual RegionAttributes for a REPLICATE region set the {@link DataPolicy} to {@link DataPolicy#REPLICATE} and {@link Scope} to {@link Scope#DISTRIBUTED_ACK}.
+   */
+  REPLICATE,
+  /**
+   * A REPLICATE_PERSISTENT has local state that is kept in sync with all other replicate
+   * regions that exist in its peers.
+   * In addition its state is written to disk and recovered from disk when the region
+   * is created.
+   * The actual RegionAttributes for a REPLICATE_PERSISTENT region set the {@link DataPolicy} to {@link DataPolicy#PERSISTENT_REPLICATE} and {@link Scope} to {@link Scope#DISTRIBUTED_ACK}.
+   */
+  REPLICATE_PERSISTENT,
+
+  /**
+   * A REPLICATE_OVERFLOW has local state that is kept in sync with all other replicate
+   * regions that exist in its peers.
+   * The actual RegionAttributes for a REPLICATE_OVERFLOW region set the {@link DataPolicy}
+   * to {@link DataPolicy#REPLICATE}, the {@link Scope} to {@link Scope#DISTRIBUTED_ACK}
+   * and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+   * with {@link EvictionAction#OVERFLOW_TO_DISK}.
+   */
+  REPLICATE_OVERFLOW,
+  /**
+   * A REPLICATE_PERSISTENT_OVERFLOW has local state that is kept in sync with all other replicate
+   * regions that exist in its peers.
+   * In addition its state is written to disk and recovered from disk when the region
+   * is created.
+   * It will also remove the values of entries from memory once it detects that the
+   * java vm is running low of memory.
+   * The actual RegionAttributes for a REPLICATE_PERSISTENT_OVERFLOW region set the {@link DataPolicy} 
+   * to {@link DataPolicy#PERSISTENT_REPLICATE}, the {@link Scope} to {@link Scope#DISTRIBUTED_ACK},
+   * and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+   * with {@link EvictionAction#OVERFLOW_TO_DISK}.
+   */
+  REPLICATE_PERSISTENT_OVERFLOW,
+  /**
+   * A REPLICATE_HEAP_LRU has local state that is kept in sync with all other replicate
+   * regions that exist in its peers.
+   * It will also destroy entries once it detects that the java vm is running low
+   * of memory.
+   * The actual RegionAttributes for a REPLICATE_HEAP_LRU region set the {@link DataPolicy} to {@link DataPolicy#PRELOADED}, the {@link Scope} to {@link Scope#DISTRIBUTED_ACK},
+   * {@link SubscriptionAttributes} to {@link InterestPolicy#ALL},
+   * and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+   * with {@link EvictionAction#LOCAL_DESTROY}.   
+   */
+  REPLICATE_HEAP_LRU,
+
+  /**
+   * A LOCAL region only has local state and never sends operations to others.
+   * The actual RegionAttributes for a LOCAL region  set the {@link DataPolicy} to {@link DataPolicy#NORMAL}.
+   */
+  LOCAL,
+  /**
+   * A LOCAL_PERSISTENT region only has local state and never sends operations to others
+   * but it does write its state to disk and can recover that state when the region
+   * is created.
+   * The actual RegionAttributes for a LOCAL_PERSISTENT region set the {@link DataPolicy} to {@link DataPolicy#PERSISTENT_REPLICATE}.
+   */
+  LOCAL_PERSISTENT,
+
+  /**
+   * A LOCAL_HEAP_LRU region only has local state and never sends operations to others.
+   * It will also destroy entries once it detects that the java vm is running low
+   * of memory.
+   * The actual RegionAttributes for a LOCAL_HEAP_LRU region set the {@link DataPolicy} to {@link DataPolicy#NORMAL} and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+   * with {@link EvictionAction#LOCAL_DESTROY}.
+   */
+  LOCAL_HEAP_LRU,
+  /**
+   * A LOCAL_OVERFLOW region only has local state and never sends operations to others.
+   * It will also move the values of entries to disk once it detects that the
+   * java vm is running low of memory.
+   * The actual RegionAttributes for a LOCAL_OVERFLOW region set the {@link DataPolicy} to {@link DataPolicy#NORMAL} and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+   * with {@link EvictionAction#OVERFLOW_TO_DISK}.
+   */
+  LOCAL_OVERFLOW,
+  /**
+   * A LOCAL_PERSISTENT_OVERFLOW region only has local state and never sends operations to others
+   * but it does write its state to disk and can recover that state when the region
+   * is created.
+   * It will also remove the values of entries from memory once it detects that the
+   * java vm is running low of memory.
+   * The actual RegionAttributes for a LOCAL_PERSISTENT_OVERFLOW region set the {@link DataPolicy} to {@link DataPolicy#PERSISTENT_REPLICATE} and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+   * with {@link EvictionAction#OVERFLOW_TO_DISK}.
+   */
+  LOCAL_PERSISTENT_OVERFLOW,
+
+  /**
+   * A PARTITION_PROXY has no local state and forwards all operations to a PARTITION
+   * or a PARTITION_PERSISTENT that exists in its peers.
+   * The actual RegionAttributes for a PARTITION_PROXY region set the {@link DataPolicy} to {@link DataPolicy#PARTITION} and the local-max-memory to 0.
+   */
+  PARTITION_PROXY,
+  /**
+   * A PARTITION_PROXY_REDUNDANT has no local state and forwards all operations to a PARTITION_REDUNDANT
+   * or a PARTITION_REDUNDANT_PERSISTENT that exists in its peers.
+   * The actual RegionAttributes for a PARTITION_PROXY_REDUNDANT region set the {@link DataPolicy} to {@link DataPolicy#PARTITION}, the local-max-memory to 0,
+   * and the redundant-copies to 1.
+   */
+  PARTITION_PROXY_REDUNDANT,
+  /**
+   * A REPLICATE_PROXY has no local state and forwards all operations (except queries) to a REPLICATE
+   * or a REPLICATE_PERSISTENT that exists in its peers.
+   * Queries will be executed on this PROXY region.
+   * The actual RegionAttributes for a REPLICATE_PROXY region set the {@link DataPolicy} to {@link DataPolicy#EMPTY} and {@link Scope} to {@link Scope#DISTRIBUTED_ACK}.
+   */
+  REPLICATE_PROXY,  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RemoteTransactionException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RemoteTransactionException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RemoteTransactionException.java
new file mode 100755
index 0000000..352ed3d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RemoteTransactionException.java
@@ -0,0 +1,33 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * Indicates that an unexpected runtime exception occurred
+ * during a cache operation on the transactional data host.
+ *
+ * <p>This exception only occurs when a transaction
+ * is hosted on a member that is not
+ * the initiator of the transaction.
+ *
+ * @author gregp
+ * @since 6.5
+ * @deprecated as of 6.6 exceptions from a remote node are no longer wrapped in this exception.  Instead of this, {@link TransactionDataNodeHasDepartedException} is thrown.
+ */
+public class RemoteTransactionException extends TransactionException {
+  
+  private static final long serialVersionUID = -2217135580436381984L;
+
+  public RemoteTransactionException(String s) {
+    super(s);
+  }
+  
+  public RemoteTransactionException(Exception e) {
+    super(e);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RequiredRoles.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RequiredRoles.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RequiredRoles.java
new file mode 100755
index 0000000..41fa829
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RequiredRoles.java
@@ -0,0 +1,108 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.distributed.Role;
+import com.gemstone.gemfire.internal.Assert;
+import com.gemstone.gemfire.internal.cache.DistributedRegion;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import java.util.*;
+
+/**
+ * Provides information on presence or absence of a <code>Region</code>'s 
+ * required roles. Configuration of required roles is accomplished using the
+ * <code>Region</code>'s {@link MembershipAttributes}. 
+ *
+ * A {@link com.gemstone.gemfire.distributed.Role Role} may be present in the
+ * distributed system even if it the <code>Role</code> is not present in the
+ * <code>Region</code> membership. This would occur if none of the members
+ * filling that <code>Role</code> currently have a <code>Cache</code> or the
+ * specific <code>Region</code> created. In this case the <code>Role</code> is
+ * considered to be absent for that <code>Region</code>.
+ *
+ * @author Kirk Lund
+ * @see com.gemstone.gemfire.distributed.Role
+ * @since 5.0
+ */
+public class RequiredRoles {
+  
+  /**
+   * Returns a set of any currently missing required roles for the
+   * specified region.  If the region is not configured to require roles
+   * an empty set will always be returned.
+   *
+   * @param region the region to check for missing required roles
+   * @return set of required roles that are currently missing
+   * @throws IllegalStateException if region is not configured with required roles
+   */
+  public static Set<Role> checkForRequiredRoles(Region<?,?> region) {
+    try {
+      return waitForRequiredRoles(region, 0);
+    }
+    catch (InterruptedException ie) {
+      // This could happen if we were in an interrupted state
+      // upon method entry
+      Thread.currentThread().interrupt();
+      ((LocalRegion)region).getCancelCriterion().checkCancelInProgress(ie);
+      Assert.assertTrue(false, 
+          "checkForRequiredRoles cannot throw InterruptedException");
+      return Collections.emptySet(); // keep compiler happy
+    }
+  }
+
+  /**
+   * Returns a set of any currently missing required roles for the
+   * specified region.  This will wait the specified timeout in milliseconds 
+   * for any missing required roles to be filled.  If there are no missing 
+   * required roles or if the region is not configured to require any roles
+   * then an empty set will immediately be returned.
+   *
+   * @param region the region to check for missing required roles
+   * @param timeout milliseconds to wait for any missing required roles
+   * @return set of required roles that are currently missing
+   * @throws NullPointerException if region is null
+   * @throws InterruptedException if thread is interrupted while waiting
+   * @throws IllegalStateException if region is not configured with required roles
+   */
+  public static Set<Role> waitForRequiredRoles(Region<?,?> region, long timeout)
+  throws InterruptedException {
+//    if (Thread.interrupted()) throw new InterruptedException(); not necessary waitForRequiredRoles does this
+    if (region == null) {
+      throw new NullPointerException(LocalizedStrings.RequiredRoles_REGION_MUST_BE_SPECIFIED.toLocalizedString());
+    }
+    if (!(region instanceof DistributedRegion)) {
+      throw new IllegalStateException(LocalizedStrings.RequiredRoles_REGION_HAS_NOT_BEEN_CONFIGURED_WITH_REQUIRED_ROLES.toLocalizedString());
+    }
+    DistributedRegion dr = (DistributedRegion) region;
+    return dr.waitForRequiredRoles(timeout);
+  }
+  
+  /**
+   * Returns true if the {@link com.gemstone.gemfire.distributed.Role Role}
+   * is currently present in the {@link Region} membership. This returns true
+   * only if one or more members filling this role actually have the region
+   * currently created. The role may be present in the distributed system even
+   * if the role is not present in the region membership.
+   *
+   * @param region the region whose membership will be searched
+   * @param role the role to check for
+   */
+  public static boolean isRoleInRegionMembership(Region<?,?> region, Role role) {
+    if (region instanceof DistributedRegion) {
+      DistributedRegion dr = (DistributedRegion) region;
+      return dr.isRoleInRegionMembership(role);
+    }
+    else {
+      return role.isPresent();
+    }
+  }
+  
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ResourceException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ResourceException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ResourceException.java
new file mode 100644
index 0000000..31d0575
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ResourceException.java
@@ -0,0 +1,52 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/**
+ * A Generic exception to indicate that a resource exception has occurred.
+ * This class is abstract so that only subclasses can be instantiated.
+ * 
+ * @author sbawaska
+ * @since 6.0
+ */
+public abstract class ResourceException extends CacheRuntimeException {
+  /**
+   * Creates a new instance of <code>ResourceException</code> without detail message.
+   */
+  public ResourceException() {
+  }
+  
+  
+  /**
+   * Constructs an instance of <code>ResourceException</code> with the specified detail message.
+   * @param msg the detail message
+   */
+  public ResourceException(String msg) {
+    super(msg);
+  }
+  
+  /**
+   * Constructs an instance of <code>ResourceException</code> with the specified detail message
+   * and cause.
+   * @param msg the detail message
+   * @param cause the causal Throwable
+   */
+  public ResourceException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+  
+  /**
+   * Constructs an instance of <code>ResourceException</code> with the specified cause.
+   * @param cause the causal Throwable
+   */
+  public ResourceException(Throwable cause) {
+    super(cause);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ResumptionAction.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ResumptionAction.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ResumptionAction.java
new file mode 100755
index 0000000..e0d2615
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/ResumptionAction.java
@@ -0,0 +1,105 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Specifies how the region is affected by resumption of reliability when
+ * one or more missing required roles return to the distributed membership.  
+ * The <code>ResumptionAction</code> is specified when configuring a region's 
+ * {@link com.gemstone.gemfire.cache.MembershipAttributes}.
+ * 
+ * @author Kirk Lund
+ * @since 5.0
+ */
+public class ResumptionAction implements java.io.Serializable {
+  private static final long serialVersionUID = 6632254151314915610L;
+
+  /** No special action takes place when reliability resumes. */
+  public static final ResumptionAction NONE = 
+      new ResumptionAction("NONE");
+
+  /** 
+   * Resumption of reliability causes the region to be cleared of all data 
+   * and {@link DataPolicy#withReplication replicated} regions will do a new
+   * getInitialImage operation to repopulate the region.  Any existing 
+   * references to this region become unusable in that any subsequent methods
+   * invoked on those references will throw a {@link 
+   * RegionReinitializedException}.
+   */
+  public static final ResumptionAction REINITIALIZE = 
+      new ResumptionAction("REINITIALIZE");
+
+  /** The name of this mirror type. */
+  private final transient String name;
+
+  // The 4 declarations below are necessary for serialization
+  /** byte used as ordinal to represent this Scope */
+  public final byte ordinal = nextOrdinal++;
+
+  private static byte nextOrdinal = 0;
+  
+  private static final ResumptionAction[] PRIVATE_VALUES =
+    { NONE, REINITIALIZE };
+
+  /** List of all ResumptionAction values */
+  public static final List VALUES = 
+    Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));
+    
+  private Object readResolve() throws ObjectStreamException {
+    return PRIVATE_VALUES[ordinal];  // Canonicalize
+  }
+  
+  /** Creates a new instance of ResumptionAction. */
+  private ResumptionAction(String name) {
+      this.name = name;
+  }
+  
+  /** Return the ResumptionAction represented by specified ordinal */
+  public static ResumptionAction fromOrdinal(byte ordinal) {
+    return PRIVATE_VALUES[ordinal];
+  }
+  
+  /** Return the ResumptionAction specified by name */
+  public static ResumptionAction fromName(String name) {
+    if (name == null || name.length() == 0) {
+      throw new IllegalArgumentException(LocalizedStrings.ResumptionAction_INVALID_RESUMPTIONACTION_NAME_0.toLocalizedString(name));
+    }
+    for (int i = 0; i < PRIVATE_VALUES.length; i++) {
+      if (name.equals(PRIVATE_VALUES[i].name)) {
+        return PRIVATE_VALUES[i];
+      }
+    }
+    throw new IllegalArgumentException(LocalizedStrings.ResumptionAction_INVALID_RESUMPTIONACTION_NAME_0.toLocalizedString(name));
+  }
+  
+  /** Returns true if this is <code>NONE</code>. */
+  public boolean isNone() {
+    return this == NONE;
+  }
+  
+  /** Returns true if this is <code>REINITIALIZE</code>. */
+  public boolean isReinitialize() {
+    return this == REINITIALIZE;
+  }
+  
+  /** 
+   * Returns a string representation for this resumption action.
+   * @return the name of this resumption action
+   */
+  @Override
+  public String toString() {
+      return this.name;
+  }
+  
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RoleEvent.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RoleEvent.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RoleEvent.java
new file mode 100755
index 0000000..40ef361
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RoleEvent.java
@@ -0,0 +1,30 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import java.util.Set;
+
+/** 
+ * Contains information about an event affecting a region reliability, 
+ * including its identity and the circumstances of the event. This is 
+ * passed in to {@link RegionRoleListener}.
+ *
+ * @author Kirk Lund
+ * @see RegionRoleListener
+ * @since 5.0
+ */
+public interface RoleEvent<K,V> extends RegionEvent<K,V> {
+  
+  /**
+   * Returns the required roles that were lost or gained because of this
+   * event.
+   */
+  public Set<String> getRequiredRoles();
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RoleException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RoleException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RoleException.java
new file mode 100755
index 0000000..98b55d6
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RoleException.java
@@ -0,0 +1,59 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * <code>RoleException</code> is the superclass of those exceptions
+ * that can be thrown to indicate a reliability failure on one or more {@link
+ * Region regions} that have been configured with required roles using 
+ * {@link MembershipAttributes}.
+ *
+ * @author Kirk Lund
+ * @since 5.0
+ */
+public abstract class RoleException extends CacheRuntimeException {
+  private static final long serialVersionUID = -7521056108445887394L;
+
+  /**
+   * Creates a new instance of <code>RoleException</code> without
+   * detail message.
+   */
+  public RoleException() {
+  }
+  
+  
+  /**
+   * Constructs an instance of <code>RoleException</code> with the
+   * specified detail message.
+   * @param msg the detail message
+   */
+  public RoleException(String msg) {
+    super(msg);
+  }
+  
+  /**
+   * Constructs an instance of <code>RoleException</code> with the
+   * specified detail message and cause.
+   * @param msg the detail message
+   * @param cause the causal Throwable
+   */
+  public RoleException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+  
+  /**
+   * Constructs an instance of <code>RoleException</code> with the
+   * specified cause.
+   * @param cause the causal Throwable
+   */
+  public RoleException(Throwable cause) {
+    super(cause);
+  }
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Scope.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Scope.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Scope.java
new file mode 100644
index 0000000..b2576f9
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Scope.java
@@ -0,0 +1,159 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import java.io.*;
+
+/**
+ * Enumerated type for region distribution scope.
+ *
+ * @author Eric Zoerner
+ *
+ *
+ * @see RegionAttributes#getScope
+ * @see AttributesFactory#setScope
+ * @since 3.0
+ */
+public class Scope implements Serializable {
+    private static final long serialVersionUID = 5534399159504301602L;
+  
+    /** The region with this attribute is scoped to this JVM only. Operations and data
+     * are not distributed to other caches.
+     */
+    public static final Scope LOCAL = new Scope("LOCAL");
+    
+    /** The region or cached object with this attribute is scoped
+     * to the distributed cached system; any distributed
+     * operation will return without waiting for the remote acknowledgment.
+     */
+    public static final Scope DISTRIBUTED_NO_ACK = new Scope("DISTRIBUTED_NO_ACK");
+    
+    /**
+     * The region or cached object with this attribute is scoped
+     * to the distributed cached system; any distributed
+     * operation will not return until all the remote acknowledgments
+     * come back.
+     */
+    public static final Scope DISTRIBUTED_ACK = new Scope("DISTRIBUTED_ACK");
+    
+    /**
+     * The region or cached object with this attribute is scoped
+     * to the distributed cached system; locking is used 
+     * for all distributed operations on entries
+     * to guarantee consistency across the distributed caches.
+     */
+    public static final Scope GLOBAL = new Scope("GLOBAL");
+
+    /** The name of this scope.*/
+    private final transient String name;
+    
+    // The 4 declarations below are necessary for serialization
+    /** int used as ordinal to represent this Scope */
+    public final int ordinal = nextOrdinal++;
+ 
+    private static int nextOrdinal = 0;
+    
+    private static final Scope[] VALUES =
+      { LOCAL, DISTRIBUTED_NO_ACK, DISTRIBUTED_ACK, GLOBAL };
+      
+    /* The following 4 definitions are included for use by the C 
+     * interface. Any changes to the order of the scopes in VALUES
+     * must be reflected here and changed in gemfire.h.
+     */
+    final static int SCOPE_LOCAL = 0;
+    final static int SCOPE_DISTRIBUTED_NO_ACK= 1;
+    final static int SCOPE_DISTRIBUTED_ACK = 2;
+    final static int SCOPE_GLOBAL = 3;
+
+    private Object readResolve() throws ObjectStreamException {
+      return fromOrdinal(ordinal);  // Canonicalize
+    }
+   
+    
+    /** Creates a new instance of Scope. */
+    private Scope(String name) {
+        this.name = name;
+    }
+    
+    /** Return the Scope represented by specified ordinal */
+    public static Scope fromOrdinal(int ordinal) {
+      return VALUES[ordinal];
+    }
+    
+    /** Returns whether this is local scope.
+     * @return true if this is LOCAL
+     */    
+    public boolean isLocal() {
+      return this == LOCAL;
+    }
+    
+    /** Returns whether this is one of the distributed scopes.
+     * @return true if this is any scope other than LOCAL
+     */    
+    public boolean isDistributed() {
+      return this != LOCAL;
+    }
+    
+    /** Returns whether this is distributed no ack scope.
+     * @return true if this is DISTRIBUTED_NO_ACK
+     */    
+    public boolean isDistributedNoAck() {
+      return this == DISTRIBUTED_NO_ACK;
+    }
+    
+    /** Returns whether this is distributed ack scope.
+     * @return true if this is DISTRIBUTED_ACK
+     */    
+    public boolean isDistributedAck() {
+      return this == DISTRIBUTED_ACK;
+    }
+    
+    /** Returns whether this is global scope.
+     * @return true if this is GLOBAL
+     */    
+    public boolean isGlobal() {
+      return this == GLOBAL;
+    }
+    
+    /** Returns whether acknowledgements are required for this scope.
+     * @return true if this is DISTRIBUTED_ACK or GLOBAL, false otherwise
+     */    
+    public boolean isAck() {
+      return this == DISTRIBUTED_ACK || this == GLOBAL;
+    }
+    
+    
+    /** Returns a string representation for this scope.
+     * @return String the name of this scope
+     */
+    @Override
+    public String toString() {
+        return this.name;
+    }
+
+    /**
+     * Parse the given string into a Scope 
+     * @param scope the provided String form of Scope
+     * @return the canonical Scope associated with the string
+     */
+    public static Scope fromString(String scope) {
+      for (int i=0; i<VALUES.length; i++) {
+        if (VALUES[i].toString().equals(scope)) {
+          return VALUES[i]; 
+        }
+      }
+      throw new IllegalArgumentException(
+        LocalizedStrings.Scope_0_IS_NOT_A_VALID_STRING_REPRESENTATION_OF_1
+          .toLocalizedString(new Object[] {scope, Scope.class.getName()}));
+    }
+        
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/SerializedCacheValue.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/SerializedCacheValue.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/SerializedCacheValue.java
new file mode 100755
index 0000000..33f60f3
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/SerializedCacheValue.java
@@ -0,0 +1,40 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/**
+ * Class <code>SerializedCacheValue</code> represents a serialized cache value.
+ * Instances of this class obtained from a region can be put into another region
+ * without a copy of this value being made. The two region entries will both have a
+ * reference to the same value.
+ * <p>
+ * If this value originated from a region stored off heap then this object can
+ * only be used as long as notification method that obtained it has not returned.
+ * For example if your implementation of {@link CacheListener#afterUpdate(EntryEvent)} obtains one
+ * by calling {@link EntryEvent#getSerializedOldValue()} then the SerializedCacheValue returned
+ * is only valid until your afterUpdate method returns. It is not safe to store instances of this
+ * class and use them later when using off heap storage.
+ *
+ * @author Barry Oglesby
+ * @since 5.5
+ */
+public interface SerializedCacheValue<V> {
+
+  /**
+   * Returns the raw byte[] that represents this cache value.
+   * @return the raw byte[] that represents this cache value
+   */
+  public byte[] getSerializedValue();
+
+  /**
+   * Returns the deserialized object for this cache value.
+   * @return the deserialized object for this cache value
+   */
+  public V getDeserializedValue();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/StatisticsDisabledException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/StatisticsDisabledException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/StatisticsDisabledException.java
new file mode 100644
index 0000000..846b278
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/StatisticsDisabledException.java
@@ -0,0 +1,59 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/**
+ * Thrown if statistics are requested when statistics are disabled on the
+ * region.
+ *
+ * @author Eric Zoerner
+ *
+ *
+ * @see AttributesFactory#setStatisticsEnabled
+ * @see RegionAttributes#getStatisticsEnabled
+ * @see Region#getStatistics
+ * @see Region.Entry#getStatistics
+ * @since 3.0
+ */
+public class StatisticsDisabledException extends CacheRuntimeException {
+private static final long serialVersionUID = -2987721454129719551L;
+  
+  /**
+   * Creates a new instance of <code>StatisticsDisabledException</code> without detail message.
+   */
+  public StatisticsDisabledException() {
+  }
+  
+  
+  /**
+   * Constructs an instance of <code>StatisticsDisabledException</code> with the specified detail message.
+   * @param msg the detail message
+   */
+  public StatisticsDisabledException(String msg) {
+    super(msg);
+  }
+  
+  /**
+   * Constructs an instance of <code>StatisticsDisabledException</code> with the specified detail message
+   * and cause.
+   * @param msg the detail message
+   * @param cause the causal Throwable
+   */
+  public StatisticsDisabledException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+  
+  /**
+   * Constructs an instance of <code>StatisticsDisabledException</code> with the specified cause.
+   * @param cause the causal Throwable
+   */
+  public StatisticsDisabledException(Throwable cause) {
+    super(cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/SubscriptionAttributes.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/SubscriptionAttributes.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/SubscriptionAttributes.java
new file mode 100644
index 0000000..2bf2f35
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/SubscriptionAttributes.java
@@ -0,0 +1,108 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.DataSerializable;
+import java.io.*;
+
+/**
+ * Configuration attributes for defining subscriber requirements and behavior
+ * for a <code>Region</code>.
+ * 
+ * <p>The {@link InterestPolicy} defines what remote operation's data/event
+ * are of interest to this cache's region.</p>
+ * 
+ * @author Darrel
+ * @since 5.0
+ */
+public class SubscriptionAttributes implements DataSerializable, Externalizable {
+  
+  /** 
+   * this subscriber's interest policy
+   */
+  private /*final*/ InterestPolicy interestPolicy;
+
+  /**
+   * Creates a new <code>SubscriptionAttributes</code> with the default
+   * configuration
+   */
+  public SubscriptionAttributes() {
+    this.interestPolicy = InterestPolicy.DEFAULT;
+  }
+  /**
+   * Creates a new <code>SubscriptionAttributes</code> with the given
+   * interest policy.
+   * @param interestPolicy the interest policy this subscriber will use
+   */
+  public SubscriptionAttributes(InterestPolicy interestPolicy) {
+    this.interestPolicy = interestPolicy;
+  }
+  /**
+   * Returns the interest policy of this subscriber.
+   */
+  public InterestPolicy getInterestPolicy() {
+    return this.interestPolicy;
+  }
+  
+  @Override
+  public boolean equals(Object other) {
+    if (other == this) return true;
+    if (other == null) return false;
+    if (!(other instanceof SubscriptionAttributes)) return  false;
+    final SubscriptionAttributes that = (SubscriptionAttributes) other;
+
+    if (this.interestPolicy != that.interestPolicy &&
+        !(this.interestPolicy != null &&
+          this.interestPolicy.equals(that.interestPolicy))) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = 17;
+    final int mult = 37;
+
+    result = mult * result + this.interestPolicy.hashCode();
+
+    return result;
+  }
+
+  /**
+   * Returns a string representation of the object.
+   * 
+   * @return a string representation of the object
+   */
+  @Override
+  public String toString() {
+    final StringBuffer sb = new StringBuffer();
+    sb.append("InterestPolicy=");
+    sb.append(this.interestPolicy.toString());
+    return sb.toString();
+  }
+  
+  public void toData(DataOutput out) throws IOException {
+    out.writeByte(this.interestPolicy.ordinal);
+  }
+
+  public void fromData(DataInput in)
+    throws IOException, ClassNotFoundException {
+    this.interestPolicy = InterestPolicy.fromOrdinal(in.readByte());
+  }
+
+  public void writeExternal(ObjectOutput out) throws IOException {
+    // added to fix bug 36619
+    toData(out);
+  }
+  
+  public void readExternal(ObjectInput in)
+    throws IOException, ClassNotFoundException {
+    // added to fix bug 36619
+    fromData(in);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/SynchronizationCommitConflictException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/SynchronizationCommitConflictException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/SynchronizationCommitConflictException.java
new file mode 100644
index 0000000..7b40afd
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/SynchronizationCommitConflictException.java
@@ -0,0 +1,40 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/** Thrown when a commit operation of a JTA enlisted cache transaction fails
+ *
+ * @author Mitch Thomas
+ *
+ * @see javax.transaction.UserTransaction#commit
+ * @since 4.0
+ */
+public class SynchronizationCommitConflictException extends CacheRuntimeException {
+private static final long serialVersionUID = 2619806460255259492L;
+  /**
+   * Constructs an instance of
+   * <code>SynchronizationCommitConflictException</code> with the
+   * specified detail message.
+   * @param msg the detail message
+   */
+  public SynchronizationCommitConflictException(String msg) {
+    super(msg);
+  }
+  
+  /**
+   * Constructs an instance of
+   * <code>SynchronizationCommitConflictException</code> with the
+   * specified detail message and cause.
+   * @param msg the detail message
+   * @param cause the causal Throwable
+   */
+  public SynchronizationCommitConflictException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TimeoutException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TimeoutException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TimeoutException.java
new file mode 100644
index 0000000..761815d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TimeoutException.java
@@ -0,0 +1,64 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/** Thrown if a <code>netSearch</code> times out without getting a response back from a cache,
+ * or when attempting to acquire a distributed lock.
+ *
+ * @author Eric Zoerner
+ *
+ *
+ * @see LoaderHelper#netSearch
+ * @see com.gemstone.gemfire.cache.Region#invalidateRegion()
+ * @see com.gemstone.gemfire.cache.Region#destroyRegion()
+ * @see Region#createSubregion
+ * @see com.gemstone.gemfire.cache.Region#get(Object)
+ * @see com.gemstone.gemfire.cache.Region#put(Object, Object)
+ * @see com.gemstone.gemfire.cache.Region#create(Object, Object)
+ * @see com.gemstone.gemfire.cache.Region#invalidate(Object)
+ * @see com.gemstone.gemfire.cache.Region#destroy(Object)
+ * @see com.gemstone.gemfire.distributed.DistributedLockService
+ * @since 3.0
+ */
+public class TimeoutException extends OperationAbortedException {
+private static final long serialVersionUID = -6260761691185737442L;
+  
+  /**
+   * Creates a new instance of <code>TimeoutException</code> without detail message.
+   */
+  public TimeoutException() {
+  }
+  
+  
+  /**
+   * Constructs an instance of <code>TimeoutException</code> with the specified detail message.
+   * @param msg the detail message
+   */
+  public TimeoutException(String msg) {
+    super(msg);
+  }
+  
+  /**
+   * Constructs an instance of <code>TimeoutException</code> with the specified detail message
+   * and cause.
+   * @param msg the detail message
+   * @param cause the causal Throwable
+   */
+  public TimeoutException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+  
+  /**
+   * Constructs an instance of <code>TimeoutException</code> with the specified cause.
+   * @param cause the causal Throwable
+   */
+  public TimeoutException(Throwable cause) {
+    super(cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionDataNodeHasDepartedException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionDataNodeHasDepartedException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionDataNodeHasDepartedException.java
new file mode 100755
index 0000000..6ccb41b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionDataNodeHasDepartedException.java
@@ -0,0 +1,33 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * Thrown when the transactional data host has shutdown or no longer has the data
+ * being modified by the transaction.
+ * This can be thrown while doing transactional operations or during commit.
+ *
+ * <p>This exception only occurs when a transaction
+ * is hosted on a member that is not
+ * the initiator of the transaction.
+ *
+ * @author gregp
+ * @since 6.5
+ */
+public class TransactionDataNodeHasDepartedException extends TransactionException {
+  
+  private static final long serialVersionUID = -2217135580436381984L;
+
+  public TransactionDataNodeHasDepartedException(String s) {
+    super(s);
+  }
+  
+  public TransactionDataNodeHasDepartedException(Throwable e) {
+    super(e);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionDataNotColocatedException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionDataNotColocatedException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionDataNotColocatedException.java
new file mode 100755
index 0000000..abcc313
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionDataNotColocatedException.java
@@ -0,0 +1,37 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * Indicates that an attempt was made to transactionally modify multiple keys that
+ * are not colocated on the same data host.
+ * This can be thrown while doing transactional operations or during commit.
+ *
+ * <p>This exception only occurs when a transaction
+ * is hosted on a member that is not
+ * the initiator of the transaction.
+ *
+ * <p>Note: a rebalance can cause this exception to be thrown for data that
+ * is usually colocated. This is because data can be moved from one node to another
+ * during the time between the original transactional operations and the commit. 
+ *
+ * @author gregp
+ * @since 6.5
+ */
+public class TransactionDataNotColocatedException extends TransactionException {
+  
+  private static final long serialVersionUID = -2217135580436381984L;
+
+  public TransactionDataNotColocatedException(String s) {
+    super(s);
+  }
+
+  public TransactionDataNotColocatedException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionDataRebalancedException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionDataRebalancedException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionDataRebalancedException.java
new file mode 100644
index 0000000..f10ffcd
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionDataRebalancedException.java
@@ -0,0 +1,29 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.cache.control.RebalanceOperation;
+
+/**
+ * Thrown when a {@link RebalanceOperation} occurs concurrently with a transaction.
+ * This can be thrown while doing transactional operations or during commit.
+ *
+ * <p>This exception only occurs when a transaction
+ * involves partitioned regions.
+ * 
+ * @author gregp
+ * @since 6.6
+ */
+public class TransactionDataRebalancedException extends TransactionException {
+  
+  private static final long serialVersionUID = -2217135580436381984L;
+
+  public TransactionDataRebalancedException(String s) {
+    super(s);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionEvent.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionEvent.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionEvent.java
new file mode 100644
index 0000000..8b93005
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionEvent.java
@@ -0,0 +1,105 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+import java.util.*;
+
+/**
+ * <p>An event that describes the culmination of an entire transaction.
+ * It either describes the work done by a committed transaction
+ * or the work abandoned by an explicit rollback or failed commit.
+ * The actual work is represented by an ordered list of {@link EntryEvent}
+ * instances.
+ * 
+ * <p>A <code>TransactionListener</code> receives an instance of this
+ * class allowing exploration of the resultant operations.  The
+ * resultant operation is the final result of, potentially, a sequence
+ * of operations on a key such that earlier operations might be
+ * masked.  For example, multiple put operations using the same key
+ * will result in only one {@link EntryEvent} for that key.
+ * 
+ * <p>An instance of TransactionEvent for the same transaction on
+ * the originating VM may differ from a recipient VM.  The amount of
+ * variation will depend on the variation of the state of Entries on
+ * each VM.  One reason for why this might occur is the different
+ * Expiration/Eviction settings of the similar Regions on different
+ * VMs.
+ *
+ * <p>The event lists are ordered according to the chronological order of
+ * the indiviual operations.
+ *
+ * <p>The {@link EntryEvent} instances always return <code>null</code>
+ * as their {@link CacheEvent#getCallbackArgument callback argument}.
+ *
+ * @author Mitch Thomas
+ *
+ * @see TransactionListener
+ * @see EntryEvent
+ * @since 4.0
+ */
+public interface TransactionEvent {
+
+  /** Gets the <code>TransactionId</code> associated this TransactionEvent.
+   * 
+   */
+  public TransactionId getTransactionId();
+
+  /** Gets all "create" EntryEvents for this transaction;
+   * <code>Region.create</code> and/or <code>Region.put</code>
+   *
+   * @return <code>List</code> of <code>EntryEvents</code> or <code>Collections.EMPTY_LIST</code>
+   * @deprecated as of GemFire 5.0, use {@link #getEvents} instead
+   */
+  @Deprecated
+  public List<EntryEvent<?,?>> getCreateEvents();
+
+  /** Gets all "destroy" EntryEvents for this
+   * transaction; <code>Region.destroy</code> and
+   * <code>Region.localDestroy</code>.
+   * 
+   * @return <code>List</code> of <code>EntryEvents</code> or <code>Collections.EMPTY_LIST</code>
+   * @deprecated as of GemFire 5.0, use {@link #getEvents} instead
+   */
+  @Deprecated
+  public List<EntryEvent<?,?>> getDestroyEvents();
+
+  /** Gets all <code>Region.put</code> EntryEvents for this transaction.
+   *
+   * @return <code>List</code> of <code>EntryEvents</code> or <code>Collections.EMPTY_LIST</code>
+   * @deprecated as of GemFire 5.0, use {@link #getEvents} instead
+   */
+  @Deprecated
+  public List<EntryEvent<?,?>> getPutEvents();
+
+  /** Gets all "invalidate" EntryEvents for this transaction; 
+   *  <code>Region.invalidate</code> and
+   *  <code>Region.localInvalidate</code>.
+   *
+   * @return <code>List</code> of <code>EntryEvents</code> or <code>Collections.EMPTY_LIST</code>
+   * @deprecated as of GemFire 5.0, use {@link #getEvents} instead
+   */
+  @Deprecated
+  public List<EntryEvent<?,?>> getInvalidateEvents();
+
+  /**
+   * Returns an ordered list of every {@link CacheEvent} for this transaction.
+   * The event order is consistent with the order in which the operations were
+   * performed during the transaction.
+   * @return an unmodifiable <code>List</code> of all the {@link CacheEvent} instances;
+   * one for each operation performed by this transaction.
+   * @since 5.0
+   */
+  public List<CacheEvent<?,?>> getEvents();
+  
+  /** Gets the Cache for this transaction event
+   *
+   * @return <code>Cache</code>
+   */
+  public Cache getCache();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionException.java
new file mode 100644
index 0000000..b1c96e7
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionException.java
@@ -0,0 +1,34 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * This is the superclass for all Exceptions that may be thrown
+ * by a GemFire transaction.
+ * @author sbawaska
+ * @since 6.5
+ */
+public class TransactionException extends CacheException {
+
+  private static final long serialVersionUID = -8400774340264221993L;
+
+  public TransactionException() {
+  }
+
+  public TransactionException(String message) {
+    super(message);
+  }
+
+  public TransactionException(Throwable cause) {
+    super(cause);
+  }
+  
+  public TransactionException(String message, Throwable cause) {
+    super(message, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionId.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionId.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionId.java
new file mode 100644
index 0000000..85cc607
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionId.java
@@ -0,0 +1,24 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import java.io.Externalizable;
+
+/** The TransactionId interface is a "marker" interface that
+ * represents a unique GemFire transaction.
+ *
+ * @author Mitch Thomas
+ * 
+ * @since 4.0
+ * 
+ * @see Cache#getCacheTransactionManager
+ * @see CacheTransactionManager#getTransactionId
+ */
+public interface TransactionId extends Externalizable {
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionInDoubtException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionInDoubtException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionInDoubtException.java
new file mode 100644
index 0000000..f4bfc0e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionInDoubtException.java
@@ -0,0 +1,33 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * This Exception is thrown in presence of node failures, when GemFire cannot
+ * know with certainty about the outcome of the transaction.
+ * @author sbawaska
+ * @since 6.5
+ */
+public class TransactionInDoubtException extends TransactionException {
+  private static final long serialVersionUID = 4895453685211922512L;
+
+  public TransactionInDoubtException() {
+  }
+
+  public TransactionInDoubtException(String message) {
+    super(message);
+  }
+
+  public TransactionInDoubtException(Throwable cause) {
+    super(cause);
+  }
+
+  public TransactionInDoubtException(String message, Throwable cause) {
+    super(message, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionListener.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionListener.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionListener.java
new file mode 100644
index 0000000..1184701
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionListener.java
@@ -0,0 +1,57 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/**
+ * <p>A listener that can be implemented to handle transaction related
+ * events.  The methods on <code>TransactionListener</code> are
+ * invoked synchronously after the operation, commit or rollback,
+ * completes.  The transaction that causes the listener to be called
+ * will no longer exist at the time the listener code executes.  The
+ * thread that performed the transaction operation will not see that
+ * operation complete until the listener method completes its
+ * execution. 
+ *
+ * <p>Multiple transactions, on the same cache, can cause concurrent
+ * invocation of <code>TransactionListener</code> methods.  Any
+ * exceptions thrown by the listener are caught and logged.
+ *
+ * <p>Rollback and failed commit operations are local.
+ *
+ * @author Darrel Schneider
+ *
+ * @see CacheTransactionManager#setListener
+ * @see CacheTransactionManager#getListener
+ * @since 4.0
+ */
+
+public interface TransactionListener extends CacheCallback {
+  
+  /** Called after a successful commit of a transaction.
+   * 
+   * @param event the TransactionEvent
+   * @see CacheTransactionManager#commit
+   */
+  public void afterCommit(TransactionEvent event);
+
+  /** Called after an unsuccessful commit operation.
+   * 
+   * @param event the TransactionEvent
+   * @see CacheTransactionManager#commit
+   */
+  public void afterFailedCommit(TransactionEvent event);
+
+  /** Called after an explicit rollback of a transaction.
+   * 
+   * @param event the TransactionEvent
+   * @see CacheTransactionManager#rollback
+   * @see CacheTransactionManager#commit
+   */
+  public void afterRollback(TransactionEvent event);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionWriter.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionWriter.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionWriter.java
new file mode 100755
index 0000000..9ca6097
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionWriter.java
@@ -0,0 +1,35 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+
+/**
+ * A callback that is allowed to veto a transaction. Only one TransactionWriter can exist 
+ * per cache, and only one TransactionWriter will be fired in the 
+ * entire distributed system for each transaction.
+ *
+ * This writer can be used to update a backend data source before the GemFire cache is updated during commit.
+ * If the backend update fails, the implementer can throw a {@link TransactionWriterException} to veto the transaction.
+ * @see CacheTransactionManager#setWriter
+ * @since 6.5
+ */
+
+public interface TransactionWriter extends CacheCallback {
+  
+  /** Called before the transaction has finished committing, but after conflict checking. 
+   * Provides an opportunity for implementors to cause transaction abort by throwing a
+   * TransactionWriterException
+   * 
+   * @param event the TransactionEvent
+   * @see CacheTransactionManager#commit
+   * @throws TransactionWriterException in the event that the transaction should be rolled back
+   */
+  public void beforeCommit(TransactionEvent event) throws TransactionWriterException;
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionWriterException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionWriterException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionWriterException.java
new file mode 100755
index 0000000..a0793f3
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/TransactionWriterException.java
@@ -0,0 +1,36 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+
+
+/**
+ * Exception thrown by implementors of {@link TransactionWriter#beforeCommit} to 
+ * signal that the current transaction should be aborted.
+ * 
+ * @see TransactionWriter#beforeCommit
+ * @author gregp
+ * @since 6.5
+ *
+ */
+public class TransactionWriterException extends Exception {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = -5557392877576634835L;
+
+  public TransactionWriterException(String s) {
+    super(s);
+  }
+  
+  public TransactionWriterException(Throwable t) {
+    super(t);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/UnsupportedOperationInTransactionException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/UnsupportedOperationInTransactionException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/UnsupportedOperationInTransactionException.java
new file mode 100755
index 0000000..3ccab66
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/UnsupportedOperationInTransactionException.java
@@ -0,0 +1,28 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * Indicates that an attempt was mode to invoke an operation that is not
+ * allowed in a transaction.
+ *
+ * @author gregp
+ * @since 6.5
+ */
+public class UnsupportedOperationInTransactionException extends
+    UnsupportedOperationException {
+
+  public UnsupportedOperationInTransactionException(String s) {
+    super(s);
+  }
+  
+  public UnsupportedOperationInTransactionException() {
+    super();
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/UnsupportedVersionException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/UnsupportedVersionException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/UnsupportedVersionException.java
new file mode 100755
index 0000000..721d053
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/UnsupportedVersionException.java
@@ -0,0 +1,35 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * An <code>UnsupportedVersionException</code> indicates an unsupported version.
+ *
+ * @since 5.7
+ */
+public class UnsupportedVersionException extends VersionException {
+private static final long serialVersionUID = 1152280300663399399L;
+
+  /**
+   * Constructs a new <code>UnsupportedVersionException</code>.
+   * 
+   * @param versionOrdinal The ordinal of the requested <code>Version</code>
+   */
+  public UnsupportedVersionException(short versionOrdinal) {
+    super(String.valueOf(versionOrdinal));
+  }
+  
+  /**
+   * Constructs a new <code>UnsupportedVersionException</code>.
+   * 
+   * @param message The exception message
+   */
+  public UnsupportedVersionException(String message) {
+    super(message);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/VersionException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/VersionException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/VersionException.java
new file mode 100755
index 0000000..9552aa2
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/VersionException.java
@@ -0,0 +1,41 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.GemFireCheckedException;
+
+/**
+ * An <code>VersionException</code> is an exception that indicates
+ * a client / server version mismatch exception has occurred.
+ *
+ * @since 5.7
+ */
+public abstract class VersionException extends GemFireCheckedException {
+
+  /** Constructs a new <code>VersionException</code>. */
+  public VersionException() {
+    super();
+  }
+
+  /** Constructs a new <code>VersionException</code> with a message string. */
+  public VersionException(String s) {
+    super(s);
+  }
+
+  /** Constructs a <code>VersionException</code> with a message string and
+   * a base exception
+   */
+  public VersionException(String s, Throwable cause) {
+    super(s, cause);
+  }
+
+  /** Constructs a <code>VersionException</code> with a cause */
+  public VersionException(Throwable cause) {
+    super(cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/AsyncEvent.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/AsyncEvent.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/AsyncEvent.java
new file mode 100644
index 0000000..b8e0020
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/AsyncEvent.java
@@ -0,0 +1,33 @@
+/* =========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved. 
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ * ========================================================================
+ */
+package com.gemstone.gemfire.cache.asyncqueue;
+
+import com.gemstone.gemfire.cache.wan.EventSequenceID;
+import com.gemstone.gemfire.cache.wan.GatewayQueueEvent;
+
+/**
+ * Represents <code>Cache</code> events delivered to <code>AsyncEventListener</code>.
+ * 
+ * @author pdeole
+ * @since 7.0
+ */
+public interface AsyncEvent<K, V> extends GatewayQueueEvent<K, V>{
+  /**
+   * Returns whether possibleDuplicate is set for this event.
+   */
+  public boolean getPossibleDuplicate();
+  
+  /**
+   * Returns the wrapper over the DistributedMembershipID, ThreadID, SequenceID
+   * which are used to uniquely identify any region operation like create, update etc.
+   * This helps in sequencing the events belonging to a unique producer.
+   * e.g. The EventID can be used to track events received by <code>AsyncEventListener</code>
+   * to avoid processing duplicates.
+   */
+  public EventSequenceID getEventSequenceID();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/AsyncEventListener.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/AsyncEventListener.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/AsyncEventListener.java
new file mode 100644
index 0000000..b15be28
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/AsyncEventListener.java
@@ -0,0 +1,67 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014, Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.cache.asyncqueue;
+
+import java.util.List;
+
+import com.gemstone.gemfire.cache.CacheCallback;
+
+/**
+ * A callback for events passing through the <code>AsyncEventQueue</code> to which this
+ * listener is attached. Implementers of interface <code>AsyncEventListener</code> process
+ * batches of <code>AsyncEvent</code> delivered by the corresponding <code>AsyncEventQueue</code>.
+ * <br>
+ * A sample implementation of this interface is as follows: <br>
+ * 
+ * <pre>
+ * public class MyEventListener implements AsyncEventListener {
+ *      
+ *      public boolean processEvents(List<AsyncEvent> events) {
+ *          for (Iterator i = events.iterator(); i.hasNext();) {
+ *              AsyncEvent event = (AsyncEvent)i.next();
+ *              
+ *              String originalRegionName = event.getRegion().getName();
+ *              //For illustration purpose, use the event to update the duplicate of above region.
+ *              final Region duplicateRegion = CacheHelper.getCache().getRegion(originalRegionName + "_DUP");
+ *               
+ *              final Object key = event.getKey();
+ *              final Object value = event.getDeserializedValue();
+ *              final Operation op = event.getOperation();
+ *              
+ *              if (op.isCreate()) {
+ *                  duplicateRegion.create(key, value);
+ *              } else if (op.isUpdate()) {
+ *                  duplicateRegion.put(key, value);
+ *              } else if (op.isDestroy()) {
+ *                  duplicateRegion.destroy(key);
+ *              }
+ *              
+ *          }
+ *      }
+ * }
+ * </pre>
+ * 
+ * @author pdeole
+ * @since 7.0
+ */
+public interface AsyncEventListener extends CacheCallback {
+
+  /**
+   * Process the list of <code>AsyncEvent</code>s. This method will
+   * asynchronously be called when events are queued to be processed.
+   * The size of the list will be up to batch size events where batch
+   * size is defined in the <code>AsyncEventQueueFactory</code>.
+   *
+   * @param events The list of <code>AsyncEvent</code> to process
+   *
+   * @return boolean    True represents whether the events were successfully processed,
+   *                    false otherwise.
+   */
+  public boolean processEvents(List<AsyncEvent> events);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/AsyncEventQueue.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/AsyncEventQueue.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/AsyncEventQueue.java
new file mode 100644
index 0000000..cadb0ca
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/asyncqueue/AsyncEventQueue.java
@@ -0,0 +1,142 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.asyncqueue;
+
+import java.util.List;
+
+import com.gemstone.gemfire.cache.wan.GatewayEventFilter;
+import com.gemstone.gemfire.cache.wan.GatewayEventSubstitutionFilter;
+import com.gemstone.gemfire.cache.wan.GatewaySender.OrderPolicy;
+
+/**
+ * Interface of AsyncEventQueue. 
+ * This represents the channel over which the events are delivered to the <code>AsyncEventListener</code>. 
+ * 
+ * @author pdeole
+ * @since 7.0
+ */
+public interface AsyncEventQueue {
+
+  /**
+   * @return String  Id of the AsyncEventQueue  
+   */
+  public String getId();
+  
+  /**
+   * The Disk store that is required for overflow and persistence
+   * @return    String
+   */
+  public String getDiskStoreName();//for overflow and persistence
+  
+  /**
+   * The maximum memory after which the data needs to be overflowed to disk.
+   * Default is 100 MB.
+   * @return    int
+   */
+  public int getMaximumQueueMemory();//for overflow
+  
+  /**
+   * Represents the size of a batch that gets delivered over the AsyncEventQueue.
+   * Default batchSize is 100. 
+   * @return    int
+   */
+  public int getBatchSize();
+  
+  /**
+   * Represents the maximum time interval that can elapse before a batch is sent 
+   * from <code>AsyncEventQueue</code>.
+   * Default batchTimeInterval is 5 ms.
+   * 
+   * @return    int
+   */
+  public int getBatchTimeInterval();
+  
+  /**
+   * Represents whether batch conflation is enabled for batches sent 
+   * from <code>AsyncEventQueue</code>.
+   * Default is false.
+   * @return    boolean
+   */
+  public boolean isBatchConflationEnabled();
+  
+  /**
+   * Represents whether the AsyncEventQueue is configured to be persistent or non-persistent.
+   * Default is false.
+   * @return    boolean
+   */
+  public boolean isPersistent();
+  
+  /**
+   * Represents whether writing to disk is synchronous or not.
+   * Default is true.
+   * @return    boolean
+   */
+  public boolean isDiskSynchronous();
+  
+  /**
+   * Represents whether the queue is primary or secondary. 
+   * Events get delivered only by the primary queue. 
+   * If the primary queue goes down then the secondary queue first becomes primary 
+   * and then starts delivering the events.  
+   * @return    boolean
+   */
+  public boolean isPrimary();
+  
+  /**
+   * The <code>AsyncEventListener</code> that is attached to the queue. 
+   * All the event passing over the queue are delivered to attached listener.
+   * @return    AsyncEventListener      Implementation of AsyncEventListener
+   */
+  public AsyncEventListener getAsyncEventListener();
+  
+  /**
+   * Represents whether this queue is parallel (higher throughput) or serial.
+   * @return    boolean    True if the queue is parallel, false otherwise.
+   */
+  public boolean isParallel();
+  
+  /**
+   * Returns the number of dispatcher threads working for this <code>AsyncEventQueue</code>.
+   * Default number of dispatcher threads is 5.
+   * 
+   * @return the number of dispatcher threads working for this <code>AsyncEventQueue</code>
+   */
+  public int getDispatcherThreads();
+  
+  /**
+   * Returns the order policy followed while dispatching the events to AsyncEventListener.
+   * Order policy is set only when dispatcher threads are > 1.
+   * Default order policy is KEY.
+   * @return the order policy followed while dispatching the events to AsyncEventListener.
+   */
+  public OrderPolicy getOrderPolicy();
+  
+  /**
+   * Returns the number of entries in this <code>AsyncEventQueue</code>.
+   * @return the number of entries in this <code>AsyncEventQueue</code>.
+   */
+  public int size();
+  
+  /**
+   * Returns the <code>GatewayEventFilters</code> for this
+   * <code>AsyncEventQueue</code>
+   * 
+   * @return the <code>GatewayEventFilters</code> for this
+   *         <code>AsyncEventQueue</code>
+   */
+  public List<GatewayEventFilter> getGatewayEventFilters();
+  
+  /**
+   * Returns the <code>GatewayEventSubstitutionFilter</code> for this
+   * <code>AsyncEventQueue</code>
+   * 
+   * @return the <code>GatewayEventSubstitutionFilter</code> for this
+   *         <code>AsyncEventQueue</code>
+   */
+  public GatewayEventSubstitutionFilter getGatewayEventSubstitutionFilter();
+}


[37/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberRegionImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberRegionImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberRegionImpl.java
new file mode 100644
index 0000000..e4eebde
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMemberRegionImpl.java
@@ -0,0 +1,372 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.*;
+import com.gemstone.gemfire.cache.*;
+//import com.gemstone.gemfire.internal.Assert;
+//import com.gemstone.gemfire.internal.admin.*;
+import com.gemstone.gemfire.internal.admin.remote.*;
+
+import java.io.File;
+import java.util.*;
+
+/**
+ * View of a region in a GemFire system member's cache.
+ *
+ * @author    Darrel Schneider
+ * @since     3.5
+ */
+public class SystemMemberRegionImpl implements SystemMemberRegion {
+
+  private AdminRegion r;
+  private RegionAttributes ra;
+  private CacheStatistics rs;
+  private Set subregionNames;
+  private Set subregionFullPaths;
+  private int entryCount;
+  private int subregionCount;
+
+  /** The cache to which this region belongs */
+  private final SystemMemberCacheImpl cache;
+
+  // constructors
+  public SystemMemberRegionImpl(SystemMemberCacheImpl cache, Region r)
+  {
+    this.cache = cache;
+    this.r = (AdminRegion)r;
+  }
+
+  private void refreshFields() {
+    this.ra = this.r.getAttributes();
+    if (getStatisticsEnabled() && !this.ra.getDataPolicy().withPartitioning()) {
+      this.rs = this.r.getStatistics();
+    } else {
+      this.rs = null;
+    }
+    { // set subregionNames
+      Set s = this.r.subregions(false);
+      Set names = new TreeSet();
+      Set paths = new TreeSet();
+      Iterator it = s.iterator();
+      while (it.hasNext()) {
+        Region r = (Region)it.next();
+        String name = r.getName();
+        names.add(name);
+        paths.add(this.getFullPath() + Region.SEPARATOR_CHAR + name);
+      }
+      this.subregionNames = names;
+      this.subregionFullPaths = paths;
+    }
+    try {
+      int[] sizes = this.r.sizes();
+      this.entryCount = sizes[0];
+      this.subregionCount = sizes[1];
+    } catch (CacheException ignore) {
+      this.entryCount = 0;
+      this.subregionCount = 0;
+    }
+  }
+  
+  // attributes
+  public String getName() {
+    return this.r.getName();
+  }
+  
+  public String getFullPath() {
+    return this.r.getFullPath();
+  }
+
+  public java.util.Set getSubregionNames() {
+    return this.subregionNames;
+  }
+
+  public java.util.Set getSubregionFullPaths() {
+    return this.subregionFullPaths;
+  }
+
+  public String getUserAttribute() {
+    return (String)r.getUserAttribute();
+  }
+
+  public String getCacheLoader() {
+    Object o = this.ra.getCacheLoader();
+    if (o == null) {
+      return "";
+    } else {
+      return o.toString();
+    }
+  }
+  public String getCacheWriter() {
+    Object o = this.ra.getCacheWriter();
+    if (o == null) {
+      return "";
+    } else {
+      return o.toString();
+    }
+  }
+
+  public String getKeyConstraint() {
+    Class constraint = this.ra.getKeyConstraint();
+    if (constraint == null) {
+      return "";
+    } else {
+      return constraint.getName();
+    }
+  }
+
+  public String getValueConstraint() {
+    Class constraint = this.ra.getValueConstraint();
+    if (constraint == null) {
+      return "";
+    } else {
+      return constraint.getName();
+    }
+  }
+
+  public boolean getEarlyAck() {
+    return this.ra.getEarlyAck();
+  }
+
+  public int getRegionTimeToLiveTimeLimit() {
+    return this.ra.getRegionTimeToLive().getTimeout();
+  }
+
+  public ExpirationAction getRegionTimeToLiveAction() {
+    return this.ra.getRegionTimeToLive().getAction();
+  }
+
+  public int getEntryTimeToLiveTimeLimit() {
+    return this.ra.getEntryTimeToLive().getTimeout();
+  }
+
+  public ExpirationAction getEntryTimeToLiveAction() {
+    return this.ra.getEntryTimeToLive().getAction();
+  }
+
+  public String getCustomEntryTimeToLive() {
+    Object o = this.ra.getCustomEntryTimeToLive();
+    if (o == null) {
+      return "";
+    } else {
+      return o.toString();
+    }
+  }
+  
+  public int getRegionIdleTimeoutTimeLimit() {
+    return this.ra.getRegionIdleTimeout().getTimeout();
+  }
+
+  public ExpirationAction getRegionIdleTimeoutAction() {
+    return this.ra.getRegionIdleTimeout().getAction();
+  }
+
+  public int getEntryIdleTimeoutTimeLimit() {
+    return this.ra.getEntryIdleTimeout().getTimeout();
+  }
+
+  public ExpirationAction getEntryIdleTimeoutAction() {
+    return this.ra.getEntryIdleTimeout().getAction();
+  }
+
+  public String getCustomEntryIdleTimeout() {
+    Object o = this.ra.getCustomEntryIdleTimeout();
+    if (o == null) {
+      return "";
+    } else {
+      return o.toString();
+    }
+  }
+  
+  public MirrorType getMirrorType() {
+    return this.ra.getMirrorType();
+  }
+  
+  public DataPolicy getDataPolicy() {
+    return this.ra.getDataPolicy();
+  }
+  
+  public Scope getScope() {
+    return this.ra.getScope();
+  }
+
+  public EvictionAttributes getEvictionAttributes() {
+    return this.ra.getEvictionAttributes();
+  }
+
+  /**
+   * This method will return an empty string if there are no CacheListeners
+   * defined on the region. If there are more than 1 CacheListeners defined,
+   * this method will return the description of the 1st CacheListener in the
+   * list returned by the getCacheListeners method. If there is only one
+   * CacheListener defined this method will return it's description
+   * 
+   * @return String the region's <code>CacheListener</code> description
+   * @deprecated as of 6.0, use {@link #getCacheListeners} instead
+   */
+  @Deprecated
+  public String getCacheListener() {
+    String[] o = this.getCacheListeners();
+    if (o.length == 0) {
+      return "";
+    }
+    else {
+      return o[0].toString();
+    }
+  }
+
+  /**
+   * This method will return an empty array if there are no CacheListeners
+   * defined on the region. If there are one or more than 1 CacheListeners
+   * defined, this method will return an array which has the description of all
+   * the CacheListeners
+   * 
+   * @return String[] the region's <code>CacheListeners</code> descriptions as a
+   *         String array
+   * @since 6.0
+   */
+  public String[] getCacheListeners() {
+    Object[] o = this.ra.getCacheListeners();
+    String[] ret = null;
+    if (o == null || o.length == 0) {
+      ret = new String[0];
+    }
+    else {
+      ret = new String[o.length];
+      for (int i = 0; i < o.length; i++) {
+        ret[i] = o[i].toString();
+      }
+    }
+    return ret;
+  }
+
+  public int getInitialCapacity() {
+    return this.ra.getInitialCapacity();
+  }
+
+  public float getLoadFactor() {
+    return this.ra.getLoadFactor();
+  }
+
+  public int getConcurrencyLevel() {
+    return this.ra.getConcurrencyLevel();
+  }
+
+  public boolean getConcurrencyChecksEnabled() {
+    return this.ra.getConcurrencyChecksEnabled();
+  }
+
+  public boolean getStatisticsEnabled() {
+    return this.ra.getStatisticsEnabled();
+  }
+
+  public boolean getPersistBackup() {
+    return this.ra.getPersistBackup();
+  }
+
+  public DiskWriteAttributes getDiskWriteAttributes() {
+    return this.ra.getDiskWriteAttributes();
+  }
+
+  public File[] getDiskDirs() {
+    return this.ra.getDiskDirs();
+  }
+
+  public int getEntryCount() {
+    return this.entryCount;
+  }
+  
+  public int getSubregionCount() {
+    return this.subregionCount;
+  }
+
+  public long getLastModifiedTime() {
+    if (this.rs == null) {
+      return 0;
+    } else {
+      return this.rs.getLastModifiedTime();
+    }
+  }
+
+  public long getLastAccessedTime() {
+    if (this.rs == null) {
+      return 0;
+    } else {
+      return this.rs.getLastAccessedTime();
+    }
+  }
+
+  public long getHitCount() {
+    if (this.rs == null) {
+      return 0;
+    } else {
+      return this.rs.getHitCount();
+    }
+  }
+
+  public long getMissCount() {
+    if (this.rs == null) {
+      return 0;
+    } else {
+      return this.rs.getMissCount();
+    }
+  }
+
+  public float getHitRatio() {
+    if (this.rs == null) {
+      return 0;
+    } else {
+      return this.rs.getHitRatio();
+    }
+  }
+  
+  // operations
+  public void refresh() {
+    refreshFields();
+  }
+
+	/**
+	 * Returns a string representation of the object.
+	 * 
+	 * @return a string representation of the object
+	 */
+  @Override
+	public String toString() {
+		return getName();
+	}
+
+  public SystemMemberRegion createSubregion(String name,
+                                            RegionAttributes attrs)
+    throws AdminException {
+
+    Region r =
+      this.cache.getVM().createSubregion(this.cache.getCacheInfo(),
+                                         this.getFullPath(), name, attrs);
+    if (r == null) {
+      return null;
+
+    } else {
+      return this.cache.createSystemMemberRegion(r);
+    }
+
+  }
+
+  public MembershipAttributes getMembershipAttributes() {
+    return this.ra.getMembershipAttributes();
+  }
+  
+  public SubscriptionAttributes getSubscriptionAttributes() {
+    return this.ra.getSubscriptionAttributes();
+  }
+  
+  public PartitionAttributes getPartitionAttributes() {
+    return this.ra.getPartitionAttributes();
+  }
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMembershipEventImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMembershipEventImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMembershipEventImpl.java
new file mode 100644
index 0000000..40e821c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/SystemMembershipEventImpl.java
@@ -0,0 +1,62 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.*;
+import com.gemstone.gemfire.distributed.DistributedMember;
+
+/**
+ * An event delivered to a {@link SystemMembershipListener} when a
+ * member has joined or left the distributed system.
+ *
+ * @author Darrel Schneider
+ * @since 5.0
+ */
+public class SystemMembershipEventImpl implements SystemMembershipEvent {
+
+  /** The id of the member that generated this event */
+  private DistributedMember id;
+
+  ///////////////////////  Constructors  ///////////////////////
+
+  /**
+   * Creates a new <code>SystemMembershipEvent</code> for the member
+   * with the given id.
+   */
+  protected SystemMembershipEventImpl(DistributedMember id) {
+    this.id = id;
+  }
+
+  /////////////////////  Instance Methods  /////////////////////
+
+  public String getMemberId() {
+    return this.id.toString();
+  }
+  
+  public DistributedMember getDistributedMember() {
+    return this.id;
+  }
+
+//   /**
+//    * Returns the user specified callback object associated with this
+//    * membership event.  Note that the callback argument is always
+//    * <code>null</code> for the event delivered to the {@link
+//    * SystemMembershipListener#memberCrashed} method.
+//    *
+//    * @since 4.0
+//    */
+//   public Object getCallbackArgument() {
+//     throw new UnsupportedOperationException("Not implemented yet");
+//   }
+
+  @Override
+  public String toString() {
+    return "Member " + this.getMemberId();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/doc-files/config-hierarchy.fig
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/doc-files/config-hierarchy.fig b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/doc-files/config-hierarchy.fig
new file mode 100644
index 0000000..7d3f34d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/doc-files/config-hierarchy.fig
@@ -0,0 +1,156 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+Letter  
+100.00
+Single
+-2
+1200 2
+6 150 3825 2325 4725
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 150 4200 2325 4200
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 150 4725 2325 4725 2325 3825 150 3825 150 4725
+4 0 0 50 -1 1 12 0.0000 4 180 630 300 4425 port : int\001
+4 0 0 50 -1 1 12 0.0000 4 180 1485 300 4665 bindAddress : String\001
+4 0 0 50 -1 1 12 0.0000 4 180 1920 300 4050 DistributionLocatorConfig\001
+-6
+6 2475 3825 4500 4125
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 2475 3825 4500 3825 4500 4125 2475 4125 2475 3825
+4 0 0 50 -1 1 12 0.0000 4 180 1785 2625 4050 GemFireManagerConfig\001
+-6
+6 4650 3825 6375 4500
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 4650 4500 6375 4500 6375 3825 4650 3825 4650 4500
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 4650 4200 6375 4200
+4 0 0 50 -1 1 12 0.0000 4 180 1545 4725 4425 cacheXmlFile : String\001
+4 0 0 50 -1 1 12 0.0000 4 180 1395 4800 4050 CacheServerConfig\001
+-6
+6 6525 3825 7950 4125
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 6525 3825 7950 3825 7950 4125 6525 4125 6525 3825
+4 0 0 50 -1 1 12 0.0000 4 180 1290 6600 4050 GFXServerConfig\001
+-6
+6 3225 675 5250 2925
+6 3300 2400 4575 2850
+6 3300 2400 4575 2625
+4 0 0 50 -1 1 12 0.0000 4 180 1245 3300 2565 +validate() : void\001
+-6
+4 0 0 50 -1 1 12 0.0000 4 180 1230 3300 2805 +clone() : Object\001
+-6
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 3225 2925 5250 2925 5250 675 3225 675 3225 2925
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 3225 1050 5250 1050
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 3225 2325 5250 2325
+4 0 0 50 -1 1 12 0.0000 4 180 885 3300 1275 host : String\001
+4 0 0 50 -1 1 12 0.0000 4 180 1860 3300 1515 workingDirectory : String\001
+4 0 0 50 -1 1 12 0.0000 4 180 1830 3300 1755 productDirectory : String\001
+4 0 0 50 -1 1 12 0.0000 4 180 1830 3300 1995 remoteCommand : String\001
+4 0 0 50 -1 1 12 0.0000 4 180 720 3300 2235 id : String\001
+4 0 0 50 -1 1 12 0.0000 4 180 1560 3450 900 ManagedEntityConfig\001
+-6
+6 6750 7725 7650 8025
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 6750 7725 7650 7725 7650 8025 6750 8025 6750 7725
+4 0 0 50 -1 1 12 0.0000 4 135 810 6825 7950 GFXServer\001
+-6
+6 525 7725 2100 8025
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 525 7725 2100 7725 2100 8025 525 8025 525 7725
+4 0 0 50 -1 1 12 0.0000 4 135 1440 600 7950 DistributionLocator\001
+-6
+6 2025 5625 3600 7050
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 2025 7050 3600 7050 3600 5625 2025 5625 2025 7050
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 2025 6000 3600 6000
+4 0 0 50 -1 1 12 0.0000 4 180 1440 2100 6225 isRunning : boolean\001
+4 0 0 50 -1 1 12 0.0000 4 180 900 2100 6465 start() : void\001
+4 0 0 50 -1 1 12 0.0000 4 180 870 2100 6705 stop() : void\001
+4 0 0 50 -1 1 12 0.0000 4 180 1200 2100 6945 getLog() : String\001
+4 0 0 50 -1 1 12 0.0000 4 180 1080 2250 5850 ManagedEntity\001
+-6
+6 5175 5625 7275 6975
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 5175 6975 7275 6975 7275 5625 5175 5625 5175 6975
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 5175 6000 7275 6000
+4 0 0 50 -1 1 12 0.0000 4 180 1875 5325 6225 type : SystemMemberType\001
+4 0 0 50 -1 1 12 0.0000 4 180 1455 5325 6465 licsense : Properties\001
+4 0 0 50 -1 1 12 0.0000 4 180 1110 5325 6705 version : String\001
+4 0 0 50 -1 1 12 0.0000 4 135 1425 5325 6945 hasCache : boolean\001
+4 0 0 50 -1 1 12 0.0000 4 180 1095 5700 5850 SystemMember\001
+-6
+6 4875 7725 5925 8025
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 4875 7725 5925 7725 5925 8025 4875 8025 4875 7725
+4 0 0 50 -1 1 12 0.0000 4 135 915 4950 7950 CacheServer\001
+-6
+6 2925 7725 4350 8025
+6 2925 7725 4350 8025
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 2925 7725 4350 7725 4350 8025 2925 8025 2925 7725
+4 0 0 50 -1 1 12 0.0000 4 180 1305 3000 7950 GemFireManager\001
+-6
+-6
+6 150 9375 2550 9675
+2 2 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 5
+	 150 9375 2550 9375 2550 9675 150 9675 150 9375
+4 0 0 50 -1 2 12 0.0000 4 180 2250 225 9600 DistributionLocatorJmxImpl\001
+-6
+6 525 8625 2625 8925
+2 2 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 5
+	 525 8625 2625 8625 2625 8925 525 8925 525 8625
+4 0 0 50 -1 2 12 0.0000 4 180 1920 600 8850 DistributionLocatorImpl\001
+-6
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4
+	 1050 3825 1050 3375 7200 3375 7200 3825
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 3450 3375 3450 3825
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 5475 3375 5475 3825
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	1 0 1.00 120.00 120.00
+	 4200 3375 4200 2925
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4
+	 1125 7725 1125 7500 7200 7500 7200 7725
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 3375 7725 3375 7500
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 5250 7725 5250 7500
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	1 0 1.00 120.00 120.00
+	 2700 7500 2700 7050
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4
+	 4200 7725 4200 7275 7350 7275 7350 7725
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	1 0 1.00 120.00 120.00
+	 6150 7275 6150 6975
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 5475 7725 5475 7275
+2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
+	0 0 1.00 120.00 120.00
+	 750 7725 750 4725
+2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
+	0 0 1.00 120.00 120.00
+	 3825 7725 3825 4125
+2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
+	0 0 1.00 120.00 120.00
+	 4950 7725 4950 4500
+2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
+	0 0 1.00 120.00 120.00
+	 7500 7725 7500 4125
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
+	1 0 1.00 120.00 120.00
+	 300 9375 300 4725
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
+	1 0 1.00 120.00 120.00
+	 1275 8625 1275 8025
+2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
+	1 0 1.00 120.00 120.00
+	 1275 9375 1275 8925

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/doc-files/health-classes.fig
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/doc-files/health-classes.fig b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/doc-files/health-classes.fig
new file mode 100644
index 0000000..b2f8342
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/doc-files/health-classes.fig
@@ -0,0 +1,233 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter  
+100.00
+Single
+-2
+1200 2
+6 300 2475 4050 4050
+6 2550 3000 4050 3300
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 2550 3000 4050 3000 4050 3300 2550 3300 2550 3000
+4 1 0 50 -1 1 12 0.0000 4 180 1410 3300 3225 CacheHealthConfig\001
+-6
+6 300 3000 1950 3300
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 300 3000 1950 3000 1950 3300 300 3300 300 3000
+4 1 0 50 -1 1 12 0.0000 4 180 1560 1125 3225 MemberHealthConfig\001
+-6
+6 1350 3750 3150 4050
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 1350 3750 3150 3750 3150 4050 1350 4050 1350 3750
+4 1 0 50 -1 1 12 0.0000 4 180 1605 2250 3975 GemFireHealthConfig\001
+-6
+6 1200 2475 3450 2775
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 1200 2475 3450 2475 3450 2775 1200 2775 1200 2475
+4 1 0 50 -1 1 12 0.0000 4 180 2115 2325 2700 SystemManagerHealthConfig\001
+-6
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 4
+	1 0 1.00 150.00 150.00
+	1 0 1.00 150.00 150.00
+	 1125 3300 1125 3600 3300 3600 3300 3300
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2
+	1 0 1.00 150.00 150.00
+	 2250 2775 2250 3750
+-6
+6 1125 5925 3525 6225
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 1125 5925 3525 5925 3525 6225 1125 6225 1125 5925
+4 1 0 50 -1 1 12 0.0000 4 180 2265 2325 6150 DistributedSystemHealthConfig\001
+-6
+6 2325 5025 3525 5325
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 2325 5025 3525 5025 3525 5325 2325 5325 2325 5025
+4 1 0 50 -1 1 12 0.0000 4 135 1125 2925 5250 GemFireHealth\001
+-6
+6 4950 5925 7950 6225
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 4950 5925 7950 5925 7950 6225 4950 6225 4950 5925
+4 1 0 50 -1 2 12 0.0000 4 180 2850 6450 6150 DistributedSystemHealthConfigImpl\001
+-6
+6 9000 6750 12150 7425
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 9075 6825 12075 6825 12075 7350 9075 7350 9075 6825
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 9000 6750 12150 6750 12150 7425 9000 7425 9000 6750
+4 2 0 50 -1 -1 10 0.0000 4 135 2760 11925 7050 Class Hierarchy of the "Health" admin classes\001
+4 2 0 50 -1 -1 10 0.0000 6 105 765 11925 7230 GemFire 3.5\001
+-6
+6 5775 1050 7275 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 7275 1350 5775 1350 5775 1050 7275 1050 7275 1350
+4 1 0 50 -1 1 12 0.0000 4 180 1365 6525 1275 java.io.Serializable\001
+-6
+6 5475 1725 7725 2025
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 5475 1725 7725 1725 7725 2025 5475 2025 5475 1725
+4 1 0 50 -1 2 12 0.0000 4 180 2055 6600 1950 MemberHealthConfigImpl\001
+-6
+6 5475 3750 7725 4050
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 5475 3750 7725 3750 7725 4050 5475 4050 5475 3750
+4 1 0 50 -1 2 12 0.0000 4 180 2070 6600 3975 GemFireHealthConfigImpl\001
+-6
+6 5625 2400 7725 2700
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 5625 2400 7725 2400 7725 2700 5625 2700 5625 2400
+4 1 0 50 -1 2 12 0.0000 4 180 1890 6675 2625 CacheHealthConfigImpl\001
+-6
+6 5325 3075 8175 3375
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 5325 3075 8175 3075 8175 3375 5325 3375 5325 3075
+4 1 0 50 -1 2 12 0.0000 4 180 2655 6750 3300 SystemManagerHealthConfigImpl\001
+-6
+6 8775 3075 11475 3375
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 8775 3075 11475 3075 11475 3375 8775 3375 8775 3075
+4 1 0 50 -1 2 12 0.0000 4 180 2520 10125 3300 SystemManagerHealthEvaluator\001
+-6
+6 10125 3750 12225 4050
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 10125 3750 12225 3750 12225 4050 10125 4050 10125 3750
+4 1 0 50 -1 2 12 0.0000 4 135 1935 11175 3975 GemFireHealthEvaluator\001
+-6
+6 8025 975 8775 1275
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 8025 975 8775 975 8775 1275 8025 1275 8025 975
+4 1 0 50 -1 1 12 0.0000 4 135 630 8400 1200 Statistics\001
+-6
+6 9600 975 11625 1275
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 9600 975 11625 975 11625 1275 9600 1275 9600 975
+4 0 0 50 -1 3 12 0.0000 4 135 1845 9675 1200 AbstractHealthEvaluator\001
+-6
+6 9000 2400 10950 2700
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 9000 2400 10950 2400 10950 2700 9000 2700 9000 2400
+4 1 0 50 -1 2 12 0.0000 4 135 1755 9975 2625 CacheHealthEvaluator\001
+-6
+6 8325 1725 10425 2025
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 8325 1725 10425 1725 10425 2025 8325 2025 8325 1725
+4 1 0 50 -1 2 12 0.0000 4 135 1920 9375 1950 MemberHealthEvaluator\001
+-6
+6 4725 4350 6150 4650
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 4725 4350 6150 4350 6150 4650 4725 4650 4725 4350
+4 1 0 50 -1 1 12 0.0000 4 135 1305 5475 4575 JoinLeaveListener\001
+-6
+6 6600 4350 9600 4650
+6 6600 4350 7875 4650
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 6600 4350 7875 4350 7875 4650 6600 4650 6600 4350
+4 1 0 50 -1 1 12 0.0000 4 135 1065 7275 4575 HealthListener\001
+-6
+6 8550 4350 9600 4650
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 8550 4350 9600 4350 9600 4650 8550 4650 8550 4350
+4 1 0 50 -1 1 12 0.0000 4 135 900 9075 4575 GemFireVM\001
+-6
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	0 0 1.00 75.00 150.00
+	 7875 4500 8550 4500
+-6
+6 5175 5025 6900 5325
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 5175 5025 6900 5025 6900 5325 5175 5325 5175 5025
+4 1 0 50 -1 2 12 0.0000 4 180 1545 6000 5250 GemFireHealthImpl\001
+-6
+6 10350 4725 12000 5025
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 10350 4725 12000 4725 12000 5025 10350 5025 10350 4725
+4 0 0 50 -1 2 12 0.0000 4 180 1515 10425 4950 HealthMonitorImpl\001
+-6
+6 8625 5925 11475 6225
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+	 8625 5925 11475 5925 11475 6225 8625 6225 8625 5925
+4 1 0 50 -1 2 12 0.0000 4 180 2715 10050 6150 DistributedSystemHealthEvaluator\001
+-6
+2 1 2 1 0 7 50 -1 -1 3.000 0 0 -1 0 0 2
+	 4500 525 4500 7500
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2
+	1 0 1.00 150.00 150.00
+	 3150 3900 5475 3900
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 2625 5025 2625 4050
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	0 0 1.00 75.00 150.00
+	 2925 5325 2925 5925
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2
+	1 0 1.00 150.00 150.00
+	 3525 5175 5175 5175
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 1 2
+	1 0 1.00 150.00 150.00
+	 3525 6075 4950 6075
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	0 0 1.00 75.00 150.00
+	 5550 5325 5550 5925
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	0 0 1.00 75.00 150.00
+	 8625 6075 7950 6075
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	0 0 1.00 75.00 150.00
+	 6375 5025 6375 4050
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	1 0 1.00 150.00 150.00
+	 6525 3750 6525 3375
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	1 0 1.00 150.00 150.00
+	 6525 3075 6525 2700
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	1 0 1.00 150.00 150.00
+	 6525 2400 6525 2025
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
+	1 0 1.00 150.00 150.00
+	 6525 1725 6525 1350
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	0 0 1.00 75.00 150.00
+	 8775 3225 8175 3225
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	0 0 1.00 75.00 150.00
+	 10125 3900 7725 3900
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	0 0 1.00 75.00 150.00
+	 8325 1875 7725 1875
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	0 0 1.00 75.00 150.00
+	 8925 2550 7725 2550
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	1 0 1.00 150.00 150.00
+	 11325 3075 11325 1275
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	1 0 1.00 150.00 150.00
+	 9975 1725 9975 1275
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
+	 9600 1125 8775 1125
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 3
+	0 0 1.00 60.00 120.00
+	 10425 1875 11925 1875 11925 3750
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2
+	0 0 1.00 60.00 120.00
+	 10950 2550 11925 2550
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	1 0 1.00 150.00 150.00
+	 10800 2400 10800 1275
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
+	1 0 1.00 150.00 150.00
+	 5475 5025 5475 4650
+2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
+	1 0 1.00 150.00 150.00
+	 6750 5025 6750 4650
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+	0 0 1.00 60.00 120.00
+	 11100 4725 11100 4050
+2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 4
+	0 0 1.00 60.00 120.00
+	 6375 5325 6375 5625 9975 5625 9975 5925
+4 1 0 50 -1 -1 12 0.0000 4 75 90 2700 4200 *\001
+4 2 0 50 -1 -1 12 0.0000 4 180 2085 4350 675 com.gemstone.gemfire.admin\001
+4 0 0 50 -1 -1 12 0.0000 4 180 2655 4650 675 com.gemstone.gemfire.admin.internal\001
+4 1 0 50 -1 -1 12 0.0000 4 75 90 8925 1050 *\001

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/doc-files/health-classes.gif
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/doc-files/health-classes.gif b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/doc-files/health-classes.gif
new file mode 100644
index 0000000..131347a
Binary files /dev/null and b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/doc-files/health-classes.gif differ

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/package.html
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/package.html b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/package.html
new file mode 100644
index 0000000..0bffe07
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/package.html
@@ -0,0 +1,37 @@
+<HTML>
+<BODY>
+
+<P>Contains the implementation of the external admin APIs from {@link
+com.gemstone.gemfire.admin}.</P>
+
+<H2>Monitoring the "health" of GemFire</H2>
+
+<P>The health monitoring implementation comes in two pieces.  On the
+client (administrator) side there is a {@link
+com.gemstone.gemfire.admin.internal.GemFireHealthImpl} object that is
+responsible for configuring a {@link
+com.gemstone.gemfire.distributed.internal.HealthMonitorImpl} that runs
+in the member VMs.  The communication between the administration
+process and the member process is accomplised via a {@link
+com.gemstone.gemfire.internal.admin.GemFireVM GemFireVM} from the
+"internal admin" API.  The <code>HealthMonitorImpl</code> is a thread
+that periodically consults a {@link
+com.gemstone.gemfire.admin.internal.GemFireHealthEvaluator} that uses
+a {@link com.gemstone.gemfire.admin.internal.GemFireHealthConfigImpl}
+to determine the health of a GemFire component.  Most of the health
+criteria are based on {@linkplain com.gemstone.gemfire.Statistics
+statistics} that are maintained by GemFire.  When the
+<code>HealthMonitorImpl</code> determines that the health of a GemFire
+component has changed, it alerts the administrator process via a
+{@link com.gemstone.gemfire.internal.admin.HealthListener}.</P>
+
+
+<P>The below diagram explains how the classes that monitor the health
+of GemFire are implemented.</P>
+
+<CENTER>
+<IMG src="doc-files/health-classes.gif" HEIGHT="803" WIDTH="473"/>
+</CENTER>
+
+</BODY>
+</HTML>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/Agent.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/Agent.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/Agent.java
new file mode 100644
index 0000000..43ec592
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/Agent.java
@@ -0,0 +1,156 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx;
+
+import com.gemstone.gemfire.LogWriter;
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.AdminDistributedSystem;
+
+//import javax.management.MBeanException;
+import javax.management.MalformedObjectNameException;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+/**
+ * A server component that provides administration-related information
+ * about a GemFire distributed system via the Java Management
+ * Extension JMX API.  When a JMX <code>Agent</code> is created, it
+ * registers an MBean that represents {@link #getObjectName itself}. 
+ * Click <A href="doc-files/mbeans-descriptions.html">here</A> for a
+ * description of the attributes, operations, and notifications of
+ * this and other GemFire JMX MBeans.
+ *
+ * <P>
+ *
+ * The GemFire JMX Agent currently supports three JMX "adapters"
+ * through which clients can access the GemFire management beans: an
+ * "HTTP adapter" that allows a web browser client to view and modify
+ * management beans via HTTP or HTTPS, an "RMI adapter" that allows
+ * Java programs to access management beans using Remote Method
+ * Invocation, and an "SNMP adapter" that allows SNMP to access
+ * management beans.  Information about configuring these adapters can
+ * be found in {@link AgentConfig}.
+ *
+ * <P>
+ *
+ * In most distributed caching architectures, JMX administration
+ * agents are run in their own processes.  A stand-alone JMX agent is
+ * managed using the <code>agent</code> command line utility:
+ *
+ * <PRE>
+ * $ agent start
+ * </PRE>
+ *
+ * This class allows a GemFire application VM to host a JMX management
+ * agent.  Architectures with "co-located" JMX agents reduce the
+ * number of overall proceses required.  However, hosting a JMX
+ * management agent in the same VM as a GemFire application is not
+ * generally recommended because it adds extra burden to an
+ * application VM and in the event that the application VM exits the
+ * administration information will no longer be available.
+ *
+ * @see AgentConfig
+ * @see AgentFactory
+ *
+ * @author David Whitlock
+ * @since 4.0
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface Agent {
+
+  /** Lookup name for RMIConnector when rmi-registry-enabled is true */
+  public static final String JNDI_NAME = "/jmxconnector";
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  /**
+   * Returns the configuration object for this JMX Agent.
+   */
+  public AgentConfig getConfig();
+
+  /**
+   * Starts this JMX Agent and its associated adapters.  This method
+   * does not {@linkplain #connectToSystem connect} to the distributed
+   * system.
+   */
+  public void start();
+
+  /**
+   * Returns the JMX <code>MBeanServer</code> with which GemFire
+   * MBeans are registered or <code>null</code> if this
+   * <code>Agent</code> is not started.
+   */
+  public MBeanServer getMBeanServer();
+
+  /**
+   * {@linkplain #disconnectFromSystem Disconnects} from the
+   * distributed system and stops this JMX Agent and all of its
+   * associated adapters.
+   */
+  public void stop();
+
+  /**
+   * Returns the <code>ObjectName</code> of the JMX management bean
+   * that represents this agent or <code>null</code> if this
+   * <code>Agent</code> has not been started.
+   */
+  public ObjectName getObjectName();
+
+  /**
+   * Returns whether or not this JMX <code>Agent</code> is currently
+   * providing information about a distributed system.
+   */
+  public boolean isConnected();
+
+  /**
+   * Connects to the distributed system described by this <code>Agent</code>'s 
+   * configuration.
+   *
+   * @return The object name of the system that the <code>Agent</code>
+   *         is now connected to.
+   */
+  public ObjectName connectToSystem()
+    throws AdminException, MalformedObjectNameException;
+
+  /**
+   * Returns the <code>AdminDistributedSystem</code> that underlies
+   * this JMX <code>Agent</code> or <code>null</code> is this agent is
+   * not {@linkplain #isConnected connected}.
+   */
+  public AdminDistributedSystem getDistributedSystem();
+
+  /**
+   * Returns the object name of the JMX MBean that represents the
+   * distributed system administered by this <code>Agent</code> or
+   * <code>null</code> if this <code>Agent</code> has not {@linkplain
+   * #connectToSystem connected} to the distributed system.
+   */
+  public ObjectName manageDistributedSystem()
+    throws MalformedObjectNameException;
+
+  /**
+   * Disconnects this agent from the distributed system and
+   * unregisters the management beans that provided information about
+   * it.  However, this agent's adapters are not stopped and it is
+   * possible to reconfigure this <code>Agent</code> to connect to
+   * another distributed system.
+   */
+  public void disconnectFromSystem();
+
+  /**
+   * Saves the configuration for this <code>Agent</code> to the file
+   * specified by @link AgentConfig#getPropertyFile.
+   */
+  public void saveProperties();
+
+  /**
+   * Returns the <code>LogWriter</code> used for logging information.
+   */
+  public LogWriter getLogWriter();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/AgentConfig.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/AgentConfig.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/AgentConfig.java
new file mode 100644
index 0000000..c48cc11
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/AgentConfig.java
@@ -0,0 +1,875 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx;
+
+import com.gemstone.gemfire.admin.DistributedSystemConfig;
+//import com.gemstone.gemfire.admin.internal.InetAddressUtil;
+
+/**
+ * A configuration object for a JMX administration {@linkplain Agent
+ * agent} that is hosted by a GemFire application VM.  A file named
+ * {@link #DEFAULT_PROPERTY_FILE "agent.properties"} can be used to
+ * override the default values of <code>AgentConfig</code> attributes.
+ * The "gfAgentPropertyFile" {@linkplain System#getProperty(java.lang.String) system
+ * property} can be used to specify an agent properties file other
+ * than "agent.properties".  System properties prefixed with
+ * {@linkplain #SYSTEM_PROPERTY_PREFIX "gemfire.agent."} can be used to
+ * override the values in the properties file.  For instance
+ * "-Dgemfire.agent.http-port=8081" can be used to override the
+ * default port for the HTTP adapter.  Configuration related to the
+ * distributed system that the JMX agent administers is inherited from
+ * and described in <code>AgentConfig</code>'s superinterface, {@link
+ * DistributedSystemConfig}.
+ *
+ * <P>
+ *
+ * An <code>AgentConfig</code> can be modified using a number of
+ * mutator methods until it is used to create an <code>Agent</code>.
+ * After that, attempts to modify most attributes in the
+ * <code>AgentConfig</code> will result in an {@link
+ * IllegalStateException} being thrown.  If you wish to use the same
+ * <code>AgentConfig</code> to configure multiple <code>Agent</code>s,
+ * a copy of the <code>AgentConfig</code> object can be made by
+ * invoking its {@link #clone} method.
+ *
+ * <P>
+ *
+ * <B>JMX Administation Agent Configuration Properties</B>
+ *
+ * <dl>
+ *   <a name="auto-connect"><dt>{@linkplain #AUTO_CONNECT_NAME auto-connect}</dt></a>
+ *   <dd><U>Description</U>: whether or not a JMX agent will
+ *   automatically connect to the distributed system it is configured to
+ *   administer.</dd>
+ *   <dd><U>{@linkplain #DEFAULT_AUTO_CONNECT Default}</U>: false</dd>
+ * </dl>
+ *
+ * <B>JMX Agent SSL Configuration Properties</B>
+ *
+ * <P>
+ *
+ * These parameters configure sockets that are created by the GemFire
+ * JMX Agent regardless of which adapters are enabled.  These setting
+ * apply to all adapters.  For example, if clients connect to the RMI
+ * adapter using SSL, then clients must also connect to the HTTP
+ * adapter using SSL (HTTPS).  Note that these configuration
+ * attributes do <b>not</b> effect how the agent connects to the
+ * distributed system it administers, only how JMX clients connect to
+ * the agent.
+ *
+ * <dl>
+ *   <a name="agent-ssl-enabled"><dt>{@linkplain #AGENT_SSL_ENABLED_NAME agent-ssl-enabled}</dt></a>
+ *   <dd><U>Description</U>: whether or not connections to the JMX agent
+ *   require SSL
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_AGENT_SSL_ENABLED Default}</U>: false</dd>
+ * </dl>
+ * 
+ * <dl>
+ *   <a name="agent-ssl-protocols"><dt>{@linkplain #AGENT_SSL_PROTOCOLS_NAME agent-ssl-protocols}</dt></a>
+ *   <dd><U>Description</U>: the SSL protocols to be used when connecting
+ *   to the JMX agent
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_AGENT_SSL_PROTOCOLS Default}</U>: any</dd>
+ * </dl>
+ *
+ * <dl>
+ *   <a name="agent-ssl-ciphers"><dt>{@linkplain #AGENT_SSL_CIPHERS_NAME agent-ssl-ciphers}</dt></a>
+ *   <dd><U>Description</U>: the SSL ciphers to be used when connecting
+ *   to the JMX agent
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_AGENT_SSL_CIPHERS Default}</U>: any</dd>
+ * </dl>
+ *
+ * <dl>
+ *   <a name="agent-ssl-require-authentication"><dt>{@linkplain #AGENT_SSL_REQUIRE_AUTHENTICATION_NAME agent-ssl-require-authentication}</dt></a>
+ *   <dd><U>Description</U>: whether or not SSL connections to the RMI
+ *   adapter require authentication
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_AGENT_SSL_REQUIRE_AUTHENTICATION Default}</U>: true</dd>
+ * </dl>
+ *
+ * <dl>
+ *   <a name="http-ssl-require-authentication"><dt>{@linkplain #HTTP_SSL_REQUIRE_AUTHENTICATION_NAME http-ssl-require-authentication}</dt></a>
+ *   <dd><U>Description</U>: whether or not SSL connections to the HTTP
+ *   adapter require authentication
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_HTTP_SSL_REQUIRE_AUTHENTICATION Default}</U>: false</dd>
+ * </dl>
+ *
+ * <B>HTTP Adapter Configuration</B>
+ *
+ * <dl>
+ *   <a name="http-enabled"><dt>{@linkplain #HTTP_ENABLED_NAME http-enabled}</dt></a>
+ *   <dd><U>Description</U>: whether or not the HTTP adapter is
+ *   enabled in the JMX agent.</dd>
+ *   <dd><U>{@linkplain #DEFAULT_HTTP_ENABLED Default}</U>: true</dd>
+ * </dl>
+ * 
+ * <dl>
+ *   <a name="http-port"><dt>{@linkplain #HTTP_PORT_NAME http-port}</dt></a>
+ *   <dd><U>Description</U>: the port on which the HTTP adapter should
+ *   listen for client connections.
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_HTTP_PORT Default}</U>: 8080</dd>
+ * </dl>
+ *
+ * <dl>
+ *   <a name="http-bind-address"><dt>{@linkplain #HTTP_BIND_ADDRESS_NAME http-bind-address}</dt></a>
+ *   <dd><U>Description</U>: the machine name or IP address to which
+ *   the HTTP listening socket should be bound.  If this value is
+ *   "localhost", then the socket will be bound to the loopback
+ *   address (127.0.0.1) and the adapter will only be accessible via
+ *   the URL <code>http://localhost:8080</code>.</dd>
+ *   <dd><U>{@linkplain #DEFAULT_HTTP_BIND_ADDRESS Default}</U>: ""
+ *   (all network addresses)</dd>
+ * </dl>
+ *
+ * <dl>
+ *   <a name="http-authentication-enabled"><dt>{@linkplain #HTTP_AUTHENTICATION_ENABLED_NAME http-authentication-enabled}</dt></a>
+ *   <dd><U>Description</U>: Whether or not connections to the HTTP
+ *   adapter should be authenticated with a user name and password.
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_HTTP_AUTHENTICATION_ENABLED Default}</U>: false</dd>
+ * </dl>
+ *
+ * <dl>
+ *   <a name="http-authentication-user"><dt>{@linkplain #HTTP_AUTHENTICATION_USER_NAME http-authentication-user}</dt></a>
+ *   <dd><U>Description</U>: the user name for authenticating secure
+ *   communication. 
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_HTTP_AUTHENTICATION_USER Default}</U>: admin</dd>
+ * </dl>
+ *
+ * <dl>
+ *   <a name="http-authentication-password"><dt>{@linkplain #HTTP_AUTHENTICATION_PASSWORD_NAME http-authentication-password}</dt></a>
+ *   <dd><U>Description</U>: the password for authenticating secure
+ *   communication. 
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_HTTP_AUTHENTICATION_PASSWORD Default}</U>: password</dd>
+ * </dl>
+ *
+ * <B>RMI Adapter Configuration Properties</B>
+ *
+ * <dl>
+ *   <a name="rmi-enabled"><dt>{@linkplain #RMI_ENABLED_NAME rmi-enabled}</dt></a>
+ *   <dd><U>Description</U>: whether or not the RMI JMX adapter is enabled
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_RMI_ENABLED Default}</U>: true</dd>
+ * </dl>
+ *
+ * <dl>
+ *   <a name="rmi-registry-enabled"><dt>{@linkplain #RMI_REGISTRY_ENABLED_NAME rmi-registry-enabled}</dt></a>
+ *   <dd><U>Description</U>: whether or not the JMX agent should start
+ *   an RMI registry.  Alternatively, a registry outside of the JMX
+ *   agent VM can be used.
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_RMI_REGISTRY_ENABLED Default}</U>: true</dd>
+ * </dl>
+ *
+ * <dl>
+ *   <a name="rmi-port"><dt>{@linkplain #RMI_PORT_NAME rmi-port}</dt></a>
+ *   <dd><U>Description</U>: the port of the RMI registry in which the
+ *   JMX Agent should bind remote objects.
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_RMI_PORT Default}</U>: 1099</dd>
+ * </dl>
+ * 
+ * <dl>
+ *   <a name="rmi-server-port"><dt>{@linkplain #RMI_PORT_NAME rmi-server-port}</dt></a>
+ *   <dd><U>Description</U>: the port to be used by the RMI Server started by
+ *   JMX Agent.
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_RMI_SERVER_PORT Default}</U>: 0</dd>
+ * </dl> 
+ *
+ * <dl>
+ *   <a name="rmi-bind-address"><dt>{@linkplain #RMI_BIND_ADDRESS_NAME rmi-bind-address}</dt></a>
+ *   <dd><U>Description</U>: the bind address on which the RMI
+ *   registry binds its sockets.
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_RMI_BIND_ADDRESS Default}</U>: ""
+ *   (all network addresses)</dd>
+ * </dl>
+ *
+ * <B>AdventNet SNMP Adapter Configuration Properties</B>
+ *
+ * <dl>
+ *   <a name="snmp-enabled"><dt>{@linkplain #SNMP_ENABLED_NAME snmp-enabled}</dt></a>
+ *   <dd><U>Description</U>: whether or not the SNMP JMX adapter is
+ *   enabled 
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_SNMP_ENABLED Default}</U>: false</dd>
+ * </dl>
+ * 
+ * <dl>
+ *   <a name="snmp-bind-address"><dt>{@linkplain #SNMP_BIND_ADDRESS_NAME snmp-bind-address}</dt></a>
+ *   <dd><U>Description</U>: the host name to which sockets used by the
+ *   SNMP adapter should be bound.
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_SNMP_BIND_ADDRESS Default}</U>: the name of
+ *   the local machine (not <code>localhost</code>)</dd>
+ * </dl>
+ *
+ * <dl>
+ *   <a name="snmp-directory"><dt>{@linkplain #SNMP_DIRECTORY_NAME snmp-directory}</dt></a>
+ *   <dd><U>Description</U>: the deployment directory for AdventNet
+ *   SNMP Adaptor 
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_SNMP_DIRECTORY Default}</U>: ""</dd>
+ * </dl>
+ * 
+ * <B>JMX Agent Email Notification Properties (for statistics alerts)</B>
+ * 
+ * <dl>
+ *   <a name="email-notification-enabled"><dt>{@linkplain #EMAIL_NOTIFICATIONS_ENABLED_NAME email-notification-enabled}</dt></a>
+ *   <dd><U>Description</U>: Whether or not email notifications are enabled for statistics alerts.
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_EMAIL_NOTIFICATIONS_ENABLED Default}</U>: false</dd>
+ * </dl>
+ * 
+ * <dl>
+ *   <a name="email-notification-from"><dt>{@linkplain #EMAIL_NOTIFICATIONS_FROM_NAME email-notification-from}</dt></a>
+ *   <dd><U>Description</U>: Email address to be used to send email notifications.
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_EMAIL_FROM Default}</U>: ""</dd>
+ * </dl>
+ * 
+ * <dl>
+ *   <a name="email-notification-host"><dt>{@linkplain #EMAIL_NOTIFICATIONS_HOST_NAME email-notification-host}</dt></a>
+ *   <dd><U>Description</U>: The host name of the mail server to be used for email communication. 
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_EMAIL_HOST Default}</U>: ""</dd>
+ * </dl>
+ * 
+ * <dl>
+ *   <a name="email-notification-to"><dt>{@linkplain #EMAIL_NOTIFICATIONS_TO_LIST_NAME email-notification-to}</dt></a>
+ *   <dd><U>Description</U>: Email address where the email notifications should be sent.
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_EMAIL_TO_LIST Default}</U>: ""</dd>
+ * </dl>
+ * 
+ * <dl>
+ *   <a name="state-save-file"><dt>{@linkplain #STATE_SAVE_FILE_NAME state-save-file}</dt></a>
+ *   <dd><U>Description</U>: The name of the file to be used for saving agent state. The file
+         is stored in the same directory in which the agent.properties file is located
+ *   </dd>
+ *   <dd><U>{@linkplain #DEFAULT_STATE_SAVE_FILE Default}</U>: ""</dd>
+ * </dl>
+ * 
+ *
+ * @author David Whitlock
+ * @since 4.0
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface AgentConfig extends DistributedSystemConfig {
+
+  /** The prefix for JMX Agent configuration system properties */
+  public static final String SYSTEM_PROPERTY_PREFIX =
+    "gemfire.agent.";
+
+  /** The default "propertyFile" value */
+  public static final String DEFAULT_PROPERTY_FILE = "agent.properties";
+
+  /** The default name for file that has "agent state saved serialized" */
+  public static final String DEFAULT_STATE_SAVE_FILE = "agent.ser";
+  
+  /** The name of the "auto-connect" property */
+  public static final String AUTO_CONNECT_NAME = "auto-connect";
+
+  /** The default value of the "auto-connect" property  */
+  public static final boolean DEFAULT_AUTO_CONNECT = true;
+
+  // -------------------------------------------------------------------------
+  //   HttpAdaptor properties...
+  // -------------------------------------------------------------------------
+  
+  /** The name of the "httpEnabled" property */
+  public static final String HTTP_ENABLED_NAME = "http-enabled";
+
+  /** The default value of the "httpEnabled" property  */
+  public static final boolean DEFAULT_HTTP_ENABLED = true;
+  
+  /** The name of the "httpBindAddress" property */
+  public static final String HTTP_BIND_ADDRESS_NAME = "http-bind-address";
+
+  /** The default value of the "httpBindAddress" property */
+  public static final String DEFAULT_HTTP_BIND_ADDRESS = "";
+  
+  /** The name of the "httpPort" property */
+  public static final String HTTP_PORT_NAME = "http-port";
+
+  /** The default value of the "httpPort" property (8080) */
+  public static final int DEFAULT_HTTP_PORT = 8080;
+
+  /** The minimum httpPort (0) */
+  public static final int MIN_HTTP_PORT = 0;
+
+  /** The maximum httpPort (65535) */
+  public static final int MAX_HTTP_PORT = 65535;
+
+  /** The name of the "state-save-file-name" property */
+  public static final String STATE_SAVE_FILE_NAME =
+    "state-save-file";
+
+  /** The name of the "http-authentication-enabled" property */
+  public static final String HTTP_AUTHENTICATION_ENABLED_NAME =
+    "http-authentication-enabled";
+
+  /** The default value of the "http-authentication-enabled" property
+   *  */ 
+  public static final boolean DEFAULT_HTTP_AUTHENTICATION_ENABLED = false;
+
+  /** The name of the "http-authentication-user" property */
+  public static final String HTTP_AUTHENTICATION_USER_NAME =
+    "http-authentication-user";
+
+  /** The default value of the "http-authentication-user" property  */
+  public static final String DEFAULT_HTTP_AUTHENTICATION_USER = "admin";
+
+  /** The name of the "http-authentication-password" property */
+  public static final String HTTP_AUTHENTICATION_PASSWORD_NAME =
+    "http-authentication-password";
+
+  /** The default value of the "http-authentication-password" property
+   *  */
+  public static final String DEFAULT_HTTP_AUTHENTICATION_PASSWORD =
+    "password";
+
+  /** The name of the "email-notification-enabled" property */
+  public static final String EMAIL_NOTIFICATIONS_ENABLED_NAME =
+    "email-notification-enabled";
+
+  /** The default value of the "email-notification-enabled" property
+   *  */ 
+  public static final boolean DEFAULT_EMAIL_NOTIFICATIONS_ENABLED = false;
+
+  /** The name of the "email-notification-from" property */
+  public static final String EMAIL_NOTIFICATIONS_FROM_NAME =
+    "email-notification-from";
+
+  /** The default value of the "email-notification-from" property
+   *  */ 
+  public static final String DEFAULT_EMAIL_FROM = "";
+
+  /** The name of the "email-notification-host" property */
+  public static final String EMAIL_NOTIFICATIONS_HOST_NAME =
+    "email-notification-host";
+
+  /** The default value of the "email-notification-host" property
+   *  */ 
+  public static final String DEFAULT_EMAIL_HOST = "";
+
+  /** The name of the "email-notification-to" property */
+  public static final String EMAIL_NOTIFICATIONS_TO_LIST_NAME =
+    "email-notification-to";
+
+  /** The default value of the "email-notification-to" property
+   *  */ 
+  public static final String DEFAULT_EMAIL_TO_LIST = "";
+
+  // -------------------------------------------------------------------------
+  //   RMIConnectorServer properties...
+  // -------------------------------------------------------------------------
+  
+  /** The name of the "rmiEnabled" property */
+  public static final String RMI_ENABLED_NAME = "rmi-enabled";
+
+  /** The default value of the {@linkplain #RMI_ENABLED_NAME rmi-enabled} property  */
+  public static final boolean DEFAULT_RMI_ENABLED = true;
+  
+  /** The name of the "rmi-registry-enabled" property */
+  public static final String RMI_REGISTRY_ENABLED_NAME =
+    "rmi-registry-enabled"; 
+
+  /** The default value of the {@linkplain #RMI_REGISTRY_ENABLED_NAME rmi-registry-enabled} property*/
+  public static final boolean DEFAULT_RMI_REGISTRY_ENABLED = true;
+  
+  /** The name of the "rmiBindAddress" property */
+  public static final String RMI_BIND_ADDRESS_NAME = "rmi-bind-address";
+
+  /** The default value of the {@linkplain #RMI_BIND_ADDRESS_NAME rmi-bind-address} property  */
+  public static final String DEFAULT_RMI_BIND_ADDRESS = "";
+
+  /** The name of the "rmiPort" property */
+  public static final String RMI_PORT_NAME = "rmi-port";
+
+  /** The default value of the {@linkplain #RMI_PORT_NAME rmi-port} property (1099) */
+  public static final int DEFAULT_RMI_PORT = 1099;
+  
+  /** 
+   * The name of the "rmi-server-port" property
+   * 
+   * @since 6.5
+   */
+  public static final String RMI_SERVER_PORT_NAME = "rmi-server-port";
+
+  /** 
+   * The default value of the {@linkplain #RMI_SERVER_PORT_NAME rmi-server-port} 
+   * property (0)
+   * 
+   * @since 6.5
+   */
+  public static final int DEFAULT_RMI_SERVER_PORT = 0;
+
+  /**
+   * The minimum value for {@linkplain #RMI_PORT_NAME rmi-port} or
+   * {@linkplain #RMI_SERVER_PORT_NAME rmi-server-port} (0)
+   */
+  public static final int MIN_RMI_PORT = 0;
+
+  /**
+   * The maximum value for {@linkplain #RMI_PORT_NAME rmi-port} or
+   * {@linkplain #RMI_SERVER_PORT_NAME rmi-server-port} (65535)
+   */
+  public static final int MAX_RMI_PORT = 65535;
+  
+  // -------------------------------------------------------------------------
+  //   AdventNetSNMPAdaptor properties...
+  // -------------------------------------------------------------------------
+  
+  /** The name of the "snmpEnabled" property */
+  public static final String SNMP_ENABLED_NAME = "snmp-enabled";
+
+  /** The default value of the "snmpEnabled" property  */
+  public static final boolean DEFAULT_SNMP_ENABLED = false;
+  
+  /** The name of the "snmpBindAddress" property */
+  public static final String SNMP_BIND_ADDRESS_NAME = "snmp-bind-address";
+
+  /** The default value of the "snmpBindAddress" property */
+  public static final String DEFAULT_SNMP_BIND_ADDRESS = "";
+
+  /** The name of the "snmpDirectory" property */
+  public static final String SNMP_DIRECTORY_NAME = "snmp-directory";
+
+  /** The default value of the "snmpDirectory" property  */
+  public static final String DEFAULT_SNMP_DIRECTORY = "";
+
+  // -------------------------------------------------------------------------
+  //   JMX SSL properties...
+  // -------------------------------------------------------------------------
+
+  /** The name of the "agent-ssl-enabled" property */
+  public static final String AGENT_SSL_ENABLED_NAME = "agent-ssl-enabled";
+
+  /** The default value of the "agent-ssl-enabled" property  */
+  public static final boolean DEFAULT_AGENT_SSL_ENABLED = false;
+
+  /** The name of the "agent-ssl-protocols" property */
+  public static final String AGENT_SSL_PROTOCOLS_NAME = "agent-ssl-protocols";
+
+   /** The default value of the "agent-ssl-protocols" property  */
+  public static final String DEFAULT_AGENT_SSL_PROTOCOLS = "any";
+
+  /** The name of the "agent-ssl-ciphers" property */
+  public static final String AGENT_SSL_CIPHERS_NAME = "agent-ssl-ciphers";
+
+   /** The default value of the "agent-ssl-ciphers" property  */
+  public static final String DEFAULT_AGENT_SSL_CIPHERS = "any";
+
+  /** The name of the "agent-ssl-require-authentication" property */
+  public static final String AGENT_SSL_REQUIRE_AUTHENTICATION_NAME =
+    "agent-ssl-require-authentication";
+
+   /** The default value of the "agent-ssl-require-authentication"
+    * property  */
+  public static final boolean DEFAULT_AGENT_SSL_REQUIRE_AUTHENTICATION = true;
+    
+  /** The name of the "http-ssl-require-authentication" property */
+  public static final String HTTP_SSL_REQUIRE_AUTHENTICATION_NAME =
+    "http-ssl-require-authentication";
+
+   /** The default value of the "http-ssl-require-authentication"
+    * property  */
+  public static final boolean DEFAULT_HTTP_SSL_REQUIRE_AUTHENTICATION = false;
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  /**
+   * Returns whether or not the JMX agent will automatically connect
+   * to the distributed system it administers.
+   *
+   * See <a href="#auto-connect">description</a> above.
+   */
+  public boolean getAutoConnect();
+
+  /**
+   * Sets whether or not the JMX agent will automatically connect
+   * to the distributed system it administers.
+   *
+   * See <a href="#auto-connect">description</a> above.
+   */
+  public void setAutoConnect(boolean autoConnect);
+
+  /**
+   * Returns whether or not the HTTP adapter is enabled.
+   *
+   * See <a href="#http-enabled">description</a> above.
+   */
+  public boolean isHttpEnabled();
+
+  /**
+   * Sets whether or not the HTTP adapter is enabled.
+   *
+   * See <a href="#http-enabled">description</a> above.
+   */
+  public void setHttpEnabled(boolean httpEnabled);
+
+  /**
+   * Returns the port of the HTTP adapter.
+   *
+   * See <a href="#http-port">description</a> above.
+   */
+  public int getHttpPort();
+
+  /**
+   * Sets the port of the HTTP adapter.
+   *
+   * See <a href="#http-port">description</a> above.
+   */
+  public void setHttpPort(int port);
+
+  /**
+   * Returns the bind address to which the HTTP adapter's listening
+   * socket is bound.
+   *
+   * See <a href="#http-bind-address">description</a> above.
+   */
+  public String getHttpBindAddress();
+
+  /**
+   * Sets the bind address to which the HTTP adapter's listening
+   * socket is bound.
+   *
+   * See <a href="#http-bind-address">description</a> above.
+   */
+  public void setHttpBindAddress(String address);
+
+  /**
+   * Returns whether or not the HTTP adapter authenticates
+   * connections.
+   *
+   * See <a href="#http-authentication-enabled">description</a>
+   * above.
+   */ 
+  public boolean isHttpAuthEnabled();
+
+  /**
+   * Sets whether or not the HTTP adapter authenticates connections.
+   *
+   * See <a href="#http-authentication-enabled">description</a>
+   * above.
+   */
+  public void setHttpAuthEnabled(boolean enabled);
+
+  /**
+   * Returns the user name for HTTP adapter authentication.
+   *
+   * See <a href="#http-authentication-user">description</a>
+   * above.
+   */
+  public String getHttpAuthUser();
+  
+  /**
+   * Sets the user name for HTTP adapter authentication.
+   *
+   * See <a href="#http-authentication-user">description</a>
+   * above.
+   */
+  public void setHttpAuthUser(String user);
+
+  /**
+   * Returns the password for HTTP adapter authentication.
+   *
+   * See <a href="#http-authentication-password">description</a>
+   * above.
+   */
+  public String getHttpAuthPassword();
+  
+  /**
+   * Sets the password for HTTP adapter authentication.
+   *
+   * See <a href="#http-authentication-password">description</a>
+   * above.
+   */
+  public void setHttpAuthPassword(String password);
+
+  /**
+   * Returns whether or not the RMI adapter is enabled.
+   *
+   * See <a href="#rmi-enabled">description</a> above.
+   */
+  public boolean isRmiEnabled();
+
+  /**
+   * Sets whether or not the RMI adapter is enabled.
+   *
+   * See <a href="#rmi-enabled">description</a> above.
+   */
+  public void setRmiEnabled(boolean rmiEnabled);
+
+  /**
+   * Returns whether or not the agent hosts an RMI registry.
+   *
+   * See <a href="#rmi-registry-enabled">description</a> above.
+   */
+  public boolean isRmiRegistryEnabled();
+
+  /**
+   * Sets whether or not the agent hosts an RMI registry.
+   *
+   * See <a href="#rmi-registry-enabled">description</a> above.
+   */
+  public void setRmiRegistryEnabled(boolean enabled);
+
+  /**
+   * Returns the port of the RMI adapter.
+   *
+   * See <a href="#rmi-port">description</a> above.
+   */
+  public int getRmiPort();
+
+  /**
+   * Sets the port of the RMI adapter.
+   *
+   * See <a href="#rmi-port">description</a> above.
+   */
+  public void setRmiPort(int port);
+  
+  /**
+   * Returns the port of the RMI Connector Server.
+   *
+   * See <a href="#rmi-server-port">description</a> above.
+   * 
+   * @return the value set for rmi-server-port
+   * @since 6.5
+   */
+  public int getRmiServerPort();
+
+  /**
+   * Sets the port of the RMI Connector Server.
+   *
+   * See <a href="#rmi-server-port">description</a> above.
+   * 
+   * @param port rmi-server-port to set. 
+   * @since 6.5
+   */
+  public void setRmiServerPort(int port);
+
+  /**
+   * Returns the bind address to which the RMI adapter's listening
+   * sockets are bound.
+   *
+   * See <a href="#rmi-bind-address">description</a> above.
+   */
+  public String getRmiBindAddress();
+
+  /**
+   * Sets the bind address to which the RMI adapter's listening
+   * sockets are bound.
+   *
+   * See <a href="#rmi-bind-address">description</a> above.
+   */
+  public void setRmiBindAddress(String address);
+
+  /**
+   * Returns whether or not the SNMP adapter is enabled.
+   *
+   * See <a href="#snmp-enabled">description</a> above.
+   */
+  public boolean isSnmpEnabled();
+
+  /**
+   * Sets whether or not the SNMP adapter is enabled.
+   *
+   * See <a href="#snmp-enabled">description</a> above.
+   */
+  public void setSnmpEnabled(boolean enabled);
+
+  /**
+   * Returns the bind address used with the SNMP adapter.
+   *
+   * See <a href="#snmp-bind-address">description</a> above.
+   */
+  public String getSnmpBindAddress();
+
+  /**
+   * Sets the bind address used with the SNMP adapter.
+   *
+   * See <a href="#snmp-bind-address">description</a> above.
+   */
+  public void setSnmpBindAddress(String address);
+
+  /**
+   * Returns the directory for the SNMP adapater.
+   *
+   * See <a href="#snmp-directory">description</a> above.
+   */
+  public String getSnmpDirectory();
+
+  /**
+   * Sets the directory for the SNMP adapater.
+   *
+   * See <a href="#snmp-directory">description</a> above.
+   */
+  public void setSnmpDirectory(String snmpDirectory);
+  
+  /**
+   * Returns whether or not SSL is required for the JMX agent.
+   *
+   * See <a href="#agent-ssl-enabled">description</a> above.
+   */
+  public boolean isAgentSSLEnabled();
+
+  /**
+   * Sets whether or not SSL is required for the JMX agent.
+   *
+   * See <a href="#agent-ssl-enabled">description</a> above.
+   */
+  public void setAgentSSLEnabled(boolean enabled);
+
+  /**
+   * Returns the SSL protocols used when connecting to the JMX agent.
+   *
+   * See <a href="#agent-ssl-protocols">description</a> above.
+   */
+  public String getAgentSSLProtocols();
+
+  /**
+   * Sets the SSL protocols used when connecting to the JMX agent.
+   *
+   * See <a href="#agent-ssl-protocols">description</a> above.
+   */
+  public void setAgentSSLProtocols(String protocols);
+
+  /**
+   * Returns the SSL ciphers used when connecting to the JMX agent.
+   *
+   * See <a href="#agent-ssl-ciphers">description</a> above.
+   */
+  public String getAgentSSLCiphers();
+
+  /**
+   * Sets the SSL ciphers used when connecting to the JMX agent.
+   *
+   * See <a href="#agent-ssl-ciphers">description</a> above.
+   */
+  public void setAgentSSLCiphers(String ciphers);
+
+  /**
+   * Returns whether SSL authentication is used when connecting to the
+   * RMI connector.
+   *
+   * See <a href="#agent-ssl-require-authentication">description</a> above.
+   */
+  public boolean isAgentSSLRequireAuth();
+  
+  /**
+   * Sets whether SSL authentication is used when connecting to the
+   * RMI connector.
+   *
+   * See <a href="#agent-ssl-require-authentication">description</a> above.
+   */
+  public void setAgentSSLRequireAuth(boolean require);
+
+  /**
+   * Returns whether SSL authentication is used when connecting to the
+   * HTTP connector.
+   *
+   * See <a href="#http-ssl-require-authentication">description</a> above.
+   */
+  public boolean isHttpSSLRequireAuth();
+  
+  /**
+   * Sets whether SSL authentication is used when connecting to the
+   * HTTP connector.
+   *
+   * See <a href="#http-ssl-require-authentication">description</a> above.
+   */
+  public void setHttpSSLRequireAuth(boolean require);
+
+  /**
+   * Returns whether Emails for Notifications is enabled
+   *
+   * See <a href="#email-notification-enabled">description</a> above.
+   */
+  public boolean isEmailNotificationEnabled();
+
+  /**
+   * Sets whether Emails for Notifications is enabled
+   *
+   * See <a href="#email-notification-enabled">description</a> above.
+   */
+  public void setEmailNotificationEnabled(boolean enabled);
+
+  /**
+   * Returns the EmailID from whom notification emails are sent.
+   *
+   * See <a href="#email-notification-from">description</a> above.
+   */
+  public String getEmailNotificationFrom();
+  
+  /**
+   * Sets the EmailID from whom notification emails are sent.
+   *
+   * See <a href="#email-notification-from">description</a> above.
+   */
+  public void setEmailNotificationFrom(String emailID);
+
+  /**
+   * Returns the Host Name using which notification emails are sent.
+   *
+   * See <a href="#email-notification-host">description</a> above.
+   */
+  public String getEmailNotificationHost();
+  
+  /**
+   * Sets the Host Name from whom notification emails are sent.
+   *
+   * See <a href="#email-notification-host">description</a> above.
+   */
+  public void setEmailNotificationHost(String hostName);
+
+  /**
+   * Returns the comma separated EmailID list to whom notification
+   * emails are sent.
+   *
+   * See <a href="#email-notification-to">description</a> above.
+   */
+  public String getEmailNotificationToList();
+  
+  /**
+   * Sets the EmailID from whom notification emails are sent as a
+   * comma separated list.
+   *
+   * See <a href="#email-notification-to">description</a> above.
+   */
+  public void setEmailNotificationToList(String emailIDs);
+  
+  /**
+   * Returns the name of the file to be used for saving agent state
+   *
+   * See <a href="#state-save-file">description</a> above.
+   */
+  public String getStateSaveFile();
+
+  /**
+   * Sets the name of the file to be used for saving agent state
+   *
+   * See <a href="#state-save-file">description</a> above.
+   */
+  public void setStateSaveFile(String file);
+
+  /**
+   * Returns an <code>AgentConfig</code> with the same configuration
+   * as this <code>AgentConfig</code>.
+   */
+  public Object clone() throws CloneNotSupportedException; 
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/AgentFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/AgentFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/AgentFactory.java
new file mode 100644
index 0000000..ad03a71
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/AgentFactory.java
@@ -0,0 +1,43 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx;
+
+//import com.gemstone.gemfire.admin.AdminDistributedSystem;
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.jmx.internal.AgentConfigImpl;
+import com.gemstone.gemfire.admin.jmx.internal.AgentImpl;
+
+/**
+ * A factory class that creates JMX administration entities.
+ *
+ * @author David Whitlock
+ * @since 4.0
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public class AgentFactory {
+
+  /**
+   * Defines a "default" GemFire JMX administration agent
+   * configuration.
+   */
+  public static AgentConfig defineAgent() {
+    return new AgentConfigImpl();
+  }
+
+  /**
+   * Creates an unstarted GemFire JMX administration agent with the
+   * given configuration.
+   *
+   * @see Agent#start
+   */
+  public static Agent getAgent(AgentConfig config) 
+    throws AdminException {
+    return new AgentImpl((AgentConfigImpl) config);
+  }
+
+}


[29/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/StatisticAttributeInfo.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/StatisticAttributeInfo.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/StatisticAttributeInfo.java
new file mode 100755
index 0000000..c0ed2cc
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/StatisticAttributeInfo.java
@@ -0,0 +1,71 @@
+/*
+ *  =========================================================================
+ *  Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *  ========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import com.gemstone.gemfire.admin.Statistic;
+import com.gemstone.gemfire.internal.Assert;
+
+import javax.management.Descriptor;
+import javax.management.modelmbean.DescriptorSupport;
+import javax.management.modelmbean.ModelMBeanAttributeInfo;
+
+/** 
+ * Subclass of AttributeInfo with {@link com.gemstone.gemfire.admin.Statistic} 
+ * added for use as the {@link 
+ * javax.management.modelmbean.ModelMBeanAttributeInfo} descriptor's 
+ * <i>targetObject</i> value.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ */
+class StatisticAttributeInfo extends org.apache.commons.modeler.AttributeInfo {
+  private static final long serialVersionUID = 28022387514935560L;
+    
+  private Statistic stat;
+  
+  public StatisticAttributeInfo() {
+    super();
+  }
+  
+  public Statistic getStat() {
+    return this.stat;
+  }
+  public void setStat(Statistic stat) {
+    //System.out.println(">> stat = " + stat);
+    Assert.assertTrue(stat != null, "Attempting to set stat to null");
+    this.stat = stat;
+  }
+  
+  @Override
+  public ModelMBeanAttributeInfo createAttributeInfo() {
+    Descriptor desc = new DescriptorSupport(
+        new String[] {
+        "name=" + this.displayName,
+        "descriptorType=attribute",
+        "currencyTimeLimit=-1", // always stale
+        "displayName=" + this.displayName,
+        "getMethod=getValue" });
+
+    Assert.assertTrue(this.stat != null, "Stat target object is null!");
+    desc.setField("targetObject", this.stat);
+
+    ModelMBeanAttributeInfo info = new ModelMBeanAttributeInfo(
+        this.displayName, // name
+        this.type,        // type
+        this.description, // description
+        this.readable,    // isReadable
+        this.writeable,   // isWritable
+        this.is,          // isIs
+        desc);
+        
+    return info;
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/StatisticResourceJmxImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/StatisticResourceJmxImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/StatisticResourceJmxImpl.java
new file mode 100755
index 0000000..1c51b1c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/StatisticResourceJmxImpl.java
@@ -0,0 +1,352 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import javax.management.Notification;
+import javax.management.ObjectName;
+import javax.management.modelmbean.ModelMBean;
+import javax.naming.OperationNotSupportedException;
+
+import org.apache.commons.modeler.ManagedBean;
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.LogWriter;
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.Statistic;
+import com.gemstone.gemfire.internal.admin.StatResource;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * Provides MBean support for the monitoring of a statistic resource.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ */
+public class StatisticResourceJmxImpl 
+extends com.gemstone.gemfire.admin.internal.StatisticResourceImpl
+implements javax.management.NotificationListener, 
+           com.gemstone.gemfire.admin.jmx.internal.ManagedResource {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  /** 
+   * Interval in seconds between refreshes. Values less than one results in no 
+   * refreshing .
+   */
+  private int refreshInterval = 0;
+  
+  /** The JMX object name of this managed resource */
+  private ObjectName objectName;
+
+  /** A flag to indicate if time is inited. MBeanUtil lookup is costly */
+  private boolean timerInited = false;
+
+  // -------------------------------------------------------------------------
+  //   Constructor(s)
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Constructor for the StatisticResource object
+   *
+   * @param statResource  the admin StatResource to manage/monitor
+   * @param member        the SystemMember owning this resource
+   * @exception com.gemstone.gemfire.admin.AdminException 
+   *            if unable to create this StatisticResource for administration
+   */
+  public StatisticResourceJmxImpl(StatResource statResource,
+                                  SystemMemberJmx member)
+                           throws com.gemstone.gemfire.admin.AdminException {
+    super(statResource, member);
+    initializeMBean();
+  }
+
+  /** Create and register the MBean to manage this resource */
+  private void initializeMBean() 
+  throws com.gemstone.gemfire.admin.AdminException {
+    this.mbeanName = new StringBuffer("GemFire.Statistic:")
+                      .append("source=").append(MBeanUtil.makeCompliantMBeanNameProperty(this.member.getId()))
+                      .append(",type=").append(MBeanUtil.makeCompliantMBeanNameProperty(getType()))
+                      .append(",name=").append(MBeanUtil.makeCompliantMBeanNameProperty(getName()))
+                      .append(",uid=").append(getUniqueId()).toString();
+      
+    this.objectName =
+      MBeanUtil.createMBean(this, 
+        addDynamicAttributes(MBeanUtil.lookupManagedBean(this)));
+
+    // Refresh Interval
+    AdminDistributedSystemJmxImpl sysJmx = (AdminDistributedSystemJmxImpl)this.member.getDistributedSystem();
+    if (sysJmx.getRefreshInterval()>0)
+      this.refreshInterval = sysJmx.getRefreshInterval();
+  }
+
+  // -------------------------------------------------------------------------
+  //   MBean attributes - accessors/mutators
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Gets the interval in seconds between statistics refreshes
+   *
+   * @return the current refresh interval in seconds
+   */
+  public int getRefreshInterval() {
+    return this.refreshInterval;
+  }
+
+  /**
+   * Sets interval in seconds between statistic refreshes; zero or less turns 
+   * off auto refreshing.  Manual refreshing has no effect on when the next
+   * scheduled refresh will occur.
+   *
+   * @param refreshInterval  the new refresh interval in seconds
+   */
+  private void _setRefreshInterval(int refreshInterval) {
+    boolean isRegistered = MBeanUtil.isRefreshNotificationRegistered(this,
+        RefreshNotificationType.STATISTIC_RESOURCE_STATISTICS);
+
+    if (isRegistered && (getRefreshInterval() == refreshInterval))
+      return;
+
+    try {
+      MBeanUtil.registerRefreshNotification(
+          this, // NotificationListener
+          getMBeanName(), // User Data as MBean Name
+          RefreshNotificationType.STATISTIC_RESOURCE_STATISTICS, 
+          refreshInterval); // int
+
+      this.refreshInterval = refreshInterval;
+      timerInited = true;
+    } catch (RuntimeException e) {
+      logger.warn(e.getMessage(), e); // dead in water, print, and then ignore
+      this.refreshInterval = 0; // zero out to avoid more exceptions
+    } 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 (Error 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();
+      logger.error(e.getMessage(), e); // dead in water, print, and then ignore
+      this.refreshInterval = 0; // zero out to avoid more exceptions
+    }
+  }
+  
+  /**
+   * RefreshInterval is now set only through the AdminDistributedSystem property
+   * refreshInterval. Attempt to set refreshInterval on StatisticResourceJmx
+   * MBean would result in an OperationNotSupportedException
+   * Auto-refresh is enabled on demand when a call to getStatistics is made
+   * 
+   * @param refreshInterval
+   *          the new refresh interval in seconds
+   * @deprecated since 6.0 use DistributedSystemConfig.refreshInterval instead
+   */
+  @Deprecated
+  public void setRefreshInterval(int refreshInterval)
+      throws OperationNotSupportedException {
+    throw new OperationNotSupportedException(
+        LocalizedStrings.MANAGED_RESOURCE_REFRESH_INTERVAL_CANT_BE_SET_DIRECTLY.toLocalizedString());
+  }
+  
+  // -------------------------------------------------------------------------
+  //   JMX Notification listener
+  // -------------------------------------------------------------------------
+
+  /**
+   * Handles notification to refresh. Reacts by refreshing the values of this
+   * SystemMember's ConfigurationParamaters. Any other notification is ignored.
+   * Given notification is handled only if there is any JMX client connected to 
+   * the system.
+   * <p>
+   * TODO: investigate use of NotificationFilter instead of explicit check...
+   * 
+   * @param notification
+   *          the JMX notification being received
+   * @param hb
+   *          handback object is unused
+   */
+  public void handleNotification(Notification notification, Object hb) {
+    AdminDistributedSystemJmxImpl adminDSJmx = 
+      (AdminDistributedSystemJmxImpl) this.member.getDistributedSystem();
+    
+    String typeStatResourceStats = 
+              RefreshNotificationType.STATISTIC_RESOURCE_STATISTICS.getType();
+    
+    if (typeStatResourceStats.equals(notification.getType()) && 
+        getMBeanName().equals(notification.getUserData()) &&
+        !adminDSJmx.isRmiClientCountZero()) {
+      try {
+        refresh();
+
+      } catch (com.gemstone.gemfire.admin.AdminException e) {
+        logger.warn(e.getMessage(), e);
+      } catch (com.gemstone.gemfire.admin.OperationCancelledException e) {
+        // underlying resource is no longer reachable by remote admin
+        logger.warn(e.getMessage(), e);
+        _setRefreshInterval(0);
+      } catch (CancelException e) {
+        // shutting down - okay to ignore
+      } catch (java.lang.RuntimeException e) {
+        logger.debug(e.getMessage(), e); // dead in water, print, and then ignore
+        _setRefreshInterval(0); // zero out to avoid more exceptions
+      } 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 (java.lang.Error 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();
+        logger.error(e.getMessage(), e); // dead in water, print, and then ignore
+        this.refreshInterval = 0; // zero out to avoid more exceptions
+      }
+    }
+  }
+  
+  // -------------------------------------------------------------------------
+  //   Create MBean attributes for each Statistic
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Add MBean attribute definitions for each Statistic.
+   *
+   * @param managed   the mbean definition to add attributes to
+   * @return a new instance of ManagedBean copied from <code>managed</code> but 
+   *         with the new attributes added
+   */
+  ManagedBean addDynamicAttributes(ManagedBean managed) 
+  throws com.gemstone.gemfire.admin.AdminException {
+    if (managed == null) {
+      throw new IllegalArgumentException(LocalizedStrings.StatisticResourceJmxImpl_MANAGEDBEAN_IS_NULL.toLocalizedString());
+    }
+    
+    refresh(); // to get the stats...
+    
+    // need to create a new instance of ManagedBean to clean the "slate"...
+    ManagedBean newManagedBean = new DynamicManagedBean(managed);
+    for (int i = 0; i < this.statistics.length; i++) {
+      StatisticAttributeInfo attrInfo = new StatisticAttributeInfo();
+
+      attrInfo.setName(this.statistics[i].getName());
+      attrInfo.setDisplayName(this.statistics[i].getName());
+      attrInfo.setDescription(this.statistics[i].getDescription());
+      attrInfo.setType("java.lang.Number");
+
+      attrInfo.setIs(false);
+      attrInfo.setReadable(true);
+      attrInfo.setWriteable(false);
+
+      attrInfo.setStat(this.statistics[i]);
+      
+      newManagedBean.addAttribute(attrInfo);
+    }
+    return newManagedBean;
+  }
+
+  public Statistic[] getStatistics() {
+    if (!timerInited) {
+      // 1st call to getStatistics would trigger
+      // the auto-refresh if an interval is set
+      if (this.refreshInterval>0) {
+        this._setRefreshInterval(this.refreshInterval);
+      }
+    }
+
+    if (this.statistics == null) {
+      try {
+        this.refresh();
+      }
+      catch (AdminException e) {
+        this.statistics = new Statistic[0];
+      }
+    }
+
+    return this.statistics;
+  }
+
+  // -------------------------------------------------------------------------
+  //   ManagedResource implementation
+  // -------------------------------------------------------------------------
+  
+  /** The name of the MBean that will manage this resource */
+  private String mbeanName;
+
+  /** The ModelMBean that is configured to manage this resource */
+  private ModelMBean modelMBean;
+  
+	public String getMBeanName() {
+		return this.mbeanName;
+	}
+  
+	public ModelMBean getModelMBean() {
+		return this.modelMBean;
+	}
+	public void setModelMBean(ModelMBean modelMBean) {
+		this.modelMBean = modelMBean;
+	}
+  
+  public ObjectName getObjectName() {
+    return this.objectName;
+  }
+
+  public ManagedResourceType getManagedResourceType() {
+    return ManagedResourceType.STATISTIC_RESOURCE;
+  }
+  
+  public void cleanupResource() {
+    this.modelMBean = null;
+    this.member = null;
+    this.statistics = null;
+    this.statResource = null;
+  }
+  
+  /**
+   * Checks equality of the given object with <code>this</code> based on the
+   * type (Class) and the MBean Name returned by <code>getMBeanName()</code>
+   * methods.
+   * 
+   * @param obj
+   *          object to check equality with
+   * @return true if the given object is if the same type and its MBean Name is
+   *         same as <code>this</code> object's MBean Name, false otherwise
+   */
+  @Override
+  public boolean equals(Object obj) {
+    if ( !(obj instanceof StatisticResourceJmxImpl) ) {
+      return false;
+    }
+    
+    StatisticResourceJmxImpl other = (StatisticResourceJmxImpl) obj;
+
+    return this.getMBeanName().equals(other.getMBeanName());
+  }
+
+  /**
+   * Returns hash code for <code>this</code> object which is based on the MBean 
+   * Name generated. 
+   * 
+   * @return hash code for <code>this</code> object
+   */
+  @Override
+  public int hashCode() {
+    return this.getMBeanName().hashCode();
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberBridgeServerJmxImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberBridgeServerJmxImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberBridgeServerJmxImpl.java
new file mode 100644
index 0000000..2e84e4e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberBridgeServerJmxImpl.java
@@ -0,0 +1,126 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.internal.SystemMemberBridgeServerImpl;
+import com.gemstone.gemfire.admin.internal.SystemMemberCacheImpl;
+import com.gemstone.gemfire.internal.admin.AdminBridgeServer;
+import com.gemstone.gemfire.internal.admin.GemFireVM;
+
+import javax.management.ObjectName;
+import javax.management.modelmbean.ModelMBean;
+
+/**
+ * MBean representation of a {@link
+ * com.gemstone.gemfire.admin.SystemMemberBridgeServer}. 
+ *
+ * @author David Whitlock
+ * @since 4.0
+ */
+public class SystemMemberBridgeServerJmxImpl
+  extends SystemMemberBridgeServerImpl implements ManagedResource {
+
+  /** The object name of this managed resource */
+  private ObjectName objectName;
+
+  /** The name of the MBean that will manage this resource */
+  private String mbeanName;
+
+  /** The ModelMBean that is configured to manage this resource */
+  private ModelMBean modelMBean;
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a new <code>SystemMemberBridgeServerJmxImpl</code> that
+   * serves the contents of the given cache.
+   */
+  SystemMemberBridgeServerJmxImpl(SystemMemberCacheImpl cache,
+                                  AdminBridgeServer bridgeInfo) 
+    throws AdminException {
+
+    super(cache, bridgeInfo);
+    initializeMBean(cache);
+  }
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  /** 
+   * Creates and registers the MBean to manage this resource
+   */
+  private void initializeMBean(SystemMemberCacheImpl cache)
+    throws AdminException {
+    
+    GemFireVM vm = cache.getVM();
+    this.mbeanName = new StringBuffer("GemFire.Cache:")
+        .append("name=")
+        .append(MBeanUtil.makeCompliantMBeanNameProperty(cache.getName()))
+        .append(",id=")
+        .append(this.getBridgeId())
+        .append(",owner=")
+        .append(MBeanUtil.makeCompliantMBeanNameProperty(vm.getId().toString()))
+        .append(",type=CacheServer").toString();
+      
+    this.objectName = MBeanUtil.createMBean(this);
+  }
+
+  public String getMBeanName() {
+    return this.mbeanName;
+  }
+  
+  public ModelMBean getModelMBean() {
+    return this.modelMBean;
+  }
+  public void setModelMBean(ModelMBean modelMBean) {
+    this.modelMBean = modelMBean;
+  }
+  
+  public ObjectName getObjectName() {
+    return this.objectName;
+  }
+
+  public ManagedResourceType getManagedResourceType() {
+    return ManagedResourceType.SYSTEM_MEMBER_CACHE_SERVER;
+  }
+  
+  public void cleanupResource() {}
+  
+  /**
+   * Checks equality of the given object with <code>this</code> based on the
+   * type (Class) and the MBean Name returned by <code>getMBeanName()</code>
+   * methods.
+   * 
+   * @param obj
+   *          object to check equality with
+   * @return true if the given object is if the same type and its MBean Name is
+   *         same as <code>this</code> object's MBean Name, false otherwise
+   */
+  @Override
+  public boolean equals(Object obj) {
+    if ( !(obj instanceof SystemMemberBridgeServerJmxImpl) ) {
+      return false;
+    }
+    
+    SystemMemberBridgeServerJmxImpl other = 
+                                (SystemMemberBridgeServerJmxImpl) obj; 
+    
+    return this.getMBeanName().equals(other.getMBeanName());
+  }
+
+  /**
+   * Returns hash code for <code>this</code> object which is based on the MBean 
+   * Name generated. 
+   * 
+   * @return hash code for <code>this</code> object
+   */
+  @Override
+  public int hashCode() {
+    return this.getMBeanName().hashCode();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberCacheJmxImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberCacheJmxImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberCacheJmxImpl.java
new file mode 100644
index 0000000..8a7c582
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberCacheJmxImpl.java
@@ -0,0 +1,479 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.modelmbean.ModelMBean;
+
+import org.apache.commons.modeler.ManagedBean;
+import org.apache.logging.log4j.Level;
+
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.SystemMemberCacheServer;
+import com.gemstone.gemfire.admin.SystemMemberRegion;
+import com.gemstone.gemfire.admin.internal.SystemMemberBridgeServerImpl;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.internal.admin.AdminBridgeServer;
+import com.gemstone.gemfire.internal.admin.GemFireVM;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.InternalLogWriter;
+
+/**
+ * MBean representation of {@link com.gemstone.gemfire.admin.SystemMemberCache}.
+ *
+ * @author    Darrel Schneider
+ * @author    Kirk Lund
+ * @since     3.5
+ */
+public class SystemMemberCacheJmxImpl 
+extends com.gemstone.gemfire.admin.internal.SystemMemberCacheImpl
+implements com.gemstone.gemfire.admin.jmx.internal.ManagedResource {
+
+  /** The object name of this managed resource */
+  private ObjectName objectName;
+  
+  /** collection to collect all the resources created for this member */
+  private Map<String, SystemMemberRegionJmxImpl> managedRegionResourcesMap = new HashMap<String, SystemMemberRegionJmxImpl>();
+  private Map<Number, SystemMemberBridgeServerJmxImpl> managedCacheServerResourcesMap = new HashMap<Number, SystemMemberBridgeServerJmxImpl>();
+
+  // -------------------------------------------------------------------------
+  //   Constructor(s)
+  // -------------------------------------------------------------------------
+  
+  /** 
+   * Constructs an instance of SystemMemberCacheJmxImpl.
+   *
+   * @param vm
+   *        The vm owning the cache this object will manage
+   */
+  public SystemMemberCacheJmxImpl(GemFireVM vm)
+  throws com.gemstone.gemfire.admin.AdminException { 
+    super(vm);
+    initializeMBean();
+  }
+
+  /** Create and register the MBean to manage this resource */
+  private void initializeMBean() 
+  throws com.gemstone.gemfire.admin.AdminException {
+    this.mbeanName = new StringBuffer("GemFire.Cache:")
+        .append("name=")
+        .append(MBeanUtil.makeCompliantMBeanNameProperty(getName()))
+        .append(",id=")
+        .append(getId())
+        .append(",owner=")
+        .append(MBeanUtil.makeCompliantMBeanNameProperty(vm.getId().toString()))
+        .append(",type=Cache").toString();
+      
+    this.objectName = 
+      MBeanUtil.createMBean(this, 
+                            addDynamicAttributes(MBeanUtil.lookupManagedBean(this)));
+  }
+  
+  // -------------------------------------------------------------------------
+  //   Template methods overriden from superclass...
+  // -------------------------------------------------------------------------
+
+  /**
+   * Override createSystemMemberRegion by instantiating
+   * SystemMemberRegionJmxImpl. This instance is also added to the
+   * managedResources collection.
+   * 
+   * @param r
+   *          reference to Region instance for which this JMX resource is to be
+   *          created
+   * @return SystemMemberRegionJmxImpl - JMX Implementation of
+   *         SystemMemberRegion
+   * @throws AdminException
+   *           if constructing SystemMemberRegionJmxImpl instance fails
+   */
+  @Override  
+  protected SystemMemberRegion createSystemMemberRegion(Region r)
+    throws com.gemstone.gemfire.admin.AdminException {
+    SystemMemberRegionJmxImpl managedSystemMemberRegion = null;
+    boolean needsRefresh = false;
+    synchronized (this.managedRegionResourcesMap) {
+      /* 
+       * Ensuring that a single instance of System Member Region is created 
+       * per Region.
+       */
+      SystemMemberRegionJmxImpl managedResource = managedRegionResourcesMap.get(r.getFullPath());
+      if (managedResource != null) {
+        managedSystemMemberRegion = managedResource;
+      } else {
+        managedSystemMemberRegion = new SystemMemberRegionJmxImpl(this, r);
+        managedRegionResourcesMap.put(r.getFullPath(), managedSystemMemberRegion);
+        needsRefresh = true;
+      }
+    }
+    if (needsRefresh) {
+      managedSystemMemberRegion.refresh();
+    }
+    return managedSystemMemberRegion;
+  }
+
+  /**
+   * Creates a SystemMemberBridgeServerJmxImpl instance. This instance is also
+   * added to the managedResources collection.
+   * 
+   * @param bridge
+   *          reference to AdminBridgeServer for which this JMX resource is to
+   *          be created
+   * @return SystemMemberBridgeServerJmxImpl - JMX Implementation of
+   *         SystemMemberBridgeServerImpl
+   * @throws AdminException
+   *           if constructing SystemMemberBridgeServerJmxImpl instance fails
+   */
+  @Override  
+  protected SystemMemberBridgeServerImpl
+    createSystemMemberBridgeServer(AdminBridgeServer bridge) 
+    throws AdminException {
+    SystemMemberBridgeServerJmxImpl managedSystemMemberBridgeServer = null;
+    synchronized (this.managedCacheServerResourcesMap) {
+      /* 
+       * Ensuring that a single instance of SystemMember BridgeServer is 
+       * created per AdminBridgeServer.
+       */
+      SystemMemberBridgeServerJmxImpl managedCacheServerResource = managedCacheServerResourcesMap.get(bridge.getId());
+      if (managedCacheServerResource != null) {
+        managedSystemMemberBridgeServer = managedCacheServerResource;
+      } else {
+        managedSystemMemberBridgeServer = new SystemMemberBridgeServerJmxImpl(this, bridge);
+        managedCacheServerResourcesMap.put(bridge.getId(), managedSystemMemberBridgeServer);
+      }
+    }
+    return managedSystemMemberBridgeServer;
+  }
+
+  // -------------------------------------------------------------------------
+  //   Create MBean attributes for each Statistic
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Add MBean attribute definitions for each Statistic.
+   *
+   * @param managed   the mbean definition to add attributes to
+   * @return a new instance of ManagedBean copied from <code>managed</code> but 
+   *         with the new attributes added
+   */
+  ManagedBean addDynamicAttributes(ManagedBean managed)
+  throws com.gemstone.gemfire.admin.AdminException {
+    if (managed == null) {
+      throw new IllegalArgumentException(LocalizedStrings.SystemMemberCacheJmxImpl_MANAGEDBEAN_IS_NULL.toLocalizedString());
+    }
+    
+    refresh(); // to get the stats...
+    
+    // need to create a new instance of ManagedBean to clean the "slate"...
+    ManagedBean newManagedBean = new DynamicManagedBean(managed);
+    for (int i = 0; i < this.statistics.length; i++) {
+      StatisticAttributeInfo attrInfo = new StatisticAttributeInfo();
+
+      attrInfo.setName(this.statistics[i].getName());
+      attrInfo.setDisplayName(this.statistics[i].getName());
+      attrInfo.setDescription(this.statistics[i].getDescription());
+      attrInfo.setType("java.lang.Number");
+
+      attrInfo.setIs(false);
+      attrInfo.setReadable(true);
+      attrInfo.setWriteable(false);
+
+      attrInfo.setStat(this.statistics[i]);
+      
+      newManagedBean.addAttribute(attrInfo);
+    }
+
+    return newManagedBean;
+  }
+
+  // -------------------------------------------------------------------------
+  //   MBean Operations
+  // -------------------------------------------------------------------------
+
+  /** 
+   * Returns the ObjectName of the Region for the specified path.
+   *
+   * @throws AdminException
+   *         If no region with path <code>path</code> exists
+   */
+  public ObjectName manageRegion(String path)
+  throws AdminException, MalformedObjectNameException {
+    try {
+      SystemMemberRegionJmxImpl region = null;
+
+      try {
+        region = (SystemMemberRegionJmxImpl) getRegion(path);
+
+      } catch (AdminException e) {
+        MBeanUtil.logStackTrace(Level.WARN, e);
+        throw e;
+      }
+
+      if (region == null) {
+        throw new AdminException(LocalizedStrings.SystemMemberCacheJmxImpl_THIS_CACHE_DOES_NOT_CONTAIN_REGION_0.toLocalizedString(path));
+          
+      } else {
+        return ObjectName.getInstance(region.getMBeanName());
+      }
+    } catch (RuntimeException e) { 
+      MBeanUtil.logStackTrace(Level.WARN, e);
+      throw 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 (Error 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();
+      MBeanUtil.logStackTrace(Level.ERROR, e);
+      throw e; 
+    }
+  }
+
+  /**
+   * Creates a new cache server MBean and returns its
+   * <code>ObjectName</code>.
+   *
+   * @since 5.7
+   */
+  public ObjectName manageCacheServer()
+    throws AdminException, MalformedObjectNameException {
+
+    try {
+      SystemMemberBridgeServerJmxImpl bridge =
+        (SystemMemberBridgeServerJmxImpl) addCacheServer();
+      return ObjectName.getInstance(bridge.getMBeanName());
+    } catch (AdminException e) { 
+ 	  MBeanUtil.logStackTrace(Level.WARN, e);
+ 	  throw e; 
+    } catch (RuntimeException e) { 
+	  MBeanUtil.logStackTrace(Level.WARN, e); 
+	  throw 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 (Error 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();
+      MBeanUtil.logStackTrace(Level.ERROR, e); 
+      throw e; 
+    }
+  }
+
+  /**
+   * Creates a new bridge server MBean and returns its
+   * <code>ObjectName</code>.
+   *
+   * @since 4.0
+   * @deprecated as of 5.7
+   */
+  @Deprecated
+  public ObjectName manageBridgeServer()
+    throws AdminException, MalformedObjectNameException {
+    return manageCacheServer();
+  }
+  
+  /**
+   * Returns the MBean <code>ObjectName</code>s for all cache servers
+   * that serve this cache to clients.
+   *
+   * @since 4.0
+   */
+  public ObjectName[] manageCacheServers()
+    throws AdminException, MalformedObjectNameException {
+
+    try {
+      SystemMemberCacheServer[] bridges = getCacheServers();
+      ObjectName[] names = new ObjectName[bridges.length];
+      for (int i = 0; i < bridges.length; i++) {
+        SystemMemberBridgeServerJmxImpl bridge =
+          (SystemMemberBridgeServerJmxImpl) bridges[i];
+        names[i] = ObjectName.getInstance(bridge.getMBeanName());
+      }
+
+      return names;
+    } catch (AdminException e) { 
+  	  MBeanUtil.logStackTrace(Level.WARN, e); 
+  	  throw e;
+    } catch (RuntimeException e) { 
+      MBeanUtil.logStackTrace(Level.WARN, e); 
+      throw 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 (Error 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();
+      MBeanUtil.logStackTrace(Level.ERROR, e); 
+      throw e;
+    }
+  }
+
+  /**
+   * Returns the MBean <code>ObjectName</code>s for all bridge servers
+   * that serve this cache.
+   *
+   * @since 4.0
+   * @deprecated as of 5.7
+   */
+  @Deprecated
+  public ObjectName[] manageBridgeServers()
+    throws AdminException, MalformedObjectNameException {
+    return manageCacheServers();
+  }
+
+  // -------------------------------------------------------------------------
+  //   ManagedResource implementation
+  // -------------------------------------------------------------------------
+  
+  /** The name of the MBean that will manage this resource */
+  private String mbeanName;
+
+  /** The ModelMBean that is configured to manage this resource */
+  private ModelMBean modelMBean;
+  
+	public String getMBeanName() {
+		return this.mbeanName;
+	}
+  
+	public ModelMBean getModelMBean() {
+		return this.modelMBean;
+	}
+	public void setModelMBean(ModelMBean modelMBean) {
+		this.modelMBean = modelMBean;
+	}
+  
+  public ObjectName getObjectName() {
+    return this.objectName;
+  }
+
+  public ManagedResourceType getManagedResourceType() {
+    return ManagedResourceType.SYSTEM_MEMBER_CACHE;
+  }
+
+  
+  /**
+   * Un-registers all the statistics & cache managed resource created for this 
+   * member. After un-registering the resource MBean instances, clears 
+   * this.memberResources collection.
+   * 
+   * Creates ConfigurationParameterJmxImpl, StatisticResourceJmxImpl and 
+   * SystemMemberCacheJmxImpl. But cleans up only StatisticResourceJmxImpl and 
+   * SystemMemberCacheJmxImpl which are of type ManagedResource.  
+   */
+  public void cleanupResource() {
+    synchronized (this.managedRegionResourcesMap) {
+      Collection<SystemMemberRegionJmxImpl> values = managedRegionResourcesMap.values();
+      
+      for (SystemMemberRegionJmxImpl systemMemberRegionJmxImpl : values) {
+        MBeanUtil.unregisterMBean(systemMemberRegionJmxImpl);
+      }
+      
+      this.managedRegionResourcesMap.clear();
+    }
+    
+    synchronized (this.managedCacheServerResourcesMap) {
+      Collection<SystemMemberBridgeServerJmxImpl> values = managedCacheServerResourcesMap.values();
+      
+      for (SystemMemberBridgeServerJmxImpl SystemMemberBridgeServerJmxImpl : values) {
+        MBeanUtil.unregisterMBean(SystemMemberBridgeServerJmxImpl);
+      }
+      
+      this.managedCacheServerResourcesMap.clear();
+    }
+  }
+
+  /**
+   * Cleans up managed resources created for the region that was (created and)
+   * destroyed in a cache represented by this Managed Resource.
+   * 
+   * @param regionPath
+   *          path of the region that got destroyed
+   * @return a managed resource related to this region path
+   */
+  public ManagedResource cleanupRegionResources(String regionPath) {
+    ManagedResource cleaned = null;
+    
+    synchronized (this.managedRegionResourcesMap) {
+      Set<Entry<String, SystemMemberRegionJmxImpl>> entries = managedRegionResourcesMap.entrySet();
+      for (Iterator<Entry<String, SystemMemberRegionJmxImpl>> it = entries.iterator(); it.hasNext();) {
+        Entry<String, SystemMemberRegionJmxImpl> entry = it.next();
+        SystemMemberRegionJmxImpl managedResource = entry.getValue();
+        ObjectName                objName         = managedResource.getObjectName();
+        
+        String pathProp = objName.getKeyProperty("path");
+        if (pathProp != null && pathProp.equals(regionPath)) {
+          cleaned = managedResource;
+          it.remove();
+          
+          break;
+        }
+      }
+    }
+
+    return cleaned;
+  }
+  
+  /**
+   * Checks equality of the given object with <code>this</code> based on the
+   * type (Class) and the MBean Name returned by <code>getMBeanName()</code>
+   * methods.
+   * 
+   * @param obj
+   *          object to check equality with
+   * @return true if the given object is if the same type and its MBean Name is
+   *         same as <code>this</code> object's MBean Name, false otherwise
+   */
+  @Override
+  public boolean equals(Object obj) {
+    if ( !(obj instanceof SystemMemberCacheJmxImpl) ) {
+      return false;
+    }
+    
+    SystemMemberCacheJmxImpl other = (SystemMemberCacheJmxImpl) obj;
+
+    return this.getMBeanName().equals(other.getMBeanName());
+  }
+  
+  /**
+   * Returns hash code for <code>this</code> object which is based on the MBean 
+   * Name generated. 
+   * 
+   * @return hash code for <code>this</code> object
+   */
+  @Override
+  public int hashCode() {
+    return this.getMBeanName().hashCode();
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberJmx.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberJmx.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberJmx.java
new file mode 100644
index 0000000..04ba087
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberJmx.java
@@ -0,0 +1,499 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.management.MBeanException;
+import javax.management.MalformedObjectNameException;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.RuntimeOperationsException;
+import javax.naming.OperationNotSupportedException;
+
+import org.apache.commons.modeler.ManagedBean;
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.ConfigurationParameter;
+import com.gemstone.gemfire.admin.OperationCancelledException;
+import com.gemstone.gemfire.admin.StatisticResource;
+import com.gemstone.gemfire.admin.SystemMember;
+import com.gemstone.gemfire.admin.SystemMemberCache;
+import com.gemstone.gemfire.admin.SystemMemberCacheEvent;
+import com.gemstone.gemfire.admin.SystemMemberRegionEvent;
+import com.gemstone.gemfire.cache.Operation;
+import com.gemstone.gemfire.internal.admin.ClientMembershipMessage;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+
+/**
+ * Defines methods that all <code>SystemMember</code> MBeans should
+ * implement.
+ *
+ * @author David Whitlock
+ * @since 4.0
+ */
+public interface SystemMemberJmx
+  extends SystemMember, NotificationListener {
+  /** 
+   * Notification type for indicating a cache got created on a member of this 
+   * distributed system.
+   */
+  public static final String NOTIF_CACHE_CREATED = 
+    "gemfire.distributedsystem.cache.created";
+  /** 
+   * Notification type for indicating a cache is closed on a member of this 
+   * distributed system.
+   */
+  public static final String NOTIF_CACHE_CLOSED = 
+    "gemfire.distributedsystem.cache.closed";
+  /** 
+   * Notification type for indicating a region is created in a cache on a member 
+   * of this distributed system.
+   */
+  public static final String NOTIF_REGION_CREATED = 
+    "gemfire.distributedsystem.cache.region.created";
+  /** 
+   * Notification type for indicating a region was removed from a cache on a 
+   * member of this distributed system.
+   */
+  public static final String NOTIF_REGION_LOST = 
+    "gemfire.distributedsystem.cache.region.lost";
+  
+  /** Notification type for indicating client joined */
+  public static final String NOTIF_CLIENT_JOINED = 
+    "gemfire.distributedsystem.cache.client.joined";
+  
+  /** Notification type for indicating client left */
+  public static final String NOTIF_CLIENT_LEFT =
+    "gemfire.distributedsystem.cache.client.left";
+  
+  /** Notification type for indicating client crashed */
+  public static final String NOTIF_CLIENT_CRASHED =
+    "gemfire.distributedsystem.cache.client.crashed";
+
+  /**
+   * Gets the interval in seconds between config refreshes
+   *
+   * @return the current refresh interval in seconds
+   */
+  public int getRefreshInterval();
+
+  /**
+   * RefreshInterval is now set only through the AdminDistributedSystem property
+   * refreshInterval. Attempt to set refreshInterval on SystemMemberJmx MBean
+   * would result in an OperationNotSupportedException Auto-refresh is enabled
+   * on demand when a call to refreshConfig is made
+   *
+   * @param refreshInterval
+   *          the new refresh interval in seconds
+   * @deprecated since 6.0 use DistributedSystemConfig.refreshInterval instead
+   */
+  @Deprecated
+  public void setRefreshInterval(int refreshInterval) throws OperationNotSupportedException;
+
+  /**
+   * Sets the refresh interval field.
+   * Sets interval in seconds between config refreshes; zero or less turns 
+   * off auto refreshing.  Manual refreshing has no effect on when the next
+   * scheduled refresh will occur.
+   */
+  public void _setRefreshInterval(int refreshInterval);
+
+  /** 
+   * Gets this member's cache.
+   *
+   * @return <code>ObjectName</code> for this member's cache
+   *
+   * @throws AdminException
+   *         If this system member does not host a cache
+   */
+  public ObjectName manageCache() 
+    throws AdminException, MalformedObjectNameException;
+
+  /** 
+   * Gets all active StatisticResources for this manager.
+   *
+   * @return array of ObjectName instances
+   */
+  public ObjectName[] manageStats() 
+    throws AdminException, MalformedObjectNameException;
+
+  /** 
+   * Gets the active StatisticResources for this manager, based on the
+   * typeName as the key
+   *
+   * @return ObjectName of StatisticResourceJMX instance
+   */
+  public ObjectName[] manageStat(String statisticsTypeName) 
+    throws AdminException, MalformedObjectNameException;
+
+  /**
+   * Handles notification to refresh. Reacts by refreshing the values of this
+   * GemFireManager's ConfigurationParamaters.  Any other notification is
+   * ignored.
+   *
+   * @param notification  the JMX notification being received
+   * @param hb            handback object is unused
+   */
+  public void handleNotification(Notification notification, Object hb);
+
+  /**
+   * Add MBean attribute definitions for each ConfigurationParameter.
+   *
+   * @param managed the mbean definition to add attributes to
+   * @return a new instance of ManagedBean copied from <code>managed</code> but 
+   *         with the new attributes added
+   */
+  public ManagedBean addDynamicAttributes(ManagedBean managed) 
+    throws AdminException;
+
+
+  /**
+   * Implementation should handle creation of cache by extracting the details
+   * from the given event object.
+   * 
+   * @param event
+   *          event object corresponding to the creation of the cache
+   */
+  public void handleCacheCreate(SystemMemberCacheEvent event);
+
+  /**
+   * Implementation should handle closure of cache by extracting the details
+   * from the given event object.
+   * 
+   * @param event
+   *          event object corresponding to the closure of the cache
+   */
+  public void handleCacheClose(SystemMemberCacheEvent event);
+
+  /**
+   * Implementation should handle creation of region by extracting the details
+   * from the given event object.
+   * 
+   * @param event
+   *          event object corresponding to the creation of a region
+   */
+  public void handleRegionCreate(SystemMemberRegionEvent event);
+
+  /**
+   * Implementation should handle loss of region by extracting the details
+   * from the given event object.
+   * 
+   * @param event
+   *          event object corresponding to the loss of a region
+   */
+  public void handleRegionLoss(SystemMemberRegionEvent event);
+
+  /**
+   * Implementation should handle client membership changes.
+   * 
+   * @param clientId
+   *          id of the client for whom membership change happened
+   * @param eventType
+   *          membership change type; one of
+   *          {@link ClientMembershipMessage#JOINED},
+   *          {@link ClientMembershipMessage#LEFT}, 
+   *          {@link ClientMembershipMessage#CRASHED}
+   */
+  public void handleClientMembership(String clientId, int eventType);
+
+  //////////////////////  Inner Classess  //////////////////////
+
+  /**
+   * A helper class that provides implementation of the
+   * <code>SystemMemberJmx</code> interface as static methods.
+   */
+  public static class Helper {
+    private static final Logger logger = LogService.getLogger();
+    
+    private static AtomicInteger notificationSequenceNumber = new AtomicInteger();
+
+    public static int setAndReturnRefreshInterval(SystemMemberJmx member,
+                                          int refreshInterval) {
+      int ret = refreshInterval;
+      
+      try {
+        MBeanUtil.registerRefreshNotification(
+          member, // NotificationListener
+          ((ManagedResource)member).getMBeanName(), // User Data
+          RefreshNotificationType.SYSTEM_MEMBER_CONFIG, 
+          refreshInterval); // int
+
+      } catch (RuntimeException e) {
+        logger.warn(e.getMessage(), e); // dead in water, print, and then ignore
+        ret = 0; // zero out to avoid more exceptions
+
+      } 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 (Error 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();
+        logger.error(e.getMessage(), e); // dead in water, print, and then ignore
+        ret = 0; // zero out to avoid more exceptions
+      }
+      
+      return ret;
+    }
+
+    public static ObjectName manageCache(SystemMemberJmx member) 
+      throws AdminException, MalformedObjectNameException {
+      boolean IthrewIt = false;
+      try {
+        SystemMemberCache cache = member.getCache();
+        if (cache == null) {
+          IthrewIt = true;
+          throw new AdminException(LocalizedStrings.SystemMemberJmx_THIS_SYSTEM_MEMBER_DOES_NOT_HAVE_A_CACHE.toLocalizedString());
+        }
+//        Assert.assertTrue(cache != null); (cannot be null)
+        SystemMemberCacheJmxImpl cacheJmx = (SystemMemberCacheJmxImpl) cache;
+        return ObjectName.getInstance(cacheJmx.getMBeanName());
+      } catch (AdminException e) { 
+        if (!IthrewIt) {
+          logger.warn(e.getMessage(), e); 
+        }
+        throw e; 
+      } catch (RuntimeException e) { 
+        logger.warn(e.getMessage(), e);
+        throw 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 (Error 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();
+        logger.error(e.getMessage(), e); 
+        throw e; 
+      }
+    }
+
+    public static ObjectName[] manageStats(SystemMemberJmx member) 
+      throws AdminException, MalformedObjectNameException {
+        try {
+          StatisticResource[] stats = member.getStats();
+          ObjectName[] onames = new ObjectName[stats.length];
+          for (int i = 0; i < stats.length; i++) {
+            StatisticResourceJmxImpl stat =
+              (StatisticResourceJmxImpl) stats[i];
+            onames[i] = ObjectName.getInstance(stat.getMBeanName());
+          }
+          return onames;
+        } catch (AdminException e) { 
+          logger.warn(e.getMessage(), e); 
+          throw e;
+        } catch (RuntimeException e) {
+          logger.warn(e.getMessage(), e); 
+          throw 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 (Error 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();
+          logger.error(e.getMessage(), e); 
+          throw e; 
+        }
+      }
+
+    public static ObjectName[] manageStat(SystemMemberJmx member, String statisticsTypeName) 
+    throws AdminException, MalformedObjectNameException {
+      try {
+        StatisticResource[] stats = member.getStat(statisticsTypeName);
+        if (stats==null)
+          return null;
+        else {
+          ObjectName[] statNames = new ObjectName[stats.length]; 
+          for (int i=0; i<stats.length; i++) {
+            StatisticResourceJmxImpl statJMX = (StatisticResourceJmxImpl) stats[i];
+            statNames[i] = ObjectName.getInstance(statJMX.getMBeanName()); 
+          }
+          return statNames;
+        }
+      } catch (AdminException e) { 
+        logger.warn(e.getMessage(), e); 
+        throw e; 
+      } catch (RuntimeException e) { 
+        logger.warn(e.getMessage(), e); 
+        throw e;
+      } catch (Error e) { 
+        logger.error(e.getMessage(), e); 
+        throw e;
+      }
+    }
+
+    public static void handleNotification(SystemMemberJmx member,
+                                          Notification notification,
+                                          Object hb) {
+      if (RefreshNotificationType.SYSTEM_MEMBER_CONFIG.
+                           getType().equals(notification.getType()) &&
+          ((ManagedResource)member).getMBeanName().
+                           equals(notification.getUserData())
+         ) {
+          
+        try {
+          member.refreshConfig();
+
+        } catch (com.gemstone.gemfire.admin.AdminException e) {
+          logger.warn(e.getMessage(), e);
+        } catch (OperationCancelledException e) {
+          // underlying resource is no longer reachable by remote admin
+          logger.warn(e.getMessage(), e);
+          member._setRefreshInterval(0);
+
+        } catch (java.lang.RuntimeException e) {
+          logger.warn(e.getMessage(), e); // dead in water, print, and then ignore
+          member._setRefreshInterval(0); // zero out to avoid more exceptions
+
+        } 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 (java.lang.Error 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();
+          logger.error(e.getMessage(), e); // dead in water, print, and then ignore
+          member._setRefreshInterval(0); // zero out to avoid more exceptions
+        }
+      }
+    }
+
+    public static ManagedBean
+      addDynamicAttributes(SystemMemberJmx member, ManagedBean managed)
+      throws AdminException {
+
+      if (managed == null) {
+        throw new IllegalArgumentException(LocalizedStrings.SystemMemberJmx_MANAGEDBEAN_IS_NULL.toLocalizedString());
+      }
+    
+      member.refreshConfig(); // to get the config parms...
+    
+      // need to create a new instance of ManagedBean to clean the "slate"...
+      ManagedBean newManagedBean = new DynamicManagedBean(managed);
+      ConfigurationParameter[] params = member.getConfiguration();
+      for (int i = 0; i < params.length; i++) {
+        ConfigurationParameterJmxImpl parm =
+          (ConfigurationParameterJmxImpl) params[i];
+        ConfigAttributeInfo attrInfo = new ConfigAttributeInfo(parm);
+
+        attrInfo.setName(parm.getName());
+        attrInfo.setDisplayName(parm.getName());
+        attrInfo.setDescription(parm.getDescription());
+        attrInfo.setType(parm.getJmxValueType().getName());
+        
+        attrInfo.setIs(false);
+        attrInfo.setReadable(true);
+        attrInfo.setWriteable(parm.isModifiable());
+        
+        newManagedBean.addAttribute(attrInfo);
+      }
+      return newManagedBean;
+    }
+
+    /**
+     * Returns the next notification sequence number.
+     * 
+     * @return the notificationSequenceNumber
+     */
+    /*default*/static int getNextNotificationSequenceNumber() {
+      return notificationSequenceNumber.incrementAndGet();
+    }
+    
+    /**
+     * Returns the cache event details extracted from the given
+     * SystemMemberCacheEvent
+     * 
+     * @param event
+     *          SystemMemberCacheEvent instance
+     * @return the cache event details extracted from the given
+     *         SystemMemberCacheEvent
+     */
+    /*default*/static String getCacheEventDetails(SystemMemberCacheEvent event) {
+      String    memberId  = event.getMemberId();
+      Operation operation = event.getOperation();
+      
+      return "CacheEvent[MemberId: "+memberId+", operation: "+operation+"]";
+    }
+    
+    /**
+     * Returns the region event details extracted from the given
+     * SystemMemberRegionEvent
+     * 
+     * @param event
+     *          SystemMemberRegionEvent instance
+     * @return the cache event details extracted from the given
+     *         SystemMemberRegionEvent
+     */  
+    /*default*/static String getRegionEventDetails(SystemMemberRegionEvent event) {
+      String    memberId  = event.getMemberId();
+      Operation operation = event.getOperation();
+      
+      return "RegionEvent[MemberId: " + memberId + ", operation: " + operation
+          + ", region:" + event.getRegionPath() + "]";
+    }
+
+    /**
+     * Sends the given notification.
+     * 
+     * @param notif
+     *          notification to send
+     * 
+     * @throws NullPointerException
+     *           if resource or ModelMBean for resource is null
+     */
+    /*default*/static void sendNotification(ManagedResource resource, Notification notif) {
+      try {
+        if (MBeanUtil.isRegistered(resource.getObjectName())) {
+          resource.getModelMBean().sendNotification(notif);
+          if (logger.isDebugEnabled()) {
+            logger.debug("Sent '{}' notification", notif.getType());
+          }
+        }
+      } catch (RuntimeOperationsException e) {
+        logger.info(LocalizedMessage.create(
+            LocalizedStrings.SystemMemberJmx_FAILED_TO_SEND_0_NOTIFICATION_FOR_1,
+            new Object[] { "'" + notif.getType() + "'", 
+                          "'" + notif.getMessage() + "'" }), 
+            e);
+      } catch (MBeanException e) {
+        logger.info(LocalizedMessage.create(
+            LocalizedStrings.SystemMemberJmx_FAILED_TO_SEND_0_NOTIFICATION_FOR_1,
+            new Object[] { "'" + notif.getType() + "'", 
+                           "'" + notif.getMessage() + "'" }), 
+            e);
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberJmxImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberJmxImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberJmxImpl.java
new file mode 100755
index 0000000..f0dea30
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberJmxImpl.java
@@ -0,0 +1,584 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+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 java.util.Map.Entry;
+import java.util.Set;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.Notification;
+import javax.management.ObjectName;
+import javax.management.modelmbean.ModelMBean;
+import javax.naming.OperationNotSupportedException;
+
+import org.apache.commons.modeler.ManagedBean;
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.ConfigurationParameter;
+import com.gemstone.gemfire.admin.StatisticResource;
+import com.gemstone.gemfire.admin.SystemMemberCache;
+import com.gemstone.gemfire.admin.SystemMemberCacheEvent;
+import com.gemstone.gemfire.admin.SystemMemberRegionEvent;
+import com.gemstone.gemfire.admin.internal.ConfigurationParameterImpl;
+import com.gemstone.gemfire.distributed.internal.membership.InternalDistributedMember;
+import com.gemstone.gemfire.i18n.LogWriterI18n;
+import com.gemstone.gemfire.internal.admin.ApplicationVM;
+import com.gemstone.gemfire.internal.admin.ClientMembershipMessage;
+import com.gemstone.gemfire.internal.admin.GemFireVM;
+import com.gemstone.gemfire.internal.admin.StatResource;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * Provides MBean support for managing a SystemMember application.
+ * <p>
+ * TODO: refactor to implement SystemMember and delegate to SystemMemberImpl. 
+ * Wrap all delegate calls w/ e.printStackTrace() since the HttpAdaptor devours 
+ * them
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ */
+public class SystemMemberJmxImpl 
+extends com.gemstone.gemfire.admin.internal.SystemMemberImpl
+implements SystemMemberJmx, javax.management.NotificationListener,
+           com.gemstone.gemfire.admin.jmx.internal.ManagedResource {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  /** 
+   * Interval in seconds between refreshes. Value less than one results in no 
+   * refreshing 
+   */
+  private int refreshInterval = 0;
+  
+  /** The JMX object name of this managed resource */
+  private ObjectName objectName;
+
+  /** Reference to the cache MBean representing a Cache in the Cache VM Member */
+  private SystemMemberCacheJmxImpl managedSystemMemberCache;
+  
+  /** collection to collect all the resources created for this member */
+  private Map<StatResource, StatisticResourceJmxImpl> managedStatisticsResourcesMap = new HashMap<StatResource, StatisticResourceJmxImpl>();
+
+
+  // -------------------------------------------------------------------------
+  //   Constructor(s)
+  // -------------------------------------------------------------------------
+  
+  /** 
+   * Constructs an instance of SystemMemberJmxImpl.
+   *
+   * @param system  the distributed system this SystemMember is a member of
+   * @param application the internal admin application to delegate actual work
+   */
+  public SystemMemberJmxImpl(AdminDistributedSystemJmxImpl system,
+                             ApplicationVM application)
+                      throws com.gemstone.gemfire.admin.AdminException { 
+    super(system, application);
+    initializeMBean();
+  }
+  
+  /**
+   * Constructs the instance of SystemMember using the corresponding
+   * InternalDistributedMember instance of a DS member for the given
+   * AdminDistributedSystem.
+   * 
+   * @param system
+   *          Current AdminDistributedSystem instance
+   * @param member
+   *          InternalDistributedMember instance for which a SystemMember
+   *          instance is to be constructed.
+   * @throws AdminException
+   *           if construction of SystemMember fails
+   *           
+   * @since 6.5
+   */
+  protected SystemMemberJmxImpl(AdminDistributedSystemJmxImpl system,
+      InternalDistributedMember member) throws AdminException {
+    super(system, member);
+    initializeMBean();
+  }
+
+  /** Create and register the MBean to manage this resource */
+  private void initializeMBean() 
+  throws com.gemstone.gemfire.admin.AdminException {
+    //initialize Managed Resources for stats & cache first.
+//    initializeManagedResources();
+
+    this.mbeanName = new StringBuffer("GemFire.Member:id=")
+      .append(MBeanUtil.makeCompliantMBeanNameProperty(getId()))
+      .append(",type=").append(MBeanUtil.makeCompliantMBeanNameProperty(getType().getName())).toString();
+      
+    this.objectName =
+      MBeanUtil.createMBean(this, 
+        addDynamicAttributes(MBeanUtil.lookupManagedBean(this)));
+
+    // Refresh Interval
+    AdminDistributedSystemJmxImpl sysJmx = (AdminDistributedSystemJmxImpl)system;
+    if (sysJmx.getRefreshInterval() > 0)
+      this.refreshInterval = sysJmx.getRefreshInterval();
+  }
+  
+  // -------------------------------------------------------------------------
+  //   MBean attributes - accessors/mutators
+  // -------------------------------------------------------------------------
+
+  /**
+   * Gets the interval in seconds between config refreshes
+   *
+   * @return the current refresh interval in seconds
+   */
+  public int getRefreshInterval() {
+    return this.refreshInterval;
+  }
+  
+  /**
+   * RefreshInterval is now set only through the AdminDistributedSystem property
+   * refreshInterval. Attempt to set refreshInterval on SystemMemberJmx MBean
+   * would result in an OperationNotSupportedException Auto-refresh is enabled
+   * on demand when a call to refreshConfig is made
+   * 
+   * @param refreshInterval
+   *          the new refresh interval in seconds
+   * @deprecated since 6.0 use DistributedSystemConfig.refreshInterval instead
+   */
+  @Deprecated
+  public void setRefreshInterval(int refreshInterval)
+      throws OperationNotSupportedException {
+    throw new OperationNotSupportedException(
+        LocalizedStrings.MANAGED_RESOURCE_REFRESH_INTERVAL_CANT_BE_SET_DIRECTLY.toLocalizedString());
+  }
+
+  /**
+   * Sets interval in seconds between member config refreshes; zero or less
+   * turns off auto refreshing. Manual refreshing has no effect on when the next
+   * scheduled refresh will occur.
+   * 
+   * @param refreshInterval
+   *          the new refresh interval in seconds
+   */
+  public void _setRefreshInterval(int refreshInterval) {
+    boolean isRegistered = MBeanUtil.isRefreshNotificationRegistered(this,
+        RefreshNotificationType.SYSTEM_MEMBER_CONFIG);
+
+    if (isRegistered && (getRefreshInterval() == refreshInterval))
+      return;
+
+    this.refreshInterval = Helper.setAndReturnRefreshInterval(this,
+        refreshInterval);
+  }
+  
+  // -------------------------------------------------------------------------
+  //   MBean Operations
+  // -------------------------------------------------------------------------
+
+  public void refreshConfig() throws com.gemstone.gemfire.admin.AdminException {
+    // 1st call to refreshConfig would trigger
+    // the auto-refresh if an interval is set
+    if (this.refreshInterval > 0) {
+      this._setRefreshInterval(this.refreshInterval);
+    }
+
+    super.refreshConfig();
+  }
+  
+  /**
+   * Initializes Cache & Statistics managed resources.
+   * 
+   * @throws AdminException
+   *           if initialization of managed resources fails
+   */
+//  private void initializeManagedResources() throws AdminException {
+//    try {
+//      manageCache();
+//    } catch (MalformedObjectNameException e) {
+//      throw new AdminException(LocalizedStrings.SystemMemberJmxImpl_EXCEPTION_OCCURRED_WHILE_INITIALIZING_0_MBEANS_FOR_1.toLocalizedString(
+//              new Object[] {"Cache", getId()}), 
+//              e);
+//    } catch (AdminException ae) {
+//      if (LocalizedStrings.SystemMemberJmx_THIS_SYSTEM_MEMBER_DOES_NOT_HAVE_A_CACHE.toLocalizedString().equals(ae.getMessage())) {
+//        //ignore this exception for a cache-less peer 
+//      } else {
+//        throw ae;
+//      }
+//    }
+//    try {
+//      manageStats();
+//    } catch (MalformedObjectNameException e) {
+//      throw new AdminException(LocalizedStrings.SystemMemberJmxImpl_EXCEPTION_OCCURRED_WHILE_INITIALIZING_0_MBEANS_FOR_1.toLocalizedString(
+//          new Object[] {"Statistics", getId()}), 
+//          e);
+//    }
+//  }
+
+  /** 
+   * Gets this member's cache.
+   *
+   * @return <code>ObjectName</code> for this member's cache
+   *
+   * @throws AdminException
+   *         If this system member does not host a cache
+   */
+  public ObjectName manageCache() 
+    throws AdminException, MalformedObjectNameException {
+
+    return Helper.manageCache(this);
+  }
+  
+  /** 
+   * Gets all active StatisticResources for this manager.
+   *
+   * @return array of ObjectName instances
+   */
+  public ObjectName[] manageStats() 
+    throws AdminException, MalformedObjectNameException {
+
+    return Helper.manageStats(this);
+  }
+  
+  /** 
+   * Gets the active StatisticResources for this manager, based on the
+   * typeName as the key
+   *
+   * @return ObjectName of StatisticResourceJMX instance
+   */
+  public ObjectName[] manageStat(String statisticsTypeName) 
+    throws AdminException, MalformedObjectNameException {
+    
+    return Helper.manageStat(this, statisticsTypeName);
+  }
+  
+  // -------------------------------------------------------------------------
+  //   JMX Notification listener
+  // -------------------------------------------------------------------------
+
+  /**
+   * Handles notification to refresh. Reacts by refreshing the values of this
+   * SystemMember's ConfigurationParamaters. Any other notification is ignored.
+   * Given notification is handled only if there is any JMX client connected to 
+   * the system. 
+   * 
+   * @param notification
+   *          the JMX notification being received
+   * @param hb
+   *          handback object is unused
+   */
+  public void handleNotification(Notification notification, Object hb) {
+    AdminDistributedSystemJmxImpl systemJmx = 
+                                  (AdminDistributedSystemJmxImpl) this.system;
+    
+    if (!systemJmx.isRmiClientCountZero()) {
+      Helper.handleNotification(this, notification, hb);
+    }
+  }
+
+  // -------------------------------------------------------------------------
+  //   Template methods overriden from superclass...
+  // -------------------------------------------------------------------------
+
+  /**
+   * Template method for creating instance of ConfigurationParameter.  
+   * Overridden to return ConfigurationParameterJmxImpl.
+   */
+  @Override
+  protected ConfigurationParameter createConfigurationParameter(String name,
+                                                                String description,
+                                                                Object value,
+                                                                Class type,
+                                                                boolean userModifiable) {
+    return new ConfigurationParameterJmxImpl(
+        name, description, value, type, userModifiable);
+  }
+
+  /**
+   * Override createStatisticResource by instantiating StatisticResourceJmxImpl 
+   * if it was not created earlier otherwise returns the same instance.
+   * 
+   * @param stat
+   *         StatResource reference for which this JMX resource is to be created
+   * @return StatisticResourceJmxImpl - JMX Implementation of StatisticResource
+   * @throws AdminException
+   *           if constructing StatisticResourceJmxImpl instance fails
+   */
+  @Override
+  protected StatisticResource createStatisticResource(StatResource stat)
+    throws com.gemstone.gemfire.admin.AdminException {
+    StatisticResourceJmxImpl managedStatisticResource = null;
+    
+    synchronized (this.managedStatisticsResourcesMap) {
+      /* 
+       * Ensuring that a single instance of Statistic Resource is created per 
+       * StatResource.
+       */
+      StatisticResourceJmxImpl statisticResourceJmxImpl = managedStatisticsResourcesMap.get(stat);
+      if (statisticResourceJmxImpl != null) {
+        managedStatisticResource = statisticResourceJmxImpl;
+      } else {
+        managedStatisticResource = new StatisticResourceJmxImpl(stat, this);
+        managedStatisticResource.getStatistics();//inits timer
+        managedStatisticsResourcesMap.put(stat, managedStatisticResource);
+      }
+    }
+    return managedStatisticResource;
+  }
+
+  /**
+   * Override createSystemMemberCache by instantiating SystemMemberCacheJmxImpl 
+   * if it was not created earlier.
+   * 
+   * @param vm
+   *          GemFireVM reference for which this JMX resource is to be created
+   * @return SystemMemberCacheJmxImpl - JMX Implementation of SystemMemberCache
+   * @throws AdminException
+   *           if constructing SystemMemberCacheJmxImpl instance fails
+   */
+  @Override
+  protected SystemMemberCache createSystemMemberCache(GemFireVM vm)
+    throws com.gemstone.gemfire.admin.AdminException {
+    if (managedSystemMemberCache == null) {
+      managedSystemMemberCache = new SystemMemberCacheJmxImpl(vm);
+    }
+    return managedSystemMemberCache;
+  }
+
+  // -------------------------------------------------------------------------
+  //   Create MBean attributes for each ConfigurationParameter
+  // -------------------------------------------------------------------------
+  
+  /**
+   * Add MBean attribute definitions for each ConfigurationParameter.
+   *
+   * @param managed the mbean definition to add attributes to
+   * @return a new instance of ManagedBean copied from <code>managed</code> but 
+   *         with the new attributes added
+   */
+  public ManagedBean addDynamicAttributes(ManagedBean managed) 
+    throws AdminException {
+
+    return Helper.addDynamicAttributes(this, managed);
+  }
+
+  // -------------------------------------------------------------------------
+  //   ManagedResource implementation
+  // -------------------------------------------------------------------------
+  
+  /** The name of the MBean that will manage this resource */
+  private String mbeanName;
+
+  /** The ModelMBean that is configured to manage this resource */
+  private ModelMBean modelMBean;
+  
+	public String getMBeanName() {
+		return this.mbeanName;
+	}
+  
+	public ModelMBean getModelMBean() {
+		return this.modelMBean;
+	}
+	public void setModelMBean(ModelMBean modelMBean) {
+		this.modelMBean = modelMBean;
+	}
+  
+  public ObjectName getObjectName() {
+    return this.objectName;
+  }
+
+  public ManagedResourceType getManagedResourceType() {
+    return ManagedResourceType.SYSTEM_MEMBER;
+  }
+  
+  /**
+   * Un-registers all the statistics & cache managed resource created for this 
+   * member. After un-registering the resource MBean instances, clears 
+   * managedStatisticsResourcesMap collection.
+   */
+  public void cleanupResource() {
+    synchronized (this.managedStatisticsResourcesMap) {
+      ConfigurationParameter[] names = getConfiguration();
+      if (names != null) {
+        for (int i = 0; i < names.length; i++) {
+          ConfigurationParameter parm = names[i];
+          ((ConfigurationParameterImpl) parm).removeConfigurationParameterListener(this);
+        }
+      }
+      this.parms.clear();
+
+      Collection<StatisticResourceJmxImpl> statisticResources = managedStatisticsResourcesMap.values();
+      
+      for (StatisticResourceJmxImpl statisticResource : statisticResources) {
+        MBeanUtil.unregisterMBean(statisticResource);
+      }
+        
+      this.managedStatisticsResourcesMap.clear();
+    }
+    MBeanUtil.unregisterMBean(managedSystemMemberCache);
+  }
+
+
+  /**
+   * Cleans up Managed Resources created for the client that was connected to
+   * the server represented by this class.
+   * 
+   * @param clientId
+   *          id of the client to be removed
+   * @return List of ManagedResources associated with the client of given client
+   *         id
+   */
+  /*
+   * This clean up is for the clients. The clients are started with a loner DM.
+   * Hence the clientId is not supposed to contain '/' as per 
+   * InternalDistributedMember.toString().  
+   */
+  public List<ManagedResource> cleanupBridgeClientResources(String clientId) {
+    List<ManagedResource> returnedResources = new ArrayList<ManagedResource>();
+
+    String compatibleId = "id_"+MBeanUtil.makeCompliantMBeanNameProperty(clientId);
+    synchronized (this.managedStatisticsResourcesMap) {
+      Set<Entry<StatResource, StatisticResourceJmxImpl>> entrySet = this.managedStatisticsResourcesMap.entrySet();
+      
+      for (Iterator<Entry<StatResource, StatisticResourceJmxImpl>> it = entrySet.iterator(); it.hasNext();) {
+        Entry<StatResource, StatisticResourceJmxImpl> entry = it.next();
+        StatisticResourceJmxImpl resource = entry.getValue();
+        if (resource.getMBeanName().contains(compatibleId)) {
+          it.remove(); //remove matching entry
+          returnedResources.add(resource);
+        }
+      }
+    }
+    return returnedResources;
+  }
+  
+  /**
+   * Implementation handles client membership changes.
+   * 
+   * @param clientId
+   *          id of the client for whom membership change happened
+   * @param eventType
+   *          membership change type; one of
+   *          {@link ClientMembershipMessage#JOINED},
+   *          {@link ClientMembershipMessage#LEFT}, 
+   *          {@link ClientMembershipMessage#CRASHED}
+   */
+  public void handleClientMembership(String clientId, int eventType) {
+    String notifType                = null;
+    List<ManagedResource> cleanedUp = null;
+    
+    if (eventType == ClientMembershipMessage.LEFT) {
+      notifType = NOTIF_CLIENT_LEFT;
+      cleanedUp = cleanupBridgeClientResources(clientId);
+    } else if (eventType == ClientMembershipMessage.CRASHED) {
+      notifType = NOTIF_CLIENT_CRASHED;
+      cleanedUp = cleanupBridgeClientResources(clientId);
+    } else if (eventType == ClientMembershipMessage.JOINED) {
+      notifType = NOTIF_CLIENT_JOINED;
+    }
+    
+    if (cleanedUp != null) {
+      for (ManagedResource resource : cleanedUp) {
+        MBeanUtil.unregisterMBean(resource);
+      }
+    }
+
+    Helper.sendNotification(this, 
+        new Notification(notifType, this.modelMBean, 
+        Helper.getNextNotificationSequenceNumber(),
+        clientId));
+  }
+  
+  /**
+   * Implementation handles creation of cache by extracting the details from the 
+   * given event object and sending the 
+   * {@link SystemMemberJmx#NOTIF_CACHE_CREATED} notification to the connected 
+   * JMX Clients.
+   * 
+   * @param event
+   *          event object corresponding to the creation of the cache
+   */
+  public void handleCacheCreate(SystemMemberCacheEvent event) {
+    Helper.sendNotification(this, 
+      new Notification(NOTIF_CACHE_CREATED, this.modelMBean, 
+      Helper.getNextNotificationSequenceNumber(),
+      Helper.getCacheEventDetails(event)));
+  }  
+
+  /**
+   * Implementation handles closure of cache by extracting the details from the 
+   * given event object and sending the
+   * {@link SystemMemberJmx#NOTIF_CACHE_CLOSED} notification to the connected 
+   * JMX Clients. 
+   * 
+   * @param event
+   *          event object corresponding to the closure of the cache
+   */
+  public void handleCacheClose(SystemMemberCacheEvent event) {
+    Helper.sendNotification(this, 
+        new Notification(NOTIF_CACHE_CLOSED, this.modelMBean, 
+        Helper.getNextNotificationSequenceNumber(),
+        Helper.getCacheEventDetails(event)));
+  }
+
+  /**
+   * Implementation handles creation of region by extracting the details from 
+   * the given event object and sending the
+   * {@link SystemMemberJmx#NOTIF_REGION_CREATED} notification to the connected 
+   * JMX Clients. Region Path is set as User Data in Notification. 
+   * 
+   * @param event
+   *          event object corresponding to the creation of a region
+   */
+  public void handleRegionCreate(SystemMemberRegionEvent event) {
+    Notification notification = new Notification(NOTIF_REGION_CREATED, this.modelMBean, 
+        Helper.getNextNotificationSequenceNumber(),
+        Helper.getRegionEventDetails(event));
+    
+    notification.setUserData(event.getRegionPath());
+
+    Helper.sendNotification(this, notification);
+  }
+
+  /**
+   * Implementation should handle loss of region by extracting the details from 
+   * the given event object and sending the
+   * {@link SystemMemberJmx#NOTIF_REGION_LOST} notification to the connected 
+   * JMX Clients. Region Path is set as User Data in Notification. Additionally, 
+   * it also clears the ManagedResources created for the region that is lost. 
+   * 
+   * @param event
+   *          event object corresponding to the loss of a region
+   */
+  public void handleRegionLoss(SystemMemberRegionEvent event) {
+    SystemMemberCacheJmxImpl cacheResource = this.managedSystemMemberCache;
+    
+    if (cacheResource != null) {
+      ManagedResource cleanedUp = 
+                cacheResource.cleanupRegionResources(event.getRegionPath());
+      
+      if (cleanedUp != null) {
+        MBeanUtil.unregisterMBean(cleanedUp);
+      }
+    }
+    
+    Notification notification = new Notification(NOTIF_REGION_LOST, this.modelMBean, 
+        Helper.getNextNotificationSequenceNumber(),
+        Helper.getRegionEventDetails(event));
+    
+    notification.setUserData(event.getRegionPath());
+
+    Helper.sendNotification(this, notification);
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberRegionJmxImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberRegionJmxImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberRegionJmxImpl.java
new file mode 100644
index 0000000..480423d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/SystemMemberRegionJmxImpl.java
@@ -0,0 +1,131 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import com.gemstone.gemfire.admin.internal.SystemMemberCacheImpl;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.internal.admin.GemFireVM;
+
+import javax.management.ObjectName;
+import javax.management.modelmbean.ModelMBean;
+
+/**
+ * MBean representation of {@link 
+ * com.gemstone.gemfire.admin.SystemMemberRegion}.
+ *
+ * @author    Darrel Schneider
+ * @author    Kirk Lund
+ * @since     3.5
+ */
+public class SystemMemberRegionJmxImpl 
+extends com.gemstone.gemfire.admin.internal.SystemMemberRegionImpl
+implements com.gemstone.gemfire.admin.jmx.internal.ManagedResource {
+
+  /** The object name of this managed resource */
+  private ObjectName objectName;
+
+  // -------------------------------------------------------------------------
+  //   Constructor(s)
+  // -------------------------------------------------------------------------
+
+  /** 
+   * Constructs an instance of SystemMemberRegionJmxImpl.
+   *
+   * @param cache   the cache this region belongs to
+   * @param region  internal region to delegate real work to
+   */
+  public SystemMemberRegionJmxImpl(SystemMemberCacheImpl cache, 
+                                   Region region)
+                            throws com.gemstone.gemfire.admin.AdminException {
+    super(cache, region);
+    initializeMBean(cache);
+  }
+
+  /** Create and register the MBean to manage this resource */
+  private void initializeMBean(SystemMemberCacheImpl cache)
+  throws com.gemstone.gemfire.admin.AdminException {
+    
+    GemFireVM vm = cache.getVM();
+    this.mbeanName = new StringBuffer("GemFire.Cache:")
+        .append("path=")
+        .append(MBeanUtil.makeCompliantMBeanNameProperty(getFullPath()))
+        .append(",name=")
+        .append(MBeanUtil.makeCompliantMBeanNameProperty(cache.getName()))
+        .append(",id=")
+        .append(cache.getId())
+        .append(",owner=")
+        .append(MBeanUtil.makeCompliantMBeanNameProperty(vm.getId().toString()))
+        .append(",type=Region").toString();
+      
+    this.objectName = MBeanUtil.createMBean(this);
+  }
+  
+  // -------------------------------------------------------------------------
+  //   ManagedResource implementation
+  // -------------------------------------------------------------------------
+  
+  /** The name of the MBean that will manage this resource */
+  private String mbeanName;
+
+  /** The ModelMBean that is configured to manage this resource */
+  private ModelMBean modelMBean;
+  
+	public String getMBeanName() {
+		return this.mbeanName;
+	}
+  
+	public ModelMBean getModelMBean() {
+		return this.modelMBean;
+	}
+	public void setModelMBean(ModelMBean modelMBean) {
+		this.modelMBean = modelMBean;
+	}
+  
+  public ObjectName getObjectName() {
+    return this.objectName;
+  }
+
+  public ManagedResourceType getManagedResourceType() {
+    return ManagedResourceType.SYSTEM_MEMBER_REGION;
+  }
+  
+  public void cleanupResource() {}
+
+  /**
+   * Checks equality of the given object with <code>this</code> based on the
+   * type (Class) and the MBean Name returned by <code>getMBeanName()</code>
+   * methods.
+   * 
+   * @param obj
+   *          object to check equality with
+   * @return true if the given object is if the same type and its MBean Name is
+   *         same as <code>this</code> object's MBean Name, false otherwise
+   */
+  @Override
+  public boolean equals(Object obj) {
+    if ( !(obj instanceof SystemMemberRegionJmxImpl) ) {
+      return false;
+    }
+    
+    SystemMemberRegionJmxImpl other = (SystemMemberRegionJmxImpl) obj; 
+    
+    return this.getMBeanName().equals(other.getMBeanName());
+  }
+
+  /**
+   * Returns hash code for <code>this</code> object which is based on the MBean 
+   * Name generated. 
+   * 
+   * @return hash code for <code>this</code> object
+   */
+  @Override
+  public int hashCode() {
+    return this.getMBeanName().hashCode();
+  }
+}
+


[16/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/PoolManager.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/PoolManager.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/PoolManager.java
new file mode 100644
index 0000000..1651a2a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/PoolManager.java
@@ -0,0 +1,89 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache.client;
+import java.util.Map;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.internal.cache.PoolManagerImpl;
+import com.gemstone.gemfire.distributed.DistributedSystem; // for javadocs
+
+/**
+ * Manages creation and access to {@link Pool connection pools} for clients.
+ * <p>
+ * To create a pool get a factory by calling {@link #createFactory}.
+ * <p>
+ * To find an existing pool by name call {@link #find(String)}.
+ * <p>
+ * To get rid of all created pool call {@link #close()}.
+ *
+ * @author darrel
+ * @since 5.7
+ *
+ */
+public final class PoolManager {
+  
+  private PoolManager() {
+    // no instances allowed!
+  }
+  
+  /**
+   * Creates a new {@link PoolFactory pool factory},
+   * which is used to configure and create new {@link Pool}s.
+   * @return the new pool factory
+   */
+  public static PoolFactory createFactory() {
+    return PoolManagerImpl.getPMI().createFactory();
+  }
+
+  /**
+   * Find by name an existing connection pool returning
+   * the existing pool or <code>null</code> if it does not exist.
+   * @param name the name of the connection pool
+   * @return the existing connection pool or <code>null</code> if it does not exist.
+   */
+  public static Pool find(String name) {
+    return PoolManagerImpl.getPMI().find(name);
+  }
+  /**
+   * Returns a map containing all the pools in this manager.
+   * The keys are pool names
+   * and the values are {@link Pool} instances.
+   * <p> The map contains the pools that this manager knows of at the time of this call.
+   * The map is free to be changed without affecting this manager.
+   * @return a Map that is a snapshot of all the pools currently known to this manager.
+   */
+  public static Map<String,Pool> getAll() { 
+    return PoolManagerImpl.getPMI().getMap();
+  }
+  /**
+   * Unconditionally destroys all created pools that are in this manager.
+   * @param keepAlive whether the server should keep the durable client's subscriptions alive for the <code>durable-client-timeout</code>.
+   * @see DistributedSystem#connect for a description of <code>durable-client-timeout</code>.
+   */
+  public static void close(boolean keepAlive) {
+    PoolManagerImpl.getPMI().close(keepAlive);
+  }
+  
+  /**
+   * Find the pool used by the given region.
+   * @param region The region that is using the pool.
+   * @return the pool used by that region or <code>null</code> if the region does
+   * not have a pool. 
+   */
+  public static Pool find(Region<?,?> region) {
+    return PoolManagerImpl.getPMI().find(region);
+  }
+  
+  /**
+   * Unconditionally destroys all created pools that are in this manager.
+   */
+  public static void close() {
+    close(false);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ServerConnectivityException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ServerConnectivityException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ServerConnectivityException.java
new file mode 100644
index 0000000..9b0f284
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ServerConnectivityException.java
@@ -0,0 +1,54 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client;
+
+import com.gemstone.gemfire.GemFireException;
+
+/**
+ * A generic exception indicating that a failure has happened while communicating
+ * with a gemfire server. Subclasses of this exception provide more detail
+ * on specific failures.
+ * @author dsmith
+ * @since 5.7
+ */
+public class ServerConnectivityException extends GemFireException {
+private static final long serialVersionUID = -5205644901262051330L;
+
+  /**
+   * Create a new instance of ServerConnectivityException without a detail message or cause.
+   */
+  public ServerConnectivityException() {
+  }
+
+  /**
+   * 
+   * Create a new instance of ServerConnectivityException with a detail message
+   * @param message the detail message
+   */
+  public ServerConnectivityException(String message) {
+    super(message);
+  }
+
+  /**
+   * Create a new instance of ServerConnectivityException with a detail message and cause
+   * @param message the detail message
+   * @param cause the cause
+   */
+  public ServerConnectivityException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Create a new instance of ServerConnectivityException with a cause
+   * @param cause the cause
+   */
+  public ServerConnectivityException(Throwable cause) {
+    super(cause);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ServerOperationException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ServerOperationException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ServerOperationException.java
new file mode 100644
index 0000000..4e5150e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ServerOperationException.java
@@ -0,0 +1,77 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client;
+
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+
+/**
+ * An exception indicating that a failure has happened on the server
+ * while processing an operation that was sent to it by a client.
+ * @author darrel
+ * @since 5.7
+ */
+public class ServerOperationException extends ServerConnectivityException {
+private static final long serialVersionUID = -3106323103325266219L;
+
+  /**
+   * Create a new instance of ServerOperationException without a detail message or cause.
+   */
+  public ServerOperationException() {
+  }
+
+  /**
+   * 
+   * Create a new instance of ServerOperationException with a detail message
+   * @param message the detail message
+   */
+  public ServerOperationException(String message) {
+    super(getServerMessage(message));
+  }
+
+  /**
+   * Create a new instance of ServerOperationException with a detail message and cause
+   * @param message the detail message
+   * @param cause the cause
+   */
+  public ServerOperationException(String message, Throwable cause) {
+    super(getServerMessage(message), cause);
+  }
+
+  /**
+   * Create a new instance of ServerOperationException with a cause
+   * @param cause the cause
+   */
+  public ServerOperationException(Throwable cause) {
+    super(getServerMessage(cause), cause);
+  }
+
+  private static String getServerMessage(Throwable cause) {
+    return getServerMessage(cause != null ? cause.toString() : null);
+  }
+
+  private static String getServerMessage(String msg) {
+    // To fix bug 44679 add a description of the member the server is on.
+    // Do this without changing how this class gets serialized so that old
+    // clients will still work.
+    InternalDistributedSystem ids = InternalDistributedSystem.getAnyInstance();
+    if (ids != null) {
+      if (msg != null) {
+        return "remote server on " + ids.getMemberId() + ": " + msg;
+      } else {
+        return "remote server on " + ids.getMemberId();
+      }
+    } else {
+      if (msg != null) {
+        return "remote server on unknown location: " + msg;
+      } else {
+        return "remote server on unknown location";
+      }
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ServerRefusedConnectionException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ServerRefusedConnectionException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ServerRefusedConnectionException.java
new file mode 100755
index 0000000..dd079c1
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ServerRefusedConnectionException.java
@@ -0,0 +1,32 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache.client;
+
+import com.gemstone.gemfire.cache.OperationAbortedException;
+import com.gemstone.gemfire.distributed.DistributedMember;
+
+/**
+ * A <code>ServerRefusedConnectionException</code> indicates a client attempted
+ * to connect to a server, but the handshake was rejected.
+ *
+ * @author darrel
+ *
+ * @since 5.7
+ */
+public class ServerRefusedConnectionException extends OperationAbortedException {
+private static final long serialVersionUID = 1794959225832197946L;
+  /**
+   * Constructs an instance of <code>ServerRefusedConnectionException</code> with the
+   * specified detail message.
+   * @param server the server that rejected the connection
+   * @param msg the detail message
+   */
+  public ServerRefusedConnectionException(DistributedMember server, String msg) {
+    super(server + " refused connection: " + msg);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/SubscriptionNotEnabledException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/SubscriptionNotEnabledException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/SubscriptionNotEnabledException.java
new file mode 100644
index 0000000..7839930
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/SubscriptionNotEnabledException.java
@@ -0,0 +1,54 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client;
+
+import com.gemstone.gemfire.cache.Region;
+
+
+/**
+ * An exception indicating that client subscriptions are not enabled on this client, but
+ * the client is trying to perform an operation that requires a client subscription,
+ *  such as {@link Region#registerInterest(Object)}.
+ * @author dsmith
+ * @since 5.7
+ */
+public class SubscriptionNotEnabledException extends ServerConnectivityException {
+  private static final long serialVersionUID = -8212446737778234890L;
+
+  /**
+   * Create a new instance of SubscriptionNotEnabledException without a detail message or cause.
+   */
+  public SubscriptionNotEnabledException() {
+  }
+
+  /**
+   * Create a new instance of SubscriptionNotEnabledException with a detail message
+   * @param message the detail message
+   */
+  public SubscriptionNotEnabledException(String message) {
+    super(message);
+  }
+
+  /**
+   * Create a new instance of SubscriptionNotEnabledException with a detail message and cause
+   * @param message the detail message
+   * @param cause the cause
+   */
+  public SubscriptionNotEnabledException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Create a new instance of SubscriptionNotEnabledException with a and cause
+   * @param cause the cause
+   */
+  public SubscriptionNotEnabledException(Throwable cause) {
+    super(cause);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/doc-files/example-client-cache.xml
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/doc-files/example-client-cache.xml b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/doc-files/example-client-cache.xml
new file mode 100644
index 0000000..edff479
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/doc-files/example-client-cache.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- A sample client GemFire declarative caching XML File -->
+
+<!DOCTYPE client-cache PUBLIC
+  "-//GemStone Systems, Inc.//GemFire Declarative Cache 6.5//EN"
+  "http://www.gemstone.com/dtd/cache6_5.dtd">
+<client-cache copy-on-read="false">
+
+  <pool name="myPool">
+    <locator host="myHostName" port="41111"/>
+  </pool>
+
+  <!-- Create a proxy region -->
+  <region name="region1" refid="PROXY"/>
+
+  <!-- Create a caching proxy region -->
+  <region name="region2" refid="CACHING_PROXY">
+    <region-attributes>
+
+      <entry-time-to-live>
+        <expiration-attributes action="destroy" timeout="3000"/>
+      </entry-time-to-live>
+
+      <entry-idle-time>
+        <expiration-attributes timeout="600"/>
+      </entry-idle-time>
+    </region-attributes>
+  </region>
+</client-cache>

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AbstractOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AbstractOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AbstractOp.java
new file mode 100644
index 0000000..ab11517
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AbstractOp.java
@@ -0,0 +1,427 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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.BridgeServerImpl;
+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);
+      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/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AddPDXEnumOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AddPDXEnumOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AddPDXEnumOp.java
new file mode 100644
index 0000000..2965843
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AddPDXEnumOp.java
@@ -0,0 +1,89 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014, Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().send(false);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AddPDXTypeOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AddPDXTypeOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AddPDXTypeOp.java
new file mode 100644
index 0000000..ca080ee
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AddPDXTypeOp.java
@@ -0,0 +1,89 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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().send(false);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AuthenticateUserOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AuthenticateUserOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AuthenticateUserOp.java
new file mode 100644
index 0000000..e3c7fa3
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AuthenticateUserOp.java
@@ -0,0 +1,301 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+/**
+ * 
+ */
+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;
+      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);
+      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);
+    }
+
+    @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;
+        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/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AutoConnectionSourceImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AutoConnectionSourceImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AutoConnectionSourceImpl.java
new file mode 100644
index 0000000..fa45199
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/AutoConnectionSourceImpl.java
@@ -0,0 +1,378 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+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.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.cache.client.NoAvailableLocatorsException;
+import com.gemstone.gemfire.cache.client.internal.PoolImpl.PoolTask;
+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.ClientReplacementRequest;
+import com.gemstone.gemfire.cache.client.internal.locator.GetAllServersRequest;
+import com.gemstone.gemfire.cache.client.internal.locator.GetAllServersResponse;
+import com.gemstone.gemfire.cache.client.internal.locator.LocatorListRequest;
+import com.gemstone.gemfire.cache.client.internal.locator.LocatorListResponse;
+import com.gemstone.gemfire.cache.client.internal.locator.QueueConnectionRequest;
+import com.gemstone.gemfire.cache.client.internal.locator.QueueConnectionResponse;
+import com.gemstone.gemfire.cache.client.internal.locator.ServerLocationRequest;
+import com.gemstone.gemfire.cache.client.internal.locator.ServerLocationResponse;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.distributed.internal.tcpserver.TcpClient;
+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;
+
+/**
+ * A connection source which uses locators to find
+ * the least loaded server.
+ * @author dsmith
+ * @since 5.7
+ *
+ */
+public class AutoConnectionSourceImpl implements ConnectionSource {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  protected static final LocatorListRequest LOCATOR_LIST_REQUEST = new LocatorListRequest();
+  private static final Comparator<InetSocketAddress> SOCKET_ADDRESS_COMPARATOR = new Comparator<InetSocketAddress>() {
+    public int compare(InetSocketAddress o1,InetSocketAddress o2){
+      //shouldn't happen, but if it does we'll say they're the same.
+      if(o1.getAddress() == null || o2.getAddress() == null) {
+        return 0;
+      }
+      
+      int result = o1.getAddress().getCanonicalHostName().compareTo(o1.getAddress().getCanonicalHostName());
+      if(result != 0) {
+        return result;
+      }
+      
+      else return o1.getPort() - o2.getPort();
+    }
+  };
+  protected final List<InetSocketAddress> initialLocators;
+  private final String serverGroup;
+  private AtomicReference<LocatorList> locators = new AtomicReference<LocatorList>();
+  protected InternalPool pool;
+  private final int connectionTimeout;  
+  private long pingInterval;
+  private volatile LocatorDiscoveryCallback locatorCallback = new LocatorDiscoveryCallbackAdapter();
+  private volatile boolean isBalanced = true;
+  /**
+   * key is the InetSocketAddress of the locator.
+   * value will be an exception if we have already found the locator to be dead.
+   * value will be null if we last saw him alive.
+   */
+  private final Map<InetSocketAddress,Exception> locatorState = new HashMap<InetSocketAddress,Exception>();
+  
+  /**
+   * @param contacts
+   * @param serverGroup
+   * @param handshakeTimeout
+   */
+  public AutoConnectionSourceImpl(List<InetSocketAddress>contacts, String serverGroup, int handshakeTimeout) {
+    ArrayList<InetSocketAddress> tmpContacts = new ArrayList<InetSocketAddress>(contacts);
+    this.locators.set(new LocatorList(tmpContacts));
+    this.initialLocators = Collections.unmodifiableList(tmpContacts);
+    this.connectionTimeout = handshakeTimeout;
+    this.serverGroup = serverGroup;
+  }
+  
+  public boolean isBalanced() {
+    return isBalanced;
+  }
+
+  public ServerLocation findReplacementServer(ServerLocation currentServer, Set/*<ServerLocation>*/ excludedServers) {
+    if(PoolImpl.TEST_DURABLE_IS_NET_DOWN) {
+      return null;
+    }
+    ClientReplacementRequest request  = new ClientReplacementRequest(currentServer, excludedServers, serverGroup);
+    ClientConnectionResponse response = (ClientConnectionResponse) queryLocators(request);
+    if (response==null) {
+      // why log a warning if we are going to throw the caller and exception?
+      //getLogger().warning("Unable to connect to any locators in the list " + locators);
+      throw new NoAvailableLocatorsException("Unable to connect to any locators in the list " + locators);
+    }
+//    if(getLogger().fineEnabled()) {
+//      getLogger().fine("Received client connection response with server " + response.getServer());
+//    }
+    
+    return response.getServer();
+  }
+
+  public ServerLocation findServer(Set excludedServers) {
+    if(PoolImpl.TEST_DURABLE_IS_NET_DOWN) {
+      return null;
+    }
+    ClientConnectionRequest request  = new ClientConnectionRequest(excludedServers, serverGroup);
+    ClientConnectionResponse response = (ClientConnectionResponse) queryLocators(request);
+    if (response==null) {
+      // why log a warning if we are going to throw the caller and exception?
+      //getLogger().warning("Unable to connect to any locators in the list " + locators);
+      throw new NoAvailableLocatorsException("Unable to connect to any locators in the list " + locators);
+    }
+//    if(getLogger().fineEnabled()) {
+//      getLogger().fine("Received client connection response with server " + response.getServer());
+//    }
+    
+    return response.getServer();
+  }
+  
+  
+  public ArrayList<ServerLocation> findAllServers() {
+    if (PoolImpl.TEST_DURABLE_IS_NET_DOWN) {
+      return null;
+    }
+    GetAllServersRequest request = new GetAllServersRequest(serverGroup);
+    GetAllServersResponse response = (GetAllServersResponse)queryLocators(request);
+    if(response != null){
+      return response.getServers();
+    }else {
+      return null ;
+    }
+  }
+  
+  public List/* ServerLocation */findServersForQueue(      
+      Set/* <ServerLocation> */excludedServers, int numServers,
+      ClientProxyMembershipID proxyId, boolean findDurableQueue) {
+    if(PoolImpl.TEST_DURABLE_IS_NET_DOWN) {
+      return new ArrayList();
+    }
+    QueueConnectionRequest request  = new QueueConnectionRequest(proxyId,numServers,excludedServers, serverGroup,findDurableQueue);
+    QueueConnectionResponse response = (QueueConnectionResponse) queryLocators(request);
+    if (response==null) {
+      // why log a warning if we are going to throw the caller and exception?
+      //getLogger().warning("Unable to connect to any locators in the list " + locators);
+      throw new NoAvailableLocatorsException("Unable to connect to any locators in the list " + locators);
+    }
+    //TODO - do this logic on the server side, return one list in the message.
+    List result = response.getServers();
+//    if(getLogger().fineEnabled()) {
+//      getLogger().fine("Received queue connection response with server " + result+" excludeList:"+excludedServers);
+//    }
+    
+    return result;
+  }
+  
+  
+  private ServerLocationResponse queryOneLocator(InetSocketAddress locator, ServerLocationRequest request) {
+    InetAddress addr = locator.getAddress();
+    int port = locator.getPort();
+    Object returnObj = null;
+    try {
+      pool.getStats().incLocatorRequests();
+      returnObj = TcpClient.requestToServer(addr, port, request, connectionTimeout);
+      ServerLocationResponse response = (ServerLocationResponse)returnObj; 
+      pool.getStats().incLocatorResponses();
+      if(response != null) {
+        reportLiveLocator(locator);
+      }
+      return response;
+    } catch(IOException ioe) {
+      reportDeadLocator(locator, ioe);
+      return null;
+    } catch (ClassNotFoundException e) {
+      logger.warn(LocalizedMessage.create(LocalizedStrings.AutoConnectionSourceImpl_RECEIVED_EXCEPTION_FROM_LOCATOR_0, locator), e);
+      return null;    
+    } catch (ClassCastException e) {
+      if (logger.isDebugEnabled()) {
+        logger.debug("Received odd response object from the locator: {}", returnObj);
+      }
+      reportDeadLocator(locator, e);
+      return null;
+    }
+  }
+
+  protected ServerLocationResponse queryLocators(ServerLocationRequest request) {
+    Iterator controllerItr = locators.get().iterator();
+    ServerLocationResponse response = null;
+    
+    final boolean isDebugEnabled = logger.isDebugEnabled();
+    do {
+      InetSocketAddress locator = (InetSocketAddress) controllerItr.next();
+      if (isDebugEnabled) {
+        logger.debug("Sending query to locator {}: {}", locator, request);
+      }
+      response = queryOneLocator(locator, request);
+      if (isDebugEnabled) {
+        logger.debug("Received query response from locator {}: {}", locator, response);
+      }
+    } while(controllerItr.hasNext() && (response == null || !response.hasResult()));
+    
+    if(response == null) {
+      return null;
+    }
+    
+    return response;
+  }
+
+  protected void updateLocatorList(LocatorListResponse response) {
+    if (response == null) return;
+    isBalanced = response.isBalanced();
+    ArrayList<ServerLocation> locatorResponse = response.getLocators();
+
+    ArrayList<InetSocketAddress> newLocators  = new ArrayList<InetSocketAddress>(locatorResponse.size());
+
+    Set<InetSocketAddress> badLocators  = new HashSet<InetSocketAddress>(initialLocators);
+    for(Iterator<ServerLocation> itr = locatorResponse.iterator(); itr.hasNext(); ) {
+      ServerLocation locator =  itr.next();
+      InetSocketAddress address = new InetSocketAddress(locator.getHostName(), locator.getPort());
+      newLocators.add(address);
+      badLocators.remove(address);
+    }
+
+    newLocators.addAll(badLocators);
+
+    if(logger.isInfoEnabled()) {
+      LocatorList oldLocators = (LocatorList) locators.get();
+      ArrayList<InetSocketAddress> removedLocators  = new ArrayList<InetSocketAddress>(oldLocators.getLocators());
+      removedLocators.removeAll(newLocators);
+
+      ArrayList<InetSocketAddress> addedLocators  = new ArrayList<InetSocketAddress>(newLocators);
+      addedLocators.removeAll(oldLocators.getLocators());
+      if(!addedLocators.isEmpty()) {
+        locatorCallback.locatorsDiscovered(Collections.unmodifiableList(addedLocators));
+        logger.info(LocalizedMessage.create(LocalizedStrings.AutoConnectionSourceImpl_AUTOCONNECTIONSOURCE_DISCOVERED_NEW_LOCATORS_0, addedLocators));
+      }
+      if(!removedLocators.isEmpty()) {
+        locatorCallback.locatorsRemoved(Collections.unmodifiableList(removedLocators));
+        logger.info(LocalizedMessage.create(LocalizedStrings.AutoConnectionSourceImpl_AUTOCONNECTIONSOURCE_DROPPING_PREVIOUSLY_DISCOVERED_LOCATORS_0, removedLocators));
+      }
+    }
+    LocatorList newLocatorList = new LocatorList(newLocators);
+    locators.set(newLocatorList);
+    pool.getStats().setLocatorCount(newLocators.size());
+  }
+
+  public void start(InternalPool pool) {
+    this.pool = pool;
+    pool.getStats().setInitialContacts(((LocatorList)locators.get()).size());
+    this.pingInterval = pool.getPingInterval();
+    
+    pool.getBackgroundProcessor().scheduleWithFixedDelay(new UpdateLocatorListTask(), 0, pingInterval, TimeUnit.MILLISECONDS);
+  }
+
+  public void stop() {
+    
+  }
+  
+  public void setLocatorDiscoveryCallback(LocatorDiscoveryCallback callback) {
+    this.locatorCallback = callback;
+  }
+  
+  private synchronized void reportLiveLocator(InetSocketAddress l) {
+    Object prevState = this.locatorState.put(l, null);
+    if (prevState != null) {
+      logger.info(LocalizedMessage.create(LocalizedStrings.AutoConnectionSourceImpl_COMMUNICATION_HAS_BEEN_RESTORED_WITH_LOCATOR_0, l));
+    }
+  }
+  
+  private synchronized void reportDeadLocator(InetSocketAddress l, Exception ex) {
+    Object prevState = this.locatorState.put(l, ex);
+    if (prevState == null) {
+      if (ex instanceof ConnectException) {
+        logger.info(LocalizedMessage.create(LocalizedStrings.AutoConnectionSourceImpl_LOCATOR_0_IS_NOT_RUNNING, l),ex);
+      } else {
+        logger.info(LocalizedMessage.create(
+            LocalizedStrings.AutoConnectionSourceImpl_COMMUNICATION_WITH_LOCATOR_0_FAILED_WITH_1,
+            new Object[] {l, ex}),ex);
+      }
+    }
+  }
+  
+  /** A list of locators, which
+   * remembers the last known good locator.
+   */
+  private static class LocatorList {
+    protected final List<InetSocketAddress> locators;
+    protected AtomicInteger currentLocatorIndex = new AtomicInteger();
+    
+    public LocatorList(List<InetSocketAddress> locators) {
+      Collections.sort(locators, SOCKET_ADDRESS_COMPARATOR);
+      this.locators = Collections.unmodifiableList(locators);
+    }
+    
+    public Collection<InetSocketAddress> getLocators() {
+      return locators;
+    }
+
+    public int size() {
+      return locators.size();
+    }
+
+    public Iterator<InetSocketAddress> iterator() {
+      return new LocatorIterator();
+    }
+    
+    @Override
+    public String toString() {
+      return locators.toString();
+    }
+    
+    
+    /**
+     * An iterator which iterates all of the controllers,
+     * starting at the last known good controller.
+     * 
+     */
+    protected class LocatorIterator implements Iterator<InetSocketAddress> {
+      private int startLocator= currentLocatorIndex.get();
+      private int locatorNum = 0;
+      
+      public boolean hasNext() {
+        return locatorNum < locators.size();
+      }
+      
+      public InetSocketAddress next() {
+        if(!hasNext()) {
+          return null;
+        } else {
+          int index = (locatorNum + startLocator) % locators.size();
+          InetSocketAddress nextLocator = locators.get(index);
+          currentLocatorIndex.set(index);
+          locatorNum++;
+          return nextLocator;
+        }
+      }
+      
+      public void remove() {
+        throw new UnsupportedOperationException();
+      }
+    }
+  }
+  
+  protected class UpdateLocatorListTask extends PoolTask {
+    @Override
+    public void run2() {
+      if(pool.getCancelCriterion().cancelInProgress() != null) {
+        return;
+      }
+      LocatorListResponse response = (LocatorListResponse) queryLocators(LOCATOR_LIST_REQUEST);
+      updateLocatorList(response);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/BridgePoolImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/BridgePoolImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/BridgePoolImpl.java
new file mode 100644
index 0000000..25abf2d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/BridgePoolImpl.java
@@ -0,0 +1,479 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.cache.CacheLoaderException;
+import com.gemstone.gemfire.cache.CacheWriterException;
+import com.gemstone.gemfire.cache.NoSubscriptionServersAvailableException;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.client.Pool;
+import com.gemstone.gemfire.cache.client.PoolManager;
+import com.gemstone.gemfire.cache.client.ServerConnectivityException;
+import com.gemstone.gemfire.cache.client.SubscriptionNotEnabledException;
+import com.gemstone.gemfire.cache.client.internal.GetOp.GetOpImpl;
+import com.gemstone.gemfire.cache.util.BridgeWriterException;
+import com.gemstone.gemfire.cache.util.EndpointDoesNotExistException;
+import com.gemstone.gemfire.cache.util.EndpointExistsException;
+import com.gemstone.gemfire.cache.util.EndpointInUseException;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.cache.PoolFactoryImpl;
+import com.gemstone.gemfire.internal.cache.PoolManagerImpl;
+import com.gemstone.gemfire.internal.cache.tier.ConnectionProxy;
+import com.gemstone.gemfire.internal.cache.tier.sockets.AcceptorImpl;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * A pool for use by the old BridgeLoader/BridgeWriter.
+ * This class can go away once we drop these deprecated classes
+ * 
+ * @author darrel
+ * @since 5.7
+ */
+@SuppressWarnings("deprecation")
+public class BridgePoolImpl extends PoolImpl implements ConnectionProxy {
+  private static final Logger logger = LogService.getLogger();
+  
+  private static final AtomicInteger ID_COUNTER = new AtomicInteger();
+  public static final int DEFAULT_CONNECTIONSPERSERVER = 1;
+  public static final int DEFAULT_HANDSHAKE_TIMEOUT = AcceptorImpl.DEFAULT_HANDSHAKE_TIMEOUT_MS;
+  public static final String DEFAULT_LBPOLICY = LBPolicy.STICKY_PROPERTY_NAME;
+  
+  //this field is only set to true when the cache is closing with
+  //keep alive set to true.
+  private boolean keepAlive;
+
+  private static int getBridgePoolId() {
+    return ID_COUNTER.incrementAndGet();
+  }
+  
+  public static BridgePoolImpl create(Properties props, boolean usedByBridgeWriter) {
+    return create(props, usedByBridgeWriter, false/*usedByGateway*/);
+  }
+
+  public static BridgePoolImpl create(Properties props, boolean usedByBridgeWriter,
+                                      boolean usedByGateway) {
+    
+    String name = (usedByGateway ? "GatewayPool-" : "BridgePool-") + getBridgePoolId();
+    PoolFactoryImpl pf = (PoolFactoryImpl)PoolManager.createFactory();
+    pf.init(props, usedByBridgeWriter, usedByGateway);
+    BridgePoolImpl result = (BridgePoolImpl)pf.create(name);
+    if (!result.isDestroyed()) {
+      result.attach();
+    }
+    return result;
+  }
+  /**
+   * Should only be called by PoolFactoryImpl#create.
+   * All other creators should use the static create method
+   */
+  public BridgePoolImpl(PoolManagerImpl pm, String name, Pool attributes) {
+    super(pm, name, attributes);
+    finishCreate(pm); // do this last since we are escaping the constructor
+  }
+  public static void loadEmergencyClasses() {
+    // nyi
+  }
+
+  ////////////////// ConnectionProxy methods ////////////////////
+  /**
+   * Initializes this <code>ConnectionProxy</code> according to the
+   * given properties.
+   */
+  public void initialize(Properties p) {
+    throw new IllegalStateException("nyi");
+  }
+
+
+
+  public void finalizeProxy() {
+    detach();
+    if (getAttachCount() <= 0) {
+      destroy(keepAlive);
+    }
+  }
+
+
+  /**
+   * Returns the load balancing policy in effect for this connection
+   * proxy.
+   */
+  public String getLBPolicy() {
+    if (getThreadLocalConnections()) {
+      return "Sticky";
+    } else {
+      return "RoundRobin";
+    }
+  }
+
+
+  /**
+   * Returns the number of milliseconds to wait before re-connecting
+   * to a dead server.
+   */
+  public int getRetryInterval() {
+    return (int)getPingInterval();
+  }
+
+
+  /**
+   * Closes this connection proxy and all of its connections
+   */
+  public void close() {
+    if (logger.isDebugEnabled()) {
+      logger.debug("BridgePoolImpl - closing");
+    }
+    finalizeProxy();
+  }
+
+
+  /**
+   * Returned true if this ConnectionProxy has been initialized and not closed.
+   */
+  public boolean isOpen() {
+    return !isDestroyed();
+  }
+
+
+  /**
+   * Update bookkeeping on this proxy associated with the loss of a region.
+   * In particular, remove all region interests.
+   */
+  public void detachRegion(Region r) {
+    // nyi
+  }
+
+
+  /**
+   * Returns the number of {@link Connection}s that should be created
+   * to every cache server.
+   */
+  public int getConnectionsPerServer() {
+    return getMinConnections();
+  }
+
+
+  /**
+   * Notes that the server with the given name is unavailable
+   */
+  public void setServerUnavailable(String name) {
+    throw new IllegalStateException("nyi");
+  }
+
+
+  /**
+   * Notes that the server with the given name is available
+   */
+  public void setServerAvailable(String name) {
+    throw new IllegalStateException("nyi");
+  }
+
+
+  /**
+   * Stops this connection proxy and
+   */
+  public void terminate() {
+    finalizeProxy();
+  }
+
+
+  /**
+   * Releases the connection associated with the current thread
+   */
+  public void release() {
+    // nyi
+  }
+
+  /**
+   * Returns value of establishCallbackConnection property.
+   * @since 4.2.3
+   */
+  public boolean getEstablishCallbackConnection() {
+    return getSubscriptionEnabled();
+  }
+
+
+  /**
+   * Add an <code>Endpoint</code> to the known <code>Endpoint</code>s.
+   *
+   * @param name The name of the endpoint to add
+   * @param host The host name or ip address of the endpoint to add
+   * @param port The port of the endpoint to add
+   *
+   * @throws EndpointExistsException if the <code>Endpoint</code> to be
+   * added already exists.
+   *
+   * @since 5.0.2
+   */
+  public void addEndpoint(String name, String host, int port)
+  throws EndpointExistsException {
+    ((ExplicitConnectionSourceImpl)getConnectionSource()).addEndpoint(host,port);
+  }
+
+
+  /**
+   * Remove an <code>Endpoint</code> from the dead <code>Endpoint</code>s.
+   * The specified <code>Endpoint</code> must be dead.
+   *
+   * @param name The name of the endpoint to remove
+   * @param host The host name or ip address of the endpoint to remove
+   * @param port The port of the endpoint to remove
+   *
+   * @throws EndpointDoesNotExistException if the <code>Endpoint</code> to be
+   * removed doesn't exist.
+   *
+   * @since 5.0.2
+   */
+  public void removeEndpoint(String name, String host, int port)
+  throws EndpointDoesNotExistException,EndpointInUseException {
+    ((ExplicitConnectionSourceImpl)getConnectionSource()).removeEndpoint(host,port);
+  }
+
+
+  /**
+   * @return Returns the redundancy number
+   * @since 5.1
+   */
+  public int getRedundancyLevel() {
+    return getSubscriptionRedundancy();
+  }
+
+  /**
+   * The configurable expiry time of last received sequence ID
+   *
+   * @return The configurable expiry time of last received sequence ID
+   */
+  public long getMessageTrackingTimeout() {
+    return getSubscriptionMessageTrackingTimeout();
+  }
+
+  public void reuse() {
+    attach();
+  }
+  
+  
+  public static boolean isLoaderOp(Op op) {
+    return op instanceof GetOpImpl;
+  }
+
+  private RuntimeException transformException(RuntimeException ex, Op op) {
+    if(isLoaderOp(op)) {
+      if (ex instanceof SubscriptionNotEnabledException) {
+        return new CacheLoaderException("establishCallbackConnection must be set to true", ex);
+      } else if (ex instanceof CacheLoaderException) {
+        return ex;
+      } else if (ex instanceof CancelException) {
+        return ex;
+      } else if (ex instanceof ServerConnectivityException && ex.getCause() != null) {
+        return new CacheLoaderException(ex.getCause());
+      } else {
+        return new CacheLoaderException(ex);
+      }
+    }
+    else {
+      if (ex instanceof SubscriptionNotEnabledException) {
+        return new BridgeWriterException("establishCallbackConnection must be set to true", ex);
+      } else if (ex instanceof CacheWriterException) {
+        return ex;
+      } else if (ex instanceof CancelException) {
+        return ex;
+      } else if (ex instanceof ServerConnectivityException && ex.getCause() != null) {
+        return new BridgeWriterException(ex.getCause());
+      } else {
+        return new BridgeWriterException(ex);
+      }
+    }
+  }
+  
+  @Override
+  public Object execute(Op op) {
+    try {
+      return super.execute(op);
+    } catch (RuntimeException ex) {
+      throw transformException(ex, op);
+    }
+  }
+
+  @Override
+  public Object executeOn(ServerLocation server, Op op) {
+    try {
+      return super.executeOn(server, op);
+    } catch (RuntimeException ex) {
+      throw transformException(ex, op);
+    }
+  }
+  
+  @Override
+  public Object executeOn(Connection con, Op op) {
+    try {
+      return super.executeOn(con, op);
+    } catch (RuntimeException ex) {
+      throw transformException(ex, op);
+    }
+  }
+
+  @Override
+  public Object executeOn(Connection con, Op op, boolean timeoutFatal) {
+    try {
+      return super.executeOn(con, op, timeoutFatal);
+    } catch (RuntimeException ex) {
+      throw transformException(ex, op);
+    }
+  }
+
+  @Override
+  public Object executeOnQueuesAndReturnPrimaryResult(Op op) {
+    try {
+      return super.executeOnQueuesAndReturnPrimaryResult(op);
+    } catch (RuntimeException ex) {
+      throw transformException(ex, op);
+    }
+  }
+
+  @Override
+  public void executeOnAllQueueServers(Op op)
+    throws NoSubscriptionServersAvailableException, SubscriptionNotEnabledException {
+    try {
+      super.executeOnAllQueueServers(op);
+    } catch (RuntimeException ex) {
+      throw transformException(ex, op);
+    }
+  }
+
+  @Override
+  public Object executeOnPrimary(Op op) {
+    try {
+      return super.executeOnPrimary(op);
+    } catch (RuntimeException ex) {
+      throw transformException(ex, op);
+    }
+  }
+  public void setKeepAlive(boolean keepAlive) {
+    this.keepAlive = keepAlive;
+  }
+  
+  /** ******** INNER CLASSES ************************* */
+  public static class LBPolicy
+  {
+    public static final String STICKY_PROPERTY_NAME = "Sticky";
+
+    public static final String RANDOMSTICKY_PROPERTY_NAME = "RandomSticky";
+
+    public static final String ROUNDROBIN_PROPERTY_NAME = "RoundRobin";
+
+    public static final String RANDOM_PROPERTY_NAME = "Random";
+
+    public static final String APPASSISTED_PROPERTY_NAME = "AppAssisted";
+
+    public static final int STICKY = 0;
+
+    public static final int ROUNDROBIN = 1;
+
+    public static final int APPASSISTED = 2;
+
+    public static final int RANDOM = 3;
+
+    public static final int RANDOMSTICKY = 4;
+
+    public final int thePolicy;
+
+    public LBPolicy(String name) {
+      if (name.equalsIgnoreCase(STICKY_PROPERTY_NAME)) {
+        this.thePolicy = STICKY;
+      }
+      else if (name.equalsIgnoreCase(ROUNDROBIN_PROPERTY_NAME)) {
+        this.thePolicy = ROUNDROBIN;
+      }
+      else if (name.equalsIgnoreCase(APPASSISTED_PROPERTY_NAME)) {
+        this.thePolicy = APPASSISTED;
+      }
+      else if (name.equalsIgnoreCase(RANDOM_PROPERTY_NAME)) {
+        this.thePolicy = RANDOM;
+      }
+      else if (name.equalsIgnoreCase(RANDOMSTICKY_PROPERTY_NAME)) {
+        this.thePolicy = RANDOMSTICKY;
+      }
+      else {
+        this.thePolicy = STICKY; // DEFAULT
+      }
+    }
+
+    public int getPolicy()
+    {
+      return this.thePolicy;
+    }
+
+    public boolean isSticky() {
+      return getPolicy() == STICKY || getPolicy() == RANDOMSTICKY;
+    }
+
+    public boolean isRandom() {
+      return getPolicy() == RANDOM || getPolicy() == RANDOMSTICKY;
+    }
+
+    public String getPolicyPropertyName(int pol)
+    {
+      String retStr;
+      switch (pol) {
+      case STICKY:
+        retStr = STICKY_PROPERTY_NAME;
+        break;
+      case ROUNDROBIN:
+        retStr = ROUNDROBIN_PROPERTY_NAME;
+        break;
+      case APPASSISTED:
+        retStr = APPASSISTED_PROPERTY_NAME;
+        break;
+      case RANDOM:
+        retStr = RANDOM_PROPERTY_NAME;
+        break;
+      case RANDOMSTICKY:
+        retStr = RANDOMSTICKY_PROPERTY_NAME;
+        break;
+      default:
+        return Integer.toString(pol);
+      }
+      return retStr;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+      if (obj == this) {
+        return true;
+      }
+
+      if (obj instanceof LBPolicy) {
+        LBPolicy other = (LBPolicy)obj;
+        return this.thePolicy == other.thePolicy;
+      }
+      else {
+        return false;
+      }
+    }
+
+    @Override
+    public int hashCode()
+    {
+      return this.thePolicy;
+    }
+
+    @Override
+    public String toString()
+    {
+      return getPolicyPropertyName(this.thePolicy);
+    }
+  }
+
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/BridgeServerLoadMessage.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/BridgeServerLoadMessage.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/BridgeServerLoadMessage.java
new file mode 100644
index 0000000..a419216
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/BridgeServerLoadMessage.java
@@ -0,0 +1,99 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.server.ServerLoad;
+import com.gemstone.gemfire.distributed.Locator;
+import com.gemstone.gemfire.distributed.internal.DistributionManager;
+import com.gemstone.gemfire.distributed.internal.InternalLocator;
+import com.gemstone.gemfire.distributed.internal.SerialDistributionMessage;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.distributed.internal.ServerLocator;
+import com.gemstone.gemfire.internal.InternalDataSerializer;
+
+/**
+ * A message from bridge server to locator to update the locator
+ * with new load information from the bridge server.
+ * Also includes the id of any clients whose estimate is no
+ * longer needed on the server-locator.
+ * @author dsmith
+ * @since 5.7
+ *
+ */
+public class BridgeServerLoadMessage extends SerialDistributionMessage {
+  protected ServerLoad load;
+  protected ServerLocation location;
+  protected ArrayList clientIds;
+
+  public BridgeServerLoadMessage() {
+    super();
+  }
+  
+  public BridgeServerLoadMessage(ServerLoad load, ServerLocation location,
+                                 ArrayList clientIds) {
+    super();
+    this.load = load;
+    this.location = location;
+    this.clientIds = clientIds;
+  }
+
+  @Override
+  protected void process(DistributionManager dm) {
+    updateLocalLocators();
+  }
+
+  public void updateLocalLocators() {
+    List locators = Locator.getLocators();
+    for (int i=0; i < locators.size(); i++) {
+      InternalLocator l = (InternalLocator)locators.get(i);
+      ServerLocator serverLocator = l.getServerLocatorAdvisee();
+      if(serverLocator != null) {
+        serverLocator.updateLoad(location, load, this.clientIds);
+      }
+    }
+  }
+  
+  
+
+  public int getDSFID() {
+   return BRIDGE_SERVER_LOAD_MESSAGE;
+  }
+
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    super.fromData(in);
+    load = new ServerLoad();
+    InternalDataSerializer.invokeFromData(load, in);
+    location = new ServerLocation();
+    InternalDataSerializer.invokeFromData(location, in);
+    this.clientIds = DataSerializer.readArrayList(in);
+  }
+
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    super.toData(out);
+    InternalDataSerializer.invokeToData(load, out);
+    InternalDataSerializer.invokeToData(location, out);
+    DataSerializer.writeArrayList(this.clientIds, out);
+  }
+
+  @Override
+  protected Object clone() throws CloneNotSupportedException {
+    return super.clone();
+  }
+  
+  
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClearOp.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClearOp.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClearOp.java
new file mode 100644
index 0000000..0d77f39
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ClearOp.java
@@ -0,0 +1,97 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+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.internal.cache.EventID;
+
+/**
+ * Does a region clear (or create) on a server
+ * @author darrel
+ * @since 5.7
+ */
+public class ClearOp {
+  /**
+   * Does a region clear 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 clear on
+   * @param eventId the event id for this clear
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   */
+  public static void execute(ExecutablePool pool,
+                             String region,
+                             EventID eventId,
+                             Object callbackArg)
+  {
+    AbstractOp op = new ClearOpImpl(region, eventId, callbackArg);
+    pool.execute(op);
+  }
+                                                               
+  /**
+   * Does a region clear on a server using the given connection
+   * from the given pool
+   * to communicate with the server.
+   * @param con the connection to use to send to the server
+   * @param pool the pool to use to communicate with the server.
+   * @param region the name of the region to do the clear on
+   * @param eventId the event id for this clear
+   * @param callbackArg an optional callback arg to pass to any cache callbacks
+   */
+  public static void execute(Connection con,
+                             ExecutablePool pool,
+                             String region,
+                             EventID eventId,
+                             Object callbackArg)
+  {
+    AbstractOp op = new ClearOpImpl(region, eventId, callbackArg);
+    pool.executeOn(con, op);
+  }
+
+  private ClearOp() {
+    // no instances allowed
+  }
+  
+  private static class ClearOpImpl extends AbstractOp {
+    /**
+     * @throws com.gemstone.gemfire.SerializationException if serialization fails
+     */
+    public ClearOpImpl(String region,
+                       EventID eventId,
+                       Object callbackArg) {
+      super(MessageType.CLEAR_REGION, callbackArg != null ? 3 : 2);
+      getMessage().addStringPart(region);
+      getMessage().addBytesPart(eventId.calcBytes());
+      if (callbackArg != null) {
+        getMessage().addObjPart(callbackArg);
+      }
+    }
+    @Override
+    protected Object processResponse(Message msg) throws Exception {
+      processAck(msg, "clear region");
+      return null;
+    }
+    @Override
+    protected boolean isErrorResponse(int msgType) {
+      return msgType == MessageType.CLEAR_REGION_DATA_ERROR;
+    }
+    @Override
+    protected long startAttempt(ConnectionStats stats) {
+      return stats.startClear();
+    }
+    @Override
+    protected void endSendAttempt(ConnectionStats stats, long start) {
+      stats.endClearSend(start, hasFailed());
+    }
+    @Override
+    protected void endAttempt(ConnectionStats stats, long start) {
+      stats.endClear(start, hasTimedOut(), hasFailed());
+    }
+  }
+}


[03/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ClientConnectionResponse.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ClientConnectionResponse.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ClientConnectionResponse.java
new file mode 100644
index 0000000..ff59d2e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ClientConnectionResponse.java
@@ -0,0 +1,76 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+
+/**
+ * A response from a locator to a client
+ * Indicating which server to connect to for client to server traffic.
+ * @author dsmith
+ *
+ */
+public class ClientConnectionResponse extends ServerLocationResponse {
+
+  private ServerLocation server;
+
+  private boolean serverFound = false;
+
+  /** For data serializer */
+  public ClientConnectionResponse() {
+    super();
+  }
+
+  public ClientConnectionResponse(ServerLocation server) {
+    this.server = server;
+    if (server != null) {
+      this.serverFound = true;
+    }
+  }
+
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.serverFound = DataSerializer.readPrimitiveBoolean(in);
+    if (this.serverFound) {
+      server = new ServerLocation();
+      server.fromData(in);
+    }
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    boolean serverFound = server != null;
+    DataSerializer.writePrimitiveBoolean(serverFound, out);
+    if(serverFound) {
+      server.toData(out);
+    }
+  }
+  
+  public ServerLocation getServer() {
+    return server;
+  }
+  
+  @Override
+  public String toString() {
+    return "ClientConnectionResponse{server=" + getServer() + "}";
+  }
+
+  public int getDSFID() {
+    return DataSerializableFixedID.CLIENT_CONNECTION_RESPONSE;
+  }
+  
+  @Override
+  public boolean hasResult() {
+    return this.serverFound;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ClientReplacementRequest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ClientReplacementRequest.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ClientReplacementRequest.java
new file mode 100644
index 0000000..ba639e2
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ClientReplacementRequest.java
@@ -0,0 +1,66 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Set;
+
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.InternalDataSerializer;
+
+/**
+ * A request from a client to the locator asking for a
+ * server to connect to for client to server traffic.
+ * @author dsmith
+ *
+ */
+public class ClientReplacementRequest extends ClientConnectionRequest {
+  private ServerLocation currentServer;
+  
+  public ClientReplacementRequest() {
+    
+  }
+
+  public ClientReplacementRequest(ServerLocation currentServer, Set/*<ServerLocation>*/ excludedServers, String serverGroup) {
+    super(excludedServers, serverGroup);
+    this.currentServer = currentServer;
+  }
+
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    super.fromData(in);
+    this.currentServer = new ServerLocation();
+    InternalDataSerializer.invokeFromData(this.currentServer, in);
+  }
+
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    super.toData(out);
+    InternalDataSerializer.invokeToData(this.currentServer, out);
+  }
+
+  public ServerLocation getCurrentServer() {
+    return this.currentServer;
+  }
+  
+  @Override
+  public String toString() {
+    return "ClientReplacementRequest{group=" + getServerGroup()
+      + ", excluded=" + getExcludedServers()
+      + ", currentServer=" + getCurrentServer()
+      + "}";
+  }
+
+  @Override
+  public int getDSFID() {
+    return DataSerializableFixedID.CLIENT_REPLACEMENT_REQUEST;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/GetAllServersRequest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/GetAllServersRequest.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/GetAllServersRequest.java
new file mode 100644
index 0000000..b65ea7a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/GetAllServersRequest.java
@@ -0,0 +1,50 @@
+/*
+ * ========================================================================= 
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved. 
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ * =========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+/**
+ * 
+ * @author ymahajan
+ *
+ */
+
+public class GetAllServersRequest extends ServerLocationRequest {
+
+  public GetAllServersRequest() {
+
+  }
+
+  public GetAllServersRequest(String serverGroup) {
+    super(serverGroup);
+  }
+
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    super.fromData(in);
+  }
+
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    super.toData(out);
+  }
+
+  @Override
+  public String toString() {
+    return "GetAllServersRequest{group=" + getServerGroup();
+  }
+
+  public int getDSFID() {
+    return DataSerializableFixedID.GET_ALL_SERVERS_REQUEST;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/GetAllServersResponse.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/GetAllServersResponse.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/GetAllServersResponse.java
new file mode 100644
index 0000000..680ccec
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/GetAllServersResponse.java
@@ -0,0 +1,72 @@
+/*
+ * ========================================================================= 
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved. 
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ * =========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+/**
+ * 
+ * @author ymahajan
+ *
+ */
+public class GetAllServersResponse extends ServerLocationResponse {
+
+  private ArrayList servers;
+
+  private boolean serversFound = false;
+
+  /** For data serializer */
+  public GetAllServersResponse() {
+    super();
+  }
+
+  public GetAllServersResponse(ArrayList servers) {
+    this.servers = servers;
+    if (servers != null && !servers.isEmpty()) {
+      this.serversFound = true;
+    }
+  }
+
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.servers = SerializationHelper.readServerLocationList(in);
+    if (this.servers != null && !this.servers.isEmpty()) {
+      this.serversFound = true;
+    }
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    SerializationHelper.writeServerLocationList(servers, out);
+  }
+
+  public ArrayList getServers() {
+    return servers;
+  }
+
+  @Override
+  public String toString() {
+    return "GetAllServersResponse{servers=" + getServers() + "}";
+  }
+
+  public int getDSFID() {
+    return DataSerializableFixedID.GET_ALL_SERVRES_RESPONSE;
+  }
+
+  @Override
+  public boolean hasResult() {
+    return this.serversFound;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/LocatorListRequest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/LocatorListRequest.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/LocatorListRequest.java
new file mode 100644
index 0000000..0bb5f25
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/LocatorListRequest.java
@@ -0,0 +1,27 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator;
+
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+
+
+/**
+ * @author dsmith
+ *
+ */
+public class LocatorListRequest extends ServerLocationRequest {
+
+  @Override
+  public String toString() {
+    return "LocatorListRequest{group=" + getServerGroup() + "}";
+  }
+  
+  public int getDSFID() {
+    return DataSerializableFixedID.LOCATOR_LIST_REQUEST;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/LocatorListResponse.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/LocatorListResponse.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/LocatorListResponse.java
new file mode 100644
index 0000000..e722495
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/LocatorListResponse.java
@@ -0,0 +1,83 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+
+/**
+ * @author dsmith
+ *
+ */
+public class LocatorListResponse extends ServerLocationResponse {
+  /** ArrayList of ServerLocations for controllers */
+  private ArrayList controllers;
+  private boolean isBalanced;
+  private boolean locatorsFound = false;
+
+  /** Used by DataSerializer */
+  public LocatorListResponse() {
+  }
+  
+  public LocatorListResponse(ArrayList locators, boolean isBalanced) {
+    this.controllers = locators;
+    if (locators != null && !locators.isEmpty()) {
+      this.locatorsFound = true;
+    }
+    this.isBalanced = isBalanced;
+  }
+  
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.controllers = SerializationHelper.readServerLocationList(in);
+    this.isBalanced = in.readBoolean();
+    if (this.controllers != null && !this.controllers.isEmpty()) {
+      this.locatorsFound = true;
+    }
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    SerializationHelper.writeServerLocationList(this.controllers, out);
+    out.writeBoolean(isBalanced);
+  }
+
+  /**
+   * Returns an array list of type ServerLocation containing controllers.
+   * @return list of controllers
+   */
+  public ArrayList getLocators() {
+    return this.controllers;
+  }
+
+  /**
+   * Returns whether or not the locator thinks that the servers 
+   * in this group are currently balanced.
+   * @return true if the servers are balanced.
+   */
+  public boolean isBalanced() {
+    return isBalanced;
+  }
+  
+  @Override
+  public String toString() {
+    return "LocatorListResponse{locators=" + controllers + ",isBalanced=" + isBalanced + "}";
+  }
+
+  public int getDSFID() {
+    return DataSerializableFixedID.LOCATOR_LIST_RESPONSE;
+  }
+
+  @Override
+  public boolean hasResult() {
+    return this.locatorsFound;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/LocatorStatusRequest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/LocatorStatusRequest.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/LocatorStatusRequest.java
new file mode 100644
index 0000000..2dee308
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/LocatorStatusRequest.java
@@ -0,0 +1,29 @@
+/*
+ * =========================================================================
+ *  Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ *  This product is protected by U.S. and international copyright
+ *  and intellectual property laws. Pivotal products are covered by
+ *  more patents listed at http://www.pivotal.io/patents.
+ * ========================================================================
+ */
+
+package com.gemstone.gemfire.cache.client.internal.locator;
+
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+
+/**
+ * The LocatorStatusRequest class...
+ * </p>
+ * @author John Blum
+ * @see com.gemstone.gemfire.cache.client.internal.locator.ServerLocationRequest
+ * @see com.gemstone.gemfire.internal.DataSerializableFixedID
+ * @since 7.0
+ */
+public class LocatorStatusRequest extends ServerLocationRequest {
+
+  @Override
+  public int getDSFID() {
+    return DataSerializableFixedID.LOCATOR_STATUS_REQUEST;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/LocatorStatusResponse.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/LocatorStatusResponse.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/LocatorStatusResponse.java
new file mode 100644
index 0000000..a526dd7
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/LocatorStatusResponse.java
@@ -0,0 +1,313 @@
+/*
+ * =========================================================================
+ *  Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ *  This product is protected by U.S. and international copyright
+ *  and intellectual property laws. Pivotal products are covered by
+ *  more patents listed at http://www.pivotal.io/patents.
+ * ========================================================================
+ */
+
+package com.gemstone.gemfire.cache.client.internal.locator;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.GemFireVersion;
+import com.gemstone.gemfire.internal.lang.ObjectUtils;
+import com.gemstone.gemfire.internal.lang.StringUtils;
+import com.gemstone.gemfire.internal.process.PidUnavailableException;
+import com.gemstone.gemfire.internal.process.ProcessUtils;
+
+/**
+ * The LocatorStatusResponse class...
+ * </p>
+ * @author John Blum
+ * @see com.gemstone.gemfire.cache.client.internal.locator.ServerLocationResponse
+ * @since 7.0
+ */
+public class LocatorStatusResponse extends ServerLocationResponse {
+
+  private Integer pid;
+
+  private List<String> jvmArgs;
+
+  private Long uptime;
+
+  private String classpath;
+  private String gemfireVersion;
+  private String javaVersion;
+  private String workingDirectory;
+
+  private String logFile;
+  private String host;
+  private Integer port;
+  private String name;
+  
+  private static Integer identifyPid() {
+    try {
+      return ProcessUtils.identifyPid();
+    }
+    catch (PidUnavailableException ignore) {
+      return null;
+    }
+  }
+
+  public LocatorStatusResponse initialize(final int locatorPort,
+                                          final String locatorHost,
+                                          final String locatorLogFile,
+                                          final String locatorName) {
+    final RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
+    this.pid = identifyPid();
+    this.jvmArgs = runtimeBean.getInputArguments();
+    this.uptime = runtimeBean.getUptime();
+    this.classpath = runtimeBean.getClassPath();
+    this.gemfireVersion = GemFireVersion.getGemFireVersion();
+    this.javaVersion = System.getProperty("java.version");
+    this.workingDirectory = System.getProperty("user.dir");
+    this.logFile = locatorLogFile;
+    this.host = locatorHost;
+    this.port = locatorPort;
+    this.name = locatorName;
+    return this;
+  }
+
+  @Override
+  public int getDSFID() {
+    return DataSerializableFixedID.LOCATOR_STATUS_RESPONSE;
+  }
+
+  public String getClasspath() {
+    return classpath;
+  }
+
+  public String getGemFireVersion() {
+    return gemfireVersion;
+  }
+
+  public String getJavaVersion() {
+    return javaVersion;
+  }
+
+  @SuppressWarnings("unchecked")
+  public List<String> getJvmArgs() {
+    return Collections.unmodifiableList(ObjectUtils.defaultIfNull(jvmArgs, Collections.<String>emptyList()));
+  }
+
+  public Integer getPid() {
+    return pid;
+  }
+
+  public Long getUptime() {
+    return uptime;
+  }
+
+  public String getWorkingDirectory() {
+    return workingDirectory;
+  }
+  
+  public String getLogFile() {
+    return this.logFile;
+  }
+  
+  public String getHost() {
+    return this.host;
+  }
+  
+  public Integer getPort() {
+    return this.port;
+  }
+  
+  public String getName() {
+    return this.name;
+  }
+
+  @Override
+  public boolean hasResult() {
+    return true;
+  }
+
+  @Override
+  public void fromData(final DataInput in) throws IOException, ClassNotFoundException {
+    readPid(in);
+    readUptime(in);
+    readWorkingDirectory(in);
+    readJvmArguments(in);
+    readClasspath(in);
+    readGemFireVersion(in);
+    readJavaVersion(in);
+    readLogFile(in);
+    readHost(in);
+    readPort(in);
+    readName(in);
+  }
+
+  protected void readPid(final DataInput in) throws IOException {
+    final int pid = in.readInt();
+    this.pid = (pid == 0 ? null : pid);
+  }
+
+  protected void readUptime(final DataInput in) throws IOException {
+    this.uptime = in.readLong();
+  }
+
+  protected void readWorkingDirectory(final DataInput in) throws IOException {
+    this.workingDirectory = StringUtils.defaultIfBlank(in.readUTF());
+  }
+
+  protected void readJvmArguments(final DataInput in) throws IOException {
+    final int length = in.readInt();
+    final List<String> jvmArgs = new ArrayList<String>(length);
+    for (int index = 0; index < length; index++) {
+      jvmArgs.add(in.readUTF());
+    }
+    this.jvmArgs = jvmArgs;
+  }
+
+  protected void readClasspath(final DataInput in) throws IOException {
+    this.classpath = StringUtils.defaultIfBlank(in.readUTF());
+  }
+
+  protected void readGemFireVersion(final DataInput in) throws IOException {
+    this.gemfireVersion = StringUtils.defaultIfBlank(in.readUTF());
+  }
+
+  protected void readJavaVersion(final DataInput in) throws IOException {
+    this.javaVersion = StringUtils.defaultIfBlank(in.readUTF());
+  }
+  
+  protected void readLogFile(final DataInput in) throws IOException {
+    this.logFile = StringUtils.defaultIfBlank(in.readUTF());
+  }
+  
+  protected void readHost(final DataInput in) throws IOException {
+    this.host = StringUtils.defaultIfBlank(in.readUTF());
+  }
+  
+  protected void readPort(final DataInput in) throws IOException {
+    final int port = in.readInt();
+    this.port = (port == 0 ? null : port);
+  }
+  
+  protected void readName(final DataInput in) throws IOException {
+    this.name = StringUtils.defaultIfBlank(in.readUTF());
+  }
+
+  @Override
+  public void toData(final DataOutput out) throws IOException {
+    writePid(out);
+    writeUptime(out);
+    writeWorkingDirectory(out);
+    writeJvmArguments(out);
+    writeClasspath(out);
+    writeGemFireVersion(out);
+    writeJavaVersion(out);
+    writeLogFile(out);
+    writeHost(out);
+    writePort(out);
+    writeName(out);
+  }
+
+  protected void writePid(final DataOutput out) throws IOException {
+    out.writeInt(ObjectUtils.defaultIfNull(getPid(), 0));
+  }
+
+  protected void writeUptime(final DataOutput out) throws IOException {
+    out.writeLong(getUptime());
+  }
+
+  protected void writeWorkingDirectory(final DataOutput out) throws IOException {
+    out.writeUTF(ObjectUtils.defaultIfNull(getWorkingDirectory(), ""));
+  }
+
+  protected void writeJvmArguments(final DataOutput out) throws IOException {
+    final List<String> jvmArgs = getJvmArgs();
+    out.writeInt(jvmArgs.size());
+    for (final String jvmArg : jvmArgs) {
+      out.writeUTF(jvmArg);
+    }
+  }
+
+  protected void writeClasspath(final DataOutput out) throws IOException {
+    out.writeUTF(ObjectUtils.defaultIfNull(getClasspath(), ""));
+  }
+
+  protected void writeGemFireVersion(final DataOutput out) throws IOException {
+    out.writeUTF(ObjectUtils.defaultIfNull(getGemFireVersion(), ""));
+  }
+
+  protected void writeJavaVersion(final DataOutput out) throws IOException {
+    out.writeUTF(ObjectUtils.defaultIfNull(getJavaVersion(), ""));
+  }
+  
+  protected void writeLogFile(final DataOutput out)throws IOException {
+    out.writeUTF(ObjectUtils.defaultIfNull(getLogFile(), ""));
+  }
+  
+  protected void writeHost(final DataOutput out)throws IOException {
+    out.writeUTF(ObjectUtils.defaultIfNull(getHost(), ""));
+  }
+  
+  protected void writePort(final DataOutput out) throws IOException {
+    out.writeInt(ObjectUtils.defaultIfNull(getPort(), 0));
+  }
+  
+  protected void writeName(final DataOutput out)throws IOException {
+    out.writeUTF(ObjectUtils.defaultIfNull(getName(), ""));
+  }
+
+  @Override
+  public boolean equals(final Object obj) {
+    if (obj == this) {
+      return true;
+    }
+
+    if (!(obj instanceof LocatorStatusResponse)) {
+      return false;
+    }
+
+    final LocatorStatusResponse that = (LocatorStatusResponse) obj;
+
+    return ObjectUtils.equalsIgnoreNull(this.getPid(), that.getPid())
+      && ObjectUtils.equals(this.getUptime(), that.getUptime())
+      && ObjectUtils.equals(this.getWorkingDirectory(), that.getWorkingDirectory())
+      && ObjectUtils.equals(this.getJvmArgs(), that.getJvmArgs())
+      && ObjectUtils.equals(this.getClasspath(), that.getClasspath())
+      && ObjectUtils.equals(this.getGemFireVersion(), that.getGemFireVersion())
+      && ObjectUtils.equals(this.getJavaVersion(), that.getJavaVersion());
+  }
+
+  @Override
+  public int hashCode() {
+    int hashValue = 17;
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getPid());
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getUptime());
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getWorkingDirectory());
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getJvmArgs());
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getClasspath());
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getGemFireVersion());
+    hashValue = 37 * hashValue + ObjectUtils.hashCode(getJavaVersion());
+    return hashValue;
+  }
+
+  @Override
+  public String toString() {
+    final StringBuilder buffer = new StringBuilder(getClass().getSimpleName());
+    buffer.append("{ pid = ").append(getPid());
+    buffer.append(", uptime = ").append(getUptime());
+    buffer.append(", workingDirectory = ").append(getWorkingDirectory());
+    buffer.append(", jvmArgs = ").append(getJvmArgs());
+    buffer.append(", classpath = ").append(getClasspath());
+    buffer.append(", gemfireVersion = ").append(getGemFireVersion());
+    buffer.append(", javaVersion = ").append(getJavaVersion());
+    buffer.append("}");
+    return buffer.toString();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/QueueConnectionRequest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/QueueConnectionRequest.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/QueueConnectionRequest.java
new file mode 100644
index 0000000..46d5109
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/QueueConnectionRequest.java
@@ -0,0 +1,90 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Set;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
+
+/**
+ * A request from a client to locator asking for a server
+ * to host a queue. If the durable client Id is specified, the locator
+ * will attempt to discover a pre-existing queue.
+ * @author dsmith
+ * @author gregp
+ *
+ */
+public class QueueConnectionRequest extends ServerLocationRequest {
+  private ClientProxyMembershipID proxyId;
+  private Set excludedServers;
+  private int redundantCopies;
+  private boolean findDurable = false;
+  
+  public QueueConnectionRequest() {
+    super();
+  }
+
+  public QueueConnectionRequest(ClientProxyMembershipID proxyId, int redundantCopies, Set excludedServers, String serverGroup,boolean findDurable) {
+    super(serverGroup);
+    this.proxyId = proxyId;
+    this.excludedServers = excludedServers;
+    this.redundantCopies = redundantCopies;
+    this.findDurable = findDurable;
+  }
+  
+  @Override
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    super.fromData(in);
+    
+    proxyId = ClientProxyMembershipID.readCanonicalized(in);
+    redundantCopies = DataSerializer.readPrimitiveInt(in);
+    this.excludedServers = SerializationHelper.readServerLocationSet(in);
+    this.findDurable = in.readBoolean();
+  }
+
+  @Override
+  public void toData(DataOutput out) throws IOException {
+    super.toData(out);
+    DataSerializer.writeObject(proxyId, out);
+    DataSerializer.writePrimitiveInt(redundantCopies, out);
+    SerializationHelper.writeServerLocationSet(this.excludedServers, out);
+    out.writeBoolean(this.findDurable);
+  }
+  
+  public Set getExcludedServers() {
+    return excludedServers;
+  }
+
+  public ClientProxyMembershipID getProxyId() {
+    return proxyId;
+  }
+
+  public int getRedundantCopies() {
+    return redundantCopies;
+  }
+  
+  public boolean isFindDurable() {
+    return this.findDurable;
+  }
+  
+  @Override
+  public String toString() {
+    return "QueueConnectionRequest{group=" + getServerGroup() + ", excluded="
+        + getExcludedServers() + ", redundant= " + redundantCopies
+        + ",findDurable=" + findDurable + ",proxyId=" + proxyId + "}";
+  }
+  
+  public int getDSFID() {
+    return DataSerializableFixedID.QUEUE_CONNECTION_REQUEST;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/QueueConnectionResponse.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/QueueConnectionResponse.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/QueueConnectionResponse.java
new file mode 100644
index 0000000..f005e86
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/QueueConnectionResponse.java
@@ -0,0 +1,78 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.List;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+
+/**
+ * A response from locator to client indicating the servers
+ * to use to host the clients queue. The servers already
+ * contain the queue if the durableQueueFound flag is true.
+ * @author dsmith
+ *
+ */
+public class QueueConnectionResponse extends ServerLocationResponse {
+  
+  private boolean durableQueueFound;
+  private List servers;
+  private boolean serversFound = false;
+
+  public QueueConnectionResponse() {
+  }
+
+  public QueueConnectionResponse(boolean durableQueueFound, List servers) {
+    this.durableQueueFound = durableQueueFound;
+    this.servers = servers;
+    if (servers != null && !servers.isEmpty()) {
+      this.serversFound = true;
+    }
+  }
+
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    durableQueueFound = DataSerializer.readPrimitiveBoolean(in);
+    servers = SerializationHelper.readServerLocationList(in);
+    if (this.servers != null && !this.servers.isEmpty()) {
+      this.serversFound = true;
+    }
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    DataSerializer.writePrimitiveBoolean(durableQueueFound, out);
+    SerializationHelper.writeServerLocationList(servers, out);
+  }
+
+  public boolean isDurableQueueFound() {
+    return durableQueueFound;
+  }
+
+  public List getServers() {
+    return servers;
+  }
+  
+  @Override
+  public String toString() {
+    return "QueueConnectionResponse{durableQueueFound=" + durableQueueFound + ", servers="
+        + servers + "}";
+  }
+  
+  public int getDSFID() {
+    return DataSerializableFixedID.QUEUE_CONNECTION_RESPONSE;
+  }
+
+  @Override
+  public boolean hasResult() {
+    return this.serversFound;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/SerializationHelper.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/SerializationHelper.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/SerializationHelper.java
new file mode 100644
index 0000000..65c353a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/SerializationHelper.java
@@ -0,0 +1,114 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.InternalDataSerializer;
+import com.gemstone.gemfire.internal.cache.BucketServerLocation66;
+
+/**
+ * @author dsmith
+ *
+ */
+public class SerializationHelper {
+
+  private static void writeServerLocations(Collection/*<ServerLocation>*/ serverLocations, DataOutput out) throws IOException {
+    if(serverLocations == null) {
+      out.writeInt(-1);
+      return;
+    }
+    int length = serverLocations.size();
+    out.writeInt(length);
+    for(Iterator itr = serverLocations.iterator(); itr.hasNext(); ) {
+      ServerLocation next = (ServerLocation) itr.next();
+      InternalDataSerializer.invokeToData(next, out);
+    }
+  }
+
+  private static void writeBucketServerLocations(Collection<BucketServerLocation66> bucketServerLocations, DataOutput out) throws IOException {
+    if(bucketServerLocations == null) {
+      out.writeInt(-1);
+      return;
+    }
+    int length = bucketServerLocations.size();
+    out.writeInt(length);
+    for(Iterator itr = bucketServerLocations.iterator(); itr.hasNext(); ) {
+      ServerLocation next = (ServerLocation) itr.next();
+      InternalDataSerializer.invokeToData(next, out);
+    }
+  }
+  
+  public static ArrayList/*<ServerLocation>*/ readServerLocationList(DataInput in) throws IOException, ClassNotFoundException {
+    int size = in.readInt();
+    if(size < 0) {
+      return null;
+    }
+    ArrayList serverLocations  = new ArrayList(size);
+    for(int i = 0; i < size; i++) {
+      ServerLocation next = new ServerLocation();
+      InternalDataSerializer.invokeFromData(next, in);
+      serverLocations.add(next);
+    }
+    return serverLocations;
+  }
+  
+  public static void writeServerLocationList(List/*<ServerLocation>*/ serverLocations, DataOutput out) throws IOException {
+    writeServerLocations(serverLocations, out);
+  }
+
+  public static void writeServerLocationSet(Set/*<ServerLocation>*/ serverLocations, DataOutput out) throws IOException {
+    writeServerLocations(serverLocations, out);
+  }
+
+  public static void writeBucketServerLocationSet(Set<BucketServerLocation66> bucketServerLocations, DataOutput out) throws IOException {
+    writeBucketServerLocations(bucketServerLocations, out);
+  }
+  
+  public static HashSet/*<ServerLocation>*/ readServerLocationSet(DataInput in) throws IOException, ClassNotFoundException {
+    int size = in.readInt();
+    if(size < 0) {
+      return null;
+    }
+    HashSet serverLocations  = new HashSet(size);
+    for(int i = 0; i < size; i++) {
+      ServerLocation next = new ServerLocation();
+      InternalDataSerializer.invokeFromData(next, in);
+      serverLocations.add(next);
+    }
+    return serverLocations;
+  }
+  
+  public static HashSet<BucketServerLocation66> readBucketServerLocationSet(DataInput in) throws IOException, ClassNotFoundException {
+    int size = in.readInt();
+    if(size < 0) {
+      return null;
+    }
+    HashSet bucketServerLocations  = new HashSet(size);
+    for(int i = 0; i < size; i++) {
+      BucketServerLocation66 next = new BucketServerLocation66();
+      InternalDataSerializer.invokeFromData(next, in);
+      bucketServerLocations.add(next);
+    }
+    return bucketServerLocations;
+  }
+  
+
+  private SerializationHelper() {
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ServerLocationRequest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ServerLocationRequest.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ServerLocationRequest.java
new file mode 100644
index 0000000..e313b4e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ServerLocationRequest.java
@@ -0,0 +1,52 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.Version;
+
+/**
+ * @author dsmith
+ *
+ */
+public abstract class ServerLocationRequest implements DataSerializableFixedID {
+
+ private String serverGroup;
+  
+  public ServerLocationRequest(String serverGroup) {
+    super();
+    this.serverGroup = serverGroup;
+  }
+  
+  /** Used by DataSerializer */
+  public ServerLocationRequest() {
+    
+  }
+
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    serverGroup = DataSerializer.readString(in);
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    DataSerializer.writeString(serverGroup, out);
+  }
+
+  public String getServerGroup() {
+    return serverGroup;
+  }
+  
+  @Override
+  public Version[] getSerializationVersions() {
+    return null;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ServerLocationResponse.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ServerLocationResponse.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ServerLocationResponse.java
new file mode 100644
index 0000000..d6fea17
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/ServerLocationResponse.java
@@ -0,0 +1,24 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator;
+
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.Version;
+
+/**
+ * @author dsmith
+ *
+ */
+public abstract class ServerLocationResponse implements DataSerializableFixedID {
+  public abstract boolean hasResult();
+  
+  @Override
+  public Version[] getSerializationVersions() {
+    return null;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/LocatorJoinMessage.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/LocatorJoinMessage.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/LocatorJoinMessage.java
new file mode 100644
index 0000000..124ca2e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/LocatorJoinMessage.java
@@ -0,0 +1,96 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator.wan;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.client.internal.locator.ServerLocationRequest;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.admin.remote.DistributionLocatorId;
+
+public class LocatorJoinMessage extends ServerLocationRequest {
+
+  private DistributionLocatorId locator;
+  
+  private int distributedSystemId;
+  
+  private DistributionLocatorId sourceLocator;
+
+  public LocatorJoinMessage() {
+    super();
+  }
+
+  public LocatorJoinMessage(int distributedSystemId, DistributionLocatorId locator,
+      DistributionLocatorId sourceLocator, String serverGroup) {
+    super(serverGroup);
+    this.locator = locator;
+    this.distributedSystemId = distributedSystemId;
+    this.sourceLocator = sourceLocator;
+  }
+
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    super.fromData(in);
+    this.locator = DataSerializer.readObject(in);
+    this.distributedSystemId = in.readInt();
+    this.sourceLocator = DataSerializer.readObject(in);
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    super.toData(out);
+    DataSerializer.writeObject(locator, out);
+    out.writeInt(this.distributedSystemId);
+    DataSerializer.writeObject(sourceLocator, out);
+  }
+
+  public DistributionLocatorId getLocator() {
+    return this.locator;
+  }
+
+  public int getDistributedSystemId() {
+    return distributedSystemId;
+  }
+  
+  public DistributionLocatorId getSourceLocator() {
+    return sourceLocator;
+  }
+  
+  public int getDSFID() {
+    return DataSerializableFixedID.LOCATOR_JOIN_MESSAGE;
+  }
+
+  @Override
+  public String toString() {
+    return "LocatorJoinMessage{distributedSystemId="+ distributedSystemId +" locators=" + locator + " Source Locator : " + sourceLocator +"}";
+  }
+
+  @Override
+  public boolean equals(Object obj){
+    if ( this == obj ) return true;
+    if ( !(obj instanceof LocatorJoinMessage) ) return false;
+    LocatorJoinMessage myObject = (LocatorJoinMessage)obj;
+    if((this.distributedSystemId == myObject.getDistributedSystemId()) && this.locator.equals(myObject.getLocator())){
+      return true;
+    }
+    return false;
+  }
+  
+  @Override
+  public int hashCode() {
+    // it is sufficient for all messages having the same locator to hash to the same bucket
+    if (this.locator == null) {
+      return 0;
+    } else {
+      return this.locator.hashCode();
+    }
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/LocatorMembershipListener.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/LocatorMembershipListener.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/LocatorMembershipListener.java
new file mode 100644
index 0000000..3a59e91
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/LocatorMembershipListener.java
@@ -0,0 +1,48 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator.wan;
+
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.internal.admin.remote.DistributionLocatorId;
+
+/**
+ * A listener to handle membership when new locator is added to remote locator
+ * metadata. This listener is expected to inform all other locators in remote
+ * locator metadata about the new locator so that they can update their remote
+ * locator metadata.
+ * 
+ * @author kbachhav
+ * 
+ */
+public interface LocatorMembershipListener {
+
+  public Object handleRequest(Object request);
+  
+  public void setPort(int port);
+  public void setConfig(DistributionConfig config);
+  
+  /**
+   * When the new locator is added to remote locator metadata, inform all other
+   * locators in remote locator metadata about the new locator so that they can
+   * update their remote locator metadata.
+   * 
+   * @param locator
+   */
+  public void locatorJoined(int distributedSystemId, DistributionLocatorId locator, DistributionLocatorId sourceLocator);
+  
+  public Set<String> getRemoteLocatorInfo(int dsId);
+
+  public ConcurrentMap<Integer,Set<DistributionLocatorId>> getAllLocatorsInfo();
+  
+  public ConcurrentMap<Integer,Set<String>> getAllServerLocatorsInfo();
+  
+  public void clearLocatorInfo();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorJoinRequest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorJoinRequest.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorJoinRequest.java
new file mode 100644
index 0000000..b31a6bd
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorJoinRequest.java
@@ -0,0 +1,78 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator.wan;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.client.internal.locator.ServerLocationRequest;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.admin.remote.DistributionLocatorId;
+
+/**
+ * Requests remote locators of a remote WAN site
+ * 
+ * @author Suranjan Kumar
+ * @author Yogesh Mahajan
+ * @author Kishor Bachhav
+ * 
+ * @since 6.6
+ * 
+ */
+public class RemoteLocatorJoinRequest implements DataSerializableFixedID {
+
+  private DistributionLocatorId locator = null;
+ 
+  private int distributedSystemId = -1;
+
+  public RemoteLocatorJoinRequest() {
+    super();
+  }
+
+  public RemoteLocatorJoinRequest(int distributedSystemId, DistributionLocatorId locator,
+      String serverGroup) {
+    this.distributedSystemId = distributedSystemId;
+    this.locator = locator;
+  }
+
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.locator = DataSerializer.readObject(in);
+    this.distributedSystemId = in.readInt();
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    DataSerializer.writeObject(locator, out);
+    out.writeInt(this.distributedSystemId);
+  }
+
+  public DistributionLocatorId getLocator() {
+    return this.locator;
+  }
+  
+  public int getDistributedSystemId() {
+    return distributedSystemId;
+  }
+  
+  public int getDSFID() {
+    return DataSerializableFixedID.REMOTE_LOCATOR_JOIN_REQUEST;
+  }
+
+  @Override
+  public String toString() {
+    return "RemoteLocatorJoinRequest{locator=" + locator + "}";
+  }
+
+  @Override
+  public Version[] getSerializationVersions() {
+    return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorJoinResponse.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorJoinResponse.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorJoinResponse.java
new file mode 100644
index 0000000..4bd478d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorJoinResponse.java
@@ -0,0 +1,80 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator.wan;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.internal.CopyOnWriteHashSet;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.admin.remote.DistributionLocatorId;
+
+/**
+ * List of remote locators as a response
+ * 
+ * @author Suranjan Kumar
+ * @author Yogesh Mahajan
+ * @author Kishor Bachhav
+ * 
+ * 
+ */
+public class RemoteLocatorJoinResponse implements DataSerializableFixedID{
+
+  private HashMap<Integer, Set<DistributionLocatorId>> locators = new HashMap<Integer, Set<DistributionLocatorId>>();
+  
+  /** Used by DataSerializer */
+  public RemoteLocatorJoinResponse() {
+    super();
+  }
+
+  public RemoteLocatorJoinResponse(
+      Map<Integer, Set<DistributionLocatorId>> locators) {
+    super();
+    this.locators = new HashMap<Integer, Set<DistributionLocatorId>>();
+    for (Map.Entry<Integer, Set<DistributionLocatorId>> entry : locators
+        .entrySet()) {
+      this.locators.put(entry.getKey(), new CopyOnWriteHashSet<DistributionLocatorId>(
+          entry.getValue()));
+    }
+  }
+  
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.locators = DataSerializer.readHashMap(in);
+    
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    DataSerializer.writeHashMap(locators, out);
+  }
+
+  public Map<Integer, Set<DistributionLocatorId>> getLocators() {
+    return this.locators;
+  }
+
+  @Override
+  public String toString() {
+    return "RemoteLocatorJoinResponse{locators=" + locators + "}";
+  }
+
+  public int getDSFID() {
+    return DataSerializableFixedID.REMOTE_LOCATOR_JOIN_RESPONSE;
+  }
+
+  @Override
+  public Version[] getSerializationVersions() {
+    return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorPingRequest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorPingRequest.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorPingRequest.java
new file mode 100644
index 0000000..937b676
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorPingRequest.java
@@ -0,0 +1,47 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator.wan;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.Version;
+
+/**
+ * 
+ * @author Kishor Bachhav
+ *
+ */
+
+public class RemoteLocatorPingRequest implements DataSerializableFixedID{
+
+  public RemoteLocatorPingRequest() {
+    super();
+  }
+
+  public RemoteLocatorPingRequest(String serverGroup) {
+  }
+
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+  }
+
+  public void toData(DataOutput out) throws IOException {
+  }
+
+  public int getDSFID() {
+    return DataSerializableFixedID.REMOTE_LOCATOR_PING_REQUEST;
+  }
+
+  @Override
+  public Version[] getSerializationVersions() {
+    return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorPingResponse.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorPingResponse.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorPingResponse.java
new file mode 100644
index 0000000..3978e81
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorPingResponse.java
@@ -0,0 +1,46 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator.wan;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.Version;
+
+/**
+ * 
+ * @author Kishor Bachhav
+ */
+public class RemoteLocatorPingResponse implements DataSerializableFixedID {
+
+
+  /** Used by DataSerializer */
+  public RemoteLocatorPingResponse() {
+    super();
+  }
+
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+  }
+
+  public void toData(DataOutput out) throws IOException {
+  }
+
+
+
+  public int getDSFID() {
+    return DataSerializableFixedID.REMOTE_LOCATOR_PING_RESPONSE;
+  }
+
+  @Override
+  public Version[] getSerializationVersions() {
+    return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorRequest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorRequest.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorRequest.java
new file mode 100644
index 0000000..8187531
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorRequest.java
@@ -0,0 +1,57 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator.wan;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.Version;
+/**
+ * 
+ * @author Suranjan Kumar
+ * @author Yogesh Mahajan
+ * @author Kishor Bachhav
+ *
+ */
+public class RemoteLocatorRequest implements DataSerializableFixedID{
+  private int distributedSystemId ;
+
+  public RemoteLocatorRequest() {
+    super();
+  }
+  public RemoteLocatorRequest(int dsId, String serverGroup) {
+    this.distributedSystemId = dsId;
+  }
+  
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.distributedSystemId = in.readInt();
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    out.writeInt(this.distributedSystemId);
+  }
+
+  public int getDsId() {
+    return this.distributedSystemId;
+  }
+  
+  public int getDSFID() {
+    return DataSerializableFixedID.REMOTE_LOCATOR_REQUEST;
+  }
+
+  @Override
+  public String toString() {
+    return "RemoteLocatorRequest{dsName=" + distributedSystemId + "}";
+  }
+  @Override
+  public Version[] getSerializationVersions() {
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorResponse.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorResponse.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorResponse.java
new file mode 100644
index 0000000..5c61bdf
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/locator/wan/RemoteLocatorResponse.java
@@ -0,0 +1,65 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.locator.wan;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Set;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.internal.DataSerializableFixedID;
+import com.gemstone.gemfire.internal.Version;
+
+/**
+ * 
+ * @author Suranjan Kumar
+ * @author Yogesh Mahajan
+ * @author Kishor Bachhav
+ *
+ */
+public class RemoteLocatorResponse implements DataSerializableFixedID{
+
+  private Set<String> locators ;
+
+  /** Used by DataSerializer */
+  public RemoteLocatorResponse() {
+    super();
+  }
+  
+  public RemoteLocatorResponse(Set<String> locators) {
+    this.locators = locators;
+  }
+  
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.locators = DataSerializer.readObject(in);
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    DataSerializer.writeObject(this.locators, out);
+  }
+
+  public Set<String> getLocators() {
+    return this.locators;
+  }
+  
+  @Override
+  public String toString() {
+    return "RemoteLocatorResponse{locators=" + locators +"}";
+  }
+
+  public int getDSFID() {
+    return DataSerializableFixedID.REMOTE_LOCATOR_RESPONSE;
+  }
+
+  @Override
+  public Version[] getSerializationVersions() {
+     return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/package.html
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/package.html b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/package.html
new file mode 100644
index 0000000..28abb54
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/package.html
@@ -0,0 +1,47 @@
+<HTML>
+<BODY>
+
+<P>
+
+<CENTER>
+<IMG SRC="doc-files/client_static_diagram.png"
+     />
+     <h3> Static Architecture Overview </h3>
+</CENTER>
+</P>
+
+<h2> ServerRegionProxy </h2>
+
+Classes in this package implement the client code for gemfire clients. Product code accesses the client API through the Server*Proxy classes. For example, when a LocalRegion is configured to use a connection pool, it will create a ServerRegionProxy to perform region operations on the server.
+
+<h2> Operations </h2>
+The ServerRegionProxy delegates to Operation classes to do the actual work. Each operation is responsible for sending and receiving the response for a single client operation, for example PutOp sends one put.
+
+<h2> PoolImpl and OpExecutorIml </h2>
+Operations are performed on the PoolImpl. The pool impl class has methods, such as execute(Op) which will retry the operation a configurable number of times one different servers until it succeeds. Those methods are actually implemented in OpExecutorImpl
+
+<h2> ConnectionManager </h2>
+
+The ConnectionManagerImpl class owns the client to server connections. It creates new connections (using a connection factory and connection source) and allows the pool to check out/check in connections. It keeps track of the maximum and minimum number of connections allowed, and the idle timeout for connections.
+
+<CENTER>
+<IMG SRC="doc-files/ConnectionManagerImpl.png"
+     />
+     <h3> Connection Manager Static Diagram </h3>
+</CENTER>
+
+<h2> QueueManager </h2>
+
+The ConnectionManagerImpl class owns the server to client connections. It creates new server to client connections (using a connection factory and connection source). It's responsible for maintaing the redundancy of the connections, and recovering interest on new connections.
+
+<CENTER>
+<IMG SRC="doc-files/QueueManagerImpl.png"
+     />
+     <h3> Connection Manager Static Diagram </h3>
+</CENTER>
+
+<h2> ConnectionSource </h2>
+The connection source is the logic that decides which server to create a connection to. There are two modes right now, auto and explicit. Auto uses the locators to discover servers and route to the least loaded server. Explicit allows the user to configure an explicit list of endpoints.
+
+</BODY>
+</HTML>

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/pooling/ConnectionDestroyedException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/pooling/ConnectionDestroyedException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/pooling/ConnectionDestroyedException.java
new file mode 100644
index 0000000..b537bc3
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/pooling/ConnectionDestroyedException.java
@@ -0,0 +1,39 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.pooling;
+
+import com.gemstone.gemfire.GemFireException;
+
+/**
+ * Indicates that the current connection has already been destroyed.
+ * This exception should not propagate all the way back to the 
+ * user, but is a signal to retry an attempt.
+ * @author dsmith
+ *
+ */
+public class ConnectionDestroyedException extends GemFireException {
+private static final long serialVersionUID = -6918516787578041316L;
+
+  public ConnectionDestroyedException() {
+    super();
+  }
+
+  public ConnectionDestroyedException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  public ConnectionDestroyedException(String message) {
+    super(message);
+  }
+
+  public ConnectionDestroyedException(Throwable cause) {
+    super(cause);
+  }
+
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/pooling/ConnectionManager.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/pooling/ConnectionManager.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/pooling/ConnectionManager.java
new file mode 100644
index 0000000..dbaab41
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/pooling/ConnectionManager.java
@@ -0,0 +1,123 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal.pooling;
+
+import java.util.Set;
+
+import java.util.concurrent.ScheduledExecutorService;
+import com.gemstone.gemfire.cache.client.AllConnectionsInUseException;
+import com.gemstone.gemfire.cache.client.NoAvailableServersException;
+import com.gemstone.gemfire.cache.client.internal.Connection;
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+
+/**
+ * A pool for managing client to server connections. This interface
+ * allows connections to be checked out and checked in, and keeps
+ * the number of connections within the min and max boundaries. 
+ * @author dsmith
+ * @since 5.7
+ *
+ */
+public interface ConnectionManager {
+
+  /**
+   * Borrow an existing idle connection or create a new one.
+   * 
+   * @param aquireTimeout
+   *                The amount of time to wait for a connection to become
+   *                available.
+   * @return A connection to use.
+   * @throws AllConnectionsInUseException
+   *                 If the maximum number of connections are already in use and
+   *                 no connection becomes free within the aquireTimeout.
+   * @throws NoAvailableServersException
+   *                 if we can't connect to any server
+   */
+  Connection borrowConnection(long aquireTimeout)
+      throws AllConnectionsInUseException, NoAvailableServersException;
+
+  /**
+   * Borrow an existing idle connection or create a new one to a specific server.
+   *
+   * @param server  The server the connection needs to be to.
+   * @param aquireTimeout
+   *                The amount of time to wait for a connection to become
+   *                available.
+   * @return A connection to use.
+   * @throws AllConnectionsInUseException
+   *                 If the maximum number of connections are already in use and
+   *                 no connection becomes free within the aquireTimeout.
+   * @throws NoAvailableServersException
+   *                 if we can't connect to any server
+   * 
+   */
+  Connection borrowConnection(ServerLocation server, long aquireTimeout,boolean onlyUseExistingCnx)
+      throws AllConnectionsInUseException, NoAvailableServersException;
+
+  /**
+   * Return a connection to the pool. The connection should not be
+   * used after it is returned.
+   * @param connection the connection to return
+   */
+  void returnConnection(Connection connection);
+
+  /**
+   * Return a connection to the pool. The connection should not be
+   * used after it is returned.
+   * @param connection the connection to return
+   * @param accessed if true then the connection was accessed
+   */
+  void returnConnection(Connection connection, boolean accessed);
+
+  /**
+   * Start the idle expiration for the pool and prefill the pool.
+   */
+  void start(ScheduledExecutorService backgroundProcessor);
+
+  /**
+   * Shutdown the pool.
+   * 
+   * @param keepAlive
+   *                whether to signal to servers to keep the connection alive
+   */
+  void close(boolean keepAlive);
+
+  /**
+   * Exchange one connection for a new connection to a different server.
+   * 
+   * @param conn
+   *                connection to exchange. It will be returned to the pool (or
+   *                destroyed if it has been invalidated).
+   * @param excludedServers
+   *                servers to exclude when looking for a new connection
+   * @return a new connection to the pool to a server that is not in the list of
+   *         excluded servers
+   * @throws AllConnectionsInUseException
+   */
+  Connection exchangeConnection(Connection conn,
+      Set/* <ServerLocation> */excludedServers, long aquireTimeout)
+      throws AllConnectionsInUseException;
+
+  /**
+   * Test hook to find out current number of connections this manager has.
+   */
+  public int getConnectionCount();
+
+  void emergencyClose();
+
+  /**
+   * Used to active a thread local connection
+   */
+  public void activate(Connection conn);
+  /**
+   * Used to passivate a thread local connection
+   */
+  public void passivate(Connection conn, boolean accessed);
+
+  public Connection getConnection(Connection conn);
+}


[32/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/GemFireHealthJmxImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/GemFireHealthJmxImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/GemFireHealthJmxImpl.java
new file mode 100644
index 0000000..0230d71
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/GemFireHealthJmxImpl.java
@@ -0,0 +1,170 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.modelmbean.ModelMBean;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.admin.AdminException;
+import com.gemstone.gemfire.admin.DistributedSystemHealthConfig;
+import com.gemstone.gemfire.admin.GemFireHealthConfig;
+import com.gemstone.gemfire.admin.RuntimeAdminException;
+import com.gemstone.gemfire.admin.internal.GemFireHealthImpl;
+import com.gemstone.gemfire.internal.admin.GfManagerAgent;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+//import org.apache.commons.modeler.ManagedBean;
+
+/**
+ * The JMX "managed resource" that represents the health of GemFire.
+ * Basically, it provides the behavior of
+ * <code>GemFireHealthImpl</code>, but does some JMX stuff like
+ * registering beans with the agent.
+ *
+ * @see AdminDistributedSystemJmxImpl#createGemFireHealth
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ */
+public class GemFireHealthJmxImpl extends GemFireHealthImpl 
+  implements ManagedResource {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  /** The name of the MBean that will manage this resource */
+  private String mbeanName;
+
+  /** The ModelMBean that is configured to manage this resource */
+  private ModelMBean modelMBean;
+
+  /** The object name of the MBean created for this managed resource */
+  private final ObjectName objectName;
+
+  ///////////////////////  Constructors  ///////////////////////
+
+  /**
+   * Creates a new <code>GemFireHealthJmxImpl</code> that monitors the
+   * health of the given distributed system and uses the given JMX
+   * agent. 
+   */
+  GemFireHealthJmxImpl(GfManagerAgent agent,
+                       AdminDistributedSystemJmxImpl system)
+    throws AdminException {
+
+    super(agent, system);
+    this.mbeanName = new StringBuffer()
+      .append(MBEAN_NAME_PREFIX)
+      .append("GemFireHealth,id=")
+      .append(MBeanUtil.makeCompliantMBeanNameProperty(system.getId()))
+      .toString();
+    this.objectName = MBeanUtil.createMBean(this);
+  }
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  public String getHealthStatus() {
+    return getHealth().toString();
+  }
+  
+  public ObjectName manageGemFireHealthConfig(String hostName)
+  throws MalformedObjectNameException {
+    try {
+      GemFireHealthConfig config = getGemFireHealthConfig(hostName);
+      GemFireHealthConfigJmxImpl jmx = (GemFireHealthConfigJmxImpl) config;
+      return new ObjectName(jmx.getMBeanName());
+    } //catch (AdminException e) { logWriter.warning(e); throw e; }
+    catch (RuntimeException e) { 
+      logger.warn(e.getMessage(), e); 
+      throw 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 (Error 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();
+      logger.error(e.getMessage(), e);
+      throw e; 
+    }
+  }
+    
+  /**
+   * Creates a new {@link DistributedSystemHealthConfigJmxImpl}
+   */
+  @Override
+  protected DistributedSystemHealthConfig
+    createDistributedSystemHealthConfig() {
+
+    try {
+      return new DistributedSystemHealthConfigJmxImpl(this);
+
+    } catch (AdminException ex) {
+      throw new RuntimeAdminException(LocalizedStrings.GemFireHealthJmxImpl_WHILE_GETTING_THE_DISTRIBUTEDSYSTEMHEALTHCONFIG.toLocalizedString(), ex);
+    }
+  }
+
+  /**
+   * Creates a new {@link GemFireHealthConfigJmxImpl}
+   */
+  @Override
+  protected GemFireHealthConfig
+    createGemFireHealthConfig(String hostName) {
+
+    try {
+      return new GemFireHealthConfigJmxImpl(this, hostName);
+
+    } catch (AdminException ex) {
+      throw new RuntimeAdminException(LocalizedStrings.GemFireHealthJmxImpl_WHILE_GETTING_THE_GEMFIREHEALTHCONFIG.toLocalizedString(), ex);
+    }
+  }
+
+  /**
+   * Ensures that the three primary Health MBeans are registered and returns
+   * their ObjectNames. 
+   */
+  protected void ensureMBeansAreRegistered() {
+    MBeanUtil.ensureMBeanIsRegistered(this);
+    MBeanUtil.ensureMBeanIsRegistered((ManagedResource)this.defaultConfig);
+    MBeanUtil.ensureMBeanIsRegistered((ManagedResource)this.dsHealthConfig);
+  }
+  
+  public String getMBeanName() {
+    return this.mbeanName;
+  }
+  
+  public ModelMBean getModelMBean() {
+    return this.modelMBean;
+  }
+
+  public void setModelMBean(ModelMBean modelMBean) {
+    this.modelMBean = modelMBean;
+  }
+
+  public ManagedResourceType getManagedResourceType() {
+    return ManagedResourceType.GEMFIRE_HEALTH;
+  }
+
+  public ObjectName getObjectName() {
+    return this.objectName;
+  }
+
+  public void cleanupResource() {
+    close();
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/GenerateMBeanHTML.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/GenerateMBeanHTML.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/GenerateMBeanHTML.java
new file mode 100644
index 0000000..5124b58
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/GenerateMBeanHTML.java
@@ -0,0 +1,505 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import com.gemstone.gemfire.internal.ClassPathLoader;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import org.xml.sax.*;
+import org.xml.sax.helpers.DefaultHandler;
+import java.io.*;
+//import java.util.*;
+
+/**
+ * A tool that reads the XML description of MBeans used with the
+ * Jakarta Commons Modeler and generates an HTML file that documents
+ * each MBean.
+ *
+ * @author David Whitlock
+ * @since 3.5
+ */
+public class GenerateMBeanHTML extends DefaultHandler {
+
+  /** The location of the DTD for the MBean descriptions */
+  private static final String DTD_LOCATION =
+    "/com/gemstone/gemfire/admin/jmx/internal/doc-files/mbeans-descriptors.dtd";
+
+//  /** The system id of MBean description's DTD */
+//  private static final String SYSTEM_ID = 
+//    "http://jakarta.apache.org/commons/dtds/mbeans-descriptors.dtd";
+
+//  /** The public id for the DTD */
+//  private static final String PUBLIC_ID =
+//    "-//Apache Software Foundation//DTD Model MBeans Configuration File";
+
+  /** The name of the "mbean-descriptors" element */
+  private static final String MBEANS_DESCRIPTORS = "mbeans-descriptors";
+
+  /** The name of the "mbean" element */
+  private static final String MBEAN = "mbean";
+
+  /** The name of the "name" attribute */
+  private static final String NAME = "name";
+
+  /** The name of the "description" attribute */
+  private static final String DESCRIPTION = "description";
+
+  /** The name of the "type" attribute */
+  private static final String TYPE = "type";
+
+  /** The name of the "attribute" element */
+  private static final String ATTRIBUTE = "attribute";
+
+  /** The name of the "writeable" attribute */
+  private static final String WRITEABLE = "writeable";
+
+  /** The name of the "operation" element */
+  private static final String OPERATION = "operation";
+
+  /** The name of the "returnType" attribute */
+  private static final String RETURN_TYPE = "returnType";
+
+  /** The name of the "paremeter" element */
+  private static final String PARAMETER = "parameter";
+
+  /** The name of the "notification" element */
+  private static final String NOTIFICATION = "notification";
+
+//  /** The name of the "description" element */
+//  private static final String DESCRIPTOR = "descriptor";
+
+  /** The name of the "field" element */
+  private static final String FIELD = "field";
+
+  /** The name of the "value" attribute */
+  private static final String VALUE = "value";
+
+  //////////////////////  Instance Fields  ///////////////////////
+
+  /** Where the generated HTML data is written */
+  private PrintWriter pw;
+
+  /** Have we seen attributes for the current MBean? */
+  private boolean seenAttribute = false;
+
+  /** Have we seen operations for the current MBean? */
+  private boolean seenOperation = false;
+
+  /** Have we seen notifications for the current MBean? */
+  private boolean seenNotifications = false;
+
+  ///////////////////////  Static Methods  ///////////////////////
+
+  /**
+   * Converts data from the given <code>InputStream</code> into HTML
+   * that is written to the given <code>PrintWriter</code>
+   */
+  private static void convert(InputStream in, PrintWriter out) 
+    throws Exception {
+
+    SAXParserFactory factory = SAXParserFactory.newInstance();
+    factory.setValidating(true);
+    SAXParser parser = factory.newSAXParser();
+    DefaultHandler handler = new GenerateMBeanHTML(out);
+    parser.parse(in, handler);
+  }
+
+  ////////////////////////  Constructors  ////////////////////////
+
+  /**
+   * Creates a new <code>GenerateMBeanHTML</code> that writes to the
+   * given <code>PrintWriter</code>.
+   */
+  private GenerateMBeanHTML(PrintWriter pw) {
+    this.pw = pw;
+  }
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  /**
+   * Given a public id, attempt to resolve it to a DTD.  Returns an
+   * <code>InputSoure</code> for the DTD.
+   */
+  @Override
+  public InputSource resolveEntity(String publicId, String systemId) 
+    throws SAXException {
+
+    if (publicId == null || systemId == null) {
+      throw new SAXException(LocalizedStrings.GenerateMBeanHTML_PUBLIC_ID_0_SYSTEM_ID_1.toLocalizedString(new Object[] {publicId, systemId}));
+    }
+
+    // Figure out the location for the publicId.
+    String location = DTD_LOCATION;
+
+    InputSource result;
+//    if (location != null) (cannot be null) 
+    {
+      InputStream stream = ClassPathLoader.getLatest().getResourceAsStream(getClass(), location);
+      if (stream != null) {
+        result = new InputSource(stream);
+      } else {
+        throw new SAXNotRecognizedException(LocalizedStrings.GenerateMBeanHTML_DTD_NOT_FOUND_0.toLocalizedString(location));
+      }
+
+//    } else {
+//      throw new SAXNotRecognizedException(LocalizedStrings.GenerateMBeanHTML_COULD_NOT_FIND_DTD_FOR_0_1.toLocalizedString(new Object[] {publicId, systemId}));
+    }
+
+    return result;
+  }
+
+  /**
+   * Warnings are ignored
+   */
+  @Override
+  public void warning(SAXParseException ex) throws SAXException { 
+
+  }
+
+  /**
+   * Rethrow the <code>SAXParseException</code>
+   */
+  @Override
+  public void error(SAXParseException ex) throws SAXException {
+    throw ex;
+  }
+  
+  /**
+   * Rethrow the <code>SAXParseException</code>
+   */
+  @Override
+  public void fatalError(SAXParseException ex) throws SAXException {
+    throw ex;
+  }
+  
+  /**
+   * Starts the HTML document
+   */
+  private void startMBeansDescriptors() {
+    pw.println("<HTML>");
+    pw.println("<HEAD>");
+    pw.println("<TITLE>GemFire MBeans Interface</TITLE>");
+    pw.println("</HEAD>");
+    pw.println("");
+    pw.println("<h1>GemFire Management Beans</h1>");
+    pw.println("");
+    pw.println("<P>This document describes the attributes, operations,"); 
+    pw.println("and notifications of the GemFire Administration");
+    pw.println("Management Beans (MBeans).</P>"); 
+    pw.println("");
+  }
+
+  /**
+   * Ends the HTML document
+   */
+  private void endMBeansDescriptors() {
+    pw.println("</HTML>");
+  }
+
+  /**
+   * Generates a heading and a table declaration for an MBean
+   */
+  private void startMBean(Attributes atts) {
+    String name = atts.getValue(NAME);
+    /*String description =*/ atts.getValue(DESCRIPTION);
+    pw.println("<h2><b>" + name + "</b> MBean</h2>");
+    pw.println("<table border=\"0\" cellpadding=\"3\">");
+    pw.println("<tr valign=\"top\">");
+    pw.println("  <th align=\"left\">Description:</th>");
+    pw.println("  <td colspan=\"4\">GemFire distributed system</td>");
+    pw.println("</tr>");
+  }
+
+  /**
+   * Ends the MBean table
+   */
+  private void endMBean() {
+    this.seenAttribute = false;
+    this.seenOperation = false;
+    this.seenNotifications = false;
+
+    pw.println("</table>");
+    pw.println("");
+
+    pw.println("<P></P>");
+    pw.println("");
+  }
+
+  /**
+   * Generates a table row for an MBean attribute
+   */
+  private void startAttribute(Attributes atts) {
+    if (!this.seenAttribute) {
+      // Print header row
+      pw.println("<tr valign=\"top\">");
+      pw.println("  <th align=\"left\">Attributes</th>");
+      pw.println("  <th align=\"left\" colspan=\"2\">Name</th>");
+      pw.println("  <th align=\"left\">Type</th>");
+      pw.println("  <th align=\"left\">Description</th>");
+      pw.println("  <th align=\"left\">Writable</th>");
+      pw.println("</tr>");
+
+    }
+
+    this.seenAttribute = true;
+
+    String name = atts.getValue(NAME);
+    String description = atts.getValue(DESCRIPTION);
+    String type = atts.getValue(TYPE);
+    String writeable = atts.getValue(WRITEABLE);
+
+    pw.println("<tr valign=\"top\">");
+    pw.println("  <td></td>");
+    pw.println("  <td colspan=\"2\">" + name + "</td>");
+    pw.println("  <td>" + type + "</td>");
+    pw.println("  <td>" + description + "</td>");
+    pw.println("  <td>" + writeable + "</td>");
+    pw.println("</tr>");
+  }
+
+  /**
+   * Generates a table row for an MBean operation
+   */
+  private void startOperation(Attributes atts) {
+    if (!this.seenOperation) {
+      if (!this.seenAttribute) {
+        pw.println("<tr valign=\"top\">");
+        pw.println("  <th align=\"left\">Operations</th>");
+        pw.println("  <th align=\"left\" colspan=\"2\">Name</th>");
+        pw.println("  <th align=\"left\">Type</th>");
+        pw.println("  <th align=\"left\">Description</th>");
+        pw.println("  <th align=\"left\"></th>");
+        pw.println("</tr>");
+
+      } else {
+      String title = "Operations and Parameters";
+        pw.println("<tr valign=\"top\">");
+        pw.println("  <th align=\"left\" colspan=\"6\">" + title + "</th>");
+        pw.println("</tr>");
+      }
+    }
+
+    this.seenOperation = true;
+
+    String name = atts.getValue(NAME);
+    String type = atts.getValue(RETURN_TYPE);
+    String description = atts.getValue(DESCRIPTION);
+
+    pw.println("<tr valign=\"top\">");
+    pw.println("  <td></td>");
+    pw.println("  <td colspan=\"2\">" + name + "</td>");
+    pw.println("  <td>" + type + "</td>");
+    pw.println("  <td colspan=\"2\">" + description + "</td>");
+    pw.println("</tr>");
+    
+  }
+
+  /**
+   * Generates a table row for the parameter of an MBean operation
+   */
+  private void startParameter(Attributes atts) {
+    String name = atts.getValue(NAME);
+    String description = atts.getValue(DESCRIPTION);
+    String type = atts.getValue(TYPE);
+
+    pw.println("<tr valign=\"top\">");
+    pw.println("  <td></td>");
+    pw.println("  <td width=\"10\"></td>");
+    pw.println("  <td>" + name + "</td>");
+    pw.println("  <td>" + type + "</td>");
+    pw.println("  <td colspan=\"2\">" + description + "</td>");
+    pw.println("</tr>");
+  }
+
+  /**
+   * Generates a row in a table for an MBean notification
+   */
+  private void startNotification(Attributes atts) {
+    if (!this.seenNotifications) {
+      if (!this.seenAttribute && !this.seenOperation) {
+        pw.println("<tr valign=\"top\">");
+        pw.println("  <th align=\"left\">Notifications</th>");
+        pw.println("  <th align=\"left\" colspan=\"2\">Name</th>");
+        pw.println("  <th align=\"left\">Type</th>");
+        pw.println("  <th align=\"left\">Description</th>");
+        pw.println("  <th align=\"left\"></th>");
+        pw.println("</tr>");
+        pw.println("</tr>");
+
+      } else {
+        pw.println("<tr valign=\"top\">");
+        pw.println("  <th align=\"left\" colspan=\"6\">Notifications and Fields</th>");
+        pw.println("</tr>");
+      }
+    }
+
+    this.seenNotifications = true;
+
+    String name = atts.getValue(NAME);
+    String description = atts.getValue(DESCRIPTION);
+    
+    pw.println("<tr valign=\"top\">");
+    pw.println("  <td></td>");
+    pw.println("  <td colspan=\"3\">" + name + "</td>");
+    pw.println("  <td colspan=\"3\">" + description + "</td>");
+    pw.println("</tr>");
+    
+  }
+
+  /**
+   * Generates a table row for a descriptor field
+   */
+  private void startField(Attributes atts) {
+    String name = atts.getValue(NAME);
+    String value = atts.getValue(VALUE);
+
+    pw.println("<tr valign=\"top\">");
+    pw.println("  <td></td>");
+    pw.println("  <td width=\"10\"></td>");
+    pw.println("  <td colspan=\"2\">" + name + "</td>");
+    pw.println("  <td colspan=\"2\">" + value + "</td>");
+    pw.println("</tr>");
+    
+  }
+
+  @Override
+  public void startElement(String namespaceURI, String localName,
+                           String qName, Attributes atts)
+    throws SAXException {
+
+    if (qName.equals(MBEANS_DESCRIPTORS)) {
+      startMBeansDescriptors();
+
+    } else if (qName.equals(MBEAN)) {
+      startMBean(atts);
+
+    } else if (qName.equals(ATTRIBUTE)) {
+      startAttribute(atts);
+
+    } else if (qName.equals(OPERATION)) {
+      startOperation(atts);
+
+    } else if (qName.equals(PARAMETER)) {
+      startParameter(atts);
+
+    } else if (qName.equals(NOTIFICATION)) {
+      startNotification(atts);
+
+    } else if (qName.equals(FIELD)) {
+      startField(atts);
+    }
+
+  }
+
+
+  @Override
+  public void endElement(String namespaceURI, String localName,
+                         String qName)
+    throws SAXException {
+
+    if (qName.equals(MBEANS_DESCRIPTORS)) {
+      endMBeansDescriptors();
+
+    } else if (qName.equals(MBEAN)) {
+      endMBean();
+    }
+
+  }
+
+  //////////  Inherited methods that don't do anything  //////////
+
+  @Override
+  public void characters(char[] ch, int start, int length)
+    throws SAXException {
+
+  }
+
+  @Override
+  public void setDocumentLocator(Locator locator) { }
+
+  @Override
+  public void startDocument() throws SAXException { }
+
+  @Override
+  public void endDocument() throws SAXException { }
+
+  @Override
+  public void startPrefixMapping(String prefix, String uri) 
+    throws SAXException { }
+
+  @Override
+  public void endPrefixMapping(String prefix)
+    throws SAXException { }
+
+  @Override
+  public void ignorableWhitespace(char[] ch, int start, int length)
+    throws SAXException { }
+
+  @Override
+  public void processingInstruction(String target, String data)
+    throws SAXException { }
+
+  @Override
+  public void skippedEntity(String name) throws SAXException { }
+
+  ////////////////////////  Main Program  ////////////////////////
+
+//  private static final PrintStream out = System.out;
+  private static final PrintStream err = System.err;
+
+  /**
+   * Prints usage information about this program
+   */
+  private static void usage(String s) {
+    err.println("\n** " + s + "\n");
+    err.println("usage: java GenerateMBeanHTML xmlFile htmlFile");
+    err.println("");
+    err.println("Converts an MBeans description XML file into an HTML");
+    err.println("file suitable for documentation");
+
+    err.println("");
+
+    System.exit(1);
+  }
+
+  public static void main(String[] args) throws Exception {
+    String xmlFileName = null;
+    String htmlFileName = null;
+
+    for (int i = 0; i < args.length; i++) {
+      if (xmlFileName == null) {
+        xmlFileName = args[i];
+
+      } else if (htmlFileName == null) {
+        htmlFileName = args[i];
+
+      } else {
+        usage("Extraneous command line argument: " + args[i]);
+      }
+    }
+
+    if (xmlFileName == null) {
+      usage("Missing XML file name");
+
+    } else if (htmlFileName == null) {
+      usage("Missing HTML file name");
+    }
+
+    File xmlFile = new File(xmlFileName);
+    if (!xmlFile.exists()) {
+      usage("XML file \"" + xmlFile + "\" does not exist");
+    }
+
+    File htmlFile = new File(htmlFileName);
+    convert(new FileInputStream(xmlFile),
+            new PrintWriter(new FileWriter(htmlFile), true));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MBeanUtil.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MBeanUtil.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MBeanUtil.java
new file mode 100755
index 0000000..b580af5
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MBeanUtil.java
@@ -0,0 +1,761 @@
+/*
+ *  =========================================================================
+ *  Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *  ========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import java.net.URL;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.JMException;
+import javax.management.JMRuntimeException;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MBeanServerNotification;
+import javax.management.MalformedObjectNameException;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.timer.TimerMBean;
+
+import org.apache.commons.modeler.ManagedBean;
+import org.apache.commons.modeler.Registry;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.LogWriter;
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.admin.RuntimeAdminException;
+import com.gemstone.gemfire.admin.internal.AdminDistributedSystemImpl;
+import com.gemstone.gemfire.internal.ClassPathLoader;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.InternalLogWriter;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * Common support for MBeans and {@link ManagedResource}s.  Static loading of
+ * this class creates the MBeanServer and Modeler Registry.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ */
+public class MBeanUtil {
+  
+  private static final Logger logger = LogService.getLogger();
+  
+  /** The default MBeanServer domain name is "GemFire" */
+  private static final String DEFAULT_DOMAIN = "GemFire";
+
+  /** MBean Name for refreshTimer */
+  private static String REFRESH_TIMER_NAME = DEFAULT_DOMAIN + ":type=RefreshTimer";
+  
+  /* indicates whether the mbeanServer, registry & refreshTimer are started */
+  private static boolean isStarted;
+  
+  /** The Commons-Modeler configuration registry for our managed beans */
+  private static Registry registry;
+
+  /** The <code>MBeanServer</code> for this application */
+  private static MBeanServer mbeanServer;
+    
+  /** MBean name of the Timer which handles refresh notifications */
+  private static ObjectName refreshTimerObjectName;
+  
+  /** Actual TimerMBean responsible for refresh notifications */
+  private static TimerMBean refreshTimer;
+  
+  /** 
+   * Map of ObjectNames to current timerNotificationIds
+   * <p>
+   * map: key=ObjectName, 
+   *      value=map: key=RefreshNotificationType,
+   *                 value=timerNotificationId
+   */
+  private static Map<NotificationListener, Map<RefreshNotificationType, Integer>> refreshClients = new HashMap<NotificationListener, Map<RefreshNotificationType, Integer>>();
+  
+  /** key=ObjectName, value=ManagedResource */
+  private final static Map<ObjectName, ManagedResource> managedResources = new HashMap<ObjectName, ManagedResource>();
+
+  static {
+    try {
+      refreshTimerObjectName = ObjectName.getInstance(REFRESH_TIMER_NAME);
+    } catch (Exception e) {
+      logStackTrace(Level.ERROR, e);
+    }
+  }
+  
+  /**
+   * Initializes Mbean Server, Registry, Refresh Timer & registers Server 
+   * Notification Listener.
+   * 
+   * @return reference to the mbeanServer
+   */
+  static MBeanServer start() {
+    if (!isStarted) {
+      mbeanServer = createMBeanServer();
+      registry    = createRegistry();
+      
+      registerServerNotificationListener();
+      createRefreshTimer();
+      isStarted = true;
+    }
+
+    return mbeanServer;
+  }
+  
+  /**
+   * Stops Registry, Refresh Timer. Releases Mbean Server after.
+   */
+  static void stop() {
+    if (isStarted) {
+      stopRefreshTimer();
+      
+      registry.stop();
+      registry = null;
+      releaseMBeanServer();//makes mbeanServer null
+      isStarted = false;
+    }
+  }
+
+  /**
+   * Create and configure (if necessary) and return the <code>MBeanServer</code> 
+   * with which we will be registering our <code>ModelMBean</code> 
+   * implementations.
+   *
+   * @see javax.management.MBeanServer
+   */
+  static synchronized MBeanServer createMBeanServer() {
+    if (mbeanServer == null) {
+      mbeanServer = MBeanServerFactory.createMBeanServer(DEFAULT_DOMAIN);
+    }
+    return mbeanServer;
+  }
+
+  /**
+   * Create and configure (if necessary) and return the Commons-Modeler registry 
+   * of managed object descriptions.
+   *
+   * @see org.apache.commons.modeler.Registry
+   */
+  static synchronized Registry createRegistry() {
+    if (registry == null) {
+      try {
+        registry = Registry.getRegistry(null, null);
+        if (mbeanServer == null) {
+          throw new IllegalStateException(LocalizedStrings.MBeanUtil_MBEAN_SERVER_NOT_INITIALIZED_YET.toLocalizedString());
+        }
+        registry.setMBeanServer(mbeanServer);
+  
+        String mbeansResource = getOSPath("/com/gemstone/gemfire/admin/jmx/mbeans-descriptors.xml");
+        //System.out.println(LocalizedStrings.MBeanUtil_LOADING_RESOURCE_0.toLocalizedString(mbeansResource));
+        
+        URL url = ClassPathLoader.getLatest().getResource(MBeanUtil.class, mbeansResource);
+        raiseOnFailure(url != null, 
+            LocalizedStrings.MBeanUtil_FAILED_TO_FIND_0.toLocalizedString(new Object[] {mbeansResource}));
+        registry.loadMetadata(url);
+        
+        // simple test to make sure the xml was actually loaded and is valid...
+        String[] test = registry.findManagedBeans();
+        raiseOnFailure(test != null && test.length > 0,
+            LocalizedStrings.MBeanUtil_FAILED_TO_LOAD_0.toLocalizedString(new Object[] {mbeansResource}));
+      } catch (Exception e) {
+        logStackTrace(Level.WARN, e);
+        throw new RuntimeAdminException(LocalizedStrings.MBeanUtil_FAILED_TO_GET_MBEAN_REGISTRY.toLocalizedString(), e);
+      }
+    }
+    return registry;
+  }
+
+  /**
+   * Creates and registers a <code>ModelMBean</code> for the specified
+   * <code>ManagedResource</code>. State changing callbacks into the 
+   * <code>ManagedResource</code> will also be made.
+   *
+   * @param resource
+   *        the ManagedResource to create a managing MBean for
+   *
+   * @return The object name of the newly-created MBean
+   *
+   * @see ManagedResource#setModelMBean
+   */
+  static ObjectName createMBean(ManagedResource resource) {
+    return createMBean(resource, lookupManagedBean(resource));
+  }
+  
+  /**
+   * Creates and registers a <code>ModelMBean</code> for the specified
+   * <code>ManagedResource</code>. State changing callbacks into the 
+   * <code>ManagedResource</code> will also be made.
+   *
+   * @param resource the ManagedResource to create a managing MBean for
+   * @param managed  the ManagedBean definition to create the MBean with
+   * @see ManagedResource#setModelMBean
+   */
+  static ObjectName createMBean(ManagedResource resource, ManagedBean managed) {
+
+    try {
+      DynamicManagedBean mb = new DynamicManagedBean(managed);
+      resource.setModelMBean(mb.createMBean(resource));
+      
+      // create the ObjectName and register the MBean...
+      final ObjectName objName;
+      try {
+        objName = ObjectName.getInstance(resource.getMBeanName());
+      } catch (MalformedObjectNameException e) {
+        throw new MalformedObjectNameException(LocalizedStrings.MBeanUtil_0_IN_1.toLocalizedString(new Object[] { e.getMessage(), resource.getMBeanName()} ) );
+      }
+
+      synchronized (MBeanUtil.class) {
+        // Only register a bean once.  Otherwise, you risk race
+        // conditions with things like the RMI connector accessing it.
+
+        if (mbeanServer != null && !mbeanServer.isRegistered(objName)) {
+          mbeanServer.registerMBean(resource.getModelMBean(), objName);
+          synchronized (managedResources) {
+            managedResources.put(objName, resource);
+          }
+        }
+      }
+      return objName;
+    } catch (java.lang.Exception e) {
+      throw new RuntimeAdminException(LocalizedStrings.MBeanUtil_FAILED_TO_CREATE_MBEAN_FOR_0.toLocalizedString(new Object[]{resource.getMBeanName()}), e);
+    }
+  }
+  
+  /**
+   * Ensures that an MBean is registered for the specified 
+   * <code>ManagedResource</code>.  If an MBean cannot be found in the
+   * <code>MBeanServer</code>, then this creates and registers a 
+   * <code>ModelMBean</code>. State changing callbacks into the 
+   * <code>ManagedResource</code> will also be made.
+   *
+   * @param resource
+   *        the ManagedResource to create a managing MBean for
+   *
+   * @return The object name of the MBean that manages the ManagedResource
+   *
+   * @see ManagedResource#setModelMBean
+   */
+  static ObjectName ensureMBeanIsRegistered(ManagedResource resource) {
+    try {
+      ObjectName objName = ObjectName.getInstance(resource.getMBeanName());
+      synchronized (MBeanUtil.class) {
+        if (mbeanServer != null && !mbeanServer.isRegistered(objName)) {
+          return createMBean(resource);
+        }
+      }
+      raiseOnFailure(mbeanServer.isRegistered(objName), 
+          LocalizedStrings.MBeanUtil_COULDNT_FIND_MBEAN_REGISTERED_WITH_OBJECTNAME_0.toLocalizedString(new Object[] {objName.toString()}));
+      return objName;
+    } 
+    catch (java.lang.Exception e) {
+      throw new RuntimeAdminException(e);
+    }
+  }
+  
+  /**
+   * Retrieves the <code>ManagedBean</code> configuration from the Registry for 
+   * the specified <code>ManagedResource</code>
+   *
+   * @param resource the ManagedResource to find the configuration for
+   */
+  static ManagedBean lookupManagedBean(ManagedResource resource) {
+    // find the registry defn for our MBean...
+    ManagedBean managed = null;
+    if (registry != null) {
+      managed = registry.findManagedBean(
+          resource.getManagedResourceType().getClassTypeName());
+    } else {
+      throw new IllegalArgumentException(LocalizedStrings.MBeanUtil_MANAGEDBEAN_IS_NULL.toLocalizedString());
+    }
+    
+    if (managed == null) {
+      throw new IllegalArgumentException(LocalizedStrings.MBeanUtil_MANAGEDBEAN_IS_NULL.toLocalizedString());
+    }
+    
+    // customize the defn...
+    managed.setClassName(
+        "com.gemstone.gemfire.admin.jmx.internal.MX4JModelMBean");
+
+    return managed;
+  }
+
+  /**
+   * Registers a refresh notification for the specified client MBean.  
+   * Specifying zero for the refreshInterval disables notification for the 
+   * refresh client. Note: this does not currently support remote connections.
+   *
+   * @param client          client to listen for refresh notifications
+   * @param userData        userData to register with the Notification 
+   * @param type            refresh notification type the client will use
+   * @param refreshInterval the seconds between refreshes
+   */
+  static void registerRefreshNotification(NotificationListener client, 
+                                          Object userData, 
+                                          RefreshNotificationType type,
+                                          int refreshInterval) {
+    if (client == null) {
+      throw new IllegalArgumentException(LocalizedStrings.MBeanUtil_NOTIFICATIONLISTENER_IS_REQUIRED.toLocalizedString());
+    }
+    if (type == null) {
+      throw new IllegalArgumentException(LocalizedStrings.MBeanUtil_REFRESHNOTIFICATIONTYPE_IS_REQUIRED.toLocalizedString());
+    }
+    if (refreshTimerObjectName == null || refreshTimer == null) {
+      throw new IllegalStateException(LocalizedStrings.MBeanUtil_REFRESHTIMER_HAS_NOT_BEEN_PROPERLY_INITIALIZED.toLocalizedString());
+    }
+    
+    try {
+      // get the notifications for the specified client...
+      Map<RefreshNotificationType, Integer> notifications = null;
+      synchronized (refreshClients) {
+        notifications = (Map<RefreshNotificationType, Integer>) refreshClients.get(client);        
+      }
+      
+      if (notifications == null) {
+        // If refreshInterval is being set to zero and notifications is removed return
+        if (refreshInterval <= 0) {
+          return;
+        }
+        
+        // never registered before, so add client...
+        notifications = new HashMap<RefreshNotificationType, Integer>();
+        synchronized (refreshClients) {
+          refreshClients.put(client, notifications);
+        }
+        validateRefreshTimer();
+        try {
+          // register client as a listener with MBeanServer...
+          mbeanServer.addNotificationListener(
+              refreshTimerObjectName, // timer to listen to
+              client,       // the NotificationListener object
+              null,         // optional NotificationFilter TODO: convert to using
+              new Object()  // not used but null throws IllegalArgumentException
+              );
+        } catch (InstanceNotFoundException e) {
+          // should not happen since we already checked refreshTimerObjectName
+          logStackTrace(Level.WARN, e, LocalizedStrings.MBeanUtil_COULD_NOT_FIND_REGISTERED_REFRESHTIMER_INSTANCE.toLocalizedString());
+        }
+      }
+
+      // TODO: change to manipulating timer indirectly thru mserver...
+      
+      // check for pre-existing refresh notification entry...
+      Integer timerNotificationId = (Integer) notifications.get(type);
+      if (timerNotificationId != null) {
+        try {
+          // found one, so let's remove it...
+          refreshTimer.removeNotification(timerNotificationId);
+        } catch (InstanceNotFoundException e) {
+          // that's ok cause we just wanted to remove it anyway
+        } finally {
+          // null out the map entry for that notification type...
+          notifications.put(type, null);
+        }
+      }
+      
+      if (refreshInterval > 0) {
+        // add notification to the refresh timer...
+        timerNotificationId = refreshTimer.addNotification(
+            type.getType(),                   // type
+            type.getMessage(),                // message = "refresh"
+            userData,                         // userData
+            new Date(System.currentTimeMillis() + 
+                     refreshInterval * 1000), // first occurence
+            refreshInterval * 1000);          // period to repeat  
+        
+        // put an entry into the map for the listener...
+        notifications.put(type, timerNotificationId);
+      } else {
+        // do nothing!  refreshInterval must be over 0 to do anything...
+      }
+    } catch (java.lang.RuntimeException e) {
+      logStackTrace(Level.WARN, e);
+      throw 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 (java.lang.Error 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();
+      logStackTrace(Level.ERROR, e);
+      throw e;
+    }
+  }
+
+  /**
+   * Verifies a refresh notification for the specified client MBean.
+   * If notification is not registered, then returns a false
+   *
+   * @param client          client to listen for refresh notifications
+   * @param type            refresh notification type the client will use
+   *
+   * @return isRegistered   boolean indicating if a notification is registered
+   */
+  static boolean isRefreshNotificationRegistered(NotificationListener client,
+                                          RefreshNotificationType type) {
+    boolean isRegistered = false;
+
+    // get the notifications for the specified client...
+    Map<RefreshNotificationType, Integer> notifications = null;
+    synchronized(refreshClients) {
+      notifications = (Map<RefreshNotificationType, Integer>) refreshClients.get(client);
+    }
+
+    // never registered before if  null ...
+    if (notifications != null) {
+      // check for pre-existing refresh notification entry...
+      Integer timerNotificationId = notifications.get(type);
+      if (timerNotificationId != null) {
+        isRegistered = true;
+      }
+    }
+
+    return isRegistered;
+  }
+  
+  /** 
+   * Validates refreshTimer has been registered without problems and attempts 
+   * to re-register if there is a problem. 
+   */
+  static void validateRefreshTimer() {
+    if (refreshTimerObjectName == null || refreshTimer == null) {
+      //if (refreshTimerObjectName == null) System.out.println("refreshTimerObjectName is null");
+      //if (refreshTimer == null) System.out.println("refreshTimer is null");
+      //System.out.println("[validateRefreshTimer] createRefreshTimer");
+      createRefreshTimer();
+    }
+    
+    raiseOnFailure(refreshTimer != null, 
+                      "Failed to validate Refresh Timer");
+
+    if (mbeanServer != null && !mbeanServer.isRegistered(refreshTimerObjectName)) {
+      //System.out.println("[validateRefreshTimer] registerMBean");
+      try {
+        mbeanServer.registerMBean(refreshTimer, refreshTimerObjectName);
+      } catch (JMException e) { 
+        logStackTrace(Level.WARN, e); 
+  	  } catch (JMRuntimeException e) { 
+        logStackTrace(Level.WARN, e); 
+  	  }
+    }                       
+  }
+  
+  /**
+   * Initializes the timer for sending refresh notifications.
+   */
+  static void createRefreshTimer() {        
+    try {
+      refreshTimer = new javax.management.timer.Timer();
+      mbeanServer.registerMBean(refreshTimer, refreshTimerObjectName);
+            
+      refreshTimer.start();
+    } catch (JMException e) {
+      logStackTrace(Level.WARN, e, LocalizedStrings.MBeanUtil_FAILED_TO_CREATE_REFRESH_TIMER.toLocalizedString());
+    } catch (JMRuntimeException e) {
+      logStackTrace(Level.WARN, e, LocalizedStrings.MBeanUtil_FAILED_TO_CREATE_REFRESH_TIMER.toLocalizedString());
+    } catch (Exception e) {
+      logStackTrace(Level.WARN, e, LocalizedStrings.MBeanUtil_FAILED_TO_CREATE_REFRESH_TIMER.toLocalizedString());
+    }
+  }
+  
+  /**
+   * Initializes the timer for sending refresh notifications.
+   */
+  static void stopRefreshTimer() {        
+    try {
+      if (refreshTimer != null && mbeanServer != null) {
+        mbeanServer.unregisterMBean(refreshTimerObjectName);
+              
+        refreshTimer.stop();
+      }
+    } catch (JMException e) {
+      logStackTrace(Level.WARN, e);
+    } catch (JMRuntimeException e) {
+      logStackTrace(Level.WARN, e);
+    } catch (Exception e) {
+      logStackTrace(Level.DEBUG,e, "Failed to stop refresh timer for MBeanUtil");
+    }
+  }
+  
+  /**
+   * Return a String that been modified to be compliant as a property of an 
+   * ObjectName.
+   * <p>
+   * The property name of an ObjectName may not contain any of the following
+   * characters:  <b><i>:  ,  =  *  ?</i></b>
+   * <p>
+   * This method will replace the above non-compliant characters with a
+   * dash:  <b><i>-</i></b>
+   * <p>
+   * If value is empty, this method will return the string "nothing".
+   * <p>
+   * Note: this is <code>public</code> because certain tests call this from
+   * outside of the package. TODO: clean this up
+   *
+   * @param value  the potentially non-compliant ObjectName property
+   * @return the value modified to be compliant as an ObjectName property
+   */
+  public static String makeCompliantMBeanNameProperty(String value) {
+    value = value.replace(':', '-');
+    value = value.replace(',', '-');
+    value = value.replace('=', '-');
+    value = value.replace('*', '-');
+    value = value.replace('?', '-');
+    if (value.length() < 1) {
+      value = "nothing";
+    }
+    return value;
+  }
+  
+  /**
+   * Unregisters all GemFire MBeans and then releases the MBeanServer for
+   * garbage collection.
+   */
+  static void releaseMBeanServer() {
+    try {
+      // unregister all GemFire mbeans...
+      Iterator iter = mbeanServer.queryNames(null, null).iterator();
+      while (iter.hasNext()) {
+        ObjectName name = (ObjectName)iter.next();
+        if (name.getDomain().startsWith(DEFAULT_DOMAIN)) {
+          unregisterMBean(name);
+        }
+      }
+      
+      // last, release the mbean server...
+      MBeanServerFactory.releaseMBeanServer(mbeanServer);
+      mbeanServer = null;
+    } catch (JMRuntimeException e) { 
+      logStackTrace(Level.WARN, e); 
+   	} 
+	  /* See #42391. Cleaning up the static maps which might be still holding  
+	   * references to ManagedResources */ 
+	   synchronized (MBeanUtil.managedResources) { 
+	     MBeanUtil.managedResources.clear(); 
+	   } 
+	   synchronized (refreshClients) { 
+	     refreshClients.clear();
+	   }
+    /* See #42391. Cleaning up the static maps which might be still holding 
+     * references to ManagedResources */
+    synchronized (MBeanUtil.managedResources) {
+      MBeanUtil.managedResources.clear();
+    }
+    synchronized (refreshClients) {
+      refreshClients.clear();
+    }
+  }
+  
+  /**
+   * Returns true if a MBean with given ObjectName is registered.
+   * 
+   * @param objectName
+   *          ObjectName to use for checking if MBean is registered
+   * @return true if MBeanServer is not null & MBean with given ObjectName is
+   *         registered with the MBeanServer        
+   */
+  static boolean isRegistered(ObjectName objectName) {
+    return mbeanServer != null && mbeanServer.isRegistered(objectName);
+  }
+  
+  /**
+   * Unregisters the identified MBean if it's registered.
+   */
+  static void unregisterMBean(ObjectName objectName) {
+    try {
+      if (mbeanServer != null && mbeanServer.isRegistered(objectName)) {
+        mbeanServer.unregisterMBean(objectName);
+      }
+    } catch (MBeanRegistrationException e) {
+      logStackTrace(Level.WARN, null, LocalizedStrings.MBeanUtil_FAILED_WHILE_UNREGISTERING_MBEAN_WITH_OBJECTNAME_0.toLocalizedString(new Object[] {objectName}));
+    } catch (InstanceNotFoundException e) {
+      logStackTrace(Level.WARN, null, LocalizedStrings.MBeanUtil_WHILE_UNREGISTERING_COULDNT_FIND_MBEAN_WITH_OBJECTNAME_0.toLocalizedString(new Object[] {objectName}));
+    } catch (JMRuntimeException e) { 
+      logStackTrace(Level.WARN, null, LocalizedStrings.MBeanUtil_COULD_NOT_UNREGISTER_MBEAN_WITH_OBJECTNAME_0.toLocalizedString(new Object[] {objectName}));
+    }
+  }
+  static void unregisterMBean(ManagedResource resource) {
+    if (resource != null) {
+      unregisterMBean(resource.getObjectName());
+  
+      // call cleanup on managedResource here and not rely on listener
+      // since it is possible that notification listener not deliver
+      // all notifications of un-registration. If resource is 
+      // cleaned here, another call from the listener should be as good as a no-op
+      cleanupResource(resource);
+    }
+  }
+  
+  // cleanup resource
+  private static void cleanupResource(ManagedResource resource) {
+    synchronized (MBeanUtil.managedResources) {
+      MBeanUtil.managedResources.remove(resource.getObjectName());
+    }
+    resource.cleanupResource();
+
+    // get the notifications for the specified client...
+    Map<RefreshNotificationType, Integer> notifications = null;
+    synchronized (refreshClients) {
+      notifications = (Map<RefreshNotificationType, Integer>) refreshClients.remove(resource);
+    }
+
+    // never registered before if  null ...
+    // Also as of current, there is ever only 1 Notification type per 
+    // MBean, so we do need need a while loop here
+    if (notifications != null) {
+
+      // Fix for findbugs reported inefficiency with keySet().
+      Set<Map.Entry<RefreshNotificationType, Integer>> entries = notifications.entrySet();
+      
+      for(Map.Entry<RefreshNotificationType, Integer> e : entries) {
+        Integer timerNotificationId = e.getValue();
+        if(null != timerNotificationId) {
+          try {
+            // found one, so let's remove it...
+            refreshTimer.removeNotification(timerNotificationId);
+          } catch (InstanceNotFoundException xptn) {
+            // that's ok cause we just wanted to remove it anyway
+            logStackTrace(Level.DEBUG, xptn);
+          }
+        }
+      }
+      
+      try {
+        if (mbeanServer != null && mbeanServer.isRegistered(refreshTimerObjectName)) {
+          // remove client as a listener with MBeanServer...
+          mbeanServer.removeNotificationListener(
+              refreshTimerObjectName, // timer to listen to
+              (NotificationListener)resource       // the NotificationListener object
+          );
+        }
+      } catch (ListenerNotFoundException xptn) {
+        // should not happen since we already checked refreshTimerObjectName
+        logStackTrace(Level.WARN, null, xptn.getMessage());
+      } catch (InstanceNotFoundException xptn) {
+        // should not happen since we already checked refreshTimerObjectName
+        logStackTrace(Level.WARN, null, LocalizedStrings.MBeanUtil_WHILE_UNREGISTERING_COULDNT_FIND_MBEAN_WITH_OBJECTNAME_0.toLocalizedString(new Object[] {refreshTimerObjectName}));
+      }
+    }
+  }
+  
+  // ----- borrowed the following from admin.internal.RemoteCommand -----
+  /** Translates the path between Windows and UNIX. */
+  static String getOSPath(String path) {
+    if (pathIsWindows(path)) {
+      return path.replace('/', '\\');
+    } else {
+      return path.replace('\\', '/');
+    }
+  }
+
+  /** Returns true if the path is on Windows. */
+  static boolean pathIsWindows(String path) {
+    if (path != null && path.length() > 1) {
+      return (Character.isLetter(path.charAt(0)) && path.charAt(1) == ':') ||
+        (path.startsWith("//") || path.startsWith("\\\\"));
+    }
+    return false;
+  }
+
+  static void registerServerNotificationListener() {
+    if (mbeanServer == null) {
+      return;
+    }
+    try {
+      // the MBeanServerDelegate name is spec'ed as the following...
+      ObjectName delegate = ObjectName.getInstance("JMImplementation:type=MBeanServerDelegate");
+      mbeanServer.addNotificationListener(
+        delegate,
+        new NotificationListener() {
+          public void handleNotification(Notification notification, Object handback) {
+            MBeanServerNotification serverNotification = (MBeanServerNotification) notification;
+            if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(serverNotification.getType())) {
+              ObjectName objectName = serverNotification.getMBeanName();
+              synchronized (MBeanUtil.managedResources) {
+                Object entry = MBeanUtil.managedResources.get(objectName);
+                if (entry == null) return;
+                if (!(entry instanceof ManagedResource)) {
+                  throw new ClassCastException(LocalizedStrings.MBeanUtil_0_IS_NOT_A_MANAGEDRESOURCE.toLocalizedString(new Object[] {entry.getClass().getName()}));
+                }
+                ManagedResource resource = (ManagedResource) entry;
+                {
+                  // call cleanup on managedResource
+                  cleanupResource(resource);
+                }
+              }
+            }
+          }
+        }, 
+        null, null);
+    } catch (JMException e) {
+      logStackTrace(Level.WARN, e, 
+          LocalizedStrings.MBeanUtil_FAILED_TO_REGISTER_SERVERNOTIFICATIONLISTENER.toLocalizedString());
+    } catch (JMRuntimeException e) {
+      logStackTrace(Level.WARN, e, 
+          LocalizedStrings.MBeanUtil_FAILED_TO_REGISTER_SERVERNOTIFICATIONLISTENER.toLocalizedString());
+    }
+  }
+
+  /**
+   * Logs the stack trace for the given Throwable if logger is initialized else
+   * prints the stack trace using System.out.
+   * 
+   * @param level
+   *          severity level to log at
+   * @param throwable
+   *          Throwable to log stack trace for
+   */
+  public static void logStackTrace(Level level, Throwable throwable) {
+    logStackTrace(level, throwable, null);
+  }
+
+  /**
+   * Logs the stack trace for the given Throwable if logger is initialized else
+   * prints the stack trace using System.out.
+   * 
+   * @param level
+   *          severity level to log at
+   * @param throwable
+   *          Throwable to log stack trace for
+   * @param message
+   *          user friendly error message to show
+   */
+  public static void logStackTrace(Level level, Throwable throwable, 
+                                   String message) {
+    logger.log(level, message, throwable);
+  }
+
+  /**
+   * Raises RuntimeAdminException with given 'message' if given 'condition' is
+   * false.
+   * 
+   * @param condition
+   *          condition to evaluate
+   * @param message
+   *          failure message
+   */
+  private static void raiseOnFailure(boolean condition, String message) {
+    if (!condition) {
+      throw new RuntimeAdminException(message);
+    }
+  }
+}
+


[45/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminDistributedSystemFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminDistributedSystemFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminDistributedSystemFactory.java
new file mode 100755
index 0000000..e3e8127
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminDistributedSystemFactory.java
@@ -0,0 +1,154 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+import com.gemstone.gemfire.admin.internal.DistributedSystemConfigImpl;
+import com.gemstone.gemfire.admin.internal.AdminDistributedSystemImpl;
+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.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.InternalLogWriter;
+import com.gemstone.gemfire.internal.logging.LocalLogWriter;
+
+import java.util.Properties;
+
+/**
+ * Factory for creating GemFire administration entities. 
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public class AdminDistributedSystemFactory {
+  
+  /**
+   * Sets the address this VM should bind to when connecting to the distributed
+   * system.  This involves a system property, so using this option will limit
+   * all connections to distributed systems to this one network interface.
+   * <p>
+   * Using a null or empty bindAddress will clear the usage of this option and
+   * connections to distributed systems will return to using all available
+   * network interfaces.
+   * <p>
+   * This method always throws UnsupportedOperationException because it is
+   * now deprecated and is unsafe to use. Please use {@link 
+   * DistributedSystemConfig#setBindAddress} instead.
+   *
+   * @param bindAddress machine name or IP address to bind to
+   * @throws UnsupportedOperationException because of deprecation
+   * @deprecated Use {@link DistributedSystemConfig#setBindAddress} instead.
+   */
+  @Deprecated
+  public static void bindToAddress(String bindAddress) {
+    throw new UnsupportedOperationException(LocalizedStrings.AdminDistributedSystemFactory_PLEASE_USE_DISTRIBUTEDSYSTEMCONFIGSETBINDADDRESS_INSTEAD.toLocalizedString());
+  }
+  
+  /**
+   * Defines a "default" distributed system configuration based on VM
+   * system properties and the content of
+   * <code>gemfire.properties</code>.  The {@linkplain
+   * DistributedSystemConfig#DEFAULT_REMOTE_COMMAND} default remote
+   * command is used.
+   *
+   * @see DistributedSystem#connect
+   */
+  public static DistributedSystemConfig defineDistributedSystem() {
+    DistributionConfig dc = new DistributionConfigImpl(new Properties());
+
+    String remoteCommand =
+      DistributedSystemConfig.DEFAULT_REMOTE_COMMAND;
+    return new DistributedSystemConfigImpl(dc, remoteCommand);
+  }
+
+  /**
+   * Call this method with a value of <code>true</code>
+   * to dedicate the VM to GemFire administration only.
+   * Default is <code>false</code>.
+   * <p>This method <em>must</em> be called before calling
+   * {@link AdminDistributedSystem#connect}. It <em>must</em> also be called
+   * before {@link DistributedSystem#connect} is when creating a colocated distributed system.
+   * <p>
+   * Once it has been enabled be careful to only use GemFire APIs from the
+   * <code>com.gemstone.gemfire.admin</code> package. In particular do not create
+   * a {@link com.gemstone.gemfire.cache.Cache} or a normal {@link DistributedSystem}.
+   * @param adminOnly <code>true</code> if this VM should be limited to administration APIs;
+   *  <code>false</code> if this VM should allow all GemFire APIs.
+   * @throws IllegalStateException if a {@link DistributedSystem}
+   * or {@link AdminDistributedSystem} connection already exists.
+   * 
+   * @since 5.7
+   */
+  public static void setEnableAdministrationOnly(boolean adminOnly) {
+    InternalDistributedSystem.setEnableAdministrationOnly(adminOnly);
+  }
+  
+  /**
+   * Defines a distributed system configuration for administering the
+   * distributed system to which this VM is currently connected.  The
+   * <code>DistributedSystem</code> is used to configure the discovery
+   * mechanism (multicast or locators), bind address, SSL attributes,
+   * as well as the logger of the
+   * <code>DistributedSystemConfig</code>.  Note that the distributed
+   * system will not be able to be administered until the {@link
+   * AdminDistributedSystem#connect connect} method is invoked.
+   *
+   * @param system
+   *        A connection to the distributed system
+   * @param remoteCommand
+   *        The shell command that is used to launch processes that
+   *        run on remote machines.  If <code>null</code>, then the
+   *        {@linkplain DistributedSystemConfig#DEFAULT_REMOTE_COMMAND
+   *        default} will be used.
+   *
+   * @since 4.0
+   */
+  public static DistributedSystemConfig
+    defineDistributedSystem(DistributedSystem system,
+                            String remoteCommand)
+    throws AdminException {
+
+    InternalDistributedSystem internal =
+      (InternalDistributedSystem) system;
+    if (remoteCommand == null) {
+      remoteCommand = DistributedSystemConfig.DEFAULT_REMOTE_COMMAND;
+    }
+    
+    DistributedSystemConfigImpl impl =
+      new DistributedSystemConfigImpl(internal.getConfig(),
+                                      remoteCommand);
+    return impl;
+  }
+
+  /**
+   * Returns the distributed system for administrative monitoring and
+   * managing.  You must then call {@link
+   * AdminDistributedSystem#connect} before interacting with the
+   * actual system.
+   *
+   * @param config configuration definition of the system to administer
+   * @return administrative interface for a distributed system
+   */
+  public static AdminDistributedSystem getDistributedSystem(DistributedSystemConfig config) {
+    return new AdminDistributedSystemImpl((DistributedSystemConfigImpl)config);
+  }
+  
+  /**
+   * Returns a default GemFire LogWriterI18n for logging.  This LogWriterI18n will
+   * log to standard out.
+   *
+   * @return a GemFire LogWriterI18n for logging
+   */
+  public static LogWriterI18n getLogWriter() {
+    return new LocalLogWriter(DistributionConfig.DEFAULT_LOG_LEVEL);
+  }
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminException.java
new file mode 100755
index 0000000..ceb6f5f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminException.java
@@ -0,0 +1,81 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+   
+package com.gemstone.gemfire.admin;
+
+import com.gemstone.gemfire.GemFireCheckedException;
+
+/**
+ * An <code>AdminException</code> is thrown when administration or monitoring
+ * of GemFire fails. 
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public class AdminException extends GemFireCheckedException {
+private static final long serialVersionUID = 879398950879472021L;
+
+  /**
+   * Constructs a new exception with <code>null</code> as its detail message.
+   * The cause is not initialized, and may subsequently be initialized by a
+   * call to {@link Throwable#initCause}.
+   */
+  public AdminException() {
+    super();
+  }
+
+  /**
+   * Constructs a new exception with the specified detail message.  The
+   * cause is not initialized, and may subsequently be initialized by
+   * a call to {@link Throwable#initCause}.
+   *
+   * @param   message   the detail message. The detail message is saved for 
+   *          later retrieval by the {@link #getMessage()} method.
+   */
+  public AdminException(String message) {
+    super(message);
+  }
+
+  /**
+   * Constructs a new exception with the specified detail message and
+   * cause.  <p>Note that the detail message associated with
+   * <code>cause</code> is <i>not</i> automatically incorporated in
+   * this exception's detail message.
+   *
+   * @param  message the detail message (which is saved for later retrieval
+   *         by the {@link #getMessage()} method).
+   * @param  cause the cause (which is saved for later retrieval by the
+   *         {@link #getCause()} method).  (A <tt>null</tt> value is
+   *         permitted, and indicates that the cause is nonexistent or
+   *         unknown.)
+   */
+  public AdminException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Constructs a new exception with the specified cause.
+   * The detail
+   * message will be <tt>(cause==null ? null : cause.toString())</tt> (which
+   * typically contains the class and detail message of <tt>cause</tt>).
+   * This constructor is useful for exceptions that are little more than
+   * wrappers for other throwables (for example, {@link
+   * java.security.PrivilegedActionException}).
+   *
+   * @param  cause the cause (which is saved for later retrieval by the
+   *         {@link #getCause()} method).  (A <tt>null</tt> value is
+   *         permitted, and indicates that the cause is nonexistent or
+   *         unknown.)
+   */
+  public AdminException(Throwable cause) {
+    super(cause);
+  }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminXmlException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminXmlException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminXmlException.java
new file mode 100644
index 0000000..d858d0f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AdminXmlException.java
@@ -0,0 +1,39 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+/**
+ * Thrown when a problem is encountered while working with
+ * admin-related XML data.
+ *
+ * @see DistributedSystemConfig#getEntityConfigXMLFile
+ *
+ * @author David Whitlock
+ * @since 4.0
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public class AdminXmlException extends RuntimeAdminException {
+  private static final long serialVersionUID = -6848726449157550169L;
+
+  /**
+   * Creates a new <code>AdminXmlException</code> with the given
+   * descriptive message.
+   */
+  public AdminXmlException(String s) {
+    super(s);
+  }
+
+  /**
+   * Creates a new <code>AdminXmlException</code> with the given
+   * descriptive message and cause.
+   */
+  public AdminXmlException(String s, Throwable cause) {
+    super(s, cause);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/Alert.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/Alert.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/Alert.java
new file mode 100755
index 0000000..cb057c1
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/Alert.java
@@ -0,0 +1,47 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+/**
+ * An administration alert that is issued by a member of a GemFire
+ * distributed system.  It is similar to a {@linkplain
+ * com.gemstone.gemfire.i18n.LogWriterI18n log message}.
+ *
+ * @author    Kirk Lund
+ * @see       AlertListener
+ * @since     3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface Alert {
+  
+  /** The level at which this alert is issued */
+  public AlertLevel getLevel();
+
+  /**
+   * The member of the distributed system that issued the alert, or
+   * null if the issuer is no longer a member of the distributed system.
+   */
+  public SystemMember getSystemMember();
+
+  /** 
+   * The name of the {@linkplain
+   * com.gemstone.gemfire.distributed.DistributedSystem#getName
+   * distributed system}) through which the alert was issued.
+   */
+  public String getConnectionName();
+
+  /** The id of the source of the alert (such as a thread in a VM) */
+  public String getSourceId();
+
+  /** The alert's message */
+  public String getMessage();
+
+  /** The time at which the alert was issued */
+  public java.util.Date getDate();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AlertLevel.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AlertLevel.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AlertLevel.java
new file mode 100755
index 0000000..292cdc5
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AlertLevel.java
@@ -0,0 +1,165 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+import com.gemstone.gemfire.internal.admin.Alert;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+/**
+ * Type-safe enumeration for {@link com.gemstone.gemfire.admin.Alert
+ * Alert} level.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public class AlertLevel implements java.io.Serializable {
+  private static final long serialVersionUID = -4752438966587392126L;
+    
+  public static final AlertLevel WARNING =
+    new AlertLevel(Alert.WARNING, "WARNING");
+  public static final AlertLevel ERROR = 
+    new AlertLevel(Alert.ERROR, "ERROR");
+  public static final AlertLevel SEVERE =
+    new AlertLevel(Alert.SEVERE, "SEVERE");
+  
+  public static final AlertLevel OFF =
+    new AlertLevel(Alert.OFF, "OFF");
+
+  /** The severity level of this AlertLevel. Greater is more severe. */
+  private final transient int severity;
+  
+  /** The name of this AlertLevel. */
+  private final transient String name;
+  
+  // The 4 declarations below are necessary for serialization
+  /** int used as ordinal to represent this AlertLevel */
+  public final int ordinal = nextOrdinal++;
+
+  private static int nextOrdinal = 0;
+  
+  private static final AlertLevel[] VALUES =
+    { WARNING, ERROR, SEVERE, OFF };
+
+  private Object readResolve() throws java.io.ObjectStreamException {
+    return VALUES[ordinal];  // Canonicalize
+  }
+  
+  /** Creates a new instance of AlertLevel. */
+  private AlertLevel(int severity, String name) {
+    this.severity = severity;
+    this.name = name;
+  }
+    
+  /** Return the AlertLevel represented by specified ordinal */
+  public static AlertLevel fromOrdinal(int ordinal) {
+    return VALUES[ordinal];
+  }
+
+  /**
+   * Returns the <code>AlertLevel</code> for the given severity
+   *
+   * @throws IllegalArgumentException
+   *         If there is no alert level with the given
+   *         <code>severity</code> 
+   */
+  public static AlertLevel forSeverity(int severity) {
+    switch (severity) {
+    case Alert.WARNING:
+      return AlertLevel.WARNING;
+    case Alert.ERROR:
+      return AlertLevel.ERROR;
+    case Alert.SEVERE:
+      return AlertLevel.SEVERE;
+    case Alert.OFF:
+      return AlertLevel.OFF;
+    default:
+      throw new IllegalArgumentException(LocalizedStrings.AlertLevel_UNKNOWN_ALERT_SEVERITY_0.toLocalizedString(Integer.valueOf(severity)));
+    }
+  }
+
+  /**
+   * Returns the <code>AlertLevel</code> with the given name
+   *
+   * @throws IllegalArgumentException
+   *         If there is no alert level named <code>name</code>
+   */
+  public static AlertLevel forName(String name) {
+    for (int i = 0; i < VALUES.length; i++) {
+      AlertLevel level = VALUES[i];
+      if (level.getName().equalsIgnoreCase(name)) {
+        return level;
+      }
+    }
+
+    throw new IllegalArgumentException(LocalizedStrings.AlertLevel_THERE_IS_NO_ALERT_LEVEL_0.toLocalizedString(name));
+  }
+
+  public int getSeverity() {
+    return this.severity;
+  }
+  
+  public String getName() {
+    return this.name;
+  }
+
+  public static AlertLevel[] values() {
+    return VALUES;
+  }
+  
+  /** 
+   * Returns a string representation for this alert level.
+   *
+   * @return the name of this alert level
+   */
+  @Override
+  public String toString() {
+    return this.name /* + "=" + this.severity */;
+  }
+
+	/**
+	 * Indicates whether some other object is "equal to" this one.
+	 *
+	 * @param  other  the reference object with which to compare.
+	 * @return true if this object is the same as the obj argument;
+	 *         false otherwise.
+	 */
+  @Override
+	public boolean equals(Object other) {
+		if (other == this) return true;
+		if (other == null) return false;
+		if (!(other instanceof AlertLevel)) return  false;
+		final AlertLevel that = (AlertLevel) other;
+
+		if (this.severity != that.severity) return false;
+		if (this.name != that.name &&
+	  		!(this.name != null &&
+	  		this.name.equals(that.name))) return false;
+
+		return true;
+	}
+
+	/**
+	 * Returns a hash code for the object. This method is supported for the
+	 * benefit of hashtables such as those provided by java.util.Hashtable.
+	 *
+	 * @return the integer 0 if description is null; otherwise a unique integer.
+	 */
+  @Override
+	public int hashCode() {
+		int result = 17;
+		final int mult = 37;
+
+		result = mult * result + this.severity;
+		result = mult * result + 
+			(this.name == null ? 0 : this.name.hashCode());
+
+		return result;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AlertListener.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AlertListener.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AlertListener.java
new file mode 100755
index 0000000..ab509f1
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/AlertListener.java
@@ -0,0 +1,21 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+/**
+ * A listener whose callback methods are invoked when an {@link Alert}
+ * is received.
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface AlertListener extends java.util.EventListener {
+
+  /**
+   * Invoked when an <code>Alert</code> is received.
+   */
+  public void alert(Alert alert);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/BackupStatus.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/BackupStatus.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/BackupStatus.java
new file mode 100644
index 0000000..f9e983f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/BackupStatus.java
@@ -0,0 +1,40 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+import java.util.Map;
+import java.util.Set;
+
+import com.gemstone.gemfire.cache.persistence.PersistentID;
+import com.gemstone.gemfire.distributed.DistributedMember;
+
+/**
+ * The status of a backup operation, returned by
+ * {@link AdminDistributedSystem#backupAllMembers(java.io.File,java.io.File)}.
+ * 
+ * @author dsmith
+ * @since 6.5 
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface BackupStatus {
+  
+  /**
+   * Returns a map of disk stores that were successfully backed up.
+   * The key is an online distributed member. The value is the set of disk 
+   * stores on that distributed member. 
+   */
+  Map<DistributedMember, Set<PersistentID>> getBackedUpDiskStores();
+  
+  /**
+   * Returns the set of disk stores that were known to be offline at the 
+   * time of the backup. These members were not backed up. If this set
+   * is not empty the backup may not contain a complete snapshot of 
+   * any partitioned regions in the distributed system.
+   */
+  Set<PersistentID> getOfflineDiskStores();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheDoesNotExistException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheDoesNotExistException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheDoesNotExistException.java
new file mode 100644
index 0000000..04b3818
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheDoesNotExistException.java
@@ -0,0 +1,78 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+   
+package com.gemstone.gemfire.admin;
+
+/**
+ * An <code>CacheDoesNotExistException</code> is thrown when an attempt
+ * is made to get a cache and one does not exist.
+ *
+ * @author    Darrel Schneider
+ * @since     3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public class CacheDoesNotExistException extends AdminException {
+private static final long serialVersionUID = -1639933911265729978L;
+
+  /**
+   * Constructs a new exception with <code>null</code> as its detail message.
+   * The cause is not initialized, and may subsequently be initialized by a
+   * call to {@link Throwable#initCause}.
+   */
+  public CacheDoesNotExistException() {
+    super();
+  }
+
+  /**
+   * Constructs a new exception with the specified detail message.  The
+   * cause is not initialized, and may subsequently be initialized by
+   * a call to {@link Throwable#initCause}.
+   *
+   * @param   message   the detail message. The detail message is saved for 
+   *          later retrieval by the {@link #getMessage()} method.
+   */
+  public CacheDoesNotExistException(String message) {
+    super(message);
+  }
+
+  /**
+   * Constructs a new exception with the specified detail message and
+   * cause.  <p>Note that the detail message associated with
+   * <code>cause</code> is <i>not</i> automatically incorporated in
+   * this exception's detail message.
+   *
+   * @param  message the detail message (which is saved for later retrieval
+   *         by the {@link #getMessage()} method).
+   * @param  cause the cause (which is saved for later retrieval by the
+   *         {@link #getCause()} method).  (A <tt>null</tt> value is
+   *         permitted, and indicates that the cause is nonexistent or
+   *         unknown.)
+   */
+  public CacheDoesNotExistException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Constructs a new exception with the specified cause and a detail
+   * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+   * typically contains the class and detail message of <tt>cause</tt>).
+   * This constructor is useful for exceptions that are little more than
+   * wrappers for other throwables (for example, {@link
+   * java.security.PrivilegedActionException}).
+   *
+   * @param  cause the cause (which is saved for later retrieval by the
+   *         {@link #getCause()} method).  (A <tt>null</tt> value is
+   *         permitted, and indicates that the cause is nonexistent or
+   *         unknown.)
+   */
+  public CacheDoesNotExistException(Throwable cause) {
+    super(cause);
+  }
+    
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheHealthConfig.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheHealthConfig.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheHealthConfig.java
new file mode 100644
index 0000000..fab6448
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheHealthConfig.java
@@ -0,0 +1,148 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+/**
+ * Provides configuration information relating to the health of a
+ * member of a GemFire distributed system that hosts a GemFire {@link
+ * com.gemstone.gemfire.cache.Cache Cache}.
+ *
+ * <P>
+ *
+ * If any of the following criteria is true, then a cache member is
+ * considered to be in {@link GemFireHealth#OKAY_HEALTH OKAY_HEALTH}.
+ *
+ * <UL>
+ *
+ * <LI><code>netSearch</code> operations take {@linkplain
+ * #getMaxNetSearchTime too long} to complete.</LI>
+ *
+ * <LI>Cache <code>load</code> operations take {@linkplain
+ * #getMaxLoadTime too long} to complete.</LI>
+ *
+ * <LI>The overall cache {@link #getMinHitRatio hitRatio} is too
+ * small</LI> 
+ *
+ * <LI>The number of entries in the Cache {@link #getMaxEventQueueSize
+ * event delivery queue} is too large.</LI>
+ * 
+ * <LI>If one of the regions is configured with {@link com.gemstone.gemfire.cache.LossAction#FULL_ACCESS FULL_ACCESS}
+ * on role loss.</LI>
+ *
+ * </UL>
+ *
+ * If any of the following criteria is true, then a cache member is
+ * considered to be in {@link GemFireHealth#POOR_HEALTH POOR_HEALTH}.
+ * 
+ * <UL>
+ * 
+ * <LI>If one of the regions is configured with {@link com.gemstone.gemfire.cache.LossAction#NO_ACCESS NO_ACCESS}
+ * on role loss.</LI> 
+ * 
+ * <LI>If one of the regions is configured with {@link com.gemstone.gemfire.cache.LossAction#LIMITED_ACCESS LIMITED_ACCESS}
+ * on role loss.</LI> 
+ * 
+ * </UL>
+ * 
+ * <UL>
+ *
+ * </UL>
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ * */
+public interface CacheHealthConfig {
+
+  /** The default maximum number of milliseconds a
+   * <code>netSearch</code> operation can take before the cache member
+   * is considered to be unhealthy. */
+  public static final long DEFAULT_MAX_NET_SEARCH_TIME = 60 * 1000;
+
+  /** The default maximum mumber of milliseconds a cache
+   * <code>load</code> operation can take before the cache member is
+   * considered to be unhealthy. */
+  public static final long DEFAULT_MAX_LOAD_TIME = 60 * 1000;
+
+  /** The default minimum hit ratio of a healthy cache member. */
+  public static final double DEFAULT_MIN_HIT_RATIO = 0.0;
+
+  /** The default maximum number of entries in the event delivery queue
+   * of a healthy cache member. */
+  public static final long DEFAULT_MAX_EVENT_QUEUE_SIZE = 1000;
+
+  ///////////////////////  Instance Methods  ///////////////////////
+  
+  /**
+   * Returns the maximum number of milliseconds a
+   * <code>netSearch</code> operation can take before the cache member
+   * is considered to be unhealthy.
+   *
+   * @see #DEFAULT_MAX_NET_SEARCH_TIME
+   */
+  public long getMaxNetSearchTime();
+
+  /**
+   * Sets the maximum number of milliseconds a
+   * <code>netSearch</code> operation can take before the cache member
+   * is considered to be unhealthy.
+   *
+   * @see #getMaxNetSearchTime
+   */
+  public void setMaxNetSearchTime(long maxNetSearchTime);
+
+  /**
+   * Returns the maximum mumber of milliseconds a cache
+   * <code>load</code> operation can take before the cache member is
+   * considered to be unhealthy.
+   *
+   * @see #DEFAULT_MAX_LOAD_TIME
+   */
+  public long getMaxLoadTime();
+
+  /**
+   * Sets the maximum mumber of milliseconds a cache
+   * <code>load</code> operation can take before the cache member is
+   * considered to be unhealthy.
+   *
+   * @see #getMaxLoadTime
+   */
+  public void setMaxLoadTime(long maxLoadTime);
+
+  /**
+   * Returns the minimum hit ratio of a healthy cache member.
+   *
+   * @see #DEFAULT_MIN_HIT_RATIO
+   */
+  public double getMinHitRatio();
+
+  /**
+   * Sets the minimum hit ratio of a healthy cache member.
+   *
+   * @see #getMinHitRatio
+   */
+  public void setMinHitRatio(double minHitRatio);
+
+  /**
+   * Returns the maximum number of entries in the event delivery queue
+   * of a healthy cache member.
+   *
+   * @see #DEFAULT_MAX_EVENT_QUEUE_SIZE
+   */
+  public long getMaxEventQueueSize();
+
+  /**
+   * Sets the maximum number of entries in the event delivery queue
+   * of a healthy cache member.
+   *
+   * @see #getMaxEventQueueSize
+   */
+  public void setMaxEventQueueSize(long maxEventQueueSize);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheServer.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheServer.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheServer.java
new file mode 100644
index 0000000..2bb8f0c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheServer.java
@@ -0,0 +1,37 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+/**
+ * A dedicated cache server VM that is managed by the administration
+ * API.
+ *
+ * @author David Whitlock
+ * @since 4.0
+ * @deprecated as of 5.7 use {@link CacheVm} instead.
+ */
+@Deprecated
+public interface CacheServer extends SystemMember, ManagedEntity {
+  /**
+   * Returns the configuration of this cache vm
+   * @deprecated as of 5.7 use {@link CacheVm#getVmConfig} instead.
+   */
+  @Deprecated
+  public CacheServerConfig getConfig();
+  /**
+   * Find whether this server is primary for given client (durableClientId)
+   * 
+   * @param durableClientId -
+   *                durable-id of the client
+   * @return true if the server is primary for given client
+   * 
+   * @since 5.6
+   */
+  public boolean isPrimaryForDurableClient(String durableClientId);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheServerConfig.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheServerConfig.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheServerConfig.java
new file mode 100644
index 0000000..65f4a0a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheServerConfig.java
@@ -0,0 +1,46 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+/**
+ * Configuration for a GemFire cache server that is managed by the
+ * administration API.  The cache server may or may not be running.
+ *
+ * @see AdminDistributedSystem#addCacheServer()
+ *
+ * @author David Whitlock
+ * @since 4.0
+ * @deprecated as of 5.7 use {@link CacheVmConfig} instead.
+ */
+@Deprecated
+public interface CacheServerConfig extends CacheVmConfig {
+  /**
+   * Returns the <code>cache.xml</code> declarative caching
+   * initialization file used to configure this cache server VM.  By
+   * default, a cache server VM is started without an XML file.
+   */
+  public String getCacheXMLFile();
+
+  /**
+   * Sets the <code>cache.xml</code> declarative caching
+   * initialization file used to configure this cache server VM.
+   */
+  public void setCacheXMLFile(String cacheXml);
+
+  /**
+   * Returns the location(s) of user classes (such as cache loaders)
+   * required by the cache server VM.
+   */
+  public String getClassPath();
+
+  /**
+   * Sets the location(s) of user classes (such as cache loaders)
+   * required by the cache server VM.
+   */
+  public void setClassPath(String classpath);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheVm.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheVm.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheVm.java
new file mode 100755
index 0000000..944592b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheVm.java
@@ -0,0 +1,29 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+/**
+ * A dedicated cache server VM that is managed by the administration
+ * API.
+ * <p>Note that this may not represent an instance of
+ * {@link com.gemstone.gemfire.cache.server.CacheServer}. It is possible for
+ * a cache VM to be started but for it not to listen for client connections
+ * in which case it is not a 
+ * {@link com.gemstone.gemfire.cache.server.CacheServer}
+ * but is an instance of this interface.
+ *
+ * @author darrel
+ * @since 5.7
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface CacheVm extends SystemMember, ManagedEntity {
+  /**
+   * Returns the configuration of this cache vm
+   */
+  public CacheVmConfig getVmConfig();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheVmConfig.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheVmConfig.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheVmConfig.java
new file mode 100755
index 0000000..4b24dd5
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/CacheVmConfig.java
@@ -0,0 +1,45 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+/**
+ * Configuration for a GemFire cache server VM that is managed by the
+ * administration API.  The VM may or may not be running.
+ *
+ * @see AdminDistributedSystem#addCacheVm()
+ *
+ * @author darrel
+ * @since 5.7
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface CacheVmConfig extends ManagedEntityConfig {
+  /**
+   * Returns the <code>cache.xml</code> declarative caching
+   * initialization file used to configure this cache server VM.  By
+   * default, a cache server VM is started without an XML file.
+   */
+  public String getCacheXMLFile();
+
+  /**
+   * Sets the <code>cache.xml</code> declarative caching
+   * initialization file used to configure this cache server VM.
+   */
+  public void setCacheXMLFile(String cacheXml);
+
+  /**
+   * Returns the location(s) of user classes (such as cache loaders)
+   * required by the cache server VM.
+   */
+  public String getClassPath();
+
+  /**
+   * Sets the location(s) of user classes (such as cache loaders)
+   * required by the cache server VM.
+   */
+  public void setClassPath(String classpath);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/ConfigurationParameter.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/ConfigurationParameter.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/ConfigurationParameter.java
new file mode 100755
index 0000000..0351098
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/ConfigurationParameter.java
@@ -0,0 +1,65 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.admin;
+
+/**
+* A single configuration parameter of a {@link SystemMember}.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface ConfigurationParameter {
+  
+  /** Gets the identifying name of this configuration parameter. */
+  public String getName();
+  
+  /** Gets the full description of this configuration parameter */
+  public String getDescription();
+  
+  /** Gets the current value */
+  public Object getValue();
+  
+  /** Gets the current value as a string */
+  public String getValueAsString();
+  
+  /** Gets the class type of the value */
+  public Class getValueType();
+  
+  /** True if this is modifiable; false if read-only */
+  public boolean isModifiable();
+  
+  /** Returns true if this config parameter uses a string array for value. */
+  public boolean isArray();
+  
+  /** Returns true if this config parameter represents an InetAddress value. */
+  public boolean isInetAddress();
+  
+  /** Returns true if this config parameter represents a File value. */
+  public boolean isFile();
+  
+  /** Returns true if this config parameter represents an octal value. */
+  public boolean isOctal();
+    
+  /** Returns true if this config parameter represents a string value. */
+  public boolean isString();
+  
+  /**
+   * Sets a new value for this configuration parameter.
+   *
+   * @param value   the new value which must be of type {@link #getValueType}
+   * @throws IllegalArgumentException
+   *         if value type does not match {@link #getValueType}
+   * @throws UnmodifiableConfigurationException
+   *         if attempting to set value when isModifiable is false
+   */
+  public void setValue(Object value) throws UnmodifiableConfigurationException;
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/DistributedSystemConfig.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/DistributedSystemConfig.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/DistributedSystemConfig.java
new file mode 100755
index 0000000..4f57862
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/DistributedSystemConfig.java
@@ -0,0 +1,673 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+import com.gemstone.gemfire.admin.internal.InetAddressUtil;
+//import com.gemstone.gemfire.admin.jmx.AgentConfig;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+
+//import java.net.InetAddress;
+import java.util.Properties;
+
+/**
+ * Configuration for defining a GemFire distributed system to
+ * administrate.  This configuration includes information about the
+ * discovery mechanism used to find members of the distributed system
+ * and information about {@linkplain ManagedEntity managed entities}
+ * such as {@linkplain DistributionLocator distribution locators}
+ * and {@linkplain CacheVm GemFire cache vms}
+ * that can be {@linkplain AdminDistributedSystem#start started}.  
+ *
+ * <P>
+ *
+ * Detailed descriptions of many of these configuration attributes can
+ * be found in the {@link
+ * com.gemstone.gemfire.distributed.DistributedSystem
+ * DistributedSystem} class.  Note that the default values of these
+ * configuration attributes can be specified using Java system
+ * properties.
+ *
+ * <P>
+ *
+ * A <code>DistributedSystemConfig</code> can be modified using a
+ * number of mutator methods until the
+ * <code>AdminDistributedSystem</code> that it configures {@linkplain
+ * AdminDistributedSystem#connect connects} to the distributed system.
+ * After that, attempts to modify most attributes in the
+ * <code>DistributedSystemConfig</code> will result in an {@link
+ * IllegalStateException} being thrown.  If you wish to use the same
+ * <code>DistributedSystemConfig</code> to configure multiple
+ * <code>AdminDistributedSystem</code>s, a copy of the
+ * <code>DistributedSystemConfig</code> object can be made by invoking
+ * the {@link #clone} method.
+ *
+ * @author    Kirk Lund
+ * @since 3.5 
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+*/
+public interface DistributedSystemConfig extends Cloneable {
+
+  /** The name of an XML file that specifies the configuration for the
+   * {@linkplain ManagedEntity managed entities} administered by the
+   * <code>DistributedSystem</code>.  The XML file must conform to a
+   * <a href="doc-files/ds5_0.dtd">dtd</a>. */
+  public static final String ENTITY_CONFIG_XML_FILE_NAME =
+    "entity-config-xml-file";
+
+  /** The default value of the "entity-config-xml-file" property
+   * ("distributed-system.xml"). */
+  public static final String DEFAULT_ENTITY_CONFIG_XML_FILE =
+    "distributed-system.xml";
+
+  /** The name of the "system-id" property */
+  public static final String SYSTEM_ID_NAME = "system-id";
+
+  /** The default value of the "system-id" property ("") */
+  public static final String DEFAULT_SYSTEM_ID = "Default System";
+
+  /** The name of the "name" property. See {@link #getSystemName()}. */
+  public static final String NAME_NAME = DistributionConfig.NAME_NAME;
+
+  /** The default value of the "name" property (""). See {@link #getSystemName()}. */
+  public static final String DEFAULT_NAME = "";
+
+  /** The name of the "mcastPort" property */
+  public static final String MCAST_PORT_NAME = 
+    DistributionConfig.MCAST_PORT_NAME;
+
+  /** The default value of the "mcastPort" property (10334) */
+  public static final int DEFAULT_MCAST_PORT =
+    DistributionConfig.DEFAULT_MCAST_PORT;
+
+  /** The minimum mcastPort (0) */
+  public static final int MIN_MCAST_PORT =
+    DistributionConfig.MIN_MCAST_PORT;
+
+  /** The maximum mcastPort (65535) */
+  public static final int MAX_MCAST_PORT =
+    DistributionConfig.MAX_MCAST_PORT;
+  
+  /** The name of the "mcastAddress" property */
+  public static final String MCAST_ADDRESS_NAME = 
+    DistributionConfig.MCAST_ADDRESS_NAME;
+
+  /** The default value of the "mcastAddress" property (239.192.81.1). */
+  public static final String DEFAULT_MCAST_ADDRESS = 
+      InetAddressUtil.toString(DistributionConfig.DEFAULT_MCAST_ADDRESS);
+  
+  /** The name of the "membership-port-range" property
+   * @since 6.5
+   */
+  public static final String MEMBERSHIP_PORT_RANGE_NAME = 
+    DistributionConfig.MEMBERSHIP_PORT_RANGE_NAME;
+
+  /**
+   * The default membership-port-range.
+   * <p> Actual value is <code>[1024,65535]</code>.
+   * @since 6.5
+   */
+  public static final int[] DEFAULT_MEMBERSHIP_PORT_RANGE = 
+    DistributionConfig.DEFAULT_MEMBERSHIP_PORT_RANGE;
+  
+  /** settings for tcp-port
+   * @since 6.5
+   */
+  public static final String TCP_PORT_NAME = DistributionConfig.TCP_PORT_NAME;
+  /** The default value of the "tcpPort" property.
+   * <p> Actual value is <code>0</code>.
+   * @since 6.5
+   */
+  public static final int DEFAULT_TCP_PORT = DistributionConfig.DEFAULT_TCP_PORT;
+
+  /**
+   * The default AckWaitThreshold.
+   * <p> Actual value of this constant is <code>15</code> seconds.
+   */
+  public static final int DEFAULT_ACK_WAIT_THRESHOLD =
+    DistributionConfig.DEFAULT_ACK_WAIT_THRESHOLD;
+  /**
+   * The minimum AckWaitThreshold.
+   * <p> Actual value of this constant is <code>1</code> second.
+   */
+  public static final int MIN_ACK_WAIT_THRESHOLD =
+    DistributionConfig.MIN_ACK_WAIT_THRESHOLD;
+  /**
+   * The maximum AckWaitThreshold.
+   * <p> Actual value of this constant is <code>MAX_INT</code> seconds.
+   */
+  public static final int MAX_ACK_WAIT_THRESHOLD =
+    DistributionConfig.MIN_ACK_WAIT_THRESHOLD;
+  
+  /**
+   * The default ackSevereAlertThreshold.
+   * <p> Actual value of this constant is <code>0</code> seconds, which
+   * turns off forced disconnects based on ack wait periods.
+   */
+  public static final int DEFAULT_ACK_SEVERE_ALERT_THRESHOLD =
+    DistributionConfig.DEFAULT_ACK_SEVERE_ALERT_THRESHOLD;
+  /**
+   * The minimum ackSevereAlertThreshold.
+   * <p> Actual value of this constant is <code>0</code> second,
+   * which turns off forced disconnects based on ack wait periods.
+   */
+  public static final int MIN_ACK_SEVERE_ALERT_THRESHOLD =
+    DistributionConfig.MIN_ACK_SEVERE_ALERT_THRESHOLD;
+  /**
+   * The maximum ackSevereAlertThreshold.
+   * <p> Actual value of this constant is <code>MAX_INT</code> seconds.
+   */
+  public static final int MAX_ACK_SEVERE_ALERT_THRESHOLD =
+    DistributionConfig.MAX_ACK_SEVERE_ALERT_THRESHOLD;
+
+  /** The name of the "locators" property (comma-delimited host[port] list) */
+  public static final String LOCATORS_NAME = 
+    DistributionConfig.LOCATORS_NAME;
+
+  /** The default value of the "locators" property ("") */
+  public static final String DEFAULT_LOCATORS =
+    DistributionConfig.DEFAULT_LOCATORS;
+
+  /** The name of the "bindAddress" property */
+  public static final String BIND_ADDRESS_NAME =
+    DistributionConfig.BIND_ADDRESS_NAME;
+
+  /** The default value of the "bindAddress" property */
+  public static final String DEFAULT_BIND_ADDRESS =
+    DistributionConfig.DEFAULT_BIND_ADDRESS;
+
+  /** The name of the remote-command property */
+  public static final String REMOTE_COMMAND_NAME = "remote-command";
+
+  /** The default value of the remote-command property */
+  public static final String DEFAULT_REMOTE_COMMAND =
+    "rsh -n {HOST} {CMD}";
+
+  /** The name of the "SSLEnabled" property */
+  public static final String SSL_ENABLED_NAME = 
+    DistributionConfig.SSL_ENABLED_NAME;
+
+  /** The default ssl-enabled state (<code>false</code>) */
+  public static final boolean DEFAULT_SSL_ENABLED =
+    DistributionConfig.DEFAULT_SSL_ENABLED;
+ 
+  /** The name of the "SSLProtocols" property */
+  public static final String SSL_PROTOCOLS_NAME =
+    DistributionConfig.SSL_PROTOCOLS_NAME;
+
+  /** The default ssl-protocols value (<code>any</code>) */
+  public static final String DEFAULT_SSL_PROTOCOLS =
+    DistributionConfig.DEFAULT_SSL_PROTOCOLS;
+   
+  /** The name of the "SSLCiphers" property */
+  public static final String SSL_CIPHERS_NAME = 
+    DistributionConfig.SSL_CIPHERS_NAME;
+
+  /** The default ssl-ciphers value. (<code>any</code>) */
+  public static final String DEFAULT_SSL_CIPHERS =
+    DistributionConfig.DEFAULT_SSL_CIPHERS; 
+  
+  /** The name of the "SSLRequireAuthentication" property */
+  public static final String SSL_REQUIRE_AUTHENTICATION_NAME =
+    DistributionConfig.SSL_REQUIRE_AUTHENTICATION_NAME;
+
+  /** The default ssl-require-authentication value (<code>true</code>) */
+  public static final boolean DEFAULT_SSL_REQUIRE_AUTHENTICATION =
+    DistributionConfig.DEFAULT_SSL_REQUIRE_AUTHENTICATION; 
+
+  /** The default disable-tcp value (<code>false</code>) */
+  public static final boolean DEFAULT_DISABLE_TCP = DistributionConfig.DEFAULT_DISABLE_TCP;
+  
+  /** The default enable-network-partition-detection setting (<code>false</code>) */
+  public static final boolean DEFAULT_ENABLE_NETWORK_PARTITION_DETECTION = DistributionConfig.DEFAULT_ENABLE_NETWORK_PARTITION_DETECTION;
+  
+  /** The default disable-auto-reconnect setting (<code>false</code>) */
+  public static final boolean DEFAULT_DISABLE_AUTO_RECONNECT = DistributionConfig.DEFAULT_DISABLE_AUTO_RECONNECT;
+
+  /** The default failure-detection timeout period for member heart-beat responses */
+  public static final int DEFAULT_MEMBER_TIMEOUT = DistributionConfig.DEFAULT_MEMBER_TIMEOUT;
+  
+  /** The name of the "logFile" property */
+  public static final String LOG_FILE_NAME = "log-file";
+
+  /** The default log-file value ("" which directs logging to standard
+   * output) */
+  public static final String DEFAULT_LOG_FILE = "";
+
+  /** The name of the "logLevel" property */
+  public static final String LOG_LEVEL_NAME = "log-level";
+
+  /** The default log level ("config") */
+  public static final String DEFAULT_LOG_LEVEL = "config";
+
+  /** The name of the "LogDiskSpaceLimit" property */
+  public static final String LOG_DISK_SPACE_LIMIT_NAME =
+    "log-disk-space-limit";
+
+  /** The default log disk space limit in megabytes (0) */
+  public static final int DEFAULT_LOG_DISK_SPACE_LIMIT =
+    DistributionConfig.DEFAULT_LOG_DISK_SPACE_LIMIT;
+
+  /** The minimum log disk space limit in megabytes (0) */
+  public static final int MIN_LOG_DISK_SPACE_LIMIT = 
+    DistributionConfig.MIN_LOG_DISK_SPACE_LIMIT;
+
+  /** The minimum log disk space limit in megabytes (1000000) */
+  public static final int MAX_LOG_DISK_SPACE_LIMIT =
+    DistributionConfig.MAX_LOG_DISK_SPACE_LIMIT;
+    
+  /** The name of the "LogFileSizeLimit" property */
+  public static final String LOG_FILE_SIZE_LIMIT_NAME =
+    "log-file-size-limit";
+
+  /** The default log file size limit in megabytes (0) */
+  public static final int DEFAULT_LOG_FILE_SIZE_LIMIT =
+    DistributionConfig.DEFAULT_LOG_FILE_SIZE_LIMIT;
+
+  /** The minimum log file size limit in megabytes (0) */
+  public static final int MIN_LOG_FILE_SIZE_LIMIT =
+    DistributionConfig.MIN_LOG_FILE_SIZE_LIMIT;
+
+  /** The minimum log file size limit in megabytes (1000000) */
+  public static final int MAX_LOG_FILE_SIZE_LIMIT =
+    DistributionConfig.MAX_LOG_FILE_SIZE_LIMIT;
+
+  /**
+   * The name of the "refreshInterval" property which will apply to
+   * SystemMember, SystemMemberCache and StatisticResource refresh. This interval
+   * (in seconds) is used for auto-polling and updating AdminDistributedSystem
+   * constituents including SystemMember, CacheServer, SystemMemberCache and
+   * StatisticResource. This interval is read-only and retains the value set
+   * when the config is created. Note that the resource MBeans actually refresh
+   * and hit the DS only if there is an RMI client connected
+   * */
+  public static final String REFRESH_INTERVAL_NAME =
+    "refresh-interval";
+
+  /**
+   * The default "refreshInterval" in seconds which will apply to
+   * REFRESH_INTERVAL_NAME property. The default value is 15 secs
+   * */
+  public static final int DEFAULT_REFRESH_INTERVAL = 15;
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  /**
+   * Returns the name of the XML file that specifies the configuration
+   * of the {@linkplain com.gemstone.gemfire.admin.ManagedEntity
+   * managed entities} administered by the
+   * <code>DistributedSystem</code>.  The XML file must conform to a
+   * <a href="doc-files/ds5_0.dtd">dtd</a>.
+   *
+   * @since 4.0
+   */
+  public String getEntityConfigXMLFile();
+
+  /**
+   * Sets the name of the XML file that specifies the configuration of
+   * managed entities administered by the
+   * <code>DistributedSystem</code>. 
+   */
+  public void setEntityConfigXMLFile(String xmlFile);
+
+  /** Returns the string identity for the system */
+  public String getSystemId();
+
+  /** Sets the string identity for the system */
+  public void setSystemId(String systemId);
+
+  /** Returns the optional non-unique name for the system */
+  public String getSystemName();
+
+  /** Sets the optional non-unique name for the system */
+  public void setSystemName(final String name);
+
+  /** Returns the multicast address for the system */
+  public String getMcastAddress();
+
+  /** Sets the multicast address for the system */
+  public void setMcastAddress(String mcastAddress);
+
+  /** Returns the multicast port for the system */
+  public int getMcastPort();
+  
+  /** Sets the multicast port for the system */
+  public void setMcastPort(int mcastPort);
+
+  /** Returns the ack-wait-threshold for the system */
+  public int getAckWaitThreshold();
+  
+  /** Sets the ack-wait-threshold for the system */
+  public void setAckWaitThreshold(int seconds);
+
+  /** Returns the ack-severe-alert-threshold for the system */
+  public int getAckSevereAlertThreshold();
+  
+  /** Sets the ack-severe-alert-threshold for the system */
+  public void setAckSevereAlertThreshold(int seconds);
+
+  /** Returns a comma-delimited list of locators for the system */
+  public String getLocators();
+
+  /** Sets the comma-delimited list of locators for the system */
+  public void setLocators(String locators);
+
+  /**
+   * Returns the membership-port-range property of the Distributed System. This 
+   * range is given as two numbers separated by a minus sign.
+   * @since 6.5
+   */
+  public String getMembershipPortRange();
+  
+  /**
+   * Sets the membership-port-range property of the Distributed System. This 
+   * range is given as two numbers separated by a minus sign.
+   * @since 6.5
+   */
+  public void setMembershipPortRange(String membershipPortRange);
+  
+  
+  /**
+   * Sets the primary communication port number for the Distributed System.
+   * @since 6.5
+   */
+  public void setTcpPort(int port);
+
+  /**
+   * Returns the primary communication port number for the Distributed System.
+   * @since 6.5
+   */
+  public int getTcpPort();
+
+
+  /** Sets the disable-tcp property for the system.  When tcp is disabled,
+      the cache uses udp for unicast messaging.   This must be consistent
+      across all members of the distributed system. The default is to enable
+      tcp. */
+  public void setDisableTcp(boolean flag);
+  
+  /** Returns the disable-tcp property for the system.  When tcp is
+      disabled, the cache uses udp for unicast messaging.  This must be
+      consistent across all members of the distributed system.  The default
+      is to enable tcp.
+   */
+  public boolean getDisableTcp();
+
+
+  /**
+   * Turns on network partition detection
+   */
+  public void setEnableNetworkPartitionDetection(boolean newValue);
+  /**
+   * Returns true if network partition detection is enabled.
+   */
+  public boolean getEnableNetworkPartitionDetection();
+  
+  /**
+   * Disables auto reconnect after being forced out of the distributed system
+   */
+  public void setDisableAutoReconnect(boolean newValue);
+  
+  /**
+   * Returns true if auto reconnect is disabled
+   */
+  public boolean getDisableAutoReconnect();
+  
+  
+
+  /**
+   * Returns the member-timeout millisecond value used in failure-detection
+   * protocols
+   */
+  public int getMemberTimeout();
+
+  /**
+   * Set the millisecond value of the member-timeout used in failure-detection
+   * protocols.  This timeout determines how long a member has to respond to
+   * a heartbeat request. The member is given three chances before being
+   * kicked out of the distributed system with a SystemConnectException.
+   */
+  public void setMemberTimeout(int value);
+
+  /**
+   * Returns the IP address to which the distributed system's server
+   * sockets are bound.
+   *
+   * @since 4.0
+   */
+  public String getBindAddress();
+
+  /**
+   * Sets the IP address to which the distributed system's server
+   * sockets are bound.
+   *
+   * @since 4.0
+   */
+  public void setBindAddress(String bindAddress);
+  
+  
+  /**
+   * Returns the IP address to which client/server server sockets are
+   * bound
+   */
+  public String getServerBindAddress();
+  
+  /**
+   * Sets the IP address to which a server cache will bind when listening
+   * for client cache connections. 
+   */
+  public void setServerBindAddress(String bindAddress);
+  
+
+  /** Returns the remote command setting to use for remote administration */
+  public String getRemoteCommand();
+
+  /** 
+   * Sets the remote command setting to use for remote administration.
+   * This attribute may be modified after this
+   * <code>DistributedSystemConfig</code> has been used to create an
+   * <codE>AdminDistributedSystem</code>.
+   */
+  public void setRemoteCommand(String command);
+
+  /** Returns the value of the "ssl-enabled" property. */
+  public boolean isSSLEnabled();
+
+  /** Sets the value of the "ssl-enabled" property. */
+  public void setSSLEnabled(boolean enabled);
+
+  /** Returns the value of the "ssl-protocols" property. */
+  public String getSSLProtocols();
+
+  /** Sets the value of the "ssl-protocols" property. */
+  public void setSSLProtocols(String protocols);
+
+  /** Returns the value of the "ssl-ciphers" property. */
+  public String getSSLCiphers();
+
+  /** Sets the value of the "ssl-ciphers" property. */
+  public void setSSLCiphers(String ciphers);
+
+  /** Returns the value of the "ssl-require-authentication" property. */
+  public boolean isSSLAuthenticationRequired();
+
+  /** Sets the value of the "ssl-require-authentication" property. */
+  public void setSSLAuthenticationRequired(boolean authRequired);
+  
+  /** Returns the provider-specific properties for SSL. */
+  public Properties getSSLProperties();
+
+  /** Sets the provider-specific properties for SSL. */
+  public void setSSLProperties(Properties sslProperties);
+
+  /** Adds an SSL property */
+  public void addSSLProperty(String key, String value);
+
+  /** Removes an SSL property */
+  public void removeSSLProperty(String key);
+  
+  /**
+   * Returns the name of the log file to which informational messages
+   * are written.
+   *
+   * @see com.gemstone.gemfire.i18n.LogWriterI18n
+   */
+  public String getLogFile();
+
+  /**
+   * Sets the name of the log file to which informational messages
+   * are written.
+   *
+   * @see com.gemstone.gemfire.i18n.LogWriterI18n
+   */
+  public void setLogFile(String logFile);
+
+  /**
+   * Returns the level at which informational messages are logged.
+   */
+  public String getLogLevel();
+
+  /**
+   * Sets the level at which information messages are logged.
+   */
+  public void setLogLevel(String logLevel);
+
+  /**
+   * Returns the log disk space limit in megabytes
+   */
+  public int getLogDiskSpaceLimit();
+
+  /**
+   * Sets the log disk space limit in megabytes
+   */
+  public void setLogDiskSpaceLimit(int limit);
+
+  /**
+   * Returns the log file size limit in megabytes
+   */
+  public int getLogFileSizeLimit();
+
+  /**
+   * Sets the log file size limit in megabytes
+   */
+  public void setLogFileSizeLimit(int limit);
+
+  /**
+   * Returns the refreshInterval in seconds used for auto-polling and updating
+   * AdminDistributedSystem constituents including SystemMember, CacheServer,
+   * SystemMemberCache and StatisticResource
+   * @since 6.0
+   */
+  public int getRefreshInterval();
+
+  /**
+   * Sets the refreshInterval in seconds
+   * @since 6.0
+   */
+  public void setRefreshInterval(int timeInSecs);
+
+  /** 
+   * Returns an array of configurations for statically known
+   * <code>CacheServers</code>.
+   * @deprecated as of 5.7 use {@link #getCacheVmConfigs} instead.
+   */ 
+  @Deprecated
+  public CacheServerConfig[] getCacheServerConfigs();
+
+  /** 
+   * Creates the configuration for a CacheServer
+   * @deprecated as of 5.7 use {@link #createCacheVmConfig} instead.
+   */
+  @Deprecated
+  public CacheServerConfig createCacheServerConfig();
+
+  /** 
+   * Removes the configuration for a CacheServer
+   * @deprecated as of 5.7 use {@link #removeCacheVmConfig} instead.
+   */
+  @Deprecated
+  public void removeCacheServerConfig(CacheServerConfig managerConfig);
+
+  /** 
+   * Returns an array of configurations for statically known
+   * {@link CacheVm}s.
+   * @since 5.7
+   */ 
+  public CacheVmConfig[] getCacheVmConfigs();
+
+  /** 
+   * Creates the configuration for a {@link CacheVm}.
+   * @since 5.7
+   */
+  public CacheVmConfig createCacheVmConfig();
+
+  /** 
+   * Removes the configuration for a {@link CacheVm}
+   * @since 5.7
+   */
+  public void removeCacheVmConfig(CacheVmConfig existing);
+
+  /**
+   * Returns configuration information about {@link
+   * DistributionLocator}s that are managed by an
+   * <code>AdminDistributedSystem</code>.
+   */
+  public DistributionLocatorConfig[] getDistributionLocatorConfigs();
+  
+  /**
+   * Creates a new <code>DistributionLocatorConfig</code> for a
+   * distribution locator that is managed in this distributed system.
+   * The default locator config is set to not use multicast
+   */
+  public DistributionLocatorConfig createDistributionLocatorConfig();
+
+  /**
+   * Removes a <code>DistributionLocatorConfig</code> from the
+   * distributed system.
+   */
+  public void removeDistributionLocatorConfig(DistributionLocatorConfig config);
+
+  /** Registers listener for notification of changes in this config. */
+  public void addListener(ConfigListener listener);
+
+  /** Removes previously registered listener of this config. */
+  public void removeListener(ConfigListener listener);
+
+  /**
+   * Validates that this distributed system configuration is correct
+   * and consistent.
+   *
+   * @throws IllegalStateException
+   *         If this config is not valid
+   * @throws AdminXmlException
+   *         If the {@linkplain #getEntityConfigXMLFile entity config
+   *         XML file} is not valid 
+   */
+  public void validate();
+
+  /**
+   * Returns a copy of this <code>DistributedSystemConfig</code>
+   * object whose configuration can be modified.  Note that this
+   * {@link DistributedSystemConfig.ConfigListener ConfigListener}s
+   * that are registered on this config object are not cloned.
+   *
+   * @since 4.0
+   */
+  public Object clone() throws CloneNotSupportedException;
+
+  ////////////////////// Inner Classes  //////////////////////
+
+  /** A listener whose callback methods are invoked when this config
+   * changes. */
+  public interface ConfigListener extends java.util.EventListener {
+
+    /** Invoked when this configurated is changed. */
+    public void configChanged(DistributedSystemConfig config);
+  }
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/DistributedSystemHealthConfig.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/DistributedSystemHealthConfig.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/DistributedSystemHealthConfig.java
new file mode 100644
index 0000000..f01acc0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/DistributedSystemHealthConfig.java
@@ -0,0 +1,68 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+/**
+ * Provides configuration information relating to the health of an
+ * entire GemFire distributed system.
+ *
+ * <P>
+ *
+ * If any of the following criteria is
+ * true, then the distributed system is considered to be in
+ * {@link GemFireHealth#OKAY_HEALTH OKAY_HEALTH}.
+ *
+ * <UL>
+ *
+ * </UL>
+ *
+ * If any of the following criteria is true, then the distributed
+ * system is considered to be in {@link GemFireHealth#POOR_HEALTH
+ * POOR_HEALTH}.
+ *
+ * <UL>
+ *
+ * <LI>Too many application members {@linkplain
+ * #getMaxDepartedApplications unexpectedly leave} the distributed
+ * system.</LI>
+ *
+ * <LI>Too many application members {@linkplain
+ * #getMaxDepartedApplications unexpectedly leave} the distributed
+ * system.</LI>
+ *
+ * </UL>
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ * */
+public interface DistributedSystemHealthConfig {
+
+  /** The default maximum number of application members that can
+   * unexceptedly leave a healthy the distributed system. */
+  public static final long DEFAULT_MAX_DEPARTED_APPLICATIONS = 10;
+
+  ///////////////////////  Instance Methods  ///////////////////////
+
+  /**
+   * Returns the maximum number of application members that can
+   * unexceptedly leave a healthy the distributed system.
+   *
+   * @see #DEFAULT_MAX_DEPARTED_APPLICATIONS
+   */
+  public long getMaxDepartedApplications();
+
+  /**
+   * Sets the maximum number of application members that can
+   * unexceptedly leave a healthy the distributed system.
+   *
+   * @see #getMaxDepartedApplications
+   */
+  public void setMaxDepartedApplications(long maxDepartedApplications);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/DistributionLocator.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/DistributionLocator.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/DistributionLocator.java
new file mode 100755
index 0000000..94eafe9
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/DistributionLocator.java
@@ -0,0 +1,38 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.admin;
+
+/**
+ * Represents a single distribution locator server, of which a
+ * distributed system may use zero or many.  The distributed system
+ * will be configured to use either multicast discovery or locator
+ * service.
+ *
+ * @see DistributionLocatorConfig
+ *
+ * @author    Kirk Lund
+ * @since 3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface DistributionLocator extends ManagedEntity {
+  
+  /** 
+   * Returns the identity name for this locator.
+   */
+  public String getId();
+  
+  /**
+   * Returns the configuration object for this distribution locator.
+   *
+   * @since 4.0
+   */
+  public DistributionLocatorConfig getConfig();
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/DistributionLocatorConfig.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/DistributionLocatorConfig.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/DistributionLocatorConfig.java
new file mode 100644
index 0000000..ef5b5e0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/DistributionLocatorConfig.java
@@ -0,0 +1,81 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+import java.util.Properties;
+
+/**
+ * Describes the configuration of a {@link DistributionLocator}
+ * managed by the GemFire administration APIs.  
+ *
+ * <P>
+ *
+ * A <code>DistributionLocatorConfig</code> can be modified using a
+ * number of mutator methods until the
+ * <code>DistributionLocator</code> configured by this object is
+ * {@linkplain ManagedEntity#start started}.  After that,
+ * attempts to modify most attributes in the
+ * <code>DistributionLocatorConfig</code> will result in an {@link
+ * IllegalStateException} being thrown.  If you wish to use the same
+ * <code>DistributionLocatorConfig</code> to configure another
+ * <code>DistributionLocator</code>s, a copy of the
+ * <code>DistributionLocatorConfig</code> object can be made by
+ * invoking the {@link Object#clone} method.
+ *
+ * @see AdminDistributedSystem#addDistributionLocator
+ * @see com.gemstone.gemfire.distributed.Locator
+ *
+ * @author David Whitlock
+ * @since 4.0
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface DistributionLocatorConfig
+  extends ManagedEntityConfig {
+
+  /**
+   * Returns the port on which ths distribution locator listens for
+   * members to connect.  There is no default locator port, so a
+   * non-default port must be specified.
+   */
+  public int getPort();
+
+  /**
+   * Sets the port on which the distribution locator listens for
+   * members to connect.
+   */
+  public void setPort(int port);
+
+  /**
+   * Returns the address to which the distribution locator's port is
+   * (or will be) bound.  By default, the bind address is
+   * <code>null</code> meaning that the port will be bound to all
+   * network addresses on the host.
+   */
+  public String getBindAddress();
+
+  /**
+   * Sets the address to which the distribution locator's port is
+   * (or will be) bound.
+   */
+  public void setBindAddress(String bindAddress);
+
+  /**
+   * Sets the properties used to configure the locator's
+   * DistributedSystem.
+   * @since 5.0
+   */
+  public void setDistributedSystemProperties(Properties props);
+  
+  /**
+   * Retrieves the properties used to configure the locator's
+   * DistributedSystem.
+   * @since 5.0
+   */
+  public Properties getDistributedSystemProperties();
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/GemFireHealth.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/GemFireHealth.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/GemFireHealth.java
new file mode 100644
index 0000000..f59c3bc
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/GemFireHealth.java
@@ -0,0 +1,225 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+import com.gemstone.gemfire.internal.Assert;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+/**
+ * Provides information about the aggregate health of the members of a
+ * GemFire distributed system ("components").  The {@link #getHealth
+ * getHealth} method provides an indication of the overall health.
+ * Health is expressed as one of three levels: {@link #GOOD_HEALTH
+ * GOOD_HEALTH}, {@link #OKAY_HEALTH OKAY_HEALTH}, and {@link
+ * #POOR_HEALTH POOR_HEALTH}.  The {@link #getDiagnosis getDiagnosis}
+ * method provides a more detailed explanation of the cause of ill
+ * health.
+ *
+ * <P>
+ *
+ * The aggregate health of the GemFire component is evaluated
+ * {@linkplain GemFireHealthConfig#setHealthEvaluationInterval every
+ * so often} and if certain criteria are met, then the overall health
+ * of the component changes accordingly.  If any of the components is
+ * in <code>OKAY_HEALTH</code>, then the overall health is
+ * <code>OKAY_HEALTH</code>.  If any of the components is in
+ * <code>POOR_HEALTH</code>, then the overall health is
+ * <code>POOR_HEALTH</code>.
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ * */
+public interface GemFireHealth {
+
+  /** An indicator that the GemFire components are healthy.
+   *
+   * @see #getHealth */
+  public static final Health GOOD_HEALTH =
+    new Health(Health.GOOD_STRING);
+
+  /** An indicator that one or more GemFire components is slightly
+   * unhealthy.  The problem may or may not require configuration
+   * changes and may not necessarily lead to poorer component health.
+   *
+   * @see #getHealth */
+  public static final Health OKAY_HEALTH =
+    new Health(Health.OKAY_STRING);
+
+  /** An indicator that one or more GemFire components is unhealthy.
+   * While it may be possible for the components to recover on their
+   * own, it is likely that they will have to be restarted.
+   *
+   * @see #getHealth */
+  public static final Health POOR_HEALTH =
+    new Health(Health.POOR_STRING);
+
+  ///////////////////////  Instance Methods  ///////////////////////
+
+  /**
+   * Returns an indicator of the overall health of the GemFire
+   * components. 
+   *
+   * @see #GOOD_HEALTH
+   * @see #OKAY_HEALTH
+   * @see #POOR_HEALTH
+   */
+  public Health getHealth();
+
+  /** 
+   * Resets the overall health of the GemFire components to {@link
+   * #GOOD_HEALTH}.  This operation should be invoked when the
+   * operator has determined that warnings about the components's
+   * health do not need to be regarded.
+   */
+  public void resetHealth();
+
+  /**
+   * Returns a message that provides a description of the cause of a
+   * component's ill health.
+   */
+  public String getDiagnosis();
+
+  /**
+   * Returns the configuration for determining the health of the
+   * distributed system itself.
+   */
+  public DistributedSystemHealthConfig getDistributedSystemHealthConfig();
+
+  /**
+   * Sets the configuration for determining the health of the
+   * distributed system itself.
+   */
+  public void setDistributedSystemHealthConfig(DistributedSystemHealthConfig config);
+
+  /**
+   * Returns the <code>GemFireHealthConfig</code> for GemFire
+   * components whose configurations are not overridden on a per-host
+   * basis.  Note that changes made to the returned
+   * <code>GemFireHealthConfig</code> will not take effect until
+   * {@link #setDefaultGemFireHealthConfig} is invoked.
+   */
+  public GemFireHealthConfig getDefaultGemFireHealthConfig();
+
+  /**
+   * Sets the <code>GemFireHealthConfig</code> for
+   * GemFire components whose configurations are not overridden on a
+   * per-host basis.
+   *
+   * @throws IllegalArgumentException
+   *         If <code>config</code> specifies the config for a host
+   */
+  public void setDefaultGemFireHealthConfig(GemFireHealthConfig config);
+
+  /**
+   * Returns the <code>GemFireHealthConfig</code> for GemFire
+   * components that reside on a given host.  This configuration will
+   * override the {@linkplain #getDefaultGemFireHealthConfig default}
+   * configuration.
+   *
+   * @param hostName
+   *        The {@linkplain java.net.InetAddress#getCanonicalHostName
+   *        canonical} name of the host.
+   */
+  public GemFireHealthConfig getGemFireHealthConfig(String hostName);
+
+  /**
+   * Sets the <code>GemFireHealthConfig</code> for GemFire
+   * components that reside on a given host.  This configuration will
+   * override the {@linkplain #getDefaultGemFireHealthConfig default}
+   * configuration.  Note that changes made to the returned
+   * <code>GemFireHealthConfig</code> will not take effect until
+   * {@link #setDefaultGemFireHealthConfig} is invoked.
+   *
+   * @param hostName
+   *        The {@linkplain java.net.InetAddress#getCanonicalHostName
+   *        canonical} name of the host.
+   *
+   * @throws IllegalArgumentException
+   *         If host <code>hostName</code> does not exist or if there
+   *         are no GemFire components running on that host or if
+   *         <code>config</code> does not configure host
+   *         <code>hostName</code>. 
+   */
+  public void setGemFireHealthConfig(String hostName,
+                                     GemFireHealthConfig config);
+
+  /**
+   * Closes this health monitor and releases all resources associated
+   * with it.
+   */
+  public void close();
+
+  /**
+   * Returns whether or not this <code>GemFireHealth</code> is
+   * {@linkplain #close closed}.
+   */
+  public boolean isClosed();
+
+  //////////////////////  Inner Classes  //////////////////////
+
+  /**
+   * An enumerated type for the health of GemFire.
+   */
+  public static class Health implements java.io.Serializable {
+    private static final long serialVersionUID = 3039539430412151801L;
+    /** The string for good health */
+    static final String GOOD_STRING = LocalizedStrings.GemFireHealth_GOOD.toLocalizedString();
+
+    /** The string for okay health */
+    static final String OKAY_STRING = LocalizedStrings.GemFireHealth_OKAY.toLocalizedString();
+
+    /** The string for poor health */
+    static final String POOR_STRING = LocalizedStrings.GemFireHealth_POOR.toLocalizedString();
+
+    ////////////////////  Instance Fields  ////////////////////
+
+    /** The string for this health */
+    private String healthString;
+
+    /////////////////////  Constructors  //////////////////////
+
+    /**
+     * Creates a new <code>Health</code> with the given string
+     */
+    protected Health(String healthString) {
+      this.healthString = healthString;
+    }
+    
+    ////////////////////  Instance Methods  ////////////////////
+
+    /**
+     * Returns the appropriate canonical instance of
+     * <code>Health</code>.
+     */
+    public Object readResolve() {
+      if (this.healthString.equals(GOOD_STRING)) {
+        return GemFireHealth.GOOD_HEALTH;
+
+      } else if (this.healthString.equals(OKAY_STRING)) {
+        return GemFireHealth.OKAY_HEALTH;
+
+      } else if (this.healthString.equals(POOR_STRING)) {
+        return GemFireHealth.POOR_HEALTH;
+
+      } else {
+        Assert.assertTrue(false, "Unknown healthString: " +
+                          this.healthString);
+        return null;
+      }
+    }
+
+    @Override
+    public String toString() {
+      return this.healthString;
+    }
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/GemFireHealthConfig.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/GemFireHealthConfig.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/GemFireHealthConfig.java
new file mode 100644
index 0000000..3326aeb
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/GemFireHealthConfig.java
@@ -0,0 +1,49 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+/**
+ * Provides configuration information relating to all of the
+ * components of a GemFire distributed system.
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ * */
+public interface GemFireHealthConfig
+  extends MemberHealthConfig, CacheHealthConfig {
+
+  /** The default number of seconds between assessments of the health
+   * of the GemFire components. */
+  public static final int DEFAULT_HEALTH_EVALUATION_INTERVAL = 30;
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  /**
+   * Returns the name of the host to which this configuration
+   * applies.  If this is the "default" configuration, then
+   * <code>null</code> is returned.
+   *
+   * @see GemFireHealth#getGemFireHealthConfig
+   */
+  public String getHostName();
+
+  /**
+   * Sets the number of seconds between assessments of the health of
+   * the GemFire components.
+   */
+  public void setHealthEvaluationInterval(int interval);
+
+  /**
+   * Returns the number of seconds between assessments of the health of
+   * the GemFire components.
+   */
+  public int getHealthEvaluationInterval();
+
+}


[35/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/AgentConfigImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/AgentConfigImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/AgentConfigImpl.java
new file mode 100644
index 0000000..2a915c6
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/AgentConfigImpl.java
@@ -0,0 +1,1847 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.InetAddress;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import com.gemstone.gemfire.GemFireIOException;
+import com.gemstone.gemfire.admin.DistributedSystemConfig;
+import com.gemstone.gemfire.admin.DistributionLocatorConfig;
+import com.gemstone.gemfire.admin.internal.DistributedSystemConfigImpl;
+import com.gemstone.gemfire.admin.internal.InetAddressUtil;
+import com.gemstone.gemfire.admin.jmx.Agent;
+import com.gemstone.gemfire.admin.jmx.AgentConfig;
+import com.gemstone.gemfire.distributed.internal.AbstractDistributionConfig;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.internal.ClassPathLoader;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.util.IOUtils;
+
+/**
+ * Provides the JMX Agent configuration properties.
+ * <p>
+ * Supports importing of persisted properties from an external configuration
+ * file.
+ * <p>
+ * Select values can also be overridden with command line arguments.  See
+ * remarks on individual properties for further information.
+ * <p>
+ * Extends and implements DistributedSystemConfig.
+ *
+ * @author    Kirk Lund
+ * @author    David Whitlock
+ * @since     3.5 (in which it was named AgentConfig)
+ */
+public class AgentConfigImpl extends DistributedSystemConfigImpl
+  implements AgentConfig {
+
+  // -------------------------------------------------------------------------
+  //   Static class variable(s)
+  // -------------------------------------------------------------------------
+
+  /** Command-line arg to enable agent debugging */
+  public static final String AGENT_DEBUG = "agent-debug";
+
+  /** The name of the "propertyFile" property. May specify as cmd-line arg */
+  public static final String PROPERTY_FILE_NAME = "property-file";
+
+  /** The name of the "gfAgentPropertyFile" property, can be specified as System Property */
+   public static final String AGENT_PROPSFILE_PROPERTY_NAME = "gfAgentPropertyFile";
+
+  // -------------------------------------------------------------------------
+  //   DistributionLocator properties...
+  // -------------------------------------------------------------------------
+
+  /** The name of the "locator.host-" property */
+  public static final String LOCATOR_HOST_NAME =
+      "locator.host-";
+  /** The name of the "locator.port-" property */
+  public static final String LOCATOR_PORT_NAME =
+      "locator.port-";
+  /** The name of the "locator.product-directory-" property */
+  public static final String LOCATOR_PRODUCT_DIRECTORY_NAME =
+      "locator.product-directory-";
+  /** The name of the "locator.working-directory-" property */
+  public static final String LOCATOR_WORKING_DIRECTORY_NAME =
+      "locator.working-directory-";
+  /** The name of the "locator.remote-command-" property */
+  public static final String LOCATOR_REMOTE_COMMAND =
+      "locator.remote-command-";
+  /** The name of the "locator.bind-address-" property */
+  public static final String LOCATOR_BIND_ADDRESS =
+      "locator.bind-address-";
+  /** the properties used in configuring a locator's distributed system */
+  public static final String LOCATOR_DS_PROPERTIES =
+      "locator.ds-properties";
+
+  /** The default log file for stand-alone JMX agents */
+  /*package scope*/
+  static final String DEFAULT_LOG_FILE = "agent.log";
+
+  /** The default startup log file to be used by agent launcher */
+  /*package scope*/
+  static final String DEFAULT_STARTUP_LOG_FILE = "start_agent.log";
+
+  private static String OBFUSCATED_STRING = "********";
+
+  //////////////////////  Static Methods  //////////////////////
+
+  /**
+   * The <code>propertyFile</code> is the name of the property file that will
+   * be loaded on startup of the Agent.
+   * <p>
+   * The file will be searched for, in order, in the following directories:
+   * <ol>
+   * <li> the current directory
+   * <li> the home directory
+   * <li> the class path
+   * </ol>
+   * Only the first file found will be used.
+   * <p>
+   * The default value of propertyFile is <code>"agent.properties"</code>. However
+   * if the "gfAgentPropertyFile" system property is set then its value is the
+   * value of propertyFile. If this value is a relative file system path then
+   * the above search is done. If its an absolute file system path then that
+   * file must exist; no search for it is done.
+   */
+  static String retrievePropertyFile() {
+    return System.getProperty(AGENT_PROPSFILE_PROPERTY_NAME, DEFAULT_PROPERTY_FILE);
+  }
+
+  /**
+   * Creates a new <code>Properties</code> object that contains all of
+   * the default values.
+   */
+  private static Properties getDefaultProperties() {
+    Properties props = new Properties();
+
+    props.setProperty(AUTO_CONNECT_NAME,
+                      String.valueOf(DEFAULT_AUTO_CONNECT));
+
+    props.setProperty(HTTP_ENABLED_NAME,
+                      String.valueOf(DEFAULT_HTTP_ENABLED));
+    props.setProperty(HTTP_BIND_ADDRESS_NAME,
+                      String.valueOf(DEFAULT_HTTP_BIND_ADDRESS));
+    props.setProperty(HTTP_PORT_NAME,
+                      String.valueOf(DEFAULT_HTTP_PORT));
+    props.setProperty(HTTP_AUTHENTICATION_ENABLED_NAME,
+                      String.valueOf(DEFAULT_HTTP_AUTHENTICATION_ENABLED));
+    props.setProperty(HTTP_AUTHENTICATION_USER_NAME,
+                      String.valueOf(DEFAULT_HTTP_AUTHENTICATION_USER));
+    props.setProperty(HTTP_AUTHENTICATION_PASSWORD_NAME,
+                      String.valueOf(DEFAULT_HTTP_AUTHENTICATION_PASSWORD));
+
+    props.setProperty(RMI_ENABLED_NAME,
+                      String.valueOf(DEFAULT_RMI_ENABLED));
+    props.setProperty(RMI_REGISTRY_ENABLED_NAME,
+                      String.valueOf(DEFAULT_RMI_REGISTRY_ENABLED));
+    props.setProperty(RMI_BIND_ADDRESS_NAME,
+                      String.valueOf(DEFAULT_RMI_BIND_ADDRESS));
+    props.setProperty(RMI_PORT_NAME,
+                      String.valueOf(DEFAULT_RMI_PORT));
+    props.setProperty(RMI_SERVER_PORT_NAME,
+                      String.valueOf(DEFAULT_RMI_SERVER_PORT));
+
+    props.setProperty(SNMP_ENABLED_NAME,
+                      String.valueOf(DEFAULT_SNMP_ENABLED));
+    props.setProperty(SNMP_DIRECTORY_NAME,
+                      String.valueOf(DEFAULT_SNMP_DIRECTORY));
+
+    props.setProperty(AGENT_SSL_ENABLED_NAME,
+                      String.valueOf(DEFAULT_AGENT_SSL_ENABLED));
+    props.setProperty(AGENT_SSL_PROTOCOLS_NAME,
+                      String.valueOf(DEFAULT_AGENT_SSL_PROTOCOLS));
+    props.setProperty(AGENT_SSL_CIPHERS_NAME,
+                      String.valueOf(DEFAULT_AGENT_SSL_CIPHERS));
+    props.setProperty(AGENT_SSL_REQUIRE_AUTHENTICATION_NAME,
+                      String.valueOf(DEFAULT_AGENT_SSL_REQUIRE_AUTHENTICATION));
+    props.setProperty(HTTP_SSL_REQUIRE_AUTHENTICATION_NAME,
+                      String.valueOf(DEFAULT_HTTP_SSL_REQUIRE_AUTHENTICATION));
+
+
+    return props;
+  }
+
+  /**
+   * Returns default values for all valid agent properties as a Properties
+   * object.
+   *
+   * @return default values for all valid agent properties
+   */
+  static Properties getDefaultValuesForAllProperties() {
+    Properties props = new Properties();
+
+    props.setProperty(AUTO_CONNECT_NAME,
+        String.valueOf(DEFAULT_AUTO_CONNECT));
+
+    props.setProperty(HTTP_ENABLED_NAME,
+        String.valueOf(DEFAULT_HTTP_ENABLED));
+
+    props.setProperty(HTTP_BIND_ADDRESS_NAME,
+        String.valueOf(DEFAULT_HTTP_BIND_ADDRESS));
+
+    props.setProperty(HTTP_PORT_NAME,
+        String.valueOf(DEFAULT_HTTP_PORT));
+
+    props.setProperty(HTTP_AUTHENTICATION_ENABLED_NAME,
+        String.valueOf(DEFAULT_HTTP_AUTHENTICATION_ENABLED));
+
+    props.setProperty(HTTP_AUTHENTICATION_USER_NAME,
+        String.valueOf(DEFAULT_HTTP_AUTHENTICATION_USER));
+
+    props.setProperty(HTTP_AUTHENTICATION_PASSWORD_NAME,
+        String.valueOf(DEFAULT_HTTP_AUTHENTICATION_PASSWORD));
+
+    props.setProperty(RMI_ENABLED_NAME,
+        String.valueOf(DEFAULT_RMI_ENABLED));
+
+    props.setProperty(RMI_REGISTRY_ENABLED_NAME,
+        String.valueOf(DEFAULT_RMI_REGISTRY_ENABLED));
+
+    props.setProperty(RMI_BIND_ADDRESS_NAME,
+        String.valueOf(DEFAULT_RMI_BIND_ADDRESS));
+
+    props.setProperty(RMI_PORT_NAME,
+        String.valueOf(DEFAULT_RMI_PORT));
+
+    props.setProperty(RMI_SERVER_PORT_NAME,
+        String.valueOf(DEFAULT_RMI_SERVER_PORT));
+
+    props.setProperty(SNMP_ENABLED_NAME,
+        String.valueOf(DEFAULT_SNMP_ENABLED));
+
+    props.setProperty(SNMP_DIRECTORY_NAME,
+        String.valueOf(DEFAULT_SNMP_DIRECTORY));
+
+    props.setProperty(AGENT_SSL_ENABLED_NAME,
+        String.valueOf(DEFAULT_AGENT_SSL_ENABLED));
+
+    props.setProperty(AGENT_SSL_PROTOCOLS_NAME,
+        String.valueOf(DEFAULT_AGENT_SSL_PROTOCOLS));
+
+    props.setProperty(AGENT_SSL_CIPHERS_NAME,
+        String.valueOf(DEFAULT_AGENT_SSL_CIPHERS));
+
+    props.setProperty(AGENT_SSL_REQUIRE_AUTHENTICATION_NAME,
+        String.valueOf(DEFAULT_AGENT_SSL_REQUIRE_AUTHENTICATION));
+
+    props.setProperty(HTTP_SSL_REQUIRE_AUTHENTICATION_NAME,
+        String.valueOf(DEFAULT_HTTP_SSL_REQUIRE_AUTHENTICATION));
+
+    props.setProperty(SNMP_BIND_ADDRESS_NAME,
+        String.valueOf(DEFAULT_SNMP_BIND_ADDRESS));
+
+    props.setProperty(EMAIL_NOTIFICATIONS_ENABLED_NAME,
+        String.valueOf(DEFAULT_EMAIL_NOTIFICATIONS_ENABLED));
+
+    props.setProperty(EMAIL_NOTIFICATIONS_HOST_NAME,
+        String.valueOf(DEFAULT_EMAIL_HOST));
+
+    props.setProperty(EMAIL_NOTIFICATIONS_FROM_NAME,
+        String.valueOf(DEFAULT_EMAIL_FROM));
+
+    props.setProperty(EMAIL_NOTIFICATIONS_TO_LIST_NAME,
+        String.valueOf(DEFAULT_EMAIL_TO_LIST));
+
+    props.setProperty(STATE_SAVE_FILE_NAME,
+        String.valueOf(DEFAULT_STATE_SAVE_FILE));
+
+    props.setProperty(SSL_ENABLED_NAME,
+        String.valueOf(DEFAULT_SSL_ENABLED));
+
+    props.setProperty(SSL_PROTOCOLS_NAME,
+        String.valueOf(DEFAULT_SSL_PROTOCOLS));
+
+    props.setProperty(SSL_CIPHERS_NAME,
+        String.valueOf(DEFAULT_SSL_CIPHERS));
+
+    props.setProperty(SSL_REQUIRE_AUTHENTICATION_NAME,
+        String.valueOf(DEFAULT_SSL_REQUIRE_AUTHENTICATION));
+
+    props.setProperty(ENTITY_CONFIG_XML_FILE_NAME,
+        String.valueOf(DEFAULT_ENTITY_CONFIG_XML_FILE));
+
+    props.setProperty(MCAST_PORT_NAME,
+        String.valueOf(DEFAULT_MCAST_PORT));
+
+    props.setProperty(MCAST_ADDRESS_NAME,
+        String.valueOf(DEFAULT_MCAST_ADDRESS));
+
+    props.setProperty(LOCATORS_NAME,
+        String.valueOf(DEFAULT_LOCATORS));
+
+    props.setProperty(BIND_ADDRESS_NAME,
+        String.valueOf(DEFAULT_BIND_ADDRESS));
+
+    props.setProperty(REMOTE_COMMAND_NAME,
+        String.valueOf(DEFAULT_REMOTE_COMMAND));
+
+    props.setProperty(LOG_FILE_NAME,
+        String.valueOf(DEFAULT_LOG_FILE));
+
+    props.setProperty(LOG_LEVEL_NAME,
+        String.valueOf(DEFAULT_LOG_LEVEL));
+
+    props.setProperty(LOG_DISK_SPACE_LIMIT_NAME,
+        String.valueOf(DEFAULT_LOG_DISK_SPACE_LIMIT));
+
+    props.setProperty(LOG_FILE_SIZE_LIMIT_NAME,
+        String.valueOf(DEFAULT_LOG_FILE_SIZE_LIMIT));
+
+    props.setProperty(REFRESH_INTERVAL_NAME,
+        String.valueOf(DEFAULT_REFRESH_INTERVAL));
+
+    return props;
+
+  }
+
+  // -------------------------------------------------------------------------
+  //   Member variable(s)
+  // -------------------------------------------------------------------------
+
+  /** Does agent automatically connect to the distributed system? */
+  private boolean autoConnect;
+
+  /** True if Agent adaptors should use SSL */
+  private boolean agentSSLEnabled;
+
+  /** The SSL Protocols that the Agent adaptors will use */
+  private String agentSSLProtocols;
+
+  /** The SSL Ciphers that the Agent adaptors will use */
+  private String agentSSLCiphers;
+
+  /** True if Agent adaptors require authentication when SSL is enabled */
+  private boolean agentSSLRequireAuth;
+
+  /**
+   * HttpAdaptor won't work with ssl authentication required, so this attribute
+   * allows this option to be turned on for RMI but off for HTTP in the event
+   * that both adaptors are being used with ssl.
+   */
+  private boolean httpSSLRequireAuth;
+
+  /** True if HttpAdaptor authentication is enabled */
+  private boolean httpAuthEnabled;
+
+  /** The login user for HttpAdaptor authentication */
+  private String httpAuthUser;
+
+  /** The login password for HttpAdaptor authentication */
+  private String httpAuthPassword;
+
+  /** True if the HttpAdaptor is enabled */
+  private boolean httpEnabled;
+
+  /** The port for the MX4J HttpAdatper */
+  private int httpPort;
+
+  /** The host for the MX4J HttpAdatper */
+  private String httpBindAddress;
+
+  /** True if the RMIConnectorServer is enabled */
+  private boolean rmiEnabled;
+
+  /** True if the Agent is to create its own RMI registry */
+  private boolean rmiRegistryEnabled;
+
+  /** The host for the MX4J RMIConnectorServer */
+  private String rmiBindAddress;
+
+  /** The port for the RMI Registry created by the Agent */
+  private int rmiPort;
+
+  /** The port for the MX4J RMIConnectorServer */
+  private int rmiServerPort;
+
+  /** True if the SnmpAdaptor is enabled */
+  private boolean snmpEnabled;
+
+  /** The bind address for sockets used by the SNMP adapter */
+  private String snmpBindAddress;
+
+  /** Path to the directory containing the SNMP Adaptor and its sub-dirs */
+  private String snmpDirectory;
+
+  /** Is Email notification enabled */
+  private boolean isEmailNotificationEnabled;
+
+  /** Email notification from: emailID */
+  private String emailNotificationFrom;
+
+  /** The host name of the mail server to be used for email communication.  */
+  private String emailNotificationHostName;
+
+  /** Email notification to: emailIDs list */
+  private String emailNotificationToList;
+
+  /** State Save File Name */
+  private String stateSaveFile;
+
+  /**
+   * Describes the property file used to load configuration from.
+   * Null if no file was found.
+   */
+  private URL url;
+
+  /** Original command line arguments */
+  private String[] originalCmdLineArgs = null;
+
+  /** The <code>Agent</code> that is configured by this
+   * <code>AgentConfigImpl</code> */
+  private Agent agent;
+
+  // -------------------------------------------------------------------------
+  //   Constructor(s)
+  // -------------------------------------------------------------------------
+
+  /**
+   * Constructs new instance of <code>AgentConfigImpl</code> with the
+   * default configuration.
+   */
+  public AgentConfigImpl() {
+    this(getDefaultProperties());
+  }
+
+  /**
+   * Constructs new instance of AgentConfig. Supplied command-line arguments
+   * are used to create a set of non-default properties for initializing this
+   * AgentConfig.
+   *
+   * @param args  array of non-default configuration arguments
+   */
+  public AgentConfigImpl(String[] args) {
+    this(toProperties(args));
+    this.originalCmdLineArgs = args;
+  }
+
+  /**
+   * Creates a new <code>AgentConfig</code> with the given non-default
+   * configuration properties.
+   *
+   * @param props  overriding non-default configuration properties
+   */
+  public AgentConfigImpl(Properties props) {
+    // for admin bug #40434
+    super(filterOutAgentProperties(appendOptionalPropertyFileProperties(props)), true/*ignore gemfire.properties*/);
+
+    // first get any property values set in the optional property file
+    this.url = getPropertyFileURL(retrievePropertyFile());
+
+    initialize(appendOptionalPropertyFileProperties(props));
+  }
+
+  /**
+   * Constructs new instance of AgentConfig using the specified property file.
+   *
+   * @param propFile  the file to load configuration properties from
+   */
+  public AgentConfigImpl(File propFile) {
+    // Initialize default values
+    this();
+
+    Properties props = new Properties();
+    if (propFile.exists()) {
+      try {
+        FileInputStream in = new FileInputStream(propFile);
+        props.load(in);
+        in.close();
+      }
+      catch (java.io.IOException e) {
+        throw new GemFireIOException(LocalizedStrings.AgentConfigImpl_FAILED_READING_0.toLocalizedString(propFile), e);
+      }
+    }
+    else {
+      throw new IllegalArgumentException(LocalizedStrings.AgentConfigImpl_SPECIFIED_PROPERTIES_FILE_DOES_NOT_EXIST_0.toLocalizedString(propFile));
+    }
+
+    initialize(props);
+  }
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  /**
+   * Sets the <code>Agent</code> associated with this
+   * <code>AgentConfigImpl</code>.
+   */
+  void setAgent(Agent agent) {
+    this.agent = agent;
+  }
+
+  /**
+   * Checks to see if this config object is "read only".  If it is,
+   * then an {@link IllegalStateException} is thrown.
+   *
+   * @since 4.0
+   */
+  @Override
+  protected void checkReadOnly() {
+    if (this.agent != null) {
+      throw new IllegalStateException(LocalizedStrings.AgentConfigImpl_AN_AGENTCONFIG_OBJECT_CANNOT_BE_MODIFIED_AFTER_IT_HAS_BEEN_USED_TO_CREATE_AN_AGENT.toLocalizedString());
+    }
+
+    super.checkReadOnly();
+  }
+
+  // -------------------------------------------------------------------------
+  //   Methods for handling Properties and the Properties file
+  // -------------------------------------------------------------------------
+
+  /**
+   * Returns a description of the property file used to load this config.
+   * If no property file was used then the description will say so.
+   */
+  public String getPropertyFileDescription() {
+    /*
+     * Checking if the specified or the default properties file exists. If not,
+     * just log this as an information.
+     */
+    if (this.url == null) {
+      return LocalizedStrings.AgentConfigImpl_USING_DEFAULT_CONFIGURATION_BECAUSE_PROPERTY_FILE_WAS_FOUND.toLocalizedString();
+    } else {
+      return LocalizedStrings.AgentConfigImpl_CONFIGURATION_LOADED_FROM_0
+        .toLocalizedString(this.url);
+    }
+  }
+
+  /**
+   * Returns the default property file that will be used when configuration
+   * is saved.
+   */
+  public File getPropertyFile() {
+    File f;
+    if (this.url == null) {
+      f = new File(retrievePropertyFile());
+      if (!f.isAbsolute()) {
+        // save to <cwd>/propertyFile
+        f = new File(System.getProperty("user.dir"),
+                     retrievePropertyFile());
+      }
+    } else {
+      f = new File(this.url.getFile());
+    }
+    return f;
+  }
+
+  /**
+   * Converts the contents of this config to a property instance and Stringifies
+   * it
+   *
+   * @return contents of this config as String
+   */
+  public String toPropertiesAsString() {
+    Properties p = toProperties(true /* include DS properties */);
+
+    StringWriter sw = new StringWriter();
+    PrintWriter pw = new PrintWriter(sw);
+    pw.println(LocalizedStrings.AgentConfigImpl_AGENT_CONFIGURATION.toLocalizedString());
+    Enumeration e = p.propertyNames();
+    while (e.hasMoreElements()) {
+      String pn = (String)e.nextElement();
+      String pv = p.getProperty(pn);
+      pw.println("  " + pn + " = " + pv);
+    }
+    pw.close();
+
+    return sw.toString();
+  }
+
+  /**
+   * Converts the contents of this config to a property instance.
+   *
+   * @return contents of this config as java.util.Properties
+   */
+  public Properties toProperties() {
+    return toProperties(false /* include DS properties */);
+  }
+
+
+  /**
+   * Converts the contents of this config to a property instance.
+   *
+   * @param includeDSProperties
+   *        Should distributed system properties be included in the
+   *        <code>Properties</code> object?  See bug 32682.
+   *
+   * @return contents of this config as java.util.Properties
+   */
+  public Properties toProperties(boolean includeDSProperties) {
+    Properties props = new Properties();
+
+    props.setProperty(AUTO_CONNECT_NAME, toString(AUTO_CONNECT_NAME, getAutoConnect()));
+
+    props.setProperty(HTTP_ENABLED_NAME, toString(HTTP_ENABLED_NAME, isHttpEnabled()));
+    props.setProperty(HTTP_BIND_ADDRESS_NAME, toString(HTTP_BIND_ADDRESS_NAME, getHttpBindAddress()));
+    props.setProperty(HTTP_PORT_NAME, toString(HTTP_PORT_NAME, getHttpPort()));
+
+    props.setProperty(RMI_ENABLED_NAME, toString(RMI_ENABLED_NAME, isRmiEnabled()));
+    props.setProperty(RMI_REGISTRY_ENABLED_NAME, toString(RMI_REGISTRY_ENABLED_NAME, isRmiRegistryEnabled()));
+    props.setProperty(RMI_BIND_ADDRESS_NAME, toString(RMI_BIND_ADDRESS_NAME, getRmiBindAddress()));
+    props.setProperty(RMI_PORT_NAME, toString(RMI_PORT_NAME, getRmiPort()));
+    props.setProperty(RMI_SERVER_PORT_NAME, toString(RMI_SERVER_PORT_NAME, getRmiServerPort()));
+
+    props.setProperty(SNMP_ENABLED_NAME, toString(SNMP_ENABLED_NAME, isSnmpEnabled()));
+    props.setProperty(SNMP_BIND_ADDRESS_NAME, toString(SNMP_BIND_ADDRESS_NAME, getSnmpBindAddress()));
+    props.setProperty(SNMP_DIRECTORY_NAME, toString(SNMP_DIRECTORY_NAME, getSnmpDirectory()));
+
+    props.setProperty(AGENT_SSL_ENABLED_NAME, toString(AGENT_SSL_ENABLED_NAME, isAgentSSLEnabled()));
+    props.setProperty(AGENT_SSL_PROTOCOLS_NAME, toString(AGENT_SSL_PROTOCOLS_NAME, getAgentSSLProtocols()));
+    props.setProperty(AGENT_SSL_CIPHERS_NAME, toString(AGENT_SSL_CIPHERS_NAME, getAgentSSLCiphers()));
+    props.setProperty(AGENT_SSL_REQUIRE_AUTHENTICATION_NAME, toString(AGENT_SSL_REQUIRE_AUTHENTICATION_NAME, isAgentSSLRequireAuth()));
+    props.setProperty(HTTP_SSL_REQUIRE_AUTHENTICATION_NAME, toString(HTTP_SSL_REQUIRE_AUTHENTICATION_NAME, isHttpSSLRequireAuth()));
+
+    props.setProperty(HTTP_AUTHENTICATION_ENABLED_NAME, toString(HTTP_AUTHENTICATION_ENABLED_NAME, isHttpAuthEnabled()));
+    props.setProperty(HTTP_AUTHENTICATION_USER_NAME, toString(HTTP_AUTHENTICATION_USER_NAME, getHttpAuthUser()));
+    props.setProperty(HTTP_AUTHENTICATION_PASSWORD_NAME, toString(HTTP_AUTHENTICATION_PASSWORD_NAME, getHttpAuthPassword()));
+
+    props.setProperty(EMAIL_NOTIFICATIONS_ENABLED_NAME, toString(EMAIL_NOTIFICATIONS_ENABLED_NAME, isEmailNotificationEnabled()));
+    props.setProperty(EMAIL_NOTIFICATIONS_HOST_NAME, toString(EMAIL_NOTIFICATIONS_HOST_NAME, getEmailNotificationHost()));
+    props.setProperty(EMAIL_NOTIFICATIONS_FROM_NAME, toString(EMAIL_NOTIFICATIONS_FROM_NAME, getEmailNotificationFrom()));
+    props.setProperty(EMAIL_NOTIFICATIONS_TO_LIST_NAME, toString(EMAIL_NOTIFICATIONS_TO_LIST_NAME, getEmailNotificationToList()));
+
+    props.setProperty(STATE_SAVE_FILE_NAME, toString(STATE_SAVE_FILE_NAME, getStateSaveFile()));
+
+    props.setProperty(EMAIL_NOTIFICATIONS_ENABLED_NAME, toString(EMAIL_NOTIFICATIONS_ENABLED_NAME, isEmailNotificationEnabled()));
+    props.setProperty(EMAIL_NOTIFICATIONS_HOST_NAME, toString(EMAIL_NOTIFICATIONS_HOST_NAME, getEmailNotificationHost()));
+    props.setProperty(EMAIL_NOTIFICATIONS_FROM_NAME, toString(EMAIL_NOTIFICATIONS_FROM_NAME, getEmailNotificationFrom()));
+    props.setProperty(EMAIL_NOTIFICATIONS_TO_LIST_NAME, toString(EMAIL_NOTIFICATIONS_TO_LIST_NAME, getEmailNotificationToList()));
+
+    props.setProperty(SSL_ENABLED_NAME, toString(SSL_ENABLED_NAME, isSSLEnabled()));
+    props.setProperty(SSL_PROTOCOLS_NAME, toString(SSL_PROTOCOLS_NAME, getSSLProtocols()));
+    props.setProperty(SSL_CIPHERS_NAME, toString(SSL_CIPHERS_NAME, getSSLCiphers()));
+    props.setProperty(SSL_REQUIRE_AUTHENTICATION_NAME, toString(SSL_REQUIRE_AUTHENTICATION_NAME, isSSLAuthenticationRequired()));
+
+    Properties sslProps = getSSLProperties();
+    if (sslProps.size() > 0) {
+      int sequence = 0;
+      for (Iterator iter = sslProps.keySet().iterator(); iter.hasNext();) {
+        String key = (String) iter.next();
+        String value = sslProps.getProperty(key);
+        props.setProperty("ssl-property-" + sequence, key+"="+OBFUSCATED_STRING);
+        sequence++;
+      }
+    }
+
+    if (this.getDistributionLocatorConfigs().length > 0) {
+      DistributionLocatorConfig[] configs =
+        this.getDistributionLocatorConfigs();
+      for (int i = 0; i < configs.length; i++) {
+        DistributionLocatorConfig locator = configs[i];
+        props.setProperty(LOCATOR_HOST_NAME + i, toString(LOCATOR_HOST_NAME, locator.getHost()));
+        props.setProperty(LOCATOR_PORT_NAME + i, toString(LOCATOR_PORT_NAME, locator.getPort()));
+        props.setProperty(LOCATOR_PRODUCT_DIRECTORY_NAME + i, toString(LOCATOR_PRODUCT_DIRECTORY_NAME, locator.getProductDirectory()));
+        props.setProperty(LOCATOR_WORKING_DIRECTORY_NAME + i, toString(LOCATOR_WORKING_DIRECTORY_NAME, locator.getWorkingDirectory()));
+        props.setProperty(LOCATOR_REMOTE_COMMAND + i, toString(LOCATOR_REMOTE_COMMAND, locator.getRemoteCommand()));
+        props.setProperty(LOCATOR_BIND_ADDRESS + i, toString(LOCATOR_BIND_ADDRESS, locator.getBindAddress()));
+//        props.setProperty(LOCATOR_DS_PROPERTIES + i,
+//                          getdsPropertiesString(locator));
+      }
+    }
+
+    if (includeDSProperties) {
+      props.setProperty(ENTITY_CONFIG_XML_FILE_NAME, toString(ENTITY_CONFIG_XML_FILE_NAME, getEntityConfigXMLFile()));
+      // This could be different each time agent is started
+//       props.setProperty(SYSTEM_ID_NAME, toString(getSystemId()));
+      props.setProperty(MCAST_PORT_NAME, toString(MCAST_PORT_NAME, getMcastPort()));
+      props.setProperty(MCAST_ADDRESS_NAME, toString(MCAST_ADDRESS_NAME, getMcastAddress()));
+      props.setProperty(LOCATORS_NAME, toString(LOCATORS_NAME, getLocators()));
+      props.setProperty(MEMBERSHIP_PORT_RANGE_NAME, getMembershipPortRange());
+      props.setProperty(TCP_PORT_NAME, ""+getTcpPort());
+      props.setProperty(BIND_ADDRESS_NAME, toString(BIND_ADDRESS_NAME, getBindAddress()));
+      props.setProperty(REMOTE_COMMAND_NAME, toString(REMOTE_COMMAND_NAME, getRemoteCommand()));
+      props.setProperty(LOG_FILE_NAME, toString(LOG_FILE_NAME, getLogFile()));
+      props.setProperty(LOG_LEVEL_NAME, toString(LOG_LEVEL_NAME, getLogLevel()));
+      props.setProperty(LOG_DISK_SPACE_LIMIT_NAME, toString(LOG_DISK_SPACE_LIMIT_NAME, getLogDiskSpaceLimit()));
+      props.setProperty(LOG_FILE_SIZE_LIMIT_NAME, toString(LOG_FILE_SIZE_LIMIT_NAME, getLogFileSizeLimit()));
+      props.setProperty(REFRESH_INTERVAL_NAME, toString(REFRESH_INTERVAL_NAME, getRefreshInterval()));
+    }
+
+    return props;
+  }
+
+
+  /* return a string with the given locator's distributed system property
+      settings */
+  /*public String getdsPropertiesString(DistributionLocatorConfig locator) {
+    Properties props = locator.getDistributedSystemProperties();
+    if (props != null) {
+      final StringBuffer sb = new StringBuffer(30);
+      OutputStream os = new OutputStream() {
+        @Override
+        public void write(int i) {
+          sb.append((char)i);
+        }
+      };
+      try {
+        props.store(os, "");
+        os.flush();
+      } catch (java.io.IOException io) {
+        getLogWriter().warning(io);
+      } finally {
+        try {
+          os.close();
+        } catch (IOException e) {
+          getLogWriter().warning(e);
+        }
+      }
+      return sb.toString();
+    }
+    return "";
+  }*/
+
+  // -------------------------------------------------------------------------
+  //   Agent specific properties
+  // -------------------------------------------------------------------------
+
+  public boolean isAgentSSLEnabled() {
+    return this.agentSSLEnabled;
+  }
+
+  public void setAgentSSLEnabled(boolean agentSSLEnabled) {
+    checkReadOnly();
+    this.agentSSLEnabled = agentSSLEnabled;
+    configChanged();
+  }
+
+  public String getAgentSSLProtocols() {
+    return this.agentSSLProtocols;
+  }
+
+  public void setAgentSSLProtocols(String agentSSLProtocols) {
+    checkReadOnly();
+    this.agentSSLProtocols = agentSSLProtocols;
+    configChanged();
+  }
+
+  public String getAgentSSLCiphers() {
+    return this.agentSSLCiphers;
+  }
+
+  public void setAgentSSLCiphers(String agentSSLCiphers) {
+    checkReadOnly();
+    this.agentSSLCiphers = agentSSLCiphers;
+    configChanged();
+  }
+
+  public boolean isAgentSSLRequireAuth() {
+    return this.agentSSLRequireAuth;
+  }
+
+  public void setAgentSSLRequireAuth(boolean agentSSLRequireAuth) {
+    checkReadOnly();
+    this.agentSSLRequireAuth = agentSSLRequireAuth;
+    configChanged();
+  }
+
+  public boolean isHttpSSLRequireAuth() {
+    return this.httpSSLRequireAuth;
+  }
+
+  public void setHttpSSLRequireAuth(boolean httpSSLRequireAuth) {
+    checkReadOnly();
+    this.httpSSLRequireAuth = httpSSLRequireAuth;
+    configChanged();
+  }
+
+  public boolean isHttpAuthEnabled() {
+    return this.httpAuthEnabled;
+  }
+
+  public void setHttpAuthEnabled(boolean httpAuthEnabled) {
+    checkReadOnly();
+    this.httpAuthEnabled = httpAuthEnabled;
+    configChanged();
+  }
+
+  public String getHttpAuthUser() {
+    return this.httpAuthUser;
+  }
+
+  public void setHttpAuthUser(String httpAuthUser) {
+    checkReadOnly();
+    this.httpAuthUser = httpAuthUser;
+    configChanged();
+  }
+
+  public String getHttpAuthPassword() {
+    return this.httpAuthPassword;
+  }
+
+  public void setHttpAuthPassword(String httpAuthPassword) {
+    checkReadOnly();
+    this.httpAuthPassword = httpAuthPassword;
+    configChanged();
+  }
+
+  public boolean isSnmpEnabled() {
+    return this.snmpEnabled;
+  }
+
+  public void setSnmpEnabled(boolean snmpEnabled) {
+    checkReadOnly();
+    this.snmpEnabled = snmpEnabled;
+    configChanged();
+  }
+
+  public String getSnmpBindAddress() {
+    return this.snmpBindAddress;
+  }
+
+  public void setSnmpBindAddress(String snmpBindAddress) {
+    checkReadOnly();
+    this.snmpBindAddress = validateSnmpBindAddress(snmpBindAddress);
+    configChanged();
+  }
+
+  public String getSnmpDirectory() {
+    return this.snmpDirectory;
+  }
+
+  public void setSnmpDirectory(String snmpDirectory) {
+    checkReadOnly();
+    this.snmpDirectory = validateSnmpDirectory(snmpDirectory);
+    configChanged();
+  }
+
+  public boolean isRmiEnabled() {
+    return this.rmiEnabled;
+  }
+
+  public void setRmiEnabled(boolean rmiEnabled) {
+    checkReadOnly();
+    this.rmiEnabled = rmiEnabled;
+    configChanged();
+  }
+
+  public boolean isRmiRegistryEnabled() {
+    return this.rmiRegistryEnabled;
+  }
+
+  public void setRmiRegistryEnabled(boolean rmiRegistryEnabled) {
+    checkReadOnly();
+    this.rmiRegistryEnabled = rmiRegistryEnabled;
+    configChanged();
+  }
+
+  public String getRmiBindAddress() {
+    return this.rmiBindAddress;
+  }
+
+  public void setRmiBindAddress(String rmiBindAddress) {
+    checkReadOnly();
+    this.rmiBindAddress = validateRmiBindAddress(rmiBindAddress);
+    configChanged();
+  }
+
+  public int getRmiPort() {
+    return this.rmiPort;
+  }
+
+  public void setRmiPort(int rmiPort) {
+    checkReadOnly();
+    this.rmiPort = validateRmiPort(rmiPort);
+    configChanged();
+  }
+
+  /**
+   * Returns the port of the RMI Connector Server.
+   *
+   * See <a href="#rmi-server-port">description</a> above.
+   *
+   * @return the value set for rmi-server-port
+   * @since 6.5
+   */
+  public int getRmiServerPort() {
+    return this.rmiServerPort;
+  }
+
+  /**
+   * Sets the port of the RMI Connector Server.
+   *
+   * @param port rmi-server-port to set.
+   * @since 6.5
+   */
+  public void setRmiServerPort(int port) {
+    checkReadOnly();
+    this.rmiServerPort = validateRmiServerPort(rmiServerPort);
+    configChanged();
+  }
+
+  public boolean isHttpEnabled() {
+    return this.httpEnabled;
+  }
+
+  public void setHttpEnabled(boolean httpEnabled) {
+    checkReadOnly();
+    this.httpEnabled = httpEnabled;
+    configChanged();
+  }
+
+  public int getHttpPort() {
+    return this.httpPort;
+  }
+
+  public void setHttpPort(int httpPort) {
+    checkReadOnly();
+    this.httpPort = validateHttpPort(httpPort);
+    configChanged();
+  }
+
+  public String getHttpBindAddress() {
+    return this.httpBindAddress;
+  }
+
+  public void setHttpBindAddress(String httpBindAddress) {
+    checkReadOnly();
+    this.httpBindAddress = validateHttpBindAddress(httpBindAddress);
+    configChanged();
+  }
+
+  public void setHttpBindAddress(InetAddress httpBindAddress) {
+    checkReadOnly();
+    this.httpBindAddress = validateHttpBindAddress(httpBindAddress);
+    configChanged();
+  }
+
+  public boolean getAutoConnect() {
+    return this.autoConnect;
+  }
+
+  public void setAutoConnect(boolean v) {
+    checkReadOnly();
+    this.autoConnect = v;
+    configChanged();
+  }
+
+  // -------------------------------------------------------------------------
+  //   Implementation methods
+  // -------------------------------------------------------------------------
+
+  /**
+   * Initialize the values of this AgentConfig.
+   *
+   * @param props the configuration values to use
+   */
+  private void initialize(Properties props) {
+    this.autoConnect = validateBoolean(props.getProperty(
+        AUTO_CONNECT_NAME),
+        DEFAULT_AUTO_CONNECT);
+
+    this.httpEnabled = validateBoolean(props.getProperty(
+        HTTP_ENABLED_NAME),
+        DEFAULT_HTTP_ENABLED);
+    this.httpBindAddress = validateHttpBindAddress(props.getProperty(
+        HTTP_BIND_ADDRESS_NAME));
+    this.httpPort = validateHttpPort(props.getProperty(
+        HTTP_PORT_NAME));
+
+    this.rmiEnabled = validateBoolean(props.getProperty(
+        RMI_ENABLED_NAME),
+        DEFAULT_RMI_ENABLED);
+    this.rmiRegistryEnabled = validateBoolean(props.getProperty(
+        RMI_REGISTRY_ENABLED_NAME),
+        DEFAULT_RMI_REGISTRY_ENABLED);
+
+    this.rmiBindAddress = validateRmiBindAddress(props.getProperty(
+        RMI_BIND_ADDRESS_NAME));
+    this.rmiPort = validateRmiPort(props.getProperty(
+        RMI_PORT_NAME));
+    this.rmiServerPort = validateRmiServerPort(props.getProperty(
+        RMI_SERVER_PORT_NAME));
+
+    this.snmpEnabled = validateBoolean(props.getProperty(
+        SNMP_ENABLED_NAME),
+        DEFAULT_SNMP_ENABLED);
+    this.snmpDirectory = validateSnmpDirectory(props.getProperty(
+        SNMP_DIRECTORY_NAME));
+
+    this.agentSSLEnabled = validateBoolean(props.getProperty(
+        AGENT_SSL_ENABLED_NAME),
+        DEFAULT_AGENT_SSL_ENABLED);
+    this.agentSSLProtocols = validateNonEmptyString(props.getProperty(
+        AGENT_SSL_PROTOCOLS_NAME),
+        DEFAULT_AGENT_SSL_PROTOCOLS);
+    this.agentSSLCiphers = validateNonEmptyString(props.getProperty(
+        AGENT_SSL_CIPHERS_NAME),
+        DEFAULT_AGENT_SSL_CIPHERS);
+    this.agentSSLRequireAuth = validateBoolean(props.getProperty(
+        AGENT_SSL_REQUIRE_AUTHENTICATION_NAME),
+        DEFAULT_AGENT_SSL_REQUIRE_AUTHENTICATION);
+    this.httpSSLRequireAuth = validateBoolean(props.getProperty(
+        HTTP_SSL_REQUIRE_AUTHENTICATION_NAME),
+        DEFAULT_HTTP_SSL_REQUIRE_AUTHENTICATION);
+
+    this.httpAuthEnabled = validateBoolean(props.getProperty(
+        HTTP_AUTHENTICATION_ENABLED_NAME),
+        DEFAULT_HTTP_AUTHENTICATION_ENABLED);
+    this.httpAuthUser = validateNonEmptyString(props.getProperty(
+        HTTP_AUTHENTICATION_USER_NAME),
+        DEFAULT_HTTP_AUTHENTICATION_USER);
+    this.httpAuthPassword = validateNonEmptyString(props.getProperty(
+        HTTP_AUTHENTICATION_PASSWORD_NAME),
+        DEFAULT_HTTP_AUTHENTICATION_PASSWORD);
+
+    this.sslEnabled = validateBoolean(props.getProperty(
+        SSL_ENABLED_NAME),
+        DEFAULT_SSL_ENABLED);
+    this.sslProtocols = validateNonEmptyString(props.getProperty(
+        SSL_PROTOCOLS_NAME),
+        DEFAULT_SSL_PROTOCOLS);
+    this.sslCiphers = validateNonEmptyString(props.getProperty(
+        SSL_CIPHERS_NAME),
+        DEFAULT_SSL_CIPHERS);
+    this.sslAuthenticationRequired = validateBoolean(props.getProperty(
+        SSL_REQUIRE_AUTHENTICATION_NAME),
+        DEFAULT_SSL_REQUIRE_AUTHENTICATION);
+    this.sslProperties = new Properties();
+    for (int i = 0; true; i++) {
+      String key = "ssl-property-"+i;
+      String value = props.getProperty(key);
+      if (value == null) break;
+      StringTokenizer st = new StringTokenizer(value, "=");
+      if (!st.hasMoreTokens()) break;
+      String propKey = st.nextToken();
+      if (!st.hasMoreTokens()) break;
+      String propValue = st.nextToken();
+      this.sslProperties.put(propKey, propValue);
+    }
+
+    this.isEmailNotificationEnabled = validateBoolean(props.getProperty(
+            AgentConfig.EMAIL_NOTIFICATIONS_ENABLED_NAME),
+            DEFAULT_EMAIL_NOTIFICATIONS_ENABLED);
+    this.emailNotificationHostName= validateNonEmptyString(props.getProperty(
+    		AgentConfig.EMAIL_NOTIFICATIONS_HOST_NAME),
+            DEFAULT_EMAIL_HOST);
+    this.emailNotificationFrom= validateNonEmptyString(props.getProperty(
+    		AgentConfig.EMAIL_NOTIFICATIONS_FROM_NAME),
+            DEFAULT_EMAIL_FROM);
+    this.emailNotificationToList= validateNonEmptyString(props.getProperty(
+    		AgentConfig.EMAIL_NOTIFICATIONS_TO_LIST_NAME),
+            DEFAULT_EMAIL_TO_LIST);
+
+    this.stateSaveFile = validateNonEmptyString(props.getProperty(
+    		AgentConfig.STATE_SAVE_FILE_NAME),
+            DEFAULT_STATE_SAVE_FILE);
+
+    try {
+      for (int i = 0; true; i++) {
+        String hostProp = props.getProperty(LOCATOR_HOST_NAME + i);
+        if (isEmpty(hostProp)) break;
+        String host = hostProp;
+        int port = Integer.parseInt(
+            props.getProperty(LOCATOR_PORT_NAME + i));
+        File workDir = validateWorkingDirectory(
+            props.getProperty(LOCATOR_WORKING_DIRECTORY_NAME + i));
+        File prodDir = new File(validateProductDirectory(
+            props.getProperty(LOCATOR_PRODUCT_DIRECTORY_NAME + i)));
+        String remoteCmd =
+            props.getProperty(LOCATOR_REMOTE_COMMAND + i);
+        String bindAddr =
+            props.getProperty(LOCATOR_BIND_ADDRESS + i);
+
+        DistributionLocatorConfig config =
+          this.createDistributionLocatorConfig();
+        config.setHost(host);
+        config.setPort(port);
+        config.setBindAddress(bindAddr);
+        config.setWorkingDirectory(workDir.getAbsolutePath());
+        config.setProductDirectory(prodDir.getAbsolutePath());
+        config.setRemoteCommand(remoteCmd);
+      }
+    } catch (IllegalArgumentException e) {
+      // This is how we break out of the loop?  Yuck!
+      /*
+       * LogWriter is initialized afterwards. Hence printing the stack trace.
+       * This is done to avoid creation of duplicate log writer.
+       */
+      e.printStackTrace();
+    }
+  }
+
+  /**
+   * Filter all agent configuration attributes out of the given <code>Properties</code> object.
+   * <p/>
+   * @param props the <code>Properties</code> object of filter agent configuration attributes out of.
+   * @see AgentConfigImpl#_getPropertyDescription(String)
+   */
+  private static Properties filterOutAgentProperties(final Properties props) {
+    final Properties filteredProps = new Properties();
+
+    for (final Object key : props.keySet()) {
+      if (_getPropertyDescription(key.toString()) == null) {
+        final String value = props.getProperty(key.toString());
+        if (value != null) {
+          filteredProps.setProperty(key.toString(), value);
+        }
+      }
+    }
+
+    appendLogFileProperty(filteredProps);
+
+    return filteredProps;
+  }
+
+  /**
+   * Appends the log-file property to the Properties object if set of properties does not already define the
+   * log-file property or the gemfire.agent.log-file property.
+   * <p/>
+   * @param props the <code>Properties</code> to append the log-file property to if the property does not exist.
+   */
+  private static void appendLogFileProperty(final Properties props) {
+    if (!(props.containsKey(DistributedSystemConfig.LOG_FILE_NAME)
+      || props.containsKey(SYSTEM_PROPERTY_PREFIX + DistributedSystemConfig.LOG_FILE_NAME)))
+    {
+      props.put(DistributedSystemConfig.LOG_FILE_NAME, DEFAULT_LOG_FILE);
+    }
+  }
+
+  /**
+   * Appends any additional property-file specified properties to the supplied
+   * Properties. If the supplied property overrides the property in the
+   * property-file, then property-file value is ignored. System Properties always
+   * override the supplied properties
+   * @return appendedProps Properties appened to from the property-file if any
+   */
+  private static Properties appendOptionalPropertyFileProperties(final Properties props) {
+    final URL url = getPropertyFileURL(retrievePropertyFile());
+    final Properties appendedProps = new Properties();
+
+    appendedProps.putAll(props);
+
+    // first, get any property values set in the optional property file
+    if (url != null) {
+      InputStream in = null;
+
+      try {
+        in = url.openStream();
+
+        final Properties agentPropertyFileProperties = new Properties();
+
+        agentPropertyFileProperties.load(in);
+
+        // don't let any properties from the file override those on the command-line
+        for (final Object key : agentPropertyFileProperties.keySet()) {
+          if (props.getProperty(key.toString()) == null) {
+            appendedProps.setProperty(key.toString(), agentPropertyFileProperties.getProperty(key.toString()));
+          }
+        }
+      }
+      catch (IOException e) {
+        throw new GemFireIOException(LocalizedStrings.AgentConfigImpl_FAILED_READING_0.toLocalizedString(
+          url.toString()), e);
+      }
+      finally {
+        IOUtils.close(in);
+      }
+    }
+
+    // last override values with those from the system properties
+    // TODO this is not exactly overriding!
+    for (final Object propSuffix : props.keySet()) {
+      final String key = SYSTEM_PROPERTY_PREFIX + propSuffix;
+      final String value = System.getProperty(key);
+
+      if (value != null) {
+        appendedProps.put(key, value);
+      }
+    }
+
+    return appendedProps;
+  }
+
+  /**
+   * Returns a description of the given agent config property
+   *
+   * @throws IllegalArgumentException
+   *         If <code>prop</code> is not a recognized agent
+   *         configuration property
+   */
+  public static String getPropertyDescription(String prop) {
+    if (prop.equals(LOG_FILE_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_NAME_OF_THE_AGENTS_LOG_FILE.toLocalizedString();
+    } else if (prop.equals(LOG_LEVEL_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_MINIMUM_LEVEL_OF_LOGGING_PERFORMED_BY_AGENT.toLocalizedString();
+    } else if (prop.equals(AGENT_DEBUG)) {
+      return LocalizedStrings.AgentConfigImpl_WHETHER_THE_AGENT_SHOULD_PRINT_DEBUGGING_INFORMATION.toLocalizedString();
+    } else if (prop.equals(LOG_DISK_SPACE_LIMIT_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_LIMIT_IN_MEGABYTES_OF_HOW_MUCH_DISK_SPACE_CAN_BE_CONSUMED_BY_OLD_INACTIVE_LOG_FILES.toLocalizedString();
+    } else if (prop.equals(LOG_FILE_SIZE_LIMIT_NAME)) {
+      return  LocalizedStrings.AgentConfigImpl_LIMIT_IN_MEGABYTES_OF_HOW_LARGE_THE_CURRENT_STATISTIC_ARCHIVE_FILE_CAN_GROW_BEFORE_IT_IS_CLOSED_AND_ARCHIVAL_ROLLS_ON_TO_A_NEW_FILE.toLocalizedString();
+    } else if (prop.equals(MCAST_PORT_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_MULTICAST_PORT_USED_TO_CONNECT_TO_DISTRIBUTED_SYSTEM.toLocalizedString();
+    } else if (prop.equals(MCAST_ADDRESS_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_MULTICAST_ADDRESS_USED_TO_CONNECT_TO_DISTRIBUTED_SYSTEM.toLocalizedString();
+    } else if (prop.equals(BIND_ADDRESS_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_IP_ADDRESS_OF_THE_AGENTS_DISTRIBUTED_SYSTEM.toLocalizedString();
+    } else if (prop.equals(TCP_PORT_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_TCP_PORT.toLocalizedString();
+    } else if (prop.equals(LOCATORS_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_ADDRESSES_OF_THE_LOCATORS_OF_THE_DISTRIBUTED_SYSTEM.toLocalizedString();
+    } else if (prop.equals(MEMBERSHIP_PORT_RANGE_NAME)) {
+        return LocalizedStrings.AgentConfigImpl_ALLOWED_RANGE_OF_UDP_PORTS_TO_FORM_UNIQUE_MEMBERSHIP_ID.toLocalizedString();
+//     } else if (prop.equals(SYSTEM_ID_NAME)) {
+//       return "The id of the distributed system";
+    } else if (prop.equals(ENTITY_CONFIG_XML_FILE_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_XML_CONFIGURATION_FILE_FOR_MANAGED_ENTITIES.toLocalizedString();
+    } else if (prop.equals(REFRESH_INTERVAL_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_REFRESH_INTERVAL_IN_SECONDS_FOR_AUTOREFRESH_OF_MEMBERS_AND_STATISTIC_RESOURCES.toLocalizedString();
+    } else if (prop.equals(REMOTE_COMMAND_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_COMMAND_PREFIX_USED_FOR_LAUNCHING_MEMBERS_OF_THE_DISTRIBUTED_SYSTEM.toLocalizedString();
+    } else if (prop.equals(SSL_ENABLED_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_DOES_THE_DISTRIBUTED_SYSTEM_COMMUNICATE_USING_SSL.toLocalizedString();
+    } else if (prop.equals(SSL_PROTOCOLS_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_SSL_PROTOCOLS_USED_TO_COMMUNICATE_WITH_DISTRIBUTED_SYSTEM.toLocalizedString();
+    } else if (prop.equals(SSL_CIPHERS_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_SSL_CIPHERS_USED_TO_COMMUNICATE_WITH_DISTRIBUTED_SYSTEM.toLocalizedString();
+    } else if (prop.equals(SSL_REQUIRE_AUTHENTICATION_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_DOES_CONNECTING_TO_THE_DISTRIBUTED_SYSTEM_REQUIRE_SSL_AUTHENTICATION.toLocalizedString();
+    } else {
+      String description = _getPropertyDescription(prop);
+      if (description == null) {
+        throw new IllegalArgumentException(LocalizedStrings.AgentConfigImpl_UNKNOWN_CONFIG_PROPERTY_0.toLocalizedString(prop));
+
+      } else {
+        return description;
+      }
+    }
+  }
+
+  /**
+   * Returns a description of the given agent config property or
+   * <code>null</code> if <code>prop</code> is not a recognized agent
+   * property.
+   */
+  public static String _getPropertyDescription(String prop) {
+    if (prop.equals(AUTO_CONNECT_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_WILL_THE_AGENT_AUTOMATICALLY_CONNECT_TO_THE_DISTRIBUTED_SYSTEM.toLocalizedString();
+
+//     } else if (prop.equals(SYSTEM_NAME_NAME)) {
+//       return "The logical name of the distributed system";
+
+    } else if (prop.equals(HTTP_ENABLED_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_WILL_THE_AGENT_START_THE_HTTP_JMX_ADAPTER.toLocalizedString();
+
+    } else if (prop.equals(HTTP_BIND_ADDRESS_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_BIND_ADDRESS_OF_HTTP_ADAPTERS_SOCKETS.toLocalizedString();
+
+    } else if (prop.equals(HTTP_PORT_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_THE_PORT_ON_WHICH_THE_HTTP_ADAPTER_WILL_BE_STARTED.toLocalizedString();
+
+    } else if (prop.equals(RMI_ENABLED_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_WILL_THE_AGENT_START_THE_RMI_JMX_ADAPTER.toLocalizedString();
+
+    } else if (prop.equals(RMI_REGISTRY_ENABLED_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_WILL_THE_AGENT_HOST_AN_RMI_REGISTRY.toLocalizedString();
+
+    } else if (prop.equals(RMI_BIND_ADDRESS_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_BIND_ADDRESS_OF_RMI_ADAPTERS_SOCKETS.toLocalizedString();
+
+    } else if (prop.equals(RMI_PORT_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_THE_PORT_ON_WHICH_TO_CONTACT_THE_RMI_REGISTER.toLocalizedString();
+
+    } else if (prop.equals(RMI_SERVER_PORT_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_THE_PORT_USED_TO_CONFIGURE_RMI_CONNECTOR_SERVER.toLocalizedString();
+
+    } else if (prop.equals(SNMP_ENABLED_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_WILL_THE_AGENT_START_THE_SNMP_JMX_ADAPTER.toLocalizedString();
+
+    } else if (prop.equals(SNMP_BIND_ADDRESS_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_BIND_ADDRESS_OF_SNMP_ADAPTERS_SOCKETS.toLocalizedString();
+
+    } else if (prop.equals(SNMP_DIRECTORY_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_THE_DIRECTORY_IN_WHICH_SNMP_CONFIGURATION_RESIDES.toLocalizedString();
+
+    } else if (prop.equals(AGENT_SSL_ENABLED_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_WILL_THE_AGENT_COMMUNICATE_USING_SSL.toLocalizedString();
+
+    } else if (prop.equals(AGENT_SSL_PROTOCOLS_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_THE_SSL_PROTOCOLS_USED_BY_THE_AGENT.toLocalizedString();
+
+    } else if (prop.equals(AGENT_SSL_CIPHERS_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_THE_SSL_CIPHERS_USED_BY_THE_AGENT.toLocalizedString();
+
+    } else if (prop.equals(AGENT_SSL_REQUIRE_AUTHENTICATION_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_WILL_THE_AGENT_REQUIRE_SSL_AUTHENTICATION.toLocalizedString();
+
+    } else if (prop.equals(HTTP_SSL_REQUIRE_AUTHENTICATION_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_WILL_THE_HTTP_ADAPTER_REQUIRE_SSL_AUTHENTICATION.toLocalizedString();
+
+    } else if (prop.equals(HTTP_AUTHENTICATION_ENABLED_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_WILL_THE_HTTP_JMX_ADAPTER_USE_HTTP_AUTHENTICATION.toLocalizedString();
+
+    } else if (prop.equals(HTTP_AUTHENTICATION_USER_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_THE_USER_NAME_FOR_AUTHENTICATION_IN_THE_HTTP_JMX_ADAPTER.toLocalizedString();
+
+    } else if (prop.equals(HTTP_AUTHENTICATION_PASSWORD_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_THE_PASSWORD_FOR_AUTHENTICATION_IN_THE_HTTP_JMX_ADAPTER.toLocalizedString();
+
+    } else if (prop.equals(PROPERTY_FILE_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_PROPERTY_FILE_FROM_WHICH_AGENT_READS_CONFIGURATION.toLocalizedString();
+
+    } else if (prop.equals(LOCATOR_HOST_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_HOST_ON_WHICH_THE_DISTRIBUTED_SYSTEMS_LOCATOR_RUNS.toLocalizedString();
+
+    } else if (prop.equals(LOCATOR_PORT_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_HOST_ON_WHICH_THE_DISTRIBUTED_SYSTEMS_LOCATOR_RUNS.toLocalizedString();
+
+    } else if (prop.equals(LOCATOR_PRODUCT_DIRECTORY_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_GEMFIRE_PRODUCT_DIRECTORY_USED_TO_LAUNCH_A_LOCATOR.toLocalizedString();
+
+    } else if (prop.equals(LOCATOR_WORKING_DIRECTORY_NAME)) {
+      return LocalizedStrings.AgentConfigImpl_DIRECTORY_IN_WHICH_A_LOCATOR_WILL_BE_LAUNCHED.toLocalizedString();
+
+    } else if (prop.equals(LOCATOR_REMOTE_COMMAND)) {
+      return LocalizedStrings.AgentConfigImpl_COMMAND_PREFIX_USED_WHEN_LAUNCHING_A_LOCATOR.toLocalizedString();
+
+    } else if (prop.equals(LOCATOR_BIND_ADDRESS)) {
+      return LocalizedStrings.AgentConfigImpl_IP_ADDRESS_TO_USE_WHEN_CONTACTING_LOCATOR.toLocalizedString();
+
+    } else if (prop.equals(LOCATOR_DS_PROPERTIES)) {
+      return LocalizedStrings.AgentConfigImpl_PROPERTIES_FOR_CONFIGURING_A_LOCATORS_DISTRIBUTED_SYSTEM.toLocalizedString();
+
+    } else if (prop.equals(EMAIL_NOTIFICATIONS_ENABLED_NAME)) {
+        return LocalizedStrings.AgentConfigImpl_IDENTIFY_IF_EMAIL_NOTIFICATIONS_ARE_ENABLED_OR_NOT.toLocalizedString();
+
+    } else if (prop.equals(EMAIL_NOTIFICATIONS_FROM_NAME)) {
+        return LocalizedStrings.AgentConfigImpl_IDENTIFY_THE_EMAIL_ADDRESS_USING_WHICH_EMAIL_NOTIFICATIONS_ARE_SENT.toLocalizedString();
+
+    } else if (prop.equals(EMAIL_NOTIFICATIONS_HOST_NAME)) {
+        return LocalizedStrings.AgentConfigImpl_IDENTIFY_THE_EMAIL_SERVER_HOST_USING_WHICH_EMAIL_NOTIFICATIONS_ARE_SENT.toLocalizedString();
+
+    } else if (prop.equals(EMAIL_NOTIFICATIONS_TO_LIST_NAME)) {
+        return LocalizedStrings.AgentConfigImpl_IDENTIFY_THE_COMMA_SEPARATED_EMAIL_ADDRESSES_LIST_TO_WHICH_EMAIL_NOTIFICATIONS_ARE_SENT.toLocalizedString();
+
+    } else if (prop.equals(STATE_SAVE_FILE_NAME)) {
+        return LocalizedStrings.AgentConfigImpl_IDENTIFY_THE_NAME_OF_THE_FILE_TO_BE_USED_FOR_SAVING_AGENT_STATE.toLocalizedString();
+
+    } else {
+      return null;
+    }
+  }
+
+  /**
+   * Parses the array of command-line arguments (format: key=value) into an
+   * instance of Properties.
+   *
+   * @param args the command-line arguments to convert into a Properties
+   */
+  private static Properties toProperties(String[] args) {
+    Properties props = new Properties();
+    // loop all args and pick out key=value pairs...
+    for (int i = 0; i < args.length; i++) {
+      // VM args...
+      if (args[i].startsWith("-J")) {
+        int eq = args[i].indexOf("=");
+        String key = args[i].substring(2, eq);
+        String value = args[i].substring(eq+1);
+        System.setProperty(key, value);
+      }
+
+      else if (args[i].indexOf(AGENT_DEBUG) > 0) {
+        int eq = args[i].indexOf("=");
+        String key = args[i].substring(2, eq);
+        String value = args[i].substring(eq+1);
+        System.setProperty(key, value);
+      }
+
+      // all other args
+      else if (args[i].indexOf("=") > 0) {
+        int eq = args[i].indexOf("=");
+        String key = args[i].substring(0, eq);
+        String value = args[i].substring(eq+1);
+        props.setProperty(key, value);
+      }
+    }
+
+    return props;
+  }
+
+  /** Returns the original command-line arguments. */
+  public String[] getOriginalArgs() {
+    return this.originalCmdLineArgs;
+  }
+
+  // -------------------------------------------------------------------------
+  //   Validation methods for configuration options
+  // -------------------------------------------------------------------------
+
+    /**
+   * Makes sure that the mcast port and locators are correct and
+   * consistent.
+   *
+   * @throws IllegalArgumentException
+   *         If configuration is not valid
+   */
+  @Override
+  public void validate() {
+    super.validate();
+
+    if (this.httpPort < 0 || this.httpPort > MAX_HTTP_PORT) {
+      throw new IllegalArgumentException(LocalizedStrings.AgentConfigImpl_0_MUST_BE_ZERO_OR_AN_INTEGER_BETWEEN_1_AND_2.toLocalizedString(new Object[] {HTTP_PORT_NAME, Integer.valueOf(MIN_HTTP_PORT), Integer.valueOf(MAX_HTTP_PORT)}));
+    }
+
+    if (this.rmiPort < 0 || this.rmiPort > MAX_RMI_PORT) {
+      throw new IllegalArgumentException(LocalizedStrings.AgentConfigImpl_0_MUST_BE_ZERO_OR_AN_INTEGER_BETWEEN_1_AND_2.toLocalizedString(new Object[] {RMI_PORT_NAME, Integer.valueOf(MIN_RMI_PORT), Integer.valueOf(MAX_RMI_PORT)}));
+    }
+
+    if (this.rmiServerPort < 0 || this.rmiServerPort > MAX_RMI_PORT) {
+      throw new IllegalArgumentException(LocalizedStrings.AgentConfigImpl_0_MUST_BE_ZERO_OR_AN_INTEGER_BETWEEN_1_AND_2.toLocalizedString(new Object[] {RMI_SERVER_PORT_NAME, Integer.valueOf(MIN_RMI_PORT), Integer.valueOf(MAX_RMI_PORT)}));
+    }
+
+  }
+
+  /** Returns defaultValue if value is empty. */
+  private String validateNonEmptyString(String value,
+                                        String defaultValue) {
+    return isEmpty(value) ? defaultValue : value;
+  }
+
+  /** Validates that systemHost can be used for an InetAddress. */
+  private String validateSystemHost(String systemHost) {
+    return InetAddressUtil.validateHost(systemHost);
+  }
+
+  /** Returns null if productDir is empty; else converts it to File. */
+  private String validateProductDirectory(String productDir) {
+    if (isEmpty(productDir)) {
+      return null;
+    }
+    return productDir;
+  }
+
+  /** Returns true if value parses as true; null value returns defaultValue. */
+  private boolean validateBoolean(String value, boolean defaultValue) {
+    if (isEmpty(value)) return defaultValue;
+    return Boolean.valueOf(value).booleanValue();
+  }
+
+  // HttpAdaptor property validators...
+
+  /**
+   * Returns {@link
+   * com.gemstone.gemfire.admin.jmx.AgentConfig#DEFAULT_HTTP_PORT}
+   * if httpPort is empty; else validates
+   * that it's an integer and returns the int form.
+   */
+  private int validateHttpPort(String val) {
+    if (isEmpty(val)) {
+      return DEFAULT_HTTP_PORT;
+    } else {
+      return validateHttpPort(Integer.parseInt(val));
+    }
+  }
+  /**
+   * Validates that httpPort is either zero or within the {@link
+   * com.gemstone.gemfire.admin.jmx.AgentConfig#MIN_HTTP_PORT} and {@link
+   * com.gemstone.gemfire.admin.jmx.AgentConfig#MAX_HTTP_PORT} values.
+   */
+  private int validateHttpPort(int val) {
+    if (val < 0 || val > MAX_HTTP_PORT) {
+      throw new IllegalArgumentException(LocalizedStrings.AgentConfigImpl_0_MUST_BE_ZERO_OR_AN_INTEGER_BETWEEN_1_AND_2.toLocalizedString(new Object[] {HTTP_PORT_NAME, Integer.valueOf(MIN_HTTP_PORT), Integer.valueOf(MAX_HTTP_PORT)}));
+    }
+    return val;
+  }
+
+  /**
+   * Returns {@link
+   * com.gemstone.gemfire.admin.jmx.AgentConfig#DEFAULT_HTTP_BIND_ADDRESS}
+   * unless httpBindAddress can be used to
+   * create a valid InetAddress.
+   */
+  private String validateHttpBindAddress(String val) {
+    String value = InetAddressUtil.validateHost(val);
+    if (value == null) {
+      return DEFAULT_HTTP_BIND_ADDRESS;
+    }
+    else {
+      return value;
+    }
+  }
+
+  /**
+   * Validates that httpBindAddress is not null and then returns the string form of it.
+   */
+  private String validateHttpBindAddress(InetAddress val) {
+    if (val == null) {
+      throw new IllegalArgumentException(LocalizedStrings.AgentConfigImpl_HTTPBINDADDRESS_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+    return toString("", val);
+  }
+
+  // SnmpAdaptor property validators...
+
+  /**
+   * Returns {@link
+   * com.gemstone.gemfire.admin.jmx.AgentConfig#DEFAULT_SNMP_BIND_ADDRESS}
+   * unless snmpBindAddress can be used to
+   * create a valid InetAddress.
+   */
+  private String validateSnmpBindAddress(String val) {
+    String value = InetAddressUtil.validateHost(val);
+    if (value == null) {
+      return DEFAULT_SNMP_BIND_ADDRESS;
+    }
+    else {
+      return value;
+    }
+  }
+
+//  /**
+//   * Validates that snmpBindAddress is not null and then returns the string form of it.
+//   */
+//  private String validateSnmpBindAddress(InetAddress snmpBindAddress) {
+//    if (snmpBindAddress == null) {
+//      throw new IllegalArgumentException("SnmpBindAddress must not be null");
+//    }
+//    return toString(snmpBindAddress);
+//  }
+
+  /**
+   * SnmpDirectory must be specified if SNMP is enabled.  This directory must
+   * also exist.
+   */
+  private String validateSnmpDirectory(String snmpDir) {
+    /*if (isSnmpEnabled() && isEmpty(snmpDir)) {
+      throw new IllegalArgumentException(LocalizedStrings.AgentConfigImpl_SNMPDIRECTORY_MUST_BE_SPECIFIED_BECAUSE_SNMP_IS_ENABLED.toLocalizedString());
+    }
+    File root new File(snmpDir);
+    if (!root.exists())
+      throw new IllegalArgumentException(LocalizedStrings.AgentConfigImpl_SNMPDIRECTORY_DOES_NOT_EXIST.toLocalizedString());
+    */
+
+    return snmpDir;
+  }
+
+  // RMIConnectorServer property validators...
+
+  /**
+   * Returns {@link com.gemstone.gemfire.admin.jmx.AgentConfig#DEFAULT_RMI_PORT}
+   * if rmiPort is empty; else validates
+   * that it's an integer and returns the int form.
+   */
+  private int validateRmiPort(String val) {
+    if (isEmpty(val)) {
+      return DEFAULT_RMI_PORT;
+    } else {
+      return validateRmiPort(Integer.parseInt(val));
+    }
+  }
+
+  /**
+   * Validates that rmiPort is either zero or within the {@link
+   * com.gemstone.gemfire.admin.jmx.AgentConfig#MIN_RMI_PORT}
+   * and {@link com.gemstone.gemfire.admin.jmx.AgentConfig#MAX_RMI_PORT}
+   * values.
+   */
+  private int validateRmiPort(int val) {
+    if (val < MIN_RMI_PORT || val > MAX_RMI_PORT) {
+      throw new IllegalArgumentException(LocalizedStrings.AgentConfigImpl_0_MUST_BE_ZERO_OR_AN_INTEGER_BETWEEN_1_AND_2.toLocalizedString(new Object[] {RMI_PORT_NAME, Integer.valueOf(MIN_RMI_PORT), Integer.valueOf(MAX_RMI_PORT)}));
+    }
+    return val;
+  }
+
+  /**
+   * Returns {@link com.gemstone.gemfire.admin.jmx.AgentConfig#DEFAULT_RMI_SERVER_PORT}
+   * if rmi-server-port is empty; else validates that it's an integer within the
+   * allowed range and returns the int form.
+   */
+  private int validateRmiServerPort(String val) {
+    if (isEmpty(val)) {
+      return DEFAULT_RMI_SERVER_PORT;
+    } else {
+      return validateRmiServerPort(Integer.parseInt(val));
+    }
+  }
+
+  /**
+   * Validates that rmiPort is either zero or within the {@link
+   * com.gemstone.gemfire.admin.jmx.AgentConfig#MIN_RMI_PORT}
+   * and {@link com.gemstone.gemfire.admin.jmx.AgentConfig#MAX_RMI_PORT}
+   * values.
+   */
+  private int validateRmiServerPort(int val) {
+    if (val < MIN_RMI_PORT || val > MAX_RMI_PORT) {
+      throw new IllegalArgumentException(LocalizedStrings.AgentConfigImpl_0_MUST_BE_ZERO_OR_AN_INTEGER_BETWEEN_1_AND_2.toLocalizedString(new Object[] {RMI_SERVER_PORT_NAME, Integer.valueOf(MIN_RMI_PORT), Integer.valueOf(MAX_RMI_PORT)}));
+    }
+    return val;
+  }
+
+  /**
+   * Returns {@link
+   * com.gemstone.gemfire.admin.jmx.AgentConfig#DEFAULT_RMI_BIND_ADDRESS}
+   * unless rmiBindAddress can be used to create a
+   * valid InetAddress.
+   */
+  private String validateRmiBindAddress(String val) {
+    String value = InetAddressUtil.validateHost(val);
+    if (value == null) {
+      return DEFAULT_RMI_BIND_ADDRESS;
+    }
+    else {
+      return value;
+    }
+  }
+//  /**
+//   * Validates that rmiBindAddress is not null and then returns the string form of it.
+//   */
+//  private String validateRmiBindAddress(InetAddress rmiBindAddress) {
+//    if (rmiBindAddress == null) {
+//      throw new IllegalArgumentException("RmiBindAddress must not be null");
+//    }
+//    return toString(rmiBindAddress);
+//  }
+
+  /** Validates working directory is not null or empty. */
+  private File validateWorkingDirectory(String workingDir) {
+    if (isEmpty(workingDir)) {
+      throw new IllegalArgumentException(LocalizedStrings.AgentConfigImpl_LOCATOR_WORKINGDIRECTORY_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+    return new File(workingDir);
+  }
+
+  // -------------------------------------------------------------------------
+  //   Static utility methods
+  // -------------------------------------------------------------------------
+
+  /**
+   * Gets an <code>URL</code> for the property file, if one can be found,
+   * that the create method would use to determine the systemName and
+   * product home.
+   * <p>
+   * The file will be searched for, in order, in the following locations:
+   * <ol>
+   * <li> the current directory
+   * <li> the home directory
+   * <li> the class path
+   * </ol>
+   * Only the first file found will be used.
+   *
+   * @return a <code>URL</code> that names the property file;
+   *         otherwise Null if no property file was found.
+   */
+  public static URL getPropertyFileURL(final String propFileLocation) {
+    File propFile = new File(propFileLocation);
+
+    // first, try the current directory...
+    if (propFile.exists()) {
+      propFile = IOUtils.tryGetCanonicalFileElseGetAbsoluteFile(propFile);
+
+      try {
+        return propFile.toURI().toURL();
+      }
+      catch (java.net.MalformedURLException ignore) {
+      }
+    }
+
+    // next, try the user's home directory...
+    if (propFileLocation != null && propFileLocation.length() > 0) {
+      propFile = new File(System.getProperty("user.home"), propFileLocation);
+
+      if (propFile.exists()) {
+        propFile = IOUtils.tryGetCanonicalFileElseGetAbsoluteFile(propFile);
+
+        try {
+          return propFile.toURI().toURL();
+        }
+        catch (java.net.MalformedURLException ignore) {
+        }
+      }
+    }
+
+    // finally, try the classpath...
+    return ClassPathLoader.getLatest().getResource(AgentConfigImpl.class, propFileLocation);
+  }
+
+  private static boolean okToDisplayPropertyValue(String attName) {
+    if (attName.startsWith(HTTP_AUTHENTICATION_USER_NAME)) {
+      return false;
+    }
+    if (attName.startsWith(HTTP_AUTHENTICATION_PASSWORD_NAME)) {
+      return false;
+    }
+    if (attName.startsWith(AGENT_SSL_PROTOCOLS_NAME)) {
+      return false;
+    }
+    if (attName.startsWith(AGENT_SSL_CIPHERS_NAME)) {
+      return false;
+    }
+    if (attName.toLowerCase().contains("javax.net.ssl")) {
+      return false;
+    }
+    if (attName.toLowerCase().contains("password")) {
+      return false;
+    }
+    return true;
+  }
+  
+  /**
+   * Returns string representation of the specified object with special
+   * handling for InetAddress.
+   *
+   * @param obj   the object to convert to string
+   * @return string representation of the specified object
+   */
+  private static String toString(String attName, java.lang.Object obj) {
+    if (okToDisplayPropertyValue(attName)) {
+      if (obj == null) return "";
+      if (obj instanceof InetAddress) {
+        return InetAddressUtil.toString(obj);
+      }
+      return obj.toString();
+    } else {
+      return OBFUSCATED_STRING;
+    }
+  }
+
+  /** Returns string representation of the int. */
+  private static String toString(String attName, int num) {
+    if (okToDisplayPropertyValue(attName)) {
+      return String.valueOf(num);
+    } else {
+      return OBFUSCATED_STRING;
+    }
+  }
+
+  /** Returns string representation of the boolean value. */
+  private static String toString(String attName, boolean v) {
+    if (okToDisplayPropertyValue(attName)) {
+      return String.valueOf(v);
+    } else {
+      return OBFUSCATED_STRING;
+    }
+  }
+
+  /** Returns true if the string is null or empty. */
+  public static boolean isEmpty(String string) {
+    return string == null || string.length() == 0;
+  }
+
+  // -------------------------------------------------------------------------
+  //   SSL support...
+  // -------------------------------------------------------------------------
+  private boolean sslEnabled = DEFAULT_SSL_ENABLED;
+  private String sslProtocols = DEFAULT_SSL_PROTOCOLS;
+  private String sslCiphers = DEFAULT_SSL_CIPHERS;
+  private boolean sslAuthenticationRequired = DEFAULT_SSL_REQUIRE_AUTHENTICATION;
+  private Properties sslProperties = new Properties();
+
+  @Override
+  public boolean isSSLEnabled() {
+    return this.sslEnabled;
+  }
+  @Override
+  public void setSSLEnabled(boolean enabled) {
+    this.sslEnabled = enabled;
+    configChanged();
+  }
+  @Override
+  public String getSSLProtocols() {
+    return this.sslProtocols;
+  }
+  @Override
+  public void setSSLProtocols(String protocols) {
+    this.sslProtocols = protocols;
+    configChanged();
+  }
+  @Override
+  public String getSSLCiphers() {
+    return this.sslCiphers;
+  }
+  @Override
+  public void setSSLCiphers(String ciphers) {
+    this.sslCiphers = ciphers;
+    configChanged();
+  }
+  @Override
+  public boolean isSSLAuthenticationRequired() {
+    return this.sslAuthenticationRequired;
+  }
+  @Override
+  public void setSSLAuthenticationRequired(boolean authRequired) {
+    this.sslAuthenticationRequired = authRequired;
+    configChanged();
+  }
+  @Override
+  public Properties getSSLProperties() {
+    return this.sslProperties;
+  }
+  @Override
+  public void setSSLProperties(Properties sslProperties) {
+    this.sslProperties = sslProperties;
+    if (this.sslProperties == null) {
+      this.sslProperties = new Properties();
+    }
+    configChanged();
+  }
+
+  public String getStateSaveFile() {
+	  return this.stateSaveFile;
+  }
+
+  public void setStateSaveFile(String file) {
+	  checkReadOnly();
+	  this.stateSaveFile = file;
+	  configChanged();
+  }
+
+  public boolean isEmailNotificationEnabled() {
+	  return this.isEmailNotificationEnabled;
+  }
+
+  public void setEmailNotificationEnabled(boolean enabled) {
+	  checkReadOnly();
+	  this.isEmailNotificationEnabled = enabled;
+	  configChanged();
+  }
+
+  public String getEmailNotificationFrom() {
+	  return this.emailNotificationFrom;
+  }
+
+  public void setEmailNotificationFrom(String emailID) {
+	  this.emailNotificationFrom = emailID;
+	  configChanged();
+  }
+
+  public String getEmailNotificationHost() {
+	  return this.emailNotificationHostName;
+  }
+
+  public void setEmailNotificationHost(String hostName) {
+	  this.emailNotificationHostName = hostName;
+	  configChanged();
+  }
+
+  public String getEmailNotificationToList() {
+	  return this.emailNotificationToList;
+  }
+
+  public void setEmailNotificationToList(String emailIDs) {
+	  this.emailNotificationToList = emailIDs;
+	  configChanged();
+  }
+
+  @Override
+  public Object clone() throws CloneNotSupportedException {
+    return super.clone();
+  }
+}
+


[39/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/GemFireHealthImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/GemFireHealthImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/GemFireHealthImpl.java
new file mode 100644
index 0000000..498cac6
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/GemFireHealthImpl.java
@@ -0,0 +1,527 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.admin.*;
+import com.gemstone.gemfire.internal.Assert;
+import com.gemstone.gemfire.internal.admin.*;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.*;
+
+/**
+ * Provides the implementation of the <code>GemFireHealth</code>
+ * administration API.  This class is responsible for {@linkplain
+ * GemFireVM#addHealthListener sending} the {@link
+ * GemFireHealthConfig}s to the remote member VM in which the health
+ * is calcualted.
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ */
+public class GemFireHealthImpl
+  implements GemFireHealth, JoinLeaveListener, HealthListener {
+
+  /** The distributed system whose health is being monitored */
+  private final GfManagerAgent agent;
+
+  /** The default configuration for checking GemFire health */
+  protected GemFireHealthConfig defaultConfig;
+
+  /** Maps the name of a host to its <code>GemFireHealthConfig</code>.
+   * Note that the mappings are created lazily. */
+  private final Map hostConfigs;
+
+  /** Maps the name of a host to all of the members
+   * (<code>GemFireVM</code>s) that run on that host. */
+  private final Map hostMembers;
+
+  /** The members that are known to be in {@link #OKAY_HEALTH}. */
+  private Collection okayHealth;
+
+  /** The members that are known to be in {@link #POOR_HEALTH}. */
+  private Collection poorHealth;
+
+  /** The overall health of GemFire */
+  private GemFireHealth.Health overallHealth;
+
+  /** Is this GemFireHealthImpl closed? */
+  private boolean isClosed;
+
+  /** The configuration specifying how the health of the distributed
+   * system should be computed.  */
+  protected volatile DistributedSystemHealthConfig dsHealthConfig;
+
+  /** Monitors the health of the entire distributed system */
+  private DistributedSystemHealthMonitor dsHealthMonitor = null;
+
+  /** The distributed system whose health is monitored by this
+   * <Code>GemFireHealth</code>. */
+  private final AdminDistributedSystem system;
+
+  
+  ///////////////////////  Constructors  ///////////////////////
+
+  /**
+   * Creates a new <code>GemFireHealthImpl</code> that monitors the
+   * health of member of the given distributed system.
+   */
+  protected GemFireHealthImpl(GfManagerAgent agent,
+                              AdminDistributedSystem system) {
+//     agent.getDM().getLogger().info("Creating GemFireHealthImpl",
+//                                    new Exception("Stack trace"));
+
+    this.agent = agent;
+    this.system = system;
+
+    this.hostConfigs = new HashMap();
+    this.hostMembers = new HashMap();
+    this.okayHealth = new HashSet();
+    this.poorHealth = new HashSet();
+    this.overallHealth = GOOD_HEALTH;
+    this.isClosed = false;
+
+    GemFireVM[] apps = this.agent.listApplications();
+    for (int i = 0; i < apps.length; i++) {
+      GemFireVM member = apps[i];
+      this.noteNewMember(member);
+    }
+
+    agent.addJoinLeaveListener(this);
+    setDefaultGemFireHealthConfig(createGemFireHealthConfig(null));
+    setDistributedSystemHealthConfig(createDistributedSystemHealthConfig());
+  }
+
+  @Override
+  public String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.append("closed=" + isClosed);
+    sb.append("; hostMembers=" + hostMembers);
+    sb.append("; okayHealth=" + okayHealth);
+    sb.append("; poorHealth=" + poorHealth);
+    sb.append("; overallHealth=" + overallHealth);
+    sb.append("; diagnosis=" + getDiagnosis());
+    return sb.toString();
+  }
+  //////////////////////  Instance Methods  //////////////////////
+
+  /**
+   * Returns the <code>DistributedSystem</code> whose health this
+   * <code>GemFireHealth</code> monitors.
+   */
+  public AdminDistributedSystem getDistributedSystem() {
+    return this.system;
+  }
+
+  /**
+   * A "template factory" method for creating a
+   * <code>DistributedSystemHealthConfig</code>. It can be overridden
+   * by subclasses to produce instances of different
+   * <code>DistributedSystemHealthConfig</code> implementations.
+   */
+  protected DistributedSystemHealthConfig
+    createDistributedSystemHealthConfig() {
+
+    return new DistributedSystemHealthConfigImpl();
+  }
+
+  /**
+   * A "template factory" method for creating a
+   * <code>GemFireHealthConfig</code>.  It can be overridden by
+   * subclasses to produce instances of different
+   * <code>GemFireHealthConfig</code> implementations.
+   *
+   * @param hostName
+   *        The host whose health we are configuring
+   */
+  protected GemFireHealthConfig
+    createGemFireHealthConfig(String hostName) {
+
+    return new GemFireHealthConfigImpl(hostName);
+  }
+
+  /**
+   * Throws an {@link IllegalStateException} if this
+   * <code>GemFireHealthImpl</code> is closed.
+   */
+  private void checkClosed() {
+    if (this.isClosed) {
+      throw new IllegalStateException(LocalizedStrings.GemFireHealthImpl_CANNOT_ACCESS_A_CLOSED_GEMFIREHEALTH_INSTANCE.toLocalizedString());
+    }
+  }
+
+  /**
+   * Returns the overall health of GemFire.  Note that this method
+   * does not contact any of the member VMs.  Instead, it relies on
+   * the members to alert it of changes in its health via a {@link
+   * HealthListener}.
+   */
+  public GemFireHealth.Health getHealth() {
+    checkClosed();
+    return this.overallHealth;
+  }
+
+  /**
+   * Resets the overall health to be {@link #GOOD_HEALTH}.  It also
+   * resets the health in the member VMs.
+   *
+   * @see GemFireVM#resetHealthStatus
+   */
+  public void resetHealth() {
+    checkClosed();
+
+    this.overallHealth = GOOD_HEALTH;
+    this.okayHealth.clear();
+    this.poorHealth.clear();
+
+    synchronized (this) {
+      for (Iterator iter = hostMembers.values().iterator();
+           iter.hasNext(); ) {
+        List members = (List) iter.next();
+        for (Iterator iter2 = members.iterator(); iter2.hasNext(); ) {
+          GemFireVM member = (GemFireVM) iter2.next();
+          member.resetHealthStatus();
+        }
+      }
+    }
+  }
+
+  /**
+   * Aggregates the diagnoses from all members of the distributed
+   * system. 
+   */
+  public String getDiagnosis() {
+    checkClosed();
+
+    StringBuffer sb = new StringBuffer();
+
+    synchronized (this) {
+      for (Iterator iter = hostMembers.values().iterator();
+           iter.hasNext(); ) {
+        List members = (List) iter.next();
+        for (Iterator iter2 = members.iterator(); iter2.hasNext(); ) {
+          GemFireVM member = (GemFireVM) iter2.next();
+          String[] diagnoses =
+            member.getHealthDiagnosis(this.overallHealth);
+          for (int i = 0; i < diagnoses.length; i++) {
+            sb.append(diagnoses[i]).append("\n");;
+          }
+        }
+      }
+    }
+
+    return sb.toString();
+  }
+
+  /**
+   * Starts a new {@link DistributedSystemHealthMonitor}
+   */
+  public void setDistributedSystemHealthConfig(DistributedSystemHealthConfig
+                                               config) {
+    synchronized (this.hostConfigs) {
+      // If too many threads are changing the health config, then we
+      // will might get an OutOfMemoryError trying to start a new
+      // health monitor thread.
+
+      if (this.dsHealthMonitor != null) {
+        this.dsHealthMonitor.stop();
+      }
+
+      this.dsHealthConfig = config;
+
+      DistributedSystemHealthEvaluator eval =
+        new DistributedSystemHealthEvaluator(config, this.agent.getDM());
+      int interval =
+        this.getDefaultGemFireHealthConfig().getHealthEvaluationInterval();
+      this.dsHealthMonitor =
+        new DistributedSystemHealthMonitor(eval, this, interval);
+      this.dsHealthMonitor.start();
+    }
+  }
+
+  public DistributedSystemHealthConfig
+    getDistributedSystemHealthConfig() {
+
+    checkClosed();
+    return this.dsHealthConfig;
+  }
+
+  public GemFireHealthConfig getDefaultGemFireHealthConfig() {
+    checkClosed();
+    return this.defaultConfig;
+  }
+
+  public void setDefaultGemFireHealthConfig(GemFireHealthConfig config) {
+    checkClosed();
+
+    if (config.getHostName() != null) {
+      throw new IllegalArgumentException(LocalizedStrings.GemFireHealthImpl_THE_GEMFIREHEALTHCONFIG_FOR_FOR_0_CANNOT_SERVE_AS_THE_DEFAULT_HEALTH_CONFIG.toLocalizedString(config.getHostName()));
+    }
+
+    this.defaultConfig = config;
+
+    synchronized (this) {
+      for (Iterator iter = this.hostMembers.entrySet().iterator();
+           iter.hasNext(); ) {
+        Map.Entry entry = (Map.Entry) iter.next();
+        InetAddress hostIpAddress = (InetAddress) entry.getKey();
+        List members = (List) entry.getValue();
+
+        GemFireHealthConfig hostConfig =
+          (GemFireHealthConfig) hostConfigs.get(hostIpAddress);
+        if (hostConfig == null) {
+          hostConfig = config;
+        }
+
+        for (Iterator iter2 = members.iterator(); iter2.hasNext(); ) {
+          GemFireVM member = (GemFireVM) iter2.next();
+          Assert.assertTrue(member.getHost().equals(hostIpAddress));
+          member.addHealthListener(this, hostConfig);
+        }
+      }
+    }
+
+    // We only need to do this if the health monitoring interval has
+    // change.  This is probably not the most efficient way of doing
+    // things.
+    if (this.dsHealthConfig != null) {
+      setDistributedSystemHealthConfig(this.dsHealthConfig);
+    }
+  }
+
+  /**
+   * Returns the GemFireHealthConfig object for the given host name.
+   * 
+   * @param hostName
+   *          host name for which the GemFire Health Config is needed
+   * 
+   * @throws IllegalArgumentException
+   *           if host with given name could not be found
+   */
+  public synchronized GemFireHealthConfig
+    getGemFireHealthConfig(String hostName){
+
+    checkClosed();
+
+    InetAddress hostIpAddress = null;
+    try {
+      hostIpAddress = InetAddress.getByName(hostName);
+    } catch (UnknownHostException e) {
+      throw new IllegalArgumentException(
+          LocalizedStrings.GemFireHealthImpl_COULD_NOT_FIND_A_HOST_WITH_NAME_0
+              .toLocalizedString(hostName), e);
+    }
+    
+    GemFireHealthConfig config =
+      (GemFireHealthConfig) this.hostConfigs.get(hostIpAddress);
+    if (config == null) {
+      config = createGemFireHealthConfig(hostName);
+      this.hostConfigs.put(hostIpAddress, config);
+    }
+
+    return config;
+  }
+
+  /**
+   * Sets the GemFireHealthConfig object for the given host name.
+   * 
+   * @param hostName
+   *          host name for which the GemFire Health Config is needed
+   * @param config
+   *          GemFireHealthConfig object to set
+   * 
+   * @throws IllegalArgumentException
+   *           if (1) given host name & the host name in the given config do not
+   *           match OR (2) host with given name could not be found OR (3) there
+   *           are no GemFire components running on the given host
+   */
+  public void setGemFireHealthConfig(String hostName,
+                                     GemFireHealthConfig config) {
+    checkClosed();
+
+    synchronized (this) {
+      String configHost = config.getHostName();
+      if (configHost == null || !configHost.equals(hostName)) {
+        StringBuffer sb = new StringBuffer();
+        sb.append("The GemFireHealthConfig configures ");
+        if (configHost == null) {
+          sb.append("the default host ");
+
+        } else {
+          sb.append("host \"");
+          sb.append(config.getHostName());
+          sb.append("\" ");
+        }
+        sb.append("not \"" + hostName + "\"");
+        throw new IllegalArgumentException(sb.toString());
+      }
+      InetAddress hostIpAddress = null;
+      try {
+        hostIpAddress = InetAddress.getByName(hostName);
+      } catch (UnknownHostException e) {
+        throw new IllegalArgumentException(
+            LocalizedStrings.GemFireHealthImpl_COULD_NOT_FIND_A_HOST_WITH_NAME_0
+                .toLocalizedString(hostName), e);
+      }
+      
+      List members = (List) this.hostMembers.get(hostIpAddress);
+      if (members == null || members.isEmpty()) {
+        throw new IllegalArgumentException(
+            LocalizedStrings.GemFireHealthImpl_THERE_ARE_NO_GEMFIRE_COMPONENTS_ON_HOST_0
+                .toLocalizedString(hostName));
+      }
+
+      for (Iterator iter = members.iterator(); iter.hasNext(); ) {
+        GemFireVM member = (GemFireVM) iter.next();
+        member.addHealthListener(this, config);
+      }
+    }
+  }
+
+  /**
+   * Tells the members of the distributed system that we are no longer
+   * interested in monitoring their health.
+   *
+   * @see GemFireVM#removeHealthListener
+   */
+  public void close(){
+    this.agent.removeJoinLeaveListener(this);
+    
+    synchronized (this) {
+      if (this.isClosed) {
+        return;
+      }
+
+      this.isClosed = true;
+
+      if (this.dsHealthMonitor != null) {
+        this.dsHealthMonitor.stop();
+        this.dsHealthMonitor = null;
+      }
+
+      try {
+        for (Iterator iter = hostMembers.values().iterator();
+             iter.hasNext(); ) {
+          List members = (List) iter.next();
+          for (Iterator iter2 = members.iterator(); iter2.hasNext(); ) {
+            GemFireVM member = (GemFireVM) iter2.next();
+            member.removeHealthListener();
+          }
+        }
+      } catch (CancelException e) {
+        // if the DS is disconnected, stop trying to distribute to other members
+      }
+
+      hostConfigs.clear();
+      hostMembers.clear();
+      okayHealth.clear();
+      poorHealth.clear();
+    }
+  }
+
+  public boolean isClosed() {
+    return this.isClosed;
+  }
+
+  /**
+   * Makes note of the newly-joined member
+   */
+  private void noteNewMember(GemFireVM member) {
+    InetAddress hostIpAddress = member.getHost();
+    List members = (List) this.hostMembers.get(hostIpAddress);
+    if (members == null) {
+      members = new ArrayList();
+      this.hostMembers.put(hostIpAddress, members);
+    }
+    members.add(member);
+
+  }
+
+  public synchronized void nodeJoined(GfManagerAgent source,
+                                      GemFireVM joined) {
+    noteNewMember(joined);
+
+    InetAddress hostIpAddress = joined.getHost();
+
+    GemFireHealthConfig config =
+      (GemFireHealthConfig) this.hostConfigs.get(hostIpAddress);
+    if (config == null) {
+      config = this.getDefaultGemFireHealthConfig();
+    }
+    joined.addHealthListener(this, config);
+  }
+
+  /**
+   * Makes note of the newly-left member
+   */
+  public synchronized void nodeLeft(GfManagerAgent source,
+                                    GemFireVM left) {
+    InetAddress hostIpAddress = left.getHost();
+    List members = (List) this.hostMembers.get(hostIpAddress);
+    if (members != null) {
+      members.remove(left);
+      if (members.isEmpty()) {
+        // No more members on the host
+        this.hostConfigs.remove(hostIpAddress);
+        this.hostMembers.remove(hostIpAddress);
+      }
+    }
+
+    this.okayHealth.remove(left);
+    this.poorHealth.remove(left);
+
+    reevaluateHealth();
+  }
+
+  /**
+   * Does the same thing as {@link #nodeLeft}
+   */
+  public void nodeCrashed(GfManagerAgent source, GemFireVM crashed) {
+    nodeLeft(source, crashed);
+  }
+
+  /**
+   * Re-evaluates the overall health of GemFire
+   */
+  private void reevaluateHealth() {
+    if (!this.poorHealth.isEmpty()) {
+      this.overallHealth = POOR_HEALTH;
+
+    } else if (!this.okayHealth.isEmpty()) {
+      this.overallHealth = OKAY_HEALTH;
+
+    } else {
+      this.overallHealth = GOOD_HEALTH;
+    }
+  }
+
+  public void healthChanged(GemFireVM member, GemFireHealth.Health status) {
+    if (status == GOOD_HEALTH) {
+      this.okayHealth.remove(member);
+      this.poorHealth.remove(member);
+
+    } else if (status == OKAY_HEALTH) {
+      this.okayHealth.add(member);
+      this.poorHealth.remove(member);
+
+    } else if (status == POOR_HEALTH) {
+      this.okayHealth.remove(member);
+      this.poorHealth.add(member);
+
+    } else {
+      Assert.assertTrue(false, "Unknown health code: " + status);
+    }
+
+    reevaluateHealth();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/InetAddressUtil.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/InetAddressUtil.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/InetAddressUtil.java
new file mode 100755
index 0000000..3decb8d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/InetAddressUtil.java
@@ -0,0 +1,200 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Enumeration;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.GemFireIOException;
+import com.gemstone.gemfire.internal.Assert;
+import com.gemstone.gemfire.internal.SocketCreator;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+
+/**
+ * Provides static utilities for manipulating, validating, and converting
+ * InetAddresses and host strings.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ */
+public class InetAddressUtil {
+  
+  private static final Logger logger = LogService.getLogger();
+  
+  /** InetAddress instance representing the local host  */
+  public static final InetAddress LOCALHOST = createLocalHost();
+  
+  public static  final String LOOPBACK_ADDRESS =
+    Boolean.getBoolean("java.net.preferIPv6Addresses") ? "::1" : "127.0.0.1"; 
+  
+  public static final InetAddress LOOPBACK = 
+      InetAddressUtil.toInetAddress(LOOPBACK_ADDRESS);
+  
+  /** Disallows InetAddressUtil instantiation. */
+  private InetAddressUtil() {}
+
+  /** 
+   * Returns a string version of InetAddress which can be converted back to an 
+   * InetAddress later.  Essentially any leading slash is trimmed.
+   *
+   * @param val the InetAddress or String to return a formatted string of
+   * @return string version the InetAddress minus any leading slash
+   */
+  public static String toString(Object val) {
+    if (val instanceof String) {
+      return trimLeadingSlash((String) val);
+
+    } else if (val instanceof InetAddress) {
+      return ((InetAddress) val).getHostAddress();
+
+    } else {
+      return trimLeadingSlash(val.toString());
+    }
+  }
+  
+  /** 
+   * Converts the string host to an instance of InetAddress.  Returns null if
+   * the string is empty.  Fails Assertion if the conversion would result in
+   * <code>java.lang.UnknownHostException</code>.
+   * <p>
+   * Any leading slashes on host will be ignored.
+   *
+   * @param   host  string version the InetAddress
+   * @return  the host converted to InetAddress instance
+   */
+  public static InetAddress toInetAddress(String host) {
+    if (host == null || host.length() == 0) {
+      return null;
+    }
+    try {
+      if (host.indexOf("/") > -1) {
+        return InetAddress.getByName(host.substring(host.indexOf("/") + 1));
+      }
+      else {
+        return InetAddress.getByName(host);
+      }
+    } catch (java.net.UnknownHostException e) {
+      logStackTrace(e);
+      Assert.assertTrue(false, "Failed to get InetAddress: " + host);
+      return null; // will never happen since the Assert will fail
+    }
+  }
+
+  /** 
+   * Creates an InetAddress representing the local host.  The checked exception
+   * <code>java.lang.UnknownHostException</code> is captured and results in
+   * an Assertion failure instead.
+   *
+   * @return InetAddress instance representing the local host
+   */
+  public static InetAddress createLocalHost() {
+    try {
+      return SocketCreator.getLocalHost();
+    } catch (java.net.UnknownHostException e) {
+      logStackTrace(e);
+      Assert.assertTrue(false, "Failed to get local host");
+      return null; // will never happen
+    }
+  }
+
+  /** 
+   * Validates the host by making sure it can successfully be used to get an
+   * instance of InetAddress.  If the host string is null, empty or would result
+   * in <code>java.lang.UnknownHostException</code> then null is returned.
+   * <p>
+   * Any leading slashes on host will be ignored.
+   *
+   * @param   host  string version the InetAddress
+   * @return  the host converted to InetAddress instance
+   */
+  public static String validateHost(String host) {
+    if (host == null || host.length() == 0) {
+      return null; 
+    }
+    try {
+      InetAddress.getByName(trimLeadingSlash(host));
+      return host;
+    } catch (java.net.UnknownHostException e) { 
+      logStackTrace(e);
+      return null;
+    }
+  }
+
+  /** Returns true if host matches the LOCALHOST. */
+  public static boolean isLocalHost(Object host) {
+    if (host instanceof InetAddress) {
+      if (LOCALHOST.equals(host)) {
+        return true;
+      }
+      else {
+//        InetAddress hostAddr = (InetAddress)host;
+        try {
+          Enumeration en=NetworkInterface.getNetworkInterfaces();
+          while(en.hasMoreElements()) {
+            NetworkInterface i=(NetworkInterface)en.nextElement();
+            for(Enumeration en2=i.getInetAddresses(); en2.hasMoreElements();) {
+              InetAddress addr=(InetAddress)en2.nextElement();
+              if (host.equals(addr)) {
+                return true;
+              }
+            }
+          }
+          return false;
+        }
+        catch (SocketException e) {
+          throw new GemFireIOException(LocalizedStrings.InetAddressUtil_UNABLE_TO_QUERY_NETWORK_INTERFACE.toLocalizedString(), e);
+        }
+      }
+    }
+    else {
+      return isLocalHost(InetAddressUtil.toInetAddress(host.toString()));
+    }
+  }
+  
+  /** Returns true if host matches the LOOPBACK (127.0.0.1). */
+  public static boolean isLoopback(Object host) {
+    if (host instanceof InetAddress) {
+      return LOOPBACK.equals(host);
+    }
+    else {
+      return isLoopback(InetAddressUtil.toInetAddress(host.toString()));
+    }
+  }
+  
+  /** Returns a version of the value after removing any leading slashes */
+  private static String trimLeadingSlash(String value) {
+    if (value == null) return "";
+    while (value.indexOf("/") > -1) {
+      value = value.substring(value.indexOf("/") + 1);
+    }
+    return value;
+  }
+
+  /**
+   * Logs the stack trace for the given Throwable if logger is initialized else
+   * prints the stack trace using System.out. If logged the logs are logged at 
+   * WARNING level.
+   * 
+   * @param throwable
+   *          Throwable to log stack trace for
+   */
+  private static void logStackTrace(Throwable throwable) {
+    AdminDistributedSystemImpl adminDS = 
+                              AdminDistributedSystemImpl.getConnectedInstance();
+
+    logger.warn(throwable.getMessage(), throwable);
+  }  
+  
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/InternalManagedEntity.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/InternalManagedEntity.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/InternalManagedEntity.java
new file mode 100644
index 0000000..c93eddf
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/InternalManagedEntity.java
@@ -0,0 +1,97 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.AdminDistributedSystem;
+import com.gemstone.gemfire.admin.ManagedEntity;
+import com.gemstone.gemfire.admin.ManagedEntityConfig;
+
+/**
+ * Provides internal-only functionality that is expected of all
+ * <code>ManagedEntity<code>s.  This functionality is used by the
+ * {@link ManagedEntityController} to manage the entity.
+ *
+ * @author David Whitlock
+ * @since 4.0
+ */
+public interface InternalManagedEntity extends ManagedEntity {
+
+  /** The state of a managed entity is unknown. */
+  public static final int UNKNOWN = 10;
+
+  /** A managed entity is stopped */
+  public static final int STOPPED = 11;
+
+  /** A managed entity is stopping (being stopped) */
+  public static final int STOPPING = 12;
+
+  /** A managed entity is starting */
+  public static final int STARTING = 13;
+
+  /** A managed entity is running (is started) */
+  public static final int RUNNING = 14;
+
+  //////////////////////  Instance Methods  //////////////////////
+
+  /**
+   * Returns the <code>ManagedEntityConfig</code> for this
+   * <code>ManagedEntity</code>. 
+   */
+  public ManagedEntityConfig getEntityConfig();
+
+  /**
+   * Returns a brief description (such as "locator") of this managed
+   * entity. 
+   */
+  public String getEntityType();
+
+  /**
+   * Returns the (local) command to execute in order to start this
+   * managed entity.  The command includes the full path to the
+   * executable (include <code>$GEMFIRE/bin</code>) and any
+   * command-line arguments.  It does not take the {@linkplain
+   * ManagedEntityConfig#getRemoteCommand remote command} into account.
+   */
+  public String getStartCommand();
+
+  /**
+   * Returns the (local) command to execute in order to stop this
+   * managed entity.
+   */
+  public String getStopCommand();
+
+  /**
+   * Returns the (local) command to execute in order to determine
+   * whether or not this managed entity is runing.
+   */
+  public String getIsRunningCommand();
+
+  /**
+   * Returns a descriptive, one-word, unique id for a newly-created
+   * <code>ManagedEntity</code>.   This ensures that we do not have
+   * collisions in the ids of entities.
+   */
+  public String getNewId();
+
+  /**
+   * Returns the distributed system to which this managed entity
+   * belongs.
+   */
+  public AdminDistributedSystem getDistributedSystem();
+
+  /**
+   * Sets the state of this managed entity and informs threads that
+   * are waiting for a state change.  See bug 32455.
+   *
+   * @return The previous state of this managed entity.
+   *
+   * @see #RUNNING
+   */
+  public int setState(int state);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/LogCollator.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/LogCollator.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/LogCollator.java
new file mode 100755
index 0000000..061259c
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/LogCollator.java
@@ -0,0 +1,128 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.internal.admin.GfManagerAgent;
+import com.gemstone.gemfire.internal.admin.GemFireVM;
+import com.gemstone.gemfire.internal.admin.ApplicationVM;
+import com.gemstone.gemfire.internal.logging.MergeLogFiles;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;  
+import java.io.PrintWriter;  
+import java.io.StringWriter;  
+import java.util.ArrayList;
+import java.util.List;
+
+public class LogCollator {
+  
+  private GfManagerAgent system;
+  private List logTails;
+    
+  public LogCollator() {
+  }
+  
+  public String collateLogs(GfManagerAgent system) {
+    try {
+      if (system == null) {
+        return "";
+      }
+      this.system = system;
+      this.logTails = new ArrayList();
+      gatherActiveLogs();
+      gatherInactiveLogs();
+      return mergeLogs();
+    }
+    finally {
+      this.system = null;
+      this.logTails = null;
+    }
+  }
+
+  // -------------------------------------------------------------------------
+  
+  private String mergeLogs() {
+    // combine logs...
+    InputStream[] logFiles = new InputStream[this.logTails.size()];
+    String[] logFileNames = new String[logFiles.length];
+    for (int i = 0; i < this.logTails.size(); i++) {
+      Loglet loglet = (Loglet) this.logTails.get(i);
+      logFiles[i] = new ByteArrayInputStream(loglet.tail.getBytes());
+      logFileNames[i] = loglet.name;
+    }
+    
+    // delegate to MergeLogFiles...
+    StringWriter writer = new StringWriter();
+    PrintWriter mergedLog = new PrintWriter(writer);
+    if (!MergeLogFiles.mergeLogFiles(logFiles, logFileNames, mergedLog)) {
+      return writer.toString();
+    } 
+    else {
+      return "";
+    }
+  }
+
+  private void gatherActiveLogs() {
+    ApplicationVM[] runningsApps = this.system.listApplications();
+    for (int i = 0; i < runningsApps.length; i++) {
+      addLogFrom(runningsApps[i]);
+    }
+  }
+  
+  private void gatherInactiveLogs() {
+    /* not yet supported....
+    if (useStopped) {
+      LogViewHelper helper = new LogViewHelper();
+      for (Iterator iter = stoppedNodes.iterator(); iter.hasNext(); ) {
+        Object adminEntity = iter.next();
+        helper.setAdminEntity(adminEntity);
+        try {
+          if (helper.logViewAvailable()) {
+            String[] logs = helper.getSystemLogs();
+            addTail(allTails, logs, adminEntity.toString());
+          }
+        } catch (Exception e) {
+          Service.getService().reportSystemError(e);
+        }
+      }
+    }
+    */
+  }
+  
+  private void addLogFrom(GemFireVM vm) {
+    String name = null;
+    name = vm.toString();
+    String[] logs = vm.getSystemLogs();
+    addTail(name, logs);
+  }
+
+  private void addTail(String logName, String[] logs) {
+    if (logs.length > 0) {
+      String tail = (logs.length > 1) ? logs[1] : logs[0];      
+      this.logTails.add(new Loglet(logName, tail));
+    }
+  }
+
+  /*
+  public void setUseStoppedManagers(boolean useStopped) {
+    this.useStopped = useStopped;
+  }
+  */
+
+  private static class Loglet {
+    String name;
+    String tail;
+    Loglet(String name, String tail) {
+      this.name = name;
+      this.tail = tail;
+    }
+  }
+  
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityConfigImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityConfigImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityConfigImpl.java
new file mode 100644
index 0000000..9356175
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityConfigImpl.java
@@ -0,0 +1,254 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+//import com.gemstone.gemfire.admin.DistributedSystemConfig;
+//import com.gemstone.gemfire.admin.ManagedEntity;
+import com.gemstone.gemfire.admin.ManagedEntityConfig;
+import com.gemstone.gemfire.internal.admin.GemFireVM;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.GemFireVersion;
+import com.gemstone.gemfire.internal.SocketCreator;
+
+import java.io.File;
+import java.net.*;
+
+/**
+ * The abstract superclass of objects that configure a managed entity
+ * such as a GemFire cache server or a distribution locator.
+ * It contains configuration state and behavior common to all managed
+ * entities.
+ *
+ * @author David Whitlock
+ * @since 4.0
+ */
+public abstract class ManagedEntityConfigImpl
+  implements ManagedEntityConfig {
+
+  /** The name of the host on which the managed entity runs */
+  private String host;
+
+  /** Directory in which the locator runs */
+  private String workingDirectory;
+
+  /** The directory in which GemFire is installed */
+  private String productDirectory;
+
+  /** Command used to launch locator on remote machine */
+  private String remoteCommand;
+
+  /** The managed entity configured by this object.
+   *
+   * @see #isReadOnly */
+  private InternalManagedEntity entity = null;
+
+  /////////////////////  Static Methods  /////////////////////
+
+  /**
+   * Returns the {@linkplain InetAddress#getCanonicalHostName
+   * canonical name} of the local machine.
+   */
+  protected static String getLocalHostName() {
+    try {
+      return SocketCreator.getLocalHost().getCanonicalHostName();
+
+    } catch (UnknownHostException ex) {
+      IllegalStateException ex2 = new IllegalStateException(LocalizedStrings.ManagedEntityConfigImpl_COULD_NOT_DETERMINE_LOCALHOST.toLocalizedString());
+      ex2.initCause(ex);
+      throw ex2;
+    }
+  }
+
+  /**
+   * Returns the current working directory for this VM.
+   */
+  private static File getCurrentWorkingDirectory() {
+    File cwd = new File(System.getProperty("user.dir"));
+    return cwd.getAbsoluteFile();
+  }
+
+  /**
+   * Returns the location of the GemFire product installation.  This
+   * is determined by finding the location of the gemfire jar
+   * and working backwards.
+   */
+  private static File getGemFireInstallation() {
+    URL url = GemFireVersion.getJarURL();
+    if (url == null) {
+      throw new IllegalStateException(LocalizedStrings.ManagedEntityConfigImpl_COULD_NOT_FIND_GEMFIREJAR.toLocalizedString());
+    }
+
+    File gemfireJar = new File(url.getPath());
+    File lib = gemfireJar.getParentFile();
+    File product = lib.getParentFile();
+
+    return product;
+  }
+
+  //////////////////////  Constructors  //////////////////////
+
+  /**
+   * Creates a <code>ManagedEntityConfigImpl</code> with the default
+   * configuration.
+   */
+  protected ManagedEntityConfigImpl() {
+    this.host = getLocalHostName();
+    this.workingDirectory =
+      getCurrentWorkingDirectory().getAbsolutePath(); 
+    this.productDirectory =
+      getGemFireInstallation().getAbsolutePath();
+    this.remoteCommand = null;  // Delegate to AdminDistributedSystem
+  }
+
+  /**
+   * Creates a new <code>ManagedEntityConfigImpl</code> based on the
+   * configuration of a running <code>GemFireVM</code>
+   */
+  protected ManagedEntityConfigImpl(GemFireVM vm) {
+    this.host = SocketCreator.getHostName(vm.getHost());
+    this.workingDirectory = vm.getWorkingDirectory().getAbsolutePath();
+    this.productDirectory = vm.getGemFireDir().getAbsolutePath();
+    this.remoteCommand = null;
+  }
+
+  /**
+   * A copy constructor that creates a new
+   * <code>ManagedEntityConfigImpl</code> with the same configuration
+   * as another <code>ManagedEntityConfig</code>.
+   */
+  protected ManagedEntityConfigImpl(ManagedEntityConfig other) {
+    this.host = other.getHost();
+    this.workingDirectory = other.getWorkingDirectory();
+    this.productDirectory = other.getProductDirectory();
+    this.remoteCommand = other.getRemoteCommand();
+  }
+
+  ////////////////////  Instance Methods  ////////////////////
+
+  /**
+   * Checks to see if this config object is "read only".  If it is,
+   * then an {@link IllegalStateException} is thrown.  It should be
+   * called by every setter method.
+   *
+   * @see #isReadOnly
+   */
+  public void checkReadOnly() {
+    if (this.isReadOnly()) {
+      throw new IllegalStateException(LocalizedStrings.ManagedEntityConfigImpl_THIS_CONFIGURATION_CANNOT_BE_MODIFIED_WHILE_ITS_MANAGED_ENTITY_IS_RUNNING.toLocalizedString());
+    }
+  }
+
+  /**
+   * Returns whether or not this <code>ManagedEntityConfigImpl</code>
+   * is read-only (can be modified).
+   */
+  protected boolean isReadOnly() {
+    return this.entity != null && this.entity.isRunning();
+  }
+
+  /**
+   * Sets the entity that is configured by this config object.  Once
+   * the entity is running, the config object cannot be modified.
+   *
+   * @see #checkReadOnly
+   */
+  public void setManagedEntity(InternalManagedEntity entity) {
+    this.entity = entity;
+  }
+
+  /**
+   * Notifies any configuration listeners that this configuration has
+   * changed.
+   */
+  protected abstract void configChanged();
+
+  public String getHost() {
+    return this.host;
+  }
+
+  public void setHost(String host) {
+    checkReadOnly();
+    this.host = host;
+    configChanged();
+  }
+
+  public String getWorkingDirectory() {
+    String dir = this.workingDirectory;
+    return dir;
+  }
+
+  public void setWorkingDirectory(String workingDirectory) {
+    checkReadOnly();
+    this.workingDirectory = workingDirectory;
+    configChanged();
+  }
+
+  public String getProductDirectory() {
+    return this.productDirectory;
+  }
+
+  public void setProductDirectory(String productDirectory) {
+    checkReadOnly();
+    this.productDirectory = productDirectory;
+    configChanged();
+  }
+
+  public String getRemoteCommand() {
+    return this.remoteCommand;
+  }
+
+  public void setRemoteCommand(String remoteCommand) {
+    checkReadOnly();
+    this.remoteCommand = remoteCommand;
+    configChanged();
+  }
+
+  /**
+   * Validates this configuration.
+   *
+   * @throws IllegalStateException
+   *         If this config is not valid
+   */
+  public void validate() {
+    if (InetAddressUtil.validateHost(this.host) == null) {
+      throw new IllegalStateException(LocalizedStrings.ManagedEntityConfigImpl_INVALID_HOST_0.toLocalizedString(this.host));
+    }
+  }
+
+  @Override
+  public Object clone() throws CloneNotSupportedException {
+    // Since all fields are immutable objects, no deep cloning is
+    // necessary.
+    ManagedEntityConfigImpl clone =
+      (ManagedEntityConfigImpl) super.clone();
+    clone.entity = null;
+    return clone;
+  }
+
+  @Override
+  public String toString() {
+    String className = this.getClass().getName();
+    int index = className.lastIndexOf('.');
+    className = className.substring(index + 1);
+
+    StringBuffer sb = new StringBuffer();
+    sb.append(className);
+    
+    sb.append(" host=");
+    sb.append(this.getHost());
+    sb.append(" workingDirectory=");
+    sb.append(this.getWorkingDirectory());
+    sb.append(" productDirectory=");
+    sb.append(this.getProductDirectory());
+    sb.append(" remoteCommand=\"");
+    sb.append(this.getRemoteCommand());
+    sb.append("\"");
+
+    return sb.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityConfigXml.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityConfigXml.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityConfigXml.java
new file mode 100644
index 0000000..00b4116
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityConfigXml.java
@@ -0,0 +1,161 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.internal.ClassPathLoader;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import org.xml.sax.*;
+import java.io.*;
+
+/**
+ * The abstract superclass of classes that convert XML into a {@link
+ * com.gemstone.gemfire.admin.DistributedSystemConfig} and vice versa.
+ * It provides helper methods and constants.
+ *
+ * @author David Whitlock
+ * @since 4.0
+ */
+abstract class ManagedEntityConfigXml implements EntityResolver, ErrorHandler {
+
+  /** The location of the DTD file */
+  protected static final String DTD_LOCATION =
+    "/com/gemstone/gemfire/admin/doc-files/ds5_0.dtd";
+
+  /** The URL for the DTD */
+  protected static final String SYSTEM_ID =
+    "http://www.gemstone.com/dtd/ds5_0.dtd";
+
+  /** The public ID for the DTD */
+  protected static final String PUBLIC_ID = 
+    "-//GemStone Systems, Inc.//GemFire Distributed System 5.0//EN";
+
+  /** The name of the <code>distributed-system</code> element. */
+  public static final String DISTRIBUTED_SYSTEM =
+    "distributed-system";
+
+  /** The name of the <code>id</code> attribute. */
+  public static final String ID = "id";
+
+  /** The name of the <code>disable-tcp</code> attribute. */
+  public static final String DISABLE_TCP = "disable-tcp";
+
+  /** The name of the <code>remote-command</code> element. */
+  public static final String REMOTE_COMMAND = "remote-command";
+
+  /** The name of the <code>locators</code> element. */
+  public static final String LOCATORS = "locators";
+
+  /** The name of the <code>ssl</code> element. */
+  public static final String SSL = "ssl";
+
+  /** The name of the <code>cache-server</code> element */
+  public static final String CACHE_SERVER = "cache-server";
+
+  /** The name of the <code>multicast</code> element */
+  public static final String MULTICAST = "multicast";
+
+  /** The name of the <code>locator</code> element */
+  public static final String LOCATOR = "locator";
+
+  /** The name of the <code>port</code> attribute */
+  public static final String PORT = "port";
+
+  /** The name of the <code>address</code> attribute */
+  public static final String ADDRESS = "address";
+
+  /** The name of the <code>host</code> element. */
+  public static final String HOST = "host";
+
+  /** The name of the <code>working-directory</code> element */
+  public static final String WORKING_DIRECTORY = "working-directory";
+
+  /** The name of the <code>product-directory</code> element */
+  public static final String PRODUCT_DIRECTORY = "product-directory";
+
+  /** The name of the <code>protocols</code> element */
+  public static final String PROTOCOLS = "protocols";
+
+  /** The name of the <code>ciphers</code> element */
+  public static final String CIPHERS = "ciphers";
+
+  /** The name of the <code>property</code> element */
+  public static final String PROPERTY = "property";
+
+  /** Name of the <code>authentication-required</code> attribute */
+  public static final String AUTHENTICATION_REQUIRED =
+    "authentication-required";
+
+  /** The name of the <code>key</code> element */
+  public static final String KEY = "key";
+
+  /** The name of the <code>value</code> element */
+  public static final String VALUE = "value";
+  
+  /** The name of the <code>classpath</code> element */
+  public static final String CLASSPATH = "classpath";
+
+  ///////////////////////  Instance Methods  ///////////////////////
+
+  /**
+   * Given a public id, attempt to resolve it to a DTD.  Returns an
+   * <code>InputSoure</code> for the DTD.
+   */
+  public InputSource resolveEntity(String publicId, String systemId) 
+    throws SAXException {
+
+    if (publicId == null || systemId == null) {
+      throw new SAXException(LocalizedStrings.ManagedEntityConfigXml_PUBLIC_ID_0_SYSTEM_ID_1.toLocalizedString(new Object[] {publicId, systemId}));
+    }
+
+    // Figure out the location for the publicId.
+    String location = DTD_LOCATION;
+
+    InputSource result;
+//    if (location != null) (cannot be null) 
+    {
+      InputStream stream = ClassPathLoader.getLatest().getResourceAsStream(getClass(), location);
+      if (stream != null) {
+        result = new InputSource(stream);
+      } else {
+        throw new SAXNotRecognizedException(LocalizedStrings.ManagedEntityConfigXml_DTD_NOT_FOUND_0.toLocalizedString(location));
+      }
+
+//    } else {
+//      throw new SAXNotRecognizedException(LocalizedStrings.ManagedEntityConfigXml_COULD_NOT_FIND_DTD_FOR_0_1.toLocalizedString(new Object[] {publicId, systemId}));
+    }
+
+    return result;
+  }
+
+  /**
+   * Warnings are ignored
+   */
+  public void warning(SAXParseException ex) throws SAXException { 
+
+  }
+
+  /**
+   * Throws a {@link com.gemstone.gemfire.cache.CacheXmlException}
+   */
+  public void error(SAXParseException ex) throws SAXException {
+    IllegalArgumentException ex2 = new IllegalArgumentException(LocalizedStrings.ManagedEntityConfigXml_ERROR_WHILE_PARSING_XML.toLocalizedString());
+    ex2.initCause(ex);
+    throw ex2;
+  }
+  
+  /**
+   * Throws a {@link com.gemstone.gemfire.cache.CacheXmlException}
+   */
+  public void fatalError(SAXParseException ex) throws SAXException {
+    IllegalArgumentException ex2 = new IllegalArgumentException(LocalizedStrings.ManagedEntityConfigXml_FATAL_ERROR_WHILE_PARSING_XML.toLocalizedString());
+    ex2.initCause(ex);
+    throw ex2;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityConfigXmlGenerator.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityConfigXmlGenerator.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityConfigXmlGenerator.java
new file mode 100644
index 0000000..31eaf2f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityConfigXmlGenerator.java
@@ -0,0 +1,394 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.*;
+import com.gemstone.gemfire.internal.Assert;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import javax.xml.transform.*; 
+//import javax.xml.transform.dom.DOMSource; 
+import javax.xml.transform.sax.SAXSource; 
+import javax.xml.transform.stream.StreamResult;  
+import org.xml.sax.*;
+//import org.xml.sax.ext.*;
+import org.xml.sax.helpers.AttributesImpl; 
+import java.io.*;
+import java.util.*;
+
+/**
+ * Generates XML data that represents the managed entities in an
+ * <code>AdminDistributedSystem</code>.  This class is used mainly for
+ * testing.
+ *
+ * @author David Whitlock
+ * @since 4.0
+ */
+public class ManagedEntityConfigXmlGenerator
+  extends ManagedEntityConfigXml implements XMLReader {
+
+  /** An empty <code>Attributes</code> */
+  private static Attributes EMPTY = new AttributesImpl();
+
+  /////////////////////////  Instance Fields  ////////////////////////
+
+  /** The <code>AdminDistributedSystem</code> for which we are
+   * generating XML */
+  private AdminDistributedSystem system;
+
+  /** The content handler to which SAX events are generated */
+  private ContentHandler handler;
+
+  /////////////////////////  Static Methods  ////////////////////////
+
+  /**
+   * Generates an XML representation of all of the managed entities in
+   * the given <code>AdminDistributedSystem</code>.
+   */
+  public static void generate(AdminDistributedSystem system,
+                              PrintWriter pw) {
+    (new ManagedEntityConfigXmlGenerator(system)).generate(pw);
+  }
+
+  /////////////////////////  Constructors  //////////////////////////
+
+  /**
+   * Creates a new generator for the given
+   * <code>AdminDistributedSystem</code>. 
+   */
+  private ManagedEntityConfigXmlGenerator(AdminDistributedSystem
+                                          system) {
+    this.system = system;
+  }
+
+  ///////////////////////  Instance Methods  ///////////////////////
+
+  /**
+   * Generates XML and writes it to the given <code>PrintWriter</code>
+   */
+  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");
+      xform.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, SYSTEM_ID);
+      xform.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, PUBLIC_ID);
+      xform.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+      xform.transform(src, res);
+      pw.flush();
+
+    } catch (Exception ex) {
+      RuntimeException ex2 = new RuntimeException(LocalizedStrings.ManagedEntityConfigXmlGenerator_EXCEPTION_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);
+
+    handler.startDocument();
+
+    AttributesImpl atts = new AttributesImpl();
+
+    atts.addAttribute("", "", ID, "",
+                      String.valueOf(this.system.getConfig().getSystemId()));
+
+    handler.startElement("", DISTRIBUTED_SYSTEM, DISTRIBUTED_SYSTEM, atts);
+
+    // Add generation methods here
+    try {
+      generateRemoteCommand();
+      generateDiscovery();
+      generateSSL();
+      generateCacheServers();
+
+    } catch (AdminException ex) {
+      throw new SAXException(LocalizedStrings.ManagedEntityConfigXmlGenerator_AN_ADMINEXCEPTION_WAS_THROWN_WHILE_GENERATING_XML.toLocalizedString(), ex);
+    }
+
+    handler.endElement("", DISTRIBUTED_SYSTEM, DISTRIBUTED_SYSTEM);
+    handler.endDocument();
+  }
+
+  /**
+   * Generates XML for the remote command
+   */
+  private void generateRemoteCommand() throws SAXException {
+    String remoteCommand = this.system.getRemoteCommand();
+
+    handler.startElement("", REMOTE_COMMAND, REMOTE_COMMAND, EMPTY);
+
+    handler.characters(remoteCommand.toCharArray(), 0,
+                       remoteCommand.length());
+
+    handler.endElement("", REMOTE_COMMAND, REMOTE_COMMAND);
+  }
+
+  /**
+   * Generates XML for locators in the distributed system
+   */
+  private void generateDiscovery() throws SAXException {
+    if (!this.system.isMcastDiscovery()) {
+      handler.startElement("", LOCATORS, LOCATORS, EMPTY);
+
+      generateLocators();
+    }
+    
+    handler.endElement("", LOCATORS, LOCATORS);
+  }
+
+  /**
+   * Generates XML for multicast discovery
+   */
+  private void generateMulticast() throws SAXException {
+    int port = this.system.getMcastPort();
+    String address = this.system.getMcastAddress();
+
+    AttributesImpl atts = new AttributesImpl();
+    atts.addAttribute("", "", PORT, "", String.valueOf(port));
+    atts.addAttribute("", "", ADDRESS, "", address);
+
+    handler.startElement("", MULTICAST, MULTICAST, atts);
+    handler.endElement("", MULTICAST, MULTICAST);
+  }
+
+  /**
+   * Generates XML for the distributed system's locators
+   */
+  private void generateLocators() throws SAXException {
+    DistributionLocator[] locators =
+      this.system.getDistributionLocators();
+    for (int i = 0; i < locators.length; i++) {
+      generateLocator(locators[i].getConfig());
+    }
+  }
+
+  /**
+   * Generates XML for a locator
+   */
+  private void generateLocator(DistributionLocatorConfig config) 
+    throws SAXException {
+    
+    AttributesImpl atts = new AttributesImpl();
+    atts.addAttribute("", "", PORT, "",
+                      String.valueOf(config.getPort()));
+
+    handler.startElement("", LOCATOR, LOCATOR, atts);
+
+    generateEntityConfig(config);
+
+    handler.endElement("", LOCATOR, LOCATOR);
+  }
+
+  /**
+   * Generates XML for attributes common to all managed entities.
+   */
+  private void generateEntityConfig(ManagedEntityConfig config) 
+    throws SAXException {
+
+    String host = config.getHost();
+    if (host != null) {
+      handler.startElement("", HOST, HOST, EMPTY);
+      handler.characters(host.toCharArray(), 0, host.length());
+      handler.endElement("", HOST, HOST);
+    }
+
+    String remoteCommand = config.getRemoteCommand();
+    if (remoteCommand != null) {
+      handler.startElement("", REMOTE_COMMAND, REMOTE_COMMAND, EMPTY);
+      handler.characters(remoteCommand.toCharArray(), 0,
+                         remoteCommand.length());
+      handler.endElement("", REMOTE_COMMAND, REMOTE_COMMAND);
+    }
+
+    String workingDirectory = config.getWorkingDirectory();
+    if (workingDirectory != null) {
+      handler.startElement("", WORKING_DIRECTORY, WORKING_DIRECTORY, EMPTY);
+      handler.characters(workingDirectory.toCharArray(), 0,
+                         workingDirectory.length());
+      handler.endElement("", WORKING_DIRECTORY, WORKING_DIRECTORY);
+    }
+
+    String productDirectory = config.getProductDirectory();
+    if (productDirectory != null) {
+      handler.startElement("", PRODUCT_DIRECTORY, PRODUCT_DIRECTORY, EMPTY);
+      handler.characters(productDirectory.toCharArray(), 0,
+                         productDirectory.length());
+      handler.endElement("", PRODUCT_DIRECTORY, PRODUCT_DIRECTORY);
+    }
+  }
+
+  /**
+   * Generates XML for the SSL configuration of the distributed
+   * system.
+   */
+  private void generateSSL() throws SAXException {
+    DistributedSystemConfig config = this.system.getConfig();
+
+    boolean sslEnabled = config.isSSLEnabled();
+    if (!sslEnabled) {
+      return;
+    }
+
+    AttributesImpl atts = new AttributesImpl();
+    atts.addAttribute("", "", AUTHENTICATION_REQUIRED, "",
+                      String.valueOf(config.isSSLAuthenticationRequired()));
+
+    handler.startElement("", SSL, SSL, atts);
+
+    String protocols = config.getSSLProtocols();
+    if (protocols != null) {
+      handler.startElement("", PROTOCOLS, PROTOCOLS, EMPTY);
+      handler.characters(protocols.toCharArray(), 0,
+                         protocols.length());
+      handler.endElement("", PROTOCOLS, PROTOCOLS);
+    }
+
+    String ciphers = config.getSSLCiphers();
+    if (ciphers != null) {
+      handler.startElement("", CIPHERS, CIPHERS, EMPTY);
+      handler.characters(ciphers.toCharArray(), 0,
+                         ciphers.length());
+      handler.endElement("", CIPHERS, CIPHERS);
+    }
+
+    Properties sslProps = config.getSSLProperties();
+    for (Iterator iter = sslProps.entrySet().iterator();
+         iter.hasNext(); ) {
+      Map.Entry entry = (Map.Entry) iter.next();
+      String key = (String) entry.getKey();
+      String value = (String) entry.getValue();
+      
+      handler.startElement("", PROPERTY, PROPERTY, EMPTY);
+
+      handler.startElement("", KEY, KEY, EMPTY);
+      handler.characters(key.toCharArray(), 0, key.length());
+      handler.endElement("", KEY, KEY);
+
+      handler.startElement("", VALUE, VALUE, EMPTY);
+      handler.characters(value.toCharArray(), 0, value.length());
+      handler.endElement("", VALUE, VALUE);
+
+      handler.endElement("", PROPERTY, PROPERTY);
+    }
+
+    handler.endElement("", SSL, SSL);
+  }
+
+  /**
+   * Generates an XML representation of the
+   * <code>CacheServer</code>s in the distributed system.
+   */
+  private void generateCacheServers()
+    throws SAXException, AdminException {
+
+    CacheServer[] servers = this.system.getCacheServers();
+    for (int i = 0; i < servers.length; i++) {
+      generateCacheServer(servers[i].getConfig());
+    }
+  }
+
+  /**
+   * Generates an XML representation of a
+   * <code>CacheServerConfig</code>.
+   */
+  private void generateCacheServer(CacheServerConfig config) 
+    throws SAXException {
+
+    handler.startElement("", CACHE_SERVER, CACHE_SERVER, EMPTY);
+
+    generateEntityConfig(config);
+
+    String classpath = config.getClassPath();
+    if (classpath != null) {
+      handler.startElement("", CLASSPATH, CLASSPATH, EMPTY);
+      handler.characters(classpath.toCharArray(), 0,
+                         classpath.length());
+      handler.endElement("", CLASSPATH, CLASSPATH);
+    }
+
+    handler.endElement("", CACHE_SERVER, CACHE_SERVER);
+  }
+
+  /**
+   * Keep track of the content handler for use during {@link #parse(String)}.
+   */
+  public void setContentHandler(ContentHandler handler) {
+    this.handler = handler;
+  }  
+
+  public ContentHandler getContentHandler() {
+    return this.handler;
+  }  
+
+  public ErrorHandler getErrorHandler() {
+    return this;
+  }
+
+  //////////  Inherited methods that don't do anything  //////////
+
+  public boolean getFeature(String name)
+    throws SAXNotRecognizedException, SAXNotSupportedException {
+    return false;
+  }
+
+  public void setFeature(String name, boolean value)
+    throws SAXNotRecognizedException, SAXNotSupportedException {
+
+  }
+
+  public Object getProperty(String name)
+    throws SAXNotRecognizedException, SAXNotSupportedException {
+
+    return null;
+  }
+
+  public void setProperty(String name, Object value)
+    throws SAXNotRecognizedException, SAXNotSupportedException {
+
+  }
+
+  public void setEntityResolver(EntityResolver resolver) {
+
+  }
+
+  public EntityResolver getEntityResolver() {
+    return this;
+  }
+  
+  public void setDTDHandler(DTDHandler handler) {
+
+  }
+
+  public DTDHandler getDTDHandler() {
+    return null;
+  }
+
+  public void setErrorHandler(ErrorHandler handler) {
+
+  }
+
+  public void parse(String systemId)
+    throws IOException, SAXException {
+
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityConfigXmlParser.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityConfigXmlParser.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityConfigXmlParser.java
new file mode 100644
index 0000000..35f822f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityConfigXmlParser.java
@@ -0,0 +1,614 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.*;
+import com.gemstone.gemfire.internal.Assert;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import org.xml.sax.*;
+import org.xml.sax.helpers.DefaultHandler;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Parses an XML file and configures a {@link DistributedSystemConfig}
+ * from it.
+ *
+ * @author David Whitlock
+ * @since 4.0
+ */
+public class ManagedEntityConfigXmlParser
+  extends ManagedEntityConfigXml implements ContentHandler {
+
+  /** The <code>DistributedSystemConfig</code> to be configured */
+  private DistributedSystemConfig config;
+
+  /** The stack of intermediate values used while parsing */
+  private Stack stack = new Stack();
+
+  //////////////////////  Static Methods  //////////////////////
+
+  /**
+   * Parses XML data and from it configures a
+   * <code>DistributedSystemConfig</code>.
+   *
+   * @throws AdminXmlException
+   *         If an error is encountered while parsing the XML
+   */
+  public static void parse(InputStream is,
+                           DistributedSystemConfig config) {
+    ManagedEntityConfigXmlParser handler =
+      new ManagedEntityConfigXmlParser();
+    handler.config = config;
+
+    try {
+      SAXParserFactory factory = SAXParserFactory.newInstance();
+      factory.setValidating(true);
+      SAXParser parser = factory.newSAXParser();
+      parser.parse(is, new DefaultHandlerDelegate(handler));
+
+    } catch (Exception ex) {
+      if (ex instanceof AdminXmlException) {
+        throw (AdminXmlException) ex;
+
+      } else if (ex.getCause() instanceof AdminXmlException) {
+        throw (AdminXmlException) ex.getCause();
+
+      } else if (ex instanceof SAXException) {
+        // Silly JDK 1.4.2 XML parser wraps RunTime exceptions in a
+        // SAXException.  Pshaw!
+
+        SAXException sax = (SAXException) ex;
+        Exception cause = sax.getException();
+        if (cause instanceof AdminXmlException) {
+          throw (AdminXmlException) cause;
+        }
+      }
+
+      throw new AdminXmlException(LocalizedStrings.ManagedEntityConfigXmlParser_WHILE_PARSING_XML.toLocalizedString(), ex);
+    }
+  }
+
+  /**
+   * Helper method for parsing an integer
+   *
+   * @throws com.gemstone.gemfire.cache.CacheXmlException
+   *         If <code>s</code> is a malformed integer
+   */
+  private static int parseInt(String s) {
+    try {
+      return Integer.parseInt(s);
+
+    } catch (NumberFormatException ex) {
+      throw new AdminXmlException(LocalizedStrings.ManagedEntityConfigXmlParser_MALFORMED_INTEGER_0.toLocalizedString(s), ex);
+    }
+  }
+
+  //////////////////////  Instance Methods  //////////////////////
+
+//    if (this.system.isMcastEnabled()) {
+//      generateMulticast();
+//    }
+
+  public void startElement(String namespaceURI, String localName,
+                           String qName, Attributes atts)
+    throws SAXException {
+
+    if (qName.equals(DISTRIBUTED_SYSTEM)) {
+      startDistributedSystem(atts);
+
+    } else if (qName.equals(REMOTE_COMMAND)) {
+      startRemoteCommand(atts);
+
+    } else if (qName.equals(LOCATORS)) {
+      startLocators(atts);
+      
+    } else if (qName.equals(MULTICAST)) {
+      startMulticast(atts);
+
+    } else if (qName.equals(LOCATOR)) {
+      startLocator(atts);
+
+    } else if (qName.equals(HOST)) {
+      startHost(atts);
+
+    } else if (qName.equals(WORKING_DIRECTORY)) {
+      startWorkingDirectory(atts);
+
+    } else if (qName.equals(PRODUCT_DIRECTORY)) {
+      startProductDirectory(atts);
+
+    } else if (qName.equals(SSL)) {
+      startSSL(atts);
+
+    } else if (qName.equals(PROTOCOLS)) {
+      startProtocols(atts);
+
+    } else if (qName.equals(CIPHERS)) {
+      startCiphers(atts);
+
+    } else if (qName.equals(PROPERTY)) {
+      startProperty(atts);
+
+    } else if (qName.equals(KEY)) {
+      startKey(atts);
+
+    } else if (qName.equals(VALUE)) {
+      startValue(atts);
+
+    } else if (qName.equals(CACHE_SERVER)) {
+      startCacheServer(atts);
+
+    } else if (qName.equals(CLASSPATH)) {
+      startClassPath(atts);
+
+    } else {
+      throw new AdminXmlException(LocalizedStrings.ManagedEntityConfigXmlParser_UNKNOWN_XML_ELEMENT_0.toLocalizedString(qName));
+    }
+  }
+
+  public void endElement(String namespaceURI, String localName,
+                         String qName)
+    throws SAXException {
+
+    if (qName.equals(DISTRIBUTED_SYSTEM)) {
+      endDistributedSystem();
+
+    } else if (qName.equals(REMOTE_COMMAND)) {
+      endRemoteCommand();
+
+    } else if (qName.equals(LOCATORS)) {
+      endLocators();
+
+    } else if (qName.equals(MULTICAST)) {
+      endMulticast();
+
+    } else if (qName.equals(LOCATOR)) {
+      endLocator();
+
+    } else if (qName.equals(HOST)) {
+      endHost();
+
+    } else if (qName.equals(WORKING_DIRECTORY)) {
+      endWorkingDirectory();
+
+    } else if (qName.equals(PRODUCT_DIRECTORY)) {
+      endProductDirectory();
+
+    } else if (qName.equals(SSL)) {
+      endSSL();
+
+    } else if (qName.equals(PROTOCOLS)) {
+      endProtocols();
+
+    } else if (qName.equals(CIPHERS)) {
+      endCiphers();
+
+    } else if (qName.equals(PROPERTY)) {
+      endProperty();
+
+    } else if (qName.equals(KEY)) {
+      endKey();
+
+    } else if (qName.equals(VALUE)) {
+      endValue();
+
+    } else if (qName.equals(CACHE_SERVER)) {
+      endCacheServer();
+
+    } else if (qName.equals(CLASSPATH)) {
+      endClassPath();
+
+    } else {
+      throw new AdminXmlException(LocalizedStrings.ManagedEntityConfigXmlParser_UNKNOWN_XML_ELEMENT_0.toLocalizedString(qName));
+    }
+  }
+
+  /**
+   * When a <code>distributed-system</code> element is encountered, we
+   * push the <code>DistributedSystemConfig</code> on the stack.
+   */
+  private void startDistributedSystem(Attributes atts) {
+    Assert.assertTrue(stack.isEmpty());
+
+    String id = atts.getValue(ID);
+    if (id != null) {
+      this.config.setSystemId(id);
+    }
+    
+    String disable_tcp = atts.getValue(DISABLE_TCP);
+    if (disable_tcp != null) {
+      this.config.setDisableTcp(DISABLE_TCP.equalsIgnoreCase("true"));
+    }
+
+    stack.push(this.config);
+  }
+
+  /**
+   * When a <code>distributed-system</code> element is finished
+   */
+  private void endDistributedSystem() {
+    
+  }
+
+  /**
+   * When a <code>multicast</code> is first encountered, get the
+   * <code>DistributedSystemConfig</code> off of the top of the stack
+   * and set its multicast config appropriately.
+   */
+  private void startMulticast(Attributes atts) {
+    DistributedSystemConfig config =
+      (DistributedSystemConfig) stack.peek();
+
+    String port = atts.getValue(PORT);
+    config.setMcastPort(parseInt(port));
+
+    String address = atts.getValue(ADDRESS);
+    if (address != null) {
+      config.setMcastAddress(address);
+    }
+  }
+
+  private void endMulticast() {
+
+  }
+
+  /**
+   * Starts a <code>remote-command</code> element.  The item on top of
+   * the stack may be a <code>DistributedSystemConfig</code> or it
+   * might be a <code>ManagedEntityConfig</code>.
+   */
+  private void startRemoteCommand(Attributes atts) {
+
+  }
+
+  /**
+   * Ends a <code>remote-command</code> element.  Pop the command off
+   * the top of the stack and set it on the
+   * <code>DistributedSystemConfig</code> or it might be a
+   * <code>ManagedEntityConfig</code> on top of the stack.
+   */
+  private void endRemoteCommand() {
+    String remoteCommand = popString();
+    Object top = stack.peek();
+    Assert.assertTrue(top != null);
+
+    if (top instanceof DistributedSystemConfig) {
+      ((DistributedSystemConfig) top).setRemoteCommand(remoteCommand);
+
+    } else if (top instanceof ManagedEntityConfig) {
+      ((ManagedEntityConfig) top).setRemoteCommand(remoteCommand);
+
+    } else {
+      String s = "Did not expect a " + top.getClass().getName() +
+        " on top of the stack";
+      Assert.assertTrue(false, s);
+    }
+  }
+
+  private void startLocators(Attributes atts) {
+
+  }
+
+  private void endLocators() {
+
+  }
+
+  private void startLocator(Attributes atts) {
+    String port = atts.getValue(PORT);
+
+    DistributedSystemConfig system =
+      (DistributedSystemConfig) stack.peek();
+    system.setMcastPort(0);
+
+    DistributionLocatorConfig config =
+      system.createDistributionLocatorConfig();
+    
+    config.setPort(parseInt(port));
+
+    stack.push(config);
+  }
+
+  private void endLocator() {
+    Object o = stack.pop();
+    Assert.assertTrue(o instanceof DistributionLocatorConfig);
+  }
+
+  private void startHost(Attributes atts) {
+
+  }
+
+  /**
+   * We assume that there is a <code>ManagedEntityConfig</code> on top
+   * of the stack.
+   */
+  private void endHost() {
+    String host = popString();
+    ManagedEntityConfig config = (ManagedEntityConfig) stack.peek();
+    config.setHost(host);
+  }
+
+  private void startWorkingDirectory(Attributes atts) {
+
+  }
+
+  private void endWorkingDirectory() {
+    String workingDirectory = popString();
+    ManagedEntityConfig config = (ManagedEntityConfig) stack.peek();
+    config.setWorkingDirectory(workingDirectory);
+  }
+
+  private void startProductDirectory(Attributes atts) {
+
+  }
+
+  private void endProductDirectory() {
+    String productDirectory = popString();
+    ManagedEntityConfig config = (ManagedEntityConfig) stack.peek();
+    config.setProductDirectory(productDirectory);
+  }
+
+  private void startSSL(Attributes atts) {
+    DistributedSystemConfig config =
+      (DistributedSystemConfig) stack.peek();
+    config.setSSLEnabled(true);
+
+    String authenticationRequired =
+      atts.getValue(AUTHENTICATION_REQUIRED);
+    config.setSSLAuthenticationRequired(Boolean.valueOf(authenticationRequired).booleanValue());
+  }
+
+  private void endSSL() {
+
+  }
+
+  private void startProtocols(Attributes atts) {
+
+  }
+
+  private void endProtocols() {
+    String protocols = popString();
+    DistributedSystemConfig config =
+      (DistributedSystemConfig) stack.peek();
+    config.setSSLProtocols(protocols);
+  }
+
+  private void startCiphers(Attributes atts) {
+
+  }
+
+  private void endCiphers() {
+    String ciphers = popString();
+    DistributedSystemConfig config =
+      (DistributedSystemConfig) stack.peek();
+    config.setSSLCiphers(ciphers);
+  }
+
+  private void startProperty(Attributes atts) {
+
+  }
+
+  private void endProperty() {
+    String value = popString();
+    String key = popString();
+    DistributedSystemConfig config =
+      (DistributedSystemConfig) stack.peek();
+    config.addSSLProperty(key, value);
+  }
+
+  private void startKey(Attributes atts) {
+
+  }
+
+  private void endKey() {
+    String key = popString();
+    stack.push(key);
+  }
+
+  private void startValue(Attributes atts) {
+
+  }
+
+  private void endValue() {
+    String value = popString();
+    stack.push(value);
+  }
+
+  private void startCacheServer(Attributes atts) {
+    DistributedSystemConfig config =
+      (DistributedSystemConfig) stack.peek();
+    CacheServerConfig server =
+      config.createCacheServerConfig();
+    stack.push(server);
+  }
+
+  private void endCacheServer() {
+    /* CacheServerConfig server = (CacheServerConfig) */ stack.pop();
+  }
+
+  private void startClassPath(Attributes atts) {
+
+  }
+
+  private void endClassPath() {
+    String classpath = popString();
+    CacheServerConfig server = (CacheServerConfig) stack.peek();
+    server.setClassPath(classpath);
+  }
+
+  /**
+   * Pops a <code>String</code> off of the stack.
+   */
+  private String popString() {
+    Object o = stack.pop();
+
+    if (o instanceof StringBuffer) {
+      StringBuffer sb = (StringBuffer) o;
+      return sb.toString();
+
+    } else {
+      return (String) o;
+    }
+  }
+
+  /**
+   * Long strings in XML files may generate multiple
+   * <code>characters</code> callbacks.  Coalesce multiple callbacks
+   * into one big string by using a <code>StringBuffer</code>.  See
+   * bug 32122.
+   */
+  public void characters(char[] ch, int start, int length)
+    throws SAXException {
+
+    Object top = stack.peek();
+
+    StringBuffer sb;
+    if (top instanceof StringBuffer) {
+      sb = (StringBuffer) top;
+
+    } else {
+      sb = new StringBuffer();
+      stack.push(sb);
+    }
+
+    sb.append(ch, start, length);
+  }
+
+  //////////  Inherited methods that don't do anything  //////////
+
+  public void setDocumentLocator(Locator locator) { }
+
+  public void startDocument() throws SAXException { }
+
+  public void endDocument() throws SAXException { }
+
+  public void startPrefixMapping(String prefix, String uri) 
+    throws SAXException { }
+
+  public void endPrefixMapping(String prefix)
+    throws SAXException { }
+
+  public void ignorableWhitespace(char[] ch, int start, int length)
+    throws SAXException { }
+
+  public void processingInstruction(String target, String data)
+    throws SAXException { }
+
+  public void skippedEntity(String name) throws SAXException { }
+
+  ///////////////////////  Inner Classes  ///////////////////////
+
+  /**
+   * Class that delegates all of the methods of a {@link
+   * DefaultHandler} to a {@link ManagedEntityConfigXmlParser} that
+   * implements all of the methods of <code>DefaultHandler</code>, but
+   * <B>is not</B> a <code>DefaultHandler</code>.
+   */
+  static class DefaultHandlerDelegate extends DefaultHandler {
+    /** The <code>ManagedEntityConfigXmlParser</code> that does the
+     * real work */ 
+    private ManagedEntityConfigXmlParser handler;
+
+    /**
+     * Creates a new <code>DefaultHandlerDelegate</code> that
+     * delegates to the given
+     * <code>ManagedEntityConfigXmlParser</code>.
+     */
+    public DefaultHandlerDelegate(ManagedEntityConfigXmlParser handler) {
+      this.handler = handler;
+    }
+
+    @Override
+    public InputSource resolveEntity(String publicId, 
+                                     String systemId)
+      throws SAXException {
+      return handler.resolveEntity(publicId, systemId);
+    }
+
+    @Override
+    public void setDocumentLocator(Locator locator) {
+      handler.setDocumentLocator(locator);
+    }
+
+    @Override
+    public void startDocument() throws SAXException {
+      handler.startDocument();
+    }
+
+    @Override
+    public void endDocument() throws SAXException {
+      handler.endDocument();
+    }
+
+    @Override
+    public void startPrefixMapping(String prefix, String uri)
+      throws SAXException {
+      handler.startPrefixMapping(prefix, uri);
+    }
+
+    @Override
+    public void endPrefixMapping(String prefix) throws SAXException {
+      handler.endPrefixMapping(prefix);
+    }
+
+    @Override
+    public void startElement(String uri, String localName,
+                             String qName, Attributes attributes)
+      throws SAXException {
+      handler.startElement(uri, localName, qName, attributes);
+    }
+
+    @Override
+    public void endElement(String uri, String localName, String qName)
+      throws SAXException {
+      handler.endElement(uri, localName, qName);
+    }
+
+    @Override
+    public void characters(char[] ch, int start, int length)
+      throws SAXException {
+      handler.characters(ch, start, length);
+    }
+
+    @Override
+    public void ignorableWhitespace(char[] ch, int start, int length)
+      throws SAXException {
+      handler.ignorableWhitespace(ch, start, length);
+    }
+
+    @Override
+    public void processingInstruction(String target, String data)
+      throws SAXException {
+      handler.processingInstruction(target, data);
+    }
+
+    @Override
+    public void skippedEntity(String name) throws SAXException {
+      handler.skippedEntity(name);
+    }
+
+    @Override
+    public void warning(SAXParseException e) throws SAXException {
+      handler.warning(e);
+    }
+
+    @Override
+    public void error(SAXParseException e) throws SAXException {
+      handler.error(e);
+    }
+
+    @Override
+    public void fatalError(SAXParseException e) throws SAXException {
+      handler.fatalError(e);
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityController.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityController.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityController.java
new file mode 100644
index 0000000..b625d86
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityController.java
@@ -0,0 +1,65 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import com.gemstone.gemfire.admin.DistributedSystemConfig;
+import com.gemstone.gemfire.admin.ManagedEntity;
+import com.gemstone.gemfire.admin.ManagedEntityConfig;
+
+/**
+ * Defines the actual administration (starting, stopping, etc.) of
+ * GemFire {@link ManagedEntity}s.
+ * 
+ * @author Kirk Lund
+ */
+interface ManagedEntityController {
+  /**
+   * Starts a managed entity.
+   */
+  public void start(final InternalManagedEntity entity);
+
+  /**
+   * Stops a managed entity.
+   */
+  public void stop(final InternalManagedEntity entity);
+
+  /**
+   * Returns whether or not a managed entity is running
+   */
+  public boolean isRunning(InternalManagedEntity entity);
+  
+  /**
+   * Returns the contents of a locator's log file.  Other APIs are
+   * used to get the log file of managed entities that are also system
+   * members.
+   */
+  public String getLog(DistributionLocatorImpl locator);
+  
+  /**
+   * Returns the full path to the executable in
+   * <code>$GEMFIRE/bin</code> taking into account the {@linkplain
+   * ManagedEntityConfig#getProductDirectory product directory} and the
+   * platform's file separator.
+   *
+   * <P>
+   *
+   * Note: we should probably do a better job of determine whether or
+   * not the machine on which the entity runs is Windows or Linux.
+   *
+   * @param executable
+   *        The name of the executable that resides in
+   *        <code>$GEMFIRE/bin</code>.
+   */
+  public String getProductExecutable(InternalManagedEntity entity, String executable);
+  
+  /**
+   * Builds optional SSL command-line arguments.  Returns null if SSL is not
+   * enabled for the distributed system.
+   */
+  public String buildSSLArguments(DistributedSystemConfig config);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityControllerFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityControllerFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityControllerFactory.java
new file mode 100755
index 0000000..5e0f6a9
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/internal/ManagedEntityControllerFactory.java
@@ -0,0 +1,52 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.internal;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.admin.AdminDistributedSystem;
+import com.gemstone.gemfire.admin.ManagedEntity;
+import com.gemstone.gemfire.internal.ClassPathLoader;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LogMarker;
+
+/**
+ * Creates ManagedEntityController for administration (starting, stopping, etc.) 
+ * of GemFire {@link ManagedEntity}s.
+ * 
+ * @author Kirk Lund
+ */
+public class ManagedEntityControllerFactory {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  private static final String ENABLED_MANAGED_ENTITY_CONTROLLER_CLASS_NAME = "com.gemstone.gemfire.admin.internal.EnabledManagedEntityController";
+  
+  static ManagedEntityController createManagedEntityController(final AdminDistributedSystem system) {
+    if (isEnabledManagedEntityController()) {
+      logger.info(LogMarker.CONFIG, "Local and remote OS command invocations are enabled for the Admin API.");
+      return createEnabledManagedEntityController(system);
+    } else {
+      logger.info(LogMarker.CONFIG, "Local and remote OS command invocations are disabled for the Admin API.");
+      return new DisabledManagedEntityController();
+    }
+  }
+
+  public static boolean isEnabledManagedEntityController() {
+    try {
+      ClassPathLoader.getLatest().forName(ENABLED_MANAGED_ENTITY_CONTROLLER_CLASS_NAME);
+      return true;
+    } catch (ClassNotFoundException e) {
+      return false;
+    }
+  }
+  
+  private static ManagedEntityController createEnabledManagedEntityController(final AdminDistributedSystem system) {
+    return new EnabledManagedEntityController(system);
+  }
+}


[22/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/MembershipAttributes.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/MembershipAttributes.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/MembershipAttributes.java
new file mode 100755
index 0000000..aa1e98d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/MembershipAttributes.java
@@ -0,0 +1,260 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.distributed.internal.membership.InternalRole;
+import com.gemstone.gemfire.distributed.Role;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Configuration attributes for defining reliability requirements and behavior
+ * for a <code>Region</code>.
+ * 
+ * <p><code>MembershipAttributes</code> provides options for configuring a 
+ * <code>Region</code> to require one or more membership roles to be present
+ * in the system for reliable access to the <code>Region</code>. Each 
+ * {@link Role} is a user defined string name, such as Producer or Backup or 
+ * FooProducer.</p>
+ *
+ * <p>The {@link LossAction} defines the behavior when one or 
+ * more required roles are missing.</p>
+ * 
+ * <p>The {@link ResumptionAction} specifies the action to be taken when
+ * reliability resumes.</p>
+ * 
+ * <p><code>MembershipAttributes</code> have no effect unless one or more
+ * required roles are specified.  These attributes are immutable after the
+ * <code>Region</code> has been created.</p>
+ * 
+ * @author Kirk Lund
+ * @since 5.0
+ */
+public class MembershipAttributes implements DataSerializable, Externalizable {
+  
+  /** 
+   * Array of required role names by this process for reliable access to the 
+   * region
+   */
+  private /*final*/ Set<Role> requiredRoles;
+  
+  /** 
+   * The configuration defining how this process behaves when there are 
+   * missing required roles 
+   */
+  private /*final*/ LossAction lossAction;
+  
+  /** 
+   * The action to take when missing required roles return to the system 
+   */
+  private /*final*/ ResumptionAction resumptionAction;
+
+  /**
+   * Creates a new <code>MembershipAttributes</code> with the default
+   * configuration of no required roles.
+   */
+  public MembershipAttributes() {
+    this.requiredRoles = Collections.emptySet();
+    this.lossAction = LossAction.FULL_ACCESS;
+    this.resumptionAction = ResumptionAction.NONE;
+  }
+
+  /**
+   * Creates a new <code>MembershipAttributes</code> with the specified
+   * required role names. Reliability policy will default to {@linkplain 
+   * LossAction#NO_ACCESS NO_ACCESS}, and resumption action will
+   * default to {@linkplain ResumptionAction#REINITIALIZE REINITIALIZE}.
+   *
+   * @param requiredRoles
+   *        array of role names required by this process for reliable access to 
+   *        the region
+   * @throws IllegalArgumentException
+   *         if no requiredRoles are specified
+   */
+   public MembershipAttributes(String[] requiredRoles){
+     this(requiredRoles, LossAction.NO_ACCESS, ResumptionAction.REINITIALIZE);
+  }
+  
+  /**
+   * Creates a new <code>MembershipAttributes</code> with the specified
+   * required role names, reliability policy, and resumption action.
+   *
+   * @param requiredRoles
+   *        array of role names required by this process for reliable access to 
+   *        the region
+   * @param lossAction
+   *        the configuration defining how this process behaves when there are
+   *        missing required roles
+   * @param resumptionAction
+   *        the action to take when missing required roles return to the system
+   * @throws IllegalArgumentException
+   *         if the resumptionAction is incompatible with the lossAction
+   *         or if no requiredRoles are specified
+   */
+  public MembershipAttributes(String[] requiredRoles,
+                               LossAction lossAction,
+                               ResumptionAction resumptionAction) {
+    this.requiredRoles = toRoleSet(requiredRoles);
+    if (this.requiredRoles.isEmpty()) {
+      throw new IllegalArgumentException(LocalizedStrings.MembershipAttributes_ONE_OR_MORE_REQUIRED_ROLES_MUST_BE_SPECIFIED.toLocalizedString());
+    }
+    this.lossAction = lossAction;
+    this.resumptionAction = resumptionAction;
+  }
+  
+  /**
+   * Returns the set of {@linkplain com.gemstone.gemfire.distributed.Role 
+   * Role}s that are required for the reliability of this region.
+   */
+  public Set<Role> getRequiredRoles() {
+    return Collections.unmodifiableSet(this.requiredRoles);
+  }
+  
+  /**
+   * Returns true if there are one or more required roles specified.
+   */
+  public boolean hasRequiredRoles() {
+    return !this.requiredRoles.isEmpty();
+  }
+  
+  /**
+   * Returns the reliability policy that describes behavior if any required
+   * roles are missing.
+   */
+  public LossAction getLossAction() {
+    return this.lossAction;
+  }
+  
+  /**
+   * Returns the resumption action that describes behavior when 
+   */
+  public ResumptionAction getResumptionAction() {
+    return this.resumptionAction;
+  }
+  
+  private final Set<Role> toRoleSet(String[] roleNames) {
+    if (roleNames == null || roleNames.length == 0) {
+      return Collections.emptySet();
+    }
+    Set<Role> roleSet = new HashSet<Role>();
+    for (int i = 0; i < roleNames.length; i++) {
+      roleSet.add(InternalRole.getRole(roleNames[i]));
+    }
+    return roleSet;
+  }
+  
+	/**
+	 * Indicates whether some other object is "equal to" this one.
+	 *
+	 * @param  other  the reference object with which to compare.
+	 * @return true if this object is the same as the obj argument;
+	 *         false otherwise.
+	 */
+  @Override
+	public boolean equals(Object other) {
+		if (other == this) return true;
+		if (other == null) return false;
+		if (!(other instanceof MembershipAttributes)) return  false;
+		final MembershipAttributes that = (MembershipAttributes) other;
+
+		if (this.requiredRoles != that.requiredRoles &&
+	  		!(this.requiredRoles != null &&
+	  		this.requiredRoles.equals(that.requiredRoles))) return false;
+		if (this.lossAction != that.lossAction &&
+	  		!(this.lossAction != null &&
+	  		this.lossAction.equals(that.lossAction))) return false;
+		if (this.resumptionAction != that.resumptionAction &&
+	  		!(this.resumptionAction != null &&
+	  		this.resumptionAction.equals(that.resumptionAction))) return false;
+
+		return true;
+	}
+
+	/**
+	 * Returns a hash code for the object. This method is supported for the
+	 * benefit of hashtables such as those provided by java.util.Hashtable.
+	 *
+	 * @return the integer 0 if description is null; otherwise a unique integer.
+	 */
+  @Override
+	public int hashCode() {
+		int result = 17;
+		final int mult = 37;
+
+		result = mult * result + 
+			(this.requiredRoles == null ? 0 : this.requiredRoles.hashCode());
+		result = mult * result + 
+			(this.lossAction == null ? 0 : this.lossAction.hashCode());
+		result = mult * result + 
+			(this.resumptionAction == null ? 0 : this.resumptionAction.hashCode());
+
+		return result;
+	}
+
+	/**
+	 * Returns a string representation of the object.
+	 * 
+	 * @return a string representation of the object
+	 */
+  @Override
+	public String toString() {
+    if (!hasRequiredRoles()) {
+      return "RequiredRoles(none)";
+    }
+    else {
+      final StringBuffer sb = new StringBuffer();
+      sb.append("RequiredRoles(");
+      boolean comma = false;
+      for (Iterator<Role> iter = this.requiredRoles.iterator(); iter.hasNext();) {
+        if (comma) sb.append(",");
+        Role role = iter.next();
+        sb.append(role.getName());
+        comma = true;
+      }
+      sb.append("); Policy:");
+      sb.append(this.lossAction.toString());
+      sb.append("; Action:");
+      sb.append(this.resumptionAction.toString());
+      return sb.toString();
+    }
+	}
+  
+  public void toData(DataOutput out) throws IOException {
+    String[] names = new String[this.requiredRoles.size()];
+    Iterator<Role> iter = this.requiredRoles.iterator();
+    for (int i = 0; i < names.length; i++) {
+      names[i] = iter.next().getName();
+    }
+    DataSerializer.writeStringArray(names, out);
+    out.writeByte(this.lossAction.ordinal);
+    out.writeByte(this.resumptionAction.ordinal);
+  }
+
+  public void fromData(DataInput in)
+    throws IOException, ClassNotFoundException {
+    this.requiredRoles = toRoleSet(DataSerializer.readStringArray(in));
+    this.lossAction = LossAction.fromOrdinal(in.readByte());
+    this.resumptionAction = ResumptionAction.fromOrdinal(in.readByte());
+  }
+
+  public void writeExternal(ObjectOutput out) throws IOException {
+    // added to fix bug 36619
+    toData(out);
+  }
+  
+  public void readExternal(ObjectInput in)
+    throws IOException, ClassNotFoundException {
+    // added to fix bug 36619
+    fromData(in);
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/MirrorType.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/MirrorType.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/MirrorType.java
new file mode 100644
index 0000000..9e2e060
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/MirrorType.java
@@ -0,0 +1,127 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+
+package com.gemstone.gemfire.cache;
+import java.io.*;
+
+/**
+ * Enumerated type for region mirroring.
+ *
+ * @author Eric Zoerner
+ *
+ *
+ * @see AttributesFactory#setMirrorType
+ * @see RegionAttributes#getMirrorType
+ *
+ * @deprecated as of GemFire 5.0, use {@link DataPolicy} instead.
+ *
+ * @since 3.0
+ */
+@Deprecated
+public class MirrorType implements java.io.Serializable {
+    private static final long serialVersionUID = -6632651349646672540L;
+    
+    /** New entries created in other caches for this region are
+     * not automatically propagated to this region in this cache.
+     * @deprecated as of GemFire 5.0, use {@link DataPolicy#NORMAL} instead.
+     */
+    @Deprecated
+    public static final MirrorType NONE = new MirrorType("NONE", DataPolicy.NORMAL);
+
+    /**
+     * New entries created in other caches for this region are
+     * propagated to this region in this cache, but the value is not
+     * necessarily copied to this cache with the key.
+     * @deprecated as of GemFire 5.0, use {@link DataPolicy#REPLICATE} instead.
+     */
+    @Deprecated
+    public static final MirrorType KEYS = new MirrorType("KEYS", DataPolicy.REPLICATE);
+
+    /**
+     * New entries created in other caches for this region
+     * are propagated to this region in this cache and the value
+     * is also copied to this cache.
+     * @deprecated as of GemFire 5.0, use {@link DataPolicy#REPLICATE} instead.
+     */
+    @Deprecated
+    public static final MirrorType KEYS_VALUES = new MirrorType("KEYS_VALUES", DataPolicy.REPLICATE);
+    
+    
+    /** The name of this mirror type. */
+    private final transient String name;
+
+    /**
+     * The data policy that corresponds to this mirror type.
+     */
+    private final transient DataPolicy dataPolicy;
+    
+        // The 4 declarations below are necessary for serialization
+    /** int used as ordinal to represent this Scope */
+    public final int ordinal = nextOrdinal++;
+
+    private static int nextOrdinal = 0;
+    
+    private static final MirrorType[] VALUES =
+      { NONE, KEYS, KEYS_VALUES };
+
+    private Object readResolve() throws ObjectStreamException {
+      return VALUES[ordinal];  // Canonicalize
+    }
+    
+    
+    /** Creates a new instance of MirrorType. */
+    private MirrorType(String name, DataPolicy dataPolicy) {
+        this.name = name;
+        this.dataPolicy = dataPolicy;
+    }
+    
+    /** Return the MirrorType represented by specified ordinal */
+    public static MirrorType fromOrdinal(int ordinal) {
+      return VALUES[ordinal];
+    }
+    
+
+    /**
+     * Returns the {@link DataPolicy} that corresponds to this mirror type.
+     * @since 5.0
+     */
+    public DataPolicy getDataPolicy() {
+      return this.dataPolicy;
+    }
+  
+    /** Return whether this is <code>KEYS</code>. */
+    public boolean isKeys() {
+      return this == KEYS;
+    }
+    
+    /** Return whether this is <code>KEYS_VALUES</code>. */
+    public boolean isKeysValues() {
+      return this == KEYS_VALUES;
+    }
+    
+    /** Return whether this is <code>NONE</code>. */
+    public boolean isNone() {
+      return this == NONE;
+    }
+    
+    /** Return whether this indicates a mirrored type.
+     * @return true if <code>KEYS</code> or <code>KEYS_VALUES</code>
+     */
+    public boolean isMirrored() {
+      return this != NONE;
+    }
+    
+    /** Returns a string representation for this mirror type.
+     * @return the name of this mirror type
+     */
+    @Override
+    public String toString() {
+        return this.name;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/NoQueueServersAvailableException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/NoQueueServersAvailableException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/NoQueueServersAvailableException.java
new file mode 100644
index 0000000..4eee7b4
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/NoQueueServersAvailableException.java
@@ -0,0 +1,55 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.cache.client.ServerConnectivityException;
+
+/**
+ * Indicates that this client cannot contact any queue servers and
+ * therefore cannot perform operations that require a queue, such as
+ * registering interest.
+ * @author dsmith
+ * @since 5.7
+ */
+public class NoQueueServersAvailableException extends ServerConnectivityException {
+
+  private static final long serialVersionUID = 8484086019155762365L;
+
+  /**
+   * Create a new instance of NoPrimaryAvailableException without a detail message or cause.
+   */
+  public NoQueueServersAvailableException() {
+  }
+
+  /**
+   * 
+   * Create a new instance of NoPrimaryAvailableException with a detail message
+   * @param message the detail message
+   */
+  public NoQueueServersAvailableException(String message) {
+    super(message);
+  }
+
+  /**
+   * Create a new instance of NoPrimaryAvailableException with a detail message and cause
+   * @param message the detail message
+   * @param cause the cause
+   */
+  public NoQueueServersAvailableException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Create a new instance of NoPrimaryAvailableException with a cause
+   * @param cause the cause
+   */
+  public NoQueueServersAvailableException(Throwable cause) {
+    super(cause);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/NoSubscriptionServersAvailableException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/NoSubscriptionServersAvailableException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/NoSubscriptionServersAvailableException.java
new file mode 100644
index 0000000..3e19a5e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/NoSubscriptionServersAvailableException.java
@@ -0,0 +1,55 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.cache.client.ServerConnectivityException;
+
+/**
+ * Indicates that this client cannot contact any servers and
+ * therefore cannot perform operations that require subscriptions, such as
+ * registering interest.
+ * @author dsmith
+ * @since 5.7
+ */
+public class NoSubscriptionServersAvailableException extends ServerConnectivityException {
+
+  private static final long serialVersionUID = 8484086019155762365L;
+
+  /**
+   * Create a new instance of NoSubscriptionServersAvailableException without a detail message or cause.
+   */
+  public NoSubscriptionServersAvailableException() {
+  }
+
+  /**
+   * 
+   * Create a new instance of NoSubscriptionServersAvailableException with a detail message
+   * @param message the detail message
+   */
+  public NoSubscriptionServersAvailableException(String message) {
+    super(message);
+  }
+
+  /**
+   * Create a new instance of NoSubscriptionServersAvailableException with a detail message and cause
+   * @param message the detail message
+   * @param cause the cause
+   */
+  public NoSubscriptionServersAvailableException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Create a new instance of NoSubscriptionServersAvailableException with a cause
+   * @param cause the cause
+   */
+  public NoSubscriptionServersAvailableException(Throwable cause) {
+    super(cause);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Operation.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Operation.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Operation.java
new file mode 100644
index 0000000..c2571fe
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Operation.java
@@ -0,0 +1,987 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+
+package com.gemstone.gemfire.cache;
+import java.io.*;
+import com.gemstone.gemfire.internal.cache.OpType;
+import com.gemstone.gemfire.cache.execute.FunctionService;
+
+/**
+ * Enumerated type for an event operation.
+ * This class describes the operation that generated the event.
+ *
+ * @author Darrel Schneider
+ *
+ *
+ * @see CacheEvent#getOperation
+ *
+ * @since 5.0
+ */
+public final class Operation implements java.io.Serializable {
+  private static final long serialVersionUID = -7521751729852504238L;
+
+  private static byte nextOrdinal = 0;
+  private static final Operation[] VALUES = new Operation[55];
+
+  private static final byte OP_TYPE_CREATE = OpType.CREATE;
+  private static final byte OP_TYPE_UPDATE = OpType.UPDATE;
+  private static final byte OP_TYPE_GET = OpType.GET;
+  private static final byte OP_TYPE_INVALIDATE = OpType.INVALIDATE;
+  private static final byte OP_TYPE_GET_ENTRY = OpType.GET_ENTRY;
+  private static final byte OP_TYPE_CONTAINS_KEY = OpType.CONTAINS_KEY;
+  private static final byte OP_TYPE_CONTAINS_VALUE = OpType.CONTAINS_VALUE;
+  private static final byte OP_TYPE_DESTROY = OpType.DESTROY;
+  private static final byte OP_TYPE_CONTAINS_VALUE_FOR_KEY = OpType.CONTAINS_VALUE_FOR_KEY;
+  private static final byte OP_TYPE_FUNCTION_EXECUTION = OpType.FUNCTION_EXECUTION;
+  private static final byte OP_TYPE_CLEAR = OpType.CLEAR;
+  private static final byte OP_TYPE_MARKER = OpType.MARKER;
+  private static final byte OP_TYPE_UPDATE_VERSION = OpType.UPDATE_ENTRY_VERSION;
+
+  private static final int OP_DETAILS_NONE = 0;
+  private static final int OP_DETAILS_SEARCH = 1;
+  private static final int OP_DETAILS_LOCAL_LOAD = 2;
+  private static final int OP_DETAILS_NET_LOAD = 4;
+  private static final int OP_DETAILS_EXPIRE = 8;
+  private static final int OP_DETAILS_EVICT = 16;
+  private static final int OP_DETAILS_PUTALL = 32;
+  private static final int OP_DETAILS_GUARANTEES_OLD_VALUE = 64;
+  private static final int OP_DETAILS_REMOVEALL = 128;
+
+  /**
+   * TAKE NOTE!!!
+   * The order if the following static constructors calls must be maintained for backwards compatibility.
+   * Any new operations need to be added to the end.
+   */
+
+  /**
+   * A marker operation.
+   */
+  public static final Operation MARKER
+    = new Operation("MARKER",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_MARKER,
+                    OP_DETAILS_NONE
+                    );
+  
+  /**
+   * An entry creation.
+   * @see Region#create(Object, Object)
+   */
+  public static final Operation CREATE
+    = new Operation("CREATE",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_CREATE,
+                    OP_DETAILS_NONE
+                    );
+
+  /**
+   * An entry creation caused by a putAll invocation
+   * @see Region#putAll
+   */
+  public static final Operation PUTALL_CREATE
+    = new Operation("PUTALL_CREATE",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_CREATE,
+                    OP_DETAILS_PUTALL
+                    );
+
+  /**
+   * A 'value for key' operation.
+   * @see Region#get(Object)
+   */
+  public static final Operation GET
+    = new Operation("GET",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_GET,
+                    OP_DETAILS_NONE
+                    );
+  
+  /**
+   * A 'entry for key' operation.
+   * @see Region#getEntry(Object)
+   */
+  public static final Operation GET_ENTRY
+    = new Operation("GET_ENTRY",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_GET_ENTRY,
+                    OP_DETAILS_NONE
+                    );
+  
+  /**
+   * A 'check for existence of key' operation.
+   * @see Region#containsKey(Object)
+   */
+  public static final Operation CONTAINS_KEY
+    = new Operation("CONTAINS_KEY",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_CONTAINS_KEY,
+                    OP_DETAILS_NONE
+                    );
+  /**
+   * A 'check for existence of value' operation.
+   * @see Region#containsValueForKey(Object)
+   */
+  public static final Operation CONTAINS_VALUE
+    = new Operation("CONTAINS_VALUE",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_CONTAINS_VALUE,
+                    OP_DETAILS_NONE
+                    );
+  
+  /**
+   * A 'check for existence of value for given key' operation.
+   * @see Region#containsValueForKey(Object)
+   */
+  public static final Operation CONTAINS_VALUE_FOR_KEY
+    = new Operation("CONTAINS_VALUE_FOR_KEY",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_CONTAINS_VALUE_FOR_KEY,
+                    OP_DETAILS_NONE
+                    );
+  
+  /**
+   * A 'function execution' operation.
+   * @see FunctionService
+   */
+  public static final Operation FUNCTION_EXECUTION
+    = new Operation("FUNCTION_EXECUTION",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_FUNCTION_EXECUTION,
+                    OP_DETAILS_NONE
+                    );
+  
+  /**
+   * An entry creation caused by a netsearch
+   * @see Region#get(Object)
+   */
+  public static final Operation SEARCH_CREATE
+    = new Operation("SEARCH_CREATE",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_CREATE,
+                    OP_DETAILS_SEARCH
+                    );
+    
+  /**
+   * An entry creation caused by a local loader
+   * @see Region#get(Object)
+   * @see CacheLoader
+   */
+  public static final Operation LOCAL_LOAD_CREATE
+    = new Operation("LOCAL_LOAD_CREATE",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_CREATE,
+                    OP_DETAILS_LOCAL_LOAD
+                    );
+  /**
+   * An entry creation caused by a net loader
+   * @see Region#get(Object)
+   * @see CacheLoader
+   */
+  public static final Operation NET_LOAD_CREATE
+    = new Operation("NET_LOAD_CREATE",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_CREATE,
+                    OP_DETAILS_NET_LOAD
+                    );
+    
+  /**
+   * An entry update.
+   * @see Region#put(Object, Object)
+   */
+  public static final Operation UPDATE
+    = new Operation("UPDATE",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_UPDATE,
+                    OP_DETAILS_NONE
+                    );
+    
+  /**
+   * An entry update caused by a putAll invocation.
+   * @see Region#putAll
+   */
+  public static final Operation PUTALL_UPDATE
+    = new Operation("PUTALL_UPDATE",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_UPDATE,
+                    OP_DETAILS_PUTALL
+                    );
+    
+  /**
+   * An entry update caused by a net search.
+   * @see Region#get(Object)
+   */
+  public static final Operation SEARCH_UPDATE
+    = new Operation("SEARCH_UPDATE",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_UPDATE,
+                    OP_DETAILS_SEARCH
+                    );
+
+  /**
+   * An entry update caused by a local load.
+   * @see Region#get(Object)
+   * @see CacheLoader
+   */
+  public static final Operation LOCAL_LOAD_UPDATE
+    = new Operation("LOCAL_LOAD_UPDATE",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_UPDATE,
+                    OP_DETAILS_LOCAL_LOAD
+                    );
+    
+  /**
+   * An entry update caused by a net load.
+   * @see Region#get(Object)
+   * @see CacheLoader
+   */
+  public static final Operation NET_LOAD_UPDATE
+    = new Operation("NET_LOAD_UPDATE",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_UPDATE,
+                    OP_DETAILS_NET_LOAD
+                    );
+    
+  /**
+   * An entry distributed invalidate.
+   * @see Region#invalidate(Object)
+   */
+  public static final Operation INVALIDATE
+    = new Operation("INVALIDATE",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_INVALIDATE,
+                    OP_DETAILS_NONE
+                    );
+    
+  /**
+   * An entry local invalidate.
+   * @see Region#localInvalidate(Object)
+   */
+  public static final Operation LOCAL_INVALIDATE
+    = new Operation("LOCAL_INVALIDATE",
+                    true, // isLocal
+                    false, // isRegion
+                    OP_TYPE_INVALIDATE,
+                    OP_DETAILS_NONE
+                    );
+
+  /**
+   * An entry distributed destroy.
+   * @see Region#destroy(Object)
+   */
+  public static final Operation DESTROY
+    = new Operation("DESTROY",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_DESTROY,
+                    OP_DETAILS_NONE
+                    );
+  /**
+   * An entry local destroy.
+   * @see Region#localDestroy(Object)
+   */
+  public static final Operation LOCAL_DESTROY
+    = new Operation("LOCAL_DESTROY",
+                    true, // isLocal
+                    false, // isRegion
+                    OP_TYPE_DESTROY,
+                    OP_DETAILS_NONE
+                    );
+    
+  /**
+   * An entry local destroy caused by an eviction.
+   * @see Region#localDestroy(Object)
+   */
+  public static final Operation EVICT_DESTROY
+    = new Operation("EVICT_DESTROY",
+                    true, // isLocal
+                    false, // isRegion
+                    OP_TYPE_DESTROY,
+                    OP_DETAILS_EVICT
+                    );
+    
+  /**
+   * A region load snapshot.
+   * @see Region#loadSnapshot
+   */
+  public static final Operation REGION_LOAD_SNAPSHOT
+    = new Operation("REGION_LOAD_SNAPSHOT",
+                    false, // isLocal
+                    true, // isRegion
+                    OP_TYPE_DESTROY,
+                    OP_DETAILS_NONE
+                    );
+
+  /**
+   * A region local destroy.
+   * @see Region#localDestroyRegion()
+   */
+  public static final Operation REGION_LOCAL_DESTROY
+    = new Operation("REGION_LOCAL_DESTROY",
+                    true, // isLocal
+                    true, // isRegion
+                    OP_TYPE_DESTROY,
+                    OP_DETAILS_NONE
+                    );
+
+  /**
+   * A region create.
+   * @see Region#createSubregion
+   * @see Cache#createRegion
+   */
+  public static final Operation REGION_CREATE
+    = new Operation("REGION_CREATE",
+                    true, // isLocal
+                    true, // isRegion
+                    OP_TYPE_CREATE,
+                    OP_DETAILS_NONE
+                    );
+
+  /**
+   * A region close
+   * @see Region#close
+   */
+  public static final Operation REGION_CLOSE
+    = new Operation("REGION_CLOSE",
+                    true, // isLocal
+                    true, // isRegion
+                    OP_TYPE_DESTROY, // @todo darrel: should close be a destroy?
+                    OP_DETAILS_NONE
+                    );
+
+  /**
+   * A region distributed destroy.
+   * @see Region#destroyRegion()
+   */
+  public static final Operation REGION_DESTROY
+    = new Operation("REGION_DESTROY",
+                    false, // isLocal
+                    true, // isRegion
+                    OP_TYPE_DESTROY,
+                    OP_DETAILS_NONE
+                    );
+
+  /**
+   * An entry distributed destroy triggered by expiration 
+   * @see RegionAttributes#getEntryTimeToLive
+   * @see RegionAttributes#getEntryIdleTimeout
+   * @see ExpirationAction#DESTROY
+   */
+  public static final Operation EXPIRE_DESTROY
+    = new Operation("EXPIRE_DESTROY",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_DESTROY,
+                    OP_DETAILS_EXPIRE
+                    );
+  /**
+   * An entry local destroy triggered by expiration 
+   * @see RegionAttributes#getEntryTimeToLive
+   * @see RegionAttributes#getEntryIdleTimeout
+   * @see ExpirationAction#LOCAL_DESTROY
+   */
+  public static final Operation EXPIRE_LOCAL_DESTROY
+    = new Operation("EXPIRE_LOCAL_DESTROY",
+                    true, // isLocal
+                    false, // isRegion
+                    OP_TYPE_DESTROY,
+                    OP_DETAILS_EXPIRE
+                    );
+  /**
+   * An entry distributed invalidate triggered by expiration 
+   * @see RegionAttributes#getEntryTimeToLive
+   * @see RegionAttributes#getEntryIdleTimeout
+   * @see ExpirationAction#INVALIDATE
+   */
+  public static final Operation EXPIRE_INVALIDATE
+    = new Operation("EXPIRE_INVALIDATE",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_INVALIDATE,
+                    OP_DETAILS_EXPIRE
+                    );
+
+  /**
+   * An entry local invalidate triggered by expiration 
+   * @see RegionAttributes#getEntryTimeToLive
+   * @see RegionAttributes#getEntryIdleTimeout
+   * @see ExpirationAction#LOCAL_INVALIDATE
+   */
+  public static final Operation EXPIRE_LOCAL_INVALIDATE
+    = new Operation("EXPIRE_LOCAL_INVALIDATE",
+                    true, // isLocal
+                    false, // isRegion
+                    OP_TYPE_INVALIDATE,
+                    OP_DETAILS_EXPIRE
+                    );
+
+  /**
+   * A region distributed destroy triggered by expiration 
+   * @see RegionAttributes#getRegionTimeToLive
+   * @see RegionAttributes#getRegionIdleTimeout
+   * @see ExpirationAction#DESTROY
+   */
+  public static final Operation REGION_EXPIRE_DESTROY
+    = new Operation("REGION_EXPIRE_DESTROY",
+                    false, // isLocal
+                    true, // isRegion
+                    OP_TYPE_DESTROY,
+                    OP_DETAILS_EXPIRE
+                    );
+  /**
+   * A region local destroy triggered by expiration 
+   * @see RegionAttributes#getRegionTimeToLive
+   * @see RegionAttributes#getRegionIdleTimeout
+   * @see ExpirationAction#LOCAL_DESTROY
+   */
+  public static final Operation REGION_EXPIRE_LOCAL_DESTROY
+    = new Operation("REGION_EXPIRE_LOCAL_DESTROY",
+                    true, // isLocal
+                    true, // isRegion
+                    OP_TYPE_DESTROY,
+                    OP_DETAILS_EXPIRE
+                    );
+  /**
+   * A region distributed invalidate triggered by expiration 
+   * @see RegionAttributes#getRegionTimeToLive
+   * @see RegionAttributes#getRegionIdleTimeout
+   * @see ExpirationAction#INVALIDATE
+   */
+  public static final Operation REGION_EXPIRE_INVALIDATE
+    = new Operation("REGION_EXPIRE_INVALIDATE",
+                    false, // isLocal
+                    true, // isRegion
+                    OP_TYPE_INVALIDATE,
+                    OP_DETAILS_EXPIRE
+                    );
+  /**
+   * A region local invalidate triggered by expiration 
+   * @see RegionAttributes#getRegionTimeToLive
+   * @see RegionAttributes#getRegionIdleTimeout
+   * @see ExpirationAction#LOCAL_INVALIDATE
+   */
+  public static final Operation REGION_EXPIRE_LOCAL_INVALIDATE
+    = new Operation("REGION_EXPIRE_LOCAL_INVALIDATE",
+                    true, // isLocal
+                    true, // isRegion
+                    OP_TYPE_INVALIDATE,
+                    OP_DETAILS_EXPIRE
+                    );
+  /**
+   * A region local invalidate.
+   * @see Region#localInvalidateRegion()
+   */
+  public static final Operation REGION_LOCAL_INVALIDATE
+    = new Operation("REGION_LOCAL_INVALIDATE",
+                    true, // isLocal
+                    true, // isRegion
+                    OP_TYPE_INVALIDATE,
+                    OP_DETAILS_NONE
+                    );
+
+  /**
+   * A region distributed invalidate.
+   * @see Region#invalidateRegion()
+   */
+  public static final Operation REGION_INVALIDATE
+    = new Operation("REGION_INVALIDATE",
+                    false, // isLocal
+                    true, // isRegion
+                    OP_TYPE_INVALIDATE,
+                    OP_DETAILS_NONE
+                    );
+
+  /**
+   * A region clear.
+   * @see Region#clear
+   */
+  public static final Operation REGION_CLEAR
+    = new Operation("REGION_CLEAR",
+                    false, // isLocal
+                    true, // isRegion
+                    OP_TYPE_CLEAR,
+                    OP_DETAILS_NONE
+                    );
+  /**
+   * A region local clear.
+   * @see Region#localClear
+   */
+  public static final Operation REGION_LOCAL_CLEAR
+    = new Operation("REGION_LOCAL_CLEAR",
+                    true, // isLocal
+                    true, // isRegion
+                    OP_TYPE_CLEAR,
+                    OP_DETAILS_NONE
+                    );
+    
+  /**
+   * A cache create. Note that this is marked as a region operation.
+   * @see CacheFactory#create
+   */
+  public static final Operation CACHE_CREATE
+    = new Operation("CACHE_CREATE",
+                    true, // isLocal
+                    true, // isRegion
+                    OP_TYPE_CREATE,
+                    OP_DETAILS_NONE
+                    );
+
+  /**
+   * A cache close.  Note that this is marked as a region operation.
+   * @see Cache#close()
+   */
+  public static final Operation CACHE_CLOSE
+    = new Operation("CACHE_CLOSE",
+                    true, // isLocal
+                    true, // isRegion
+                    OP_TYPE_DESTROY, // @todo darrel: should close be a destroy?
+                    OP_DETAILS_NONE
+                    );
+  
+  /**
+   * A cache close due to being forced out of the distributed system
+   * by other members.  This typically happens
+   * when a member becomes unresponsive and does not respond to heartbeat requests
+   * within the <a href="../distributed/DistributedSystem.html#member-timeout">"member-timeout"</a>
+   * period.<br>
+   * Note that this is marked as a region operation.
+   */
+  public static final Operation FORCED_DISCONNECT
+    = new Operation("FORCED_DISCONNECT",
+                    true, // isLocal
+                    true, // isRegion
+                    OP_TYPE_DESTROY,
+                    OP_DETAILS_NONE
+                    );
+  
+  /**
+   * A region destroy triggered by {@link ResumptionAction#REINITIALIZE}.
+   * @see ResumptionAction#REINITIALIZE
+   */
+  public static final Operation REGION_REINITIALIZE
+    = new Operation("REGION_REINITIALIZE",
+                    true, // isLocal
+                    true, // isRegion
+                    OP_TYPE_DESTROY,
+                    OP_DETAILS_NONE
+                    );
+                    
+  /**
+   * A cache close triggered by {@link LossAction#RECONNECT}.
+   * @see LossAction#RECONNECT
+   */
+  public static final Operation CACHE_RECONNECT 
+    = new Operation("CACHE_RECONNECT",
+                    true, // isLocal
+                    true, // isRegion
+                    OP_TYPE_DESTROY,
+                    OP_DETAILS_NONE
+                    );
+                    
+  /**
+   * An atomic entry creation operation
+   * @see java.util.concurrent.ConcurrentMap#putIfAbsent(Object, Object)
+   * @since 6.5
+   */
+  public static final Operation PUT_IF_ABSENT
+    = new Operation("PUT_IF_ABSENT",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_CREATE,
+                    OP_DETAILS_GUARANTEES_OLD_VALUE
+                    );
+
+  /**
+   * An atomic update operation 
+   * @see java.util.concurrent.ConcurrentMap#replace(Object, Object, Object)
+   * @since 6.5
+   */
+  public static final Operation REPLACE
+    = new Operation("REPLACE",
+        false, // isLocal
+        false, // isRegion
+        OP_TYPE_UPDATE,
+        OP_DETAILS_GUARANTEES_OLD_VALUE);
+  
+  /**
+   * An atomic destroy destroy operation
+   * @see java.util.concurrent.ConcurrentMap#remove(Object, Object)
+   * @since 6.5
+   */
+  public static final Operation REMOVE
+    = new Operation("REMOVE",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_DESTROY,
+                    OP_DETAILS_NONE
+                    );
+
+  /**
+   * An internal operation used to update the version stamp of an entry.
+   */
+  public static final Operation UPDATE_VERSION_STAMP 
+    = new Operation("UPDATE_VERSION",
+                     false, //isLocal
+                     false, //isRegion
+                     OP_TYPE_UPDATE_VERSION, //opType
+                     OP_DETAILS_NONE //opDetails
+                     );
+
+  /**
+   * An entry distributed destroy caused by a removeAll.
+   * @see Region#removeAll(java.util.Collection)
+   * @since 8.1
+   */
+  public static final Operation REMOVEALL_DESTROY
+    = new Operation("REMOVEALL_DESTROY",
+                    false, // isLocal
+                    false, // isRegion
+                    OP_TYPE_DESTROY,
+                    OP_DETAILS_REMOVEALL
+                    );
+    
+  /** The name of this mirror type. */
+  private final transient String name;
+    
+  /** byte used as ordinal to represent this Operation */
+  public final byte ordinal;
+
+  /** True if a local op; false if distributed op. */
+  private final transient boolean isLocal;
+
+  /** True if a region operation; false if entry op. */
+  private final transient boolean isRegion;
+
+  /** One of the following:
+   *    OP_TYPE_CREATE,
+   *    OP_TYPE_UPDATE,
+   *    OP_TYPE_INVALIDATE,
+   *    OP_TYPE_DESTROY,
+   *    OP_TYPE_CLEAR
+   */
+  private final transient byte opType;
+
+  /** One of the following:
+   *    OP_DETAILS_NONE,
+   *    OP_DETAILS_SEARCH,
+   *    OP_DETAILS_LOCAL_LOAD,
+   *    OP_DETAILS_NET_LOAD,
+   *    OP_DETAILS_EXPIRE,
+   *    OP_DETAILS_EVICT
+   *    OP_DETAILS_PUTALL
+   *    OP_DETAILS_GUARANTEES_OLD_VALUE
+   *    OP_DETAILS_REMOVEALL
+   */
+  private final transient int opDetails;
+
+  
+  private Object readResolve() throws ObjectStreamException {
+    return VALUES[ordinal];  // Canonicalize
+  }
+    
+    
+  /** Creates a new instance of Operation. */
+  private Operation(String name, boolean isLocal, boolean isRegion, byte opType, int opDetails) {
+    this.name = name;
+    this.isLocal = isLocal;
+    this.isRegion = isRegion;
+    this.opType = opType;
+    this.opDetails = opDetails;
+    this.ordinal = nextOrdinal++;
+    VALUES[this.ordinal] = this;
+  }
+    
+  /** Return the Operation represented by specified ordinal */
+  public static Operation fromOrdinal(byte ordinal) {
+    return VALUES[ordinal];
+  }
+    
+
+  /**
+   * Returns true if this operation created a new entry.
+   */
+  public boolean isCreate() {
+    return this.opType == OP_TYPE_CREATE && isEntry();
+  }
+
+  /**
+   * Returns true if this operation updated an existing entry.
+   */
+  public boolean isUpdate() {
+    return this.opType == OP_TYPE_UPDATE && isEntry();
+  }
+
+  /**
+   * Returns true if this operation gets the value for given key.
+   */
+  public boolean isGet() {
+    return this.opType == OP_TYPE_GET;
+  }
+  
+  /**
+   * Returns true if this operation checks whether given key is present in region.
+   */
+  public boolean isContainsKey() {
+    return this.opType == OP_TYPE_CONTAINS_KEY;
+  }
+  
+  /**
+   * Returns true if this operation checks whether given value is present in region.
+   */
+  public boolean isContainsValue() {
+    return this.opType == OP_TYPE_CONTAINS_VALUE;
+  }
+  
+  /**
+   * Returns true if this operation checks whether value is present for the given key.
+   */
+  public boolean isContainsValueForKey() {
+    return this.opType == OP_TYPE_CONTAINS_VALUE_FOR_KEY;
+  }
+  /**
+   * Returns true if this operation is function execution operation.
+   */
+  public boolean isFunctionExecution() {
+    return this.opType == OP_TYPE_FUNCTION_EXECUTION;
+  }
+  /**
+   * Returns true if this operation gets the entry for given key.
+   */
+  public boolean isGetEntry() {
+    return this.opType == OP_TYPE_GET_ENTRY;
+  }
+  /**
+   * Returns true if the operation invalidated an entry.
+   */
+  public boolean isInvalidate() {
+    return this.opType == OP_TYPE_INVALIDATE && isEntry();
+  }
+
+  /**
+   * Returns true if the operation destroyed an entry.
+   */
+  public boolean isDestroy() {
+    return this.opType == OP_TYPE_DESTROY && isEntry();
+  }
+
+  /**
+   * Returns true if the operation cleared the region.
+   */
+  public boolean isClear() {
+    return this.opType == OP_TYPE_CLEAR;
+  }
+  /**
+   * Returns true if the operation closed the cache or a region.
+   */
+  public boolean isClose() {
+    return (this == REGION_CLOSE)
+      || (this == CACHE_CLOSE)
+      || (this == CACHE_RECONNECT)
+      || (this == FORCED_DISCONNECT);
+  }
+  /**
+   * Returns true if this operation was initiated by a putAll.
+   */
+  public boolean isPutAll() {
+    return (this.opDetails & OP_DETAILS_PUTALL) != 0;
+  }
+
+  /**
+   * Returns true if this operation was initiated by a removeAll.
+   * @see Region#removeAll(java.util.Collection)
+   * @since 8.1
+   */
+  public boolean isRemoveAll() {
+    return (this.opDetails & OP_DETAILS_REMOVEALL) != 0;
+  }
+
+  /**
+   * Returns true if the operation invalidated a region.
+   */
+  public boolean isRegionInvalidate() {
+    return this.opType == OP_TYPE_INVALIDATE && isRegion();
+  }
+  /**
+   * Returns true if the operation destroyed a region.
+   */
+  public boolean isRegionDestroy() {
+    return this.opType == OP_TYPE_DESTROY && isRegion();
+  }
+  /**
+   * Returns true if the operation applies to the entire region.
+   */
+  public boolean isRegion() {
+    return this.isRegion;
+  }
+  /**
+   * Returns true if the operation is limited to the local cache.
+   */
+  public boolean isLocal() {
+    return this.isLocal;
+  }
+  /**
+   * Returns true if the operation may be distributed.
+   */
+  public boolean isDistributed() {
+    return !isLocal();
+  }
+  /**
+   * Returns true if the operation applies to a single entry.
+   */
+  public boolean isEntry() {
+    return !isRegion();
+  }
+  /** Answer true if this operation resulted from expiration.
+   * @return true if this operation resulted from expiration
+   *
+   */
+  public boolean isExpiration() {
+    return (this.opDetails & OP_DETAILS_EXPIRE) != 0;
+  }
+  
+  /**
+   * Answer true if this operation resulted from eviction
+   * @return true if this operatino resulted from eviction
+   */
+  public boolean isEviction() {
+    return (this.opDetails & OP_DETAILS_EVICT) != 0;
+  }
+
+  /** Returns true if this operation included a loader running in this cache.
+   * Note that this will be true even if the local loader called <code>netSearch</code>.
+   *
+   * If this operation is for a Partitioned Region, then true will be returned if the
+   * loader ran in the same VM as where the data is hosted. If true is returned, and {@link CacheEvent#isOriginRemote}
+   * is true, it means the data is not hosted locally, but the loader was run local to the data.
+   * 
+   * @return true if this operation included a local loader execution
+   */
+  public boolean isLocalLoad() {
+    return (this.opDetails & OP_DETAILS_LOCAL_LOAD) != 0;
+  }
+
+  /** Returns true if this operation included a loader running that was remote
+   * from the cache that requested it, i.e., a netLoad. Note that the cache
+   * that requested the netLoad may not be this cache.
+   * @return true if this operation included a netLoad
+   */
+  public boolean isNetLoad() {
+    return (this.opDetails & OP_DETAILS_NET_LOAD) != 0;
+  }
+  
+  /** Returns true if this operation included running a loader.
+   * @return true if isLocalLoad or isNetLoad
+   */
+  public boolean isLoad() {
+    return (this.opDetails & (OP_DETAILS_LOCAL_LOAD|OP_DETAILS_NET_LOAD)) != 0;
+  }
+  
+  /** Returns true if this operation included a <code>netSearch</code>. If the <code>netSearch</code>
+   * was invoked by a loader however, this will return false and <code>isLocalLoad()</code>
+   * or <code>isNetLoad()</code> will return true instead.
+   *
+   * @return true if this operation included a netSearch
+   */
+  public boolean isNetSearch() {
+    return (this.opDetails & OP_DETAILS_SEARCH) != 0;
+  }
+
+  /**
+   * Returns true if this operation was a {@link #isNetSearch net search} or a
+   * {@link #isLoad load}.
+   * @return true if this operation include a netSearch or any type of load.
+   */
+  public boolean isSearchOrLoad() {
+    return (this.opDetails & (OP_DETAILS_SEARCH|OP_DETAILS_LOCAL_LOAD|OP_DETAILS_NET_LOAD)) != 0;
+  }
+
+  /**
+   * Returns true if this operation is a ConcurrentMap operation that
+   * guarantees the old value to be returned no matter what expense may
+   * be incurred in doing so.
+   * @return true if this operation has this guarantee
+   * @since 6.5
+   */
+  public boolean guaranteesOldValue() {
+    return (this.opDetails & OP_DETAILS_GUARANTEES_OLD_VALUE) != 0;
+  }
+
+  /**
+   * Returns the update operation that corresponds to this operation.
+   * For a create operation the corresponding update op is returned.
+   * For all other operations <code>this</code> is returned.
+   */
+  public Operation getCorrespondingUpdateOp() {
+    if (isCreate()) {
+      switch (this.opDetails) {
+      case OP_DETAILS_SEARCH:
+        return Operation.SEARCH_UPDATE;
+      case OP_DETAILS_LOCAL_LOAD:
+        return Operation.LOCAL_LOAD_UPDATE;
+      case OP_DETAILS_NET_LOAD:
+        return Operation.NET_LOAD_UPDATE;
+      case OP_DETAILS_PUTALL:
+        return Operation.PUTALL_UPDATE;
+      default:
+        return Operation.UPDATE;
+      }
+    } else {
+      return this;
+    }
+  }
+
+  /**
+   * Returns the create operation that corresponds to this operation.
+   * For an update operation the corresponding create op is returned.
+   * For all other operations <code>this</code> is returned.
+   */
+  public Operation getCorrespondingCreateOp() {
+    if (isUpdate()) {
+      switch (this.opDetails) {
+      case OP_DETAILS_SEARCH:
+        return Operation.SEARCH_CREATE;
+      case OP_DETAILS_LOCAL_LOAD:
+        return Operation.LOCAL_LOAD_CREATE;
+      case OP_DETAILS_NET_LOAD:
+        return Operation.NET_LOAD_CREATE;
+      case OP_DETAILS_PUTALL:
+        return Operation.PUTALL_CREATE;
+      default:
+        return Operation.CREATE;
+      }
+    } else {
+      return this;
+    }
+  }
+  
+  /** Returns a string representation for this operation.
+     * @return the name of this operation.
+     */
+  @Override
+  public String toString() {
+    return this.name;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/OperationAbortedException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/OperationAbortedException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/OperationAbortedException.java
new file mode 100644
index 0000000..b1d8987
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/OperationAbortedException.java
@@ -0,0 +1,54 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/** Indicates that the operation that
+ * would have otherwise affected the cache has been aborted.
+ * Only subclasses are instantiated.
+ *
+ * @author Eric Zoerner
+ *
+ *
+ * @since 3.0
+ */
+public abstract class OperationAbortedException extends CacheRuntimeException {
+  
+  /**
+   * Creates a new instance of <code>OperationAbortedException</code> without detail message.
+   */
+  public OperationAbortedException() {
+  }
+  
+  
+  /**
+   * Constructs an instance of <code>OperationAbortedException</code> with the specified detail message.
+   * @param msg the detail message
+   */
+  public OperationAbortedException(String msg) {
+    super(msg);
+  }
+  
+  /**
+   * Constructs an instance of <code>OperationAbortedException</code> with the specified detail message
+   * and cause.
+   * @param msg the detail message
+   * @param cause the causal Throwable
+   */
+  public OperationAbortedException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+  
+  /**
+   * Constructs an instance of <code>OperationAbortedException</code> with the specified cause.
+   * @param cause the causal Throwable
+   */
+  public OperationAbortedException(Throwable cause) {
+    super(cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionAttributes.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionAttributes.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionAttributes.java
new file mode 100644
index 0000000..f2eb2b1
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionAttributes.java
@@ -0,0 +1,162 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import java.util.List;
+import java.util.Properties;
+
+import com.gemstone.gemfire.cache.PartitionResolver;
+import com.gemstone.gemfire.cache.partition.PartitionListener;
+
+/**
+ * 
+ * Attributes that define the partitioned character of a Partitioned Region.  
+ * This interface allows for the discovery of Partitioned Region attributes using 
+ * {@link com.gemstone.gemfire.cache.RegionAttributes#getPartitionAttributes()} as well
+ * as the configuration of a Partitioned Region using {@link com.gemstone.gemfire.cache.AttributesFactory#setPartitionAttributes(PartitionAttributes)}.
+ * 
+ * PartitionAttributes are created using the {@link com.gemstone.gemfire.cache.PartitionAttributesFactory}
+ * 
+ * The default PartitionAttributes can be determined using {@link com.gemstone.gemfire.cache.PartitionAttributesFactory#create()} with out
+ * calling any of its mutator methods e.g.  {@link com.gemstone.gemfire.cache.PartitionAttributesFactory#setLocalMaxMemory(int)}
+ *
+ * Also see {@link com.gemstone.gemfire.cache.DataPolicy#PARTITION}.
+ * 
+ * @author rreja
+ * @since 5.0
+ * 
+ */
+public interface PartitionAttributes<K,V>
+{
+  /**
+   * returns entryTimeToLive in ExpirationAttributes.
+   * 
+   * @return expirationAttributes
+   */
+  // public ExpirationAttributes getEntryTimeToLive();
+
+  /**
+   * returns entryIdleTimeout in ExpirationAttributes.
+   * 
+   * @return expirationAttributes
+   */
+  // public ExpirationAttributes getEntryIdleTimeout();
+
+  /**
+   * The number of Backups for an entry in PartitionedRegion. This value should
+   * be between 0 and 3 (for a total of 1 to 4 instances of the data).
+   * The default value is 0.
+   * 
+   * @return redundantCopies.
+   */
+  public int getRedundantCopies();
+
+  /**
+   * This method returns the maximum total size of the region in megabytes.
+   * @deprecated use getTotalMaxMemory() instead
+   * @return total size in megabytes.
+   */
+  @Deprecated
+  public long getTotalSize();
+  
+  /**
+   * This method returns the maximum total size of the region, in megabytes.
+   * Default value is Integer.MAX_VALUE.
+   * @return maximum size of the partitioned region, in megabytes
+   */
+  public long getTotalMaxMemory();
+
+  /**
+   * This method returns total number of buckets for a PartitionedRegion.
+   * Default number of buckets for a PartitionedRegion is 113.
+   * 
+   * @return total number of buckets for a PartitionedRegion.
+   */
+  public int getTotalNumBuckets();  
+
+  /**
+   * This method returns the maximum amount of local memory that can be used
+   * by the Region.
+   * By default, a PartitionedRegion can contribute 90% of the maximum memory allocated to a VM.
+   */
+  public int getLocalMaxMemory();
+  
+  /**
+   * Returns name of the colocated PartitionedRegion's name 
+   * @since 6.0
+   */
+  public String getColocatedWith();
+
+  /**
+   * This method returns local properties.  There are currently no local
+   * properties defined that are not also deprecated.
+   * 
+   * @deprecated use {@link #getLocalMaxMemory()} in GemFire 5.1 and later releases
+   * @return localProperties
+   */
+  @Deprecated
+  public Properties getLocalProperties();
+
+  /**
+   * This method returns global properties.  There are currently no global
+   * properties defined that are not also deprecated.
+   * 
+   * @deprecated use {@link #getTotalMaxMemory()} and {@link #getTotalNumBuckets()} in GemFire 5.1 and later releases
+   * @return globalProperties
+   */
+  @Deprecated
+  public Properties getGlobalProperties();
+
+  /**
+   * Returns the PartitionResolver set for custom partitioning
+   * @return <code>PartitionResolver</code> for the PartitionedRegion
+   * @since 6.0
+   */
+  public PartitionResolver<K,V> getPartitionResolver();
+
+  /**
+   * Returns the delay in milliseconds that
+   * existing members will wait before satisfying redundancy
+   * after another member crashes.
+   * Default value of recoveryDelay is -1 which indicates that redundancy won't 
+   * be recovered if a member crashes.
+   * 
+   * @since 6.0
+   */
+  public long getRecoveryDelay();
+
+  /**
+   * Returns the delay in milliseconds that a new
+   * member will wait before trying to satisfy redundancy
+   * of data hosted on other members.
+   * Default value is 0 which is to recover redundancy immediately when a new
+   * member is added. 
+   * 
+   * @since 6.0
+   */
+  public long getStartupRecoveryDelay();
+  
+  /**
+   * Returns array of PartitionListener{s} configured on this partitioned region
+   * 
+   * @see PartitionListener
+   * @return PartitionListener configured on this partitioned region
+   * @since 6.5
+   */
+  public PartitionListener[] getPartitionListeners();
+
+  /**
+   * Returns <code>FixedPartitionAttributes</code>'s list of local partitions
+   * defined on this Partitioned Region
+   * 
+   * @since 6.6
+   */
+  public List<FixedPartitionAttributes> getFixedPartitionAttributes();
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionAttributesFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionAttributesFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionAttributesFactory.java
new file mode 100644
index 0000000..9dc4563
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionAttributesFactory.java
@@ -0,0 +1,445 @@
+/*
+ * ========================================================================= 
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved. 
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ * =========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import java.util.Properties;
+
+import com.gemstone.gemfire.cache.partition.PartitionListener;
+import com.gemstone.gemfire.internal.cache.PartitionAttributesImpl;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+/**
+ * <p>
+ * A factory that creates instances of {@link PartitionAttributes} which are
+ * used to create a partitioned {@link Region}. The setter methods follow the
+ * self-return idiom so that they can be "chained" together with the
+ * {@link #create} method to create
+ * {@link PartitionAttributes}. For example:<br>
+ * 
+ * <pre>
+ * PartitionAttributes pa = new PartitionAttributesFactory()
+ *  .setRedundantCopies(1)
+ *  .setLocalMaxMemory(1240)
+ *  .create();
+ *     
+ * final Region myRegion = new RegionFactory()
+ *  .setPartitionAttributes(pa)
+ *  .setKeyConstraint(String.class)
+ *  .setValueConstraint(ArrayList.class)
+ *  .create("myRegion");
+ * </pre>
+ * 
+ * </p>
+ * 
+ * <p>
+ * {@link PartitionAttributes} can also be defined in a declarative fashion using a
+ * <a href="package-summary.html#declarative">cache.xml</a> file. Here is an
+ * example of how to configure a Partitioned Region named "pRoot" whose 
+ * {@link com.gemstone.gemfire.cache.Scope} is Distributed Ack, which maintains
+ * a {@link #setRedundantCopies(int) redundant copy} of any given 
+ * {@link com.gemstone.gemfire.cache.Region.Entry}, configures a 
+ * {@link com.gemstone.gemfire.cache.CacheLoader} implementation, and sets 
+ * {@link #setGlobalProperties(Properties) global properties} as well as 
+ * {@link #setLocalMaxMemory(int) local max memory to use}.
+ * 
+ * <pre>
+ *    &lt;root-region name=&quot;pRoot&quot;&gt;
+ *      &lt;region-attributes scope=&quot;distributed-ack&quot; &gt;
+ *        &lt;partition-attributes redundant-copies=&quot;1&quot;,&nbsp;local-max-memory=&quot;1240&quot;/&gt;
+ *      &lt;/region-attributes&gt;
+ *    &lt;/root-region&gt;
+ * </pre>
+ * </p>
+ * 
+ * @see com.gemstone.gemfire.cache.PartitionAttributes
+ * @see com.gemstone.gemfire.cache.AttributesFactory#setPartitionAttributes(PartitionAttributes)
+ * @author rreja
+ * @author bruce
+ * @since 5.0
+ */
+public class PartitionAttributesFactory<K,V>
+{
+  private final PartitionAttributesImpl partitionAttributes = new PartitionAttributesImpl();
+
+  /**
+   * @deprecated - please use the {@link #setLocalMaxMemory(int)} method instead.<p>
+   * The {@link #setLocalProperties(Properties) local property} name that sets
+   * the maximum heap storage a VM contributes to a partitioned Region. When set
+   * to zero, the resulting Region reference allows access to the partitioned
+   * Region without any consuming any heap storage.
+   */
+  public static final String LOCAL_MAX_MEMORY_PROPERTY = "LOCAL_MAX_MEMORY";
+
+  /**
+   * Default local max memory value in megabytes.  By default each partitioned
+   * Region can contribute 90% of the maximum memory allocated to a VM.
+   */
+  private static int computeMaxMem()
+  {
+    final long maxMemInMegabytes = Runtime.getRuntime().maxMemory() / (1024 * 1024);
+    final long maxMemoryToUse = (long) (maxMemInMegabytes * 0.90); 
+    int ret;
+    if (maxMemoryToUse < Integer.MAX_VALUE) {
+      ret = (int) maxMemoryToUse; 
+      if (ret < 1) {
+        ret = 1;
+      }
+    } else {
+      ret = Integer.MAX_VALUE;
+    }
+    return ret;
+  }
+  
+  /**
+   * The default maximum amount of memory to be used by this region in this
+   * process, in megabytes.
+   */
+  public static final int LOCAL_MAX_MEMORY_DEFAULT = computeMaxMem();
+
+  /**
+   * @deprecated - use {@link #setTotalMaxMemory(long)} instead.<p>
+   * The {@link #setGlobalProperties(Properties) global property} name that
+   * defines the total maximum size for the partitioned Region.<p>
+   * <em>This setting must be the same in all processes using the Region.</em>
+   */
+  public static final String GLOBAL_MAX_MEMORY_PROPERTY = "GLOBAL_MAX_MEMORY";
+
+  /**
+   * Default maximum total size of the region across all processes, in megabytes.
+   */
+  public static final long GLOBAL_MAX_MEMORY_DEFAULT = Integer.MAX_VALUE;
+
+  /**
+   * @deprecated - please use {@link #setTotalNumBuckets(int)} instead.<p>
+   * <em>This setting must be the same in all processes using the Region.</em>
+   */
+  public static final String GLOBAL_MAX_BUCKETS_PROPERTY = "GLOBAL_MAX_BUCKETS"; // "GLOBAL_MAX_BUCKETS";
+
+  /**
+   * The default total number of buckets (113).
+   */
+  public static final int GLOBAL_MAX_BUCKETS_DEFAULT = 113;
+
+  public static final long RECOVERY_DELAY_DEFAULT = -1;
+
+  public static final long STARTUP_RECOVERY_DELAY_DEFAULT = 0;
+
+  /**
+   * Creates a new instance of PartitionAttributesFactory ready to create a
+   * <code>PartitionAttributes</code> with default settings.
+   */
+  public PartitionAttributesFactory() {
+  }
+
+  /**
+   * Creates a new instance of PartitionAttributesFactory ready to create a
+   * {@link PartitionAttributes} with the same settings as those in
+   * the specified {@link PartitionAttributes}
+   * 
+   * @param pa  the <code>PartitionAttributes</code> used to initialize this
+   *          PartitionAttributesFactory
+   */
+  public PartitionAttributesFactory(PartitionAttributes pa) {
+    this.partitionAttributes.setAll(pa);
+  
+  }
+
+  // CALLBACKS
+
+  /**
+   * 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.<p>
+   * <em>This setting must be the same in all processes using the Region.</em>
+   * Default number of redundant copies is 0.
+   * 
+   * @param redundantCopies
+   *          the number of redundant bucket copies, limited to values 0, 1, 2 and 3.
+   * 
+   * @return this
+   */
+  public PartitionAttributesFactory<K,V> setRedundantCopies(int redundantCopies)
+  {
+    this.partitionAttributes.setRedundantCopies(redundantCopies);
+    return this;
+  }
+
+  /**
+   * Sets the cache writer for the next <code>PartitionAttributes</code>
+   * created.  <i>Currently unsupported for the early access release.</i>
+   * 
+   * @param cacheWriter
+   *          the cache writer or null if no cache writer
+   * @return this
+  public PartitionAttributesFactory<K,V> setCacheWriter(CacheWriter cacheWriter)
+  {
+    this.partitionAttributes.setCacheWriter(cacheWriter);
+    return this;
+  }
+     */
+
+  /**
+   * Sets the maximum amount of memory, in megabytes, to be used by the
+   * region in this process.  If not set, a default of 
+   * 90% of available heap is used.
+   */
+  public PartitionAttributesFactory<K,V> setLocalMaxMemory(int mb) {
+    this.partitionAttributes.setLocalMaxMemory(mb);
+    return this;
+  }
+  
+  /**
+   * Sets the maximum amount of memory, in megabytes, to be used by the
+   * region in all processes.<p>
+   * <em>This setting must be the same in all processes using the Region.</em>
+   * The default value is Integer.MAX_VALUE.
+   */
+  public PartitionAttributesFactory<K,V> setTotalMaxMemory(long mb) {
+    this.partitionAttributes.setTotalMaxMemory(mb);
+    return this;
+  }
+  
+  /**
+   * Sets the total number of hash buckets to be used by the region in
+   * all processes.
+   * <p>
+   * <em>This setting must be the same in all processes using the Region.</em>
+   * <p>
+   * A bucket is the smallest unit of data management in a partitioned region.
+   * {@link com.gemstone.gemfire.cache.Region.Entry Entries} are stored in
+   * buckets and buckets may move from one VM to another. Buckets may also have
+   * copies, depending on {@link #setRedundantCopies(int) redundancy} to provide
+   * high availability in the face of VM failure.
+   * </p>
+   * <p>
+   * The number of buckets should be prime and as a rough guide at the least four
+   * times the number of partition VMs. However, there is significant overhead
+   * to managing a bucket, particularly for higher values of
+   * {@link #setRedundantCopies(int) redundancy}.
+   * </p>
+   * The default number of buckets for a PartitionedRegion is 113.
+   */
+  public PartitionAttributesFactory<K,V> setTotalNumBuckets(int numBuckets) {
+    this.partitionAttributes.setTotalNumBuckets(numBuckets);
+    return this;
+  }
+  /**
+   * Sets the <code>PartitionResolver</code> for the PartitionRegion.
+   */
+  public PartitionAttributesFactory<K,V> setPartitionResolver(
+                  PartitionResolver<K,V> resolver) {
+    this.partitionAttributes.setPartitionResolver(resolver);
+    return this;
+  }
+  /**
+   *  Sets the name of the PartitionRegion with which this newly created
+   *  partitioned region is colocated 
+   */
+  public PartitionAttributesFactory<K,V> setColocatedWith(String colocatedRegionFullPath) {
+    this.partitionAttributes.setColocatedWith(colocatedRegionFullPath);
+    return this;
+  }
+  
+  /**
+   *  Sets the delay in milliseconds that
+   * existing members will wait before satisfying redundancy
+   * after another member crashes. 
+   * Default value is set to -1 which indicates
+   * that redundancy will not be recovered after a failure.
+   * 
+   * @since 6.0
+   */
+  public PartitionAttributesFactory<K,V> setRecoveryDelay(long recoveryDelay) {
+    this.partitionAttributes.setRecoveryDelay(recoveryDelay);
+    return this;
+  }
+  
+  /**
+   *  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 (set to 0) is to recover redundancy immediately when a new
+   * member is added. 
+   * 
+   * @since 6.0
+   */
+  public PartitionAttributesFactory<K,V> setStartupRecoveryDelay(long startupRecoveryDelay) {
+    this.partitionAttributes.setStartupRecoveryDelay(startupRecoveryDelay);
+    return this;
+  }
+  
+  /**
+   * adds a PartitionListener for the partitioned region.
+   * 
+   * @param listener
+   * @return PartitionAttributeFactory
+   * @since 6.5
+   */
+  public PartitionAttributesFactory<K, V> addPartitionListener(
+      PartitionListener listener) {
+    if (listener == null) {
+      throw new IllegalArgumentException(
+          LocalizedStrings.PartitionAttributesFactory_PARTITION_LISTENER_PARAMETER_WAS_NULL
+              .toLocalizedString());
+    }
+    synchronized (this.partitionAttributes) {
+      this.partitionAttributes.addPartitionListener(listener);
+    }
+    return this;
+  }  
+  
+  /**
+   * Sets the <code>Properties</code> for the local instance the partitioned
+   * Region. Local properties define how the local instance of the partitioned
+   * region and any storage it may provide, behaves.  There are currently no
+   * non-deprecated local properties.
+   * @deprecated use {@link #setLocalMaxMemory(int)}  in GemFire 5.1 and later releases
+   * @param localProps
+   * @return PartitionAttributeFactory.
+   * 
+   */
+  @Deprecated
+  public PartitionAttributesFactory<K,V> setLocalProperties(Properties localProps)
+  {
+    if (localProps == null) {
+      return this;
+    }
+    this.partitionAttributes.setLocalProperties(localProps);
+ 
+    return this;
+  }
+
+  /**
+   * Sets the global <code>Properties</code> for the next <code>PartitionAttributes</code>
+   * created.  Global properties define how the entire partitioned Region behaves.
+   * <p>
+   * Note that global settings must be the same in all processes using the Region.
+   * 
+   * @deprecated use {@link #setTotalMaxMemory(long)} and {@link #setTotalNumBuckets(int)} in GemFire 5.1 and later releases
+   * @param globalProps
+   * @return PartitionAttributeFactory.
+   * 
+   * @see #GLOBAL_MAX_MEMORY_PROPERTY
+   */
+  @Deprecated
+  public PartitionAttributesFactory<K,V> setGlobalProperties(Properties globalProps)
+  {
+    this.partitionAttributes.setGlobalProperties(globalProps);
+    return this;
+  }
+  
+  /**
+   * FixedPartitionAttributes defined for this partitioned region is added to
+   * PR attributes.
+   * 
+   * @since 6.6
+   */
+  public PartitionAttributesFactory<K, V> addFixedPartitionAttributes(
+      FixedPartitionAttributes fpa) {
+    synchronized (this.partitionAttributes) {
+      this.partitionAttributes.addFixedPartitionAttributes(fpa);
+      return this;
+    }
+  }
+  
+  // EXPIRATION ATTRIBUTES
+
+  /**
+   * Sets the idleTimeout expiration attributes for region entries for the next
+   * <code>PartitionAttributes</code> created.
+   * 
+   * @param idleTimeout
+   *          the idleTimeout ExpirationAttributes for entries in this region
+   * @throws IllegalArgumentException
+   *           if idleTimeout is null
+   * @return PartitionAttributeFactory
+   */
+  /*
+  public PartitionAttributesFactory<K,V> setEntryIdleTimeout(
+      ExpirationAttributes idleTimeout)
+  {
+    if (idleTimeout == null) {
+      throw new IllegalArgumentException(LocalizedStrings.PartitionAttributesFactory_IDLETIMEOUT_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+    this.partitionAttributes.entryIdleTimeoutExpiration = idleTimeout;
+    return this;
+  }
+  */
+
+  /**
+   * Sets the timeToLive expiration attributes for region entries for the next
+   * <code>PartitionAttributes</code> created.
+   * 
+   * @param timeToLive
+   *          the timeToLive ExpirationAttributes for entries in this region
+   * @throws IllegalArgumentException
+   *           if timeToLive is null
+   */
+  /*
+  public PartitionAttributesFactory<K,V> setEntryTimeToLive(
+      ExpirationAttributes timeToLive)
+  {
+    if (timeToLive == null) {
+      throw new IllegalArgumentException(LocalizedStrings.PartitionAttributesFactory_TIMETOLIVE_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+    this.partitionAttributes.entryTimeToLiveExpiration = timeToLive;
+    return this;
+  }
+  */
+
+  /**
+   * Enables/Disables local Caching for this node for region entries for the
+   * next <code>PartitionAttributes</code> created. Default is true.
+   * 
+   * @param isLocalCache
+   * @return PartitionAttributesFactory
+   */
+  // TODO: Enable when we have local caching propertly implemented - mthomas
+  // 2/32/2006
+  // public PartitionAttributesFactory<K,V> enableLocalCaching(boolean isLocalCache)
+  // {
+  // this.partitionAttributes.localCaching = isLocalCache;
+  // return this;
+  // }
+  // DISTRIBUTION ATTRIBUTES
+  // FACTORY METHOD
+  /**
+   * Creates a <code>PartitionAttributes</code> with the current settings.
+   * 
+   * @return the newly created <code>PartitionAttributes</code>
+   * @throws IllegalStateException
+   *           if the current settings violate the <a
+   *           href="#compatibility">compatibility rules </a>
+   */
+  @SuppressWarnings("unchecked")
+  public PartitionAttributes<K,V> create()
+  {
+    this.partitionAttributes.validateAttributes();
+//    setDefaults();  [bruce] defaults are set in the PartitionedRegion when the
+//                            attributes are applied
+    return (PartitionAttributes<K,V>)this.partitionAttributes.clone();
+  }
+
+//  /**
+//   * This method sets the properties to their default values in preparation
+//   * for returning a PartitionAttributes to the user. For example, if it
+//   * doesn't have localMaxMemory, it would set it to
+//   * LOCAL_MAX_MEMORY_DEFAULT.
+//   * 
+//   */
+//  private void setDefaults()
+//  {
+//    if (this.partitionAttributes.localProperties
+//        .get(PartitionAttributesFactory.LOCAL_MAX_MEMORY_PROPERTY) == null) {
+//      this.partitionAttributes.setLocalMaxMemory(PartitionAttributesFactory.LOCAL_MAX_MEMORY_DEFAULT);
+//    }
+//
+//  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionResolver.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionResolver.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionResolver.java
new file mode 100755
index 0000000..61805dc
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionResolver.java
@@ -0,0 +1,76 @@
+/*
+ * ========================================================================= 
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved. 
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ * =========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * Implementers of interface <code>PartitionResolver</code> enable custom
+ * partitioning on the <code>PartitionedRegion</code>.<br>
+ * <p>
+ * 1. The Key class can implement PartitionResolver interface to
+ * enable custom partitioning OR <br>
+ * 2. Configure your own PartitionResolver class in partition attributes (For
+ * instance when the Key is a primitive type or String) Implement the
+ * appropriate equals - For all implementations, you need to be sure to code the
+ * class equals method so it properly verifies equality for the
+ * PartitionResolver implementation. This might mean verifying that class names
+ * are the same or that the returned routing objects are the same etc.. When you
+ * initiate the partitioned region on multiple nodes, GemFire uses the equals
+ * method to ensure you are using the same PartitionResolver implementation for
+ * all of the nodes for the region.
+ * </p>
+ * <p>
+ * GemFire uses the routing object's hashCode to determine where the data is
+ * being managed. Say, for example, you want to colocate all Trades by month and
+ * year.The key is implemented by TradeKey class which also implements the
+ * PartitionResolver interface.
+ * </p>
+ * public class TradeKey implements PartitionResolver {<br>
+ * &nbsp &nbsp private String tradeID;<br>
+ * &nbsp &nbsp private Month month ;<br>
+ * &nbsp &nbsp private Year year ;<br>
+ * 
+ * &nbsp &nbsp public TradingKey(){ } <br>
+ * &nbsp &nbsp public TradingKey(Month month, Year year){<br>
+ * &nbsp &nbsp &nbsp &nbsp this.month = month;<br>
+ * &nbsp &nbsp &nbsp &nbsp this.year = year;<br>
+ * &nbsp &nbsp } <br>
+ * &nbsp &nbsp public Object getRoutingObject(EntryOperation opDetails){<br>
+ * &nbsp &nbsp &nbsp &nbsp return this.month + this.year;<br>
+ * &nbsp &nbsp }<br> }<br>
+ * 
+ * In the example above, all trade entries with the same month and year are
+ * guaranteed to be colocated.
+ * </p>
+ * 
+ * @author Yogesh Mahajan
+ * @author Mitch Thomas
+ * 
+ * @since 6.0
+ */
+public interface PartitionResolver<K,V> extends CacheCallback {
+
+  /**
+   * @param opDetails
+   *                the detail of the entry operation e.g.
+   *                {@link Region#get(Object)}
+   * @throws RuntimeException
+   *                 any exception thrown will terminate the operation and the
+   *                 exception will be passed to the calling thread.
+   * @return object associated with entry operation which allows the Partitioned
+   *         Region to store associated data together
+   */
+  public Object getRoutingObject(EntryOperation<K,V> opDetails);
+
+  /**
+   * Returns the name of the PartitionResolver
+   * 
+   * @return String name
+   */
+  public String getName();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionedRegionDistributionException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionedRegionDistributionException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionedRegionDistributionException.java
new file mode 100644
index 0000000..b960582
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionedRegionDistributionException.java
@@ -0,0 +1,37 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * Indicates a failure to perform a distributed operation on a Partitioned Region 
+ * after multiple attempts.
+ *
+ * @since 5.1
+ * @author Mitch Thomas
+ */
+public class PartitionedRegionDistributionException extends
+   CacheRuntimeException
+{
+  private static final long serialVersionUID = -3004093739855972548L;
+   
+  public PartitionedRegionDistributionException() {
+    super();
+  }
+
+  public PartitionedRegionDistributionException(String msg) {
+    super(msg);
+  }
+
+  public PartitionedRegionDistributionException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+
+  public PartitionedRegionDistributionException(Throwable cause) {
+    super(cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionedRegionStorageException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionedRegionStorageException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionedRegionStorageException.java
new file mode 100644
index 0000000..4c97ffb
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/PartitionedRegionStorageException.java
@@ -0,0 +1,87 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * 
+ * <h3>Description of the conditions under which this exception is thrown</h3>
+ * <p>
+ * When a <code>PartitionedRegionStorageException</code> message contains
+ * the string:
+ * 
+ * <pre>
+ * There are not enough data store members to create a bucket.
+ * </pre>
+ * 
+ * A new data store must be added to the partitioned region for future bucket creation.
+ * </p>
+ * 
+ * <p>
+ * When a <code>PartitionedRegionStorageException</code> message contains
+ * the string:
+ * 
+ * <pre>
+ * Too many data store members have refused the request to create a bucket.
+ * </pre>
+ * 
+ * There are enough data stores, however some have refused possibly due to these
+ * conditions:
+ * <ol>
+ * <li>The amount of storage allocated to the partitioned region on that
+ * distributed member exceeds its localMaxMemory setting.</li>
+ * <li>The partitioned region instance on that distributed member has been
+ * closed or destroyed.</li>
+ * <li>The cache on that distributed member has been closed.</li>
+ * <li>The distributed system on that member has been disconnected.</li>
+ * </ol>
+ * </p>
+ * 
+ * <p>
+ * When a <code>PartitionedRegionStorageException</code> message contains
+ * the string:
+ * 
+ * <pre>
+ * Creation of a bucket for partitioned region failed in N attempts.
+ * </pre>
+ * If the number of attempts is lesser than the number of available
+ * data store members, contact GemFire support providing all logs and statistics files from 
+ * all members containing the partitioned region.  Otherwise, shutdown and then restart one 
+ * or more of the data stores, given that it is safe to do so, for example when redundantCopies 
+ * is greater than 0.
+ * </p>
+ * 
+ * 
+ * @see com.gemstone.gemfire.cache.PartitionAttributesFactory
+ * @since 5.0
+ */
+public class PartitionedRegionStorageException extends CacheRuntimeException  {
+private static final long serialVersionUID = 5905463619475329732L;
+
+    /** Creates a new instance of PartitionedRegionStorageException */
+    public PartitionedRegionStorageException() {
+    }
+    
+    
+    /**
+     * Creates a new {@link PartitionedRegionStorageException} with a message.
+     * @param msg The string message for the PartitionedRegionStorageException.
+     */
+ 
+    public PartitionedRegionStorageException(String msg) {
+      super(msg);
+    }    
+    
+    /**
+     * Creates a new {@link PartitionedRegionStorageException} with a message and Throwable cause.
+     * @param message The string message for the PartitionedRegionStorageException.
+     * @param cause Throwable cause for this {@link PartitionedRegionStorageException}.
+     */
+    public PartitionedRegionStorageException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}


[14/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionImpl.java
new file mode 100644
index 0000000..eca73fc
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionImpl.java
@@ -0,0 +1,326 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.NoRouteToHostException;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+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.cache.client.internal.ExecuteFunctionOp.ExecuteFunctionOpImpl;
+import com.gemstone.gemfire.cache.client.internal.ExecuteRegionFunctionOp.ExecuteRegionFunctionOpImpl;
+import com.gemstone.gemfire.cache.client.internal.ExecuteRegionFunctionSingleHopOp.ExecuteRegionFunctionSingleHopOpImpl;
+import com.gemstone.gemfire.cache.wan.GatewaySender;
+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.internal.SocketCreator;
+import com.gemstone.gemfire.internal.SocketUtils;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.tier.Acceptor;
+import com.gemstone.gemfire.internal.cache.tier.sockets.HandShake;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ServerQueueStatus;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+
+/**
+ * A single client to server connection.
+ * 
+ * The execute  method of this class is synchronized to
+ * prevent two ops from using the client to server connection
+ *  at the same time.
+ * @author dsmith
+ * @since 5.7
+ *
+ */
+public class ConnectionImpl implements Connection {
+  
+  private static Logger logger = LogService.getLogger();
+  
+  /**Test hook to simulate a client crashing. If true, we will
+   * not notify the server when we close the connection.
+   */
+  private static boolean TEST_DURABLE_CLIENT_CRASH = false;
+  
+  private Socket theSocket;
+  private ByteBuffer commBuffer;
+  private ByteBuffer commBufferForAsyncRead;
+//  private int handShakeTimeout = AcceptorImpl.DEFAULT_HANDSHAKE_TIMEOUT_MS;
+  private ServerQueueStatus status;
+  private volatile boolean connectFinished;
+  private final AtomicBoolean destroyed = new AtomicBoolean();
+  private Endpoint endpoint;
+  private short wanSiteVersion = -1;//In Gateway communication version of connected wan site
+                                   //will be stored after successful handshake
+//  private final CancelCriterion cancelCriterion;
+  private final DistributedSystem ds;
+
+  private OutputStream out;
+  private InputStream in;
+
+  private long connectionID = Connection.DEFAULT_CONNECTION_ID;
+
+  private HandShake handShake;
+
+  public ConnectionImpl(DistributedSystem ds, CancelCriterion cancelCriterion) {
+//    this.cancelCriterion = cancelCriterion;
+    this.ds = ds;
+  }
+  
+  public ServerQueueStatus connect(EndpointManager endpointManager,
+      ServerLocation location, HandShake handShake, int socketBufferSize,
+      int handShakeTimeout, int readTimeout, byte communicationMode, GatewaySender sender)
+      throws IOException {
+    SocketCreator sc = SocketCreator.getDefaultInstance();
+    DistributionConfig config = InternalDistributedSystem.getConnectedInstance().getConfig();
+    if (communicationMode == Acceptor.GATEWAY_TO_GATEWAY) {
+      sc = SocketCreator.createNonDefaultInstance(config.getGatewaySSLEnabled(),
+          config.getGatewaySSLRequireAuthentication(), config.getGatewaySSLProtocols(),
+          config.getGatewaySSLCiphers(), config.getGatewaySSLProperties());
+      if (sender!= null && !sender.getGatewayTransportFilters().isEmpty()) {
+        sc.initializeTransportFilterClientSocketFactory(sender);
+      }
+    } else {
+      //If configured use SSL properties for cache-server
+      sc = SocketCreator.createNonDefaultInstance(config.getServerSSLEnabled(),
+          config.getServerSSLRequireAuthentication(),
+          config.getServerSSLProtocols(),
+          config.getServerSSLCiphers(),
+          config.getServerSSLProperties());
+    }
+    if (!sc
+        .isHostReachable(InetAddress.getByName(location.getHostName()))) {
+      throw new NoRouteToHostException("Server is not reachable: " + location.getHostName());
+    }
+    theSocket = sc.connectForClient(
+        location.getHostName(), location.getPort(), handShakeTimeout, socketBufferSize);
+    theSocket.setTcpNoDelay(true);
+    //System.out.println("ConnectionImpl setting buffer sizes: " +
+    // socketBufferSize);
+    theSocket.setSendBufferSize(socketBufferSize);
+
+    // Verify buffer sizes
+    verifySocketBufferSize(socketBufferSize, theSocket.getReceiveBufferSize(), "receive");
+    verifySocketBufferSize(socketBufferSize, theSocket.getSendBufferSize(), "send");
+    
+    theSocket.setSoTimeout(handShakeTimeout);
+    out = SocketUtils.getOutputStream(theSocket);//theSocket.getOutputStream();
+    in = SocketUtils.getInputStream(theSocket);//theSocket.getInputStream();
+    this.status = handShake.greet(this, location, communicationMode);
+    commBuffer = ServerConnection.allocateCommBuffer(socketBufferSize);
+    if (sender != null) {
+      commBufferForAsyncRead = ServerConnection
+          .allocateCommBuffer(socketBufferSize);
+    }
+    theSocket.setSoTimeout(readTimeout);
+    endpoint = endpointManager.referenceEndpoint(location, this.status.getMemberId());
+    //logger.warning("ESTABLISHING ENDPOINT:"+location+" MEMBERID:"+endpoint.getMemberId(),new Exception());
+    this.connectFinished = true;
+    this.endpoint.getStats().incConnections(1);
+    return status;
+  }
+  
+  public void close(boolean keepAlive) throws Exception {
+    
+    try {
+      // if a forced-disconnect has occurred, we can't send messages to anyone
+      SocketCreator sc = SocketCreator.getDefaultInstance();
+      if (!sc.isHostReachable(this.theSocket.getInetAddress())) {
+        return;
+      }
+
+      boolean sendCloseMsg = !TEST_DURABLE_CLIENT_CRASH;
+      if (sendCloseMsg) {
+        try {
+          ((InternalDistributedSystem)ds).getDistributionManager();
+        }
+        catch (CancelException e) { // distribution has stopped
+          Throwable t = e.getCause();
+          if (t instanceof ForcedDisconnectException) {
+            // we're crashing - don't attempt to send a message (bug 39317)
+            sendCloseMsg = false;
+          }
+        }
+      }
+      
+      if (sendCloseMsg) {
+        if (logger.isDebugEnabled()) {
+          logger.debug("Closing connection {} with keepAlive: {}", this, keepAlive);
+        }
+        CloseConnectionOp.execute(this, keepAlive);
+      }
+    }
+    finally {
+      destroy();
+    }
+  }
+  
+  public void emergencyClose() {
+    commBuffer = null;
+    try {
+      theSocket.close();
+    } catch (IOException e) {
+      //ignore
+    } catch (RuntimeException e) {
+      //ignore
+    }
+  }
+
+  public boolean isDestroyed() {
+    return this.destroyed.get();
+  }
+  
+  public void destroy() {
+    if (!this.destroyed.compareAndSet(false, true)) {
+      // was already set to true so someone else did the destroy
+      return;
+    }
+
+    if (endpoint != null) {
+      if (this.connectFinished) {
+        endpoint.getStats().incConnections(-1);
+      }
+      endpoint.removeReference();
+    }
+    try {
+      if (theSocket != null)
+        theSocket.close();
+    }
+    catch (Exception e) {
+      if (logger.isDebugEnabled()) {
+        logger.debug(e.getMessage(), e);
+      }
+    }
+  }
+
+  public ByteBuffer getCommBuffer() {
+    return commBuffer;
+  }
+
+  public ServerLocation getServer() {
+    return endpoint.getLocation();
+  }
+
+  public Socket getSocket() {
+    return theSocket;
+  }
+  
+  public OutputStream getOutputStream() {
+    return out;
+  }
+  
+  public InputStream getInputStream() {
+    return in;
+  }
+  
+
+  public ConnectionStats getStats() {
+    return endpoint.getStats();
+  }
+  
+  @Override
+  public String toString() {
+    return "Connection[" + endpoint + "]@" + this.hashCode();
+  }
+
+  public Endpoint getEndpoint() {
+    return endpoint;
+  }
+
+  public ServerQueueStatus getQueueStatus() {
+    return status;
+  }
+
+  public Object execute(Op op) throws Exception {
+    Object result;
+    // Do not synchronize when used for GatewaySender
+    // as the same connection is being used 
+    if ((op instanceof AbstractOp) && ((AbstractOp)op).isGatewaySenderOp()) {
+      result = op.attempt(this);
+      endpoint.updateLastExecute();
+      return result;
+    }
+    synchronized (this) {
+      if (op instanceof ExecuteFunctionOpImpl
+          || op instanceof ExecuteRegionFunctionOpImpl
+          || op instanceof ExecuteRegionFunctionSingleHopOpImpl) {
+        int earliertimeout = this.getSocket().getSoTimeout();
+        this.getSocket().setSoTimeout(GemFireCacheImpl.getClientFunctionTimeout());
+        result = op.attempt(this);
+        this.getSocket().setSoTimeout(earliertimeout);
+      } else {
+        result = op.attempt(this);
+      }
+    }
+    endpoint.updateLastExecute();
+    return result;
+
+  }
+  
+  
+  public static void loadEmergencyClasses() {
+    //do nothing
+  }
+  public short getWanSiteVersion(){
+    return wanSiteVersion;
+  }
+  
+  public void setWanSiteVersion(short wanSiteVersion){
+    this.wanSiteVersion = wanSiteVersion;
+  }
+  
+  public int getDistributedSystemId() {
+    return ((InternalDistributedSystem)this.ds).getDistributionManager().getDistributedSystemId();
+  }
+  
+  public void setConnectionID(long id) {
+    this.connectionID = id;
+  }
+
+  public long getConnectionID() {
+    return this.connectionID;
+  }
+
+  protected HandShake getHandShake() {
+    return handShake;
+  }
+
+  protected void setHandShake(HandShake handShake) {
+    this.handShake = handShake;
+  }
+
+  /**
+   * test hook
+   */
+  public static void setTEST_DURABLE_CLIENT_CRASH(boolean v) {
+    TEST_DURABLE_CLIENT_CRASH = v;
+  }
+
+  public ByteBuffer getCommBufferForAsyncRead() {
+    return commBufferForAsyncRead;
+  }
+  
+  private void verifySocketBufferSize(int requestedBufferSize, int actualBufferSize, String type) {
+    if (actualBufferSize < requestedBufferSize) {
+      logger.info(LocalizedMessage.create(LocalizedStrings.Connection_SOCKET_0_IS_1_INSTEAD_OF_THE_REQUESTED_2,
+          new Object[] { new StringBuilder(type).append(" buffer size").toString(), actualBufferSize, requestedBufferSize }));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionSource.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionSource.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionSource.java
new file mode 100644
index 0000000..6cf5d65
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/internal/ConnectionSource.java
@@ -0,0 +1,68 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client.internal;
+
+import java.util.List;
+import java.util.Set;
+
+import com.gemstone.gemfire.distributed.internal.ServerLocation;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
+
+
+/**
+ * A source for discovering servers and finding the least loaded
+ * server to connect to.
+ * @author dsmith
+ * @since 5.7
+ *
+ */
+public interface ConnectionSource {
+  
+  ServerLocation findServer(Set/*<ServerLocation>*/ excludedServers);
+
+  /**
+   * Asks if we should replace a connection to <code>currentServer</code>
+   * with one to the returned server.
+   * @param currentServer the server we currently have a connection to.
+   * @param excludedServers the replacement server can not be one in this set
+   * @return the server we should connect to;
+   *         <code>currentServer</code> if a replacement is not needed;
+   *         <code>null</code> if no server found
+   */
+  ServerLocation findReplacementServer(ServerLocation currentServer, Set/*<ServerLocation>*/ excludedServers);
+  
+  /**
+   * Find the servers to host the queue
+   * 
+   * @param excludedServers
+   *                the servers to exclude from the search
+   * @param numServers
+   *                the number of servers to find, or -1 if we should just find
+   *                all of them
+   * @param proxyId
+   *                the proxy id for this client
+   * @param findDurableQueue
+   *                if true, the source should make an effort to find the
+   *                durable queues for this client
+   * @return a list of locations to connect to
+   */
+  List/* ServerLocation */findServersForQueue(
+      Set/* <ServerLocation> */excludedServers, int numServers,
+      ClientProxyMembershipID proxyId, boolean findDurableQueue);
+
+  void start(InternalPool poolImpl);
+
+  void stop();
+  
+  /**
+   * Check to see if the load on the servers is balanced, according
+   * to this connection source.
+   * @return true if the servers have balanced load.
+   */
+  boolean isBalanced();
+}


[44/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/GemFireMemberStatus.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/GemFireMemberStatus.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/GemFireMemberStatus.java
new file mode 100755
index 0000000..b1b91dd
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/GemFireMemberStatus.java
@@ -0,0 +1,705 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.client.PoolManager;
+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.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.internal.SocketCreator;
+import com.gemstone.gemfire.internal.admin.ClientHealthMonitoringRegion;
+import com.gemstone.gemfire.internal.admin.remote.ClientHealthStats;
+import com.gemstone.gemfire.internal.cache.CacheClientStatus;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.HARegion;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.cache.PartitionedRegion;
+import com.gemstone.gemfire.internal.cache.PartitionedRegionStatus;
+import com.gemstone.gemfire.internal.cache.RegionStatus;
+import com.gemstone.gemfire.internal.cache.tier.InternalBridgeMembership;
+import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID;
+
+/**
+ * Class <code>GemFireMemberStatus</code> provides the status of a specific
+ * GemFire member VM. This VM can be a peer, a client, a server and/or a
+ * gateway.
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public class GemFireMemberStatus implements Serializable {
+  private static final long serialVersionUID = 3389997790525991310L;
+
+  /**
+   * Notifies whether this member is a client to a cache server.
+   */
+  protected boolean _isClient;
+
+  /**
+   * Notifies whether this member is a cache server.
+   */
+  protected boolean _isServer;
+
+  /**
+   * Notifies whether this member is a hub for WAN gateways.
+   */
+  protected boolean _isGatewayHub;
+
+  /**
+   * Notifies whether this member is a locator.
+   */
+  protected boolean _isLocator;
+
+  protected boolean _isPrimaryGatewayHub;
+
+  protected Object/*GatewayHubStatus*/ _gatewayHubStatus;
+
+  protected boolean _isConnected;
+  protected Serializable _memberId;
+  protected Set _connectedPeers;
+  protected Set _connectedServers;
+  protected Set _unconnectedServers;
+  protected Set _connectedClients;
+  protected Map _connectedIncomingGateways;
+  protected Map _outgoingGateways;
+
+  protected Map _clientHostNames;
+  protected Map _clientQueueSizes;
+  protected Map _gatewayQueueSizes;
+  protected Map _regionStatuses;
+  protected Map _clientHealthStats;
+
+  protected String _memberName;
+  protected int _mcastPort;
+  protected int _serverPort;
+  protected InetAddress _mcastAddress;
+  protected String _bindAddress;
+  protected String _locators;
+  protected InetAddress _hostAddress;
+
+  protected long _maximumHeapSize;
+  protected long _freeHeapSize;
+  
+  protected long upTime = -1;
+
+  protected transient final Cache cache;
+  
+  public GemFireMemberStatus() {
+    this(null);
+  }
+
+  public GemFireMemberStatus(Cache cache) {
+    this.cache = cache;
+    DistributedSystem ds = null;
+    if (cache != null) {
+      ds = cache.getDistributedSystem();
+    }
+    initialize(ds);
+  }
+
+  public boolean getIsConnected() {
+    return this._isConnected;
+  }
+
+  protected void setIsConnected(boolean isConnected) {
+    this._isConnected = isConnected;
+  }
+
+  /**
+   * Returns whether this member is a client to a cache server
+   * @return whether this member is a client to a cache server
+   */
+  public boolean getIsClient() {
+    return this._isClient;
+  }
+
+  /**
+   * Sets whether this member is a client to a cache server
+   * @param isClient Boolean defining whether this member is a client to a
+   * cache server
+   */
+  protected void setIsClient(boolean isClient) {
+    this._isClient = isClient;
+  }
+
+  /**
+   * Returns whether this member is a cache server
+   * @return whether this member is a cache server
+   */
+  public boolean getIsServer() {
+    return this._isServer;
+  }
+
+  /**
+   * Sets whether this member is a cache server
+   * @param isServer Boolean defining whether this member is a cache server
+   */
+  protected void setIsServer(boolean isServer) {
+    this._isServer = isServer;
+  }
+
+  public int getServerPort() {
+	  return this._serverPort;
+  }
+  
+  protected void setServerPort(int port) {
+	  this._serverPort = port;
+  }
+  
+  /**
+   * Returns whether this member is a hub for WAN gateways
+   * @return whether this member is a hub for WAN gateways
+   */
+  public boolean getIsGatewayHub() {
+    return this._isGatewayHub;
+  }
+
+  /**
+   * Sets whether this member is a cache server
+   * @param isGatewayHub Boolean defining whether this member is a hub for
+   * WAN gateways
+   */
+  protected void setIsGatewayHub(boolean isGatewayHub) {
+    this._isGatewayHub = isGatewayHub;
+  }
+
+  public boolean getIsLocator() {
+    return this._isLocator;
+  }
+
+  protected void setIsLocator(boolean isLocator) {
+    this._isLocator = isLocator;
+  }
+
+  public boolean getIsPrimaryGatewayHub() {
+    return this._isPrimaryGatewayHub;
+  }
+
+  protected void setIsPrimaryGatewayHub(boolean isPrimaryGatewayHub) {
+    this._isPrimaryGatewayHub = isPrimaryGatewayHub;
+  }
+
+  /**
+   * For internal use only
+   * @return status of the gateway hub
+   */
+  public Object/*GatewayHubStatus*/ getGatewayHubStatus() {
+    return this._gatewayHubStatus;
+  }
+
+//  protected void setGatewayHubStatus(GatewayHubStatus gatewayHubStatus) {
+//    this._gatewayHubStatus = gatewayHubStatus;
+//  }
+
+  public boolean getIsSecondaryGatewayHub() {
+    return !this._isPrimaryGatewayHub;
+  }
+
+  public Set getConnectedPeers() {
+    return this._connectedPeers;
+  }
+
+  protected void setConnectedPeers(Set connectedPeers) {
+    this._connectedPeers = connectedPeers;
+  }
+
+  public Set getConnectedServers() {
+    return this._connectedServers;
+  }
+
+  protected void setConnectedServers(Set connectedServers) {
+    this._connectedServers = connectedServers;
+  }
+
+  protected void addConnectedServer(String connectedServer) {
+    this._connectedServers.add(connectedServer);
+  }
+
+  public Set getUnconnectedServers() {
+    return this._unconnectedServers;
+  }
+
+  protected void setUnconnectedServers(Set unconnectedServers) {
+    this._unconnectedServers = unconnectedServers;
+  }
+
+  protected void addUnconnectedServer(String unconnectedServer) {
+    this._unconnectedServers.add(unconnectedServer);
+  }
+
+  public Set getConnectedClients() {
+    return this._connectedClients;
+  }
+
+  protected void addConnectedClient(String connectedClient) {
+    this._connectedClients.add(connectedClient);
+  }
+
+  public Map getOutgoingGateways() {
+	    return this._outgoingGateways;
+  }
+
+  public Map getConnectedIncomingGateways() {
+    return this._connectedIncomingGateways;
+  }
+
+  protected void setConnectedIncomingGateways(Map connectedIncomingGateways) {
+    this._connectedIncomingGateways = connectedIncomingGateways;
+  }
+
+  public Map getClientQueueSizes() {
+    return this._clientQueueSizes;
+  }
+
+  protected void setClientQueueSizes(Map clientQueueSizes) {
+    this._clientQueueSizes = clientQueueSizes;
+  }
+
+  public int getClientQueueSize(String clientMemberId) {
+    Integer clientQueueSize = (Integer) getClientQueueSizes().get(clientMemberId);
+    return clientQueueSize == null ? 0 : clientQueueSize.intValue();
+  }
+
+  protected void putClientQueueSize(String clientMemberId, int size) {
+    getClientQueueSizes().put(clientMemberId, Integer.valueOf(size));
+  }
+
+  public Map getClientHealthStats() {
+    return this._clientHealthStats;
+  }
+  
+  protected void setClientHealthStats(Map stats) {
+    this._clientHealthStats = stats;
+  }
+  
+  /**
+   * For internal use only
+   * @param clientID client for health
+   * @return the client's health
+   */
+  public Object/*ClientHealthStats*/ getClientHealthStats(String clientID) {
+    return this._clientHealthStats.get(clientID);
+  }
+  
+  protected void setClientHealthStats(String clientID, ClientHealthStats stats) {
+    this._clientHealthStats.put(clientID, stats);
+  }
+  
+  protected void putClientHostName(String clientId, String hostName) {
+    this._clientHostNames.put(clientId, hostName);
+  }
+  
+  public String getClientHostName(String clientId) {
+    return (String)this._clientHostNames.get(clientId);
+  }
+  
+  public Map getRegionStatuses() {
+    return this._regionStatuses;
+  }
+
+  /**
+   * For internal use only
+   * @param fullRegionPath region path
+   * @return status for the region
+   */
+  public Object/*RegionStatus*/ getRegionStatus(String fullRegionPath) {
+    return getRegionStatuses().get(fullRegionPath);
+  }
+
+  protected void putRegionStatus(String fullRegionPath, RegionStatus status) {
+    getRegionStatuses().put(fullRegionPath, status);
+  }
+
+  public Serializable getMemberId() {
+    return this._memberId;
+  }
+
+  protected void setMemberId(Serializable memberId) {
+    this._memberId = memberId;
+  }
+
+  public String getMemberName() {
+    return this._memberName;
+  }
+
+  protected void setMemberName(String memberName) {
+    this._memberName = memberName;
+  }
+
+  public int getMcastPort() {
+    return this._mcastPort;
+  }
+
+  protected void setMcastPort(int mcastPort) {
+    this._mcastPort = mcastPort;
+  }
+
+  public InetAddress getMcastAddress() {
+    return this._mcastAddress;
+  }
+
+  protected void setMcastAddress(InetAddress mcastAddress) {
+    this._mcastAddress = mcastAddress;
+  }
+
+  public InetAddress getHostAddress() {
+    return this._hostAddress;
+  }
+
+  protected void setHostAddress(InetAddress hostAddress) {
+    this._hostAddress = hostAddress;
+  }
+
+  public String getBindAddress() {
+    return this._bindAddress;
+  }
+
+  protected void setBindAddress(String bindAddress) {
+    this._bindAddress = bindAddress;
+  }
+
+  public String getLocators() {
+    return this._locators;
+  }
+
+  protected void setLocators(String locators) {
+    this._locators = locators;
+  }
+
+  public long getMaximumHeapSize() {
+    return this._maximumHeapSize;
+  }
+
+  protected void setMaximumHeapSize(long size) {
+    this._maximumHeapSize = size;
+  }
+
+  public long getFreeHeapSize() {
+    return this._freeHeapSize;
+  }
+
+  protected void setFreeHeapSize(long size) {
+    this._freeHeapSize = size;
+  }
+
+  public long getUsedHeapSize() {
+    return getMaximumHeapSize() - getFreeHeapSize();
+  }
+  
+  public long getUpTime() {
+    return upTime;
+  }
+  
+  public void setUpTime(long upTime) {
+    this.upTime = upTime;
+  }
+
+  @Override
+  public String toString() {
+    StringBuffer buffer = new StringBuffer();
+    buffer
+      .append("GemFireMemberStatus[")
+      .append("isConnected=")
+      .append(this._isConnected)
+      .append("; memberName=")
+      .append(this._memberName)
+      .append("; memberId=")
+      .append(this._memberId)
+      .append("; hostAddress=")
+      .append(this._hostAddress)
+      .append("; mcastPort=")
+      .append(this._mcastPort)
+      .append("; mcastAddress=")
+      .append(this._mcastAddress)
+      .append("; bindAddress=")
+      .append(this._bindAddress)
+      .append("; serverPort=")
+      .append(this._serverPort)
+      .append("; locators=")
+      .append(this._locators)
+      .append("; isClient=")
+      .append(this._isClient)
+      .append("; isServer=")
+      .append(this._isServer)
+      .append("; isGatewayHub=")
+      .append(this._isGatewayHub)
+      .append("; isLocator=")
+      .append(this._isLocator)
+      .append("; isPrimaryGatewayHub=")
+      .append(this._isPrimaryGatewayHub)
+      .append("; gatewayHubStatus=")
+      .append(this._gatewayHubStatus)
+      .append("; connectedPeers=")
+      .append(this._connectedPeers)
+      .append("; connectedServers=")
+      .append(this._connectedServers)
+      .append("; unconnectedServers=")
+      .append(this._unconnectedServers)
+      .append("; connectedClients=")
+      .append(this._connectedClients)
+      .append("; clientHostNames=")
+      .append(this._clientHostNames)
+      .append("; clientQueueSizes=")
+      .append(this._clientQueueSizes)
+      .append("; clientHealthStats=")
+      .append(this._clientHealthStats)
+      .append("; gatewayQueueSizes=")
+      .append(this._gatewayQueueSizes)
+      .append("; regionStatuses=")
+      .append(this._regionStatuses)
+      .append("; maximumHeapSize=")
+      .append(this._maximumHeapSize)
+      .append("; freeHeapSize=")
+      .append(this._freeHeapSize)
+      .append("; upTime=")
+      .append(this.upTime)
+      .append("]");
+    return buffer.toString();
+  }
+  
+  protected void initialize(DistributedSystem distributedSystem) {
+    // Initialize instance variables
+    initializeInstanceVariables();
+
+    // If the cache is set, initialize the status.
+    // If the cache is not set, then this is most
+    // likely an unconnected status.
+    if (cache != null) {
+      // Initialize server
+      initializeServer();
+
+      // Initialize client
+      initializeClient();
+
+      // Initialize region sizes
+      initializeRegionSizes();
+    }
+
+    if (distributedSystem != null) {
+      // Initialize all
+      initializeAll(distributedSystem);
+    }
+
+    // If this is a locator, initialize the locator status
+    if (Locator.getLocators().size() > 0) {
+      setIsLocator(true);
+    }
+  }
+
+  protected void initializeInstanceVariables() {
+    // Variables for servers
+    this._connectedClients = new HashSet();
+    this._clientQueueSizes = new HashMap();
+    this._clientHealthStats = new HashMap();
+    this._clientHostNames = new HashMap();
+
+    // Variables for gateway hubs
+    this._outgoingGateways = new HashMap();
+    //this._connectedOutgoingGateways = new HashSet();
+    //this._unconnectedOutgoingGateways = new HashSet();
+    this._connectedIncomingGateways = new HashMap();
+    this._gatewayQueueSizes = new HashMap();
+
+    // Variables for clients
+    this._connectedServers = new HashSet();
+    this._unconnectedServers = new HashSet();
+
+    // Variables for all
+    this._connectedPeers = new HashSet();
+    this._regionStatuses = new HashMap();
+  }
+
+  protected void initializeServer() {
+    Collection servers = cache.getCacheServers();
+    if (servers.size() == 0) {
+      setIsServer(false);
+    } else {
+      setIsServer(true);
+
+      // Get connected clients.
+      // The following method returns a map of client member id to a cache
+      // client info. For now, keep track of the member ids in the set of
+      // _connectedClients.
+      Map allConnectedClients = InternalBridgeMembership.getStatusForAllClientsIgnoreSubscriptionStatus();
+      Iterator allConnectedClientsIterator = allConnectedClients.values().iterator();
+      while (allConnectedClientsIterator.hasNext()) {
+        CacheClientStatus ccs = (CacheClientStatus) allConnectedClientsIterator.next();
+        addConnectedClient(ccs.getMemberId());
+        // host address is available directly by id, hence CacheClientStatus need not be populated
+        putClientHostName(ccs.getMemberId(), ccs.getHostAddress());  
+      }
+
+      // Get client queue sizes
+      Map clientQueueSize = getClientIDMap(InternalBridgeMembership.getClientQueueSizes());
+      setClientQueueSizes(clientQueueSize);
+      
+      // Set server acceptor port (set it based on the first CacheServer)
+      CacheServer server = (CacheServer) servers.toArray()[0];
+      setServerPort(server.getPort());
+      
+      // Get Client Health Stats
+//      Assert.assertTrue(cache != null); (cannot be null)
+      Region clientHealthMonitoringRegion = ClientHealthMonitoringRegion.getInstance(
+          (GemFireCacheImpl)cache);
+      if(clientHealthMonitoringRegion != null) {
+        String [] clients = (String[])clientHealthMonitoringRegion.keySet().toArray(new String[0]);
+        for (int i = 0; i < clients.length; i++) {
+          String clientId = clients[i];
+          ClientHealthStats stats = (ClientHealthStats)clientHealthMonitoringRegion.get(clientId);
+          setClientHealthStats(clientId, stats);
+        } 
+      }
+    }
+  }
+  
+	/**
+	 * returning  Map of client queue size against client Id
+	 *  
+	 * param clientMap is a  Map of client queue size against ClientProxyMembershipID
+	 */
+	private Map getClientIDMap(Map ClientProxyMembershipIDMap) {
+	   Map clientIdMap = new HashMap();
+	   Set entrySet = ClientProxyMembershipIDMap.entrySet();
+	   Iterator entries = entrySet.iterator();
+	   while (entries.hasNext()) {
+             Map.Entry entry = (Map.Entry)entries.next();
+             ClientProxyMembershipID key = (ClientProxyMembershipID)entry.getKey();
+             Integer size = (Integer)entry.getValue();
+             clientIdMap.put(key.getDSMembership(), size);
+	   }
+           return clientIdMap;
+	  }
+
+  protected void initializeClient() {
+    // There are several ways to detect a client:
+    // - is a loner
+    // - has regions that use BridgeWriters or BridgeLoaders
+    // This method uses the presence of a connection proxy or
+    // a pool on the PoolManager.
+    Map poolMap = PoolManager.getAll();
+    if (poolMap.size() == 0) {
+      setIsClient(false);
+    } else {
+      setIsClient(true);
+
+      // Get connected servers.
+      // The following method returns a map of server name to a count of logical
+      // connections. A logical connection will be made for each region that
+      // references the live server. If the client is not connected to the server,
+      // the logical connections for that server will be 0. For now, keep track
+      // of the keys (server names) of this map in the sets of _connectedServers
+      // and _unconnectedServers.
+      Map connectedServers = InternalBridgeMembership.getConnectedServers();
+      if (!connectedServers.isEmpty()) {
+        Iterator connected = connectedServers.entrySet().iterator();
+        while (connected.hasNext()) {
+          Map.Entry entry = (Map.Entry) connected.next();
+          String server = (String) entry.getKey();
+//          Integer connections = (Integer) entry.getValue();
+//          if (connections.intValue()==0) {
+//            addUnconnectedServer(server);
+//          } else {
+            addConnectedServer(server);
+//          }
+          //System.out.println(connections.size() + " logical connnections to server " + server);
+        }
+      }
+    }
+  }
+
+  protected void initializeAll(DistributedSystem distributedSystem) {
+    // Initialize isConnected
+    setIsConnected(true);
+
+    // Initialize distributed system status
+    initializeDistributedSystem(distributedSystem);
+
+    // Initialize peers
+    initializePeers(distributedSystem);
+
+    // Initialize memory
+    initializeMemory();
+  }
+
+  protected void initializeDistributedSystem(DistributedSystem distributedSystem) {
+    InternalDistributedSystem ids = (InternalDistributedSystem) distributedSystem;
+    setMemberId(ids.getMemberId());
+    DistributionConfig config = ids.getConfig();
+    setMemberName(config.getName());
+    setMcastPort(config.getMcastPort());
+    setMcastAddress(config.getMcastAddress());
+    String bindAddress = config.getBindAddress();
+    setBindAddress(bindAddress);
+    setLocators(config.getLocators());
+    setUpTime(System.currentTimeMillis() - ids.getStartTime());
+    try {
+      setHostAddress((bindAddress != null && bindAddress.length() > 0)
+        ? InetAddress.getByName(bindAddress)
+        : SocketCreator.getLocalHost());
+    } catch (IOException e) {/*ignore - leave null host address*/}
+  }
+
+  protected void initializePeers(DistributedSystem distributedSystem) {
+    InternalDistributedSystem ids = (InternalDistributedSystem) distributedSystem;
+    DM dm = ids.getDistributionManager();
+    Set connections = dm.getOtherNormalDistributionManagerIds();
+    Set connectionsIDs = new HashSet(connections.size());
+    for (Iterator iter=connections.iterator(); iter.hasNext() ; ) {
+      InternalDistributedMember idm = (InternalDistributedMember)iter.next();
+      connectionsIDs.add(idm.getId());
+    }
+    setConnectedPeers(connectionsIDs);
+  }
+
+  protected void initializeMemory() {
+    //InternalDistributedSystem system = (InternalDistributedSystem) region.getCache().getDistributedSystem();
+    //GemFireStatSampler sampler = system.getStatSampler();
+    //VMStatsContract statsContract = sampler.getVMStats();
+
+    Runtime rt = Runtime.getRuntime();
+    setMaximumHeapSize(rt.maxMemory());
+    setFreeHeapSize(rt.freeMemory());
+  }
+
+  protected void initializeRegionSizes() {
+    Iterator rootRegions = cache.rootRegions().iterator();
+
+    while (rootRegions.hasNext()) {
+      LocalRegion rootRegion = (LocalRegion) rootRegions.next();
+      if (!(rootRegion instanceof HARegion)) {
+        RegionStatus rootRegionStatus = rootRegion instanceof PartitionedRegion
+          ? new PartitionedRegionStatus((PartitionedRegion) rootRegion)
+          : new RegionStatus(rootRegion);
+        putRegionStatus(rootRegion.getFullPath(), rootRegionStatus);
+        Iterator subRegions = rootRegion.subregions(true).iterator();
+        while (subRegions.hasNext()) {
+          LocalRegion subRegion = (LocalRegion) subRegions.next();
+          RegionStatus subRegionStatus = subRegion instanceof PartitionedRegion
+            ? new PartitionedRegionStatus((PartitionedRegion) subRegion)
+            : new RegionStatus(subRegion);
+          putRegionStatus(subRegion.getFullPath(), subRegionStatus);
+        }
+      }
+    }
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/ManagedEntity.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/ManagedEntity.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/ManagedEntity.java
new file mode 100644
index 0000000..3d0f48d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/ManagedEntity.java
@@ -0,0 +1,116 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+/**
+ * A entity that can be managed with the GemFire administration API.
+ *
+ * @see ManagedEntityConfig
+ *
+ * @author David Whitlock
+ * @since 4.0
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface ManagedEntity {
+
+  /**
+   * Starts this managed entity.  Note that this method may return
+   * before the managed entity is actually started.
+   *
+   * @throws AdminException
+   *         If a problem is encountered while starting this managed
+   *         entity. 
+   * @throws IllegalStateException
+   *         If this managed entity resides on a remote machine and a
+   *         <code>null</code> or empty (<code>""</code>) {@linkplain
+   *         ManagedEntityConfig#getRemoteCommand remote command} has
+   *         been specified.
+   *
+   * @see #waitToStart
+   */
+  public void start() throws AdminException;
+
+  /**
+   * Stops this managed entity.  Note that this method may return
+   * before the managed entity is actually stopped.
+   *
+   * @throws AdminException
+   *         If a problem is encountered while stopping this managed
+   *         entity. 
+   * @throws IllegalStateException
+   *         If this managed entity resides on a remote machine and a
+   *         <code>null</code> or empty (<code>""</code>) {@linkplain
+   *         ManagedEntityConfig#getRemoteCommand remote command} has
+   *         been specified.
+   *
+   * @see #waitToStop
+   */
+  public void stop() throws AdminException;
+
+  /**
+   * Waits for up to a given number of milliseconds for this managed
+   * entity to {@linkplain #start start}.
+   *
+   * @param timeout
+   *        The number of milliseconds to wait for this managed entity
+   *        to start.
+   *
+   * @return Whether or not the entity has started.
+   *         <code>false</code>, if the method times out.
+   *
+   * @throws InterruptedException
+   *         If the thread invoking this method is interrupted while
+   *         waiting. 
+   */
+  public boolean waitToStart(long timeout)
+    throws InterruptedException;
+
+  /**
+   * Waits for up to a given number of milliseconds for this managed
+   * entity to {@linkplain #stop stop}.
+   *
+   * @param timeout
+   *        The number of milliseconds to wait for this managed entity
+   *        to stop.
+   *
+   * @return Whether or not the entity has stopped.
+   *         <code>false</code>, if the method times out.
+   *
+   * @throws InterruptedException
+   *         If the thread invoking this method is interrupted while
+   *         waiting. 
+   */
+  public boolean waitToStop(long timeout)
+    throws InterruptedException;
+
+  /**
+   * Returns whether or not this managed entity is running.  Note that
+   * this operation may attempt to contact the managed entity.
+   *
+   * @throws IllegalStateException
+   *         If this managed entity resides on a remote machine and a
+   *         <code>null</code> or empty (<code>""</code>) {@linkplain
+   *         ManagedEntityConfig#getRemoteCommand remote command} has
+   *         been specified.
+   */
+  public boolean isRunning();
+
+  /**
+   * Returns the tail of this manage entity's log file.  Note that not
+   * all managed entities implement this functionality.
+   *
+   * @throws AdminException
+   *         If a problem is encountered while getting the log of this
+   *         managed entity.
+   * @throws UnsupportedOperationException
+   *         If this managed entity does not support retrieving its
+   *         log.
+   */
+  public String getLog() throws AdminException;
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/ManagedEntityConfig.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/ManagedEntityConfig.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/ManagedEntityConfig.java
new file mode 100644
index 0000000..b49e411
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/ManagedEntityConfig.java
@@ -0,0 +1,91 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+/**
+ * Common configuration for all entities that can be managed using the
+ * GemFire administration API.  Note that once a managed entity has
+ * been {@linkplain ManagedEntity#start started}, attempts to modify
+ * its configuration will cause an {@link IllegalStateException} to be
+ * thrown.
+ *
+ * @see ManagedEntity
+ *
+ * @author David Whitlock
+ * @since 4.0
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface ManagedEntityConfig extends Cloneable {
+
+  /**
+   * Returns the name of the host on which the managed entity runs or
+   * will run.
+   */
+  public String getHost();
+
+  /**
+   * Sets the name of the host on which the managed entity will run.
+   */
+  public void setHost(String host);
+
+  /**
+   * Returns the name of the working directory in which the managed
+   * entity runs or will run.
+   */
+  public String getWorkingDirectory();
+
+  /**
+   * Sets the name of the working directory in which the managed
+   * entity will run.
+   */
+  public void setWorkingDirectory(String dir);
+
+  /**
+   * Returns the name of the GemFire product directory to use when
+   * administering the managed entity.
+   */
+  public String getProductDirectory();
+
+  /**
+   * Sets the name of the GemFire product directory to use when
+   * administering the managed entity.
+   */
+  public void setProductDirectory(String dir);
+
+  /**
+   * Returns the command prefix used to administer a managed entity
+   * that is hosted on a remote machine.  If the remote command is
+   * <code>null</code> (the default value), then the remote command
+   * associated with the {@linkplain
+   * AdminDistributedSystem#getRemoteCommand() distributed system}
+   * will be used.
+   */
+  public String getRemoteCommand();
+
+  /**
+   * Sets the command prefix used to administer a managed entity that
+   * is hosted on a remote machine.
+   */
+  public void setRemoteCommand(String remoteCommand);
+
+  /**
+   * Validates this configuration.
+   *
+   * @throws IllegalStateException
+   *         If a managed entity cannot be administered using this
+   *         configuration 
+   */
+  public void validate();
+
+  /**
+   * Returns a new <code>ManagedEntityConfig</code> with the same
+   * configuration as this <code>ManagedEntityConfig</code>.
+   */
+  public Object clone() throws CloneNotSupportedException; 
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/MemberHealthConfig.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/MemberHealthConfig.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/MemberHealthConfig.java
new file mode 100644
index 0000000..5ae1610
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/MemberHealthConfig.java
@@ -0,0 +1,133 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+/**
+ * Provides configuration information relating to the health of a
+ * member of a GemFire distributed system.
+ *
+ * <P>
+ *
+ * If any of the following criteria is true, then a member is
+ * considered to be in {@link GemFireHealth#OKAY_HEALTH OKAY_HEALTH}.
+ *
+ * <UL>
+ *
+ * <LI>The size of the {@linkplain #getMaxVMProcessSize VM process} is
+ * too large.</LI>
+ *
+ * <LI>There are too many {@linkplain #getMaxMessageQueueSize enqueued}
+ * incoming/outgoing messages.</LI>
+ *
+ * <LI>Too many message sends {@link #getMaxReplyTimeouts timeout}
+ * while waiting for a reply.</LI>
+ *
+ * </UL>
+ *
+ * If any of the following criteria is true, then a member is
+ * considered to be in {@link GemFireHealth#POOR_HEALTH POOR_HEALTH}.
+ *
+ * <UL>
+ *
+ * </UL>
+ *
+ * @author David Whitlock
+ *
+ * @since 3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ * */
+public interface MemberHealthConfig {
+
+  /** The default maximum VM process size (in megabytes) of a health
+   * member of the distributed system. The default value is 1000. */
+  public static final long DEFAULT_MAX_VM_PROCESS_SIZE = 1000;
+
+  /** The default maximum number of enqueued incoming or outgoing
+   * messages that a healthy member of a distributed system can have.
+   * The default value is 1000. */
+  public static final long DEFAULT_MAX_MESSAGE_QUEUE_SIZE = 1000;
+
+  /** The default maximum number of message reply timeouts that can
+   * occur in a given health monitoring interval. The default value
+   * is zero. */
+  public static final long DEFAULT_MAX_REPLY_TIMEOUTS = 0;
+
+  /** The default maximum multicast retransmission ratio.  The default
+   * value is 0.20 (twenty percent of messages retransmitted)
+   */
+  public static final double DEFAULT_MAX_RETRANSMISSION_RATIO = 0.20;
+  
+  ///////////////////////  Instance Methods  ///////////////////////
+
+  /**
+   * Returns the maximum VM process size (in megabytes) of a healthy
+   * member of the distributed system.
+   *
+   * @see #DEFAULT_MAX_VM_PROCESS_SIZE
+   */
+  public long getMaxVMProcessSize();
+
+  /**
+   * Sets the maximum VM process size (in megabytes) of a healthy
+   * member of the distributed system.
+   *
+   * @see #getMaxVMProcessSize
+   */
+  public void setMaxVMProcessSize(long size);
+  
+  /**
+   * Returns the maximum number of enqueued incoming or outgoing
+   * messages that a healthy member of a distributed system can have.
+   *
+   * @see #DEFAULT_MAX_MESSAGE_QUEUE_SIZE
+   */
+  public long getMaxMessageQueueSize();
+
+  /**
+   * Sets the maximum number of enqueued incoming or outgoing
+   * messages that a healthy member of a distributed system can have.
+   *
+   * @see #getMaxMessageQueueSize
+   */
+  public void setMaxMessageQueueSize(long maxMessageQueueSize);
+
+  /**
+   * Returns the maximum number message replies that can timeout in a
+   * healthy member.
+   *
+   * @see #DEFAULT_MAX_REPLY_TIMEOUTS
+   */
+  public long getMaxReplyTimeouts();
+
+  /**
+   * Sets the maximum number message replies that can timeout in a
+   * healthy member.
+   *
+   * @see #getMaxReplyTimeouts
+   */
+  public void setMaxReplyTimeouts(long maxReplyTimeouts);
+
+  /**
+   * Returns the maximum ratio of multicast retransmissions / total multicast
+   * messages.  Retransmissions are requestor-specific (i.e., unicast), so
+   * a single lost message may result in multiple retransmissions.<p>
+   * A high retransmission ratio may indicate
+   * poor network conditions requiring reduced flow-control settings,
+   * a udp-fragment-size setting that is too high.
+   * @see #DEFAULT_MAX_RETRANSMISSION_RATIO
+   */
+  public double getMaxRetransmissionRatio();
+  
+  /**
+   * Sets the maximum ratio of multicast retransmissions / total multicast
+   * messages.
+   * @see #getMaxRetransmissionRatio
+   */
+  public void setMaxRetransmissionRatio(double ratio);
+   
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/OperationCancelledException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/OperationCancelledException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/OperationCancelledException.java
new file mode 100644
index 0000000..746be25
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/OperationCancelledException.java
@@ -0,0 +1,39 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.admin;
+
+//import com.gemstone.gemfire.GemFireException;
+
+/**
+ * Thrown when an administration operation that accesses information
+ * in a remote system member is cancelled.  The cancelation may occur
+ * because the system member has left the distributed system.
+ *
+ * @since 3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public class OperationCancelledException extends RuntimeAdminException {
+   private static final long serialVersionUID = 5474068770227602546L;
+    
+    public OperationCancelledException() {
+      super();
+    }
+    
+    public OperationCancelledException( String message ) {
+        super( message );
+    }
+    
+    public OperationCancelledException( Throwable cause ){
+      super(cause);
+    }
+    
+    public OperationCancelledException( String message, Throwable cause ) {
+      super(message, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/RegionNotFoundException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/RegionNotFoundException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/RegionNotFoundException.java
new file mode 100644
index 0000000..1111631
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/RegionNotFoundException.java
@@ -0,0 +1,30 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+//import com.gemstone.gemfire.cache.CacheException;
+import com.gemstone.gemfire.cache.CacheRuntimeException;
+
+/**
+ * Thrown by the administration API when the region administered by a
+ * {@link SystemMemberRegion} has been closed or destroyed in system
+ * member. 
+ * <P>Also thrown by {@link com.gemstone.gemfire.DataSerializer#readRegion(java.io.DataInput)}
+ * if the named region no longer exists.
+ *
+ * @since 3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public class RegionNotFoundException extends CacheRuntimeException {
+private static final long serialVersionUID = 1758668137691463909L;
+
+  public RegionNotFoundException(String message) {
+    super(message);
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/RegionSubRegionSnapshot.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/RegionSubRegionSnapshot.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/RegionSubRegionSnapshot.java
new file mode 100644
index 0000000..a703103
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/RegionSubRegionSnapshot.java
@@ -0,0 +1,184 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.i18n.LogWriterI18n;
+import com.gemstone.gemfire.internal.cache.PartitionedRegion;
+
+/**
+ * Class <code>RegionSubRegionSnapshot</code> provides information about
+ * <code>Region</code>s. This also provides the information about sub regions
+ * This class is used by the monitoring tool.
+ * 
+ * @author Harsh Khanna
+ * 
+ * @since 5.7
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public class RegionSubRegionSnapshot implements DataSerializable {
+  private static final long serialVersionUID = -8052137675270041871L;
+  public RegionSubRegionSnapshot() {
+    this.parent = null;
+    this.subRegionSnapshots = new HashSet();
+  }
+
+  public RegionSubRegionSnapshot(Region reg) {
+    this();
+    this.name = reg.getName();
+    if (reg instanceof PartitionedRegion) {
+      PartitionedRegion p_reg = (PartitionedRegion)reg;
+      this.entryCount = p_reg.entryCount(true);
+    }
+    else {
+      this.entryCount = reg.entrySet().size();
+    }
+    final LogWriterI18n logger = reg.getCache().getLoggerI18n();
+    if((logger != null) && logger.fineEnabled()) {
+      logger.fine(
+        "RegionSubRegionSnapshot Region entry count =" + this.entryCount
+        + " for region =" + this.name);
+    }
+  }
+
+  /**
+   * add the snapshot of sub region
+   * 
+   * @param snap
+   *                snapshot of sub region
+   * @return true if operation is successful
+   */
+  public boolean addSubRegion(RegionSubRegionSnapshot snap) {
+    if (subRegionSnapshots.contains(snap)) {
+      return true;
+    }
+
+    if (subRegionSnapshots.add(snap)) {
+      snap.setParent(this);
+      return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * @return get entry count of region
+   */
+  public final int getEntryCount() {
+    return entryCount;
+  }
+
+  /**
+   * @param entryCount
+   *                entry count of region
+   */
+  public final void setEntryCount(int entryCount) {
+    this.entryCount = entryCount;
+  }
+
+  /**
+   * @return name of region
+   */
+  public final String getName() {
+    return name;
+  }
+
+  /**
+   * @param name
+   *                name of region
+   */
+  public final void setName(String name) {
+    this.name = name;
+  }
+
+  /**
+   * @return subRegionSnapshots of all the sub regions
+   */
+  public final Set getSubRegionSnapshots() {
+    return subRegionSnapshots;
+  }
+
+  /**
+   * @param subRegionSnapshots
+   *                subRegionSnapshots of all the sub regions
+   */
+  public final void setSubRegionSnapshots(Set subRegionSnapshots) {
+    this.subRegionSnapshots = subRegionSnapshots;
+  }
+
+  /**
+   * @return snapshot of parent region
+   */
+  public final RegionSubRegionSnapshot getParent() {
+    return parent;
+  }
+
+  /**
+   * @param parent
+   *                snapshot of parent region
+   */
+  public final void setParent(RegionSubRegionSnapshot parent) {
+    this.parent = parent;
+  }
+
+  /**
+   * 
+   * @return full path of region
+   */
+  public String getFullPath() {
+    return (getParent() == null ? "/" : getParent().getFullPath()) + getName()
+        + "/";
+  }
+
+  public void toData(DataOutput out) throws IOException {
+    DataSerializer.writeString(this.name, out);
+    out.writeInt(this.entryCount);
+    DataSerializer.writeHashSet((HashSet)this.subRegionSnapshots, out);
+  }
+
+  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+    this.name = DataSerializer.readString(in);
+    this.entryCount = in.readInt();
+    this.subRegionSnapshots = DataSerializer.readHashSet(in);
+    for (Iterator iter = this.subRegionSnapshots.iterator(); iter.hasNext();) {
+      ((RegionSubRegionSnapshot)iter.next()).setParent(this);
+    }
+  }
+
+  @Override
+  public String toString() {
+    String toStr = "RegionSnapshot [" + "path=" + this.getFullPath()
+        + ",parent=" + (this.parent == null ? "null" : this.parent.name)
+        + ", entryCount=" + this.entryCount + ", subRegionCount="
+        + this.subRegionSnapshots.size() + "<<";
+
+    for (Iterator iter = subRegionSnapshots.iterator(); iter.hasNext();) {
+      toStr = toStr + ((RegionSubRegionSnapshot)iter.next()).getName() + ", ";
+    }
+
+    toStr = toStr + ">>" + "]";
+    return toStr;
+  }
+
+  protected String name;
+
+  protected int entryCount;
+
+  protected RegionSubRegionSnapshot parent;
+
+  protected Set subRegionSnapshots;
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/RuntimeAdminException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/RuntimeAdminException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/RuntimeAdminException.java
new file mode 100755
index 0000000..072c47e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/RuntimeAdminException.java
@@ -0,0 +1,41 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+   
+package com.gemstone.gemfire.admin;
+
+/**
+ * A <code>RuntimeAdminException</code> is thrown when a runtime errors occurs
+ * during administration or monitoring of GemFire. 
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public class RuntimeAdminException 
+extends com.gemstone.gemfire.GemFireException {
+
+  private static final long serialVersionUID = -7512771113818634005L;
+
+  public RuntimeAdminException() {
+    super();
+  }
+
+  public RuntimeAdminException(String message) {
+    super(message);
+  }
+
+  public RuntimeAdminException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  public RuntimeAdminException(Throwable cause) {
+    super(cause);
+  }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/Statistic.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/Statistic.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/Statistic.java
new file mode 100755
index 0000000..cd795f0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/Statistic.java
@@ -0,0 +1,57 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.admin;
+
+/**
+ * Interface to represent a single statistic of a <code>StatisticResource</code>
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface Statistic extends java.io.Serializable {
+    
+  /**
+   * Gets the identifying name of this statistic.
+   *
+   * @return the identifying name of this statistic 
+   */
+  public String getName();
+    
+  /**
+   * Gets the value of this statistic as a <code>java.lang.Number</code>.
+   *
+   * @return the value of this statistic
+   */
+  public Number getValue();
+  
+  /**
+   * Gets the unit of measurement (if any) this statistic represents.
+   *
+   * @return the unit of measurement (if any) this statistic represents
+   */
+  public String getUnits();
+  
+  /**
+   * Returns true if this statistic represents a numeric value which always 
+   * increases.
+   *
+   * @return true if this statistic represents a value which always increases
+   */
+  public boolean isCounter();
+  
+  /**
+   * Gets the full description of this statistic.
+   *
+   * @return the full description of this statistic
+   */
+  public String getDescription();
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/StatisticResource.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/StatisticResource.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/StatisticResource.java
new file mode 100755
index 0000000..f6323f0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/StatisticResource.java
@@ -0,0 +1,77 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+/**
+ * Adminitrative interface for monitoring a statistic resource in a GemFire
+ * system member.  A resource is comprised of one or many 
+ * <code>Statistics</code>.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface StatisticResource {
+  
+  /**
+   * Gets the identifying name of this resource.
+   *
+   * @return the identifying name of this resource
+   */
+  public String getName();
+
+  /**
+   * Gets the full description of this resource.
+   *
+   * @return the full description of this resource
+   */
+  public String getDescription();
+  
+  /**
+   * Gets the classification type of this resource.
+   *
+   * @return the classification type of this resource
+   * @since 5.0
+   */
+  public String getType();
+  
+  /**
+   * Returns a display string of the {@link SystemMember} owning this 
+   * resource.
+   *
+   * @return a display string of the owning {@link SystemMember}
+   */
+  public String getOwner();
+  
+  /**
+   * Returns an ID that uniquely identifies the resource within the
+   * {@link SystemMember} it belongs to.
+   *
+   * @return unique id within the owning {@link SystemMember}
+   */
+  public long getUniqueId();
+  
+  /**
+   * Returns a read-only array of every {@link Statistic} in this resource.
+   *
+   * @return read-only array of every {@link Statistic} in this resource
+   */
+  public Statistic[] getStatistics();
+  
+  /**
+   * Refreshes the values of every {@link Statistic} in this resource by
+   * retrieving them from the member's VM.
+   *
+   * @throws com.gemstone.gemfire.admin.AdminException 
+   *         if unable to refresh statistic values
+   */
+  public void refresh() throws com.gemstone.gemfire.admin.AdminException;
+  
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMember.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMember.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMember.java
new file mode 100755
index 0000000..7c7374b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMember.java
@@ -0,0 +1,139 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+import com.gemstone.gemfire.distributed.DistributedMember;
+
+import java.net.InetAddress;
+
+/**
+ * Administrative interface for monitoring a GemFire system member.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface SystemMember {
+  
+  /** Gets the {@link AdminDistributedSystem} this member belongs to. */
+  public AdminDistributedSystem getDistributedSystem();
+  
+  /** 
+   * Gets identifying name of this member.
+   * For applications this is the string form of {@link #getDistributedMember}.
+   * For cache servers it is a unique cache server string.
+   */
+  public String getId();
+  
+  /** 
+   * Retrieves display friendly name for this member.  If this member defined 
+   * an optional name for its connection to the distributed system, that name 
+   * will be returned.  Otherwise the returned value will be {@link
+   * com.gemstone.gemfire.admin.SystemMember#getId}.
+   *
+   * @see com.gemstone.gemfire.distributed.DistributedSystem#connect
+   * @see com.gemstone.gemfire.distributed.DistributedSystem#getName
+   */
+  public String getName();
+  
+  /** Gets the type of {@link SystemMemberType} this member is. */
+  public SystemMemberType getType();
+  
+  /** Gets host name of the machine this member resides on. */
+  public String getHost();
+
+  /** Gets the host of this member as an <code>java.net.InetAddress<code>. */
+  public InetAddress getHostAddress();
+  
+  /** Retrieves the log for this member. */
+  public String getLog();
+
+  /**
+   * Returns the GemFire license this member is using.
+   *
+   * @deprecated Removed licensing in 8.0.
+   */
+   @Deprecated
+   public java.util.Properties getLicense();
+
+  /** Returns this member's GemFire version information. */
+  public String getVersion();
+  
+  /** 
+   * Gets the configuration parameters for this member.
+   */
+  public ConfigurationParameter[] getConfiguration();
+  
+  /**
+   * Sets the configuration of this member.  The argument is an array of any
+   * and all configuration parameters that are to be updated in the member.
+   * <p>
+   * The entire array of configuration parameters is then returned.
+   *
+   * @param parms subset of the configuration parameters to be changed
+   * @return all configuration parameters including those that were changed
+   * @throws com.gemstone.gemfire.admin.AdminException
+   *         if this fails to make the configuration changes
+   */
+  public ConfigurationParameter[] setConfiguration(ConfigurationParameter[] parms) throws com.gemstone.gemfire.admin.AdminException;
+  
+  /** Refreshes this member's configuration from the member or it's properties */
+  public void refreshConfig() throws com.gemstone.gemfire.admin.AdminException;
+  
+  /** 
+   * Retrieves this members statistic resources. If the member is not running 
+   * then an empty array is returned. 
+   *
+   *@param statisticsTypeName String ame of the Statistics Type
+   * @return array of runtime statistic resources owned by this member
+   * @since 5.7
+   */
+  public StatisticResource[] getStat(String statisticsTypeName) throws com.gemstone.gemfire.admin.AdminException;
+  
+  /** 
+   * Retrieves this members statistic resources. If the member is not running 
+   * then an empty array is returned. All Stats are returned
+   *
+   * @return array of runtime statistic resources owned by this member
+   */
+  public StatisticResource[] getStats() throws com.gemstone.gemfire.admin.AdminException;
+  
+  /**
+   * Returns whether or not this system member hosts a GemFire {@link
+   * com.gemstone.gemfire.cache.Cache Cache}.
+   *
+   * @see #getCache
+   */
+  public boolean hasCache()
+    throws com.gemstone.gemfire.admin.AdminException;
+
+  /**
+   * Returns an object that provides admin access to this member's cache.
+   * If the member currently has no cache then <code>null</code> is returned.
+   */
+  public SystemMemberCache getCache() throws com.gemstone.gemfire.admin.AdminException;
+  
+  /**
+   * Returns the names of the membership roles filled by this member.
+   *
+   * @return array of string membership role names
+   * @since 5.0
+   */
+  public String[] getRoles();
+  
+  /**
+   * Returns the {@link com.gemstone.gemfire.distributed.DistributedMember}
+   * that represents this system member.
+   *
+   * @return DistributedMember instance representing this system member
+   * @since 5.0
+   */
+  public DistributedMember getDistributedMember();
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberBridgeServer.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberBridgeServer.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberBridgeServer.java
new file mode 100644
index 0000000..4cef371
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberBridgeServer.java
@@ -0,0 +1,301 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+import com.gemstone.gemfire.cache.server.ServerLoadProbe;
+
+/**
+ * Administrative interface that represents a {@link
+ * com.gemstone.gemfire.cache.util.BridgeServer BridgeServer} that
+ * serves the contents of a system member's cache. 
+ *
+ * @see SystemMemberCache#addBridgeServer
+ *
+ * @author David Whitlock
+ * @since 4.0
+ * @deprecated as of 5.7 use {@link SystemMemberCacheServer} instead.
+ */
+@Deprecated
+public interface SystemMemberBridgeServer {
+
+  /** 
+   * Returns the port on which this bridge server listens for bridge
+   * clients to connect.
+   */
+  public int getPort();
+
+  /**
+   * Sets the port on which this bridge server listens for bridge
+   * clients to connect.
+   *
+   * @throws AdminException
+   *         If this bridge server is running
+   */
+  public void setPort(int port) throws AdminException;
+
+  /**
+   * Starts this bridge server.  Once the server is running, its
+   * configuration cannot be changed.
+   *
+   * @throws AdminException
+   *         If an error occurs while starting the bridge server
+   */
+  public void start() throws AdminException;
+
+  /** 
+   * Returns whether or not this bridge server is running
+   */
+  public boolean isRunning();
+
+  /**
+   * Stops this bridge server.  Note that the
+   * <code>BridgeServer</code> can be reconfigured and restarted if
+   * desired.
+   */
+  public void stop() throws AdminException;
+
+  /**
+   * Updates the information about this bridge server.
+   */
+  public void refresh();
+
+  /**
+   * Returns a string representing the ip address or host name that this server
+   * will listen on.
+   * @return the ip address or host name that this server is to listen on
+   * @since 5.7
+   */
+  public String getBindAddress();
+  /**
+   * Sets the ip address or host name that this server is to listen on for
+   * client connections.
+   * <p>Setting a specific bind address will cause the bridge server to always
+   * use this address and ignore any address specified by "server-bind-address"
+   * or "bind-address" in the <code>gemfire.properties</code> file
+   * (see {@link com.gemstone.gemfire.distributed.DistributedSystem}
+   * for a description of these properties).
+   * <p> A <code>null</code> value will be treated the same as the default "".
+   * <p> The default value does not override the gemfire.properties. If you wish to
+   * override the properties and want to have your server bind to all local
+   * addresses then use this string <code>"0.0.0.0"</code>.
+   * @param address the ip address or host name that this server is to listen on
+   * @throws AdminException if this bridge server is running
+   * @since 5.7
+   */
+  public void setBindAddress(String address) throws AdminException;
+  /**
+   * Returns a string representing the ip address or host name that server locators
+   * will tell clients that this server is listening on.
+   * @return the ip address or host name to give to clients so they can connect
+   *         to this server
+   * @since 5.7
+   */
+  public String getHostnameForClients();
+  /**
+   * Sets the ip address or host name that this server is to listen on for
+   * client connections.
+   * <p>Setting a specific hostname-for-clients will cause server locators
+   * to use this value when telling clients how to connect to this server.
+   * <p> The default value causes the bind-address to be given to clients
+   * <p> A <code>null</code> value will be treated the same as the default "".
+   * @param name the ip address or host name that will be given to clients
+   *   so they can connect to this server
+   * @throws AdminException if this bridge server is running
+   * @since 5.7
+   */
+  public void setHostnameForClients(String name) throws AdminException;
+  /**
+   * Sets whether or not this bridge server should notify clients based on
+   * key subscription.
+   *
+   * If false, then an update to any key on the server causes an update to
+   * be sent to all clients. This update does not push the actual data to the
+   * clients. Instead, it causes the client to locally invalidate or destroy
+   * the corresponding entry. The next time the client requests the key, it
+   * goes to the bridge server for the value.
+   *
+   * If true, then an update to any key on the server causes an update to be
+   * sent to only those clients who have registered interest in that key. Other
+   * clients are not notified of the change. In addition, the actual value is
+   * pushed to the client. The client does not need to request the new value
+   * from the bridge server.
+   * @throws AdminException if this bridge server is running
+   * @since 5.7
+   */
+  public void setNotifyBySubscription(boolean b) throws AdminException;
+
+  /**
+   * Answers whether or not this bridge server should notify clients based on
+   * key subscription.
+   * @since 5.7
+   */
+  public boolean getNotifyBySubscription();
+
+  /**
+   * Sets the buffer size in bytes of the socket connection for this
+   * <code>BridgeServer</code>. The default is 32768 bytes.
+   *
+   * @param socketBufferSize The size in bytes of the socket buffer
+   * @throws AdminException if this bridge server is running
+   * @since 5.7
+   */
+  public void setSocketBufferSize(int socketBufferSize) throws AdminException;
+
+  /**
+   * Returns the configured buffer size of the socket connection for this
+   * <code>BridgeServer</code>. The default is 32768 bytes.
+   * @return the configured buffer size of the socket connection for this
+   * <code>BridgeServer</code>
+   * @since 5.7
+   */
+  public int getSocketBufferSize();
+
+  /**
+   * Sets the maximum amount of time between client pings. This value is
+   * used by the <code>ClientHealthMonitor</code> to determine the health
+   * of this <code>BridgeServer</code>'s clients. The default is 60000 ms.
+   *
+   * @param maximumTimeBetweenPings The maximum amount of time between client
+   * pings
+   * @throws AdminException if this bridge server is running
+   * @since 5.7
+   */
+  public void setMaximumTimeBetweenPings(int maximumTimeBetweenPings) throws AdminException;
+
+  /**
+   * Returns the maximum amount of time between client pings. This value is
+   * used by the <code>ClientHealthMonitor</code> to determine the health
+   * of this <code>BridgeServer</code>'s clients. The default is 60000 ms.
+   * @return the maximum amount of time between client pings.
+   * @since 5.7
+   */
+  public int getMaximumTimeBetweenPings();
+
+  /** 
+   *  Returns the maximum allowed client connections
+   * @since 5.7
+   */
+  public int getMaxConnections();
+
+  /**
+   * Sets the maxium number of client connections allowed.
+   * When the maximum is reached the server will stop accepting
+   * connections.
+   * @throws AdminException if this bridge server is running
+   * @since 5.7
+   */
+  public void setMaxConnections(int maxCons) throws AdminException;
+
+  /** 
+   * Returns the maxium number of threads allowed in this server to service
+   * client requests.
+   * The default of <code>0</code> causes the server to dedicate a thread for
+   * every client connection.
+   * @since 5.7
+   */
+  public int getMaxThreads();
+
+  /**
+   * Sets the maxium number of threads allowed in this server to service
+   * client requests.
+   * The default of <code>0</code> causes the server to dedicate a thread for
+   * every client connection.
+   * @throws AdminException if this bridge server is running
+   * @since 5.7
+   */
+  public void setMaxThreads(int maxThreads) throws AdminException;
+
+  /**
+   * Returns the maximum number of messages that can be enqueued in a
+   * client-queue.
+   * @since 5.7
+   */
+  public int getMaximumMessageCount();
+
+  /**
+   * Sets maximum number of messages that can be enqueued in a client-queue.
+   * @throws AdminException if this bridge server is running
+   * @since 5.7
+   */
+  public void setMaximumMessageCount(int maxMessageCount) throws AdminException;
+  
+  /**
+   * Returns the time (in seconds ) after which a message in the client queue
+   * will expire.
+   * @since 5.7
+   */
+  public int getMessageTimeToLive();
+
+  /**
+   * Sets the time (in seconds ) after which a message in the client queue
+   * will expire.
+   * @throws AdminException if this bridge server is running
+   * @since 5.7
+   */
+  public void setMessageTimeToLive(int messageTimeToLive) throws AdminException;
+  /**
+   * Sets the list of server groups this bridge server will belong to.
+   * By default bridge servers belong to the default global server group
+   * which all bridge servers always belong to.
+   * @param groups possibly empty array of <code>String</code> where each string
+   * is a server groups that this bridge server will be a member of.
+   * @throws AdminException if this bridge server is running
+   * @since 5.7
+   */
+  public void setGroups(String[] groups) throws AdminException;
+  /**
+   * Returns the list of server groups that this bridge server belongs to.
+   * @return a possibly empty array of <code>String</code>s where
+   * each string is a server group. Modifying this array will not change the
+   * server groups that this bridge server belongs to.
+   * @since 5.7
+   */
+  public String[] getGroups();
+  
+  /**
+   * Get a description of the load probe for this bridge server.
+   * {@link ServerLoadProbe} for details on the load probe.
+   * @return the load probe used by this bridge
+   * server.
+   * @since 5.7
+   */
+  public String getLoadProbe();
+
+  /**
+   * Set the load probe for this bridge server. See
+   * {@link ServerLoadProbe} for details on how to implement
+   * a load probe.
+   * 
+   * The load probe should implement DataSerializable if 
+   * it is used with this interface, because it will be sent to the remote
+   * VM.
+   * @param loadProbe the load probe to use for
+   * this bridge server.
+   * @throws AdminException  if the bridge server is running
+   * @since 5.7
+   */
+  public void setLoadProbe(ServerLoadProbe loadProbe) throws AdminException;
+
+  /**
+   * Get the frequency in milliseconds to poll the load probe on this bridge
+   * server.
+   * 
+   * @return the frequency in milliseconds that we will poll the load probe.
+   */
+  public long getLoadPollInterval();
+
+  /**
+   * Set the frequency in milliseconds to poll the load probe on this bridge
+   * server
+   * @param loadPollInterval the frequency in milliseconds to poll
+   * the load probe. Must be greater than 0.
+   * @throws AdminException if the bridge server is running
+   */
+  public void setLoadPollInterval(long loadPollInterval) throws AdminException;
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberCache.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberCache.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberCache.java
new file mode 100644
index 0000000..00749d6
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberCache.java
@@ -0,0 +1,223 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+import com.gemstone.gemfire.cache.RegionAttributes;
+
+/**
+ * Administrative interface that represent's the {@link SystemMember}'s view
+ * of its {@link com.gemstone.gemfire.cache.Cache}.
+ *
+ * @author    Darrel Schneider
+ * @since     3.5
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface SystemMemberCache {
+  // attributes
+  /**
+   * The name of the cache.
+   */
+  public String getName();
+  /**
+   * Value that uniquely identifies an instance of a cache for a given member.
+   */
+  public int getId();
+  /**
+   * Indicates if this cache has been closed.
+   * @return true, if this cache is closed; false, otherwise
+   */
+  public boolean isClosed();
+  /**
+   * Gets the number of seconds a cache operation will wait to obtain
+   * a distributed lock lease.
+   */
+  public int getLockTimeout();
+  /**
+   * Sets the number of seconds a cache operation may wait to obtain a
+   * distributed lock lease before timing out.
+   *
+   * @throws AdminException
+   *         If a problem is encountered while setting the lock
+   *         timeout 
+   *
+   * @see com.gemstone.gemfire.cache.Cache#setLockTimeout
+   */
+  public void setLockTimeout(int seconds) throws AdminException;
+  
+  /**
+   * Gets the length, in seconds, of distributed lock leases obtained
+   * by this cache.
+   */
+  public int getLockLease();
+  /**
+   * Sets the length, in seconds, of distributed lock leases obtained
+   * by this cache.
+   *
+   * @throws AdminException
+   *         If a problem is encountered while setting the lock
+   *         lease
+   *
+   * @see com.gemstone.gemfire.cache.Cache#setLockLease
+   */
+  public void setLockLease(int seconds) throws AdminException;
+  
+  /**
+   * Gets the number of seconds a cache
+   * {@link com.gemstone.gemfire.cache.Region#get(Object) get} operation
+   * can spend searching for a value before it times out.
+   * The search includes any time spent loading the object.
+   * When the search times out it causes the get to fail by throwing
+   * an exception.
+   */
+  public int getSearchTimeout();
+  /**
+   * Sets the number of seconds a cache get operation can spend searching
+   * for a value.
+   *
+   * @throws AdminException
+   *         If a problem is encountered while setting the search
+   *         timeout 
+   *
+   * @see com.gemstone.gemfire.cache.Cache#setSearchTimeout
+   */
+  public void setSearchTimeout(int seconds) throws AdminException;
+  /**
+   * Returns number of seconds since this member's cache has been created.
+   * Returns <code>-1</code> if this member does not have a cache or its cache
+   * has been closed.
+   */
+  public int getUpTime();
+
+  /**
+   * Returns the names of all the root regions currently in this cache.
+   */
+  public java.util.Set getRootRegionNames();
+
+  // operations
+
+  /**
+   * Returns statistics related to this cache's performance.
+   */
+  public Statistic[] getStatistics();
+
+  /**
+   * Return the existing region (or subregion) with the specified
+   * path that already exists in the cache.
+   * Whether or not the path starts with a forward slash it is interpreted as a
+   * full path starting at a root.
+   *
+   * @param path the path to the region
+   * @return the Region or null if not found
+   * @throws IllegalArgumentException if path is null, the empty string, or "/"
+   */
+  public SystemMemberRegion getRegion(String path) throws AdminException;
+
+  /**
+   * Creates a VM root <code>Region</code> in this cache.
+   *
+   * @param name
+   *        The name of the region to create
+   * @param attrs
+   *        The attributes of the root region
+   *
+   * @throws AdminException
+   *         If the region cannot be created
+   *
+   * @since 4.0
+   * @deprecated as of GemFire 5.0, use {@link #createRegion} instead
+   */
+  @Deprecated
+  public SystemMemberRegion createVMRegion(String name,
+                                           RegionAttributes attrs)
+    throws AdminException;
+
+  /**
+   * Creates a root <code>Region</code> in this cache.
+   *
+   * @param name
+   *        The name of the region to create
+   * @param attrs
+   *        The attributes of the root region
+   *
+   * @throws AdminException
+   *         If the region cannot be created
+   *
+   * @since 5.0
+   */
+  public SystemMemberRegion createRegion(String name,
+                                         RegionAttributes attrs)
+    throws AdminException;
+
+  /**
+   * Updates the state of this cache instance. Note that once a cache
+   * instance is closed refresh will never change the state of that instance.
+   */
+  public void refresh();
+
+  /**
+   * Adds a new, unstarted bridge server that will serve the contents
+   * of this cache.
+   *
+   * @see com.gemstone.gemfire.cache.Cache#addBridgeServer
+   *
+   * @since 4.0
+   * @deprecated as of 5.7 use {@link #addCacheServer} instead.
+   */
+  @Deprecated
+  public SystemMemberBridgeServer addBridgeServer()
+    throws AdminException;
+
+  /**
+   * Returns the bridge servers that run in this member's VM.  Note
+   * that this list will not be updated until {@link #refresh} is
+   * called.
+   *
+   * @see com.gemstone.gemfire.cache.Cache#getBridgeServers
+   *
+   * @since 4.0
+   * @deprecated as of 5.7 use {@link #getCacheServers} instead.
+   */
+  @Deprecated
+  public SystemMemberBridgeServer[] getBridgeServers()
+    throws AdminException;
+
+  /**
+   * Adds a new, unstarted cache server that will serve the contents
+   * of this cache to clients.
+   *
+   * @see com.gemstone.gemfire.cache.Cache#addCacheServer
+   *
+   * @since 5.7
+   */
+  public SystemMemberCacheServer addCacheServer()
+    throws AdminException;
+
+  /**
+   * Returns the cache servers that run in this member's VM.  Note
+   * that this list will not be updated until {@link #refresh} is
+   * called.
+   *
+   * @see com.gemstone.gemfire.cache.Cache#getCacheServers
+   *
+   * @since 5.7
+   */
+  public SystemMemberCacheServer[] getCacheServers()
+    throws AdminException;
+
+  /**
+   * Returns whether or not this cache acts as a server.  This method
+   * will always return <code>true</code> for the
+   * <code>SystemMemberCache</code> obtained from a {@link
+   * CacheServer}.  Note that this value will not be updated until
+   * {@link #refresh} is invoked.
+   *
+   * @since 4.0
+   */
+  public boolean isServer() throws AdminException;
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberCacheEvent.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberCacheEvent.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberCacheEvent.java
new file mode 100644
index 0000000..86ffcf3
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberCacheEvent.java
@@ -0,0 +1,18 @@
+package com.gemstone.gemfire.admin;
+
+import com.gemstone.gemfire.cache.Operation;
+/**
+ * An event that describes an operation on a cache.
+ * Instances of this are delivered to a {@link SystemMemberCacheListener} when a
+ * a cache is created or closed.
+ *
+ * @author Darrel Schneider
+ * @since 5.0
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface SystemMemberCacheEvent extends SystemMembershipEvent {
+  /**
+   * Returns the actual operation that caused this event.
+   */
+  public Operation getOperation();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberCacheListener.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberCacheListener.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberCacheListener.java
new file mode 100644
index 0000000..0afd855
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/SystemMemberCacheListener.java
@@ -0,0 +1,64 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin;
+
+import com.gemstone.gemfire.cache.*;
+
+/**
+ * A listener whose callback methods can be used to track the lifecycle of
+ * {@link Cache caches} and {@link Region regions} in the GemFire distributed system.
+ *
+ * @see AdminDistributedSystem#addCacheListener
+ * @see AdminDistributedSystem#removeCacheListener
+ *
+ * @author Darrel Schneider
+ * @since 5.0 
+ * @deprecated as of 7.0 use the {@link com.gemstone.gemfire.management} package instead
+ */
+public interface SystemMemberCacheListener {
+
+  /**
+   * Invoked after a region is created in any node of distributed system.
+   * @param event describes the region that was created.
+   * @see CacheFactory#create
+   * @see Cache#createRegion
+   * @see Region#createSubregion
+   */
+  public void afterRegionCreate(SystemMemberRegionEvent event);
+
+  /**
+   * Invoked when a region is destroyed or closed in any node of distributed system.
+   * @param event describes the region that was lost. The operation on this event
+   * can be used to determine the actual operation that caused the loss. Note that
+   * {@link Cache#close()} invokes this callback with <code>Operation.CACHE_CLOSE</code>
+   * for each region in the closed cache and it invokes {@link #afterCacheClose}.
+   
+   * @see Cache#close()
+   * @see Region#close
+   * @see Region#localDestroyRegion()
+   * @see Region#destroyRegion()
+   */
+  public void afterRegionLoss(SystemMemberRegionEvent event);
+
+  /**
+   * Invoked after a cache is created in any node of a distributed system.
+   * Note that this callback will be done before any regions are created in the
+   * cache.
+   * @param event describes the member that created the cache.
+   * @see CacheFactory#create
+   */
+  public void afterCacheCreate(SystemMemberCacheEvent event);
+  /**
+   * Invoked after a cache is closed in any node of a distributed system.
+   * This callback is done after those done for each region in the cache.
+   * This callback is not done if the distributed member that has a cache crashes.
+   * @param event describes the member that closed its cache.
+   * @see Cache#close()
+   */
+  public void afterCacheClose(SystemMemberCacheEvent event);
+}


[17/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientCacheFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientCacheFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientCacheFactory.java
new file mode 100644
index 0000000..48bc074
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientCacheFactory.java
@@ -0,0 +1,680 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache.client;
+
+import java.util.Properties;
+
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.server.CacheServer;
+import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.internal.GemFireVersion;
+import com.gemstone.gemfire.internal.cache.CacheConfig;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.jndi.JNDIInvoker;
+import com.gemstone.gemfire.pdx.PdxSerializer;
+import com.gemstone.gemfire.pdx.PdxInstance;
+
+/**
+Factory class used to create the singleton {@link ClientCache client cache} and connect to one or more GemFire Cache Servers. If the application wants to connect to GemFire as a peer it should use {@link com.gemstone.gemfire.cache.CacheFactory} instead.
+<p> Once the factory has been configured using its set* methods you produce a {@link ClientCache} by calling the {@link #create} method.
+The
+<a href="../distribution/DistributedSystem.html#cache-xml-file">"cache-xml-file"</a>
+property can be used to specify a cache.xml file to initialize the cache with.
+The contents of this file must comply with the
+ <code>"doc-files/cache8_0.dtd"</code> file and the top level element must be a <code>client-cache</code> element.
+<p> Client connections are managed through connection {@link Pool pools}. ClientCacheFactory creates a single pool to use by default on the cache it creates. ClientCacheFactory can also be used to configure the default connection pool using its <code>setPool*</code> and <code>addPool*</code> methods. In most cases, the defaults used by this implementation will suffice. For the default pool attributes see {@link PoolFactory}.
+If no pool is configured and a pool was not declared in cache.xml or created using {@link PoolManager} then a default one will be created that connects to a server on the default cache server port and local host. If multiple pools are declared in cache.xml or created by the PoolFactory then no default pool will exist and <code>ClientRegionFactory.setPoolName</code> will need to be called on each region created.
+<p>
+To get the existing unclosed singleton client cache instance call {@link #getAnyInstance}.
+<p>
+The following examples illustrate bootstrapping the client cache using region shortcuts:
+<p>
+Example 1: Connect to a CacheServer on the default host and port and access a region "customers"
+<PRE>
+  ClientCache c = new ClientCacheFactory().create();
+  Region r = c.createClientRegionFactory(PROXY).create("customers");
+  // The PROXY shortcut tells GemFire to route all requests to the servers
+  //. i.e. there is no local caching
+</PRE>
+Example 2: Connect using the GemFire locator and create a local LRU cache
+<PRE>
+  ClientCache c = new ClientCacheFactory()
+      .addPoolLocator(host, port)
+      .create();
+  Region r = c.createClientRegionFactory(CACHING_PROXY_HEAP_LRU)
+      .create("customers");
+  // The local LRU "customers" data region will automatically start evicting, by default, at 80% heap utilization threshold
+</PRE>
+Example 3: Access the query service
+<PRE>
+  QueryService qs = new ClientCacheFactory().create().getQueryService();
+</PRE>
+Example 4: Construct the client cache region declaratively in cache.xml
+<PRE>
+  &lt;!DOCTYPE client-cache PUBLIC
+    "-//GemStone Systems, Inc.//GemFire Declarative Caching 6.5//EN"
+    "http://www.gemstone.com/dtd/cache8_0.dtd">
+  &lt;client-cache>	
+    &lt;pool name="myPool">
+      &lt;locator host="hostName" port="10334"/>
+    &lt;/pool>
+    &lt;region name="myRegion" refid="PROXY"/>
+      &lt;!-- you can override or add to the PROXY attributes by adding
+           a region-attributes sub element here -->
+  &lt;/client-cache>
+</PRE>
+Now, create the cache telling it to read your cache.xml file:
+<PRE>
+  ClientCache c = new ClientCacheFactory()
+    .set("cache-xml-file", "myCache.xml")
+    .create();
+  Region r = c.getRegion("myRegion");
+</PRE>
+
+<p> For a complete list of all client region shortcuts see {@link ClientRegionShortcut}. 
+Applications that need to explicitly control the individual region attributes can do this declaratively in XML or using API.
+<p>
+Example 5: Define custom region attributes for persistence in XML and create region using API.
+  Define new region attributes with ID "MYAPP_CACHING_PROXY_MEM_LRU" that overrides the 
+  "CACHING_PROXY" shortcut
+<PRE>
+ &lt;!DOCTYPE client-cache PUBLIC
+    "-//GemStone Systems, Inc.//GemFire Declarative Caching 8.0//EN"
+    "http://www.gemstone.com/dtd/cache8_0.dtd">
+ &lt;client-cache>
+  &lt;!-- now create a named region attributes that uses the CACHING_PROXY shortcut
+       and adds a memory LRU limited to 900 megabytes --> 
+  &lt;region-attributes id="MYAPP_CACHING_PROXY_MEM_LRU" refid="CACHING_PROXY" >
+    &lt;lru-memory-size maximum="900"/>
+  &lt;/region-attributes>
+ &lt;/client-cache> 
+</PRE>
+Now, create the data region in the client cache using this new attributes ID.
+<PRE>
+  ClientCache c = new ClientCacheFactory()
+    .set("cache-xml-file", "myCache.xml")
+    .addPoolLocator(host, port)
+    .create();
+  Region r = c.createClientRegionFactory("MYAPP_CACHING_PROXY_MEM_LRU").create("customers");
+</PRE>
+ * @since 6.5
+ * @author darrel
+ */
+public class ClientCacheFactory {
+
+  private PoolFactory pf;
+  
+  private final Properties dsProps;
+
+  private final CacheConfig cacheConfig = new CacheConfig();
+  
+  /**
+   * Creates a new client cache factory.
+   */
+  public ClientCacheFactory() {
+    this.dsProps = new Properties();
+  }
+  /**
+   * Create a new client cache factory given the initial gemfire properties.
+   * @param props The initial gemfire properties to be used.
+   * These properties can be overridden using the {@link #set} method
+   * For a full list of valid gemfire properties see {@link com.gemstone.gemfire.distributed.DistributedSystem}.
+   */
+  public ClientCacheFactory(Properties props) {
+    if (props == null) {
+      props = new Properties();
+    }
+    this.dsProps = props;
+  }
+
+  /**
+   * Sets a gemfire property that will be used when creating the ClientCache.
+   * For a full list of valid gemfire properties see {@link com.gemstone.gemfire.distributed.DistributedSystem}.
+   * @param name the name of the gemfire property
+   * @param value the value of the gemfire property
+   * @return a reference to this ClientCacheFactory object
+   */
+  public ClientCacheFactory set(String name, String value) {
+    this.dsProps.setProperty(name, value);
+    return this;
+  }
+
+  /**
+   * Create a singleton client cache. If a client cache already exists in this
+   * vm that is not compatible with this factory's configuration then create
+   * will fail.
+   * <p> While creating the cache instance any declarative cache configuration (cache.xml) is processed and used to initialize the created cache.
+   * <P>Note that the cache that is produced is a singleton. Before a different instance
+   * can be produced the old one must be {@link ClientCache#close closed}.
+   * @return the singleton client cache
+   * @throws IllegalStateException if a client cache already exists and it
+   * is not compatible with this factory's configuration.
+   */
+  public ClientCache create() {
+    return basicCreate();
+  }
+
+  private ClientCache basicCreate() {
+    synchronized (ClientCacheFactory.class) {
+    GemFireCacheImpl instance = GemFireCacheImpl.getInstance();
+
+    {
+      String propValue = this.dsProps.getProperty("mcast-port");
+      if (propValue != null) {
+        int mcastPort = Integer.parseInt(propValue);
+        if (mcastPort != 0) {
+          throw new IllegalStateException("On a client cache the mcast-port must be set to 0 or not set. It was set to " + mcastPort);
+        }
+      }
+    }
+    {
+      String propValue = this.dsProps.getProperty("locators");
+      if (propValue != null && !propValue.equals("")) {
+        throw new IllegalStateException("On a client cache the locators property must be set to an empty string or not set. It was set to \"" + propValue + "\".");
+      }
+    }
+    this.dsProps.setProperty("mcast-port", "0");
+    this.dsProps.setProperty("locators", "");
+    DistributedSystem system = DistributedSystem.connect(this.dsProps);
+
+    if (instance != null && !instance.isClosed()) {
+      // this is ok; just make sure it is a client cache
+      if (!instance.isClient()) {
+        throw new IllegalStateException("A client cache can not be created because a non-client cache already exists.");
+      }
+
+      // check if pool is compatible
+      Pool pool = instance.determineDefaultPool(this.pf);
+      if (pool == null) {
+        if (instance.getDefaultPool() != null) {
+          throw new IllegalStateException("Existing cache's default pool was not compatible");
+        }
+      }
+      
+      // Check if cache configuration matches.
+      cacheConfig.validateCacheConfig(instance);
+      
+      return instance;
+    } else {
+      GemFireCacheImpl gfc = GemFireCacheImpl.create(true, this.pf, system, cacheConfig);
+      return gfc;
+    }
+    }
+  }
+
+  private PoolFactory getPoolFactory() {
+    if (this.pf == null) {
+      this.pf = PoolManager.createFactory();
+    }
+    return this.pf;
+  }
+  
+  /**
+   * Sets the free connection timeout for this pool.
+   * If the pool has a max connections setting, operations will block
+   * if all of the connections are in use. The free connection timeout
+   * specifies how long those operations will block waiting for
+   * a free connection before receiving
+   * an {@link AllConnectionsInUseException}. If max connections 
+   * is not set this setting has no effect.
+   * @see #setPoolMaxConnections(int)
+   * @param connectionTimeout the connection timeout in milliseconds
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>connectionTimeout</code>
+   * is less than or equal to <code>0</code>.
+   */
+  public ClientCacheFactory setPoolFreeConnectionTimeout(int connectionTimeout) {
+    getPoolFactory().setFreeConnectionTimeout(connectionTimeout);
+    return this;
+  }
+  /**
+   * Sets the load conditioning interval for this pool.
+   * This interval controls how frequently the pool will check to see if 
+   * a connection to a given server should be moved to a different
+   * server to improve the load balance.  
+   * <p>A value of <code>-1</code> disables load conditioning
+   * @param loadConditioningInterval the connection lifetime in milliseconds
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>connectionLifetime</code>
+   * is less than <code>-1</code>.
+   */
+  public ClientCacheFactory setPoolLoadConditioningInterval(int loadConditioningInterval) {
+    getPoolFactory().setLoadConditioningInterval(loadConditioningInterval);
+    return this;
+  }
+
+  /**
+   * Sets the socket buffer size for each connection made in this pool.
+   * Large messages can be received and sent faster when this buffer is larger.
+   * Larger buffers also optimize the rate at which servers can send events
+   * for client subscriptions.
+   * @param bufferSize the size of the socket buffers used for reading and
+   * writing on each connection in this pool.
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>bufferSize</code>
+   * is less than or equal to <code>0</code>.
+   */
+  public ClientCacheFactory setPoolSocketBufferSize(int bufferSize) {
+    getPoolFactory().setSocketBufferSize(bufferSize);
+    return this;
+  }
+
+  /**
+   * Sets the thread local connections policy for this pool.
+   * If <code>true</code> then any time a thread goes to use a connection
+   * from this pool it will check a thread local cache and see if it already
+   * has a connection in it. If so it will use it. If not it will get one from
+   * this pool and cache it in the thread local. This gets rid of thread contention
+   * for the connections but increases the number of connections the servers see.
+   * <p>If <code>false</code> then connections are returned to the pool as soon
+   * as the operation being done with the connection completes. This allows
+   * connections to be shared amonst multiple threads keeping the number of
+   * connections down.
+   * @param threadLocalConnections if <code>true</code> then enable thread local
+   * connections.
+   * @return a reference to <code>this</code>
+   */
+  public ClientCacheFactory setPoolThreadLocalConnections(boolean threadLocalConnections) {
+    getPoolFactory().setThreadLocalConnections(threadLocalConnections);
+    return this;
+  }
+
+  
+  /**
+   * Sets the number of milliseconds to wait for a response from a server before
+   * timing out the operation and trying another server (if any are available).
+   * @param timeout number of milliseconds to wait for a response from a server
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>timeout</code>
+   * is less than <code>0</code>.
+   */
+  public ClientCacheFactory setPoolReadTimeout(int timeout) {
+    getPoolFactory().setReadTimeout(timeout);
+    return this;
+  }
+
+  
+  /**
+   * Set the minimum number of connections to keep available at all times.
+   * When the pool is created, it will create this many connections. 
+   * If <code>0</code> then connections will not be made until an actual operation
+   * is done that requires client-to-server communication.
+   * @param minConnections the initial number of connections
+   * this pool will create.
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>minConnections</code>
+   * is less than <code>0</code>.
+   */
+  public ClientCacheFactory setPoolMinConnections(int minConnections) {
+    getPoolFactory().setMinConnections(minConnections);
+    return this;
+  }
+
+  
+  /**
+   * Set the max number of client to server connections that the pool will create. If all of 
+   * the connections are in use, an operation requiring a client to server connection
+   * will block until a connection is available.
+   * @see #setPoolFreeConnectionTimeout(int) 
+   * @param maxConnections the maximum number of connections in the pool.
+   * this pool will create. -1 indicates that there is no maximum number of connections
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>maxConnections</code>
+   * is less than <code>minConnections</code>.
+   */
+  public ClientCacheFactory setPoolMaxConnections(int maxConnections) {
+    getPoolFactory().setMaxConnections(maxConnections);
+    return this;
+  }
+
+  
+  /**
+   * Set the amount of time a connection can be idle before expiring the connection.
+   * If the pool size is greater than the minimum specified by 
+   * {@link #setPoolMinConnections(int)}, connections which have been idle
+   * for longer than the idleTimeout will be closed. 
+   * @param idleTimeout The amount of time in milliseconds that an idle connection
+   * should live before expiring. -1 indicates that connections should never expire.
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>idleTimout</code>
+   * is less than <code>-1</code>.
+   */
+  public ClientCacheFactory setPoolIdleTimeout(long idleTimeout) {
+    getPoolFactory().setIdleTimeout(idleTimeout);
+    return this;
+  }
+
+  
+  /**
+   * Set the number of times to retry a request after timeout/exception.
+   * @param retryAttempts The number of times to retry a request 
+   * after timeout/exception. -1 indicates that a request should be 
+   * tried against every available server before failing
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>idleTimout</code>
+   * is less than <code>-1</code>.
+   */
+  public ClientCacheFactory setPoolRetryAttempts(int retryAttempts) {
+    getPoolFactory().setRetryAttempts(retryAttempts);
+    return this;
+  }
+
+  
+  /**
+   * How often to ping servers to verify that they are still alive. Each
+   * server will be sent a ping every pingInterval if there has not
+   * been any other communication with the server.
+   * 
+   * These pings are used by the server to monitor the health of
+   * the client. Make sure that the pingInterval is less than the 
+   * maximum time between pings allowed by the cache server.
+   * @param pingInterval The amount of time in milliseconds between
+   * pings.
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>pingInterval</code>
+   * is less than or equal to <code>0</code>.
+   * @see CacheServer#setMaximumTimeBetweenPings(int)
+   */
+  public ClientCacheFactory setPoolPingInterval(long pingInterval) {
+    getPoolFactory().setPingInterval(pingInterval);
+    return this;
+  }
+
+
+  /**
+   * How often to send client statistics to the server.
+   * Doing this allows <code>gfmon</code> to monitor clients.
+   * <p>A value of <code>-1</code> disables the sending of client statistics
+   * to the server.
+   * 
+   * @param statisticInterval The amount of time in milliseconds between
+   * sends of client statistics to the server.
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>statisticInterval</code>
+   * is less than <code>-1</code>.
+   */
+  public ClientCacheFactory setPoolStatisticInterval(int statisticInterval) {
+    getPoolFactory().setStatisticInterval(statisticInterval);
+    return this;
+  }
+
+
+  /**
+   * Configures the group that all servers this pool connects to must belong to.
+   * @param group the server group that this pool will connect to.
+   * If <code>null</code> or <code>""</code> then all servers will be connected to.
+   * @return a reference to <code>this</code>
+   */
+  public ClientCacheFactory setPoolServerGroup(String group) {
+    getPoolFactory().setServerGroup(group);
+    return this;
+  }
+
+
+  /**
+   * Add a locator, given its host and port, to this factory.
+   * The locator must be a server locator and will be used to discover other running
+   * cache servers and locators.
+   * @param host the host name or ip address that the locator is listening on.
+   * @param port the port that the locator is listening on
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>host</code> is an unknown host
+   * according to {@link java.net.InetAddress#getByName(String)} or if port is outside
+   * the valid range of [1..65535] inclusive.
+   * @throws IllegalStateException if a server has already been {@link #addPoolServer added} to this factory.
+   */
+  public ClientCacheFactory addPoolLocator(String host, int port) {
+    getPoolFactory().addLocator(host, port);
+    return this;
+  }
+
+
+  /**
+   * Add a server, given its host and port, to this factory.
+   * The server must be a cache server and this client will
+   * directly connect to without consulting a server locator.
+   * @param host the host name or ip address that the server is listening on.
+   * @param port the port that the server is listening on
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>host</code> is an unknown host
+   * according to {@link java.net.InetAddress#getByName(String)} or if port is outside
+   * the valid range of [1..65535] inclusive.
+   * @throws IllegalStateException if a locator has already been {@link #addPoolLocator added} to this factory.
+   */
+  public ClientCacheFactory addPoolServer(String host, int port) {
+    getPoolFactory().addServer(host, port);
+    return this;
+  }
+
+
+  /**
+   * If set to <code>true</code> then the created pool will have server-to-client
+   * subscriptions enabled.
+   * If set to <code>false</code> then all <code>Subscription*</code> attributes
+   * are ignored at create time.
+   * @return a reference to <code>this</code>
+   */
+  public ClientCacheFactory setPoolSubscriptionEnabled(boolean enabled) {
+    getPoolFactory().setSubscriptionEnabled(enabled);
+    return this;
+  }
+
+  
+  /**
+   * Sets the redundancy level for this pools server-to-client subscriptions.
+   * If <code>0</code> then no redundant copies will be kept on the servers.
+   * Otherwise an effort will be made to maintain the requested number of
+   * copies of the server-to-client subscriptions. At most one copy per server will
+   * be made up to the requested level.
+   * @param redundancy the number of redundant servers for this client's subscriptions.
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>redundancyLevel</code>
+   * is less than <code>-1</code>.
+   */
+  public ClientCacheFactory setPoolSubscriptionRedundancy(int redundancy) {
+    getPoolFactory().setSubscriptionRedundancy(redundancy);
+    return this;
+  }
+
+  /**
+   * Sets the messageTrackingTimeout attribute which is the time-to-live period, in
+   * milliseconds, for subscription events the client has received from the server. It's used
+   * to minimize duplicate events.
+   * Entries that have not been modified for this amount of time
+   * are expired from the list
+   * @param messageTrackingTimeout number of milliseconds to set the timeout to.
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>messageTrackingTimeout</code>
+   * is less than or equal to <code>0</code>.
+   */
+  public ClientCacheFactory setPoolSubscriptionMessageTrackingTimeout(int messageTrackingTimeout) {
+    getPoolFactory().setSubscriptionMessageTrackingTimeout(messageTrackingTimeout);
+    return this;
+  }
+
+  
+  /**
+   * Sets the interval in milliseconds
+   * to wait before sending acknowledgements to the cache server for
+   * events received from the server subscriptions.
+   * 
+   * @param ackInterval number of milliseconds to wait before sending event
+   * acknowledgements.
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>ackInterval</code>
+   * is less than or equal to <code>0</code>.
+   */
+  public ClientCacheFactory setPoolSubscriptionAckInterval(int ackInterval) {
+    getPoolFactory().setSubscriptionAckInterval(ackInterval);
+    return this;
+  }
+
+
+  /**
+   * By default setPRSingleHopEnabled is <code>true</code>
+   * in which case the client is aware of the location of partitions on servers hosting
+   * {@link Region regions} with
+   * {@link com.gemstone.gemfire.cache.DataPolicy#PARTITION}.
+   * Using this information, the client routes the client cache operations
+   * directly to the server which is hosting the required partition for the
+   * cache operation using a single network hop.
+   * This mode works best 
+   * when {@link #setPoolMaxConnections(int)} is set
+   * to <code>-1</code> which is the default.
+   * This mode causes the client to have more connections to the servers.
+   * <p>
+   * If setPRSingleHopEnabled is <code>false</code> the client may need to do an extra network hop on servers
+   * to go to the required partition for that cache operation.
+   * The client will use fewer network connections to the servers.
+   * <p>
+   * Caution: for {@link com.gemstone.gemfire.cache.DataPolicy#PARTITION partition} regions
+   *  with
+   * {@link com.gemstone.gemfire.cache.PartitionAttributesFactory#setLocalMaxMemory(int) local-max-memory}
+   * equal to zero, no cache operations mentioned above will be routed to those
+   * servers as they do not host any partitions.
+   * 
+   * @return the newly created pool.
+   */
+  public ClientCacheFactory setPoolPRSingleHopEnabled(boolean enabled) {
+    getPoolFactory().setPRSingleHopEnabled(enabled);
+    return this;
+  }
+
+
+  /**
+   * If set to <code>true</code> then the created pool can be used by multiple
+   * users. <br>
+   * <br>
+   * Note: If set to true, all the client side regions must be
+   * {@link ClientRegionShortcut#PROXY proxies}. No client side storage is allowed.
+   * 
+   * @return a reference to <code>this</code>
+   */
+  public ClientCacheFactory setPoolMultiuserAuthentication(boolean enabled) {
+    getPoolFactory().setMultiuserAuthentication(enabled);
+    return this;
+  }
+
+
+  /** Returns the version of the cache implementation.
+   * @return the version of the cache implementation as a <code>String</code>
+   */
+  public static String getVersion() {
+    return GemFireVersion.getGemFireVersion();
+  }
+  /**
+   * Gets an arbitrary open instance of {@link ClientCache} produced by an
+   * earlier call to {@link #create}.
+   * @throws CacheClosedException if a cache has not been created
+   * or the only created one is {@link ClientCache#isClosed closed}
+   * @throws IllegalStateException if the cache was created by CacheFactory instead
+   * of ClientCacheFactory
+   */
+  public static synchronized ClientCache getAnyInstance() {
+    GemFireCacheImpl instance = GemFireCacheImpl.getInstance();
+    if (instance == null) {
+      throw new CacheClosedException(LocalizedStrings.CacheFactory_A_CACHE_HAS_NOT_YET_BEEN_CREATED.toLocalizedString());
+    } else {
+      if (!instance.isClient()) {
+        throw new IllegalStateException("The singleton cache was created by CacheFactory not ClientCacheFactory.");
+      }
+      instance.getCancelCriterion().checkCancelInProgress(null);
+      return instance;
+    }
+  }
+  
+  /** Sets the object preference to PdxInstance type.
+   * When a cached object that was serialized as a PDX is read
+   * from the cache a {@link PdxInstance} will be returned instead of the actual domain class.
+   * The PdxInstance is an interface that provides run time access to 
+   * the fields of a PDX without deserializing the entire PDX. 
+   * The PdxInstance implementation is a light weight wrapper 
+   * that simply refers to the raw bytes of the PDX that are kept 
+   * in the cache. Using this method applications can choose to 
+   * access PdxInstance instead of Java object.
+   * <p>Note that a PdxInstance is only returned if a serialized PDX is found in the cache.
+   * If the cache contains a deserialized PDX, then a domain class instance is returned instead of a PdxInstance.
+   * 
+   *  @param pdxReadSerialized true to prefer PdxInstance
+   *  @return this ClientCacheFactory
+   *  @since 6.6
+   *  @see com.gemstone.gemfire.pdx.PdxInstance 
+   */
+  public ClientCacheFactory setPdxReadSerialized(boolean pdxReadSerialized) {
+    this.cacheConfig.setPdxReadSerialized(pdxReadSerialized);
+    return this;
+  }
+  
+  /**
+   * Set the PDX serializer for the cache. If this serializer is set,
+   * it will be consulted to see if it can serialize any domain classes which are 
+   * added to the cache in portable data exchange format. 
+   * @param serializer the serializer to use
+   * @return this ClientCacheFactory
+   * @since 6.6
+   * @see PdxSerializer
+   */
+  public ClientCacheFactory setPdxSerializer(PdxSerializer serializer) {
+    this.cacheConfig.setPdxSerializer(serializer);
+    return this;
+  }
+  
+  /**
+   * Set the disk store that is used for PDX meta data. When
+   * serializing objects in the PDX format, the type definitions
+   * are persisted to disk. This setting controls which disk store
+   * is used for that persistence.
+   * 
+   * If not set, the metadata will go in the default disk store.
+   * @param diskStoreName the name of the disk store to use
+   * for the PDX metadata.
+   * @return this ClientCacheFactory
+   * @since 6.6
+   */
+  public ClientCacheFactory setPdxDiskStore(String diskStoreName) {
+    this.cacheConfig.setPdxDiskStore(diskStoreName);
+    return this;
+  }
+
+  /**
+   * Control whether the type metadata for PDX objects is persisted to disk.
+   * The default for this setting is false. 
+   * If you are using persistent regions with PDX then you must set this to true.
+   * If you are using a WAN gateway with PDX then you should set this to true.
+   * 
+   * @param isPersistent true if the metadata should be persistent
+   * @return this ClientCacheFactory
+   * @since 6.6
+   */
+  public ClientCacheFactory setPdxPersistent(boolean isPersistent) {
+    this.cacheConfig.setPdxPersistent(isPersistent);
+    return this;
+  }
+  /**
+   * Control whether pdx ignores fields that were unread during deserialization.
+   * The default is to preserve unread fields be including their data during serialization.
+   * But if you configure the cache to ignore unread fields then their data will be lost
+   * during serialization.
+   * <P>You should only set this attribute to <code>true</code> if you know this member
+   * will only be reading cache data. In this use case you do not need to pay the cost
+   * of preserving the unread fields since you will never be reserializing pdx data. 
+   * 
+   * @param ignore <code>true</code> if fields not read during pdx deserialization should be ignored;
+   * <code>false</code>, the default, if they should be preserved.
+   * @return this ClientCacheFactory
+   * @since 6.6
+   */
+  public ClientCacheFactory setPdxIgnoreUnreadFields(boolean ignore) {
+    this.cacheConfig.setPdxIgnoreUnreadFields(ignore);
+    return this;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientNotReadyException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientNotReadyException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientNotReadyException.java
new file mode 100755
index 0000000..2297789
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientNotReadyException.java
@@ -0,0 +1,47 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache.client;
+
+import com.gemstone.gemfire.cache.OperationAbortedException;
+
+/**
+ * A <code>ClientNotReadyException</code> indicates a client attempted to invoke
+ * the {@link com.gemstone.gemfire.cache.Cache#readyForEvents}
+ * method, but failed.
+ * <p>This exception was moved from the <code>util</code> package in 5.7.
+ * 
+ * @author darrel
+ *
+ * @since 5.7
+ * @deprecated as of 6.5 this exception is no longer thrown by GemFire so any code that catches it should be removed.
+ * 
+ */
+public class ClientNotReadyException extends OperationAbortedException {
+private static final long serialVersionUID = -315765802919271588L;
+  /**
+   * Constructs an instance of <code>ClientNotReadyException</code> with the
+   * specified detail message.
+   * 
+   * @param msg the detail message
+   */
+  public ClientNotReadyException(String msg) {
+    super(msg);
+  }
+  
+  /**
+   * Constructs an instance of <code>ClientNotReadyException</code> with the
+   * specified detail message and cause.
+   * 
+   * @param msg the detail message
+   * @param cause the causal Throwable
+   */
+  public ClientNotReadyException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientRegionFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientRegionFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientRegionFactory.java
new file mode 100644
index 0000000..f8fc717
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientRegionFactory.java
@@ -0,0 +1,337 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client;
+
+import com.gemstone.gemfire.cache.AttributesFactory;
+import com.gemstone.gemfire.cache.CacheClosedException;
+import com.gemstone.gemfire.cache.CacheListener;
+import com.gemstone.gemfire.cache.CustomExpiry;
+import com.gemstone.gemfire.cache.EvictionAttributes;
+import com.gemstone.gemfire.cache.ExpirationAttributes;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionDestroyedException;
+import com.gemstone.gemfire.cache.RegionExistsException;
+import com.gemstone.gemfire.compression.Compressor;
+
+/**
+ * A factory for constructing {@link ClientCache client cache} {@link Region
+ * regions}. Instances of this interface can be created using region shortcuts
+ * by calling
+ * {@link ClientCache#createClientRegionFactory(ClientRegionShortcut)} or using
+ * named region attributes by calling
+ * {@link ClientCache#createClientRegionFactory(String)}.
+ * <p>
+ * The factory can then be customized using its methods.
+ * <p>
+ * The final step is to produce a {@link Region} by calling
+ * {@link #create(String)}.
+ * <p>
+ * Client regions may be:
+ * <ul>
+ * <li>PROXY: which pass through to server and have no local data.
+ * <li>CACHING_PROXY: which fetch data from servers and cache it locally.
+ * <li>LOCAL: which only have local data; they do not communicate with the
+ * servers.
+ * </ul>
+ * See {@link ClientRegionShortcut} for the shortcuts for these three types of
+ * client regions.
+ * <p>
+ * Example: Create a client region with a CacheListener
+ * 
+ * <PRE>
+ * ClientCache c = new ClientCacheFactory().addLocator(host, port).create();
+ * // Create local caching region that is connected to a server side region
+ * // Add a cache listener before creating region
+ * Region r = c.createClientRegionFactory(CACHING_PROXY).addCacheListener(
+ *     myListener).create(&quot;customers&quot;);
+ * </PRE>
+ * 
+ * @author darrel
+ * @since 6.5
+ */
+
+public interface ClientRegionFactory<K,V> {
+  /**
+   * Adds a cache listener to the end of the list of cache listeners on this factory.
+   * @param aListener the cache listener to add
+   * @return a reference to this ClientRegionFactory object
+   * @throws IllegalArgumentException if <code>aListener</code> is null
+   * @see AttributesFactory#addCacheListener
+   */
+  public ClientRegionFactory<K,V> addCacheListener(CacheListener<K,V> aListener);
+
+  /**
+   * Removes all cache listeners and then adds each listener in the specified array.
+   * for the next <code>RegionAttributes</code> created.
+   * @param newListeners a possibly null or empty array of listeners to add to this factory.
+   * @return a reference to this ClientRegionFactory object
+   * @throws IllegalArgumentException if the <code>newListeners</code> array has a null element
+   * @see AttributesFactory#initCacheListeners
+   */
+  public ClientRegionFactory<K,V> initCacheListeners(CacheListener<K,V>[] newListeners);
+
+  /**
+   * Sets the eviction attributes that controls growth of the Region to be created.
+   *
+   * @param evictionAttributes for the Region to create
+   * @return a reference to this ClientRegionFactory object
+   */
+  public ClientRegionFactory<K,V> setEvictionAttributes(EvictionAttributes evictionAttributes);
+
+  /**
+   * Sets the idleTimeout expiration attributes for region entries for the next
+   * <code>RegionAttributes</code> created.
+   *
+   * @param idleTimeout
+   *          the idleTimeout ExpirationAttributes for entries in this region
+   * @return a reference to this ClientRegionFactory object
+   * @throws IllegalArgumentException
+   *           if idleTimeout is null
+   * @see AttributesFactory#setEntryIdleTimeout
+   */
+  public ClientRegionFactory<K,V> setEntryIdleTimeout(ExpirationAttributes idleTimeout);
+
+  /**
+   * Sets the custom idleTimeout for the next <code>RegionAttributes</code>
+   * created.
+   * 
+   * @param custom the custom method
+   * @return the receiver
+   * @see AttributesFactory#setCustomEntryIdleTimeout(CustomExpiry)
+   */
+  public ClientRegionFactory<K,V> setCustomEntryIdleTimeout(CustomExpiry<K,V> custom);
+  
+  /**
+   * Sets the timeToLive expiration attributes for region entries for the next
+   * <code>RegionAttributes</code> created.
+   *
+   * @param timeToLive
+   *          the timeToLive ExpirationAttributes for entries in this region
+   * @return a reference to this ClientRegionFactory object
+   * @throws IllegalArgumentException
+   *           if timeToLive is null
+   * @see AttributesFactory#setEntryTimeToLive
+   */
+  public ClientRegionFactory<K,V> setEntryTimeToLive(ExpirationAttributes timeToLive);
+
+  /**
+   * Sets the custom timeToLive expiration method for the next 
+   * <code>RegionAttributes</code> created.
+   * @param custom the custom method
+   * @return the receiver
+   * @see AttributesFactory#setCustomEntryTimeToLive(CustomExpiry)
+   */
+  public ClientRegionFactory<K,V> setCustomEntryTimeToLive(CustomExpiry<K,V> custom);
+  
+  /**
+   * Sets the idleTimeout expiration attributes for the region itself for the
+   * next <code>RegionAttributes</code> created.
+   *
+   * @param idleTimeout
+   *          the ExpirationAttributes for this region idleTimeout
+   * @return a reference to this ClientRegionFactory object
+   * @throws IllegalArgumentException
+   *           if idleTimeout is null
+   * @see AttributesFactory#setRegionIdleTimeout
+   */
+  public ClientRegionFactory<K,V> setRegionIdleTimeout(ExpirationAttributes idleTimeout);
+
+  /**
+   * Sets the timeToLive expiration attributes for the region itself for the
+   * next <code>RegionAttributes</code> created.
+   *
+   * @param timeToLive
+   *          the ExpirationAttributes for this region timeToLive
+   * @return a reference to this ClientRegionFactory object
+   * @throws IllegalArgumentException
+   *           if timeToLive is null
+   * @see AttributesFactory#setRegionTimeToLive
+   */
+  public ClientRegionFactory<K,V> setRegionTimeToLive(ExpirationAttributes timeToLive);
+
+  /**
+   * Sets the key constraint for the next <code>RegionAttributes</code>
+   * created. Keys in the region will be constrained to this class (or
+   * subclass). Any attempt to store a key of an incompatible type in the region
+   * will cause a <code>ClassCastException</code> to be thrown.
+   *
+   * @param keyConstraint
+   *          The Class to constrain the keys to, or null if no constraint
+   * @return a reference to this ClientRegionFactory object
+   * @throws IllegalArgumentException
+   *           if <code>keyConstraint</code> is a class denoting a primitive
+   *           type
+   * @see AttributesFactory#setKeyConstraint
+   */
+  public ClientRegionFactory<K,V> setKeyConstraint(Class<K> keyConstraint);
+
+  /**
+   * Sets the value constraint for the next <code>RegionAttributes</code>
+   * created. Values in the region will be constrained to this class (or
+   * subclass). Any attempt to store a value of an incompatible type in the
+   * region will cause a <code>ClassCastException</code> to be thrown.
+   *
+   * @param valueConstraint
+   *          The Class to constrain the values to, or null if no constraint
+   * @return a reference to this ClientRegionFactory object
+   * @throws IllegalArgumentException
+   *           if <code>valueConstraint</code> is a class denoting a primitive
+   *           type
+   * @see AttributesFactory#setValueConstraint
+   */
+  public ClientRegionFactory<K,V> setValueConstraint(Class<V> valueConstraint);
+
+  /**
+   * Sets the entry initial capacity for the next <code>RegionAttributes</code>
+   * created. This value is used in initializing the map that holds the entries.
+   *
+   * @param initialCapacity
+   *          the initial capacity of the entry map
+   * @return a reference to this ClientRegionFactory object
+   * @throws IllegalArgumentException if initialCapacity is negative.
+   * @see java.util.HashMap
+   * @see AttributesFactory#setInitialCapacity
+   */
+  public ClientRegionFactory<K,V> setInitialCapacity(int initialCapacity);
+
+  /**
+   * Sets the entry load factor for the next <code>RegionAttributes</code>
+   * created. This value is used in initializing the map that holds the entries.
+   *
+   * @param loadFactor
+   *          the load factor of the entry map
+   * @return a reference to this ClientRegionFactory object
+   * @throws IllegalArgumentException
+   *           if loadFactor is nonpositive
+   * @see java.util.HashMap
+   * @see AttributesFactory#setLoadFactor
+   */
+  public ClientRegionFactory<K,V> setLoadFactor(float loadFactor);
+
+  /**
+   * Sets the concurrency level tof the next <code>RegionAttributes</code>
+   * created. This value is used in initializing the map that holds the entries.
+   *
+   * @param concurrencyLevel
+   *          the concurrency level of the entry map
+   * @return a reference to this ClientRegionFactory object
+   * @throws IllegalArgumentException
+   *           if concurrencyLevel is nonpositive
+   * @see AttributesFactory#setConcurrencyLevel
+   */
+  public ClientRegionFactory<K,V> setConcurrencyLevel(int concurrencyLevel);
+
+  /**
+   * Enables or disabled concurrent modification checks
+   * @since 7.0
+   * @param concurrencyChecksEnabled whether to perform concurrency checks on operations
+   */
+  public void setConcurrencyChecksEnabled(boolean concurrencyChecksEnabled);
+
+  /**
+   * Sets the DiskStore name attribute.
+   * This causes the region to belong to the DiskStore.
+   * @param name the name of the diskstore
+   * @return a reference to this ClientRegionFactory object
+   * 
+   * @see AttributesFactory#setDiskStoreName
+   */
+  public ClientRegionFactory<K,V> setDiskStoreName(String name);
+
+  /**
+   * Sets whether or not the writing to the disk is synchronous.
+   * 
+   * @param isSynchronous
+   *          boolean if true indicates synchronous writes
+   * @return a reference to this ClientRegionFactory object
+   */
+  public ClientRegionFactory<K,V> setDiskSynchronous(boolean isSynchronous);
+
+  /**
+   * Sets whether statistics are enabled for this region and its entries.
+   *
+   * @param statisticsEnabled
+   *          whether statistics are enabled
+   * @return a reference to this ClientRegionFactory object
+   * @see AttributesFactory#setStatisticsEnabled
+   */
+  public ClientRegionFactory<K,V> setStatisticsEnabled(boolean statisticsEnabled);
+
+  /**
+   * Sets cloning on region
+   * @param cloningEnable
+   * @return a reference to this ClientRegionFactory object
+   * @see AttributesFactory#setCloningEnabled
+   */
+  public ClientRegionFactory<K,V> setCloningEnabled(boolean cloningEnable);
+
+  /**
+   * Sets the pool name attribute.
+   * This causes regions that use these attributes
+   * to be a client region which communicates with the
+   * servers that the connection pool communicates with.
+   * <p>The named connection pool must exist on the cache at the time these
+   * attributes are used to create a region. See {@link PoolManager#createFactory}
+   * for how to create a connection pool.
+   * @param poolName the name of the connection pool to use
+   * @return a reference to this ClientRegionFactory object
+   * @throws IllegalStateException if a cache loader or cache writer has already
+   * been set.
+   * @see PoolManager
+   */
+  public ClientRegionFactory<K,V> setPoolName(String poolName);
+
+  /**
+   * Set the compressor to be used by this region for compressing
+   * region entry values.
+   * @param compressor a compressor
+   * @return a reference to this RegionFactory instance
+   * @since 8.0
+   */
+  public ClientRegionFactory<K,V> setCompressor(Compressor compressor);
+  
+  /**
+   * Creates a region in the {@link ClientCache} using
+   * the configuration contained in this ClientRegionFactory. Validation of the
+   * provided attributes may cause exceptions to be thrown if there are problems
+   * with the configuration data.
+   *
+   * @param name
+   *          the name of the region to create
+   *
+   * @return the region object
+   * @throws RegionExistsException
+   *           if a region with the given name already exists in this cache
+   * @throws CacheClosedException
+   *           if the cache is closed
+   */
+  public Region<K,V> create(String name) throws RegionExistsException;
+  /**
+   * Creates a sub-region in the {@link ClientCache} using
+   * the configuration contained in this ClientRegionFactory. Validation of the
+   * provided attributes may cause exceptions to be thrown if there are problems
+   * with the configuration data.
+   *
+   * @param parent
+   *          the existing region that will contain the created sub-region
+   * @param name
+   *          the name of the region to create
+   *
+   * @return the region object
+   * @throws RegionExistsException
+   *           if a region with the given name already exists in this cache
+   * @throws RegionDestroyedException
+   *           if the parent region has been closed or destroyed
+   * @throws CacheClosedException
+   *           if the cache is closed
+   * @since 7.0
+   */
+  public Region<K,V> createSubregion(Region<?,?> parent, String name) throws RegionExistsException;
+  
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientRegionShortcut.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientRegionShortcut.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientRegionShortcut.java
new file mode 100644
index 0000000..b3c0590
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/ClientRegionShortcut.java
@@ -0,0 +1,99 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache.client;
+
+import com.gemstone.gemfire.cache.*;
+
+/**
+ * Each enum represents a predefined {@link RegionAttributes} in a {@link ClientCache}.
+ * These enum values can be used to create regions using a {@link ClientRegionFactory}
+ * obtained by calling {@link ClientCache#createClientRegionFactory(ClientRegionShortcut)}.
+ * <p>Another way to use predefined region attributes is in cache.xml by setting
+ * the refid attribute on a region element or region-attributes element to the
+ * string of each value.
+ * @since 6.5
+ * @author darrel
+ */
+public enum ClientRegionShortcut {
+  /**
+   * A PROXY region has no local state and forwards all operations to a server.
+   * The actual RegionAttributes for a PROXY set the {@link DataPolicy} to {@link DataPolicy#EMPTY}.
+   */
+  PROXY,
+
+  /**
+   * A CACHING_PROXY region has local state but can also send operations to a server.
+   * If the local state is not found then the operation is sent to the server
+   * and the local state is updated to contain the server result.
+   * The actual RegionAttributes for a CACHING_PROXY set the {@link DataPolicy} to {@link DataPolicy#NORMAL}.
+   */
+  CACHING_PROXY,
+    
+  /**
+   * A CACHING_PROXY_HEAP_LRU region has local state but can also send operations to a server.
+   * If the local state is not found then the operation is sent to the server
+   * and the local state is updated to contain the server result.
+   * It will also destroy entries once it detects that the java vm is running low
+   * of memory.
+   * The actual RegionAttributes for a CACHING_PROXY_HEAP_LRU set the {@link DataPolicy} to {@link DataPolicy#NORMAL}.
+   * and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+     * with {@link EvictionAction#LOCAL_DESTROY}.
+     */
+  CACHING_PROXY_HEAP_LRU,
+  /**
+   * A CACHING_PROXY_OVERFLOW region has local state but can also send operations to a server.
+   * If the local state is not found then the operation is sent to the server
+   * and the local state is updated to contain the server result.
+   * It will also move the values of entries to disk once it detects that the
+   * java vm is running low of memory.
+   * The actual RegionAttributes for a CACHING_PROXY_OVERFLOW set the {@link DataPolicy} to {@link DataPolicy#NORMAL}.
+   * and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+     * with {@link EvictionAction#OVERFLOW_TO_DISK}.
+     */
+  CACHING_PROXY_OVERFLOW,
+
+  /**
+   * A LOCAL region only has local state and never sends operations to a server.
+   * The actual RegionAttributes for a LOCAL region set the {@link DataPolicy} to {@link DataPolicy#NORMAL}.
+   */
+    LOCAL,
+  /**
+   * A LOCAL_PERSISTENT region only has local state and never sends operations to a server
+   * but it does write its state to disk and can recover that state when the region
+   * is created.
+   * The actual RegionAttributes for a LOCAL_PERSISTENT region set the {@link DataPolicy} to {@link DataPolicy#PERSISTENT_REPLICATE}.
+   */
+    LOCAL_PERSISTENT,
+    /**
+     * A LOCAL_HEAP_LRU region only has local state and never sends operations to a server.
+     * It will also destroy entries once it detects that the java vm is running low
+     * of memory.
+     * The actual RegionAttributes for a LOCAL_HEAP_LRU region set the {@link DataPolicy} to {@link DataPolicy#NORMAL} and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+     * with {@link EvictionAction#LOCAL_DESTROY}.
+     */
+    LOCAL_HEAP_LRU,
+    /**
+     * A LOCAL_OVERFLOW region only has local state and never sends operations to a server.
+     * It will also move the values of entries to disk once it detects that the
+     * java vm is running low of memory.
+     * The actual RegionAttributes for a LOCAL_OVERFLOW region set the {@link DataPolicy} to {@link DataPolicy#NORMAL} and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+     * with {@link EvictionAction#OVERFLOW_TO_DISK}.
+     */
+    LOCAL_OVERFLOW,
+    /**
+     * A LOCAL_PERSISTENT_OVERFLOW region only has local state and never sends operations to a server
+     * but it does write its state to disk and can recover that state when the region
+     * is created.
+     * It will also remove the values of entries from memory once it detects that the
+     * java vm is running low of memory.
+     * The actual RegionAttributes for a LOCAL_PERSISTENT_OVERFLOW region set the {@link DataPolicy} to {@link DataPolicy#PERSISTENT_REPLICATE} and {@link EvictionAttributes} are set to {@link EvictionAlgorithm#LRU_HEAP}
+     * with {@link EvictionAction#OVERFLOW_TO_DISK}.
+     */
+    LOCAL_PERSISTENT_OVERFLOW
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/NoAvailableLocatorsException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/NoAvailableLocatorsException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/NoAvailableLocatorsException.java
new file mode 100644
index 0000000..70fb6c1
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/NoAvailableLocatorsException.java
@@ -0,0 +1,50 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client;
+
+
+/**
+ * An exception indicating that there are no active locators available to connect to.
+ * @author dsmith
+ * @since 5.7
+ */
+public class NoAvailableLocatorsException extends ServerConnectivityException {
+  private static final long serialVersionUID = -8212446737778234890L;
+
+  /**
+   * Create a new instance of NoAvailableLocatorsException without a detail message or cause.
+   */
+  public NoAvailableLocatorsException() {
+  }
+
+  /**
+   * Create a new instance of NoAvailableServersException with a detail message
+   * @param message the detail message
+   */
+  public NoAvailableLocatorsException(String message) {
+    super(message);
+  }
+
+  /**
+   * Create a new instance of NoAvailableLocatorsException with a detail message and cause
+   * @param message the detail message
+   * @param cause the cause
+   */
+  public NoAvailableLocatorsException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Create a new instance of NoAvailableLocatorsException with a and cause
+   * @param cause the cause
+   */
+  public NoAvailableLocatorsException(Throwable cause) {
+    super(cause);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/NoAvailableServersException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/NoAvailableServersException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/NoAvailableServersException.java
new file mode 100644
index 0000000..23bdfaa
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/NoAvailableServersException.java
@@ -0,0 +1,50 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client;
+
+
+/**
+ * An exception indicating that there are no active servers available to connect to.
+ * @author dsmith
+ * @since 5.7
+ */
+public class NoAvailableServersException extends ServerConnectivityException {
+  private static final long serialVersionUID = -8212446737778234890L;
+
+  /**
+   * Create a new instance of NoAvailableServersException without a detail message or cause.
+   */
+  public NoAvailableServersException() {
+  }
+
+  /**
+   * Create a new instance of NoAvailableServersException with a detail message
+   * @param message the detail message
+   */
+  public NoAvailableServersException(String message) {
+    super(message);
+  }
+
+  /**
+   * Create a new instance of NoAvailableServersException with a detail message and cause
+   * @param message the detail message
+   * @param cause the cause
+   */
+  public NoAvailableServersException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Create a new instance of NoAvailableServersException with a and cause
+   * @param cause the cause
+   */
+  public NoAvailableServersException(Throwable cause) {
+    super(cause);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/Pool.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/Pool.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/Pool.java
new file mode 100644
index 0000000..99c318b
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/Pool.java
@@ -0,0 +1,242 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client;
+
+import java.net.InetSocketAddress;
+import java.util.Properties;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.RegionFactory;
+import com.gemstone.gemfire.cache.query.QueryService;
+
+
+/**
+ * A pool for connections from a client to a set of GemFire Cache Servers.
+ * <p>A single instance of this interface can be created using {@link ClientCacheFactory#create}.
+ * Multiple instances may also be created using
+ * {@link PoolFactory#create}.
+ * A {@link PoolFactory} instance is created by calling
+ * {@link PoolManager#createFactory}. So to create a default <code>Pool</code> do this:
+ * <PRE>
+     new ClientCacheFactory().create();
+ * </PRE>
+ * or this:
+ * <PRE>
+     PoolManager.createFactory().create("myPool");
+ * </PRE>
+ * Instances may also be created by declaring them in cache.xml with a <code>pool</code> element.
+ * <p>Existing Pool instances can be found using {@link PoolManager#find(String)}
+ * and {@link PoolManager#getAll}.
+ * <p>The pool name must be configured
+ * on the client regions that will use this pool by calling
+ * {@link RegionFactory#setPoolName}.
+ *
+ * @author darrel
+ * @since 5.7
+ *
+ */
+public interface Pool {
+
+  /**
+   * Get the name of the connection pool
+   * 
+   * @return the name of the pool
+   * @see PoolFactory#create
+   */
+  public String getName();
+
+  /**
+   * Returns the connection timeout of this pool.
+   * @see PoolFactory#setFreeConnectionTimeout
+   */
+  public int getFreeConnectionTimeout();
+  /**
+   * Returns the load conditioning interval of this pool.
+   * @see PoolFactory#setLoadConditioningInterval
+   */
+  public int getLoadConditioningInterval();
+  /**
+   * Returns the socket buffer size of this pool.
+   * @see PoolFactory#setSocketBufferSize
+   */
+  public int getSocketBufferSize();
+  /**
+   * Returns the read timeout of this pool.
+   * @see PoolFactory#setReadTimeout
+   */
+  public int getReadTimeout();
+  /**
+   * Get the minimum connections for this pool.
+   * @see PoolFactory#setMinConnections(int)
+   */
+  public int getMinConnections();
+  /**
+   * Get the maximum connections for this pool.
+   * @see PoolFactory#setMaxConnections(int)
+   */
+  public int getMaxConnections();
+  /**
+   * Get the maximum connections for this pool.
+   * @see PoolFactory#setIdleTimeout(long)
+   */
+  public long getIdleTimeout();
+  /**
+   * Get the ping interval for this pool.
+   * @see PoolFactory#setPingInterval(long)
+   */
+  public long getPingInterval();
+  /**
+   * Get the statistic interval for this pool.
+   * @see PoolFactory#setStatisticInterval(int)
+   */
+  public int getStatisticInterval();
+  /**
+   * Get the retry attempts for this pool.
+   * @see PoolFactory#setRetryAttempts(int)
+   */
+  public int getRetryAttempts();
+  /**
+   * Returns <code>true</code> if thread local connections are enabled on this pool.
+   * @see PoolFactory#setThreadLocalConnections
+   */
+  public boolean getThreadLocalConnections();
+
+  /**
+   * Returns the true if a server-to-client subscriptions are enabled on this pool.
+   * @see PoolFactory#setSubscriptionEnabled
+   */
+  public boolean getSubscriptionEnabled();
+  /**
+   * Returns true if single-hop optimisation is enabled on this pool.
+   * @see PoolFactory#setPRSingleHopEnabled
+   * @since 6.5
+   */
+  public boolean getPRSingleHopEnabled();
+  /**
+   * Returns the subscription redundancy level of this pool.
+   * @see PoolFactory#setSubscriptionRedundancy
+   */
+  public int getSubscriptionRedundancy();
+  /**
+   * Returns the subscription message tracking timeout of this pool.
+   * @see PoolFactory#setSubscriptionMessageTrackingTimeout
+   */
+  public int getSubscriptionMessageTrackingTimeout();
+  /**
+   * Returns the subscription ack interval of this pool.
+   * @see PoolFactory#setSubscriptionAckInterval(int)
+   */
+  public int getSubscriptionAckInterval();
+  
+  /**
+   * Returns the server group of this pool.
+   * @see PoolFactory#setServerGroup
+   */
+  public String getServerGroup();
+  /**
+   * Returns true if multiuser mode is enabled on this pool.
+   * @see PoolFactory#setMultiuserAuthentication(boolean)
+   * @since 6.5
+   */
+  public boolean getMultiuserAuthentication();
+
+  
+  /**
+   * Returns an unmodifiable list of {@link java.net.InetSocketAddress} of the
+   * locators this pool is using. Each locator is either one
+   * {@link PoolFactory#addLocator added explicitly}
+   * when the pool was created or were discovered using the explicit locators.
+   * <p> If a pool has no locators then it can not discover servers or locators at runtime.
+   */
+  public java.util.List<InetSocketAddress> getLocators();
+  /**
+   * Returns an unmodifiable list of {@link java.net.InetSocketAddress} of the
+   * servers this pool is using. These servers where either
+   * {@link PoolFactory#addServer added explicitly}
+   * when the pool was created or were discovered using this pools {@link #getLocators locators}.
+   */
+  public java.util.List<InetSocketAddress> getServers();
+
+  /**
+   * Destroys this pool closing any connections it produced.
+   * @param keepAlive
+   *                whether the server should keep the durable client's
+   *                subscriptions alive for the timeout period
+   * @throws IllegalStateException
+   *                 if the pool is still in use
+   */
+  public void destroy(boolean keepAlive);
+  
+  /**
+   * Destroys this pool closing any connections it produced.
+   * @throws IllegalStateException if the pool is still in use
+   */
+  public void destroy();
+  
+  /**
+   * Indicates whether this Pool has been
+   * destroyed.
+   * 
+   * @return true if the pool has been destroyed
+   */
+  public boolean isDestroyed();
+  
+  /**
+   * If this pool was configured to to use thread local connections,
+   * then this method will release the connection cached for the calling thread.
+   * The connection will then be available for use by other threads.
+   * 
+   * If this pool is not using thread local connections, this method
+   * will have no effect.
+   */
+  public void releaseThreadLocalConnection();
+  
+  /**
+   * Returns the QueryService for this Pool. The query operations performed
+   * using this QueryService will be executed on the servers that are associated
+   * with this pool.
+   * 
+   * @return the QueryService
+   */
+  public QueryService getQueryService();
+
+  /**
+   * Returns the approximate number of pending subscription events maintained at
+   * server for this durable client pool at the time it (re)connected to the
+   * server. Server would start dispatching these events to this durable client
+   * pool when it receives {@link ClientCache#readyForEvents()} from it.
+   * <p>
+   * Durable clients can call this method on reconnect to assess the amount of
+   * 'stale' data i.e. events accumulated at server while this client was away
+   * and, importantly, before calling {@link ClientCache#readyForEvents()}.
+   * <p>
+   * Any number of invocations of this method during a single session will
+   * return the same value.
+   * <p>
+   * It may return a zero value if there are no events pending at server for
+   * this client pool. A negative value returned tells us that no queue was
+   * available at server for this client pool.
+   * <p>
+   * A value -1 indicates that this client pool reconnected to server after its
+   * 'durable-client-timeout' period elapsed and hence its subscription queue at
+   * server was removed, possibly causing data loss.
+   * <p>
+   * A value -2 indicates that this client pool connected to server for the
+   * first time.
+   * 
+   * @return int The number of subscription events maintained at server for this
+   *         durable client pool at the time this pool (re)connected. A negative
+   *         value indicates no queue was found for this client pool.
+   * @throws IllegalStateException
+   *           If called by a non-durable client or if invoked any time after
+   *           invocation of {@link ClientCache#readyForEvents()}.
+   * @since 8.1
+   */
+  public int getPendingEventCount();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/PoolFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/PoolFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/PoolFactory.java
new file mode 100644
index 0000000..3f09262
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/client/PoolFactory.java
@@ -0,0 +1,462 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache.client;
+
+import com.gemstone.gemfire.cache.server.CacheServer;
+import com.gemstone.gemfire.cache.*; // for javadocs
+import com.gemstone.gemfire.cache.query.*; // for javadocs
+
+
+/**
+ * This interface provides for the configuration and creation of instances of
+ * {@link Pool}.
+ * <p>Every pool needs to have at least one {@link #addLocator locator} or {@link #addServer server} added
+ * to it. Locators should be added unless direct connections to
+ * bridge servers are desired.
+ * <p>The setter methods are used to specify
+ * non-default values for the other pool properties.
+ * <p>Once it is configured {@link #create}
+ * will produce an instance.
+ * <p>The factory can be restored to its default
+ * configuration by calling {@link #reset}.
+ * <p>Instances of this interface can be created by calling
+ * {@link PoolManager#createFactory}.
+ * <p>
+ * If a subscription is going to be made using a pool then subscriptions
+ * {@link #setSubscriptionEnabled must be enabled} on the pool.
+ * Subscriptions are made using these APIs:
+ * <ul>
+ * <li>{@link QueryService#newCq(String, CqAttributes)}
+ * <li>{@link QueryService#newCq(String, CqAttributes, boolean)}
+ * <li>{@link QueryService#newCq(String, String, CqAttributes)}
+ * <li>{@link QueryService#newCq(String, String, CqAttributes, boolean)}
+ * <li>{@link Region#registerInterest(Object)}
+ * <li>{@link Region#registerInterest(Object, boolean)}
+ * <li>{@link Region#registerInterest(Object, InterestResultPolicy)}
+ * <li>{@link Region#registerInterest(Object, InterestResultPolicy, boolean)}
+ * <li>{@link Region#registerInterestRegex(String)}
+ * <li>{@link Region#registerInterestRegex(String, boolean)}
+ * <li>{@link Region#registerInterestRegex(String, InterestResultPolicy)}
+ * <li>{@link Region#registerInterestRegex(String, InterestResultPolicy, boolean)}
+ * </ul>
+ *
+ * @author darrel
+ * @since 5.7
+ */
+public interface PoolFactory {
+  /**
+   * The default amount of time, in milliseconds, which we will wait for a free
+   * connection if max connections is set and all of the connections are in use.
+   * <p>Current value: <code>10000</code>.
+   */
+  public static final int DEFAULT_FREE_CONNECTION_TIMEOUT = 10000;
+
+  /**
+   * The default interval in which the pool will check to see if 
+   * a connection to a given server should be moved to a different
+   * server to improve the load balance.
+   * <p>Current value: <code>300,000</code> (which is 5 minutes).
+   */
+  public static final int DEFAULT_LOAD_CONDITIONING_INTERVAL = 1000*60*5;
+
+  /**
+   * Default size in bytes of the socket buffer on each connection established.
+   * <p>Current value: <code>32768</code>.
+   */
+  public static final int DEFAULT_SOCKET_BUFFER_SIZE = 32768;
+
+  /**
+   * The default amount of time, in milliseconds, to wait for a response from a server
+   * <p>Current value: <code>10000</code>.
+   */
+  public static final int DEFAULT_READ_TIMEOUT = 10000;
+
+  /**
+   * The default number of connections to initially create
+   * <p>Current value: <code>1</code>.
+   */
+  public static final int DEFAULT_MIN_CONNECTIONS = 1;
+  
+  /**
+   * The default maximum number of connections to create
+   * <p>Current value: <code>-1</code>.
+   */
+  public static final int DEFAULT_MAX_CONNECTIONS = -1;
+  
+  /**
+   * The default amount of time in milliseconds, to wait for a connection to become idle
+   * <p>Current value: <code>5000</code>.
+   */
+  public static final long DEFAULT_IDLE_TIMEOUT = 5000;
+
+  /**
+   * The default number of times to retry an operation after a timeout or exception.
+   * <p>Current value: <code>-1</code>.
+   */
+  public static final int DEFAULT_RETRY_ATTEMPTS = -1;
+  
+  /**
+   * The default frequency, in milliseconds, to ping servers.
+   * <p>Current value: <code>10000</code>.
+   */
+  public static final long DEFAULT_PING_INTERVAL = 10000;
+  
+  /**
+   * The default frequency, in milliseconds, that client statistics
+   * will be sent to the server.
+   * <p>Current value: <code>-1</code>.
+   */
+  public static final int DEFAULT_STATISTIC_INTERVAL = -1;
+
+  /**
+   * The default value for whether connections should have affinity to the thread
+   * that last used them.
+   * <p>Current value: <code>false</code>.
+   */
+  public static final boolean DEFAULT_THREAD_LOCAL_CONNECTIONS = false;
+
+  /**
+   * The default value for whether to establish a server to client subscription.
+   * <p>Current value: <code>false</code>.
+   */
+  public static final boolean DEFAULT_SUBSCRIPTION_ENABLED = false;
+
+  /**
+   * The default redundancy for servers holding subscriptions established by this
+   * client
+   * <p>Current value: <code>0</code>.
+   */
+  public static final int DEFAULT_SUBSCRIPTION_REDUNDANCY = 0;
+  
+  /**
+   * The default amount of time, in milliseconds, that messages sent from a
+   * server to a client will be tracked. The tracking is done to minimize
+   * duplicate events.
+   * <p>Current value: <code>900000</code>.
+   */
+  public static final int DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT = 900000;
+  
+  /**
+   * The default amount of time, in milliseconds, to wait before
+   * sending an acknowledgement to the server about events
+   * received from the subscriptions.
+   * <p>Current value: <code>100</code>.
+   */
+  public static final int DEFAULT_SUBSCRIPTION_ACK_INTERVAL = 100;
+
+  /**
+   * The default server group.
+   * <p>Current value: <code>""</code>.
+   */
+  public static final String DEFAULT_SERVER_GROUP = "";
+
+  /**
+   * The default value for whether to have single hop optimisations enabled.
+   * <p>Current value: <code>true</code>.
+   * @since 6.5
+   */
+  public static final boolean DEFAULT_PR_SINGLE_HOP_ENABLED = true;
+  /**
+   * The default value for whether to use multiuser mode.
+   * <p>Current value: <code>false</code>.
+   * @since 6.5
+   */  
+  public static final boolean DEFAULT_MULTIUSER_AUTHENTICATION = false;
+  /**
+   * Sets the free connection timeout for this pool.
+   * If the pool has a max connections setting, operations will block
+   * if all of the connections are in use. The free connection timeout
+   * specifies how long those operations will block waiting for
+   * a free connection before receiving
+   * an {@link AllConnectionsInUseException}. If max connections 
+   * is not set this setting has no effect.
+   * @see #setMaxConnections(int)
+   * @param connectionTimeout the connection timeout in milliseconds
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>connectionTimeout</code>
+   * is less than or equal to <code>0</code>.
+   */
+  public PoolFactory setFreeConnectionTimeout(int connectionTimeout);
+  /**
+   * Sets the load conditioning interval for this pool.
+   * This interval controls how frequently the pool will check to see if 
+   * a connection to a given server should be moved to a different
+   * server to improve the load balance.  
+   * <p>A value of <code>-1</code> disables load conditioning
+   * @param loadConditioningInterval the connection lifetime in milliseconds
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>connectionLifetime</code>
+   * is less than <code>-1</code>.
+   */
+  public PoolFactory setLoadConditioningInterval(int loadConditioningInterval);
+  /**
+   * Sets the socket buffer size for each connection made in this pool.
+   * Large messages can be received and sent faster when this buffer is larger.
+   * Larger buffers also optimize the rate at which servers can send events
+   * for client subscriptions.
+   * @param bufferSize the size of the socket buffers used for reading and
+   * writing on each connection in this pool.
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>bufferSize</code>
+   * is less than or equal to <code>0</code>.
+   */
+  public PoolFactory setSocketBufferSize(int bufferSize);
+  /**
+   * Sets the thread local connections policy for this pool.
+   * If <code>true</code> then any time a thread goes to use a connection
+   * from this pool it will check a thread local cache and see if it already
+   * has a connection in it. If so it will use it. If not it will get one from
+   * this pool and cache it in the thread local. This gets rid of thread contention
+   * for the connections but increases the number of connections the servers see.
+   * <p>If <code>false</code> then connections are returned to the pool as soon
+   * as the operation being done with the connection completes. This allows
+   * connections to be shared amonst multiple threads keeping the number of
+   * connections down.
+   * @param threadLocalConnections if <code>true</code> then enable thread local
+   * connections.
+   * @return a reference to <code>this</code>
+   */
+  public PoolFactory setThreadLocalConnections(boolean threadLocalConnections);
+  
+  /**
+   * Sets the number of milliseconds to wait for a response from a server before
+   * timing out the operation and trying another server (if any are available).
+   * @param timeout number of milliseconds to wait for a response from a server
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>timeout</code>
+   * is less than <code>0</code>.
+   */
+  public PoolFactory setReadTimeout(int timeout);
+  
+  /**
+   * Set the minimum number of connections to keep available at all times.
+   * When the pool is created, it will create this many connections. 
+   * If <code>0</code> then connections will not be made until an actual operation
+   * is done that requires client-to-server communication.
+   * @param minConnections the initial number of connections
+   * this pool will create.
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>minConnections</code>
+   * is less than <code>0</code>.
+   */
+  public PoolFactory setMinConnections(int minConnections);
+  
+  /**
+   * Set the max number of client to server connections that the pool will create. If all of 
+   * the connections are in use, an operation requiring a client to server connection
+   * will block until a connection is available.
+   * @see #setFreeConnectionTimeout(int) 
+   * @param maxConnections the maximum number of connections in the pool.
+   * this pool will create. -1 indicates that there is no maximum number of connections
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>maxConnections</code>
+   * is less than <code>minConnections</code>.
+   */
+  public PoolFactory setMaxConnections(int maxConnections);
+  
+  /**
+   * Set the amount of time a connection can be idle before expiring the connection.
+   * If the pool size is greater than the minimum specified by 
+   * {@link PoolFactory#setMinConnections(int)}, connections which have been idle
+   * for longer than the idleTimeout will be closed. 
+   * @param idleTimeout The amount of time in milliseconds that an idle connection
+   * should live before expiring. -1 indicates that connections should never expire.
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>idleTimout</code>
+   * is less than <code>-1</code>.
+   */
+  public PoolFactory setIdleTimeout(long idleTimeout);
+  
+  /**
+   * Set the number of times to retry a request after timeout/exception.
+   * @param retryAttempts The number of times to retry a request 
+   * after timeout/exception. -1 indicates that a request should be 
+   * tried against every available server before failing
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>retryAttempts</code>
+   * is less than <code>-1</code>.
+   */
+  public PoolFactory setRetryAttempts(int retryAttempts);
+  
+  /**
+   * How often to ping servers to verify that they are still alive. Each
+   * server will be sent a ping every pingInterval if there has not
+   * been any other communication with the server.
+   * 
+   * These pings are used by the server to monitor the health of
+   * the client. Make sure that the pingInterval is less than the 
+   * maximum time between pings allowed by the bridge server.
+   * @param pingInterval The amount of time in milliseconds between
+   * pings.
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>pingInterval</code>
+   * is less than or equal to <code>0</code>.
+   * @see CacheServer#setMaximumTimeBetweenPings(int)
+   */
+  public PoolFactory setPingInterval(long pingInterval);
+
+  /**
+   * How often to send client statistics to the server.
+   * Doing this allows <code>gfmon</code> to monitor clients.
+   * <p>A value of <code>-1</code> disables the sending of client statistics
+   * to the server.
+   * 
+   * @param statisticInterval The amount of time in milliseconds between
+   * sends of client statistics to the server.
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>statisticInterval</code>
+   * is less than <code>-1</code>.
+   */
+  public PoolFactory setStatisticInterval(int statisticInterval);
+
+  /**
+   * Configures the group that all servers this pool connects to must belong to.
+   * @param group the server group that this pool will connect to.
+   * If <code>null</code> or <code>""</code> then all servers will be connected to.
+   * @return a reference to <code>this</code>
+   */
+  public PoolFactory setServerGroup(String group);
+
+  /**
+   * Add a locator, given its host and port, to this factory.
+   * The locator must be a server locator and will be used to discover other running
+   * bridge servers and locators.
+   * @param host the host name or ip address that the locator is listening on.
+   * @param port the port that the locator is listening on
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>host</code> is an unknown host
+   * according to {@link java.net.InetAddress#getByName(String)} or if port is outside
+   * the valid range of [1..65535] inclusive.
+   * @throws IllegalStateException if a server has already been {@link #addServer added} to this factory.
+   */
+  public PoolFactory addLocator(String host, int port);
+
+  /**
+   * Add a server, given its host and port, to this factory.
+   * The server must be a bridge server and this client will
+   * directly connect to without consulting a server locator.
+   * @param host the host name or ip address that the server is listening on.
+   * @param port the port that the server is listening on
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>host</code> is an unknown host
+   * according to {@link java.net.InetAddress#getByName(String)} or if port is outside
+   * the valid range of [1..65535] inclusive.
+   * @throws IllegalStateException if a locator has already been {@link #addLocator added} to this factory.
+   */
+  public PoolFactory addServer(String host, int port);
+
+  /**
+   * If set to <code>true</code> then the created pool will have server-to-client
+   * subscriptions enabled.
+   * If set to <code>false</code> then all <code>Subscription*</code> attributes
+   * are ignored at create time.
+   * @return a reference to <code>this</code>
+   */
+  public PoolFactory setSubscriptionEnabled(boolean enabled);
+  
+  /**
+   * Sets the redundancy level for this pools server-to-client subscriptions.
+   * If <code>0</code> then no redundant copies will be kept on the servers.
+   * Otherwise an effort will be made to maintain the requested number of
+   * copies of the server-to-client subscriptions. At most one copy per server will
+   * be made up to the requested level.
+   * @param redundancy the number of redundant servers for this client's subscriptions.
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>redundancyLevel</code>
+   * is less than <code>-1</code>.
+   */
+  public PoolFactory setSubscriptionRedundancy(int redundancy);
+  /**
+   * Sets the messageTrackingTimeout attribute which is the time-to-live period, in
+   * milliseconds, for subscription events the client has received from the server. It's used
+   * to minimize duplicate events.
+   * Entries that have not been modified for this amount of time
+   * are expired from the list
+   * @param messageTrackingTimeout number of milliseconds to set the timeout to.
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>messageTrackingTimeout</code>
+   * is less than or equal to <code>0</code>.
+   */
+  public PoolFactory setSubscriptionMessageTrackingTimeout(int messageTrackingTimeout);
+  
+  /**
+   * Sets the interval in milliseconds
+   * to wait before sending acknowledgements to the bridge server for
+   * events received from the server subscriptions.
+   * 
+   * @param ackInterval number of milliseconds to wait before sending event
+   * acknowledgements.
+   * @return a reference to <code>this</code>
+   * @throws IllegalArgumentException if <code>ackInterval</code>
+   * is less than or equal to <code>0</code>.
+   */
+  public PoolFactory setSubscriptionAckInterval(int ackInterval);
+
+  /**
+   * Resets the configuration of this factory to its defaults.
+   * @return a reference to <code>this</code>
+   */
+  public PoolFactory reset();
+  
+  /**
+   * Create a new Pool for connecting a client to a set of GemFire Cache Servers.
+   * using this factory's settings for attributes.
+   * 
+   * @param name the name of the pool, used when connecting regions to it
+   * @throws IllegalStateException if a pool with <code>name</code> already exists
+   * @throws IllegalStateException if a locator or server has not been added.
+   * @return the newly created pool.
+   */
+  public Pool create(String name);
+  
+  /**
+   * By default setPRSingleHopEnabled is <code>true</code>
+   * in which case the client is aware of the location of partitions on servers hosting
+   * {@link Region regions} with
+   * {@link com.gemstone.gemfire.cache.DataPolicy#PARTITION}.
+   * Using this information, the client routes the client cache operations
+   * directly to the server which is hosting the required partition for the
+   * cache operation using a single network hop.
+   * This mode works best 
+   * when {@link #setMaxConnections(int)} is set
+   * to <code>-1</code> which is the default.
+   * This mode causes the client to have more connections to the servers.
+   * <p>
+   * If setPRSingleHopEnabled is <code>false</code> the client may need to do an extra network hop on servers
+   * to go to the required partition for that cache operation.
+   * The client will use fewer network connections to the servers.
+   * <p>
+   * Caution: for {@link com.gemstone.gemfire.cache.DataPolicy#PARTITION partition} regions
+   *  with
+   * {@link com.gemstone.gemfire.cache.PartitionAttributesFactory#setLocalMaxMemory(int) local-max-memory}
+   * equal to zero, no cache operations mentioned above will be routed to those
+   * servers as they do not host any partitions.
+   * 
+   * @return a reference to <code>this</code>
+   * @since 6.5
+   */
+  public PoolFactory setPRSingleHopEnabled(boolean enabled);
+
+  /**
+   * If set to <code>true</code> then the created pool can be used by multiple
+   * authenticated users. <br>
+   * 
+   * This setting should only be used for applications that require the client
+   * to authenticate itself with the server multiple users.
+   * 
+   * <br>
+   * Note: If set to true, all the client side regions must have their
+   * data-policy set to empty.
+   * 
+   * @return a reference to <code>this</code>
+   * @see ClientCache#createAuthenticatedView(java.util.Properties)
+   * @since 6.5
+   */
+  public PoolFactory setMultiuserAuthentication(boolean enabled);
+  
+}


[27/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesFactory.java
new file mode 100644
index 0000000..9f6984d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesFactory.java
@@ -0,0 +1,1999 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
+import com.gemstone.gemfire.cache.client.PoolManager;
+import com.gemstone.gemfire.compression.Compressor;
+import com.gemstone.gemfire.internal.cache.AbstractRegion;
+import com.gemstone.gemfire.internal.cache.DiskStoreFactoryImpl;
+import com.gemstone.gemfire.internal.cache.DiskWriteAttributesImpl;
+import com.gemstone.gemfire.internal.cache.EvictionAttributesImpl;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.PartitionAttributesImpl;
+import com.gemstone.gemfire.internal.cache.PartitionedRegionHelper;
+import com.gemstone.gemfire.internal.cache.UserSpecifiedRegionAttributes;
+import com.gemstone.gemfire.internal.cache.xmlcache.RegionAttributesCreation;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+/** Creates instances of {@link RegionAttributes}. An <code>AttributesFactory</code>
+ * instance maintains state for creating <code>RegionAttributes</code> instances.
+ * The setter methods are used to change the settings that will be used for
+ * creating the next attributes instance with the {@link #create}
+ * method. If you create a factory with the default constructor, then the
+ * factory is set up to create attributes with all default settings. You can
+ * also create a factory by providing a <code>RegionAttributes</code>, which
+ * will set up the new factory with the settings provided in that attributes
+ * instance.
+ *
+ * <p>Once a <code>RegionAttributes</code> is created, it can only be modified
+ * after it has been used to create a <code>Region</code>, and then only by
+ * using an {@link AttributesMutator} obtained from the region.
+ *
+ * <h3>Attributes</h3>
+ * <h4>Callbacks</h4>
+ * <dl>
+ * <dt>{@link CacheLoader} [<em>default:</em> <code>null</code>, meaning no loader]</dt>
+ *     <dd>User-implemented plug-in for loading data on cache misses.<br>
+ *        {@link #setCacheLoader} {@link RegionAttributes#getCacheLoader}
+ *        {@link AttributesMutator#setCacheLoader}</dd>
+ *
+ * <dt>{@link CacheWriter} [<em>default:</em> <code>null</code>, meaning no writer]</dt>
+ *     <dd>User-implemented plug-in for intercepting cache modifications, e.g.
+ *         for writing to an external data source.<br>
+ *         {@link #setCacheWriter} {@link RegionAttributes#getCacheWriter}
+ *         {@link AttributesMutator#setCacheWriter}</dd>
+ *
+ * <dt>{@link CacheListener} [<em>default:</em> <code>null</code>, meaning no listener ]</dt>
+ *     <dd>User-implemented plug-in for receiving and handling cache related events.<br>
+ *         {@link #addCacheListener} {@link #initCacheListeners}
+ *         {@link #initCacheListeners}
+ *         {@link RegionAttributes#getCacheListeners}
+ *         {@link AttributesMutator#initCacheListeners}
+ *         {@link AttributesMutator#addCacheListener}
+ *         {@link AttributesMutator#removeCacheListener}</dd>
+ * </dl>
+ * <h4>Expiration</h4>
+ * <dl>
+ * <dt>RegionTimeToLive [<em>default:</em> no expiration]</dt>
+ * <dd>Expiration configuration for the entire region based on the
+ * {@link CacheStatistics#getLastModifiedTime lastModifiedTime}.<br>
+ * {@link #setRegionTimeToLive} {@link RegionAttributes#getRegionTimeToLive}
+ * {@link AttributesMutator#setRegionTimeToLive}</dd>
+ *
+ * <dt>RegionIdleTimeout [<em>default:</em> no expiration]</dt>
+ * <dd>Expiration configuration for the entire region based on the
+ * {@link CacheStatistics#getLastAccessedTime lastAccessedTime}.<br>
+ * {@link #setRegionIdleTimeout} {@link RegionAttributes#getRegionIdleTimeout}
+ * {@link AttributesMutator#setRegionIdleTimeout}</dd>
+ *
+ * <dt>EntryTimeToLive [<em>default:</em> no expiration]</dt>
+ * <dd>Expiration configuration for individual entries based on the
+ * {@link CacheStatistics#getLastModifiedTime lastModifiedTime}.<br>
+ * {@link #setEntryTimeToLive} {@link RegionAttributes#getEntryTimeToLive}
+ * {@link AttributesMutator#setEntryTimeToLive}</dd>
+ *
+ * <dt>EntryIdleTimeout [<em>default:</em> no expiration]</dt>
+ * <dd>Expiration configuration for individual entries based on the
+ * {@link CacheStatistics#getLastAccessedTime lastAccessedTime}.<br>
+ * {@link #setEntryIdleTimeout} {@link RegionAttributes#getEntryIdleTimeout}
+ * {@link AttributesMutator#setEntryIdleTimeout}</dd>
+ * </dl>
+ * <h4>Distribution</h4>
+ * <dl>
+ * <dt>{@link Scope}[<em>default:</em> {@link Scope#DISTRIBUTED_NO_ACK}]
+ * </dt>
+ * <dd>Properties of distribution for the region, including whether it is
+ * distributed at all, whether acknowledgements are required, and whether
+ * distributed synchronization is required. <br>
+ * {@link #setScope} {@link RegionAttributes#getScope}</dd>
+ *
+ * <dt>EarlyAck [<em>default:</em> <code>false</code>]</dt>
+ *     <dd>Whether or not acks required by <code>Scope.DISTRIBUTED_ACK</code>
+ *     are sent after an operation is processed. If <code>true</code>
+ *     then remote caches will ACK before processing an operation sent
+ *     by the cache that has set earlyAck to <code>true</code>.
+ *     Note that this attribute is only meaningful on the cache that
+ *     is initiating an operation; it does not matter what it is set to
+ *     on the cache that receives the operation.<br>
+ *     {@link #setEarlyAck} {@link RegionAttributes#getEarlyAck}</dd>
+
+ * <dt>{@link SubscriptionAttributes} [<em>default:</em> {@link InterestPolicy#DEFAULT}]</dt>
+ *     <dd>How will the region in this cache subscribe to other distributed
+ *     instances of this region.
+ *     <br>
+ *     {@link #setSubscriptionAttributes} {@link RegionAttributes#getSubscriptionAttributes}</dd>
+ *
+ * <dt>EnableAsyncConflation [<em>default:</em> <code>false</code>]</dt>
+ *     <dd>Whether or not conflation is enabled for sending
+ *     messages to async peers. Async peers are those whose
+ *     <code>async-distribution-timeout</code> gemfire.property is greater
+ *     than zero. AsyncConflation is ignored if the scope is
+ *     <code>DISTRIBUTED_ACK</code> or <code>GLOBAL</code>.
+ *     Conflation is only done on entry update operations. It is done
+ *     by dropping the earlier update from the message queue.
+ *     {@link #setEnableAsyncConflation} {@link RegionAttributes#getEnableAsyncConflation}</dd>
+ * <dt>poolName [<em>default:</em> <code>null</code>, meaning no pool]</dt>
+ *     <dd>Whether or not this region is a client that is to use
+ *     connections from the named pool to communicate with servers.
+ *     If <code>null</code>, then it is not a client.
+ *     If <code>non-null</code>, then the named pool will be used.
+ *     {@link #setPoolName} {@link RegionAttributes#getPoolName}</dd>
+ * 
+ *
+ * <dt>EnableSubscriptionConflation [<em>default:</em> <code>false</code>]</dt>
+ *     <dd>Whether or not conflation is enabled for sending
+ *     messages from a cache server to its clients. Note: This parameter
+ *     is only valid for cache server to client communication. It has no
+ *     effect in peer to peer communication.
+ *     If <code>true</code>, messages will be conflated before they are
+ *     sent from a cache server to its clients. Only the latest value
+ *     will be sent.
+ *     Note that this attribute is only meaningful in a client server
+ *     topology.
+ *     {@link #setEnableSubscriptionConflation} {@link RegionAttributes#getEnableSubscriptionConflation}</dd>
+ * <dt>Publisher [<em>default:</em> <code>false</code>]</dt>
+ *     <dd>Whether or not a region is a publisher. Publishers are regions
+ *         that will have distributed write operations done on them.
+ *         If a publisher is also a replicate then it will be used
+ *         as the preferred source for initializing other replicates.
+ *     {@link #setPublisher} {@link RegionAttributes#getPublisher}</dd>
+ * <dt>isCloningEnabled [<em>default:</em> <code>false</code>]</dt>
+ *     <dd>Whether or not value is cloned before appling <code>Delta</code>s
+ *     If <code>false</code>, value will not be cloned
+ *     {@link #setCloningEnabled} {@link RegionAttributes#getCloningEnabled()}</dd></dt>
+ * </dl>
+ * <h4>Storage (see also <a href="package-summary.html#storage">package summary
+ * </a>)</h4>
+ * <dl>
+ * <dt>{@link DataPolicy} [<em>default:</em> <code>DataPolicy.NORMAL</code>]</dt>
+ *     <dd>Specifies the data storage policy.<br>
+ *         {@link #setDataPolicy} {@link RegionAttributes#getDataPolicy}</dd>
+ *
+ * <dt>{@link MirrorType} [<em>default:</em> <code>MirrorType.NONE</code>]</dt>
+ *     <dd><em>Deprecated</em>, use DataPolicy instead.</dd>
+ *
+ * <dt>{@link #setEvictionAttributes(EvictionAttributes) EvictionAttributes}</dt>
+ *      <dd>{@link EvictionAttributes} are the replacement for the deprecated and removed CapacityController interface.
+ *          EvictionAttributes describe the {@link EvictionAlgorithm} and the {@link EvictionAction}
+ *          as well as the various conditions under which the algorithm perform the action
+ *          e.g. when the maximum number of entries has been reached or
+ *          the maximum percentage of JVM heap has been consumed.
+ *          Setting <code>EvictionAttributes</code> installs an eviction controller
+ *          on the Region instantiated with the associated RegionAttributes </dd>
+ *
+ * <dt>KeyConstraint [<em>default:</em> <code>null</code>, meaning no constraint]</dt>
+ *     <dd>The Class to constrain the keys to in the region.<br>
+ *         {@link #setKeyConstraint} {@link RegionAttributes#getKeyConstraint}</dd>
+ *
+ * <dt>ValueConstraint [<em>default:</em> <code>null</code>, meaning no constraint]</dt>
+ *     <dd>The Class to constrain the values to in the region. In addition to the
+ *         utility of this for applications in general, a <code>valueConstraint</code>
+ *         is helpful for compiling queries.<br>
+ *         {@link #setValueConstraint} {@link RegionAttributes#getValueConstraint}</dd>
+ *
+ * <dt>InitialCapacity [<em>default:</em> <code>16</code>]</dt>
+ * <dd>The initial capacity of the map used for storing the entries. <br>
+ * {@link java.util.HashMap} {@link #setInitialCapacity}
+ * {@link RegionAttributes#getInitialCapacity}</dd>
+ *
+ * <dt>LoadFactor [<em>default:</em> <code>0.75</code>]</dt>
+ * <dd>The load factor of the map used for storing the entries. <br>
+ * {@link java.util.HashMap} {@link #setLoadFactor}
+ * {@link RegionAttributes#getLoadFactor}</dd>
+ *
+ * <dt>ConcurrencyLevel [<em>default:</em> <code>16</code>]</dt>
+ * <dd>The allowed concurrency among updates to values in the region is guided
+ * by the <tt>concurrencyLevel</tt>, which is used as a hint for internal
+ * sizing. The actual concurrency will vary. Ideally, you should choose a value
+ * to accommodate as many threads as will ever concurrently modify values in the
+ * region. Using a significantly higher value than you need can waste space and
+ * time, and a significantly lower value can lead to thread contention. But
+ * overestimates and underestimates within an order of magnitude do not usually
+ * have much noticeable impact. A value of one is appropriate when it is known
+ * that only one thread will modify and all others will only read. <br>
+ * {@link #setConcurrencyLevel} {@link RegionAttributes#getConcurrencyLevel}
+ * </dd>
+ * 
+ * <dt>ConcurrencyChecksEnabled [<em>default:</em> <code>false</code>]</dt>
+ * <dd>Enables a distributed versioning algorithm that detects concurrency
+ * conflicts in regions and ensures that changes to an
+ * entry are not applied in a different order in other members.  This can
+ * cause operations to be conflated, so that some cache listeners may see
+ * an event while others do not, but it guarantees that the system will
+ * be consistent.
+ * </dd>
+ *
+ * <dt>StatisticsEnabled [<em>default:</em> <code>false</code>]</dt>
+ * <dd>Whether statistics are enabled for this region. The default is disabled,
+ * which conserves on memory. <br>
+ * {@link #setStatisticsEnabled} {@link RegionAttributes#getStatisticsEnabled}
+ * </dd>
+ *
+ * <dt>IgnoreJTA [<em>default:</em> <code>false</code>]</dt>
+ *     <dd>Whether JTA transactions are ignored for this region.  The
+ *     default is to look for and join JTA transactions for operations
+ *     performed on a region.
+ *
+ * <dt>DiskStoreName [<em>default:</em> <code>null</code>, meaning no disk store]</dt>
+ *    <dd>If not <code>null</code> then this region will write its data
+ *    to the named {@link DiskStore}.<br>
+ *    {@link #setDiskStoreName} {@link RegionAttributes#getDiskStoreName}</dd>
+ *
+ * <dt>DiskSynchronous [<em>default:</em> <code>true</code>]</dt>
+ *    <dd>If <code>true</code> then any writes to disk done for this region
+ *    will be done synchronously. This means that they will be in the file system
+ *    buffer before the operation doing the write returns.<br>
+ *    If <code>false</code> then any writes to disk done for this region
+ *    will be done asynchronously. This means that they are queued up to be written
+ *    and when they are actually written to the file system buffer is determined
+ *    by the region's {@link DiskStore} configuration.
+ *    Asynchronous writes will be conflated if the same entry is written while a
+ *    previous operation for the same entry is still in the queue.<br>
+ *    {@link #setDiskSynchronous} {@link RegionAttributes#isDiskSynchronous}</dd>
+
+ * <dt>PersistBackup [<em>default:</em> <code>false</code>]</dt>
+ *     <dd>Whether or not a persistent backup should be made of the
+ *     region.<br>
+ *     {@link #setPersistBackup} {@link RegionAttributes#getPersistBackup}</dd>
+ *     <dd><em>Deprecated</em>, use {@link DataPolicy#PERSISTENT_REPLICATE} or {@link DataPolicy#PERSISTENT_PARTITION} instead.</dd>
+ *
+ * <dt>DiskWriteAttributes [<em>default:</em> Asynchronously write to
+ *            disk every second (a <code>timeInterval</code> of 1000 and a
+ *            <code>byteThreshold</codE> of 0). <code>rollOplogs</code> is set to true and
+ *            <code>maxOplogSize</code> is set to 1024 MB]</dt>
+ *     <dd>How region data should be written to disk.  Determines
+ *     whether data should be written synchronously or asynchronously.
+ *     Data that is written asynchronously can be written at a certain
+ *     {@linkplain DiskWriteAttributes#getTimeInterval time interval}
+ *     or once a certain number of {@linkplain
+ *     DiskWriteAttributes#getBytesThreshold bytes of data} have been
+ *     enqueued.<br>
+ *     {@link DiskWriteAttributes} {@link #setDiskWriteAttributes} {@link RegionAttributes#getDiskWriteAttributes}</dd>
+ *     <dd><em>Deprecated</em>, use {@link #setDiskStoreName} and {@link #setDiskSynchronous} instead.</dd>
+ *
+ * <dt>DiskDirs [<em>default:</em> Current working directory (<code>user.dir</code> {@linkplain System#getProperties system property})]</dt>
+ *     <dd>The directories to which the region's data are written.  If
+ *     multiple directories are used, GemFire will attempt to distribute the
+ *     data evenly among them. <br>
+ *     {@link #setDiskDirs} {@link RegionAttributes#getDiskDirs}</dd>
+ *     <dd><em>Deprecated</em>, use {@link #setDiskStoreName} instead.</dd>
+ *
+ * <dt>DiskDirSizes [<em>default:</em> 10240 MB]</dt>
+ * <dd> The size of the directory to which region's data is written.<br>
+ * {@link #setDiskDirsAndSizes} {@link RegionAttributes#getDiskDirSizes}</dd>
+ * <dd><em>Deprecated</em>, use {@link #setDiskStoreName} instead.</dd>
+ *
+ *
+ * <dt>{@link PartitionAttributes} [<em>default:</em> <code>null</code>, meaning no region partitioning]</dt>
+ *     <dd>How region data is partitioned among the members of the
+ *     distributed system.
+ *     <br>
+ *     {@link #setPartitionAttributes} {@link RegionAttributes#getPartitionAttributes}</dd>
+ *
+ * <dt>{@link MembershipAttributes} [<em>default:</em> no required roles]</dt>
+ *     <dd>How access to the region is affected when one or more required roles
+ *     are missing from the region membership.
+ *     <br>
+ *     {@link #setMembershipAttributes} {@link RegionAttributes#getMembershipAttributes}</dd>
+ *
+ * </dt>
+ * </dl>
+ *
+ * <h4>Locking</h4>
+ * <dl>
+ * <dt>LockGrantor [<em>default:</em> <code>false</code>]</dt>
+ *     <dd>Should this process become lock grantor for the region?</dd><br>
+ *     {@link #setLockGrantor} {@link RegionAttributes#isLockGrantor}
+ *     {@link Region#becomeLockGrantor}
+ * </dl>
+ *
+ * <h4>Querying</h4>
+ * <dl>
+ * <dt>IndexMaintenanceSynchronous [<em>default:</em> <code>false</code>]</dt>
+ *     <dd>Are indexes built over in this region updated
+ *         synchronously when the underlying data is
+ *         modified?</dd><br>
+ *     {@link #setIndexMaintenanceSynchronous} {@link
+ *     RegionAttributes#getIndexMaintenanceSynchronous}
+ * </dl>
+ *
+ * <p>Note that the RegionAttributes are not distributed with the region.
+ *
+ * <a name="compatibility"><h3>Compatibility Rules</h3>
+ * <h4>RegionAttributes Creation Constraints</h4>
+ * If any of the following compatibility rules are violated when
+ * {@link #create}</code> is called then an
+ * {@link IllegalStateException} is thrown.
+ * See {@link #validateAttributes}.
+ *
+ * <a name="creationConstraints"><h3>Creation Constraints</h3>
+ * <h4>Region Creation Constraints on RegionAttributes</h4>
+ *
+ * If any of the following rules are violated when {@link
+ * Region#createSubregion createSubregion} or {@link Cache#createRegion
+ * createRegion} are called, then an
+ * <code>IllegalStateException</code> is thrown.
+ *
+ * <ul>
+ * <li>A region with <code>Scope.LOCAL</code> can only have subregions with
+ * <code>Scope.LOCAL</code>.</li>
+ * <li><code>Scope.GLOBAL</code> is illegal if there is any other cache in
+ * the distributed system that has the same region with
+ * <code>Scope.DISTRIBUTED_NO_ACK</code> or <code>Scope.DISTRIBUTED_ACK</code>.
+ * </li>
+ * <li><code>Scope.DISTRIBUTED_ACK</code> is illegal if there is any other
+ * cache in the distributed system that has the same region with
+ * <code>Scope.DISTRIBUTED_NO_ACK</code> or <code>Scope.GLOBAL</code>.
+ * </li>
+ * <li><code>Scope.DISTRIBUTED_NO_ACK</code> is illegal if there is any other
+ * cache in the distributed system that has the same region with
+ * <code>Scope.DISTRIBUTED_ACK</code> or <code>Scope.GLOBAL</code>.</li>
+ * </ul>
+ *
+ * @see RegionAttributes
+ * @see AttributesMutator
+ * @see Region#createSubregion(String, RegionAttributes)
+ *
+ * @author Eric Zoerner
+ * @since 3.0
+ * @deprecated as of 6.5 use {@link Cache#createRegionFactory(RegionShortcut)} or {@link ClientCache#createClientRegionFactory(ClientRegionShortcut)} instead.
+ */
+@SuppressWarnings("synthetic-access")
+public class AttributesFactory<K,V> {
+  private final RegionAttributesImpl<K,V> regionAttributes = new RegionAttributesImpl<K,V>();
+
+  /**
+   * The default disk synchronous write setting
+   * <p>Current value: <code>true</code> each.
+   * @since 6.5
+   */
+  public static final boolean DEFAULT_DISK_SYNCHRONOUS = true;
+  
+  /**
+   * Creates a new instance of AttributesFactory ready to create a
+   * <code>RegionAttributes</code> with default settings.
+   */
+  public AttributesFactory() {
+  }
+
+  /**
+   * Creates a new instance of AttributesFactory ready to create a
+   * <code>RegionAttributes</code> with the same settings as those in the
+   * specified <code>RegionAttributes</code>.
+   *
+   * @param regionAttributes
+   *          the <code>RegionAttributes</code> used to initialize this
+   *          AttributesFactory
+   */
+  @SuppressWarnings("deprecation")
+  public AttributesFactory(RegionAttributes<K,V> regionAttributes) {
+    synchronized (this.regionAttributes) {
+      this.regionAttributes.cacheListeners = new ArrayList<CacheListener<K,V>>(Arrays.asList(regionAttributes.getCacheListeners()));
+    }
+    this.regionAttributes.cacheLoader = regionAttributes.getCacheLoader();
+    this.regionAttributes.cacheWriter = regionAttributes.getCacheWriter();
+    this.regionAttributes.regionTimeToLive = regionAttributes
+        .getRegionTimeToLive().getTimeout();
+    this.regionAttributes.regionTimeToLiveExpirationAction = regionAttributes
+        .getRegionTimeToLive().getAction();
+    this.regionAttributes.regionIdleTimeout = regionAttributes
+        .getRegionIdleTimeout().getTimeout();
+    this.regionAttributes.regionIdleTimeoutExpirationAction = regionAttributes
+        .getRegionIdleTimeout().getAction();
+    
+    this.regionAttributes.entryTimeToLive = regionAttributes
+        .getEntryTimeToLive().getTimeout();
+    this.regionAttributes.entryTimeToLiveExpirationAction = regionAttributes
+        .getEntryTimeToLive().getAction();
+    this.regionAttributes.customEntryTimeToLive = regionAttributes
+        .getCustomEntryTimeToLive();
+    this.regionAttributes.entryIdleTimeout = regionAttributes
+        .getEntryIdleTimeout().getTimeout();
+    this.regionAttributes.entryIdleTimeoutExpirationAction = regionAttributes
+        .getEntryIdleTimeout().getAction();
+    this.regionAttributes.customEntryIdleTimeout = regionAttributes
+        .getCustomEntryIdleTimeout();
+    
+    this.regionAttributes.scope = regionAttributes.getScope();
+    this.regionAttributes.dataPolicy = regionAttributes.getDataPolicy();
+    this.regionAttributes.statisticsEnabled = regionAttributes.getStatisticsEnabled();
+    this.regionAttributes.ignoreJTA = regionAttributes.getIgnoreJTA();
+    this.regionAttributes.keyConstraint = regionAttributes.getKeyConstraint();
+    this.regionAttributes.valueConstraint = regionAttributes
+        .getValueConstraint();
+    this.regionAttributes.initialCapacity = regionAttributes
+        .getInitialCapacity();
+    this.regionAttributes.loadFactor = regionAttributes.getLoadFactor();
+    this.regionAttributes.concurrencyLevel = regionAttributes
+        .getConcurrencyLevel();
+    this.regionAttributes.concurrencyChecksEnabled = regionAttributes.getConcurrencyChecksEnabled();
+    this.regionAttributes.earlyAck = regionAttributes.getEarlyAck();
+    this.regionAttributes.diskStoreName = regionAttributes.getDiskStoreName();
+    if (this.regionAttributes.diskStoreName == null) {
+      this.regionAttributes.diskWriteAttributes = regionAttributes
+      .getDiskWriteAttributes();
+      this.regionAttributes.diskDirs = regionAttributes.getDiskDirs();
+      this.regionAttributes.diskSizes = regionAttributes.getDiskDirSizes();
+    }
+    this.regionAttributes.diskSynchronous = regionAttributes.isDiskSynchronous();
+    this.regionAttributes.indexMaintenanceSynchronous = regionAttributes
+        .getIndexMaintenanceSynchronous();
+    this.regionAttributes.partitionAttributes = regionAttributes
+        .getPartitionAttributes();
+    this.regionAttributes.evictionAttributes = (EvictionAttributesImpl)regionAttributes
+        .getEvictionAttributes();
+
+    this.regionAttributes.membershipAttributes = regionAttributes.getMembershipAttributes();
+    this.regionAttributes.subscriptionAttributes = regionAttributes.getSubscriptionAttributes();
+    this.regionAttributes.evictionAttributes = (EvictionAttributesImpl) regionAttributes.getEvictionAttributes();
+
+    this.regionAttributes.publisher = regionAttributes.getPublisher();
+    this.regionAttributes.enableAsyncConflation = regionAttributes.getEnableAsyncConflation();
+    this.regionAttributes.enableSubscriptionConflation = regionAttributes.getEnableSubscriptionConflation();
+    this.regionAttributes.poolName = regionAttributes.getPoolName();
+    this.regionAttributes.isCloningEnabled = regionAttributes.getCloningEnabled();
+    this.regionAttributes.multicastEnabled = regionAttributes.getMulticastEnabled();
+    this.regionAttributes.gatewaySenderIds = new CopyOnWriteArraySet<String>(regionAttributes.getGatewaySenderIds());
+    this.regionAttributes.asyncEventQueueIds = new CopyOnWriteArraySet<String>(regionAttributes.getAsyncEventQueueIds());
+    this.regionAttributes.isLockGrantor = regionAttributes.isLockGrantor(); // fix for bug 47067
+    if (regionAttributes instanceof UserSpecifiedRegionAttributes) {
+      this.regionAttributes.setIndexes(((UserSpecifiedRegionAttributes<K,V>) regionAttributes).getIndexes());
+    }
+
+    if (regionAttributes instanceof UserSpecifiedRegionAttributes) {
+      // Selectively set has* fields to true, propigating those non-default 
+      // (aka user specified) fields as such
+      UserSpecifiedRegionAttributes<K,V> nonDefault = (UserSpecifiedRegionAttributes<K,V>) regionAttributes;
+      this.regionAttributes.initHasFields(nonDefault);
+      this.regionAttributes.requiresPoolName = nonDefault.requiresPoolName;
+    } else {
+      // Set all fields to false, essentially starting with a new set of defaults
+      this.regionAttributes.setAllHasFields(false);
+      
+      
+      
+//      
+//      // Special Partitioned Region handling by
+//      // pretending the user didn't explicitly ask for the default scope
+//      if (AbstractRegion.DEFAULT_SCOPE.equals(this.regionAttributes.getScope())) {
+//        this.regionAttributes.setHasScope(false); 
+//      }
+    }
+    
+    this.regionAttributes.compressor = regionAttributes.getCompressor();
+  }
+
+  // CALLBACKS
+
+  /**
+   * Sets the cache loader for the next <code>RegionAttributes</code> created.
+   *
+   * @param cacheLoader
+   *          the cache loader or null if no loader
+   * @throws IllegalStateException if this region has a {@link #setPoolName pool name set}
+   */
+  public void setCacheLoader(CacheLoader<K,V> cacheLoader)
+  {
+    if (cacheLoader != null) {
+      if (AbstractRegion.isBridgeLoader(cacheLoader) && this.regionAttributes.getPoolName() != null) {
+        throw new IllegalStateException("A region with a pool name can not have a BridgeLoader or BridgeClient. Please use pools OR BridgeClient.");
+      }
+    }
+    this.regionAttributes.cacheLoader = cacheLoader;
+    this.regionAttributes.setHasCacheLoader(true);
+  }
+
+  /**
+   * Sets the cache writer for the next <code>RegionAttributes</code> created.
+   *
+   * @param cacheWriter
+   *          the cache writer or null if no cache writer
+   * @throws IllegalStateException if this region has a {@link #setPoolName pool name set}
+   */
+  public void setCacheWriter(CacheWriter<K,V> cacheWriter)
+  {
+    if (cacheWriter != null) {
+      if (AbstractRegion.isBridgeWriter(cacheWriter) &&  this.regionAttributes.getPoolName() != null) {
+        throw new IllegalStateException("A region with a pool name can not have a BridgeWriter or BridgeClient. Please use pools OR BridgeClient.");
+      }
+    }
+    this.regionAttributes.cacheWriter = cacheWriter;
+    this.regionAttributes.setHasCacheWriter(true);
+  }
+
+  /** Sets the CacheListener for the next <code>RegionAttributes</code> created.
+   * Any existing cache listeners on this factory are removed.
+   * @param aListener a user defined CacheListener, null if no listener
+   * @deprecated as of GemFire 5.0, use {@link #addCacheListener} instead.
+   */
+  @Deprecated
+  public void setCacheListener(CacheListener<K,V> aListener) {
+    ArrayList<CacheListener<K,V>> col;
+    if (aListener == null) {
+      col = null;
+    } else {
+      col = new ArrayList<CacheListener<K,V>>(1);
+      col.add(aListener);
+    }
+    synchronized (this.regionAttributes) {
+      this.regionAttributes.cacheListeners = col;
+    }
+    this.regionAttributes.setHasCacheListeners(true);
+  }
+  /**
+   * Adds a cache listener to the end of the list of cache listeners on this factory.
+   * @param aListener the cache listener to add to the factory.
+   * @throws IllegalArgumentException if <code>aListener</code> is null
+   * @since 5.0
+   */
+  public void addCacheListener(CacheListener<K,V> aListener) {
+    if (aListener == null) {
+      throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_ADDCACHELISTENER_PARAMETER_WAS_NULL.toLocalizedString());
+    }
+    synchronized (this.regionAttributes) {
+      this.regionAttributes.addCacheListener(aListener);
+    }
+  }
+  /**
+   * Removes all cache listeners and then adds each listener in the specified array.
+   * @param newListeners a possibly null or empty array of listeners to add to this factory.
+   * @throws IllegalArgumentException if the <code>newListeners</code> array has a null element
+   * @since 5.0
+   */
+  public void initCacheListeners(CacheListener<K,V>[] newListeners) {
+    synchronized (this.regionAttributes) {
+      if (newListeners == null || newListeners.length == 0) {
+        this.regionAttributes.cacheListeners = null;
+      } else {
+        List<CacheListener<K,V>> nl = Arrays.asList(newListeners);
+        if (nl.contains(null)) {
+          throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_INITCACHELISTENERS_PARAMETER_HAD_A_NULL_ELEMENT.toLocalizedString());
+        }
+        this.regionAttributes.cacheListeners = new ArrayList<CacheListener<K,V>>(nl);
+      }
+    }
+    this.regionAttributes.setHasCacheListeners(true);
+  }
+
+
+  // EXPIRATION ATTRIBUTES
+
+  /**
+   * Sets the idleTimeout expiration attributes for region entries for the next
+   * <code>RegionAttributes</code> created.
+   * Default is 0 which indicates no expiration of this type.
+   *
+   * @param idleTimeout
+   *          the idleTimeout ExpirationAttributes for entries in this region
+   * @throws IllegalArgumentException
+   *           if idleTimeout is null
+   */
+  public void setEntryIdleTimeout(ExpirationAttributes idleTimeout)
+  {
+    if (idleTimeout == null) {
+      throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_IDLETIMEOUT_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+    this.regionAttributes.entryIdleTimeout = idleTimeout.getTimeout();
+    this.regionAttributes.entryIdleTimeoutExpirationAction = idleTimeout
+        .getAction();
+    this.regionAttributes.setHasEntryIdleTimeout(true);
+  }
+
+  /**
+   * Sets the idleTimeout CustomExpiry for the next <code>RegionAttributes</code>
+   * created.
+   * 
+   * @param custom the CustomExpiry to use; null means none will be used.
+   */
+  public void setCustomEntryIdleTimeout(CustomExpiry<K,V> custom) {
+    this.regionAttributes.customEntryIdleTimeout = custom;
+    this.regionAttributes.setHasCustomEntryIdleTimeout(true);
+  }
+  
+  /**
+   * Sets the timeToLive expiration attributes for region entries for the next
+   * <code>RegionAttributes</code> created.
+   * Default is 0 which indicates no expiration of this type.
+   *
+   * @param timeToLive
+   *          the timeToLive ExpirationAttributes for entries in this region
+   * @throws IllegalArgumentException
+   *           if timeToLive is null
+   */
+  public void setEntryTimeToLive(ExpirationAttributes timeToLive)
+  {
+    if (timeToLive == null) {
+      throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_TIMETOLIVE_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+    this.regionAttributes.entryTimeToLive = timeToLive.getTimeout();
+    this.regionAttributes.entryTimeToLiveExpirationAction = timeToLive
+        .getAction();
+    this.regionAttributes.setHasEntryTimeToLive(true);
+  }
+
+  /**
+   * Sets the custom timeToLive for the next <code>RegionAttributes</code>
+   * created.
+   * 
+   * @param custom the CustomExpiry to use, none if the default for the region
+   * is to be used.
+   */
+  public void setCustomEntryTimeToLive(CustomExpiry<K,V> custom) {
+    this.regionAttributes.customEntryTimeToLive = custom;
+    this.regionAttributes.setHasCustomEntryTimeToLive(true);
+  }
+  
+  /**
+   * Sets the idleTimeout expiration attributes for the region itself for the
+   * next <code>RegionAttributes</code> created.
+   * Default is 0 which indicates no expiration of this type is set. 
+   *
+   * @param idleTimeout
+   *          the ExpirationAttributes for this region idleTimeout
+   * @throws IllegalArgumentException
+   *           if idleTimeout is null
+   */
+  public void setRegionIdleTimeout(ExpirationAttributes idleTimeout)
+  {
+    if (idleTimeout == null) {
+      throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_IDLETIMEOUT_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+    this.regionAttributes.regionIdleTimeout = idleTimeout.getTimeout();
+    this.regionAttributes.regionIdleTimeoutExpirationAction = idleTimeout
+        .getAction();
+    this.regionAttributes.setHasRegionIdleTimeout(true);
+  }
+  
+
+  /**
+   * Sets the timeToLive expiration attributes for the region itself for the
+   * next <code>RegionAttributes</code> created.
+   * Default is 0 i.e. no expiration of this type.
+   *
+   * @param timeToLive
+   *          the ExpirationAttributes for this region timeToLive
+   * @throws IllegalArgumentException
+   *           if timeToLive is null
+   */
+  public void setRegionTimeToLive(ExpirationAttributes timeToLive)
+  {
+    if (timeToLive == null) {
+      throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_TIMETOLIVE_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+    this.regionAttributes.regionTimeToLive = timeToLive.getTimeout();
+    this.regionAttributes.regionTimeToLiveExpirationAction = timeToLive
+        .getAction();
+    this.regionAttributes.setHasRegionTimeToLive(true);
+  }
+
+  // DISTRIBUTION ATTRIBUTES
+
+  /**
+   * Sets the scope for the next <code>RegionAttributes</code> created.
+   * Default scope is DISTRIBUTED_NO_ACK. Refer gemfire documentation for more details on this.
+   * @param scopeType
+   *          the type of Scope to use for the region
+   * @throws IllegalArgumentException
+   *           if scopeType is null
+   */
+  public void setScope(Scope scopeType)
+  {
+    if (scopeType == null) {
+      throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_SCOPETYPE_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+    this.regionAttributes.setScope(scopeType);
+  }
+
+  // STORAGE ATTRIBUTES
+
+  /**
+   * Sets the EvictionController for the next <code>RegionAttributes</code>
+   * created. Use one of the creation methods on {@link EvictionAttributes} e.g.
+   * {@link EvictionAttributes#createLRUHeapAttributes()} to create the desired
+   * instance for this <code>AttributesFactory</code>
+   *
+   * @param evictAttrs
+   *          Explains how and when eviction occurs in the Region.
+   */
+   public void setEvictionAttributes(EvictionAttributes evictAttrs) {
+     if (evictAttrs != null) {
+       this.regionAttributes.evictionAttributes = (EvictionAttributesImpl) evictAttrs;
+     } else {
+       this.regionAttributes.evictionAttributes = new EvictionAttributesImpl();
+     }
+     this.regionAttributes.setHasEvictionAttributes(true);
+   }
+
+  /** Sets the mirror type for the next <code>RegionAttributes</code> created.
+   * @param mirrorType The type of mirroring to use for the region
+   * @throws IllegalArgumentException if mirrorType is null
+   * @deprecated use {@link #setDataPolicy} instead.
+   */
+  @Deprecated
+  public void setMirrorType(MirrorType mirrorType) {
+    if (mirrorType == null) {
+      throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_MIRRORTYPE_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+    DataPolicy dp = mirrorType.getDataPolicy();
+    if (dp.withReplication()) {
+      // requested a mirror type that has replication
+      // if current data policy is not replicated change it
+      if (!this.regionAttributes.getDataPolicy().withReplication()) {
+        setDataPolicy(dp);
+      }
+    } else {
+      // requested a mirror type none;
+      // if current data policy is replicated change it
+      if (this.regionAttributes.getDataPolicy().withReplication()) {
+        setDataPolicy(dp);
+      }
+    }
+  }
+  /** Sets the data policy for the next <code>RegionAttributes</code> created.
+   * Default data policy is 'Normal'. Please refer gemfire documentation for more details on this.
+   * @param dataPolicy The data policy to use for the region
+   * @throws IllegalArgumentException if dataPolicy is null
+   */
+  public void setDataPolicy(DataPolicy dataPolicy) {
+    if (dataPolicy == null) {
+      throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_DATAPOLICY_MUST_NOT_BE_NULL.toLocalizedString());
+    }
+    if (this.regionAttributes.partitionAttributes != null) {
+      if ( !PartitionedRegionHelper.ALLOWED_DATA_POLICIES.contains(dataPolicy) ) {
+        throw new IllegalStateException( LocalizedStrings.AttributesFactory_DATA_POLICIES_OTHER_THAN_0_ARE_NOT_SUPPORTED_FOR_PARTITIONED_REGIONS
+            .toLocalizedString(PartitionedRegionHelper.ALLOWED_DATA_POLICIES));
+      }
+    }
+    this.regionAttributes.setDataPolicy(dataPolicy);
+  }
+
+
+
+  /** Sets the key constraint for the next <code>RegionAttributes</code> created.
+   * Keys in the region will be constrained to this class (or subclass).
+   * Any attempt to store a key of an incompatible type in the region will
+   * cause a <code>ClassCastException</code> to be thrown.
+   * @param keyConstraint The Class to constrain the keys to, or null if no constraint
+   * @throws IllegalArgumentException if <code>keyConstraint</code> is a class
+   * denoting a primitive type
+   */
+  public void setKeyConstraint(Class<K> keyConstraint) {
+    if (keyConstraint != null && keyConstraint.isPrimitive())
+      throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_KEYCONSTRAINT_MUST_NOT_BE_A_PRIMITIVE_TYPE.toLocalizedString());
+    this.regionAttributes.keyConstraint = keyConstraint;
+    this.regionAttributes.setHasKeyConstraint(true);
+  }
+
+  /** Sets the value constraint for the next <code>RegionAttributes</code> created.
+   * Values in the region will be constrained to this class (or subclass).
+   * Any attempt to store a value of an incompatible type in the region will
+   * cause a <code>ClassCastException</code> to be thrown.
+   * @param valueConstraint The Class to constrain the values to, or null if no constraint
+   * @throws IllegalArgumentException if <code>valueConstraint</code> is a class
+   * denoting a primitive type
+   */
+  public void setValueConstraint(Class<V> valueConstraint) {
+    if (valueConstraint != null && valueConstraint.isPrimitive())
+      throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_VALUECONSTRAINT_MUST_NOT_BE_A_PRIMITIVE_TYPE.toLocalizedString());
+    this.regionAttributes.valueConstraint = valueConstraint;
+    this.regionAttributes.setHasValueConstraint(true);
+  }
+
+
+
+  // MAP ATTRIBUTES
+  /** Sets the entry initial capacity for the next <code>RegionAttributes</code>
+   * created. This value
+   * is used in initializing the map that holds the entries.
+   * Default is 16.
+   * @param initialCapacity the initial capacity of the entry map
+   * @throws IllegalArgumentException if initialCapacity is negative.
+   * @see java.util.HashMap
+   */
+  public void setInitialCapacity(int initialCapacity) {
+    if (initialCapacity < 0)
+        throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_INITIALCAPACITY_MUST_BE_0.toLocalizedString());
+    this.regionAttributes.initialCapacity = initialCapacity;
+    this.regionAttributes.setHasInitialCapacity(true);
+  }
+
+  /** Sets the entry load factor for the next <code>RegionAttributes</code>
+   * created. This value is
+   * used in initializing the map that holds the entries.
+   * Default is 0.75.
+   * @param loadFactor the load factor of the entry map
+   * @throws IllegalArgumentException if loadFactor is nonpositive
+   * @see java.util.HashMap
+   */
+  public void setLoadFactor(float loadFactor) {
+    if (loadFactor <= 0)
+        throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_LOADFACTOR_MUST_BE_0_VALUE_IS_0.toLocalizedString(new Float(loadFactor)));
+    this.regionAttributes.loadFactor = loadFactor;
+    this.regionAttributes.setHasLoadFactor(true);
+  }
+
+  /** Sets the concurrency level of the next <code>RegionAttributes</code>
+   * created. This value is used in initializing the map that holds the entries.
+   * Default is 16.
+   * @param concurrencyLevel the concurrency level of the entry map
+   * @throws IllegalArgumentException if concurrencyLevel is nonpositive
+   */
+  public void setConcurrencyLevel(int concurrencyLevel) {
+    if (concurrencyLevel <= 0)
+        throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_CONCURRENCYLEVEL_MUST_BE_0.toLocalizedString());
+    this.regionAttributes.concurrencyLevel = concurrencyLevel;
+    this.regionAttributes.setHasConcurrencyLevel(true);
+  }
+  
+  /**
+   * Enables or disabled concurrent modification checks.  Concurrency checks are enabled
+   * by default.
+   * @since 7.0
+   * @param concurrencyChecksEnabled whether to perform concurrency checks on operations
+   */
+  public void setConcurrencyChecksEnabled(boolean concurrencyChecksEnabled) {
+    this.regionAttributes.concurrencyChecksEnabled = concurrencyChecksEnabled;
+    this.regionAttributes.setHasConcurrencyChecksEnabled(true);
+  }
+
+  /**
+   * Sets whether or not a persistent backup should be made of the
+   * region.
+   *
+   * @since 3.2
+   * @deprecated as of GemFire 5.0, use {@link DataPolicy#PERSISTENT_REPLICATE} instead
+   */
+  @Deprecated
+  public void setPersistBackup(boolean persistBackup) {
+    if (persistBackup) {
+      if (!this.regionAttributes.getDataPolicy().withPersistence()) {
+        if (this.regionAttributes.getDataPolicy().withPartitioning()) {
+          setDataPolicy(DataPolicy.PERSISTENT_PARTITION);
+        } else {
+          setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
+        }
+      }
+    } else {
+      // It is less clear what we should do here for backwards compat.
+      // If the current data policy is persist then we need to change it
+      // otherwise just leave it alone
+      if (this.regionAttributes.getDataPolicy().withReplication()) {
+        setDataPolicy(DataPolicy.REPLICATE);
+      } else if (this.regionAttributes.getDataPolicy().withPartitioning()) {
+        setDataPolicy(DataPolicy.PARTITION);
+      }
+    }
+  }
+  /**
+   * Sets whether or not acks are sent after an operation is processed.
+   *
+   * @since 4.1
+   * @deprecated This setting no longer has any effect. 
+   */
+  @Deprecated
+  public void setEarlyAck(boolean earlyAck) {
+    this.regionAttributes.earlyAck = earlyAck;
+    this.regionAttributes.setHasEarlyAck(true);
+  }
+  
+  /**
+   * Sets whether or not this region should be considered a publisher.
+   *
+   * @since 4.2.3
+   * @deprecated as of 6.5
+   */
+  @Deprecated
+  public void setPublisher(boolean v) {
+//    this.regionAttributes.publisher = v;
+//    this.regionAttributes.setHasPublisher(true);
+  }
+
+  /**
+   * Sets whether or not conflation is enabled for sending messages
+   * to async peers.
+   * Default value is false.
+   *
+   * @since 4.2.3
+   */
+  public void setEnableAsyncConflation(boolean enableAsyncConflation) {
+    this.regionAttributes.enableAsyncConflation = enableAsyncConflation;
+    this.regionAttributes.setHasEnableAsyncConflation(true);
+  }
+  
+
+  /**
+   * Sets whether or not conflation is enabled for sending messages
+   * from a cache server to its clients.
+   * Default is false.
+   *
+   * @since 5.0
+   */
+  public void setEnableSubscriptionConflation(boolean enableSubscriptionConflation) {
+    this.regionAttributes.enableSubscriptionConflation = enableSubscriptionConflation;
+    this.regionAttributes.setHasEnableSubscriptionConflation(true);
+  }
+
+  /**
+   * adds a gateway sender to the end of list of gateway senders on this factory
+   * @param gatewaySenderId
+   * @throws IllegalArgumentException if <code>gatewaySender</code> is null
+   * @since 7.0
+   */
+  public void addGatewaySenderId(String gatewaySenderId) {
+    if (gatewaySenderId == null) {
+      throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_GATEWAY_SENDER_ID_IS_NULL.toLocalizedString());
+    }
+    synchronized (this.regionAttributes) {
+      this.regionAttributes.addGatewaySenderId(gatewaySenderId);
+    }
+  }
+  
+  /**
+   * Adds a AsyncEventQueue to the end of list of async event queues on this factory
+   * @param asyncEventQueueId
+   * @throws IllegalArgumentException if <code>gatewaySender</code> is null
+   * @since 7.0
+   */
+  public void addAsyncEventQueueId(String asyncEventQueueId) {
+    if (asyncEventQueueId == null) {
+      throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_GATEWAY_SENDER_ID_IS_NULL.toLocalizedString());
+    }
+    synchronized (this.regionAttributes) {
+      this.regionAttributes.addAsyncEventQueueId(asyncEventQueueId);
+    }
+  }
+  
+  /**
+   * Sets whether or not conflation is enabled for sending messages
+   * from a cache server to its clients.
+   *
+   * @since 5.0
+   * @deprecated as of 5.7 use {@link #setEnableSubscriptionConflation} instead.
+   */
+  @Deprecated
+  public void setEnableBridgeConflation(boolean enableBridgeConflation) {
+    setEnableSubscriptionConflation(enableBridgeConflation);
+  }
+
+  /**
+   * Sets whether or not conflation is enabled for sending messages
+   * from a cache server to its clients.
+   *
+   * @deprecated as of GemFire 5.0, use {@link #setEnableSubscriptionConflation}
+  */
+  @Deprecated
+  public void setEnableConflation(boolean enableBridgeConflation) {
+    setEnableSubscriptionConflation(enableBridgeConflation);
+  }
+
+  /**
+   * Returns whether or not disk writes are asynchronous.
+   *
+   * @see Region#writeToDisk
+   *
+   * @since 3.2
+   * @deprecated as of 6.5 use {@link #setDiskStoreName} instead
+   */
+  @Deprecated
+  public void setDiskWriteAttributes(DiskWriteAttributes attrs) {
+    if (this.regionAttributes.getDiskStoreName() != null) {
+      throw new IllegalStateException(LocalizedStrings.DiskStore_Deprecated_API_0_Cannot_Mix_With_DiskStore_1
+          .toLocalizedString(new Object[] {"setDiskWriteAttributes", this.regionAttributes.getDiskStoreName()}));
+    }
+    this.regionAttributes.diskWriteAttributes = attrs;
+    this.regionAttributes.setHasDiskWriteAttributes(true);
+    if (attrs != null) {
+      // keep new apis in sync with old
+      this.regionAttributes.diskSynchronous = attrs.isSynchronous();
+    }
+  }
+
+  /**
+   * Sets the directories with
+   * the default size of 10240 MB to which the region's data is written
+   *
+   * @throws IllegalArgumentException if a directory does not exist
+   *
+   * @since 3.2
+   * @deprecated as of 6.5 use {@link DiskStoreFactory#setDiskDirs} instead
+   */
+  @Deprecated
+  public void setDiskDirs(File[] diskDirs) {
+    if (this.regionAttributes.getDiskStoreName() != null) {
+      throw new IllegalStateException(LocalizedStrings.DiskStore_Deprecated_API_0_Cannot_Mix_With_DiskStore_1
+          .toLocalizedString(new Object[] {"setDiskDirs", this.regionAttributes.getDiskStoreName()}));
+    }
+    DiskStoreFactoryImpl.checkIfDirectoriesExist(diskDirs);
+    this.regionAttributes.diskDirs = diskDirs;
+    this.regionAttributes.diskSizes = new int[diskDirs.length];
+    for (int i=0; i < diskDirs.length; i++) {
+      this.regionAttributes.diskSizes[i] = DiskStoreFactory.DEFAULT_DISK_DIR_SIZE;
+    }
+    if (!this.regionAttributes.hasDiskWriteAttributes()
+        && !this.regionAttributes.hasDiskSynchronous()) {
+      // switch to the old default
+      this.regionAttributes.diskSynchronous = false;
+      this.regionAttributes.diskWriteAttributes = DiskWriteAttributesImpl.getDefaultAsyncInstance();
+    }
+    this.regionAttributes.setHasDiskDirs(true);
+  }
+
+  /**
+   * Sets the DiskStore name attribute.
+   * This causes the region to use the {@link DiskStore}.
+   * @param name the name of the diskstore
+   * @since 6.5 
+   */
+  public void setDiskStoreName(String name) {
+    if (this.regionAttributes.hasDiskDirs() ||  this.regionAttributes.hasDiskWriteAttributes()) {
+      throw new IllegalStateException(LocalizedStrings.DiskStore_Deprecated_API_0_Cannot_Mix_With_DiskStore_1
+          .toLocalizedString(new Object[] {"setDiskDirs or setDiskWriteAttributes", name}));
+    }
+    this.regionAttributes.diskStoreName = name;
+    this.regionAttributes.setHasDiskStoreName(true);
+  }
+  
+  /**
+   * Sets whether or not the writing to the disk is synchronous.
+   * Default is true.
+   * 
+   * @param isSynchronous
+   *          boolean if true indicates synchronous writes
+   * @since 6.5 
+   */
+  @SuppressWarnings("deprecation")
+  public void setDiskSynchronous(boolean isSynchronous)
+  {
+    this.regionAttributes.diskSynchronous = isSynchronous;
+    this.regionAttributes.setHasDiskSynchronous(true);
+    if (this.regionAttributes.hasDiskWriteAttributes()) {
+      DiskWriteAttributesFactory dwaf = new DiskWriteAttributesFactory(this.regionAttributes.diskWriteAttributes);
+      dwaf.setSynchronous(isSynchronous);
+      this.regionAttributes.diskWriteAttributes = dwaf.create();
+    } else {
+      if (isSynchronous) {
+        this.regionAttributes.diskWriteAttributes = DiskWriteAttributesImpl.getDefaultSyncInstance();
+      } else {
+        this.regionAttributes.diskWriteAttributes = DiskWriteAttributesImpl.getDefaultAsyncInstance();
+      }
+    }
+  }
+
+  /**
+   * Sets the directories to which the region's data is written and also set their sizes in megabytes
+   *
+   * @throws IllegalArgumentException if a dir does not exist or the length of the size array
+   * does not match to the length of the dir array or the given length is not a valid positive number
+   *
+   * @since 5.1
+   * @deprecated as of 6.5 use {@link DiskStoreFactory#setDiskDirsAndSizes} instead
+   */
+  @Deprecated
+  public void setDiskDirsAndSizes(File[] diskDirs,int[] diskSizes) {
+    if (this.regionAttributes.getDiskStoreName() != null) {
+      throw new IllegalStateException(LocalizedStrings.DiskStore_Deprecated_API_0_Cannot_Mix_With_DiskStore_1
+          .toLocalizedString(new Object[] {"setDiskDirsAndSizes", this.regionAttributes.getDiskStoreName()}));
+    }
+    DiskStoreFactoryImpl.checkIfDirectoriesExist(diskDirs);
+    this.regionAttributes.diskDirs = diskDirs;
+    if(diskSizes.length != this.regionAttributes.diskDirs.length) {
+      throw new IllegalArgumentException(LocalizedStrings.AttributesFactory_NUMBER_OF_DISKSIZES_IS_0_WHICH_IS_NOT_EQUAL_TO_NUMBER_OF_DISK_DIRS_WHICH_IS_1.toLocalizedString(new Object[] {Integer.valueOf(diskSizes.length), Integer.valueOf(diskDirs.length)}));
+    }
+    DiskStoreFactoryImpl.verifyNonNegativeDirSize(diskSizes);
+    this.regionAttributes.diskSizes = diskSizes;
+    if (!this.regionAttributes.hasDiskWriteAttributes()
+        && !this.regionAttributes.hasDiskSynchronous()) {
+      // switch to the old default
+      this.regionAttributes.diskSynchronous = false;
+      this.regionAttributes.diskWriteAttributes = DiskWriteAttributesImpl.getDefaultAsyncInstance();
+    }
+    this.regionAttributes.setHasDiskDirs(true);
+  }
+
+  /**
+   * Sets the <code>PartitionAttributes</code> that describe how the
+   * region is partitioned among members of the distributed system.  This
+   * also establishes a data policy of {@link DataPolicy#PARTITION PARTITION},
+   * if the data policy has not already been set.
+   *
+   * @since 5.0
+   */
+  public void setPartitionAttributes(PartitionAttributes partition) {
+    if (partition != null) {
+      if (! this.regionAttributes.hasDataPolicy()) { 
+          this.regionAttributes.dataPolicy = PartitionedRegionHelper.DEFAULT_DATA_POLICY;        
+      }
+      else if ( !PartitionedRegionHelper.ALLOWED_DATA_POLICIES.contains(this.regionAttributes.dataPolicy) ) {
+        throw new IllegalStateException(LocalizedStrings.AttributesFactory_DATA_POLICY_0_IS_NOT_ALLOWED_FOR_A_PARTITIONED_REGION_DATAPOLICIES_OTHER_THAN_1_ARE_NOT_ALLOWED
+            .toLocalizedString(new Object[] {this.regionAttributes.dataPolicy, PartitionedRegionHelper.ALLOWED_DATA_POLICIES}));
+      }
+      if (this.regionAttributes.hasPartitionAttributes() 
+          && this.regionAttributes.partitionAttributes instanceof PartitionAttributesImpl
+          && partition instanceof PartitionAttributesImpl) {
+        // Make a copy and call merge on it to prevent bug 51616
+        PartitionAttributesImpl copy = ((PartitionAttributesImpl) this.regionAttributes.partitionAttributes).copy();
+        copy.merge((PartitionAttributesImpl) partition);
+        this.regionAttributes.partitionAttributes = copy;
+      } else {
+        this.regionAttributes.partitionAttributes = partition;
+        this.regionAttributes.setHasPartitionAttributes(true);
+      }
+    }
+    else {
+      this.regionAttributes.partitionAttributes = null;
+      this.regionAttributes.setHasPartitionAttributes(false);
+    }
+  }
+
+  protected void setBucketRegion(boolean b) {
+    this.regionAttributes.isBucketRegion = b;
+  }   
+   
+  /**
+   * Sets the <code>MembershipAttributes</code> that describe the membership
+   * roles required for reliable access to the region.
+   *
+   * @since 5.0
+   */
+  public void setMembershipAttributes(MembershipAttributes membership) {
+    this.regionAttributes.membershipAttributes = membership;
+    this.regionAttributes.setHasMembershipAttributes(true);
+  }
+
+  /**
+   * Sets the <code>SubscriptionAttributes</code> that describe how the region
+   * will subscribe to other distributed cache instances of the region.
+   *
+   * @since 5.0
+   */
+  public void setSubscriptionAttributes(SubscriptionAttributes subscription) {
+    this.regionAttributes.subscriptionAttributes = subscription;
+    this.regionAttributes.setHasSubscriptionAttributes(true);
+  }
+
+  /**
+   * Set how indexes on the region should be maintained. It will be either synchronous
+   * or asynchronous.
+   * Default is true.
+   */
+  public void setIndexMaintenanceSynchronous(boolean synchronous) {
+    this.regionAttributes.indexMaintenanceSynchronous = synchronous;
+    this.regionAttributes.setHasIndexMaintenanceSynchronous(true);
+  }
+
+  // STATISTICS
+  /** Sets whether statistics are enabled for this region and its entries.
+   * Default is false.
+   * @param statisticsEnabled whether statistics are enabled
+   */
+  public void setStatisticsEnabled(boolean statisticsEnabled) {
+    this.regionAttributes.statisticsEnabled = statisticsEnabled;
+    this.regionAttributes.setHasStatisticsEnabled(true);
+  }
+
+  /**
+   * Sets the flag telling a region to ignore JTA transactions.
+   * Default is false.
+   * @since 5.0
+   */
+  public void setIgnoreJTA(boolean flag) {
+    this.regionAttributes.ignoreJTA = flag;
+    this.regionAttributes.setHasIgnoreJTA(true);
+  }
+
+  /** Sets whether this region should become lock grantor.
+   * Default value is false.
+   * @param isLockGrantor whether this region should become lock grantor
+   */
+  public void setLockGrantor(boolean isLockGrantor) {
+    this.regionAttributes.isLockGrantor = isLockGrantor;
+    this.regionAttributes.setHasIsLockGrantor(true);
+  }
+
+  /** Sets whether distributed operations on this region should attempt
+      to use multicast.  Multicast must also be enabled in the
+      cache's DistributedSystem (see
+      <a href=../distributed/DistributedSystem.html#mcast-port">"mcast-port"</a>).
+      Default is false.
+      @since 5.0
+      @see RegionAttributes#getMulticastEnabled
+   */
+  public void setMulticastEnabled(boolean value) {
+    this.regionAttributes.multicastEnabled = value;
+    this.regionAttributes.setHasMulticastEnabled(true);
+  }  
+  /**
+   * Sets cloning on region.
+   * Default is false.
+   * 
+   * @param cloningEnable
+   * @since 6.1
+   * @see RegionAttributes#getCloningEnabled()
+   */
+  public void setCloningEnabled(boolean cloningEnable) {
+    this.regionAttributes.isCloningEnabled = cloningEnable;
+    this.regionAttributes.setHasCloningEnabled(true);
+  }
+
+  
+  /**
+   * Sets the pool name attribute.
+   * This causes regions that use these attributes
+   * to be a client region which communicates with the
+   * servers that the connection pool communicates with.
+   * <p>If this attribute is set to <code>null</code> or <code>""</code>
+   * then the connection pool is disabled causing regions that use these attributes
+   * to be communicate with peers instead of servers.
+   * <p>The named connection pool must exist on the cache at the time these
+   * attributes are used to create a region. See {@link PoolManager#createFactory}
+   * for how to create a connection pool.
+   * @param name the name of the connection pool to use; if <code>null</code>
+   * or <code>""</code> then the connection pool is disabled for regions
+   * using these attributes.
+   * @throws IllegalStateException if a cache loader or cache writer has already
+   * been set.
+   * @since 5.7
+   */
+  public void setPoolName(String name) {
+    String nm = name;
+    if ("".equals(nm)) {
+      nm = null;
+    }
+    if (nm != null) {
+      // make sure a cache listener or writer has not already been installed
+      if (this.regionAttributes.getCacheLoader() != null 
+          && AbstractRegion.isBridgeLoader(this.regionAttributes.getCacheLoader())) {
+        throw new IllegalStateException("A region with a bridge loader can not have a pool name.");
+      }
+      if (this.regionAttributes.getCacheWriter() != null 
+          && AbstractRegion.isBridgeWriter(this.regionAttributes.getCacheWriter())) {
+        throw new IllegalStateException("A region with a bridge writer can not have a pool name.");
+      }
+    }
+    this.regionAttributes.poolName = nm;
+    this.regionAttributes.setHasPoolName(true);
+    
+  }
+  
+  /**
+   * Sets this region's compressor for compressing entry values.
+   * @since 8.0
+   * @param compressor a compressor.
+   */
+  public void setCompressor(Compressor compressor) {
+    this.regionAttributes.compressor = compressor;
+    this.regionAttributes.setHasCompressor(true);
+    
+    // Cloning must be enabled when a compressor is set
+    if (compressor != null) {
+      setCloningEnabled(true);
+    }
+  }
+
+  // FACTORY METHOD
+
+  /** Creates a <code>RegionAttributes</code> with the current settings.
+   * @return the newly created <code>RegionAttributes</code>
+   * @throws IllegalStateException if the current settings violate the
+   * <a href="#compatibility">compatibility rules</a>
+   * @deprecated as of GemFire 5.0, use {@link #create} instead
+   */
+  @Deprecated
+  public RegionAttributes<K,V> createRegionAttributes() {
+    return create();
+  }
+  /** Creates a <code>RegionAttributes</code> with the current settings.
+   * @return the newly created <code>RegionAttributes</code>
+   * @throws IllegalStateException if the current settings violate the
+   * <a href="#compatibility">compatibility rules</a>
+   * @since 5.0
+   */
+  @SuppressWarnings("unchecked")
+  public RegionAttributes<K,V> create() {
+    if (this.regionAttributes.hasDataPolicy() &&
+        this.regionAttributes.dataPolicy.withPartitioning() &&
+        this.regionAttributes.partitionAttributes == null) {
+      this.regionAttributes.partitionAttributes = (new PartitionAttributesFactory()).create();
+    }
+    // As of 6.5 we automatically enable stats if expiration is used.
+    {
+      RegionAttributesImpl attrs = this.regionAttributes;
+      if (!attrs.hasStatisticsEnabled() && !attrs.getStatisticsEnabled() &&
+          (attrs.getRegionTimeToLive().getTimeout() != 0 ||
+           attrs.getRegionIdleTimeout().getTimeout() != 0 ||
+           attrs.getEntryTimeToLive().getTimeout() != 0 ||
+           attrs.getEntryIdleTimeout().getTimeout() != 0 ||
+           attrs.getCustomEntryIdleTimeout() != null ||
+           attrs.getCustomEntryTimeToLive() != null)
+          ) {
+        // @todo we could do some more implementation work so that we would
+        // not need to enable stats unless entryIdleTimeout is enabled.
+        // We need the stats in that case because we need a new type of RegionEntry
+        // so we know that last time it was accessed. But for all the others we
+        // the stat less region keeps track of everything we need.
+        // The only problem is that some places in the code are conditionalized
+        // on statisticsEnabled.
+        setStatisticsEnabled(true);
+      }
+      // SQLFabric does not handle PRELOADED, so do not change the policy
+      if (attrs.getDataPolicy().withReplication()
+          && !attrs.getDataPolicy().withPersistence()
+          && attrs.getScope().isDistributed()
+          && !GemFireCacheImpl.sqlfSystem()) {
+        RegionAttributesImpl<?,?> rattr = attrs;
+        if (!rattr.isForBucketRegion()) {
+          if (attrs.getEvictionAttributes().getAction().isLocalDestroy()
+              || attrs.getEntryIdleTimeout().getAction().isLocal()
+              || attrs.getEntryTimeToLive().getAction().isLocal()
+              || attrs.getRegionIdleTimeout().getAction().isLocalInvalidate()
+              || attrs.getRegionTimeToLive().getAction().isLocalInvalidate()) {
+            // new to 6.5; switch to PRELOADED and interest ALL
+            setDataPolicy(DataPolicy.PRELOADED);
+            setSubscriptionAttributes(new SubscriptionAttributes(InterestPolicy.ALL));
+          }
+        }
+      }
+    }
+    validateAttributes(this.regionAttributes);
+    return (RegionAttributes<K,V>)this.regionAttributes.clone();
+  }
+
+  /**
+   * Validates that the attributes are consistent with each other.
+   * The following rules are checked and enforced:
+   <ul>
+   <li>If the data policy {@link DataPolicy#withReplication uses replication}
+       and the scope is {@link Scope#isDistributed distributed} then the
+       following are incompatible:
+      <ul>
+      <li>ExpirationAction.LOCAL_INVALIDATE on the region</li
+      <li>ExpirationAction.LOCAL_DESTROY on the entries</li>
+      <li>ExpirationAction.LOCAL_INVALIDATE on the entries</li>
+      <li>An LRU with local destroy eviction action</li>
+      </ul>
+   </li>
+   <li>Region or entry expiration
+      is incompatible with disabled statistics on the region</li>
+   <li>Entry expiration
+      is incompatible with the {@link DataPolicy#EMPTY} data policy</li>
+   <li>{@link EvictionAttributes Eviction}
+      is incompatible with the {@link DataPolicy#EMPTY} data policy</li>
+   </ul>
+   * @param attrs the attributes to validate
+   * @throws IllegalStateException if the attributes are not consistent with each other.
+   * @since 3.5
+   */
+  public static void validateAttributes(RegionAttributes<?, ?> attrs) {
+    // enforce the creation constraints
+
+    if (attrs.getDataPolicy().withReplication()
+        && attrs.getScope().isDistributed()) {
+      boolean isForBucketRegion = false; 
+      if (attrs instanceof RegionAttributesImpl) {
+        RegionAttributesImpl<?,?> regionAttributes = (RegionAttributesImpl<?,?>)attrs;
+        if (regionAttributes.isForBucketRegion()) {
+          isForBucketRegion = true;
+        }
+      }
+      if (!isForBucketRegion) {
+        ExpirationAction idleAction = attrs.getEntryIdleTimeout().getAction();
+        ExpirationAction ttlAction = attrs.getEntryTimeToLive().getAction();
+
+        if (idleAction == ExpirationAction.LOCAL_DESTROY
+            || ttlAction == ExpirationAction.LOCAL_DESTROY) {
+        throw new IllegalStateException(LocalizedStrings.AttributesFactory_EXPIRATIONACTIONLOCAL_DESTROY_ON_THE_ENTRIES_IS_INCOMPATIBLE_WITH_DISTRIBUTED_REPLICATION.toLocalizedString());
+        }
+
+        if (attrs.getEvictionAttributes().getAction().isLocalDestroy()) {
+          throw new IllegalStateException(LocalizedStrings.AttributesFactory_AN_EVICTION_CONTROLLER_WITH_LOCAL_DESTROY_EVICTION_ACTION_IS_INCOMPATIBLE_WITH_DISTRIBUTED_REPLICATION.toLocalizedString());
+        }
+
+        if (attrs.getRegionIdleTimeout().getAction() == ExpirationAction.LOCAL_INVALIDATE
+            || attrs.getRegionTimeToLive().getAction() == ExpirationAction.LOCAL_INVALIDATE) {
+          throw new IllegalStateException(LocalizedStrings.AttributesFactory_EXPIRATIONACTIONLOCAL_INVALIDATE_ON_THE_REGION_IS_INCOMPATIBLE_WITH_DISTRIBUTED_REPLICATION.toLocalizedString());
+        }
+
+        if (idleAction == ExpirationAction.LOCAL_INVALIDATE
+            || ttlAction == ExpirationAction.LOCAL_INVALIDATE) {
+        throw new IllegalStateException(LocalizedStrings.AttributesFactory_EXPIRATIONACTIONLOCAL_INVALIDATE_ON_THE_ENTRIES_IS_INCOMPATIBLE_WITH_DISTRIBUTED_REPLICATION.toLocalizedString());
+        }
+         //TODO: Is it possible to add this check while region is getting created
+//        for(String senderId : attrs.getGatewaySenderIds()){
+//          if(sender.isParallel()){
+//            throw new IllegalStateException(
+//                LocalizedStrings.AttributesFactory_PARALLELGATEWAYSENDER_0_IS_INCOMPATIBLE_WITH_DISTRIBUTED_REPLICATION
+//                    .toLocalizedString(sender));
+//          }
+//        }
+      }
+    }
+    
+    if (attrs.getDiskStoreName() != null) {
+      EvictionAttributes ea = attrs.getEvictionAttributes();
+      if (!attrs.getDataPolicy().withPersistence() && (ea != null && ea.getAction() != EvictionAction.OVERFLOW_TO_DISK)) {
+        throw new IllegalStateException(LocalizedStrings.DiskStore_IS_USED_IN_NONPERSISTENT_REGION.toLocalizedString());        
+      }
+    }
+
+    if (!attrs.getStatisticsEnabled() &&
+          (attrs.getRegionTimeToLive().getTimeout() != 0 ||
+           attrs.getRegionIdleTimeout().getTimeout() != 0 ||
+           attrs.getEntryTimeToLive().getTimeout() != 0 ||
+           attrs.getEntryIdleTimeout().getTimeout() != 0 ||
+           attrs.getCustomEntryIdleTimeout() != null ||
+           attrs.getCustomEntryTimeToLive() != null)
+           ) {
+      throw new IllegalStateException(LocalizedStrings.AttributesFactory_STATISTICS_MUST_BE_ENABLED_FOR_EXPIRATION.toLocalizedString());
+    }
+
+    if (attrs.getDataPolicy() == DataPolicy.EMPTY) {
+      if (attrs.getEntryTimeToLive().getTimeout() != 0 ||
+          attrs.getEntryIdleTimeout().getTimeout() != 0 ||
+          attrs.getCustomEntryTimeToLive() != null ||
+          attrs.getCustomEntryIdleTimeout() != null
+          ) {
+        throw new IllegalStateException(LocalizedStrings.AttributesFactory_IF_THE_DATA_POLICY_IS_0_THEN_ENTRY_EXPIRATION_IS_NOT_ALLOWED
+            .toLocalizedString(attrs.getDataPolicy()));
+      }
+      if (!attrs.getEvictionAttributes().getAlgorithm().isNone()) {
+        throw new IllegalStateException(LocalizedStrings.AttributesFactory_IF_THE_DATA_POLICY_IS_0_THEN_EVICTION_IS_NOT_ALLOWED
+            .toLocalizedString(attrs.getDataPolicy()));
+      }
+    }
+    if (attrs.getMembershipAttributes().hasRequiredRoles()) {
+      if (attrs.getScope().isLocal()) {
+        throw new IllegalStateException(LocalizedStrings.AttributesFactory_IF_THE_MEMBERSHIP_ATTRIBUTES_HAS_REQUIRED_ROLES_THEN_SCOPE_MUST_NOT_BE_LOCAL.toLocalizedString());
+      }
+    }
+    if (attrs.getPoolName() != null) {
+      if (attrs.getCacheLoader() != null && AbstractRegion.isBridgeLoader(attrs.getCacheLoader())) {
+        throw new IllegalStateException("A region with a pool name can not have a BridgeLoader or BridgeClient. Please use pools OR BridgeClient.");
+      }
+      if (attrs.getCacheWriter() != null && AbstractRegion.isBridgeWriter(attrs.getCacheWriter())) {
+        throw new IllegalStateException("A region with a pool name can not have a BridgeWriter or BridgeClient. Please use pools OR BridgeClient.");
+      }
+    }
+    
+    final PartitionAttributes pa = attrs.getPartitionAttributes();
+    // Validations for PartitionRegion Attributes
+    if (pa != null) {
+      ((PartitionAttributesImpl)pa).validateWhenAllAttributesAreSet(attrs instanceof RegionAttributesCreation);
+      ExpirationAttributes regionIdleTimeout = attrs.getRegionIdleTimeout();
+      ExpirationAttributes regionTimeToLive = attrs.getRegionTimeToLive();
+      if ((regionIdleTimeout.getAction().isInvalidate() && regionIdleTimeout.getTimeout() > 0)
+          || (regionIdleTimeout.getAction().isLocalInvalidate() && regionIdleTimeout.getTimeout() > 0)
+          || (regionTimeToLive.getAction().isInvalidate() && regionTimeToLive.getTimeout() > 0)
+          || (regionTimeToLive.getAction().isLocalInvalidate()) && regionTimeToLive.getTimeout() > 0 ) {
+        throw new IllegalStateException(
+            LocalizedStrings.AttributesFactory_INVALIDATE_REGION_NOT_SUPPORTED_FOR_PR.toLocalizedString());
+      }
+      
+      if ((regionIdleTimeout.getAction().isDestroy() && regionIdleTimeout.getTimeout() > 0)
+          || (regionIdleTimeout.getAction().isLocalDestroy() && regionIdleTimeout.getTimeout() > 0)
+          || (regionTimeToLive.getAction().isDestroy() && regionTimeToLive.getTimeout() > 0)
+          || (regionTimeToLive.getAction().isLocalDestroy() && regionTimeToLive.getTimeout() > 0)) {
+        throw new IllegalStateException(
+            LocalizedStrings.AttributesFactory_DESTROY_REGION_NOT_SUPPORTED_FOR_PR
+                .toLocalizedString());
+      }
+      
+      ExpirationAttributes entryIdleTimeout = attrs.getEntryIdleTimeout();
+      ExpirationAttributes entryTimeToLive = attrs.getEntryTimeToLive();
+      if ((entryIdleTimeout.getAction().isLocalDestroy() && entryIdleTimeout.getTimeout() > 0)
+          || (entryTimeToLive.getAction().isLocalDestroy() && entryTimeToLive.getTimeout() > 0)) {
+        throw new IllegalStateException(
+            LocalizedStrings.AttributesFactory_LOCAL_DESTROY_IS_NOT_SUPPORTED_FOR_PR.toLocalizedString());
+      }
+      if ((entryIdleTimeout.getAction().isLocalInvalidate() && entryIdleTimeout.getTimeout() > 0)
+          || (entryTimeToLive.getAction().isLocalInvalidate() && entryTimeToLive.getTimeout() > 0)) {
+        throw new IllegalStateException(
+            LocalizedStrings.AttributesFactory_LOCAL_INVALIDATE_IS_NOT_SUPPORTED_FOR_PR.toLocalizedString());
+      }
+
+      if (attrs instanceof UserSpecifiedRegionAttributes<?,?>) {
+        UserSpecifiedRegionAttributes<?,?> rac = (UserSpecifiedRegionAttributes<?,?>) attrs;
+        if (rac.hasScope()) {
+          throw new IllegalStateException(LocalizedStrings.AttributesFactory_SETTING_SCOPE_ON_A_PARTITIONED_REGIONS_IS_NOT_ALLOWED.toLocalizedString());
+        }
+      }
+      
+      if (attrs.getPoolName() != null) {
+        throw new IllegalStateException("Setting pool name on a Partitioned Region is not allowed");
+      }
+      
+//    if (attrs.getScope() == Scope.GLOBAL) {
+//    throw new IllegalStateException(
+//    "Global Scope is incompatible with Partitioned Regions");
+//  }
+//  if (attrs.getScope() == Scope.LOCAL) {
+//    throw new IllegalStateException(
+//        "Local Scope is incompatible with Partitioned Regions");
+//  }
+      if (pa.getTotalMaxMemory() <= 0) {
+        throw new IllegalStateException(LocalizedStrings.AttributesFactory_TOTAL_SIZE_OF_PARTITION_REGION_MUST_BE_0.toLocalizedString());
+      }
+// listeners are supported here as of v5.1
+//      if (attrs.getCacheListeners().length > 0) {
+//        throw new IllegalStateException(
+//            "Can not add cache listeners to RegionAttributes when PartitionAttributes are set.");
+//      }
+// loaders are supported here as of v5.1
+//      if (attrs.getCacheLoader() != null) {
+//        throw new IllegalStateException(
+//            "Can not set CacheLoader in RegionAttributes when PartitionAttributes are set.");
+//      }
+      if ( ! PartitionedRegionHelper.ALLOWED_DATA_POLICIES.contains(attrs.getDataPolicy())) {
+        throw new IllegalStateException(LocalizedStrings.AttributesFactory_DATA_POLICIES_OTHER_THAN_0_ARE_NOT_ALLOWED_IN_PARTITIONED_REGIONS
+            .toLocalizedString(PartitionedRegionHelper.ALLOWED_DATA_POLICIES));
+      }
+//      if ( attrs.getDataPolicy().isEmpty() && pa.getLocalMaxMemory() != 0) {
+//        throw new IllegalStateException(
+//            "A non-zero PartitionAttributes localMaxMemory setting is not compatible" +
+//            " with an empty DataPolicy.  Please use DataPolicy.NORMAL instead.");
+//      }
+      if (pa.getLocalMaxMemory() < 0) {
+        throw new IllegalStateException(LocalizedStrings.AttributesFactory_PARTITIONATTRIBUTES_LOCALMAXMEMORY_MUST_NOT_BE_NEGATIVE.toLocalizedString());
+      }
+      if (attrs.isLockGrantor() == true) {
+        throw new IllegalStateException(LocalizedStrings.AttributesFactory_SETLOCKGRANTERTRUE_IS_NOT_ALLOWED_IN_PARTITIONED_REGIONS.toLocalizedString());
+      }
+      if (pa.getLocalMaxMemory() == 0 && attrs.getDataPolicy() == DataPolicy.PERSISTENT_PARTITION) {
+        throw new IllegalStateException("Persistence is not allowed when local-max-memory is zero.");
+      }
+    }
+    
+    if (null != attrs.getCompressor() && !attrs.getCloningEnabled()) {
+      throw new IllegalStateException("Cloning cannot be disabled when a compressor is set.");
+    }
+  }
+
+
+  private static class RegionAttributesImpl<K,V>
+  extends UserSpecifiedRegionAttributes<K,V> implements Cloneable, Serializable {
+    public Set<String> gatewaySenderIds;
+    public Set<String>  asyncEventQueueIds;
+    private static final long serialVersionUID = -3663000883567530374L;
+
+    ArrayList<CacheListener<K,V>> cacheListeners;
+    CacheLoader<K,V> cacheLoader;
+    CacheWriter<K,V> cacheWriter;
+    int regionTimeToLive = 0;
+    ExpirationAction regionTimeToLiveExpirationAction = ExpirationAction.INVALIDATE;
+    int regionIdleTimeout = 0;
+    ExpirationAction regionIdleTimeoutExpirationAction = ExpirationAction.INVALIDATE;
+
+    int entryTimeToLive = 0;
+    ExpirationAction entryTimeToLiveExpirationAction = ExpirationAction.INVALIDATE;
+    CustomExpiry<K,V> customEntryTimeToLive = null;
+    int entryIdleTimeout = 0;
+    ExpirationAction entryIdleTimeoutExpirationAction = ExpirationAction.INVALIDATE;
+    CustomExpiry<K,V> customEntryIdleTimeout = null;
+
+    Scope scope = AbstractRegion.DEFAULT_SCOPE;
+    DataPolicy dataPolicy = DataPolicy.DEFAULT;
+    boolean statisticsEnabled = false;
+    boolean ignoreJTA = false;
+    boolean isLockGrantor = false;
+    Class<K> keyConstraint = null;
+    Class<V> valueConstraint = null;
+    int initialCapacity = 16;
+    float loadFactor = 0.75f;
+    int concurrencyLevel = 16;
+    boolean concurrencyChecksEnabled = true;
+    boolean earlyAck = false;
+    boolean publisher = false;
+    boolean enableAsyncConflation = false;
+    boolean enableSubscriptionConflation = false;
+    @SuppressWarnings("deprecation")
+    DiskWriteAttributes diskWriteAttributes = DiskWriteAttributesImpl.getDefaultSyncInstance();
+    File[] diskDirs = DiskStoreFactory.DEFAULT_DISK_DIRS;
+    int[] diskSizes = new int[] {DiskStoreFactory.DEFAULT_DISK_DIR_SIZE}; // 10* 1024 MB }
+    boolean indexMaintenanceSynchronous = true;
+    PartitionAttributes partitionAttributes = null; //new PartitionAttributes();
+    MembershipAttributes membershipAttributes = new MembershipAttributes();
+    SubscriptionAttributes subscriptionAttributes = new SubscriptionAttributes();
+    boolean multicastEnabled = false;
+    EvictionAttributesImpl evictionAttributes = new EvictionAttributesImpl();  // TODO need to determine the constructor
+    String poolName = null;
+    String diskStoreName = null;
+    boolean diskSynchronous = DEFAULT_DISK_SYNCHRONOUS;
+    protected boolean isBucketRegion = false;
+    private boolean isCloningEnabled = false;
+    Compressor compressor = null;
+    
+    /** Constructs an instance of <code>RegionAttributes</code> with default settings.
+     * @see AttributesFactory
+     */
+    public RegionAttributesImpl() {
+    }
+    @Override
+    public String toString() {
+      StringBuffer buf = new StringBuffer(1000);
+      buf
+        .append("RegionAttributes@").append(System.identityHashCode(this)).append(": ")
+        .append("scope=").append(scope)
+        .append("; earlyAck=").append(earlyAck)
+        .append("; publisher=").append(publisher)
+        .append("; partitionAttrs=").append(partitionAttributes)
+        .append("; membershipAttrs=").append(membershipAttributes)
+        .append("; subscriptionAttrs=").append(subscriptionAttributes)
+        .append("; regionTTL=").append(regionTimeToLive)
+        .append("; action=").append(regionTimeToLiveExpirationAction)
+        .append("; regionIdleTimeout=").append(regionIdleTimeout)
+        .append("; action=").append(regionIdleTimeoutExpirationAction)
+        .append("; TTL=").append(entryTimeToLive)
+        .append("; action=").append(entryTimeToLiveExpirationAction)
+        .append("; custom=").append(customEntryTimeToLive)
+        .append("; idleTimeout=").append(entryIdleTimeout)
+        .append("; action=").append(entryIdleTimeoutExpirationAction)
+        .append("; custom=").append(customEntryIdleTimeout)
+        .append("; dataPolicy=").append(dataPolicy)
+        .append("; statisticsEnabled=").append(statisticsEnabled)
+        .append("; ignoreJTA=").append(ignoreJTA)
+        .append("; isLockGrantor=").append(isLockGrantor)
+        .append("; keyConstraint=").append(keyConstraint)
+        .append("; valueConstraint=").append(valueConstraint)
+        .append("; initialCapacity=").append(initialCapacity)
+        .append("; loadFactor=").append(loadFactor)
+        .append("; concurrencyLevel=").append(concurrencyLevel)
+        .append("; concurrencyChecksEnabled=").append(concurrencyChecksEnabled)
+        .append("; enableAsyncConflation=").append(enableAsyncConflation)
+        .append("; enableSubscriptionConflation=").append(enableSubscriptionConflation)
+        .append("; isBucketRegion=").append(isBucketRegion) 
+        .append("; poolName=").append(poolName)
+        .append("; diskSynchronous=").append(diskSynchronous)
+        .append("; multicastEnabled=").append(multicastEnabled)
+        .append("; isCloningEnabled=").append(isCloningEnabled)
+        ;
+      if (hasDiskWriteAttributes() || hasDiskDirs()) {
+        buf.append("; diskAttrs=").append(diskWriteAttributes)
+          .append("; diskDirs=").append(Arrays.toString(diskDirs))
+          .append("; diskDirSizes=").append(Arrays.toString(diskSizes));
+      } else {
+        buf.append("; diskStoreName=").append(diskStoreName);
+      }
+      buf.append("; GatewaySenderIds=").append(gatewaySenderIds);
+      buf.append("; AsyncEventQueueIds=").append(asyncEventQueueIds);
+      buf.append("; compressor=").append(compressor == null ? null : compressor.getClass().getName());
+      return buf.toString();
+    }
+    public CacheLoader<K,V> getCacheLoader() {
+      return this.cacheLoader;
+    }
+    public CacheWriter<K,V> getCacheWriter() {
+      return this.cacheWriter;
+    }
+    public Class<K> getKeyConstraint() {
+      return this.keyConstraint;
+    }
+    public Class<V> getValueConstraint() {
+      return this.valueConstraint;
+    }
+    private boolean isForBucketRegion() {
+      return this.isBucketRegion;
+    } 
+    public ExpirationAttributes getRegionTimeToLive() {
+      return new ExpirationAttributes(
+      this.regionTimeToLive, this.regionTimeToLiveExpirationAction);
+    }
+    public ExpirationAttributes getRegionIdleTimeout() {
+      return new ExpirationAttributes(
+      this.regionIdleTimeout, this.regionIdleTimeoutExpirationAction);
+    }
+
+    public ExpirationAttributes getEntryTimeToLive() {
+      return new ExpirationAttributes(
+      this.entryTimeToLive, this.entryTimeToLiveExpirationAction);
+    }
+    public CustomExpiry<K,V> getCustomEntryTimeToLive() {
+      return this.customEntryTimeToLive;
+    }
+    public ExpirationAttributes getEntryIdleTimeout() {
+      return new ExpirationAttributes(
+      this.entryIdleTimeout, this.entryIdleTimeoutExpirationAction);
+    }
+    public CustomExpiry<K,V> getCustomEntryIdleTimeout() {
+      return this.customEntryIdleTimeout;
+    }
+
+    @SuppressWarnings("deprecation")
+    public MirrorType getMirrorType() {
+      if (this.dataPolicy.isNormal() || this.dataPolicy.isPreloaded()
+          || this.dataPolicy.isEmpty() || this.dataPolicy.withPartitioning()) {
+        return MirrorType.NONE;
+      } else if (this.dataPolicy.withReplication()) {
+        return MirrorType.KEYS_VALUES;
+      } else {
+        throw new IllegalStateException(LocalizedStrings.AttributesFactory_NO_MIRROR_TYPE_CORRESPONDS_TO_DATA_POLICY_0
+            .toLocalizedString(this.dataPolicy));
+      }
+    }
+    public DataPolicy getDataPolicy() {
+      return this.dataPolicy;
+    }
+    public void setDataPolicy(DataPolicy dp) {
+      this.dataPolicy = dp;
+      setHasDataPolicy(true);
+    }
+    
+    public Scope getScope() {
+      return this.scope;
+    }
+    public void setScope(Scope s) {
+      this.scope = s;
+      setHasScope(true);
+    }
+    private static final CacheListener<?,?>[] EMPTY_LISTENERS = new CacheListener[0];
+    @SuppressWarnings("unchecked")
+    public CacheListener<K,V>[] getCacheListeners() {
+      ArrayList<CacheListener<K,V>> listeners = this.cacheListeners;
+      if (listeners == null) {
+        return (CacheListener<K,V>[])EMPTY_LISTENERS;
+      } else {
+        synchronized (listeners) {
+          if (listeners.size() == 0) {
+            return (CacheListener<K,V>[])EMPTY_LISTENERS;
+          } else {
+            CacheListener<K,V>[] result = new CacheListener[listeners.size()];
+            listeners.toArray(result);
+            return result;
+          }
+        }
+      }
+    }
+    public CacheListener<K,V> getCacheListener() {
+      ArrayList<CacheListener<K,V>> listeners = this.cacheListeners;
+      if (listeners == null) {
+        return null;
+      }
+      synchronized (listeners) {
+        if (listeners.size() == 0) {
+          return null;
+        }
+        if (listeners.size() == 1) {
+          return this.cacheListeners.get(0);
+        }
+      }
+      throw new IllegalStateException(LocalizedStrings.AttributesFactory_MORE_THAN_ONE_CACHE_LISTENER_EXISTS.toLocalizedString());
+    }
+    protected void addCacheListener(CacheListener<K,V> aListener) {
+      ArrayList<CacheListener<K,V>> listeners = this.cacheListeners;
+      if (listeners == null) {
+        ArrayList<CacheListener<K,V>> al = new ArrayList<CacheListener<K,V>>(1);
+        al.add(aListener);
+        this.cacheListeners = al;
+      } else {
+        synchronized (listeners) {
+          listeners.add(aListener);
+        }
+      }
+      setHasCacheListeners(true);
+    }
+    
+    public void addGatewaySenderId(String gatewaySenderId) {
+      if(this.gatewaySenderIds == null){
+        this.gatewaySenderIds = new CopyOnWriteArraySet<String>();
+        this.gatewaySenderIds.add(gatewaySenderId);
+      }else{
+        synchronized (this.gatewaySenderIds) { // TODO: revisit this
+          // synchronization : added as per
+          // above code
+          if (this.gatewaySenderIds.contains(gatewaySenderId)) {
+            throw new IllegalArgumentException(
+                LocalizedStrings.AttributesFactory_GATEWAY_SENDER_ID_0_IS_ALREADY_ADDED
+                .toLocalizedString(gatewaySenderId));
+          }
+          this.gatewaySenderIds.add(gatewaySenderId);
+        }
+      }
+      setHasGatewaySenderIds(true);
+    }
+    
+    public void addAsyncEventQueueId(String asyncEventQueueId) {
+      if(this.asyncEventQueueIds == null){
+        this.asyncEventQueueIds = new CopyOnWriteArraySet<String>();
+        this.asyncEventQueueIds.add(asyncEventQueueId);
+      } else{
+        synchronized (this.asyncEventQueueIds) { // TODO: revisit this
+          // synchronization : added as per
+          // above code
+          if (this.asyncEventQueueIds.contains(asyncEventQueueId)) {
+            throw new IllegalArgumentException(
+                LocalizedStrings.AttributesFactory_ASYNC_EVENT_QUEUE_ID_0_IS_ALREADY_ADDED
+                .toLocalizedString(asyncEventQueueId));
+          }
+          this.asyncEventQueueIds.add(asyncEventQueueId);
+        }
+      }
+      setHasAsyncEventListeners(true);
+    }
+    
+    public int getInitialCapacity() {
+      return this.initialCapacity;
+    }
+    public float getLoadFactor() {
+      return this.loadFactor;
+    }
+    public boolean getStatisticsEnabled() {
+      return this.statisticsEnabled;
+    }
+    public boolean getIgnoreJTA() {
+      return this.ignoreJTA;
+    }
+    public boolean isLockGrantor() {
+      return this.isLockGrantor;
+    }
+    public int getConcurrencyLevel() {
+      return this.concurrencyLevel;
+    }
+    public boolean getConcurrencyChecksEnabled() {
+      return this.concurrencyChecksEnabled;
+    }
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Override
+    public Object clone() {
+      try {
+        RegionAttributesImpl<K,V> copy = (RegionAttributesImpl<K,V>) super.clone();
+        if (copy.getIndexes() != null) {
+          copy.setIndexes(new ArrayList(copy.getIndexes()));
+        }
+        if (copy.partitionAttributes != null) {
+          copy.partitionAttributes = ((PartitionAttributesImpl)copy.partitionAttributes).copy();
+        }
+        if (copy.cacheListeners != null) {
+          copy.cacheListeners = new ArrayList<CacheListener<K,V>>(copy.cacheListeners);
+        }
+        if (copy.gatewaySenderIds != null) {
+          copy.gatewaySenderIds =  new CopyOnWriteArraySet<String>(copy.gatewaySenderIds);
+        }
+        if (copy.asyncEventQueueIds != null) {
+          copy.asyncEventQueueIds = new CopyOnWriteArraySet<String>(copy.asyncEventQueueIds);
+        }
+        return copy;
+      }
+      catch (CloneNotSupportedException e) {
+        throw new InternalError(LocalizedStrings.AttributesFactory_CLONENOTSUPPORTEDEXCEPTION_THROWN_IN_CLASS_THAT_IMPLEMENTS_CLONEABLE.toLocalizedString());
+      }
+    }
+
+    public boolean getPersistBackup() {
+      return getDataPolicy().withPersistence();
+    }
+
+    public boolean getEarlyAck() {
+      return this.earlyAck;
+    }
+
+    /*
+     * @deprecated as of 6.5
+     */
+    @Deprecated
+    public boolean getPublisher() {
+      return this.publisher;
+    }
+
+    public boolean getEnableConflation() { // deprecated in 5.0
+      return getEnableSubscriptionConflation();
+    }
+
+    public boolean getEnableAsyncConflation() {
+      return this.enableAsyncConflation;
+    }
+
+    public boolean getEnableBridgeConflation() { // deprecated in 5.7
+      return getEnableSubscriptionConflation();
+    }
+
+    public boolean getEnableSubscriptionConflation() {
+      return this.enableSubscriptionConflation;
+    }
+    
+    /**
+     * @deprecated as of 6.5
+     */
+    @Deprecated
+    public DiskWriteAttributes getDiskWriteAttributes() {
+      if (this.diskStoreName != null) {
+        throw new IllegalStateException(LocalizedStrings.DiskStore_Deprecated_API_0_Cannot_Mix_With_DiskStore_1
+            .toLocalizedString(new Object[] {"getDiskWriteAttributes", this.diskStoreName}));
+      }
+      return this.diskWriteAttributes;
+    }
+
+    /**
+     * @deprecated as of 6.5
+     */
+    @Deprecated
+    public File[] getDiskDirs() {
+      if (this.diskStoreName != null) {
+        throw new IllegalStateException(LocalizedStrings.DiskStore_Deprecated_API_0_Cannot_Mix_With_DiskStore_1
+            .toLocalizedString(new Object[] {"getDiskDirs", this.diskStoreName}));
+      }
+      return this.diskDirs;
+    }
+
+    public boolean getIndexMaintenanceSynchronous() {
+      return this.indexMaintenanceSynchronous;
+    }
+
+    public PartitionAttributes getPartitionAttributes() {
+      return this.partitionAttributes;
+    }
+    public EvictionAttributes getEvictionAttributes()
+    {
+      return this.evictionAttributes;
+    }
+    public MembershipAttributes getMembershipAttributes() {
+      retur

<TRUNCATED>

[26/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesMutator.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesMutator.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesMutator.java
new file mode 100644
index 0000000..e5bfdb1
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesMutator.java
@@ -0,0 +1,194 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+
+/**
+ * Supports modification of certain region attributes after the region has been
+ * created. It is recommended that the attributes be completely initialized
+ * using an {@link AttributesFactory} before creating the region instead of
+ * using an <code>AttributesMutator</code> after region creation. This will
+ * avoid a potential performance penalty due to the additional
+ * network traffic.
+ *<p>
+ * The setter methods all return the previous value of the attribute. 
+ *
+ * @author Eric Zoerner
+ *
+ *
+ * @see Region#getAttributesMutator
+ * @see RegionAttributes
+ * @see AttributesFactory
+ * @since 3.0
+ */
+public interface AttributesMutator<K,V> {
+  
+  /** Returns the Region whose attributes this mutator affects.
+   * @return the Region this mutator affects
+   */
+  public Region<K,V> getRegion();
+  
+  /** Changes the timeToLive expiration attributes for the region as a whole
+   *
+   * @param timeToLive the expiration attributes for the region timeToLive
+   * @return the previous value of region timeToLive
+   * @throws IllegalArgumentException if timeToLive is null or if the
+   * ExpirationAction is LOCAL_INVALIDATE and the region is
+   * {@link DataPolicy#withReplication replicated}
+   * @throws IllegalStateException if statistics are disabled for this region.
+   */
+  public ExpirationAttributes setRegionTimeToLive(ExpirationAttributes timeToLive);
+  
+  /** Changes the idleTimeout expiration attributes for the region as a whole.
+   * Resets the {@link CacheStatistics#getLastAccessedTime} for the region.
+   *
+   * @param idleTimeout the ExpirationAttributes for this region idleTimeout
+   * @return the previous value of region idleTimeout
+   * @throws IllegalArgumentException if idleTimeout is null or if the
+   * ExpirationAction is LOCAL_INVALIDATE and the region is
+   * {@link DataPolicy#withReplication replicated}
+   * @throws IllegalStateException if statistics are disabled for this region.
+   */
+  public ExpirationAttributes setRegionIdleTimeout(ExpirationAttributes idleTimeout);
+    
+  /** Changes the timeToLive expiration attributes for values in this region.
+   *
+   * @param timeToLive the timeToLive expiration attributes for entries
+   * @return the previous value of entry timeToLive
+   * @throws IllegalArgumentException if timeToLive is null or if the
+   * ExpirationAction is LOCAL_DESTROY and the region is {@link DataPolicy#withReplication replicated} or if 
+   * the ExpirationAction is LOCAL_INVALIDATE and the region is 
+   * {@link DataPolicy#withReplication replicated}
+   * @throws IllegalStateException if statistics are disabled for this region.
+   */
+  public ExpirationAttributes setEntryTimeToLive(ExpirationAttributes timeToLive);
+  
+  /**
+   * Changes the custom timeToLive for values in this region
+   * @param custom the new CustomExpiry
+   * @return the old CustomExpiry
+   */
+  public CustomExpiry<K,V> setCustomEntryTimeToLive(CustomExpiry<K,V> custom);
+  
+  /** Changes the idleTimeout expiration attributes for values in the region.
+   *
+   * @param idleTimeout the idleTimeout expiration attributes for entries
+   * @return the previous value of entry idleTimeout
+   * @throws IllegalArgumentException if idleTimeout is null or if the
+   * ExpirationAction is LOCAL_DESTROY and the region is
+   * {@link DataPolicy#withReplication replicated}
+   * or if the the ExpirationAction is LOCAL_INVALIDATE and the region is 
+   * {@link DataPolicy#withReplication replicated}
+   * @see AttributesFactory#setStatisticsEnabled
+   * @throws IllegalStateException if statistics are disabled for this region.
+   */
+  public ExpirationAttributes setEntryIdleTimeout(ExpirationAttributes idleTimeout);
+  
+  /** Changes the CustomExpiry for idleTimeout for values in the region
+   * 
+   * @param custom the new CustomExpiry
+   * @return the old CustomExpiry
+   */
+  public CustomExpiry<K,V> setCustomEntryIdleTimeout(CustomExpiry<K,V> custom);
+  
+  /** Changes the CacheListener for the region.
+   * Removes listeners already added and calls {@link CacheCallback#close} on each of them.
+   * @param aListener a user defined cache listener
+   * @return the previous CacheListener if a single one exists; otherwise null.
+   * @throws IllegalStateException if more than one cache listener has already been added
+   * @deprecated as of GemFire 5.0, use {@link #addCacheListener} or {@link #initCacheListeners} instead.
+   */
+  @Deprecated
+  public CacheListener<K,V> setCacheListener(CacheListener<K,V> aListener);
+  /**
+   * Adds a cache listener to the end of the list of cache listeners on this region.
+   * @param aListener the user defined cache listener to add to the region.
+   * @throws IllegalArgumentException if <code>aListener</code> is null
+   * @since 5.0
+   */
+  public void addCacheListener(CacheListener<K,V> aListener);
+  /**
+   * Removes a cache listener from the list of cache listeners on this region.
+   * Does nothing if the specified listener has not been added.
+   * If the specified listener has been added then {@link CacheCallback#close} will
+   * be called on it; otherwise does nothing.
+   * @param aListener the cache listener to remove from the region.
+   * @throws IllegalArgumentException if <code>aListener</code> is null
+   * @since 5.0
+   */
+  public void removeCacheListener(CacheListener<K,V> aListener);
+  /**
+   * Removes all cache listeners, calling {@link CacheCallback#close} on each of them, and then adds each listener in the specified array.
+   * @param newListeners a possibly null or empty array of listeners to add to this region.
+   * @throws IllegalArgumentException if the <code>newListeners</code> array has a null element
+   * @since 5.0
+   */
+  public void initCacheListeners(CacheListener<K,V>[] newListeners);
+  
+  /** Changes the cache writer for the region.
+   * @param cacheWriter the cache writer
+   * @return the previous CacheWriter
+   */
+  public CacheWriter<K,V> setCacheWriter(CacheWriter<K,V> cacheWriter);
+  
+  /** Changes the cache loader for the region.
+   * @param cacheLoader the cache loader
+   * @return the previous CacheLoader
+   */
+  public CacheLoader<K,V> setCacheLoader(CacheLoader<K,V> cacheLoader);
+  
+
+  /** Allows changing the eviction controller attributes for the region.
+   * 
+   * @return the {@link EvictionAttributesMutator} used to change the EvictionAttributes
+   */
+  public EvictionAttributesMutator getEvictionAttributesMutator();
+  
+  /**
+   * Sets cloning on region
+   * @param cloningEnable
+   * @since 6.1
+   */
+  public void setCloningEnabled(boolean cloningEnable);
+  /**
+   * Returns whether or not cloning is enabled on region
+   *
+   * @return True if cloning is enabled (default);
+   *         false cloning is not enabled.
+   *
+   * @since 6.1
+   */
+  public boolean getCloningEnabled();
+  
+  /**
+   * Adds GatewaySenderId to the list of GatewaySenderIds of the region.
+   * If the GatewaySenderId is not present on this VM then it will try to send it to other VM's
+   * 
+   * @param gatewaySenderId
+   */
+   public void addGatewaySenderId(String gatewaySenderId);
+   
+   /**
+    * Removes GatewaySenderId from the list of GatewaySenderIds of the region.
+    * @param gatewaySenderId 
+    */
+   public void removeGatewaySenderId(String gatewaySenderId);
+   
+   /**
+    * Adds AsyncEventQueueId to the list of AsyncEventQueueId of the region.
+    * @param asyncEventQueueId 
+    */
+   public void addAsyncEventQueueId(String asyncEventQueueId);
+   
+   /**
+    * Removes AsyncEventQueueId from the list of AsyncEventQueuesId of the region.
+    * @param asyncEventQueueId 
+    */
+   public void removeAsyncEventQueueId(String asyncEventQueueId);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Cache.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Cache.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Cache.java
new file mode 100644
index 0000000..4389fda
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/Cache.java
@@ -0,0 +1,474 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueue;
+import com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueueFactory;
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.client.Pool;
+import com.gemstone.gemfire.cache.server.CacheServer;
+import com.gemstone.gemfire.cache.snapshot.CacheSnapshotService;
+import com.gemstone.gemfire.cache.util.BridgeServer;
+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.distributed.DistributedMember;
+import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.i18n.LogWriterI18n;
+
+
+/** 
+ * Caches are obtained from the {@link CacheFactory#create()} method.
+ * See {@link CacheFactory} for common usage patterns for creating the cache instance.
+ * <p>
+ * When a cache is created a {@link DistributedSystem} is also created.
+ * This system tells the cache where to find other caches on the network
+ * and how to communicate with them.
+ * The system can also specify a
+ * <a href="../distribution/DistributedSystem.html#cache-xml-file">"cache-xml-file"</a>
+ * property which will cause this cache to be initialized with the contents
+ * of that file. The contents must comply with the
+ * <code>"doc-files/cache8_0.dtd"</code> file
+ * and the top level element must be a <code>cache</code> element.
+ * <p>
+ * When a cache will no longer be used it should be {@link #close() closed}.
+ * Once it {@link #isClosed is closed} any attempt to use it or any {@link Region}
+ * obtained from it will cause a {@link CacheClosedException} to be thrown.
+ *
+ * <p>A cache can have multiple root regions, each with a different name.
+ *
+ * @author Darrel Schneider
+ *
+ * @since 2.0
+ */
+@SuppressWarnings("deprecation")
+public interface Cache extends GemFireCache {
+  /**
+   * Terminates this object cache and releases all the resources.
+   * Calls {@link Region#close} on each region in the cache.
+   * After this cache is closed, any further
+   * method call on this cache or any region object will throw
+   * {@link CacheClosedException}, unless otherwise noted.
+   * @param keepalive whether the server should keep the durable client's queues alive for the timeout period
+   * @throws CacheClosedException if the cache is already closed.
+   * @deprecated as of 6.5 use {@link ClientCache#close(boolean)} instead.
+   */
+  @Deprecated
+  public void close(boolean keepalive);  
+  
+  /**
+   * Creates a VM region using the specified
+   * RegionAttributes.
+   *
+   * @param name the name of the region to create
+   * @param aRegionAttributes the attributes of the root region
+   * @return the region object
+   * @throws RegionExistsException if a region is already in
+   * this cache
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out getting distributed lock for Scope.GLOBAL
+   * @throws CacheClosedException if the cache is closed
+   * @throws IllegalStateException If the supplied RegionAttributes violate the
+   *         <a href="AttributesFactory.html#creationConstraints">region creation constraints</a>
+   *         with a region of the same name in another cache in the distributed system
+   * @deprecated as of GemFire 5.0, use {@link #createRegion} instead.
+   */
+  @Deprecated
+  public <K,V> Region<K,V> createVMRegion(String name, RegionAttributes<K,V> aRegionAttributes)
+  throws RegionExistsException, TimeoutException;
+
+  /**
+   * Creates a region using the specified RegionAttributes.
+   *
+   * @param name the name of the region to create
+   * @param aRegionAttributes the attributes of the root region
+   * @return the region object
+   * @throws RegionExistsException if a region is already in this cache
+   * @throws com.gemstone.gemfire.distributed.LeaseExpiredException if lease expired on distributed lock for Scope.GLOBAL
+   * @throws TimeoutException if timed out getting distributed lock for Scope.GLOBAL
+   * @throws CacheClosedException if the cache is closed
+   * @throws IllegalStateException If the supplied RegionAttributes violate the
+   *         <a href="AttributesFactory.html#creationConstraints">region creation constraints</a>
+   *         with a region of the same name in another cache in the distributed system
+   * @since 5.0
+   * @deprecated as of 6.5 use {@link #createRegionFactory(RegionAttributes)} instead
+   */
+  @Deprecated
+  public <K,V> Region<K,V> createRegion(String name, RegionAttributes<K,V> aRegionAttributes)
+    throws RegionExistsException, TimeoutException;
+
+  /**
+   * Creates a {@link RegionFactory} which can be used to specify additional
+   * attributes for {@link Region} creation.
+   * @see #createRegionFactory(RegionShortcut)
+   * @since 6.5
+   */
+  public <K,V> RegionFactory<K,V> createRegionFactory();
+  
+  /**
+   * Creates a {@link RegionFactory} for the most commonly used {@link Region} types
+   * defined by {@link RegionShortcut}
+   * @since 6.5
+   */
+  public <K,V> RegionFactory<K,V> createRegionFactory(RegionShortcut atts);
+  
+  /**
+   * Creates a {@link RegionFactory} for creating a {@link Region} from
+   * {@link RegionAttributes} mapped to this regionAttributesId
+   * @param regionAttributesId the Id of RegionAttributes to be used
+   * @see #setRegionAttributes(String, RegionAttributes)
+   * @since 6.5
+   */
+  public <K,V> RegionFactory<K,V> createRegionFactory(String regionAttributesId);
+  
+  /**
+   * Creates a {@link RegionFactory} for creating a {@link Region} from
+   * the given regionAttributes
+   * @param regionAttributes regionAttributes for the new region
+   * @see #createRegionFactory(RegionShortcut)
+   * @since 6.5
+   */
+  public <K,V> RegionFactory<K,V> createRegionFactory(RegionAttributes<K,V> regionAttributes);
+  
+  /**
+   * Internal GemStone method for accessing the internationalized 
+   * logging object for GemFire, use {@link #getLogger()} instead.
+   * This method does not throw
+   * <code>CacheClosedException</code> if the cache is closed.
+   * @return the logging object
+   * @deprecated as of 6.5 use getLogger().convertToLogWriterI18n() instead
+   */
+  @Deprecated
+  public LogWriterI18n getLoggerI18n();
+  
+  /**
+   * Internal GemStone method for accessing the internationalized 
+   * logging object for GemFire, use {@link #getSecurityLogger()} instead.
+   * This method does not throw
+   * <code>CacheClosedException</code> if the cache is closed.
+   * @return the security logging object
+   * @deprecated as of 6.5 use getSecurityLogger().convertToLogWriterI18n() instead
+   */
+  @Deprecated
+  public LogWriterI18n getSecurityLoggerI18n();
+  
+  /**
+   * Gets the number of seconds a cache operation will wait to obtain
+   * a distributed lock lease.
+   * This method does not throw
+   * <code>CacheClosedException</code> if the cache is closed.
+   */
+  public int getLockTimeout();
+  /**
+   * Sets the number of seconds a cache operation may wait to obtain a
+   * distributed lock lease before timing out.
+   *
+   * @throws IllegalArgumentException if <code>seconds</code> is less than zero
+   */
+  public void setLockTimeout(int seconds);
+
+  /**
+   * Gets the frequency (in seconds) at which a message will be sent by the
+   * primary cache-server to all the secondary cache-server nodes to remove the
+   * events which have already been dispatched from the queue.
+   * 
+   * @return The time interval in seconds
+   */
+  public int getMessageSyncInterval();
+
+  /**
+   * 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.
+   * 
+   * @param seconds -
+   *          the time interval in seconds
+   * @throws IllegalArgumentException
+   *           if <code>seconds</code> is less than zero
+   */
+  public void setMessageSyncInterval(int seconds);
+  
+  /**
+   * Gets the length, in seconds, of distributed lock leases obtained
+   * by this cache.
+   * This method does not throw
+   * <code>CacheClosedException</code> if the cache is closed.
+   */
+  public int getLockLease();
+  /**
+   * Sets the length, in seconds, of distributed lock leases obtained
+   * by this cache.
+   *
+   * @throws IllegalArgumentException if <code>seconds</code> is less than zero.
+   */
+  public void setLockLease(int seconds);
+  
+  /**
+   * Gets the number of seconds a cache
+   * {@link com.gemstone.gemfire.cache.Region#get(Object) get} operation
+   * can spend searching for a value before it times out.
+   * The search includes any time spent loading the object.
+   * When the search times out it causes the get to fail by throwing
+   * an exception.
+   * This method does not throw
+   * <code>CacheClosedException</code> if the cache is closed.
+   */
+  public int getSearchTimeout();
+  /**
+   * Sets the number of seconds a cache get operation can spend searching
+   * for a value.
+   *
+   * @throws IllegalArgumentException if <code>seconds</code> is less than zero
+   */
+  public void setSearchTimeout(int seconds);
+
+  /**
+   * Creates a new bridge server with the default configuration.
+   *
+   * @see com.gemstone.gemfire.cache.util.BridgeLoader
+   * @see com.gemstone.gemfire.cache.util.BridgeWriter
+   *
+   * @since 4.0
+   * @deprecated as of 5.7 use {@link #addCacheServer} instead.
+   */
+  @Deprecated
+  public BridgeServer addBridgeServer();
+
+  /**
+   * Creates a new cache server, with the default configuration,
+   * that will allow clients to access this cache.
+   * <p>For the default configuration see the constants in
+   * {@link com.gemstone.gemfire.cache.server.CacheServer}.
+   * @see com.gemstone.gemfire.cache.server
+   *
+   * @since 5.7
+   */
+  public CacheServer addCacheServer();
+
+  /**
+   * Returns a collection of all of the <code>BridgeServer</code>s
+   * that can serve the contents of this <code>Cache</code>.
+   * <p>Since <code>5.7</code> this method returns a <code>List</code
+   * instead of a <code>Collection</code>.
+   *
+   * @see #addBridgeServer
+   *
+   * @since 4.0
+   * @deprecated as of 5.7 use {@link #getCacheServers} instead.
+   */
+  @Deprecated
+  public List<CacheServer> getBridgeServers();
+
+  /**
+   * Returns a collection of all of the <code>CacheServer</code>s
+   * that can serve the contents of this <code>Cache</code> to clients.
+   *
+   * @see #addCacheServer
+   *
+   * @since 5.7
+   */
+  public List<CacheServer> getCacheServers();
+  
+  /**
+   * Adds a gateway event conflict resolution resolver.  This is invoked
+   * if an event is processed that comes from a different distributed system
+   * than the last event to modify the affected entry.  It may alter
+   * the event or disallow the event.  If it does neither the event is applied
+   * to the cache if its timestamp is newer than what is in the cache or if
+   * it is the same and the event's distributed system ID is larger than that
+   * of the last event to modify the affected entry.
+   * @param resolver
+   * @since 7.0
+   */
+  public void setGatewayConflictResolver(GatewayConflictResolver resolver);
+  
+  /**
+   * Returns the current gateway event conflict resolver
+   * @since 7.0
+   */
+  public GatewayConflictResolver getGatewayConflictResolver();
+  
+  /**
+   * Sets whether or not this <code>Cache</code> resides in a
+   * long-running "cache server" VM.  A cache server may be an
+   * application VM or may be a stand-along VM launched using {@linkplain
+   * com.gemstone.gemfire.admin.AdminDistributedSystem#addCacheServer
+   * administration API} or the <code>cacheserver</code> command line
+   * utility.
+   *
+   * @since 4.0
+   */
+  public void setIsServer(boolean isServer);
+
+  /**
+   * Returns whether or not this cache resides in a "cache server" VM.
+   *
+   * @see #setIsServer
+   *
+   * @since 4.0
+   */
+  public boolean isServer();
+
+  /**
+   * Notifies the server that this client is ready to receive updates.
+   * This method is used by durable clients to notify servers that they
+   * are ready to receive updates. As soon as the server receives this message, 
+   * it will forward updates to this client (if necessary).
+   * <p>
+   * Durable clients must call this method after they are done creating regions.
+   * If it is called before the client creates the regions then updates will be lost.
+   * Any time a new {@link Pool} is created and regions have been added to it then
+   * this method needs to be called again.
+   * <p>
+   *
+   * @throws IllegalStateException if called by a non-durable client
+   *
+   * @since 5.5
+   * @deprecated as of 6.5 use {@link ClientCache#readyForEvents} instead.
+   */
+  @Deprecated
+  public void readyForEvents();
+
+  /**
+   * Creates {@link GatewaySenderFactory} for creating a
+   * SerialGatewaySender
+   * 
+   * @return SerialGatewaySenderFactory
+   * @since 7.0
+   */
+  public GatewaySenderFactory createGatewaySenderFactory();
+
+  /**
+   * Creates {@link AsyncEventQueueFactory} for creating a
+   * AsyncEventQueue
+   * 
+   * @return AsyncEventQueueFactory
+   * @since 7.0
+   */
+  public AsyncEventQueueFactory createAsyncEventQueueFactory();
+  
+  /**
+   * Creates {@link GatewayReceiverFactory} for creating a GatewayReceiver
+   * 
+   * @return GatewayReceiverFactory
+   * @since 7.0
+   */
+  public GatewayReceiverFactory createGatewayReceiverFactory();
+
+  /**
+   * Returns all {@link GatewaySender}s for this Cache. 
+   * 
+   * @return Set of GatewaySenders
+   * @since 7.0
+   */
+  public Set<GatewaySender> getGatewaySenders();
+
+  /**
+   * Returns the {@link GatewaySender} with the given id added to this Cache.
+   * 
+   * @return GatewaySender with id
+   * @since 7.0
+   */  
+  public GatewaySender getGatewaySender(String id);
+  /**
+   * Returns all {@link GatewayReceiver}s for this Cache
+   * 
+   * @return Set of GatewaySenders
+   * @since 7.0
+   */
+  public Set<GatewayReceiver> getGatewayReceivers();
+  
+  /**
+   * Returns all {@link AsyncEventQueue}s for this Cache
+   * 
+   * @return Set of AsyncEventQueue
+   * @since 7.0
+   */
+  public Set<AsyncEventQueue> getAsyncEventQueues(); 
+  
+  /**
+   * Returns the {@link AsyncEventQueue} with the given id added to this Cache.
+   * 
+   * @return AsyncEventQueue with id
+   * @since 7.0
+   */  
+  public AsyncEventQueue getAsyncEventQueue(String id);
+
+  /**
+   * Returns a set of the other non-administrative members in the distributed system.
+   * @since 6.6
+   */
+  public Set<DistributedMember> getMembers();
+  
+  /**
+   * Returns a set of the administrative members in the distributed system.
+   * @since 6.6
+   */
+  public Set<DistributedMember> getAdminMembers();
+  
+  /**
+   * Returns a set of the members in the distributed system that have the
+   * given region.  For regions with local scope an empty set is returned.
+   * @param r a Region in the cache
+   * @since 6.6
+   */
+  public Set<DistributedMember> getMembers(Region r);
+  
+  /**
+   * Obtains the snapshot service to allow the cache data to be imported
+   * or exported.
+   * 
+   * @return the snapshot service
+   */
+  public CacheSnapshotService getSnapshotService();
+  
+  /**
+   * Test to see whether the Cache is in the process of reconnecting
+   * and recreating a new cache after it has been removed from the system
+   * by other members or has shut down due to missing Roles and is reconnecting.<p>
+   * This will also return true if the Cache has finished reconnecting.
+   * When reconnect has completed you can use {@link Cache#getReconnectedCache} to
+   * retrieve the new cache instance.
+   * 
+   * @return true if the Cache is attempting to reconnect or has finished reconnecting
+   */
+  public boolean isReconnecting();
+
+  /**
+   * Wait for the Cache to finish reconnecting to the distributed system
+   * and recreate a new Cache.
+   * @see #getReconnectedCache
+   * @param time amount of time to wait, or -1 to wait forever
+   * @param units
+   * @return true if the cache was reconnected
+   * @throws InterruptedException if the thread is interrupted while waiting
+   */
+  public boolean waitUntilReconnected(long time, TimeUnit units) throws InterruptedException;
+  
+  /**
+   * Force the Cache to stop reconnecting.  If the Cache
+   * is currently connected this will disconnect and close it.
+   * 
+   */
+  public void stopReconnecting();
+  
+  /**
+   * Returns the new Cache if there was an auto-reconnect and the cache was
+   * recreated.
+   */
+  public Cache getReconnectedCache();
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheCallback.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheCallback.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheCallback.java
new file mode 100644
index 0000000..82e52f9
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheCallback.java
@@ -0,0 +1,38 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/**
+ * User-defined objects that can be plugged into caching to receive callback
+ * notifications.
+ *
+ * @author Eric Zoerner
+ *
+ * @since 3.0
+ */
+public interface CacheCallback {
+  /** Called when the region containing this callback is closed or destroyed, when
+   * the cache is closed, or when a callback is removed from a region
+   * using an <code>AttributesMutator</code>.
+   *
+   * <p>Implementations should cleanup any external
+   * resources such as database connections. Any runtime exceptions this method
+   * throws will be logged.
+   *
+   * <p>It is possible for this method to be called multiple times on a single
+   * callback instance, so implementations must be tolerant of this.
+   *
+   * @see Cache#close()
+   * @see Region#close
+   * @see Region#localDestroyRegion()
+   * @see Region#destroyRegion()
+   * @see AttributesMutator
+   */
+  public void close();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheClosedException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheClosedException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheClosedException.java
new file mode 100644
index 0000000..8df8228
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheClosedException.java
@@ -0,0 +1,68 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.CancelException;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+
+/**
+ * Indicates that the caching system has 
+ * been closed. Can be thrown from almost any method related to regions or the
+ * <code>Cache</code> after the cache has been closed.
+ *
+ * @author Eric Zoerner
+ *
+ *
+ * @see Cache
+ * @since 3.0
+ */
+public class CacheClosedException extends CancelException {
+private static final long serialVersionUID = -6479561694497811262L;
+  
+  /**
+   * Constructs a new <code>CacheClosedException</code>.
+   */
+  public CacheClosedException() {
+    super();
+  }
+  
+  /**
+   * Constructs a new <code>CacheClosedException</code> with a message string.
+   *
+   * @param msg a message string
+   */
+  public CacheClosedException(String msg) {
+    super(msg);
+    // bug #43108 - CacheClosedException should include cause of closure
+    GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+    if (cache != null) {
+      initCause(cache.getDisconnectCause());
+    }
+  }
+  
+  /**
+   * Constructs a new <code>CacheClosedException</code> with a message string
+   * and a cause.
+   *
+   * @param msg the message string
+   * @param cause a causal Throwable
+   */
+  public CacheClosedException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+  
+  /**
+   * Constructs a new <code>CacheClosedException</code> with a cause.
+   *
+   * @param cause a causal Throwable
+   */
+  public CacheClosedException(Throwable cause) {
+    super(cause);
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheEvent.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheEvent.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheEvent.java
new file mode 100644
index 0000000..5c99dc2
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheEvent.java
@@ -0,0 +1,101 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.distributed.DistributedMember;
+import com.gemstone.gemfire.internal.cache.EnumListenerEvent;
+
+/**
+ * A region- or entry-related event affecting the cache.
+   * <P>
+   * Prior to release <code>6.0</code> the <code>NOT_AVAILABLE</code> constant
+   * was used to indicate an object value was not available.
+   * However in <code>6.0</code> generic typing was added
+   * to {@link Region} and since this constant's type will not be an
+   * instance of the generic type <code>V</code> returning it would cause
+   * a ClassCastException. So in <code>6.0</code> and later
+   * <code>null</code> is now used in place of <code>NOT_AVAILABLE</code>.
+ *
+ * @see CacheListener
+ *
+ * @author Eric Zoerner
+ *
+ *
+ * @since 2.0
+ */
+public interface CacheEvent<K,V> {
+
+  /** Returns the region to which this cached object belongs or
+   * the region that raised this event for <code>RegionEvent</code>s.
+   * @return the region associated with this object or the region that raised
+   * this event.
+   */
+  public Region<K,V> getRegion();
+
+  /**
+   * Return a description of the operation that triggered this event.
+   * @return the operation that triggered this event.
+   * @since 5.0
+   */
+  public Operation getOperation();
+  
+  /** Returns the callbackArgument passed to the method that generated this event.
+   * Provided primarily in case this object or region has already been
+   * destroyed. See the {@link Region} interface methods that take a
+   * callbackArgument parameter.
+   * @return the callbackArgument associated with this event. <code>null</code>
+   * is returned if the callback argument is not propagated to the event.
+   * This happens for events given to {@link TransactionListener}
+   * and to {@link CacheListener} on the remote side of a transaction commit.
+   */
+  public Object getCallbackArgument();
+  /**
+   * Returns <code>true</code> if the callback argument is "available".
+   * Not available means that the callback argument may have existed but it could
+   * not be obtained.
+   * Note that {@link #getCallbackArgument} will return <code>null</code>
+   * when this method returns <code>false</code>.
+   * @since 6.0
+   */
+  public boolean isCallbackArgumentAvailable();
+
+  /** Answer true if this event originated in a cache other than this one.
+   * Answer false if this event originated in this cache.
+   * @return true if this event originated remotely
+   *
+   */
+  public boolean isOriginRemote();
+  /**
+   * Returns the {@link DistributedMember} that this event originated in.
+   * @return the member that performed the operation that originated this event.
+   * @since 5.0
+   */
+  public DistributedMember getDistributedMember();
+
+  /** Answer true if this event resulted from expiration.
+   * @return true if this event resulted from expiration
+   * @deprecated as of GemFire 5.0, use {@link Operation#isExpiration} instead.
+   *
+   */
+  @Deprecated
+  public boolean isExpiration();
+
+  /** Answers true if this event resulted from a distributed operation;
+   * false if a local operation.
+   * 
+   * This is useful to distinguish between invalidate and localInvalidate, and
+   * destroy and localDestroy.
+   *
+   * @return true if this event resulted from a distributed operation
+   * @deprecated as of GemFire 5.0, use {@link Operation#isDistributed} instead.
+   *
+   */
+  @Deprecated
+  public boolean isDistributed();
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheException.java
new file mode 100644
index 0000000..9d8e449
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheException.java
@@ -0,0 +1,61 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.GemFireException;
+
+
+/**
+ * A generic exception, which indicates
+ * a cache error has occurred. All the other cache exceptions are 
+ * subclasses of this class. This class is abstract and therefore only
+ * subclasses are instantiated.
+ *
+ * @author Eric Zoerner
+ *
+ * @since 2.0
+ */
+public abstract class CacheException extends GemFireException {
+  /** Constructs a new <code>CacheException</code>. */
+  public CacheException() {
+    super();
+  }
+  
+  /** Constructs a new <code>CacheException</code> with a message string. */
+  public CacheException(String s) {
+    super(s);
+  }
+  
+  /** Constructs a <code>CacheException</code> with a message string and
+   * a base exception
+   */
+  public CacheException(String s, Throwable cause) {
+    super(s, cause);
+  }
+  
+  /** Constructs a <code>CacheException</code> with a cause */
+  public CacheException(Throwable cause) {
+    super(cause);
+  }
+
+  @Override
+  public String toString() {
+    String result = super.toString();
+    Throwable cause = getCause();
+    if (cause != null) {
+      String causeStr = cause.toString();
+      final String glue = ", caused by ";
+      StringBuffer sb = new StringBuffer(result.length() + causeStr.length() + glue.length());
+      sb.append(result)
+        .append(glue)
+        .append(causeStr);
+      result = sb.toString();
+    }
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheExistsException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheExistsException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheExistsException.java
new file mode 100644
index 0000000..fb4878a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheExistsException.java
@@ -0,0 +1,57 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+
+/** Thrown when attempting to create a {@link Cache} if one already exists.
+ *
+ * @author Darrel Schneider
+ *
+ * @see CacheFactory#create
+ * @since 3.0
+ */
+public class CacheExistsException extends CacheException {
+private static final long serialVersionUID = 4090002289325418100L;
+
+  /** The <code>Cache</code> that already exists */
+  private final transient Cache cache;
+
+  ///////////////////////  Constructors  ///////////////////////
+
+  /**
+   * Constructs an instance of <code>CacheExistsException</code> with the specified detail message.
+   * @param msg the detail message
+   */
+  public CacheExistsException(Cache cache, String msg) {
+    super(msg);
+    this.cache = cache;
+  }
+  
+  /**
+   * Constructs an instance of <code>CacheExistsException</code> with the specified detail message
+   * and cause.
+   * @param msg the detail message
+   * @param cause the causal Throwable
+   */
+  public CacheExistsException(Cache cache, String msg, Throwable cause) {
+    super(msg, cause);
+    this.cache = cache;
+  }
+
+  ///////////////////////  Instance Methods  ///////////////////////
+
+  /**
+   * Returns the <code>Cache</code> that already exists.
+   *
+   * @since 4.0
+   */
+  public Cache getCache() {
+    return this.cache;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheFactory.java
new file mode 100755
index 0000000..11536df
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheFactory.java
@@ -0,0 +1,397 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import java.util.Properties;
+
+import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.internal.GemFireVersion;
+import com.gemstone.gemfire.internal.cache.CacheConfig;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.jndi.JNDIInvoker;
+import com.gemstone.gemfire.pdx.PdxInstance;
+import com.gemstone.gemfire.pdx.PdxSerializer;
+
+
+/**
+ * Factory class used to create the singleton {@link Cache cache} and connect to the GemFire singleton {@link DistributedSystem distributed system}. If the application wants to connect to GemFire as a client it should use {@link com.gemstone.gemfire.cache.client.ClientCacheFactory} instead.
+<p> Once the factory has been configured using its {@link #set(String, String)} method you produce a {@link Cache} by calling the {@link #create()} method.
+ * <p>
+ * To get the existing unclosed singleton cache instance call {@link #getAnyInstance}.
+ * <p>
+ * If an instance of {@link DistributedSystem} already exists when this factory
+ * creates a cache, that instance will be used if it is compatible with this factory.
+<p>
+The following examples illustrate bootstrapping the cache using region shortcuts:
+<p>
+Example 1: Create a cache and a replicate region named customers.
+<PRE>
+  Cache c = new CacheFactory().create();
+  Region r = c.createRegionFactory(REPLICATE).create("customers");
+</PRE>
+Example 2: Create a cache and a partition region with redundancy
+<PRE>
+  Cache c = new CacheFactory().create();
+  Region r = c.createRegionFactory(PARTITION_REDUNDANT).create("customers");
+</PRE>
+Example 3: Construct the  cache region declaratively in cache.xml
+<PRE>
+  &lt;!DOCTYPE cache PUBLIC
+    "-//GemStone Systems, Inc.//GemFire Declarative Caching 8.0//EN"
+    "http://www.gemstone.com/dtd/cache8_0.dtd">
+  &lt;cache>	
+    &lt;region name="myRegion" refid="REPLICATE"/>
+      &lt;!-- you can override or add to the REPLICATE attributes by adding
+           a region-attributes sub element here -->
+  &lt;/cache>
+</PRE>
+Now, create the cache telling it to read your cache.xml file:
+<PRE>
+  Cache c = new CacheFactory()
+    .set("cache-xml-file", "myCache.xml")
+    .create();
+  Region r = c.getRegion("myRegion");
+</PRE>
+
+<p> For a complete list of all region shortcuts see {@link RegionShortcut}. 
+Applications that need to explicitly control the individual region attributes can do this declaratively in XML or using APIs.
+ *
+ * @author Darrel Schneider
+ *
+ *
+ * @since 3.0
+ */
+public class CacheFactory {
+
+  private final Properties dsProps;
+  
+  private final CacheConfig cacheConfig =  new CacheConfig();
+       
+  /**
+   * Creates a default cache factory.
+   * @since 6.5
+   */
+  public CacheFactory() {
+    this(null);
+  }
+  /**
+   * Create a CacheFactory initialized with the given gemfire properties.
+   * For a list of valid gemfire properties see {@link DistributedSystem}.
+   * @param props the gemfire properties to initialize the factory with.
+   * @since 6.5
+   */
+  public CacheFactory(Properties props) {
+    if (props == null) {
+      props = new Properties();
+    }
+    this.dsProps = props;
+  }
+
+  /**
+   * Sets a gemfire property that will be used when creating the Cache.
+   * For a list of valid gemfire properties see {@link DistributedSystem}.
+   * @param name the name of the gemfire property
+   * @param value the value of the gemfire property
+   * @return a reference to this CacheFactory object
+   * @since 6.5
+   */
+  public CacheFactory set(String name, String value) {
+    this.dsProps.setProperty(name, value);
+    return this;
+  }
+  /**
+   * Creates a new cache that uses the specified <code>system</code>.
+   *
+   * <p>
+   *
+   * The <code>system</code> can specify a <A
+   * href="../distributed/DistributedSystem.html#cache-xml-file">"cache-xml-file"</a>
+   * property which will cause this creation to also create the
+   * regions, objects, and attributes declared in the file.  The
+   * contents of the file must comply with the
+   * <code>"doc-files/cache8_0.dtd"></code> file.
+   * Note that when parsing the XML file {@link Declarable} classes
+   * are loaded using the current thread's {@linkplain
+   * Thread#getContextClassLoader context class loader}.
+   *
+   * @param system
+   *        a <code>DistributedSystem</code> obtained by calling
+   *        {@link DistributedSystem#connect}.
+   *
+   * @return a <code>Cache</code> that uses the specified
+   *         <code>system</code> for distribution.
+   *
+   * @throws IllegalArgumentException
+   *         If <code>system</code> is not {@link
+   *         DistributedSystem#isConnected connected}.
+   * @throws CacheExistsException
+   *         If an open cache already exists.
+   * @throws CacheXmlException
+   *         If a problem occurs while parsing the declarative caching
+   *         XML file.
+   * @throws TimeoutException
+   *         If a {@link Region#put(Object, Object)} times out while initializing the
+   *         cache.
+   * @throws CacheWriterException
+   *         If a <code>CacheWriterException</code> is thrown while
+   *         initializing the cache.
+   * @throws GatewayException
+   *         If a <code>GatewayException</code> is thrown while
+   *         initializing the cache.
+   * @throws RegionExistsException
+   *         If the declarative caching XML file describes a region
+   *         that already exists (including the root region).
+   * @deprecated as of 6.5 use {@link #CacheFactory(Properties)} instead.
+   */
+  @Deprecated
+  public static synchronized Cache create(DistributedSystem system)
+    throws CacheExistsException, TimeoutException, CacheWriterException,
+           GatewayException,
+           RegionExistsException 
+  {
+    return create(system, false, new CacheConfig());
+  }
+  
+  private static synchronized Cache create(DistributedSystem system, boolean existingOk, CacheConfig cacheConfig)
+    throws CacheExistsException, TimeoutException, CacheWriterException,
+           GatewayException,
+           RegionExistsException 
+  {
+    GemFireCacheImpl instance = GemFireCacheImpl.getInstance();
+    
+    if (instance != null && !instance.isClosed()) {
+      if (existingOk) {
+        // Check if cache configuration matches.
+        cacheConfig.validateCacheConfig(instance);
+        
+        return instance;
+      } else {
+        // instance.creationStack argument is for debugging...
+        throw new CacheExistsException(instance, LocalizedStrings.CacheFactory_0_AN_OPEN_CACHE_ALREADY_EXISTS.toLocalizedString(instance), instance.creationStack);
+      }
+    }
+    return GemFireCacheImpl.create(system, cacheConfig);
+  }
+
+  /**
+   * Creates a new cache that uses the configured distributed system.
+   * If a connected distributed system already exists it will be used
+   * if it is compatible with the properties on this factory.
+   * Otherwise a a distributed system will be created with the configured properties.
+   * If a cache already exists it will be returned.
+   * <p>If the cache does need to be created it will also be initialized from
+   * cache.xml if it exists.
+   *
+   * @return the created or already existing singleton cache
+   *
+   * @throws CacheXmlException
+   *         If a problem occurs while parsing the declarative caching
+   *         XML file.
+   * @throws TimeoutException
+   *         If a {@link Region#put(Object, Object)} times out while initializing the
+   *         cache.
+   * @throws CacheWriterException
+   *         If a <code>CacheWriterException</code> is thrown while
+   *         initializing the cache.
+   * @throws GatewayException
+   *         If a <code>GatewayException</code> is thrown while
+   *         initializing the cache.
+   * @throws RegionExistsException
+   *         If the declarative caching XML file describes a region
+   *         that already exists (including the root region).
+   * @throws ManagementException
+   *         If the jmx manager can not be initialized.
+   * @since 6.5
+   */
+  public Cache create()
+    throws TimeoutException, CacheWriterException,
+           GatewayException,
+           RegionExistsException 
+  {
+    synchronized(CacheFactory.class) {
+      DistributedSystem ds = null;
+      if (this.dsProps.isEmpty()) {
+        // any ds will do
+        ds = InternalDistributedSystem.getConnectedInstance();
+      }
+      if (ds == null) {
+        ds = DistributedSystem.connect(this.dsProps);
+      }
+      return create(ds, true, cacheConfig);
+    }
+  }
+
+  /**
+   * Gets the instance of {@link Cache} produced by an
+   * earlier call to {@link #create()}.
+   * @param system the <code>DistributedSystem</code> the cache was created with.
+   * @return the {@link Cache} associated with the specified system.
+   * @throws CacheClosedException if a cache has not been created
+   * or the created one is {@link Cache#isClosed closed}
+   */
+  public static Cache getInstance(DistributedSystem system) {
+    return basicGetInstance(system, false);
+  }
+
+  /**
+   * Gets the instance of {@link Cache} produced by an
+   * earlier call to {@link #create()} even if it has been closed.
+   * @param system the <code>DistributedSystem</code> the cache was created with.
+   * @return the {@link Cache} associated with the specified system.
+   * @throws CacheClosedException if a cache has not been created
+   * @since 3.5
+   */
+  public static Cache getInstanceCloseOk(DistributedSystem system) {
+    return basicGetInstance(system, true);
+  }
+
+  private static Cache basicGetInstance(DistributedSystem system, boolean closeOk) {
+
+    // Avoid synchronization if this is an initialization thread to avoid
+    // deadlock when messaging returns to this VM
+    final int initReq = LocalRegion.threadInitLevelRequirement();
+    if (initReq == LocalRegion.ANY_INIT
+        || initReq == LocalRegion.BEFORE_INITIAL_IMAGE) { // fix bug 33471
+      return basicGetInstancePart2(system, closeOk);
+    } else {
+      synchronized (CacheFactory.class) {
+        return basicGetInstancePart2(system, closeOk);
+      }
+    }
+  }
+  private static Cache basicGetInstancePart2(DistributedSystem system, boolean closeOk) {
+    GemFireCacheImpl instance = GemFireCacheImpl.getInstance();
+    if (instance == null) {
+      throw new CacheClosedException(LocalizedStrings.CacheFactory_A_CACHE_HAS_NOT_YET_BEEN_CREATED.toLocalizedString());
+    } else {
+      if (instance.isClosed() && !closeOk) {
+        throw instance.getCacheClosedException(LocalizedStrings.CacheFactory_THE_CACHE_HAS_BEEN_CLOSED.toLocalizedString(), null);
+      }
+      if (!instance.getDistributedSystem().equals(system)) {
+        throw new CacheClosedException(LocalizedStrings.CacheFactory_A_CACHE_HAS_NOT_YET_BEEN_CREATED_FOR_THE_GIVEN_DISTRIBUTED_SYSTEM.toLocalizedString());
+      }
+      return instance;
+    }
+  }
+
+  /**
+   * Gets an arbitrary open instance of {@link Cache} produced by an
+   * earlier call to {@link #create()}.
+   * @throws CacheClosedException if a cache has not been created
+   * or the only created one is {@link Cache#isClosed closed}
+   */
+  public static synchronized Cache getAnyInstance() {
+    GemFireCacheImpl instance = GemFireCacheImpl.getInstance();
+    if (instance == null) {
+      throw new CacheClosedException(LocalizedStrings.CacheFactory_A_CACHE_HAS_NOT_YET_BEEN_CREATED.toLocalizedString());
+    } else {
+      instance.getCancelCriterion().checkCancelInProgress(null);
+      return instance;
+    }
+  }
+
+  /** Returns the version of the cache implementation.
+   * @return the version of the cache implementation as a <code>String</code>
+   */
+  public static String getVersion() {
+    return GemFireVersion.getGemFireVersion();
+  }
+  
+  /** Sets the object preference to PdxInstance type. 
+   * When a cached object that was serialized as a PDX is read
+   * from the cache a {@link PdxInstance} will be returned instead of the actual domain class.
+   * The PdxInstance is an interface that provides run time access to 
+   * the fields of a PDX without deserializing the entire PDX. 
+   * The PdxInstance implementation is a light weight wrapper 
+   * that simply refers to the raw bytes of the PDX that are kept 
+   * in the cache. Using this method applications can choose to 
+   * access PdxInstance instead of Java object.
+   * <p>Note that a PdxInstance is only returned if a serialized PDX is found in the cache.
+   * If the cache contains a deserialized PDX, then a domain class instance is returned instead of a PdxInstance.
+   *  
+   *  @param readSerialized true to prefer PdxInstance
+   *  @return this CacheFactory 
+   *  @since 6.6
+   *  @see com.gemstone.gemfire.pdx.PdxInstance 
+   */
+  public  CacheFactory setPdxReadSerialized(boolean readSerialized) {
+    this.cacheConfig.setPdxReadSerialized(readSerialized);
+    return this;
+  }
+  
+  /**
+   * Set the PDX serializer for the cache. If this serializer is set,
+   * it will be consulted to see if it can serialize any domain classes which are 
+   * added to the cache in portable data exchange format. 
+   * @param serializer the serializer to use
+   * @return this CacheFactory
+   * @since 6.6
+   * @see PdxSerializer
+   */
+  public CacheFactory setPdxSerializer(PdxSerializer serializer) {
+    this.cacheConfig.setPdxSerializer(serializer);
+    return this;
+  }
+  
+  /**
+   * Set the disk store that is used for PDX meta data. When
+   * serializing objects in the PDX format, the type definitions
+   * are persisted to disk. This setting controls which disk store
+   * is used for that persistence.
+   * 
+   * If not set, the metadata will go in the default disk store.
+   * @param diskStoreName the name of the disk store to use
+   * for the PDX metadata.
+   * @return this CacheFactory
+   * @since 6.6
+   */
+  public CacheFactory setPdxDiskStore(String diskStoreName) {
+    this.cacheConfig.setPdxDiskStore(diskStoreName);
+    return this;
+  }
+
+  /**
+   * Control whether the type metadata for PDX objects is persisted to disk. The
+   * default for this setting is false. If you are using persistent regions with
+   * PDX then you must set this to true. If you are using a
+   * <code>GatewaySender</code> or <code>AsyncEventQueue</code> with PDX then
+   * you should set this to true.
+   * 
+   * @param isPersistent
+   *          true if the metadata should be persistent
+   * @return this CacheFactory
+   * @since 6.6
+   */
+  public CacheFactory setPdxPersistent(boolean isPersistent) {
+    this.cacheConfig.setPdxPersistent(isPersistent);
+    return this;
+  }
+  /**
+   * Control whether pdx ignores fields that were unread during deserialization.
+   * The default is to preserve unread fields be including their data during serialization.
+   * But if you configure the cache to ignore unread fields then their data will be lost
+   * during serialization.
+   * <P>You should only set this attribute to <code>true</code> if you know this member
+   * will only be reading cache data. In this use case you do not need to pay the cost
+   * of preserving the unread fields since you will never be reserializing pdx data. 
+   * 
+   * @param ignore <code>true</code> if fields not read during pdx deserialization should be ignored;
+   * <code>false</code>, the default, if they should be preserved.
+   * @return this CacheFactory
+   * @since 6.6
+   */
+  public CacheFactory setPdxIgnoreUnreadFields(boolean ignore) {
+    this.cacheConfig.setPdxIgnoreUnreadFields(ignore);
+    return this;
+  }
+} 
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheListener.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheListener.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheListener.java
new file mode 100644
index 0000000..55ee4f7
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheListener.java
@@ -0,0 +1,165 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * <p>
+ * A listener to handle region or entry related events.
+ * </p>
+ * 
+ * <p>
+ * Instead of implementing this interface it is recommended that you extend the
+ * {@link com.gemstone.gemfire.cache.util.CacheListenerAdapter} class.
+ * </p>
+ * 
+ * <h4>Avoiding the risk of deadlock</h4>
+ * <p>
+ * The methods on a <code>CacheListener</code> are invoked while holding a lock
+ * on the entry described by the {@link EntryEvent}, as a result if the listener
+ * method takes a long time to execute then it will cause the operation that
+ * caused it to be invoked to take a long time. In addition, listener code which
+ * calls {@link Region} methods could result in a deadlock. For example, in
+ * {@link #afterUpdate(EntryEvent)} for entry key k1,
+ * {@link Region#put(Object, Object) put(k2, someVal)} is called at the same
+ * time {@link #afterUpdate(EntryEvent)} for entry key k2 calls
+ * {@link Region#put(Object, Object) put(k1, someVal)} a deadlock may result.
+ * This co-key dependency example can be extended to a co-Region dependency
+ * where listener code in Region "A" performs Region operations on "B" and
+ * listener code in Region "B" performs Region operations on "A". Deadlocks may
+ * be either java-level or distributed multi-VM dead locks depending on Region
+ * configuration. To be assured of no deadlocks, listener code should cause some
+ * other thread to access the region and must not wait for that thread to
+ * complete the task.
+ * </p>
+ * 
+ * <h4>Concurrency</h4>
+ * <p>
+ * Multiple events, on different entries, can cause concurrent invocation of
+ * <code>CacheListener</code> methods. Any exceptions thrown by the listener are
+ * caught by GemFire and logged.
+ * </p>
+ * 
+ * <h4>Declaring instances in Cache XML files</h4> 
+ * <p>
+ * To declare a CacheListener in a Cache XML file, it must also implement
+ * {@link Declarable}
+ * </p>
+ * 
+ * @author Eric Zoerner
+ * 
+ * @see AttributesFactory#addCacheListener
+ * @see AttributesFactory#initCacheListeners
+ * @see RegionAttributes#getCacheListeners
+ * @see AttributesMutator#addCacheListener
+ * @see AttributesMutator#removeCacheListener
+ * @see AttributesMutator#initCacheListeners
+ * @since 3.0
+ */
+public interface CacheListener<K,V> extends CacheCallback {
+
+  /**
+   * Handles the event of new key being added to a region. The entry did not
+   * previously exist in this region in the local cache (even with a null
+   * value).
+   * 
+   * @param event the EntryEvent
+   * @see Region#create(Object, Object)
+   * @see Region#put(Object, Object)
+   * @see Region#get(Object)
+   */
+  public void afterCreate(EntryEvent<K,V> event);
+
+  /**
+   * Handles the event of an entry's value being modified in a region. This
+   * entry previously existed in this region in the local cache, but its
+   * previous value may have been null.
+   * 
+   * @param event the EntryEvent
+   * @see Region#put(Object, Object)
+   */
+  public void afterUpdate(EntryEvent<K,V> event);
+
+  /**
+   * Handles the event of an entry's value being invalidated.
+   * 
+   * @param event the EntryEvent
+   * @see Region#invalidate(Object)
+   */
+  public void afterInvalidate(EntryEvent<K,V> event);
+
+  /**
+   * Handles the event of an entry being destroyed.
+   * 
+   * @param event the EntryEvent
+   * @see Region#destroy(Object)
+   */
+  public void afterDestroy(EntryEvent<K,V> event);
+
+  /**
+   * Handles the event of a region being invalidated. Events are not invoked for
+   * each individual value that is invalidated as a result of the region being
+   * invalidated. Each subregion, however, gets its own
+   * <code>regionInvalidated</code> event invoked on its listener.
+   * 
+   * @param event the RegionEvent
+   * @see Region#invalidateRegion()
+   * @see Region#localInvalidateRegion()
+   */
+  public void afterRegionInvalidate(RegionEvent<K,V> event);
+
+  /**
+   * Handles the event of a region being destroyed. Events are not invoked for
+   * each individual entry that is destroyed as a result of the region being
+   * destroyed. Each subregion, however, gets its own
+   * <code>afterRegionDestroyed</code> event invoked on its listener.
+   * 
+   * @param event the RegionEvent
+   * @see Region#destroyRegion()
+   * @see Region#localDestroyRegion()
+   * @see Region#close
+   * @see Cache#close()
+   */
+  public void afterRegionDestroy(RegionEvent<K,V> event);
+
+  /**
+   * Handles the event of a region being cleared. Events are not invoked for
+   * each individual entry that is removed as a result of the region being
+   * cleared.
+   * 
+   * @param event the RegionEvent
+   *
+   * @see Region#clear
+   * @since 5.0
+   */
+  public void afterRegionClear(RegionEvent<K,V> event);
+  
+  /**
+   * Handles the event of a region being created. Events are invoked for
+   * each individual region that is created.
+   * <p>Note that this method is only called
+   * for creates done in the local vm. To be notified of creates done in remote
+   * vms use {@link RegionMembershipListener#afterRemoteRegionCreate}.
+   * 
+   * @param event the RegionEvent
+   *
+   * @see Cache#createRegion
+   * @see Region#createSubregion
+   * @since 5.0
+   */
+  public void afterRegionCreate(RegionEvent<K,V> event);
+
+  /**
+   * Handles the event of a region being live after receiving the marker from the server.
+   *
+   * @param event the RegionEvent
+   * 
+   * @see Cache#readyForEvents
+   * @since 5.5
+   */
+  public void afterRegionLive(RegionEvent<K,V> event);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheLoader.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheLoader.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheLoader.java
new file mode 100644
index 0000000..39fedaf
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheLoader.java
@@ -0,0 +1,55 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * Allows data from outside of the VM to be placed into a region.  
+ * When {@link com.gemstone.gemfire.cache.Region#get(Object)} is called for a region
+ * entry that has a <code>null</code> value, the 
+ * {@link CacheLoader#load load} method of the
+ * region's cache loader is invoked.  The <code>load</code> method
+ * creates the value for the desired key by performing an operation such
+ * as a database query.  The <code>load</code> may also perform a
+ * {@linkplain LoaderHelper#netSearch net search}
+ * that will look for the value in a cache instance hosted by
+ * another member of the distributed system.</p>
+ *
+ * @author Dave Monnie
+ *
+ *
+ * @see AttributesFactory#setCacheLoader
+ * @see RegionAttributes#getCacheLoader
+ * @see AttributesMutator#setCacheLoader
+ * @since 2.0
+ */
+public interface CacheLoader<K,V> extends CacheCallback {
+  /**
+   * Loads a value. Application writers should implement this
+   * method to customize the loading of a value. This method is called
+   * by the caching service when the requested value is not in the cache.
+   * Any exception (including an unchecked exception) thrown by this
+   * method is propagated back to and thrown by the invocation of
+   * {@link Region#get(Object, Object)} that triggered this load.
+   * <p>
+   *
+   * @param helper a LoaderHelper object that is passed in from cache service
+   *   and provides access to the key, region, argument, and <code>netSearch</code>.
+   * @return the value supplied for this key, or null if no value can be
+   *    supplied.  A local loader will always be invoked if one exists.
+   *    Otherwise one remote loader is invoked.
+   *    Returning <code>null</code> causes
+   *    {@link Region#get(Object, Object)} to return <code>null</code>.
+   * @throws CacheLoaderException, if an error occurs. This exception or any
+   * other exception thrown by this method will be propagated back to the
+   * application from the get method.
+   *
+   * @see   Region#get(Object, Object) Region.get
+   */
+  public V load(LoaderHelper<K,V> helper)
+  throws CacheLoaderException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheLoaderException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheLoaderException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheLoaderException.java
new file mode 100755
index 0000000..5770d0d
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheLoaderException.java
@@ -0,0 +1,57 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/** Thrown from the {@link CacheLoader#load} method indicating that an error
+ * occurred when a CacheLoader was attempting to load a value. This
+ * exception is propagated back to the caller of <code>Region.get</code>.
+ *
+ * @author Eric Zoerner
+ *
+ *
+ * @see com.gemstone.gemfire.cache.Region#get(Object)
+ * @see CacheLoader#load
+ * @since 3.0
+ */
+public class CacheLoaderException extends OperationAbortedException {
+private static final long serialVersionUID = -3383072059406642140L;
+  
+  /**
+   * Creates a new instance of <code>CacheLoaderException</code>.
+   */
+  public CacheLoaderException() {
+  }
+  
+  
+  /**
+   * Constructs an instance of <code>CacheLoaderException</code> with the specified detail message.
+   * @param msg the detail message
+   */
+  public CacheLoaderException(String msg) {
+    super(msg);
+  }
+  
+  /**
+   * Constructs an instance of <code>CacheLoaderException</code> with the specified detail message
+   * and cause.
+   * @param msg the detail message
+   * @param cause the causal Throwable
+   */
+  public CacheLoaderException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+  
+  /**
+   * Constructs an instance of <code>CacheLoaderException</code> with the specified cause.
+   * @param cause the causal Throwable
+   */
+  public CacheLoaderException(Throwable cause) {
+    super(cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheRuntimeException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheRuntimeException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheRuntimeException.java
new file mode 100644
index 0000000..4e0dc3a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheRuntimeException.java
@@ -0,0 +1,72 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.GemFireException;
+
+/** A generic runtime exception that indicates
+ * a cache error has occurred. All the other runtime cache exceptions are the
+ * subclass of this class. This class is abstract so only subclasses can be
+ * instantiated
+ *
+ * @author Eric Zoerner
+ *
+ * @since 3.0
+ */
+public abstract class CacheRuntimeException extends GemFireException {
+  
+  /**
+   * Creates a new instance of <code>CacheRuntimeException</code> without detail message.
+   */
+  public CacheRuntimeException() {
+  }
+  
+  
+  /**
+   * Constructs an instance of <code>CacheRuntimeException</code> with the specified detail message.
+   * @param msg the detail message
+   */
+  public CacheRuntimeException(String msg) {
+    super(msg);
+  }
+  
+  /**
+   * Constructs an instance of <code>CacheRuntimeException</code> with the specified detail message
+   * and cause.
+   * @param msg the detail message
+   * @param cause the causal Throwable
+   */
+  public CacheRuntimeException(String msg, Throwable cause) {
+    super(msg, cause);
+  }
+  
+  /**
+   * Constructs an instance of <code>CacheRuntimeException</code> with the specified cause.
+   * @param cause the causal Throwable
+   */
+  public CacheRuntimeException(Throwable cause) {
+    super(cause);
+  }
+
+  @Override
+  public String toString() {
+    String result = super.toString();
+    Throwable cause = getCause();
+    if (cause != null) {
+      String causeStr = cause.toString();
+      final String glue = ", caused by ";
+      StringBuffer sb = new StringBuffer(result.length() + causeStr.length() + glue.length());
+      sb.append(result)
+        .append(glue)
+        .append(causeStr);
+      result = sb.toString();
+    }
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheStatistics.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheStatistics.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheStatistics.java
new file mode 100644
index 0000000..bdcea93
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/CacheStatistics.java
@@ -0,0 +1,121 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/**
+ * Defines common statistics information
+ * for both region and entries. All of these methods may throw a
+ * CacheClosedException, RegionDestroyedException or an EntryDestroyedException.
+ *
+ * @author Eric Zoerner
+ *
+ *
+ * @see Region#getStatistics
+ * @see Region.Entry#getStatistics
+ * @since 2.0
+ */
+
+public interface CacheStatistics
+{
+  /** For an entry, returns the time that the entry's value was last modified;
+   * for a region, the last time any of the region's entries' values or the
+   * values in subregions' entries were modified. The
+   * modification may have been initiated locally or it may have been an update
+   * distributed from another cache. It may also have been a new value provided
+   * by a loader. The modification time on a region is propagated upward to parent
+   * regions, transitively, to the root region.
+   * <p>
+   * The number is expressed as the number of milliseconds since January 1, 1970.
+   * The granularity may be as course as 100ms, so the accuracy may be off by
+   * up to 50ms.
+   * <p>
+   * Entry and subregion creation will update the modification time on a
+   * region, but <code>destroy</code>, <code>destroyRegion</code>,
+   * <code>invalidate</code>, and <code>invalidateRegion</code>
+   * do not update the modification time.
+   * @return the last modification time of the region or the entry;
+   * returns 0 if entry is invalid or modification time is uninitialized.
+   * @see Region#put(Object, Object)
+   * @see Region#get(Object)
+   * @see Region#create(Object, Object)
+   * @see Region#createSubregion
+   */
+  public long getLastModifiedTime();
+
+  /**
+   * For an entry, returns the last time it was accessed via <code>Region.get</code>;
+   * for a region, the last time any of its entries or the entries of its
+   * subregions were accessed with <code>Region.get</code>.
+   * Any modifications will also update the lastAccessedTime, so
+   * <code>lastAccessedTime</code> is always <code>>= lastModifiedTime</code>.
+   * The <code>lastAccessedTime</code> on a region is propagated upward to
+   * parent regions, transitively, to the the root region.
+   * <p>
+   * The number is expressed as the number of milliseconds
+   * since January 1, 1970.
+   * The granularity may be as course as 100ms, so the accuracy may be off by
+   * up to 50ms.
+   *
+   * @return the last access time of the region or the entry's value;
+   * returns 0 if entry is invalid or access time is uninitialized.
+   * @see Region#get(Object)
+   * @see #getLastModifiedTime
+   * @throws StatisticsDisabledException if statistics are not available
+   */
+  public long getLastAccessedTime() throws StatisticsDisabledException;
+
+  /**
+   * Returns the number of times that {@link Region#get(Object) Region.get} on
+   * the region or the entry was called and there was no value found
+   * locally.  Unlike <code>lastAccessedTime</code>, the miss count is
+   * not propagated to parent regions.  Note that remote operations
+   * such as a "net search" do not effect the miss count.
+   *
+   * @return the number of cache misses on the region or the
+   * entry.  
+   * @throws StatisticsDisabledException if statistics are not available
+   */
+  public long getMissCount() throws StatisticsDisabledException;
+  
+  /**
+   * Returns the number of hits for this region or entry.  The number
+   * of hits is defined as the number of times when the 
+   * {@link Region#get(Object) Region.get} finds a value locally.  Unlike
+   * <code>lastAccessedTime</code>, the hit count is not propagated to
+   * parent regions.  Note that remote operations such as a "net
+   * search" do not effect the hit count.
+   *
+   * @return the number of hits for this region or entry.
+   * @throws StatisticsDisabledException if statistics are not available
+   */
+  public long getHitCount() throws StatisticsDisabledException;
+  
+  /** Return the hit ratio, a convenience method defined as the ratio of hits
+   *  to the number of calls to {@link Region#get(Object) Region.get}. If there have been zero
+   *  calls to <code>Region.get</code>, then zero is returned.
+   *  <p>
+   *  The hit ratio is equivalent to:
+   *  <pre>
+   *  long hitCount = getHitCount();
+   *  long total = hitCount + getMissCount();
+   *  return total == 0L ? 0.0f : ((float)hitCount / total);
+   *  </pre>
+   *
+   *  @throws StatisticsDisabledException if statistics are not available
+   *  @return the hit ratio as a float
+   */
+  public float getHitRatio() throws StatisticsDisabledException;
+    
+  
+  /** Reset the missCount and hitCount to zero for this entry.
+   * 
+   * @throws StatisticsDisabledException if statistics are not available
+   */
+  public void resetCounts() throws StatisticsDisabledException;
+}


[31/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MX4JModelMBean.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MX4JModelMBean.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MX4JModelMBean.java
new file mode 100755
index 0000000..f1413f0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MX4JModelMBean.java
@@ -0,0 +1,1246 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Date;
+import java.util.Iterator;
+
+import javax.management.Attribute;
+import javax.management.AttributeChangeNotification;
+import javax.management.AttributeChangeNotificationFilter;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.Descriptor;
+import javax.management.InstanceNotFoundException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationEmitter;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.RuntimeErrorException;
+import javax.management.RuntimeOperationsException;
+import javax.management.ServiceNotFoundException;
+import javax.management.loading.ClassLoaderRepository;
+import javax.management.modelmbean.InvalidTargetObjectTypeException;
+import javax.management.modelmbean.ModelMBean;
+import javax.management.modelmbean.ModelMBeanAttributeInfo;
+import javax.management.modelmbean.ModelMBeanInfo;
+import javax.management.modelmbean.ModelMBeanOperationInfo;
+
+import mx4j.ImplementationException;
+import mx4j.log.FileLogger;
+import mx4j.log.Log;
+import mx4j.log.Logger;
+import mx4j.log.MBeanLogger;
+import mx4j.persist.FilePersister;
+import mx4j.persist.MBeanPersister;
+import mx4j.persist.PersisterMBean;
+import mx4j.util.Utils;
+
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+/**
+ * @author <a href="mailto:biorn_steedom@users.sourceforge.net">Simone Bordet</a>
+ * @version $Revision: 1.14 $
+ */
+public class MX4JModelMBean implements ModelMBean, MBeanRegistration, NotificationEmitter
+{
+   private static final String OBJECT_RESOURCE_TYPE = "ObjectReference";
+
+   private static final int ALWAYS_STALE = 1;
+   private static final int NEVER_STALE = 2;
+   private static final int STALE = 3;
+   private static final int NOT_STALE = 4;
+
+   private static final int PERSIST_NEVER = -1;
+   private static final int PERSIST_ON_TIMER = -2;
+   private static final int PERSIST_ON_UPDATE = -3;
+   private static final int PERSIST_NO_MORE_OFTEN_THAN = -4;
+
+   private MBeanServer m_mbeanServer;
+   private Object m_managedResource;
+   private boolean m_canBeRegistered;
+   private ModelMBeanInfo m_modelMBeanInfo;
+   private NotificationBroadcasterSupport m_attributeChangeBroadcaster = new NotificationBroadcasterSupport();
+   private NotificationBroadcasterSupport m_generalBroadcaster = new NotificationBroadcasterSupport();
+
+   public MX4JModelMBean() throws MBeanException, RuntimeOperationsException
+   {
+      try
+      {
+         load();
+      }
+      catch (Exception x)
+      {
+         Logger logger = getLogger();
+         logger.warn(LocalizedStrings.MX4JModelMBean_CANNOT_RESTORE_PREVIOUSLY_SAVED_STATUS.toLocalizedString(), x);
+      }
+   }
+
+   public MX4JModelMBean(ModelMBeanInfo info) throws MBeanException, RuntimeOperationsException
+   {
+      if (info == null)
+         throw new RuntimeOperationsException(new IllegalArgumentException(LocalizedStrings.MX4JModelMBean_MODELMBEANINFO_PARAMETER_CANT_BE_NULL.toLocalizedString()));
+      else
+         setModelMBeanInfo(info);
+   }
+
+   private Logger getLogger()
+   {
+      return Log.getLogger(getClass().getName());
+   }
+
+   public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception
+   {
+      if (m_canBeRegistered)
+      {
+         m_mbeanServer = server;
+         return name;
+      }
+      else
+      {
+         throw new MBeanRegistrationException(new IllegalStateException(LocalizedStrings.MX4JModelMBean_MODELMBEAN_CANNOT_BE_REGISTERED_UNTIL_SETMODELMBEANINFO_HAS_BEEN_CALLED.toLocalizedString()));
+      }
+   }
+
+   public void postRegister(Boolean registrationDone)
+   {
+      if (!registrationDone.booleanValue()) clear();
+   }
+
+   public void preDeregister() throws Exception
+   {
+   }
+
+   public void postDeregister()
+   {
+      clear();
+   }
+
+   private void clear()
+   {
+      m_mbeanServer = null;
+      m_managedResource = null;
+      m_modelMBeanInfo = null;
+      m_generalBroadcaster = null;
+      m_attributeChangeBroadcaster = null;
+      // PENDING: also remove generic listeners, attribute change listeners, log4j appenders...
+   }
+
+   public void setModelMBeanInfo(ModelMBeanInfo modelMBeanInfo) throws MBeanException, RuntimeOperationsException
+   {
+      if (modelMBeanInfo == null) throw new RuntimeOperationsException(new IllegalArgumentException(LocalizedStrings.MX4JModelMBean_MODELMBEANINFO_CANNOT_BE_NULL.toLocalizedString()));
+      if (!isModelMBeanInfoValid(modelMBeanInfo)) throw new RuntimeOperationsException(new IllegalArgumentException(LocalizedStrings.MX4JModelMBean_MODELMBEANINFO_IS_INVALID.toLocalizedString()));
+
+      m_modelMBeanInfo = (ModelMBeanInfo)modelMBeanInfo.clone();
+
+      Logger logger = getLogger();
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("ModelMBeanInfo successfully set to: " + m_modelMBeanInfo);
+      // Only now the MBean can be registered in the MBeanServer
+      m_canBeRegistered = true;
+   }
+
+   private boolean isModelMBeanInfoValid(ModelMBeanInfo info)
+   {
+      if (info == null || info.getClassName() == null) return false;
+      // PENDING: maybe more checks are needed
+      return true;
+   }
+
+   public void setManagedResource(Object resource, String resourceType) throws MBeanException, RuntimeOperationsException, InstanceNotFoundException, InvalidTargetObjectTypeException
+   {
+      if (resource == null) throw new RuntimeOperationsException(new IllegalArgumentException(LocalizedStrings.MX4JModelMBean_MANAGED_RESOURCE_CANNOT_BE_NULL.toLocalizedString()));
+      if (!isResourceTypeSupported(resourceType)) throw new InvalidTargetObjectTypeException(resourceType);
+
+      Logger logger = getLogger();
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Setting managed resource to be: " + resource);
+      m_managedResource = resource;
+   }
+
+   private boolean isResourceTypeSupported(String resourceType)
+   {
+      // For now only object reference is supported
+      return OBJECT_RESOURCE_TYPE.equals(resourceType);
+   }
+
+   private Object getManagedResource()
+   {
+      return m_managedResource;
+   }
+
+   public MBeanInfo getMBeanInfo()
+   {
+      return m_modelMBeanInfo == null ? null : (MBeanInfo)m_modelMBeanInfo.clone();
+   }
+
+   public void addAttributeChangeNotificationListener(NotificationListener listener, String attributeName, Object handback) throws MBeanException, RuntimeOperationsException, IllegalArgumentException
+   {
+      if (listener == null) throw new RuntimeOperationsException(new IllegalArgumentException(LocalizedStrings.MX4JModelMBean_LISTENER_CANNOT_BE_NULL.toLocalizedString()));
+      AttributeChangeNotificationFilter filter = new AttributeChangeNotificationFilter();
+      if (attributeName != null)
+      {
+         filter.enableAttribute(attributeName);
+      }
+      else
+      {
+         MBeanAttributeInfo[] ai = m_modelMBeanInfo.getAttributes();
+         for (int i = 0; i < ai.length; i++)
+         {
+            Descriptor d = ((ModelMBeanAttributeInfo)ai[i]).getDescriptor();
+            filter.enableAttribute((String)d.getFieldValue("name"));
+         }
+      }
+
+      getAttributeChangeBroadcaster().addNotificationListener(listener, filter, handback);
+
+      Logger logger = getLogger();
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Listener " + listener + " for attribute " + attributeName + " added successfully, handback is " + handback);
+   }
+
+   public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws IllegalArgumentException
+   {
+      m_generalBroadcaster.addNotificationListener(listener, filter, handback);
+   }
+
+   public MBeanNotificationInfo[] getNotificationInfo()
+   {
+      return m_modelMBeanInfo.getNotifications();
+   }
+
+   public void removeAttributeChangeNotificationListener(NotificationListener listener, String attributeName) throws RuntimeOperationsException, ListenerNotFoundException
+   {
+      try
+      {
+         removeAttributeChangeNotificationListener(listener, attributeName, null);
+      }
+      catch (MBeanException e)
+      {
+         throw new RuntimeOperationsException(new RuntimeException(e.getMessage()));
+      }
+   }
+
+   // Not in the spec but needed
+   private void removeAttributeChangeNotificationListener(NotificationListener listener, String attributeName, Object handback) throws MBeanException, RuntimeOperationsException, ListenerNotFoundException
+   {
+      if (listener == null) throw new RuntimeOperationsException(new IllegalArgumentException(LocalizedStrings.MX4JModelMBean_LISTENER_CANNOT_BE_NULL.toLocalizedString()));
+      AttributeChangeNotificationFilter filter = new AttributeChangeNotificationFilter();
+      if (attributeName != null)
+      {
+         filter.enableAttribute(attributeName);
+      }
+      else
+      {
+         MBeanAttributeInfo[] ai = m_modelMBeanInfo.getAttributes();
+         for (int i = 0; i < ai.length; i++)
+         {
+            Descriptor d = ((ModelMBeanAttributeInfo)ai[i]).getDescriptor();
+            filter.enableAttribute((String)d.getFieldValue("name"));
+         }
+      }
+
+      getAttributeChangeBroadcaster().removeNotificationListener(listener, filter, handback);
+
+      Logger logger = getLogger();
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Listener " + listener + " for attribute " + attributeName + " removed successfully, handback is " + handback);
+   }
+
+   public void removeNotificationListener(NotificationListener listener) throws RuntimeOperationsException, ListenerNotFoundException
+   {
+      m_generalBroadcaster.removeNotificationListener(listener);
+   }
+
+   public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws RuntimeOperationsException, ListenerNotFoundException
+   {
+      m_generalBroadcaster.removeNotificationListener(listener, filter, handback);
+   }
+
+   public void sendAttributeChangeNotification(Attribute oldAttribute, Attribute newAttribute) throws MBeanException, RuntimeOperationsException
+   {
+      if (oldAttribute == null || newAttribute == null) throw new RuntimeOperationsException(new IllegalArgumentException(LocalizedStrings.MX4JModelMBean_ATTRIBUTE_CANNOT_BE_NULL.toLocalizedString()));
+      if (!oldAttribute.getName().equals(newAttribute.getName())) throw new RuntimeOperationsException(new IllegalArgumentException(LocalizedStrings.MX4JModelMBean_ATTRIBUTE_NAMES_CANNOT_BE_DIFFERENT.toLocalizedString()));
+
+      // TODO: the source must be the object name of the MBean if the listener was registered through MBeanServer
+      Object oldValue = oldAttribute.getValue();
+      AttributeChangeNotification n = new AttributeChangeNotification(this,
+                                                                      1,
+                                                                      System.currentTimeMillis(),
+                                                                      "Attribute value changed",
+                                                                      oldAttribute.getName(),
+                                                                      oldValue == null ? null : oldValue.getClass().getName(),
+                                                                      oldValue,
+                                                                      newAttribute.getValue());
+      sendAttributeChangeNotification(n);
+   }
+
+   public void sendAttributeChangeNotification(AttributeChangeNotification notification) throws MBeanException, RuntimeOperationsException
+   {
+      if (notification == null) throw new RuntimeOperationsException(new IllegalArgumentException(LocalizedStrings.MX4JModelMBean_NOTIFICATION_CANNOT_BE_NULL.toLocalizedString()));
+
+      getAttributeChangeBroadcaster().sendNotification(notification);
+
+      Logger modelMBeanLogger = getModelMBeanLogger(notification.getType());
+      if (modelMBeanLogger != null) if (modelMBeanLogger.isEnabledFor(Logger.DEBUG)) modelMBeanLogger.debug("ModelMBean log: " + new Date() + " - " + notification);
+
+      Logger logger = getLogger();
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Attribute change notification " + notification + " sent");
+   }
+
+   public void sendNotification(String message) throws MBeanException, RuntimeOperationsException
+   {
+      Notification notification = new Notification("jmx.modelmbean.general", this, 1, message);
+      sendNotification(notification);
+   }
+
+   public void sendNotification(Notification notification) throws MBeanException, RuntimeOperationsException
+   {
+     if (m_generalBroadcaster != null) {
+       m_generalBroadcaster.sendNotification(notification);
+     }
+   }
+
+   public AttributeList getAttributes(String[] attributes)
+   {
+      if (attributes == null) throw new RuntimeOperationsException(new IllegalArgumentException(LocalizedStrings.MX4JModelMBean_ATTRIBUTE_NAMES_CANNOT_BE_NULL.toLocalizedString()));
+
+      Logger logger = getLogger();
+
+      AttributeList list = new AttributeList();
+      for (int i = 0; i < attributes.length; ++i)
+      {
+         String attrName = attributes[i];
+         Attribute attribute = null;
+         try
+         {
+            Object value = getAttribute(attrName);
+            attribute = new Attribute(attrName, value);
+            list.add(attribute);
+         }
+         catch (Exception x)
+         {
+            if (logger.isEnabledFor(Logger.TRACE)) logger.trace("getAttribute for attribute " + attrName + " failed", x);
+            // And go on with the next attribute
+         }
+      }
+      return list;
+   }
+
+   public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException
+   {
+      if (attribute == null) throw new RuntimeOperationsException(new IllegalArgumentException(LocalizedStrings.MX4JModelMBean_ATTRIBUTE_NAME_CANNOT_BE_NULL.toLocalizedString()));
+
+      Logger logger = getLogger();
+
+      // I want the real info, not its clone
+      ModelMBeanInfo info = getModelMBeanInfo();
+      if (info == null) throw new AttributeNotFoundException(LocalizedStrings.MX4JModelMBean_MODELMBEANINFO_IS_NULL.toLocalizedString());
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("ModelMBeanInfo is: " + info);
+
+      // This is a clone, we use it read only
+      ModelMBeanAttributeInfo attrInfo = info.getAttribute(attribute);
+      if (attrInfo == null) throw new AttributeNotFoundException(LocalizedStrings.MX4JModelMBean_CANNOT_FIND_MODELMBEANATTRIBUTEINFO_FOR_ATTRIBUTE_0.toLocalizedString(attribute));
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Attribute info is: " + attrInfo);
+      if (!attrInfo.isReadable()) throw new AttributeNotFoundException(LocalizedStrings.MX4JModelMBean_ATTRIBUTE_0_IS_NOT_READABLE.toLocalizedString(attribute));
+
+      // This returns a clone of the mbean descriptor, we use it read only
+      Descriptor mbeanDescriptor = info.getMBeanDescriptor();
+      if (mbeanDescriptor == null) throw new AttributeNotFoundException(LocalizedStrings.MX4JModelMBean_MBEAN_DESCRIPTOR_CANNOT_BE_NULL.toLocalizedString());
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBean descriptor is: " + mbeanDescriptor);
+
+      // This descriptor is a clone
+      Descriptor attributeDescriptor = attrInfo.getDescriptor();
+      if (attributeDescriptor == null) throw new AttributeNotFoundException(LocalizedStrings.MX4JModelMBean_ATTRIBUTE_DESCRIPTOR_FOR_ATTRIBUTE_0_CANNOT_BE_NULL.toLocalizedString(attribute));
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Attribute descriptor is: " + attributeDescriptor);
+
+      Object returnValue = null;
+
+      String lastUpdateField = "lastUpdatedTimeStamp";
+
+      int staleness = getStaleness(attributeDescriptor, mbeanDescriptor, lastUpdateField);
+
+      if (staleness == ALWAYS_STALE || staleness == STALE)
+      {
+         if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Value is stale");
+
+         String getter = (String)attributeDescriptor.getFieldValue("getMethod");
+         if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("getMethod field is: " + getter);
+         if (getter == null)
+         {
+            // No getter, use default value
+            returnValue = attributeDescriptor.getFieldValue("default");
+
+            if (returnValue != null)
+            {
+               // Check if the return type is of the same type
+               // As an extension allow covariant return type
+               Class returned = returnValue.getClass();
+               Class declared = loadClassWithContextClassLoader(attrInfo.getType());
+
+               checkAssignability(returned, declared);
+            }
+
+            if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("getAttribute for attribute " + attribute + " returns default value: " + returnValue);
+         }
+         else
+         {
+            if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Invoking attribute getter...");
+            // As an extension, allow attributes to be called on target objects also
+            Object target = resolveTargetObject(attributeDescriptor);
+            returnValue = invokeMethod(target, getter, new Class[0], new Object[0]);
+            if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Returned value is: " + returnValue);
+
+            if (returnValue != null)
+            {
+               // Check if the return type is of the same type
+               // As an extension allow covariant return type
+               Class returned = returnValue.getClass();
+               Class declared = loadClassWithContextClassLoader(attrInfo.getType());
+
+               checkAssignability(returned, declared);
+            }
+
+            // Cache the new value only if caching is needed
+            if (staleness != ALWAYS_STALE)
+            {
+               attributeDescriptor.setField("value", returnValue);
+               attributeDescriptor.setField(lastUpdateField, Long.valueOf(System.currentTimeMillis()));
+               if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Returned value has been cached");
+
+               // And now replace the descriptor with the updated clone
+               info.setDescriptor(attributeDescriptor, "attribute");
+            }
+
+            if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("getAttribute for attribute " + attribute + " returns invoked value: " + returnValue);
+         }
+      }
+      else
+      {
+         // Return cached value
+         returnValue = attributeDescriptor.getFieldValue("value");
+
+         if (returnValue != null)
+         {
+            // Check if the return type is of the same type
+            // As an extension allow covariant return type
+            Class returned = returnValue.getClass();
+            Class declared = loadClassWithContextClassLoader(attrInfo.getType());
+
+            checkAssignability(returned, declared);
+         }
+
+         if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("getAttribute for attribute " + attribute + " returns cached value: " + returnValue);
+      }
+
+      // Puff, everything went ok
+      return returnValue;
+   }
+
+   public AttributeList setAttributes(AttributeList attributes)
+   {
+      if (attributes == null) throw new RuntimeOperationsException(new IllegalArgumentException(LocalizedStrings.MX4JModelMBean_ATTRIBUTE_LIST_CANNOT_BE_NULL.toLocalizedString()));
+
+      Logger logger = getLogger();
+
+      AttributeList list = new AttributeList();
+      for (Iterator i = attributes.iterator(); i.hasNext();)
+      {
+         Attribute attribute = (Attribute)i.next();
+         String name = attribute.getName();
+         try
+         {
+            setAttribute(attribute);
+            list.add(attribute);
+         }
+         catch (Exception x)
+         {
+            if (logger.isEnabledFor(Logger.TRACE)) logger.trace("setAttribute for attribute " + name + " failed", x);
+            // And go on with the next one
+         }
+      }
+      return list;
+   }
+
+   public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException
+   {
+      if (attribute == null) throw new RuntimeOperationsException(new IllegalArgumentException(LocalizedStrings.MX4JModelMBean_ATTRIBUTE_CANNOT_BE_NULL.toLocalizedString()));
+
+      Logger logger = getLogger();
+
+      // No need to synchronize: I work mostly on clones
+      // I want the real info, not its clone
+      ModelMBeanInfo info = getModelMBeanInfo();
+      if (info == null) throw new AttributeNotFoundException(LocalizedStrings.MX4JModelMBean_MODELMBEANINFO_IS_NULL.toLocalizedString());
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("ModelMBeanInfo is: " + info);
+
+      String attrName = attribute.getName();
+      Object attrValue = attribute.getValue();
+
+      // This is a clone, we use it read only
+      ModelMBeanAttributeInfo attrInfo = info.getAttribute(attrName);
+      if (attrInfo == null) throw new AttributeNotFoundException(LocalizedStrings.MX4JModelMBean_CANNOT_FIND_MODELMBEANATTRIBUTEINFO_FOR_ATTRIBUTE_0.toLocalizedString(attrName));
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Attribute info is: " + attrInfo);
+
+      if (!attrInfo.isWritable()) throw new AttributeNotFoundException(LocalizedStrings.MX4JModelMBean_ATTRIBUTE_0_IS_NOT_WRITABLE.toLocalizedString(attrName));
+
+      // This returns a clone of the mbean descriptor, we use it read only
+      Descriptor mbeanDescriptor = info.getMBeanDescriptor();
+      if (mbeanDescriptor == null) throw new AttributeNotFoundException(LocalizedStrings.MX4JModelMBean_MBEAN_DESCRIPTOR_CANNOT_BE_NULL.toLocalizedString());
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBean descriptor is: " + mbeanDescriptor);
+
+      // This descriptor is a clone
+      Descriptor attributeDescriptor = attrInfo.getDescriptor();
+      if (attributeDescriptor == null) throw new AttributeNotFoundException(LocalizedStrings.MX4JModelMBean_ATTRIBUTE_DESCRIPTOR_FOR_ATTRIBUTE_0_CANNOT_BE_NULL.toLocalizedString(attrName));
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Attribute descriptor is: " + attributeDescriptor);
+
+      String lastUpdateField = "lastUpdatedTimeStamp";
+
+      Object oldValue = null;
+      try
+      {
+         oldValue = getAttribute(attrName);
+         if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Previous value of attribute " + attrName + ": " + oldValue);
+      }
+      catch (Exception x)
+      {
+         if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Cannot get previous value of attribute " + attrName, x);
+      }
+
+      // Check if setMethod is present
+      String method = (String)attributeDescriptor.getFieldValue("setMethod");
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("setMethod field is: " + method);
+      if (method != null)
+      {
+         Class declared = loadClassWithContextClassLoader(attrInfo.getType());
+         if (attrValue != null)
+         {
+            Class parameter = attrValue.getClass();
+            checkAssignability(parameter, declared);
+         }
+
+         // As an extension, allow attributes to be called on target objects also
+         Object target = resolveTargetObject(attributeDescriptor);
+         invokeMethod(target, method, new Class[]{declared}, new Object[]{attrValue});
+
+         // Cache the value only if currencyTimeLimit is not 0, ie it is not always stale
+         int staleness = getStaleness(attributeDescriptor, mbeanDescriptor, lastUpdateField);
+         if (staleness != ALWAYS_STALE)
+         {
+            attributeDescriptor.setField("value", attrValue);
+            attributeDescriptor.setField(lastUpdateField, Long.valueOf(System.currentTimeMillis()));
+            if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Attribute's value has been cached");
+         }
+         else
+         {
+            if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Always stale, avoiding to cache attribute's value");
+         }
+      }
+      else
+      {
+         if (attrValue != null)
+         {
+            Class parameter = attrValue.getClass();
+            Class declared = loadClassWithContextClassLoader(attrInfo.getType());
+
+            checkAssignability(parameter, declared);
+         }
+
+         // Always store the value in the descriptor: no setMethod
+         attributeDescriptor.setField("value", attrValue);
+      }
+
+      // And now replace the descriptor with the updated clone
+      info.setDescriptor(attributeDescriptor, "attribute");
+
+      // Send notifications to listeners
+      if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Sending attribute change notifications");
+      sendAttributeChangeNotification(new Attribute(attrName, oldValue), attribute);
+
+      // Persist this ModelMBean
+      boolean persistNow = shouldPersistNow(attributeDescriptor, mbeanDescriptor, lastUpdateField);
+      if (persistNow)
+      {
+         if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Persisting this ModelMBean...");
+         try
+         {
+            store();
+            if (logger.isEnabledFor(Logger.TRACE)) logger.trace("ModelMBean persisted successfully");
+         }
+         catch (Exception x)
+         {
+            logger.error(LocalizedStrings.MX4JModelMBean_CANNOT_STORE_MODELMBEAN_AFTER_SETATTRIBUTE, x);
+            if (x instanceof MBeanException)
+               throw (MBeanException)x;
+            else
+               throw new MBeanException(x);
+         }
+      }
+   }
+
+   public Object invoke(String method, Object[] arguments, String[] params) throws MBeanException, ReflectionException
+   {
+      if (method == null) throw new RuntimeOperationsException(new IllegalArgumentException(LocalizedStrings.MX4JModelMBean_METHOD_NAME_CANNOT_BE_NULL.toLocalizedString()));
+      if (arguments == null) arguments = new Object[0];
+      if (params == null) params = new String[0];
+
+      Logger logger = getLogger();
+
+      // Find operation descriptor
+      ModelMBeanInfo info = getModelMBeanInfo();
+      if (info == null) throw new MBeanException(new ServiceNotFoundException(LocalizedStrings.MX4JModelMBean_MODELMBEANINFO_IS_NULL.toLocalizedString()));
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("ModelMBeanInfo is: " + info);
+
+      // This is a clone, we use it read only
+      ModelMBeanOperationInfo operInfo = info.getOperation(method);
+      if (operInfo == null) throw new MBeanException(new ServiceNotFoundException(LocalizedStrings.MX4JModelMBean_CANNOT_FIND_MODELMBEANOPERATIONINFO_FOR_OPERATION_0.toLocalizedString(method)));
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Operation info is: " + operInfo);
+
+      // This descriptor is a clone
+      Descriptor operationDescriptor = operInfo.getDescriptor();
+      if (operationDescriptor == null) throw new MBeanException(new ServiceNotFoundException(LocalizedStrings.MX4JModelMBean_OPERATION_DESCRIPTOR_FOR_OPERATION_0_CANNOT_BE_NULL.toLocalizedString(method)));
+      String role = (String)operationDescriptor.getFieldValue("role");
+      if (role == null || !role.equals("operation")) throw new MBeanException(new ServiceNotFoundException(LocalizedStrings.MX4JModelMBean_OPERATION_DESCRIPTOR_FIELD_ROLE_MUST_BE_OPERATION_NOT_0.toLocalizedString(role)));
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Operation descriptor is: " + operationDescriptor);
+
+      // This returns a clone of the mbean descriptor, we use it read only
+      Descriptor mbeanDescriptor = info.getMBeanDescriptor();
+      if (mbeanDescriptor == null) throw new MBeanException(new ServiceNotFoundException(LocalizedStrings.MX4JModelMBean_MBEAN_DESCRIPTOR_CANNOT_BE_NULL.toLocalizedString()));
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBean descriptor is: " + mbeanDescriptor);
+
+      Object returnValue = null;
+
+      String lastUpdateField = "lastReturnedTimeStamp";
+
+      // Check if the method should be invoked given the cache settings
+      int staleness = getStaleness(operationDescriptor, mbeanDescriptor, lastUpdateField);
+
+      if (staleness == ALWAYS_STALE || staleness == STALE)
+      {
+         if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Value is stale");
+
+         // Find parameters classes
+         Class[] parameters = null;
+         try
+         {
+           parameters = Utils.loadClasses(Thread.currentThread().getContextClassLoader(), params);
+         }
+         catch (ClassNotFoundException x)
+         {
+            logger.error(LocalizedStrings.MX4JModelMBean_CANNOT_FIND_OPERATIONS_PARAMETER_CLASSES, x);
+            throw new ReflectionException(x);
+         }
+
+         if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Invoking operation...");
+
+         // Find target object
+         Object target = resolveTargetObject(operationDescriptor);
+         returnValue = invokeMethod(target, method, parameters, arguments);
+
+         if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Returned value is: " + returnValue);
+
+         if (returnValue != null)
+         {
+            Class parameter = returnValue.getClass();
+            Class declared = loadClassWithContextClassLoader(operInfo.getReturnType());
+
+            checkAssignability(parameter, declared);
+         }
+
+         // Cache the new value only if caching is needed
+         if (staleness != ALWAYS_STALE)
+         {
+            operationDescriptor.setField("lastReturnedValue", returnValue);
+            operationDescriptor.setField(lastUpdateField, Long.valueOf(System.currentTimeMillis()));
+            if (logger.isEnabledFor(Logger.TRACE))
+            {
+               logger.trace("Returned value has been cached");
+            }
+
+            // And now replace the descriptor with the updated clone
+            info.setDescriptor(operationDescriptor, "operation");
+         }
+
+         if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("invoke for operation " + method + " returns invoked value: " + returnValue);
+      }
+      else
+      {
+         // Return cached value
+         returnValue = operationDescriptor.getFieldValue("lastReturnedValue");
+
+         if (returnValue != null)
+         {
+            Class parameter = returnValue.getClass();
+            Class declared = loadClassWithContextClassLoader(operInfo.getReturnType());
+
+            checkAssignability(parameter, declared);
+         }
+
+         if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("invoke for operation " + method + " returns cached value: " + returnValue);
+      }
+
+      // As an extension, persist this model mbean also after operation invocation, but using only
+      // settings provided in the operation descriptor, without falling back to defaults set in
+      // the MBean descriptor
+      boolean persistNow = shouldPersistNow(operationDescriptor, null, lastUpdateField);
+      int impact = operInfo.getImpact();
+      if (persistNow && impact != MBeanOperationInfo.INFO)
+      {
+         if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Persisting this ModelMBean...");
+         try
+         {
+            store();
+            if (logger.isEnabledFor(Logger.TRACE)) logger.trace("ModelMBean persisted successfully");
+         }
+         catch (Exception x)
+         {
+            logger.error(LocalizedStrings.MX4JModelMBean_CANNOT_STORE_MODELMBEAN_AFTER_OPERATION_INVOCATION, x);
+            if (x instanceof MBeanException)
+               throw (MBeanException)x;
+            else
+               throw new MBeanException(x);
+         }
+      }
+
+      return returnValue;
+   }
+
+   private Object resolveTargetObject(Descriptor descriptor) throws MBeanException
+   {
+      Logger logger = getLogger();
+      Object target = descriptor.getFieldValue("targetObject");
+      if (logger.isEnabledFor(Logger.TRACE)) logger.trace("targetObject is: " + target);
+      if (target == null)
+      {
+         target = getManagedResource();
+      }
+      else
+      {
+         String targetObjectType = (String)descriptor.getFieldValue("targetObjectType");
+         if (logger.isEnabledFor(Logger.TRACE)) logger.trace("targetObjectType is: " + targetObjectType);
+         if (targetObjectType == null)
+         {
+            // Not defined, assume object reference
+            targetObjectType = OBJECT_RESOURCE_TYPE;
+         }
+
+         if (!isResourceTypeSupported(targetObjectType)) throw new MBeanException(new InvalidTargetObjectTypeException(targetObjectType));
+      }
+      return target;
+   }
+
+   public void load() throws MBeanException, RuntimeOperationsException, InstanceNotFoundException
+   {
+      PersisterMBean persister = findPersister();
+      if (persister != null)
+      {
+         ModelMBeanInfo info = (ModelMBeanInfo)persister.load();
+         setModelMBeanInfo(info);
+      }
+   }
+
+   public void store() throws MBeanException, RuntimeOperationsException, InstanceNotFoundException
+   {
+      PersisterMBean persister = findPersister();
+      if (persister != null)
+      {
+         // Take a clone to avoid synchronization problems
+         ModelMBeanInfo info = (ModelMBeanInfo)getMBeanInfo();
+         persister.store(info);
+      }
+   }
+
+   protected ClassLoaderRepository getClassLoaderRepository()
+   {
+      if (m_mbeanServer != null)
+         return m_mbeanServer.getClassLoaderRepository();
+      else
+         return null;
+   }
+
+
+   private boolean shouldPersistNow(Descriptor attribute, Descriptor mbean, String lastUpdateField)
+   {
+      int persist = getPersistPolicy(attribute, mbean);
+      if (persist == PERSIST_NO_MORE_OFTEN_THAN)
+      {
+         Long period = getFieldTimeValue(attribute, mbean, "persistPeriod");
+         long now = System.currentTimeMillis();
+         Long lastUpdate = (Long)attribute.getFieldValue(lastUpdateField);
+         if (now - lastUpdate.longValue() < period.longValue())
+            return false;
+         else
+            return true;
+      }
+      else if (persist == PERSIST_NEVER)
+      {
+         return false;
+      }
+      else if (persist == PERSIST_ON_TIMER)
+      {
+         return false;
+      }
+      else if (persist == PERSIST_ON_UPDATE)
+      {
+         return true;
+      }
+      else
+      {
+         throw new ImplementationException(LocalizedStrings.MX4JModelMBean_INVALID_PERSIST_VALUE.toLocalizedString());
+      }
+   }
+
+   private int getPersistPolicy(Descriptor descriptor, Descriptor mbean)
+   {
+      Logger logger = getLogger();
+
+      String persist = (String)descriptor.getFieldValue("persistPolicy");
+      if (persist == null && mbean != null) persist = (String)mbean.getFieldValue("persistPolicy");
+      if (persist == null)
+      {
+         if (logger.isEnabledFor(Logger.TRACE)) logger.trace("No persist policy defined, assuming Never");
+         return PERSIST_NEVER;
+      }
+      else
+      {
+         if (persist.equals("Never"))
+         {
+            if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Persist never");
+            return PERSIST_NEVER;
+         }
+         else if (persist.equals("OnUpdate"))
+         {
+            if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Persist on update");
+            return PERSIST_ON_UPDATE;
+         }
+         else if (persist.equals("OnTimer"))
+         {
+            if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Persist on update");
+            return PERSIST_ON_TIMER;
+         }
+         else if (persist.equals("NoMoreOftenThan"))
+         {
+            if (logger.isEnabledFor(Logger.TRACE))
+            {
+               Long period = getFieldTimeValue(descriptor, mbean, "persistPeriod");
+               logger.trace("Persist no more often than " + period);
+            }
+            return PERSIST_NO_MORE_OFTEN_THAN;
+         }
+         else
+         {
+            // Garbage, assuming Never
+            if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Invalid persist policy, assuming persist never");
+            return PERSIST_NEVER;
+         }
+      }
+   }
+
+   private int getStaleness(Descriptor attribute, Descriptor mbean, String lastUpdateField)
+   {
+      Logger logger = getLogger();
+
+      Long currencyTimeLimit = getFieldTimeValue(attribute, mbean, "currencyTimeLimit");
+      if (currencyTimeLimit == null)
+      {
+         // No time limit defined
+         if (logger.isEnabledFor(Logger.TRACE)) logger.trace("No currencyTimeLimit defined, assuming always stale");
+         return ALWAYS_STALE;
+      }
+      else
+      {
+         long ctl = currencyTimeLimit.longValue() * 1000;
+         if (logger.isEnabledFor(Logger.TRACE)) logger.trace("currencyTimeLimit is (ms): " + ctl);
+
+         if (ctl == 0)
+         {
+            // Never stale
+            if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Never stale");
+            return NEVER_STALE;
+         }
+         else if (ctl < 0) // this should be == -1 but the other cases are in the air
+         {
+            // Always stale
+            if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Always stale");
+            return ALWAYS_STALE;
+         }
+         else
+         {
+            Long timestamp = (Long)attribute.getFieldValue(lastUpdateField);
+            long luts = 0;
+
+            if (timestamp != null) luts = timestamp.longValue();
+            if (logger.isEnabledFor(Logger.DEBUG)) logger.debug(lastUpdateField + " is: " + luts);
+
+            long now = System.currentTimeMillis();
+            if (now < luts + ctl)
+            {
+               // Seems to be not stale, but has been set at least once ?
+               if (timestamp == null)
+               {
+                  // Return stale to call it the first time
+                  if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Stale since was never set");
+                  return STALE;
+               }
+               else
+               {
+                  if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Not stale");
+                  return NOT_STALE;
+               }
+            }
+            else
+            {
+               // Stale
+               if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Stale");
+               return STALE;
+            }
+         }
+      }
+   }
+
+   private Long getFieldTimeValue(Descriptor descriptor, Descriptor mbean, String field)
+   {
+      Logger logger = getLogger();
+
+      Object value = descriptor.getFieldValue(field);
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Descriptor's " + field + " field: " + value);
+
+      if (value == null && mbean != null)
+      {
+         value = mbean.getFieldValue(field);
+         if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBean's " + field + " field: " + value);
+         if (value == null) return null;
+      }
+
+      if (value instanceof Number) return Long.valueOf(((Number)value).longValue());
+
+      if (value instanceof String)
+      {
+         try
+         {
+            long ctl = Long.parseLong((String)value);
+            return Long.valueOf(ctl);
+         }
+         catch (NumberFormatException x)
+         {
+            return Long.valueOf(0);
+         }
+      }
+      return Long.valueOf(0);
+   }
+
+   private Object invokeMethod(Object target, String methodName, Class[] params, Object[] args) throws MBeanException, ReflectionException
+   {
+      // First try on this instance, then on the target
+      Object realTarget = null;
+      Method method = null;
+      try
+      {
+         realTarget = this;
+         method = realTarget.getClass().getMethod(methodName, params);
+      }
+      catch (NoSuchMethodException x)
+      {
+         realTarget = target;
+      }
+
+      if (realTarget == null) throw new MBeanException(new ServiceNotFoundException(LocalizedStrings.MX4JModelMBean_COULD_NOT_FIND_TARGET.toLocalizedString()));
+
+      if (method == null)
+      {
+         try
+         {
+            method = realTarget.getClass().getMethod(methodName, params);
+         }
+         catch (NoSuchMethodException x)
+         {
+            throw new ReflectionException(x);
+         }
+      }
+
+      try
+      {
+         Object value = method.invoke(realTarget, args);
+         Logger logger = getLogger();
+         if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Method invocation returned value: " + value);
+         return value;
+      }
+      catch (IllegalAccessException x)
+      {
+         throw new ReflectionException(x);
+      }
+      catch (IllegalArgumentException x)
+      {
+         throw new MBeanException(x);
+      }
+      catch (InvocationTargetException x)
+      {
+         Throwable t = x.getTargetException();
+         if (t instanceof Error)
+            throw new MBeanException(new RuntimeErrorException((Error)t));
+         else
+            throw new MBeanException((Exception)t);
+      }
+   }
+
+   private Logger getModelMBeanLogger(String notificationType) throws MBeanException
+   {
+      // Get a copy to avoid synchronization
+      ModelMBeanInfo info = getModelMBeanInfo();
+
+      // First look if there is a suitable notification descriptor, otherwise use MBean descriptor
+      Descriptor descriptor = null;
+      Logger modelMBeanLogger = null;
+      if (notificationType != null)
+      {
+         descriptor = info.getDescriptor(notificationType, "notification");
+         modelMBeanLogger = findLogger(descriptor);
+      }
+
+      if (modelMBeanLogger == null)
+      {
+         descriptor = info.getMBeanDescriptor();
+         modelMBeanLogger = findLogger(descriptor);
+         if (modelMBeanLogger != null) return modelMBeanLogger;
+      }
+
+      return null;
+   }
+
+   private Logger findLogger(Descriptor descriptor)
+   {
+      Logger logger = getLogger();
+
+      if (descriptor == null)
+      {
+         if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Can't find MBean logger, descriptor is null");
+         return null;
+      }
+
+      String log = (String)descriptor.getFieldValue("log");
+      String location = (String)descriptor.getFieldValue("logFile");
+
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Log fields: log=" + log + ", file=" + location);
+
+      if (log == null || !Boolean.valueOf(log).booleanValue())
+      {
+         if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Logging is not supported by this ModelMBean");
+         return null;
+      }
+      // Logger is supported, where log to ?
+      if (location == null)
+      {
+         // As an extension, see if the field logMBean has been defined
+         location = (String)descriptor.getFieldValue("logMBean");
+         if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Log fields: mbean=" + location);
+
+         if (location == null)
+         {
+            if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Logging is not supported by this ModelMBean");
+            return null;
+         }
+
+         // It seems that the user wants to delegate a registered mbean to log
+         try
+         {
+            ObjectName objectName = new ObjectName(location);
+            MBeanServer server = getMBeanServer();
+            if (server == null) throw new MBeanException(new IllegalStateException(LocalizedStrings.MX4JModelMBean_MX4JMODELMBEAN_IS_NOT_REGISTERED.toLocalizedString()));
+            if (server.isRegistered(objectName))
+            {
+               MBeanLogger l = new MBeanLogger(server, objectName);
+               if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("ModelMBean log supported by delegating to this MBean: " + objectName);
+               return l;
+            }
+
+            return null;
+         }
+         catch (MalformedObjectNameException x)
+         {
+            // Ah, was not a correct object name
+            if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Specified logMBean field does not contain a valid ObjectName: " + location);
+            return null;
+         }
+         catch (MBeanException x)
+         {
+            if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("logMBean field does not specify an MBean that supports logging delegation", x);
+            return null;
+         }
+      }
+      else
+      {
+         // User decided to log to a file
+         if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("ModelMBean log supported on file system");
+         return new FileLogger(location);
+      }
+   }
+
+   private NotificationBroadcasterSupport getAttributeChangeBroadcaster()
+   {
+      return m_attributeChangeBroadcaster;
+   }
+
+   private MBeanServer getMBeanServer()
+   {
+      return m_mbeanServer;
+   }
+
+   private ModelMBeanInfo getModelMBeanInfo()
+   {
+      // No cloning performed
+      return m_modelMBeanInfo;
+   }
+
+   private PersisterMBean findPersister() throws MBeanException, InstanceNotFoundException
+   {
+      Logger logger = getLogger();
+
+      ModelMBeanInfo info = getModelMBeanInfo();
+      if (info == null)
+      {
+         // Not yet initialized
+         if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Can't find persister, ModelMBeanInfo is null");
+         return null;
+      }
+      Descriptor mbeanDescriptor = info.getMBeanDescriptor();
+      if (mbeanDescriptor == null)
+      {
+         // This is normally should not happen if ModelMBeanInfoSupport is used
+         if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Can't find persister, MBean descriptor is null");
+         return null;
+      }
+
+      String location = (String)mbeanDescriptor.getFieldValue("persistLocation");
+      String name = (String)mbeanDescriptor.getFieldValue("persistName");
+      String mbeanName = (String)mbeanDescriptor.getFieldValue("name");
+      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Persistence fields: location=" + location + ", name=" + name);
+
+      if (mbeanName == null && name == null)
+      {
+         if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Persistence is not supported by this ModelMBean");
+         return null;
+      }
+
+      // Try to see if this mbean should delegate to another mbean
+      if (name != null)
+      {
+         try
+         {
+            ObjectName objectName = new ObjectName(name.trim());
+            // OK, a valid object name
+            MBeanServer server = getMBeanServer();
+            if (server == null) throw new MBeanException(new IllegalStateException(LocalizedStrings.MX4JModelMBean_MX4JMODELMBEAN_IS_NOT_REGISTERED.toLocalizedString()));
+
+            if (server.isRegistered(objectName) && server.isInstanceOf(objectName, PersisterMBean.class.getName()))
+            {
+               // OK, the given mbean is registered with this mbean server
+               PersisterMBean persister = new MBeanPersister(server, objectName);
+               if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Persistence is delegated to this MBean: " + objectName);
+               return persister;
+            }
+            else
+            {
+               throw new InstanceNotFoundException(objectName.toString());
+            }
+         }
+         catch (MalformedObjectNameException ignored)
+         {
+            // It does not delegates to another mbean, use default
+            if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Persistence is not delegated to another MBean");
+         }
+
+         // Default is serialization to file
+         FilePersister persister = new FilePersister(location, name);
+         if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Persistence is realized through file system in " + persister.getFileName());
+         return persister;
+      }
+      else
+      {
+         // Only location given, use MBean name
+         FilePersister persister = new FilePersister(location, mbeanName);
+         if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Persistence is realized through file system in " + persister.getFileName());
+         return persister;
+      }
+   }
+
+   private Class loadClassWithContextClassLoader(String name)
+   {
+      try
+      {
+         return Utils.loadClass(Thread.currentThread().getContextClassLoader(), name);
+      }
+      catch (ClassNotFoundException x)
+      {
+         Logger logger = getLogger();
+         if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Cannot find attribute's declared return class", x);
+         return null;
+      }
+   }
+
+   private void checkAssignability(Class parameter, Class declared) throws MBeanException
+   {
+      Logger logger = getLogger();
+
+      if (logger.isEnabledFor(Logger.DEBUG))
+      {
+         logger.debug("The class of the parameter is: " + parameter);
+         if (parameter != null) logger.debug("The classloder of the parameter's class is: " + parameter.getClassLoader());
+         logger.debug("The class declared as type of the attribute is: " + declared);
+         if (declared != null) logger.debug("The classloader of the declared parameter's class is: " + declared.getClassLoader());
+      }
+
+      boolean assignable = false;
+
+      if (declared == null || parameter == null)
+         assignable = false;
+      else if (declared == boolean.class && parameter == Boolean.class)
+         assignable = true;
+      else if (declared == byte.class && parameter == Byte.class)
+         assignable = true;
+      else if (declared == char.class && parameter == Character.class)
+         assignable = true;
+      else if (declared == short.class && parameter == Short.class)
+         assignable = true;
+      else if (declared == int.class && parameter == Integer.class)
+         assignable = true;
+      else if (declared == long.class && parameter == Long.class)
+         assignable = true;
+      else if (declared == float.class && parameter == Float.class)
+         assignable = true;
+      else if (declared == double.class && parameter == Double.class)
+         assignable = true;
+      else
+         assignable = declared.isAssignableFrom(parameter);
+
+      if (!assignable)
+      {
+         if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Parameter value's class and attribute's declared return class are not assignable");
+         throw new MBeanException(new InvalidAttributeValueException(LocalizedStrings.MX4JModelMBean_RETURNED_TYPE_AND_DECLARED_TYPE_ARE_NOT_ASSIGNABLE.toLocalizedString()));
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MX4JServerSocketFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MX4JServerSocketFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MX4JServerSocketFactory.java
new file mode 100644
index 0000000..139569f
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MX4JServerSocketFactory.java
@@ -0,0 +1,152 @@
+/*=========================================================================
+ *Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *All Rights Reserved.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.util.Properties;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.admin.DistributedSystemConfig;
+import com.gemstone.gemfire.admin.internal.InetAddressUtil;
+import com.gemstone.gemfire.distributed.internal.DistributionConfig;
+import com.gemstone.gemfire.internal.SocketCreator;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * Creates <code>ServerSockets</code> for JMX adaptors.
+ * <p>
+ * The interface {@link mx4j.tools.adaptor.AdaptorServerSocketFactory} is
+ * implemented in order to support securing of {@link 
+ * mx4j.tools.adaptor.http.HttpAdaptor}.
+ * <p>
+ * The interface {@link java.rmi.server.RMIServerSocketFactory} is implemented
+ * to support the securing of {@link 
+ * javax.management.remote.JMXConnectorServer}.  See {@link
+ * javax.management.remote.rmi.RMIConnectorServer} for the actual subclass that
+ * is used for the JMX RMI adaptor.
+ * <p>
+ * Complete info on JSSE, including debugging, can be found at
+ * <a href="http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/JSSERefGuide.html">
+ * http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/JSSERefGuide.html</a>
+ *
+ * @author    Kirk Lund
+ * @since     3.5 (old name was SSLAdaptorServerSocketFactory)
+ */
+public class MX4JServerSocketFactory 
+implements mx4j.tools.adaptor.AdaptorServerSocketFactory,
+           java.rmi.server.RMIServerSocketFactory {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  private static final int DEFAULT_BACKLOG = 50;
+  
+  private final SocketCreator socketCreator;
+  private String bindAddress = DistributedSystemConfig.DEFAULT_BIND_ADDRESS;
+  private int backlog = DEFAULT_BACKLOG;
+  
+  /**
+   * Constructs new instance of MX4JServerSocketFactory.
+   * 
+   * @param useSSL
+   *          true if ssl is to be enabled
+   * @param needClientAuth
+   *          true if client authentication is required
+   * @param protocols
+   *          space-delimited list of ssl protocols to use
+   * @param ciphers
+   *          space-delimited list of ssl ciphers to use
+   * @param gfsecurityProps
+   *          vendor properties passed in through gfsecurity.properties
+   */
+  public MX4JServerSocketFactory(boolean useSSL,
+                                       boolean needClientAuth,
+                                       String protocols,
+                                       String ciphers,
+                                       Properties gfsecurityProps) {
+    if (protocols == null || protocols.length() == 0) {
+      protocols = DistributionConfig.DEFAULT_SSL_PROTOCOLS;
+    }
+    if (ciphers == null || ciphers.length() == 0) {
+      ciphers = DistributionConfig.DEFAULT_SSL_CIPHERS;
+    }
+    this.socketCreator = SocketCreator.createNonDefaultInstance(
+        useSSL, needClientAuth, protocols, ciphers, gfsecurityProps);
+  }
+
+  /**
+   * Constructs new instance of MX4JServerSocketFactory.
+   * 
+   * @param useSSL
+   *          true if ssl is to be enabled
+   * @param needClientAuth
+   *          true if client authentication is required
+   * @param protocols
+   *          space-delimited list of ssl protocols to use
+   * @param ciphers
+   *          space-delimited list of ssl ciphers to use
+   * @param bindAddress
+   *          host or address to bind to (bind-address)
+   * @param backlog
+   *          how many connections are queued
+   * @param gfsecurityProps
+   *          vendor properties passed in through gfsecurity.properties
+   */
+  public MX4JServerSocketFactory(boolean useSSL,
+                                       boolean needClientAuth,
+                                       String protocols,
+                                       String ciphers,
+                                       String bindAddress, // optional for RMI impl
+                                       int backlog, // optional for RMI impl
+                                       Properties gfsecurityProps) {
+    this(useSSL, needClientAuth, protocols, ciphers, gfsecurityProps);
+    this.bindAddress = bindAddress;
+    this.backlog = backlog;
+  }
+
+  // -------------------------------------------------------------------------
+  //   mx4j.tools.adaptor.AdaptorServerSocketFactory impl...
+  // -------------------------------------------------------------------------
+  
+	public ServerSocket createServerSocket(int port, 
+                                         int backlog, 
+                                         String bindAddress) throws IOException {
+          if ("".equals(bindAddress)) {
+            return socketCreator.createServerSocket(
+              port, backlog);
+
+          } else {
+            return socketCreator.createServerSocket(
+              port, backlog, InetAddressUtil.toInetAddress(bindAddress));
+          }
+  }
+  
+  // -------------------------------------------------------------------------
+  //   java.rmi.server.RMIServerSocketFactory impl...
+  // -------------------------------------------------------------------------
+  
+   public ServerSocket createServerSocket(int port) throws IOException {
+     ServerSocket sock = null;    
+     if ("".equals(bindAddress)) {
+       sock = socketCreator.createServerSocket(port, this.backlog);
+     } else {
+       sock = socketCreator.createServerSocket(
+               port, this.backlog, InetAddressUtil.toInetAddress(this.bindAddress));
+     }
+     
+     if (logger.isDebugEnabled()) {
+      logger.debug("MX4JServerSocketFactory RMIServerSocketFactory, INetAddress {}, LocalPort {}, LocalSocketAddress {}",
+          sock.getInetAddress(), sock.getLocalPort(), sock.getLocalSocketAddress());
+     }
+     return sock;
+   }
+   
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MailManager.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MailManager.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MailManager.java
new file mode 100755
index 0000000..f454191
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/MailManager.java
@@ -0,0 +1,324 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Properties;
+
+import javax.mail.Message;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.SystemFailure;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage;
+
+/**
+ * Provides the ways to send emails to all the registered email id It also
+ * provides the way to add/remove email ids. Can be used to send email in case
+ * of any alerts raised / warning / failure in gemfire.
+ * 
+ * @author Harsh Khanna
+ * @since 5.1
+ */
+public class MailManager {
+
+  private static final Logger logger = LogService.getLogger();
+  
+  public MailManager() {
+  }
+
+  public MailManager(Properties mailProperties) {
+    setMailProperties(mailProperties);
+  }
+
+  public MailManager(File mailPropertiesFile) throws IOException {
+    Properties prop = new Properties();
+    FileInputStream fio = new FileInputStream(mailPropertiesFile);
+    try {
+      prop.load(fio);
+    }
+    finally {
+      fio.close();
+    }
+    setMailProperties(prop);
+  }
+
+  public MailManager(String mailHost, String mailFrom) {
+    this.mailHost = mailHost;
+    this.mailFrom = mailFrom;
+  }
+
+  /**
+   * Send email to all the registered email id with given subject and message
+   */
+  public void sendEmail(String subject, String message) {
+    processEmail(new EmailData(subject, message));
+  }
+
+  /**
+   * Send Emails to all the registered email id
+   * 
+   * @param emailData
+   *                Instance of EmailData
+   */
+  // Why a separate method & class EmailData needed??? 
+  private void processEmail(EmailData emailData) {
+    if (logger.isTraceEnabled()) {
+      logger.trace("Entered MailManager:processEmail");
+    }
+
+    if (mailHost == null || mailHost.length() == 0
+        || emailData == null || mailToAddresses.length == 0) {
+      logger.error(LocalizedMessage.create(LocalizedStrings.MailManager_REQUIRED_MAILSERVER_CONFIGURATION_NOT_SPECIFIED));
+      if (logger.isDebugEnabled()) {
+        logger.debug("Exited MailManager:processEmail: Not sending email as conditions not met");
+      }
+      return;
+    }
+
+    Session session = Session.getDefaultInstance(getMailHostConfiguration());
+    MimeMessage mimeMessage = new MimeMessage(session);
+    String subject = emailData.subject;
+    String message = emailData.message;
+    String mailToList = getMailToAddressesAsString();
+
+    try {
+      for (int i = 0; i < mailToAddresses.length; i++) {
+        mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(
+            mailToAddresses[i]));
+      }
+
+      if (subject == null) {
+        subject = LocalizedStrings.MailManager_ALERT_MAIL_SUBJECT.toLocalizedString();
+      }
+      mimeMessage.setSubject(subject);
+
+      if (message == null) {
+        message = "";
+      }
+      mimeMessage.setText(message);
+
+      Transport.send(mimeMessage);
+      logger.info(LocalizedMessage.create(
+          LocalizedStrings.MailManager_EMAIL_ALERT_HAS_BEEN_SENT_0_1_2,
+          new Object[] { mailToList, subject, message }));
+    } 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();
+      StringBuilder buf = new StringBuilder();
+      buf.append(LocalizedStrings.MailManager_AN_EXCEPTION_OCCURRED_WHILE_SENDING_EMAIL.toLocalizedString());
+      buf.append(LocalizedStrings.MailManager_UNABLE_TO_SEND_EMAIL_PLEASE_CHECK_YOUR_EMAIL_SETTINGS_AND_LOG_FILE.toLocalizedString());
+      buf.append("\n\n").append(LocalizedStrings.MailManager_EXCEPTION_MESSAGE_0.toLocalizedString(ex.getMessage()));
+      buf.append("\n\n").append(LocalizedStrings.MailManager_FOLLOWING_EMAIL_WAS_NOT_DELIVERED.toLocalizedString());
+      buf.append("\n\t").append(LocalizedStrings.MailManager_MAIL_HOST_0.toLocalizedString(mailHost));
+      buf.append("\n\t").append(LocalizedStrings.MailManager_FROM_0.toLocalizedString(mailFrom));
+      buf.append("\n\t").append(LocalizedStrings.MailManager_TO_0.toLocalizedString(mailToList));
+      buf.append("\n\t").append(LocalizedStrings.MailManager_SUBJECT_0.toLocalizedString(subject));
+      buf.append("\n\t").append(LocalizedStrings.MailManager_CONTENT_0.toLocalizedString(message));
+
+      logger.error(buf.toString(), ex);
+    }
+    if (logger.isTraceEnabled()) {
+      logger.trace("Exited MailManager:processEmail");
+    }
+  }
+
+  /**
+   * Not yet implemented
+   */
+  public void close() {
+  }
+
+  /**
+   * @return All the registered email id as string
+   */
+  private String getMailToAddressesAsString() {
+    StringBuffer mailToList = new StringBuffer();
+    for (int i = 0; i < mailToAddresses.length; i++) {
+      mailToList.append(mailToAddresses[i]);
+      mailToList.append(", ");
+    }
+    return mailToList.toString();
+  }
+
+  /**
+   * 
+   * @return Properties consisting mailHost and mailFrom property
+   */
+  private Properties getMailHostConfiguration() {
+    Properties result = new Properties();
+    if (mailHost == null) {
+      mailHost = "";
+    }
+    if (mailFrom == null) {
+      mailFrom = "";
+    }
+    result.setProperty("mail.host", mailHost);
+    result.put("mail.from", mailFrom);
+    return result;
+  }
+
+  /**
+   * 
+   * @param host
+   *                mail host server name
+   */
+  public void setMailHost(String host) {
+    this.mailHost = host;
+  }
+
+  /**
+   * 
+   * @return mail host server name
+   */
+  public String getMailHost() {
+    return this.mailHost;
+  }
+
+  /**
+   * 
+   * @param fromAddress
+   *                mailFrom email id
+   */
+  public void setMailFromAddress(String fromAddress) {
+    mailFrom = fromAddress;
+  }
+
+  /**
+   * 
+   * @return mailFrom email id
+   */
+  public String getMailFromAddress() {
+    return mailFrom;
+  }
+
+  /**
+   * add new mail id to ToList
+   */
+  public void addMailToAddress(String toAddress) {
+    mailToSet.add(toAddress);
+    mailToAddresses = getAllToAddresses();
+  }
+
+  /**
+   * remove given mail id from ToList
+   */
+  public void removeMailToAddress(String toAddress) {
+    mailToSet.remove(toAddress);
+    mailToAddresses = getAllToAddresses();
+  }
+
+  /**
+   * @return list all the registered email id
+   */
+  public String[] getAllToAddresses() {
+    return (String[])mailToSet.toArray(new String[0]);
+  }
+
+  /**
+   * remove all the registered email ids from ToList
+   */
+  public void removeAllMailToAddresses() {
+    mailToSet.clear();
+    mailToAddresses = new String[0];
+  }
+
+  /**
+   * Set the mail properties, e.g mail host, mailFrom, MailTo etc
+   */
+  public void setMailProperties(Properties mailProperties) {
+    mailHost = mailProperties.getProperty(PROPERTY_MAIL_HOST);
+    mailFrom = mailProperties.getProperty(PROPERTY_MAIL_FROM);
+    String mailList = mailProperties.getProperty(PROPERTY_MAIL_TO_LIST, "");
+    String split[] = mailList.split(",");
+    removeAllMailToAddresses();
+    for (int i = 0; i < split.length; i++) {
+      addMailToAddress(split[i].trim());
+    }
+  }
+
+  @Override
+  public String toString() {
+    StringBuffer buffer = new StringBuffer(200);
+    buffer.append("[Mail Host: ");
+    buffer.append(getMailHost());
+    buffer.append("]");
+    buffer.append(" [Mail From: ");
+    buffer.append(getMailFromAddress());
+    buffer.append("]");
+    buffer.append(" [Mail To: ");
+    if (mailToAddresses.length > 0) {
+
+      for (int i = 0; i < mailToAddresses.length; i++) {
+        buffer.append(mailToAddresses[i]);
+        buffer.append(", ");
+      }
+      buffer.replace(buffer.length() - 2, buffer.length(), "");
+    }
+    else {
+      buffer.append(" Undefined");
+    }
+    buffer.append("]");
+    return buffer.toString();
+  }
+
+  private HashSet mailToSet = new HashSet();
+
+  private String mailToAddresses[] = new String[0];
+
+  protected String mailHost;
+
+  protected String mailFrom;
+
+  public final static String PROPERTY_MAIL_HOST = "mail.host";
+
+  public final static String PROPERTY_MAIL_FROM = "mail.from";
+
+  public final static String PROPERTY_MAIL_TO_LIST = "mail.toList";
+
+  /**
+   * Incorporating subject and message of email
+   * 
+   * @author Harsh Khanna
+   * 
+   */
+  static private class EmailData {
+    String subject;
+
+    String message;
+
+    EmailData(String subject, String message) {
+      this.subject = subject;
+      this.message = message;
+    }
+  }
+
+  public static void main(String args[]) {
+    MailManager mailManager = new MailManager("mailsrv1.gemstone.com",
+        "hkhanna@gemstone.com");
+    mailManager.sendEmail("Alert!", "Test");
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/ManagedResource.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/ManagedResource.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/ManagedResource.java
new file mode 100755
index 0000000..a1dbbec
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/ManagedResource.java
@@ -0,0 +1,69 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+import javax.management.ObjectName;
+import javax.management.modelmbean.ModelMBean;
+
+/**
+ * Represents a component or resource that is managed by a 
+ * {@link javax.management.modelmbean.ModelMBean}.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ */
+public interface ManagedResource {
+  
+  /** 
+   * The prefix of MBean names. Note: this is NOT used by Members, Stats, or
+   * any other MBean that has it's own domain.
+   *
+   * @see #getMBeanName 
+   */
+  public static final String MBEAN_NAME_PREFIX = "GemFire:type=";
+
+  /** 
+   * Returns the name of the ModelMBean that will manage this
+   * resource.  They [some] are of the form
+   *
+   * <PRE>
+   * MBEAN_NAME_PREFIX + typeName + ",id=" + id
+   * </PRE>
+   *
+   * @see #MBEAN_NAME_PREFIX
+   */
+  public String getMBeanName();
+  
+  /** Returns the ModelMBean that is configured to manage this resource */
+  public ModelMBean getModelMBean();
+
+  /** Sets the ModelMBean that is configured to manage this resource */
+  public void setModelMBean(ModelMBean modelMBean);
+  
+  /** 
+   * Returns the enumerated ManagedResourceType of this resource.
+   *
+   * @see ManagedResourceType
+   */
+  public ManagedResourceType getManagedResourceType();
+
+  /**
+   * Returns the JMX <code>ObjectName</code> of this managed resource.
+   *
+   * @see #getMBeanName
+   */
+  public ObjectName getObjectName();
+ 
+  /**
+   * Perform any cleanup necessary before stopping management of this resource.
+   */
+  public void cleanupResource();
+  
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/ManagedResourceType.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/ManagedResourceType.java b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/ManagedResourceType.java
new file mode 100755
index 0000000..c11697a
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/admin/jmx/internal/ManagedResourceType.java
@@ -0,0 +1,201 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.admin.jmx.internal;
+
+/**
+ * Type-safe definition for ModelMBean managed resources.  The class type 
+ * ({@link #getClassTypeName}) must match the fully qualified class name listed
+ * in the type descriptor in mbeans-descriptors.xml.
+ *
+ * @author    Kirk Lund
+ * @since     3.5
+ *
+ */
+public class ManagedResourceType implements java.io.Serializable {
+  private static final long serialVersionUID = 3752874768667480449L;
+  
+  /** Agent managed resource type */
+  public static final ManagedResourceType AGENT = 
+      new ManagedResourceType("Agent", com.gemstone.gemfire.admin.jmx.Agent.class);
+
+  /** DistributedSystem managed resource type */
+  public static final ManagedResourceType DISTRIBUTED_SYSTEM = 
+      new ManagedResourceType("AdminDistributedSystem", com.gemstone.gemfire.admin.AdminDistributedSystem.class);
+
+  /** SystemMember managed resource type */
+  public static final ManagedResourceType SYSTEM_MEMBER = 
+      new ManagedResourceType("SystemMember", com.gemstone.gemfire.admin.SystemMember.class);
+
+  /** SystemMemberCache managed resource type */
+  public static final ManagedResourceType SYSTEM_MEMBER_CACHE = 
+      new ManagedResourceType("SystemMemberCache", com.gemstone.gemfire.admin.SystemMemberCache.class);
+
+  /** SystemMemberCache managed resource type */
+  public static final ManagedResourceType SYSTEM_MEMBER_REGION = 
+      new ManagedResourceType("SystemMemberRegion", com.gemstone.gemfire.admin.SystemMemberRegion.class);
+
+  /** SystemMemberCacheServer managed resource type */
+  public static final ManagedResourceType SYSTEM_MEMBER_CACHE_SERVER = 
+      new ManagedResourceType("SystemMemberCacheServer", com.gemstone.gemfire.admin.SystemMemberCacheServer.class);
+
+  /** CacheVm managed resource type */
+  public static final ManagedResourceType CACHE_VM = 
+      new ManagedResourceType("CacheVm", com.gemstone.gemfire.admin.CacheVm.class);
+
+  /** StatisticResource managed resource type */
+  public static final ManagedResourceType STATISTIC_RESOURCE = 
+      new ManagedResourceType("StatisticResource", com.gemstone.gemfire.admin.StatisticResource.class);
+
+  public static final ManagedResourceType GEMFIRE_HEALTH = 
+      new ManagedResourceType("GemFireHealth", com.gemstone.gemfire.admin.GemFireHealth.class);
+
+  public static final ManagedResourceType DISTRIBUTED_SYSTEM_HEALTH_CONFIG = 
+      new ManagedResourceType("DistributedSystemHealthConfig", com.gemstone.gemfire.admin.DistributedSystemHealthConfig.class);
+
+  public static final ManagedResourceType GEMFIRE_HEALTH_CONFIG = 
+      new ManagedResourceType("GemFireHealthConfig", com.gemstone.gemfire.admin.GemFireHealthConfig.class);
+
+  public static final ManagedResourceType DISTRIBUTION_LOCATOR = 
+      new ManagedResourceType("DistributionLocator", com.gemstone.gemfire.admin.DistributionLocator.class);
+
+  ////////////////////  Instance Fields  ////////////////////
+
+  /** The display-friendly name of this managed resource type. */
+  private final transient String name;
+  
+  /** 
+   * The interface/class used to externally represent this type. Note: this must 
+   * match the mbean type descriptor in mbeans-descriptors.xml.
+   */
+  private final transient Class clazz;
+  
+  // The 4 declarations below are necessary for serialization
+  /** int used as ordinal to represent this Scope */
+  public final int ordinal = nextOrdinal++;
+
+  private static int nextOrdinal = 0;
+  
+  private static final ManagedResourceType[] VALUES =
+    { AGENT, DISTRIBUTED_SYSTEM, SYSTEM_MEMBER,
+      SYSTEM_MEMBER_CACHE, SYSTEM_MEMBER_REGION,
+      SYSTEM_MEMBER_CACHE_SERVER, CACHE_VM,
+      STATISTIC_RESOURCE, GEMFIRE_HEALTH, DISTRIBUTED_SYSTEM_HEALTH_CONFIG, 
+      GEMFIRE_HEALTH_CONFIG, DISTRIBUTION_LOCATOR 
+    };
+
+  private Object readResolve() throws java.io.ObjectStreamException {
+    return VALUES[ordinal];  // Canonicalize
+  }
+  
+  /** Creates a new instance of ManagedResourceType. */
+  private ManagedResourceType(String name, Class clazz) {
+    this.name = name;
+    this.clazz = clazz;
+  }
+    
+  /** Returns the ManagedResourceType represented by specified ordinal */
+  public static ManagedResourceType fromOrdinal(int ordinal) {
+    return VALUES[ordinal];
+  }
+
+  /** Returns the display-friendly name of this managed resource type */
+  public String getName() {
+    return this.name;
+  }
+  
+  /** Returns the interface/class used to externally represent this type */
+  public Class getClassType() {
+    return this.clazz;
+  }
+  
+  /** 
+   * Returns the fully qualified name of the interface/class used to externally 
+   * represent this type 
+   */
+  public String getClassTypeName() {
+    return this.clazz.getName();
+  }
+  
+  /** Returns true if this is <code>AGENT</code>. */
+  public boolean isAgent() {
+    return this.equals(AGENT);
+  }
+    
+  /** Returns true if this is <code>DISTRIBUTED_SYSTEM</code>. */
+  public boolean isDistributedSystem() {
+    return this.equals(DISTRIBUTED_SYSTEM);
+  }
+    
+  /** Returns true if this is <code>SYSTEM_MEMBER</code>. */
+  public boolean isSystemMember() {
+    return this.equals(SYSTEM_MEMBER);
+  }
+    
+  /** Returns whether this is <code>STATISTIC_RESOURCE</code>. */
+  public boolean isStatisticResource() {
+    return this.equals(STATISTIC_RESOURCE);
+  }
+    
+  /** Return whether this is <code>GEMFIRE_HEALTH</code>. */
+  public boolean isGemFireHealth() {
+    return this.equals(GEMFIRE_HEALTH);
+  }
+
+  /** 
+   * Returns a string representation for this type.
+   */
+  @Override
+  public String toString() {
+      return this.name;
+  }
+  
+	/**
+	 * Indicates whether some other object is "equal to" this one.
+	 *
+	 * @param  other  the reference object with which to compare.
+	 * @return true if this object is the same as the obj argument;
+	 *         false otherwise.
+	 */
+  @Override
+	public boolean equals(Object other) {
+		if (other == this) return true;
+		if (other == null) return false;
+		if (!(other instanceof ManagedResourceType)) return  false;
+		final ManagedResourceType that = (ManagedResourceType) other;
+
+		if (this.name != that.name &&
+	  		!(this.name != null &&
+	  		this.name.equals(that.name))) return false;
+		if (this.clazz != that.clazz &&
+	  		!(this.clazz != null &&
+	  		this.clazz.equals(that.clazz))) return false;
+
+		return true;
+	}
+
+	/**
+	 * Returns a hash code for the object. This method is supported for the
+	 * benefit of hashtables such as those provided by java.util.Hashtable.
+	 *
+	 * @return the integer 0 if description is null; otherwise a unique integer.
+	 */
+  @Override
+	public int hashCode() {
+		int result = 17;
+		final int mult = 37;
+
+		result = mult * result + 
+			(this.name == null ? 0 : this.name.hashCode());
+		result = mult * result + 
+			(this.clazz == null ? 0 : this.clazz.hashCode());
+
+		return result;
+	}
+
+}
+


[20/51] [partial] incubator-geode git commit: Init

Posted by rv...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionAccessException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionAccessException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionAccessException.java
new file mode 100755
index 0000000..759f674
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionAccessException.java
@@ -0,0 +1,109 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import java.io.*;
+import java.util.*;
+import com.gemstone.gemfire.distributed.Role;
+import com.gemstone.gemfire.distributed.internal.membership.InternalRole;
+
+/**
+ * Indicates that an attempt to access the region has failed.  Failure is
+ * due to one or more missing {@link MembershipAttributes#getRequiredRoles 
+ * required roles}.  Region operations may throw this exception when the 
+ * {@link MembershipAttributes} have been configured with {@link 
+ * LossAction#NO_ACCESS} or {@link LossAction#LIMITED_ACCESS}.
+ *
+ * @author Kirk Lund
+ * @since 5.0
+ */
+public class RegionAccessException extends RegionRoleException {
+private static final long serialVersionUID = 3142958723089038406L;
+  
+  /** 
+   * Set of missing required roles causing access to the region to fail.
+   * missingRoles is transient to avoid NotSerializableException. See {@link
+   * #writeObject} and {@link #readObject} for custom serialization.
+   */
+  private transient Set missingRoles = Collections.EMPTY_SET;
+  
+  /** 
+   * Constructs a <code>RegionAccessException</code> with a message.
+   * @param s the String message
+   * @param regionFullPath full path of region for which access was attempted
+   * @param missingRoles the missing required roles that caused this exception
+   */
+  public RegionAccessException(String s, String regionFullPath, Set missingRoles) {
+    super(s, regionFullPath);
+    this.missingRoles = missingRoles;
+    if (this.missingRoles == null) {
+      this.missingRoles = Collections.EMPTY_SET;
+    }
+  }
+  
+  /** 
+   * Constructs a <code>RegionAccessException</code> with a message and
+   * a cause.
+   * @param s the String message
+   * @param regionFullPath full path of region for which access was attempted
+   * @param missingRoles the missing required roles that caused this exception
+   * @param ex the Throwable cause
+   */
+  public RegionAccessException(String s,  String regionFullPath, Set missingRoles, Throwable ex) {
+    super(s, regionFullPath, ex);
+    this.missingRoles = missingRoles;
+    if (this.missingRoles == null) {
+      this.missingRoles = Collections.EMPTY_SET;
+    }
+  }
+  
+  /** 
+   * Returns the missing required roles that caused this exception.
+   * @return the missing required roles that caused this exception
+   */
+  public Set getMissingRoles() {
+    return this.missingRoles;
+  }
+  
+  /** 
+   * Override writeObject which is used in serialization. Customize 
+   * serialization of this exception to avoid escape of InternalRole
+   * which is not Serializable. 
+   */
+  private void writeObject(java.io.ObjectOutputStream out)
+  throws IOException {
+    out.defaultWriteObject();
+    // transform roles to string names which are serializable...
+    Set roleNames = new HashSet(this.missingRoles.size());
+    for (Iterator iter = this.missingRoles.iterator(); iter.hasNext();) {
+      String name = ((Role)iter.next()).getName();
+      roleNames.add(name);
+    }
+    out.writeObject(roleNames);
+  }
+  
+  /** 
+   * Override readObject which is used in serialization. Customize 
+   * serialization of this exception to avoid escape of InternalRole
+   * which is not Serializable. 
+   */
+  private void readObject(java.io.ObjectInputStream in)
+  throws IOException, ClassNotFoundException {
+    in.defaultReadObject();
+    // transform string names which are serializable back into roles...
+    Set roleNames = (Set)in.readObject();
+    Set roles = new HashSet(roleNames.size());
+    for (Iterator iter = roleNames.iterator(); iter.hasNext();) {
+      String name = (String) iter.next();
+      roles.add(InternalRole.getRole(name));
+    }
+    this.missingRoles = roles;
+  }
+     
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionAttributes.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionAttributes.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionAttributes.java
new file mode 100644
index 0000000..b97e744
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionAttributes.java
@@ -0,0 +1,450 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import java.io.File;
+import java.util.Set;
+
+import com.gemstone.gemfire.cache.client.Pool;
+import com.gemstone.gemfire.compression.Compressor;
+
+/** Defines attributes for configuring a region.
+ * These are <code>EvictionAttributes</code>,
+ * <code>CacheListener</code>, <code>CacheLoader</code>, <code>CacheWriter</code>,
+ * scope, data policy, and expiration attributes
+ * for the region itself, expiration attributes for the region entries,
+ * and whether statistics are enabled for the region and its entries.
+ *
+ * To create an instance of this interface use {@link AttributesFactory#createRegionAttributes}.
+ *
+ * For compatibility rules and default values, see {@link AttributesFactory}.
+ *
+ * <p>Note that the <code>RegionAttributes</code> are not distributed with the region.
+ *
+ * @author Eric Zoerner
+ *
+ * @see AttributesFactory
+ * @see AttributesMutator
+ * @see Region#getAttributes
+ * @see com.gemstone.gemfire.cache.EvictionAttributes
+ * @since 2.0
+ */
+public interface RegionAttributes<K,V> {
+
+  /** Returns the cache loader associated with this region.
+   * @return the cache loader
+   */
+  public CacheLoader<K,V> getCacheLoader();
+
+  /** Returns the cache writer associated with this region.
+   * @return the cache writer
+   */
+  public CacheWriter<K,V> getCacheWriter();
+
+  /** Returns the class that the keys in this region are constrained to.
+   *
+   * @return the <code>Class</code> the keys must be an
+   * <code>instanceof</code>
+   */
+  public Class<K> getKeyConstraint();
+
+  /** Returns the class that the values in this region are constrained to.
+   *
+   * @return the <code>Class</code> the values must be an
+   * <code>instanceof</code>
+   */
+  
+  public Class<V> getValueConstraint();
+
+
+  /** Gets the <code>timeToLive</code> expiration attributes for the region as a whole.
+   * Default is 0 which indicates that no expiration of this type will happen.
+   * @return the timeToLive expiration attributes for this region
+   */
+  public ExpirationAttributes getRegionTimeToLive();
+
+  /** Gets the idleTimeout expiration attributes for the region as a whole.
+   * Default is 0 which indicates that no expiration of this type will happen.
+   * Note that the XML element that corresponds to this method "region-idle-time", does not include "out" in its name.
+   *
+   * @return the IdleTimeout expiration attributes for this region
+   */
+  public ExpirationAttributes getRegionIdleTimeout();
+
+  /** Gets the <code>timeToLive</code> expiration attributes for entries in this region.
+   * Default is 0 which indicates that no expiration of this type is set.
+   * @return the timeToLive expiration attributes for entries in this region
+   */
+  public ExpirationAttributes getEntryTimeToLive();
+
+  /** Gets the <code>idleTimeout</code> expiration attributes for entries in this region.
+   * Default is 0 which indicates that no expiration of this type is set.
+   * Note that the XML element that corresponds to this method "entry-idle-time", does not include "out" in its name.
+   * @return the idleTimeout expiration attributes for entries in this region
+   */
+  public ExpirationAttributes getEntryIdleTimeout();
+
+  /** Gets the <code>entryTimeToLive</code> <code>CustomExpiry</code>, if any 
+   * for entries in this region
+   * @return the entryTimeToLive CustomExpiry for entries in this region
+   */
+  public CustomExpiry<K,V> getCustomEntryTimeToLive();
+  
+  /** Gets the <code>idleTimeout</code> <code>CustomExpiry</code>, if any 
+   * for entries in this region
+   * @return the idleTimeout CustomExpiry for entries in this region
+   */
+  public CustomExpiry<K,V> getCustomEntryIdleTimeout();
+
+  /**
+   * Gets the flag telling a region to ignore JTA transactions.
+   * Default value is set to false.
+   * @since 5.0
+   */
+  public boolean getIgnoreJTA();
+
+  /** Returns the type of mirroring for this region.
+   *
+   * @return the region's <code>MirrorType</code>
+   * @deprecated as of GemFire 5.0, use {@link #getDataPolicy} instead.
+   */
+  @Deprecated
+  public MirrorType getMirrorType();
+
+
+  /** Returns the data policy for this region.
+   * Default value of DataPolicy is set to 'Normal'. Please refer the gemfire documentation for more details on this.
+   *
+   * @return the region's <code>DataPolicy</code>
+   * @since 5.0
+   */
+  public DataPolicy getDataPolicy();
+
+  /** Returns the scope of the region.
+   *  Default scope is DISTRIBUTED_NO_ACK. Please refer the gemfire documentation for more details on this.
+   * @return the region's <code>Scope</code>
+   */
+  public Scope getScope();
+
+
+ /**
+   * Attributes that control the size of the <code>Region</code> using an
+   * {@link EvictionAlgorithm} and a {@link EvictionAction}.
+   * @return the region's EvictionAttributes
+   */
+  public EvictionAttributes getEvictionAttributes();
+
+  /** Returns the cache listener for the region.
+   * @throws IllegalStateException if more than one cache listener exists on this attributes
+   * @return the region's <code>CacheListener</code>
+   * @deprecated as of GemFire 5.0, use {@link #getCacheListeners} instead
+   */
+  @Deprecated
+  public CacheListener<K,V> getCacheListener();
+
+  /** Returns an array of all the cache listeners on this attributes.
+   * Modifications to the returned array will not effect the attributes.
+   * @return the region's <code>CacheListener</code>s; an empty array if no listeners
+   * @since 5.0
+   */
+  public CacheListener<K,V>[] getCacheListeners();
+
+  // MAP ATTRIBUTES
+
+
+  /** Returns the initial capacity of the entries map.
+   * Default is 16.
+   * @return the initial capacity of the entries map
+   * @see java.util.HashMap
+   */
+  public int getInitialCapacity();
+
+  /** Returns the load factor of the entries map.
+   * Default is 0.75.
+   * @return the load factor of the entries map
+   * @see java.util.HashMap
+   */
+  public float getLoadFactor();
+
+  /**
+   * Returns true if this member is configured to be lock grantor for the
+   * region. Result will always be false if the scope is not
+   * <code>Scope.GLOBAL</code>.
+   * <p>
+   * This attribute does not indicate whether or not this member is currently
+   * lock grantor. It only indicates that at the time of region creation, this
+   * member should attempt to become lock grantor.
+   * Default value is false.
+   *
+   * @return true if this member is configured to be lock grantor for the region
+   * @see AttributesFactory
+   * @see Region#becomeLockGrantor
+   */
+  public boolean isLockGrantor();
+
+  /**
+   * Returns true if multicast communications are enabled for this region.
+   * Multicast must also be enabled in the DistributedSystem.
+   * Default value is set to false.
+   *
+   * @since 5.0
+   * @return true if this region is configured to allow use of multicast
+   * for distributed messaging
+   * @see AttributesFactory#setMulticastEnabled
+   */
+  public boolean getMulticastEnabled();
+
+  /** Returns the concurrencyLevel of the entries map.
+   * Default is 16.
+   * @return the concurrencyLevel
+   * @see AttributesFactory
+   */
+  public int getConcurrencyLevel();
+
+  /**
+   * Returns whether or not a persistent backup should be made of the
+   * region (as opposed to just writing the overflow data to disk).
+   *
+   * @since 3.2
+   * @deprecated as of GemFire 5.0, use {@link DataPolicy#PERSISTENT_REPLICATE} instead
+   */
+  @Deprecated
+  public boolean getPersistBackup();
+
+  /**
+   * Returns the <code>DiskWriteAttributes</code> that configure how
+   * the region is written to disk.
+   *
+   * @since 3.2
+   * @deprecated as of 6.5 use {@link #getDiskStoreName} instead.
+   */
+  @Deprecated
+  public DiskWriteAttributes getDiskWriteAttributes();
+
+  /**
+   * Returns the directories to which the region's data are written.  If
+   * multiple directories are used, GemFire will attempt to distribute the
+   * data evenly amongst them.
+   *
+   * @since 3.2
+   * @deprecated as of 6.5 use {@link DiskStore#getDiskDirs} instead.
+   */
+  @Deprecated
+  public File[] getDiskDirs();
+
+  /**
+   * Returns the value of <code>IndexMaintenanceSynchronous</code> which
+   * specifies whether the region indexes are updated synchronously when a
+   * region is modified or asynchronously in a background thread. 
+   * Default value is true.
+   *
+   * @since 4.0
+   */
+  public boolean getIndexMaintenanceSynchronous();
+
+  /**
+   * Returns the <code>PartitionAttributes</code> that configure how
+   * the region is partitioned.
+   *
+   * @since 5.0
+   */
+  public PartitionAttributes getPartitionAttributes();
+
+  /**
+   * Returns the <code>MembershipAttributes</code> that configure required
+   * roles for reliable access to the region.
+   *
+   * @since 5.0
+   */
+  public MembershipAttributes getMembershipAttributes();
+
+  /**
+   * Returns the <code>SubscriptionAttributes</code> that configure
+   * how this region behaves as a subscriber to remote caches.
+   *
+   * @since 5.0
+   */
+  public SubscriptionAttributes getSubscriptionAttributes();
+
+
+  // STATISTICS
+  /** Returns whether the statistics are enabled for this region and its
+   * entries.
+   * Default is false.
+   * @return true if statistics are enabled
+   */
+  public boolean getStatisticsEnabled();
+
+  /**
+   * Returns whether or not acks are sent after an update is processed.
+   * @return True if acks are sent after updates are processed;
+   *         false if acks are sent before updates are processed.
+   *
+   * @since 4.1
+   * @deprecated Setting early ack no longer has any effect.
+   */
+  @Deprecated
+  public boolean getEarlyAck();
+
+  /**
+   * Returns whether or not this region is a publisher. Publishers are regions
+   * on which distributed write operations are done.
+   * @return True if a publisher;
+   *         false if not (default).
+   *
+   * @since 4.2.3
+   * @deprecated as of 6.5
+   */
+  public boolean getPublisher();
+
+  /**
+   * Returns whether or not conflation is enabled for sending
+   * messages from a cache server to its clients.
+   *
+   * Note: This parameter is only valid for cache server to client
+   * communication. It has no effect in peer to peer communication.
+   *
+   * @deprecated as of GemFire 5.0, use {@link #getEnableSubscriptionConflation} instead
+   #
+   * @return True if conflation is enabled;
+   *         false conflation is not enabled (default).
+   *
+   * @since 4.2
+   */
+  @Deprecated
+  public boolean getEnableConflation();
+
+  /**
+   * Returns whether or not conflation is enabled for sending
+   * messages from a cache server to its clients.
+   *
+   * Note: This parameter is only valid for cache server to client
+   * communication. It has no effect in peer to peer communication.
+   *
+   * @return True if conflation is enabled;
+   *         false conflation is not enabled (default).
+   *
+   * @since 5.0
+   * @deprecated as of GemFire 5.0, use {@link #getEnableSubscriptionConflation} instead
+   */
+  @Deprecated
+  public boolean getEnableBridgeConflation();
+
+  /**
+   * Returns whether or not conflation is enabled for sending
+   * messages from a cache server to its clients.
+   *
+   * Note: This parameter is only valid for cache server to client
+   * communication. It has no effect in peer to peer communication.
+   * 
+   * Default is false.
+   *
+   * @return True if conflation is enabled;
+   *         false conflation is not enabled (default).
+   *
+   * @since 5.7
+   */
+  public boolean getEnableSubscriptionConflation();
+  /**
+   * Returns whether or not async conflation is enabled for sending
+   * messages to async peers.
+   * 
+   * Default is false.
+   *
+   * @return True if async conflation is enabled;
+   *         false async conflation is not enabled (default).
+   *
+   * @since 4.2.3
+   */
+  public boolean getEnableAsyncConflation();
+
+  /**
+   * Returns the sizes of the disk directories in megabytes
+   * @return int[] sizes of the disk directories
+   * @deprecated as of 6.5 use {@link DiskStore#getDiskDirSizes} instead.
+   */
+  public int[] getDiskDirSizes();
+  
+  
+  /**
+   * Returns the name of the {@link Pool} that this region
+   * will use to communicate with servers, if any.
+   * Returns <code>null</code> if this region communicates with peers.
+   * @return the name of the client-server {@link Pool}
+   * this region will use for server communication; <code>null</code> is returned if
+   * the region communicates with peers.
+   * @since 5.7
+   */
+  public String getPoolName();
+  
+  /**
+   * Returns whether or not cloning is enabled on region.
+   * Default is false.
+   *
+   * @return True if cloning is enabled;
+   *         false cloning is not enabled (default).
+   *
+   * @since 6.1
+   */
+  public boolean getCloningEnabled();
+
+  /**
+   * Returns the name of the {@link DiskStore} that this region belongs
+   * to, if any.
+   * Returns <code>null</code> if this region belongs to default {@link DiskStore}.
+   * @return the name of the {@link DiskStore} of this region; 
+   * <code>null</code> is returned if this region belongs to default 
+   * {@link DiskStore}.
+   * @since 6.5
+   */
+  public String getDiskStoreName();
+  
+  /**
+   * Returns true if configured synchronous disk writes.
+   * Default is set to true.
+   * 
+   * @return Returns true if writes to disk are synchronous and false otherwise
+   * @since 6.5 
+   */
+  public boolean isDiskSynchronous();
+  
+  /**
+   * Returns a set of gatewaysenderIds
+   */
+  public Set<String> getGatewaySenderIds();
+  
+  /**
+   * Returns a set of AsyncEventQueueIds added to the region
+   */
+  public Set<String> getAsyncEventQueueIds();
+  
+  /**
+   * Returns true if concurrent update checks are turned on for this region.
+   * <p>
+   * When this is enabled, concurrent updates will be conflated if they are
+   * applied out of order.
+   * <p>
+   * All members must set this attribute the same.
+   * 
+   * Default is set to true.
+   * 
+   * @since 7.0
+   * @return true if concurrent update checks are turned on
+   */
+  public boolean getConcurrencyChecksEnabled();
+  
+  /**
+   * Returns the compressor used by this region's entry values.
+   * @since 8.0
+   * @return null if the region does not have compression enabled.
+   */
+  public Compressor getCompressor();
+}
+
+
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionDestroyedException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionDestroyedException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionDestroyedException.java
new file mode 100644
index 0000000..9bdef20
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionDestroyedException.java
@@ -0,0 +1,43 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * Indicates that the region has been destroyed. Further operations
+ * on the region object are not allowed.
+ *
+ * @author Eric Zoerner
+ *
+ * @since 2.0
+ */
+public class RegionDestroyedException extends CacheRuntimeException {
+private static final long serialVersionUID = 319804842308010754L;
+  private String regionFullPath;
+  
+  /** Constructs a <code>RegionDestroyedException</code> with a message.
+   * @param msg the String message
+   */
+  public RegionDestroyedException(String msg, String regionFullPath) {
+    super(msg);
+    this.regionFullPath = regionFullPath;
+  }
+  
+  /** Constructs a <code>RegionDestroyedException</code> with a message and
+   * a cause.
+   * @param s the String message
+   * @param ex the Throwable cause
+   */
+  public RegionDestroyedException(String s, String regionFullPath, Throwable ex) {
+    super(s, ex);
+    this.regionFullPath = regionFullPath;
+  }
+  
+  public String getRegionFullPath() {
+    return this.regionFullPath;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionDistributionException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionDistributionException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionDistributionException.java
new file mode 100755
index 0000000..a03f979
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionDistributionException.java
@@ -0,0 +1,114 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import java.io.*;
+import java.util.*;
+import com.gemstone.gemfire.distributed.Role;
+import com.gemstone.gemfire.distributed.internal.membership.InternalRole;
+
+/**
+ * Indicates that an attempt to send a distributed cache event to one or more
+ * {@link MembershipAttributes#getRequiredRoles required roles} may have
+ * failed.  Failure may be caused by departure of one or more required roles
+ * while sending the message to them.  If the region scope is {@linkplain 
+ * com.gemstone.gemfire.cache.Scope#DISTRIBUTED_NO_ACK DISTRIBUTED_NO_ACK} or
+ * {@linkplain com.gemstone.gemfire.cache.Scope#GLOBAL GLOBAL} then failure
+ * may be caused by one or more required roles not acknowledging receipt of
+ * the message.
+ *
+ * @author Kirk Lund
+ * @since 5.0
+ */
+public class RegionDistributionException extends RegionRoleException {
+private static final long serialVersionUID = -5950359426786805646L;
+  
+  /** 
+   * Set of missing required roles causing access to the region to fail.
+   * failedRoles is transient to avoid NotSerializableException. See {@link
+   * #writeObject} and {@link #readObject} for custom serialization.
+   */
+  private transient Set failedRoles = Collections.EMPTY_SET;
+  
+  /** 
+   * Constructs a <code>RegionDistributionException</code> with a message.
+   * @param s the String message
+   * @param regionFullPath full path of region for which access was attempted
+   * @param failedRoles the required roles that caused this exception
+   */
+  public RegionDistributionException(String s, String regionFullPath, Set failedRoles) {
+    super(s, regionFullPath);
+    this.failedRoles = failedRoles;
+    if (this.failedRoles == null) {
+      this.failedRoles = Collections.EMPTY_SET;
+    }
+  }
+  
+  /** 
+   * Constructs a <code>RegionDistributionException</code> with a message and
+   * a cause.
+   * @param s the String message
+   * @param regionFullPath full path of region for which access was attempted
+   * @param failedRoles the required roles that caused this exception
+   * @param ex the Throwable cause
+   */
+  public RegionDistributionException(String s,  String regionFullPath, Set failedRoles, Throwable ex) {
+    super(s, regionFullPath, ex);
+    this.failedRoles = failedRoles;
+    if (this.failedRoles == null) {
+      this.failedRoles = Collections.EMPTY_SET;
+    }
+  }
+  
+  /** 
+   * Returns the required roles that caused this exception. One or more
+   * roles failed to receive a cache distribution message or acknowledge
+   * receipt of that message.
+   * @return the required roles that caused this exception
+   */
+  public Set getFailedRoles() {
+    return this.failedRoles;
+  }
+  
+  /** 
+   * Override writeObject which is used in serialization. Customize 
+   * serialization of this exception to avoid escape of InternalRole
+   * which is not Serializable. 
+   */
+  private void writeObject(java.io.ObjectOutputStream out)
+  throws IOException {
+    out.defaultWriteObject();
+    // transform roles to string names which are serializable...
+    Set roleNames = new HashSet(this.failedRoles.size());
+    for (Iterator iter = this.failedRoles.iterator(); iter.hasNext();) {
+      String name = ((Role)iter.next()).getName();
+      roleNames.add(name);
+    }
+    out.writeObject(roleNames);
+  }
+  
+  /** 
+   * Override readObject which is used in serialization. Customize 
+   * serialization of this exception to avoid escape of InternalRole
+   * which is not Serializable. 
+   */
+  private void readObject(java.io.ObjectInputStream in)
+  throws IOException, ClassNotFoundException {
+    in.defaultReadObject();
+    // transform string names which are serializable back into roles...
+    Set roleNames = (Set)in.readObject();
+    Set roles = new HashSet(roleNames.size());
+    for (Iterator iter = roleNames.iterator(); iter.hasNext();) {
+      String name = (String) iter.next();
+      roles.add(InternalRole.getRole(name));
+    }
+    this.failedRoles = roles;
+  }
+     
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionEvent.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionEvent.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionEvent.java
new file mode 100644
index 0000000..eee2c17
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionEvent.java
@@ -0,0 +1,32 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/** Contains information about an event affecting a region, including
+ * its identity and the circumstances of the event.
+ * This is passed in to <code>CacheListener</code> and <code>CacheWriter</code>.
+ *
+ * @author Eric Zoerner
+ *
+ *
+ * @see CacheListener
+ * @see CacheWriter
+ * @see EntryEvent
+ * @since 2.0
+ */
+public interface RegionEvent<K,V> extends CacheEvent<K,V> {
+  
+  /**
+   * Return true if this region was destroyed but is being reinitialized,
+   * for example if a snapshot was just loaded. Can only return true for
+   * an event related to region destruction.
+   */
+  public boolean isReinitializing();
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionExistsException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionExistsException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionExistsException.java
new file mode 100644
index 0000000..e3e89c6
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionExistsException.java
@@ -0,0 +1,56 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+/**
+ * Indicates that the requested region already exists when a region is
+ * being created.
+ *
+ * @author Eric Zoerner
+ *
+ * 
+ * @see Region#createSubregion
+ * @see Cache#createRegion
+ * @since 2.0
+ */
+public class RegionExistsException extends CacheException {
+private static final long serialVersionUID = -5643670216230359426L;
+  private transient Region region;
+  
+  /**
+   * Constructs an instance of <code>RegionExistsException</code> with the specified Region.
+   * @param rgn the Region that exists
+   */
+  public RegionExistsException(Region rgn) {
+    super(rgn.getFullPath());
+    this.region = rgn;
+  }
+  
+  /**
+   * Constructs an instance of <code>RegionExistsException</code> with the specified detail message
+   * and cause.
+   * @param rgn the Region that exists
+   * @param cause the causal Throwable
+   */
+  public RegionExistsException(Region rgn, Throwable cause) {
+    super(rgn.getFullPath(), cause);
+    this.region = rgn;
+  }
+  
+  
+  /**
+   * Return the Region that already exists which prevented region creation.
+   * @return the Region that already exists, or null if this exception has
+   * been serialized, in which {@link Throwable#getMessage } will return the
+   * pathFromRoot for the region that exists.
+   */
+  public Region getRegion() {
+    return this.region;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionFactory.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionFactory.java
new file mode 100644
index 0000000..7de43a7
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionFactory.java
@@ -0,0 +1,893 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import java.io.File;
+import java.util.Properties;
+
+import com.gemstone.gemfire.cache.client.PoolManager;
+import com.gemstone.gemfire.compression.Compressor;
+import com.gemstone.gemfire.distributed.LeaseExpiredException;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+
+/**
+ * <code>RegionFactory</code> is used to create {@link Region regions}
+ * in a {@link Cache cache}.
+ * Instances of this interface can be created:
+<ul>
+<li>using a {@link RegionShortcut shortcut} by calling {@link Cache#createRegionFactory(RegionShortcut)} which will initialize the factory with the shortcut's region attributes
+<li>using a named region attribute by calling {@link Cache#createRegionFactory(String)} which will initialize the factory the named region attributes
+<li>using a region attribute instance by calling {@link Cache#createRegionFactory(RegionAttributes)} which will initialize the factory with the given region attributes
+<li>by calling {@link Cache#createRegionFactory()} which will initialize the factory with defaults
+</ul>
+Once the factory has been created it can be customized with its setter methods.
+<p>
+The final step is to produce a {@link Region} by calling {@link #create(String)}.
+<p>Example: Create a replicate region with a CacheListener
+<PRE>
+  Cache c = new CacheFactory().create();
+  // Create replicate region.
+  // Add a cache listener before creating region
+  Region r = c.createRegionFactory(REPLICATE)
+    .addCacheListener(myListener)
+    .create("replicate");
+</PRE>
+<p>Example: Create a partition region that has redundancy
+<PRE>
+  Cache c = new CacheFactory().create();
+  // Create replicate region.
+  // Add a cache listener before creating region
+  Region r = c.createRegionFactory(PARTITION_REDUNDANT)
+    .create("partition");
+</PRE>
+ *
+ * @author Mitch Thomas
+ * @since 5.0
+ */
+
+public class RegionFactory<K,V>
+{
+  private final AttributesFactory<K,V> attrsFactory;
+  private final GemFireCacheImpl cache;
+
+  /**
+   * For internal use only.
+   * @since 6.5
+   */
+  protected RegionFactory(GemFireCacheImpl cache) {
+    this.cache = cache;
+    this.attrsFactory = new AttributesFactory<K,V>();
+  }
+
+  /**
+   * For internal use only.
+   * @since 6.5
+   */
+  protected RegionFactory(GemFireCacheImpl cache, RegionShortcut pra) {
+    this.cache = cache;
+    RegionAttributes ra = cache.getRegionAttributes(pra.toString());
+    if (ra == null) {
+      throw new IllegalStateException("The region shortcut " + pra
+                                      + " has been removed.");
+    }
+    this.attrsFactory = new AttributesFactory<K,V>(ra);
+  }
+
+  /**
+   * For internal use only.
+   * @since 6.5
+   */
+  protected RegionFactory(GemFireCacheImpl cache, RegionAttributes ra) {
+    this.cache = cache;
+    this.attrsFactory = new AttributesFactory<K,V>(ra);
+  }
+
+  /**
+   * For internal use only.
+   * @since 6.5
+   */
+  protected RegionFactory(GemFireCacheImpl cache, String regionAttributesId) {
+    this.cache = cache;
+    RegionAttributes<K,V> ra = getCache().getRegionAttributes(regionAttributesId);
+    if (ra == null) {
+      throw new IllegalStateException(LocalizedStrings.RegionFactory_NO_ATTRIBUTES_ASSOCIATED_WITH_0.toLocalizedString(regionAttributesId));
+    }
+    this.attrsFactory = new AttributesFactory<K,V>(ra);
+  }
+
+  /**
+   * Constructs a RegionFactory by creating a DistributedSystem and a Cache. If
+   * no DistributedSystem exists it creates a DistributedSystem with default
+   * configuration, otherwise it uses the existing DistributedSystem. The
+   * default Region configuration is used.
+   *
+   * @throws CacheException
+   *           if unable to connect the DistributedSystem or create a Cache
+   * @deprecated as of 6.5 use {@link Cache#createRegionFactory()} instead.
+   */
+  @Deprecated
+  public RegionFactory() throws CacheWriterException, RegionExistsException,
+    TimeoutException {
+    this((GemFireCacheImpl)new CacheFactory().create());
+  }
+
+  /**
+   * Constructs a RegionFactory by creating a DistributedSystem and a Cache. If
+   * no DistributedSystem exists it creates a DistributedSystem with default
+   * configuration, otherwise it uses the existing DistributedSystem. The Region
+   * configuration is initialized using the provided RegionAttributes.
+   *
+   * @throws CacheException
+   *           if unable to connect the DistributedSystem or create a Cache
+   * @deprecated as of 6.5 use {@link Cache#createRegionFactory(RegionAttributes)} instead.
+   */
+  @Deprecated
+  public RegionFactory(RegionAttributes<K,V> regionAttributes)
+    throws CacheWriterException, RegionExistsException, TimeoutException {
+    this((GemFireCacheImpl)new CacheFactory().create(), regionAttributes);
+  }
+
+  /**
+   * Constructs a RegionFactory by creating a DistributedSystem and a Cache. If
+   * no DistributedSystem exists it creates a DistributedSystem with default
+   * configuration, otherwise it uses the existing DistributedSystem. The Region
+   * configuration is initialized using the RegionAttributes identified in the
+   * cache.xml file by the provided identifier.
+   *
+   * @param regionAttributesId
+   *          that identifies a set of RegionAttributes in the cache-xml file.
+   * @see Cache#getRegionAttributes
+   * @throws IllegalArgumentException
+   *           if there are no attributes associated with the id
+   * @throws CacheException
+   *           if unable to connect the DistributedSystem or create a Cache
+   * @deprecated as of 6.5 use {@link Cache#createRegionFactory(String)} instead.
+   */
+  @Deprecated
+  public RegionFactory(String regionAttributesId) throws CacheWriterException,
+               RegionExistsException, TimeoutException {
+    this((GemFireCacheImpl)new CacheFactory().create(), regionAttributesId);
+  }
+
+  /**
+   * Constructs a RegionFactory by creating a DistributedSystem and a Cache. If
+   * a DistributedSystem already exists with the same properties it uses that
+   * DistributedSystem, otherwise a DistributedSystem is created using the
+   * provided properties. The default Region configuration is used.
+   *
+   * @param distributedSystemProperties
+   *          an instance of Properties containing
+   *          <code>DistributedSystem</code configuration
+   * @throws CacheException if unable to connect the DistributedSystem or create a Cache
+   * @deprecated as of 6.5 use {@link CacheFactory#CacheFactory(Properties)} and {@link Cache#createRegionFactory()} instead.
+   */
+  @Deprecated
+  public RegionFactory(Properties distributedSystemProperties)
+    throws CacheWriterException, RegionExistsException, TimeoutException {
+    this((GemFireCacheImpl)new CacheFactory(distributedSystemProperties).create());
+  }
+
+  /**
+   * Constructs a RegionFactory by creating a DistributedSystem and a Cache. If
+   * a DistributedSystem already exists with the same properties it uses that
+   * DistributedSystem, otherwise a DistributedSystem is created using the
+   * provided properties. The initial Region configuration is set using the
+   * RegionAttributes provided.
+   *
+   * @param distributedSystemProperties
+   *          properties used to either find or create a DistributedSystem.
+   * @param regionAttributes
+   *          the initial Region configuration for this RegionFactory.
+   * @throws CacheException
+   *           if unable to connect the DistributedSystem or create a Cache
+   * @deprecated as of 6.5 use {@link CacheFactory#CacheFactory(Properties)} and {@link Cache#createRegionFactory(RegionAttributes)} instead.
+   */
+  @Deprecated
+  public RegionFactory(Properties distributedSystemProperties,
+      RegionAttributes<K,V> regionAttributes) throws CacheWriterException,
+      RegionExistsException, TimeoutException {
+    this((GemFireCacheImpl)new CacheFactory(distributedSystemProperties).create(), regionAttributes);
+  }
+
+  /**
+   * Constructs a RegionFactory by creating a DistributedSystem and a Cache. If
+   * a DistributedSystem already exists whose properties match those provied, it
+   * uses that DistributedSystem. The Region configuration is initialized using
+   * the RegionAttributes identified in the cache.xml file by the provided
+   * identifier.
+   *
+   * @param distributedSystemProperties
+   *          properties used to either find or create a DistributedSystem.
+   * @param regionAttributesId
+   *          the identifier for set of RegionAttributes in the cache.xml file
+   *          used as the initial Region configuration for this RegionFactory.
+   * @throws IllegalArgumentException
+   *           if there are no attributes associated with the id
+   *
+   * @throws CacheException
+   *           if unable to connect the DistributedSystem or create a Cache
+   * @deprecated as of 6.5 use {@link CacheFactory#CacheFactory(Properties)} and {@link Cache#createRegionFactory(String)} instead.
+   *
+   */
+  @Deprecated
+  public RegionFactory(Properties distributedSystemProperties,
+      String regionAttributesId) throws CacheWriterException,
+      RegionExistsException, TimeoutException {
+    this((GemFireCacheImpl)new CacheFactory(distributedSystemProperties).create(), regionAttributesId);
+  }
+
+  /**
+   * Returns the cache used by this factory.
+   */
+  private synchronized GemFireCacheImpl getCache() {
+    return this.cache;
+  }
+  
+  /**
+   * Sets the cache loader for the next <code>RegionAttributes</code> created.
+   *
+   * @param cacheLoader
+   *          the cache loader or null if no loader
+   * @return a reference to this RegionFactory object
+   * @see AttributesFactory#setCacheLoader
+   *
+   */
+  public RegionFactory<K,V> setCacheLoader(CacheLoader<K,V> cacheLoader)
+  {
+    this.attrsFactory.setCacheLoader(cacheLoader);
+    return this;
+  }
+
+  /**
+   * Sets the cache writer for the next <code>RegionAttributes</code> created.
+   *
+   * @param cacheWriter
+   *          the cache writer or null if no cache writer
+   * @return a reference to this RegionFactory object
+   * @see AttributesFactory#setCacheWriter
+   */
+  public RegionFactory<K,V> setCacheWriter(CacheWriter<K,V> cacheWriter)
+  {
+    this.attrsFactory.setCacheWriter(cacheWriter);
+    return this;
+  }
+
+  /**
+   * Adds a cache listener to the end of the list of cache listeners on this factory.
+   * @param aListener the cache listener to add
+   * @return a reference to this RegionFactory object
+   * @throws IllegalArgumentException if <code>aListener</code> is null
+   * @see AttributesFactory#addCacheListener
+   */
+  public RegionFactory<K,V> addCacheListener(CacheListener<K,V> aListener)
+  {
+    this.attrsFactory.addCacheListener(aListener);
+    return this;
+  }
+
+  /**
+   * Removes all cache listeners and then adds each listener in the specified array.
+   * for the next <code>RegionAttributes</code> created.
+   * @param newListeners a possibly null or empty array of listeners to add to this factory.
+   * @return a reference to this RegionFactory object
+   * @throws IllegalArgumentException if the <code>newListeners</code> array has a null element
+   * @see AttributesFactory#initCacheListeners
+   */
+  public RegionFactory<K,V> initCacheListeners(CacheListener<K,V>[] newListeners)
+  {
+    this.attrsFactory.initCacheListeners(newListeners);
+    return this;
+  }
+
+  /**
+   * Sets the eviction attributes that controls growth of the Region to be created.
+   *
+   * @param evictionAttributes for the Region to create
+   * @return a reference to this RegionFactory object
+   */
+  public RegionFactory<K,V> setEvictionAttributes(EvictionAttributes evictionAttributes) {
+    this.attrsFactory.setEvictionAttributes(evictionAttributes);
+    return this;
+  }
+
+  /**
+   * Sets the idleTimeout expiration attributes for region entries for the next
+   * <code>RegionAttributes</code> created.
+   * Note that the XML element that corresponds to this method "entry-idle-time", does not include "out" in its name.
+   *
+   * @param idleTimeout
+   *          the idleTimeout ExpirationAttributes for entries in this region
+   * @return a reference to this RegionFactory object
+   * @throws IllegalArgumentException
+   *           if idleTimeout is null
+   * @see AttributesFactory#setEntryIdleTimeout
+   */
+  public RegionFactory<K,V> setEntryIdleTimeout(ExpirationAttributes idleTimeout)
+  {
+    this.attrsFactory.setEntryIdleTimeout(idleTimeout);
+    return this;
+  }
+
+  /**
+   * Sets the custom idleTimeout for the next <code>RegionAttributes</code>
+   * created.
+   * 
+   * @param custom the custom method
+   * @return the receiver
+   * @see AttributesFactory#setCustomEntryIdleTimeout(CustomExpiry)
+   */
+  public RegionFactory<K,V> setCustomEntryIdleTimeout(CustomExpiry<K,V> custom) {
+    this.attrsFactory.setCustomEntryIdleTimeout(custom);
+    return this;
+  }
+  
+  /**
+   * Sets the timeToLive expiration attributes for region entries for the next
+   * <code>RegionAttributes</code> created.
+   *
+   * @param timeToLive
+   *          the timeToLive ExpirationAttributes for entries in this region
+   * @return a reference to this RegionFactory object
+   * @throws IllegalArgumentException
+   *           if timeToLive is null
+   * @see AttributesFactory#setEntryTimeToLive
+   */
+  public RegionFactory<K,V> setEntryTimeToLive(ExpirationAttributes timeToLive)
+  {
+    this.attrsFactory.setEntryTimeToLive(timeToLive);
+    return this;
+  }
+
+  /**
+   * Sets the custom timeToLive expiration method for the next 
+   * <code>RegionAttributes</code> created.
+   * @param custom the custom method
+   * @return the receiver
+   * @see AttributesFactory#setCustomEntryTimeToLive(CustomExpiry)
+   */
+  public RegionFactory<K,V> setCustomEntryTimeToLive(CustomExpiry<K,V> custom) {
+    this.attrsFactory.setCustomEntryTimeToLive(custom);
+    return this;
+  }
+  
+  /**
+   * Sets the idleTimeout expiration attributes for the region itself for the
+   * next <code>RegionAttributes</code> created.
+   * Note that the XML element that corresponds to this method "region-idle-time", does not include "out" in its name.
+   *
+   * @param idleTimeout
+   *          the ExpirationAttributes for this region idleTimeout
+   * @return a reference to this RegionFactory object
+   * @throws IllegalArgumentException
+   *           if idleTimeout is null
+   * @see AttributesFactory#setRegionIdleTimeout
+   */
+  public RegionFactory<K,V> setRegionIdleTimeout(ExpirationAttributes idleTimeout)
+  {
+    this.attrsFactory.setRegionIdleTimeout(idleTimeout);
+    return this;
+  }
+
+  /**
+   * Sets the timeToLive expiration attributes for the region itself for the
+   * next <code>RegionAttributes</code> created.
+   *
+   * @param timeToLive
+   *          the ExpirationAttributes for this region timeToLive
+   * @return a reference to this RegionFactory object
+   * @throws IllegalArgumentException
+   *           if timeToLive is null
+   * @see AttributesFactory#setRegionTimeToLive
+   */
+  public RegionFactory<K,V> setRegionTimeToLive(ExpirationAttributes timeToLive)
+  {
+    this.attrsFactory.setRegionTimeToLive(timeToLive);
+    return this;
+  }
+
+  /**
+   * Sets the scope for the next <code>RegionAttributes</code> created.
+   *
+   * @param scopeType
+   *          the type of Scope to use for the region
+   * @return a reference to this RegionFactory object
+   * @throws IllegalArgumentException
+   *           if scopeType is null
+   * @see AttributesFactory#setScope
+   */
+  public RegionFactory<K,V> setScope(Scope scopeType)
+  {
+    this.attrsFactory.setScope(scopeType);
+    return this;
+  }
+
+  /**
+   * Sets the data policy for the next <code>RegionAttributes</code> created.
+   *
+   * @param dataPolicy
+   *          The type of mirroring to use for the region
+   * @return a reference to this RegionFactory object
+   * @throws IllegalArgumentException
+   *           if dataPolicy is null
+   * @see AttributesFactory#setDataPolicy
+   */
+  public RegionFactory<K,V> setDataPolicy(DataPolicy dataPolicy)
+  {
+    this.attrsFactory.setDataPolicy(dataPolicy);
+    return this;
+  }
+
+  /**
+   * Sets for this region whether or not acks are sent after an update is processed.
+   *
+   * @param earlyAck set to true for the acknowledgement to be sent prior to processing the update
+   * @return a reference to this RegionFactory object
+   * @see AttributesFactory#setEarlyAck(boolean)
+   * @deprecated As of 6.5 this setting no longer has any effect.
+   */
+  @Deprecated
+  public RegionFactory<K,V> setEarlyAck(boolean earlyAck) {
+    this.attrsFactory.setEarlyAck(earlyAck);
+    return this;
+  }
+
+  /**
+   * Sets whether distributed operations on this region should attempt to use multicast.
+   *
+   * @since 5.0
+   * @param value true to enable multicast
+   * @return a reference to this RegionFactory object
+   * @see AttributesFactory#setMulticastEnabled(boolean)
+   */
+  public RegionFactory<K,V> setMulticastEnabled(boolean value) {
+    this.attrsFactory.setMulticastEnabled(value);
+    return this;
+  }
+  
+  /**
+   * Sets the pool name attribute.
+   * This causes regions that use these attributes
+   * to be a client region which communicates with the
+   * servers that the connection pool communicates with.
+   * <p>If this attribute is set to <code>null</code> or <code>""</code>
+   * then the connection pool is disabled causing regions that use these attributes
+   * to be communicate with peers instead of servers.
+   * <p>The named connection pool must exist on the cache at the time these
+   * attributes are used to create a region. See {@link PoolManager#createFactory}
+   * for how to create a connection pool.
+   * @param poolName the name of the connection pool to use; if <code>null</code>
+   * or <code>""</code> then the connection pool attribute is disabled for regions
+   * using these attributes.
+   * @return a reference to this RegionFactory object
+   * @throws IllegalStateException if a cache loader or cache writer has already
+   * been set.
+   * @since 5.7
+   */
+  public RegionFactory<K,V> setPoolName(String poolName) {
+    this.attrsFactory.setPoolName(poolName);
+    return this;
+  }
+
+  /**
+   * Sets whether or not this region should be considered a publisher.
+   * @since 5.0
+   * @deprecated as of 6.5
+   */
+  @Deprecated
+  public void setPublisher(boolean v) {
+//    this.attrsFactory.setPublisher(v);
+  }
+  /**
+   * Sets whether or not conflation is enabled for sending messages
+   * to async peers.
+   * @param value true to enable async conflation
+   * @return a reference to this RegionFactory object
+   * @see AttributesFactory#setEnableAsyncConflation(boolean)
+   */
+  public RegionFactory<K,V> setEnableAsyncConflation(boolean value) {
+    this.attrsFactory.setEnableAsyncConflation(value);
+    return this;
+  }
+
+  /**
+   * Sets whether or not conflation is enabled for sending messages
+   * from a cache server to its clients.
+   * @param value true to enable subscription conflation
+   * @return a reference to this RegionFactory object
+   * @see AttributesFactory#setEnableSubscriptionConflation(boolean)
+   */
+  public RegionFactory<K,V> setEnableSubscriptionConflation(boolean value) {
+    this.attrsFactory.setEnableSubscriptionConflation(value);
+    return this;
+  }
+
+  /**
+   * Sets the key constraint for the next <code>RegionAttributes</code>
+   * created. Keys in the region will be constrained to this class (or
+   * subclass). Any attempt to store a key of an incompatible type in the region
+   * will cause a <code>ClassCastException</code> to be thrown.
+   *
+   * @param keyConstraint
+   *          The Class to constrain the keys to, or null if no constraint
+   * @return a reference to this RegionFactory object
+   * @throws IllegalArgumentException
+   *           if <code>keyConstraint</code> is a class denoting a primitive
+   *           type
+   * @see AttributesFactory#setKeyConstraint
+   */
+  public RegionFactory<K,V> setKeyConstraint(Class<K> keyConstraint)
+  {
+    this.attrsFactory.setKeyConstraint(keyConstraint);
+    return this;
+  }
+
+  /**
+   * Sets the value constraint for the next <code>RegionAttributes</code>
+   * created. Values in the region will be constrained to this class (or
+   * subclass). Any attempt to store a value of an incompatible type in the
+   * region will cause a <code>ClassCastException</code> to be thrown.
+   *
+   * @param valueConstraint
+   *          The Class to constrain the values to, or null if no constraint
+   * @return a reference to this RegionFactory object
+   * @throws IllegalArgumentException
+   *           if <code>valueConstraint</code> is a class denoting a primitive
+   *           type
+   * @see AttributesFactory#setValueConstraint
+   */
+  public RegionFactory<K,V> setValueConstraint(Class<V> valueConstraint)
+  {
+    this.attrsFactory.setValueConstraint(valueConstraint);
+    return this;
+  }
+
+  /**
+   * Sets the entry initial capacity for the next <code>RegionAttributes</code>
+   * created. This value is used in initializing the map that holds the entries.
+   *
+   * @param initialCapacity
+   *          the initial capacity of the entry map
+   * @return a reference to this RegionFactory object
+   * @throws IllegalArgumentException if initialCapacity is negative.
+   * @see java.util.HashMap
+   * @see AttributesFactory#setInitialCapacity
+   */
+  public RegionFactory<K,V> setInitialCapacity(int initialCapacity)
+  {
+    this.attrsFactory.setInitialCapacity(initialCapacity);
+    return this;
+  }
+
+  /**
+   * Sets the entry load factor for the next <code>RegionAttributes</code>
+   * created. This value is used in initializing the map that holds the entries.
+   *
+   * @param loadFactor
+   *          the load factor of the entry map
+   * @return a reference to this RegionFactory object
+   * @throws IllegalArgumentException
+   *           if loadFactor is nonpositive
+   * @see java.util.HashMap
+   * @see AttributesFactory#setLoadFactor
+   */
+  public RegionFactory<K,V> setLoadFactor(float loadFactor)
+  {
+    this.attrsFactory.setLoadFactor(loadFactor);
+    return this;
+  }
+
+  /**
+   * Sets the concurrency level tof the next <code>RegionAttributes</code>
+   * created. This value is used in initializing the map that holds the entries.
+   *
+   * @param concurrencyLevel
+   *          the concurrency level of the entry map
+   * @return a reference to this RegionFactory object
+   * @throws IllegalArgumentException
+   *           if concurrencyLevel is nonpositive
+   * @see AttributesFactory#setConcurrencyLevel
+   */
+  public RegionFactory<K,V> setConcurrencyLevel(int concurrencyLevel)
+  {
+    this.attrsFactory.setConcurrencyLevel(concurrencyLevel);
+    return this;
+  }
+
+  /**
+   * Enables a versioning system that detects concurrent modifications and
+   * ensures that region contents are consistent across the distributed
+   * system.  This setting must be the same in each member having the region.
+   *
+   * @since 7.0
+   * @param enabled whether concurrency checks should be enabled for the region
+   * @see AttributesFactory#setConcurrencyChecksEnabled
+   */
+  public RegionFactory<K,V> setConcurrencyChecksEnabled(boolean enabled)
+  {
+    this.attrsFactory.setConcurrencyChecksEnabled(enabled);
+    return this;
+  }
+
+  /**
+   * Returns whether or not disk writes are asynchronous.
+   *
+   * @return a reference to this RegionFactory object
+   * @see Region#writeToDisk
+   * @see AttributesFactory#setDiskWriteAttributes
+   * @deprecated as of 6.5 use {@link #setDiskStoreName} instead
+   *
+   */
+  @Deprecated
+  public RegionFactory<K,V> setDiskWriteAttributes(DiskWriteAttributes attrs)
+  {
+    this.attrsFactory.setDiskWriteAttributes(attrs);
+    return this;
+  }
+
+  /**
+   * Sets the DiskStore name attribute.
+   * This causes the region to belong to the DiskStore.
+   * @param name the name of the diskstore
+   * @return a reference to this RegionFactory object
+   * @since 6.5 
+   * 
+   * @see AttributesFactory#setDiskStoreName
+   */
+  public RegionFactory<K,V> setDiskStoreName(String name) {
+    this.attrsFactory.setDiskStoreName(name);
+    return this;
+  }
+  
+  /**
+   * Sets whether or not the writing to the disk is synchronous.
+   * 
+   * @param isSynchronous
+   *          boolean if true indicates synchronous writes
+   * @return a reference to this RegionFactory object
+   * @since 6.5 
+   */
+  public RegionFactory<K,V> setDiskSynchronous(boolean isSynchronous)
+  {
+    this.attrsFactory.setDiskSynchronous(isSynchronous);
+    return this;
+  }
+
+  /**
+   * Sets the directories to which the region's data are written. If multiple
+   * directories are used, GemFire will attempt to distribute the data evenly
+   * amongst them.
+   *
+   * @return a reference to this RegionFactory object
+   * @throws GemfireIOException if a directory cannot be created
+   *
+   * @see AttributesFactory#setDiskDirs
+   * @deprecated as of 6.5 use {@link DiskStoreFactory#setDiskDirs} instead
+   */
+  @Deprecated
+  public RegionFactory<K,V> setDiskDirs(File[] diskDirs)
+  {
+    this.attrsFactory.setDiskDirs(diskDirs);
+    return this;
+  }
+
+  /**
+   * Sets the directories to which the region's data are written and also set their sizes in megabytes
+   *  
+   * @return a reference to this RegionFactory object
+   * @throws IllegalArgumentException if length of the size array
+   * does not match to the length of the dir array
+   * @throws GemfireIOException if a directory cannot be created
+   *   
+   * @since 5.1
+   * @see AttributesFactory#setDiskDirsAndSizes
+   * @deprecated as of 6.5 use {@link DiskStoreFactory#setDiskDirsAndSizes} instead
+   */
+  @Deprecated
+  public RegionFactory<K,V> setDiskDirsAndSizes(File[] diskDirs,int[] diskSizes) {
+    this.attrsFactory.setDiskDirsAndSizes(diskDirs, diskSizes);
+    return this;
+  }
+
+  /**
+   * Sets the <code>PartitionAttributes</code> that describe how the region is
+   * partitioned among members of the distributed system.
+   *
+   * @return a reference to this RegionFactory object
+   * @see AttributesFactory#setPartitionAttributes
+   */
+  public RegionFactory<K,V> setPartitionAttributes(PartitionAttributes partition)
+  {
+    this.attrsFactory.setPartitionAttributes(partition);
+    return this;
+  }
+
+  /**
+   * Sets the <code>MembershipAttributes</code> that describe the membership
+   * roles required for reliable access to the region.
+   *
+   * @param ra the MembershipAttributes to use
+   * @return a reference to this RegionFactory object
+   * @see AttributesFactory#setMembershipAttributes
+   */
+  public RegionFactory<K,V> setMembershipAttributes(MembershipAttributes ra) {
+    this.attrsFactory.setMembershipAttributes(ra);
+    return this;
+  }
+
+  /**
+   * Sets how indexes on this region are kept current.
+   *
+   * @param synchronous
+   *          whether indexes are maintained in a synchronized fashion
+   * @return a reference to this RegionFactory object
+   */
+  public RegionFactory<K,V> setIndexMaintenanceSynchronous(boolean synchronous)
+  {
+    this.attrsFactory.setIndexMaintenanceSynchronous(synchronous);
+    return this;
+  }
+
+  /**
+   * Sets whether statistics are enabled for this region and its entries.
+   *
+   * @param statisticsEnabled
+   *          whether statistics are enabled
+   * @return a reference to this RegionFactory object
+   * @see AttributesFactory#setStatisticsEnabled
+   */
+  public RegionFactory<K,V> setStatisticsEnabled(boolean statisticsEnabled)
+  {
+    this.attrsFactory.setStatisticsEnabled(statisticsEnabled);
+    return this;
+  }
+
+  /**
+   * Sets whether operations on this region should be controlled by
+   * JTA transactions or not
+   * @since 5.0
+   */
+  public RegionFactory<K,V> setIgnoreJTA(boolean flag) {
+    this.attrsFactory.setIgnoreJTA(flag);
+    return this;
+  }
+
+  /**
+   * Sets whether this region should become lock grantor.
+   *
+   * @param isLockGrantor
+   *          whether this region should become lock grantor
+   * @return a reference to this RegionFactory object
+   * @see AttributesFactory#setLockGrantor
+   */
+  public RegionFactory<K,V> setLockGrantor(boolean isLockGrantor)
+  {
+    this.attrsFactory.setLockGrantor(isLockGrantor);
+    return this;
+  }
+
+  /**
+   * Sets the kind of interest this region has in events occuring in other caches that define
+   * the region by the same name.
+   * @param sa the attributes decribing the interest
+   * @return a reference to this RegionFactory object
+   * @see AttributesFactory#setSubscriptionAttributes(SubscriptionAttributes)
+   */
+  public RegionFactory<K,V> setSubscriptionAttributes(SubscriptionAttributes sa) {
+    this.attrsFactory.setSubscriptionAttributes(sa);
+    return this;
+  }
+
+  /**
+   * Creates a region with the given name in this factory's {@link Cache}
+   * using the configuration contained in this factory. Validation of the
+   * provided attributes may cause exceptions to be thrown if there are problems
+   * with the configuration data.
+   *
+   * @param name
+   *          the name of the region to create
+   *
+   * @return the region object
+   * @throws LeaseExpiredException
+   *           if lease expired on distributed lock for Scope.GLOBAL
+   * @throws RegionExistsException
+   *           if a region, shared or unshared, is already in this cache
+   * @throws TimeoutException
+   *           if timed out getting distributed lock for Scope.GLOBAL
+   * @throws CacheClosedException
+   *           if the cache is closed
+   * @throws IllegalStateException
+   *           if the supplied RegionAttributes are incompatible with this region
+   *           in another cache in the distributed system (see
+   *           {@link AttributesFactory} for compatibility rules)
+   */
+  @SuppressWarnings("unchecked")
+  public Region<K,V> create(String name) throws CacheExistsException,
+             RegionExistsException, CacheWriterException, TimeoutException
+  {
+    @SuppressWarnings("deprecation")
+    RegionAttributes<K,V> ra = this.attrsFactory.create();
+    return getCache().createRegion(name, ra);
+  }
+  /**
+   * Creates a sub-region in the {@link Cache} using
+   * the configuration contained in this RegionFactory. Validation of the
+   * provided attributes may cause exceptions to be thrown if there are problems
+   * with the configuration data.
+   *
+   * @param parent
+   *          the existing region that will contain the created sub-region
+   * @param name
+   *          the name of the region to create
+   *
+   * @return the region object
+   * @throws RegionExistsException
+   *           if a region with the given name already exists in this cache
+   * @throws RegionDestroyedException
+   *           if the parent region has been closed or destroyed
+   * @throws CacheClosedException
+   *           if the cache is closed
+   * @since 7.0
+   */
+  @SuppressWarnings("unchecked")
+  public Region<K,V> createSubregion(Region<?,?> parent, String name) throws RegionExistsException {
+    @SuppressWarnings("deprecation")
+    RegionAttributes<K,V> ra = this.attrsFactory.create();
+    return ((LocalRegion)parent).createSubregion(name, ra);
+  }
+  
+  /**
+   * Sets cloning on region
+   * @param cloningEnable
+   * @return a reference to this RegionFactory object
+   * @since 6.1
+   * @see AttributesFactory#setCloningEnabled
+   */
+  public RegionFactory<K,V> setCloningEnabled(boolean cloningEnable) {
+    this.attrsFactory.setCloningEnabled(cloningEnable);
+    return this;
+  }
+
+  /**
+   * Adds a gatewaySenderId to the RegionAttributes
+   * @param gatewaySenderId
+   * @return a reference to this RegionFactory object
+   * @since 7.0
+   * @see AttributesFactory#addGatewaySenderId(String) 
+   */
+  public RegionFactory<K,V> addGatewaySenderId(String gatewaySenderId)
+  {
+    this.attrsFactory.addGatewaySenderId(gatewaySenderId);
+    return this;
+  } 
+  
+  /**
+   * Adds a asyncEventQueueId to the RegionAttributes
+   * 
+   * @param asyncEventQueueId id of AsyncEventQueue 
+   * @return a reference to this RegionFactory instance
+   * @since 7.0
+   */
+  public RegionFactory<K,V> addAsyncEventQueueId(String asyncEventQueueId) {
+    this.attrsFactory.addAsyncEventQueueId(asyncEventQueueId);
+    return this;
+  }
+
+  /**
+   * Set the compressor to be used by this region for compressing
+   * region entry values.
+   * @param compressor a compressor
+   * @return a reference to this RegionFactory instance
+   * @since 8.0
+   */
+  public RegionFactory<K,V> setCompressor(Compressor compressor) {
+    this.attrsFactory.setCompressor(compressor);
+    return this;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionMembershipListener.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionMembershipListener.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionMembershipListener.java
new file mode 100644
index 0000000..584e4f5
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionMembershipListener.java
@@ -0,0 +1,74 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+import com.gemstone.gemfire.distributed.DistributedMember;
+
+/**
+ * A listener that can be implemented to handle region membership events.
+ * 
+ * <p>
+ * Instead of implementing this interface it is recommended that you extend
+ * the {@link com.gemstone.gemfire.cache.util.RegionMembershipListenerAdapter} class.
+ * 
+ * @author Darrel Schneider
+ * 
+ * 
+ * @see AttributesFactory#addCacheListener
+ * @see AttributesFactory#initCacheListeners
+ * @see RegionAttributes#getCacheListeners
+ * @see AttributesMutator#addCacheListener
+ * @see AttributesMutator#removeCacheListener
+ * @see AttributesMutator#initCacheListeners
+ * @since 5.0
+ */
+public interface RegionMembershipListener<K,V> extends CacheListener<K,V> {
+  /**
+   * Invoked when the listener is first initialized and is
+   * given the set of members that have the region created at that time.
+   * The listener is initialized when:
+   * <ul>
+   * <li> the region is created with an already added listener
+   * <li> a listener is added using the {@link AttributesMutator}.
+   * </ul>
+   * @param region the {@link Region} the listener is registered on
+   * @param initialMembers an array of the other members that have this region
+   *   at the time this listener is added.
+   */
+  public void initialMembers(Region<K,V> region, DistributedMember[] initialMembers);
+  /**
+   * Invoked when another member has created the distributed region this
+   * listener is on.
+   * @param event the event from the member whose region was created.
+   */
+  public void afterRemoteRegionCreate(RegionEvent<K,V> event);
+
+  /**
+   * Invoked when another member's distributed region is no longer
+   * available to this cache due to normal operations.  
+   * This can be triggered by one of the following methods:
+   * <ul>
+   * <li>{@link Region#localDestroyRegion()}
+   * <li>{@link Region#close}
+   * <li>{@link Cache#close()}
+   * </ul>
+   * This differs from afterRemoteRegionCrash notification in that the
+   * departed member performed an action either to remove its region or to close
+   * its region or cache.
+   * @param event the event from the member whose region is no longer available.
+   */
+  public void afterRemoteRegionDeparture(RegionEvent<K,V> event);
+  /**
+   * Invoked when another member's distributed region is no longer
+   * available to this cache because the member has crashed or is no
+   * longer reachable on the network.<p>
+
+   * @param event the event from the member whose region is no longer available.
+   */
+  public void afterRemoteRegionCrash(RegionEvent<K,V> event);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionReinitializedException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionReinitializedException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionReinitializedException.java
new file mode 100644
index 0000000..61b9e6e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionReinitializedException.java
@@ -0,0 +1,39 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * Indicates that the region has been reinitialized. Further operations
+ * on the region object are not allowed using this region reference.
+ * A new reference must be acquired from the Cache the region's parent
+ * region.
+ *
+ * @author Eric Zoerner
+ *
+ * @since 4.0
+ */
+public class RegionReinitializedException extends RegionDestroyedException {
+private static final long serialVersionUID = 8532904304288670752L;
+//  private String regionFullPath;
+  
+  /** Constructs a <code>RegionReinitializedException</code> with a message.
+   * @param msg the String message
+   */
+  public RegionReinitializedException(String msg, String regionFullPath) {
+    super(msg, regionFullPath);
+  }
+  
+  /** Constructs a <code>RegionDestroyedException</code> with a message and
+   * a cause.
+   * @param s the String message
+   * @param ex the Throwable cause
+   */
+  public RegionReinitializedException(String s, String regionFullPath, Throwable ex) {
+    super(s, regionFullPath, ex);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionRoleException.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionRoleException.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionRoleException.java
new file mode 100755
index 0000000..49a854e
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionRoleException.java
@@ -0,0 +1,54 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * Indicates that a {@link Region} reliability failure has occurred.
+ * Reliability for a <code>Region</code> is defined by its 
+ * {@link MembershipAttributes}.
+ *
+ * @author Kirk Lund
+ * @since 5.0
+ */
+public abstract class RegionRoleException extends RoleException {
+  
+  /** The full path of the region affected by the reliability failure */
+  private String regionFullPath;
+  
+  /** 
+   * Constructs a <code>RegionRoleException</code> with a message.
+   * @param s the String message
+   * @param regionFullPath full path of region for which access was attempted
+   */
+  public RegionRoleException(String s, String regionFullPath) {
+    super(s);
+    this.regionFullPath = regionFullPath;
+  }
+  
+  /** 
+   * Constructs a <code>RegionRoleException</code> with a message and
+   * a cause.
+   * @param s the String message
+   * @param regionFullPath full path of region for which access was attempted
+   * @param ex the Throwable cause
+   */
+  public RegionRoleException(String s,  String regionFullPath, Throwable ex) {
+    super(s, ex);
+    this.regionFullPath = regionFullPath;
+  }
+  
+  /** 
+   * Returns the full path of the region for which access was attempted.
+   * @return the full path of the region for which access was attempted
+   */
+  public String getRegionFullPath() {
+    return this.regionFullPath;
+  }
+  
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionRoleListener.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionRoleListener.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionRoleListener.java
new file mode 100755
index 0000000..01a0663
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionRoleListener.java
@@ -0,0 +1,45 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+package com.gemstone.gemfire.cache;
+
+/**
+ * A listener that can be implemented to handle region reliability membership 
+ * events.  These are membership events that are specific to loss or gain of
+ * required roles as defined by the region's {@link MembershipAttributes}.
+ * <p>
+ * Instead of implementing this interface it is recommended that you extend
+ * the {@link com.gemstone.gemfire.cache.util.RegionRoleListenerAdapter} 
+ * class.
+ * 
+ * @author Kirk Lund
+ * 
+ * @see AttributesFactory#setCacheListener
+ * @see RegionAttributes#getCacheListener
+ * @see AttributesMutator#setCacheListener
+ * @since 5.0
+ */
+public interface RegionRoleListener<K,V> extends CacheListener<K,V> {
+
+  /**
+   * Invoked when a required role has returned to the distributed system
+   * after being absent.
+   *
+   * @param event describes the member that fills the required role.
+   */
+  public void afterRoleGain(RoleEvent<K,V> event);
+  
+  /**
+   * Invoked when a required role is no longer available in the distributed
+   * system.
+   *
+   * @param event describes the member that last filled the required role.
+   */
+  public void afterRoleLoss(RoleEvent<K,V> event);
+  
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/19459053/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionService.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionService.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionService.java
new file mode 100644
index 0000000..9ea65c0
--- /dev/null
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/RegionService.java
@@ -0,0 +1,133 @@
+/*=========================================================================
+ * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * more patents listed at http://www.pivotal.io/patents.
+ *========================================================================
+ */
+
+package com.gemstone.gemfire.cache;
+
+import java.util.Properties;
+import java.util.Set;
+
+import com.gemstone.gemfire.CancelCriterion;
+import com.gemstone.gemfire.cache.client.ClientCacheFactory;
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.query.QueryService;
+import com.gemstone.gemfire.pdx.PdxInstance;
+import com.gemstone.gemfire.pdx.PdxInstanceFactory;
+
+/**
+ * A RegionService provides access to existing {@link Region regions} that exist
+ * in a {@link GemFireCache GemFire cache}.
+ * Regions can be obtained using {@link #getRegion}
+ * and queried using {@link #getQueryService}.
+ * The service should be {@link #close closed} to free up resources
+ * once it is no longer needed.
+ * Once it {@link #isClosed is closed} any attempt to use it or any {@link Region regions}
+ * obtained from it will cause a {@link CacheClosedException} to be thrown.
+ * <p>
+ * Instances of the interface are created using one of the following methods:
+ * <ul>
+ * <li> {@link CacheFactory#create()} creates a server instance of {@link Cache}.
+ * <li> {@link ClientCacheFactory#create()} creates a client instance of {@link ClientCache}.
+ * <li> {@link ClientCache#createAuthenticatedView(Properties)} creates a client multiuser authenticated cache view.
+ * </ul>
+ * <p>
+ *
+ * @since 6.5
+ * @author darrel
+ */
+public interface RegionService {
+  /**
+   * the cancellation criterion for this service
+   * @return the service's cancellation object
+   */
+  public CancelCriterion getCancelCriterion();
+  /**
+   * Return the existing region (or subregion) with the specified
+   * path.
+   * Whether or not the path starts with a forward slash it is interpreted as a
+   * full path starting at a root.
+   *
+   * @param path the path to the region
+   * @return the Region or null if not found
+   * @throws IllegalArgumentException if path is null, the empty string, or "/"
+   */
+  public <K,V> Region<K,V> getRegion(String path);
+
+  /**
+   * Returns unmodifiable set of the root regions that are in the region service.
+   * This set is a snapshot; it is not backed by the region service.
+   *
+   * @return a Set of regions
+   */
+  public Set<Region<?,?>> rootRegions();
+  
+  // We did not have time to add this feature to 6.6.2
+//  /**
+//   * Returns a factory that can create a {@link PdxInstance}.
+//   * If you want to be able to deserialize the PdxInstance then name
+//   * must be a correct class name and expectDomainClass should be set to true.
+//   * If you want to just create an object that will always be a PdxInstance set expectDomainClass to false.
+//   * @param name the name of the pdx type that
+//   * the PdxInstance will represent. If expectDomainClass is true then
+//   * this must be the full class and package name of the domain class.
+//   * Otherwise it just needs to be a unique string that identifies this instances type.
+//   * @param expectDomainClass if true then during deserialization a domain class will
+//   * be expected. If false then this type will always deserialize to a PdxInstance
+//   * even if read-serialized is false and {@link PdxInstance#getObject()} will return
+//   * the PdxInstance.
+//   * @return the factory
+//   */
+//  public PdxInstanceFactory createPdxInstanceFactory(String name, boolean expectDomainClass);
+
+  /**
+   * Returns a factory that can create a {@link PdxInstance}.
+   * @param className the fully qualified class name that the PdxInstance will become
+   *   when it is fully deserialized.
+   * @return the factory
+   * @since 6.6.2
+   */
+  public PdxInstanceFactory createPdxInstanceFactory(String className);
+  /**
+   * Creates and returns a PdxInstance that represents an enum value.
+   * @param className the name of the enum class
+   * @param enumName the name of the enum constant
+   * @param enumOrdinal the ordinal value of the enum constant
+   * @return a PdxInstance that represents the enum value
+   * @throws IllegalArgumentException if className or enumName are <code>null</code>.
+   * @since 6.6.2
+   */
+  public PdxInstance createPdxEnum(String className, String enumName, int enumOrdinal);
+
+  /**
+   * Return the QueryService for this region service.
+   * For a region service in a client the returned QueryService will
+   * execute queries on the server.
+   * For a region service not in a client the returned QueryService will
+   * execute queries on the local and peer regions.
+   */
+  public QueryService getQueryService();
+  /**
+   * Terminates this region service and releases all its resources.
+   * Calls {@link Region#close} on each region in the service.
+   * After this service is closed, any further
+   * method calls on this service or any region object
+   * obtained from the service will throw
+   * {@link CacheClosedException}, unless otherwise noted.
+   * @throws CacheClosedException if the service is already closed.
+   */
+  public void close();
+  /**
+   * Indicates if this region service has been closed.
+   * After a new service is created, this method returns false;
+   * After close is called on this service, this method
+   * returns true. This method does not throw <code>CacheClosedException</code>
+   * if the service is closed.
+   *
+   * @return true, if this service has just been created or has started to close; false, otherwise
+   */
+  public boolean isClosed();
+}
\ No newline at end of file