GUI2 add in support for Preferences Service

Change-Id: Icdf2165d9f638aeff1b110a64777b93295935ed2
diff --git a/web/gui/BUILD b/web/gui/BUILD
index 77fa7f7..f8b70c8 100644
--- a/web/gui/BUILD
+++ b/web/gui/BUILD
@@ -210,14 +210,24 @@
 genrule(
     name = "onos-gui-java-for-gui2",
     srcs = glob([
-        "src/main/java/org/onosproject/ui/impl/Main*Resource.java",
-        "src/main/java/org/onosproject/ui/impl/ApplicationResource.java",
+        "src/main/java/org/onosproject/ui/impl/**/*.java",
     ]),
     outs = ["onos-gui-java-for-gui2.srcjar"],
     cmd = "jar cf $@ $(SRCS)",
     visibility = ["//visibility:public"],
 )
 
+genrule(
+    name = "onos-gui-lion-for-gui2",
+    srcs = glob([
+        "src/main/resources/org/onosproject/ui/lion/**/*",
+        "src/main/resources/core/**/*",
+    ]),
+    outs = ["onos-gui-lion-for-gui2.srcjar"],
+    cmd = "jar cf $@ $(SRCS)",
+    visibility = ["//visibility:public"],
+)
+
 """
     Builds the tar ball for the ONOS GUI
 """
diff --git a/web/gui2-fw-lib/BUILD b/web/gui2-fw-lib/BUILD
index 667814f..b47749b 100644
--- a/web/gui2-fw-lib/BUILD
+++ b/web/gui2-fw-lib/BUILD
@@ -281,8 +281,14 @@
           " export PATH=$$ROOT/$$(dirname $${NODE}):$$ROOT/web/gui2-fw-lib/node_modules/@angular/cli/bin:$$PATH &&" +
           " node -v > ../../$(location onos-gui2-fw-ng-ver.log) &&" +
           " npm -v >> ../../$(location onos-gui2-fw-ng-ver.log) &&" +
-          " ng version >> ../../$(location onos-gui2-fw-ng-ver.log) &&" +
-          " ng lint gui2-fw-lib > ../../$(location onos-gui2-fw-ng-lint.log);" +
+          " ng version >> ../../$(location onos-gui2-fw-ng-ver.log);" +
+          " ng lint gui2-fw-lib > ../../$(location onos-gui2-fw-ng-lint.log) 2>&1 ||" +
+          " if [ $$? -eq 0 ]; then echo 'Successfully ran lint';" +
+          " else " +
+          "   echo 'Error running \'ng lint\' on \'//web/gui2-fw-lib:_onos-gui2-fw-ng-test\'. \\\n" +
+          "     See bazel-genfiles/web/gui2-fw-lib/onos-gui2-fw-ng-lint.log for more details' >&2;" +
+          "   exit 1;" +
+          " fi;" +
           " if [ -f /usr/bin/chromium-browser ]; then " +  # Add to this for Mac and Chrome
           "   export CHROME_BIN=/usr/bin/chromium-browser; " +
           " elif [ -f /opt/google/chrome/chrome ]; then " +
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/gui2-fw-lib.module.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/gui2-fw-lib.module.ts
index 6004bce..f213ca1 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/gui2-fw-lib.module.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/gui2-fw-lib.module.ts
@@ -23,6 +23,7 @@
 import { MastComponent } from './mast/mast/mast.component';
 import { TableFilterPipe } from './widget/tablefilter.pipe';
 import { TableResizeDirective } from './widget/tableresize.directive';
