diff --git a/web/gui/src/main/webapp/index2.html b/web/gui/src/main/webapp/index2.html
index 95c4e4d..703a240 100644
--- a/web/gui/src/main/webapp/index2.html
+++ b/web/gui/src/main/webapp/index2.html
@@ -70,6 +70,7 @@
     <script type="text/javascript">
         var ONOS = $.onos({
             comment: "configuration options",
+            startVid: 'topo',
             trace: false
         });
     </script>
@@ -77,12 +78,15 @@
     <!-- Framework module files included here -->
     <script src="mast2.js"></script>
 
-    <!-- Contributed (application) views injected here -->
-    <!-- TODO: replace with template marker and inject refs server-side -->
+    <!-- Sample views; can be dispensed with eventually -->
     <script src="sample2.js"></script>
     <script src="sampleAlt2.js"></script>
     <script src="sampleRadio.js"></script>
 
+    <!-- Contributed (application) views injected here -->
+    <!-- TODO: replace with template marker and inject refs server-side -->
+    <script src="topo2.js"></script>
+
     <!-- finally, build the UI-->
     <script type="text/javascript">
         $(ONOS.buildUi);
diff --git a/web/gui/src/main/webapp/onos2.js b/web/gui/src/main/webapp/onos2.js
index 85aa617..6353a6e 100644
--- a/web/gui/src/main/webapp/onos2.js
+++ b/web/gui/src/main/webapp/onos2.js
@@ -25,7 +25,7 @@
     var tsI = new Date().getTime(),         // initialize time stamp
         tsB,                                // build time stamp
         mastHeight = 36,                    // see mast2.css
-        defaultHash = 'sample';
+        defaultVid = 'sample';
 
 
     // attach our main function to the jQuery object
@@ -35,7 +35,8 @@
             navApi;
 
         var defaultOptions = {
-            trace: false
+            trace: false,
+            startVid: defaultVid
         };
 
         // compute runtime settings
@@ -91,7 +92,7 @@
             traceFn('hash', hash);
 
             if (!hash) {
-                hash = defaultHash;
+                hash = settings.startVid;
                 redo = true;
             }
 
