diff --git a/web/ons-demo/js/app.js b/web/ons-demo/js/app.js
index 5c92490..f7eb5b4 100644
--- a/web/ons-demo/js/app.js
+++ b/web/ons-demo/js/app.js
@@ -1,1206 +1,9 @@
 /*global d3, document∆*/
 
-d3.selection.prototype.moveToFront = function() {
-  return this.each(function(){
-    this.parentNode.appendChild(this);
-  });
-};
-
-var line = d3.svg.line()
-    .x(function(d) {
-    	return d.x;
-    })
-    .y(function(d) {
-    	return d.y;
-    });
-
-var model;
-var svg;
-var updateTopology;
-var pendingLinks = {};
-var selectedFlows = [];
-
-var pendingTimeout = 30000;
-
-var colors = [
-	'color1',
-	'color2',
-	'color3',
-	'color4',
-	'color7',
-	'color8',
-	'color9',
-//	'color11',
-	'color12'
-];
-colors.reverse();
-
-var controllerColorMap = {};
-
-function setPending(selection) {
-	selection.classed('pending', false);
-	setTimeout(function () {
-		selection.classed('pending', true);
-	})
-}
-
-function createTopologyView() {
-
-	window.addEventListener('resize', function () {
-		// this is too slow. instead detect first resize event and hide the paths that have explicit matrix applied
-		// either that or is it possible to position the paths so they get the automatic transform as well?
-//		updateTopology();
-	});
-
-	var svg = d3.select('#svg-container').append('svg:svg');
-
-	svg.append("svg:defs").append("svg:marker")
-	    .attr("id", "arrow")
-	    .attr("viewBox", "0 -5 10 10")
-	    .attr("refX", -1)
-	    .attr("markerWidth", 5)
-	    .attr("markerHeight", 5)
-	    .attr("orient", "auto")
-	  .append("svg:path")
-	    .attr("d", "M0,-3L10,0L0,3");
-
-	return svg.append('svg:svg').attr('id', 'viewBox').attr('viewBox', '0 0 1000 1000').attr('preserveAspectRatio', 'none').
-			attr('id', 'viewbox').append('svg:g').attr('transform', 'translate(500 500)');
-}
-
-function updateSelectedFlowsTopology() {
-	// DRAW THE FLOWS
-	var topologyFlows = [];
-	selectedFlows.forEach(function (flow) {
-		if (flow) {
-			topologyFlows.push(flow);
-		}
-	});
-
-	var flows = d3.select('svg').selectAll('.flow').data(topologyFlows);
-
-	flows.enter().append("svg:path").attr('class', 'flow')
-		.attr('stroke-dasharray', '4, 10')
-		.append('svg:animate')
-		.attr('attributeName', 'stroke-dashoffset')
-		.attr('attributeType', 'xml')
-		.attr('from', '500')
-		.attr('to', '-500')
-		.attr('dur', '20s')
-		.attr('repeatCount', 'indefinite');
-
-	flows.exit().remove();
-
-	flows.attr('d', function (d) {
-			if (!d) {
-				return;
-			}
-			var pts = [];
-			if (!d.dataPath.flowEntries) {
-				// create a temporary vector to indicate the pending flow
-				var s1 = d3.select(document.getElementById(d.srcDpid));
-				var s2 = d3.select(document.getElementById(d.dstDpid));
-
-				var pt1 = document.querySelector('svg').createSVGPoint();
-				pt1.x = s1.attr('x');
-				pt1.y = s1.attr('y');
-				pt1 = pt1.matrixTransform(s1[0][0].getCTM());
-				pts.push(pt1);
-
-				var pt2 = document.querySelector('svg').createSVGPoint();
-				pt2.x = s2.attr('x');
-				pt2.y = s2.attr('y');
-				pt2 = pt2.matrixTransform(s2[0][0].getCTM());
-				pts.push(pt2);
-
-			} else {
-				d.dataPath.flowEntries.forEach(function (flowEntry) {
-					var s = d3.select(document.getElementById(flowEntry.dpid.value));
-					// s[0] is null if the flow entry refers to a non-existent switch
-					if (s[0][0]) {
-						var pt = document.querySelector('svg').createSVGPoint();
-						pt.x = s.attr('x');
-						pt.y = s.attr('y');
-						pt = pt.matrixTransform(s[0][0].getCTM());
-						pts.push(pt);
-					} else {
-						console.log('flow refers to non-existent switch: ' + flowEntry.dpid.value);
-					}
-				});
-			}
-			if (pts.length) {
-				return line(pts);
-			} else {
-				return "M0,0";
-			}
-		})
-		.attr('id', function (d) {
-			if (d) {
-				return makeFlowKey(d);
-			}
-		})
-		.classed('pending', function (d) {
-			return d && (d.createPending || d.deletePending);
-		});
-
-	// "marching ants"
-	flows.select('animate').attr('from', 500);
-
-}
-
-function updateSelectedFlowsTable() {
-	function rowEnter(d) {
-		var row = d3.select(this);
-		row.append('div').classed('deleteFlow', true);
-		row.append('div').classed('flowId', true);
-		row.append('div').classed('srcDPID', true);
-		row.append('div').classed('dstDPID', true);
-		row.append('div').classed('iperf', true);
-
-		row.select('.iperf')
-			.append('div')
-			.attr('class', 'iperf-container')
-			.append('svg:svg')
-			.attr('viewBox', '0 0 1000 32')
-			.attr('preserveAspectRatio', 'none')
-			.append('svg:g')
-			.append('svg:path')
-			.attr('class', 'iperfdata');
-
-		row.on('mouseover', function (d) {
-			if (d) {
-				var path = document.getElementById(makeFlowKey(d));
-				d3.select(path).classed('highlight', true);
-			}
-		});
-		row.on('mouseout', function (d) {
-			if (d) {
-				var path = document.getElementById(makeFlowKey(d));
-				d3.select(path).classed('highlight', false);
-			}
-		});
-	}
-
-	function rowUpdate(d) {
-		var row = d3.select(this);
-		row.attr('id', function (d) {
-			if (d) {
-				return makeSelectedFlowKey(d);
-			}
-		});
-
-		if (!d || !hasIPerf(d)) {
-			row.select('.iperfdata')
-				.attr('d', 'M0,0');
-		}
-
-		row.select('.deleteFlow').on('click', function () {
-			deselectFlow(d);
-		});
-		row.on('dblclick', function () {
-			if (d) {
-				var prompt = 'Delete flow ' + d.flowId + '?';
-				if (confirm(prompt)) {
-					deleteFlow(d);
-					d.deletePending = true;
-					updateSelectedFlows();
-
-					setTimeout(function () {
-						d.deletePending = false;
-						updateSelectedFlows();
-					}, pendingTimeout)
-				};
-			}
-		});
-
-		row.select('.flowId')
-			.text(function (d) {
-				if (d) {
-					if (d.flowId) {
-						return d.flowId;
-					} else {
-						return '0x--';
-					}
-				}
-			})
-			.classed('pending', function (d) {
-				return d && (d.createPending || d.deletePending);
-			});
-
-		row.select('.srcDPID')
-			.text(function (d) {
-				if (d) {
-					return d.srcDpid;
-				}
-			});
-
-		row.select('.dstDPID')
-			.text(function (d) {
-				if (d) {
-					return d.dstDpid;
-				}
-			});
-	}
-
-	var flows = d3.select('#selectedFlows')
-		.selectAll('.selectedFlow')
-		.data(selectedFlows);
-
-	flows.enter()
-		.append('div')
-		.classed('selectedFlow', true)
-		.each(rowEnter);
-
-	flows.each(rowUpdate);
-
-	flows.exit().remove();
-}
-
-// TODO: cancel the interval when the flow is desel
-function startIPerfForFlow(flow) {
-	var duration = 10000; // seconds
-	var interval = 100; // ms. this is defined by the server
-	var updateRate = 2000; // ms
-	var pointsToDisplay = 1000;
-
-	function makePoints() {
-		var pts = [];
-		var i;
-		for (i=0; i < pointsToDisplay; ++i) {
-			var sample = flow.iperfData.samples[i];
-			var height = 30 * sample/1000000;
-			if (height > 30)
-				height = 30;
-			pts.push({
-				x: i * 1000/(pointsToDisplay-1),
-				y: 32 - height
-			})
-		}
-		return pts;
-	}
-
-	if (flow.flowId) {
-		console.log('starting iperf for: ' + flow.flowId);
-		startIPerf(flow, duration, updateRate/interval);
-		flow.iperfDisplayInterval = setInterval(function () {
-			if (flow.iperfData) {
-				while (flow.iperfData.samples.length < pointsToDisplay) {
-					flow.iperfData.samples.push(0);
-				}
-				var iperfPath = d3.select(document.getElementById(makeSelectedFlowKey(flow))).select('path');
-				iperfPath.attr('d', line(makePoints()));
-				flow.iperfData.samples.shift();
-			}
-
-
-		}, interval);
-		flow.iperfFetchInterval = setInterval(function () {
-			getIPerfData(flow, function (data) {
-				try {
-					if (!flow.iperfData) {
-						flow.iperfData = {
-							samples: []
-						};
-						var i;
-						for (i = 0; i < pointsToDisplay; ++i) {
-							flow.iperfData.samples.push(0);
-						}
-					}
-
-					var iperfData = JSON.parse(data);
-
-//				console.log(iperfData.timestamp);
-
-					// if the data is fresh
-					if (flow.iperfData.timestamp && iperfData.timestamp != flow.iperfData.timestamp) {
-
-						while (flow.iperfData.samples.length > pointsToDisplay + iperfData.samples.length) {
-							flow.iperfData.samples.shift();
-						}
-
-						iperfData.samples.forEach(function (s) {
-							flow.iperfData.samples.push(s);
-						});
-					}
-					flow.iperfData.timestamp = iperfData.timestamp;
-				} catch (e) {
-					console.log('bad iperf data: ' + data);
-				}
-//				console.log(data);
-			});
-		}, updateRate/2); // over sample to avoid gaps
-	}
-}
-
-function updateSelectedFlows() {
-	// make sure that all of the selected flows are either
-	// 1) valid (meaning they are in the latest list of flows)
-	// 2) pending
-	if (model) {
-		var flowMap = {};
-		model.flows.forEach(function (flow) {
-			flowMap[makeFlowKey(flow)] = flow;
-		});
-
-		var newSelectedFlows = [];
-		selectedFlows.forEach(function (flow) {
-			if (flow) {
-				var liveFlow = flowMap[makeFlowKey(flow)];
-				if (liveFlow) {
-					newSelectedFlows.push(liveFlow);
-					liveFlow.deletePending = flow.deletePending;
-					liveFlow.iperfFetchInterval = flow.iperfFetchInterval;
-					liveFlow.iperfDisplayInterval = flow.iperfDisplayInterval;
-				} else if (flow.createPending) {
-					newSelectedFlows.push(flow);
-				} else if (hasIPerf(flow)) {
-					clearIPerf(flow);
-				}
-			}
-		});
-		selectedFlows = newSelectedFlows;
-	}
-	selectedFlows.forEach(function (flow) {
-		if (!hasIPerf(flow)) {
-			startIPerfForFlow(flow);
-		}
-	});
-	while (selectedFlows.length < 3) {
-		selectedFlows.push(null);
-	}
-
-	updateSelectedFlowsTable();
-	updateSelectedFlowsTopology();
-}
-
-function selectFlow(flow) {
-	var flowKey = makeFlowKey(flow);
-	var alreadySelected = false;
-	selectedFlows.forEach(function (f) {
-		if (f && makeFlowKey(f) === flowKey) {
-			alreadySelected = true;
-		}
-	});
-
-	if (!alreadySelected) {
-		selectedFlows.unshift(flow);
-		selectedFlows = selectedFlows.slice(0, 3);
-		updateSelectedFlows();
-	}
-}
-
-function hasIPerf(flow) {
-	return flow && flow.iperfFetchInterval;
-}
-
-function clearIPerf(flow) {
-	console.log('clearing iperf interval for: ' + flow.flowId);
-	clearInterval(flow.iperfFetchInterval);
-	delete flow.iperfFetchInterval;
-	clearInterval(flow.iperfDisplayInterval);
-	delete flow.iperfDisplayInterval;
-	delete flow.iperfData;
-}
-
-function deselectFlow(flow, ifCreatePending) {
-	var flowKey = makeFlowKey(flow);
-	var newSelectedFlows = [];
-	selectedFlows.forEach(function (flow) {
-		if (!flow ||
-				flowKey !== makeFlowKey(flow) ||
-				flowKey === makeFlowKey(flow) && ifCreatePending && !flow.createPending ) {
-			newSelectedFlows.push(flow);
-		} else {
-			if (hasIPerf(flow)) {
-				clearIPerf(flow);
-			}
-		}
-	});
-	selectedFlows = newSelectedFlows;
-	while (selectedFlows.length < 3) {
-		selectedFlows.push(null);
-	}
-
-	updateSelectedFlows();
-}
-
-function deselectFlowIfCreatePending(flow) {
-	deselectFlow(flow, true);
-}
-
-function showFlowChooser() {
-	function rowEnter(d) {
-		var row = d3.select(this);
-
-		row.append('div')
-			.classed('black-eye', true).
-			on('click', function () {
-				selectFlow(d);
-			});
-
-		row.append('div')
-			.classed('flowId', true)
-			.text(function (d) {
-				return d.flowId;
-			});
-
-		row.append('div')
-			.classed('srcDPID', true)
-			.text(function (d) {
-				return d.srcDpid;
-			});
-
-
-		row.append('div')
-			.classed('dstDPID', true)
-			.text(function (d) {
-				return d.dstDpid;
-			});
-
-	}
-
-	var flows = d3.select('#flowChooser')
-		.append('div')
-		.style('pointer-events', 'auto')
-		.selectAll('.selectedFlow')
-		.data(model.flows)
-		.enter()
-		.append('div')
-		.classed('selectedFlow', true)
-		.each(rowEnter);
-
-	setTimeout(function () {
-		d3.select(document.body).on('click', function () {
-			d3.select('#flowChooser').html('');
-			d3.select(document.body).on('click', null);
-		});
-	}, 0);
-}
-
-
-
-function updateHeader(model) {
-	d3.select('#lastUpdate').text(new Date());
-	d3.select('#activeSwitches').text(model.edgeSwitches.length + model.aggregationSwitches.length + model.coreSwitches.length);
-	d3.select('#activeFlows').text(model.flows.length);
-}
-
-function toRadians (angle) {
-  return angle * (Math.PI / 180);
-}
-
-var widths = {
-	edge: 6,
-	aggregation: 12,
-	core: 18
-}
-
-function createRingsFromModel(model) {
-	var rings = [{
-		radius: 3,
-		width: widths.edge,
-		switches: model.edgeSwitches,
-		className: 'edge',
-		angles: []
-	}, {
-		radius: 2.25,
-		width: widths.aggregation,
-		switches: model.aggregationSwitches,
-		className: 'aggregation',
-		angles: []
-	}, {
-		radius: 0.75,
-		width: widths.core,
-		switches: model.coreSwitches,
-		className: 'core',
-		angles: []
-	}];
-
-
-	var aggRanges = {};
-
-	// arrange edge switches at equal increments
-	var k = 360 / rings[0].switches.length;
-	rings[0].switches.forEach(function (s, i) {
-		var angle = k * i;
-
-		rings[0].angles[i] = angle;
-
-		// record the angle for the agg switch layout
-		var dpid = s.dpid.split(':');
-		dpid[7] = '01'; // the last component of the agg switch is always '01'
-		var aggdpid = dpid.join(':');
-		var aggRange = aggRanges[aggdpid];
-		if (!aggRange) {
-			aggRange = aggRanges[aggdpid] = {};
-			aggRange.min = aggRange.max = angle;
-		} else {
-			aggRange.max = angle;
-		}
-	});
-
-	// arrange aggregation switches to "fan out" to edge switches
-	k = 360 / rings[1].switches.length;
-	rings[1].switches.forEach(function (s, i) {
-//		rings[1].angles[i] = k * i;
-		var range = aggRanges[s.dpid];
-
-		rings[1].angles[i] = (range.min + range.max)/2;
-	});
-
-	// find the association between core switches and aggregation switches
-	var aggregationSwitchMap = {};
-	model.aggregationSwitches.forEach(function (s, i) {
-		aggregationSwitchMap[s.dpid] = i;
-	});
-
-	// put core switches next to linked aggregation switches
-	k = 360 / rings[2].switches.length;
-	rings[2].switches.forEach(function (s, i) {
-//		rings[2].angles[i] = k * i;
-		var associatedAggregationSwitches = model.configuration.association[s.dpid];
-		// TODO: go between if there are multiple
-		var index = aggregationSwitchMap[associatedAggregationSwitches[0]];
-
-		rings[2].angles[i] = rings[1].angles[index];
-	});
-
-	// TODO: construct this form initially rather than converting. it works better because
-	// it allows binding by dpid
-	var testRings = [];
-	rings.forEach(function (ring) {
-		var testRing = [];
-		ring.switches.forEach(function (s, i) {
-			var testSwitch = {
-				dpid: s.dpid,
-				state: s.state,
-				radius: ring.radius,
-				width: ring.width,
-				className: ring.className,
-				angle: ring.angles[i],
-				controller: s.controller
-			};
-			testRing.push(testSwitch);
-		});
-
-
-		testRings.push(testRing);
-	});
-
-
-//	return rings;
-	return testRings;
-}
-
-function makeLinkKey(link) {
-	return link['src-switch'] + '=>' + link['dst-switch'];
-}
-
-function makeFlowKey(flow) {
-	return flow.srcDpid + '=>' + flow.dstDpid;
-}
-
-function makeSelectedFlowKey(flow) {
-	return 'S' + makeFlowKey(flow);
-}
-
-function createLinkMap(links) {
-	var linkMap = {};
-	links.forEach(function (link) {
-		var srcDPID = link['src-switch'];
-		var dstDPID = link['dst-switch'];
-
-		var srcMap = linkMap[srcDPID] || {};
-
-		srcMap[dstDPID] = link;
-
-		linkMap[srcDPID]  = srcMap;
-	});
-	return linkMap;
-}
-
-// removes links from the pending list that are now in the model
-function reconcilePendingLinks(model) {
-	var links = [];
-	model.links.forEach(function (link) {
-		links.push(link);
-		delete pendingLinks[makeLinkKey(link)]
-	})
-	var linkId;
-	for (linkId in pendingLinks) {
-		links.push(pendingLinks[linkId]);
-	}
-	return links
-}
-
-updateTopology = function() {
-
-	// DRAW THE SWITCHES
-	var rings = svg.selectAll('.ring').data(createRingsFromModel(model));
-
-	var links = reconcilePendingLinks(model);
-	var linkMap = createLinkMap(links);
-
-	function mouseOverSwitch(data) {
-
-		d3.event.preventDefault();
-
-		d3.select(document.getElementById(data.dpid + '-label')).classed('nolabel', false);
-
-		if (data.highlighted) {
-			return;
-		}
-
-		// only highlight valid link or flow destination by checking for class of existing highlighted circle
-		var highlighted = svg.selectAll('.highlight')[0];
-		if (highlighted.length == 1) {
-			var s = d3.select(highlighted[0]).select('circle');
-			// only allow links
-			// 	edge->edge (flow)
-			//  aggregation->core
-			//	core->core
-			if (data.className == 'edge' && !s.classed('edge') ||
-				data.className == 'core' && !s.classed('core') && !s.classed('aggregation') ||
-				data.className == 'aggregation' && !s.classed('core')) {
-				return;
-			}
-
-			// don't highlight if there's already a link or flow
-			// var map = linkMap[data.dpid];
-			// console.log(map);
-			// console.log(s.data()[0].dpid);
-			// console.log(map[s.data()[0].dpid]);
-			// if (map && map[s.data()[0].dpid]) {
-			// 	return;
-			// }
-
-			// the second highlighted switch is the target for a link or flow
-			data.target = true;
-		}
-
-		var node = d3.select(document.getElementById(data.dpid));
-		node.classed('highlight', true).select('circle').transition().duration(100).attr("r", widths.core);
-		data.highlighted = true;
-		node.moveToFront();
-	}
-
-	function mouseOutSwitch(data) {
-		d3.select(document.getElementById(data.dpid + '-label')).classed('nolabel', true);
-
-		if (data.mouseDown)
-			return;
-
-		var node = d3.select(document.getElementById(data.dpid));
-		node.classed('highlight', false).select('circle').transition().duration(100).attr("r", widths[data.className]);
-		data.highlighted = false;
-		data.target = false;
-	}
-
-	function mouseDownSwitch(data) {
-		mouseOverSwitch(data);
-		data.mouseDown = true;
-		d3.select('#topology').classed('linking', true);
-
-		d3.select('svg')
-			.append('svg:path')
-			.attr('id', 'linkVector')
-			.attr('d', function () {
-				var s = d3.select(document.getElementById(data.dpid));
-
-				var pt = document.querySelector('svg').createSVGPoint();
-				pt.x = s.attr('x');
-				pt.y = s.attr('y');
-				pt = pt.matrixTransform(s[0][0].getCTM());
-
-				return line([pt, pt]);
-			});
-
-
-		if (data.className === 'core') {
-			d3.selectAll('.edge').classed('nodrop', true);
-		}
-		if (data.className === 'edge') {
-			d3.selectAll('.core').classed('nodrop', true);
-			d3.selectAll('.aggregation').classed('nodrop', true);
-		}
-		if (data.className === 'aggregation') {
-			d3.selectAll('.edge').classed('nodrop', true);
-			d3.selectAll('.aggregation').classed('nodrop', true);
-		}
-	}
-
-	function mouseUpSwitch(data) {
-		if (data.mouseDown) {
-			data.mouseDown = false;
-			d3.select('#topology').classed('linking', false);
-			d3.event.stopPropagation();
-			d3.selectAll('.nodrop').classed('nodrop', false);
-		}
-	}
-
-	function doubleClickSwitch(data) {
-		var circle = d3.select(document.getElementById(data.dpid)).select('circle');
-		if (data.state == 'ACTIVE') {
-			var prompt = 'Deactivate ' + data.dpid + '?';
-			if (confirm(prompt)) {
-				switchDown(data);
-				setPending(circle);
-			}
-		} else {
-			var prompt = 'Activate ' + data.dpid + '?';
-			if (confirm(prompt)) {
-				switchUp(data);
-				setPending(circle);
-			}
-		}
-	}
-
-	function ringEnter(data, i) {
-		if (!data.length) {
-			return;
-		}
-
-		// create the nodes
-		var nodes = d3.select(this).selectAll("g")
-			.data(data, function (data) {
-				return data.dpid;
-			})
-			.enter().append("svg:g")
-			.attr("id", function (data, i) {
-				return data.dpid;
-			})
-			.attr("transform", function(data, i) {
-				return "rotate(" + data.angle+ ")translate(" + data.radius * 150 + ")rotate(" + (-data.angle) + ")";
-			});
-
-		// add the cirles representing the switches
-		nodes.append("svg:circle")
-			.attr("transform", function(data, i) {
-				var m = document.querySelector('#viewbox').getTransformToElement().inverse();
-				if (data.scale) {
-					m = m.scale(data.scale);
-				}
-				return "matrix( " + m.a + " " + m.b + " " + m.c + " " + m.d + " " + m.e + " " + m.f + " )";
-			})
-			.attr("x", function (data) {
-				return -data.width / 2;
-			})
-			.attr("y", function (data) {
-				return -data.width / 2;
-			})
-			.attr("r", function (data) {
-				return data.width;
-			});
-
-		// setup the mouseover behaviors
-		nodes.on('mouseover', mouseOverSwitch);
-		nodes.on('mouseout', mouseOutSwitch);
-		nodes.on('mouseup', mouseUpSwitch);
-		nodes.on('mousedown', mouseDownSwitch);
-
-		// only do switch up/down for core switches
-		if (i == 2) {
-			nodes.on('dblclick', doubleClickSwitch);
-		}
-	}
-
-	// append switches
-	rings.enter().append("svg:g")
-		.attr("class", "ring")
-		.each(ringEnter);
-
-
-	function ringUpdate(data, i) {
-		var nodes = d3.select(this).selectAll("g")
-			.data(data, function (data) {
-				return data.dpid;
-			});
-		nodes.select('circle')
-			.each(function (data) {
-				// if there's a pending state changed and then the state changes, clear the pending class
-				var circle = d3.select(this);
-				if (data.state === 'ACTIVE' && circle.classed('inactive') ||
-					data.state === 'INACTIVE' && circle.classed('active')) {
-					circle.classed('pending', false);
-				}
-			})
-			.attr('class', function (data)  {
-				if (data.state === 'ACTIVE' && data.controller) {
-					return data.className + ' active ' + controllerColorMap[data.controller];
-				} else {
-					return data.className + ' inactive ' + 'colorInactive';
-				}
-			});
-	}
-
-	// update  switches
-	rings.each(ringUpdate);
-
-
-	// Now setup the labels
-	// This is done separately because SVG draws in node order and we want the labels
-	// always on top
-	var labelRings = svg.selectAll('.labelRing').data(createRingsFromModel(model));
-
-	d3.select(document.body).on('mousemove', function () {
-		if (!d3.select('#topology').classed('linking')) {
-			return;
-		}
-		var linkVector = document.getElementById('linkVector');
-		if (!linkVector) {
-			return;
-		}
-		linkVector = d3.select(linkVector);
-
-		var highlighted = svg.selectAll('.highlight')[0];
-		var s1 = null, s2 = null;
-		if (highlighted.length > 1) {
-			var s1 = d3.select(highlighted[0]);
-			var s2 = d3.select(highlighted[1]);
-
-		} else if (highlighted.length > 0) {
-			var s1 = d3.select(highlighted[0]);
-		}
-		var src = s1;
-		if (s2 && !s2.data()[0].target) {
-			src = s2;
-		}
-		if (src) {
-			linkVector.attr('d', function () {
-					var srcPt = document.querySelector('svg').createSVGPoint();
-					srcPt.x = src.attr('x');
-					srcPt.y = src.attr('y');
-					srcPt = srcPt.matrixTransform(src[0][0].getCTM());
-
-					var svg = document.getElementById('topology');
-					var mouse = d3.mouse(viewbox);
-					var dstPt = document.querySelector('svg').createSVGPoint();
-					dstPt.x = mouse[0];
-					dstPt.y = mouse[1];
-					dstPt = dstPt.matrixTransform(viewbox.getCTM());
-
-					return line([srcPt, dstPt]);
-				});
-		}
-	});
-
-	d3.select(document.body).on('mouseup', function () {
-		function clearHighlight() {
-			svg.selectAll('circle').each(function (data) {
-				data.mouseDown = false;
-				d3.select('#topology').classed('linking', false);
-				mouseOutSwitch(data);
-			});
-			d3.select('#linkVector').remove();
-		};
-
-		d3.selectAll('.nodrop').classed('nodrop', false);
-
-		function removeLink(link) {
-			var path1 = document.getElementById(link['src-switch'] + '=>' + link['dst-switch']);
-			var path2 = document.getElementById(link['dst-switch'] + '=>' + link['src-switch']);
-
-			if (path1) {
-				setPending(d3.select(path1));
-			}
-			if (path2) {
-				setPending(d3.select(path2));
-			}
-
-			linkDown(link);
-		}
-
-
-		var highlighted = svg.selectAll('.highlight')[0];
-		if (highlighted.length == 2) {
-			var s1Data = highlighted[0].__data__;
-			var s2Data = highlighted[1].__data__;
-
-			var srcData, dstData;
-			if (s1Data.target) {
-				dstData = s1Data;
-				srcData = s2Data;
-			} else {
-				dstData = s2Data;
-				srcData = s1Data;
-			}
-
-			if (s1Data.className == 'edge' && s2Data.className == 'edge') {
-				var prompt = 'Create flow from ' + srcData.dpid + ' to ' + dstData.dpid + '?';
-				if (confirm(prompt)) {
-					addFlow(srcData, dstData);
-
-					var flow = {
-						dataPath: {
-							srcPort: {
-								dpid: {
-									value: srcData.dpid
-								}
-							},
-							dstPort: {
-								dpid: {
-									value: dstData.dpid
-								}
-							}
-						},
-					        srcDpid: srcData.dpid,
-					        dstDpid: dstData.dpid,
-						createPending: true
-					};
-
-					selectFlow(flow);
-
-					setTimeout(function () {
-						deselectFlowIfCreatePending(flow);
-					}, pendingTimeout);
-				}
-			} else {
-				var map = linkMap[srcData.dpid];
-				if (map && map[dstData.dpid]) {
-					var prompt = 'Remove link between ' + srcData.dpid + ' and ' + dstData.dpid + '?';
-					if (confirm(prompt)) {
-						removeLink(map[dstData.dpid]);
-					}
-				} else {
-					map = linkMap[dstData.dpid];
-					if (map && map[srcData.dpid]) {
-						var prompt = 'Remove link between ' + dstData.dpid + ' and ' + srcData.dpid + '?';
-						if (confirm(prompt)) {
-							removeLink(map[srcData.dpid]);
-						}
-					} else {
-						var prompt = 'Create link between ' + srcData.dpid + ' and ' + dstData.dpid + '?';
-						if (confirm(prompt)) {
-							var link1 = {
-								'src-switch': srcData.dpid,
-								'src-port': 1,
-								'dst-switch': dstData.dpid,
-								'dst-port': 1,
-								pending: true
-							};
-							pendingLinks[makeLinkKey(link1)] = link1;
-							var link2 = {
-								'src-switch': dstData.dpid,
-								'src-port': 1,
-								'dst-switch': srcData.dpid,
-								'dst-port': 1,
-								pending: true
-							};
-							pendingLinks[makeLinkKey(link2)] = link2;
-							updateTopology();
-
-							linkUp(link1);
-
-							// remove the pending links after 10s
-							setTimeout(function () {
-								delete pendingLinks[makeLinkKey(link1)];
-								delete pendingLinks[makeLinkKey(link2)];
-
-								updateTopology();
-							}, pendingTimeout);
-						}
-					}
-				}
-			}
-
-			clearHighlight();
-		} else {
-			clearHighlight();
-		}
-
-	});
-
-	function labelRingEnter(data) {
-		if (!data.length) {
-			return;
-		}
-
-		// create the nodes
-		var nodes = d3.select(this).selectAll("g")
-			.data(data, function (data) {
-				return data.dpid;
-			})
-			.enter().append("svg:g")
-			.classed('nolabel', true)
-			.attr("id", function (data) {
-				return data.dpid + '-label';
-			})
-			.attr("transform", function(data, i) {
-				return "rotate(" + data.angle+ ")translate(" + data.radius * 150 + ")rotate(" + (-data.angle) + ")";
-			})
-
-		// add the text nodes which show on mouse over
-		nodes.append("svg:text")
-				.text(function (data) {return data.dpid;})
-				.attr("x", function (data) {
-					if (data.angle <= 90 || data.angle >= 270 && data.angle <= 360) {
-						if (data.className == 'edge') {
-							return - data.width*3 - 4;
-						} else {
-							return - data.width - 4;
-						}
-					} else {
-						if (data.className == 'edge') {
-							return data.width*3 + 4;
-						} else {
-							return data.width + 4;
-						}
-					}
-				})
-				.attr("y", function (data) {
-					var y;
-					if (data.angle <= 90 || data.angle >= 270 && data.angle <= 360) {
-						if (data.className == 'edge') {
-							y = data.width*3/2 + 4;
-						} else {
-							y = data.width/2 + 4;
-						}
-					} else {
-						if (data.className == 'edge') {
-							y = data.width*3/2 + 4;
-						} else {
-							y = data.width/2 + 4;
-						}
-					}
-					return y - 6;
-				})
-				.attr("text-anchor", function (data) {
-					if (data.angle <= 90 || data.angle >= 270 && data.angle <= 360) {
-						return "end";
-					} else {
-						return "start";
-					}
-				})
-				.attr("transform", function(data) {
-					var m = document.querySelector('#viewbox').getTransformToElement().inverse();
-					if (data.scale) {
-						m = m.scale(data.scale);
-					}
-					return "matrix( " + m.a + " " + m.b + " " + m.c + " " + m.d + " " + m.e + " " + m.f + " )";
-				})
-	}
-
-	labelRings.enter().append("svg:g")
-		.attr("class", "textRing")
-		.each(labelRingEnter);
-
-	// switches should not change during operation of the ui so no
-	// rings.exit()
-
-
-	// DRAW THE LINKS
-
-	// key on link dpids since these will come/go during demo
-	var links = d3.select('svg').selectAll('.link').data(links, function (d) {
-			return d['src-switch']+'->'+d['dst-switch'];
-	});
-
-	// add new links
-	links.enter().append("svg:path")
-	.attr("class", "link");
-
-	links.attr('id', function (d) {
-			return makeLinkKey(d);
-		})
-		.attr("d", function (d) {
-			var src = d3.select(document.getElementById(d['src-switch']));
-			var dst = d3.select(document.getElementById(d['dst-switch']));
-
-			var srcPt = document.querySelector('svg').createSVGPoint();
-			srcPt.x = src.attr('x');
-			srcPt.y = src.attr('y');
-			srcPt = srcPt.matrixTransform(src[0][0].getCTM());
-
-			var dstPt = document.querySelector('svg').createSVGPoint();
-			dstPt.x = dst.attr('x');
-			dstPt.y = dst.attr('y');
-			dstPt = dstPt.matrixTransform(dst[0][0].getCTM());
-
-			var midPt = document.querySelector('svg').createSVGPoint();
-			midPt.x = (srcPt.x + dstPt.x)/2;
-			midPt.y = (srcPt.y + dstPt.y)/2;
-
-			return line([srcPt, midPt, dstPt]);
-		})
-		.attr("marker-mid", function(d) { return "url(#arrow)"; })
-		.classed('pending', function (d) {
-			return d.pending;
-		});
-
-
-	// remove old links
-	links.exit().remove();
-}
-
-function updateControllers() {
-	var controllers = d3.select('#controllerList').selectAll('.controller').data(model.controllers);
-	controllers.enter().append('div')
-		.each(function (c) {
-			controllerColorMap[c] = colors.pop();
-			d3.select(document.body).classed(controllerColorMap[c] + '-selected', true);
-		})
-		.text(function (d) {
-			return d;
-		})
-		.append('div')
-		.attr('class', 'black-eye');
-
-	controllers.attr('class', function (d) {
-			var color = 'colorInactive';
-			if (model.activeControllers.indexOf(d) != -1) {
-				color = controllerColorMap[d];
-			}
-			var className = 'controller ' + color;
-			return className;
-		});
-
-	// this should never be needed
-	// controllers.exit().remove();
-
-	controllers.on('dblclick', function (c) {
-		if (model.activeControllers.indexOf(c) != -1) {
-			var prompt = 'Dectivate ' + c + '?';
-			if (confirm(prompt)) {
-				controllerDown(c);
-				setPending(d3.select(this));
-			};
-		} else {
-			var prompt = 'Activate ' + c + '?';
-			if (confirm(prompt)) {
-				controllerUp(c);
-				setPending(d3.select(this));
-			};
-		}
-	});
-
-	controllers.select('.black-eye').on('click', function (c) {
-		var allSelected = true;
-		for (var key in controllerColorMap) {
-			if (!d3.select(document.body).classed(controllerColorMap[key] + '-selected')) {
-				allSelected = false;
-				break;
-			}
-		}
-		if (allSelected) {
-			for (var key in controllerColorMap) {
-				d3.select(document.body).classed(controllerColorMap[key] + '-selected', key == c)
-			}
-		} else {
-			for (var key in controllerColorMap) {
-				d3.select(document.body).classed(controllerColorMap[key] + '-selected', true)
-			}
-		}
-
-		// var selected = d3.select(document.body).classed(controllerColorMap[c] + '-selected');
-		// d3.select(document.body).classed(controllerColorMap[c] + '-selected', !selected);
-	});
-
-
-}
 