+import { QuickhelpComponent } from './layer/quickhelp/quickhelp.component';
 
 @NgModule({
   imports: [
@@ -35,6 +36,7 @@
     VeilComponent,
     FlashComponent,
     ConfirmComponent,
+    QuickhelpComponent,
     MastComponent,
     TableFilterPipe
   ],
@@ -45,6 +47,7 @@
     VeilComponent,
     FlashComponent,
     ConfirmComponent,
+    QuickhelpComponent,
     MastComponent,
     TableFilterPipe
   ]
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/layer/quickhelp/quickhelp.component.css b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/layer/quickhelp/quickhelp.component.css
new file mode 100644
index 0000000..26c1643
--- /dev/null
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/layer/quickhelp/quickhelp.component.css
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2016-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 -- Quickhelp Panel -- CSS file
+ */
+
+/*
+ ONOS GUI -- Quick Help Service (layout) -- CSS file
+ */
+
+#quickhelp {
+    top: 100px;
+    z-index: 5000;
+    position: relative;
+}
+
+#quickhelp div.help {
+    background: black;
+    opacity: 0.8;
+}
+
+#quickhelp div.help table {
+    vertical-align: top;
+}
+
+#quickhelp div.help p {
+    text-align: center;
+    color: white;
+    font-weight: bold;
+}
+
+#quickhelp td.key {
+    color: #add;
+    padding-left: 8px;
+    padding-right: 4px;
+}
+
+#quickhelp td.desc {
+    color: white;
+}
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/layer/quickhelp/quickhelp.component.html b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/layer/quickhelp/quickhelp.component.html
new file mode 100644
index 0000000..d387284
--- /dev/null
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/layer/quickhelp/quickhelp.component.html
@@ -0,0 +1,160 @@
+<!--
+~ 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.
+-->
+<div id="quickhelp" [@quickHelpState]="ks.quickHelpShown">
+    <div class="help" *ngIf="ks.quickHelpShown">
+        <p class="title">{{lionFn("qh_title")}}</p>
+        <!-- TODO: drive this through the keys service keyHandler -->
+        <table class="qhrow">
+            <tr>
+                <td class="key">&#92;</td>
+                <td class="desc">Afficher/cacher l'aide rapide</td>
+            </tr>
+            <tr>
+                <td class="key">/</td>
+                <td class="desc">Afficher/cacher l'aide rapide</td>
+            </tr>
+            <tr>
+                <td class="key">Esc</td>
+                <td class="desc">ignorer la boîte de dialogue ou annuler les
+                    sélections
+                </td>
+            </tr>
+            <tr>
+                <td class="key">T</td>
+                <td class="desc">basculer de thème</td>
+            </tr>
+        </table>
+        <hr class="qhrowsep">
+        <table class="qhrow">
+            <tr>
+                <td class="key">I</td>
+                <td class="desc">Basculer au panneau de instance
+                    ONOS
+                </td>
+                <td class="key">O</td>
+                <td class="desc">Baculer au panneau récapitulatif
+                    ONOS
+                </td>
+                <td class="key">D</td>
+                <td class="desc">Basculer le panneau de détails</td>
+            </tr>
+            <tr>
+                <td class="key">H</td>
+                <td class="desc">Basculer la visibilité de l'hôte
+                </td>
+                <td class="key">M</td>
+                <td class="desc">Basculer la visibilité hors-ligne
+                </td>
+                <td class="key">P</td>
+                <td class="desc">Basculer le port mis en évidence
+                </td>
+            </tr>
+            <tr>
+                <td class="key">Dash</td>
+                <td class="desc">Montrer les mauvais liens</td>
+                <td class="key">B</td>
+                <td class="desc">Basculer la carte géo de fond</td>
+                <td class="key">G</td>
+                <td class="desc">Sélectionner la carte géo de fond
+                </td>
+            </tr>
+            <tr>
+                <td class="key">S</td>
+                <td class="desc">Toggle sprite layer</td>
+                <td class="key" y="0">X</td>
+                <td class="desc" y="0" x="33.53125">réinitialiser la
+                    carte des noeuds
+                </td>
+                <td class="key">Z</td>
+                <td class="desc">Basculer la vue oblique
+                    (expérimental)
+                </td>
+            </tr>
+            <tr>
+                <td class="key">N</td>
+                <td class="desc">cycle couche de noeuds</td>
+                <td class="key">L</td>
+                <td class="desc">Parcourir étiquettes appareils</td>
+                <td class="key">Shift-l</td>
+                <td class="desc">Parcourir étiquettes hôte</td>
+            </tr>
+            <tr>
+                <td class="key">U</td>
+                <td class="desc">survoler avec la souris</td>
+                <td class="key">R</td>
+                <td class="desc">réinitialiser le zoom et le
+                    panoramique
+                </td>
+                <td class="key">E</td>
+                <td class="desc">Egaliser les rôles de maîtrises
+                </td>
+            </tr>
+            <tr>
+                <td class="key">Dot</td>
+                <td class="desc">Basculer a la barre d'outils</td>
+                <td class="key">0</td>
+                <td class="desc">Annuler la surveillance du trafic
+                </td>
+                <td class="key">A</td>
+                <td class="desc">Surveiller tout le trafic</td>
+            </tr>
+            <tr>
+                <td class="key">F</td>
+                <td class="desc">Afficher les flux de liaison de périphérique
+                </td>
+                <td class="key">V</td>
+                <td class="desc">Show all related intents</td>
+                <td class="key">L-arrow</td>
+                <td class="desc">Show previous related intent</td>
+            </tr>
+            <tr>
+                <td class="key">R-arrow</td>
+                <td class="desc">Show next related intent</td>
+                <td class="key">W</td>
+                <td class="desc">Monitor traffic of selected intent</td>
+            </tr>
+        </table>
+        <hr>
+        <div class="qhrow">
+            <table class="qh-r4-c0">
+                <tr>
+                    <td class="key">cliquer</td>
+                    <td class="desc">Sélectionner l'article et montrer les
+                        détails
+                    </td>
+                </tr>
+                <tr>
+                    <td class="key">Cliquer sur MAJ</td>
+                    <td class="desc">Basculer l'état de sélection</td>
+                </tr>
+                <tr>
+                    <td class="key">Glisser</td>
+                    <td class="desc">Repositionner (et épingler) le périphérique
+                        / l'hôte
+                    </td>
+                </tr>
+                <tr>
+                    <td class="key">cmd défiler</td>
+                    <td class="desc">Zoom avant/arrière</td>
+                </tr>
+                <tr>
+                    <td class="key" y="48">cmd-glisser</td>
+                    <td class="desc" y="48" x="74.84375">Pan
+                </tr>
+            </table>
+        </div>
+    </div>
+</div>
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/layer/quickhelp/quickhelp.component.spec.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/layer/quickhelp/quickhelp.component.spec.ts
new file mode 100644
index 0000000..da60a1b
--- /dev/null
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/layer/quickhelp/quickhelp.component.spec.ts
@@ -0,0 +1,80 @@
+/*
+ * 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 { QuickhelpComponent } from './quickhelp.component';
+import {LogService} from '../../log.service';
+import {ConsoleLoggerService} from '../../consolelogger.service';
+import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
+import {FnService} from '../../util/fn.service';
+import {LionService} from '../../util/lion.service';
+import {KeysService} from '../../util/keys.service';
+
+class MockFnService {}
+
+class MockKeysService {
+
+}
+
+/**
+ * ONOS GUI -- Layer -- Quickhelp Component - Unit Tests
+ */
+describe('QuickhelpComponent', () => {
+    let log: LogService;
+    let component: QuickhelpComponent;
+    let fixture: ComponentFixture<QuickhelpComponent>;
+    const bundleObj = {
+        'core.fw.QuickHelp': {
+            test: 'test1',
+            tt_help: 'Help!'
+        }
+    };
+    const mockLion = (key) =>  {
+        return bundleObj[key] || '%' + key + '%';
+    };
+
+    beforeEach(async(() => {
+        log = new ConsoleLoggerService();
+        TestBed.configureTestingModule({
+            imports: [ BrowserAnimationsModule ],
+            declarations: [ QuickhelpComponent ],
+            providers: [
+                { provide: LogService, useValue: log },
+                { provide: FnService, useClass: MockFnService },
+                { provide: LionService, useFactory: (() => {
+                        return {
+                            bundle: ((bundleId) => mockLion),
+                            ubercache: new Array(),
+                            loadCbs: new Map<string, () => void>([])
+                        };
+                    })
+                },
+                { provide: KeysService, useClass: MockKeysService }
+            ]
+        })
+        .compileComponents();
+    }));
+
+    beforeEach(() => {
+        fixture = TestBed.createComponent(QuickhelpComponent);
+        component = fixture.componentInstance;
+        fixture.detectChanges();
+    });
+
+    it('should create', () => {
+        expect(component).toBeTruthy();
+    });
+});
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/layer/quickhelp/quickhelp.component.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/layer/quickhelp/quickhelp.component.ts
new file mode 100644
index 0000000..6789e14
--- /dev/null
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/layer/quickhelp/quickhelp.component.ts
@@ -0,0 +1,74 @@
+/*
+ * 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 {Component} from '@angular/core';
+import {animate, state, style, transition, trigger} from '@angular/animations';
+import {LogService} from '../../log.service';
+import {FnService} from '../../util/fn.service';
+import {KeysService} from '../../util/keys.service';
+import {LionService} from '../../util/lion.service';
+
+
+@Component({
+    selector: 'onos-quickhelp',
+    templateUrl: './quickhelp.component.html',
+    styleUrls: ['./quickhelp.component.css'],
+    animations: [
+        trigger('quickHelpState', [
+            state('true', style({
+                opacity: '1.0',
+            })),
+            state('false', style({
+                opacity: '0.0',
+            })),
+            transition('0 => 1', animate('500ms ease-in')),
+            transition('1 => 0', animate('500ms ease-out'))
+        ])
+    ]
+})
+export class QuickhelpComponent {
+    lionFn; // Function
+
+    constructor(
+        private log: LogService,
+        private fs: FnService,
+        public ks: KeysService,
+        private lion: LionService
+    ) {
+        if (this.lion.ubercache.length === 0) {
+            this.lionFn = this.dummyLion;
+            this.lion.loadCbs.set('quickhelp', () => this.doLion());
+        } else {
+            this.doLion();
+        }
+
+        this.log.debug('Quickhelp component constructed');
+    }
+
+    /**
+     * Read the LION bundle for Toolbar and set up the lionFn
+     */
+    doLion() {
+        this.lionFn = this.lion.bundle('core.fw.QuickHelp');
+    }
+
+    /**
+    * 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 + '%';
+    }
+}
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/nav/nav.service.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/nav/nav.service.ts
index 337b104..98de228 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/nav/nav.service.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/nav/nav.service.ts
@@ -48,10 +48,8 @@
     }
 
     hideNav() {
-        this.showNav = !this.showNav;
-        if (!this.showNav) {
-            this.log.debug('Hiding Nav menu');
-        }
+        this.showNav = false;
+        this.log.debug('Hiding Nav menu');
     }
 
     toggleNav() {
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/remote/urlfn.service.spec.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/remote/urlfn.service.spec.ts
index 2c31610..37a0cbd 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/remote/urlfn.service.spec.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/remote/urlfn.service.spec.ts
@@ -71,7 +71,7 @@
         windowMock.location.port = p;
         windowMock.location.protocol = prot;
         windowMock.location.href = prot + '://' + h + ':' + p +
-            ctx + '/onos/ui/';
+            ctx + '/onos/ui2/';
     }
 
     it('should define UrlFnService', () => {
@@ -87,37 +87,37 @@
 
     it('should return the correct (http) RS url', () => {
         setLoc('http', 'foo', '123');
-        expect(ufs.rsUrl('path')).toEqual('http://foo:123/onos/ui/rs/path');
+        expect(ufs.rsUrl('path')).toEqual('http://foo:123/onos/ui2/rs/path');
     });
 
     it('should return the correct (https) RS url', () => {
         setLoc('https', 'foo', '123');
-        expect(ufs.rsUrl('path')).toEqual('https://foo:123/onos/ui/rs/path');
+        expect(ufs.rsUrl('path')).toEqual('https://foo:123/onos/ui2/rs/path');
     });
 
     it('should return the correct (ws) WS url', () => {
         setLoc('http', 'foo', '123');
-        expect(ufs.wsUrl('path')).toEqual('ws://foo:123/onos/ui/websock/path');
+        expect(ufs.wsUrl('path')).toEqual('ws://foo:123/onos/ui2/websock/path');
     });
 
     it('should return the correct (wss) WS url', () => {
         setLoc('https', 'foo', '123');
-        expect(ufs.wsUrl('path')).toEqual('wss://foo:123/onos/ui/websock/path');
+        expect(ufs.wsUrl('path')).toEqual('wss://foo:123/onos/ui2/websock/path');
     });
 
     it('should allow us to define an alternate WS port', () => {
         setLoc('http', 'foo', '123');
-        expect(ufs.wsUrl('xyyzy', '456')).toEqual('ws://foo:456/onos/ui/websock/xyyzy');
+        expect(ufs.wsUrl('xyyzy', '456')).toEqual('ws://foo:456/onos/ui2/websock/xyyzy');
     });
 
     it('should allow us to define an alternate host', () => {
         setLoc('http', 'foo', '123');
-        expect(ufs.wsUrl('core', '456', 'bar')).toEqual('ws://bar:456/onos/ui/websock/core');
+        expect(ufs.wsUrl('core', '456', 'bar')).toEqual('ws://bar:456/onos/ui2/websock/core');
     });
 
     it('should allow us to inject an app context', () => {
         setLoc('http', 'foo', '123', '/my/app');
-        expect(ufs.wsUrl('path')).toEqual('ws://foo:123/my/app/onos/ui/websock/path');
+        expect(ufs.wsUrl('path')).toEqual('ws://foo:123/my/app/onos/ui2/websock/path');
     });
 
 });
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/remote/urlfn.service.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/remote/urlfn.service.ts
index a7576c0..12ca11c 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/remote/urlfn.service.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/remote/urlfn.service.ts
@@ -16,7 +16,7 @@
 import { Injectable, Inject } from '@angular/core';
 import { LogService } from '../log.service';
 
-const UICONTEXT = '/onos/ui/';
+const UICONTEXT = '/onos/ui2/';
 const RSSUFFIX = UICONTEXT + 'rs/';
 const WSSUFFIX = UICONTEXT + 'websock/';
 
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/remote/websocket.service.spec.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/remote/websocket.service.spec.ts
index 7695e13..6c6ade8 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/remote/websocket.service.spec.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/remote/websocket.service.spec.ts
@@ -64,8 +64,8 @@
                 port: '80',
                 protocol: 'http',
                 search: { debug: 'true'},
-                href: 'ws://foo:123/onos/ui/websock/path',
-                absUrl: 'ws://foo:123/onos/ui/websock/path'
+                href: 'ws://foo:123/onos/ui2/websock/path',
+                absUrl: 'ws://foo:123/onos/ui2/websock/path'
             }
         };
         fs = new FnService(ar, logSpy, windowMock);
@@ -108,13 +108,13 @@
 
     it('should use the appropriate URL, createWebsocket', () => {
         const url = wss.createWebSocket();
-        expect(url).toEqual('ws://foo:80/onos/ui/websock/core');
+        expect(url).toEqual('ws://foo:80/onos/ui2/websock/core');
     });
 
     it('should use the appropriate URL with modified port, createWebsocket',
         () => {
             const url = wss.createWebSocket(<WsOptions>{ wsport: 1243 });
-            expect(url).toEqual('ws://foo:1243/onos/ui/websock/core');
+            expect(url).toEqual('ws://foo:1243/onos/ui2/websock/core');
     });
 
     it('should verify websocket event handlers, createWebsocket', () => {
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/remote/websocket.service.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/remote/websocket.service.ts
index c4d5227..2a254b4 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/remote/websocket.service.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/remote/websocket.service.ts
@@ -91,6 +91,7 @@
      */
     private bootstrap(data: Bootstrap) {
         this.loggedInUser = data.user;
+        this.log.info('Websocket connection bootstraped', data);
 
         this.clusterNodes = data.clusterNodes;
         this.clusterNodes.forEach((d, i) => {
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.spec.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.spec.ts
index 5f4b349..47299e7 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.spec.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.spec.ts
@@ -89,7 +89,6 @@
         });
         ks = TestBed.get(KeysService);
         ks.installOn(d3Elem);
-        ks.bindQhs(qhs);
         logServiceSpy = TestBed.get(LogService);
     });
 
