Removed legacy GUI.
FIxed an NPE in the devices table.
Added cord-gui to obs.exclude

Change-Id: I18a53d2c44c6c97fb7f5d16b7446942a1a37ddca
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/DeviceViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/DeviceViewMessageHandler.java
index d1cbcb4..fb83cdd 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/DeviceViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/DeviceViewMessageHandler.java
@@ -121,6 +121,8 @@
             boolean available = ds.isAvailable(id);
             String iconId = available ? ICON_ID_ONLINE : ICON_ID_OFFLINE;
 
+            String protocol = dev.annotations().value(PROTOCOL);
+
             row.cell(ID, id)
                 .cell(AVAILABLE, available)
                 .cell(AVAILABLE_IID, iconId)
@@ -128,7 +130,7 @@
                 .cell(MFR, dev.manufacturer())
                 .cell(HW, dev.hwVersion())
                 .cell(SW, dev.swVersion())
-                .cell(PROTOCOL, dev.annotations().value(PROTOCOL))
+                .cell(PROTOCOL, protocol != null ? protocol : "")
                 .cell(NUM_PORTS, ds.getPorts(id).size())
                 .cell(MASTER_ID, ms.getMasterFor(id));
         }
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
deleted file mode 100644
index 835058f..0000000
--- a/web/gui/src/main/java/org/onosproject/ui/impl/GuiWebSocketServlet.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2014-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 org.eclipse.jetty.websocket.WebSocket;
-import org.eclipse.jetty.websocket.WebSocketServlet;
-import org.onlab.osgi.DefaultServiceDirectory;
-import org.onlab.osgi.ServiceDirectory;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
-
-/**
- * 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;
-
-    private ServiceDirectory directory = new DefaultServiceDirectory();
-
-    private final Set<TopologyViewWebSocket> sockets = new HashSet<>();
-    private final Timer timer = new Timer();
-    private final TimerTask pruner = new Pruner();
-
-    @Override
-    public void init() throws ServletException {
-        super.init();
-        timer.schedule(pruner, PING_DELAY_MS, PING_DELAY_MS);
-    }
-
-    @Override
-    public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
-        TopologyViewWebSocket socket = new TopologyViewWebSocket(directory);
-        synchronized (sockets) {
-            sockets.add(socket);
-        }
-        return socket;
-    }
-
-    // Task for pruning web-sockets that are idle.
-    private class Pruner extends TimerTask {
-        @Override
-        public void run() {
-            synchronized (sockets) {
-                Iterator<TopologyViewWebSocket> it = sockets.iterator();
-                while (it.hasNext()) {
-                    TopologyViewWebSocket socket = it.next();
-                    if (socket.isIdle()) {
-                        it.remove();
-                        socket.close();
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyResource.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyResource.java
index 2e37b6f..b71b9f8 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyResource.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyResource.java
@@ -52,7 +52,7 @@
         ArrayNode devices = mapper.createArrayNode();
         ArrayNode hosts = mapper.createArrayNode();
 
-        Map<String, ObjectNode> metaUi = TopologyViewMessages.getMetaUi();
+        Map<String, ObjectNode> metaUi = TopologyViewMessageHandler.getMetaUi();
         for (String id : metaUi.keySet()) {
             ObjectNode memento = metaUi.get(id);
             if (id.charAt(17) == '/') {
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
deleted file mode 100644
index 463f8b3..0000000
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessages.java
+++ /dev/null
@@ -1,885 +0,0 @@
-/*
- * Copyright 2014-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.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.
- */
-@Deprecated
-public abstract class TopologyViewMessages {
-
-    protected static final Logger log = LoggerFactory.getLogger(TopologyViewMessages.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 final ServiceDirectory directory;
-    protected final ClusterService clusterService;
-    protected final DeviceService deviceService;
-    protected final LinkService linkService;
-    protected final HostService hostService;
-    protected final MastershipService mastershipService;
-    protected final IntentService intentService;
-    protected final FlowRuleService flowService;
-    protected final StatisticService statService;
-    protected final TopologyService topologyService;
-
-    protected final ObjectMapper mapper = new ObjectMapper();
-    private final String version;
-
-    // TODO: extract into an external & durable state; good enough for now and demo
-    private static Map<String, ObjectNode> metaUi = new ConcurrentHashMap<>();
-
-    /**
-     * 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);
-    }
-
-    /**
-     * Creates a messaging facility for creating messages for topology viewer.
-     *
-     * @param directory service directory
-     */
-    protected TopologyViewMessages(ServiceDirectory 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.allInstructions()) {
-                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/TopologyViewWebSocket.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewWebSocket.java
deleted file mode 100644
index 16b0eb6..0000000
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewWebSocket.java
+++ /dev/null
@@ -1,752 +0,0 @@
-/*
- * Copyright 2014-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 java.io.IOException;
-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 org.eclipse.jetty.websocket.WebSocket;
-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 com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-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.
- */
-@Deprecated
-public class TopologyViewWebSocket
-        extends TopologyViewMessages
-        implements WebSocket.OnTextMessage, WebSocket.OnControl {
-
-    private static final long MAX_AGE_MS = 15000;
-
-    private static final byte PING = 0x9;
-    private static final byte PONG = 0xA;
-    private static final byte[] PING_DATA = new byte[]{(byte) 0xde, (byte) 0xad};
-
-    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 final ApplicationId appId;
-
-    private Connection connection;
-    private FrameConnection control;
-
-    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 long lastActive = System.currentTimeMillis();
-    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.
-     *
-     * @param directory service directory
-     */
-    public TopologyViewWebSocket(ServiceDirectory directory) {
-        super(directory);
-        intentFilter = new TopologyViewIntentFilter(intentService, deviceService,
-                                                    hostService, linkService);
-        appId = directory.get(CoreService.class).registerApplication(APP_ID);
-    }
-
-    /**
-     * Issues a close on the connection.
-     */
-    synchronized void close() {
-        removeListeners();
-        if (connection.isOpen()) {
-            connection.close();
-        }
-    }
-
-    /**
-     * Indicates if this connection is idle.
-     *
-     * @return true if idle or closed
-     */
-    synchronized boolean isIdle() {
-        boolean idle = (System.currentTimeMillis() - lastActive) > MAX_AGE_MS;
-        if (idle || (connection != null && !connection.isOpen())) {
-            return true;
-        } else if (connection != null) {
-            try {
-                control.sendControl(PING, PING_DATA, 0, PING_DATA.length);
-            } catch (IOException e) {
-                log.warn("Unable to send ping message due to: ", e);
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public void onOpen(Connection connection) {
-        log.info("Legacy GUI client connected");
-        this.connection = connection;
-        this.control = (FrameConnection) connection;
-        addListeners();
-
-        sendAllInstances(null);
-        sendAllDevices();
-        sendAllLinks();
-        sendAllHosts();
-    }
-
-    @Override
-    public synchronized void onClose(int closeCode, String message) {
-        removeListeners();
-        timer.cancel();
-        log.info("Legacy GUI client disconnected");
-    }
-
-    @Override
-    public boolean onControl(byte controlCode, byte[] data, int offset, int length) {
-        lastActive = System.currentTimeMillis();
-        return true;
-    }
-
-    @Override
-    public void onMessage(String data) {
-        lastActive = System.currentTimeMillis();
-        try {
-            processMessage((ObjectNode) mapper.reader().readTree(data));
-        } catch (Exception e) {
-            log.warn("Unable to parse GUI request {} due to {}", data, e);
-            log.debug("Boom!!!", e);
-        }
-    }
-
-    // Processes the specified event.
-    private void processMessage(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);
-        }
-    }
-
-    // Sends the specified data to the client.
-    protected synchronized void sendMessage(ObjectNode data) {
-        try {
-            if (connection.isOpen()) {
-                connection.sendMessage(data.toString());
-            }
-        } catch (IOException e) {
-            log.warn("Unable to send message {} to GUI due to {}", data, e);
-            log.debug("Boom!!!", e);
-        }
-    }
-
-    // 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 =
-                HostToHostIntent.builder()
-                        .appId(appId)
-                        .one(one)
-                        .two(two)
-                        .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.emptyTreatment();
-
-        MultiPointToSinglePointIntent intent =
-                MultiPointToSinglePointIntent.builder()
-                        .appId(appId)
-                        .selector(selector)
-                        .treatment(treatment)
-                        .ingressPoints(ingressPoints)
-                        .egressPoint(dstHost.location())
-                        .build();
-
-        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.debug("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.debug("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);
-            }
-        }
-    }
-}
-