-var modelString;
 function sync(svg) {
 	var d = Date.now();
+
 	updateModel(function (newModel) {
 //		console.log('Update time: ' + (Date.now() - d)/1000 + 's');
 
@@ -1222,6 +25,8 @@
 			}
 
 			updateHeader(newModel);
+
+			d3.select('#contents').style('visibility', 'visible');
 		}
 
 		// do it again in 1s
@@ -1231,27 +36,7 @@
 	});
 }
 
-svg = createTopologyView();
-
-
-d3.xml("assets/map.svg", "image/svg+xml", function(xml) {
-  var importedNode = document.importNode(xml.documentElement, true);
-  var paths = importedNode.querySelectorAll('path');
-  var i;
-  for (i=0; i < paths.length; i+=1) {
-  	svg.append('svg:path')
-  		.attr('class', 'state')
-  		.attr('d', d3.select(paths.item(i)).attr('d'))
-  		.attr('transform', 'translate(-500 -500)scale(1 1.7)')
-  }
-});
-
-updateSelectedFlows();
-
-d3.select('#showFlowChooser').on('click', function () {
-	showFlowChooser();
-});
-
+appInit();
 
 // workaround for Chrome v25 bug
 // if executed immediately, the view box transform logic doesn't work properly
diff --git a/web/ons-demo/js/constants.js b/web/ons-demo/js/constants.js
new file mode 100644
index 0000000..7431bba
--- /dev/null
+++ b/web/ons-demo/js/constants.js
@@ -0,0 +1,21 @@
+/***************************************************************************************************
+timeout used by controller functions. after the timeout expires the "pending" action
+is removed and the topology view is whatever is reported by the API
+***************************************************************************************************/
+var pendingTimeout = 30000;
+
+/***************************************************************************************************
+CSS names for the pallette of colors used by the topology view
+***************************************************************************************************/
+var colors = [
+	'color1',
+	'color2',
+	'color3',
+	'color4',
+	'color7',
+	'color8',
+	'color9',
+//	'color11',
+	'color12'
+];
+colors.reverse();
\ No newline at end of file
diff --git a/web/ons-demo/js/controllers.js b/web/ons-demo/js/controllers.js
new file mode 100644
index 0000000..75f2689
--- /dev/null
+++ b/web/ons-demo/js/controllers.js
@@ -0,0 +1,65 @@
+function updateControllers() {
+	var controllers = d3.select('#controllerList').selectAll('.controller').data(model.controllers);
+	controllers.enter().append('div')
+		.each(function (c) {
+			controllerColorMap[c] = colors.pop();
+			d3.select(document.body).classed(controllerColorMap[c] + '-selected', true);
+		})
+		.text(function (d) {
+			return d;
+		})
+		.append('div')
+		.attr('class', 'black-eye');
+
+	controllers.attr('class', function (d) {
+			var color = 'colorInactive';
+			if (model.activeControllers.indexOf(d) != -1) {
+				color = controllerColorMap[d];
+			}
+			var className = 'controller ' + color;
+			return className;
+		});
+
+	// this should never be needed
+	// controllers.exit().remove();
+
+	controllers.on('dblclick', function (c) {
+		if (model.activeControllers.indexOf(c) != -1) {
+			var prompt = 'Dectivate ' + c + '?';
+			if (confirm(prompt)) {
+				controllerDown(c);
+				setPending(d3.select(this));
+			};
+		} else {
+			var prompt = 'Activate ' + c + '?';
+			if (confirm(prompt)) {
+				controllerUp(c);
+				setPending(d3.select(this));
+			};
+		}
+	});
+
+	controllers.select('.black-eye').on('click', function (c) {
+		var allSelected = true;
+		for (var key in controllerColorMap) {
+			if (!d3.select(document.body).classed(controllerColorMap[key] + '-selected')) {
+				allSelected = false;
+				break;
+			}
+		}
+		if (allSelected) {
+			for (var key in controllerColorMap) {
+				d3.select(document.body).classed(controllerColorMap[key] + '-selected', key == c)
+			}
+		} else {
+			for (var key in controllerColorMap) {
+				d3.select(document.body).classed(controllerColorMap[key] + '-selected', true)
+			}
+		}
+
+		// var selected = d3.select(document.body).classed(controllerColorMap[c] + '-selected');
+		// d3.select(document.body).classed(controllerColorMap[c] + '-selected', !selected);
+	});
+
+
+}
\ No newline at end of file
diff --git a/web/ons-demo/js/debug.js b/web/ons-demo/js/debug.js
new file mode 100644
index 0000000..7b66912
--- /dev/null
+++ b/web/ons-demo/js/debug.js
@@ -0,0 +1,12 @@
+/***************************************************************************************************
+find the links that include the switch with this dpid
+***************************************************************************************************/
+function debug_findlink(model, dpid) {
+	var links = [];
+	model.links.forEach(function (link) {
+		if (link['src-switch'] == dpid || link['dst-switch'] == dpid) {
+			links.push(link);
+		}
+	});
+	return links;
+}
\ No newline at end of file
diff --git a/web/ons-demo/js/flows.js b/web/ons-demo/js/flows.js
new file mode 100644
index 0000000..29fc4fa
--- /dev/null
+++ b/web/ons-demo/js/flows.js
@@ -0,0 +1,408 @@
+function updateSelectedFlowsTopology() {
+	// DRAW THE FLOWS
+	var topologyFlows = [];
+	selectedFlows.forEach(function (flow) {
+		if (flow) {
+			topologyFlows.push(flow);
+		}
+	});
+
+	var flows = d3.select('svg').selectAll('.flow').data(topologyFlows);
+
+	flows.enter().append("svg:path").attr('class', 'flow')
+		.attr('stroke-dasharray', '4, 10')
+		.append('svg:animate')
+		.attr('attributeName', 'stroke-dashoffset')
+		.attr('attributeType', 'xml')
+		.attr('from', '500')
+		.attr('to', '-500')
+		.attr('dur', '20s')
+		.attr('repeatCount', 'indefinite');
+
+	flows.exit().remove();
+
+	flows.attr('d', function (d) {
+			if (!d) {
+				return;
+			}
+			var pts = [];
+			if (!d.dataPath.flowEntries) {
+				// create a temporary vector to indicate the pending flow
+				var s1 = d3.select(document.getElementById(d.srcDpid));
+				var s2 = d3.select(document.getElementById(d.dstDpid));
+
+				var pt1 = document.querySelector('svg').createSVGPoint();
+				pt1.x = s1.attr('x');
+				pt1.y = s1.attr('y');
+				pt1 = pt1.matrixTransform(s1[0][0].getCTM());
+				pts.push(pt1);
+
+				var pt2 = document.querySelector('svg').createSVGPoint();
+				pt2.x = s2.attr('x');
+				pt2.y = s2.attr('y');
+				pt2 = pt2.matrixTransform(s2[0][0].getCTM());
+				pts.push(pt2);
+
+			} else {
+				d.dataPath.flowEntries.forEach(function (flowEntry) {
+					var s = d3.select(document.getElementById(flowEntry.dpid.value));
+					// s[0] is null if the flow entry refers to a non-existent switch
+					if (s[0][0]) {
+						var pt = document.querySelector('svg').createSVGPoint();
+						pt.x = s.attr('x');
+						pt.y = s.attr('y');
+						pt = pt.matrixTransform(s[0][0].getCTM());
+						pts.push(pt);
+					} else {
+						console.log('flow refers to non-existent switch: ' + flowEntry.dpid.value);
+					}
+				});
+			}
+			if (pts.length) {
+				return line(pts);
+			} else {
+				return "M0,0";
+			}
+		})
+		.attr('id', function (d) {
+			if (d) {
+				return makeFlowKey(d);
+			}
+		})
+		.classed('pending', function (d) {
+			return d && (d.createPending || d.deletePending);
+		});
+
+	// "marching ants"
+	flows.select('animate').attr('from', 500);
+
+}
+
+function updateSelectedFlowsTable() {
+	function rowEnter(d) {
+		var row = d3.select(this);
+		row.append('div').classed('deleteFlow', true);
+		row.append('div').classed('flowId', true);
+		row.append('div').classed('srcDPID', true);
+		row.append('div').classed('dstDPID', true);
+		row.append('div').classed('iperf', true);
+
+		row.select('.iperf')
+			.append('div')
+			.attr('class', 'iperf-container')
+			.append('svg:svg')
+			.attr('viewBox', '0 0 1000 32')
+			.attr('preserveAspectRatio', 'none')
+			.append('svg:g')
+			.append('svg:path')
+			.attr('class', 'iperfdata');
+
+		row.on('mouseover', function (d) {
+			if (d) {
+				var path = document.getElementById(makeFlowKey(d));
+				d3.select(path).classed('highlight', true);
+			}
+		});
+		row.on('mouseout', function (d) {
+			if (d) {
+				var path = document.getElementById(makeFlowKey(d));
+				d3.select(path).classed('highlight', false);
+			}
+		});
+	}
+
+	function rowUpdate(d) {
+		var row = d3.select(this);
+		row.attr('id', function (d) {
+			if (d) {
+				return makeSelectedFlowKey(d);
+			}
+		});
+
+		if (!d || !hasIPerf(d)) {
+			row.select('.iperfdata')
+				.attr('d', 'M0,0');
+		}
+
+		row.select('.deleteFlow').on('click', function () {
+			deselectFlow(d);
+		});
+		row.on('dblclick', function () {
+			if (d) {
+				var prompt = 'Delete flow ' + d.flowId + '?';
+				if (confirm(prompt)) {
+					deleteFlow(d);
+					d.deletePending = true;
+					updateSelectedFlows();
+
+					setTimeout(function () {
+						d.deletePending = false;
+						updateSelectedFlows();
+					}, pendingTimeout)
+				};
+			}
+		});
+
+		row.select('.flowId')
+			.text(function (d) {
+				if (d) {
+					if (d.flowId) {
+						return d.flowId;
+					} else {
+						return '0x--';
+					}
+				}
+			})
+			.classed('pending', function (d) {
+				return d && (d.createPending || d.deletePending);
+			});
+
+		row.select('.srcDPID')
+			.text(function (d) {
+				if (d) {
+					return d.srcDpid;
+				}
+			});
+
+		row.select('.dstDPID')
+			.text(function (d) {
+				if (d) {
+					return d.dstDpid;
+				}
+			});
+	}
+
+	var flows = d3.select('#selectedFlows')
+		.selectAll('.selectedFlow')
+		.data(selectedFlows);
+
+	flows.enter()
+		.append('div')
+		.classed('selectedFlow', true)
+		.each(rowEnter);
+
+	flows.each(rowUpdate);
+
+	flows.exit().remove();
+}
+
+// TODO: cancel the interval when the flow is desel
+function startIPerfForFlow(flow) {
+	var duration = 10000; // seconds
+	var interval = 100; // ms. this is defined by the server
+	var updateRate = 2000; // ms
+	var pointsToDisplay = 1000;
+
+	function makePoints() {
+		var pts = [];
+		var i;
+		for (i=0; i < pointsToDisplay; ++i) {
+			var sample = flow.iperfData.samples[i];
+			var height = 30 * sample/1000000;
+			if (height > 30)
+				height = 30;
+			pts.push({
+				x: i * 1000/(pointsToDisplay-1),
+				y: 32 - height
+			})
+		}
+		return pts;
+	}
+
+	if (flow.flowId) {
+		console.log('starting iperf for: ' + flow.flowId);
+		startIPerf(flow, duration, updateRate/interval);
+		flow.iperfDisplayInterval = setInterval(function () {
+			if (flow.iperfData) {
+				while (flow.iperfData.samples.length < pointsToDisplay) {
+					flow.iperfData.samples.push(0);
+				}
+				var iperfPath = d3.select(document.getElementById(makeSelectedFlowKey(flow))).select('path');
+				iperfPath.attr('d', line(makePoints()));
+				flow.iperfData.samples.shift();
+			}
+
+
+		}, interval);
+		flow.iperfFetchInterval = setInterval(function () {
+			getIPerfData(flow, function (data) {
+				try {
+					if (!flow.iperfData) {
+						flow.iperfData = {
+							samples: []
+						};
+						var i;
+						for (i = 0; i < pointsToDisplay; ++i) {
+							flow.iperfData.samples.push(0);
+						}
+					}
+
+					var iperfData = JSON.parse(data);
+
+//				console.log(iperfData.timestamp);
+
+					// if the data is fresh
+					if (flow.iperfData.timestamp && iperfData.timestamp != flow.iperfData.timestamp) {
+
+						while (flow.iperfData.samples.length > pointsToDisplay + iperfData.samples.length) {
+							flow.iperfData.samples.shift();
+						}
+
+						iperfData.samples.forEach(function (s) {
+							flow.iperfData.samples.push(s);
+						});
+					}
+					flow.iperfData.timestamp = iperfData.timestamp;
+				} catch (e) {
+					console.log('bad iperf data: ' + data);
+				}
+//				console.log(data);
+			});
+		}, updateRate/2); // over sample to avoid gaps
+	}
+}
+
+function updateSelectedFlows() {
+	// make sure that all of the selected flows are either
+	// 1) valid (meaning they are in the latest list of flows)
+	// 2) pending
+	if (model) {
+		var flowMap = {};
+		model.flows.forEach(function (flow) {
+			flowMap[makeFlowKey(flow)] = flow;
+		});
+
+		var newSelectedFlows = [];
+		selectedFlows.forEach(function (flow) {
+			if (flow) {
+				var liveFlow = flowMap[makeFlowKey(flow)];
+				if (liveFlow) {
+					newSelectedFlows.push(liveFlow);
+					liveFlow.deletePending = flow.deletePending;
+					liveFlow.iperfFetchInterval = flow.iperfFetchInterval;
+					liveFlow.iperfDisplayInterval = flow.iperfDisplayInterval;
+				} else if (flow.createPending) {
+					newSelectedFlows.push(flow);
+				} else if (hasIPerf(flow)) {
+					clearIPerf(flow);
+				}
+			}
+		});
+		selectedFlows = newSelectedFlows;
+	}
+	selectedFlows.forEach(function (flow) {
+		if (!hasIPerf(flow)) {
+			startIPerfForFlow(flow);
+		}
+	});
+	while (selectedFlows.length < 3) {
+		selectedFlows.push(null);
+	}
+
+	updateSelectedFlowsTable();
+	updateSelectedFlowsTopology();
+}
+
+function selectFlow(flow) {
+	var flowKey = makeFlowKey(flow);
+	var alreadySelected = false;
+	selectedFlows.forEach(function (f) {
+		if (f && makeFlowKey(f) === flowKey) {
+			alreadySelected = true;
+		}
+	});
+
+	if (!alreadySelected) {
+		selectedFlows.unshift(flow);
+		selectedFlows = selectedFlows.slice(0, 3);
+		updateSelectedFlows();
+	}
+}
+
+function hasIPerf(flow) {
+	return flow && flow.iperfFetchInterval;
+}
+
+function clearIPerf(flow) {
+	console.log('clearing iperf interval for: ' + flow.flowId);
+	clearInterval(flow.iperfFetchInterval);
+	delete flow.iperfFetchInterval;
+	clearInterval(flow.iperfDisplayInterval);
+	delete flow.iperfDisplayInterval;
+	delete flow.iperfData;
+}
+
+function deselectFlow(flow, ifCreatePending) {
+	var flowKey = makeFlowKey(flow);
+	var newSelectedFlows = [];
+	selectedFlows.forEach(function (flow) {
+		if (!flow ||
+				flowKey !== makeFlowKey(flow) ||
+				flowKey === makeFlowKey(flow) && ifCreatePending && !flow.createPending ) {
+			newSelectedFlows.push(flow);
+		} else {
+			if (hasIPerf(flow)) {
+				clearIPerf(flow);
+			}
+		}
+	});
+	selectedFlows = newSelectedFlows;
+	while (selectedFlows.length < 3) {
+		selectedFlows.push(null);
+	}
+
+	updateSelectedFlows();
+}
+
+function deselectFlowIfCreatePending(flow) {
+	deselectFlow(flow, true);
+}
+
+function showFlowChooser() {
+	function rowEnter(d) {
+		var row = d3.select(this);
+
+		row.append('div')
+			.classed('black-eye', true).
+			on('click', function () {
+				selectFlow(d);
+			});
+
+		row.append('div')
+			.classed('flowId', true)
+			.text(function (d) {
+				return d.flowId;
+			});
+
+		row.append('div')
+			.classed('srcDPID', true)
+			.text(function (d) {
+				return d.srcDpid;
+			});
+
+
+		row.append('div')
+			.classed('dstDPID', true)
+			.text(function (d) {
+				return d.dstDpid;
+			});
+
+	}
+
+	var flows = d3.select('#flowChooser')
+		.append('div')
+		.style('pointer-events', 'auto')
+		.selectAll('.selectedFlow')
+		.data(model.flows)
+		.enter()
+		.append('div')
+		.classed('selectedFlow', true)
+		.each(rowEnter);
+
+	setTimeout(function () {
+		d3.select(document.body).on('click', function () {
+			d3.select('#flowChooser').html('');
+			d3.select(document.body).on('click', null);
+		});
+	}, 0);
+}
diff --git a/web/ons-demo/js/forward.js b/web/ons-demo/js/forward.js
new file mode 100644
index 0000000..9c4d03f
--- /dev/null
+++ b/web/ons-demo/js/forward.js
@@ -0,0 +1,5 @@
+/***************************************************************************************************
+forward declarations for functions
+***************************************************************************************************/
+
+var updateTopology;
diff --git a/web/ons-demo/js/globals.js b/web/ons-demo/js/globals.js
new file mode 100644
index 0000000..30f42f2
--- /dev/null
+++ b/web/ons-demo/js/globals.js
@@ -0,0 +1,37 @@
+/***************************************************************************************************
+global variables
+***************************************************************************************************/
+
+
+/***************************************************************************************************
+the latest update to the model
+***************************************************************************************************/
+var model;
+
+/***************************************************************************************************
+cached JSON representation of the model. used to detect model changes and update the UI.
+***************************************************************************************************/
+var modelString;
+
+
+/***************************************************************************************************
+the svg element for the topology view
+***************************************************************************************************/
+var svg;
+
+/***************************************************************************************************
+links that were created in the webui but which have not appeared in the links API response yet
+these timeout after pendingTimeout
+***************************************************************************************************/
+var pendingLinks = {};
+
+/***************************************************************************************************
+the flows that are displayed in the selected flow table
+this may include pending flows which have not appeared in the flows API response yet
+***************************************************************************************************/
+var selectedFlows = [];
+
+/***************************************************************************************************
+a mapping from controller name to color used for color coding the topology and ONOS nodes views
+***************************************************************************************************/
+var controllerColorMap = {};
\ No newline at end of file
diff --git a/web/ons-demo/js/init.js b/web/ons-demo/js/init.js
new file mode 100644
index 0000000..36a899c
--- /dev/null
+++ b/web/ons-demo/js/init.js
@@ -0,0 +1,10 @@
+function appInit() {
+	svg = createTopologyView();
+
+	// populates selected flows with empty rows
+	updateSelectedFlows();
+
+	d3.select('#showFlowChooser').on('click', function () {
+		showFlowChooser();
+	});
+}
diff --git a/web/ons-demo/js/topology.js b/web/ons-demo/js/topology.js
new file mode 100644
index 0000000..b7a9112
--- /dev/null
+++ b/web/ons-demo/js/topology.js
@@ -0,0 +1,675 @@
+/***************************************************************************************************
+functions for creating and interacting with the topology view of the webui
+
+flow related topology is in flows.js
+***************************************************************************************************/
+
+function createLinkMap(links) {
+	var linkMap = {};
+	links.forEach(function (link) {
+		var srcDPID = link['src-switch'];
+		var dstDPID = link['dst-switch'];
+
+		var srcMap = linkMap[srcDPID] || {};
+
+		srcMap[dstDPID] = link;
+
+		linkMap[srcDPID]  = srcMap;
+	});
+	return linkMap;
+}
+
+
+// removes links from the pending list that are now in the model
+function reconcilePendingLinks(model) {
+	var links = [];
+	model.links.forEach(function (link) {
+		links.push(link);
+		delete pendingLinks[makeLinkKey(link)]
+	})
+	var linkId;
+	for (linkId in pendingLinks) {
+		links.push(pendingLinks[linkId]);
+	}
+	return links
+}
+
+
+function createTopologyView() {
+
+	window.addEventListener('resize', function () {
+		// this is too slow. instead detect first resize event and hide the paths that have explicit matrix applied
+		// either that or is it possible to position the paths so they get the automatic transform as well?
+//		updateTopology();
+	});
+
+	var svg = d3.select('#svg-container').append('svg:svg');
+
+	svg.append("svg:defs").append("svg:marker")
+	    .attr("id", "arrow")
+	    .attr("viewBox", "0 -5 10 10")
+	    .attr("refX", -1)
+	    .attr("markerWidth", 5)
+	    .attr("markerHeight", 5)
+	    .attr("orient", "auto")
+	  .append("svg:path")
+	    .attr("d", "M0,-3L10,0L0,3");
+
+	return svg.append('svg:svg').attr('id', 'viewBox').attr('viewBox', '0 0 1000 1000').attr('preserveAspectRatio', 'none').
+			attr('id', 'viewbox').append('svg:g').attr('transform', 'translate(500 500)');
+}
+
+// d3.xml("assets/map.svg", "image/svg+xml", function(xml) {
+//   var importedNode = document.importNode(xml.documentElement, true);
+//   var paths = importedNode.querySelectorAll('path');
+//   var i;
+//   for (i=0; i < paths.length; i+=1) {
+//   	svg.append('svg:path')
+//   		.attr('class', 'state')
+//   		.attr('d', d3.select(paths.item(i)).attr('d'))
+//   		.attr('transform', 'translate(-500 -500)scale(1 1.7)')
+//   }
+// });
+
+
+var widths = {
+	edge: 6,
+	aggregation: 12,
+	core: 18
+}
+
+function createRingsFromModel(model) {
+	var rings = [{
+		radius: 3,
+		width: widths.edge,
+		switches: model.edgeSwitches,
+		className: 'edge',
+		angles: []
+	}, {
+		radius: 2.25,
+		width: widths.aggregation,
+		switches: model.aggregationSwitches,
+		className: 'aggregation',
+		angles: []
+	}, {
+		radius: 0.75,
+		width: widths.core,
+		switches: model.coreSwitches,
+		className: 'core',
+		angles: []
+	}];
+
+
+	var aggRanges = {};
+
+	// arrange edge switches at equal increments
+	var k = 360 / rings[0].switches.length;
+	rings[0].switches.forEach(function (s, i) {
+		var angle = k * i;
+
+		rings[0].angles[i] = angle;
+
+		// record the angle for the agg switch layout
+		var dpid = s.dpid.split(':');
+		dpid[7] = '01'; // the last component of the agg switch is always '01'
+		var aggdpid = dpid.join(':');
+		var aggRange = aggRanges[aggdpid];
+		if (!aggRange) {
+			aggRange = aggRanges[aggdpid] = {};
+			aggRange.min = aggRange.max = angle;
+		} else {
+			aggRange.max = angle;
+		}
+	});
+
+	// arrange aggregation switches to "fan out" to edge switches
+	k = 360 / rings[1].switches.length;
+	rings[1].switches.forEach(function (s, i) {
+//		rings[1].angles[i] = k * i;
+		var range = aggRanges[s.dpid];
+
+		rings[1].angles[i] = (range.min + range.max)/2;
+	});
+
+	// find the association between core switches and aggregation switches
+	var aggregationSwitchMap = {};
+	model.aggregationSwitches.forEach(function (s, i) {
+		aggregationSwitchMap[s.dpid] = i;
+	});
+
+	// put core switches next to linked aggregation switches
+	k = 360 / rings[2].switches.length;
+	rings[2].switches.forEach(function (s, i) {
+//		rings[2].angles[i] = k * i;
+		var associatedAggregationSwitches = model.configuration.association[s.dpid];
+		// TODO: go between if there are multiple
+		var index = aggregationSwitchMap[associatedAggregationSwitches[0]];
+
+		rings[2].angles[i] = rings[1].angles[index];
+	});
+
+	// TODO: construct this form initially rather than converting. it works better because
+	// it allows binding by dpid
+	var testRings = [];
+	rings.forEach(function (ring) {
+		var testRing = [];
+		ring.switches.forEach(function (s, i) {
+			var testSwitch = {
+				dpid: s.dpid,
+				state: s.state,
+				radius: ring.radius,
+				width: ring.width,
+				className: ring.className,
+				angle: ring.angles[i],
+				controller: s.controller
+			};
+			testRing.push(testSwitch);
+		});
+
+
+		testRings.push(testRing);
+	});
+
+
+//	return rings;
+	return testRings;
+}
+
+updateTopology = function() {
+
+	// DRAW THE SWITCHES
+	var rings = svg.selectAll('.ring').data(createRingsFromModel(model));
+
+	var links = reconcilePendingLinks(model);
+	var linkMap = createLinkMap(links);
+
+	function mouseOverSwitch(data) {
+
+		d3.event.preventDefault();
+
+		d3.select(document.getElementById(data.dpid + '-label')).classed('nolabel', false);
+
+		if (data.highlighted) {
+			return;
+		}
+
+		// only highlight valid link or flow destination by checking for class of existing highlighted circle
+		var highlighted = svg.selectAll('.highlight')[0];
+		if (highlighted.length == 1) {
+			var s = d3.select(highlighted[0]).select('circle');
+			// only allow links
+			// 	edge->edge (flow)
+			//  aggregation->core
+			//	core->core
+			if (data.className == 'edge' && !s.classed('edge') ||
+				data.className == 'core' && !s.classed('core') && !s.classed('aggregation') ||
+				data.className == 'aggregation' && !s.classed('core')) {
+				return;
+			}
+
+			// don't highlight if there's already a link or flow
+			// var map = linkMap[data.dpid];
+			// console.log(map);
+			// console.log(s.data()[0].dpid);
+			// console.log(map[s.data()[0].dpid]);
+			// if (map && map[s.data()[0].dpid]) {
+			// 	return;
+			// }
+
+			// the second highlighted switch is the target for a link or flow
+			data.target = true;
+		}
+
+		var node = d3.select(document.getElementById(data.dpid));
+		node.classed('highlight', true).select('circle').transition().duration(100).attr("r", widths.core);
+		data.highlighted = true;
+		node.moveToFront();
+	}
+
+	function mouseOutSwitch(data) {
+		d3.select(document.getElementById(data.dpid + '-label')).classed('nolabel', true);
+
+		if (data.mouseDown)
+			return;
+
+		var node = d3.select(document.getElementById(data.dpid));
+		node.classed('highlight', false).select('circle').transition().duration(100).attr("r", widths[data.className]);
+		data.highlighted = false;
+		data.target = false;
+	}
+
+	function mouseDownSwitch(data) {
+		mouseOverSwitch(data);
+		data.mouseDown = true;
+		d3.select('#topology').classed('linking', true);
+
+		d3.select('svg')
+			.append('svg:path')
+			.attr('id', 'linkVector')
+			.attr('d', function () {
+				var s = d3.select(document.getElementById(data.dpid));
+
+				var pt = document.querySelector('svg').createSVGPoint();
+				pt.x = s.attr('x');
+				pt.y = s.attr('y');
+				pt = pt.matrixTransform(s[0][0].getCTM());
+
+				return line([pt, pt]);
+			});
+
+
+		if (data.className === 'core') {
+			d3.selectAll('.edge').classed('nodrop', true);
+		}
+		if (data.className === 'edge') {
+			d3.selectAll('.core').classed('nodrop', true);
+			d3.selectAll('.aggregation').classed('nodrop', true);
+		}
+		if (data.className === 'aggregation') {
+			d3.selectAll('.edge').classed('nodrop', true);
+			d3.selectAll('.aggregation').classed('nodrop', true);
+		}
+	}
+
+	function mouseUpSwitch(data) {
+		if (data.mouseDown) {
+			data.mouseDown = false;
+			d3.select('#topology').classed('linking', false);
+			d3.event.stopPropagation();
+			d3.selectAll('.nodrop').classed('nodrop', false);
+		}
+	}
+
+	function doubleClickSwitch(data) {
+		var circle = d3.select(document.getElementById(data.dpid)).select('circle');
+		if (data.state == 'ACTIVE') {
+			var prompt = 'Deactivate ' + data.dpid + '?';
+			if (confirm(prompt)) {
+				switchDown(data);
+				setPending(circle);
+			}
+		} else {
+			var prompt = 'Activate ' + data.dpid + '?';
+			if (confirm(prompt)) {
+				switchUp(data);
+				setPending(circle);
+			}
+		}
+	}
+
+	function ringEnter(data, i) {
+		if (!data.length) {
+			return;
+		}
+
+		// create the nodes
+		var nodes = d3.select(this).selectAll("g")
+			.data(data, function (data) {
+				return data.dpid;
+			})
+			.enter().append("svg:g")
+			.attr("id", function (data, i) {
+				return data.dpid;
+			})
+			.attr("transform", function(data, i) {
+				return "rotate(" + data.angle+ ")translate(" + data.radius * 150 + ")rotate(" + (-data.angle) + ")";
+			});
+
+		// add the cirles representing the switches
+		nodes.append("svg:circle")
+			.attr("transform", function(data, i) {
+				var m = document.querySelector('#viewbox').getTransformToElement().inverse();
+				if (data.scale) {
+					m = m.scale(data.scale);
+				}
+				return "matrix( " + m.a + " " + m.b + " " + m.c + " " + m.d + " " + m.e + " " + m.f + " )";
+			})
+			.attr("x", function (data) {
+				return -data.width / 2;
+			})
+			.attr("y", function (data) {
+				return -data.width / 2;
+			})
+			.attr("r", function (data) {
+				return data.width;
+			});
+
+		// setup the mouseover behaviors
+		nodes.on('mouseover', mouseOverSwitch);
+		nodes.on('mouseout', mouseOutSwitch);
+		nodes.on('mouseup', mouseUpSwitch);
+		nodes.on('mousedown', mouseDownSwitch);
+
+		// only do switch up/down for core switches
+		if (i == 2) {
+			nodes.on('dblclick', doubleClickSwitch);
+		}
+	}
+
+	// append switches
+	rings.enter().append("svg:g")
+		.attr("class", "ring")
+		.each(ringEnter);
+
+
+	function ringUpdate(data, i) {
+		var nodes = d3.select(this).selectAll("g")
+			.data(data, function (data) {
+				return data.dpid;
+			});
+		nodes.select('circle')
+			.each(function (data) {
+				// if there's a pending state changed and then the state changes, clear the pending class
+				var circle = d3.select(this);
+				if (data.state === 'ACTIVE' && circle.classed('inactive') ||
+					data.state === 'INACTIVE' && circle.classed('active')) {
+					circle.classed('pending', false);
+				}
+			})
+			.attr('class', function (data)  {
+				if (data.state === 'ACTIVE' && data.controller) {
+					return data.className + ' active ' + controllerColorMap[data.controller];
+				} else {
+					return data.className + ' inactive ' + 'colorInactive';
+				}
+			});
+	}
+
+	// update  switches
+	rings.each(ringUpdate);
+
+
+	// Now setup the labels
+	// This is done separately because SVG draws in node order and we want the labels
+	// always on top
+	var labelRings = svg.selectAll('.labelRing').data(createRingsFromModel(model));
+
+	d3.select(document.body).on('mousemove', function () {
+		if (!d3.select('#topology').classed('linking')) {
+			return;
+		}
+		var linkVector = document.getElementById('linkVector');
+		if (!linkVector) {
+			return;
+		}
+		linkVector = d3.select(linkVector);
+
+		var highlighted = svg.selectAll('.highlight')[0];
+		var s1 = null, s2 = null;
+		if (highlighted.length > 1) {
+			var s1 = d3.select(highlighted[0]);
+			var s2 = d3.select(highlighted[1]);
+
+		} else if (highlighted.length > 0) {
+			var s1 = d3.select(highlighted[0]);
+		}
+		var src = s1;
+		if (s2 && !s2.data()[0].target) {
+			src = s2;
+		}
+		if (src) {
+			linkVector.attr('d', function () {
+					var srcPt = document.querySelector('svg').createSVGPoint();
+					srcPt.x = src.attr('x');
+					srcPt.y = src.attr('y');
+					srcPt = srcPt.matrixTransform(src[0][0].getCTM());
+
+					var svg = document.getElementById('topology');
+					var mouse = d3.mouse(viewbox);
+					var dstPt = document.querySelector('svg').createSVGPoint();
+					dstPt.x = mouse[0];
+					dstPt.y = mouse[1];
+					dstPt = dstPt.matrixTransform(viewbox.getCTM());
+
+					return line([srcPt, dstPt]);
+				});
+		}
+	});
+
+	d3.select(document.body).on('mouseup', function () {
+		function clearHighlight() {
+			svg.selectAll('circle').each(function (data) {
+				data.mouseDown = false;
+				d3.select('#topology').classed('linking', false);
+				mouseOutSwitch(data);
+			});
+			d3.select('#linkVector').remove();
+		};
+
+		d3.selectAll('.nodrop').classed('nodrop', false);
+
+		function removeLink(link) {
+			var path1 = document.getElementById(link['src-switch'] + '=>' + link['dst-switch']);
+			var path2 = document.getElementById(link['dst-switch'] + '=>' + link['src-switch']);
+
+			if (path1) {
+				setPending(d3.select(path1));
+			}
+			if (path2) {
+				setPending(d3.select(path2));
+			}
+
+			linkDown(link);
+		}
+
+
+		var highlighted = svg.selectAll('.highlight')[0];
+		if (highlighted.length == 2) {
+			var s1Data = highlighted[0].__data__;
+			var s2Data = highlighted[1].__data__;
+
+			var srcData, dstData;
+			if (s1Data.target) {
+				dstData = s1Data;
+				srcData = s2Data;
+			} else {
+				dstData = s2Data;
+				srcData = s1Data;
+			}
+
+			if (s1Data.className == 'edge' && s2Data.className == 'edge') {
+				var prompt = 'Create flow from ' + srcData.dpid + ' to ' + dstData.dpid + '?';
+				if (confirm(prompt)) {
+					addFlow(srcData, dstData);
+
+					var flow = {
+						dataPath: {
+							srcPort: {
+								dpid: {
+									value: srcData.dpid
+								}
+							},
+							dstPort: {
+								dpid: {
+									value: dstData.dpid
+								}
+							}
+						},
+					        srcDpid: srcData.dpid,
+					        dstDpid: dstData.dpid,
+						createPending: true
+					};
+
+					selectFlow(flow);
+
+					setTimeout(function () {
+						deselectFlowIfCreatePending(flow);
+					}, pendingTimeout);
+				}
+			} else {
+				var map = linkMap[srcData.dpid];
+				if (map && map[dstData.dpid]) {
+					var prompt = 'Remove link between ' + srcData.dpid + ' and ' + dstData.dpid + '?';
+					if (confirm(prompt)) {
+						removeLink(map[dstData.dpid]);
+					}
+				} else {
+					map = linkMap[dstData.dpid];
+					if (map && map[srcData.dpid]) {
+						var prompt = 'Remove link between ' + dstData.dpid + ' and ' + srcData.dpid + '?';
+						if (confirm(prompt)) {
+							removeLink(map[srcData.dpid]);
+						}
+					} else {
+						var prompt = 'Create link between ' + srcData.dpid + ' and ' + dstData.dpid + '?';
+						if (confirm(prompt)) {
+							var link1 = {
+								'src-switch': srcData.dpid,
+								'src-port': 1,
+								'dst-switch': dstData.dpid,
+								'dst-port': 1,
+								pending: true
+							};
+							pendingLinks[makeLinkKey(link1)] = link1;
+							var link2 = {
+								'src-switch': dstData.dpid,
+								'src-port': 1,
+								'dst-switch': srcData.dpid,
+								'dst-port': 1,
+								pending: true
+							};
+							pendingLinks[makeLinkKey(link2)] = link2;
+							updateTopology();
+
+							linkUp(link1);
+
+							// remove the pending links after 10s
+							setTimeout(function () {
+								delete pendingLinks[makeLinkKey(link1)];
+								delete pendingLinks[makeLinkKey(link2)];
+
+								updateTopology();
+							}, pendingTimeout);
+						}
+					}
+				}
+			}
+
+			clearHighlight();
+		} else {
+			clearHighlight();
+		}
+
+	});
+
+	function labelRingEnter(data) {
+		if (!data.length) {
+			return;
+		}
+
+		// create the nodes
+		var nodes = d3.select(this).selectAll("g")
+			.data(data, function (data) {
+				return data.dpid;
+			})
+			.enter().append("svg:g")
+			.classed('nolabel', true)
+			.attr("id", function (data) {
+				return data.dpid + '-label';
+			})
+			.attr("transform", function(data, i) {
+				return "rotate(" + data.angle+ ")translate(" + data.radius * 150 + ")rotate(" + (-data.angle) + ")";
+			})
+
+		// add the text nodes which show on mouse over
+		nodes.append("svg:text")
+				.text(function (data) {return data.dpid;})
+				.attr("x", function (data) {
+					if (data.angle <= 90 || data.angle >= 270 && data.angle <= 360) {
+						if (data.className == 'edge') {
+							return - data.width*3 - 4;
+						} else {
+							return - data.width - 4;
+						}
+					} else {
+						if (data.className == 'edge') {
+							return data.width*3 + 4;
+						} else {
+							return data.width + 4;
+						}
+					}
+				})
+				.attr("y", function (data) {
+					var y;
+					if (data.angle <= 90 || data.angle >= 270 && data.angle <= 360) {
+						if (data.className == 'edge') {
+							y = data.width*3/2 + 4;
+						} else {
+							y = data.width/2 + 4;
+						}
+					} else {
+						if (data.className == 'edge') {
+							y = data.width*3/2 + 4;
+						} else {
+							y = data.width/2 + 4;
+						}
+					}
+					return y - 6;
+				})
+				.attr("text-anchor", function (data) {
+					if (data.angle <= 90 || data.angle >= 270 && data.angle <= 360) {
+						return "end";
+					} else {
+						return "start";
+					}
+				})
+				.attr("transform", function(data) {
+					var m = document.querySelector('#viewbox').getTransformToElement().inverse();
+					if (data.scale) {
+						m = m.scale(data.scale);
+					}
+					return "matrix( " + m.a + " " + m.b + " " + m.c + " " + m.d + " " + m.e + " " + m.f + " )";
+				})
+	}
+
+	labelRings.enter().append("svg:g")
+		.attr("class", "textRing")
+		.each(labelRingEnter);
+
+	// switches should not change during operation of the ui so no
+	// rings.exit()
+
+
+	// DRAW THE LINKS
+
+	// key on link dpids since these will come/go during demo
+	var links = d3.select('svg').selectAll('.link').data(links, function (d) {
+			return d['src-switch']+'->'+d['dst-switch'];
+	});
+
+	// add new links
+	links.enter().append("svg:path")
+	.attr("class", "link");
+
+	links.attr('id', function (d) {
+			return makeLinkKey(d);
+		})
+		.attr("d", function (d) {
+			var src = d3.select(document.getElementById(d['src-switch']));
+			var dst = d3.select(document.getElementById(d['dst-switch']));
+
+			var srcPt = document.querySelector('svg').createSVGPoint();
+			srcPt.x = src.attr('x');
+			srcPt.y = src.attr('y');
+			srcPt = srcPt.matrixTransform(src[0][0].getCTM());
+
+			var dstPt = document.querySelector('svg').createSVGPoint();
+			dstPt.x = dst.attr('x');
+			dstPt.y = dst.attr('y');
+			dstPt = dstPt.matrixTransform(dst[0][0].getCTM());
+
+			var midPt = document.querySelector('svg').createSVGPoint();
+			midPt.x = (srcPt.x + dstPt.x)/2;
+			midPt.y = (srcPt.y + dstPt.y)/2;
+
+			return line([srcPt, midPt, dstPt]);
+		})
+		.attr("marker-mid", function(d) { return "url(#arrow)"; })
+		.classed('pending', function (d) {
+			return d.pending;
+		});
+
+
+	// remove old links
+	links.exit().remove();
+}
\ No newline at end of file
diff --git a/web/ons-demo/js/utils.js b/web/ons-demo/js/utils.js
index 4f6d0c1..d597507 100644
--- a/web/ons-demo/js/utils.js
+++ b/web/ons-demo/js/utils.js
@@ -1,3 +1,6 @@
+/***************************************************************************************************
+extract url parameters into a map
+***************************************************************************************************/
 function parseURLParameters() {
 	var parameters = {};
 
@@ -13,12 +16,72 @@
 	return parameters;
 }
 
