diff --git a/web/ons-demo/js/constants.js b/web/ons-demo/js/constants.js
index 7431bba..0ef0882 100644
--- a/web/ons-demo/js/constants.js
+++ b/web/ons-demo/js/constants.js
@@ -18,4 +18,13 @@
 //	'color11',
 	'color12'
 ];
-colors.reverse();
\ No newline at end of file
+colors.reverse();
+
+/***************************************************************************************************
+Widths of each switch type
+***************************************************************************************************/
+var widths = {
+	edge: 6,
+	aggregation: 12,
+	core: 18
+}
\ No newline at end of file
diff --git a/web/ons-demo/js/forward.js b/web/ons-demo/js/forward.js
index 9c4d03f..5e854ee 100644
--- a/web/ons-demo/js/forward.js
+++ b/web/ons-demo/js/forward.js
@@ -3,3 +3,10 @@
 ***************************************************************************************************/
 
 var updateTopology;
+
+
+/***************************************************************************************************
+defined by whichever topology module is included
+***************************************************************************************************/
+var createTopologyView;
+var drawTopology;
diff --git a/web/ons-demo/js/globals.js b/web/ons-demo/js/globals.js
index c7cf5bb..f0922a6 100644
--- a/web/ons-demo/js/globals.js
+++ b/web/ons-demo/js/globals.js
@@ -13,7 +13,6 @@
 ***************************************************************************************************/
 var modelString;
 
-
 /***************************************************************************************************
 the svg element for the topology view
 ***************************************************************************************************/
diff --git a/web/ons-demo/js/rings.js b/web/ons-demo/js/rings.js
index 5141195..ec6d59f 100644
--- a/web/ons-demo/js/rings.js
+++ b/web/ons-demo/js/rings.js
@@ -1,4 +1,6 @@
-function createTopologyView() {
+(function () {
+
+createTopologyView = function () {
 
 	window.addEventListener('resize', function () {
 		// this is too slow. instead detect first resize event and hide the paths that have explicit matrix applied
@@ -22,13 +24,7 @@
 			attr('id', 'viewbox').append('svg:g').attr('transform', 'translate(500 500)');
 }
 
-var widths = {
-	edge: 6,
-	aggregation: 12,
-	core: 18
-}
-
-function createTopologyModel(model) {
+function createRingTopologyModel(model) {
 	var rings = [{
 		radius: 3,
 		width: widths.edge,
@@ -123,4 +119,164 @@
 
 //	return rings;
 	return testRings;
-}
\ No newline at end of file
+}
+
+drawTopology = function () {
+	// DRAW THE SWITCHES
+	var rings = svg.selectAll('.ring').data(createRingTopologyModel(model));
+
+	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;
+			});
+	}
+
+	// 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(createRingTopologyModel(model));
+
+	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()
+}
+
+})();
diff --git a/web/ons-demo/js/topology.js b/web/ons-demo/js/topology.js
index e934972..a2a69ae 100644
--- a/web/ons-demo/js/topology.js
+++ b/web/ons-demo/js/topology.js
@@ -6,233 +6,19 @@
 
 (function () {
 
-updateTopology = function() {
-
-	// DRAW THE SWITCHES
-	var rings = svg.selectAll('.ring').data(createTopologyModel(model));
-
-	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(createTopologyModel(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]);
-				});
-		}
-	});
-
-	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
+function updateLinkLines() {
 
 	// key on link dpids since these will come/go during demo
 	var linkLines = d3.select('svg').selectAll('.link').data(links, function (d) {
-			return d['src-switch']+'->'+d['dst-switch'];
+		return d['src-switch']+'->'+d['dst-switch'];
 	});
 
 	// add new links
-	linkLines.enter().append("svg:path")
-	.attr("class", "link");
+	linkLines.enter().append("svg:path").attr("class", "link");
 
 	linkLines.attr('id', function (d) {
 			return makeLinkKey(d);
-		})
-		.attr("d", function (d) {
+		}).attr("d", function (d) {
 			var src = d3.select(document.getElementById(d['src-switch']));
 			var dst = d3.select(document.getElementById(d['dst-switch']));
 
@@ -257,9 +43,32 @@
 			return d.pending;
 		});
 
-
 	// remove old links
 	linkLines.exit().remove();
 }
 
+updateTopology = function() {
+
+	/* currently rings.js and map.js can be included to define the topology display */
+
+	drawTopology();
+
+
+
+	/* the remainder should work regardless of the topology display */
+
+	updateLinkLines();
+
+	// setup the mouseover behaviors
+	var allSwitches = d3.selectAll('.edge, .core, .aggregation');
+
+	allSwitches.on('mouseover', mouseOverSwitch);
+	allSwitches.on('mouseout', mouseOutSwitch);
+	allSwitches.on('mouseup', mouseUpSwitch);
+	allSwitches.on('mousedown', mouseDownSwitch);
+
+	// only do switch up/down for core switches
+	d3.selectAll('.core').on('dblclick', doubleClickSwitch);
+}
+
 })();
diff --git a/web/ons-demo/js/topologyactions.js b/web/ons-demo/js/topologyactions.js
index a7ceaaa..4ba68f6 100644
--- a/web/ons-demo/js/topologyactions.js
+++ b/web/ons-demo/js/topologyactions.js
@@ -226,4 +226,46 @@
 	} else {
 		clearHighlight();
 	}
-});
\ No newline at end of file
+});
+
+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]);
+			});
+	}
+});