@@ -336,10 +337,6 @@
         }
 
         var viewInstanceMethods = {
-            toString: function () {
-                return '[View: id="' + this.vid + '"]';
-            },
-
             token: function () {
                 return {
                     // attributes
@@ -350,6 +347,7 @@
                     // functions
                     width: this.width,
                     height: this.height,
+                    uid: this.uid,
                     setRadio: this.setRadio
                 }
             },
@@ -433,6 +431,10 @@
 
             setRadio: function (btnSet, cb) {
                 setRadioButtons(this.vid, btnSet, cb);
+            },
+
+            uid: function (id) {
+                return uid(this, id);
             }
 
             // TODO: consider schedule, clearTimer, etc.
diff --git a/web/gui/src/main/webapp/topo2-OLD.js b/web/gui/src/main/webapp/topo2-OLD.js
new file mode 100644
index 0000000..04ce7ab
--- /dev/null
+++ b/web/gui/src/main/webapp/topo2-OLD.js
@@ -0,0 +1,1219 @@
+/*
+ * Copyright 2014 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.
+ */
+
+/*
+ ONOS network topology viewer - PoC version 1.0
+
+ @author Simon Hunt
+ */
+
+(function (onos) {
+    'use strict';
+
+    // configuration data
+    var config = {
+        useLiveData: true,
+        debugOn: false,
+        debug: {
+            showNodeXY: false,
+            showKeyHandler: true
+        },
+        options: {
+            layering: true,
+            collisionPrevention: true,
+            loadBackground: true
+        },
+        backgroundUrl: 'img/us-map.png',
+        data: {
+            live: {
+                jsonUrl: 'rs/topology/graph',
+                detailPrefix: 'rs/topology/graph/',
+                detailSuffix: ''
+            },
+            fake: {
+                jsonUrl: 'json/network2.json',
+                detailPrefix: 'json/',
+                detailSuffix: '.json'
+            }
+        },
+        iconUrl: {
+            device: 'img/device.png',
+            host: 'img/host.png',
+            pkt: 'img/pkt.png',
+            opt: 'img/opt.png'
+        },
+        mastHeight: 36,
+        force: {
+            note: 'node.class or link.class is used to differentiate',
+            linkDistance: {
+                infra: 200,
+                host: 40
+            },
+            linkStrength: {
+                infra: 1.0,
+                host: 1.0
+            },
+            charge: {
+                device: -800,
+                host: -1000
+            },
+            ticksWithoutCollisions: 50,
+            marginLR: 20,
+            marginTB: 20,
+            translate: function() {
+                return 'translate(' +
+                    config.force.marginLR + ',' +
+                    config.force.marginTB + ')';
+            }
+        },
+        labels: {
+            imgPad: 16,
+            padLR: 8,
+            padTB: 6,
+            marginLR: 3,
+            marginTB: 2,
+            port: {
+                gap: 3,
+                width: 18,
+                height: 14
+            }
+        },
+        icons: {
+            w: 32,
+            h: 32,
+            xoff: -12,
+            yoff: -8
+        },
+        constraints: {
+            ypos: {
+                host: 0.05,
+                switch: 0.3,
+                roadm: 0.7
+            }
+        },
+        hostLinkWidth: 1.0,
+        hostRadius: 7,
+        mouseOutTimerDelayMs: 120
+    };
+
+    // state variables
+    var netView = {},
+        network = {},
+        selected = {},
+        highlighted = null,
+        hovered = null,
+        viewMode = 'showAll',
+        portLabelsOn = false;
+
+
+    function debug(what) {
+        return config.debugOn && config.debug[what];
+    }
+
+    function urlData() {
+        return config.data[config.useLiveData ? 'live' : 'fake'];
+    }
+
+    function networkJsonUrl() {
+        return urlData().jsonUrl;
+    }
+
+    function safeId(id) {
+        return id.replace(/[^a-z0-9]/gi, '_');
+    }
+
+    function detailJsonUrl(id) {
+        var u = urlData(),
+            encId = config.useLiveData ? encodeURIComponent(id) : safeId(id);
+        return u.detailPrefix + encId + u.detailSuffix;
+    }
+
+
+    // load the topology view of the network
+    function loadNetworkView() {
+        // Hey, here I am, calling something on the ONOS api:
+        api.printTime();
+
+        resize();
+
+        // go get our network data from the server...
+        var url = networkJsonUrl();
+        d3.json(url , function (err, data) {
+            if (err) {
+                alert('Oops! Error reading JSON...\n\n' +
+                    'URL: ' + url + '\n\n' +
+                    'Error: ' + err.message);
+                return;
+            }
+//            console.log("here is the JSON data...");
+//            console.log(data);
+
+            network.data = data;
+            drawNetwork();
+        });
+
+        // while we wait for the data, set up the handlers...
+        setUpClickHandler();
+        setUpRadioButtonHandler();
+        setUpKeyHandler();
+        $(window).on('resize', resize);
+    }
+
+    function setUpClickHandler() {
+        // click handler for "selectable" objects
+        $(document).on('click', '.select-object', function () {
+            // when any object of class "select-object" is clicked...
+            var obj = network.lookup[$(this).data('id')];
+            if (obj) {
+                selectObject(obj);
+            }
+            // stop propagation of event (I think) ...
+            return false;
+        });
+    }
+
+    function setUpRadioButtonHandler() {
+        d3.selectAll('#displayModes .radio').on('click', function () {
+            var id = d3.select(this).attr('id');
+            if (id !== viewMode) {
+                radioButton('displayModes', id);
+                viewMode = id;
+                doRadioAction(id);
+            }
+        });
+    }
+
+    function doRadioAction(id) {
+        showAllLayers();
+        if (id === 'showPkt') {
+            showPacketLayer();
+        } else if (id === 'showOpt') {
+            showOpticalLayer();
+        }
+    }
+
+    function showAllLayers() {
+        network.node.classed('inactive', false);
+        network.link.classed('inactive', false);
+        d3.selectAll('svg .port').classed('inactive', false);
+        d3.selectAll('svg .portText').classed('inactive', false);
+    }
+
+    function showPacketLayer() {
+        network.node.each(function(d) {
+            // deactivate nodes that are not hosts or switches
+            if (d.class === 'device' && d.type !== 'switch') {
+                d3.select(this).classed('inactive', true);
+            }
+        });
+
+        network.link.each(function(lnk) {
+            // deactivate infrastructure links that have opt's as endpoints
+            if (lnk.source.type === 'roadm' || lnk.target.type === 'roadm') {
+                d3.select(this).classed('inactive', true);
+            }
+        });
+
+        // deactivate non-packet ports
+        d3.selectAll('svg .optPort').classed('inactive', true)
+    }
+
+    function showOpticalLayer() {
+        network.node.each(function(d) {
+            // deactivate nodes that are not optical devices
+            if (d.type !== 'roadm') {
+                d3.select(this).classed('inactive', true);
+            }
+        });
+
+        network.link.each(function(lnk) {
+            // deactivate infrastructure links that have opt's as endpoints
+            if (lnk.source.type !== 'roadm' || lnk.target.type !== 'roadm') {
+                d3.select(this).classed('inactive', true);
+            }
+        });
+
+        // deactivate non-packet ports
+        d3.selectAll('svg .pktPort').classed('inactive', true)
+    }
+
+    function setUpKeyHandler() {
+        d3.select('body')
+            .on('keydown', function () {
+                processKeyEvent();
+                if (debug('showKeyHandler')) {
+                    network.svg.append('text')
+                        .attr('x', 5)
+                        .attr('y', 15)
+                        .style('font-size', '20pt')
+                        .text('keyCode: ' + d3.event.keyCode +
+                            ' applied to : ' + contextLabel())
+                        .transition().duration(2000)
+                        .style('font-size', '2pt')
+                        .style('fill-opacity', 0.01)
+                        .remove();
+                }
+            });
+    }
+
+    function contextLabel() {
+        return hovered === null ? "(nothing)" : hovered.id;
+    }
+
+    function radioButton(group, id) {
+        d3.selectAll("#" + group + " .radio").classed("active", false);
+        d3.select("#" + group + " #" + id).classed("active", true);
+    }
+
+    function processKeyEvent() {
+        var code = d3.event.keyCode;
+        switch (code) {
+            case 66:    // B
+                toggleBackground();
+                break;
+            case 71:    // G
+                cycleLayout();
+                break;
+            case 76:    // L
+                cycleLabels();
+                break;
+            case 80:    // P
+                togglePorts();
+                break;
+            case 85:    // U
+                unpin();
+                break;
+        }
+
+    }
+
+    function toggleBackground() {
+        var bg = d3.select('#bg'),
+            vis = bg.style('visibility'),
+            newvis = (vis === 'hidden') ? 'visible' : 'hidden';
+        bg.style('visibility', newvis);
+    }
+
+    function cycleLayout() {
+        config.options.layering = !config.options.layering;
+        network.force.resume();
+    }
+
+    function cycleLabels() {
+        console.log('Cycle Labels - context = ' + contextLabel());
+    }
+
+    function togglePorts() {
+        portLabelsOn = !portLabelsOn;
+        var portVis = portLabelsOn ? 'visible' : 'hidden';
+        d3.selectAll('.port').style('visibility', portVis);
+        d3.selectAll('.portText').style('visibility', portVis);
+    }
+
+    function unpin() {
+        if (hovered) {
+            hovered.fixed = false;
+            findNodeFromData(hovered).classed('fixed', false);
+            network.force.resume();
+        }
+        console.log('Unpin - context = ' + contextLabel());
+    }
+
+
+    // ========================================================
+
+    function drawNetwork() {
+        $('#view').empty();
+
+        prepareNodesAndLinks();
+        createLayout();
+        console.log("\n\nHere is the augmented network object...");
+        console.log(network);
+    }
+
+    function prepareNodesAndLinks() {
+        network.lookup = {};
+        network.nodes = [];
+        network.links = [];
+
+        var nw = network.forceWidth,
+            nh = network.forceHeight;
+
+        function yPosConstraintForNode(n) {
+            return config.constraints.ypos[n.type || 'host'];
+        }
+
+        // Note that both 'devices' and 'hosts' get mapped into the nodes array
+
+        // first, the devices...
+        network.data.devices.forEach(function(n) {
+            var ypc = yPosConstraintForNode(n),
+                ix = Math.random() * 0.6 * nw + 0.2 * nw,
+                iy = ypc * nh,
+                node = {
+                    id: n.id,
+                    labels: n.labels,
+                    class: 'device',
+                    icon: 'device',
+                    type: n.type,
+                    x: ix,
+                    y: iy,
+                    constraint: {
+                        weight: 0.7,
+                        y: iy
+                    }
+                };
+            network.lookup[n.id] = node;
+            network.nodes.push(node);
+        });
+
+        // then, the hosts...
+        network.data.hosts.forEach(function(n) {
+            var ypc = yPosConstraintForNode(n),
+                ix = Math.random() * 0.6 * nw + 0.2 * nw,
+                iy = ypc * nh,
+                node = {
+                    id: n.id,
+                    labels: n.labels,
+                    class: 'host',
+                    icon: 'host',
+                    type: n.type,
+                    x: ix,
+                    y: iy,
+                    constraint: {
+                        weight: 0.7,
+                        y: iy
+                    }
+                };
+            network.lookup[n.id] = node;
+            network.nodes.push(node);
+        });
+
+
+        // now, process the explicit links...
+        network.data.links.forEach(function(lnk) {
+            var src = network.lookup[lnk.src],
+                dst = network.lookup[lnk.dst],
+                id = src.id + "-" + dst.id;
+
+            var link = {
+                class: 'infra',
+                id: id,
+                type: lnk.type,
+                width: lnk.linkWidth,
+                source: src,
+                srcPort: lnk.srcPort,
+                target: dst,
+                tgtPort: lnk.dstPort,
+                strength: config.force.linkStrength.infra
+            };
+            network.links.push(link);
+        });
+
+        // finally, infer host links...
+        network.data.hosts.forEach(function(n) {
+            var src = network.lookup[n.id],
+                dst = network.lookup[n.cp.device],
+                id = src.id + "-" + dst.id;
+
+            var link = {
+                class: 'host',
+                id: id,
+                type: 'hostLink',
+                width: config.hostLinkWidth,
+                source: src,
+                target: dst,
+                strength: config.force.linkStrength.host
+            };
+            network.links.push(link);
+        });
+    }
+
+    function createLayout() {
+
+        var cfg = config.force;
+
+        network.force = d3.layout.force()
+            .size([network.forceWidth, network.forceHeight])
+            .nodes(network.nodes)
+            .links(network.links)
+            .linkStrength(function(d) { return cfg.linkStrength[d.class]; })
+            .linkDistance(function(d) { return cfg.linkDistance[d.class]; })
+            .charge(function(d) { return cfg.charge[d.class]; })
+            .on('tick', tick);
+
+        network.svg = d3.select('#view').append('svg')
+            .attr('width', netView.width)
+            .attr('height', netView.height)
+            .append('g')
+            .attr('transform', config.force.translate());
+//            .attr('id', 'zoomable')
+//            .call(d3.behavior.zoom().on("zoom", zoomRedraw));
+
+        network.svg.append('svg:image')
+            .attr({
+                id: 'bg',
+                width: netView.width,
+                height: netView.height,
+                'xlink:href': config.backgroundUrl
+            })
+            .style('visibility',
+                    config.options.loadBackground ? 'visible' : 'hidden');
+
+//        function zoomRedraw() {
+//            d3.select("#zoomable").attr("transform",
+//                    "translate(" + d3.event.translate + ")"
+//                    + " scale(" + d3.event.scale + ")");
+//        }
+
+        // TODO: move glow/blur stuff to util script
+        var glow = network.svg.append('filter')
+            .attr('x', '-50%')
+            .attr('y', '-50%')
+            .attr('width', '200%')
+            .attr('height', '200%')
+            .attr('id', 'blue-glow');
+
+        glow.append('feColorMatrix')
+            .attr('type', 'matrix')
+            .attr('values', '0 0 0 0  0 ' +
+                '0 0 0 0  0 ' +
+                '0 0 0 0  .7 ' +
+                '0 0 0 1  0 ');
+
+        glow.append('feGaussianBlur')
+            .attr('stdDeviation', 3)
+            .attr('result', 'coloredBlur');
+
+        glow.append('feMerge').selectAll('feMergeNode')
+            .data(['coloredBlur', 'SourceGraphic'])
+            .enter().append('feMergeNode')
+            .attr('in', String);
+
+        // TODO: legend (and auto adjust on scroll)
+//        $('#view').on('scroll', function() {
+//
+//        });
+
+
+        // TODO: move drag behavior into separate method.
+        // == define node drag behavior...
+        network.draggedThreshold = d3.scale.linear()
+            .domain([0, 0.1])
+            .range([5, 20])
+            .clamp(true);
+
+        function dragged(d) {
+            var threshold = network.draggedThreshold(network.force.alpha()),
+                dx = d.oldX - d.px,
+                dy = d.oldY - d.py;
+            if (Math.abs(dx) >= threshold || Math.abs(dy) >= threshold) {
+                d.dragged = true;
+            }
+            return d.dragged;
+        }
+
+        network.drag = d3.behavior.drag()
+            .origin(function(d) { return d; })
+            .on('dragstart', function(d) {
+                d.oldX = d.x;
+                d.oldY = d.y;
+                d.dragged = false;
+                d.fixed |= 2;
+            })
+            .on('drag', function(d) {
+                d.px = d3.event.x;
+                d.py = d3.event.y;
+                if (dragged(d)) {
+                    if (!network.force.alpha()) {
+                        network.force.alpha(.025);
+                    }
+                }
+            })
+            .on('dragend', function(d) {
+                if (!dragged(d)) {
+                    selectObject(d, this);
+                }
+                d.fixed &= ~6;
+
+                // once we've finished moving, pin the node in position,
+                // if it is a device (not a host)
+                if (d.class === 'device') {
+                    d.fixed = true;
+                    d3.select(this).classed('fixed', true)
+                }
+            });
+
+        $('#view').on('click', function(e) {
+            if (!$(e.target).closest('.node').length) {
+                deselectObject();
+            }
+        });
+
+        // ...............................................................
+
+        // add links to the display
+        network.link = network.svg.append('g').attr('id', 'links')
+            .selectAll('.link')
+            .data(network.force.links(), function(d) {return d.id})
+            .enter().append('line')
+            .attr('class', function(d) {return 'link ' + d.class});
+
+        network.linkSrcPort = network.svg.append('g')
+            .attr({
+                id: 'srcPorts',
+                class: 'portLayer'
+            });
+        network.linkTgtPort = network.svg.append('g')
+            .attr({
+                id: 'tgtPorts',
+                class: 'portLayer'
+            });
+
+        var portVis = portLabelsOn ? 'visible' : 'hidden',
+            pw = config.labels.port.width,
+            ph = config.labels.port.height;
+
+        network.link.filter('.infra').each(function(d) {
+            var srcType = d.source.type === 'roadm' ? 'optPort' : 'pktPort',
+                tgtType = d.target.type === 'roadm' ? 'optPort' : 'pktPort';
+
+            if (d.source.type)
+
+            network.linkSrcPort.append('rect').attr({
+                id: 'srcPort-' + safeId(d.id),
+                class: 'port ' + srcType,
+                width: pw,
+                height: ph,
+                rx: 4,
+                ry: 4
+            }).style('visibility', portVis);
+
+            network.linkTgtPort.append('rect').attr({
+                id: 'tgtPort-' + safeId(d.id),
+                class: 'port ' + tgtType,
+                width: pw,
+                height: ph,
+                rx: 4,
+                ry: 4
+            }).style('visibility', portVis);
+
+            network.linkSrcPort.append('text').attr({
+                id: 'srcText-' + safeId(d.id),
+                class: 'portText ' + srcType
+            }).text(d.srcPort)
+                .style('visibility', portVis);
+
+            network.linkTgtPort.append('text').attr({
+                id: 'tgtText-' + safeId(d.id),
+                class: 'portText ' + tgtType
+            }).text(d.tgtPort)
+                .style('visibility', portVis);
+        });
+
+        // ...............................................................
+
+        // add nodes to the display
+        network.node = network.svg.selectAll('.node')
+            .data(network.force.nodes(), function(d) {return d.id})
+            .enter().append('g')
+            .attr('class', function(d) {
+                var cls = 'node ' + d.class;
+                if (d.type) {
+                    cls += ' ' + d.type;
+                }
+                return cls;
+            })
+            .attr('transform', function(d) {
+                return translate(d.x, d.y);
+            })
+            .call(network.drag)
+            .on('mouseover', function(d) {
+                // TODO: show tooltip
+                if (network.mouseoutTimeout) {
+                    clearTimeout(network.mouseoutTimeout);
+                    network.mouseoutTimeout = null;
+                }
+                hoverObject(d);
+            })
+            .on('mouseout', function(d) {
+                // TODO: hide tooltip
+                if (network.mouseoutTimeout) {
+                    clearTimeout(network.mouseoutTimeout);
+                    network.mouseoutTimeout = null;
+                }
+                network.mouseoutTimeout = setTimeout(function() {
+                    hoverObject(null);
+                }, config.mouseOutTimerDelayMs);
+            });
+
+
+        // deal with device nodes first
+        network.nodeRect = network.node.filter('.device')
+            .append('rect')
+            .attr({
+                rx: 5,
+                ry: 5,
+                width: 100,
+                height: 12
+            });
+            // note that width/height are adjusted to fit the label text
+            // then padded, and space made for the icon.
+
+        network.node.filter('.device').each(function(d) {
+            var node = d3.select(this),
+                icon = iconUrl(d);
+
+            node.append('text')
+            // TODO: add label cycle behavior
+                .text(d.id)
+                .attr('dy', '1.1em');
+
+            if (icon) {
+                var cfg = config.icons;
+                node.append('svg:image')
+                    .attr({
+                        width: cfg.w,
+                        height: cfg.h,
+                        'xlink:href': icon
+                    });
+                // note, icon relative positioning (x,y) is done after we have
+                // adjusted the bounds of the rectangle...
+            }
+
+            // debug function to show the modelled x,y coordinates of nodes...
+            if (debug('showNodeXY')) {
+                node.select('rect').attr('fill-opacity', 0.5);
+                node.append('circle')
+                    .attr({
+                        class: 'debug',
+                        cx: 0,
+                        cy: 0,
+                        r: '3px'
+                    });
+            }
+        });
+
+        // now process host nodes
+        network.nodeCircle = network.node.filter('.host')
+            .append('circle')
+            .attr({
+                r: config.hostRadius
+            });
+
+        network.node.filter('.host').each(function(d) {
+            var node = d3.select(this),
+                icon = iconUrl(d);
+
+            // debug function to show the modelled x,y coordinates of nodes...
+            if (debug('showNodeXY')) {
+                node.select('circle').attr('fill-opacity', 0.5);
+                node.append('circle')
+                    .attr({
+                        class: 'debug',
+                        cx: 0,
+                        cy: 0,
+                        r: '3px'
+                    });
+            }
+        });
+
+        // this function is scheduled to happen soon after the given thread ends
+        setTimeout(function() {
+            var lab = config.labels,
+                portGap = lab.port.gap,
+                midW = portGap + lab.port.width/ 2,
+                midH = portGap + lab.port.height / 2;
+
+            // post process the device nodes, to pad their size to fit the
+            // label text and attach the icon to the right location.
+            network.node.filter('.device').each(function(d) {
+                // for every node, recompute size, padding, etc. so text fits
+                var node = d3.select(this),
+                    text = node.select('text'),
+                    box = adjustRectToFitText(node);
+
+                // now make the computed adjustment
+                node.select('rect')
+                    .attr(box);
+
+                node.select('image')
+                    .attr('x', box.x + config.icons.xoff)
+                    .attr('y', box.y + config.icons.yoff);
+
+                var bounds = boundsFromBox(box),
+                    portBounds = {
+                        x1: bounds.x1 - midW,
+                        x2: bounds.x2 + midW,
+                        y1: bounds.y1 - midH,
+                        y2: bounds.y2 + midH
+                    };
+
+                // todo: clean up extent and edge work..
+                d.extent = {
+                    left: bounds.x1 - lab.marginLR,
+                    right: bounds.x2 + lab.marginLR,
+                    top: bounds.y1 - lab.marginTB,
+                    bottom: bounds.y2 + lab.marginTB
+                };
+
+                d.edge = {
+                    left   : new geo.LineSegment(bounds.x1, bounds.y1, bounds.x1, bounds.y2),
+                    right  : new geo.LineSegment(bounds.x2, bounds.y1, bounds.x2, bounds.y2),
+                    top    : new geo.LineSegment(bounds.x1, bounds.y1, bounds.x2, bounds.y1),
+                    bottom : new geo.LineSegment(bounds.x1, bounds.y2, bounds.x2, bounds.y2)
+                };
+
+                d.portEdge = {
+                    left   : new geo.LineSegment(
+                        portBounds.x1, portBounds.y1, portBounds.x1, portBounds.y2
+                    ),
+                    right  : new geo.LineSegment(
+                        portBounds.x2, portBounds.y1, portBounds.x2, portBounds.y2
+                    ),
+                    top    : new geo.LineSegment(
+                        portBounds.x1, portBounds.y1, portBounds.x2, portBounds.y1
+                    ),
+                    bottom : new geo.LineSegment(
+                        portBounds.x1, portBounds.y2, portBounds.x2, portBounds.y2
+                    )
+                };
+
+            });
+
+            network.numTicks = 0;
+            network.preventCollisions = false;
+            network.force.start();
+            for (var i = 0; i < config.force.ticksWithoutCollisions; i++) {
+                network.force.tick();
+            }
+            network.preventCollisions = true;
+            $('#view').css('visibility', 'visible');
+        });
+
+
+        // returns the newly computed bounding box of the rectangle
+        function adjustRectToFitText(n) {
+            var text = n.select('text'),
+                box = text.node().getBBox(),
+                lab = config.labels;
+
+            // not sure why n.data() returns an array of 1 element...
+            var data = n.data()[0];
+
+            text.attr('text-anchor', 'middle')
+                .attr('y', '-0.8em')
+                .attr('x', lab.imgPad/2)
+            ;
+
+            // translate the bbox so that it is centered on [x,y]
+            box.x = -box.width / 2;
+            box.y = -box.height / 2;
+
+            // add padding
+            box.x -= (lab.padLR + lab.imgPad/2);
+            box.width += lab.padLR * 2 + lab.imgPad;
+            box.y -= lab.padTB;
+            box.height += lab.padTB * 2;
+
+            return box;
+        }
+
+        function boundsFromBox(box) {
+            return {
+                x1: box.x,
+                y1: box.y,
+                x2: box.x + box.width,
+                y2: box.y + box.height
+            };
+        }
+
+    }
+
+    function iconUrl(d) {
+        return 'img/' + d.type + '.png';
+//        return config.iconUrl[d.icon];
+    }
+
+    function translate(x, y) {
+        return 'translate(' + x + ',' + y + ')';
+    }
+
+    // prevents collisions amongst device nodes
+    function preventCollisions() {
+        var quadtree = d3.geom.quadtree(network.nodes),
+            hrad = config.hostRadius;
+
+        network.nodes.forEach(function(n) {
+            var nx1, nx2, ny1, ny2;
+
+            if (n.class === 'device') {
+                nx1 = n.x + n.extent.left;
+                nx2 = n.x + n.extent.right;
+                ny1 = n.y + n.extent.top;
+                ny2 = n.y + n.extent.bottom;
+
+            } else {
+                nx1 = n.x - hrad;
+                nx2 = n.x + hrad;
+                ny1 = n.y - hrad;
+                ny2 = n.y + hrad;
+            }
+
+            quadtree.visit(function(quad, x1, y1, x2, y2) {
+                if (quad.point && quad.point !== n) {
+                    // check if the rectangles/circles intersect
+                    var p = quad.point,
+                        px1, px2, py1, py2, ix;
+
+                    if (p.class === 'device') {
+                        px1 = p.x + p.extent.left;
+                        px2 = p.x + p.extent.right;
+                        py1 = p.y + p.extent.top;
+                        py2 = p.y + p.extent.bottom;
+
+                    } else {
+                        px1 = p.x - hrad;
+                        px2 = p.x + hrad;
+                        py1 = p.y - hrad;
+                        py2 = p.y + hrad;
+                    }
+
+                    ix = (px1 <= nx2 && nx1 <= px2 && py1 <= ny2 && ny1 <= py2);
+
+                    if (ix) {
+                        var xa1 = nx2 - px1, // shift n left , p right
+                            xa2 = px2 - nx1, // shift n right, p left
+                            ya1 = ny2 - py1, // shift n up   , p down
+                            ya2 = py2 - ny1, // shift n down , p up
+                            adj = Math.min(xa1, xa2, ya1, ya2);
+
+                        if (adj == xa1) {
+                            n.x -= adj / 2;
+                            p.x += adj / 2;
+                        } else if (adj == xa2) {
+                            n.x += adj / 2;
+                            p.x -= adj / 2;
+                        } else if (adj == ya1) {
+                            n.y -= adj / 2;
+                            p.y += adj / 2;
+                        } else if (adj == ya2) {
+                            n.y += adj / 2;
+                            p.y -= adj / 2;
+                        }
+                    }
+                    return ix;
+                }
+            });
+
+        });
+    }
+
+    function tick(e) {
+        network.numTicks++;
+
+        if (config.options.layering) {
+            // adjust the y-coord of each node, based on y-pos constraints
+            network.nodes.forEach(function (n) {
+                var z = e.alpha * n.constraint.weight;
+                if (!isNaN(n.constraint.y)) {
+                    n.y = (n.constraint.y * z + n.y * (1 - z));
+                }
+            });
+        }
+
+        if (config.options.collisionPrevention && network.preventCollisions) {
+            preventCollisions();
+        }
+
+        var portHalfW = config.labels.port.width / 2,
+            portHalfH = config.labels.port.height / 2;
+
+        // clip visualization of links at bounds of nodes...
+        network.link.each(function(d) {
+            var xs = d.source.x,
+                ys = d.source.y,
+                xt = d.target.x,
+                yt = d.target.y,
+                line = new geo.LineSegment(xs, ys, xt, yt),
+                e, ix,
+                exs, eys, ext, eyt,
+                pxs, pys, pxt, pyt;
+
+            if (d.class === 'host') {
+                // no adjustment for source end of link, since hosts are dots
+                exs = xs;
+                eys = ys;
+
+            } else {
+                for (e in d.source.edge) {
+                    ix = line.intersect(d.source.edge[e].offset(xs, ys));
+                    if (ix.in1 && ix.in2) {
+                        exs = ix.x;
+                        eys = ix.y;
+
+                        // also pick off the port label intersection
+                        ix = line.intersect(d.source.portEdge[e].offset(xs, ys));
+                        pxs = ix.x;
+                        pys = ix.y;
+                        break;
+                    }
+                }
+            }
+
+            for (e in d.target.edge) {
+                ix = line.intersect(d.target.edge[e].offset(xt, yt));
+                if (ix.in1 && ix.in2) {
+                    ext = ix.x;
+                    eyt = ix.y;
+
+                    // also pick off the port label intersection
+                    ix = line.intersect(d.target.portEdge[e].offset(xt, yt));
+                    pxt = ix.x;
+                    pyt = ix.y;
+                    break;
+                }
+            }
+
+            // adjust the endpoints of the link's line to match rectangles
+            var sid = safeId(d.id);
+            d3.select(this)
+                .attr('x1', exs)
+                .attr('y1', eys)
+                .attr('x2', ext)
+                .attr('y2', eyt);
+
+            d3.select('#srcPort-' + sid)
+                .attr('x', pxs - portHalfW)
+                .attr('y', pys - portHalfH);
+
+            d3.select('#tgtPort-' + sid)
+                .attr('x', pxt - portHalfW)
+                .attr('y', pyt - portHalfH);
+
+            // TODO: fit label rect to size of port number.
+            d3.select('#srcText-' + sid)
+                .attr('x', pxs - 5)
+                .attr('y', pys + 3);
+
+            d3.select('#tgtText-' + sid)
+                .attr('x', pxt - 5)
+                .attr('y', pyt + 3);
+
+        });
+
+        // position each node by translating the node (group) by x,y
+        network.node
+            .attr('transform', function(d) {
+                return translate(d.x, d.y);
+            });
+
+    }
+
+    //    $('#docs-close').on('click', function() {
+    //        deselectObject();
+    //        return false;
+    //    });
+
+    //    $(document).on('click', '.select-object', function() {
+    //        var obj = graph.data[$(this).data('name')];
+    //        if (obj) {
+    //            selectObject(obj);
+    //        }
+    //        return false;
+    //    });
+
+    function findNodeFromData(d) {
+        var el = null;
+        network.node.filter('.' + d.class).each(function(n) {
+            if (n.id === d.id) {
+                el = d3.select(this);
+            }
+        });
+        return el;
+    }
+
+    function selectObject(obj, el) {
+        var node;
+        if (el) {
+            node = d3.select(el);
+        } else {
+            network.node.each(function(d) {
+                if (d == obj) {
+                    node = d3.select(el = this);
+                }
+            });
+        }
+        if (!node) return;
+
+        if (node.classed('selected')) {
+            deselectObject();
+            flyinPane(null);
+            return;
+        }
+        deselectObject(false);
+
+        selected = {
+            obj : obj,
+            el  : el
+        };
+
+        node.classed('selected', true);
+        flyinPane(obj);
+    }
+
+    function deselectObject(doResize) {
+        // Review: logic of 'resize(...)' function.
+        if (doResize || typeof doResize == 'undefined') {
+            resize(false);
+        }
+
+        // deselect all nodes in the network...
+        network.node.classed('selected', false);
+        selected = {};
+        flyinPane(null);
+    }
+
+    function flyinPane(obj) {
+        var pane = d3.select('#flyout'),
+            url;
+
+        if (obj) {
+            // go get details of the selected object from the server...
+            url = detailJsonUrl(obj.id);
+            d3.json(url, function (err, data) {
+                if (err) {
+                    alert('Oops! Error reading JSON...\n\n' +
+                        'URL: ' + url + '\n\n' +
+                        'Error: ' + err.message);
+                    return;
+                }
+//                console.log("JSON data... " + url);
+//                console.log(data);
+
+                displayDetails(data, pane);
+            });
+
+        } else {
+            // hide pane
+            pane.transition().duration(750)
+                .style('right', '-320px')
+                .style('opacity', 0.0);
+        }
+    }
+
+    function displayDetails(data, pane) {
+        $('#flyout').empty();
+
+        var title = pane.append("h2"),
+            table = pane.append("table"),
+            tbody = table.append("tbody");
+
+        $('<img src="img/' + data.type + '.png">').appendTo(title);
+        $('<span>').attr('class', 'icon').text(data.id).appendTo(title);
+
+
+        // TODO: consider using d3 data bind to TR/TD
+
+        data.propOrder.forEach(function(p) {
+            if (p === '-') {
+                addSep(tbody);
+            } else {
+                addProp(tbody, p, data.props[p]);
+            }
+        });
+
+        function addSep(tbody) {
+            var tr = tbody.append('tr');
+            $('<hr>').appendTo(tr.append('td').attr('colspan', 2));
+        }
+
+        function addProp(tbody, label, value) {
+            var tr = tbody.append('tr');
+
+            tr.append('td')
+                .attr('class', 'label')
+                .text(label + ' :');
+
+            tr.append('td')
+                .attr('class', 'value')
+                .text(value);
+        }
+
+        // show pane
+        pane.transition().duration(750)
+            .style('right', '20px')
+            .style('opacity', 1.0);
+    }
+
+    function highlightObject(obj) {
+        if (obj) {
+            if (obj != highlighted) {
+                // TODO set or clear "inactive" class on nodes, based on criteria
+                network.node.classed('inactive', function(d) {
+                    //                return (obj !== d &&
+                    //                    d.relation(obj.id));
+                    return (obj !== d);
+                });
+                // TODO: same with links
+                network.link.classed('inactive', function(d) {
+                    return (obj !== d.source && obj !== d.target);
+                });
+            }
+            highlighted = obj;
+        } else {
+            if (highlighted) {
+                // clear the inactive flag (no longer suppressed visually)
+                network.node.classed('inactive', false);
+                network.link.classed('inactive', false);
+            }
+            highlighted = null;
+
+        }
+    }
+
+    function hoverObject(obj) {
+        if (obj) {
+            hovered = obj;
+        } else {
+            if (hovered) {
+                hovered = null;
+            }
+        }
+    }
+
+
+    function resize() {
+        netView.height = window.innerHeight - config.mastHeight;
+        netView.width = window.innerWidth;
+        $('#view')
+            .css('height', netView.height + 'px')
+            .css('width', netView.width + 'px');
+
+        network.forceWidth = netView.width - config.force.marginLR;
+        network.forceHeight = netView.height - config.force.marginTB;
+    }
+
+    // ======================================================================
+    // register with the UI framework
+
+    onos.ui.addView('topo', {
+        load: loadNetworkView
+    });
+
+
+}(ONOS));
+
diff --git a/web/gui/src/main/webapp/topo2.css b/web/gui/src/main/webapp/topo2.css
index 2e058c1..88fcd94 100644
--- a/web/gui/src/main/webapp/topo2.css
+++ b/web/gui/src/main/webapp/topo2.css
@@ -20,3 +20,7 @@
  @author Simon Hunt
  */
 
+svg #topo-bg {
+    opacity: 0.5;
+}
+
diff --git a/web/gui/src/main/webapp/topo2.js b/web/gui/src/main/webapp/topo2.js
index 8d1f9c1..fcc4bb4 100644
--- a/web/gui/src/main/webapp/topo2.js
+++ b/web/gui/src/main/webapp/topo2.js
@@ -15,7 +15,7 @@
  */
 
 /*
- ONOS network topology viewer - PoC version 1.0
+ ONOS network topology viewer - version 1.1
 
  @author Simon Hunt
  */
