Converted UiSharedTopologyModel to be a @Service.

Change-Id: Idc8df1b9c0a52db01ac545567dacc0e1c770f84a
diff --git a/core/api/src/main/java/org/onosproject/net/region/RegionService.java b/core/api/src/main/java/org/onosproject/net/region/RegionService.java
index 7591e72..259c8b0 100644
--- a/core/api/src/main/java/org/onosproject/net/region/RegionService.java
+++ b/core/api/src/main/java/org/onosproject/net/region/RegionService.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.net.region;
 
+import org.onosproject.event.ListenerService;
 import org.onosproject.net.DeviceId;
 
 import java.util.Set;
@@ -23,7 +24,7 @@
 /**
  * Service for interacting with inventory of network control regions.
  */
-public interface RegionService {
+public interface RegionService extends ListenerService<RegionEvent, RegionListener> {
 
     /**
      * Returns set of all regions.
diff --git a/core/api/src/main/java/org/onosproject/ui/model/topo/UiCluster.java b/core/api/src/main/java/org/onosproject/ui/model/topo/UiCluster.java
index 2ec0444..87afc56b 100644
--- a/core/api/src/main/java/org/onosproject/ui/model/topo/UiCluster.java
+++ b/core/api/src/main/java/org/onosproject/ui/model/topo/UiCluster.java
@@ -19,5 +19,5 @@
 /**
  * Encapsulates the notion of the ONOS cluster.
  */
-public class UiCluster {
+public class UiCluster extends UiElement {
 }
diff --git a/core/api/src/main/java/org/onosproject/ui/model/topo/UiClusterMember.java b/core/api/src/main/java/org/onosproject/ui/model/topo/UiClusterMember.java
index 7a6ad02..71bba93 100644
--- a/core/api/src/main/java/org/onosproject/ui/model/topo/UiClusterMember.java
+++ b/core/api/src/main/java/org/onosproject/ui/model/topo/UiClusterMember.java
@@ -19,5 +19,5 @@
 /**
  * Represents an individual member of the cluster (ONOS instance).
  */
-public class UiClusterMember {
+public class UiClusterMember extends UiElement {
 }
diff --git a/core/api/src/main/java/org/onosproject/ui/model/topo/UiElement.java b/core/api/src/main/java/org/onosproject/ui/model/topo/UiElement.java
new file mode 100644
index 0000000..4f2f9cb
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/ui/model/topo/UiElement.java
@@ -0,0 +1,23 @@
+/*
+ *  Copyright 2016 Open Networking Laboratory
+ *
+ *  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 org.onosproject.ui.model.topo;
+
+/**
+ * Abstract base class of all elements in the UI topology model.
+ */
+public class UiElement {
+}
diff --git a/core/api/src/main/java/org/onosproject/ui/model/topo/UiLink.java b/core/api/src/main/java/org/onosproject/ui/model/topo/UiLink.java
index 15b3996..fe1842e 100644
--- a/core/api/src/main/java/org/onosproject/ui/model/topo/UiLink.java
+++ b/core/api/src/main/java/org/onosproject/ui/model/topo/UiLink.java
@@ -19,5 +19,5 @@
 /**
  * Represents a bi-directional link backed by two uni-directional links.
  */
-public class UiLink {
+public class UiLink extends UiElement {
 }
diff --git a/core/api/src/main/java/org/onosproject/ui/model/topo/UiNode.java b/core/api/src/main/java/org/onosproject/ui/model/topo/UiNode.java
index 09b1791..53bdfde 100644
--- a/core/api/src/main/java/org/onosproject/ui/model/topo/UiNode.java
+++ b/core/api/src/main/java/org/onosproject/ui/model/topo/UiNode.java
@@ -19,5 +19,5 @@
 /**
  * Represents a node drawn on the topology view (region, device, host).
  */
-public abstract class UiNode {
+public abstract class UiNode extends UiElement {
 }
diff --git a/core/api/src/main/java/org/onosproject/ui/model/topo/UiTopology.java b/core/api/src/main/java/org/onosproject/ui/model/topo/UiTopology.java
index e54ac66..5f4195e 100644
--- a/core/api/src/main/java/org/onosproject/ui/model/topo/UiTopology.java
+++ b/core/api/src/main/java/org/onosproject/ui/model/topo/UiTopology.java
@@ -19,5 +19,5 @@
 /**
  * Represents the overall network topology.
  */
-public class UiTopology {
+public class UiTopology extends UiElement {
 }
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/UiWebSocket.java b/web/gui/src/main/java/org/onosproject/ui/impl/UiWebSocket.java
index 5685d4d..731840e 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/UiWebSocket.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/UiWebSocket.java
@@ -29,6 +29,7 @@
 import org.onosproject.ui.UiMessageHandler;
 import org.onosproject.ui.UiTopoOverlayFactory;
 import org.onosproject.ui.impl.topo.UiTopoSession;
+import org.onosproject.ui.impl.topo.model.UiSharedTopologyModel;
 import org.onosproject.ui.topo.TopoConstants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -65,7 +66,7 @@
     private TopoOverlayCache overlayCache;
 
     /**
-     * Creates a new web-socket for serving data to GUI.
+     * Creates a new web-socket for serving data to the Web UI.
      *
      * @param directory service directory
      * @param userName user name of the logged-in user
@@ -73,7 +74,8 @@
     public UiWebSocket(ServiceDirectory directory, String userName) {
         this.directory = directory;
         this.userName = userName;
-        this.topoSession = new UiTopoSession(this);
+        this.topoSession =
+                new UiTopoSession(this, directory.get(UiSharedTopologyModel.class));
     }
 
     @Override
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/topo/UiTopoSession.java b/web/gui/src/main/java/org/onosproject/ui/impl/topo/UiTopoSession.java
index fbc7fa42..70698ec 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/topo/UiTopoSession.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/topo/UiTopoSession.java
@@ -18,6 +18,8 @@
 
 import org.onosproject.ui.UiTopoLayoutService;
 import org.onosproject.ui.impl.UiWebSocket;
+import org.onosproject.ui.impl.topo.model.UiModelEvent;
+import org.onosproject.ui.impl.topo.model.UiModelListener;
 import org.onosproject.ui.impl.topo.model.UiSharedTopologyModel;
 import org.onosproject.ui.model.topo.UiTopoLayout;
 import org.slf4j.Logger;
@@ -26,14 +28,14 @@
 /**
  * Coordinates with the {@link UiTopoLayoutService} to access
  * {@link UiTopoLayout}s, and with the {@link UiSharedTopologyModel} which
- * maintains a local model of the network entities,
- * tailored specifically for displaying on the UI.
+ * maintains a local model of the network entities, tailored specifically
+ * for displaying on the UI.
  * <p>
  * Note that an instance of this class will be created for each
  * {@link UiWebSocket} connection, and will contain
  * the state of how the topology is laid out for the logged-in user.
  */
-public class UiTopoSession {
+public class UiTopoSession implements UiModelListener {
     private final Logger log = LoggerFactory.getLogger(getClass());
 
     private final UiWebSocket webSocket;
@@ -50,11 +52,12 @@
      * Creates a new topology session for the specified web socket connection.
      *
      * @param webSocket web socket
+     * @param model share topology model
      */
-    public UiTopoSession(UiWebSocket webSocket) {
+    public UiTopoSession(UiWebSocket webSocket, UiSharedTopologyModel model) {
         this.webSocket = webSocket;
         this.username = webSocket.userName();
-        this.sharedModel = UiSharedTopologyModel.instance();
+        this.sharedModel = model;
     }
 
     /**
@@ -87,4 +90,10 @@
     public String toString() {
         return String.format("{UiTopoSession for user <%s>}", username);
     }
+
+    @Override
+    public void event(UiModelEvent event) {
+        log.info("Event received: {}", event);
+        // TODO: handle model events from the cache...
+    }
 }
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/ModelCache.java b/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/ModelCache.java
new file mode 100644
index 0000000..d72ff3d
--- /dev/null
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/ModelCache.java
@@ -0,0 +1,75 @@
+/*
+ *  Copyright 2016 Open Networking Laboratory
+ *
+ *  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 org.onosproject.ui.impl.topo.model;
+
+import org.onosproject.event.EventDispatcher;
+import org.onosproject.net.Device;
+import org.onosproject.ui.model.topo.UiDevice;
+
+/**
+ * UI Topology Model cache.
+ */
+class ModelCache {
+
+    private final EventDispatcher dispatcher;
+
+    ModelCache(EventDispatcher eventDispatcher) {
+        this.dispatcher = eventDispatcher;
+    }
+
+    /**
+     * Clear our model.
+     */
+    void clear() {
+        // TODO: clear our internal state
+    }
+
+    /**
+     * Create our internal model of the global topology.
+     */
+    void load() {
+//        loadClusterMembers();
+//        loadRegions();
+//        loadDevices();
+//        loadHosts();
+//        loadLinks();
+    }
+
+
+    // add or update device
+    void addOrUpdateDevice(Device device) {
+        // fetch UiDevice
+        UiDevice uiDevice = new UiDevice();
+
+        dispatcher.post(
+                new UiModelEvent(UiModelEvent.Type.DEVICE_ADDED, uiDevice)
+        );
+
+    }
+
+    void removeDevice(Device device) {
+        UiDevice uiDevice = new UiDevice();
+
+        dispatcher.post(
+                new UiModelEvent(UiModelEvent.Type.DEVICE_REMOVED, uiDevice)
+        );
+
+    }
+
+    // TODO remaining model objects
+
+}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/UiModelEvent.java b/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/UiModelEvent.java
new file mode 100644
index 0000000..c37f27d
--- /dev/null
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/UiModelEvent.java
@@ -0,0 +1,36 @@
+/*
+ *  Copyright 2016 Open Networking Laboratory
+ *
+ *  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 org.onosproject.ui.impl.topo.model;
+
+import org.onosproject.event.AbstractEvent;
+import org.onosproject.ui.model.topo.UiElement;
+
+/**
+ * UI Topology model events.
+ */
+public class UiModelEvent extends AbstractEvent<UiModelEvent.Type, UiElement> {
+
+    protected UiModelEvent(Type type, UiElement subject) {
+        super(type, subject);
+    }
+
+    enum Type {
+        DEVICE_ADDED,
+        DEVICE_REMOVED,
+        // TODO...
+    }
+}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/UiModelListener.java b/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/UiModelListener.java
new file mode 100644
index 0000000..cf67792
--- /dev/null
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/UiModelListener.java
@@ -0,0 +1,25 @@
+/*
+ *  Copyright 2016 Open Networking Laboratory
+ *
+ *  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 org.onosproject.ui.impl.topo.model;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Can receive {@link UiModelEvent}s.
+ */
+public interface UiModelListener extends EventListener<UiModelEvent> {
+}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/UiSharedTopologyModel.java b/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/UiSharedTopologyModel.java
index 7ce5c56..885eed2 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/UiSharedTopologyModel.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/topo/model/UiSharedTopologyModel.java
@@ -16,16 +16,22 @@
 
 package org.onosproject.ui.impl.topo.model;
 
-import org.onlab.osgi.DefaultServiceDirectory;
-import org.onlab.osgi.ServiceDirectory;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
 import org.onosproject.cluster.ClusterEvent;
 import org.onosproject.cluster.ClusterEventListener;
 import org.onosproject.cluster.ClusterService;
+import org.onosproject.event.AbstractListenerManager;
 import org.onosproject.incubator.net.PortStatisticsService;
 import org.onosproject.incubator.net.tunnel.TunnelService;
 import org.onosproject.mastership.MastershipEvent;
 import org.onosproject.mastership.MastershipListener;
 import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.Device;
 import org.onosproject.net.device.DeviceEvent;
 import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceService;
@@ -50,30 +56,104 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.HashSet;
-import java.util.Set;
-
 /**
- * A lazily-initialized Singleton that creates and maintains the UI-model
- * of the network topology.
+ * Service that creates and maintains the UI-model of the network topology.
  */
-public final class UiSharedTopologyModel {
+@Component(immediate = true)
+@Service(value = UiSharedTopologyModel.class)
+public final class UiSharedTopologyModel
+        extends AbstractListenerManager<UiModelEvent, UiModelListener> {
 
     private static final Logger log =
             LoggerFactory.getLogger(UiSharedTopologyModel.class);
 
-    private final ModelEventListener modelEventListener;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private ClusterService clusterService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private MastershipService mastershipService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private RegionService regionService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private DeviceService deviceService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private LinkService linkService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private HostService hostService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private IntentService intentService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private FlowRuleService flowService;
 
-    private final Set<UiTopoSession> sessions = new HashSet<>();
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private StatisticService flowStatsService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private PortStatisticsService portStatsService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private TopologyService topologyService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private TunnelService tunnelService;
 
-    private UiSharedTopologyModel() {
-        modelEventListener = new ModelEventListener().init();
+    private final ClusterEventListener clusterListener =
+            new InternalClusterListener();
+    private final MastershipListener mastershipListener =
+            new InternalMastershipListener();
+    private final RegionListener regionListener =
+            new InternalRegionListener();
+    private final DeviceListener deviceListener =
+            new InternalDeviceListener();
+    private final LinkListener linkListener =
+            new InternalLinkListener();
+    private final HostListener hostListener =
+            new InternalHostListener();
+    private final IntentListener intentListener =
+            new InternalIntentListener();
+    private final FlowRuleListener flowRuleListener =
+            new InternalFlowRuleListener();
 
-        // TODO: build and maintain the state of the model
-        // (1) query model for current state
-        // (2) update state as model events arrive
+
+    private ModelCache cache;
+
+
+    @Activate
+    protected void activate() {
+        cache = new ModelCache(eventDispatcher);
+
+        eventDispatcher.addSink(UiModelEvent.class, listenerRegistry);
+
+        clusterService.addListener(clusterListener);
+        mastershipService.addListener(mastershipListener);
+        regionService.addListener(regionListener);
+        deviceService.addListener(deviceListener);
+        linkService.addListener(linkListener);
+        hostService.addListener(hostListener);
+        intentService.addListener(intentListener);
+        flowService.addListener(flowRuleListener);
+
+        cache.load();
+
+        log.info("Started");
     }
 
+    @Deactivate
+    protected void deactivate() {
+        eventDispatcher.removeSink(UiModelEvent.class);
+
+        clusterService.removeListener(clusterListener);
+        mastershipService.removeListener(mastershipListener);
+        regionService.removeListener(regionListener);
+        deviceService.removeListener(deviceListener);
+        linkService.removeListener(linkListener);
+        hostService.removeListener(hostListener);
+        intentService.removeListener(intentListener);
+        flowService.removeListener(flowRuleListener);
+
+        cache.clear();
+        cache = null;
+
+        log.info("Stopped");
+    }
+
+
     /**
      * Registers a UI topology session with the topology model.
      *
@@ -81,7 +161,7 @@
      */
     public void register(UiTopoSession session) {
         log.info("Registering topology session {}", session);
-        sessions.add(session);
+        addListener(session);
     }
 
     /**
@@ -91,138 +171,82 @@
      */
     public void unregister(UiTopoSession session) {
         log.info("Unregistering topology session {}", session);
-        sessions.remove(session);
+        removeListener(session);
     }
 
 
-    // TODO: notify registered sessions when changes happen to the model
-
-
-    // ----------
-
-    // inner class to encapsulate the model listeners
-    private final class ModelEventListener {
-
-        // TODO: Review - is this good enough? couldn't otherwise see how to inject
-        private final ServiceDirectory directory = new DefaultServiceDirectory();
-
-        private ClusterService clusterService;
-        private MastershipService mastershipService;
-        private RegionService regionService;
-        private DeviceService deviceService;
-        private LinkService linkService;
-        private HostService hostService;
-        private IntentService intentService;
-        private FlowRuleService flowService;
-
-        private StatisticService flowStatsService;
-        private PortStatisticsService portStatsService;
-        private TopologyService topologyService;
-        private TunnelService tunnelService;
-
-        private ModelEventListener init() {
-            clusterService = directory.get(ClusterService.class);
-            mastershipService = directory.get(MastershipService.class);
-            regionService = directory.get(RegionService.class);
-            deviceService = directory.get(DeviceService.class);
-            linkService = directory.get(LinkService.class);
-            hostService = directory.get(HostService.class);
-            intentService = directory.get(IntentService.class);
-            flowService = directory.get(FlowRuleService.class);
-
-            // passive services (?) to whom we are not listening...
-            flowStatsService = directory.get(StatisticService.class);
-            portStatsService = directory.get(PortStatisticsService.class);
-            topologyService = directory.get(TopologyService.class);
-            tunnelService = directory.get(TunnelService.class);
-
-            return this;
+    private class InternalClusterListener implements ClusterEventListener {
+        @Override
+        public void event(ClusterEvent event) {
+            // TODO: handle cluster event
         }
+    }
 
-        private class InternalClusterListener implements ClusterEventListener {
-            @Override
-            public void event(ClusterEvent event) {
-                // TODO: handle cluster event
-                // (1) emit cluster member event
-            }
+    private class InternalMastershipListener implements MastershipListener {
+        @Override
+        public void event(MastershipEvent event) {
+            // TODO: handle mastership event
         }
+    }
 
-        private class InternalMastershipListener implements MastershipListener {
-            @Override
-            public void event(MastershipEvent event) {
-                // TODO: handle mastership event
-                // (1) emit cluster member update for all members
-                // (2) emit update device event for he whose mastership changed
-            }
+    private class InternalRegionListener implements RegionListener {
+        @Override
+        public void event(RegionEvent event) {
+            // TODO: handle region event
         }
+    }
 
-        private class InternalRegionListener implements RegionListener {
-            @Override
-            public void event(RegionEvent event) {
-                // TODO: handle region event
-                // (1) emit region event
-            }
-        }
+    private class InternalDeviceListener implements DeviceListener {
+        @Override
+        public void event(DeviceEvent event) {
 
-        private class InternalDeviceListener implements DeviceListener {
-            @Override
-            public void event(DeviceEvent event) {
-                // TODO: handle device event
-                // (1) emit device event
-            }
-        }
+            Device device = event.subject();
 
-        private class InternalLinkListener implements LinkListener {
-            @Override
-            public void event(LinkEvent event) {
-                // TODO: handle link event
-                // (1) consolidate infrastructure links -> UiLink (?)
-                // (2) emit link event
-            }
-        }
+            switch (event.type()) {
 
-        private class InternalHostListener implements HostListener {
-            @Override
-            public void event(HostEvent event) {
-                // TODO: handle host event
-                // (1) emit host event
-            }
-        }
+                case DEVICE_ADDED:
+                case DEVICE_UPDATED:
+                case DEVICE_AVAILABILITY_CHANGED:
+                case DEVICE_SUSPENDED:
+                    cache.addOrUpdateDevice(device);
+                    break;
 
-        private class InternalIntentListener implements IntentListener {
-            @Override
-            public void event(IntentEvent event) {
-                // TODO: handle intent event
-                // (1) update cache of intent counts?
-            }
-        }
+                case DEVICE_REMOVED:
+                    cache.removeDevice(device);
+                    break;
 
-        private class InternalFlowRuleListener implements FlowRuleListener {
-            @Override
-            public void event(FlowRuleEvent event) {
-                // TODO: handle flowrule event
-                // (1) update cache of flow counts?
+                default:
+                    break;
             }
         }
     }
 
-    // ----------
-
-    /**
-     * Bill Pugh Singleton pattern. INSTANCE won't be instantiated until the
-     * LazyHolder class is loaded via a call to the instance() method below.
-     */
-    private static class LazyHolder {
-        private static final UiSharedTopologyModel INSTANCE =
-                new UiSharedTopologyModel();
+    private class InternalLinkListener implements LinkListener {
+        @Override
+        public void event(LinkEvent event) {
+            // TODO: handle link event
+        }
     }
 
-    /**
-     * Returns a reference to the Singleton UI network topology model.
-     *
-     * @return the singleton topology model
-     */
-    public static UiSharedTopologyModel instance() {
-        return LazyHolder.INSTANCE;
+    private class InternalHostListener implements HostListener {
+        @Override
+        public void event(HostEvent event) {
+            // TODO: handle host event
+        }
     }
+
+    private class InternalIntentListener implements IntentListener {
+        @Override
+        public void event(IntentEvent event) {
+            // TODO: handle intent event
+        }
+    }
+
+    private class InternalFlowRuleListener implements FlowRuleListener {
+        @Override
+        public void event(FlowRuleEvent event) {
+            // TODO: handle flowrule event
+        }
+    }
+
 }