Enahnced link and host stores to extend general store.
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/MastershipStore.java b/core/api/src/main/java/org/onlab/onos/cluster/MastershipStore.java
index 3e2ee03..eae664d 100644
--- a/core/api/src/main/java/org/onlab/onos/cluster/MastershipStore.java
+++ b/core/api/src/main/java/org/onlab/onos/cluster/MastershipStore.java
@@ -4,12 +4,13 @@
 
 import org.onlab.onos.net.DeviceId;
 import org.onlab.onos.net.MastershipRole;
+import org.onlab.onos.store.Store;
 
 /**
  * Manages inventory of mastership roles for devices, across controller
  * instances; not intended for direct use.
  */
-public interface MastershipStore {
+public interface MastershipStore extends Store<MastershipEvent, MastershipStoreDelegate> {
 
     // three things to map: NodeId, DeviceId, MastershipRole
 
diff --git a/core/api/src/main/java/org/onlab/onos/net/device/DeviceStore.java b/core/api/src/main/java/org/onlab/onos/net/device/DeviceStore.java
index ef111e9..c84aac8 100644
--- a/core/api/src/main/java/org/onlab/onos/net/device/DeviceStore.java
+++ b/core/api/src/main/java/org/onlab/onos/net/device/DeviceStore.java
@@ -5,13 +5,14 @@
 import org.onlab.onos.net.Port;
 import org.onlab.onos.net.PortNumber;
 import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.store.Store;
 
 import java.util.List;
 
 /**
  * Manages inventory of infrastructure devices; not intended for direct use.
  */
-public interface DeviceStore {
+public interface DeviceStore extends Store<DeviceEvent, DeviceStoreDelegate> {
 
     /**
      * Returns the number of devices known to the system.
diff --git a/core/api/src/main/java/org/onlab/onos/net/host/HostStore.java b/core/api/src/main/java/org/onlab/onos/net/host/HostStore.java
index e70bbf2..3f1cb23 100644
--- a/core/api/src/main/java/org/onlab/onos/net/host/HostStore.java
+++ b/core/api/src/main/java/org/onlab/onos/net/host/HostStore.java
@@ -1,20 +1,21 @@
 package org.onlab.onos.net.host;
 
-import java.util.Set;
-
 import org.onlab.onos.net.ConnectPoint;
 import org.onlab.onos.net.DeviceId;
 import org.onlab.onos.net.Host;
 import org.onlab.onos.net.HostId;
 import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.store.Store;
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 
+import java.util.Set;
+
 /**
  * Manages inventory of end-station hosts; not intended for direct use.
  */
-public interface HostStore {
+public interface HostStore extends Store<HostEvent, HostStoreDelegate> {
 
     /**
      * Creates a new host or updates the existing one based on the specified
@@ -133,7 +134,7 @@
      * Returns the address bindings for a particular connection point.
      *
      * @param connectPoint the connection point to return address information
-     * for
+     *                     for
      * @return address information for the connection point
      */
     PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint);
diff --git a/core/api/src/main/java/org/onlab/onos/net/host/HostStoreDelegate.java b/core/api/src/main/java/org/onlab/onos/net/host/HostStoreDelegate.java
new file mode 100644
index 0000000..999b28f
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/host/HostStoreDelegate.java
@@ -0,0 +1,9 @@
+package org.onlab.onos.net.host;
+
+import org.onlab.onos.store.StoreDelegate;
+
+/**
+ * Infrastructure link store delegate abstraction.
+ */
+public interface HostStoreDelegate extends StoreDelegate<HostEvent> {
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/link/LinkStore.java b/core/api/src/main/java/org/onlab/onos/net/link/LinkStore.java
index dbe4877..0197417 100644
--- a/core/api/src/main/java/org/onlab/onos/net/link/LinkStore.java
+++ b/core/api/src/main/java/org/onlab/onos/net/link/LinkStore.java
@@ -4,13 +4,14 @@
 import org.onlab.onos.net.DeviceId;
 import org.onlab.onos.net.Link;
 import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.store.Store;
 
 import java.util.Set;
 
 /**
  * Manages inventory of infrastructure links; not intended for direct use.
  */
-public interface LinkStore {
+public interface LinkStore extends Store<LinkEvent, LinkStoreDelegate> {
 
     /**
      * Returns the number of links in the store.
diff --git a/core/api/src/main/java/org/onlab/onos/net/link/LinkStoreDelegate.java b/core/api/src/main/java/org/onlab/onos/net/link/LinkStoreDelegate.java
new file mode 100644
index 0000000..ec747c4
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/link/LinkStoreDelegate.java
@@ -0,0 +1,9 @@
+package org.onlab.onos.net.link;
+
+import org.onlab.onos.store.StoreDelegate;
+
+/**
+ * Infrastructure link store delegate abstraction.
+ */
+public interface LinkStoreDelegate extends StoreDelegate<LinkEvent> {
+}
diff --git a/core/api/src/main/java/org/onlab/onos/store/AbstractStore.java b/core/api/src/main/java/org/onlab/onos/store/AbstractStore.java
index efd0d03..5d76e0f 100644
--- a/core/api/src/main/java/org/onlab/onos/store/AbstractStore.java
+++ b/core/api/src/main/java/org/onlab/onos/store/AbstractStore.java
@@ -2,6 +2,8 @@
 
 import org.onlab.onos.event.Event;
 
+import static com.google.common.base.Preconditions.checkState;
+
 /**
  * Base implementation of a store.
  */
@@ -12,12 +14,21 @@
 
     @Override
     public void setDelegate(D delegate) {
+        checkState(this.delegate == null || this.delegate == delegate,
+                   "Store delegate already set");
         this.delegate = delegate;
     }
 
     @Override
-    public D getDelegate() {
-        return delegate;
+    public void unsetDelegate(D delegate) {
+        if (this.delegate == delegate) {
+            this.delegate = null;
+        }
+    }
+
+    @Override
+    public boolean hasDelegate() {
+        return delegate != null;
     }
 
     /**
diff --git a/core/api/src/main/java/org/onlab/onos/store/Store.java b/core/api/src/main/java/org/onlab/onos/store/Store.java
index 9eaef66..28bc08e 100644
--- a/core/api/src/main/java/org/onlab/onos/store/Store.java
+++ b/core/api/src/main/java/org/onlab/onos/store/Store.java
@@ -12,14 +12,25 @@
      * Sets the delegate on the store.
      *
      * @param delegate new store delegate
+     * @throws java.lang.IllegalStateException if a delegate is already
+     *                                         currently set on the store and is a different one that
      */
     void setDelegate(D delegate);
 
     /**
-     * Get the current store delegate.
+     * Withdraws the delegate from the store.
      *
-     * @return store delegate
+     * @param delegate store delegate to withdraw
+     * @throws java.lang.IllegalArgumentException if the delegate is not
+     *                                            currently set on the store
      */
-    D getDelegate();
+    void unsetDelegate(D delegate);
+
+    /**
+     * Indicates whether the store has a delegate.
+     *
+     * @return true if delegate is set
+     */
+    boolean hasDelegate();
 
 }
diff --git a/core/net/src/main/java/org/onlab/onos/cluster/impl/ClusterManager.java b/core/net/src/main/java/org/onlab/onos/cluster/impl/ClusterManager.java
index d0cc949..9913ad0 100644
--- a/core/net/src/main/java/org/onlab/onos/cluster/impl/ClusterManager.java
+++ b/core/net/src/main/java/org/onlab/onos/cluster/impl/ClusterManager.java
@@ -53,6 +53,7 @@
 
     @Deactivate
     public void deactivate() {
+        store.unsetDelegate(delegate);
         eventDispatcher.removeSink(ClusterEvent.class);
         log.info("Stopped");
     }
diff --git a/core/net/src/main/java/org/onlab/onos/net/device/impl/DeviceManager.java b/core/net/src/main/java/org/onlab/onos/net/device/impl/DeviceManager.java
index 9b6c83a..e0be29a 100644
--- a/core/net/src/main/java/org/onlab/onos/net/device/impl/DeviceManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/device/impl/DeviceManager.java
@@ -26,6 +26,7 @@
 import org.onlab.onos.net.device.DeviceProviderService;
 import org.onlab.onos.net.device.DeviceService;
 import org.onlab.onos.net.device.DeviceStore;
+import org.onlab.onos.net.device.DeviceStoreDelegate;
 import org.onlab.onos.net.device.PortDescription;
 import org.onlab.onos.net.provider.AbstractProviderRegistry;
 import org.onlab.onos.net.provider.AbstractProviderService;
@@ -33,8 +34,8 @@
 
 import java.util.List;
 
-import static org.onlab.onos.net.device.DeviceEvent.Type.*;
 import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.onos.net.device.DeviceEvent.Type.DEVICE_MASTERSHIP_CHANGED;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -57,6 +58,8 @@
     protected final AbstractListenerRegistry<DeviceEvent, DeviceListener>
             listenerRegistry = new AbstractListenerRegistry<>();
 
+    private DeviceStoreDelegate delegate = new InternalStoreDelegate();
+
     private final MastershipListener mastershipListener = new InnerMastershipListener();
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -73,6 +76,7 @@
 
     @Activate
     public void activate() {
+        store.setDelegate(delegate);
         eventDispatcher.addSink(DeviceEvent.class, listenerRegistry);
         mastershipService.addListener(mastershipListener);
         log.info("Started");
@@ -80,6 +84,7 @@
 
     @Deactivate
     public void deactivate() {
+        store.unsetDelegate(delegate);
         mastershipService.removeListener(mastershipListener);
         eventDispatcher.removeSink(DeviceEvent.class);
         log.info("Stopped");
@@ -248,4 +253,12 @@
             }
         }
     }
+
+    // Store delegate to re-post events emitted from the store.
+    private class InternalStoreDelegate implements DeviceStoreDelegate {
+        @Override
+        public void notify(DeviceEvent event) {
+            post(event);
+        }
+    }
 }
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceStore.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceStore.java
index 78d6a4c..9b78798 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceStore.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceStore.java
@@ -15,8 +15,10 @@
 import org.onlab.onos.net.device.DeviceDescription;
 import org.onlab.onos.net.device.DeviceEvent;
 import org.onlab.onos.net.device.DeviceStore;
+import org.onlab.onos.net.device.DeviceStoreDelegate;
 import org.onlab.onos.net.device.PortDescription;
 import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.store.AbstractStore;
 import org.slf4j.Logger;
 
 import java.util.ArrayList;
@@ -40,7 +42,9 @@
  */
 @Component(immediate = true)
 @Service
-public class SimpleDeviceStore implements DeviceStore {
+public class SimpleDeviceStore
+        extends AbstractStore<DeviceEvent, DeviceStoreDelegate>
+        implements DeviceStore {
 
     private final Logger log = getLogger(getClass());
 
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleHostStore.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleHostStore.java
index bcd84df..be609a8 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleHostStore.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleHostStore.java
@@ -24,8 +24,10 @@
 import org.onlab.onos.net.host.HostDescription;
 import org.onlab.onos.net.host.HostEvent;
 import org.onlab.onos.net.host.HostStore;
+import org.onlab.onos.net.host.HostStoreDelegate;
 import org.onlab.onos.net.host.PortAddresses;
 import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.store.AbstractStore;
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
@@ -41,7 +43,9 @@
  */
 @Component(immediate = true)
 @Service
-public class SimpleHostStore implements HostStore {
+public class SimpleHostStore
+        extends AbstractStore<HostEvent, HostStoreDelegate>
+        implements HostStore {
 
     private final Logger log = getLogger(getClass());
 
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkStore.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkStore.java
index 5c99682..ccb2bfb 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkStore.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleLinkStore.java
@@ -14,7 +14,9 @@
 import org.onlab.onos.net.link.LinkDescription;
 import org.onlab.onos.net.link.LinkEvent;
 import org.onlab.onos.net.link.LinkStore;
+import org.onlab.onos.net.link.LinkStoreDelegate;
 import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.store.AbstractStore;
 import org.slf4j.Logger;
 
 import java.util.Collections;
@@ -35,7 +37,9 @@
  */
 @Component(immediate = true)
 @Service
-public class SimpleLinkStore implements LinkStore {
+public class SimpleLinkStore
+        extends AbstractStore<LinkEvent, LinkStoreDelegate>
+        implements LinkStore {
 
     private final Logger log = getLogger(getClass());
 
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleMastershipStore.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleMastershipStore.java
index 24480c6..feea6ee 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleMastershipStore.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleMastershipStore.java
@@ -15,9 +15,11 @@
 import org.onlab.onos.cluster.DefaultControllerNode;
 import org.onlab.onos.cluster.MastershipEvent;
 import org.onlab.onos.cluster.MastershipStore;
+import org.onlab.onos.cluster.MastershipStoreDelegate;
 import org.onlab.onos.cluster.NodeId;
 import org.onlab.onos.net.DeviceId;
 import org.onlab.onos.net.MastershipRole;
+import org.onlab.onos.store.AbstractStore;
 import org.onlab.packet.IpPrefix;
 import org.slf4j.Logger;
 
@@ -29,7 +31,9 @@
  */
 @Component(immediate = true)
 @Service
-public class SimpleMastershipStore implements MastershipStore {
+public class SimpleMastershipStore
+        extends AbstractStore<MastershipEvent, MastershipStoreDelegate>
+        implements MastershipStore {
 
     public static final IpPrefix LOCALHOST = IpPrefix.valueOf("127.0.0.1");