@@ -103,7 +102,7 @@
 
     it('should define api functions', () => {
         expect(fs.areFunctions(ks, [
-            'bindQhs', 'installOn', 'keyBindings', 'unbindKeys', 'dialogKeys',
+            'installOn', 'keyBindings', 'unbindKeys', 'dialogKeys',
             'addSeq', 'remSeq', 'gestureNotes', 'enableKeys', 'enableGlobalKeys',
             'checkNotGlobal', 'getKeyBindings',
             'matchSeq', 'whatKey', 'textFieldInput', 'keyIn', 'qhlion', 'qhlionShowHide',
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.ts
index decb87b..035037e 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.ts
@@ -59,7 +59,7 @@
         enter: 1,
         esc: 1,
     };
-    qhs: any; // Quick Help Service ??
+    quickHelpShown: boolean = false;
 
     constructor(
         protected log: LogService,
@@ -70,10 +70,6 @@
         this.log.debug('KeyService constructed');
     }
 
-    bindQhs(_qhs_) {
-        this.qhs = _qhs_;
-    }
-
     installOn(elem) {
         this.log.debug('Installing keys handler');
         elem.on('keydown', () => { this.keyIn(); });
@@ -314,14 +310,14 @@
         if (!this.globalEnabled) {
             return false;
         }
-        this.qhs.showQuickHelp(this.keyHandler);
+        this.quickHelpShown = !this.quickHelpShown;
         return true;
     }
 
     // returns true if we 'consumed' the ESC keypress, false otherwise
     protected escapeKey(view, key, code, ev) {
+        this.quickHelpShown = false;
         return this.ns.hideNav();
-        // TODO - also hide this.qhs.hideQuickHelp();
     }
 
     protected toggleTheme(view, key, code, ev) {
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.spec.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.spec.ts
index d925ecf..13892af 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.spec.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.spec.ts
@@ -35,6 +35,19 @@
  */
 describe('PrefsService', () => {
     let log: LogService;
+    let windowMock: Window;
+
+    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'
+        }
+    };
 
     beforeEach(() => {
         log = new ConsoleLoggerService();
@@ -43,6 +56,7 @@
             providers: [PrefsService,
                 { provide: LogService, useValue: log },
                 { provide: FnService, useClass: MockFnService },
+                { provide: 'Window', useFactory: (() => windowMock ) },
                 { provide: WebSocketService, useClass: MockWebSocketService },
             ]
         });
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.ts
index 8145921..b68b4dd 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.ts
@@ -13,11 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import { Injectable } from '@angular/core';
+import {Inject, Injectable} from '@angular/core';
 import { FnService } from './fn.service';
 import { LogService } from '../log.service';
 import { WebSocketService } from '../remote/websocket.service';
 
+const UPDATE_PREFS: string = 'updatePrefs';
+const UPDATE_PREFS_REQ: string = 'updatePrefReq';
 /**
  * ONOS GUI -- Util -- User Preference Service
  */
@@ -25,32 +27,36 @@
     providedIn: 'root',
 })
 export class PrefsService {
-    protected Prefs;
     protected handlers: string[] = [];
-    cache: any;
-    listeners: any;
+    cache: Object;
+    listeners: ((data) => void)[] = [];
     constructor(
         protected fs: FnService,
         protected log: LogService,
-        protected wss: WebSocketService
+        protected wss: WebSocketService,
+        @Inject('Window') private window: any
     ) {
-        this.cache = {};
         this.wss.bindHandlers(new Map<string, (data) => void>([
-            [this.Prefs, (data) => this.updatePrefs(data)]
+            [UPDATE_PREFS, (data) => this.updatePrefs(data)]
         ]));
-        this.handlers.push(this.Prefs);
+        this.handlers.push(UPDATE_PREFS);
+
+        // When index.html is fetched it is served up by MainIndexResource.java
+        // which fetches userPrefs in to the global scope.
+        // After that updates are done through WebSocket
+        this.cache = Object.assign({}, this.window['userPrefs']);
 
         this.log.debug('PrefsService constructed');
     }
 
-    setPrefs(name: string, obj: any) {
+    setPrefs(name: string, obj: Object) {
         // keep a cached copy of the object and send an update to server
         this.cache[name] = obj;
-        this.wss.sendEvent('updatePrefReq', { key: name, value: obj });
+        this.wss.sendEvent(UPDATE_PREFS_REQ, { key: name, value: obj });
     }
     updatePrefs(data: any) {
         this.cache = data;
-        this.listeners.forEach(function (lsnr) { lsnr(); });
+        this.listeners.forEach((lsnr) => lsnr(data) );
     }
 
     asNumbers(obj: any, keys?: any, not?: any) {
@@ -101,17 +107,22 @@
     //  defined keys should overwrite the corresponding values, but any
     //  existing keys that are NOT explicitly defined here should be left
     //  alone (not deleted).
-    mergePrefs(name: string, obj: any) {
+    mergePrefs(name: string, obj: any): void {
         const merged = this.cache[name] || {};
         this.setPrefs(name, Object.assign(merged, obj));
     }
 
-    addListener(listener: any) {
+    /**
+     * Add a listener function
+     * This will get called back when an 'updatePrefs' message is received on WSS
+     * @param listener a function that can accept one param - data
+     */
+    addListener(listener: (data) => void): void {
         this.listeners.push(listener);
     }
 
-    removeListener(listener: any) {
-        this.listeners = this.listeners.filter(function (obj) { return obj === listener; });
+    removeListener(listener: (data) => void) {
+        this.listeners = this.listeners.filter((obj) => obj !== listener);
     }
 
 }
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/public_api.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/public_api.ts
index 5f162d5..3c6d141 100644
--- a/web/gui2-fw-lib/projects/gui2-fw-lib/src/public_api.ts
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/public_api.ts
@@ -49,6 +49,7 @@
 export * from './lib/layer/veil/veil.component';
 export * from './lib/layer/flash/flash.component';
 export * from './lib/layer/confirm/confirm.component';
+export * from './lib/layer/quickhelp/quickhelp.component';
 export * from './lib/svg/icon/icon.component';
 
 export * from './lib/widget/tableresize.directive';
diff --git a/web/gui2-fw-lib/src/app/app.component.html b/web/gui2-fw-lib/src/app/app.component.html
index 26f2562..f8d881f 100644
--- a/web/gui2-fw-lib/src/app/app.component.html
+++ b/web/gui2-fw-lib/src/app/app.component.html
@@ -44,3 +44,4 @@
   If you change anything in the library, you will have to build it again before
   it is picked up in this app.
 </p>
+<onos-quickhelp></onos-quickhelp>
diff --git a/web/gui2-fw-lib/src/app/app.module.ts b/web/gui2-fw-lib/src/app/app.module.ts
index d2d4a5d..1d243f5 100644
--- a/web/gui2-fw-lib/src/app/app.module.ts
+++ b/web/gui2-fw-lib/src/app/app.module.ts
@@ -19,6 +19,8 @@
 import { RouterModule, Routes } from '@angular/router';
 import { AppComponent } from './app.component';
 import { Gui2FwLibModule, ConsoleLoggerService, LogService } from 'gui2-fw-lib';
+import {HttpClientModule} from "@angular/common/http";
+import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
 
 const appRoutes: Routes = [
   { path: '**', component: AppComponent }
@@ -31,6 +33,8 @@
   imports: [
     RouterModule.forRoot(appRoutes),
     BrowserModule,
+    BrowserAnimationsModule,
+    HttpClientModule,
     Gui2FwLibModule
   ],
   providers: [
diff --git a/web/gui2/BUILD b/web/gui2/BUILD
index 54ac6e8..607f955 100644
--- a/web/gui2/BUILD
+++ b/web/gui2/BUILD
@@ -37,10 +37,11 @@
     the build is still hermetic since those files are referred to as dependencies in the genrule.
 """
 
-COMPILE_DEPS = CORE_DEPS + JACKSON + KRYO + [
+COMPILE_DEPS = CORE_DEPS + JACKSON + KRYO + CLI + [
     "@javax_ws_rs_api//jar",
     "@servlet_api//jar",
     "@jetty_websocket//jar",
+    "@jetty_websocket_api//jar",
     "@jetty_util//jar",
     "@jersey_media_multipart//jar",
     "@jersey_server//jar",
@@ -318,6 +319,14 @@
         ]) + [
             "//web/gui:onos-gui-java-for-gui2",
         ],
+    exclude_tests = [
+        "org.onosproject.ui.impl.AbstractUiImplTest",
+        "org.onosproject.ui.impl.topo.model.AbstractTopoModelTest",
+    ],
+    karaf_command_packages = [
+        "org.onosproject.ui.impl.cli",
+        "org.onosproject.ui.impl.topo",
+    ],
     suppress_checkstyle = True,
     test_deps = TEST_DEPS,
     web_context = "/onos/ui2",
@@ -334,6 +343,7 @@
         ":_onos-gui2-ng-build",
         ":_onos-gui2-base-jar",
         ":_web_inf_classes_files",
+        "//web/gui:onos-gui-lion-for-gui2",
         "src/main/webapp/WEB-INF/web.xml",
     ],
     outs = ["onos-gui2.jar"],
@@ -344,8 +354,11 @@
           " for i in $(locations :_web_inf_classes_files); do cp $$ROOT/$$i ./WEB-INF/classes/; done &&" +
           " (cd WEB-INF/classes && jar xf $$ROOT/$${BUILD_FILES[1]}) &&" +
           " jar xf $$ROOT/$(location :_onos-gui2-base-jar) &&" +
-          " find . -type f -exec touch -t 201808280000 {} \; &&" +
-          " jar cmf META-INF/MANIFEST.MF $$ROOT/$@ WEB-INF/web.xml WEB-INF/classes",
+          " unzip -q $$ROOT/$(location //web/gui:onos-gui-lion-for-gui2) web/gui/src/main/resources/**/* &&" +
+          " mv web/gui/src/main/resources/org/onosproject/ui/lion* WEB-INF/classes/org/onosproject/ui/ &&" +
+          " mv web/gui/src/main/resources/core WEB-INF/classes/ &&" +
+          " find . -type f -exec touch -t 201901200000 {} \; &&" +
+          " jar cmf META-INF/MANIFEST.MF $$ROOT/$@ WEB-INF/web.xml WEB-INF/classes OSGI-INF/*.xml",
     output_to_bindir = 1,
     visibility = ["//visibility:public"],
 )
diff --git a/web/gui2/README.md b/web/gui2/README.md
index 50f5077..3996c95 100644
--- a/web/gui2/README.md
+++ b/web/gui2/README.md
@@ -16,7 +16,7 @@
 As usual with ONOS if you want to run it in a different language set the __ONOS_LOCALE__ environment variable
 to the locale you want before starting onos. e.g.
 ```
-ONOS_LOCALE=fr_FR SHLVL=1 bazel run onos-local
+ONOS_LOCALE=fr_FR SHLVL=1 bazel run onos-local -- clean debug
 ```
 
 # Development
diff --git a/web/gui2/package-lock.json b/web/gui2/package-lock.json
index 81356c1..2645a24 100644
--- a/web/gui2/package-lock.json
+++ b/web/gui2/package-lock.json
@@ -364,7 +364,7 @@
           "requires": {
             "anymatch": "1.3.2",
             "async-each": "1.0.1",
-            "fsevents": "1.2.4",
+            "fsevents": "1.2.7",
             "glob-parent": "2.0.0",
             "inherits": "2.0.3",
             "is-binary-path": "1.0.1",
@@ -2567,7 +2567,7 @@
         "anymatch": "2.0.0",
         "async-each": "1.0.1",
         "braces": "2.3.2",
-        "fsevents": "1.2.4",
+        "fsevents": "1.2.7",
         "glob-parent": "3.1.0",
         "inherits": "2.0.3",
         "is-binary-path": "1.0.1",
@@ -4838,14 +4838,14 @@
       "dev": true
     },
     "fsevents": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz",
-      "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==",
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz",
+      "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==",
       "dev": true,
       "optional": true,
       "requires": {
         "nan": "2.11.1",
-        "node-pre-gyp": "0.10.0"
+        "node-pre-gyp": "0.10.3"
       },
       "dependencies": {
         "abbrev": {
@@ -4866,7 +4866,7 @@
           "optional": true
         },
         "are-we-there-yet": {
-          "version": "1.1.4",
+          "version": "1.1.5",
           "bundled": true,
           "dev": true,
           "optional": true,
@@ -4890,7 +4890,7 @@
           }
         },
         "chownr": {
-          "version": "1.0.1",
+          "version": "1.1.1",
           "bundled": true,
           "dev": true,
           "optional": true
@@ -4926,7 +4926,7 @@
           }
         },
         "deep-extend": {
-          "version": "0.5.1",
+          "version": "0.6.0",
           "bundled": true,
           "dev": true,
           "optional": true
@@ -4949,7 +4949,7 @@
           "dev": true,
           "optional": true,
           "requires": {
-            "minipass": "2.2.4"
+            "minipass": "2.3.5"
           }
         },
         "fs.realpath": {
@@ -4971,11 +4971,11 @@
             "signal-exit": "3.0.2",
             "string-width": "1.0.2",
             "strip-ansi": "3.0.1",
-            "wide-align": "1.1.2"
+            "wide-align": "1.1.3"
           }
         },
         "glob": {
-          "version": "7.1.2",
+          "version": "7.1.3",
           "bundled": true,
           "dev": true,
           "optional": true,
@@ -4995,7 +4995,7 @@
           "optional": true
         },
         "iconv-lite": {
-          "version": "0.4.21",
+          "version": "0.4.24",
           "bundled": true,
           "dev": true,
           "optional": true,
@@ -5061,21 +5061,21 @@
           "dev": true
         },
         "minipass": {
-          "version": "2.2.4",
+          "version": "2.3.5",
           "bundled": true,
           "dev": true,
           "requires": {
-            "safe-buffer": "5.1.1",
-            "yallist": "3.0.2"
+            "safe-buffer": "5.1.2",
+            "yallist": "3.0.3"
           }
         },
         "minizlib": {
-          "version": "1.1.0",
+          "version": "1.2.1",
           "bundled": true,
           "dev": true,
           "optional": true,
           "requires": {
-            "minipass": "2.2.4"
+            "minipass": "2.3.5"
           }
         },
         "mkdirp": {
@@ -5093,32 +5093,32 @@
           "optional": true
         },
         "needle": {
-          "version": "2.2.0",
+          "version": "2.2.4",
           "bundled": true,
           "dev": true,
           "optional": true,
           "requires": {
             "debug": "2.6.9",
-            "iconv-lite": "0.4.21",
+            "iconv-lite": "0.4.24",
             "sax": "1.2.4"
           }
         },
         "node-pre-gyp": {
-          "version": "0.10.0",
+          "version": "0.10.3",
           "bundled": true,
           "dev": true,
           "optional": true,
           "requires": {
             "detect-libc": "1.0.3",
             "mkdirp": "0.5.1",
-            "needle": "2.2.0",
+            "needle": "2.2.4",
             "nopt": "4.0.1",
-            "npm-packlist": "1.1.10",
+            "npm-packlist": "1.2.0",
             "npmlog": "4.1.2",
-            "rc": "1.2.7",
-            "rimraf": "2.6.2",
-            "semver": "5.5.0",
-            "tar": "4.4.1"
+            "rc": "1.2.8",
+            "rimraf": "2.6.3",
+            "semver": "5.6.0",
+            "tar": "4.4.8"
           }
         },
         "nopt": {
@@ -5132,19 +5132,19 @@
           }
         },
         "npm-bundled": {
-          "version": "1.0.3",
+          "version": "1.0.5",
           "bundled": true,
           "dev": true,
           "optional": true
         },
         "npm-packlist": {
-          "version": "1.1.10",
+          "version": "1.2.0",
           "bundled": true,
           "dev": true,
           "optional": true,
           "requires": {
             "ignore-walk": "3.0.1",
-            "npm-bundled": "1.0.3"
+            "npm-bundled": "1.0.5"
           }
         },
         "npmlog": {
@@ -5153,7 +5153,7 @@
           "dev": true,
           "optional": true,
           "requires": {
-            "are-we-there-yet": "1.1.4",
+            "are-we-there-yet": "1.1.5",
             "console-control-strings": "1.1.0",
             "gauge": "2.7.4",
             "set-blocking": "2.0.0"
@@ -5213,12 +5213,12 @@
           "optional": true
         },
         "rc": {
-          "version": "1.2.7",
+          "version": "1.2.8",
           "bundled": true,
           "dev": true,
           "optional": true,
           "requires": {
-            "deep-extend": "0.5.1",
+            "deep-extend": "0.6.0",
             "ini": "1.3.5",
             "minimist": "1.2.0",
             "strip-json-comments": "2.0.1"
@@ -5242,22 +5242,22 @@
             "inherits": "2.0.3",
             "isarray": "1.0.0",
             "process-nextick-args": "2.0.0",
-            "safe-buffer": "5.1.1",
+            "safe-buffer": "5.1.2",
             "string_decoder": "1.1.1",
             "util-deprecate": "1.0.2"
           }
         },
         "rimraf": {
-          "version": "2.6.2",
+          "version": "2.6.3",
           "bundled": true,
           "dev": true,
           "optional": true,
           "requires": {
-            "glob": "7.1.2"
+            "glob": "7.1.3"
           }
         },
         "safe-buffer": {
-          "version": "5.1.1",
+          "version": "5.1.2",
           "bundled": true,
           "dev": true
         },
@@ -5274,7 +5274,7 @@
           "optional": true
         },
         "semver": {
-          "version": "5.5.0",
+          "version": "5.6.0",
           "bundled": true,
           "dev": true,
           "optional": true
@@ -5307,7 +5307,7 @@
           "dev": true,
           "optional": true,
           "requires": {
-            "safe-buffer": "5.1.1"
+            "safe-buffer": "5.1.2"
           }
         },
         "strip-ansi": {
@@ -5325,18 +5325,18 @@
           "optional": true
         },
         "tar": {
-          "version": "4.4.1",
+          "version": "4.4.8",
           "bundled": true,
           "dev": true,
           "optional": true,
           "requires": {
-            "chownr": "1.0.1",
+            "chownr": "1.1.1",
             "fs-minipass": "1.2.5",
-            "minipass": "2.2.4",
-            "minizlib": "1.1.0",
+            "minipass": "2.3.5",
+            "minizlib": "1.2.1",
             "mkdirp": "0.5.1",
-            "safe-buffer": "5.1.1",
-            "yallist": "3.0.2"
+            "safe-buffer": "5.1.2",
+            "yallist": "3.0.3"
           }
         },
         "util-deprecate": {
@@ -5346,7 +5346,7 @@
           "optional": true
         },
         "wide-align": {
-          "version": "1.1.2",
+          "version": "1.1.3",
           "bundled": true,
           "dev": true,
           "optional": true,
@@ -5360,7 +5360,7 @@
           "dev": true
         },
         "yallist": {
-          "version": "3.0.2",
+          "version": "3.0.3",
           "bundled": true,
           "dev": true
         }
@@ -5560,7 +5560,7 @@
     },
     "gui2-fw-lib": {
       "version": "file:../gui2-fw-lib/dist/gui2-fw-lib/gui2-fw-lib-2.0.0.tgz",
-      "integrity": "sha512-DRtcy4kDWJxMllozKJpiS4H820mxXmP01bU91qb5sYa/0HjiuihlOiJhvF4Kyg4hUfISNF+bhDeFwr3UgI5xtA==",
+      "integrity": "sha512-vHBnAneVQg76r7k3oY0oW2iLatWXLVmr2ei4I00qM73V7Z8hqkeIyRtOtW2PCbpjtiuPT6q8ObXvkDr23bjZVA==",
       "requires": {
         "tslib": "1.9.3"
       }
@@ -7119,7 +7119,7 @@
           "requires": {
             "anymatch": "1.3.2",
             "async-each": "1.0.1",
-            "fsevents": "1.2.4",
+            "fsevents": "1.2.7",
             "glob-parent": "2.0.0",
             "inherits": "2.0.3",
             "is-binary-path": "1.0.1",
@@ -7464,7 +7464,7 @@
           "requires": {
             "anymatch": "1.3.2",
             "async-each": "1.0.1",
-            "fsevents": "1.2.4",
+            "fsevents": "1.2.7",
             "glob-parent": "2.0.0",
             "inherits": "2.0.3",
             "is-binary-path": "1.0.1",
diff --git a/web/gui2/src/main/webapp/WEB-INF/web.xml b/web/gui2/src/main/webapp/WEB-INF/web.xml
index 3eda814..5ac6e2f 100644
--- a/web/gui2/src/main/webapp/WEB-INF/web.xml
+++ b/web/gui2/src/main/webapp/WEB-INF/web.xml
@@ -147,7 +147,7 @@
             <param-value>
                 org.glassfish.jersey.media.multipart.MultiPartFeature,
                 org.onosproject.ui.impl.gui2.LogoutResource,
-                <!--org.onosproject.ui.impl.TopologyResource,-->
+                org.onosproject.ui.impl.TopologyResource,
                 org.onosproject.ui.impl.ApplicationResource,
                 org.onosproject.ui.impl.gui2.NavResource
             </param-value>
@@ -160,16 +160,15 @@
         <url-pattern>/rs/*</url-pattern>
     </servlet-mapping>
 
-    <!--<servlet>-->
-        <!--<servlet-name>Web Socket Service</servlet-name>-->
-        <!--<servlet-class>org.onosproject.ui.impl.UiWebSocketServlet-->
-        <!--</servlet-class>-->
-        <!--<load-on-startup>2</load-on-startup>-->
-    <!--</servlet>-->
+    <servlet>
+        <servlet-name>Web Socket Service</servlet-name>
+        <servlet-class>org.onosproject.ui.impl.UiWebSocketServlet</servlet-class>
+        <load-on-startup>2</load-on-startup>
+    </servlet>
 
-    <!--<servlet-mapping>-->
-        <!--<servlet-name>Web Socket Service</servlet-name>-->
-        <!--<url-pattern>/websock/*</url-pattern>-->
-    <!--</servlet-mapping>-->
+    <servlet-mapping>
+        <servlet-name>Web Socket Service</servlet-name>
+        <url-pattern>/websock/*</url-pattern>
+    </servlet-mapping>
 
 </web-app>
diff --git a/web/gui2/src/main/webapp/app/onos.component.html b/web/gui2/src/main/webapp/app/onos.component.html
index 0fedcca..029d524 100644
--- a/web/gui2/src/main/webapp/app/onos.component.html
+++ b/web/gui2/src/main/webapp/app/onos.component.html
@@ -14,7 +14,7 @@
 ~ limitations under the License.
 -->
 <div id="view" onosDetectBrowser>
-    <onos-mast username="onos"></onos-mast>
+    <onos-mast [username]="onos.username"></onos-mast>
     <onos-nav></onos-nav>
     <onos-veil #veil></onos-veil>
     <div>{{ wss.setVeilDelegate(veil) }}</div>
diff --git a/web/gui2/src/main/webapp/app/onos.component.ts b/web/gui2/src/main/webapp/app/onos.component.ts
index 0fe1346..909b74b 100644
--- a/web/gui2/src/main/webapp/app/onos.component.ts
+++ b/web/gui2/src/main/webapp/app/onos.component.ts
@@ -84,7 +84,7 @@
         private ks: KeysService,
         public wss: WebSocketService,
         private log: LogService,
-        private onos: OnosService
+        public onos: OnosService
     ) {
 
 // This is not like onos.js of AngularJS 1.x In this new structure modules are
diff --git a/web/gui2/src/main/webapp/app/onos.service.spec.ts b/web/gui2/src/main/webapp/app/onos.service.spec.ts
index 073dfa7..c9dfdb3 100644
--- a/web/gui2/src/main/webapp/app/onos.service.spec.ts
+++ b/web/gui2/src/main/webapp/app/onos.service.spec.ts
@@ -23,13 +23,26 @@
  */
 describe('OnosService', () => {
     let log: LogService;
+    let windowMock: Window;
 
     beforeEach(() => {
         log = new ConsoleLoggerService();
+        windowMock = <any>{
+            location: <any> {
+                hostname: 'foo',
+                host: 'foo',
+                port: '80',
+                protocol: 'http',
+                search: { debug: 'true'},
+                href: 'ws://foo:123/onos/ui2/websock/path',
+                absUrl: 'ws://foo:123/onos/ui2/websock/path'
+            }
+        };
 
         TestBed.configureTestingModule({
             providers: [OnosService,
                 { provide: LogService, useValue: log },
+                { provide: 'Window', useFactory: (() => windowMock ) },
             ]
         });
     });
diff --git a/web/gui2/src/main/webapp/app/onos.service.ts b/web/gui2/src/main/webapp/app/onos.service.ts
index b13129b..2cfe008 100644
--- a/web/gui2/src/main/webapp/app/onos.service.ts
+++ b/web/gui2/src/main/webapp/app/onos.service.ts
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import { Injectable } from '@angular/core';
+import {Inject, Injectable} from '@angular/core';
 import { LogService } from 'gui2-fw-lib';
 
 /**
@@ -35,10 +35,14 @@
     public browser: string;
     public mobile: boolean;
     public viewMap: View[];
+    public username: string;
 
     constructor (
-        private log: LogService
+        private log: LogService,
+        @Inject('Window') private window: any
     ) {
+        // The onosUser is added to the index.html by MainIndexResource
+        this.username = this.window['onosUser'];
         this.log.debug('OnosService constructed');
     }
 }
diff --git a/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/forcesvg.component.html b/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/forcesvg.component.html
index c4930c1..517c3e7 100644
--- a/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/forcesvg.component.html
+++ b/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/forcesvg.component.html
@@ -47,7 +47,8 @@
     <svg:g onos-devicenodesvg [device]="device"
            *ngFor="let device of regionData.devices[visibleLayerIdx()]"
            onosDraggableNode [draggableNode]="device" [draggableInGraph]="graph"
-           (selectedEvent)="updateSelected($event)">
+           (selectedEvent)="updateSelected($event)"
+            [labelToggle]="deviceLabelToggle">
         <svg:desc>Device nodes</svg:desc>
     </svg:g>
     <!-- Template explanation - only display the hosts if 'showHosts' is set true -->
@@ -67,7 +68,8 @@
         <svg:g onos-hostnodesvg [host]="host"
                *ngFor="let host of regionData.hosts[visibleLayerIdx()]"
                onosDraggableNode [draggableNode]="host" [draggableInGraph]="graph"
-               (selectedEvent)="updateSelected($event)">
+               (selectedEvent)="updateSelected($event)"
+               [labelToggle]="hostLabelToggle">
             <svg:desc>Host nodes</svg:desc>
         </svg:g>
     </svg:g>
diff --git a/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/forcesvg.component.ts b/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/forcesvg.component.ts
index b0b4a0c..d2a0b18 100644
--- a/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/forcesvg.component.ts
+++ b/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/forcesvg.component.ts
@@ -51,7 +51,6 @@
     LinkSvgComponent
 } from './visuals';
 
-
 /**
  * ONOS GUI -- Topology Forces Graph Layer View.
  *
@@ -65,16 +64,16 @@
     changeDetection: ChangeDetectionStrategy.OnPush,
 })
 export class ForceSvgComponent implements OnInit, OnChanges {
-    @Input() onosInstMastership: string = '';
-    @Input() visibleLayer: LayerType = LayerType.LAYER_DEFAULT;
-    @Output() linkSelected = new EventEmitter<RegionLink>();
-    @Output() selectedNodeEvent = new EventEmitter<UiElement>();
-    @Input() selectedLink: RegionLink = null;
-    @Input() showHosts: boolean = false;
-    @Input() highlightPorts: boolean = true;
     @Input() deviceLabelToggle: LabelToggle = LabelToggle.NONE;
     @Input() hostLabelToggle: HostLabelToggle = HostLabelToggle.NONE;
+    @Input() showHosts: boolean = false;
+    @Input() highlightPorts: boolean = true;
+    @Input() onosInstMastership: string = '';
+    @Input() visibleLayer: LayerType = LayerType.LAYER_DEFAULT;
+    @Input() selectedLink: RegionLink = null;
     @Input() regionData: Region = <Region>{devices: [ [], [], [] ], hosts: [ [], [], [] ], links: []};
+    @Output() linkSelected = new EventEmitter<RegionLink>();
+    @Output() selectedNodeEvent = new EventEmitter<UiElement>();
     private graph: ForceDirectedGraph;
     private _options: { width, height } = { width: 800, height: 600 };
 
@@ -198,30 +197,6 @@
                 this.graph.nodes.length, 'nodes,', this.graph.links.length, 'links');
         }
 
-        if (changes['showHosts']) {
-            this.showHosts = changes['showHosts'].currentValue;
-        }
-
-        if (changes['highlightPorts']) {
-            this.highlightPorts = changes['highlightPorts'].currentValue;
-        }
-
-        // Pass on the changes to device
-        if (changes['deviceLabelToggle']) {
-            this.deviceLabelToggle = changes['deviceLabelToggle'].currentValue;
-            this.devices.forEach((d) => {
-                d.ngOnChanges({'labelToggle': changes['deviceLabelToggle']});
-            });
-        }
-
-        // Pass on the changes to host
-        if (changes['hostLabelToggle']) {
-            this.hostLabelToggle = changes['hostLabelToggle'].currentValue;
-            this.hosts.forEach((h) => {
-                h.ngOnChanges({'labelToggle': changes['hostLabelToggle']});
-            });
-        }
-
         this.ref.markForCheck();
     }
 
diff --git a/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.html b/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.html
index 08ccaec..884d9ce 100644
--- a/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.html
+++ b/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.html
@@ -21,8 +21,8 @@
         line 3) Merge this blurred and shifted layer and overlay it with the
             original target object
     -->
-    <svg:filter id="drop-shadow">
-        <svg:feGaussianBlur in="SourceAlpha" stdDeviation="2" result="blur" />
+    <svg:filter id="drop-shadow" x="-25%" y="-25%" width="200%" height="200%">
+        <svg:feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur" />
         <svg:feOffset in="blur" dx="4" dy="4" result="offsetBlur"/>
         <svg:feMerge >
             <svg:feMergeNode in="offsetBlur" />
@@ -30,8 +30,8 @@
         </svg:feMerge>
     </svg:filter>
     <svg:linearGradient id="diagonal_blue" x1="0%" y1="0%" x2="100%" y2="100%">
-        <svg:stop offset= "0%" style="stop-color: #5b99d2;" />
-        <svg:stop offset= "100%" style="stop-color: #3b79b2;" />
+        <svg:stop offset= "0%" style="stop-color: #7fabdb;" />
+        <svg:stop offset= "100%" style="stop-color: #5b99d2;" />
     </svg:linearGradient>
 </svg:defs>
 <!-- Template explanation: Creates an SVG Group and in
@@ -57,7 +57,7 @@
     <svg:rect
             class="node-container" x="-18" y="-18"
             width="36" height="36"
-            [@deviceLabelToggle]="{ value: labelToggle, params: {txtWidth: (36 + labelTextLen() * 1.05)+'px' }}"
+            [@deviceLabelToggle]="{ value: labelToggle, params: {txtWidth: (36 + labelTextLen() * 1.1)+'px' }}"
             filter= "url(#drop-shadow)">
     </svg:rect>
     <!-- Template explanation: Creates an SVG Rectangle slightly smaller and
diff --git a/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.ts b/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.ts
index 756769d..9a8afc5 100644
--- a/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.ts
+++ b/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/visuals/devicenodesvg/devicenodesvg.component.ts
@@ -90,9 +90,6 @@
                 this.device.y = 0;
             }
         }
-        if (changes['labelToggle']) {
-            this.labelToggle = changes['labelToggle'].currentValue;
-        }
         this.ref.markForCheck();
     }
 
diff --git a/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.html b/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.html
index 728a8ce..5bab75d 100644
--- a/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.html
+++ b/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.html
@@ -21,9 +21,9 @@
         line 3) Merge this blurred and shifted layer and overlay it with the
             original target object
     -->
-    <svg:filter id="drop-shadow-host">
-        <svg:feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur" />
-        <svg:feOffset in="blur" dx="2" dy="2" result="offsetBlur"/>
+    <svg:filter id="drop-shadow-host" x="-25%" y="-25%" width="200%" height="200%">
+        <svg:feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur" />
+        <svg:feOffset in="blur" dx="4" dy="4" result="offsetBlur"/>
         <svg:feMerge >
             <svg:feMergeNode in="offsetBlur" />
             <svg:feMergeNode in="SourceGraphic" />
diff --git a/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.ts b/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.ts
index 0720d0e..fc55271 100644
--- a/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.ts
+++ b/web/gui2/src/main/webapp/app/view/topology/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.ts
@@ -53,11 +53,6 @@
             this.host.x = 0;
             this.host.y = 0;
         }
-
-        if (changes['labelToggle']) {
-            this.labelToggle = changes['labelToggle'].currentValue;
-        }
-        // this.ref.markForCheck();
     }
 
     hostName(): string {
diff --git a/web/gui2/src/main/webapp/app/view/topology/panel/details/details.component.css b/web/gui2/src/main/webapp/app/view/topology/panel/details/details.component.css
index 9ddfe17..05402c8 100644
--- a/web/gui2/src/main/webapp/app/view/topology/panel/details/details.component.css
+++ b/web/gui2/src/main/webapp/app/view/topology/panel/details/details.component.css
@@ -17,8 +17,16 @@
 
 #topo2-p-detail {
     padding: 16px;
-    top: 370px;
+    opacity: 1;
+    right: 20px;
+    width: 260px;
+    top: 390px;
 }
+
+#topo2-p-detail  div.actionBtns {
+    padding-top: 6px;
+}
+
 html[data-platform='iPad'] {
     top: 386px;
 }
diff --git a/web/gui2/src/main/webapp/app/view/topology/panel/details/details.component.html b/web/gui2/src/main/webapp/app/view/topology/panel/details/details.component.html
index 405fdfc..ca23ca1 100644
--- a/web/gui2/src/main/webapp/app/view/topology/panel/details/details.component.html
+++ b/web/gui2/src/main/webapp/app/view/topology/panel/details/details.component.html
@@ -14,7 +14,7 @@
 ~ limitations under the License.
 -->
 <div id="topo2-p-detail" class="floatpanel topo2-p"
-     style="opacity: 1; right: 20px; width: 260px; top: 350px;" [@detailsPanelState]="on">
+     [@detailsPanelState]="on && selectedNode !== undefined">
     <!-- Template explanation - Create a HTML header which has an SVG icon along
     side title text. -->
     <div class="header">
@@ -53,15 +53,13 @@
             The icons used here are loaded in the ForceSvgComponent
             -->
             <div *ngFor="let btn of showDetails?.buttons" class="actionBtn">
-                <div class="button" id="topo2-p-detail-core-{{ btn }}"
-                     (click)="navto(buttonAttribs(btn).path, showDetails.navPath, showDetails.id)">
-                    <onos-icon
-                            [iconSize]="25"
-                            [iconId]="buttonAttribs(btn).gid"
-                            [toolTip]="lionFn(buttonAttribs(btn).tt)"
-                            classes="icon">
-                    </onos-icon>
-                </div>
+                <onos-icon id="topo2-p-detail-core-{{ btn }}"
+                           (click)="navto(buttonAttribs(btn).path, showDetails.navPath, showDetails.id)"
+                        [iconSize]="25"
+                        [iconId]="buttonAttribs(btn).gid"
+                        [toolTip]="lionFn(buttonAttribs(btn).tt)"
+                        classes="button icon selected">
+                </onos-icon>
             </div>
         </div>
     </div>
diff --git a/web/gui2/src/main/webapp/app/view/topology/panel/details/details.component.ts b/web/gui2/src/main/webapp/app/view/topology/panel/details/details.component.ts
index f63d99a..ea1462c 100644
--- a/web/gui2/src/main/webapp/app/view/topology/panel/details/details.component.ts
+++ b/web/gui2/src/main/webapp/app/view/topology/panel/details/details.component.ts
@@ -110,6 +110,7 @@
 })
 export class DetailsComponent extends DetailsPanelBaseImpl implements OnInit, OnDestroy, OnChanges {
     @Input() selectedNode: UiElement = undefined; // Populated when user selects node or link
+    @Input() on: boolean = false; // Override the parent class attribute
 
     // deferred localization strings
     lionFn; // Function
@@ -141,7 +142,6 @@
      * is made
      */
     ngOnInit(): void {
-        this.on = false;
         this.wss.bindHandlers(new Map<string, (data) => void>([
             ['showDetails', (data) => {
                     this.showDetails = data;
@@ -211,8 +211,6 @@
             } else {
                 this.log.warn('Unexpected type for selected element', this.selectedNode);
             }
-        } else {
-            this.log.warn('Unexpected change in Topo DetailsComponent');
         }
     }
 
diff --git a/web/gui2/src/main/webapp/app/view/topology/panel/instance/instance.component.ts b/web/gui2/src/main/webapp/app/view/topology/panel/instance/instance.component.ts
index b30c706..ac47cce 100644
--- a/web/gui2/src/main/webapp/app/view/topology/panel/instance/instance.component.ts
+++ b/web/gui2/src/main/webapp/app/view/topology/panel/instance/instance.component.ts
@@ -74,6 +74,7 @@
 })
 export class InstanceComponent extends PanelBaseImpl {
     @Input() divTopPx: number = 100;
+    @Input() on: boolean = false; // Override the parent class attribute
     @Output() mastershipEvent = new EventEmitter<string>();
     public onosInstances: Array<Instance>;
     protected mastership: string;
@@ -96,7 +97,6 @@
         } else {
             this.doLion();
         }
-        this.on = true;
         this.log.debug('InstanceComponent constructed');
     }
 
diff --git a/web/gui2/src/main/webapp/app/view/topology/panel/summary/summary.component.css b/web/gui2/src/main/webapp/app/view/topology/panel/summary/summary.component.css
index 894b815..b4bd37b 100644
--- a/web/gui2/src/main/webapp/app/view/topology/panel/summary/summary.component.css
+++ b/web/gui2/src/main/webapp/app/view/topology/panel/summary/summary.component.css
@@ -25,4 +25,12 @@
 
 #topo2-p-summary  td.label {
     width: 50%;
+}
+
+#topo2-p div.header div.icon {
+    padding: 10px
+}
+
+#topo2-p-summary div.header h2 {
+    padding: 10px;
 }
\ No newline at end of file
diff --git a/web/gui2/src/main/webapp/app/view/topology/panel/summary/summary.component.ts b/web/gui2/src/main/webapp/app/view/topology/panel/summary/summary.component.ts
index a520c86..3a42a0b 100644
--- a/web/gui2/src/main/webapp/app/view/topology/panel/summary/summary.component.ts
+++ b/web/gui2/src/main/webapp/app/view/topology/panel/summary/summary.component.ts
@@ -13,7 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import {Component, OnDestroy, OnInit, ViewEncapsulation} from '@angular/core';
+import {
+    Component,
+    Input,
+    OnDestroy,
+    OnInit,
+    ViewEncapsulation
+} from '@angular/core';
 import { animate, state, style, transition, trigger } from '@angular/animations';
 import * as d3 from 'd3';
 import { TopoPanelBaseImpl } from '../topopanel.base';
@@ -28,9 +34,12 @@
 export interface SummaryResponse {
     title: string;
 }
-/*
- ONOS GUI -- Topology Summary Module.
- Defines modeling of ONOS Summary Panel.
+/**
+ * ONOS GUI -- Topology Summary Module.
+ * Defines modeling of ONOS Summary Panel.
+ * Note: This component uses the d3 DOM building technique from the old GUI - this
+ * is not the Angular way of building components and should be avoided generally
+ * See DetailsPanelComponent for a better way of doing this kind of thing
  */
 @Component({
     selector: 'onos-summary',
@@ -57,6 +66,7 @@
     ]
 })
 export class SummaryComponent extends TopoPanelBaseImpl implements OnInit, OnDestroy {
+    @Input() on: boolean = false; // Override the parent class attribute
     private handlers: string[] = [];
     private resp: string = 'showSummary';
     private summaryData: SummaryResponse;
@@ -70,7 +80,6 @@
     ) {
         super(fs, ls, log, 'summary');
         this.summaryData = <SummaryResponse>{};
-        this.on = true;
         this.log.debug('SummaryComponent constructed');
     }
 
@@ -82,7 +91,6 @@
         this.handlers.push(this.resp);
 
         this.init(d3.select('#topo2-p-summary'));
-        this.on = true;
 
         this.wss.sendEvent('requestSummary', {});
     }
diff --git a/web/gui2/src/main/webapp/app/view/topology/panel/toolbar/toolbar.component.html b/web/gui2/src/main/webapp/app/view/topology/panel/toolbar/toolbar.component.html
index 693e1b5..18f9687 100644
--- a/web/gui2/src/main/webapp/app/view/topology/panel/toolbar/toolbar.component.html
+++ b/web/gui2/src/main/webapp/app/view/topology/panel/toolbar/toolbar.component.html
@@ -63,5 +63,9 @@
                 <onos-icon [iconSize]="25" iconId="m_allTraffic" [toolTip]="lionFn('tr_btn_show_related_traffic')" classes="radioButton selected"></onos-icon>
             </div>
         </div>
+        <div class="separator"></div>
+        <div class="button" id="toolbar-topo2-toolbar-topo2-quickhelp" (click)="buttonClicked('quickhelp-btn')">
+            <onos-icon [iconSize]="25" iconId="query" [toolTip]="lionFn('qh_title')" classes="button"></onos-icon>
+        </div>
     </div>
 </div>
\ No newline at end of file
diff --git a/web/gui2/src/main/webapp/app/view/topology/panel/toolbar/toolbar.component.ts b/web/gui2/src/main/webapp/app/view/topology/panel/toolbar/toolbar.component.ts
index 1ec3dbb..f781364 100644
--- a/web/gui2/src/main/webapp/app/view/topology/panel/toolbar/toolbar.component.ts
+++ b/web/gui2/src/main/webapp/app/view/topology/panel/toolbar/toolbar.component.ts
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-present Open Networking Foundation
+ * 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.
@@ -20,8 +20,25 @@
     FnService,
     PanelBaseImpl, LionService
 } from 'gui2-fw-lib';
+
 import {animate, state, style, transition, trigger} from '@angular/animations';
 
+export const INSTANCE_TOGGLE = 'instance-tog';
+export const SUMMARY_TOGGLE = 'summary-tog';
+export const DETAILS_TOGGLE = 'details-tog';
+export const HOSTS_TOGGLE = 'hosts-tog';
+export const OFFLINE_TOGGLE = 'offline-tog';
+export const PORTS_TOGGLE = 'ports-tog';
+export const BKGRND_TOGGLE = 'bkgrnd-tog';
+export const CYCLELABELS_BTN = 'cycleLabels-btn';
+export const CYCLEHOSTLABEL_BTN = 'cycleHostLabel-btn';
+export const RESETZOOM_BTN = 'resetZoom-btn';
+export const EQMASTER_BTN = 'eqMaster-btn';
+export const CANCEL_TRAFFIC = 'cancel-traffic';
+export const ALL_TRAFFIC = 'all-traffic';
+export const QUICKHELP_BTN = 'quickhelp-btn';
+
+
 /*
  ONOS GUI -- Topology Toolbar Module.
  Defines modeling of ONOS toolbar.
@@ -50,7 +67,8 @@
         ])
     ]
 })
-export class ToolbarComponent extends PanelBaseImpl implements OnInit {
+export class ToolbarComponent extends PanelBaseImpl {
+    @Input() on: boolean = false; // Override the parent class attribute
     // deferred localization strings
     lionFn; // Function
     // Used to drive the display of the hosts icon - there is also another such variable on the forcesvg
@@ -70,7 +88,6 @@
         private lion: LionService
     ) {
         super(fs, ls, log);
-        this.on = false;
 
         if (this.lion.ubercache.length === 0) {
             this.lionFn = this.dummyLion;
@@ -82,9 +99,6 @@
         this.log.debug('ToolbarComponent constructed');
     }
 
-    ngOnInit() {
-    }
-
     /**
      * Read the LION bundle for Toolbar and set up the lionFn
      */
@@ -103,23 +117,22 @@
      */
     buttonClicked(name: string): void {
         switch (name) {
-            case 'hosts-tog':
+            case HOSTS_TOGGLE:
                 this.hostsVisible = !this.hostsVisible;
                 break;
-            case 'instance-tog':
+            case INSTANCE_TOGGLE:
                 this.instancesVisible = !this.instancesVisible;
                 break;
-            case 'summary-tog':
+            case SUMMARY_TOGGLE:
                 this.summaryVisible = !this.summaryVisible;
                 break;
-            case 'details-tog':
+            case DETAILS_TOGGLE:
                 this.detailsVisible = !this.detailsVisible;
                 break;
-            case 'bkgrnd-tog':
+            case BKGRND_TOGGLE:
                 this.backgroundVisible = !this.backgroundVisible;
                 break;
             default:
-                this.log.warn('Unhandled toolbar click', name);
         }
         // Send a message up to let TopologyComponent know of the event
         this.buttonEvent.emit(name);
diff --git a/web/gui2/src/main/webapp/app/view/topology/topology.common.css b/web/gui2/src/main/webapp/app/view/topology/topology.common.css
index 41b7851..1ad9fbe 100644
--- a/web/gui2/src/main/webapp/app/view/topology/topology.common.css
+++ b/web/gui2/src/main/webapp/app/view/topology/topology.common.css
@@ -79,10 +79,6 @@
     width: 50%;
 }
 
-#topo2-p-detail  div.actionBtns {
-    padding-top: 6px;
-}
-
 .topo2-p hr {
     height: 1px;
     border: 0;
diff --git a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.html b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.html
index 6fe0cb1..4b66bd6 100644
--- a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.html
+++ b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.html
@@ -18,13 +18,26 @@
 -->
 <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"></onos-instance>
-<onos-summary #summary></onos-summary>
-<onos-toolbar #toolbar (buttonEvent)="toolbarButtonClicked($event)"></onos-toolbar>
-<onos-details #details></onos-details>
+<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>
 
 <div id="ov-topo2">
     <!-- Template explanation -
@@ -49,8 +62,17 @@
                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 *ngIf="showBackground" onos-backgroundsvg/>
-            <svg:g #force onos-forcesvg (selectedNodeEvent)="nodeSelected($event)"/>
+            <svg:g *ngIf="prefsState.bg" onos-backgroundsvg>
+                <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"
+                   (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>
diff --git a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.spec.ts b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.spec.ts
index 23fb257..446d41c 100644
--- a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.spec.ts
+++ b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.spec.ts
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-present Open Networking Foundation
+ * 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.
@@ -31,12 +31,20 @@
 
 import {
     FlashComponent,
+    QuickhelpComponent,
     FnService,
     LogService,
-    IconService, IconComponent
+    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 {
+    DeviceNodeSvgComponent, HostNodeSvgComponent,
+    LinkSvgComponent, SubRegionNodeSvgComponent
+} from '../layer/forcesvg/visuals';
+import {DraggableDirective} from '../layer/forcesvg/draggable/draggable.directive';
 
 
 class MockActivatedRoute extends ActivatedRoute {
@@ -78,6 +86,37 @@
     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);
+    }
+
+}
+
 /**
  * ONOS GUI -- Topology View -- Unit Tests
  */
@@ -89,6 +128,16 @@
     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' });
@@ -116,7 +165,15 @@
                 DetailsComponent,
                 FlashComponent,
                 ZoomableDirective,
-                IconComponent
+                IconComponent,
+                QuickhelpComponent,
+                ForceSvgComponent,
+                LinkSvgComponent,
+                DeviceNodeSvgComponent,
+                HostNodeSvgComponent,
+                DraggableDirective,
+                ZoomableDirective,
+                SubRegionNodeSvgComponent
             ],
             providers: [
                 { provide: FnService, useValue: fs },
@@ -124,7 +181,18 @@
                 { 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);
diff --git a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts
index 3e1e1a6..ff8a050 100644
--- a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts
+++ b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts
@@ -31,7 +31,6 @@
     ZoomService
 } from 'gui2-fw-lib';
 import {InstanceComponent} from '../panel/instance/instance.component';
-import {SummaryComponent} from '../panel/summary/summary.component';
 import {DetailsComponent} from '../panel/details/details.component';
 import {BackgroundSvgComponent} from '../layer/backgroundsvg/backgroundsvg.component';
 import {ForceSvgComponent} from '../layer/forcesvg/forcesvg.component';
@@ -41,10 +40,47 @@
     LabelToggle,
     UiElement
 } from '../layer/forcesvg/models';
-import {ToolbarComponent} from '../panel/toolbar/toolbar.component';
+import {
+    INSTANCE_TOGGLE, SUMMARY_TOGGLE, DETAILS_TOGGLE,
+    HOSTS_TOGGLE, OFFLINE_TOGGLE, PORTS_TOGGLE,
+    BKGRND_TOGGLE, CYCLELABELS_BTN, CYCLEHOSTLABEL_BTN,
+    RESETZOOM_BTN, EQMASTER_BTN,
+    CANCEL_TRAFFIC, ALL_TRAFFIC, QUICKHELP_BTN
+} from '../panel/toolbar/toolbar.component';
 import {TrafficService} from '../traffic.service';
 import {ZoomableDirective} from '../layer/zoomable.directive';
 
+const TOPO2_PREFS = 'topo2_prefs';
+const PREF_BG = 'bg';
+const PREF_DETAIL = 'detail';
+const PREF_DLBLS = 'dlbls';
+const PREF_HLBLS = 'hlbls';
+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;
+}
+
 /**
  * ONOS GUI Topology View
  *
@@ -77,17 +113,27 @@
 export class TopologyComponent implements OnInit, OnDestroy {
     // These are references to the components inserted in the template
     @ViewChild(InstanceComponent) instance: InstanceComponent;
-    @ViewChild(SummaryComponent) summary: SummaryComponent;
     @ViewChild(DetailsComponent) details: DetailsComponent;
-    @ViewChild(ToolbarComponent) toolbar: ToolbarComponent;
     @ViewChild(BackgroundSvgComponent) background: BackgroundSvgComponent;
     @ViewChild(ForceSvgComponent) force: ForceSvgComponent;
     @ViewChild(ZoomableDirective) zoomDirective: ZoomableDirective;
 
     flashMsg: string = '';
-    prefsState = {};
-    hostLabelIdx: number = 1;
-    showBackground: boolean = false;
+    // 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,
+    };
     lionFn; // Function
 
     constructor(
@@ -97,7 +143,6 @@
         protected sus: SvgUtilService,
         protected ps: PrefsService,
         protected wss: WebSocketService,
-        protected zs: ZoomService,
         protected ts: TopologyService,
         protected trs: TrafficService,
         protected is: IconService,
@@ -169,15 +214,31 @@
         // 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.log.debug('Topology component initialized');
     }
 
     /**
+     * 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
+        this.prefsState = data[TOPO2_PREFS];
+        this.log.debug('Updated topo2 prefs', this.prefsState);
+    }
+
+    /**
      * 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');
     }
 
@@ -188,45 +249,48 @@
      */
     toolbarButtonClicked(name: string) {
         switch (name) {
-            case 'instance-tog':
+            case INSTANCE_TOGGLE:
                 this.toggleInstancePanel();
                 break;
-            case 'summary-tog':
+            case SUMMARY_TOGGLE:
                 this.toggleSummary();
                 break;
-            case 'details-tog':
+            case DETAILS_TOGGLE:
                 this.toggleDetails();
                 break;
-            case 'hosts-tog':
+            case HOSTS_TOGGLE:
                 this.toggleHosts();
                 break;
-            case 'offline-tog':
+            case OFFLINE_TOGGLE:
                 this.toggleOfflineDevices();
                 break;
-            case 'ports-tog':
+            case PORTS_TOGGLE:
                 this.togglePorts();
                 break;
-            case 'bkgrnd-tog':
+            case BKGRND_TOGGLE:
                 this.toggleBackground();
                 break;
-            case 'cycleLabels-btn':
+            case CYCLELABELS_BTN:
                 this.cycleDeviceLabels();
                 break;
-            case 'cycleHostLabel-btn':
+            case CYCLEHOSTLABEL_BTN:
                 this.cycleHostLabels();
                 break;
-            case 'resetZoom-btn':
+            case RESETZOOM_BTN:
                 this.resetZoom();
                 break;
-            case 'eqMaster-btn':
+            case EQMASTER_BTN:
                 this.equalizeMasters();
                 break;
-            case 'cancel-traffic':
+            case CANCEL_TRAFFIC:
                 this.cancelTraffic();
                 break;
-            case 'all-traffic':
+            case ALL_TRAFFIC:
                 this.monitorAllTraffic();
                 break;
+            case QUICKHELP_BTN:
+                this.ks.quickHelpShown = true;
+                break;
             default:
                 this.log.warn('Unhandled Toolbar action', name);
         }
@@ -262,7 +326,7 @@
                 this.sus.cat7().testCard(d3.select('svg#topo2'));
             },
 
-            esc: this.handleEscape,
+            esc: [() => {this.handleEscape(); }, 'Cancel commands'],
 
             // TODO update after adding in Background Service
             // topology overlay selections
@@ -306,6 +370,7 @@
             // 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
@@ -322,64 +387,111 @@
         }
     }
 
-
-
-    updatePrefsState(what, b) {
-        this.prefsState[what] = b ? 1 : 0;
-        this.ps.setPrefs('topo2_prefs', this.prefsState);
+    /**
+     * 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 = this.force.deviceLabelToggle;
+        const old: LabelToggle = this.prefsState.dlbls;
         const next = LabelToggle.next(old);
-        this.force.ngOnChanges({'deviceLabelToggle':
-                new SimpleChange(old, next, false)});
         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 = this.force.hostLabelToggle;
+        const old: HostLabelToggle = this.prefsState.hlbls;
         const next = HostLabelToggle.next(old);
-        this.force.ngOnChanges({'hostLabelToggle':
-                new SimpleChange(old, next, false)});
         this.flashMsg = this.lionFn(TopologyComponent.hostLabelFlashMessage(next));
+        this.updatePrefsState(PREF_HLBLS, next);
         this.log.debug('Cycling host labels', 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
+     */
     protected toggleBackground(token?: KeysToken) {
-        this.showBackground = !this.showBackground;
-        this.flashMsg = this.lionFn(this.showBackground ? 'show' : 'hide') +
+        const bg: boolean = !Boolean(this.prefsState.bg);
+        this.flashMsg = this.lionFn(bg ? 'show' : 'hide') +
             ' ' + this.lionFn('fl_background_map');
-        this.toolbar.backgroundVisible = this.showBackground;
-        this.log.debug('Toggling background', token);
+        this.updatePrefsState(PREF_BG, bg ? 1 : 0);
+        this.log.debug('Toggling background', token, bg ? 'shown' : 'hidden');
     }
 
     protected toggleDetails(token?: KeysToken) {
-        if (this.details.selectedNode) {
-            const on: boolean = this.details.togglePanel(() => {
-            });
-            this.flashMsg = this.lionFn(on ? 'show' : 'hide') +
-                ' ' + this.lionFn('fl_panel_details');
-            this.toolbar.detailsVisible = on;
-
-            this.log.debug('Toggling details', token);
-        }
+        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 = this.instance.togglePanel(() => {});
+        const on: boolean = !Boolean(this.prefsState.insts);
         this.flashMsg = this.lionFn(on ? 'show' : 'hide') +
             ' ' + this.lionFn('fl_panel_instances');
-        this.toolbar.instancesVisible = on;
+        this.updatePrefsState(PREF_INSTS, on ? 1 : 0);
         this.log.debug('Toggling instances', token, on);
     }
 
     protected toggleSummary() {
-        const on: boolean = this.summary.togglePanel(() => {});
+        const on: boolean = !Boolean(this.prefsState.summary);
         this.flashMsg = this.lionFn(on ? 'show' : 'hide') +
             ' ' + this.lionFn('fl_panel_summary');
-        this.toolbar.summaryVisible = on;
+        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() {
@@ -387,16 +499,6 @@
         this.flashMsg = this.lionFn('fl_pan_zoom_reset');
     }
 
-    protected togglePorts(token?: KeysToken) {
-        const old: boolean = this.force.highlightPorts;
-        const current: boolean = !this.force.highlightPorts;
-        this.force.ngOnChanges({'highlightPorts': new SimpleChange(old, current, false)});
-        this.flashMsg = this.lionFn(current ? 'enable' : 'disable') +
-            ' ' + this.lionFn('fl_port_highlighting');
-        this.toolbar.portsVisible = current;
-        this.log.debug(current ? 'Enable' : 'Disable', 'port highlighting');
-    }
-
     protected equalizeMasters() {
         this.wss.sendEvent('equalizeMasters', null);
         this.flashMsg = this.lionFn('fl_eq_masters');
@@ -414,29 +516,6 @@
         this.log.debug('unpinning node');
     }
 
-    protected toggleToolbar() {
-        this.log.debug('toggling toolbar');
-        this.toolbar.on = !this.toolbar.on;
-    }
-
-    protected toggleHosts() {
-        const old: boolean = this.force.showHosts;
-        const current = !this.force.showHosts;
-        this.force.ngOnChanges({'showHosts': new SimpleChange(old, current, false)});
-        this.flashMsg = this.lionFn('hosts') + ' ' +
-                        this.lionFn(this.force.showHosts ? 'visible' : 'hidden');
-        this.toolbar.hostsVisible = current;
-        this.log.debug('toggling hosts: ', this.force.showHosts ? 'Show' : 'Hide');
-    }
-
-    protected toggleOfflineDevices() {
-        // TODO: Implement toggle offline visibility
-        const on: boolean = true;
-        this.flashMsg = this.lionFn(on ? 'show' : 'hide') +
-            ' ' + this.lionFn('fl_offline_devices');
-        this.log.debug('toggling offline devices');
-    }
-
     /**
      * Check to see if this is needed anymore
      * @param what
@@ -474,7 +553,6 @@
     nodeSelected(nodeOrLink: UiElement) {
         this.details.ngOnChanges({'selectedNode':
             new SimpleChange(undefined, nodeOrLink, true)});
-        this.details.on = Boolean(nodeOrLink);
     }
 
     /**