Bug 1350646: Part 10 - Remove SDK tabs/windows modules. r=Mossop
☠☠ backed out by 9f7d0c809762 ☠ ☠
authorKris Maglione <maglione.k@gmail.com>
Sat, 05 Aug 2017 22:02:47 -0700
changeset 373639 57500d9ea8321c962ec6748082b1a084c928550f
parent 373638 5a45d9e25a007c6ab18bd8da4a41f0fe3b9318c0
child 373640 096ff315b48b51aae1863b687fff74707e8e04c3
push id93571
push usermaglione.k@gmail.com
push dateWed, 09 Aug 2017 22:31:31 +0000
treeherdermozilla-inbound@c3108aebee35 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMossop
bugs1350646
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1350646: Part 10 - Remove SDK tabs/windows modules. r=Mossop MozReview-Commit-ID: 4VlwKUNXo8O
addon-sdk/moz.build
addon-sdk/source/lib/framescript/FrameScriptManager.jsm
addon-sdk/source/lib/framescript/content.jsm
addon-sdk/source/lib/framescript/manager.js
addon-sdk/source/lib/framescript/util.js
addon-sdk/source/lib/sdk/content/content-worker.js
addon-sdk/source/lib/sdk/content/content.js
addon-sdk/source/lib/sdk/content/sandbox.js
addon-sdk/source/lib/sdk/content/sandbox/events.js
addon-sdk/source/lib/sdk/content/tab-events.js
addon-sdk/source/lib/sdk/content/worker-child.js
addon-sdk/source/lib/sdk/content/worker.js
addon-sdk/source/lib/sdk/deprecated/sync-worker.js
addon-sdk/source/lib/sdk/deprecated/unit-test.js
addon-sdk/source/lib/sdk/loader/sandbox.js
addon-sdk/source/lib/sdk/remote/child.js
addon-sdk/source/lib/sdk/remote/core.js
addon-sdk/source/lib/sdk/remote/parent.js
addon-sdk/source/lib/sdk/remote/utils.js
addon-sdk/source/lib/sdk/selection.js
addon-sdk/source/lib/sdk/tab/events.js
addon-sdk/source/lib/sdk/tabs.js
addon-sdk/source/lib/sdk/tabs/common.js
addon-sdk/source/lib/sdk/tabs/events.js
addon-sdk/source/lib/sdk/tabs/helpers.js
addon-sdk/source/lib/sdk/tabs/namespace.js
addon-sdk/source/lib/sdk/tabs/observer.js
addon-sdk/source/lib/sdk/tabs/tab-fennec.js
addon-sdk/source/lib/sdk/tabs/tab-firefox.js
addon-sdk/source/lib/sdk/tabs/tab.js
addon-sdk/source/lib/sdk/tabs/tabs-firefox.js
addon-sdk/source/lib/sdk/tabs/utils.js
addon-sdk/source/lib/sdk/tabs/worker.js
addon-sdk/source/lib/sdk/test/utils.js
addon-sdk/source/lib/sdk/window/browser.js
addon-sdk/source/lib/sdk/window/events.js
addon-sdk/source/lib/sdk/window/helpers.js
addon-sdk/source/lib/sdk/window/namespace.js
addon-sdk/source/lib/sdk/windows.js
addon-sdk/source/lib/sdk/windows/fennec.js
addon-sdk/source/lib/sdk/windows/firefox.js
addon-sdk/source/lib/sdk/windows/observer.js
addon-sdk/source/lib/sdk/windows/tabs-fennec.js
addon-sdk/source/lib/sdk/worker/utils.js
--- a/addon-sdk/moz.build
+++ b/addon-sdk/moz.build
@@ -16,47 +16,36 @@ EXTRA_JS_MODULES.sdk += [
     'source/app-extension/bootstrap.js',
 ]
 
 EXTRA_JS_MODULES.sdk.system += [
     'source/modules/system/Startup.js',
 ]
 
 modules = [
-    'framescript/FrameScriptManager.jsm',
-    'framescript/content.jsm',
-    'framescript/manager.js',
-    'framescript/util.js',
     'index.js',
     'jetpack-id/index.js',
     'method/core.js',
     'method/test/browser.js',
     'method/test/common.js',
     'mozilla-toolkit-versioning/index.js',
     'mozilla-toolkit-versioning/lib/utils.js',
     'node/os.js',
     'sdk/addon/installer.js',
     'sdk/addon/window.js',
     'sdk/base64.js',
     'sdk/browser/events.js',
     'sdk/clipboard.js',
     'sdk/console/plain-text.js',
     'sdk/console/traceback.js',
-    'sdk/content/content-worker.js',
-    'sdk/content/content.js',
     'sdk/content/events.js',
     'sdk/content/loader.js',
     'sdk/content/mod.js',
-    'sdk/content/sandbox.js',
-    'sdk/content/sandbox/events.js',
-    'sdk/content/tab-events.js',
     'sdk/content/thumbnail.js',
     'sdk/content/utils.js',
-    'sdk/content/worker-child.js',
-    'sdk/content/worker.js',
     'sdk/core/disposable.js',
     'sdk/core/heritage.js',
     'sdk/core/namespace.js',
     'sdk/core/observer.js',
     'sdk/core/promise.js',
     'sdk/core/reference.js',
     'sdk/deprecated/api-utils.js',
     'sdk/deprecated/events/assembler.js',
@@ -97,50 +86,32 @@ modules = [
     'sdk/passwords/utils.js',
     'sdk/platform/xpcom.js',
     'sdk/preferences/event-target.js',
     'sdk/preferences/service.js',
     'sdk/preferences/utils.js',
     'sdk/private-browsing.js',
     'sdk/private-browsing/utils.js',
     'sdk/querystring.js',
-    'sdk/remote/child.js',
-    'sdk/remote/core.js',
-    'sdk/remote/parent.js',
-    'sdk/remote/utils.js',
     'sdk/request.js',
-    'sdk/selection.js',
     'sdk/self.js',
     'sdk/simple-prefs.js',
     'sdk/simple-storage.js',
     'sdk/stylesheet/style.js',
     'sdk/stylesheet/utils.js',
     'sdk/system.js',
     'sdk/system/environment.js',
     'sdk/system/events-shimmed.js',
     'sdk/system/events.js',
     'sdk/system/globals.js',
     'sdk/system/process.js',
     'sdk/system/runtime.js',
     'sdk/system/unload.js',
     'sdk/system/xul-app.js',
     'sdk/system/xul-app.jsm',
-    'sdk/tab/events.js',
-    'sdk/tabs.js',
-    'sdk/tabs/common.js',
-    'sdk/tabs/events.js',
-    'sdk/tabs/helpers.js',
-    'sdk/tabs/namespace.js',
-    'sdk/tabs/observer.js',
-    'sdk/tabs/tab-fennec.js',
-    'sdk/tabs/tab-firefox.js',
-    'sdk/tabs/tab.js',
-    'sdk/tabs/tabs-firefox.js',
-    'sdk/tabs/utils.js',
-    'sdk/tabs/worker.js',
     'sdk/test.js',
     'sdk/test/assert.js',
     'sdk/test/harness.js',
     'sdk/test/httpd.js',
     'sdk/test/loader.js',
     'sdk/test/memory.js',
     'sdk/test/options.js',
     'sdk/test/runner.js',
@@ -154,27 +125,17 @@ modules = [
     'sdk/util/contract.js',
     'sdk/util/deprecate.js',
     'sdk/util/dispatcher.js',
     'sdk/util/list.js',
     'sdk/util/object.js',
     'sdk/util/sequence.js',
     'sdk/util/uuid.js',
     'sdk/view/core.js',
-    'sdk/window/browser.js',
-    'sdk/window/events.js',
-    'sdk/window/helpers.js',
-    'sdk/window/namespace.js',
     'sdk/window/utils.js',
-    'sdk/windows.js',
-    'sdk/windows/fennec.js',
-    'sdk/windows/firefox.js',
-    'sdk/windows/observer.js',
-    'sdk/windows/tabs-fennec.js',
-    'sdk/worker/utils.js',
     'sdk/zip/utils.js',
     'test.js',
     'toolkit/loader.js',
     'toolkit/require.js',
 ]
 
 commonjs = EXTRA_JS_MODULES.commonjs
 
deleted file mode 100644
--- a/addon-sdk/source/lib/framescript/FrameScriptManager.jsm
+++ /dev/null
@@ -1,27 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-const globalMM = Components.classes["@mozilla.org/globalmessagemanager;1"].
-                 getService(Components.interfaces.nsIMessageListenerManager);
-
-// Load frame scripts from the same dir as this module.
-// Since this JSM will be loaded using require(), PATH will be
-// overridden while running tests, just like any other module.
-const PATH = __URI__.replace('framescript/FrameScriptManager.jsm', '');
-
-// Builds a unique loader ID for this runtime. We prefix with the SDK path so
-// overriden versions of the SDK don't conflict
-var LOADER_ID = 0;
-this.getNewLoaderID = () => {
-  return PATH + ":" + LOADER_ID++;
-}
-
-const frame_script = function(contentFrame, PATH) {
-  let { registerContentFrame } = Components.utils.import(PATH + 'framescript/content.jsm', {});
-  registerContentFrame(contentFrame);
-}
-globalMM.loadFrameScript("data:,(" + frame_script.toString() + ")(this, " + JSON.stringify(PATH) + ");", true);
-
-this.EXPORTED_SYMBOLS = ['getNewLoaderID'];
deleted file mode 100644
--- a/addon-sdk/source/lib/framescript/content.jsm
+++ /dev/null
@@ -1,94 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-const { utils: Cu, classes: Cc, interfaces: Ci } = Components;
-const { Services } = Cu.import('resource://gre/modules/Services.jsm');
-
-const cpmm = Cc['@mozilla.org/childprocessmessagemanager;1'].
-             getService(Ci.nsISyncMessageSender);
-
-this.EXPORTED_SYMBOLS = ["registerContentFrame"];
-
-// This may be an overriden version of the SDK so use the PATH as a key for the
-// initial messages before we have a loaderID.
-const PATH = __URI__.replace('framescript/content.jsm', '');
-
-const { Loader } = Cu.import(PATH + 'toolkit/loader.js', {});
-
-// one Loader instance per addon (per @loader/options to be precise)
-var addons = new Map();
-
-// Tell the parent that a new process is ready
-cpmm.sendAsyncMessage('sdk/remote/process/start', {
-  modulePath: PATH
-});
-
-// Load a child process module loader with the given loader options
-cpmm.addMessageListener('sdk/remote/process/load', ({ data: { modulePath, loaderID, options, reason } }) => {
-  if (modulePath != PATH)
-    return;
-
-  // During startup races can mean we get a second load message
-  if (addons.has(loaderID))
-    return;
-
-  options.waiveInterposition = true;
-
-  let loader = Loader.Loader(options);
-  let addon = {
-    loader,
-    require: Loader.Require(loader, { id: 'LoaderHelper' }),
-  }
-  addons.set(loaderID, addon);
-
-  cpmm.sendAsyncMessage('sdk/remote/process/attach', {
-    loaderID,
-    processID: Services.appinfo.processID,
-    isRemote: Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT
-  });
-
-  addon.child = addon.require('sdk/remote/child');
-
-  for (let contentFrame of frames.values())
-    addon.child.registerContentFrame(contentFrame);
-});
-
-// Unload a child process loader
-cpmm.addMessageListener('sdk/remote/process/unload', ({ data: { loaderID, reason } }) => {
-  if (!addons.has(loaderID))
-    return;
-
-  let addon = addons.get(loaderID);
-  Loader.unload(addon.loader, reason);
-
-  // We want to drop the reference to the loader but never allow creating a new
-  // loader with the same ID
-  addons.set(loaderID, {});
-})
-
-
-var frames = new Set();
-
-this.registerContentFrame = contentFrame => {
-  contentFrame.addEventListener("unload", () => {
-    unregisterContentFrame(contentFrame);
-  });
-
-  frames.add(contentFrame);
-
-  for (let addon of addons.values()) {
-    if ("child" in addon)
-      addon.child.registerContentFrame(contentFrame);
-  }
-};
-
-function unregisterContentFrame(contentFrame) {
-  frames.delete(contentFrame);
-
-  for (let addon of addons.values()) {
-    if ("child" in addon)
-      addon.child.unregisterContentFrame(contentFrame);
-  }
-}
deleted file mode 100644
--- a/addon-sdk/source/lib/framescript/manager.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-const mime = "application/javascript";
-const requireURI = module.uri.replace("framescript/manager.js",
-                                      "toolkit/require.js");
-
-const requireLoadURI = `data:${mime},this["Components"].utils.import("${requireURI}")`
-
-// Loads module with given `id` into given `messageManager` via shared module loader. If `init`
-// string is passed, will call module export with that name and pass frame script environment
-// of the `messageManager` into it. Since module will load only once per process (which is
-// once for chrome proces & second for content process) it is useful to have an init function
-// to setup event listeners on each content frame.
-const loadModule = (messageManager, id, allowDelayed, init) => {
-  const moduleLoadURI = `${requireLoadURI}.require("${id}")`
-  const uri = init ? `${moduleLoadURI}.${init}(this)` : moduleLoadURI;
-  messageManager.loadFrameScript(uri, allowDelayed);
-};
-exports.loadModule = loadModule;
deleted file mode 100644
--- a/addon-sdk/source/lib/framescript/util.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-
-const { Ci } = require("chrome");
-
-const windowToMessageManager = window =>
-  window.
-    QueryInterface(Ci.nsIInterfaceRequestor).
-    getInterface(Ci.nsIDocShell).
-    sameTypeRootTreeItem.
-    QueryInterface(Ci.nsIDocShell).
-    QueryInterface(Ci.nsIInterfaceRequestor).
-    getInterface(Ci.nsIContentFrameMessageManager);
-exports.windowToMessageManager = windowToMessageManager;
-
-const nodeToMessageManager = node =>
-  windowToMessageManager(node.ownerGlobal);
-exports.nodeToMessageManager = nodeToMessageManager;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/content/content-worker.js
+++ /dev/null
@@ -1,305 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-Object.freeze({
-  // TODO: Bug 727854 Use same implementation than common JS modules,
-  // i.e. EventEmitter module
-
-  /**
-   * Create an EventEmitter instance.
-   */
-  createEventEmitter: function createEventEmitter(emit) {
-    let listeners = Object.create(null);
-    let eventEmitter = Object.freeze({
-      emit: emit,
-      on: function on(name, callback) {
-        if (typeof callback !== "function")
-          return this;
-        if (!(name in listeners))
-          listeners[name] = [];
-        listeners[name].push(callback);
-        return this;
-      },
-      once: function once(name, callback) {
-        eventEmitter.on(name, function onceCallback() {
-          eventEmitter.removeListener(name, onceCallback);
-          callback.apply(callback, arguments);
-        });
-      },
-      removeListener: function removeListener(name, callback) {
-        if (!(name in listeners))
-          return;
-        let index = listeners[name].indexOf(callback);
-        if (index == -1)
-          return;
-        listeners[name].splice(index, 1);
-      }
-    });
-    function onEvent(name) {
-      if (!(name in listeners))
-        return [];
-      let args = Array.slice(arguments, 1);
-      let results = [];
-      for (let callback of listeners[name]) {
-        results.push(callback.apply(null, args));
-      }
-      return results;
-    }
-    return {
-      eventEmitter: eventEmitter,
-      emit: onEvent
-    };
-  },
-
-  /**
-   * Create an EventEmitter instance to communicate with chrome module
-   * by passing only strings between compartments.
-   * This function expects `emitToChrome` function, that allows to send
-   * events to the chrome module. It returns the EventEmitter as `pipe`
-   * attribute, and, `onChromeEvent` a function that allows chrome module
-   * to send event into the EventEmitter.
-   *
-   *                  pipe.emit --> emitToChrome
-   *              onChromeEvent --> callback registered through pipe.on
-   */
-  createPipe: function createPipe(emitToChrome) {
-    let ContentWorker = this;
-    function onEvent(type, ...args) {
-      // JSON.stringify is buggy with cross-sandbox values,
-      // it may return "{}" on functions. Use a replacer to match them correctly.
-      let replacer = (k, v) =>
-        typeof(v) === "function"
-          ? (type === "console" ? Function.toString.call(v) : void(0))
-          : v;
-
-      let str = JSON.stringify([type, ...args], replacer);
-      emitToChrome(str);
-    }
-
-    let { eventEmitter, emit } =
-      ContentWorker.createEventEmitter(onEvent);
-
-    return {
-      pipe: eventEmitter,
-      onChromeEvent: function onChromeEvent(array) {
-        // We either receive a stringified array, or a real array.
-        // We still allow to pass an array of objects, in WorkerSandbox.emitSync
-        // in order to allow sending DOM node reference between content script
-        // and modules (only used for context-menu API)
-        let args = typeof array == "string" ? JSON.parse(array) : array;
-        return emit.apply(null, args);
-      }
-    };
-  },
-
-  injectConsole: function injectConsole(exports, pipe) {
-    exports.console = Object.freeze({
-      log: pipe.emit.bind(null, "console", "log"),
-      info: pipe.emit.bind(null, "console", "info"),
-      warn: pipe.emit.bind(null, "console", "warn"),
-      error: pipe.emit.bind(null, "console", "error"),
-      debug: pipe.emit.bind(null, "console", "debug"),
-      exception: pipe.emit.bind(null, "console", "exception"),
-      trace: pipe.emit.bind(null, "console", "trace"),
-      time: pipe.emit.bind(null, "console", "time"),
-      timeEnd: pipe.emit.bind(null, "console", "timeEnd")
-    });
-  },
-
-  injectTimers: function injectTimers(exports, chromeAPI, pipe, console) {
-    // wrapped functions from `'timer'` module.
-    // Wrapper adds `try catch` blocks to the callbacks in order to
-    // emit `error` event if exception is thrown in
-    // the Worker global scope.
-    // @see http://www.w3.org/TR/workers/#workerutils
-
-    // List of all living timeouts/intervals
-    let _timers = Object.create(null);
-
-    // Keep a reference to original timeout functions
-    let {
-      setTimeout: chromeSetTimeout,
-      setInterval: chromeSetInterval,
-      clearTimeout: chromeClearTimeout,
-      clearInterval: chromeClearInterval
-    } = chromeAPI.timers;
-
-    function registerTimer(timer) {
-      let registerMethod = null;
-      if (timer.kind == "timeout")
-        registerMethod = chromeSetTimeout;
-      else if (timer.kind == "interval")
-        registerMethod = chromeSetInterval;
-      else
-        throw new Error("Unknown timer kind: " + timer.kind);
-
-      if (typeof timer.fun == 'string') {
-        let code = timer.fun;
-        timer.fun = () => chromeAPI.sandbox.evaluate(exports, code);
-      } else if (typeof timer.fun != 'function') {
-        throw new Error('Unsupported callback type' + typeof timer.fun);
-      }
-
-      let id = registerMethod(onFire, timer.delay);
-      function onFire() {
-        try {
-          if (timer.kind == "timeout")
-            delete _timers[id];
-          timer.fun.apply(null, timer.args);
-        } catch(e) {
-          console.exception(e);
-          let wrapper = {
-            instanceOfError: instanceOf(e, Error),
-            value: e,
-          };
-          if (wrapper.instanceOfError) {
-            wrapper.value = {
-              message: e.message,
-              fileName: e.fileName,
-              lineNumber: e.lineNumber,
-              stack: e.stack,
-              name: e.name,
-            };
-          }
-          pipe.emit('error', wrapper);
-        }
-      }
-      _timers[id] = timer;
-      return id;
-    }
-
-    // copied from sdk/lang/type.js since modules are not available here
-    function instanceOf(value, Type) {
-      var isConstructorNameSame;
-      var isConstructorSourceSame;
-
-      // If `instanceof` returned `true` we know result right away.
-      var isInstanceOf = value instanceof Type;
-
-      // If `instanceof` returned `false` we do ducktype check since `Type` may be
-      // from a different sandbox. If a constructor of the `value` or a constructor
-      // of the value's prototype has same name and source we assume that it's an
-      // instance of the Type.
-      if (!isInstanceOf && value) {
-        isConstructorNameSame = value.constructor.name === Type.name;
-        isConstructorSourceSame = String(value.constructor) == String(Type);
-        isInstanceOf = (isConstructorNameSame && isConstructorSourceSame) ||
-                        instanceOf(Object.getPrototypeOf(value), Type);
-      }
-      return isInstanceOf;
-    }
-
-    function unregisterTimer(id) {
-      if (!(id in _timers))
-        return;
-      let { kind } = _timers[id];
-      delete _timers[id];
-      if (kind == "timeout")
-        chromeClearTimeout(id);
-      else if (kind == "interval")
-        chromeClearInterval(id);
-      else
-        throw new Error("Unknown timer kind: " + kind);
-    }
-
-    function disableAllTimers() {
-      Object.keys(_timers).forEach(unregisterTimer);
-    }
-
-    exports.setTimeout = function ContentScriptSetTimeout(callback, delay) {
-      return registerTimer({
-        kind: "timeout",
-        fun: callback,
-        delay: delay,
-        args: Array.slice(arguments, 2)
-      });
-    };
-    exports.clearTimeout = function ContentScriptClearTimeout(id) {
-      unregisterTimer(id);
-    };
-
-    exports.setInterval = function ContentScriptSetInterval(callback, delay) {
-      return registerTimer({
-        kind: "interval",
-        fun: callback,
-        delay: delay,
-        args: Array.slice(arguments, 2)
-      });
-    };
-    exports.clearInterval = function ContentScriptClearInterval(id) {
-      unregisterTimer(id);
-    };
-
-    // On page-hide, save a list of all existing timers before disabling them,
-    // in order to be able to restore them on page-show.
-    // These events are fired when the page goes in/out of bfcache.
-    // https://developer.mozilla.org/En/Working_with_BFCache
-    let frozenTimers = [];
-    pipe.on("pageshow", function onPageShow() {
-      frozenTimers.forEach(registerTimer);
-    });
-    pipe.on("pagehide", function onPageHide() {
-      frozenTimers = [];
-      for (let id in _timers)
-        frozenTimers.push(_timers[id]);
-      disableAllTimers();
-      // Some other pagehide listeners may register some timers that won't be
-      // frozen as this particular pagehide listener is called first.
-      // So freeze these timers on next cycle.
-      chromeSetTimeout(function () {
-        for (let id in _timers)
-          frozenTimers.push(_timers[id]);
-        disableAllTimers();
-      }, 0);
-    });
-
-    // Unregister all timers when the page is destroyed
-    // (i.e. when it is removed from bfcache)
-    pipe.on("detach", function clearTimeouts() {
-      disableAllTimers();
-      _timers = {};
-      frozenTimers = [];
-    });
-  },
-
-  injectMessageAPI: function injectMessageAPI(exports, pipe, console) {
-
-    let ContentWorker = this;
-    let { eventEmitter: port, emit : portEmit } =
-      ContentWorker.createEventEmitter(pipe.emit.bind(null, "event"));
-    pipe.on("event", portEmit);
-
-    let self = {
-      port: port,
-      postMessage: pipe.emit.bind(null, "message"),
-      on: pipe.on.bind(null),
-      once: pipe.once.bind(null),
-      removeListener: pipe.removeListener.bind(null),
-    };
-    Object.defineProperty(exports, "self", {
-      value: self
-    });
-  },
-
-  injectOptions: function (exports, options) {
-    Object.defineProperty( exports.self, "options", { value: JSON.parse( options ) });
-  },
-
-  inject: function (exports, chromeAPI, emitToChrome, options) {
-    let ContentWorker = this;
-    let { pipe, onChromeEvent } =
-      ContentWorker.createPipe(emitToChrome);
-
-    ContentWorker.injectConsole(exports, pipe);
-    ContentWorker.injectTimers(exports, chromeAPI, pipe, exports.console);
-    ContentWorker.injectMessageAPI(exports, pipe, exports.console);
-    if ( options !== undefined ) {
-      ContentWorker.injectOptions(exports, options);
-    }
-
-    Object.freeze( exports.self );
-
-    return onChromeEvent;
-  }
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/content/content.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-module.metadata = {
-  "stability": "deprecated"
-};
-
-const { deprecateUsage } = require('../util/deprecate');
-
-Object.defineProperty(exports, "Worker", {
-  get: function() {
-    deprecateUsage('`sdk/content/content` is deprecated. Please use `sdk/content/worker` directly.');
-    return require('./worker').Worker;
-  }
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/content/sandbox.js
+++ /dev/null
@@ -1,426 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-module.metadata = {
-  'stability': 'unstable'
-};
-
-const { Class } = require('../core/heritage');
-const { EventTarget } = require('../event/target');
-lazyRequire(this, '../event/core', "on", "off", "emit");
-lazyRequire(this, './sandbox/events', "events");
-lazyRequire(this, './utils', "requiresAddonGlobal");
-lazyRequire(this, '../lang/functional', {"delay": "async"});
-const { Ci, Cu, Cc } = require('chrome');
-lazyRequireModule(this, "../timers", "timer");
-lazyRequire(this, '../url', "URL");
-lazyRequire(this, '../loader/sandbox', "sandbox", "evaluate", "load");
-lazyRequire(this, '../util/object', "merge");
-lazyRequire(this, '../tabs/utils', "getTabForContentWindowNoShim");
-lazyRequire(this, '../window/utils', "getInnerId");
-lazyRequire(this, '../console/plain-text', "PlainTextConsole");
-
-lazyRequire(this, '../self', "data");
-lazyRequire(this, '../remote/core', "isChildLoader");
-
-// WeakMap of sandboxes so we can access private values
-const sandboxes = new WeakMap();
-
-/* Trick the linker in order to ensure shipping these files in the XPI.
-  require('./content-worker.js');
-  Then, retrieve URL of these files in the XPI:
-*/
-var prefix = module.uri.split('sandbox.js')[0];
-const CONTENT_WORKER_URL = prefix + 'content-worker.js';
-const metadata = require('@loader/options').metadata;
-
-// Fetch additional list of domains to authorize access to for each content
-// script. It is stored in manifest `metadata` field which contains
-// package.json data. This list is originaly defined by authors in
-// `permissions` attribute of their package.json addon file.
-const permissions = (metadata && metadata['permissions']) || {};
-const EXPANDED_PRINCIPALS = permissions['cross-domain-content'] || [];
-
-const waiveSecurityMembrane = !!permissions['unsafe-content-script'];
-
-const nsIScriptSecurityManager = Ci.nsIScriptSecurityManager;
-const secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].
-  getService(Ci.nsIScriptSecurityManager);
-
-const JS_VERSION = '1.8';
-
-// Tests whether this window is loaded in a tab
-function isWindowInTab(window) {
-  if (isChildLoader) {
-    let { frames } = require('../remote/child');
-    let frame = frames.getFrameForWindow(window.top);
-    return frame && frame.isTab;
-  }
-  else {
-    // The deprecated sync worker API still does everything in the main process
-    return getTabForContentWindowNoShim(window);
-  }
-}
-
-const WorkerSandbox = Class({
-  implements: [ EventTarget ],
-
-  /**
-   * Emit a message to the worker content sandbox
-   */
-  emit: function emit(type, ...args) {
-    // JSON.stringify is buggy with cross-sandbox values,
-    // it may return "{}" on functions. Use a replacer to match them correctly.
-    let replacer = (k, v) =>
-      typeof(v) === "function"
-        ? (type === "console" ? Function.toString.call(v) : void(0))
-        : v;
-
-    // Ensure having an asynchronous behavior
-    async(() =>
-      emitToContent(this, JSON.stringify([type, ...args], replacer))
-    );
-  },
-
-  /**
-   * Synchronous version of `emit`.
-   * /!\ Should only be used when it is strictly mandatory /!\
-   *     Doesn't ensure passing only JSON values.
-   *     Mainly used by context-menu in order to avoid breaking it.
-   */
-  emitSync: function emitSync(...args) {
-    // because the arguments could be also non JSONable values,
-    // we need to ensure the array instance is created from
-    // the content's sandbox
-    return emitToContent(this, new modelFor(this).sandbox.Array(...args));
-  },
-
-  /**
-   * Configures sandbox and loads content scripts into it.
-   * @param {Worker} worker
-   *    content worker
-   */
-  initialize: function WorkerSandbox(worker, window) {
-    let model = {};
-    sandboxes.set(this, model);
-    model.worker = worker;
-    // We receive a wrapped window, that may be an xraywrapper if it's content
-    let proto = window;
-
-    // TODO necessary?
-    // Ensure that `emit` has always the right `this`
-    this.emit = this.emit.bind(this);
-    this.emitSync = this.emitSync.bind(this);
-
-    // Use expanded principal for content-script if the content is a
-    // regular web content for better isolation.
-    // (This behavior can be turned off for now with the unsafe-content-script
-    // flag to give addon developers time for making the necessary changes)
-    // But prevent it when the Worker isn't used for a content script but for
-    // injecting `addon` object into a Panel scope, for example.
-    // That's because:
-    // 1/ It is useless to use multiple domains as the worker is only used
-    // to communicate with the addon,
-    // 2/ By using it it would prevent the document to have access to any JS
-    // value of the worker. As JS values coming from multiple domain principals
-    // can't be accessed by 'mono-principals' (principal with only one domain).
-    // Even if this principal is for a domain that is specified in the multiple
-    // domain principal.
-    let principals = window;
-    let wantGlobalProperties = [];
-    let isSystemPrincipal = secMan.isSystemPrincipal(
-      window.document.nodePrincipal);
-    if (!isSystemPrincipal && !requiresAddonGlobal(worker)) {
-      if (EXPANDED_PRINCIPALS.length > 0) {
-        // We have to replace XHR constructor of the content document
-        // with a custom cross origin one, automagically added by platform code:
-        delete proto.XMLHttpRequest;
-        wantGlobalProperties.push('XMLHttpRequest');
-      }
-      if (!waiveSecurityMembrane)
-        principals = EXPANDED_PRINCIPALS.concat(window);
-    }
-
-    // Create the sandbox and bind it to window in order for content scripts to
-    // have access to all standard globals (window, document, ...)
-    let content = sandbox(principals, {
-      sandboxPrototype: proto,
-      wantXrays: !requiresAddonGlobal(worker),
-      wantGlobalProperties: wantGlobalProperties,
-      wantExportHelpers: true,
-      sameZoneAs: window,
-      metadata: {
-        SDKContentScript: true,
-        'inner-window-id': getInnerId(window)
-      }
-    });
-    model.sandbox = content;
-
-    // We have to ensure that window.top and window.parent are the exact same
-    // object than window object, i.e. the sandbox global object. But not
-    // always, in case of iframes, top and parent are another window object.
-    let top = window.top === window ? content : content.top;
-    let parent = window.parent === window ? content : content.parent;
-    merge(content, {
-      // We need 'this === window === top' to be true in toplevel scope:
-      get window() {
-        return content;
-      },
-      get top() {
-        return top;
-      },
-      get parent() {
-        return parent;
-      }
-    });
-
-    // Use the Greasemonkey naming convention to provide access to the
-    // unwrapped window object so the content script can access document
-    // JavaScript values.
-    // NOTE: this functionality is experimental and may change or go away
-    // at any time!
-    //
-    // Note that because waivers aren't propagated between origins, we
-    // need the unsafeWindow getter to live in the sandbox.
-    var unsafeWindowGetter =
-      new content.Function('return window.wrappedJSObject || window;');
-    Object.defineProperty(content, 'unsafeWindow', {get: unsafeWindowGetter});
-
-    // Load trusted code that will inject content script API.
-    let ContentWorker = load(content, CONTENT_WORKER_URL);
-
-    // prepare a clean `self.options`
-    let options = 'contentScriptOptions' in worker ?
-      JSON.stringify(worker.contentScriptOptions) :
-      undefined;
-
-    // Then call `inject` method and communicate with this script
-    // by trading two methods that allow to send events to the other side:
-    //   - `onEvent` called by content script
-    //   - `result.emitToContent` called by addon script
-    let onEvent = Cu.exportFunction(onContentEvent.bind(null, this), ContentWorker);
-    let chromeAPI = createChromeAPI(ContentWorker);
-    let result = Cu.waiveXrays(ContentWorker).inject(content, chromeAPI, onEvent, options);
-
-    // Merge `emitToContent` into our private model of the
-    // WorkerSandbox so we can communicate with content script
-    model.emitToContent = result;
-
-    let console = new PlainTextConsole(null, getInnerId(window));
-
-    // Handle messages send by this script:
-    setListeners(this, console);
-
-    // Inject `addon` global into target document if document is trusted,
-    // `addon` in document is equivalent to `self` in content script.
-    if (requiresAddonGlobal(worker)) {
-      Object.defineProperty(getUnsafeWindow(window), 'addon', {
-          value: content.self,
-          configurable: true
-        }
-      );
-    }
-
-    // Inject our `console` into target document if worker doesn't have a tab
-    // (e.g Panel, PageWorker).
-    // `worker.tab` can't be used because bug 804935.
-    if (!isWindowInTab(window)) {
-      let win = getUnsafeWindow(window);
-
-      // export our chrome console to content window, as described here:
-      // https://developer.mozilla.org/en-US/docs/Components.utils.createObjectIn
-      let con = Cu.createObjectIn(win);
-
-      let genPropDesc = function genPropDesc(fun) {
-        return { enumerable: true, configurable: true, writable: true,
-          value: console[fun] };
-      }
-
-      const properties = {
-        log: genPropDesc('log'),
-        info: genPropDesc('info'),
-        warn: genPropDesc('warn'),
-        error: genPropDesc('error'),
-        debug: genPropDesc('debug'),
-        trace: genPropDesc('trace'),
-        dir: genPropDesc('dir'),
-        group: genPropDesc('group'),
-        groupCollapsed: genPropDesc('groupCollapsed'),
-        groupEnd: genPropDesc('groupEnd'),
-        time: genPropDesc('time'),
-        timeEnd: genPropDesc('timeEnd'),
-        profile: genPropDesc('profile'),
-        profileEnd: genPropDesc('profileEnd'),
-        exception: genPropDesc('exception'),
-        assert: genPropDesc('assert'),
-        count: genPropDesc('count'),
-        table: genPropDesc('table'),
-        clear: genPropDesc('clear'),
-        dirxml: genPropDesc('dirxml'),
-        timeStamp: genPropDesc('timeStamp'),
-      };
-
-      Object.defineProperties(con, properties);
-      Cu.makeObjectPropsNormal(con);
-
-      win.console = con;
-    };
-
-    emit(events, "content-script-before-inserted", {
-      window: window,
-      worker: worker
-    });
-
-    // The order of `contentScriptFile` and `contentScript` evaluation is
-    // intentional, so programs can load libraries like jQuery from script URLs
-    // and use them in scripts.
-    let contentScriptFile = ('contentScriptFile' in worker)
-          ? worker.contentScriptFile
-          : null,
-        contentScript = ('contentScript' in worker)
-          ? worker.contentScript
-          : null;
-
-    if (contentScriptFile)
-      importScripts.apply(null, [this].concat(contentScriptFile));
-
-    if (contentScript) {
-      evaluateIn(
-        this,
-        Array.isArray(contentScript) ? contentScript.join(';\n') : contentScript
-      );
-    }
-  },
-  destroy: function destroy(reason) {
-    if (typeof reason != 'string')
-      reason = '';
-    this.emitSync('event', 'detach', reason);
-    let model = modelFor(this);
-    model.sandbox = null
-    model.worker = null;
-  },
-
-});
-
-exports.WorkerSandbox = WorkerSandbox;
-
-/**
- * Imports scripts to the sandbox by reading files under urls and
- * evaluating its source. If exception occurs during evaluation
- * `'error'` event is emitted on the worker.
- * This is actually an analog to the `importScript` method in web
- * workers but in our case it's not exposed even though content
- * scripts may be able to do it synchronously since IO operation
- * takes place in the UI process.
- */
-function importScripts (workerSandbox, ...urls) {
-  let { worker, sandbox } = modelFor(workerSandbox);
-  for (let i in urls) {
-    let contentScriptFile = data.url(urls[i]);
-
-    try {
-      let uri = URL(contentScriptFile);
-      if (uri.scheme === 'resource')
-        load(sandbox, String(uri));
-      else
-        throw Error('Unsupported `contentScriptFile` url: ' + String(uri));
-    }
-    catch(e) {
-      emit(worker, 'error', e);
-    }
-  }
-}
-
-function setListeners (workerSandbox, console) {
-  let { worker } = modelFor(workerSandbox);
-  // console.xxx calls
-  workerSandbox.on('console', function consoleListener (kind, ...args) {
-    console[kind].apply(console, args);
-  });
-
-  // self.postMessage calls
-  workerSandbox.on('message', function postMessage(data) {
-    // destroyed?
-    if (worker)
-      emit(worker, 'message', data);
-  });
-
-  // self.port.emit calls
-  workerSandbox.on('event', function portEmit (...eventArgs) {
-    // If not destroyed, emit event information to worker
-    // `eventArgs` has the event name as first element,
-    // and remaining elements are additional arguments to pass
-    if (worker)
-      emit.apply(null, [worker.port].concat(eventArgs));
-  });
-
-  // unwrap, recreate and propagate async Errors thrown from content-script
-  workerSandbox.on('error', function onError({instanceOfError, value}) {
-    if (worker) {
-      let error = value;
-      if (instanceOfError) {
-        error = new Error(value.message, value.fileName, value.lineNumber);
-        error.stack = value.stack;
-        error.name = value.name;
-      }
-      emit(worker, 'error', error);
-    }
-  });
-}
-
-/**
- * Evaluates code in the sandbox.
- * @param {String} code
- *    JavaScript source to evaluate.
- * @param {String} [filename='javascript:' + code]
- *    Name of the file
- */
-function evaluateIn (workerSandbox, code, filename) {
-  let { worker, sandbox } = modelFor(workerSandbox);
-  try {
-    evaluate(sandbox, code, filename || 'javascript:' + code);
-  }
-  catch(e) {
-    emit(worker, 'error', e);
-  }
-}
-
-/**
- * Method called by the worker sandbox when it needs to send a message
- */
-function onContentEvent (workerSandbox, args) {
-  // As `emit`, we ensure having an asynchronous behavior
-  async(function () {
-    // We emit event to chrome/addon listeners
-    emit.apply(null, [workerSandbox].concat(JSON.parse(args)));
-  });
-}
-
-
-function modelFor (workerSandbox) {
-  return sandboxes.get(workerSandbox);
-}
-
-function getUnsafeWindow (win) {
-  return win.wrappedJSObject || win;
-}
-
-function emitToContent (workerSandbox, args) {
-  return modelFor(workerSandbox).emitToContent(args);
-}
-
-function createChromeAPI (scope) {
-  return Cu.cloneInto({
-    timers: {
-      setTimeout: timer.setTimeout.bind(timer),
-      setInterval: timer.setInterval.bind(timer),
-      clearTimeout: timer.clearTimeout.bind(timer),
-      clearInterval: timer.clearInterval.bind(timer),
-    },
-    sandbox: {
-      evaluate: evaluate,
-    },
-  }, scope, {cloneFunctions: true});
-}
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/content/sandbox/events.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-module.metadata = {
-  "stability": "experimental"
-};
-
-const events = {};
-exports.events = events;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/content/tab-events.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-const { Ci } = require('chrome');
-const system = require('sdk/system/events');
-const { frames } = require('sdk/remote/child');
-const { WorkerChild } = require('sdk/content/worker-child');
-
-// map observer topics to tab event names
-const EVENTS = {
-  'content-document-global-created': 'create',
-  'chrome-document-global-created': 'create',
-  'content-document-interactive': 'ready',
-  'chrome-document-interactive': 'ready',
-  'content-document-loaded': 'load',
-  'chrome-document-loaded': 'load',
-// 'content-page-shown': 'pageshow', // bug 1024105
-}
-
-function topicListener({ subject, type }) {
-  // NOTE detect the window from the subject:
-  // - on *-global-created the subject is the window
-  // - in the other cases it is the document object
-  let window = subject instanceof Ci.nsIDOMWindow ? subject : subject.defaultView;
-  if (!window){
-    return;
-  }
-  let frame = frames.getFrameForWindow(window);
-  if (frame) {
-    let readyState = frame.content.document.readyState;
-    frame.port.emit('sdk/tab/event', EVENTS[type], { readyState });
-  }
-}
-
-for (let topic in EVENTS)
-  system.on(topic, topicListener, true);
-
-// bug 1024105 - content-page-shown notification doesn't pass persisted param
-function eventListener({target, type, persisted}) {
-  let frame = this;
-  if (target === frame.content.document) {
-    frame.port.emit('sdk/tab/event', type, persisted);
-  }
-}
-frames.addEventListener('pageshow', eventListener, true);
-
-frames.port.on('sdk/tab/attach', (frame, options) => {
-  options.window = frame.content;
-  new WorkerChild(options);
-});
-
-// Forward the existent frames's readyState.
-for (let frame of frames) {
-  let readyState = frame.content.document.readyState;
-  frame.port.emit('sdk/tab/event', 'init', { readyState });
-}
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/content/worker-child.js
+++ /dev/null
@@ -1,158 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-lazyRequire(this, '../util/object', 'merge');
-const { Class } = require('../core/heritage');
-lazyRequire(this, '../event/core', 'emit');
-const { EventTarget } = require('../event/target');
-lazyRequire(this, '../window/utils', 'getInnerId');
-lazyRequire(this, '../lang/type', 'instanceOf', 'isObject');
-lazyRequireModule(this, '../system/events', 'system');
-const { when } = require('../system/unload');
-lazyRequire(this, './sandbox', 'WorkerSandbox');
-const { Ci } = require('chrome');
-const { process, frames } = require('../remote/child');
-
-const EVENTS = {
-  'chrome-page-shown': 'pageshow',
-  'content-page-shown': 'pageshow',
-  'chrome-page-hidden': 'pagehide',
-  'content-page-hidden': 'pagehide',
-  'inner-window-destroyed': 'detach',
-}
-
-// The parent Worker must have been created (or an async message sent to spawn
-// its creation) before creating the WorkerChild or messages from the content
-// script to the parent will get lost.
-const WorkerChild = Class({
-  implements: [EventTarget],
-
-  initialize(options) {
-    merge(this, options);
-    keepAlive.set(this.id, this);
-
-    this.windowId = getInnerId(this.window);
-    if (this.contentScriptOptions)
-      this.contentScriptOptions = JSON.parse(this.contentScriptOptions);
-
-    this.port = EventTarget();
-    this.port.on('*', this.send.bind(this, 'event'));
-    this.on('*', this.send.bind(this));
-
-    this.observe = this.observe.bind(this);
-
-    for (let topic in EVENTS)
-      system.on(topic, this.observe);
-
-    this.receive = this.receive.bind(this);
-    process.port.on('sdk/worker/message', this.receive);
-
-    this.sandbox = WorkerSandbox(this, this.window);
-
-    // If the document has an unexpected readyState, its worker-child instance is initialized
-    // as frozen until one of the known readyState is reached.
-    let initialDocumentReadyState = this.window.document.readyState;
-    this.frozen = [
-      "loading", "interactive", "complete"
-    ].includes(initialDocumentReadyState) ? false : true;
-
-    if (this.frozen) {
-      console.warn("SDK worker-child started as frozen on unexpected initial document.readyState", {
-        initialDocumentReadyState, windowLocation: this.window.location.href,
-      });
-    }
-
-    this.frozenMessages = [];
-    this.on('pageshow', () => {
-      this.frozen = false;
-      this.frozenMessages.forEach(args => this.sandbox.emit(...args));
-      this.frozenMessages = [];
-    });
-    this.on('pagehide', () => {
-      this.frozen = true;
-    });
-  },
-
-  // messages
-  receive(process, id, args) {
-    if (id !== this.id)
-      return;
-    args = JSON.parse(args);
-
-    if (this.frozen)
-      this.frozenMessages.push(args);
-    else
-      this.sandbox.emit(...args);
-
-    if (args[0] === 'detach')
-      this.destroy(args[1]);
-  },
-
-  send(...args) {
-    process.port.emit('sdk/worker/event', this.id, JSON.stringify(args, exceptions));
-  },
-
-  // notifications
-  observe({ type, subject }) {
-    if (!this.sandbox)
-      return;
-
-    if (subject.defaultView && getInnerId(subject.defaultView) === this.windowId) {
-      this.sandbox.emitSync(EVENTS[type]);
-      emit(this, EVENTS[type]);
-    }
-
-    if (type === 'inner-window-destroyed' &&
-        subject.QueryInterface(Ci.nsISupportsPRUint64).data === this.windowId) {
-      this.destroy();
-    }
-  },
-
-  get frame() {
-    return frames.getFrameForWindow(this.window.top);
-  },
-
-  // detach/destroy: unload and release the sandbox
-  destroy(reason) {
-    if (!this.sandbox)
-      return;
-
-    for (let topic in EVENTS)
-      system.off(topic, this.observe);
-    process.port.off('sdk/worker/message', this.receive);
-
-    this.sandbox.destroy(reason);
-    this.sandbox = null;
-    keepAlive.delete(this.id);
-
-    this.send('detach');
-  }
-})
-exports.WorkerChild = WorkerChild;
-
-// Error instances JSON poorly
-function exceptions(key, value) {
-  if (!isObject(value) || !instanceOf(value, Error))
-    return value;
-  let _errorType = value.constructor.name;
-  let { message, fileName, lineNumber, stack, name } = value;
-  return { _errorType, message, fileName, lineNumber, stack, name };
-}
-
-// workers for windows in this tab
-var keepAlive = new Map();
-
-process.port.on('sdk/worker/create', (process, options, cpows) => {
-  options.window = cpows.window;
-  let worker = new WorkerChild(options);
-
-  let frame = frames.getFrameForWindow(options.window.top);
-  frame.port.emit('sdk/worker/connect', options.id, options.window.location.href);
-});
-
-when(reason => {
-  for (let worker of keepAlive.values())
-    worker.destroy(reason);
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/content/worker.js
+++ /dev/null
@@ -1,180 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-lazyRequire(this, '../event/core', "emit");
-const { omit, merge } = require('../util/object');
-const { Class } = require('../core/heritage');
-const { method } = require('../lang/functional');
-lazyRequire(this, '../window/utils', "getInnerId");
-const { EventTarget } = require('../event/target');
-lazyRequire(this, '../private-browsing/utils', "isPrivate");
-lazyRequire(this, '../tabs/utils', "getTabForBrowser", "getTabForContentWindowNoShim", "getBrowserForTab");
-lazyRequire(this, './utils', "attach", "connect", "detach", "destroy", "makeChildOptions");
-const { ensure } = require('../system/unload');
-lazyRequire(this, '../system/events', {"on": "observe"});
-const { Ci, Cu } = require('chrome');
-lazyRequire(this, 'sdk/model/core', {"modelFor": "tabFor"});
-const { remoteRequire, processes, frames } = require('../remote/parent');
-remoteRequire('sdk/content/worker-child');
-
-const workers = new WeakMap();
-var modelFor = (worker) => workers.get(worker);
-
-const ERR_DESTROYED = "Couldn't find the worker to receive this message. " +
-  "The script may not be initialized yet, or may already have been unloaded.";
-
-// a handle for communication between content script and addon code
-const Worker = Class({
-  implements: [EventTarget],
-
-  initialize(options = {}) {
-    ensure(this, 'detach');
-
-    let model = {
-      attached: false,
-      destroyed: false,
-      earlyEvents: [],        // fired before worker was attached
-      frozen: true,           // document is not yet active
-      options,
-    };
-    workers.set(this, model);
-
-    this.on('detach', this.detach);
-    EventTarget.prototype.initialize.call(this, options);
-
-    this.receive = this.receive.bind(this);
-
-    this.port = EventTarget();
-    this.port.emit = this.send.bind(this, 'event');
-    this.postMessage = this.send.bind(this, 'message');
-
-    if ('window' in options) {
-      let window = options.window;
-      delete options.window;
-      attach(this, window);
-    }
-  },
-
-  // messages
-  receive(process, id, args) {
-    let model = modelFor(this);
-    if (id !== model.id || !model.attached)
-      return;
-    args = JSON.parse(args);
-    if (model.destroyed && args[0] != 'detach')
-      return;
-
-    if (args[0] === 'event')
-      emit(this.port, ...args.slice(1))
-    else
-      emit(this, ...args);
-  },
-
-  send(...args) {
-    let model = modelFor(this);
-    if (model.destroyed && args[0] !== 'detach')
-      throw new Error(ERR_DESTROYED);
-
-    if (!model.attached) {
-      model.earlyEvents.push(args);
-      return;
-    }
-
-    processes.port.emit('sdk/worker/message', model.id, JSON.stringify(args));
-  },
-
-  // properties
-  get url() {
-    let { url } = modelFor(this);
-    return url;
-  },
-
-  get contentURL() {
-    return this.url;
-  },
-
-  get tab() {
-    require('sdk/tabs');
-    let { frame } = modelFor(this);
-    if (!frame)
-      return null;
-    let rawTab = getTabForBrowser(frame.frameElement);
-    return rawTab && tabFor(rawTab);
-  },
-
-  toString: () => '[object Worker]',
-
-  detach: method(detach),
-  destroy: method(destroy),
-})
-exports.Worker = Worker;
-
-attach.define(Worker, function(worker, window) {
-  let model = modelFor(worker);
-  if (model.attached)
-    detach(worker);
-
-  let childOptions = makeChildOptions(model.options);
-  processes.port.emitCPOW('sdk/worker/create', [childOptions], { window });
-
-  let listener = (frame, id, url) => {
-    if (id != childOptions.id)
-      return;
-    frames.port.off('sdk/worker/connect', listener);
-    connect(worker, frame, { id, url });
-  };
-  frames.port.on('sdk/worker/connect', listener);
-});
-
-connect.define(Worker, function(worker, frame, { id, url }) {
-  let model = modelFor(worker);
-  if (model.attached)
-    detach(worker);
-
-  model.id = id;
-  model.frame = frame;
-  model.url = url;
-
-  // Messages from content -> chrome come through the process message manager
-  // since that lives longer than the frame message manager
-  processes.port.on('sdk/worker/event', worker.receive);
-
-  model.attached = true;
-  model.destroyed = false;
-  model.frozen = false;
-
-  model.earlyEvents.forEach(args => worker.send(...args));
-  model.earlyEvents = [];
-  emit(worker, 'attach');
-});
-
-// unload and release the child worker, release window reference
-detach.define(Worker, function(worker) {
-  let model = modelFor(worker);
-  if (!model.attached)
-    return;
-
-  processes.port.off('sdk/worker/event', worker.receive);
-  model.attached = false;
-  model.destroyed = true;
-  emit(worker, 'detach');
-});
-
-isPrivate.define(Worker, ({ tab }) => isPrivate(tab));
-
-// Something in the parent side has destroyed the worker, tell the child to
-// detach, the child will respond when it has detached
-destroy.define(Worker, function(worker, reason) {
-  let model = modelFor(worker);
-  model.destroyed = true;
-  if (!model.attached)
-    return;
-
-  worker.send('detach', reason);
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/deprecated/sync-worker.js
+++ /dev/null
@@ -1,288 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/**
- *
- * `deprecated/sync-worker` was previously `content/worker`, that was
- * incompatible with e10s. we are in the process of switching to the new
- * asynchronous `Worker`, which behaves slightly differently in some edge
- * cases, so we are keeping this one around for a short period.
- * try to switch to the new one as soon as possible..
- *
- */
-
-"use strict";
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-const { Class } = require('../core/heritage');
-const { EventTarget } = require('../event/target');
-const { on, off, emit, setListeners } = require('../event/core');
-const {
-  attach, detach, destroy
-} = require('../content/utils');
-const { method } = require('../lang/functional');
-const { Ci, Cu, Cc } = require('chrome');
-const unload = require('../system/unload');
-const events = require('../system/events');
-const { getInnerId } = require("../window/utils");
-const { WorkerSandbox } = require('../content/sandbox');
-const { isPrivate } = require('../private-browsing/utils');
-
-// A weak map of workers to hold private attributes that
-// should not be exposed
-const workers = new WeakMap();
-
-var modelFor = (worker) => workers.get(worker);
-
-const ERR_DESTROYED =
-  "Couldn't find the worker to receive this message. " +
-  "The script may not be initialized yet, or may already have been unloaded.";
-
-const ERR_FROZEN = "The page is currently hidden and can no longer be used " +
-                   "until it is visible again.";
-
-/**
- * Message-passing facility for communication between code running
- * in the content and add-on process.
- * @see https://developer.mozilla.org/en-US/Add-ons/SDK/Low-Level_APIs/content_worker
- */
-const Worker = Class({
-  implements: [EventTarget],
-  initialize: function WorkerConstructor (options) {
-    // Save model in weak map to not expose properties
-    let model = createModel();
-    workers.set(this, model);
-
-    options = options || {};
-
-    if ('contentScriptFile' in options)
-      this.contentScriptFile = options.contentScriptFile;
-    if ('contentScriptOptions' in options)
-      this.contentScriptOptions = options.contentScriptOptions;
-    if ('contentScript' in options)
-      this.contentScript = options.contentScript;
-    if ('injectInDocument' in options)
-      this.injectInDocument = !!options.injectInDocument;
-
-    setListeners(this, options);
-
-    unload.ensure(this, "destroy");
-
-    // Ensure that worker.port is initialized for contentWorker to be able
-    // to send events during worker initialization.
-    this.port = createPort(this);
-
-    model.documentUnload = documentUnload.bind(this);
-    model.pageShow = pageShow.bind(this);
-    model.pageHide = pageHide.bind(this);
-
-    if ('window' in options)
-      attach(this, options.window);
-  },
-
-  /**
-   * Sends a message to the worker's global scope. Method takes single
-   * argument, which represents data to be sent to the worker. The data may
-   * be any primitive type value or `JSON`. Call of this method asynchronously
-   * emits `message` event with data value in the global scope of this
-   * worker.
-   *
-   * `message` event listeners can be set either by calling
-   * `self.on` with a first argument string `"message"` or by
-   * implementing `onMessage` function in the global scope of this worker.
-   * @param {Number|String|JSON} data
-   */
-  postMessage: function (...data) {
-    let model = modelFor(this);
-    let args = ['message'].concat(data);
-    if (!model.inited) {
-      model.earlyEvents.push(args);
-      return;
-    }
-    processMessage.apply(null, [this].concat(args));
-  },
-
-  get url () {
-    let model = modelFor(this);
-    // model.window will be null after detach
-    return model.window ? model.window.document.location.href : null;
-  },
-
-  get contentURL () {
-    let model = modelFor(this);
-    return model.window ? model.window.document.URL : null;
-  },
-
-  // Implemented to provide some of the previous features of exposing sandbox
-  // so that Worker can be extended
-  getSandbox: function () {
-    return modelFor(this).contentWorker;
-  },
-
-  toString: function () { return '[object Worker]'; },
-  attach: method(attach),
-  detach: method(detach),
-  destroy: method(destroy)
-});
-exports.Worker = Worker;
-
-attach.define(Worker, function (worker, window) {
-  let model = modelFor(worker);
-  model.window = window;
-  // Track document unload to destroy this worker.
-  // We can't watch for unload event on page's window object as it
-  // prevents bfcache from working:
-  // https://developer.mozilla.org/En/Working_with_BFCache
-  model.windowID = getInnerId(model.window);
-  events.on("inner-window-destroyed", model.documentUnload);
-
-  // will set model.contentWorker pointing to the private API:
-  model.contentWorker = WorkerSandbox(worker, model.window);
-
-  // Listen to pagehide event in order to freeze the content script
-  // while the document is frozen in bfcache:
-  model.window.addEventListener("pageshow", model.pageShow, true);
-  model.window.addEventListener("pagehide", model.pageHide, true);
-
-  // Mainly enable worker.port.emit to send event to the content worker
-  model.inited = true;
-  model.frozen = false;
-
-  // Fire off `attach` event
-  emit(worker, 'attach', window);
-
-  // Process all events and messages that were fired before the
-  // worker was initialized.
-  model.earlyEvents.forEach(args => processMessage.apply(null, [worker].concat(args)));
-});
-
-/**
- * Remove all internal references to the attached document
- * Tells _port to unload itself and removes all the references from itself.
- */
-detach.define(Worker, function (worker, reason) {
-  let model = modelFor(worker);
-
-  // maybe unloaded before content side is created
-  if (model.contentWorker) {
-    model.contentWorker.destroy(reason);
-  }
-
-  model.contentWorker = null;
-  if (model.window) {
-    model.window.removeEventListener("pageshow", model.pageShow, true);
-    model.window.removeEventListener("pagehide", model.pageHide, true);
-  }
-  model.window = null;
-  // This method may be called multiple times,
-  // avoid dispatching `detach` event more than once
-  if (model.windowID) {
-    model.windowID = null;
-    events.off("inner-window-destroyed", model.documentUnload);
-    model.earlyEvents.length = 0;
-    emit(worker, 'detach');
-  }
-  model.inited = false;
-});
-
-isPrivate.define(Worker, ({ tab }) => isPrivate(tab));
-
-/**
- * Tells content worker to unload itself and
- * removes all the references from itself.
- */
-destroy.define(Worker, function (worker, reason) {
-  detach(worker, reason);
-  modelFor(worker).inited = true;
-  // Specifying no type or listener removes all listeners
-  // from target
-  off(worker);
-  off(worker.port);
-});
-
-/**
- * Events fired by workers
- */
-function documentUnload ({ subject, data }) {
-  let model = modelFor(this);
-  let innerWinID = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
-  if (innerWinID != model.windowID) return false;
-  detach(this);
-  return true;
-}
-
-function pageShow () {
-  let model = modelFor(this);
-  model.contentWorker.emitSync('pageshow');
-  emit(this, 'pageshow');
-  model.frozen = false;
-}
-
-function pageHide () {
-  let model = modelFor(this);
-  model.contentWorker.emitSync('pagehide');
-  emit(this, 'pagehide');
-  model.frozen = true;
-}
-
-/**
- * Fired from postMessage and emitEventToContent, or from the earlyMessage
- * queue when fired before the content is loaded. Sends arguments to
- * contentWorker if able
- */
-
-function processMessage (worker, ...args) {
-  let model = modelFor(worker) || {};
-  if (!model.contentWorker)
-    throw new Error(ERR_DESTROYED);
-  if (model.frozen)
-    throw new Error(ERR_FROZEN);
-  model.contentWorker.emit.apply(null, args);
-}
-
-function createModel () {
-  return {
-    // List of messages fired before worker is initialized
-    earlyEvents: [],
-    // Is worker connected to the content worker sandbox ?
-    inited: false,
-    // Is worker being frozen? i.e related document is frozen in bfcache.
-    // Content script should not be reachable if frozen.
-    frozen: true,
-    /**
-     * Reference to the content side of the worker.
-     * @type {WorkerGlobalScope}
-     */
-    contentWorker: null,
-    /**
-     * Reference to the window that is accessible from
-     * the content scripts.
-     * @type {Object}
-     */
-    window: null
-  };
-}
-
-function createPort (worker) {
-  let port = EventTarget();
-  port.emit = emitEventToContent.bind(null, worker);
-  return port;
-}
-
-/**
- * Emit a custom event to the content script,
- * i.e. emit this event on `self.port`
- */
-function emitEventToContent (worker, ...eventArgs) {
-  let model = modelFor(worker);
-  let args = ['event'].concat(eventArgs);
-  if (!model.inited) {
-    model.earlyEvents.push(args);
-    return;
-  }
-  processMessage.apply(null, [worker].concat(args));
-}
--- a/addon-sdk/source/lib/sdk/deprecated/unit-test.js
+++ b/addon-sdk/source/lib/sdk/deprecated/unit-test.js
@@ -29,25 +29,23 @@ const findAndRunTests = function findAnd
       stopOnError: options.stopOnError,
       onDone: options.onDone
     });
   });
 };
 exports.findAndRunTests = findAndRunTests;
 
 var runnerWindows = new WeakMap();
-var runnerTabs = new WeakMap();
 
 const TestRunner = function TestRunner(options) {
   options = options || {};
 
   // remember the id's for the open window and tab
   let window = getMostRecentBrowserWindow();
   runnerWindows.set(this, getInnerId(window));
-  runnerTabs.set(this, getTabId(getSelectedTab(window)));
 
   this.fs = options.fs;
   this.console = options.console || console;
   this.passed = 0;
   this.failed = 0;
   this.testRunSummary = [];
   this.expectFailNesting = 0;
   this.done = TestRunner.prototype.done.bind(this);
@@ -325,41 +323,28 @@ TestRunner.prototype = {
     });
 
     PromiseDebugging.flushUncaughtErrors();
     PromiseDebugging.removeUncaughtErrorObserver(this._uncaughtErrorObserver);
 
 
     return all(winPromises).then(() => {
       let browserWins = wins.filter(isBrowser);
-      let tabs = browserWins.reduce((tabs, window) => tabs.concat(getTabs(window)), []);
-      let newTabID = getTabId(getSelectedTab(wins[0]));
-      let oldTabID = runnerTabs.get(this);
-      let hasMoreTabsOpen = browserWins.length && tabs.length != 1;
       let failure = false;
 
       if (wins.length != 1 || getInnerId(wins[0]) !== runnerWindows.get(this)) {
         failure = true;
         this.fail("Should not be any unexpected windows open");
       }
-      else if (hasMoreTabsOpen) {
-        failure = true;
-        this.fail("Should not be any unexpected tabs open");
-      }
-      else if (oldTabID != newTabID) {
-        failure = true;
-        runnerTabs.set(this, newTabID);
-        this.fail("Should not be any new tabs left open, old id: " + oldTabID + " new id: " + newTabID);
-      }
 
       if (failure) {
         console.log("Windows open:");
         for (let win of wins) {
           if (isBrowser(win)) {
-            tabs = getTabs(win);
+            tabs = [];
             console.log(win.location + " - " + tabs.map(getURI).join(", "));
           }
           else {
             console.log(win.location);
           }
         }
       }
 
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/loader/sandbox.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-module.metadata = {
-  "stability": "experimental"
-};
-
-const { Cc, Ci, CC, Cu } = require('chrome');
-const systemPrincipal = CC('@mozilla.org/systemprincipal;1', 'nsIPrincipal')();
-const scriptLoader = Cc['@mozilla.org/moz/jssubscript-loader;1'].
-                     getService(Ci.mozIJSSubScriptLoader);
-const self = require('sdk/self');
-const { getTabId } = require('../tabs/utils');
-const { getInnerId } = require('../window/utils');
-
-/**
- * Make a new sandbox that inherits given `source`'s principals. Source can be
- * URI string, DOMWindow or `null` for system principals.
- */
-function sandbox(target, options) {
-  options = options || {};
-  options.metadata = options.metadata ? options.metadata : {};
-  options.metadata.addonID = options.metadata.addonID ?
-    options.metadata.addonID : self.id;
-
-  let sandbox = Cu.Sandbox(target || systemPrincipal, options);
-  Cu.setSandboxMetadata(sandbox, options.metadata);
-  return sandbox;
-}
-exports.sandbox = sandbox;
-
-/**
- * Evaluates given `source` in a given `sandbox` and returns result.
- */
-function evaluate(sandbox, code, uri, line, version) {
-  return Cu.evalInSandbox(code, sandbox, version || '1.8', uri || '', line || 1);
-}
-exports.evaluate = evaluate;
-
-/**
- * Evaluates code under the given `uri` in the given `sandbox`.
- *
- * @param {String} uri
- *    The URL pointing to the script to load.
- *    It must be a local chrome:, resource:, file: or data: URL.
- */
-function load(sandbox, uri) {
-  if (uri.indexOf('data:') === 0) {
-    let source = uri.substr(uri.indexOf(',') + 1);
-
-    return evaluate(sandbox, decodeURIComponent(source), '1.8', uri, 0);
-  } else {
-    return scriptLoader.loadSubScriptWithOptions(uri, {target: sandbox,
-                                                       charset: 'UTF-8',
-                                                       wantReturnValue: true});
-  }
-}
-exports.load = load;
-
-/**
- * Forces the given `sandbox` to be freed immediately.
- */
-exports.nuke = Cu.nukeSandbox
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/remote/child.js
+++ /dev/null
@@ -1,284 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-const { isChildLoader } = require('./core');
-if (!isChildLoader)
-  throw new Error("Cannot load sdk/remote/child in a main process loader.");
-
-const { Ci, Cc, Cu } = require('chrome');
-const runtime = require('../system/runtime');
-const { Class } = require('../core/heritage');
-const { Namespace } = require('../core/namespace');
-const { omit } = require('../util/object');
-const { when } = require('../system/unload');
-const { EventTarget } = require('../event/target');
-const { emit } = require('../event/core');
-const { Disposable } = require('../core/disposable');
-const { EventParent } = require('./utils');
-const { addListItem, removeListItem } = require('../util/list');
-
-const loaderID = require('@loader/options').loaderID;
-
-const MAIN_PROCESS = Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
-
-const mm = Cc['@mozilla.org/childprocessmessagemanager;1'].
-           getService(Ci.nsISyncMessageSender);
-
-const ns = Namespace();
-
-const process = {
-  port: new EventTarget(),
-  get id() {
-    return runtime.processID;
-  },
-  get isRemote() {
-    return runtime.processType != MAIN_PROCESS;
-  }
-};
-exports.process = process;
-
-function definePort(obj, name) {
-  obj.port.emit = (event, ...args) => {
-    let manager = ns(obj).messageManager;
-    if (!manager)
-      return;
-
-    manager.sendAsyncMessage(name, { loaderID, event, args });
-  };
-}
-
-function messageReceived({ data, objects }) {
-  // Ignore messages from other loaders
-  if (data.loaderID != loaderID)
-    return;
-
-  let keys = Object.keys(objects);
-  if (keys.length) {
-    // If any objects are CPOWs then ignore this message. We don't want child
-    // processes interracting with CPOWs
-    if (!keys.every(name => !Cu.isCrossProcessWrapper(objects[name])))
-      return;
-
-    data.args.push(objects);
-  }
-
-  emit(this.port, data.event, this, ...data.args);
-}
-
-ns(process).messageManager = mm;
-definePort(process, 'sdk/remote/process/message');
-let processMessageReceived = messageReceived.bind(process);
-mm.addMessageListener('sdk/remote/process/message', processMessageReceived);
-
-when(() => {
-  mm.removeMessageListener('sdk/remote/process/message', processMessageReceived);
-  frames = null;
-});
-
-process.port.on('sdk/remote/require', (process, uri) => {
-  require(uri);
-});
-
-function listenerEquals(a, b) {
-  for (let prop of ["type", "callback", "isCapturing"]) {
-    if (a[prop] != b[prop])
-      return false;
-  }
-  return true;
-}
-
-function listenerFor(type, callback, isCapturing = false) {
-  return {
-    type,
-    callback,
-    isCapturing,
-    registeredCallback: undefined,
-    get args() {
-      return [
-        this.type,
-        this.registeredCallback ? this.registeredCallback : this.callback,
-        this.isCapturing
-      ];
-    }
-  };
-}
-
-function removeListenerFromArray(array, listener) {
-  let index = array.findIndex(l => listenerEquals(l, listener));
-  if (index < 0)
-    return;
-  array.splice(index, 1);
-}
-
-function getListenerFromArray(array, listener) {
-  return array.find(l => listenerEquals(l, listener));
-}
-
-function arrayContainsListener(array, listener) {
-  return !!getListenerFromArray(array, listener);
-}
-
-function makeFrameEventListener(frame, callback) {
-  return callback.bind(frame);
-}
-
-var FRAME_ID = 0;
-var tabMap = new Map();
-
-const Frame = Class({
-  implements: [ Disposable ],
-  extends: EventTarget,
-  setup: function(contentFrame) {
-    // This ID should be unique for this loader across all processes
-    let priv = ns(this);
-
-    priv.id = runtime.processID + ":" + FRAME_ID++;
-
-    priv.contentFrame = contentFrame;
-    priv.messageManager = contentFrame;
-    priv.domListeners = [];
-
-    tabMap.set(contentFrame.docShell, this);
-
-    priv.messageReceived = messageReceived.bind(this);
-    priv.messageManager.addMessageListener('sdk/remote/frame/message', priv.messageReceived);
-
-    this.port = new EventTarget();
-    definePort(this, 'sdk/remote/frame/message');
-
-    priv.messageManager.sendAsyncMessage('sdk/remote/frame/attach', {
-      loaderID,
-      frameID: priv.id,
-      processID: runtime.processID
-    });
-
-    frames.attachItem(this);
-  },
-
-  dispose: function() {
-    let priv = ns(this);
-
-    emit(this, 'detach', this);
-
-    for (let listener of priv.domListeners)
-      priv.contentFrame.removeEventListener(...listener.args);
-
-    priv.messageManager.removeMessageListener('sdk/remote/frame/message', priv.messageReceived);
-    tabMap.delete(priv.contentFrame.docShell);
-    priv.contentFrame = null;
-  },
-
-  get content() {
-    return ns(this).contentFrame.content;
-  },
-
-  get isTab() {
-    let docShell = ns(this).contentFrame.docShell;
-    if (process.isRemote) {
-      // We don't want to roundtrip to the main process to get this property.
-      // This hack relies on the host app having defined webBrowserChrome only
-      // in frames that are part of the tabs. Since only Firefox has remote
-      // processes right now and does this this works.
-      let tabchild = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
-                             .getInterface(Ci.nsITabChild);
-      return !!tabchild.webBrowserChrome;
-    }
-    else {
-      // This is running in the main process so we can break out to the browser
-      // And check we can find a tab for the browser element directly.
-      let browser = docShell.chromeEventHandler;
-      let tab = require('../tabs/utils').getTabForBrowser(browser);
-      return !!tab;
-    }
-  },
-
-  addEventListener: function(...args) {
-    let priv = ns(this);
-
-    let listener = listenerFor(...args);
-    if (arrayContainsListener(priv.domListeners, listener))
-      return;
-
-    listener.registeredCallback = makeFrameEventListener(this, listener.callback);
-
-    priv.domListeners.push(listener);
-    priv.contentFrame.addEventListener(...listener.args);
-  },
-
-  removeEventListener: function(...args) {
-    let priv = ns(this);
-
-    let listener = getListenerFromArray(priv.domListeners, listenerFor(...args));
-    if (!listener)
-      return;
-
-    removeListenerFromArray(priv.domListeners, listener);
-    priv.contentFrame.removeEventListener(...listener.args);
-  }
-});
-
-const FrameList = Class({
-  implements: [ EventParent, Disposable ],
-  extends: EventTarget,
-  setup: function() {
-    EventParent.prototype.initialize.call(this);
-
-    this.port = new EventTarget();
-    ns(this).domListeners = [];
-
-    this.on('attach', frame => {
-      for (let listener of ns(this).domListeners)
-        frame.addEventListener(...listener.args);
-    });
-  },
-
-  dispose: function() {
-    // The only case where we get destroyed is when the loader is unloaded in
-    // which case each frame will clean up its own event listeners.
-    ns(this).domListeners = null;
-  },
-
-  getFrameForWindow: function(window) {
-    let docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                         .getInterface(Ci.nsIDocShell);
-
-    return tabMap.get(docShell) || null;
-  },
-
-  addEventListener: function(...args) {
-    let listener = listenerFor(...args);
-    if (arrayContainsListener(ns(this).domListeners, listener))
-      return;
-
-    ns(this).domListeners.push(listener);
-    for (let frame of this)
-      frame.addEventListener(...listener.args);
-  },
-
-  removeEventListener: function(...args) {
-    let listener = listenerFor(...args);
-    if (!arrayContainsListener(ns(this).domListeners, listener))
-      return;
-
-    removeListenerFromArray(ns(this).domListeners, listener);
-    for (let frame of this)
-      frame.removeEventListener(...listener.args);
-  }
-});
-var frames = exports.frames = new FrameList();
-
-function registerContentFrame(contentFrame) {
-  let frame = new Frame(contentFrame);
-}
-exports.registerContentFrame = registerContentFrame;
-
-function unregisterContentFrame(contentFrame) {
-  let frame = tabMap.get(contentFrame.docShell);
-  if (!frame)
-    return;
-
-  frame.destroy();
-}
-exports.unregisterContentFrame = unregisterContentFrame;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/remote/core.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-const options = require("@loader/options");
-
-exports.isChildLoader = options.childLoader;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/remote/parent.js
+++ /dev/null
@@ -1,334 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-const { isChildLoader } = require('./core');
-if (isChildLoader)
-  throw new Error("Cannot load sdk/remote/parent in a child loader.");
-
-const { Cu, Ci, Cc } = require('chrome');
-const runtime = require('../system/runtime');
-
-const MAIN_PROCESS = Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
-
-if (runtime.processType != MAIN_PROCESS) {
-  throw new Error('Cannot use sdk/remote/parent in a child process.');
-}
-
-const { Class } = require('../core/heritage');
-const { Namespace } = require('../core/namespace');
-const { Disposable } = require('../core/disposable');
-const { omit } = require('../util/object');
-const { when } = require('../system/unload');
-const { EventTarget } = require('../event/target');
-const { emit } = require('../event/core');
-const system = require('../system/events');
-const { EventParent } = require('./utils');
-const options = require('@loader/options');
-const loaderModule = require('toolkit/loader');
-
-lazyRequire(this, '../tabs/utils', "getTabForBrowser");
-
-const appInfo = Cc["@mozilla.org/xre/app-info;1"].
-                getService(Ci.nsIXULRuntime);
-
-exports.useRemoteProcesses = appInfo.browserTabsRemoteAutostart;
-
-// Chose the right function for resolving relative a module id
-var moduleResolve;
-if (options.isNative) {
-  moduleResolve = (id, requirer) => loaderModule.nodeResolve(id, requirer, { rootURI: options.rootURI });
-}
-else {
-  moduleResolve = loaderModule.resolve;
-}
-
-// Load the scripts in the child processes
-var { getNewLoaderID } = require('../../framescript/FrameScriptManager.jsm');
-var PATH = options.paths[''];
-
-const childOptions = omit(options, ['modules', 'globals', 'resolve', 'load']);
-childOptions.modules = {};
-// @l10n/data is just JSON data and can be safely sent across to the child loader
-try {
-  childOptions.modules["@l10n/data"] = require("@l10n/data");
-}
-catch (e) {
-  // There may be no l10n data
-}
-const loaderID = getNewLoaderID();
-childOptions.loaderID = loaderID;
-childOptions.childLoader = true;
-
-const ppmm = Cc['@mozilla.org/parentprocessmessagemanager;1'].
-             getService(Ci.nsIMessageBroadcaster);
-const gmm = Cc['@mozilla.org/globalmessagemanager;1'].
-            getService(Ci.nsIMessageBroadcaster);
-
-const ns = Namespace();
-
-var processMap = new Map();
-
-function definePort(obj, name) {
-  obj.port.emitCPOW = (event, args, cpows = {}) => {
-    let manager = ns(obj).messageManager;
-    if (!manager)
-      return;
-
-    let method = manager instanceof Ci.nsIMessageBroadcaster ?
-                 "broadcastAsyncMessage" : "sendAsyncMessage";
-
-    manager[method](name, { loaderID, event, args }, cpows);
-  };
-
-  obj.port.emit = (event, ...args) => obj.port.emitCPOW(event, args);
-}
-
-function messageReceived({ target, data }) {
-  // Ignore messages from other loaders
-  if (data.loaderID != loaderID)
-    return;
-
-  emit(this.port, data.event, this, ...data.args);
-}
-
-// Process represents a gecko process that can load webpages. Each process
-// contains a number of Frames. This class is used to send and receive messages
-// from a single process.
-const Process = Class({
-  implements: [ Disposable ],
-  extends: EventTarget,
-  setup: function(id, messageManager, isRemote) {
-    ns(this).id = id;
-    ns(this).isRemote = isRemote;
-    ns(this).messageManager = messageManager;
-    ns(this).messageReceived = messageReceived.bind(this);
-    this.destroy = this.destroy.bind(this);
-    ns(this).messageManager.addMessageListener('sdk/remote/process/message', ns(this).messageReceived);
-    ns(this).messageManager.addMessageListener('child-process-shutdown', this.destroy);
-
-    this.port = new EventTarget();
-    definePort(this, 'sdk/remote/process/message');
-
-    // Load any remote modules
-    for (let module of remoteModules.values())
-      this.port.emit('sdk/remote/require', module);
-
-    processMap.set(ns(this).id, this);
-    processes.attachItem(this);
-  },
-
-  dispose: function() {
-    emit(this, 'detach', this);
-    processMap.delete(ns(this).id);
-    ns(this).messageManager.removeMessageListener('sdk/remote/process/message', ns(this).messageReceived);
-    ns(this).messageManager.removeMessageListener('child-process-shutdown', this.destroy);
-    ns(this).messageManager = null;
-  },
-
-  // Returns true if this process is a child process
-  get isRemote() {
-    return ns(this).isRemote;
-  }
-});
-
-// Processes gives an API for enumerating an sending and receiving messages from
-// all processes as well as detecting when a new process starts.
-const Processes = Class({
-  implements: [ EventParent ],
-  extends: EventTarget,
-  initialize: function() {
-    EventParent.prototype.initialize.call(this);
-    ns(this).messageManager = ppmm;
-
-    this.port = new EventTarget();
-    definePort(this, 'sdk/remote/process/message');
-  },
-
-  getById: function(id) {
-    return processMap.get(id);
-  }
-});
-var processes = exports.processes = new Processes();
-
-var frameMap = new Map();
-
-function setFrameProcess(frame, process) {
-  ns(frame).process = process;
-  frames.attachItem(frame);
-}
-
-// Frames display webpages in a process. In the main process every Frame is
-// linked with a <browser> or <iframe> element. 
-const Frame = Class({
-  implements: [ Disposable ],
-  extends: EventTarget,
-  setup: function(id, node) {
-    ns(this).id = id;
-    ns(this).node = node;
-
-    let frameLoader = node.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
-    ns(this).messageManager = frameLoader.messageManager;
-
-    ns(this).messageReceived = messageReceived.bind(this);
-    ns(this).messageManager.addMessageListener('sdk/remote/frame/message', ns(this).messageReceived);
-
-    this.port = new EventTarget();
-    definePort(this, 'sdk/remote/frame/message');
-
-    frameMap.set(ns(this).messageManager, this);
-  },
-
-  dispose: function() {
-    emit(this, 'detach', this);
-    ns(this).messageManager.removeMessageListener('sdk/remote/frame/message', ns(this).messageReceived);
-
-    frameMap.delete(ns(this).messageManager);
-    ns(this).messageManager = null;
-  },
-
-  // Returns the browser or iframe element this frame displays in
-  get frameElement() {
-    return ns(this).node;
-  },
-
-  // Returns the process that this frame loads in
-  get process() {
-    return ns(this).process;
-  },
-
-  // Returns true if this frame is a tab in a main browser window
-  get isTab() {
-    let tab = getTabForBrowser(ns(this).node);
-    return !!tab;
-  }
-});
-
-function managerDisconnected({ subject: manager }) {
-  let frame = frameMap.get(manager);
-  if (frame)
-    frame.destroy();
-}
-system.on('message-manager-disconnect', managerDisconnected);
-
-// Provides an API for enumerating and sending and receiving messages from all
-// Frames
-const FrameList = Class({
-  implements: [ EventParent ],
-  extends: EventTarget,
-  initialize: function() {
-    EventParent.prototype.initialize.call(this);
-    ns(this).messageManager = gmm;
-
-    this.port = new EventTarget();
-    definePort(this, 'sdk/remote/frame/message');
-  },
-
-  // Returns the frame for a browser element
-  getFrameForBrowser: function(browser) {
-    for (let frame of this) {
-      if (frame.frameElement == browser)
-        return frame;
-    }
-    return null;
-  },
-});
-var frames = exports.frames = new FrameList();
-
-// Create the module loader in any existing processes
-ppmm.broadcastAsyncMessage('sdk/remote/process/load', {
-  modulePath: PATH,
-  loaderID,
-  options: childOptions,
-  reason: "broadcast"
-});
-
-// A loader has started in a remote process
-function processLoaderStarted({ target, data }) {
-  if (data.loaderID != loaderID)
-    return;
-
-  if (processMap.has(data.processID)) {
-    console.error("Saw the same process load the same loader twice. This is a bug in the SDK.");
-    return;
-  }
-
-  let process = new Process(data.processID, target, data.isRemote);
-
-  if (pendingFrames.has(data.processID)) {
-    for (let frame of pendingFrames.get(data.processID))
-      setFrameProcess(frame, process);
-    pendingFrames.delete(data.processID);
-  }
-}
-
-// A new process has started
-function processStarted({ target, data: { modulePath } }) {
-  if (modulePath != PATH)
-    return;
-
-  // Have it load a loader if it hasn't already
-  target.sendAsyncMessage('sdk/remote/process/load', {
-    modulePath,
-    loaderID,
-    options: childOptions,
-    reason: "response"
-  });
-}
-
-var pendingFrames = new Map();
-
-// A new frame has been created in the remote process
-function frameAttached({ target, data }) {
-  if (data.loaderID != loaderID)
-    return;
-
-  let frame = new Frame(data.frameID, target);
-
-  let process = processMap.get(data.processID);
-  if (process) {
-    setFrameProcess(frame, process);
-    return;
-  }
-
-  // In some cases frame messages can arrive earlier than process messages
-  // causing us to see a new frame appear before its process. In this case
-  // cache the frame data until we see the process. See bug 1131375.
-  if (!pendingFrames.has(data.processID))
-    pendingFrames.set(data.processID, [frame]);
-  else
-    pendingFrames.get(data.processID).push(frame);
-}
-
-// Wait for new processes and frames
-ppmm.addMessageListener('sdk/remote/process/attach', processLoaderStarted);
-ppmm.addMessageListener('sdk/remote/process/start', processStarted);
-gmm.addMessageListener('sdk/remote/frame/attach', frameAttached);
-
-when(reason => {
-  ppmm.removeMessageListener('sdk/remote/process/attach', processLoaderStarted);
-  ppmm.removeMessageListener('sdk/remote/process/start', processStarted);
-  gmm.removeMessageListener('sdk/remote/frame/attach', frameAttached);
-
-  ppmm.broadcastAsyncMessage('sdk/remote/process/unload', { loaderID, reason });
-});
-
-var remoteModules = new Set();
-
-// Ensures a module is loaded in every child process. It is safe to send 
-// messages to this module immediately after calling this.
-// Pass a module to resolve the id relatively.
-function remoteRequire(id, module = null) {
-  // Resolve relative to calling module if passed
-  if (module)
-    id = moduleResolve(id, module.id);
-
-  // Don't reload the same module
-  if (remoteModules.has(id))
-    return;
-
-  remoteModules.add(id);
-  processes.port.emit('sdk/remote/require', id);
-}
-exports.remoteRequire = remoteRequire;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/remote/utils.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-const { Class } = require('../core/heritage');
-const { List, addListItem, removeListItem } = require('../util/list');
-lazyRequire(this, '../event/core', 'emit');
-lazyRequire(this, '../event/utils', 'pipe');
-
-// A helper class that maintains a list of EventTargets. Any events emitted
-// to an EventTarget are also emitted by the EventParent. Likewise for an
-// EventTarget's port property.
-const EventParent = Class({
-  implements: [ List ],
-
-  attachItem: function(item) {
-    addListItem(this, item);
-
-    pipe(item.port, this.port);
-    pipe(item, this);
-
-    item.once('detach', () => {
-      removeListItem(this, item);
-    })
-
-    emit(this, 'attach', item);
-  },
-
-  // Calls listener for every object already in the list and every object
-  // subsequently added to the list.
-  forEvery: function(listener) {
-    for (let item of this)
-      listener(item);
-
-    this.on('attach', listener);
-  }
-});
-exports.EventParent = EventParent;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/selection.js
+++ /dev/null
@@ -1,469 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-module.metadata = {
-  "stability": "stable",
-  "engines": {
-    "Firefox": "*",
-    "SeaMonkey": "*"
-  }
-};
-
-const { Ci, Cc } = require("chrome");
-lazyRequire(this, "./timers", "setTimeout");
-lazyRequire(this, "./event/core", "emit", "off");
-const { Class, obscure } = require("./core/heritage");
-const { EventTarget } = require("./event/target");
-const { ns } = require("./core/namespace");
-const { when: unload } = require("./system/unload");
-lazyRequire(this, './private-browsing/utils', "ignoreWindow");
-lazyRequire(this, './tabs/utils', "getTabs", "getTabForContentWindow", "getAllTabContentWindows");
-lazyRequireModule(this, "./window/utils", "winUtils");
-const events = require("./system/events");
-
-// The selection types
-const HTML = 0x01,
-      TEXT = 0x02,
-      DOM  = 0x03; // internal use only
-
-// A more developer-friendly message than the caught exception when is not
-// possible change a selection.
-const ERR_CANNOT_CHANGE_SELECTION =
-  "It isn't possible to change the selection, as there isn't currently a selection";
-
-const selections = ns();
-
-const Selection = Class({
-  /**
-   * Creates an object from which a selection can be set, get, etc. Each
-   * object has an associated with a range number. Range numbers are the
-   * 0-indexed counter of selection ranges as explained at
-   * https://developer.mozilla.org/en/DOM/Selection.
-   *
-   * @param rangeNumber
-   *        The zero-based range index into the selection
-   */
-  initialize: function initialize(rangeNumber) {
-    // In order to hide the private `rangeNumber` argument from API consumers
-    // while still enabling Selection getters/setters to access it, we define
-    // it as non enumerable, non configurable property. While consumers still
-    // may discover it they won't be able to do any harm which is good enough
-    // in this case.
-    Object.defineProperties(this, {
-      rangeNumber: {
-        enumerable: false,
-        configurable: false,
-        value: rangeNumber
-      }
-    });
-  },
-  get text() { return getSelection(TEXT, this.rangeNumber); },
-  set text(value) { setSelection(TEXT, value, this.rangeNumber); },
-  get html() { return getSelection(HTML, this.rangeNumber); },
-  set html(value) { setSelection(HTML, value, this.rangeNumber); },
-  get isContiguous() {
-
-    // If there are multiple non empty ranges, the selection is definitely
-    // discontiguous. It returns `false` also if there are no valid selection.
-    let count = 0;
-    for (let sel in selectionIterator)
-      if (++count > 1)
-        break;
-
-    return count === 1;
-  }
-});
-
-const selectionListener = {
-  notifySelectionChanged: function (document, selection, reason) {
-    if (!["SELECTALL", "KEYPRESS", "MOUSEUP"].some(type => reason &
-      Ci.nsISelectionListener[type + "_REASON"]) || selection.toString() == "")
-        return;
-
-    this.onSelect();
-  },
-
-  onSelect: function() {
-    emit(module.exports, "select");
-  }
-}
-
-/**
- * Defines iterators so that discontiguous selections can be iterated.
- * Empty selections are skipped - see `safeGetRange` for further details.
- *
- * If discontiguous selections are in a text field, only the first one
- * is returned because the text field selection APIs doesn't support
- * multiple selections.
- */
-function* forOfIterator() {
-  let selection = getSelection(DOM);
-  let count = 0;
-
-  if (selection)
-    count = selection.rangeCount || (getElementWithSelection() ? 1 : 0);
-
-  for (let i = 0; i < count; i++) {
-    let sel = Selection(i);
-
-    if (sel.text)
-      yield Selection(i);
-  }
-}
-
-const selectionIteratorOptions = {
-  __iterator__: function() {
-      for (let item of this)
-          yield item;
-  }
-}
-selectionIteratorOptions[Symbol.iterator] = forOfIterator;
-const selectionIterator = obscure(selectionIteratorOptions);
-
-/**
- * Returns the most recent focused window.
- * if private browsing window is most recent and not supported,
- * then ignore it and return `null`, because the focused window
- * can't be targeted.
- */
-function getFocusedWindow() {
-  let window = winUtils.getFocusedWindow();
-
-  return ignoreWindow(window) ? null : window;
-}
-
-/**
- * Returns the focused element in the most recent focused window
- * if private browsing window is most recent and not supported,
- * then ignore it and return `null`, because the focused element
- * can't be targeted.
- */
-function getFocusedElement() {
-  let element = winUtils.getFocusedElement();
-
-  if (!element || ignoreWindow(element.ownerGlobal))
-    return null;
-
-  return element;
-}
-
-/**
- * Returns the current selection from most recent content window. Depending on
- * the specified |type|, the value returned can be a string of text, stringified
- * HTML, or a DOM selection object as described at
- * https://developer.mozilla.org/en/DOM/Selection.
- *
- * @param type
- *        Specifies the return type of the selection. Valid values are the one
- *        of the constants HTML, TEXT, or DOM.
- *
- * @param rangeNumber
- *        Specifies the zero-based range index of the returned selection.
- */
-function getSelection(type, rangeNumber) {
-  let window, selection;
-  try {
-    window = getFocusedWindow();
-    selection = window.getSelection();
-  }
-  catch (e) {
-    return null;
-  }
-
-  // Get the selected content as the specified type
-  if (type == DOM) {
-    return selection;
-  }
-  else if (type == TEXT) {
-    let range = safeGetRange(selection, rangeNumber);
-
-    if (range)
-      return range.toString();
-
-    let node = getElementWithSelection();
-
-    if (!node)
-      return null;
-
-    return node.value.substring(node.selectionStart, node.selectionEnd);
-  }
-  else if (type == HTML) {
-    let range = safeGetRange(selection, rangeNumber);
-    // Another way, but this includes the xmlns attribute for all elements in
-    // Gecko 1.9.2+ :
-    // return Cc["@mozilla.org/xmlextras/xmlserializer;1"].
-    //   createInstance(Ci.nsIDOMSerializer).serializeToSTring(range.
-    //     cloneContents());
-    if (!range)
-      return null;
-
-    let node = window.document.createElement("span");
-    node.appendChild(range.cloneContents());
-    return node.innerHTML;
-  }
-
-  throw new Error("Type " + type + " is unrecognized.");
-}
-
-/**
- * Sets the current selection of the most recent content document by changing
- * the existing selected text/HTML range to the specified value.
- *
- * @param val
- *        The value for the new selection
- *
- * @param rangeNumber
- *        The zero-based range index of the selection to be set
- *
- */
-function setSelection(type, val, rangeNumber) {
-  // Make sure we have a window context & that there is a current selection.
-  // Selection cannot be set unless there is an existing selection.
-  let window, selection;
-
-  try {
-    window = getFocusedWindow();
-    selection = window.getSelection();
-  }
-  catch (e) {
-    throw new Error(ERR_CANNOT_CHANGE_SELECTION);
-  }
-
-  let range = safeGetRange(selection, rangeNumber);
-
-  if (range) {
-    let fragment;
-
-    if (type === HTML)
-      fragment = range.createContextualFragment(val);
-    else {
-      fragment = range.createContextualFragment("");
-      fragment.textContent = val;
-    }
-
-    range.deleteContents();
-    range.insertNode(fragment);
-  }
-  else {
-    let node = getElementWithSelection();
-
-    if (!node)
-      throw new Error(ERR_CANNOT_CHANGE_SELECTION);
-
-    let { value, selectionStart, selectionEnd } = node;
-
-    let newSelectionEnd = selectionStart + val.length;
-
-    node.value = value.substring(0, selectionStart) +
-                  val +
-                  value.substring(selectionEnd, value.length);
-
-    node.setSelectionRange(selectionStart, newSelectionEnd);
-  }
-}
-
-/**
- * Returns the specified range in a selection without throwing an exception.
- *
- * @param selection
- *        A selection object as described at
- *         https://developer.mozilla.org/en/DOM/Selection
- *
- * @param [rangeNumber]
- *        Specifies the zero-based range index of the returned selection.
- *        If it's not provided the function will return the first non empty
- *        range, if any.
- */
-function safeGetRange(selection, rangeNumber) {
-  try {
-    let { rangeCount } = selection;
-    let range = null;
-
-    if (typeof rangeNumber === "undefined")
-      rangeNumber = 0;
-    else
-      rangeCount = rangeNumber + 1;
-
-    for (; rangeNumber < rangeCount; rangeNumber++ ) {
-      range = selection.getRangeAt(rangeNumber);
-
-      if (range && range.toString())
-        break;
-
-      range = null;
-    }
-
-    return range;
-  }
-  catch (e) {
-    return null;
-  }
-}
-
-/**
- * Returns a reference of the DOM's active element for the window given, if it
- * supports the text field selection API and has a text selected.
- *
- * Note:
- *   we need this method because window.getSelection doesn't return a selection
- *   for text selected in a form field (see bug 85686)
- */
-function getElementWithSelection() {
-  let element = getFocusedElement();
-
-  if (!element)
-    return null;
-
-  try {
-    // Accessing selectionStart and selectionEnd on e.g. a button
-    // results in an exception thrown as per the HTML5 spec.  See
-    // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#textFieldSelection
-
-    let { value, selectionStart, selectionEnd } = element;
-
-    let hasSelection = typeof value === "string" &&
-                      !isNaN(selectionStart) &&
-                      !isNaN(selectionEnd) &&
-                      selectionStart !== selectionEnd;
-
-    return hasSelection ? element : null;
-  }
-  catch (err) {
-    return null;
-  }
-
-}
-
-/**
- * Adds the Selection Listener to the content's window given
- */
-function addSelectionListener(window) {
-  let selection = window.getSelection();
-
-  // Don't add the selection's listener more than once to the same window,
-  // if the selection object is the same
-  if ("selection" in selections(window) && selections(window).selection === selection)
-    return;
-
-  // We ensure that the current selection is an instance of
-  // `nsISelectionPrivate` before working on it, in case is `null`.
-  //
-  // If it's `null` it's likely too early to add the listener, and we demand
-  // that operation to `document-shown` - it can easily happens for frames
-  if (selection instanceof Ci.nsISelectionPrivate)
-    selection.addSelectionListener(selectionListener);
-
-  // nsISelectionListener implementation seems not fire a notification if
-  // a selection is in a text field, therefore we need to add a listener to
-  // window.onselect, that is fired only for text fields.
-  // For consistency, we add it only when the nsISelectionListener is added.
-  //
-  // https://developer.mozilla.org/en/DOM/window.onselect
-  window.addEventListener("select", selectionListener.onSelect, true);
-
-  selections(window).selection = selection;
-};
-
-/**
- * Removes the Selection Listener to the content's window given
- */
-function removeSelectionListener(window) {
-  // Don't remove the selection's listener to a window that wasn't handled.
-  if (!("selection" in selections(window)))
-    return;
-
-  let selection = window.getSelection();
-  let isSameSelection = selection === selections(window).selection;
-
-  // Before remove the listener, we ensure that the current selection is an
-  // instance of `nsISelectionPrivate` (it could be `null`), and that is still
-  // the selection we managed for this window (it could be detached).
-  if (selection instanceof Ci.nsISelectionPrivate && isSameSelection)
-    selection.removeSelectionListener(selectionListener);
-
-  window.removeEventListener("select", selectionListener.onSelect, true);
-
-  delete selections(window).selection;
-};
-
-function onContent(event) {
-  let window = event.subject.defaultView;
-
-  // We are not interested in documents without valid defaultView (e.g. XML)
-  // that aren't in a tab (e.g. Panel); or in private windows
-   if (window && getTabForContentWindow(window) && !ignoreWindow(window)) {
-    addSelectionListener(window);
-  }
-}
-
-// Adds Selection listener to new documents
-// Note that strong reference is needed for documents that are loading slowly or
-// where the server didn't close the connection (e.g. "comet").
-events.on("document-element-inserted", onContent, true);
-
-// Adds Selection listeners to existing documents
-getAllTabContentWindows().forEach(addSelectionListener);
-
-// When a document is not visible anymore the selection object is detached, and
-// a new selection object is created when it becomes visible again.
-// That makes the previous selection's listeners added previously totally
-// useless – the listeners are not notified anymore.
-// To fix that we're listening for `document-shown` event in order to add
-// the listeners to the new selection object created.
-//
-// See bug 665386 for further details.
-
-function onShown(event) {
-  let window = event.subject.defaultView;
-
-  // We are not interested in documents without valid defaultView.
-  // For example XML documents don't have windows and we don't yet support them.
-  if (!window)
-    return;
-
-  // We want to handle only the windows where we added selection's listeners
-  if ("selection" in selections(window)) {
-    let currentSelection = window.getSelection();
-    let { selection } = selections(window);
-
-    // If the current selection for the window given is different from the one
-    // stored in the namespace, we need to add the listeners again, and replace
-    // the previous selection in our list with the new one.
-    //
-    // Notice that we don't have to remove the listeners from the old selection,
-    // because is detached. An attempt to remove the listener, will raise an
-    // error (see http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsSelection.cpp#5343 )
-    //
-    // We ensure that the current selection is an instance of
-    // `nsISelectionPrivate` before working on it, in case is `null`.
-    if (currentSelection instanceof Ci.nsISelectionPrivate &&
-      currentSelection !== selection) {
-
-      window.addEventListener("select", selectionListener.onSelect, true);
-      currentSelection.addSelectionListener(selectionListener);
-      selections(window).selection = currentSelection;
-    }
-  }
-}
-
-events.on("document-shown", onShown, true);
-
-// Removes Selection listeners when the add-on is unloaded
-unload(function(){
-  getAllTabContentWindows().forEach(removeSelectionListener);
-
-  events.off("document-element-inserted", onContent);
-  events.off("document-shown", onShown);
-
-  off(exports);
-});
-
-const selection = Class({
-  extends: EventTarget,
-  implements: [ Selection, selectionIterator ]
-})();
-
-module.exports = selection;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/tab/events.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// This module provides temporary shim until Bug 843901 is shipped.
-// It basically registers tab event listeners on all windows that get
-// opened and forwards them through observer notifications.
-
-module.metadata = {
-  "stability": "experimental"
-};
-
-const { Ci } = require("chrome");
-const { windows, isInteractive } = require("../window/utils");
-const { events } = require("../browser/events");
-const { open } = require("../event/dom");
-const { filter, map, merge, expand } = require("../event/utils");
-const isFennec = require("sdk/system/xul-app").is("Fennec");
-
-// Module provides event stream (in nodejs style) that emits data events
-// for all the tab events that happen in running firefox. At the moment
-// it does it by registering listeners on all browser windows and then
-// forwarding events when they occur to a stream. This will become obsolete
-// once Bug 843901 is fixed, and we'll just leverage observer notifications.
-
-// Set of tab events that this module going to aggregate and expose.
-const TYPES = ["TabOpen","TabClose","TabSelect","TabMove","TabPinned",
-               "TabUnpinned"];
-
-// Utility function that given a browser `window` returns stream of above
-// defined tab events for all tabs on the given window.
-function tabEventsFor(window) {
-  // Map supported event types to a streams of those events on the given
-  // `window` and than merge these streams into single form stream off
-  // all events.
-  let channels = TYPES.map(type => open(window, type));
-  return merge(channels);
-}
-
-// Create our event channels.  We do this in a separate function to
-// minimize the chance of leaking intermediate objects on the global.
-function makeEvents() {
-  // Filter DOMContentLoaded events from all the browser events.
-  var readyEvents = filter(events, e => e.type === "DOMContentLoaded");
-  // Map DOMContentLoaded events to it's target browser windows.
-  var futureWindows = map(readyEvents, e => e.target);
-  // Expand all browsers that will become interactive to supported tab events
-  // on these windows. Result will be a tab events from all tabs of all windows
-  // that will become interactive.
-  var eventsFromFuture = expand(futureWindows, tabEventsFor);
-
-  // Above covers only windows that will become interactive in a future, but some
-  // windows may already be interactive so we pick those and expand to supported
-  // tab events for them too.
-  var interactiveWindows = windows("navigator:browser", { includePrivate: true }).
-                           filter(isInteractive);
-  var eventsFromInteractive = merge(interactiveWindows.map(tabEventsFor));
-
-
-  // Finally merge stream of tab events from future windows and current windows
-  // to cover all tab events on all windows that will open.
-  return merge([eventsFromInteractive, eventsFromFuture]);
-}
-
-// Map events to Fennec format if necessary
-exports.events = map(makeEvents(), function (event) {
-  return !isFennec ? event : {
-    type: event.type,
-    target: event.target.ownerGlobal.BrowserApp
-            .getTabForBrowser(event.target)
-  };
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/tabs.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-if (require("./system/xul-app").is("Fennec")) {
-  module.exports = require("./windows/tabs-fennec").tabs;
-}
-else {
-  module.exports = require("./tabs/tabs-firefox");
-}
-
-const tabs = module.exports;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/tabs/common.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-const { validateOptions } = require("../deprecated/api-utils");
-const { data } = require("../self");
-
-function Options(options) {
-  if ('string' === typeof options)
-    options = { url: options };
-
-  return validateOptions(options, {
-    url: {
-      is: ["string"],
-      map: (v) => v ? data.url(v) : v
-    },
-    inBackground: {
-      map: Boolean,
-      is: ["undefined", "boolean"]
-    },
-    isPinned: { is: ["undefined", "boolean"] },
-    isPrivate: { is: ["undefined", "boolean"] },
-    inNewWindow: { is: ["undefined", "boolean"] },
-    onOpen: { is: ["undefined", "function"] },
-    onClose: { is: ["undefined", "function"] },
-    onReady: { is: ["undefined", "function"] },
-    onLoad: { is: ["undefined", "function"] },
-    onPageShow: { is: ["undefined", "function"] },
-    onActivate: { is: ["undefined", "function"] },
-    onDeactivate: { is: ["undefined", "function"] }
-  });
-}
-exports.Options = Options;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/tabs/events.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-const ON_PREFIX = "on";
-const TAB_PREFIX = "Tab";
-
-const EVENTS = {
-  ready: "DOMContentLoaded",
-  load: "load", // Used for non-HTML content
-  pageshow: "pageshow", // Used for cached content
-  open: "TabOpen",
-  close: "TabClose",
-  activate: "TabSelect",
-  deactivate: null,
-  pinned: "TabPinned",
-  unpinned: "TabUnpinned"
-}
-exports.EVENTS = EVENTS;
-
-Object.keys(EVENTS).forEach(function(name) {
-  EVENTS[name] = {
-    name: name,
-    listener: createListenerName(name),
-    dom: EVENTS[name]
-  }
-});
-
-function createListenerName (name) {
-  if (name === 'pageshow')
-    return 'onPageShow';
-  else
-    return ON_PREFIX + name.charAt(0).toUpperCase() + name.substr(1);
-}
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/tabs/helpers.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-module.metadata = {
-  'stability': 'unstable'
-};
-
-
-// NOTE: This file should only export Tab instances
-
-
-lazyRequire(this, './utils', { "getTabForBrowser": "getRawTabForBrowser" });
-const { modelFor } = require('../model/core');
-
-exports.getTabForRawTab = modelFor;
-
-function getTabForBrowser(browser) {
-  return modelFor(getRawTabForBrowser(browser)) || null;
-}
-exports.getTabForBrowser = getTabForBrowser;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/tabs/namespace.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-var { ns } = require('../core/namespace');
-
-exports.tabsNS = ns();
-exports.tabNS = ns();
-exports.rawTabNS = ns();
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/tabs/observer.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-const { EventTarget } = require("../event/target");
-const { emit } = require("../event/core");
-const { DOMEventAssembler } = require("../deprecated/events/assembler");
-const { Class } = require("../core/heritage");
-const { getActiveTab, getTabs } = require("./utils");
-const { browserWindowIterator } = require("../deprecated/window-utils");
-const { isBrowser, windows, getMostRecentBrowserWindow } = require("../window/utils");
-const { observer: windowObserver } = require("../windows/observer");
-const { when } = require("../system/unload");
-
-const EVENTS = {
-  "TabOpen": "open",
-  "TabClose": "close",
-  "TabSelect": "select",
-  "TabMove": "move",
-  "TabPinned": "pinned",
-  "TabUnpinned": "unpinned"
-};
-
-const selectedTab = Symbol("observer/state/selectedTab");
-
-// Event emitter objects used to register listeners and emit events on them
-// when they occur.
-const Observer = Class({
-  implements: [EventTarget, DOMEventAssembler],
-  initialize() {
-    this[selectedTab] = null;
-    // Currently Gecko does not dispatch any event on the previously selected
-    // tab before / after "TabSelect" is dispatched. In order to work around this
-    // limitation we keep track of selected tab and emit "deactivate" event with
-    // that before emitting "activate" on selected tab.
-    this.on("select", tab => {
-      const selected = this[selectedTab];
-      if (selected !== tab) {
-        if (selected) {
-          emit(this, 'deactivate', selected);
-        }
-
-        if (tab) {
-          this[selectedTab] = tab;
-          emit(this, 'activate', this[selectedTab]);
-        }
-      }
-    });
-
-
-    // We also observe opening / closing windows in order to add / remove it's
-    // containers to the observed list.
-    windowObserver.on("open", chromeWindow => {
-      if (isBrowser(chromeWindow)) {
-        this.observe(chromeWindow);
-      }
-    });
-
-    windowObserver.on("close", chromeWindow => {
-      if (isBrowser(chromeWindow)) {
-        // Bug 751546: Emit `deactivate` event on window close immediatly
-        // Otherwise we are going to face "dead object" exception on `select` event
-        if (getActiveTab(chromeWindow) === this[selectedTab]) {
-          emit(this, "deactivate", this[selectedTab]);
-          this[selectedTab] = null;
-        }
-        this.ignore(chromeWindow);
-      }
-    });
-
-
-    // Currently gecko does not dispatches "TabSelect" events when different
-    // window gets activated. To work around this limitation we emulate "select"
-    // event for this case.
-    windowObserver.on("activate", chromeWindow => {
-      if (isBrowser(chromeWindow)) {
-        emit(this, "select", getActiveTab(chromeWindow));
-      }
-    });
-
-    // We should synchronize state, since probably we already have at least one
-    // window open.
-    for (let chromeWindow of browserWindowIterator()) {
-      this.observe(chromeWindow);
-    }
-
-    when(_ => {
-      // Don't dispatch a deactivate event during unload.
-      this[selectedTab] = null;
-    });
-  },
-  /**
-   * Events that are supported and emitted by the module.
-   */
-  supportedEventsTypes: Object.keys(EVENTS),
-  /**
-   * Function handles all the supported events on all the windows that are
-   * observed. Method is used to proxy events to the listeners registered on
-   * this event emitter.
-   * @param {Event} event
-   *    Keyboard event being emitted.
-   */
-  handleEvent: function handleEvent(event) {
-    emit(this, EVENTS[event.type], event.target, event);
-  }
-});
-
-exports.observer = new Observer();
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/tabs/tab-fennec.js
+++ /dev/null
@@ -1,249 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-const { Cc, Ci } = require('chrome');
-const { Class } = require('../core/heritage');
-const { tabNS, rawTabNS } = require('./namespace');
-const { EventTarget } = require('../event/target');
-const { activateTab, getTabTitle, setTabTitle, closeTab, getTabURL,
-        getTabContentWindow, getTabForBrowser, setTabURL, getOwnerWindow,
-        getTabContentDocument, getTabContentType, getTabId, isTab } = require('./utils');
-const { emit } = require('../event/core');
-const { isPrivate } = require('../private-browsing/utils');
-const { isWindowPrivate } = require('../window/utils');
-const { when: unload } = require('../system/unload');
-const { BLANK } = require('../content/thumbnail');
-const { viewFor } = require('../view/core');
-const { EVENTS } = require('./events');
-const { modelFor } = require('../model/core');
-
-const ERR_FENNEC_MSG = 'This method is not yet supported by Fennec';
-
-const Tab = Class({
-  extends: EventTarget,
-  initialize: function initialize(options) {
-    options = options.tab ? options : { tab: options };
-    let tab = options.tab;
-
-    EventTarget.prototype.initialize.call(this, options);
-    let tabInternals = tabNS(this);
-    rawTabNS(tab).tab = this;
-
-    let window = tabInternals.window = options.window || getOwnerWindow(tab);
-    tabInternals.tab = tab;
-
-    // TabReady
-    let onReady = tabInternals.onReady = onTabReady.bind(this);
-    tab.browser.addEventListener(EVENTS.ready.dom, onReady);
-
-    // TabPageShow
-    let onPageShow = tabInternals.onPageShow = onTabPageShow.bind(this);
-    tab.browser.addEventListener(EVENTS.pageshow.dom, onPageShow);
-
-    // TabLoad
-    let onLoad = tabInternals.onLoad = onTabLoad.bind(this);
-    tab.browser.addEventListener(EVENTS.load.dom, onLoad, true);
-
-    // TabClose
-    let onClose = tabInternals.onClose = onTabClose.bind(this);
-    window.BrowserApp.deck.addEventListener(EVENTS.close.dom, onClose);
-
-    unload(cleanupTab.bind(null, this));
-  },
-
-  /**
-   * The title of the page currently loaded in the tab.
-   * Changing this property changes an actual title.
-   * @type {String}
-   */
-  get title() {
-    return getTabTitle(tabNS(this).tab);
-  },
-  set title(title) {
-    setTabTitle(tabNS(this).tab, title);
-  },
-
-  /**
-   * Location of the page currently loaded in this tab.
-   * Changing this property will loads page under under the specified location.
-   * @type {String}
-   */
-  get url() {
-    return tabNS(this).closed ? undefined : getTabURL(tabNS(this).tab);
-  },
-  set url(url) {
-    setTabURL(tabNS(this).tab, url);
-  },
-
-  getThumbnail: function() {
-    // TODO: implement!
-    console.error(ERR_FENNEC_MSG);
-
-    // return 80x45 blank default
-    return BLANK;
-  },
-
-  /**
-   * tab's document readyState, or 'uninitialized' if it doesn't even exist yet.
-   */
-  get readyState() {
-    let doc = getTabContentDocument(tabNS(this).tab);
-    return doc && doc.readyState || 'uninitialized';
-  },
-
-  get id() {
-    return getTabId(tabNS(this).tab);
-  },
-
-  /**
-   * The index of the tab relative to other tabs in the application window.
-   * Changing this property will change order of the actual position of the tab.
-   * @type {Number}
-   */
-  get index() {
-    if (tabNS(this).closed) return undefined;
-
-    let tabs = tabNS(this).window.BrowserApp.tabs;
-    let tab = tabNS(this).tab;
-    for (var i = tabs.length; i >= 0; i--) {
-      if (tabs[i] === tab)
-        return i;
-    }
-    return null;
-  },
-  set index(value) {
-    console.error(ERR_FENNEC_MSG); // TODO
-  },
-
-  /**
-   * Whether or not tab is pinned (Is an app-tab).
-   * @type {Boolean}
-   */
-  get isPinned() {
-    console.error(ERR_FENNEC_MSG); // TODO
-    return false; // TODO
-  },
-  pin: function pin() {
-    console.error(ERR_FENNEC_MSG); // TODO
-  },
-  unpin: function unpin() {
-    console.error(ERR_FENNEC_MSG); // TODO
-  },
-
-  /**
-   * Returns the MIME type that the document loaded in the tab is being
-   * rendered as.
-   * @type {String}
-   */
-  get contentType() {
-    return getTabContentType(tabNS(this).tab);
-  },
-
-  /**
-   * Create a worker for this tab, first argument is options given to Worker.
-   * @type {Worker}
-   */
-  attach: function attach(options) {
-    // BUG 792946 https://bugzilla.mozilla.org/show_bug.cgi?id=792946
-    // TODO: fix this circular dependency
-    let { Worker } = require('./worker');
-    return Worker(options, getTabContentWindow(tabNS(this).tab));
-  },
-
-  /**
-   * Make this tab active.
-   */
-  activate: function activate() {
-    activateTab(tabNS(this).tab, tabNS(this).window);
-  },
-
-  /**
-   * Close the tab
-   */
-  close: function close(callback) {
-    let tab = this;
-    this.once(EVENTS.close.name, function () {
-      tabNS(tab).closed = true;
-      if (callback) callback();
-    });
-
-    closeTab(tabNS(this).tab);
-  },
-
-  /**
-   * Reload the tab
-   */
-  reload: function reload() {
-    tabNS(this).tab.browser.reload();
-  }
-});
-exports.Tab = Tab;
-
-// Implement `viewFor` polymorphic function for the Tab
-// instances.
-viewFor.define(Tab, x => tabNS(x).tab);
-
-function cleanupTab(tab) {
-  let tabInternals = tabNS(tab);
-  if (!tabInternals.tab)
-    return;
-
-  if (tabInternals.tab.browser) {
-    tabInternals.tab.browser.removeEventListener(EVENTS.ready.dom, tabInternals.onReady);
-    tabInternals.tab.browser.removeEventListener(EVENTS.pageshow.dom, tabInternals.onPageShow);
-    tabInternals.tab.browser.removeEventListener(EVENTS.load.dom, tabInternals.onLoad, true);
-  }
-  tabInternals.onReady = null;
-  tabInternals.onPageShow = null;
-  tabInternals.onLoad = null;
-  tabInternals.window.BrowserApp.deck.removeEventListener(EVENTS.close.dom, tabInternals.onClose);
-  tabInternals.onClose = null;
-  rawTabNS(tabInternals.tab).tab = null;
-  tabInternals.tab = null;
-  tabInternals.window = null;
-}
-
-function onTabReady(event) {
-  let win = event.target.defaultView;
-
-  // ignore frames
-  if (win === win.top) {
-    emit(this, 'ready', this);
-  }
-}
-
-function onTabLoad (event) {
-  let win = event.target.defaultView;
-
-  // ignore frames
-  if (win === win.top) {
-    emit(this, 'load', this);
-  }
-}
-
-function onTabPageShow(event) {
-  let win = event.target.defaultView;
-  if (win === win.top)
-    emit(this, 'pageshow', this, event.persisted);
-}
-
-// TabClose
-function onTabClose(event) {
-  let rawTab = getTabForBrowser(event.target);
-  if (tabNS(this).tab !== rawTab)
-    return;
-
-  emit(this, EVENTS.close.name, this);
-  cleanupTab(this);
-};
-
-isPrivate.implement(Tab, tab => {
-  return isWindowPrivate(getTabContentWindow(tabNS(tab).tab));
-});
-
-// Implement `modelFor` function for the Tab instances.
-modelFor.when(isTab, rawTab => {
-  return rawTabNS(rawTab).tab;
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/tabs/tab-firefox.js
+++ /dev/null
@@ -1,353 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-const { Class } = require('../core/heritage');
-const { observer } = require('./observer');
-const { observer: windowObserver } = require('../windows/observer');
-const { addListItem, removeListItem } = require('../util/list');
-const { viewFor } = require('../view/core');
-const { modelFor } = require('../model/core');
-const { emit, setListeners } = require('../event/core');
-const { EventTarget } = require('../event/target');
-const { getBrowserForTab, setTabURL, getTabId, getTabURL, getTabForBrowser,
-        getTabs, getTabTitle, setTabTitle, getIndex, closeTab, reload, move,
-        activateTab, pin, unpin, isTab } = require('./utils');
-const { isBrowser, getInnerId, isWindowPrivate } = require('../window/utils');
-const { getThumbnailURIForWindow, BLANK } = require("../content/thumbnail");
-const { when } = require('../system/unload');
-const { ignoreWindow, isPrivate } = require('../private-browsing/utils')
-const { defer } = require('../lang/functional');
-const { getURL } = require('../url/utils');
-const { frames, remoteRequire } = require('../remote/parent');
-remoteRequire('sdk/content/tab-events');
-
-const modelsFor = new WeakMap();
-const viewsFor = new WeakMap();
-const destroyed = new WeakMap();
-
-const tabEvents = {};
-exports.tabEvents = tabEvents;
-
-function browser(tab) {
-  return getBrowserForTab(viewsFor.get(tab));
-}
-
-function isDestroyed(tab) {
-  return destroyed.has(tab);
-}
-
-function isClosed(tab) {
-  if (!viewsFor.has(tab))
-    return true;
-  return viewsFor.get(tab).closing;
-}
-
-// private tab attribute where the remote cached value is stored
-const remoteReadyStateCached = Symbol("remoteReadyStateCached");
-
-const Tab = Class({
-  implements: [EventTarget],
-  initialize: function(tabElement, options = null) {
-    modelsFor.set(tabElement, this);
-    viewsFor.set(this, tabElement);
-
-    if (options) {
-      EventTarget.prototype.initialize.call(this, options);
-
-      if (options.isPinned)
-        this.pin();
-
-      // Note that activate is defered and so will run after any open event
-      // is sent out
-      if (!options.inBackground)
-        this.activate();
-    }
-
-    getURL.implement(this, tab => tab.url);
-    isPrivate.implement(this, tab => {
-      return isWindowPrivate(viewsFor.get(tab).ownerGlobal);
-    });
-  },
-
-  get id() {
-    return isDestroyed(this) ? undefined : getTabId(viewsFor.get(this));
-  },
-
-  get title() {
-    return isDestroyed(this) ? undefined : getTabTitle(viewsFor.get(this));
-  },
-
-  set title(val) {
-    if (isDestroyed(this))
-      return;
-
-    setTabTitle(viewsFor.get(this), val);
-  },
-
-  get url() {
-    return isDestroyed(this) ? undefined : getTabURL(viewsFor.get(this));
-  },
-
-  set url(val) {
-    if (isDestroyed(this))
-      return;
-
-    setTabURL(viewsFor.get(this), val);
-  },
-
-  get contentType() {
-    return isDestroyed(this) ? undefined : browser(this).documentContentType;
-  },
-
-  get index() {
-    return isDestroyed(this) ? undefined : getIndex(viewsFor.get(this));
-  },
-
-  set index(val) {
-    if (isDestroyed(this))
-      return;
-
-    move(viewsFor.get(this), val);
-  },
-
-  get isPinned() {
-    return isDestroyed(this) ? undefined : viewsFor.get(this).pinned;
-  },
-
-  get window() {
-    if (isClosed(this))
-      return undefined;
-
-    // TODO: Remove the dependency on the windows module, see bug 792670
-    require('../windows');
-    let tabElement = viewsFor.get(this);
-    let domWindow = tabElement.ownerGlobal;
-    return modelFor(domWindow);
-  },
-
-  get readyState() {
-    return isDestroyed(this) ? undefined : this[remoteReadyStateCached] || "uninitialized";
-  },
-
-  pin: function() {
-    if (isDestroyed(this))
-      return;
-
-    pin(viewsFor.get(this));
-  },
-
-  unpin: function() {
-    if (isDestroyed(this))
-      return;
-
-    unpin(viewsFor.get(this));
-  },
-
-  close: function(callback) {
-    let tabElement = viewsFor.get(this);
-
-    if (isDestroyed(this) || !tabElement || !tabElement.parentNode) {
-      if (callback)
-        callback();
-      return;
-    }
-
-    this.once('close', () => {
-      this.destroy();
-      if (callback)
-        callback();
-    });
-
-    closeTab(tabElement);
-  },
-
-  reload: function() {
-    if (isDestroyed(this))
-      return;
-
-    reload(viewsFor.get(this));
-  },
-
-  activate: defer(function() {
-    if (isDestroyed(this))
-      return;
-
-    activateTab(viewsFor.get(this));
-  }),
-
-  getThumbnail: function() {
-    if (isDestroyed(this))
-      return BLANK;
-
-    // TODO: This is unimplemented in e10s: bug 1148601
-    if (browser(this).isRemoteBrowser) {
-      console.error('This method is not supported with E10S');
-      return BLANK;
-    }
-    return getThumbnailURIForWindow(browser(this).contentWindow);
-  },
-
-  attach: function(options) {
-    if (isDestroyed(this))
-      return;
-
-    let { Worker } = require('../content/worker');
-    let { connect, makeChildOptions } = require('../content/utils');
-
-    let worker = Worker(options);
-    worker.once("detach", () => {
-      worker.destroy();
-    });
-
-    let attach = frame => {
-      let childOptions = makeChildOptions(options);
-      frame.port.emit("sdk/tab/attach", childOptions);
-      connect(worker, frame, { id: childOptions.id, url: this.url });
-    };
-
-    // Do this synchronously if possible
-    let frame = frames.getFrameForBrowser(browser(this));
-    if (frame) {
-      attach(frame);
-    }
-    else {
-      let listener = (frame) => {
-        if (frame.frameElement != browser(this))
-          return;
-
-        frames.off("attach", listener);
-        attach(frame);
-      };
-      frames.on("attach", listener);
-    }
-
-    return worker;
-  },
-
-  destroy: function() {
-    if (isDestroyed(this))
-      return;
-
-    destroyed.set(this, true);
-  }
-});
-exports.Tab = Tab;
-
-viewFor.define(Tab, tab => viewsFor.get(tab));
-
-// Returns the high-level window for this DOM window if the windows module has
-// ever been loaded otherwise returns null
-function maybeWindowFor(domWindow) {
-  try {
-    return modelFor(domWindow);
-  }
-  catch (e) {
-    return null;
-  }
-}
-
-function tabEmit(tab, event, ...args) {
-  // Don't emit events for destroyed tabs
-  if (isDestroyed(tab))
-    return;
-
-  // If the windows module was never loaded this will return null. We don't need
-  // to emit to the window.tabs object in this case as nothing can be listening.
-  let tabElement = viewsFor.get(tab);
-  let window = maybeWindowFor(tabElement.ownerGlobal);
-  if (window)
-    emit(window.tabs, event, tab, ...args);
-
-  emit(tabEvents, event, tab, ...args);
-  emit(tab, event, tab, ...args);
-}
-
-function windowClosed(domWindow) {
-  if (!isBrowser(domWindow))
-    return;
-
-  for (let tabElement of getTabs(domWindow)) {
-    tabEventListener("close", tabElement);
-  }
-}
-windowObserver.on('close', windowClosed);
-
-// Don't want to send close events after unloaded
-when(_ => {
-  windowObserver.off('close', windowClosed);
-});
-
-// Listen for tabbrowser events
-function tabEventListener(event, tabElement, ...args) {
-  let domWindow = tabElement.ownerGlobal;
-
-  if (ignoreWindow(domWindow))
-    return;
-
-  // Don't send events for tabs that are already closing
-  if (event != "close" && (tabElement.closing || !tabElement.parentNode))
-    return;
-
-  let tab = modelsFor.get(tabElement);
-  if (!tab)
-    tab = new Tab(tabElement);
-
-  let window = maybeWindowFor(domWindow);
-
-  if (event == "open") {
-    // Note, add to the window tabs first because if this is the first access to
-    // window.tabs it will be prefilling itself with everything from tabs
-    if (window)
-      addListItem(window.tabs, tab);
-    // The tabs module will take care of adding to its internal list
-  }
-  else if (event == "close") {
-    if (window)
-      removeListItem(window.tabs, tab);
-    // The tabs module will take care of removing from its internal list
-  }
-  else if (event == "init" || event == "create" || event == "ready" || event == "load") {
-    // Ignore load events from before browser windows have fully loaded, these
-    // are for about:blank in the initial tab
-    if (isBrowser(domWindow) && !domWindow.gBrowserInit.delayedStartupFinished)
-      return;
-
-    // update the cached remote readyState value
-    let { readyState } = args[0] || {};
-    tab[remoteReadyStateCached] = readyState;
-  }
-
-  if (event == "init") {
-    // Do not emit events for the detected existent tabs, we only need to cache
-    // their current document.readyState value.
-    return;
-  }
-
-  tabEmit(tab, event, ...args);
-
-  // The tab object shouldn't be reachable after closed
-  if (event == "close") {
-    viewsFor.delete(tab);
-    modelsFor.delete(tabElement);
-  }
-}
-observer.on('*', tabEventListener);
-
-// Listen for tab events from content
-frames.port.on('sdk/tab/event', (frame, event, ...args) => {
-  if (!frame.isTab)
-    return;
-
-  let tabElement = getTabForBrowser(frame.frameElement);
-  if (!tabElement)
-    return;
-
-  tabEventListener(event, tabElement, ...args);
-});
-
-// Implement `modelFor` function for the Tab instances..
-modelFor.when(isTab, view => {
-  return modelsFor.get(view);
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/tabs/tab.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-module.metadata = {
-  'stability': 'unstable'
-};
-
-const { getTargetWindow } = require("../content/mod");
-lazyRequire(this, "./utils", "getTabContentWindow", "isTab");
-lazyRequire(this, "../view/core", "viewFor");
-
-if (require('../system/xul-app').name == 'Fennec') {
-  module.exports = require('./tab-fennec');
-}
-else {
-  module.exports = require('./tab-firefox');
-}
-
-getTargetWindow.when(isTab, tab => getTabContentWindow(tab));
-
-getTargetWindow.when(x => x instanceof module.exports.Tab,
-  tab => getTabContentWindow(viewFor(tab)));
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/tabs/tabs-firefox.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-const { Class } = require('../core/heritage');
-const { Tab, tabEvents } = require('./tab');
-const { EventTarget } = require('../event/target');
-lazyRequire(this, '../event/core', "emit", "setListeners");
-const { pipe } = require('../event/utils');
-const { observer: windowObserver } = require('../windows/observer');
-const { List, addListItem, removeListItem } = require('../util/list');
-lazyRequire(this, '../model/core', "modelFor");
-lazyRequire(this, '../view/core', "viewFor");
-lazyRequire(this, './utils', "getTabs", "getSelectedTab");
-lazyRequire(this, '../window/utils', "getMostRecentBrowserWindow", "isBrowser");
-lazyRequire(this, './common', "Options");
-lazyRequire(this, '../private-browsing', "isPrivate");
-lazyRequire(this, '../private-browsing/utils', "ignoreWindow", "isWindowPBSupported")
-const { isPrivateBrowsingSupported } = require('sdk/self');
-
-const supportPrivateTabs = isPrivateBrowsingSupported && isWindowPBSupported;
-
-const Tabs = Class({
-  implements: [EventTarget],
-  extends: List,
-  initialize: function() {
-    List.prototype.initialize.call(this);
-
-    // We must do the list manipulation here where the object is extensible
-    this.on("open", tab => {
-      addListItem(this, tab);
-    });
-
-    this.on("close", tab => {
-      removeListItem(this, tab);
-    });
-  },
-
-  get activeTab() {
-    let activeDomWin = getMostRecentBrowserWindow();
-    if (!activeDomWin)
-      return null;
-    return modelFor(getSelectedTab(activeDomWin));
-  },
-
-  open: function(options) {
-    options = Options(options);
-
-    // TODO: Remove the dependency on the windows module: bug 792670
-    let windows = require('../windows').browserWindows;
-    let activeWindow = windows.activeWindow;
-
-    let privateState = supportPrivateTabs && options.isPrivate;
-    // When no isPrivate option was passed use the private state of the active
-    // window
-    if (activeWindow && privateState === undefined)
-      privateState = isPrivate(activeWindow);
-
-    function getWindow(privateState) {
-      for (let window of windows) {
-        if (privateState === isPrivate(window)) {
-          return window;
-        }
-      }
-      return null;
-    }
-
-    function openNewWindowWithTab() {
-      windows.open({
-        url: options.url,
-        isPrivate: privateState,
-        onOpen: function(newWindow) {
-          let tab = newWindow.tabs[0];
-          setListeners(tab, options);
-
-          if (options.isPinned)
-            tab.pin();
-
-          // We don't emit the open event for the first tab in a new window so
-          // do it now the listeners are attached
-          emit(tab, "open", tab);
-        }
-      });
-    }
-
-    if (options.inNewWindow)
-      return openNewWindowWithTab();
-
-    // if the active window is in the state that we need then use it
-    if (activeWindow && (privateState === isPrivate(activeWindow)))
-      return activeWindow.tabs.open(options);
-
-    // find a window in the state that we need
-    let window = getWindow(privateState);
-    if (window)
-      return window.tabs.open(options);
-
-    return openNewWindowWithTab();
-  }
-});
-
-const allTabs = new Tabs();
-module.exports = allTabs;
-pipe(tabEvents, allTabs);
-
-function addWindowTab(window, tabElement) {
-  let tab = new Tab(tabElement);
-  if (window)
-    addListItem(window.tabs, tab);
-  addListItem(allTabs, tab);
-  emit(allTabs, "open", tab);
-}
-
-// Find tabs in already open windows
-for (let tabElement of getTabs())
-  addWindowTab(null, tabElement);
-
-// Detect tabs in new windows
-windowObserver.on('open', domWindow => {
-  if (!isBrowser(domWindow) || ignoreWindow(domWindow))
-    return;
-
-  let window = null;
-  try {
-    modelFor(domWindow);
-  }
-  catch (e) { }
-
-  for (let tabElement of getTabs(domWindow)) {
-    addWindowTab(window, tabElement);
-  }
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/tabs/utils.js
+++ /dev/null
@@ -1,370 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-module.metadata = {
-  'stability': 'unstable'
-};
-
-
-// NOTE: This file should only deal with xul/native tabs
-
-
-const { Ci, Cu } = require('chrome');
-lazyRequire(this, "../lang/functional", "defer");
-lazyRequire(this, '../window/utils', "windows", "isBrowser");
-lazyRequire(this, '../self', "isPrivateBrowsingSupported");
-const { ShimWaiver } = Cu.import("resource://gre/modules/ShimWaiver.jsm");
-
-// Bug 834961: ignore private windows when they are not supported
-function getWindows() {
-  return windows(null, { includePrivate: isPrivateBrowsingSupported });
-}
-
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-
-// Define predicate functions that can be used to detech weather
-// we deal with fennec tabs or firefox tabs.
-
-// Predicate to detect whether tab is XUL "Tab" node.
-const isXULTab = tab =>
-  tab instanceof Ci.nsIDOMNode &&
-  tab.nodeName === "tab" &&
-  tab.namespaceURI === XUL_NS;
-exports.isXULTab = isXULTab;
-
-// Predicate to detecet whether given tab is a fettec tab.
-// Unfortunately we have to guess via duck typinng of:
-// http://mxr.mozilla.org/mozilla-central/source/mobile/android/chrome/content/browser.js#2583
-const isFennecTab = tab =>
-  tab &&
-  tab.QueryInterface &&
-  Ci.nsIBrowserTab &&
-  tab.QueryInterface(Ci.nsIBrowserTab) === tab;
-exports.isFennecTab = isFennecTab;
-
-const isTab = x => isXULTab(x) || isFennecTab(x);
-exports.isTab = isTab;
-
-function activateTab(tab, window) {
-  let gBrowser = getTabBrowserForTab(tab);
-
-  // normal case
-  if (gBrowser) {
-    gBrowser.selectedTab = tab;
-  }
-  // fennec ?
-  else if (window && window.BrowserApp) {
-    window.BrowserApp.selectTab(tab);
-  }
-  return null;
-}
-exports.activateTab = activateTab;
-
-function getTabBrowser(window) {
-  // bug 1009938 - may be null in SeaMonkey
-  return window.gBrowser || window.getBrowser();
-}
-exports.getTabBrowser = getTabBrowser;
-
-function getTabContainer(window) {
-  return getTabBrowser(window).tabContainer;
-}
-exports.getTabContainer = getTabContainer;
-
-/**
- * Returns the tabs for the `window` if given, or the tabs
- * across all the browser's windows otherwise.
- *
- * @param {nsIWindow} [window]
- *    A reference to a window
- *
- * @returns {Array} an array of Tab objects
- */
-function getTabs(window) {
-  if (arguments.length === 0) {
-    return getWindows().
-               filter(isBrowser).
-               reduce((tabs, window) => tabs.concat(getTabs(window)), []);
-  }
-
-  // fennec
-  if (window.BrowserApp)
-    return window.BrowserApp.tabs;
-
-  // firefox - default
-  return Array.filter(getTabContainer(window).children, t => !t.closing);
-}
-exports.getTabs = getTabs;
-
-function getActiveTab(window) {
-  return getSelectedTab(window);
-}
-exports.getActiveTab = getActiveTab;
-
-function getOwnerWindow(tab) {
-  // normal case
-  if (tab.ownerDocument)
-    return tab.ownerGlobal;
-
-  // try fennec case
-  return getWindowHoldingTab(tab);
-}
-exports.getOwnerWindow = getOwnerWindow;
-
-// fennec
-function getWindowHoldingTab(rawTab) {
-  for (let window of getWindows()) {
-    // this function may be called when not using fennec,
-    // but BrowserApp is only defined on Fennec
-    if (!window.BrowserApp)
-      continue;
-
-    for (let tab of window.BrowserApp.tabs) {
-      if (tab === rawTab)
-        return window;
-    }
-  }
-
-  return null;
-}
-
-function openTab(window, url, options) {
-  options = options || {};
-
-  // fennec?
-  if (window.BrowserApp) {
-    return window.BrowserApp.addTab(url, {
-      selected: options.inBackground ? false : true,
-      pinned: options.isPinned || false,
-      isPrivate: options.isPrivate || false,
-      parentId: window.BrowserApp.selectedTab.id
-    });
-  }
-
-  // firefox
-  let newTab = window.gBrowser.addTab(url);
-  if (!options.inBackground) {
-    activateTab(newTab);
-  }
-  return newTab;
-};
-exports.openTab = openTab;
-
-function isTabOpen(tab) {
-  // try normal case then fennec case
-  return !!((tab.linkedBrowser) || getWindowHoldingTab(tab));
-}
-exports.isTabOpen = isTabOpen;
-
-function closeTab(tab) {
-  let gBrowser = getTabBrowserForTab(tab);
-  // normal case?
-  if (gBrowser) {
-    // Bug 699450: the tab may already have been detached
-    if (!tab.parentNode)
-      return;
-    return gBrowser.removeTab(tab);
-  }
-
-  let window = getWindowHoldingTab(tab);
-  // fennec?
-  if (window && window.BrowserApp) {
-    // Bug 699450: the tab may already have been detached
-    if (!tab.browser)
-      return;
-    return window.BrowserApp.closeTab(tab);
-  }
-  return null;
-}
-exports.closeTab = closeTab;
-
-function getURI(tab) {
-  if (tab.browser) // fennec
-    return tab.browser.currentURI.spec;
-  return tab.linkedBrowser.currentURI.spec;
-}
-exports.getURI = getURI;
-
-function getTabBrowserForTab(tab) {
-  let outerWin = getOwnerWindow(tab);
-  if (outerWin)
-    return getOwnerWindow(tab).gBrowser;
-  return null;
-}
-exports.getTabBrowserForTab = getTabBrowserForTab;
-
-function getBrowserForTab(tab) {
-  if (tab.browser) // fennec
-    return tab.browser;
-
-  return tab.linkedBrowser;
-}
-exports.getBrowserForTab = getBrowserForTab;
-
-function getTabId(tab) {
-  if (tab.browser) // fennec
-    return tab.id
-
-  return String(tab.linkedPanel).split('panel').pop();
-}
-exports.getTabId = getTabId;
-
-function getTabForId(id) {
-  return getTabs().find(tab => getTabId(tab) === id) || null;
-}
-exports.getTabForId = getTabForId;
-
-function getTabTitle(tab) {
-  return getBrowserForTab(tab).contentTitle || tab.label || "";
-}
-exports.getTabTitle = getTabTitle;
-
-function setTabTitle(tab, title) {
-  title = String(title);
-  if (tab.browser) {
-    // Fennec
-    tab.browser.contentDocument.title = title;
-  }
-  else {
-    let browser = getBrowserForTab(tab);
-    // Note that we aren't actually setting the document title in e10s, just
-    // the title the browser thinks the content has
-    if (browser.isRemoteBrowser)
-      browser._contentTitle = title;
-    else
-      browser.contentDocument.title = title;
-  }
-  tab.label = String(title);
-}
-exports.setTabTitle = setTabTitle;
-
-function getTabContentDocument(tab) {
-  return getBrowserForTab(tab).contentDocument;
-}
-exports.getTabContentDocument = getTabContentDocument;
-
-function getTabContentWindow(tab) {
-  return getBrowserForTab(tab).contentWindow;
-}
-exports.getTabContentWindow = getTabContentWindow;
-
-/**
- * Returns all tabs' content windows across all the browsers' windows
- */
-function getAllTabContentWindows() {
-  return getTabs().map(getTabContentWindow);
-}
-exports.getAllTabContentWindows = getAllTabContentWindows;
-
-// gets the tab containing the provided window
-function getTabForContentWindow(window) {
-  return getTabs().find(tab => getTabContentWindow(tab) === window.top) || null;
-}
-exports.getTabForContentWindow = getTabForContentWindow;
-
-// only sdk/selection.js is relying on shims
-function getTabForContentWindowNoShim(window) {
-  function getTabContentWindowNoShim(tab) {
-    let browser = getBrowserForTab(tab);
-    return ShimWaiver.getProperty(browser, "contentWindow");
-  }
-  return getTabs().find(tab => getTabContentWindowNoShim(tab) === window.top) || null;
-}
-exports.getTabForContentWindowNoShim = getTabForContentWindowNoShim;
-
-function getTabURL(tab) {
-  return String(getBrowserForTab(tab).currentURI.spec);
-}
-exports.getTabURL = getTabURL;
-
-function setTabURL(tab, url) {
-  let browser = getBrowserForTab(tab);
-  browser.loadURI(String(url));
-}
-// "TabOpen" event is fired when it's still "about:blank" is loaded in the
-// changing `location` property of the `contentDocument` has no effect since
-// seems to be either ignored or overridden by internal listener, there for
-// location change is enqueued for the next turn of event loop.
-exports.setTabURL = defer(setTabURL);
-
-function getTabContentType(tab) {
-  return getBrowserForTab(tab).contentDocument.contentType;
-}
-exports.getTabContentType = getTabContentType;
-
-function getSelectedTab(window) {
-  if (window.BrowserApp) // fennec?
-    return window.BrowserApp.selectedTab;
-  if (window.gBrowser)
-    return window.gBrowser.selectedTab;
-  return null;
-}
-exports.getSelectedTab = getSelectedTab;
-
-
-function getTabForBrowser(browser) {
-  for (let window of getWindows()) {
-    // this function may be called when not using fennec
-    if (!window.BrowserApp)
-      continue;
-
-    for  (let tab of window.BrowserApp.tabs) {
-      if (tab.browser === browser)
-        return tab;
-    }
-  }
-
-  let tabbrowser = browser.getTabBrowser && browser.getTabBrowser()
-  return !!tabbrowser && tabbrowser.getTabForBrowser(browser);
-}
-exports.getTabForBrowser = getTabForBrowser;
-
-function pin(tab) {
-  let gBrowser = getTabBrowserForTab(tab);
-  // TODO: Implement Fennec support
-  if (gBrowser) gBrowser.pinTab(tab);
-}
-exports.pin = pin;
-
-function unpin(tab) {
-  let gBrowser = getTabBrowserForTab(tab);
-  // TODO: Implement Fennec support
-  if (gBrowser) gBrowser.unpinTab(tab);
-}
-exports.unpin = unpin;
-
-function isPinned(tab) {
-  return !!tab.pinned;
-}
-exports.isPinned = isPinned;
-
-function reload(tab) {
-  getBrowserForTab(tab).reload();
-}
-exports.reload = reload
-
-function getIndex(tab) {
-  let gBrowser = getTabBrowserForTab(tab);
-  // Firefox
-  if (gBrowser) {
-    return tab._tPos;
-  }
-  // Fennec
-  else {
-    let window = getWindowHoldingTab(tab)
-    let tabs = window.BrowserApp.tabs;
-    for (let i = tabs.length; i >= 0; i--)
-      if (tabs[i] === tab) return i;
-  }
-}
-exports.getIndex = getIndex;
-
-function move(tab, index) {
-  let gBrowser = getTabBrowserForTab(tab);
-  // Firefox
-  if (gBrowser) gBrowser.moveTabTo(tab, index);
-  // TODO: Implement fennec support
-}
-exports.move = move;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/tabs/worker.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-const ContentWorker = require('../content/worker').Worker;
-
-function Worker(options, window) {
-  options.window = window;
-
-  let worker = ContentWorker(options);
-  worker.once("detach", function detach() {
-    worker.destroy();
-  });
-  return worker;
-}
-exports.Worker = Worker;
\ No newline at end of file
--- a/addon-sdk/source/lib/sdk/test/utils.js
+++ b/addon-sdk/source/lib/sdk/test/utils.js
@@ -178,22 +178,15 @@ function waitUntil (predicate, delay) {
   }, delay || 10);
   return promise;
 }
 exports.waitUntil = waitUntil;
 
 var cleanUI = function cleanUI() {
   let { promise, resolve } = defer();
 
-  let windows = getWindows(null, { includePrivate: true });
-  if (windows.length > 1) {
-    return closeWindow(windows[1]).then(cleanUI);
-  }
-
-  getTabs(windows[0]).slice(1).forEach(closeTab);
-
   resolve();
 
   return promise;
 }
 exports.cleanUI = cleanUI;
 
 exports.isTravisCI = ("TRAVIS" in env && "CI" in env);
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/window/browser.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-const { Class } = require('../core/heritage');
-const { windowNS } = require('./namespace');
-const { on, off, once } = require('../event/core');
-const { method } = require('../lang/functional');
-const { getWindowTitle } = require('./utils');
-const unload = require('../system/unload');
-const { EventTarget } = require('../event/target');
-const { isPrivate } = require('../private-browsing/utils');
-const { isWindowPrivate, isFocused } = require('../window/utils');
-const { viewFor } = require('../view/core');
-
-const ERR_FENNEC_MSG = 'This method is not yet supported by Fennec, consider using require("sdk/tabs") instead';
-
-const BrowserWindow = Class({
-  initialize: function initialize(options) {
-    EventTarget.prototype.initialize.call(this, options);
-    windowNS(this).window = options.window;
-  },
-  activate: function activate() {
-    // TODO
-    return null;
-  },
-  close: function() {
-    throw new Error(ERR_FENNEC_MSG);
-    return null;
-  },
-  get title() {
-    return getWindowTitle(windowNS(this).window);
-  },
-  // NOTE: Fennec only has one window, which is assumed below
-  // TODO: remove assumption below
-  // NOTE: tabs requires windows
-  get tabs() {
-    return require('../tabs');
-  },
-  get activeTab() {
-    return require('../tabs').activeTab;
-  },
-  on: method(on),
-  removeListener: method(off),
-  once: method(once)
-});
-exports.BrowserWindow = BrowserWindow;
-
-const getWindowView = window => windowNS(window).window;
-
-viewFor.define(BrowserWindow, getWindowView);
-isPrivate.define(BrowserWindow, (window) => isWindowPrivate(viewFor(window).window));
-isFocused.define(BrowserWindow, (window) => isFocused(viewFor(window).window));
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/window/events.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-const { Ci, Cu } = require("chrome");
-const { observe } = require("../event/chrome");
-const { open } = require("../event/dom");
-const { windows } = require("../window/utils");
-const { filter, merge, map, expand } = require("../event/utils");
-
-function documentMatches(weakWindow, event) {
-  let window = weakWindow.get();
-  return window && event.target === window.document;
-}
-
-function makeStrictDocumentFilter(window) {
-  // Note: Do not define a closure within this function.  Otherwise
-  //       you may leak the window argument.
-  let weak = Cu.getWeakReference(window);
-  return documentMatches.bind(null, weak);
-}
-
-function toEventWithDefaultViewTarget({type, target}) {
-  return { type: type, target: target.defaultView }
-}
-
-// Function registers single shot event listeners for relevant window events
-// that forward events to exported event stream.
-function eventsFor(window) {
-  // NOTE: Do no use pass a closure from this function into a stream
-  //       transform function.  You will capture the window in the
-  //       closure and leak the window until the event stream is
-  //       completely closed.
-  let interactive = open(window, "DOMContentLoaded", { capture: true });
-  let complete = open(window, "load", { capture: true });
-  let states = merge([interactive, complete]);
-  let changes = filter(states, makeStrictDocumentFilter(window));
-  return map(changes, toEventWithDefaultViewTarget);
-}
-
-// Create our event channels.  We do this in a separate function to
-// minimize the chance of leaking intermediate objects on the global.
-function makeEvents() {
-  // In addition to observing windows that are open we also observe windows
-  // that are already already opened in case they're in process of loading.
-  var opened = windows(null, { includePrivate: true });
-  var currentEvents = merge(opened.map(eventsFor));
-
-  // Register system event listeners for top level window open / close.
-  function rename({type, target, data}) {
-    return { type: rename[type], target: target, data: data }
-  }
-  rename.domwindowopened = "open";
-  rename.domwindowclosed = "close";
-
-  var openEvents = map(observe("domwindowopened"), rename);
-  var closeEvents = map(observe("domwindowclosed"), rename);
-  var futureEvents = expand(openEvents, ({target}) => eventsFor(target));
-
-  return merge([currentEvents, futureEvents, openEvents, closeEvents]);
-}
-
-exports.events = makeEvents();
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/window/helpers.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-const { defer, all } = require('../core/promise');
-const events = require('../system/events');
-const { open: openWindow, onFocus, getToplevelWindow,
-        isInteractive, isStartupFinished, getOuterId } = require('./utils');
-const { Ci } = require("chrome");
-
-function open(uri, options) {
-  return promise(openWindow.apply(null, arguments), 'load').then(focus);
-}
-exports.open = open;
-
-function close(window) {
-  let deferred = defer();
-  let toplevelWindow = getToplevelWindow(window);
-  let outerId = getOuterId(toplevelWindow);
-  events.on("outer-window-destroyed", function onclose({subject}) {
-    let id = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
-    if (id == outerId) {
-      events.off("outer-window-destroyed", onclose);
-      deferred.resolve();
-    }
-  }, true);
-  window.close();
-  return deferred.promise;
-}
-exports.close = close;
-
-function focus(window) {
-  let p = onFocus(window);
-  window.focus();
-  return p;
-}
-exports.focus = focus;
-
-function ready(window) {
-  let { promise: result, resolve } = defer();
-
-  if (isInteractive(window))
-    resolve(window);
-  else
-    resolve(promise(window, 'DOMContentLoaded'));
-
-  return result;
-}
-exports.ready = ready;
-
-function startup(window) {
-  let { promise: result, resolve } = defer();
-
-  if (isStartupFinished(window)) {
-    resolve(window);
-  } else {
-    events.on("browser-delayed-startup-finished", function listener({subject}) {
-      if (subject === window) {
-        events.off("browser-delayed-startup-finished", listener);
-        resolve(window);
-      }
-    });
-  }
-
-  return result;
-}
-exports.startup = startup;
-
-function promise(target, evt, capture) {
-  let deferred = defer();
-  capture = !!capture;
-
-  target.addEventListener(evt, function() {
-    deferred.resolve(target);
-  }, {capture, once: true});
-
-  return deferred.promise;
-}
-exports.promise = promise;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/window/namespace.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-exports.windowNS = require('../core/namespace').ns();
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/windows.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-module.metadata = {
-  'stability': 'stable'
-};
-
-const { isBrowser } = require('./window/utils');
-const { modelFor } = require('./model/core');
-const { viewFor } = require('./view/core');
-
-
-if (require('./system/xul-app').is('Fennec')) {
-  module.exports = require('./windows/fennec');
-}
-else {
-  module.exports = require('./windows/firefox');
-}
-
-
-const browsers = module.exports.browserWindows;
-
-//
-modelFor.when(isBrowser, view => {
-  for (let model of browsers) {
-    if (viewFor(model) === view)
-      return model;
-  }
-  return null;
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/windows/fennec.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-const { Class } = require('../core/heritage');
-const { BrowserWindow } = require('../window/browser');
-const { WindowTracker } = require('../deprecated/window-utils');
-const { isBrowser, getMostRecentBrowserWindow } = require('../window/utils');
-const { windowNS } = require('../window/namespace');
-const { on, off, once, emit } = require('../event/core');
-const { method } = require('../lang/functional');
-const { EventTarget } = require('../event/target');
-const { List, addListItem } = require('../util/list');
-
-const ERR_FENNEC_MSG = 'This method is not yet supported by Fennec, consider using require("sdk/tabs") instead';
-
-// NOTE: On Fennec there is only one window.
-
-var BrowserWindows = Class({
-  implements: [ List ],
-  extends: EventTarget,
-  initialize: function() {
-    List.prototype.initialize.apply(this);
-  },
-  get activeWindow() {
-    let window = getMostRecentBrowserWindow();
-    return window ? getBrowserWindow({window: window}) : null;
-  },
-  open: function open(options) {
-    throw new Error(ERR_FENNEC_MSG);
-    return null;
-  }
-});
-const browserWindows = exports.browserWindows = BrowserWindows();
-
-
-/**
- * Gets a `BrowserWindow` for the given `chromeWindow` if previously
- * registered, `null` otherwise.
- */
-function getRegisteredWindow(chromeWindow) {
-  for (let window of browserWindows) {
-    if (chromeWindow === windowNS(window).window)
-      return window;
-  }
-
-  return null;
-}
-
-/**
- * Gets a `BrowserWindow` for the provided window options obj
- * @params {Object} options
- *    Options that are passed to the the `BrowserWindow`
- * @returns {BrowserWindow}
- */
-function getBrowserWindow(options) {
-  let window = null;
-
-  // if we have a BrowserWindow already then use it
-  if ('window' in options)
-    window = getRegisteredWindow(options.window);
-  if (window)
-    return window;
-
-  // we don't have a BrowserWindow yet, so create one
-  window = BrowserWindow(options);
-  addListItem(browserWindows, window);
-  return window;
-}
-
-WindowTracker({
-  onTrack: function onTrack(chromeWindow) {
-    if (!isBrowser(chromeWindow)) return;
-    let window = getBrowserWindow({ window: chromeWindow });
-    emit(browserWindows, 'open', window);
-  },
-  onUntrack: function onUntrack(chromeWindow) {
-    if (!isBrowser(chromeWindow)) return;
-    let window = getBrowserWindow({ window: chromeWindow });
-    emit(browserWindows, 'close', window);
-  }
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/windows/firefox.js
+++ /dev/null
@@ -1,224 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-const { Class } = require('../core/heritage');
-const { observer } = require('./observer');
-const { isBrowser, getMostRecentBrowserWindow, windows, open, getInnerId,
-        getWindowTitle, getToplevelWindow, isFocused, isWindowPrivate } = require('../window/utils');
-const { List, addListItem, removeListItem } = require('../util/list');
-const { viewFor } = require('../view/core');
-const { modelFor } = require('../model/core');
-const { emit, emitOnObject, setListeners } = require('../event/core');
-const { once } = require('../dom/events');
-const { EventTarget } = require('../event/target');
-const { getSelectedTab } = require('../tabs/utils');
-const { Cc, Ci } = require('chrome');
-const { Options } = require('../tabs/common');
-const system = require('../system/events');
-const { ignoreWindow, isPrivate, isWindowPBSupported } = require('../private-browsing/utils');
-const { data, isPrivateBrowsingSupported } = require('../self');
-const { setImmediate } = require('../timers');
-
-const supportPrivateWindows = isPrivateBrowsingSupported && isWindowPBSupported;
-
-const modelsFor = new WeakMap();
-const viewsFor = new WeakMap();
-
-const Window = Class({
-  implements: [EventTarget],
-  initialize: function(domWindow) {
-    modelsFor.set(domWindow, this);
-    viewsFor.set(this, domWindow);
-  },
-
-  get title() {
-    return getWindowTitle(viewsFor.get(this));
-  },
-
-  activate: function() {
-    viewsFor.get(this).focus();
-  },
-
-  close: function(callback) {
-    let domWindow = viewsFor.get(this);
-
-    if (callback) {
-      // We want to catch the close event immediately after the close events are
-      // emitted everywhere but without letting the event loop spin. Registering
-      // for the same events as windowEventListener but afterwards does this
-      let listener = (event, closedWin) => {
-        if (event != "close" || closedWin != domWindow)
-          return;
-
-        observer.off("*", listener);
-        callback();
-      }
-
-      observer.on("*", listener);
-    }
-
-    domWindow.close();
-  }
-});
-
-const windowTabs = new WeakMap();
-
-const BrowserWindow = Class({
-  extends: Window,
-
-  get tabs() {
-    let tabs = windowTabs.get(this);
-    if (tabs)
-      return tabs;
-
-    return new WindowTabs(this);
-  }
-});
-
-const WindowTabs = Class({
-  implements: [EventTarget],
-  extends: List,
-  initialize: function(window) {
-    List.prototype.initialize.call(this);
-    windowTabs.set(window, this);
-    viewsFor.set(this, viewsFor.get(window));
-
-    // Make sure the tabs module has loaded and found all existing tabs
-    const tabs = require('../tabs');
-
-    for (let tab of tabs) {
-      if (tab.window == window)
-        addListItem(this, tab);
-    }
-  },
-
-  get activeTab() {
-    return modelFor(getSelectedTab(viewsFor.get(this)));
-  },
-
-  open: function(options) {
-    options = Options(options);
-
-    let domWindow = viewsFor.get(this);
-    let { Tab } = require('../tabs/tab-firefox');
-
-    // The capturing listener will see the TabOpen event before
-    // sdk/tabs/observer giving us time to set up the tab and listeners before
-    // the real open event is fired
-    let listener = event => {
-      new Tab(event.target, options);
-    };
-
-    once(domWindow, "TabOpen", listener, true);
-    domWindow.gBrowser.addTab(options.url);
-  }
-});
-
-const BrowserWindows = Class({
-  implements: [EventTarget],
-  extends: List,
-  initialize: function() {
-    List.prototype.initialize.call(this);
-  },
-
-  get activeWindow() {
-    let domWindow = getMostRecentBrowserWindow();
-    if (ignoreWindow(domWindow))
-      return null;
-    return modelsFor.get(domWindow);
-  },
-
-  open: function(options) {
-    if (typeof options == "string")
-      options = { url: options };
-
-    let { url, isPrivate } = options;
-    if (url)
-      url = data.url(url);
-
-    let args = Cc["@mozilla.org/supports-string;1"].
-               createInstance(Ci.nsISupportsString);
-    args.data = url;
-
-    let features = {
-      chrome: true,
-      all: true,
-      dialog: false
-    };
-    features.private = supportPrivateWindows && isPrivate;
-
-    let domWindow = open(null, {
-      parent: null,
-      name: "_blank",
-      features,
-      args
-    })
-
-    let window = makeNewWindow(domWindow, true);
-    setListeners(window, options);
-    return window;
-  }
-});
-
-const browserWindows = new BrowserWindows();
-exports.browserWindows = browserWindows;
-
-function windowEmit(window, event, ...args) {
-  if (window instanceof BrowserWindow && (event == "open" || event == "close"))
-    emitOnObject(window, event, browserWindows, window, ...args);
-  else
-    emit(window, event, window, ...args);
-
-  if (window instanceof BrowserWindow)
-    emit(browserWindows, event, window, ...args);
-}
-
-function makeNewWindow(domWindow, browserHint = false) {
-  if (browserHint || isBrowser(domWindow))
-    return new BrowserWindow(domWindow);
-  else
-    return new Window(domWindow);
-}
-
-for (let domWindow of windows(null, {includePrivate: supportPrivateWindows})) {
-  let window = makeNewWindow(domWindow);
-  if (window instanceof BrowserWindow)
-    addListItem(browserWindows, window);
-}
-
-var windowEventListener = (event, domWindow, ...args) => {
-  let toplevelWindow = getToplevelWindow(domWindow);
-
-  if (ignoreWindow(toplevelWindow))
-    return;
-
-  let window = modelsFor.get(toplevelWindow);
-  if (!window)
-    window = makeNewWindow(toplevelWindow);
-
-  if (isBrowser(toplevelWindow)) {
-    if (event == "open")
-      addListItem(browserWindows, window);
-    else if (event == "close")
-      removeListItem(browserWindows, window);
-  }
-
-  windowEmit(window, event, ...args);
-
-  // The window object shouldn't be reachable after closed
-  if (event == "close") {
-    viewsFor.delete(window);
-    modelsFor.delete(toplevelWindow);
-  }
-};
-observer.on("*", windowEventListener);
-
-viewFor.define(BrowserWindow, window => {
-  return viewsFor.get(window);
-})
-
-const isBrowserWindow = (x) => x instanceof BrowserWindow;
-isPrivate.when(isBrowserWindow, (w) => isWindowPrivate(viewsFor.get(w)));
-isFocused.when(isBrowserWindow, (w) => isFocused(viewsFor.get(w)));
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/windows/observer.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-const { EventTarget } = require("../event/target");
-const { emit } = require("../event/core");
-const { WindowTracker, windowIterator } = require("../deprecated/window-utils");
-const { DOMEventAssembler } = require("../deprecated/events/assembler");
-const { Class } = require("../core/heritage");
-const { Cu } = require("chrome");
-
-// Event emitter objects used to register listeners and emit events on them
-// when they occur.
-const Observer = Class({
-  initialize() {
-    // Using `WindowTracker` to track window events.
-    WindowTracker({
-      onTrack: chromeWindow => {
-        emit(this, "open", chromeWindow);
-        this.observe(chromeWindow);
-      },
-      onUntrack: chromeWindow => {
-        emit(this, "close", chromeWindow);
-        this.ignore(chromeWindow);
-      }
-    });
-  },
-  implements: [EventTarget, DOMEventAssembler],
-  /**
-   * Events that are supported and emitted by the module.
-   */
-  supportedEventsTypes: [ "activate", "deactivate" ],
-  /**
-   * Function handles all the supported events on all the windows that are
-   * observed. Method is used to proxy events to the listeners registered on
-   * this event emitter.
-   * @param {Event} event
-   *    Keyboard event being emitted.
-   */
-  handleEvent(event) {
-    // Ignore events from windows in the child process as they can't be top-level
-    if (Cu.isCrossProcessWrapper(event.target))
-      return;
-    emit(this, event.type, event.target, event);
-  }
-});
-
-exports.observer = new Observer();
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/windows/tabs-fennec.js
+++ /dev/null
@@ -1,172 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-const { Class } = require('../core/heritage');
-const { Tab } = require('../tabs/tab');
-const { browserWindows } = require('./fennec');
-const { windowNS } = require('../window/namespace');
-const { tabsNS, tabNS } = require('../tabs/namespace');
-const { openTab, getTabs, getSelectedTab, getTabForBrowser: getRawTabForBrowser,
-        getTabContentWindow } = require('../tabs/utils');
-const { Options } = require('../tabs/common');
-const { getTabForBrowser, getTabForRawTab } = require('../tabs/helpers');
-const { on, once, off, emit } = require('../event/core');
-const { method } = require('../lang/functional');
-const { EVENTS } = require('../tabs/events');
-const { EventTarget } = require('../event/target');
-const { when: unload } = require('../system/unload');
-const { windowIterator } = require('../deprecated/window-utils');
-const { List, addListItem, removeListItem } = require('../util/list');
-const { isPrivateBrowsingSupported, data } = require('../self');
-const { isTabPBSupported, ignoreWindow } = require('../private-browsing/utils');
-
-const mainWindow = windowNS(browserWindows.activeWindow).window;
-
-const ERR_FENNEC_MSG = 'This method is not yet supported by Fennec';
-
-const supportPrivateTabs = isPrivateBrowsingSupported && isTabPBSupported;
-
-const Tabs = Class({
-  implements: [ List ],
-  extends: EventTarget,
-  initialize: function initialize(options) {
-    let tabsInternals = tabsNS(this);
-    let window = tabsNS(this).window = options.window || mainWindow;
-
-    EventTarget.prototype.initialize.call(this, options);
-    List.prototype.initialize.apply(this, getTabs(window).map(Tab));
-
-    // TabOpen event
-    window.BrowserApp.deck.addEventListener(EVENTS.open.dom, onTabOpen);
-
-    // TabSelect
-    window.BrowserApp.deck.addEventListener(EVENTS.activate.dom, onTabSelect);
-  },
-  get activeTab() {
-    return getTabForRawTab(getSelectedTab(tabsNS(this).window));
-  },
-  open: function(options) {
-    options = Options(options);
-    let activeWin = browserWindows.activeWindow;
-
-    if (options.isPinned) {
-      console.error(ERR_FENNEC_MSG); // TODO
-    }
-
-    let url = options.url ? data.url(options.url) : options.url;
-    let rawTab = openTab(windowNS(activeWin).window, url, {
-      inBackground: options.inBackground,
-      isPrivate: supportPrivateTabs && options.isPrivate
-    });
-
-    // by now the tab has been created
-    let tab = getTabForRawTab(rawTab);
-
-    if (options.onClose)
-      tab.on('close', options.onClose);
-
-    if (options.onOpen) {
-      // NOTE: on Fennec this will be true
-      if (tabNS(tab).opened)
-        options.onOpen(tab);
-
-      tab.on('open', options.onOpen);
-    }
-
-    if (options.onReady)
-      tab.on('ready', options.onReady);
-
-    if (options.onLoad)
-      tab.on('load', options.onLoad);
-
-    if (options.onPageShow)
-      tab.on('pageshow', options.onPageShow);
-
-    if (options.onActivate)
-      tab.on('activate', options.onActivate);
-
-    return tab;
-  }
-});
-var gTabs = exports.tabs = Tabs(mainWindow);
-
-function tabsUnloader(event, window) {
-  window = window || (event && event.target);
-  if (!(window && window.BrowserApp))
-    return;
-  window.BrowserApp.deck.removeEventListener(EVENTS.open.dom, onTabOpen);
-  window.BrowserApp.deck.removeEventListener(EVENTS.activate.dom, onTabSelect);
-}
-
-// unload handler
-unload(function() {
-  for (let window in windowIterator()) {
-    tabsUnloader(null, window);
-  }
-});
-
-function addTab(tab) {
-  addListItem(gTabs, tab);
-  return tab;
-}
-
-function removeTab(tab) {
-  removeListItem(gTabs, tab);
-  return tab;
-}
-
-// TabOpen
-function onTabOpen(event) {
-  let browser = event.target;
-
-  // Eventually ignore private tabs
-  if (ignoreWindow(browser.contentWindow))
-    return;
-
-  let tab = getTabForBrowser(browser);
-  if (tab === null) {
-    let rawTab = getRawTabForBrowser(browser);
-
-    // create a Tab instance for this new tab
-    tab = addTab(Tab(rawTab));
-  }
-
-  tabNS(tab).opened = true;
-
-  tab.on('ready', () => emit(gTabs, 'ready', tab));
-  tab.once('close', onTabClose);
-
-  tab.on('pageshow', (_tab, persisted) =>
-    emit(gTabs, 'pageshow', tab, persisted));
-
-  emit(tab, 'open', tab);
-  emit(gTabs, 'open', tab);
-}
-
-// TabSelect
-function onTabSelect(event) {
-  let browser = event.target;
-
-  // Eventually ignore private tabs
-  if (ignoreWindow(browser.contentWindow))
-    return;
-
-  // Set value whenever new tab becomes active.
-  let tab = getTabForBrowser(browser);
-  emit(tab, 'activate', tab);
-  emit(gTabs, 'activate', tab);
-
-  for (let t of gTabs) {
-    if (t === tab) continue;
-    emit(t, 'deactivate', t);
-    emit(gTabs, 'deactivate', t);
-  }
-}
-
-// TabClose
-function onTabClose(tab) {
-  removeTab(tab);
-  emit(gTabs, EVENTS.close.name, tab);
-}
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/worker/utils.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-'use strict';
-
-module.metadata = {
-  'stability': 'deprecated'
-};
-
-const {
-  requiresAddonGlobal, attach, detach, destroy, WorkerHost
-} = require('../content/utils');
-
-exports.WorkerHost = WorkerHost;
-exports.detach = detach;
-exports.attach = attach;
-exports.destroy = destroy;
-exports.requiresAddonGlobal = requiresAddonGlobal;