diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/GuiWebSocketServlet.java b/web/gui/src/main/java/org/onosproject/ui/impl/GuiWebSocketServlet.java
index 5a660e0..bc105df 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/GuiWebSocketServlet.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/GuiWebSocketServlet.java
@@ -31,6 +31,7 @@
 /**
  * Web socket servlet capable of creating various sockets for the user interface.
  */
+@Deprecated
 public class GuiWebSocketServlet extends WebSocketServlet {
 
     private static final long PING_DELAY_MS = 5000;
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
new file mode 100644
index 0000000..29505b7
--- /dev/null
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
@@ -0,0 +1,705 @@
+/*
+ * Copyright 2015 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;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableSet;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.util.AbstractAccumulator;
+import org.onlab.util.Accumulator;
+import org.onosproject.cluster.ClusterEvent;
+import org.onosproject.cluster.ClusterEventListener;
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.event.Event;
+import org.onosproject.mastership.MastershipAdminService;
+import org.onosproject.mastership.MastershipEvent;
+import org.onosproject.mastership.MastershipListener;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.Link;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRuleEvent;
+import org.onosproject.net.flow.FlowRuleListener;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.intent.HostToHostIntent;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentListener;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.link.LinkListener;
+import org.onosproject.ui.UiConnection;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_ADDED;
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.HostId.hostId;
+import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED;
+import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_UPDATED;
+import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
+import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED;
+
+/**
+ * Web socket capable of interacting with the GUI topology view.
+ */
+public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
+
+    private static final String APP_ID = "org.onosproject.gui";
+
+    private static final long TRAFFIC_FREQUENCY = 5000;
+    private static final long SUMMARY_FREQUENCY = 30000;
+
+    private static final Comparator<? super ControllerNode> NODE_COMPARATOR =
+            new Comparator<ControllerNode>() {
+                @Override
+                public int compare(ControllerNode o1, ControllerNode o2) {
+                    return o1.id().toString().compareTo(o2.id().toString());
+                }
+            };
+
+
+    private final Timer timer = new Timer("topology-view");
+
+    private static final int MAX_EVENTS = 1000;
+    private static final int MAX_BATCH_MS = 5000;
+    private static final int MAX_IDLE_MS = 1000;
+
+    private ApplicationId appId;
+
+    private final ClusterEventListener clusterListener = new InternalClusterListener();
+    private final MastershipListener mastershipListener = new InternalMastershipListener();
+    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 flowListener = new InternalFlowListener();
+
+    private final Accumulator<Event> eventAccummulator = new InternalEventAccummulator();
+
+    private TimerTask trafficTask;
+    private ObjectNode trafficEvent;
+
+    private TimerTask summaryTask;
+    private ObjectNode summaryEvent;
+
+    private boolean listenersRemoved = false;
+
+    private TopologyViewIntentFilter intentFilter;
+
+    // Current selection context
+    private Set<Host> selectedHosts;
+    private Set<Device> selectedDevices;
+    private List<Intent> selectedIntents;
+    private int currentIntentIndex = -1;
+
+    /**
+     * Creates a new web-socket for serving data to GUI topology view.
+     */
+    public TopologyViewMessageHandler() {
+        super(ImmutableSet.of("topoStart", "topoStop",
+                              "requestDetails",
+                              "updateMeta",
+                              "addHostIntent",
+                              "addMultiSourceIntent",
+                              "requestRelatedIntents",
+                              "requestNextRelatedIntent",
+                              "requestPrevRelatedIntent",
+                              "requestSelectedIntentTraffic",
+                              "requestAllTraffic",
+                              "requestDeviceLinkFlows",
+                              "cancelTraffic",
+                              "requestSummary",
+                              "cancelSummary",
+                              "equalizeMasters"
+        ));
+    }
+
+    @Override
+    public void init(UiConnection connection, ServiceDirectory directory) {
+        super.init(connection, directory);
+        intentFilter = new TopologyViewIntentFilter(intentService, deviceService,
+                                                    hostService, linkService);
+        appId = directory.get(CoreService.class).registerApplication(APP_ID);
+    }
+
+    @Override
+    public void destroy() {
+        cancelAllRequests();
+        super.destroy();
+    }
+
+    // Processes the specified event.
+    @Override
+    public void process(ObjectNode event) {
+        String type = string(event, "event", "unknown");
+        if (type.equals("requestDetails")) {
+            requestDetails(event);
+        } else if (type.equals("updateMeta")) {
+            updateMetaUi(event);
+
+        } else if (type.equals("addHostIntent")) {
+            createHostIntent(event);
+        } else if (type.equals("addMultiSourceIntent")) {
+            createMultiSourceIntent(event);
+
+        } else if (type.equals("requestRelatedIntents")) {
+            stopTrafficMonitoring();
+            requestRelatedIntents(event);
+
+        } else if (type.equals("requestNextRelatedIntent")) {
+            stopTrafficMonitoring();
+            requestAnotherRelatedIntent(event, +1);
+        } else if (type.equals("requestPrevRelatedIntent")) {
+            stopTrafficMonitoring();
+            requestAnotherRelatedIntent(event, -1);
+        } else if (type.equals("requestSelectedIntentTraffic")) {
+            requestSelectedIntentTraffic(event);
+            startTrafficMonitoring(event);
+
+        } else if (type.equals("requestAllTraffic")) {
+            requestAllTraffic(event);
+            startTrafficMonitoring(event);
+
+        } else if (type.equals("requestDeviceLinkFlows")) {
+            requestDeviceLinkFlows(event);
+            startTrafficMonitoring(event);
+
+        } else if (type.equals("cancelTraffic")) {
+            cancelTraffic(event);
+
+        } else if (type.equals("requestSummary")) {
+            requestSummary(event);
+            startSummaryMonitoring(event);
+        } else if (type.equals("cancelSummary")) {
+            stopSummaryMonitoring();
+
+        } else if (type.equals("equalizeMasters")) {
+            equalizeMasters(event);
+
+        } else if (type.equals("topoStart")) {
+            sendAllInitialData();
+        } else if (type.equals("topoStop")) {
+            cancelAllRequests();
+        }
+    }
+
+    // Sends the specified data to the client.
+    protected synchronized void sendMessage(ObjectNode data) {
+        UiConnection connection = connection();
+        if (connection != null) {
+            connection.sendMessage(data);
+        }
+    }
+
+    private void sendAllInitialData() {
+        addListeners();
+        sendAllInstances(null);
+        sendAllDevices();
+        sendAllLinks();
+        sendAllHosts();
+
+    }
+
+    private void cancelAllRequests() {
+        stopSummaryMonitoring();
+        stopTrafficMonitoring();
+        removeListeners();
+    }
+
+    // Sends all controller nodes to the client as node-added messages.
+    private void sendAllInstances(String messageType) {
+        List<ControllerNode> nodes = new ArrayList<>(clusterService.getNodes());
+        Collections.sort(nodes, NODE_COMPARATOR);
+        for (ControllerNode node : nodes) {
+            sendMessage(instanceMessage(new ClusterEvent(INSTANCE_ADDED, node),
+                                        messageType));
+        }
+    }
+
+    // Sends all devices to the client as device-added messages.
+    private void sendAllDevices() {
+        // Send optical first, others later for layered rendering
+        for (Device device : deviceService.getDevices()) {
+            if (device.type() == Device.Type.ROADM) {
+                sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device)));
+            }
+        }
+        for (Device device : deviceService.getDevices()) {
+            if (device.type() != Device.Type.ROADM) {
+                sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device)));
+            }
+        }
+    }
+
+    // Sends all links to the client as link-added messages.
+    private void sendAllLinks() {
+        // Send optical first, others later for layered rendering
+        for (Link link : linkService.getLinks()) {
+            if (link.type() == Link.Type.OPTICAL) {
+                sendMessage(linkMessage(new LinkEvent(LINK_ADDED, link)));
+            }
+        }
+        for (Link link : linkService.getLinks()) {
+            if (link.type() != Link.Type.OPTICAL) {
+                sendMessage(linkMessage(new LinkEvent(LINK_ADDED, link)));
+            }
+        }
+    }
+
+    // Sends all hosts to the client as host-added messages.
+    private void sendAllHosts() {
+        for (Host host : hostService.getHosts()) {
+            sendMessage(hostMessage(new HostEvent(HOST_ADDED, host)));
+        }
+    }
+
+    // Sends back device or host details.
+    private void requestDetails(ObjectNode event) {
+        ObjectNode payload = payload(event);
+        String type = string(payload, "class", "unknown");
+        long sid = number(event, "sid");
+
+        if (type.equals("device")) {
+            sendMessage(deviceDetails(deviceId(string(payload, "id")), sid));
+        } else if (type.equals("host")) {
+            sendMessage(hostDetails(hostId(string(payload, "id")), sid));
+        }
+    }
+
+
+    // Creates host-to-host intent.
+    private void createHostIntent(ObjectNode event) {
+        ObjectNode payload = payload(event);
+        long id = number(event, "sid");
+        // TODO: add protection against device ids and non-existent hosts.
+        HostId one = hostId(string(payload, "one"));
+        HostId two = hostId(string(payload, "two"));
+
+        HostToHostIntent intent =
+                new HostToHostIntent(appId, one, two,
+                                     DefaultTrafficSelector.builder().build(),
+                                     DefaultTrafficTreatment.builder().build());
+
+        intentService.submit(intent);
+        startMonitoringIntent(event, intent);
+    }
+
+    // Creates multi-source-to-single-dest intent.
+    private void createMultiSourceIntent(ObjectNode event) {
+        ObjectNode payload = payload(event);
+        long id = number(event, "sid");
+        // TODO: add protection against device ids and non-existent hosts.
+        Set<HostId> src = getHostIds((ArrayNode) payload.path("src"));
+        HostId dst = hostId(string(payload, "dst"));
+        Host dstHost = hostService.getHost(dst);
+
+        Set<ConnectPoint> ingressPoints = getHostLocations(src);
+
+        // FIXME: clearly, this is not enough
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthDst(dstHost.mac()).build();
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
+
+        MultiPointToSinglePointIntent intent =
+                new MultiPointToSinglePointIntent(appId, selector, treatment,
+                                                  ingressPoints, dstHost.location());
+
+        intentService.submit(intent);
+        startMonitoringIntent(event, intent);
+    }
+
+
+    private synchronized void startMonitoringIntent(ObjectNode event, Intent intent) {
+        selectedHosts = new HashSet<>();
+        selectedDevices = new HashSet<>();
+        selectedIntents = new ArrayList<>();
+        selectedIntents.add(intent);
+        currentIntentIndex = -1;
+        requestAnotherRelatedIntent(event, +1);
+        requestSelectedIntentTraffic(event);
+    }
+
+
+    private Set<ConnectPoint> getHostLocations(Set<HostId> hostIds) {
+        Set<ConnectPoint> points = new HashSet<>();
+        for (HostId hostId : hostIds) {
+            points.add(getHostLocation(hostId));
+        }
+        return points;
+    }
+
+    private HostLocation getHostLocation(HostId hostId) {
+        return hostService.getHost(hostId).location();
+    }
+
+    // Produces a list of host ids from the specified JSON array.
+    private Set<HostId> getHostIds(ArrayNode ids) {
+        Set<HostId> hostIds = new HashSet<>();
+        for (JsonNode id : ids) {
+            hostIds.add(hostId(id.asText()));
+        }
+        return hostIds;
+    }
+
+
+    private synchronized long startTrafficMonitoring(ObjectNode event) {
+        stopTrafficMonitoring();
+        trafficEvent = event;
+        trafficTask = new TrafficMonitor();
+        timer.schedule(trafficTask, TRAFFIC_FREQUENCY, TRAFFIC_FREQUENCY);
+        return number(event, "sid");
+    }
+
+    private synchronized void stopTrafficMonitoring() {
+        if (trafficTask != null) {
+            trafficTask.cancel();
+            trafficTask = null;
+            trafficEvent = null;
+        }
+    }
+
+    // Subscribes for host traffic messages.
+    private synchronized void requestAllTraffic(ObjectNode event) {
+        long sid = startTrafficMonitoring(event);
+        sendMessage(trafficSummaryMessage(sid));
+    }
+
+    private void requestDeviceLinkFlows(ObjectNode event) {
+        ObjectNode payload = payload(event);
+        long sid = startTrafficMonitoring(event);
+
+        // Get the set of selected hosts and their intents.
+        ArrayNode ids = (ArrayNode) payload.path("ids");
+        Set<Host> hosts = new HashSet<>();
+        Set<Device> devices = getDevices(ids);
+
+        // If there is a hover node, include it in the hosts and find intents.
+        String hover = string(payload, "hover");
+        if (!isNullOrEmpty(hover)) {
+            addHover(hosts, devices, hover);
+        }
+        sendMessage(flowSummaryMessage(sid, devices));
+    }
+
+
+    // Requests related intents message.
+    private synchronized void requestRelatedIntents(ObjectNode event) {
+        ObjectNode payload = payload(event);
+        if (!payload.has("ids")) {
+            return;
+        }
+
+        long sid = number(event, "sid");
+
+        // Cancel any other traffic monitoring mode.
+        stopTrafficMonitoring();
+
+        // Get the set of selected hosts and their intents.
+        ArrayNode ids = (ArrayNode) payload.path("ids");
+        selectedHosts = getHosts(ids);
+        selectedDevices = getDevices(ids);
+        selectedIntents = intentFilter.findPathIntents(selectedHosts, selectedDevices,
+                                                       intentService.getIntents());
+        currentIntentIndex = -1;
+
+        if (haveSelectedIntents()) {
+            // Send a message to highlight all links of all monitored intents.
+            sendMessage(trafficMessage(sid, new TrafficClass("primary", selectedIntents)));
+        }
+
+        // FIXME: Re-introduce one the client click vs hover gesture stuff is sorted out.
+//        String hover = string(payload, "hover");
+//        if (!isNullOrEmpty(hover)) {
+//            // If there is a hover node, include it in the selection and find intents.
+//            processHoverExtendedSelection(sid, hover);
+//        }
+    }
+
+    private boolean haveSelectedIntents() {
+        return selectedIntents != null && !selectedIntents.isEmpty();
+    }
+
+    // Processes the selection extended with hovered item to segregate items
+    // into primary (those including the hover) vs secondary highlights.
+    private void processHoverExtendedSelection(long sid, String hover) {
+        Set<Host> hoverSelHosts = new HashSet<>(selectedHosts);
+        Set<Device> hoverSelDevices = new HashSet<>(selectedDevices);
+        addHover(hoverSelHosts, hoverSelDevices, hover);
+
+        List<Intent> primary = selectedIntents == null ? new ArrayList<>() :
+                intentFilter.findPathIntents(hoverSelHosts, hoverSelDevices,
+                                             selectedIntents);
+        Set<Intent> secondary = new HashSet<>(selectedIntents);
+        secondary.removeAll(primary);
+
+        // Send a message to highlight all links of all monitored intents.
+        sendMessage(trafficMessage(sid, new TrafficClass("primary", primary),
+                                   new TrafficClass("secondary", secondary)));
+    }
+
+    // Requests next or previous related intent.
+    private void requestAnotherRelatedIntent(ObjectNode event, int offset) {
+        if (haveSelectedIntents()) {
+            currentIntentIndex = currentIntentIndex + offset;
+            if (currentIntentIndex < 0) {
+                currentIntentIndex = selectedIntents.size() - 1;
+            } else if (currentIntentIndex >= selectedIntents.size()) {
+                currentIntentIndex = 0;
+            }
+            sendSelectedIntent(event);
+        }
+    }
+
+    // Sends traffic information on the related intents with the currently
+    // selected intent highlighted.
+    private void sendSelectedIntent(ObjectNode event) {
+        Intent selectedIntent = selectedIntents.get(currentIntentIndex);
+        log.info("Requested next intent {}", selectedIntent.id());
+
+        Set<Intent> primary = new HashSet<>();
+        primary.add(selectedIntent);
+
+        Set<Intent> secondary = new HashSet<>(selectedIntents);
+        secondary.remove(selectedIntent);
+
+        // Send a message to highlight all links of the selected intent.
+        sendMessage(trafficMessage(number(event, "sid"),
+                                   new TrafficClass("primary", primary),
+                                   new TrafficClass("secondary", secondary)));
+    }
+
+    // Requests monitoring of traffic for the selected intent.
+    private void requestSelectedIntentTraffic(ObjectNode event) {
+        if (haveSelectedIntents()) {
+            if (currentIntentIndex < 0) {
+                currentIntentIndex = 0;
+            }
+            Intent selectedIntent = selectedIntents.get(currentIntentIndex);
+            log.info("Requested traffic for selected {}", selectedIntent.id());
+
+            Set<Intent> primary = new HashSet<>();
+            primary.add(selectedIntent);
+
+            // Send a message to highlight all links of the selected intent.
+            sendMessage(trafficMessage(number(event, "sid"),
+                                       new TrafficClass("primary", primary, true)));
+        }
+    }
+
+    // Cancels sending traffic messages.
+    private void cancelTraffic(ObjectNode event) {
+        selectedIntents = null;
+        sendMessage(trafficMessage(number(event, "sid")));
+        stopTrafficMonitoring();
+    }
+
+
+    private synchronized long startSummaryMonitoring(ObjectNode event) {
+        stopSummaryMonitoring();
+        summaryEvent = event;
+        summaryTask = new SummaryMonitor();
+        timer.schedule(summaryTask, SUMMARY_FREQUENCY, SUMMARY_FREQUENCY);
+        return number(event, "sid");
+    }
+
+    private synchronized void stopSummaryMonitoring() {
+        if (summaryEvent != null) {
+            summaryTask.cancel();
+            summaryTask = null;
+            summaryEvent = null;
+        }
+    }
+
+    // Subscribes for summary messages.
+    private synchronized void requestSummary(ObjectNode event) {
+        sendMessage(summmaryMessage(number(event, "sid")));
+    }
+
+
+    // Forces mastership role rebalancing.
+    private void equalizeMasters(ObjectNode event) {
+        directory.get(MastershipAdminService.class).balanceRoles();
+    }
+
+
+    // Adds all internal listeners.
+    private void addListeners() {
+        clusterService.addListener(clusterListener);
+        mastershipService.addListener(mastershipListener);
+        deviceService.addListener(deviceListener);
+        linkService.addListener(linkListener);
+        hostService.addListener(hostListener);
+        intentService.addListener(intentListener);
+        flowService.addListener(flowListener);
+    }
+
+    // Removes all internal listeners.
+    private synchronized void removeListeners() {
+        if (!listenersRemoved) {
+            listenersRemoved = true;
+            clusterService.removeListener(clusterListener);
+            mastershipService.removeListener(mastershipListener);
+            deviceService.removeListener(deviceListener);
+            linkService.removeListener(linkListener);
+            hostService.removeListener(hostListener);
+            intentService.removeListener(intentListener);
+            flowService.removeListener(flowListener);
+        }
+    }
+
+    // Cluster event listener.
+    private class InternalClusterListener implements ClusterEventListener {
+        @Override
+        public void event(ClusterEvent event) {
+            sendMessage(instanceMessage(event, null));
+        }
+    }
+
+    // Mastership change listener
+    private class InternalMastershipListener implements MastershipListener {
+        @Override
+        public void event(MastershipEvent event) {
+            sendAllInstances("updateInstance");
+            Device device = deviceService.getDevice(event.subject());
+            sendMessage(deviceMessage(new DeviceEvent(DEVICE_UPDATED, device)));
+        }
+    }
+
+    // Device event listener.
+    private class InternalDeviceListener implements DeviceListener {
+        @Override
+        public void event(DeviceEvent event) {
+            sendMessage(deviceMessage(event));
+            eventAccummulator.add(event);
+        }
+    }
+
+    // Link event listener.
+    private class InternalLinkListener implements LinkListener {
+        @Override
+        public void event(LinkEvent event) {
+            sendMessage(linkMessage(event));
+            eventAccummulator.add(event);
+        }
+    }
+
+    // Host event listener.
+    private class InternalHostListener implements HostListener {
+        @Override
+        public void event(HostEvent event) {
+            sendMessage(hostMessage(event));
+            eventAccummulator.add(event);
+        }
+    }
+
+    // Intent event listener.
+    private class InternalIntentListener implements IntentListener {
+        @Override
+        public void event(IntentEvent event) {
+            if (trafficEvent != null) {
+                requestSelectedIntentTraffic(trafficEvent);
+            }
+            eventAccummulator.add(event);
+        }
+    }
+
+    // Intent event listener.
+    private class InternalFlowListener implements FlowRuleListener {
+        @Override
+        public void event(FlowRuleEvent event) {
+            eventAccummulator.add(event);
+        }
+    }
+
+    // Periodic update of the traffic information
+    private class TrafficMonitor extends TimerTask {
+        @Override
+        public void run() {
+            try {
+                if (trafficEvent != null) {
+                    String type = string(trafficEvent, "event", "unknown");
+                    if (type.equals("requestAllTraffic")) {
+                        requestAllTraffic(trafficEvent);
+                    } else if (type.equals("requestDeviceLinkFlows")) {
+                        requestDeviceLinkFlows(trafficEvent);
+                    } else if (type.equals("requestSelectedIntentTraffic")) {
+                        requestSelectedIntentTraffic(trafficEvent);
+                    }
+                }
+            } catch (Exception e) {
+                log.warn("Unable to handle traffic request due to {}", e.getMessage());
+                log.warn("Boom!", e);
+            }
+        }
+    }
+
+    // Periodic update of the summary information
+    private class SummaryMonitor extends TimerTask {
+        @Override
+        public void run() {
+            try {
+                if (summaryEvent != null) {
+                    requestSummary(summaryEvent);
+                }
+            } catch (Exception e) {
+                log.warn("Unable to handle summary request due to {}", e.getMessage());
+                log.warn("Boom!", e);
+            }
+        }
+    }
+
+    // Accumulates events to drive methodic update of the summary pane.
+    private class InternalEventAccummulator extends AbstractAccumulator<Event> {
+        protected InternalEventAccummulator() {
+            super(new Timer("topo-summary"), MAX_EVENTS, MAX_BATCH_MS, MAX_IDLE_MS);
+        }
+
+        @Override
+        public void processItems(List<Event> items) {
+            try {
+                if (summaryEvent != null) {
+                    sendMessage(summmaryMessage(0));
+                }
+            } catch (Exception e) {
+                log.warn("Unable to handle summary request due to {}", e.getMessage());
+                log.debug("Boom!", e);
+            }
+        }
+    }
+}
+
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
new file mode 100644
index 0000000..9e8fcc7
--- /dev/null
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
@@ -0,0 +1,892 @@
+/*
+ * Copyright 2015 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;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.packet.IpAddress;
+import org.onosproject.cluster.ClusterEvent;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.core.CoreService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.Annotated;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultEdgeLink;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.EdgeLink;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.Link;
+import org.onosproject.net.LinkKey;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.LinkCollectionIntent;
+import org.onosproject.net.intent.OpticalConnectivityIntent;
+import org.onosproject.net.intent.OpticalPathIntent;
+import org.onosproject.net.intent.PathIntent;
+import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.statistic.Load;
+import org.onosproject.net.statistic.StatisticService;
+import org.onosproject.net.topology.Topology;
+import org.onosproject.net.topology.TopologyService;
+import org.onosproject.ui.UiConnection;
+import org.onosproject.ui.UiMessageHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+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.ConcurrentHashMap;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_ADDED;
+import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_REMOVED;
+import static org.onosproject.cluster.ControllerNode.State.ACTIVE;
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.HostId.hostId;
+import static org.onosproject.net.LinkKey.linkKey;
+import static org.onosproject.net.PortNumber.P0;
+import static org.onosproject.net.PortNumber.portNumber;
+import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED;
+import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_REMOVED;
+import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
+import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED;
+import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED;
+import static org.onosproject.net.link.LinkEvent.Type.LINK_REMOVED;
+
+/**
+ * Facility for creating messages bound for the topology viewer.
+ */
+public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler {
+
+    protected static final Logger log = LoggerFactory.getLogger(TopologyViewMessageHandlerBase.class);
+
+    private static final ProviderId PID = new ProviderId("core", "org.onosproject.core", true);
+    private static final String COMPACT = "%s/%s-%s/%s";
+
+    private static final double KB = 1024;
+    private static final double MB = 1024 * KB;
+    private static final double GB = 1024 * MB;
+
+    private static final String GB_UNIT = "GB";
+    private static final String MB_UNIT = "MB";
+    private static final String KB_UNIT = "KB";
+    private static final String B_UNIT = "B";
+
+    protected ServiceDirectory directory;
+    protected ClusterService clusterService;
+    protected DeviceService deviceService;
+    protected LinkService linkService;
+    protected HostService hostService;
+    protected MastershipService mastershipService;
+    protected IntentService intentService;
+    protected FlowRuleService flowService;
+    protected StatisticService statService;
+    protected TopologyService topologyService;
+
+    protected final ObjectMapper mapper = new ObjectMapper();
+    private String version;
+
+    // TODO: extract into an external & durable state; good enough for now and demo
+    private static Map<String, ObjectNode> metaUi = new ConcurrentHashMap<>();
+
+    /**
+     * Creates a new message handler for the specified set of message types.
+     *
+     * @param messageTypes set of message types
+     */
+    protected TopologyViewMessageHandlerBase(Set<String> messageTypes) {
+        super(messageTypes);
+    }
+
+    /**
+     * Returns read-only view of the meta-ui information.
+     *
+     * @return map of id to meta-ui mementos
+     */
+    static Map<String, ObjectNode> getMetaUi() {
+        return Collections.unmodifiableMap(metaUi);
+    }
+
+    @Override
+    public void init(UiConnection connection, ServiceDirectory directory) {
+        super.init(connection, directory);
+        this.directory = checkNotNull(directory, "Directory cannot be null");
+        clusterService = directory.get(ClusterService.class);
+        deviceService = directory.get(DeviceService.class);
+        linkService = directory.get(LinkService.class);
+        hostService = directory.get(HostService.class);
+        mastershipService = directory.get(MastershipService.class);
+        intentService = directory.get(IntentService.class);
+        flowService = directory.get(FlowRuleService.class);
+        statService = directory.get(StatisticService.class);
+        topologyService = directory.get(TopologyService.class);
+
+        String ver = directory.get(CoreService.class).version().toString();
+        version = ver.replace(".SNAPSHOT", "*").replaceFirst("~.*$", "");
+    }
+
+    // Retrieves the payload from the specified event.
+    protected ObjectNode payload(ObjectNode event) {
+        return (ObjectNode) event.path("payload");
+    }
+
+    // Returns the specified node property as a number
+    protected long number(ObjectNode node, String name) {
+        return node.path(name).asLong();
+    }
+
+    // Returns the specified node property as a string.
+    protected String string(ObjectNode node, String name) {
+        return node.path(name).asText();
+    }
+
+    // Returns the specified node property as a string.
+    protected String string(ObjectNode node, String name, String defaultValue) {
+        return node.path(name).asText(defaultValue);
+    }
+
+    // Returns the specified set of IP addresses as a string.
+    private String ip(Set<IpAddress> ipAddresses) {
+        Iterator<IpAddress> it = ipAddresses.iterator();
+        return it.hasNext() ? it.next().toString() : "unknown";
+    }
+
+    // Produces JSON structure from annotations.
+    private JsonNode props(Annotations annotations) {
+        ObjectNode props = mapper.createObjectNode();
+        if (annotations != null) {
+            for (String key : annotations.keys()) {
+                props.put(key, annotations.value(key));
+            }
+        }
+        return props;
+    }
+
+    // Produces an informational log message event bound to the client.
+    protected ObjectNode info(long id, String message) {
+        return message("info", id, message);
+    }
+
+    // Produces a warning log message event bound to the client.
+    protected ObjectNode warning(long id, String message) {
+        return message("warning", id, message);
+    }
+
+    // Produces an error log message event bound to the client.
+    protected ObjectNode error(long id, String message) {
+        return message("error", id, message);
+    }
+
+    // Produces a log message event bound to the client.
+    private ObjectNode message(String severity, long id, String message) {
+        return envelope("message", id,
+                        mapper.createObjectNode()
+                                .put("severity", severity)
+                                .put("message", message));
+    }
+
+    // Puts the payload into an envelope and returns it.
+    protected ObjectNode envelope(String type, long sid, ObjectNode payload) {
+        ObjectNode event = mapper.createObjectNode();
+        event.put("event", type);
+        if (sid > 0) {
+            event.put("sid", sid);
+        }
+        event.set("payload", payload);
+        return event;
+    }
+
+    // Produces a set of all hosts listed in the specified JSON array.
+    protected Set<Host> getHosts(ArrayNode array) {
+        Set<Host> hosts = new HashSet<>();
+        if (array != null) {
+            for (JsonNode node : array) {
+                try {
+                    addHost(hosts, hostId(node.asText()));
+                } catch (IllegalArgumentException e) {
+                    log.debug("Skipping ID {}", node.asText());
+                }
+            }
+        }
+        return hosts;
+    }
+
+    // Adds the specified host to the set of hosts.
+    private void addHost(Set<Host> hosts, HostId hostId) {
+        Host host = hostService.getHost(hostId);
+        if (host != null) {
+            hosts.add(host);
+        }
+    }
+
+
+    // Produces a set of all devices listed in the specified JSON array.
+    protected Set<Device> getDevices(ArrayNode array) {
+        Set<Device> devices = new HashSet<>();
+        if (array != null) {
+            for (JsonNode node : array) {
+                try {
+                    addDevice(devices, deviceId(node.asText()));
+                } catch (IllegalArgumentException e) {
+                    log.debug("Skipping ID {}", node.asText());
+                }
+            }
+        }
+        return devices;
+    }
+
+    private void addDevice(Set<Device> devices, DeviceId deviceId) {
+        Device device = deviceService.getDevice(deviceId);
+        if (device != null) {
+            devices.add(device);
+        }
+    }
+
+    protected void addHover(Set<Host> hosts, Set<Device> devices, String hover) {
+        try {
+            addHost(hosts, hostId(hover));
+        } catch (IllegalArgumentException e) {
+            try {
+                addDevice(devices, deviceId(hover));
+            } catch (IllegalArgumentException ne) {
+                log.debug("Skipping ID {}", hover);
+            }
+        }
+    }
+
+    // Produces a cluster instance message to the client.
+    protected ObjectNode instanceMessage(ClusterEvent event, String messageType) {
+        ControllerNode node = event.subject();
+        int switchCount = mastershipService.getDevicesOf(node.id()).size();
+        ObjectNode payload = mapper.createObjectNode()
+                .put("id", node.id().toString())
+                .put("ip", node.ip().toString())
+                .put("online", clusterService.getState(node.id()) == ACTIVE)
+                .put("uiAttached", event.subject().equals(clusterService.getLocalNode()))
+                .put("switches", switchCount);
+
+        ArrayNode labels = mapper.createArrayNode();
+        labels.add(node.id().toString());
+        labels.add(node.ip().toString());
+
+        // Add labels, props and stuff the payload into envelope.
+        payload.set("labels", labels);
+        addMetaUi(node.id().toString(), payload);
+
+        String type = messageType != null ? messageType :
+                ((event.type() == INSTANCE_ADDED) ? "addInstance" :
+                        ((event.type() == INSTANCE_REMOVED ? "removeInstance" :
+                                "addInstance")));
+        return envelope(type, 0, payload);
+    }
+
+    // Produces a device event message to the client.
+    protected ObjectNode deviceMessage(DeviceEvent event) {
+        Device device = event.subject();
+        ObjectNode payload = mapper.createObjectNode()
+                .put("id", device.id().toString())
+                .put("type", device.type().toString().toLowerCase())
+                .put("online", deviceService.isAvailable(device.id()))
+                .put("master", master(device.id()));
+
+        // Generate labels: id, chassis id, no-label, optional-name
+        String name = device.annotations().value(AnnotationKeys.NAME);
+        ArrayNode labels = mapper.createArrayNode();
+        labels.add("");
+        labels.add(isNullOrEmpty(name) ? device.id().toString() : name);
+        labels.add(device.id().toString());
+
+        // Add labels, props and stuff the payload into envelope.
+        payload.set("labels", labels);
+        payload.set("props", props(device.annotations()));
+        addGeoLocation(device, payload);
+        addMetaUi(device.id().toString(), payload);
+
+        String type = (event.type() == DEVICE_ADDED) ? "addDevice" :
+                ((event.type() == DEVICE_REMOVED) ? "removeDevice" : "updateDevice");
+        return envelope(type, 0, payload);
+    }
+
+    // Produces a link event message to the client.
+    protected ObjectNode linkMessage(LinkEvent event) {
+        Link link = event.subject();
+        ObjectNode payload = mapper.createObjectNode()
+                .put("id", compactLinkString(link))
+                .put("type", link.type().toString().toLowerCase())
+                .put("online", link.state() == Link.State.ACTIVE)
+                .put("linkWidth", 1.2)
+                .put("src", link.src().deviceId().toString())
+                .put("srcPort", link.src().port().toString())
+                .put("dst", link.dst().deviceId().toString())
+                .put("dstPort", link.dst().port().toString());
+        String type = (event.type() == LINK_ADDED) ? "addLink" :
+                ((event.type() == LINK_REMOVED) ? "removeLink" : "updateLink");
+        return envelope(type, 0, payload);
+    }
+
+    // Produces a host event message to the client.
+    protected ObjectNode hostMessage(HostEvent event) {
+        Host host = event.subject();
+        String hostType = host.annotations().value(AnnotationKeys.TYPE);
+        ObjectNode payload = mapper.createObjectNode()
+                .put("id", host.id().toString())
+                .put("type", isNullOrEmpty(hostType) ? "endstation" : hostType)
+                .put("ingress", compactLinkString(edgeLink(host, true)))
+                .put("egress", compactLinkString(edgeLink(host, false)));
+        payload.set("cp", hostConnect(mapper, host.location()));
+        payload.set("labels", labels(mapper, ip(host.ipAddresses()),
+                                     host.mac().toString()));
+        payload.set("props", props(host.annotations()));
+        addGeoLocation(host, payload);
+        addMetaUi(host.id().toString(), payload);
+
+        String type = (event.type() == HOST_ADDED) ? "addHost" :
+                ((event.type() == HOST_REMOVED) ? "removeHost" : "updateHost");
+        return envelope(type, 0, payload);
+    }
+
+    // Encodes the specified host location into a JSON object.
+    private ObjectNode hostConnect(ObjectMapper mapper, HostLocation location) {
+        return mapper.createObjectNode()
+                .put("device", location.deviceId().toString())
+                .put("port", location.port().toLong());
+    }
+
+    // Encodes the specified list of labels a JSON array.
+    private ArrayNode labels(ObjectMapper mapper, String... labels) {
+        ArrayNode json = mapper.createArrayNode();
+        for (String label : labels) {
+            json.add(label);
+        }
+        return json;
+    }
+
+    // Returns the name of the master node for the specified device id.
+    private String master(DeviceId deviceId) {
+        NodeId master = mastershipService.getMasterFor(deviceId);
+        return master != null ? master.toString() : "";
+    }
+
+    // Generates an edge link from the specified host location.
+    private EdgeLink edgeLink(Host host, boolean ingress) {
+        return new DefaultEdgeLink(PID, new ConnectPoint(host.id(), portNumber(0)),
+                                   host.location(), ingress);
+    }
+
+    // Adds meta UI information for the specified object.
+    private void addMetaUi(String id, ObjectNode payload) {
+        ObjectNode meta = metaUi.get(id);
+        if (meta != null) {
+            payload.set("metaUi", meta);
+        }
+    }
+
+    // Adds a geo location JSON to the specified payload object.
+    private void addGeoLocation(Annotated annotated, ObjectNode payload) {
+        Annotations annotations = annotated.annotations();
+        if (annotations == null) {
+            return;
+        }
+
+        String slat = annotations.value(AnnotationKeys.LATITUDE);
+        String slng = annotations.value(AnnotationKeys.LONGITUDE);
+        try {
+            if (slat != null && slng != null && !slat.isEmpty() && !slng.isEmpty()) {
+                double lat = Double.parseDouble(slat);
+                double lng = Double.parseDouble(slng);
+                ObjectNode loc = mapper.createObjectNode()
+                        .put("type", "latlng").put("lat", lat).put("lng", lng);
+                payload.set("location", loc);
+            }
+        } catch (NumberFormatException e) {
+            log.warn("Invalid geo data latitude={}; longiture={}", slat, slng);
+        }
+    }
+
+    // Updates meta UI information for the specified object.
+    protected void updateMetaUi(ObjectNode event) {
+        ObjectNode payload = payload(event);
+        metaUi.put(string(payload, "id"), (ObjectNode) payload.path("memento"));
+    }
+
+    // Returns summary response.
+    protected ObjectNode summmaryMessage(long sid) {
+        Topology topology = topologyService.currentTopology();
+        return envelope("showSummary", sid,
+                        json("ONOS Summary", "node",
+                             new Prop("Devices", format(topology.deviceCount())),
+                             new Prop("Links", format(topology.linkCount())),
+                             new Prop("Hosts", format(hostService.getHostCount())),
+                             new Prop("Topology SCCs", format(topology.clusterCount())),
+                             new Separator(),
+                             new Prop("Intents", format(intentService.getIntentCount())),
+                             new Prop("Flows", format(flowService.getFlowRuleCount())),
+                             new Prop("Version", version)));
+    }
+
+    // Returns device details response.
+    protected ObjectNode deviceDetails(DeviceId deviceId, long sid) {
+        Device device = deviceService.getDevice(deviceId);
+        Annotations annot = device.annotations();
+        String name = annot.value(AnnotationKeys.NAME);
+        int portCount = deviceService.getPorts(deviceId).size();
+        int flowCount = getFlowCount(deviceId);
+        return envelope("showDetails", sid,
+                        json(isNullOrEmpty(name) ? deviceId.toString() : name,
+                             device.type().toString().toLowerCase(),
+                             new Prop("URI", deviceId.toString()),
+                             new Prop("Vendor", device.manufacturer()),
+                             new Prop("H/W Version", device.hwVersion()),
+                             new Prop("S/W Version", device.swVersion()),
+                             new Prop("Serial Number", device.serialNumber()),
+                             new Prop("Protocol", annot.value(AnnotationKeys.PROTOCOL)),
+                             new Separator(),
+                             new Prop("Master", master(deviceId)),
+                             new Prop("Latitude", annot.value(AnnotationKeys.LATITUDE)),
+                             new Prop("Longitude", annot.value(AnnotationKeys.LONGITUDE)),
+                             new Separator(),
+                             new Prop("Ports", Integer.toString(portCount)),
+                             new Prop("Flows", Integer.toString(flowCount))));
+    }
+
+    protected int getFlowCount(DeviceId deviceId) {
+        int count = 0;
+        Iterator<FlowEntry> it = flowService.getFlowEntries(deviceId).iterator();
+        while (it.hasNext()) {
+            count++;
+            it.next();
+        }
+        return count;
+    }
+
+    // Counts all entries that egress on the given device links.
+    protected Map<Link, Integer> getFlowCounts(DeviceId deviceId) {
+        List<FlowEntry> entries = new ArrayList<>();
+        Set<Link> links = new HashSet<>(linkService.getDeviceEgressLinks(deviceId));
+        Set<Host> hosts = hostService.getConnectedHosts(deviceId);
+        Iterator<FlowEntry> it = flowService.getFlowEntries(deviceId).iterator();
+        while (it.hasNext()) {
+            entries.add(it.next());
+        }
+
+        // Add all edge links to the set
+        if (hosts != null) {
+            for (Host host : hosts) {
+                links.add(new DefaultEdgeLink(host.providerId(),
+                                              new ConnectPoint(host.id(), P0),
+                                              host.location(), false));
+            }
+        }
+
+        Map<Link, Integer> counts = new HashMap<>();
+        for (Link link : links) {
+            counts.put(link, getEgressFlows(link, entries));
+        }
+        return counts;
+    }
+
+    // Counts all entries that egress on the link source port.
+    private Integer getEgressFlows(Link link, List<FlowEntry> entries) {
+        int count = 0;
+        PortNumber out = link.src().port();
+        for (FlowEntry entry : entries) {
+            TrafficTreatment treatment = entry.treatment();
+            for (Instruction instruction : treatment.instructions()) {
+                if (instruction.type() == Instruction.Type.OUTPUT &&
+                        ((OutputInstruction) instruction).port().equals(out)) {
+                    count++;
+                }
+            }
+        }
+        return count;
+    }
+
+
+    // Returns host details response.
+    protected ObjectNode hostDetails(HostId hostId, long sid) {
+        Host host = hostService.getHost(hostId);
+        Annotations annot = host.annotations();
+        String type = annot.value(AnnotationKeys.TYPE);
+        String name = annot.value(AnnotationKeys.NAME);
+        String vlan = host.vlan().toString();
+        return envelope("showDetails", sid,
+                        json(isNullOrEmpty(name) ? hostId.toString() : name,
+                             isNullOrEmpty(type) ? "endstation" : type,
+                             new Prop("MAC", host.mac().toString()),
+                             new Prop("IP", host.ipAddresses().toString().replaceAll("[\\[\\]]", "")),
+                             new Prop("VLAN", vlan.equals("-1") ? "none" : vlan),
+                             new Separator(),
+                             new Prop("Latitude", annot.value(AnnotationKeys.LATITUDE)),
+                             new Prop("Longitude", annot.value(AnnotationKeys.LONGITUDE))));
+    }
+
+
+    // Produces JSON message to trigger traffic overview visualization
+    protected ObjectNode trafficSummaryMessage(long sid) {
+        ObjectNode payload = mapper.createObjectNode();
+        ArrayNode paths = mapper.createArrayNode();
+        payload.set("paths", paths);
+
+        ObjectNode pathNodeN = mapper.createObjectNode();
+        ArrayNode linksNodeN = mapper.createArrayNode();
+        ArrayNode labelsN = mapper.createArrayNode();
+
+        pathNodeN.put("class", "plain").put("traffic", false);
+        pathNodeN.set("links", linksNodeN);
+        pathNodeN.set("labels", labelsN);
+        paths.add(pathNodeN);
+
+        ObjectNode pathNodeT = mapper.createObjectNode();
+        ArrayNode linksNodeT = mapper.createArrayNode();
+        ArrayNode labelsT = mapper.createArrayNode();
+
+        pathNodeT.put("class", "secondary").put("traffic", true);
+        pathNodeT.set("links", linksNodeT);
+        pathNodeT.set("labels", labelsT);
+        paths.add(pathNodeT);
+
+        for (BiLink link : consolidateLinks(linkService.getLinks())) {
+            boolean bi = link.two != null;
+            if (isInfrastructureEgress(link.one) ||
+                    (bi && isInfrastructureEgress(link.two))) {
+                link.addLoad(statService.load(link.one));
+                link.addLoad(bi ? statService.load(link.two) : null);
+                if (link.hasTraffic) {
+                    linksNodeT.add(compactLinkString(link.one));
+                    labelsT.add(formatBytes(link.bytes));
+                } else {
+                    linksNodeN.add(compactLinkString(link.one));
+                    labelsN.add("");
+                }
+            }
+        }
+        return envelope("showTraffic", sid, payload);
+    }
+
+    private Collection<BiLink> consolidateLinks(Iterable<Link> links) {
+        Map<LinkKey, BiLink> biLinks = new HashMap<>();
+        for (Link link : links) {
+            addLink(biLinks, link);
+        }
+        return biLinks.values();
+    }
+
+    // Produces JSON message to trigger flow overview visualization
+    protected ObjectNode flowSummaryMessage(long sid, Set<Device> devices) {
+        ObjectNode payload = mapper.createObjectNode();
+        ArrayNode paths = mapper.createArrayNode();
+        payload.set("paths", paths);
+
+        for (Device device : devices) {
+            Map<Link, Integer> counts = getFlowCounts(device.id());
+            for (Link link : counts.keySet()) {
+                addLinkFlows(link, paths, counts.get(link));
+            }
+        }
+        return envelope("showTraffic", sid, payload);
+    }
+
+    private void addLinkFlows(Link link, ArrayNode paths, Integer count) {
+        ObjectNode pathNode = mapper.createObjectNode();
+        ArrayNode linksNode = mapper.createArrayNode();
+        ArrayNode labels = mapper.createArrayNode();
+        boolean noFlows = count == null || count == 0;
+        pathNode.put("class", noFlows ? "secondary" : "primary");
+        pathNode.put("traffic", false);
+        pathNode.set("links", linksNode.add(compactLinkString(link)));
+        pathNode.set("labels", labels.add(noFlows ? "" : (count.toString() +
+                (count == 1 ? " flow" : " flows"))));
+        paths.add(pathNode);
+    }
+
+
+    // Produces JSON message to trigger traffic visualization
+    protected ObjectNode trafficMessage(long sid, TrafficClass... trafficClasses) {
+        ObjectNode payload = mapper.createObjectNode();
+        ArrayNode paths = mapper.createArrayNode();
+        payload.set("paths", paths);
+
+        // Classify links based on their traffic traffic first...
+        Map<LinkKey, BiLink> biLinks = classifyLinkTraffic(trafficClasses);
+
+        // Then separate the links into their respective classes and send them out.
+        Map<String, ObjectNode> pathNodes = new HashMap<>();
+        for (BiLink biLink : biLinks.values()) {
+            boolean hasTraffic = biLink.hasTraffic;
+            String tc = (biLink.classes + (hasTraffic ? " animated" : "")).trim();
+            ObjectNode pathNode = pathNodes.get(tc);
+            if (pathNode == null) {
+                pathNode = mapper.createObjectNode()
+                        .put("class", tc).put("traffic", hasTraffic);
+                pathNode.set("links", mapper.createArrayNode());
+                pathNode.set("labels", mapper.createArrayNode());
+                pathNodes.put(tc, pathNode);
+                paths.add(pathNode);
+            }
+            ((ArrayNode) pathNode.path("links")).add(compactLinkString(biLink.one));
+            ((ArrayNode) pathNode.path("labels")).add(hasTraffic ? formatBytes(biLink.bytes) : "");
+        }
+
+        return envelope("showTraffic", sid, payload);
+    }
+
+    // Classifies the link traffic according to the specified classes.
+    private Map<LinkKey, BiLink> classifyLinkTraffic(TrafficClass... trafficClasses) {
+        Map<LinkKey, BiLink> biLinks = new HashMap<>();
+        for (TrafficClass trafficClass : trafficClasses) {
+            for (Intent intent : trafficClass.intents) {
+                boolean isOptical = intent instanceof OpticalConnectivityIntent;
+                List<Intent> installables = intentService.getInstallableIntents(intent.key());
+                if (installables != null) {
+                    for (Intent installable : installables) {
+                        String type = isOptical ? trafficClass.type + " optical" : trafficClass.type;
+                        if (installable instanceof PathIntent) {
+                            classifyLinks(type, biLinks, trafficClass.showTraffic,
+                                          ((PathIntent) installable).path().links());
+                        } else if (installable instanceof LinkCollectionIntent) {
+                            classifyLinks(type, biLinks, trafficClass.showTraffic,
+                                          ((LinkCollectionIntent) installable).links());
+                        } else if (installable instanceof OpticalPathIntent) {
+                            classifyLinks(type, biLinks, trafficClass.showTraffic,
+                                    ((OpticalPathIntent) installable).path().links());
+                        }
+                    }
+                }
+            }
+        }
+        return biLinks;
+    }
+
+
+    // Adds the link segments (path or tree) associated with the specified
+    // connectivity intent
+    private void classifyLinks(String type, Map<LinkKey, BiLink> biLinks,
+                               boolean showTraffic, Iterable<Link> links) {
+        if (links != null) {
+            for (Link link : links) {
+                BiLink biLink = addLink(biLinks, link);
+                if (isInfrastructureEgress(link)) {
+                    if (showTraffic) {
+                        biLink.addLoad(statService.load(link));
+                    }
+                    biLink.addClass(type);
+                }
+            }
+        }
+    }
+
+
+    private BiLink addLink(Map<LinkKey, BiLink> biLinks, Link link) {
+        LinkKey key = canonicalLinkKey(link);
+        BiLink biLink = biLinks.get(key);
+        if (biLink != null) {
+            biLink.setOther(link);
+        } else {
+            biLink = new BiLink(key, link);
+            biLinks.put(key, biLink);
+        }
+        return biLink;
+    }
+
+
+    // Adds the link segments (path or tree) associated with the specified
+    // connectivity intent
+    protected void addPathTraffic(ArrayNode paths, String type, String trafficType,
+                                  Iterable<Link> links) {
+        ObjectNode pathNode = mapper.createObjectNode();
+        ArrayNode linksNode = mapper.createArrayNode();
+
+        if (links != null) {
+            ArrayNode labels = mapper.createArrayNode();
+            boolean hasTraffic = false;
+            for (Link link : links) {
+                if (isInfrastructureEgress(link)) {
+                    linksNode.add(compactLinkString(link));
+                    Load load = statService.load(link);
+                    String label = "";
+                    if (load.rate() > 0) {
+                        hasTraffic = true;
+                        label = formatBytes(load.latest());
+                    }
+                    labels.add(label);
+                }
+            }
+            pathNode.put("class", hasTraffic ? type + " " + trafficType : type);
+            pathNode.put("traffic", hasTraffic);
+            pathNode.set("links", linksNode);
+            pathNode.set("labels", labels);
+            paths.add(pathNode);
+        }
+    }
+
+    // Poor-mans formatting to get the labels with byte counts looking nice.
+    private String formatBytes(long bytes) {
+        String unit;
+        double value;
+        if (bytes > GB) {
+            value = bytes / GB;
+            unit = GB_UNIT;
+        } else if (bytes > MB) {
+            value = bytes / MB;
+            unit = MB_UNIT;
+        } else if (bytes > KB) {
+            value = bytes / KB;
+            unit = KB_UNIT;
+        } else {
+            value = bytes;
+            unit = B_UNIT;
+        }
+        DecimalFormat format = new DecimalFormat("#,###.##");
+        return format.format(value) + " " + unit;
+    }
+
+    // Formats the given number into a string.
+    private String format(Number number) {
+        DecimalFormat format = new DecimalFormat("#,###");
+        return format.format(number);
+    }
+
+    private boolean isInfrastructureEgress(Link link) {
+        return link.src().elementId() instanceof DeviceId;
+    }
+
+    // Produces compact string representation of a link.
+    private static String compactLinkString(Link link) {
+        return String.format(COMPACT, link.src().elementId(), link.src().port(),
+                             link.dst().elementId(), link.dst().port());
+    }
+
+    // Produces JSON property details.
+    private ObjectNode json(String id, String type, Prop... props) {
+        ObjectMapper mapper = new ObjectMapper();
+        ObjectNode result = mapper.createObjectNode()
+                .put("id", id).put("type", type);
+        ObjectNode pnode = mapper.createObjectNode();
+        ArrayNode porder = mapper.createArrayNode();
+        for (Prop p : props) {
+            porder.add(p.key);
+            pnode.put(p.key, p.value);
+        }
+        result.set("propOrder", porder);
+        result.set("props", pnode);
+        return result;
+    }
+
+    // Produces canonical link key, i.e. one that will match link and its inverse.
+    private LinkKey canonicalLinkKey(Link link) {
+        String sn = link.src().elementId().toString();
+        String dn = link.dst().elementId().toString();
+        return sn.compareTo(dn) < 0 ?
+                linkKey(link.src(), link.dst()) : linkKey(link.dst(), link.src());
+    }
+
+    // Representation of link and its inverse and any traffic data.
+    private class BiLink {
+        public final LinkKey key;
+        public final Link one;
+        public Link two;
+        public boolean hasTraffic = false;
+        public long bytes = 0;
+        public String classes = "";
+
+        BiLink(LinkKey key, Link link) {
+            this.key = key;
+            this.one = link;
+        }
+
+        void setOther(Link link) {
+            this.two = link;
+        }
+
+        void addLoad(Load load) {
+            if (load != null) {
+                this.hasTraffic = hasTraffic || load.rate() > 0;
+                this.bytes += load.latest();
+            }
+        }
+
+        void addClass(String trafficClass) {
+            classes = classes + " " + trafficClass;
+        }
+    }
+
+    // Auxiliary key/value carrier.
+    private class Prop {
+        public final String key;
+        public final String value;
+
+        protected Prop(String key, String value) {
+            this.key = key;
+            this.value = value;
+        }
+    }
+
+    // Auxiliary properties separator
+    private class Separator extends Prop {
+        protected Separator() {
+            super("-", "");
+        }
+    }
+
+    // Auxiliary carrier of data for requesting traffic message.
+    protected class TrafficClass {
+        public final boolean showTraffic;
+        public final String type;
+        public final Iterable<Intent> intents;
+
+        TrafficClass(String type, Iterable<Intent> intents) {
+            this(type, intents, false);
+        }
+
+        TrafficClass(String type, Iterable<Intent> intents, boolean showTraffic) {
+            this.type = type;
+            this.intents = intents;
+            this.showTraffic = showTraffic;
+        }
+    }
+
+}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessages.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessages.java
index dd891cd..b9b50ca 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessages.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessages.java
@@ -98,6 +98,7 @@
 /**
  * Facility for creating messages bound for the topology viewer.
  */