@@ -25,7 +25,7 @@
 
     // configuration data
     var config = {
-        useLiveData: true,
+        useLiveData: false,
         debugOn: false,
         debug: {
             showNodeXY: false,
@@ -34,7 +34,7 @@
         options: {
             layering: true,
             collisionPrevention: true,
-            loadBackground: true
+            showBackground: true
         },
         backgroundUrl: 'img/us-map.png',
         data: {
@@ -55,22 +55,7 @@
             pkt: 'img/pkt.png',
             opt: 'img/opt.png'
         },
-        mastHeight: 36,
         force: {
-            note: 'node.class or link.class is used to differentiate',
-            linkDistance: {
-                infra: 200,
-                host: 40
-            },
-            linkStrength: {
-                infra: 1.0,
-                host: 1.0
-            },
-            charge: {
-                device: -800,
-                host: -1000
-            },
-            ticksWithoutCollisions: 50,
             marginLR: 20,
             marginTB: 20,
             translate: function() {
@@ -78,39 +63,19 @@
                     config.force.marginLR + ',' +
                     config.force.marginTB + ')';
             }
-        },
-        labels: {
-            imgPad: 16,
-            padLR: 8,
-            padTB: 6,
-            marginLR: 3,
-            marginTB: 2,
-            port: {
-                gap: 3,
-                width: 18,
-                height: 14
-            }
-        },
-        icons: {
-            w: 32,
-            h: 32,
-            xoff: -12,
-            yoff: -8
-        },
-        constraints: {
-            ypos: {
-                host: 0.05,
-                switch: 0.3,
-                roadm: 0.7
-            }
-        },
-        hostLinkWidth: 1.0,
-        hostRadius: 7,
-        mouseOutTimerDelayMs: 120
+        }
     };
 
