diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/fn.service.spec.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/fn.service.spec.ts
new file mode 100644
index 0000000..5b86d56
--- /dev/null
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/fn.service.spec.ts
@@ -0,0 +1,492 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { TestBed, inject } from '@angular/core/testing';
+
+import { LogService } from '../log.service';
+import { ConsoleLoggerService } from '../consolelogger.service';
+import { FnService } from './fn.service';
+import { ActivatedRoute, Params } from '@angular/router';
+import { of } from 'rxjs';
+import * as d3 from 'd3';
+
+class MockActivatedRoute extends ActivatedRoute {
+    constructor(params: Params) {
+        super();
+        this.queryParams = of(params);
+    }
+}
+
+/**
+ * ONOS GUI -- Util -- General Purpose Functions - Unit Tests
+ */
+describe('FnService', () => {
+    let ar: ActivatedRoute;
+    let fs: FnService;
+    let mockWindow: Window;
+    let logServiceSpy: jasmine.SpyObj<LogService>;
+
+    const someFunction = () => {};
+    const someArray = [1, 2, 3];
+    const someObject = { foo: 'bar'};
+    const someNumber = 42;
+    const someString = 'xyyzy';
+    const someDate = new Date();
+    const stringArray = ['foo', 'bar'];
+
+    beforeEach(() => {
+        const logSpy = jasmine.createSpyObj('LogService', ['debug', 'warn']);
+        ar = new MockActivatedRoute({'debug': 'TestService'});
+        mockWindow = <any>{
+            innerWidth: 400,
+            innerHeight: 200,
+            navigator: {
+                userAgent: 'defaultUA'
+            }
+        };
+
+
+        TestBed.configureTestingModule({
+            providers: [FnService,
+                { provide: LogService, useValue: logSpy },
+                { provide: ActivatedRoute, useValue: ar },
+                { provide: 'Window', useFactory: (() => mockWindow ) }
+            ]
+        });
+
+        fs = TestBed.get(FnService);
+        logServiceSpy = TestBed.get(LogService);
+    });
+
+    it('should be created', () => {
+        expect(fs).toBeTruthy();
+    });
+
+    // === Tests for isF()
+    it('isF(): null for undefined', () => {
+        expect(fs.isF(undefined)).toBeNull();
+    });
+
+    it('isF(): null for null', () => {
+        expect(fs.isF(null)).toBeNull();
+    });
+    it('isF(): the reference for function', () => {
+        expect(fs.isF(someFunction)).toBe(someFunction);
+    });
+    it('isF(): null for string', () => {
+        expect(fs.isF(someString)).toBeNull();
+    });
+    it('isF(): null for number', () => {
+        expect(fs.isF(someNumber)).toBeNull();
+    });
+    it('isF(): null for Date', () => {
+        expect(fs.isF(someDate)).toBeNull();
+    });
+    it('isF(): null for array', () => {
+        expect(fs.isF(someArray)).toBeNull();
+    });
+    it('isF(): null for object', () => {
+        expect(fs.isF(someObject)).toBeNull();
+    });
+
+    // === Tests for isA()
+    it('isA(): null for undefined', () => {
+        expect(fs.isA(undefined)).toBeNull();
+    });
+    it('isA(): null for null', () => {
+        expect(fs.isA(null)).toBeNull();
+    });
+    it('isA(): null for function', () => {
+        expect(fs.isA(someFunction)).toBeNull();
+    });
+    it('isA(): null for string', () => {
+        expect(fs.isA(someString)).toBeNull();
+    });
+    it('isA(): null for number', () => {
+        expect(fs.isA(someNumber)).toBeNull();
+    });
+    it('isA(): null for Date', () => {
+        expect(fs.isA(someDate)).toBeNull();
+    });
+    it('isA(): the reference for array', () => {
+        expect(fs.isA(someArray)).toBe(someArray);
+    });
+    it('isA(): null for object', () => {
+        expect(fs.isA(someObject)).toBeNull();
+    });
+
+    // === Tests for isS()
+    it('isS(): null for undefined', () => {
+        expect(fs.isS(undefined)).toBeNull();
+    });
+    it('isS(): null for null', () => {
+        expect(fs.isS(null)).toBeNull();
+    });
+    it('isS(): null for function', () => {
+        expect(fs.isS(someFunction)).toBeNull();
+    });
+    it('isS(): the reference for string', () => {
+        expect(fs.isS(someString)).toBe(someString);
+    });
+    it('isS(): null for number', () => {
+        expect(fs.isS(someNumber)).toBeNull();
+    });
+    it('isS(): null for Date', () => {
+        expect(fs.isS(someDate)).toBeNull();
+    });
+    it('isS(): null for array', () => {
+        expect(fs.isS(someArray)).toBeNull();
+    });
+    it('isS(): null for object', () => {
+        expect(fs.isS(someObject)).toBeNull();
+    });
+
+    // === Tests for isO()
+    it('isO(): null for undefined', () => {
+        expect(fs.isO(undefined)).toBeNull();
+    });
+    it('isO(): null for null', () => {
+        expect(fs.isO(null)).toBeNull();
+    });
+    it('isO(): null for function', () => {
+        expect(fs.isO(someFunction)).toBeNull();
+    });
+    it('isO(): null for string', () => {
+        expect(fs.isO(someString)).toBeNull();
+    });
+    it('isO(): null for number', () => {
+        expect(fs.isO(someNumber)).toBeNull();
+    });
+    it('isO(): null for Date', () => {
+        expect(fs.isO(someDate)).toBeNull();
+    });
+    it('isO(): null for array', () => {
+        expect(fs.isO(someArray)).toBeNull();
+    });
+    it('isO(): the reference for object', () => {
+        expect(fs.isO(someObject)).toBe(someObject);
+    });
+
+
+    // === Tests for contains()
+    it('contains(): false for non-array', () => {
+        expect(fs.contains(null, 1)).toBeFalsy();
+    });
+    it('contains(): true for contained item', () => {
+        expect(fs.contains(someArray, 1)).toBeTruthy();
+        expect(fs.contains(stringArray, 'bar')).toBeTruthy();
+    });
+    it('contains(): false for non-contained item', () => {
+        expect(fs.contains(someArray, 109)).toBeFalsy();
+        expect(fs.contains(stringArray, 'zonko')).toBeFalsy();
+    });
+
+    // === Tests for areFunctions()
+    it('areFunctions(): true for empty-array', () => {
+        expect(fs.areFunctions({}, [])).toBeTruthy();
+    });
+    it('areFunctions(): true for some api', () => {
+        expect(fs.areFunctions({
+            a: () => {},
+            b: () => {}
+        }, ['b', 'a'])).toBeTruthy();
+    });
+    it('areFunctions(): false for some other api', () => {
+        expect(fs.areFunctions({
+            a: () => {},
+            b: 'not-a-function'
+        }, ['b', 'a'])).toBeFalsy();
+    });
+    it('areFunctions(): extraneous stuff NOT ignored', () => {
+        expect(fs.areFunctions({
+            a: () => {},
+            b: () => {},
+            c: 1,
+            d: 'foo'
+        }, ['a', 'b'])).toBeFalsy();
+    });
+    it('areFunctions(): extraneous stuff ignored (alternate fn)', () => {
+        expect(fs.areFunctionsNonStrict({
+            a: () => {},
+            b: () => {},
+            c: 1,
+            d: 'foo'
+        }, ['a', 'b'])).toBeTruthy();
+    });
+
+    // == use the now-tested areFunctions() on our own api:
+    it('should define api functions', () => {
+        expect(fs.areFunctions(fs, [
+            'isF', 'isA', 'isS', 'isO', 'contains',
+            'areFunctions', 'areFunctionsNonStrict', 'windowSize',
+            'isMobile', 'isChrome', 'isChromeHeadless', 'isSafari',
+            'isFirefox', 'parseDebugFlags',
+            'debugOn', 'debug', 'find', 'inArray', 'removeFromArray',
+            'isEmptyObject', 'cap', 'noPx', 'noPxStyle', 'endsWith',
+            'inEvilList', 'analyze', 'sanitize', 'sameObjProps', 'containsObj'
+//            'find', 'inArray', 'removeFromArray', 'isEmptyObject', 'sameObjProps', 'containsObj', 'cap',
+//            'eecode', 'noPx', 'noPxStyle', 'endsWith', 'addToTrie', 'removeFromTrie', 'trieLookup',
+//            'classNames', 'extend', 'sanitize'
+        ])).toBeTruthy();
+    });
+
+
+    // === Tests for windowSize()
+    it('windowSize(): adjust height', () => {
+        const dim = fs.windowSize(50);
+        expect(dim.width).toEqual(400);
+        expect(dim.height).toEqual(150);
+    });
+
+    it('windowSize(): adjust width', () => {
+        const dim = fs.windowSize(0, 50);
+        expect(dim.width).toEqual(350);
+        expect(dim.height).toEqual(200);
+    });
+
+    it('windowSize(): adjust width and height', () => {
+        const dim = fs.windowSize(101, 201);
+        expect(dim.width).toEqual(199);
+        expect(dim.height).toEqual(99);
+    });
+
+    // === Tests for isMobile()
+    const uaMap = {
+        chrome: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) ' +
+                'AppleWebKit/537.36 (KHTML, like Gecko) ' +
+                'Chrome/41.0.2272.89 Safari/537.36',
+
+        iPad: 'Mozilla/5.0 (iPad; CPU OS 7_0 like Mac OS X) ' +
+                'AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 ' +
+                'Mobile/11A465 Safari/9537.53',
+
+        iPhone: 'Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) ' +
+                'AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 ' +
+                'Mobile/11A465 Safari/9537.53'
+    };
+
+    function setUa(key) {
+        const str = uaMap[key];
+        expect(str).toBeTruthy();
+        (<any>mockWindow.navigator).userAgent = str;
+    }
+
+    it('isMobile(): should be false for Chrome on Mac OS X', () => {
+        setUa('chrome');
+        expect(fs.isMobile()).toBe(false);
+    });
+    it('isMobile(): should be true for Safari on iPad', () => {
+        setUa('iPad');
+        expect(fs.isMobile()).toBe(true);
+    });
+    it('isMobile(): should be true for Safari on iPhone', () => {
+        setUa('iPhone');
+        expect(fs.isMobile()).toBe(true);
+    });
+
+    // === Tests for find()
+    const dataset = [
+        { id: 'foo', name: 'Furby'},
+        { id: 'bar', name: 'Barbi'},
+        { id: 'baz', name: 'Basil'},
+        { id: 'goo', name: 'Gabby'},
+        { id: 'zoo', name: 'Zevvv'}
+    ];
+
+    it('should not find ooo', () => {
+        expect(fs.find('ooo', dataset)).toEqual(-1);
+    });
+    it('should find foo', () => {
+        expect(fs.find('foo', dataset)).toEqual(0);
+    });
+    it('should find zoo', () => {
+        expect(fs.find('zoo', dataset)).toEqual(4);
+    });
+
+    it('should not find Simon', () => {
+        expect(fs.find('Simon', dataset, 'name')).toEqual(-1);
+    });
+    it('should find Furby', () => {
+        expect(fs.find('Furby', dataset, 'name')).toEqual(0);
+    });
+    it('should find Zevvv', () => {
+        expect(fs.find('Zevvv', dataset, 'name')).toEqual(4);
+    });
+
+
+    // === Tests for inArray()
+    const objRef = { x: 1, y: 2 };
+    const array = [1, 3.14, 'hey', objRef, 'there', true];
+    const array2 = ['b', 'a', 'd', 'a', 's', 's'];
+
+    it('should not find HOO', () => {
+        expect(fs.inArray('HOO', array)).toEqual(-1);
+    });
+    it('should find 1', () => {
+        expect(fs.inArray(1, array)).toEqual(0);
+    });
+    it('should find pi', () => {
+        expect(fs.inArray(3.14, array)).toEqual(1);
+    });
+    it('should find hey', () => {
+        expect(fs.inArray('hey', array)).toEqual(2);
+    });
+    it('should find the object', () => {
+        expect(fs.inArray(objRef, array)).toEqual(3);
+    });
+    it('should find there', () => {
+        expect(fs.inArray('there', array)).toEqual(4);
+    });
+    it('should find true', () => {
+        expect(fs.inArray(true, array)).toEqual(5);
+    });
+
+    it('should find the first occurrence A', () => {
+        expect(fs.inArray('a', array2)).toEqual(1);
+    });
+    it('should find the first occurrence S', () => {
+        expect(fs.inArray('s', array2)).toEqual(4);
+    });
+    it('should not find X', () => {
+        expect(fs.inArray('x', array2)).toEqual(-1);
+    });
+
+    // === Tests for removeFromArray()
+    it('should keep the array the same, for non-match', () => {
+        const array1 = [1, 2, 3];
+        expect(fs.removeFromArray(4, array1)).toBe(false);
+        expect(array1).toEqual([1, 2, 3]);
+    });
+    it('should remove a value', () => {
+        const array1a = [1, 2, 3];
+        expect(fs.removeFromArray(2, array1a)).toBe(true);
+        expect(array1a).toEqual([1, 3]);
+    });
+    it('should remove the first occurrence', () => {
+        const array1b = ['x', 'y', 'z', 'z', 'y'];
+        expect(fs.removeFromArray('y', array1b)).toBe(true);
+        expect(array1b).toEqual(['x', 'z', 'z', 'y']);
+        expect(fs.removeFromArray('x', array1b)).toBe(true);
+        expect(array1b).toEqual(['z', 'z', 'y']);
+    });
+
+    // === Tests for isEmptyObject()
+    it('should return true if an object is empty', () => {
+        expect(fs.isEmptyObject({})).toBe(true);
+    });
+    it('should return false if an object is not empty', () => {
+        expect(fs.isEmptyObject({foo: 'bar'})).toBe(false);
+    });
+
+    // === Tests for cap()
+    it('should ignore non-alpha', () => {
+        expect(fs.cap('123')).toEqual('123');
+    });
+    it('should capitalize first char', () => {
+        expect(fs.cap('Foo')).toEqual('Foo');
+        expect(fs.cap('foo')).toEqual('Foo');
+        expect(fs.cap('foo bar')).toEqual('Foo bar');
+        expect(fs.cap('FOO BAR')).toEqual('Foo bar');
+        expect(fs.cap('foo Bar')).toEqual('Foo bar');
+    });
+
+    // === Tests for noPx()
+    it('should return the value without px suffix', () => {
+        expect(fs.noPx('10px')).toBe(10);
+        expect(fs.noPx('500px')).toBe(500);
+        expect(fs.noPx('-80px')).toBe(-80);
+    });
+
+    // === Tests for noPxStyle()
+    it('should give a style\'s property without px suffix', () => {
+        const d3Elem = d3.select('body')
+            .append('div')
+            .attr('id', 'fooElem')
+            .style('width', '500px')
+            .style('height', '200px')
+            .style('font-size', '12px');
+        expect(fs.noPxStyle(d3Elem, 'width')).toBe(500);
+        expect(fs.noPxStyle(d3Elem, 'height')).toBe(200);
+        expect(fs.noPxStyle(d3Elem, 'font-size')).toBe(12);
+        d3.select('#fooElem').remove();
+    });
+
+    // === Tests for endsWith()
+    it('should return true if string ends with foo', () => {
+        expect(fs.endsWith('barfoo', 'foo')).toBe(true);
+    });
+
+    it('should return false if string doesnt end with foo', () => {
+        expect(fs.endsWith('barfood', 'foo')).toBe(false);
+    });
+
+    // === Tests for sanitize()
+    it('should return foo', () => {
+        expect(fs.sanitize('foo')).toEqual('foo');
+    });
+    it('should retain < b > tags', () => {
+        const str = 'foo <b>bar</b> baz';
+        expect(fs.sanitize(str)).toEqual(str);
+    });
+    it('should retain < i > tags', () => {
+        const str = 'foo <i>bar</i> baz';
+        expect(fs.sanitize(str)).toEqual(str);
+    });
+    it('should retain < p > tags', () => {
+        const str = 'foo <p>bar</p> baz';
+        expect(fs.sanitize(str)).toEqual(str);
+    });
+    it('should retain < em > tags', () => {
+        const str = 'foo <em>bar</em> baz';
+        expect(fs.sanitize(str)).toEqual(str);
+    });
+    it('should retain < strong > tags', () => {
+        const str = 'foo <strong>bar</strong> baz';
+        expect(fs.sanitize(str)).toEqual(str);
+    });
+
+    it('should reject < a > tags', () => {
+        expect(fs.sanitize('test <a href="hah">something</a> this'))
+            .toEqual('test something this');
+    });
+
+    it('should log a warning for < script > tags', () => {
+        expect(fs.sanitize('<script>alert("foo");</script>'))
+            .toEqual('');
+        expect(logServiceSpy.warn).toHaveBeenCalledWith(
+            'Unsanitary HTML input -- <script> detected!'
+        );
+    });
+    it('should log a warning for < style > tags', () => {
+        expect(fs.sanitize('<style> h1 {color:red;} </style>'))
+            .toEqual('');
+        expect(logServiceSpy.warn).toHaveBeenCalledWith(
+            'Unsanitary HTML input -- <style> detected!'
+        );
+    });
+
+    it('should log a warning for < iframe > tags', () => {
+        expect(fs.sanitize('Foo<iframe><body><h1>fake</h1></body></iframe>Bar'))
+            .toEqual('FooBar');
+        expect(logServiceSpy.warn).toHaveBeenCalledWith(
+            'Unsanitary HTML input -- <iframe> detected!'
+        );
+    });
+
+    it('should completely strip < script >, remove < a >, retain < i >', () => {
+        expect(fs.sanitize('Hey <i>this</i> is <script>alert("foo");</script> <a href="meh">cool</a>'))
+            .toEqual('Hey <i>this</i> is  cool');
+    });
+});
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/fn.service.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/fn.service.ts
new file mode 100644
index 0000000..506ce74
--- /dev/null
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/fn.service.ts
@@ -0,0 +1,564 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Injectable, Inject } from '@angular/core';
+import { ActivatedRoute, Router} from '@angular/router';
+import { LogService } from '../log.service';
+
+// Angular>=2 workaround for missing definition
+declare const InstallTrigger: any;
+
+const matcher = /<\/?([a-zA-Z0-9]+)*(.*?)\/?>/igm;
+const whitelist: string[] = ['b', 'i', 'p', 'em', 'strong', 'br'];
+const evillist: string[] = ['script', 'style', 'iframe'];
+
+/**
+ * Used with the Window size function;
+ **/
+export interface WindowSize {
+    width: number;
+    height: number;
+}
+
+/**
+ * For the sanitize() and analyze() functions
+ */
+export interface Match {
+    full: string;
+    name: string;
+}
+
+// TODO Move all this trie stuff to its own class
+// Angular>=2 Tightened up on types to avoid compiler errors
+interface TrieC {
+    p: any;
+    s: string[];
+}
+// trie operation
+function _trieOp(op: string, trie, word: string, data) {
+    const p = trie;
+    const w: string = word.toUpperCase();
+    const s: Array<string> = w.split('');
+    let c: TrieC = { p: p, s: s };
+    let t = [];
+    let  x = 0;
+    const f1 = op === '+' ? add : probe;
+    const f2 = op === '+' ? insert : remove;
+
+    function add(cAdded): TrieC {
+        const q = cAdded.s.shift();
+        let np = cAdded.p[q];
+
+        if (!np) {
+            cAdded.p[q] = {};
+            np = cAdded.p[q];
+            x = 1;
+        }
+        return { p: np, s: cAdded.s };
+    }
+
+    function probe(cProbed): TrieC {
+        const q = cProbed.s.shift();
+        const k: number = Object.keys(cProbed.p).length;
+        const np = cProbed.p[q];
+
+        t.push({ q: q, k: k, p: cProbed.p });
+        if (!np) {
+            t = [];
+            return { p: [], s: [] };
+        }
+        return { p: np, s: cProbed.s };
+    }
+
+    function insert() {
+        c.p._data = data;
+        return x ? 'added' : 'updated';
+    }
+
+    function remove() {
+        if (t.length) {
+            t = t.reverse();
+            while (t.length) {
+                const d = t.shift();
+                delete d.p[d.q];
+                if (d.k > 1) {
+                    t = [];
+                }
+            }
+            return 'removed';
+        }
+        return 'absent';
+    }
+
+    while (c.s.length) {
+        c = f1(c);
+    }
+    return f2();
+}
+
+// add word to trie (word will be converted to uppercase)
+// data associated with the word
+// returns 'added' or 'updated'
+function addToTrie(trie, word, data) {
+    return _trieOp('+', trie, word, data);
+}
+
+// remove word from trie (word will be converted to uppercase)
+// returns 'removed' or 'absent'
+// Angular>=2 added in quotes for data. error TS2554: Expected 4 arguments, but got 3.
+function removeFromTrie(trie, word) {
+    return _trieOp('-', trie, word, '');
+}
+
+// lookup word (converted to uppercase) in trie
+// returns:
+//    undefined if the word is not in the trie
+//    -1 for a partial match (word is a prefix to an existing word)
+//    data for the word for an exact match
+function trieLookup(trie, word) {
+    const s = word.toUpperCase().split('');
+    let p = trie;
+    let n;
+
+    while (s.length) {
+        n = s.shift();
+        p = p[n];
+        if (!p) {
+            return undefined;
+        }
+    }
+    if (p._data) {
+        return p._data;
+    }
+    return -1;
+}
+
+
+/**
+ * ONOS GUI -- Util -- General Purpose Functions
+ */
+@Injectable({
+  providedIn: 'root',
+})
+export class FnService {
+    // internal state
+    private debugFlags = new Map<string, boolean>([
+//        [ "LoadingService", true ]
+    ]);
+
+    constructor(
+        private route: ActivatedRoute,
+        private log: LogService,
+        // TODO: Change the any type to Window when https://github.com/angular/angular/issues/15640 is fixed.
+        @Inject('Window') private w: any
+    ) {
+        this.route.queryParams.subscribe(params => {
+            const debugparam: string = params['debug'];
+//            log.debug('Param:', debugparam);
+            this.parseDebugFlags(debugparam);
+        });
+//        this.log.debug('FnService constructed');
+    }
+
+    /**
+     * Test if an argument is a function
+     *
+     * Note: the need for this would go away if all functions
+     * were strongly typed
+     */
+    isF(f: any): any {
+        return typeof f === 'function' ? f : null;
+    }
+
+    /**
+     * Test if an argument is an array
+     *
+     * Note: the need for this would go away if all arrays
+     * were strongly typed
+     */
+    isA(a: any): any {
+    // NOTE: Array.isArray() is part of EMCAScript 5.1
+        return Array.isArray(a) ? a : null;
+    }
+
+    /**
+     * Test if an argument is a string
+     *
+     * Note: the need for this would go away if all strings
+     * were strongly typed
+     */
+    isS(s: any): string {
+        return typeof s === 'string' ? s : null;
+    }
+
+    /**
+     * Test if an argument is an object
+     *
+     * Note: the need for this would go away if all objects
+     * were strongly typed
+     */
+    isO(o: any): Object {
+        return (o && typeof o === 'object' && o.constructor === Object) ? o : null;
+    }
+
+    /**
+     * Test that an array contains an object
+     */
+    contains(a: any[], x: any): boolean {
+        return this.isA(a) && a.indexOf(x) > -1;
+    }
+
+    /**
+     * Returns width and height of window inner dimensions.
+     * offH, offW : offset width/height are subtracted, if present
+     */
+    windowSize(offH: number = 0, offW: number = 0): WindowSize {
+        return {
+            height: this.w.innerHeight - offH,
+            width: this.w.innerWidth - offW
+        };
+    }
+
+    /**
+     * Returns true if all names in the array are defined as functions
+     * on the given api object; false otherwise.
+     * Also returns false if there are properties on the api that are NOT
+     * listed in the array of names.
+     *
+     * This gets extra complicated when the api Object is an
+     * Angular service - while the functions can be retrieved
+     * by an indexed get, the ownProperties does not show the
+     * functions of the class. We have to dive in to the prototypes
+     * properties to get these - and even then we have to filter
+     * out the constructor and any member variables
+     */
+    areFunctions(api: Object, fnNames: string[]): boolean {
+        const fnLookup: Map<string, boolean> = new Map();
+        let extraFound: boolean = false;
+
+        if (!this.isA(fnNames)) {
+            return false;
+        }
+
+        const n: number = fnNames.length;
+        let i: number;
+        let name: string;
+
+        for (i = 0; i < n; i++) {
+            name = fnNames[i];
+            if (!this.isF(api[name])) {
+                return false;
+            }
+            fnLookup.set(name, true);
+        }
+
+        // check for properties on the API that are not listed in the array,
+        const keys = Object.getOwnPropertyNames(api);
+        if (keys.length === 0) {
+            return true;
+        }
+        // If the api is a class it will have a name,
+        //  else it will just be called 'Object'
+        const apiObjectName: string = api.constructor.name;
+        if (apiObjectName === 'Object') {
+            Object.keys(api).forEach((key) => {
+                if (!fnLookup.get(key)) {
+                    extraFound = true;
+                }
+            });
+        } else { // It is a class, so its functions will be in the child (prototype)
+            const pObj: Object = Object.getPrototypeOf(api);
+            for ( const key in Object.getOwnPropertyDescriptors(pObj) ) {
+                if (key === 'constructor') { // Filter out constructor
+                    continue;
+                }
+                const value = Object.getOwnPropertyDescriptor(pObj, key);
+                // Only compare functions. Look for any not given in the map
+                if (this.isF(value.value) && !fnLookup.get(key)) {
+                    extraFound = true;
+                }
+            }
+        }
+        return !extraFound;
+    }
+
+    /**
+     * Returns true if all names in the array are defined as functions
+     * on the given api object; false otherwise. This is a non-strict version
+     * that does not care about other properties on the api.
+     */
+    areFunctionsNonStrict(api, fnNames): boolean {
+        if (!this.isA(fnNames)) {
+            return false;
+        }
+        const n = fnNames.length;
+        let i;
+        let name;
+
+        for (i = 0; i < n; i++) {
+            name = fnNames[i];
+            if (!this.isF(api[name])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns true if current browser determined to be a mobile device
+     */
+    isMobile() {
+        const ua = this.w.navigator.userAgent;
+        const patt = /iPhone|iPod|iPad|Silk|Android|BlackBerry|Opera Mini|IEMobile/;
+        return patt.test(ua);
+    }
+
+    /**
+     * Returns true if the current browser determined to be Chrome
+     */
+    isChrome() {
+        const isChromium = (this.w as any).chrome;
+        const vendorName = this.w.navigator.vendor;
+
+        const isOpera = this.w.navigator.userAgent.indexOf('OPR') > -1;
+        return (isChromium !== null &&
+        isChromium !== undefined &&
+        vendorName === 'Google Inc.' &&
+        isOpera === false);
+    }
+
+    isChromeHeadless() {
+        const vendorName = this.w.navigator.vendor;
+        const headlessChrome = this.w.navigator.userAgent.indexOf('HeadlessChrome') > -1;
+
+        return (vendorName === 'Google Inc.' && headlessChrome === true);
+    }
+
+    /**
+     * Returns true if the current browser determined to be Safari
+     */
+    isSafari() {
+        return (this.w.navigator.userAgent.indexOf('Safari') !== -1 &&
+        this.w.navigator.userAgent.indexOf('Chrome') === -1);
+    }
+
+    /**
+     * Returns true if the current browser determined to be Firefox
+     */
+    isFirefox() {
+        return typeof InstallTrigger !== 'undefined';
+    }
+
+    /**
+     * search through an array of objects, looking for the one with the
+     * tagged property matching the given key. tag defaults to 'id'.
+     * returns the index of the matching object, or -1 for no match.
+     */
+    find(key: string, array: Object[], tag: string = 'id'): number {
+        let idx: number;
+        const n: number = array.length;
+
+        for (idx = 0 ; idx < n; idx++) {
+            const d: Object = array[idx];
+            if (d[tag] === key) {
+                return idx;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * search through array to find (the first occurrence of) item,
+     * returning its index if found; otherwise returning -1.
+     */
+    inArray(item: any, array: any[]): number {
+        if (this.isA(array)) {
+            for (let i = 0; i < array.length; i++) {
+                if (array[i] === item) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * remove (the first occurrence of) the specified item from the given
+     * array, if any. Return true if the removal was made; false otherwise.
+     */
+    removeFromArray(item: any, array: any[]): boolean {
+        const i: number = this.inArray(item, array);
+        if (i >= 0) {
+            array.splice(i, 1);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * return true if the object is empty, return false otherwise
+     */
+    isEmptyObject(obj: Object): boolean {
+        for (const key in obj) {
+            if (true) { return false; }
+        }
+        return true;
+    }
+
+    /**
+     * returns true if the two objects have all the same properties
+     */
+    sameObjProps(obj1: Object, obj2: Object): boolean {
+        for (const key in obj1) {
+            if (obj1.hasOwnProperty(key)) {
+                if (!(obj1[key] === obj2[key])) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * returns true if the array contains the object
+     * does NOT use strict object reference equality,
+     * instead checks each property individually for equality
+     */
+    containsObj(arr: any[], obj: Object): boolean {
+        const len = arr.length;
+        for (let i = 0; i < len; i++) {
+            if (this.sameObjProps(arr[i], obj)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Return the given string with the first character capitalized.
+     */
+    cap(s: string): string {
+        return s ? s[0].toUpperCase() + s.slice(1).toLowerCase() : s;
+    }
+
+    /**
+     * return the parameter without a px suffix
+     */
+    noPx(num: string): number {
+        return Number(num.replace(/px$/, ''));
+    }
+
+    /**
+     * return an element's given style property without px suffix
+     */
+    noPxStyle(elem: any, prop: string): number {
+        return Number(elem.style(prop).replace(/px$/, ''));
+    }
+
+    /**
+     * Return true if a str ends with suffix
+     */
+    endsWith(str: string, suffix: string) {
+        return str.indexOf(suffix, str.length - suffix.length) !== -1;
+    }
+
+    /**
+     * output debug message to console, if debug tag set...
+     * e.g. fs.debug('mytag', arg1, arg2, ...)
+     */
+    debug(tag, ...args) {
+        if (this.debugFlags.get(tag)) {
+//            this.log.debug(tag, args.join());
+        }
+    }
+
+    private parseDebugFlags(dbgstr: string): void {
+        const bits = dbgstr ? dbgstr.split(',') : [];
+        bits.forEach((key) => {
+            this.debugFlags.set(key, true);
+        });
+//        this.log.debug('Debug flags:', dbgstr);
+    }
+
+    /**
+      * Return true if the given debug flag was specified in the query params
+      */
+    debugOn(tag: string): boolean {
+        return this.debugFlags.get(tag);
+    }
+
+
+
+    // -----------------------------------------------------------------
+    // The next section deals with sanitizing external strings destined
+    // to be loaded via a .html() function call.
+    //
+    // See definition of matcher, evillist and whitelist at the top of this file
+
+    /*
+     * Returns true if the tag is in the evil list, (and is not an end-tag)
+     */
+    inEvilList(tag: any): boolean {
+        return (evillist.indexOf(tag.name) !== -1 && tag.full.indexOf('/') === -1);
+    }
+
+    /*
+     * Returns an array of Matches of matcher in html
+     */
+    analyze(html: string): Match[] {
+        const matches: Match[] = [];
+        let match;
+
+        // extract all tags
+        while ((match = matcher.exec(html)) !== null) {
+            matches.push({
+                full: match[0],
+                name: match[1],
+                // NOTE: ignoring attributes {match[2].split(' ')} for now
+            });
+        }
+
+        return matches;
+    }
+
+    /*
+     * Returns a cleaned version of html
+     */
+    sanitize(html: string): string {
+        const matches: Match[] = this.analyze(html);
+
+        // completely obliterate evil tags and their contents...
+        evillist.forEach((tag) => {
+            const re = new RegExp('<' + tag + '(.*?)>(.*?[\r\n])*?(.*?)(.*?[\r\n])*?<\/' + tag + '>', 'gim');
+            html = html.replace(re, '');
+        });
+
+        // filter out all but white-listed tags and end-tags
+        matches.forEach((tag) => {
+            if (whitelist.indexOf(tag.name) === -1) {
+                html = html.replace(tag.full, '');
+                if (this.inEvilList(tag)) {
+                    this.log.warn('Unsanitary HTML input -- ' +
+                        tag.full + ' detected!');
+                }
+            }
+        });
+
+        // TODO: consider encoding HTML entities, e.g. '&' -> '&amp;'
+
+        return html;
+    }
+
+}
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/lion.service.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/lion.service.ts
new file mode 100644
index 0000000..b8cde73
--- /dev/null
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/lion.service.ts
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+import { Injectable } from '@angular/core';
+import { LogService } from '../log.service';
+import { WebSocketService } from '../remote/websocket.service';
+
+/**
+ * A definition of Lion data
+ */
+export interface Lion {
+    locale: any;
+    lion: any;
+}
+
+/**
+ * ONOS GUI -- Lion -- Localization Utilities
+ */
+@Injectable({
+  providedIn: 'root',
+})
+export class LionService {
+
+    ubercache: any[] = [];
+    loadCbs = new Map<string, () => void>([]); // A map of functions
+
+    /**
+     * Handler for uberlion event from WSS
+     */
+    uberlion(data: Lion) {
+        this.ubercache = data.lion;
+
+        this.log.info('LION service: Locale... [' + data.locale + ']');
+        this.log.info('LION service: Bundles installed...');
+
+        for (const p in this.ubercache) {
+            if (this.ubercache[p]) {
+                this.log.info('            :=> ', p);
+            }
+        }
+        // If any component had registered a callback, call it now
+        // that LION is loaded
+        for (const cbname of this.loadCbs.keys()) {
+            this.log.debug('Updating', cbname, 'with LION');
+            this.loadCbs.get(cbname)();
+        }
+
+        this.log.debug('LION service: uber-lion bundle received:', data);
+    }
+
+    constructor(
+        private log: LogService,
+        private wss: WebSocketService
+    ) {
+        this.wss.bindHandlers(new Map<string, (data) => void>([
+            ['uberlion', (data) => this.uberlion(data) ]
+        ]));
+        this.log.debug('LionService constructed');
+    }
+
+    /**
+     * Returns a lion bundle (function) for the given bundle ID (string)
+     * returns a function that takes a string and returns a string
+     */
+    bundle(bundleId: string): (string) => string {
+        let bundleObj = this.ubercache[bundleId];
+
+        if (!bundleObj) {
+            this.log.warn('No lion bundle registered:', bundleId);
+            bundleObj = {};
+        }
+
+        return (key) =>  {
+            return bundleObj[key] || '%' + key + '%';
+        };
+    }
+}
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
new file mode 100644
index 0000000..8145921
--- /dev/null
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/prefs.service.ts
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Injectable } from '@angular/core';
+import { FnService } from './fn.service';
+import { LogService } from '../log.service';
+import { WebSocketService } from '../remote/websocket.service';
+
+/**
+ * ONOS GUI -- Util -- User Preference Service
+ */
+@Injectable({
+    providedIn: 'root',
+})
+export class PrefsService {
+    protected Prefs;
+    protected handlers: string[] = [];
+    cache: any;
+    listeners: any;
+    constructor(
+        protected fs: FnService,
+        protected log: LogService,
+        protected wss: WebSocketService
+    ) {
+        this.cache = {};
+        this.wss.bindHandlers(new Map<string, (data) => void>([
+            [this.Prefs, (data) => this.updatePrefs(data)]
+        ]));
+        this.handlers.push(this.Prefs);
+
+        this.log.debug('PrefsService constructed');
+    }
+
+    setPrefs(name: string, obj: any) {
+        // 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 });
+    }
+    updatePrefs(data: any) {
+        this.cache = data;
+        this.listeners.forEach(function (lsnr) { lsnr(); });
+    }
+
+    asNumbers(obj: any, keys?: any, not?: any) {
+        if (!obj) {
+            return null;
+        }
+
+        const skip = {};
+        if (not) {
+            keys.forEach(k => {
+                skip[k] = 1;
+            }
+            );
+        }
+
+        if (!keys || not) {
+            // do them all
+            Array.from(obj).forEach((v, k) => {
+                if (!not || !skip[k]) {
+                    obj[k] = Number(obj[k]);
+                }
+            });
+        } else {
+            // do the explicitly named keys
+            keys.forEach(k => {
+                obj[k] = Number(obj[k]);
+            });
+        }
+        return obj;
+    }
+
+    getPrefs(name: string, defaults: any, qparams?: string) {
+        const obj = Object.assign({}, defaults || {}, this.cache[name] || {});
+
+        // if query params are specified, they override...
+        if (this.fs.isO(qparams)) {
+            obj.forEach(k => {
+                if (qparams.hasOwnProperty(k)) {
+                    obj[k] = qparams[k];
+                }
+            });
+        }
+        return obj;
+    }
+
+    // merge preferences:
+    // The assumption here is that obj is a sparse object, and that the
+    //  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) {
+        const merged = this.cache[name] || {};
+        this.setPrefs(name, Object.assign(merged, obj));
+    }
+
+    addListener(listener: any) {
+        this.listeners.push(listener);
+    }
+
+    removeListener(listener: any) {
+        this.listeners = this.listeners.filter(function (obj) { return obj === listener; });
+    }
+
+}
diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/theme.service.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/theme.service.ts
new file mode 100644
index 0000000..993d9f3
--- /dev/null
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/theme.service.ts
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Injectable } from '@angular/core';
+import { LogService } from '../log.service';
+
+
+/**
+ * ONOS GUI -- Util -- Theme Service
+ */
+@Injectable({
+  providedIn: 'root',
+})
+export class ThemeService {
+    themes: string[] = ['light', 'dark'];
+    thidx = 0;
+
+    constructor(
+        private log: LogService
+    ) {
+        this.log.debug('ThemeService constructed');
+    }
+
+    getTheme(): string {
+        return this.themes[this.thidx];
+    }
+
+    themeStr(): string {
+        return this.themes.join(' ');
+    }
+
+}