-function findLink(model, dpid) {
-	var links = [];
-	model.links.forEach(function (link) {
-		if (link['src-switch'] == dpid || link['dst-switch'] == dpid) {
-			links.push(link);
-		}
-	});
-	return links;
-}
\ No newline at end of file
+/***************************************************************************************************
+convenience function for moving an SVG element to the front so that it draws on top
+***************************************************************************************************/
+d3.selection.prototype.moveToFront = function() {
+  return this.each(function(){
+    this.parentNode.appendChild(this);
+  });
+};
+
+/***************************************************************************************************
+standard function for generating the 'd' attribute for a path from an array of points
+***************************************************************************************************/
+var line = d3.svg.line()
+    .x(function(d) {
+    	return d.x;
+    })
+    .y(function(d) {
+    	return d.y;
+    });
+
+
+/***************************************************************************************************
+starts the "pending" animation
+***************************************************************************************************/
+function setPending(selection) {
+	selection.classed('pending', false);
+	setTimeout(function () {
+		selection.classed('pending', true);
+	}, 0);
+}
+
+/***************************************************************************************************
+convert angle in degrees to radians
+***************************************************************************************************/
+function toRadians (degrees) {
+  return degrees * (Math.PI / 180);
+}
+
+/***************************************************************************************************
+used to generate DOM element id for this link
+***************************************************************************************************/
+function makeLinkKey(link) {
+	return link['src-switch'] + '=>' + link['dst-switch'];
+}
+
+/***************************************************************************************************
+used to generate DOM element id for this flow in the topology view
+***************************************************************************************************/
+function makeFlowKey(flow) {
+	return flow.srcDpid + '=>' + flow.dstDpid;
+}
+
+/***************************************************************************************************
+used to generate DOM element id for this flow in the selected flows table
+***************************************************************************************************/
+function makeSelectedFlowKey(flow) {
+	return 'S' + makeFlowKey(flow);
+}
+
+/***************************************************************************************************
+update the app header using the current model
+***************************************************************************************************/
+function updateHeader() {
+	d3.select('#lastUpdate').text(new Date());
+	d3.select('#activeSwitches').text(model.edgeSwitches.length + model.aggregationSwitches.length + model.coreSwitches.length);
+	d3.select('#activeFlows').text(model.flows.length);
+}
+
+