+    // radio buttons
+    var btnSet = [
+            { id: 'showAll', text: 'All Layers' },
+            { id: 'showPkt', text: 'Packet Only' },
+            { id: 'showOpt', text: 'Optical Only' }
+        ];
+
     // state variables
-    var view = {},
+    var svg,
+        bgImg,
         network = {},
         selected = {},
         highlighted = null,
@@ -119,84 +84,19 @@
         portLabelsOn = false;
 
 
-    function debug(what) {
-        return config.debugOn && config.debug[what];
-    }
+    // ==============================
+    // Private functions
 
-    function urlData() {
-        return config.data[config.useLiveData ? 'live' : 'fake'];
-    }
-
-    function networkJsonUrl() {
-        return urlData().jsonUrl;
-    }
-
-    function safeId(id) {
-        return id.replace(/[^a-z0-9]/gi, '_');
-    }
-
-    function detailJsonUrl(id) {
-        var u = urlData(),
-            encId = config.useLiveData ? encodeURIComponent(id) : safeId(id);
-        return u.detailPrefix + encId + u.detailSuffix;
-    }
-
-
-    // load the topology view of the network
-    function loadNetworkView() {
-        // Hey, here I am, calling something on the ONOS api:
-        api.printTime();
-
-        resize();
-
-        // go get our network data from the server...
-        var url = networkJsonUrl();
-        d3.json(url , function (err, data) {
-            if (err) {
-                alert('Oops! Error reading JSON...\n\n' +
-                    'URL: ' + url + '\n\n' +
-                    'Error: ' + err.message);
-                return;
-            }
-//            console.log("here is the JSON data...");
-//            console.log(data);
-
-            network.data = data;
-            drawNetwork();
-        });
-
-        // while we wait for the data, set up the handlers...
-        setUpClickHandler();
-        setUpRadioButtonHandler();
-        setUpKeyHandler();
-        $(window).on('resize', resize);
-    }
-
-    function setUpClickHandler() {
-        // click handler for "selectable" objects
-        $(document).on('click', '.select-object', function () {
-            // when any object of class "select-object" is clicked...
-            var obj = network.lookup[$(this).data('id')];
-            if (obj) {
-                selectObject(obj);
-            }
-            // stop propagation of event (I think) ...
-            return false;
+    // set the size of the SVG layer (or other element) to that of the view
+    function setSize(view, el) {
+        var thing = el || svg;
+        thing.attr({
+            width: view.width(),
+            height: view.height()
         });
     }
 
-    function setUpRadioButtonHandler() {
-        d3.selectAll('#displayModes .radio').on('click', function () {
-            var id = d3.select(this).attr('id');
-            if (id !== viewMode) {
-                radioButton('displayModes', id);
-                viewMode = id;
-                doRadioAction(id);
-            }
-        });
-    }
-
-    function doRadioAction(id) {
+    function doRadio(view, id) {
         showAllLayers();
         if (id === 'showPkt') {
             showPacketLayer();
@@ -206,1014 +106,68 @@
     }
 
     function showAllLayers() {
-        network.node.classed('inactive', false);
-        network.link.classed('inactive', false);
-        d3.selectAll('svg .port').classed('inactive', false)
-        d3.selectAll('svg .portText').classed('inactive', false)
+//        network.node.classed('inactive', false);
+//        network.link.classed('inactive', false);
+//        d3.selectAll('svg .port').classed('inactive', false);
+//        d3.selectAll('svg .portText').classed('inactive', false);
+        alert('show all layers');
     }
 
     function showPacketLayer() {
-        network.node.each(function(d) {
-            // deactivate nodes that are not hosts or switches
-            if (d.class === 'device' && d.type !== 'switch') {
-                d3.select(this).classed('inactive', true);
-            }
-        });
-
-        network.link.each(function(lnk) {
-            // deactivate infrastructure links that have opt's as endpoints
-            if (lnk.source.type === 'roadm' || lnk.target.type === 'roadm') {
-                d3.select(this).classed('inactive', true);
-            }
-        });
-
-        // deactivate non-packet ports
-        d3.selectAll('svg .optPort').classed('inactive', true)
+        alert('show packet layer');
     }
 
     function showOpticalLayer() {
-        network.node.each(function(d) {
-            // deactivate nodes that are not optical devices
-            if (d.type !== 'roadm') {
-                d3.select(this).classed('inactive', true);
-            }
-        });
-
-        network.link.each(function(lnk) {
-            // deactivate infrastructure links that have opt's as endpoints
-            if (lnk.source.type !== 'roadm' || lnk.target.type !== 'roadm') {
-                d3.select(this).classed('inactive', true);
-            }
-        });
-
-        // deactivate non-packet ports
-        d3.selectAll('svg .pktPort').classed('inactive', true)
+        alert('show optical layer');
     }
 
-    function setUpKeyHandler() {
-        d3.select('body')
-            .on('keydown', function () {
-                processKeyEvent();
-                if (debug('showKeyHandler')) {
-                    network.svg.append('text')
-                        .attr('x', 5)
-                        .attr('y', 15)
-                        .style('font-size', '20pt')
-                        .text('keyCode: ' + d3.event.keyCode +
-                            ' applied to : ' + contextLabel())
-                        .transition().duration(2000)
-                        .style('font-size', '2pt')
-                        .style('fill-opacity', 0.01)
-                        .remove();
-                }
-            });
-    }
+    // ==============================
+    // View life-cycle callbacks
 
-    function contextLabel() {
-        return hovered === null ? "(nothing)" : hovered.id;
-    }
+    function preload(view, ctx) {
+        var w = view.width(),
+            h = view.height(),
+            idBg = view.uid('bg'),
+            showBg = config.options.showBackground ? 'visible' : 'hidden';
 
-    function radioButton(group, id) {
-        d3.selectAll("#" + group + " .radio").classed("active", false);
-        d3.select("#" + group + " #" + id).classed("active", true);
-    }
-
-    function processKeyEvent() {
-        var code = d3.event.keyCode;
-        switch (code) {
-            case 66:    // B
-                toggleBackground();
-                break;
-            case 71:    // G
-                cycleLayout();
-                break;
-            case 76:    // L
-                cycleLabels();
-                break;
-            case 80:    // P
-                togglePorts();
-                break;
-            case 85:    // U
-                unpin();
-                break;
-        }
-
-    }
-
-    function toggleBackground() {
-        var bg = d3.select('#bg'),
-            vis = bg.style('visibility'),
-            newvis = (vis === 'hidden') ? 'visible' : 'hidden';
-        bg.style('visibility', newvis);
-    }
-
-    function cycleLayout() {
-        config.options.layering = !config.options.layering;
-        network.force.resume();
-    }
-
-    function cycleLabels() {
-        console.log('Cycle Labels - context = ' + contextLabel());
-    }
-
-    function togglePorts() {
-        portLabelsOn = !portLabelsOn;
-        var portVis = portLabelsOn ? 'visible' : 'hidden';
-        d3.selectAll('.port').style('visibility', portVis);
-        d3.selectAll('.portText').style('visibility', portVis);
-    }
-
-    function unpin() {
-        if (hovered) {
-            hovered.fixed = false;
-            findNodeFromData(hovered).classed('fixed', false);
-            network.force.resume();
-        }
-        console.log('Unpin - context = ' + contextLabel());
-    }
-
-
-    // ========================================================
-
-    function drawNetwork() {
-        $('#view').empty();
-
-        prepareNodesAndLinks();
-        createLayout();
-        console.log("\n\nHere is the augmented network object...");
-        console.log(network);
-    }
-
-    function prepareNodesAndLinks() {
-        network.lookup = {};
-        network.nodes = [];
-        network.links = [];
-
-        var nw = network.forceWidth,
-            nh = network.forceHeight;
-
-        function yPosConstraintForNode(n) {
-            return config.constraints.ypos[n.type || 'host'];
-        }
-
-        // Note that both 'devices' and 'hosts' get mapped into the nodes array
-
-        // first, the devices...
-        network.data.devices.forEach(function(n) {
-            var ypc = yPosConstraintForNode(n),
-                ix = Math.random() * 0.6 * nw + 0.2 * nw,
-                iy = ypc * nh,
-                node = {
-                    id: n.id,
-                    labels: n.labels,
-                    class: 'device',
-                    icon: 'device',
-                    type: n.type,
-                    x: ix,
-                    y: iy,
-                    constraint: {
-                        weight: 0.7,
-                        y: iy
-                    }
-                };
-            network.lookup[n.id] = node;
-            network.nodes.push(node);
-        });
-
-        // then, the hosts...
-        network.data.hosts.forEach(function(n) {
-            var ypc = yPosConstraintForNode(n),
-                ix = Math.random() * 0.6 * nw + 0.2 * nw,
-                iy = ypc * nh,
-                node = {
-                    id: n.id,
-                    labels: n.labels,
-                    class: 'host',
-                    icon: 'host',
-                    type: n.type,
-                    x: ix,
-                    y: iy,
-                    constraint: {
-                        weight: 0.7,
-                        y: iy
-                    }
-                };
-            network.lookup[n.id] = node;
-            network.nodes.push(node);
-        });
-
-
-        // now, process the explicit links...
-        network.data.links.forEach(function(lnk) {
-            var src = network.lookup[lnk.src],
-                dst = network.lookup[lnk.dst],
-                id = src.id + "-" + dst.id;
-
-            var link = {
-                class: 'infra',
-                id: id,
-                type: lnk.type,
-                width: lnk.linkWidth,
-                source: src,
-                srcPort: lnk.srcPort,
-                target: dst,
-                tgtPort: lnk.dstPort,
-                strength: config.force.linkStrength.infra
-            };
-            network.links.push(link);
-        });
-
-        // finally, infer host links...
-        network.data.hosts.forEach(function(n) {
-            var src = network.lookup[n.id],
-                dst = network.lookup[n.cp.device],
-                id = src.id + "-" + dst.id;
-
-            var link = {
-                class: 'host',
-                id: id,
-                type: 'hostLink',
-                width: config.hostLinkWidth,
-                source: src,
-                target: dst,
-                strength: config.force.linkStrength.host
-            };
-            network.links.push(link);
-        });
-    }
-
-    function createLayout() {
-
-        var cfg = config.force;
-
-        network.force = d3.layout.force()
-            .size([network.forceWidth, network.forceHeight])
-            .nodes(network.nodes)
-            .links(network.links)
-            .linkStrength(function(d) { return cfg.linkStrength[d.class]; })
-            .linkDistance(function(d) { return cfg.linkDistance[d.class]; })
-            .charge(function(d) { return cfg.charge[d.class]; })
-            .on('tick', tick);
-
-        network.svg = d3.select('#view').append('svg')
-            .attr('width', view.width)
-            .attr('height', view.height)
-            .append('g')
+        // NOTE: view.$div is a D3 selection of the view's div
+        svg = view.$div.append('svg');
+        setSize(view);
+        svg.append('g')
             .attr('transform', config.force.translate());
-//            .attr('id', 'zoomable')
-//            .call(d3.behavior.zoom().on("zoom", zoomRedraw));
 
-        network.svg.append('svg:image')
+        // load the background image
+        bgImg = svg.append('svg:image')
             .attr({
-                id: 'bg',
-                width: view.width,
-                height: view.height,
+                id: idBg,
+                width: w,
+                height: h,
                 'xlink:href': config.backgroundUrl
             })
-            .style('visibility',
-                    config.options.loadBackground ? 'visible' : 'hidden');
-
-//        function zoomRedraw() {
-//            d3.select("#zoomable").attr("transform",
-//                    "translate(" + d3.event.translate + ")"
-//                    + " scale(" + d3.event.scale + ")");
-//        }
-
-        // TODO: move glow/blur stuff to util script
-        var glow = network.svg.append('filter')
-            .attr('x', '-50%')
-            .attr('y', '-50%')
-            .attr('width', '200%')
-            .attr('height', '200%')
-            .attr('id', 'blue-glow');
-
-        glow.append('feColorMatrix')
-            .attr('type', 'matrix')
-            .attr('values', '0 0 0 0  0 ' +
-                '0 0 0 0  0 ' +
-                '0 0 0 0  .7 ' +
-                '0 0 0 1  0 ');
-
-        glow.append('feGaussianBlur')
-            .attr('stdDeviation', 3)
-            .attr('result', 'coloredBlur');
-
-        glow.append('feMerge').selectAll('feMergeNode')
-            .data(['coloredBlur', 'SourceGraphic'])
-            .enter().append('feMergeNode')
-            .attr('in', String);
-
-        // TODO: legend (and auto adjust on scroll)
-//        $('#view').on('scroll', function() {
-//
-//        });
-
-
-        // TODO: move drag behavior into separate method.
-        // == define node drag behavior...
-        network.draggedThreshold = d3.scale.linear()
-            .domain([0, 0.1])
-            .range([5, 20])
-            .clamp(true);
-
-        function dragged(d) {
-            var threshold = network.draggedThreshold(network.force.alpha()),
-                dx = d.oldX - d.px,
-                dy = d.oldY - d.py;
-            if (Math.abs(dx) >= threshold || Math.abs(dy) >= threshold) {
-                d.dragged = true;
-            }
-            return d.dragged;
-        }
-
-        network.drag = d3.behavior.drag()
-            .origin(function(d) { return d; })
-            .on('dragstart', function(d) {
-                d.oldX = d.x;
-                d.oldY = d.y;
-                d.dragged = false;
-                d.fixed |= 2;
-            })
-            .on('drag', function(d) {
-                d.px = d3.event.x;
-                d.py = d3.event.y;
-                if (dragged(d)) {
-                    if (!network.force.alpha()) {
-                        network.force.alpha(.025);
-                    }
-                }
-            })
-            .on('dragend', function(d) {
-                if (!dragged(d)) {
-                    selectObject(d, this);
-                }
-                d.fixed &= ~6;
-
-                // once we've finished moving, pin the node in position,
-                // if it is a device (not a host)
-                if (d.class === 'device') {
-                    d.fixed = true;
-                    d3.select(this).classed('fixed', true)
-                }
+            .style({
+                visibility: showBg
             });
-
-        $('#view').on('click', function(e) {
-            if (!$(e.target).closest('.node').length) {
-                deselectObject();
-            }
-        });
-
-        // ...............................................................
-
-        // add links to the display
-        network.link = network.svg.append('g').attr('id', 'links')
-            .selectAll('.link')
-            .data(network.force.links(), function(d) {return d.id})
-            .enter().append('line')
-            .attr('class', function(d) {return 'link ' + d.class});
-
-        network.linkSrcPort = network.svg.append('g')
-            .attr({
-                id: 'srcPorts',
-                class: 'portLayer'
-            });
-        network.linkTgtPort = network.svg.append('g')
-            .attr({
-                id: 'tgtPorts',
-                class: 'portLayer'
-            });
-
-        var portVis = portLabelsOn ? 'visible' : 'hidden',
-            pw = config.labels.port.width,
-            ph = config.labels.port.height;
-
-        network.link.filter('.infra').each(function(d) {
-            var srcType = d.source.type === 'roadm' ? 'optPort' : 'pktPort',
-                tgtType = d.target.type === 'roadm' ? 'optPort' : 'pktPort';
-
-            if (d.source.type)
-
-            network.linkSrcPort.append('rect').attr({
-                id: 'srcPort-' + safeId(d.id),
-                class: 'port ' + srcType,
-                width: pw,
-                height: ph,
-                rx: 4,
-                ry: 4
-            }).style('visibility', portVis);
-
-            network.linkTgtPort.append('rect').attr({
-                id: 'tgtPort-' + safeId(d.id),
-                class: 'port ' + tgtType,
-                width: pw,
-                height: ph,
-                rx: 4,
-                ry: 4
-            }).style('visibility', portVis);
-
-            network.linkSrcPort.append('text').attr({
-                id: 'srcText-' + safeId(d.id),
-                class: 'portText ' + srcType
-            }).text(d.srcPort)
-                .style('visibility', portVis);
-
-            network.linkTgtPort.append('text').attr({
-                id: 'tgtText-' + safeId(d.id),
-                class: 'portText ' + tgtType
-            }).text(d.tgtPort)
-                .style('visibility', portVis);
-        });
-
-        // ...............................................................
-
-        // add nodes to the display
-        network.node = network.svg.selectAll('.node')
-            .data(network.force.nodes(), function(d) {return d.id})
-            .enter().append('g')
-            .attr('class', function(d) {
-                var cls = 'node ' + d.class;
-                if (d.type) {
-                    cls += ' ' + d.type;
-                }
-                return cls;
-            })
-            .attr('transform', function(d) {
-                return translate(d.x, d.y);
-            })
-            .call(network.drag)
-            .on('mouseover', function(d) {
-                // TODO: show tooltip
-                if (network.mouseoutTimeout) {
-                    clearTimeout(network.mouseoutTimeout);
-                    network.mouseoutTimeout = null;
-                }
-                hoverObject(d);
-            })
-            .on('mouseout', function(d) {
-                // TODO: hide tooltip
-                if (network.mouseoutTimeout) {
-                    clearTimeout(network.mouseoutTimeout);
-                    network.mouseoutTimeout = null;
-                }
-                network.mouseoutTimeout = setTimeout(function() {
-                    hoverObject(null);
-                }, config.mouseOutTimerDelayMs);
-            });
-
-
-        // deal with device nodes first
-        network.nodeRect = network.node.filter('.device')
-            .append('rect')
-            .attr({
-                rx: 5,
-                ry: 5,
-                width: 100,
-                height: 12
-            });
-            // note that width/height are adjusted to fit the label text
-            // then padded, and space made for the icon.
-
-        network.node.filter('.device').each(function(d) {
-            var node = d3.select(this),
-                icon = iconUrl(d);
-
-            node.append('text')
-            // TODO: add label cycle behavior
-                .text(d.id)
-                .attr('dy', '1.1em');
-
-            if (icon) {
-                var cfg = config.icons;
-                node.append('svg:image')
-                    .attr({
-                        width: cfg.w,
-                        height: cfg.h,
-                        'xlink:href': icon
-                    });
-                // note, icon relative positioning (x,y) is done after we have
-                // adjusted the bounds of the rectangle...
-            }
-
-            // debug function to show the modelled x,y coordinates of nodes...
-            if (debug('showNodeXY')) {
-                node.select('rect').attr('fill-opacity', 0.5);
-                node.append('circle')
-                    .attr({
-                        class: 'debug',
-                        cx: 0,
-                        cy: 0,
-                        r: '3px'
-                    });
-            }
-        });
-
-        // now process host nodes
-        network.nodeCircle = network.node.filter('.host')
-            .append('circle')
-            .attr({
-                r: config.hostRadius
-            });
-
-        network.node.filter('.host').each(function(d) {
-            var node = d3.select(this),
-                icon = iconUrl(d);
-
-            // debug function to show the modelled x,y coordinates of nodes...
-            if (debug('showNodeXY')) {
-                node.select('circle').attr('fill-opacity', 0.5);
-                node.append('circle')
-                    .attr({
-                        class: 'debug',
-                        cx: 0,
-                        cy: 0,
-                        r: '3px'
-                    });
-            }
-        });
-
-        // this function is scheduled to happen soon after the given thread ends
-        setTimeout(function() {
-            var lab = config.labels,
-                portGap = lab.port.gap,
-                midW = portGap + lab.port.width/ 2,
-                midH = portGap + lab.port.height / 2;
-
-            // post process the device nodes, to pad their size to fit the
-            // label text and attach the icon to the right location.
-            network.node.filter('.device').each(function(d) {
-                // for every node, recompute size, padding, etc. so text fits
-                var node = d3.select(this),
-                    text = node.select('text'),
-                    box = adjustRectToFitText(node);
-
-                // now make the computed adjustment
-                node.select('rect')
-                    .attr(box);
-
-                node.select('image')
-                    .attr('x', box.x + config.icons.xoff)
-                    .attr('y', box.y + config.icons.yoff);
-
-                var bounds = boundsFromBox(box),
-                    portBounds = {
-                        x1: bounds.x1 - midW,
-                        x2: bounds.x2 + midW,
-                        y1: bounds.y1 - midH,
-                        y2: bounds.y2 + midH
-                    };
-
-                // todo: clean up extent and edge work..
-                d.extent = {
-                    left: bounds.x1 - lab.marginLR,
-                    right: bounds.x2 + lab.marginLR,
-                    top: bounds.y1 - lab.marginTB,
-                    bottom: bounds.y2 + lab.marginTB
-                };
-
-                d.edge = {
-                    left   : new geo.LineSegment(bounds.x1, bounds.y1, bounds.x1, bounds.y2),
-                    right  : new geo.LineSegment(bounds.x2, bounds.y1, bounds.x2, bounds.y2),
-                    top    : new geo.LineSegment(bounds.x1, bounds.y1, bounds.x2, bounds.y1),
-                    bottom : new geo.LineSegment(bounds.x1, bounds.y2, bounds.x2, bounds.y2)
-                };
-
-                d.portEdge = {
-                    left   : new geo.LineSegment(
-                        portBounds.x1, portBounds.y1, portBounds.x1, portBounds.y2
-                    ),
-                    right  : new geo.LineSegment(
-                        portBounds.x2, portBounds.y1, portBounds.x2, portBounds.y2
-                    ),
-                    top    : new geo.LineSegment(
-                        portBounds.x1, portBounds.y1, portBounds.x2, portBounds.y1
-                    ),
-                    bottom : new geo.LineSegment(
-                        portBounds.x1, portBounds.y2, portBounds.x2, portBounds.y2
-                    )
-                };
-
-            });
-
-            network.numTicks = 0;
-            network.preventCollisions = false;
-            network.force.start();
-            for (var i = 0; i < config.force.ticksWithoutCollisions; i++) {
-                network.force.tick();
-            }
-            network.preventCollisions = true;
-            $('#view').css('visibility', 'visible');
-        });
-
-
-        // returns the newly computed bounding box of the rectangle
-        function adjustRectToFitText(n) {
-            var text = n.select('text'),
-                box = text.node().getBBox(),
-                lab = config.labels;
-
-            // not sure why n.data() returns an array of 1 element...
-            var data = n.data()[0];
-
-            text.attr('text-anchor', 'middle')
-                .attr('y', '-0.8em')
-                .attr('x', lab.imgPad/2)
-            ;
-
-            // translate the bbox so that it is centered on [x,y]
-            box.x = -box.width / 2;
-            box.y = -box.height / 2;
-
-            // add padding
-            box.x -= (lab.padLR + lab.imgPad/2);
-            box.width += lab.padLR * 2 + lab.imgPad;
-            box.y -= lab.padTB;
-            box.height += lab.padTB * 2;
-
-            return box;
-        }
-
-        function boundsFromBox(box) {
-            return {
-                x1: box.x,
-                y1: box.y,
-                x2: box.x + box.width,
-                y2: box.y + box.height
-            };
-        }
-
-    }
-
-    function iconUrl(d) {
-        return 'img/' + d.type + '.png';
-//        return config.iconUrl[d.icon];
-    }
-
-    function translate(x, y) {
-        return 'translate(' + x + ',' + y + ')';
-    }
-
-    // prevents collisions amongst device nodes
-    function preventCollisions() {
-        var quadtree = d3.geom.quadtree(network.nodes),
-            hrad = config.hostRadius;
-
-        network.nodes.forEach(function(n) {
-            var nx1, nx2, ny1, ny2;
-
-            if (n.class === 'device') {
-                nx1 = n.x + n.extent.left;
-                nx2 = n.x + n.extent.right;
-                ny1 = n.y + n.extent.top;
-                ny2 = n.y + n.extent.bottom;
-
-            } else {
-                nx1 = n.x - hrad;
-                nx2 = n.x + hrad;
-                ny1 = n.y - hrad;
-                ny2 = n.y + hrad;
-            }
-
-            quadtree.visit(function(quad, x1, y1, x2, y2) {
-                if (quad.point && quad.point !== n) {
-                    // check if the rectangles/circles intersect
-                    var p = quad.point,
-                        px1, px2, py1, py2, ix;
-
-                    if (p.class === 'device') {
-                        px1 = p.x + p.extent.left;
-                        px2 = p.x + p.extent.right;
-                        py1 = p.y + p.extent.top;
-                        py2 = p.y + p.extent.bottom;
-
-                    } else {
-                        px1 = p.x - hrad;
-                        px2 = p.x + hrad;
-                        py1 = p.y - hrad;
-                        py2 = p.y + hrad;
-                    }
-
-                    ix = (px1 <= nx2 && nx1 <= px2 && py1 <= ny2 && ny1 <= py2);
-
-                    if (ix) {
-                        var xa1 = nx2 - px1, // shift n left , p right
-                            xa2 = px2 - nx1, // shift n right, p left
-                            ya1 = ny2 - py1, // shift n up   , p down
-                            ya2 = py2 - ny1, // shift n down , p up
-                            adj = Math.min(xa1, xa2, ya1, ya2);
-
-                        if (adj == xa1) {
-                            n.x -= adj / 2;
-                            p.x += adj / 2;
-                        } else if (adj == xa2) {
-                            n.x += adj / 2;
-                            p.x -= adj / 2;
-                        } else if (adj == ya1) {
-                            n.y -= adj / 2;
-                            p.y += adj / 2;
-                        } else if (adj == ya2) {
-                            n.y += adj / 2;
-                            p.y -= adj / 2;
-                        }
-                    }
-                    return ix;
-                }
-            });
-
-        });
-    }
-
-    function tick(e) {
-        network.numTicks++;
-
-        if (config.options.layering) {
-            // adjust the y-coord of each node, based on y-pos constraints
-            network.nodes.forEach(function (n) {
-                var z = e.alpha * n.constraint.weight;
-                if (!isNaN(n.constraint.y)) {
-                    n.y = (n.constraint.y * z + n.y * (1 - z));
-                }
-            });
-        }
-
-        if (config.options.collisionPrevention && network.preventCollisions) {
-            preventCollisions();
-        }
-
-        var portHalfW = config.labels.port.width / 2,
-            portHalfH = config.labels.port.height / 2;
-
-        // clip visualization of links at bounds of nodes...
-        network.link.each(function(d) {
-            var xs = d.source.x,
-                ys = d.source.y,
-                xt = d.target.x,
-                yt = d.target.y,
-                line = new geo.LineSegment(xs, ys, xt, yt),
-                e, ix,
-                exs, eys, ext, eyt,
-                pxs, pys, pxt, pyt;
-
-            if (d.class === 'host') {
-                // no adjustment for source end of link, since hosts are dots
-                exs = xs;
-                eys = ys;
-
-            } else {
-                for (e in d.source.edge) {
-                    ix = line.intersect(d.source.edge[e].offset(xs, ys));
-                    if (ix.in1 && ix.in2) {
-                        exs = ix.x;
-                        eys = ix.y;
-
-                        // also pick off the port label intersection
-                        ix = line.intersect(d.source.portEdge[e].offset(xs, ys));
-                        pxs = ix.x;
-                        pys = ix.y;
-                        break;
-                    }
-                }
-            }
-
-            for (e in d.target.edge) {
-                ix = line.intersect(d.target.edge[e].offset(xt, yt));
-                if (ix.in1 && ix.in2) {
-                    ext = ix.x;
-                    eyt = ix.y;
-
-                    // also pick off the port label intersection
-                    ix = line.intersect(d.target.portEdge[e].offset(xt, yt));
-                    pxt = ix.x;
-                    pyt = ix.y;
-                    break;
-                }
-            }
-
-            // adjust the endpoints of the link's line to match rectangles
-            var sid = safeId(d.id);
-            d3.select(this)
-                .attr('x1', exs)
-                .attr('y1', eys)
-                .attr('x2', ext)
-                .attr('y2', eyt);
-
-            d3.select('#srcPort-' + sid)
-                .attr('x', pxs - portHalfW)
-                .attr('y', pys - portHalfH);
-
-            d3.select('#tgtPort-' + sid)
-                .attr('x', pxt - portHalfW)
-                .attr('y', pyt - portHalfH);
-
-            // TODO: fit label rect to size of port number.
-            d3.select('#srcText-' + sid)
-                .attr('x', pxs - 5)
-                .attr('y', pys + 3);
-
-            d3.select('#tgtText-' + sid)
-                .attr('x', pxt - 5)
-                .attr('y', pyt + 3);
-
-        });
-
-        // position each node by translating the node (group) by x,y
-        network.node
-            .attr('transform', function(d) {
-                return translate(d.x, d.y);
-            });
-
-    }
-
-    //    $('#docs-close').on('click', function() {
-    //        deselectObject();
-    //        return false;
-    //    });
-
-    //    $(document).on('click', '.select-object', function() {
-    //        var obj = graph.data[$(this).data('name')];
-    //        if (obj) {
-    //            selectObject(obj);
-    //        }
-    //        return false;
-    //    });
-
-    function findNodeFromData(d) {
-        var el = null;
-        network.node.filter('.' + d.class).each(function(n) {
-            if (n.id === d.id) {
-                el = d3.select(this);
-            }
-        });
-        return el;
-    }
-
-    function selectObject(obj, el) {
-        var node;
-        if (el) {
-            node = d3.select(el);
-        } else {
-            network.node.each(function(d) {
-                if (d == obj) {
-                    node = d3.select(el = this);
-                }
-            });
-        }
-        if (!node) return;
-
-        if (node.classed('selected')) {
-            deselectObject();
-            flyinPane(null);
-            return;
-        }
-        deselectObject(false);
-
-        selected = {
-            obj : obj,
-            el  : el
-        };
-
-        node.classed('selected', true);
-        flyinPane(obj);
-    }
-
-    function deselectObject(doResize) {
-        // Review: logic of 'resize(...)' function.
-        if (doResize || typeof doResize == 'undefined') {
-            resize(false);
-        }
-
-        // deselect all nodes in the network...
-        network.node.classed('selected', false);
-        selected = {};
-        flyinPane(null);
-    }
-
-    function flyinPane(obj) {
-        var pane = d3.select('#flyout'),
-            url;
-
-        if (obj) {
-            // go get details of the selected object from the server...
-            url = detailJsonUrl(obj.id);
-            d3.json(url, function (err, data) {
-                if (err) {
-                    alert('Oops! Error reading JSON...\n\n' +
-                        'URL: ' + url + '\n\n' +
-                        'Error: ' + err.message);
-                    return;
-                }
-//                console.log("JSON data... " + url);
-//                console.log(data);
-
-                displayDetails(data, pane);
-            });
-
-        } else {
-            // hide pane
-            pane.transition().duration(750)
-                .style('right', '-320px')
-                .style('opacity', 0.0);
-        }
-    }
-
-    function displayDetails(data, pane) {
-        $('#flyout').empty();
-
-        var title = pane.append("h2"),
-            table = pane.append("table"),
-            tbody = table.append("tbody");
-
-        $('<img src="img/' + data.type + '.png">').appendTo(title);
-        $('<span>').attr('class', 'icon').text(data.id).appendTo(title);
-
-
-        // TODO: consider using d3 data bind to TR/TD
-
-        data.propOrder.forEach(function(p) {
-            if (p === '-') {
-                addSep(tbody);
-            } else {
-                addProp(tbody, p, data.props[p]);
-            }
-        });
-
-        function addSep(tbody) {
-            var tr = tbody.append('tr');
-            $('<hr>').appendTo(tr.append('td').attr('colspan', 2));
-        }
-
-        function addProp(tbody, label, value) {
-            var tr = tbody.append('tr');
-
-            tr.append('td')
-                .attr('class', 'label')
-                .text(label + ' :');
-
-            tr.append('td')
-                .attr('class', 'value')
-                .text(value);
-        }
-
-        // show pane
-        pane.transition().duration(750)
-            .style('right', '20px')
-            .style('opacity', 1.0);
-    }
-
-    function highlightObject(obj) {
-        if (obj) {
-            if (obj != highlighted) {
-                // TODO set or clear "inactive" class on nodes, based on criteria
-                network.node.classed('inactive', function(d) {
-                    //                return (obj !== d &&
-                    //                    d.relation(obj.id));
-                    return (obj !== d);
-                });
-                // TODO: same with links
-                network.link.classed('inactive', function(d) {
-                    return (obj !== d.source && obj !== d.target);
-                });
-            }
-            highlighted = obj;
-        } else {
-            if (highlighted) {
-                // clear the inactive flag (no longer suppressed visually)
-                network.node.classed('inactive', false);
-                network.link.classed('inactive', false);
-            }
-            highlighted = null;
-
-        }
-    }
-
-    function hoverObject(obj) {
-        if (obj) {
-            hovered = obj;
-        } else {
-            if (hovered) {
-                hovered = null;
-            }
-        }
     }
 
 
-    function resize() {
-        view.height = window.innerHeight - config.mastHeight;
-        view.width = window.innerWidth;
-        $('#view')
-            .css('height', view.height + 'px')
-            .css('width', view.width + 'px');
+    function load(view, ctx) {
+        view.setRadio(btnSet, doRadio);
 
-        network.forceWidth = view.width - config.force.marginLR;
-        network.forceHeight = view.height - config.force.marginTB;
     }
 
-    // ======================================================================
-    // register with the UI framework
+    function resize(view, ctx) {
+        setSize(view);
+        setSize(view, bgImg);
+    }
+
+
+    // ==============================
+    // View registration
 
     onos.ui.addView('topo', {
-        load: loadNetworkView
+        preload: preload,
+        load: load,
+        resize: resize
     });
 
-
 }(ONOS));
-
