diff --git a/pom.xml b/pom.xml
index 7850f22..cb4cc76 100755
--- a/pom.xml
+++ b/pom.xml
@@ -1,7 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
     <parent>
         <artifactId>ehcache-parent</artifactId>
         <groupId>net.sf.ehcache</groupId>
@@ -11,7 +9,7 @@
     <groupId>org.jasig.ehcache</groupId>
     <artifactId>ehcache-jgroups3replication</artifactId>
     <name>JGroups Replication</name>
-    <version>1.7.2-SNAPSHOT</version>
+    <version>1.7.4-SNAPSHOT</version>
     <packaging>jar</packaging>
     <description>This module provides replication via JGroups 3</description>
     <properties>
@@ -47,6 +45,11 @@
             <version>3.1.0.Final</version>
         </dependency>
         <dependency>
+            <groupId>com.yammer.metrics</groupId>
+            <artifactId>metrics-core</artifactId>
+            <version>2.1.2</version>
+        </dependency>
+        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
             <version>1.6.1</version>
diff --git a/src/main/java/net/sf/ehcache/distribution/jgroups/JGroupsCacheManagerPeerProvider.java b/src/main/java/net/sf/ehcache/distribution/jgroups/JGroupsCacheManagerPeerProvider.java
index 2602e87..47fd9bb 100755
--- a/src/main/java/net/sf/ehcache/distribution/jgroups/JGroupsCacheManagerPeerProvider.java
+++ b/src/main/java/net/sf/ehcache/distribution/jgroups/JGroupsCacheManagerPeerProvider.java
@@ -17,6 +17,12 @@
 
 package net.sf.ehcache.distribution.jgroups;
 
+import java.net.URL;
+import java.util.Collections;
+import java.util.List;
+
+import javax.management.MBeanServer;
+
 import net.sf.ehcache.CacheException;
 import net.sf.ehcache.CacheManager;
 import net.sf.ehcache.Ehcache;
@@ -24,16 +30,12 @@ import net.sf.ehcache.Status;
 import net.sf.ehcache.distribution.CacheManagerPeerProvider;
 import net.sf.ehcache.distribution.CachePeer;
 import net.sf.ehcache.management.ManagedCacheManagerPeerProvider;
+
 import org.jgroups.JChannel;
 import org.jgroups.jmx.JmxConfigurator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.management.MBeanServer;