+@Deprecated
 public abstract class TopologyViewMessages {
 
     protected static final Logger log = LoggerFactory.getLogger(TopologyViewMessages.class);
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewWebSocket.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewWebSocket.java
index e259cb5..24e8b82 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewWebSocket.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewWebSocket.java
@@ -77,6 +77,7 @@
 /**
  * Web socket capable of interacting with the GUI topology view.
  */
+@Deprecated
 public class TopologyViewWebSocket
         extends TopologyViewMessages
         implements WebSocket.OnTextMessage, WebSocket.OnControl {
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/UiExtensionManager.java b/web/gui/src/main/java/org/onosproject/ui/impl/UiExtensionManager.java
index 3b9156d..fa8df2e 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/UiExtensionManager.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/UiExtensionManager.java
@@ -59,7 +59,7 @@
         List<UiView> coreViews = of(new UiView("sample", "Sample"),
                                     new UiView("topo", "Topology View"),
                                     new UiView("device", "Devices"));
-        UiMessageHandlerFactory messageHandlerFactory = null;
+        UiMessageHandlerFactory messageHandlerFactory = () -> ImmutableList.of(new TopologyViewMessageHandler());
         return new UiExtension(coreViews, messageHandlerFactory, "core",
                                UiExtensionManager.class.getClassLoader());
     }
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 9b11b42..99ca2e9 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
@@ -22,6 +22,7 @@
 import org.onosproject.ui.UiConnection;
 import org.onosproject.ui.UiExtensionService;
 import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.UiMessageHandlerFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -117,7 +118,7 @@
         lastActive = System.currentTimeMillis();
         try {
             ObjectNode message = (ObjectNode) mapper.reader().readTree(data);
-            String type = message.path("type").asText("unknown");
+            String type = message.path("event").asText("unknown");
             UiMessageHandler handler = handlers.get(type);
             if (handler != null) {
                 handler.process(message);
@@ -146,10 +147,15 @@
     private void createHandlers() {
         handlers = new HashMap<>();
         UiExtensionService service = directory.get(UiExtensionService.class);
-        service.getExtensions().forEach(ext -> ext.messageHandlerFactory().newHandlers().forEach(handler -> {
-            handler.init(this, directory);
-            handler.messageTypes().forEach(type -> handlers.put(type, handler));
-        }));
+        service.getExtensions().forEach(ext -> {
+            UiMessageHandlerFactory factory = ext.messageHandlerFactory();
+            if (factory != null) {
+                factory.newHandlers().forEach(handler -> {
+                    handler.init(this, directory);
+                    handler.messageTypes().forEach(type -> handlers.put(type, handler));
+                });
+            }
+        });
     }
 
     // Destroys message handlers.
diff --git a/web/gui/src/main/webapp/WEB-INF/web.xml b/web/gui/src/main/webapp/WEB-INF/web.xml
index 511ceac..5371354 100644
--- a/web/gui/src/main/webapp/WEB-INF/web.xml
+++ b/web/gui/src/main/webapp/WEB-INF/web.xml
@@ -151,12 +151,24 @@
 
     <servlet>
         <servlet-name>Web Socket Service</servlet-name>
-        <servlet-class>org.onosproject.ui.impl.GuiWebSocketServlet</servlet-class>
+        <servlet-class>org.onosproject.ui.impl.UiWebSocketServlet</servlet-class>
         <load-on-startup>2</load-on-startup>
     </servlet>
 
     <servlet-mapping>
         <servlet-name>Web Socket Service</servlet-name>
+        <url-pattern>/websock/*</url-pattern>
+    </servlet-mapping>
+
+
+    <servlet>
+        <servlet-name>Legacy Web Socket Service</servlet-name>
+        <servlet-class>org.onosproject.ui.impl.GuiWebSocketServlet</servlet-class>
+        <load-on-startup>2</load-on-startup>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>Legacy Web Socket Service</servlet-name>
         <url-pattern>/ws/*</url-pattern>
     </servlet-mapping>
 
diff --git a/web/gui/src/main/webapp/app/fw/remote/urlfn.js b/web/gui/src/main/webapp/app/fw/remote/urlfn.js
index fe43267..c2addef 100644
--- a/web/gui/src/main/webapp/app/fw/remote/urlfn.js
+++ b/web/gui/src/main/webapp/app/fw/remote/urlfn.js
@@ -22,7 +22,7 @@
 
     var uiContext = '/onos/ui/',
         rsSuffix = uiContext + 'rs/',
-        wsSuffix = uiContext + 'ws/';
+        wsSuffix = uiContext + 'websock/';
 
     angular.module('onosRemote')
         .factory('UrlFnService', ['$location', function ($loc) {
diff --git a/web/gui/src/main/webapp/app/fw/remote/websocket.js b/web/gui/src/main/webapp/app/fw/remote/websocket.js
index abe6025..3229250 100644
--- a/web/gui/src/main/webapp/app/fw/remote/websocket.js
+++ b/web/gui/src/main/webapp/app/fw/remote/websocket.js
@@ -20,62 +20,105 @@
 (function () {
     'use strict';
 
-    var fs;
+    // injected refs
+    var fs, $log;
 
-    function fnOpen(f) {
-        // wrap the onOpen function; we will handle any housekeeping here...
-        if (!fs.isF(f)) {
-            return null;
-        }
+    // internal state
+    var ws, sws, sid = 0,
+        handlers = {};
 
-        return function (openEvent) {
-            // NOTE: nothing worth passing to the caller?
-            f();
-        };
+    function resetSid() {
+        sid = 0;
     }
 
-    function fnMessage(f) {
-        // wrap the onMessage function; we will attempt to decode the
-        // message event payload as JSON and pass that in...
-        if (!fs.isF(f)) {
-            return null;
-        }
+    // Binds the specified message handlers.
+    function bindHandlers(handlerMap) {
+        var m = d3.map(handlerMap),
+            dups = [];
 
-        return function (msgEvent) {
-            var ev;
-            try {
-                ev = JSON.parse(msgEvent.data);
-            } catch (e) {
-                ev = {
-                    error: 'Failed to parse JSON',
-                    e: e
-                };
+        m.forEach(function (key, value) {
+            var fn = fs.isF(value[key]);
+            if (!fn) {
+                $log.warn(key + ' binding not a function on ' + value);
+                return;
             }
-            f(ev);
-        };
+
+            if (handlers[key]) {
+                dups.push(key);
+            } else {
+                handlers[key] = fn;
+            }
+        });
+        if (dups.length) {
+            $log.warn('duplicate bindings ignored:', dups);
+        }
     }
 
-    function fnClose(f) {
-        // wrap the onClose function; we will handle any parameters to the
-        // close event here...
-        if (!fs.isF(f)) {
-            return null;
-        }
+    // Unbinds the specified message handlers.
+    function unbindHandlers(handlerMap) {
+        var m = d3.map(handlerMap);
+        m.forEach(function (key) {
+            delete handlers[key];
+        });
+    }
 
-        return function (closeEvent) {
-            // NOTE: only seen {reason == ""} so far, nevertheless...
-            f(closeEvent.reason);
-        };
+    // Formulates an event message and sends it via the shared web-socket.
+    function sendEvent(evType, payload) {
+        var p = payload || {};
+        if (sws) {
+            $log.debug(' *Tx* >> ', evType, payload);
+            sws.send({
+                event: evType,
+                sid: ++sid,
+                payload: p
+            });
+        } else {
+            $log.warn('sendEvent: no websocket open:', evType, payload);
+        }
+    }
+
+
+    // Handles the specified message using handler bindings.
+    function handleMessage(msgEvent) {
+        var ev;
+        try {
+            ev = JSON.parse(msgEvent.data);
+            $log.debug(' *Rx* >> ', ev.event, ev.payload);
+            dispatchToHandler(ev);
+        } catch (e) {
+            $log.error('message is not valid JSON', msgEvent);
+        }
+    }
+
+    // Dispatches the message to the appropriate handler.
+    function dispatchToHandler(event) {
+        var handler = handlers[event.event];
+        if (handler) {
+            handler(event.payload);
+        } else {
+            $log.warn('unhandled event:', event);
+        }
+    }
+
+    function handleOpen() {
+        $log.info('web socket open');
+        // FIXME: implement calling external hooks
+    }
+
+    function handleClose() {
+        $log.info('web socket closed');
+        // FIXME: implement reconnect logic
     }
 
     angular.module('onosRemote')
     .factory('WebSocketService',
             ['$log', '$location', 'UrlFnService', 'FnService',
 
-        function ($log, $loc, ufs, _fs_) {
+        function (_$log_, $loc, ufs, _fs_) {
             fs = _fs_;
+            $log = _$log_;
 
-            // creates a web socket for the given path, returning a "handle".
+            // Creates a web socket for the given path, returning a "handle".
             // opts contains the event handler callbacks, etc.
             function createWebSocket(path, opts) {
                 var o = opts || {},
@@ -85,8 +128,7 @@
                         meta: { path: fullUrl, ws: null },
                         send: send,
                         close: close
-                    },
-                    ws;
+                    };
 
                 try {
                     ws = new WebSocket(fullUrl);
@@ -97,23 +139,21 @@
                 $log.debug('Attempting to open websocket to: ' + fullUrl);
 
                 if (ws) {
-                    ws.onopen = fnOpen(o.onOpen);
-                    ws.onmessage = fnMessage(o.onMessage);
-                    ws.onclose = fnClose(o.onClose);
+                    ws.onopen = handleOpen;
+                    ws.onmessage = handleMessage;
+                    ws.onclose = handleClose;
                 }
 
-                // messages are expected to be event objects..
+                // Sends a formulated event message via the backing web-socket.
                 function send(ev) {
-                    if (ev) {
-                        if (ws) {
-                            ws.send(JSON.stringify(ev));
-                        } else {
-                            $log.warn('ws.send() no web socket open!',
-                                fullUrl, ev);
-                        }
+                    if (ev && ws) {
+                        ws.send(JSON.stringify(ev));
+                    } else if (!ws) {
+                        $log.warn('ws.send() no web socket open!', fullUrl, ev);
                     }
                 }
 
+                // Closes the backing web-socket.
                 function close() {
                     if (ws) {
                         ws.close();
@@ -122,11 +162,16 @@
                     }
                 }
 
+                sws = api; // Make the shared web-socket accessible
                 return api;
             }
 
             return {
-                createWebSocket: createWebSocket
+                resetSid: resetSid,
+                createWebSocket: createWebSocket,
+                bindHandlers: bindHandlers,
+                unbindHandlers: unbindHandlers,
+                sendEvent: sendEvent
             };
     }]);
 
diff --git a/web/gui/src/main/webapp/app/fw/remote/wsevent.js b/web/gui/src/main/webapp/app/fw/remote/wsevent.js
index bf04b86..02d71b5 100644
--- a/web/gui/src/main/webapp/app/fw/remote/wsevent.js
+++ b/web/gui/src/main/webapp/app/fw/remote/wsevent.js
@@ -15,6 +15,7 @@
  */
 
 /*
+ DEPRECATED: to be deleted
  ONOS GUI -- Remote -- Web Socket Event Service
  */
 (function () {
diff --git a/web/gui/src/main/webapp/app/view/topo/topo.js b/web/gui/src/main/webapp/app/view/topo/topo.js
index 4463936..3dd8d6e 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.js
+++ b/web/gui/src/main/webapp/app/view/topo/topo.js
@@ -263,7 +263,7 @@
             // Cleanup on destroyed scope..
             $scope.$on('$destroy', function () {
                 $log.log('OvTopoCtrl is saying Buh-Bye!');
-                tes.closeSock();
+                tes.stop();
                 tps.destroyPanels();
                 tis.destroyInst();
                 tfs.destroyForce();
@@ -291,7 +291,7 @@
             tfs.initForce(svg, forceG, uplink, dim);
             tis.initInst({ showMastership: tfs.showMastership });
             tps.initPanels({ sendEvent: tes.sendEvent });
-            tes.openSock();
+            tes.start();
 
             $log.log('OvTopoCtrl has been created');
         }]);
diff --git a/web/gui/src/main/webapp/app/view/topo/topoEvent.js b/web/gui/src/main/webapp/app/view/topo/topoEvent.js
index 099ba4e..10b6909 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoEvent.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoEvent.js
@@ -27,15 +27,15 @@
     'use strict';
 
     // injected refs
-    var $log, wss, wes, vs, tps, tis, tfs, tss, tts;
+    var $log, vs, wss, tps, tis, tfs, tss, tts;
 
     // internal state
-    var wsock, evApis;
+    var handlers;
 
     // ==========================
 
-    function bindApis() {
-        evApis = {
+    function createHandlers() {
+        handlers = {
             showSummary: tps,
 
             showDetails: tss,
@@ -58,103 +58,43 @@
         };
     }
 
-    var nilApi = {},
-        dispatcher = {
-            handleEvent: function (ev) {
-                var eid = ev.event,
-                    api = evApis[eid] || nilApi,
-                    eh = api[eid];
-
-                if (eh) {
-                    $log.debug(' << *Rx* ', eid, ev.payload);
-                    eh(ev.payload);
-                } else {
-                    $log.warn('Unknown event (ignored):', ev);
-                }
-            },
-
-            sendEvent: function (evType, payload) {
-                if (wsock) {
-                    $log.debug(' *Tx* >> ', evType, payload);
-                    wes.sendEvent(wsock, evType, payload);
-                } else {
-                    $log.warn('sendEvent: no websocket open:', evType, payload);
-                }
-            }
-        };
-
-    // ===  Web Socket functions ===
-
-    function onWsOpen() {
-        $log.debug('web socket opened...');
-        // start by requesting periodic summary data...
-        dispatcher.sendEvent('requestSummary');
-        vs.hide();
-    }
-
-    function onWsMessage(ev) {
-        dispatcher.handleEvent(ev);
-    }
-
-    function onWsClose(reason) {
-        $log.log('web socket closed; reason=', reason);
-        wsock = null;
-        vs.lostServer('OvTopoCtrl', [
-            'Oops!',
-            'Web-socket connection to server closed...',
-            'Try refreshing the page.'
-        ]);
-    }
-
-    // ==========================
+    var nilApi = {};
 
     angular.module('ovTopo')
     .factory('TopoEventService',
-        ['$log', '$location', 'WebSocketService', 'WsEventService', 'VeilService',
+        ['$log', '$location', 'VeilService', 'WebSocketService',
             'TopoPanelService', 'TopoInstService', 'TopoForceService',
             'TopoSelectService', 'TopoTrafficService',
 
-        function (_$log_, $loc, _wss_, _wes_, _vs_,
-                  _tps_, _tis_, _tfs_, _tss_, _tts_) {
+        function (_$log_, $loc, _vs_, _wss_, _tps_, _tis_, _tfs_, _tss_, _tts_) {
             $log = _$log_;
-            wss = _wss_;
-            wes = _wes_;
             vs = _vs_;
+            wss = _wss_;
             tps = _tps_;
             tis = _tis_;
             tfs = _tfs_;
             tss = _tss_;
             tts = _tts_;
 
-            bindApis();
+            createHandlers();
 
-            // TODO: handle "guiSuccessor" functionality (replace host)
-            // TODO: implement retry on close functionality
-
-            function openSock() {
-                wsock = wss.createWebSocket('topology', {
-                    onOpen: onWsOpen,
-                    onMessage: onWsMessage,
-                    onClose: onWsClose,
-                    wsport: $loc.search().wsport
-                });
-                $log.debug('web socket opened:', wsock);
+            // FIXME: need to handle async socket open to avoid race
+            function start() {
+                wss.bindHandlers(handlers);
+                wss.sendEvent('topoStart');
+                $log.debug('topo comms started');
             }
 
-            function closeSock() {
-                var path;
-                if (wsock) {
-                    path = wsock.meta.path;
-                    wsock.close();
-                    wsock = null;
-                    $log.debug('web socket closed. path:', path);
-                }
+            function stop() {
+                wss.unbindHandlers();
+                wss.sendEvent('topoStop');
+                $log.debug('topo comms stopped');
             }
 
             return {
-                openSock: openSock,
-                closeSock: closeSock,
-                sendEvent: dispatcher.sendEvent
+                start: start,
+                stop: stop,
+                sendEvent: wss.sendEvent
             };
         }]);
 }());
diff --git a/web/gui/src/main/webapp/onos.js b/web/gui/src/main/webapp/onos.js
index 0f049e9..97f3d06 100644
--- a/web/gui/src/main/webapp/onos.js
+++ b/web/gui/src/main/webapp/onos.js
@@ -64,10 +64,10 @@
         .controller('OnosCtrl', [
             '$log', '$route', '$routeParams', '$location',
             'KeyService', 'ThemeService', 'GlyphService', 'PanelService',
-            'FlashService', 'QuickHelpService',
+            'FlashService', 'QuickHelpService', 'WebSocketService',
 
             function ($log, $route, $routeParams, $location,
-                      ks, ts, gs, ps, flash, qhs) {
+                      ks, ts, gs, ps, flash, qhs, wss) {
                 var self = this;
 
                 self.$route = $route;
@@ -84,6 +84,13 @@
                 flash.initFlash();
                 qhs.initQuickHelp();
 
+                // TODO: register handlers for initial messages: instances, settings, etc.
+
+                // TODO: opts?
+                wss.createWebSocket('core', {
+                    wsport: $location.search().wsport
+                });
+
                 $log.log('OnosCtrl has been created');
 
                 $log.debug('route: ', self.$route);
