Enahnced topology and flow stores to extend general store.
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
index f00b595..bfd05f2 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
@@ -1,11 +1,12 @@
 package org.onlab.onos.net.flow;
 
 import org.onlab.onos.net.DeviceId;
+import org.onlab.onos.store.Store;
 
 /**
  * Manages inventory of flow rules; not intended for direct use.
  */
-public interface FlowRuleStore {
+public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegate> {
 
     /**
      * Returns the flow entries associated with a device.
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStoreDelegate.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStoreDelegate.java
new file mode 100644
index 0000000..119712b
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStoreDelegate.java
@@ -0,0 +1,9 @@
+package org.onlab.onos.net.flow;
+
+import org.onlab.onos.store.StoreDelegate;
+
+/**
+ * Flow rule store delegate abstraction.
+ */
+public interface FlowRuleStoreDelegate extends StoreDelegate<FlowRuleEvent> {
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/topology/TopologyStore.java b/core/api/src/main/java/org/onlab/onos/net/topology/TopologyStore.java
index adc6145..1945f4c 100644
--- a/core/api/src/main/java/org/onlab/onos/net/topology/TopologyStore.java
+++ b/core/api/src/main/java/org/onlab/onos/net/topology/TopologyStore.java
@@ -6,6 +6,7 @@
 import org.onlab.onos.net.Link;
 import org.onlab.onos.net.Path;
 import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.store.Store;
 
 import java.util.List;
 import java.util.Set;
@@ -13,7 +14,7 @@
 /**
  * Manages inventory of topology snapshots; not intended for direct use.
  */
-public interface TopologyStore {
+public interface TopologyStore extends Store<TopologyEvent, TopologyStoreDelegate> {
 
     /**
      * Returns the current topology snapshot.
diff --git a/core/api/src/main/java/org/onlab/onos/net/topology/TopologyStoreDelegate.java b/core/api/src/main/java/org/onlab/onos/net/topology/TopologyStoreDelegate.java
new file mode 100644
index 0000000..2a19a0c
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/topology/TopologyStoreDelegate.java
@@ -0,0 +1,9 @@
+package org.onlab.onos.net.topology;
+
+import org.onlab.onos.store.StoreDelegate;
+
+/**
+ * Topology store delegate abstraction.
+ */
+public interface TopologyStoreDelegate extends StoreDelegate<TopologyEvent> {
+}
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 e0be29a..3dfce00 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
@@ -60,7 +60,7 @@
 
     private DeviceStoreDelegate delegate = new InternalStoreDelegate();
 
-    private final MastershipListener mastershipListener = new InnerMastershipListener();
+    private final MastershipListener mastershipListener = new InternalMastershipListener();
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected DeviceStore store;
@@ -244,7 +244,7 @@
     }
 
     // Intercepts mastership events
-    private class InnerMastershipListener implements MastershipListener {
+    private class InternalMastershipListener implements MastershipListener {
         @Override
         public void event(MastershipEvent event) {
             // FIXME: for now we're taking action only on becoming master
diff --git a/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java b/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
index b3481c1..51fde29 100644
--- a/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
@@ -27,6 +27,8 @@
 import org.onlab.onos.net.flow.FlowRuleProviderService;
 import org.onlab.onos.net.flow.FlowRuleService;
 import org.onlab.onos.net.flow.FlowRuleStore;
+import org.onlab.onos.net.flow.FlowRuleStoreDelegate;
+import org.onlab.onos.net.host.HostStoreDelegate;
 import org.onlab.onos.net.provider.AbstractProviderRegistry;
 import org.onlab.onos.net.provider.AbstractProviderService;
 import org.slf4j.Logger;
@@ -48,6 +50,8 @@
     private final AbstractListenerRegistry<FlowRuleEvent, FlowRuleListener>
     listenerRegistry = new AbstractListenerRegistry<>();
 
+    private FlowRuleStoreDelegate delegate = new InternalStoreDelegate();
+
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected FlowRuleStore store;
 
@@ -59,12 +63,14 @@
 
     @Activate
     public void activate() {
+        store.setDelegate(delegate);
         eventDispatcher.addSink(FlowRuleEvent.class, listenerRegistry);
         log.info("Started");
     }
 
     @Deactivate
     public void deactivate() {
+        store.unsetDelegate(delegate);
         eventDispatcher.removeSink(FlowRuleEvent.class);
         log.info("Stopped");
     }
@@ -196,4 +202,11 @@
         }
     }
 
+    // Store delegate to re-post events emitted from the store.
+    private class InternalStoreDelegate implements FlowRuleStoreDelegate {
+        @Override
+        public void notify(FlowRuleEvent event) {
+            eventDispatcher.post(event);
+        }
+    }
 }
diff --git a/core/net/src/main/java/org/onlab/onos/net/host/impl/HostManager.java b/core/net/src/main/java/org/onlab/onos/net/host/impl/HostManager.java
index 9b8ecf7..e3f53fe 100644
--- a/core/net/src/main/java/org/onlab/onos/net/host/impl/HostManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/host/impl/HostManager.java
@@ -1,10 +1,5 @@
 package org.onlab.onos.net.host.impl;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.util.Set;
-
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -26,6 +21,7 @@
 import org.onlab.onos.net.host.HostProviderService;
 import org.onlab.onos.net.host.HostService;
 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.AbstractProviderRegistry;
 import org.onlab.onos.net.provider.AbstractProviderService;
@@ -35,6 +31,11 @@
 import org.onlab.packet.VlanId;
 import org.slf4j.Logger;
 
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
 /**
  * Provides basic implementation of the host SB &amp; NB APIs.
  */
@@ -50,6 +51,8 @@
     private final AbstractListenerRegistry<HostEvent, HostListener>
             listenerRegistry = new AbstractListenerRegistry<>();
 
+    private HostStoreDelegate delegate = new InternalStoreDelegate();
+
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected HostStore store;
 
@@ -59,12 +62,14 @@
 
     @Activate
     public void activate() {
+        store.setDelegate(delegate);
         eventDispatcher.addSink(HostEvent.class, listenerRegistry);
         log.info("Started");
     }
 
     @Deactivate
     public void deactivate() {
+        store.unsetDelegate(delegate);
         eventDispatcher.removeSink(HostEvent.class);
         log.info("Stopped");
     }
@@ -219,4 +224,11 @@
         }
     }
 
+    // Store delegate to re-post events emitted from the store.
+    private class InternalStoreDelegate implements HostStoreDelegate {
+        @Override
+        public void notify(HostEvent event) {
+            post(event);
+        }
+    }
 }
diff --git a/core/net/src/main/java/org/onlab/onos/net/link/impl/LinkManager.java b/core/net/src/main/java/org/onlab/onos/net/link/impl/LinkManager.java
index 9ac5e80..493580d 100644
--- a/core/net/src/main/java/org/onlab/onos/net/link/impl/LinkManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/link/impl/LinkManager.java
@@ -28,6 +28,7 @@
 import org.onlab.onos.net.link.LinkProviderService;
 import org.onlab.onos.net.link.LinkService;
 import org.onlab.onos.net.link.LinkStore;
+import org.onlab.onos.net.link.LinkStoreDelegate;
 import org.onlab.onos.net.provider.AbstractProviderRegistry;
 import org.onlab.onos.net.provider.AbstractProviderService;
 import org.slf4j.Logger;
@@ -52,7 +53,9 @@
     protected final AbstractListenerRegistry<LinkEvent, LinkListener>
             listenerRegistry = new AbstractListenerRegistry<>();
 
-    private final DeviceListener deviceListener = new InnerDeviceListener();
+    private LinkStoreDelegate delegate = new InternalStoreDelegate();
+
+    private final DeviceListener deviceListener = new InternalDeviceListener();
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected LinkStore store;
@@ -65,6 +68,7 @@
 
     @Activate
     public void activate() {
+        store.setDelegate(delegate);
         eventDispatcher.addSink(LinkEvent.class, listenerRegistry);
         deviceService.addListener(deviceListener);
         log.info("Started");
@@ -72,6 +76,7 @@
 
     @Deactivate
     public void deactivate() {
+        store.unsetDelegate(delegate);
         eventDispatcher.removeSink(LinkEvent.class);
         deviceService.removeListener(deviceListener);
         log.info("Stopped");
@@ -154,7 +159,7 @@
 
     // Auxiliary interceptor for device remove events to prune links that
     // are associated with the removed device or its port.
-    private class InnerDeviceListener implements DeviceListener {
+    private class InternalDeviceListener implements DeviceListener {
         @Override
         public void event(DeviceEvent event) {
             if (event.type() == DeviceEvent.Type.DEVICE_REMOVED) {
@@ -236,4 +241,11 @@
         }
     }
 
+    // Store delegate to re-post events emitted from the store.
+    private class InternalStoreDelegate implements LinkStoreDelegate {
+        @Override
+        public void notify(LinkEvent event) {
+            post(event);
+        }
+    }
 }
diff --git a/core/net/src/main/java/org/onlab/onos/net/topology/impl/TopologyManager.java b/core/net/src/main/java/org/onlab/onos/net/topology/impl/TopologyManager.java
index 57e9fb7..4846944 100644
--- a/core/net/src/main/java/org/onlab/onos/net/topology/impl/TopologyManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/topology/impl/TopologyManager.java
@@ -28,6 +28,7 @@
 import org.onlab.onos.net.topology.TopologyProviderService;
 import org.onlab.onos.net.topology.TopologyService;
 import org.onlab.onos.net.topology.TopologyStore;
+import org.onlab.onos.net.topology.TopologyStoreDelegate;
 import org.slf4j.Logger;
 
 import java.util.List;
@@ -56,6 +57,8 @@
     private final AbstractListenerRegistry<TopologyEvent, TopologyListener>
             listenerRegistry = new AbstractListenerRegistry<>();
 
+    private TopologyStoreDelegate delegate = new InternalStoreDelegate();
+
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected TopologyStore store;
 
@@ -65,12 +68,14 @@
 
     @Activate
     public void activate() {
+        store.setDelegate(delegate);
         eventDispatcher.addSink(TopologyEvent.class, listenerRegistry);
         log.info("Started");
     }
 
     @Deactivate
     public void deactivate() {
+        store.unsetDelegate(delegate);
         eventDispatcher.removeSink(TopologyEvent.class);
         log.info("Stopped");
     }
@@ -188,4 +193,11 @@
         }
     }
 
+    // Store delegate to re-post events emitted from the store.
+    private class InternalStoreDelegate implements TopologyStoreDelegate {
+        @Override
+        public void notify(TopologyEvent event) {
+            eventDispatcher.post(event);
+        }
+    }
 }
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleFlowRuleStore.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleFlowRuleStore.java
index fbfd0ee..9681f3b 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleFlowRuleStore.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleFlowRuleStore.java
@@ -13,6 +13,8 @@
 import org.onlab.onos.net.flow.FlowRuleEvent;
 import org.onlab.onos.net.flow.FlowRuleEvent.Type;
 import org.onlab.onos.net.flow.FlowRuleStore;
+import org.onlab.onos.net.flow.FlowRuleStoreDelegate;
+import org.onlab.onos.store.AbstractStore;
 import org.slf4j.Logger;
 
 import com.google.common.collect.ArrayListMultimap;
@@ -24,7 +26,9 @@
  */
 @Component(immediate = true)
 @Service
-public class SimpleFlowRuleStore implements FlowRuleStore {
+public class SimpleFlowRuleStore
+        extends AbstractStore<FlowRuleEvent, FlowRuleStoreDelegate>
+        implements FlowRuleStore {
 
     private final Logger log = getLogger(getClass());
 
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleTopologyStore.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleTopologyStore.java
index 5d9c8de..32cc1f7 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleTopologyStore.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleTopologyStore.java
@@ -18,6 +18,8 @@
 import org.onlab.onos.net.topology.TopologyEvent;
 import org.onlab.onos.net.topology.TopologyGraph;
 import org.onlab.onos.net.topology.TopologyStore;
+import org.onlab.onos.net.topology.TopologyStoreDelegate;
+import org.onlab.onos.store.AbstractStore;
 import org.slf4j.Logger;
 
 import java.util.List;
@@ -31,7 +33,9 @@
  */
 @Component(immediate = true)
 @Service
-public class SimpleTopologyStore implements TopologyStore {
+public class SimpleTopologyStore
+        extends AbstractStore<TopologyEvent, TopologyStoreDelegate>
+        implements TopologyStore {
 
     private final Logger log = getLogger(getClass());