-import java.net.URL;
-import java.util.Collections;
-import java.util.List;
-
 /**
  * The main Jgroup class for replication via JGroup. Starts up the Jgroup communication bus and listen for message in
  * the bus. Because of Ehcache design we have to register this as a CachePeer. In reality this class listen for change
@@ -178,7 +180,9 @@ public class JGroupsCacheManagerPeerProvider implements ManagedCacheManagerPeerP
             LOG.debug("Registered JGroups channel with MBeanServer under domain {} with name {}", JMX_DOMAIN_NAME, clusterName);
         } catch (Exception e) {
             LOG.error("Error occured while registering MBeans. Management of JGroups will not be enabled.", e);
-        }        
+        }
+        
+        this.cacheReceiver.register(mBeanServer);
     }
 
     /**
@@ -198,6 +202,7 @@ public class JGroupsCacheManagerPeerProvider implements ManagedCacheManagerPeerP
     private void shutdownCachePeer() {
         if (this.cachePeer != null) {
             this.cachePeersListCache = null;
+            this.cacheReceiver.dispose();
             this.cacheReceiver = null;
             this.cachePeer.dispose();
             this.cachePeer = null;
diff --git a/src/main/java/net/sf/ehcache/distribution/jgroups/JGroupsCacheReceiver.java b/src/main/java/net/sf/ehcache/distribution/jgroups/JGroupsCacheReceiver.java
index c473be9..359fc85 100644
--- a/src/main/java/net/sf/ehcache/distribution/jgroups/JGroupsCacheReceiver.java
+++ b/src/main/java/net/sf/ehcache/distribution/jgroups/JGroupsCacheReceiver.java
@@ -21,10 +21,16 @@ import java.io.OutputStream;
 import java.io.Serializable;
 import java.util.List;
 
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
 import net.sf.ehcache.CacheManager;
 import net.sf.ehcache.Ehcache;
-
+import net.sf.ehcache.distribution.jgroups.jmx.JGroupsCacheReceiverStatsCounter;
+import net.sf.ehcache.distribution.jgroups.jmx.JGroupsCacheReceiverStats;
+import net.sf.ehcache.distribution.jgroups.jmx.NullJGroupsCacheReceiverStats;
 import net.sf.ehcache.util.CacheTransactionHelper;
+
 import org.jgroups.Address;
 import org.jgroups.Message;
 import org.jgroups.Receiver;
@@ -43,6 +49,10 @@ public class JGroupsCacheReceiver implements Receiver {
 
     private final CacheManager cacheManager;
     private final JGroupsBootstrapManager bootstrapManager;
+    
+    private MBeanServer mBeanServer;
+    private ObjectName objectName;
+    private JGroupsCacheReceiverStatsCounter cacheReceiverStats = new NullJGroupsCacheReceiverStats();
 
     /**
      * Create a new {@link Receiver}
@@ -51,6 +61,43 @@ public class JGroupsCacheReceiver implements Receiver {
         this.cacheManager = cacheManager;
         this.bootstrapManager = bootstrapManager;
     }
+    
+    /**
+     * Register with an MBeanServer
+     */
+    public void register(MBeanServer mBeanServer) {
+        this.mBeanServer = mBeanServer;
+        
+        //Replace NULL impl with real impl
+        this.cacheReceiverStats = new JGroupsCacheReceiverStats();
+        try {
+            this.objectName = ObjectName.getInstance("net.sf.ehcache:type=JGroupsStatistics,CacheManager=" + this.cacheManager.getName()
+                    + ",name=JGroupsCacheReceiver");
+            
+            this.mBeanServer.registerMBean(
+                    cacheReceiverStats, 
+                    objectName);
+            
+            LOG.debug("Registered JGroups Cache Receiver with MBeanServer under {}", this.objectName);
+        } catch (Exception e) {
+            LOG.error("Error occured while registering JGroupsCacheReceiver MBean. JGroupsCacheReceiver Statistics will not be enabled.",
+                    e);
+        }
+    }
+
+    /**
+     * Shutdown the cache peer reciever
+     */
+    public void dispose() {
+        if (this.mBeanServer != null) {
+            try {
+                this.mBeanServer.unregisterMBean(this.objectName);
+                
+            } catch (Exception e) {
+                LOG.error("Error occured while unregistering JGroupsCacheReceiver MBean. " + this.objectName, e);
+            }
+        }
+    }
 
     /**
      * {@inheritDoc}
@@ -121,21 +168,25 @@ public class JGroupsCacheReceiver implements Receiver {
 
         switch (message.getEvent()) {
             case JGroupEventMessage.BOOTSTRAP_REQUEST: {
+                this.cacheReceiverStats.countBootstrapRequest();
                 LOG.debug("received bootstrap request:    from {} for cache={}", message.getSerializableKey(), cacheName);
                 this.bootstrapManager.sendBootstrapResponse(message);
                 break;
             }
             case JGroupEventMessage.BOOTSTRAP_COMPLETE: {
+                this.cacheReceiverStats.countBootstrapComplete();
                 LOG.debug("received bootstrap complete:   cache={}", cacheName);
                 this.bootstrapManager.handleBootstrapComplete(message);
                 break;
             }
             case JGroupEventMessage.BOOTSTRAP_INCOMPLETE: {
+                this.cacheReceiverStats.countBootstrapIncomplete();
                 LOG.debug("received bootstrap incomplete: cache={}", cacheName);
                 this.bootstrapManager.handleBootstrapIncomplete(message);
                 break;
             }
             case JGroupEventMessage.BOOTSTRAP_RESPONSE: {
+                this.cacheReceiverStats.countBootstrapResponse();
                 final Serializable serializableKey = message.getSerializableKey();
                 LOG.debug("received bootstrap reply:      cache={}, key={}", cacheName, serializableKey);
                 this.bootstrapManager.handleBootstrapResponse(message);
@@ -157,6 +208,7 @@ public class JGroupsCacheReceiver implements Receiver {
         
         switch (message.getEvent()) {
             case JGroupEventMessage.REMOVE_ALL: {
+                this.cacheReceiverStats.countRemoveAll();
                 LOG.debug("received remove all:      cache={}", cacheName);
                 cache.removeAll(true);
                 break;
@@ -164,15 +216,18 @@ public class JGroupsCacheReceiver implements Receiver {
             case JGroupEventMessage.REMOVE: {
                 final Serializable serializableKey = message.getSerializableKey();
                 if (cache.getQuiet(serializableKey) != null) {
+                    this.cacheReceiverStats.countRemoveExisting();
                     LOG.debug("received remove:          cache={}, key={}", cacheName, serializableKey);
                     cache.remove(serializableKey, true);
                 } else if (LOG.isTraceEnabled()) {
+                    this.cacheReceiverStats.countRemoveNotExisting();
                     LOG.trace("received remove:          cache={}, key={} - Ignoring, key is not in the local cache.", 
                             cacheName, serializableKey);
                 }
                 break;
             }
             case JGroupEventMessage.PUT: {
+                this.cacheReceiverStats.countPut();
                 final Serializable serializableKey = message.getSerializableKey();
                 LOG.debug("received put:             cache={}, key={}", cacheName, serializableKey);
                 cache.put(message.getElement(), true);
diff --git a/src/main/java/net/sf/ehcache/distribution/jgroups/jmx/JGroupsCacheReceiverStats.java b/src/main/java/net/sf/ehcache/distribution/jgroups/jmx/JGroupsCacheReceiverStats.java
new file mode 100644
index 0000000..243b805
--- /dev/null
+++ b/src/main/java/net/sf/ehcache/distribution/jgroups/jmx/JGroupsCacheReceiverStats.java
@@ -0,0 +1,225 @@
+/**
+ *  Copyright 2003-2010 Terracotta, Inc.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package net.sf.ehcache.distribution.jgroups.jmx;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import net.sf.ehcache.distribution.jgroups.JGroupsCacheReceiver;
+
+import com.yammer.metrics.Metrics;
+import com.yammer.metrics.core.Meter;
+
+/**
+ * Tracks JGroupsCacheReceiver Statistics
+ * 
+ * @author Eric Dalquist
+ */
+public class JGroupsCacheReceiverStats implements
+        JGroupsCacheReceiverStatsMBean, JGroupsCacheReceiverStatsCounter {
+    
+    private final AtomicLong removeAllCount = new AtomicLong();
+    private final Meter removeAllRate = Metrics.newMeter(JGroupsCacheReceiver.class,
+            "removeAll",
+            "removeAll",
+            TimeUnit.SECONDS);
+
+    private final AtomicLong removeExistingCount = new AtomicLong();
+    private final Meter removeExistingRate = Metrics.newMeter(JGroupsCacheReceiver.class,
+            "removeExisting",
+            "removeExisting",
+            TimeUnit.SECONDS);
+
+    private final AtomicLong removeNotExistingCount = new AtomicLong();
+    private final Meter removeNotExistingRate = Metrics.newMeter(JGroupsCacheReceiver.class,
+            "removeNotExisting",
+            "removeNotExisting",
+            TimeUnit.SECONDS);
+
+    private final AtomicLong putCount = new AtomicLong();
+    private final Meter putRate = Metrics.newMeter(JGroupsCacheReceiver.class, "put", "put", TimeUnit.SECONDS);
+ 
+    private final AtomicLong bootstrapRequestCount = new AtomicLong();
+    private final AtomicLong bootstrapResponseCount = new AtomicLong();
+    private final AtomicLong bootstrapCompleteCount = new AtomicLong();
+    private final AtomicLong bootstrapIncompleteCount = new AtomicLong();
+    
+    
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public void countRemoveAll() {
+        this.removeAllCount.incrementAndGet();
+        this.removeAllRate.mark();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public long getRemoveAllCount() {
+        return this.removeAllCount.get();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public double getRemoveAllRate() {
+        return removeAllRate.oneMinuteRate();
+    }
+    
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public void countRemoveExisting() {
+        this.removeExistingCount.incrementAndGet();
+        this.removeExistingRate.mark();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public long getRemoveExistingCount() {
+        return this.removeExistingCount.get();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public double getRemoveExistingRate() {
+        return this.removeExistingRate.oneMinuteRate();
+    }
+    
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public void countRemoveNotExisting() {
+        this.removeNotExistingCount.incrementAndGet();
+        this.removeNotExistingRate.mark();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public long getRemoveNotExistingCount() {
+        return this.removeNotExistingCount.get();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public double getRemoveNotExistingRate() {
+        return this.removeNotExistingRate.oneMinuteRate();
+    }
+    
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public void countPut() {
+        this.putCount.incrementAndGet();
+        this.putRate.mark();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public long getPutCount() {
+        return this.putCount.get();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public double getPutRate() {
+        return this.putRate.oneMinuteRate();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public void countBootstrapRequest() {
+        this.bootstrapRequestCount.incrementAndGet();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public void countBootstrapComplete() {
+        this.bootstrapCompleteCount.incrementAndGet();        
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public void countBootstrapIncomplete() {
+        this.bootstrapIncompleteCount.incrementAndGet();        
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public void countBootstrapResponse() {
+        this.bootstrapResponseCount.incrementAndGet();        
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public long getBootstrapRequestCount() {
+        return this.bootstrapRequestCount.get();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public long getBootstrapCompleteCount() {
+        return this.bootstrapCompleteCount.get();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public long getBootstrapIncompleteCount() {
+        return this.bootstrapIncompleteCount.get();
+    }
+
+    /**
+     * @inheritDoc
+     */
+    @Override
+    public long getBootstrapResponseCount() {
+        return this.bootstrapResponseCount.get();
+    }
+}
diff --git a/src/main/java/net/sf/ehcache/distribution/jgroups/jmx/JGroupsCacheReceiverStatsCounter.java b/src/main/java/net/sf/ehcache/distribution/jgroups/jmx/JGroupsCacheReceiverStatsCounter.java
new file mode 100644
index 0000000..e9b3082
--- /dev/null
+++ b/src/main/java/net/sf/ehcache/distribution/jgroups/jmx/JGroupsCacheReceiverStatsCounter.java
@@ -0,0 +1,66 @@
+/**
+ *  Copyright 2003-2010 Terracotta, Inc.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package net.sf.ehcache.distribution.jgroups.jmx;
+
+/**
+ * Interface for updating the receiver stats
+ * 
+ * @author Eric Dalquist
+ */
+public interface JGroupsCacheReceiverStatsCounter {
+
+    /**
+     * Count a remove all event
+     */
+    void countRemoveAll();
+
+    /**
+     * Count a remove existing event
+     */
+    void countRemoveExisting();
+
+    /**
+     * Count a remove not existing event
+     */
+    void countRemoveNotExisting();
+
+    /**
+     * Count a put event
+     */
+    void countPut();
+    
+    /**
+     * Count a bootstrap request event
+     */
+    void countBootstrapRequest();
+    
+    /**
+     * Count a bootstrap complete event
+     */
+    void countBootstrapComplete();
+    
+    /**
+     * Count a bootstrap incomplete event 
+     */
+    void countBootstrapIncomplete();
+    
+    /**
+     * Count a bootstrap response event
+     */
+    void countBootstrapResponse();
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/sf/ehcache/distribution/jgroups/jmx/JGroupsCacheReceiverStatsMBean.java b/src/main/java/net/sf/ehcache/distribution/jgroups/jmx/JGroupsCacheReceiverStatsMBean.java
new file mode 100644
index 0000000..539eeb2
--- /dev/null
+++ b/src/main/java/net/sf/ehcache/distribution/jgroups/jmx/JGroupsCacheReceiverStatsMBean.java
@@ -0,0 +1,80 @@
+/**
+ *  Copyright 2003-2010 Terracotta, Inc.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package net.sf.ehcache.distribution.jgroups.jmx;
+
+/**
+ * Describes statistics about the JGroups Receiver bean 
+ * 
+ * @author Eric Dalquist
+ */
+public interface JGroupsCacheReceiverStatsMBean {
+    /**
+     * @return Number of remove_all events received
+     */
+    long getRemoveAllCount();
+    /**
+     * @return Rate of remove_all event reception over the last second
+     */
+    double getRemoveAllRate();
+    
+    /**
+     * @return Number of remove events received where the local element existed.
+     */
+    long getRemoveExistingCount();
+    /**
+     * @return Rate of remove event reception where the local element existed over the last second
+     */
+    double getRemoveExistingRate();
+    
+    /**
+     * @return Number of remove events received where the local element did not exist
+     */
+    long getRemoveNotExistingCount();
+    /**
+     * @return Rate of remove event reception where the local element did not exist over the last second
+     */
+    double getRemoveNotExistingRate();
+    
+    /**
+     * @return Number of put events received
+     */
+    long getPutCount();
+    /**
+     * @return Rate of put event reception over the last second
+     */
+    double getPutRate();
+    
+    /**
+     * @return the bootstrap request event count
+     */
+    long getBootstrapRequestCount();
+    
+    /**
+     * @return the bootstrap complete event count
+     */
+    long getBootstrapCompleteCount();
+    
+    /**
+     * @return the bootstrap incomplete event count
+     */
+    long getBootstrapIncompleteCount();
+    
+    /**
+     * @return the bootstrap response event count
+     */
+    long getBootstrapResponseCount();
+}
diff --git a/src/main/java/net/sf/ehcache/distribution/jgroups/jmx/NullJGroupsCacheReceiverStats.java b/src/main/java/net/sf/ehcache/distribution/jgroups/jmx/NullJGroupsCacheReceiverStats.java
new file mode 100644
index 0000000..924bc3b
--- /dev/null
+++ b/src/main/java/net/sf/ehcache/distribution/jgroups/jmx/NullJGroupsCacheReceiverStats.java
@@ -0,0 +1,81 @@
+/**
+ *  Copyright 2003-2010 Terracotta, Inc.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package net.sf.ehcache.distribution.jgroups.jmx;
+
+/**
+ * Implementation that does nothing
+ * 
+ * @author Eric Dalquist
+ */
+public final class NullJGroupsCacheReceiverStats implements JGroupsCacheReceiverStatsCounter {
+
+    /**
+     * noop
+     */
+    @Override
+    public void countRemoveAll() {
+    }
+
+    /**
+     * noop
+     */
+    @Override
+    public void countRemoveExisting() {
+    }
+
+    /**
+     * noop
+     */
+    @Override
+    public void countRemoveNotExisting() {
+    }
+
+    /**
+     * noop
+     */
+    @Override
+    public void countPut() {
+    }
+
+    /**
+     * noop
+     */
+    @Override
+    public void countBootstrapRequest() {
+    }
+
+    /**
+     * noop
+     */
+    @Override
+    public void countBootstrapComplete() {
+    }
+
+    /**
+     * noop
+     */
+    @Override
+    public void countBootstrapIncomplete() {
+    }
+
+    /**
+     * noop
+     */
+    @Override
+    public void countBootstrapResponse() {
+    }
+}
diff --git a/src/main/java/net/sf/ehcache/distribution/jgroups/jmx/package.html b/src/main/java/net/sf/ehcache/distribution/jgroups/jmx/package.html
new file mode 100755
index 0000000..5487bc5
--- /dev/null
+++ b/src/main/java/net/sf/ehcache/distribution/jgroups/jmx/package.html
@@ -0,0 +1,8 @@
+<html>
+<head>
+</head>
+<body>
+This package is for jxm beans for cache replication using Jgroups.
+
+</body>
+</html>
