diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.css b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.css
new file mode 100644
index 0000000..f1cde38
--- /dev/null
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.css
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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 GUI -- Topology View (layout) -- CSS file
+ */
+/* --- Base SVG Layer --- */
+#ov-topo2 svg {
+    /* prevents the little cut/copy/paste square that would appear on iPad */
+    -webkit-user-select: none;
+    background-color: #f4f4f4;
+}
\ No newline at end of file
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.html b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.html
new file mode 100644
index 0000000..1f6c07e
--- /dev/null
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.html
@@ -0,0 +1,92 @@
+<!--
+~ Copyright 2019-present Open Networking Foundation
+~
+~ 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.
+-->
+<!-- Template explaination - Add in the flash message component - and link it to
+the local variable - this is used to display messages when keyboard shortcuts are pressed
+-->
+<onos-flash id="topoMsgFlash" message="{{ flashMsg }}" (closed)="flashMsg = ''"></onos-flash>
+
+<onos-quickhelp id="topoQuickHelp"></onos-quickhelp>
+<!-- Template explanation - Add in the Panel components for the Topology view
+    These are referenced inside the typescript by @ViewChild and their label
+-->
+<onos-instance #instance [divTopPx]="80"
+               (mastershipEvent)="force.onosInstMastership = $event"
+               [on]="prefsState.insts">
+</onos-instance>
+<onos-summary #summary [on]="prefsState.summary"></onos-summary>
+<onos-toolbar #toolbar
+              (buttonEvent)="toolbarButtonClicked($event)"
+              [on]="prefsState.toolbar"
+              [backgroundVisible]="prefsState.bg"
+              [detailsVisible]="prefsState.detail"
+              [hostsVisible]="prefsState.hosts"
+              [instancesVisible]="prefsState.insts"
+              [portsVisible]="prefsState.porthl"
+              [summaryVisible]="prefsState.summary">
+</onos-toolbar>
+<onos-details #details [on]="prefsState.detail"></onos-details>
+<onos-mapselector *ngIf="mapSelShown" (chosenMap)="changeMap($event)"></onos-mapselector>
+
+<div id="ov-topo2">
+    <!-- Template explanation -
+    Line 0) This is the root of the whole SVG canvas of the Topology View - all
+        components beneath it are SVG components only (no HTML)
+    line 1) the No Devices Connected banner is shown if the force component
+        (from line 4) does not contain any devices
+    line 2) Create an SVG Grouping and apply the onosZoomableOf directive to it,
+        passing in the whole SVG canvas (#svgZoom)
+    line 3) Add in the Background Svg Component (if showBackground is true - toggled
+        by toolbar and by keyboard shortcut 'B'
+    line 4) Add in the layer of the Force Svg Component. If any item is selected on it, pass
+        to the details view and deselect all others. This is node and line graph
+        whose contents are supplied through the Topology Service, and whose positions
+        are driven by the d3.force engine
+    -->
+    <svg:svg #svgZoom xmlns:svg="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" id="topo2"
+        preserveAspectRatio="xMaxYMax meet">
+        <svg:desc>The main SVG canvas of the Topology View</svg:desc>
+        <svg:g *ngIf="force.regionData?.devices[0].length +
+                        force.regionData?.devices[1].length +
+                        force.regionData?.devices[2].length=== 0"
+               onos-nodeviceconnected />
+        <svg:g id="topo-zoomlayer" onosZoomableOf [zoomableOf]="svgZoom">
+            <svg:desc>A logical layer that allows the main SVG canvas to be zoomed and panned</svg:desc>
+            <svg:g #gridFull *ngIf="prefsState.grid == 1 || prefsState.grid == 3" onos-gridsvg>
+            </svg:g>
+            <svg:g #geoGrid *ngIf="prefsState.grid == 2 || prefsState.grid == 3"
+                   onos-gridsvg [horizLowerLimit]="-180" [horizUpperLimit]="180"
+                   [vertLowerLimit]="-75" [vertUpperLimit]="75" [spacing]="15"
+                   [invertVertical]="true" [fit]="'fit1000high'" [aspectRatio]="0.83333"
+                   [gridcolor]="'#bfe7fb'">
+            </svg:g>
+            <svg:g *ngIf="prefsState.bg"
+                   onos-backgroundsvg [map]="mapIdState" (zoomlevel)="mapExtentsZoom($event)">
+                <svg:desc>The Background SVG component - contains maps</svg:desc>
+            </svg:g>
+            <svg:g #force onos-forcesvg
+                   [deviceLabelToggle]="prefsState.dlbls"
+                   [hostLabelToggle]="prefsState.hlbls"
+                   [showHosts]="prefsState.hosts"
+                   [highlightPorts]="prefsState.porthl"
+                   [scale]="window.innerHeight / (window.innerWidth * zoomDirective.zoomCached.sc)"
+                   (selectedNodeEvent)="nodeSelected($event)">
+                <svg:desc>The Force SVG component - contains all the devices, hosts and links</svg:desc>
+            </svg:g>
+        </svg:g>
+    </svg:svg>
+</div>
+
+<div id="breadcrumbs"></div>
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.spec.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.spec.ts
new file mode 100644
index 0000000..b4d579d
--- /dev/null
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.spec.ts
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * 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.
+ */
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { ActivatedRoute, Params } from '@angular/router';
+import { of } from 'rxjs';
+import { HttpClient } from '@angular/common/http';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import * as d3 from 'd3';
+import { TopologyComponent } from './topology.component';
+import {
+    Instance,
+    InstanceComponent
+} from '../panel/instance/instance.component';
+import { SummaryComponent } from '../panel/summary/summary.component';
+import { ToolbarComponent } from '../panel/toolbar/toolbar.component';
+import { DetailsComponent } from '../panel/details/details.component';
+import { TopologyService } from '../topology.service';
+
+import {
+    FlashComponent,
+    QuickhelpComponent,
+    FnService,
+    LogService,
+    IconService, IconComponent, PrefsService, KeysService, LionService
+} from 'gui2-fw-lib';
+import {ZoomableDirective} from '../layer/zoomable.directive';
+import {RouterTestingModule} from '@angular/router/testing';
+import {TrafficService} from '../traffic.service';
+import {ForceSvgComponent} from '../layer/forcesvg/forcesvg.component';
+import {DraggableDirective} from '../layer/forcesvg/draggable/draggable.directive';
+import {MapSelectorComponent} from '../panel/mapselector/mapselector.component';
+import {BackgroundSvgComponent} from '../layer/backgroundsvg/backgroundsvg.component';
+import {FormsModule, ReactiveFormsModule} from '@angular/forms';
+import {MapSvgComponent} from '../layer/mapsvg/mapsvg.component';
+import {GridsvgComponent} from '../layer/gridsvg/gridsvg.component';
+import {LinkSvgComponent} from '../layer/forcesvg/visuals/linksvg/linksvg.component';
+import {DeviceNodeSvgComponent} from '../layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component';
+import {SubRegionNodeSvgComponent} from '../layer/forcesvg/visuals/subregionnodesvg/subregionnodesvg.component';
+import {HostNodeSvgComponent} from '../layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component';
+
+
+class MockActivatedRoute extends ActivatedRoute {
+    constructor(params: Params) {
+        super();
+        this.queryParams = of(params);
+    }
+}
+
+class MockHttpClient {}
+
+class MockTopologyService {
+    init(instance: InstanceComponent) {
+        instance.onosInstances = [
+            <Instance>{
+                'id': 'inst1',
+                'ip': '127.0.0.1',
+                'reachable': true,
+                'online': true,
+                'ready': true,
+                'switches': 4,
+                'uiAttached': true
+            },
+            <Instance>{
+                'id': 'inst1',
+                'ip': '127.0.0.2',
+                'reachable': true,
+                'online': true,
+                'ready': true,
+                'switches': 3,
+                'uiAttached': false
+            }
+        ];
+    }
+    destroy() {}
+}
+
+class MockIconService {
+    loadIconDef() { }
+}
+
+class MockKeysService {
+    quickHelpShown: boolean = true;
+
+    keyBindings(x) {
+        return {};
+    }
+
+    gestureNotes() {
+        return {};
+    }
+}
+
+class MockTrafficService {}
+
+class MockPrefsService {
+    listeners: ((data) => void)[] = [];
+
+    getPrefs() {
+        return { 'topo2_prefs': ''};
+    }
+
+    addListener(listener: (data) => void): void {
+        this.listeners.push(listener);
+    }
+
+    removeListener(listener: (data) => void) {
+        this.listeners = this.listeners.filter((obj) => obj !== listener);
+    }
+
+    setPrefs(name: string, obj: Object) {
+
+    }
+
+}
+
+/**
+ * ONOS GUI -- Topology View -- Unit Tests
+ */
+describe('TopologyComponent', () => {
+    let fs: FnService;
+    let ar: MockActivatedRoute;
+    let windowMock: Window;
+    let logServiceSpy: jasmine.SpyObj<LogService>;
+    let component: TopologyComponent;
+    let fixture: ComponentFixture<TopologyComponent>;
+
+    const bundleObj = {
+        'core.fw.QuickHelp': {
+            test: 'test1',
+            tt_help: 'Help!'
+        }
+    };
+    const mockLion = (key) =>  {
+        return bundleObj[key] || '%' + key + '%';
+    };
+
+    beforeEach(async(() => {
+        const logSpy = jasmine.createSpyObj('LogService', ['info', 'debug', 'warn', 'error']);
+        ar = new MockActivatedRoute({ 'debug': 'txrx' });
+
+        windowMock = <any>{
+            location: <any>{
+                hostname: 'foo',
+                host: 'foo',
+                port: '80',
+                protocol: 'http',
+                search: { debug: 'true' },
+                href: 'ws://foo:123/onos/ui/websock/path',
+                absUrl: 'ws://foo:123/onos/ui/websock/path'
+            }
+        };
+        fs = new FnService(ar, logSpy, windowMock);
+
+        TestBed.configureTestingModule({
+            imports: [
+                BrowserAnimationsModule,
+                RouterTestingModule,
+                FormsModule,
+                ReactiveFormsModule
+            ],
+            declarations: [
+                TopologyComponent,
+                InstanceComponent,
+                SummaryComponent,
+                ToolbarComponent,
+                DetailsComponent,
+                FlashComponent,
+                ZoomableDirective,
+                IconComponent,
+                QuickhelpComponent,
+                ForceSvgComponent,
+                LinkSvgComponent,
+                DeviceNodeSvgComponent,
+                HostNodeSvgComponent,
+                DraggableDirective,
+                ZoomableDirective,
+                SubRegionNodeSvgComponent,
+                MapSelectorComponent,
+                BackgroundSvgComponent,
+                MapSvgComponent,
+                GridsvgComponent
+            ],
+            providers: [
+                { provide: FnService, useValue: fs },
+                { provide: LogService, useValue: logSpy },
+                { provide: 'Window', useValue: windowMock },
+                { provide: HttpClient, useClass: MockHttpClient },
+                { provide: TopologyService, useClass: MockTopologyService },
+                { provide: TrafficService, useClass: MockTrafficService },
+                { provide: IconService, useClass: MockIconService },
+                { provide: PrefsService, useClass: MockPrefsService },
+                { provide: KeysService, useClass: MockKeysService },
+                { provide: LionService, useFactory: (() => {
+                        return {
+                            bundle: ((bundleId) => mockLion),
+                            ubercache: new Array(),
+                            loadCbs: new Map<string, () => void>([])
+                        };
+                    })
+                },
+            ]
+        }).compileComponents();
+        logServiceSpy = TestBed.get(LogService);
+    }));
+
+    beforeEach(() => {
+        fixture = TestBed.createComponent(TopologyComponent);
+        component = fixture.componentInstance;
+
+        fixture.detectChanges();
+    });
+
+    it('should create', () => {
+        expect(component).toBeTruthy();
+    });
+});
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.ts
new file mode 100644
index 0000000..d7055a4
--- /dev/null
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.ts
@@ -0,0 +1,674 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * 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.
+ */
+import {
+    AfterContentInit,
+    Component, HostListener, Inject, Input,
+    OnDestroy,
+    OnInit, SimpleChange,
+    ViewChild
+} from '@angular/core';
+import * as d3 from 'd3';
+import {
+    FnService, IconService,
+    KeysService,
+    KeysToken, LionService,
+    LogService,
+    PrefsService,
+    SvgUtilService,
+    WebSocketService,
+    TopoZoomPrefs, ZoomUtils
+} from 'gui2-fw-lib';
+import {InstanceComponent} from '../panel/instance/instance.component';
+import {DetailsComponent} from '../panel/details/details.component';
+import {BackgroundSvgComponent} from '../layer/backgroundsvg/backgroundsvg.component';
+import {ForceSvgComponent} from '../layer/forcesvg/forcesvg.component';
+import {TopologyService} from '../topology.service';
+import {
+    GridDisplayToggle,
+    HostLabelToggle,
+    LabelToggle,
+    UiElement
+} from '../layer/forcesvg/models';
+import {
+    INSTANCE_TOGGLE, SUMMARY_TOGGLE, DETAILS_TOGGLE,
+    HOSTS_TOGGLE, OFFLINE_TOGGLE, PORTS_TOGGLE,
+    BKGRND_TOGGLE, CYCLELABELS_BTN, CYCLEHOSTLABEL_BTN,
+    CYCLEGRIDDISPLAY_BTN, RESETZOOM_BTN, EQMASTER_BTN,
+    CANCEL_TRAFFIC, ALL_TRAFFIC, QUICKHELP_BTN, BKGRND_SELECT
+} from '../panel/toolbar/toolbar.component';
+import {TrafficService} from '../traffic.service';
+import {ZoomableDirective} from '../layer/zoomable.directive';
+import {MapObject} from '../layer/maputils';
+
+const TOPO2_PREFS = 'topo2_prefs';
+const TOPO_MAPID_PREFS = 'topo_mapid';
+
+const PREF_BG = 'bg';
+const PREF_DETAIL = 'detail';
+const PREF_DLBLS = 'dlbls';
+const PREF_HLBLS = 'hlbls';
+const PREF_GRID = 'grid';
+const PREF_HOSTS = 'hosts';
+const PREF_INSTS = 'insts';
+const PREF_OFFDEV = 'offdev';
+const PREF_PORTHL = 'porthl';
+const PREF_SUMMARY = 'summary';
+const PREF_TOOLBAR = 'toolbar';
+
+/**
+ * Model of the topo2_prefs object - this is a subset of the overall Prefs returned
+ * by the server
+ */
+export interface Topo2Prefs {
+    bg: number;
+    detail: number;
+    dlbls: number;
+    hlbls: number;
+    hosts: number;
+    insts: number;
+    offdev: number;
+    porthl: number;
+    spr: number;
+    ovid: string;
+    summary: number;
+    toolbar: number;
+    grid: number;
+}
+
+/**
+ * ONOS GUI Topology View
+ *
+ * This Topology View component is the top level component in a hierarchy that
+ * comprises the whole Topology View
+ *
+ * There are three main parts (panels, graphical and breadcrumbs)
+ * The panel hierarchy
+ * |-- Instances Panel (shows ONOS instances)
+ * |-- Summary Panel (summary of ONOS)
+ * |-- Toolbar Panel (the toolbar)
+ * |-- Details Panel (when a node is selected in the Force graphical view (see below))
+ *
+ * The graphical hierarchy contains
+ * Topology (this)
+ *  |-- No Devices Connected (only of there are no nodes to show)
+ *  |-- Zoom Layer (everything beneath this can be zoomed and panned)
+ *      |-- Background (container for any backgrounds - can be toggled on and off)
+ *          |-- Map
+ *      |-- Forces (all of the nodes and links laid out by a d3.force simulation)
+ *
+ * The breadcrumbs
+ * |-- Breadcrumb (in region view a way of navigating back up through regions)
+ */
+@Component({
+  selector: 'onos-topology',
+  templateUrl: './topology.component.html',
+  styleUrls: ['./topology.component.css']
+})
+export class TopologyComponent implements AfterContentInit, OnInit, OnDestroy {
+    @Input() bannerHeight: number = 48;
+    // These are references to the components inserted in the template
+    @ViewChild(InstanceComponent) instance: InstanceComponent;
+    @ViewChild(DetailsComponent) details: DetailsComponent;
+    @ViewChild(BackgroundSvgComponent) background: BackgroundSvgComponent;
+    @ViewChild(ForceSvgComponent) force: ForceSvgComponent;
+    @ViewChild(ZoomableDirective) zoomDirective: ZoomableDirective;
+
+    flashMsg: string = '';
+    // These are used as defaults if nothing is set on the server
+    prefsState: Topo2Prefs = <Topo2Prefs>{
+        bg: 0,
+        detail: 1,
+        dlbls: 0,
+        hlbls: 2,
+        hosts: 0,
+        insts: 1,
+        offdev: 1,
+        ovid: 'traffic', // default to traffic overlay
+        porthl: 1,
+        spr: 0,
+        summary: 1,
+        toolbar: 0,
+        grid: 0
+    };
+
+    mapIdState: MapObject = <MapObject>{
+        id: undefined,
+        scale: 1.0
+    };
+    mapSelShown: boolean = false;
+    lionFn; // Function
+
+    gridShown: boolean = true;
+    geoGridShown: boolean = true;
+
+    constructor(
+        protected log: LogService,
+        protected fs: FnService,
+        protected ks: KeysService,
+        protected sus: SvgUtilService,
+        protected ps: PrefsService,
+        protected wss: WebSocketService,
+        protected ts: TopologyService,
+        protected trs: TrafficService,
+        protected is: IconService,
+        private lion: LionService,
+        @Inject('Window') public window: any,
+    ) {
+        if (this.lion.ubercache.length === 0) {
+            this.lionFn = this.dummyLion;
+            this.lion.loadCbs.set('topo-toolbar', () => this.doLion());
+        } else {
+            this.doLion();
+        }
+
+        this.is.loadIconDef('bird');
+        this.is.loadIconDef('active');
+        this.is.loadIconDef('uiAttached');
+        this.is.loadIconDef('m_switch');
+        this.is.loadIconDef('m_roadm');
+        this.is.loadIconDef('m_router');
+        this.is.loadIconDef('m_uiAttached');
+        this.is.loadIconDef('m_endstation');
+        this.is.loadIconDef('m_ports');
+        this.is.loadIconDef('m_summary');
+        this.is.loadIconDef('m_details');
+        this.is.loadIconDef('m_map');
+        this.is.loadIconDef('m_selectMap');
+        this.is.loadIconDef('m_cycleLabels');
+        this.is.loadIconDef('m_cycleGridDisplay');
+        this.is.loadIconDef('m_resetZoom');
+        this.is.loadIconDef('m_eqMaster');
+        this.is.loadIconDef('m_unknown');
+        this.is.loadIconDef('m_allTraffic');
+        this.is.loadIconDef('deviceTable');
+        this.is.loadIconDef('flowTable');
+        this.is.loadIconDef('portTable');
+        this.is.loadIconDef('groupTable');
+        this.is.loadIconDef('meterTable');
+        this.is.loadIconDef('triangleUp');
+        this.log.debug('Topology component constructed');
+    }
+
+    /**
+     * Static functions must come before member variables
+     * @param index Corresponds to LabelToggle.Enum index
+     */
+    private static deviceLabelFlashMessage(index: number): string {
+        switch (index) {
+            case 0: return 'fl_device_labels_hide';
+            case 1: return 'fl_device_labels_show_friendly';
+            case 2: return 'fl_device_labels_show_id';
+        }
+    }
+
+    private static hostLabelFlashMessage(index: number): string {
+        switch (index) {
+            case 0: return 'fl_host_labels_hide';
+            case 1: return 'fl_host_labels_show_friendly';
+            case 2: return 'fl_host_labels_show_ip';
+            case 3: return 'fl_host_labels_show_mac';
+        }
+    }
+
+    private static gridDisplayFlashMessage(index: number): string {
+        switch (index) {
+            case 0: return 'fl_grid_display_hide';
+            case 1: return 'fl_grid_display_1000';
+            case 2: return 'fl_grid_display_geo';
+            case 3: return 'fl_grid_display_both';
+        }
+    }
+
+    /**
+     * Pass the list of Key Commands to the KeyService, and initialize the Topology
+     * Service - which communicates with through the WebSocket to the ONOS server
+     * to get the nodes and links.
+     */
+    ngOnInit() {
+        this.bindCommands();
+        // The components from the template are handed over to TopologyService here
+        // so that WebSocket responses can be passed back in to them
+        // The handling of the WebSocket call is delegated out to the Topology
+        // Service just to compartmentalize things a bit
+        this.ts.init(this.instance, this.background, this.force);
+
+        this.ps.addListener((data) => this.prefsUpdateHandler(data));
+        this.prefsState = this.ps.getPrefs(TOPO2_PREFS, this.prefsState);
+        this.mapIdState = this.ps.getPrefs(TOPO_MAPID_PREFS, this.mapIdState);
+
+        this.log.debug('Topology component initialized');
+    }
+
+    ngAfterContentInit(): void {
+        // Scale the window initially - then after resize
+        const zoomMapExtents = ZoomUtils.zoomToWindowSize(
+            this.bannerHeight, this.window.innerWidth, this.window.innerHeight);
+        this.zoomDirective.changeZoomLevel(zoomMapExtents, true);
+        this.log.debug('Topology zoom initialized',
+            this.bannerHeight, this.window.innerWidth, this.window.innerHeight,
+            zoomMapExtents);
+    }
+
+    /**
+     * Callback function that's called whenever new Prefs are received from WebSocket
+     *
+     * Note: At present the backend server does not filter updated by logged in user,
+     * so you might get updates pertaining to a different user
+     */
+    prefsUpdateHandler(data: any): void {
+        // Extract the TOPO2 prefs from it
+        if (data[TOPO2_PREFS]) {
+            this.prefsState = data[TOPO2_PREFS];
+        }
+        this.log.debug('Updated topo2 prefs', this.prefsState, this.mapIdState);
+    }
+
+    /**
+     * When this component is being stopped, disconnect the TopologyService from
+     * the WebSocket
+     */
+    ngOnDestroy() {
+        this.ts.destroy();
+        this.ps.removeListener((data) => this.prefsUpdateHandler(data));
+        this.log.debug('Topology component destroyed');
+    }
+
+    @HostListener('window:resize', ['$event'])
+    onResize(event) {
+        const zoomMapExtents = ZoomUtils.zoomToWindowSize(
+                this.bannerHeight, event.target.innerWidth, event.target.innerHeight);
+        this.zoomDirective.changeZoomLevel(zoomMapExtents, true);
+        this.log.debug('Topology window resize',
+            event.target.innerWidth, event.target.innerHeight, this.bannerHeight, zoomMapExtents);
+    }
+
+    /**
+     * When ever a toolbar button is clicked, an event is sent up from toolbar
+     * component which is caught and passed on to here.
+     * @param name The name of the button that was clicked
+     */
+    toolbarButtonClicked(name: string) {
+        switch (name) {
+            case INSTANCE_TOGGLE:
+                this.toggleInstancePanel();
+                break;
+            case SUMMARY_TOGGLE:
+                this.toggleSummary();
+                break;
+            case DETAILS_TOGGLE:
+                this.toggleDetails();
+                break;
+            case HOSTS_TOGGLE:
+                this.toggleHosts();
+                break;
+            case OFFLINE_TOGGLE:
+                this.toggleOfflineDevices();
+                break;
+            case PORTS_TOGGLE:
+                this.togglePorts();
+                break;
+            case BKGRND_TOGGLE:
+                this.toggleBackground();
+                break;
+            case BKGRND_SELECT:
+                this.mapSelShown = !this.mapSelShown;
+                break;
+            case CYCLELABELS_BTN:
+                this.cycleDeviceLabels();
+                break;
+            case CYCLEHOSTLABEL_BTN:
+                this.cycleHostLabels();
+                break;
+            case CYCLEGRIDDISPLAY_BTN:
+                this.cycleGridDisplay();
+                break;
+            case RESETZOOM_BTN:
+                this.resetZoom();
+                break;
+            case EQMASTER_BTN:
+                this.equalizeMasters();
+                break;
+            case CANCEL_TRAFFIC:
+                this.cancelTraffic();
+                break;
+            case ALL_TRAFFIC:
+                this.monitorAllTraffic();
+                break;
+            case QUICKHELP_BTN:
+                this.ks.quickHelpShown = true;
+                break;
+            default:
+                this.log.warn('Unhandled Toolbar action', name);
+        }
+    }
+
+    /**
+     * The list of key strokes that will be active in the Topology View.
+     *
+     * This action map is passed to the KeyService through the bindCommands()
+     * when this component is being initialized
+     */
+    actionMap() {
+        return {
+            A: [() => {this.monitorAllTraffic(); }, 'Monitor all traffic'],
+            B: [(token) => {this.toggleBackground(token); }, 'Toggle background'],
+            D: [(token) => {this.toggleDetails(token); }, 'Toggle details panel'],
+            E: [() => {this.equalizeMasters(); }, 'Equalize mastership roles'],
+            H: [() => {this.toggleHosts(); }, 'Toggle host visibility'],
+            I: [(token) => {this.toggleInstancePanel(token); }, 'Toggle ONOS Instance Panel'],
+            G: [() => {this.mapSelShown = !this.mapSelShown; }, 'Show map selection dialog'],
+            L: [() => {this.cycleDeviceLabels(); }, 'Cycle device labels'],
+            M: [() => {this.toggleOfflineDevices(); }, 'Toggle offline visibility'],
+            O: [() => {this.toggleSummary(); }, 'Toggle the Summary Panel'],
+            P: [(token) => {this.togglePorts(token); }, 'Toggle Port Highlighting'],
+            Q: [() => {this.cycleGridDisplay(); }, 'Cycle grid display'],
+            R: [() => {this.resetZoom(); }, 'Reset pan / zoom'],
+            U: [() => {this.unpinNode(); }, 'Unpin node (mouse over)'],
+            X: [() => {this.resetNodeLocation(); }, 'Reset Node Location'],
+            dot: [() => {this.toggleToolbar(); }, 'Toggle Toolbar'],
+            0: [() => {this.cancelTraffic(); }, 'Cancel traffic monitoring'],
+            'shift-L': [() => {this.cycleHostLabels(); }, 'Cycle host labels'],
+
+            // -- instance color palette debug
+            9: () => {
+                this.sus.cat7().testCard(d3.select('svg#topo2'));
+            },
+
+            esc: [() => {this.handleEscape(); }, 'Cancel commands'],
+
+            // TODO update after adding in Background Service
+            // topology overlay selections
+            // F1: function () { t2tbs.fnKey(0); },
+            // F2: function () { t2tbs.fnKey(1); },
+            // F3: function () { t2tbs.fnKey(2); },
+            // F4: function () { t2tbs.fnKey(3); },
+            // F5: function () { t2tbs.fnKey(4); },
+            //
+            // _keyListener: t2tbs.keyListener.bind(t2tbs),
+
+            _helpFormat: [
+                ['I', 'O', 'D', 'H', 'M', 'P', 'dash', 'B'],
+                ['X', 'Z', 'N', 'L', 'shift-L', 'U', 'R', 'E', 'dot'],
+                [], // this column reserved for overlay actions
+            ],
+        };
+    }
+
+
+    bindCommands(additional?: any) {
+
+        const am = this.actionMap();
+        const add = this.fs.isO(additional);
+
+        this.ks.keyBindings(am);
+
+        this.ks.gestureNotes([
+            ['click', 'Select the item and show details'],
+            ['shift-click', 'Toggle selection state'],
+            ['drag', 'Reposition (and pin) device / host'],
+            ['cmd-scroll', 'Zoom in / out'],
+            ['cmd-drag', 'Pan'],
+        ]);
+    }
+
+    handleEscape() {
+
+        if (false) {
+            // TODO: Cancel show mastership
+            // TODO: Cancel Active overlay
+            // TODO: Reinstate with components
+        } else {
+            this.nodeSelected(undefined);
+            this.log.debug('Handling escape');
+            // } else if (t2rs.deselectAllNodes()) {
+            //     // else if we have node selections, deselect them all
+            //     // (work already done)
+            // } else if (t2rs.deselectLink()) {
+            //     // else if we have a link selection, deselect it
+            //     // (work already done)
+            // } else if (t2is.isVisible()) {
+            //     // If the instance panel is visible, close it
+            //     t2is.toggle();
+            // } else if (t2sp.isVisible()) {
+            //     // If the summary panel is visible, close it
+            //     t2sp.toggle();
+        }
+    }
+
+    /**
+     * Updates the cache of preferences locally and onwards to the PrefsService
+     * @param what The attribute of the local topo2-prefs cache to update
+     * @param b the value to update it with
+     */
+    updatePrefsState(what: string, b: number) {
+        this.prefsState[what] = b;
+        this.ps.setPrefs(TOPO2_PREFS, this.prefsState);
+    }
+
+    /**
+     * When the button is clicked on the toolbar or the L key is pressed
+     * 1) cycle through options
+     * 2) flash up a message
+     * 3a) Update the local prefs cache
+     * 3b) And passes on to the global prefs service which sends back to the server
+     * 3c) It also has a knock on effect of passing it on to ForceSvgComponent
+     *      because prefsState.dlbls is given as an input to it
+     * 3d) This will in turn pass it down to the DeviceSvgComponent which
+     *       displays the label
+     */
+    protected cycleDeviceLabels() {
+        const old: LabelToggle.Enum = this.prefsState.dlbls;
+        const next = LabelToggle.next(old);
+        this.flashMsg = this.lionFn(TopologyComponent.deviceLabelFlashMessage(next));
+        this.updatePrefsState(PREF_DLBLS, next);
+        this.log.debug('Cycling device labels', old, next);
+    }
+
+    protected cycleHostLabels() {
+        const old: HostLabelToggle.Enum = this.prefsState.hlbls;
+        const next = HostLabelToggle.next(old);
+        this.flashMsg = this.lionFn(TopologyComponent.hostLabelFlashMessage(next));
+        this.updatePrefsState(PREF_HLBLS, next);
+        this.log.debug('Cycling host labels', old, next);
+    }
+
+    protected cycleGridDisplay() {
+        const old: GridDisplayToggle.Enum = this.prefsState.grid;
+        const next = GridDisplayToggle.next(old);
+        this.flashMsg = this.lionFn(TopologyComponent.gridDisplayFlashMessage(next));
+        this.updatePrefsState(PREF_GRID, next);
+        this.log.debug('Cycling grid display', old, next);
+    }
+
+    /**
+     * When the button is clicked on the toolbar or the B key is pressed
+     * 1) Find the inverse of the current state (held as 1 or 0)
+     * 2) Flash up a message on screen
+     * 3b) And passes on to the global prefs service which sends back to the server
+     * 3c) It also has a knock on effect of passing it on to ToolbarComponent
+     *      because prefsState.bg is given as an input to it
+     * @param token not currently used
+     */
+    protected toggleBackground(token?: KeysToken) {
+        const bg: boolean = !Boolean(this.prefsState.bg);
+        this.flashMsg = this.lionFn(bg ? 'show' : 'hide') +
+            ' ' + this.lionFn('fl_background_map');
+        this.updatePrefsState(PREF_BG, bg ? 1 : 0);
+        this.log.debug('Toggling background', token, bg ? 'shown' : 'hidden');
+    }
+
+    protected toggleDetails(token?: KeysToken) {
+        const on: boolean = !Boolean(this.prefsState.detail);
+        this.flashMsg = this.lionFn(on ? 'show' : 'hide') +
+            ' ' + this.lionFn('fl_panel_details');
+        this.updatePrefsState(PREF_DETAIL, on ? 1 : 0);
+        this.log.debug('Toggling details', token);
+    }
+
+    protected toggleInstancePanel(token?: KeysToken) {
+        const on: boolean = !Boolean(this.prefsState.insts);
+        this.flashMsg = this.lionFn(on ? 'show' : 'hide') +
+            ' ' + this.lionFn('fl_panel_instances');
+        this.updatePrefsState(PREF_INSTS, on ? 1 : 0);
+        this.log.debug('Toggling instances', token, on);
+    }
+
+    protected toggleSummary() {
+        const on: boolean = !Boolean(this.prefsState.summary);
+        this.flashMsg = this.lionFn(on ? 'show' : 'hide') +
+            ' ' + this.lionFn('fl_panel_summary');
+        this.updatePrefsState(PREF_SUMMARY, on ? 1 : 0);
+    }
+
+    protected togglePorts(token?: KeysToken) {
+        const current: boolean = !Boolean(this.prefsState.porthl);
+        this.flashMsg = this.lionFn(current ? 'enable' : 'disable') +
+            ' ' + this.lionFn('fl_port_highlighting');
+        this.updatePrefsState(PREF_PORTHL, current ? 1 : 0);
+        this.log.debug(current ? 'Enable' : 'Disable', 'port highlighting');
+    }
+
+    protected toggleToolbar() {
+        const on: boolean = !Boolean(this.prefsState.toolbar);
+        this.updatePrefsState(PREF_TOOLBAR, on ? 1 : 0);
+        this.log.debug('toggling toolbar', on ? 'shown' : 'hidden');
+    }
+
+    protected toggleHosts() {
+        const current: boolean = !Boolean(this.prefsState.hosts);
+        this.flashMsg = this.lionFn('hosts') + ' ' +
+                        this.lionFn(this.force.showHosts ? 'visible' : 'hidden');
+        this.updatePrefsState(PREF_HOSTS, current ? 1 : 0);
+        this.log.debug('toggling hosts: ', this.prefsState.hosts ? 'Show' : 'Hide');
+    }
+
+    protected toggleOfflineDevices() {
+        const on: boolean = !Boolean(this.prefsState.offdev);
+        this.flashMsg = this.lionFn(on ? 'show' : 'hide') +
+            ' ' + this.lionFn('fl_offline_devices');
+        this.updatePrefsState(PREF_OFFDEV, on ? 1 : 0);
+        this.log.debug('toggling offline devices', this.prefsState.offdev);
+    }
+
+    protected resetZoom() {
+        const zoomMapExtents = ZoomUtils.zoomToWindowSize(
+            this.bannerHeight, this.window.innerWidth, this.window.innerHeight);
+        this.zoomDirective.changeZoomLevel(zoomMapExtents, false);
+        this.flashMsg = this.lionFn('fl_pan_zoom_reset');
+    }
+
+    protected equalizeMasters() {
+        this.wss.sendEvent('equalizeMasters', null);
+        this.flashMsg = this.lionFn('fl_eq_masters');
+        this.log.debug('equalizing masters');
+    }
+
+    protected resetNodeLocation() {
+        // TODO: Implement reset locations
+        this.force.resetNodeLocations();
+        this.flashMsg = this.lionFn('fl_reset_node_locations');
+        this.log.debug('resetting node location');
+    }
+
+    protected unpinNode() {
+        // TODO: Implement this
+        this.log.debug('unpinning node');
+    }
+
+    /**
+     * Check to see if this is needed anymore
+     * @param what - a key stroke
+     */
+    protected notValid(what) {
+        this.log.warn('topo.js getActionEntry(): Not a valid ' + what);
+    }
+
+    /**
+     * Check to see if this is needed anymore
+     * @param key - a key stroke
+     */
+    getActionEntry(key) {
+        let entry;
+
+        if (!key) {
+            this.notValid('key');
+            return null;
+        }
+
+        entry = this.actionMap()[key];
+
+        if (!entry) {
+            this.notValid('actionMap (' + key + ') entry');
+            return null;
+        }
+        return this.fs.isA(entry) || [entry, ''];
+    }
+
+    /**
+     * An event handler that updates the details panel as items are
+     * selected in the forcesvg layer
+     * @param nodeOrLink the item to display details of
+     */
+    nodeSelected(nodeOrLink: UiElement) {
+        this.details.ngOnChanges({'selectedNode':
+            new SimpleChange(undefined, nodeOrLink, true)});
+    }
+
+    /**
+     * Enable traffic monitoring
+     */
+    monitorAllTraffic() {
+        // TODO: Implement support for toggling between bits, packets and octets
+        this.flashMsg = this.lionFn('tr_fl_pstats_bits');
+        this.trs.init(this.force);
+    }
+
+    /**
+     * Cancel traffic monitoring
+     */
+    cancelTraffic() {
+        this.flashMsg = this.lionFn('fl_monitoring_canceled');
+        this.trs.destroy();
+    }
+
+    changeMap(map: MapObject) {
+        this.mapSelShown = false; // Hide the MapSelector component
+        this.mapIdState = map;
+        this.ps.setPrefs(TOPO_MAPID_PREFS, this.mapIdState);
+        this.log.debug('Map has been changed to ', map);
+    }
+
+    mapExtentsZoom(zoomMapExtents: TopoZoomPrefs) {
+        // this.zoomDirective.updateZoomState(zoomPrefs.tx, zoomPrefs.ty, zoomPrefs.sc);
+        this.zoomDirective.changeZoomLevel(zoomMapExtents);
+        this.log.debug('Map zoom prefs updated', zoomMapExtents);
+    }
+
+    /**
+     * Read the LION bundle for Toolbar and set up the lionFn
+     */
+    doLion() {
+        this.lionFn = this.lion.bundle('core.view.Topo');
+    }
+
+    /**
+     * A dummy implementation of the lionFn until the response is received and the LION
+     * bundle is received from the WebSocket
+     */
+    dummyLion(key: string): string {
+        return '%' + key + '%';
+    }
+}
