Merge inbound to m-c. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 18 Nov 2016 15:47:05 -0500
changeset 323310 f09e137ead39230eaa94f47988ccce2cfcda4195
parent 323292 46f55e7e305aeff69657cab5fdba3d6f1996d2d8 (current diff)
parent 323309 1a66e7113e83e8dbb93bfb00eb5187a76feaaf6d (diff)
child 323311 c28e425db394e9aad04d30cb383944122acce57a
child 323332 8f35042c7b486df48987eecd37c1bd4b5fa5367a
child 323478 4fefdb64d28ff835ad24def74ec09f360a3263c0
push id30973
push userryanvm@gmail.com
push dateFri, 18 Nov 2016 20:47:14 +0000
treeherdermozilla-central@f09e137ead39 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone53.0a1
first release with
nightly linux32
f09e137ead39 / 53.0a1 / 20161119030204 / files
nightly linux64
f09e137ead39 / 53.0a1 / 20161119030204 / files
nightly mac
f09e137ead39 / 53.0a1 / 20161119030204 / files
nightly win32
f09e137ead39 / 53.0a1 / 20161119030204 / files
nightly win64
f09e137ead39 / 53.0a1 / 20161119030204 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to m-c. a=merge
b2g/components/UpdatePrompt.js
config/external/nss/Makefile.in
config/external/nss/crmf/moz.build
config/external/nss/moz.build
config/external/nss/nss.mk
config/external/nss/nss.symbols
devtools/client/webide/content/permissionstable.js
devtools/client/webide/content/permissionstable.xhtml
devtools/client/webide/test/test_device_permissions.html
devtools/client/webide/themes/permissionstable.css
dom/apps/PermissionsTable.jsm
dom/apps/moz.build
dom/apps/tests/create_test_receipts.py
dom/apps/tests/head.js
dom/permission/tests/file_framework.js
dom/permission/tests/file_shim.html
dom/permission/tests/mochitest-time.ini
dom/permission/tests/test_browser.html
dom/permission/tests/test_idle.html
dom/permission/tests/test_input-manage.html
dom/permission/tests/test_keyboard.html
dom/permission/tests/test_networkstats-manage.html
dom/permission/tests/test_power.html
dom/permission/tests/test_presentation-device-manage.html
dom/permission/tests/test_systemXHR.html
dom/permission/tests/test_tcp-socket.html
dom/permission/tests/test_time.html
dom/permission/tests/test_udp-socket.html
dom/permission/tests/unit/test_bug808734.js
dom/permission/tests/unit/xpcshell.ini
dom/system/SystemUpdate.manifest
dom/system/SystemUpdateManager.js
dom/system/SystemUpdateService.jsm
dom/system/nsISystemUpdateProvider.idl
dom/system/tests/preload-SystemUpdateManager-jsm.js
dom/system/tests/test_system_update_enabled.html
dom/webidl/SystemUpdate.webidl
js/src/tests/Intl/Collator/construct-newtarget.js
js/src/tests/Intl/DateTimeFormat/construct-newtarget.js
js/src/tests/Intl/NumberFormat/construct-newtarget.js
js/src/tests/ecma_2017/AsyncFunctions/construct-newtarget.js
js/src/tests/ecma_2017/AsyncFunctions/subclass.js
js/src/tests/ecma_6/Generators/construct-newtarget.js
js/src/tests/ecma_6/Generators/subclass.js
modules/libpref/init/all.js
old-configure.in
--- a/addon-sdk/source/lib/dev/volcan.js
+++ b/addon-sdk/source/lib/dev/volcan.js
@@ -3291,27 +3291,16 @@ module.exports={
           "request": {
             "type": "screenshotToDataURL"
           },
           "response": {
             "value": {
               "_retval": "longstring"
             }
           }
-        },
-        {
-          "name": "getRawPermissionsTable",
-          "request": {
-            "type": "getRawPermissionsTable"
-          },
-          "response": {
-            "value": {
-              "_retval": "json"
-            }
-          }
         }
       ],
       "events": {}
     }
   },
   "from": "root"
 }
 
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -495,19 +495,16 @@ pref("app.update.socket.retryTimeout", 3
 // Max of 20 consecutive retries (total 10 minutes) before giving up and marking
 // the update download as failed.
 // Note: Offline errors will always retry when the network comes online.
 pref("app.update.socket.maxErrors", 20);
 
 // Enable update logging for now, to diagnose growing pains in the
 // field.
 pref("app.update.log", true);
-
-// SystemUpdate API
-pref("dom.system_update.active", "@mozilla.org/updates/update-prompt;1");
 #else
 // Explicitly disable the shutdown watchdog.  It's enabled by default.
 // When the updater is disabled, we want to know about shutdown hangs.
 pref("shutdown.watchdog.timeoutSecs", -1);
 #endif
 
 // Allow webapps update checking
 pref("webapps.update.enabled", true);
@@ -934,19 +931,16 @@ pref("identity.fxaccounts.remote.oauth.u
 pref("identity.fxaccounts.remote.profile.uri", "https://profile.accounts.firefox.com/v1");
 
 // Disable Firefox Accounts device registration until bug 1238895 is fixed.
 pref("identity.fxaccounts.skipDeviceRegistration", true);
 
 // Enable mapped array buffer.
 pref("dom.mapped_arraybuffer.enabled", true);
 
-// SystemUpdate API
-pref("dom.system_update.enabled", true);
-
 // UDPSocket API
 pref("dom.udpsocket.enabled", true);
 
 // Enable TV Manager API
 pref("dom.tv.enabled", true);
 
 // Enable Inputport Manager API
 pref("dom.inputport.enabled", true);
--- a/b2g/components/B2GComponents.manifest
+++ b/b2g/components/B2GComponents.manifest
@@ -4,23 +4,16 @@ category agent-style-sheets browser-cont
 # AlertsService.js
 component {fe33c107-82a4-41d6-8c64-5353267e04c9} AlertsService.js
 contract @mozilla.org/system-alerts-service;1 {fe33c107-82a4-41d6-8c64-5353267e04c9}
 
 # ContentPermissionPrompt.js
 component {8c719f03-afe0-4aac-91ff-6c215895d467} ContentPermissionPrompt.js
 contract @mozilla.org/content-permission/prompt;1 {8c719f03-afe0-4aac-91ff-6c215895d467}
 
-#ifdef MOZ_UPDATER
-# UpdatePrompt.js
-component {88b3eb21-d072-4e3b-886d-f89d8c49fe59} UpdatePrompt.js
-contract @mozilla.org/updates/update-prompt;1 {88b3eb21-d072-4e3b-886d-f89d8c49fe59}
-category system-update-provider MozillaProvider @mozilla.org/updates/update-prompt;1,{88b3eb21-d072-4e3b-886d-f89d8c49fe59}
-#endif
-
 #ifdef MOZ_B2G
 # DirectoryProvider.js
 component {9181eb7c-6f87-11e1-90b1-4f59d80dd2e5} DirectoryProvider.js
 contract @mozilla.org/b2g/directory-provider;1 {9181eb7c-6f87-11e1-90b1-4f59d80dd2e5}
 category xpcom-directory-providers b2g-directory-provider @mozilla.org/b2g/directory-provider;1
 #endif
 
 # SystemMessageGlue.js
--- a/b2g/components/ContentPermissionPrompt.js
+++ b/b2g/components/ContentPermissionPrompt.js
@@ -19,17 +19,16 @@ const PROMPT_FOR_UNKNOWN = ["audio-captu
                             "video-capture"];
 // Due to privary issue, permission requests like GetUserMedia should prompt
 // every time instead of providing session persistence.
 const PERMISSION_NO_SESSION = ["audio-capture", "video-capture"];
 const ALLOW_MULTIPLE_REQUESTS = ["audio-capture", "video-capture"];
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/PermissionsTable.jsm");
 
 var permissionManager = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
 var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
 
 var permissionSpecificChecker = {};
 
 XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
                                   "resource://gre/modules/SystemAppProxy.jsm");
@@ -62,66 +61,16 @@ function buildDefaultChoices(aTypesInfo)
         choices = {};
       }
       choices[type.access] = type.options[0];
     }
   }
   return choices;
 }
 
-/**
- * aTypesInfo is an array of {permission, access, action, deny} which keeps
- * the information of each permission. This arrary is initialized in
- * ContentPermissionPrompt.prompt and used among functions.
- *
- * aTypesInfo[].permission : permission name
- * aTypesInfo[].access     : permission name + request.access
- * aTypesInfo[].action     : the default action of this permission
- * aTypesInfo[].deny       : true if security manager denied this app's origin
- *                           principal.
- * Note:
- *   aTypesInfo[].permission will be sent to prompt only when
- *   aTypesInfo[].action is PROMPT_ACTION and aTypesInfo[].deny is false.
- */
-function rememberPermission(aTypesInfo, aPrincipal, aSession)
-{
-  function convertPermToAllow(aPerm, aPrincipal)
-  {
-    let type =
-      permissionManager.testExactPermissionFromPrincipal(aPrincipal, aPerm);
-    if (shouldPrompt(aPerm, type)) {
-      debug("add " + aPerm + " to permission manager with ALLOW_ACTION");
-      if (!aSession) {
-        permissionManager.addFromPrincipal(aPrincipal,
-                                           aPerm,
-                                           Ci.nsIPermissionManager.ALLOW_ACTION);
-      } else if (PERMISSION_NO_SESSION.indexOf(aPerm) < 0) {
-        permissionManager.addFromPrincipal(aPrincipal,
-                                           aPerm,
-                                           Ci.nsIPermissionManager.ALLOW_ACTION,
-                                           Ci.nsIPermissionManager.EXPIRE_SESSION, 0);
-      }
-    }
-  }
-
-  for (let i in aTypesInfo) {
-    // Expand the permission to see if we have multiple access properties
-    // to convert
-    let perm = aTypesInfo[i].permission;
-    let access = PermissionsTable[perm].access;
-    if (access) {
-      for (let idx in access) {
-        convertPermToAllow(perm + "-" + access[idx], aPrincipal);
-      }
-    } else {
-      convertPermToAllow(perm, aPrincipal);
-    }
-  }
-}
-
 function ContentPermissionPrompt() {}
 
 ContentPermissionPrompt.prototype = {
 
   handleExistingPermission: function handleExistingPermission(request,
                                                               typesInfo) {
     typesInfo.forEach(function(type) {
       type.action =
@@ -291,17 +240,16 @@ ContentPermissionPrompt.prototype = {
     this.sendToBrowserWindow("cancel-permission-prompt", request,
                              typesInfo);
   },
 
   delegatePrompt: function(request, typesInfo, callback) {
     this.sendToBrowserWindow("permission-prompt", request, typesInfo,
                              function(type, remember, choices) {
       if (type == "permission-allow") {
-        rememberPermission(typesInfo, request.principal, !remember);
         if (callback) {
           callback();
         }
         request.allow(choices);
         return;
       }
 
       let addDenyPermission = function(type) {
deleted file mode 100644
--- a/b2g/components/UpdatePrompt.js
+++ /dev/null
@@ -1,783 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
- * vim: sw=2 ts=8 et :
- */
-/* 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/. */
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/AppConstants.jsm");
-
-const VERBOSE = 1;
-var log =
-  VERBOSE ?
-  function log_dump(msg) { dump("UpdatePrompt: "+ msg +"\n"); } :
-  function log_noop(msg) { };
-
-const PREF_APPLY_PROMPT_TIMEOUT          = "b2g.update.apply-prompt-timeout";
-const PREF_APPLY_IDLE_TIMEOUT            = "b2g.update.apply-idle-timeout";
-const PREF_DOWNLOAD_WATCHDOG_TIMEOUT     = "b2g.update.download-watchdog-timeout";
-const PREF_DOWNLOAD_WATCHDOG_MAX_RETRIES = "b2g.update.download-watchdog-max-retries";
-
-const NETWORK_ERROR_OFFLINE = 111;
-const HTTP_ERROR_OFFSET     = 1000;
-
-const STATE_DOWNLOADING = 'downloading';
-
-XPCOMUtils.defineLazyServiceGetter(Services, "aus",
-                                   "@mozilla.org/updates/update-service;1",
-                                   "nsIApplicationUpdateService");
-
-XPCOMUtils.defineLazyServiceGetter(Services, "um",
-                                   "@mozilla.org/updates/update-manager;1",
-                                   "nsIUpdateManager");
-
-XPCOMUtils.defineLazyServiceGetter(Services, "idle",
-                                   "@mozilla.org/widget/idleservice;1",
-                                   "nsIIdleService");
-
-XPCOMUtils.defineLazyServiceGetter(Services, "settings",
-                                   "@mozilla.org/settingsService;1",
-                                   "nsISettingsService");
-
-XPCOMUtils.defineLazyServiceGetter(Services, 'env',
-                                   '@mozilla.org/process/environment;1',
-                                   'nsIEnvironment');
-
-function useSettings() {
-  // When we're running in the real phone, then we can use settings.
-  // But when we're running as part of xpcshell, there is no settings database
-  // and trying to use settings in this scenario causes lots of weird
-  // assertions at shutdown time.
-  if (typeof useSettings.result === "undefined") {
-    useSettings.result = !Services.env.get("XPCSHELL_TEST_PROFILE_DIR");
-  }
-  return useSettings.result;
-}
-
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
-                                  "resource://gre/modules/SystemAppProxy.jsm");
-
-function UpdateCheckListener(updatePrompt) {
-  this._updatePrompt = updatePrompt;
-}
-
-UpdateCheckListener.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdateCheckListener]),
-
-  _updatePrompt: null,
-
-  onCheckComplete: function UCL_onCheckComplete(request, updates, updateCount) {
-    if (Services.um.activeUpdate) {
-      // We're actively downloading an update, that's the update the user should
-      // see, even if a newer update is available.
-      this._updatePrompt.setUpdateStatus("active-update");
-      this._updatePrompt.showUpdateAvailable(Services.um.activeUpdate);
-      return;
-    }
-
-    if (updateCount == 0) {
-      this._updatePrompt.setUpdateStatus("no-updates");
-
-      if (this._updatePrompt._systemUpdateListener) {
-        this._updatePrompt._systemUpdateListener.onError("no-updates");
-      }
-
-      return;
-    }
-
-    let update = Services.aus.selectUpdate(updates, updateCount);
-    if (!update) {
-      this._updatePrompt.setUpdateStatus("already-latest-version");
-
-      if (this._updatePrompt._systemUpdateListener) {
-        this._updatePrompt._systemUpdateListener.onError("already-latest-version");
-      }
-
-      return;
-    }
-
-    this._updatePrompt.setUpdateStatus("check-complete");
-    this._updatePrompt.showUpdateAvailable(update);
-  },
-
-  onError: function UCL_onError(request, update) {
-    // nsIUpdate uses a signed integer for errorCode while any platform errors
-    // require all 32 bits.
-    let errorCode = update.errorCode >>> 0;
-    let isNSError = (errorCode >>> 31) == 1;
-    let errorMsg = "check-error-";
-
-    if (errorCode == NETWORK_ERROR_OFFLINE) {
-      errorMsg = "retry-when-online";
-      this._updatePrompt.setUpdateStatus(errorMsg);
-    } else if (isNSError) {
-      errorMsg = "check-error-" + errorCode;
-      this._updatePrompt.setUpdateStatus(errorMsg);
-    } else if (errorCode > HTTP_ERROR_OFFSET) {
-      let httpErrorCode = errorCode - HTTP_ERROR_OFFSET;
-      errorMsg = "check-error-http-" + httpErrorCode;
-      this._updatePrompt.setUpdateStatus(errorMsg);
-    }
-
-    if (this._updatePrompt._systemUpdateListener) {
-      this._updatePrompt._systemUpdateListener.onError(errorMsg);
-    }
-
-    Services.aus.QueryInterface(Ci.nsIUpdateCheckListener);
-    Services.aus.onError(request, update);
-  }
-};
-
-function UpdatePrompt() {
-  this.wrappedJSObject = this;
-  this._updateCheckListener = new UpdateCheckListener(this);
-}
-
-UpdatePrompt.prototype = {
-  classID: Components.ID("{88b3eb21-d072-4e3b-886d-f89d8c49fe59}"),
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdatePrompt,
-                                         Ci.nsIUpdateCheckListener,
-                                         Ci.nsIRequestObserver,
-                                         Ci.nsIProgressEventSink,
-                                         Ci.nsIObserver,
-                                         Ci.nsISystemUpdateProvider]),
-  _xpcom_factory: XPCOMUtils.generateSingletonFactory(UpdatePrompt),
-
-  _update: null,
-  _applyPromptTimer: null,
-  _waitingForIdle: false,
-  _updateCheckListner: null,
-  _systemUpdateListener: null,
-  _availableParameters: {
-    "deviceinfo.last_updated": null,
-    "gecko.updateStatus": null,
-    "app.update.channel": null,
-    "app.update.interval": null,
-    "app.update.url": null,
-  },
-  _pendingUpdateAvailablePackageInfo: null,
-  _isPendingUpdateReady: false,
-  _updateErrorQueue: [ ],
-  _receivedUpdatePromptReady: false,
-
-  // nsISystemUpdateProvider
-  checkForUpdate: function() {
-    this.forceUpdateCheck();
-  },
-
-  startDownload: function() {
-    this.downloadUpdate(this._update);
-  },
-
-  stopDownload: function() {
-    this.handleDownloadCancel();
-  },
-
-  applyUpdate: function() {
-    this.handleApplyPromptResult({result: "restart"});
-  },
-
-  setParameter: function(aName, aValue) {
-    if (!this._availableParameters.hasOwnProperty(aName)) {
-      return false;
-    }
-
-    this._availableParameters[aName] = aValue;
-
-    switch (aName) {
-      case "app.update.channel":
-      case "app.update.url":
-        Services.prefs.setCharPref(aName, aValue);
-        break;
-      case "app.update.interval":
-        Services.prefs.setIntPref(aName, parseInt(aValue, 10));
-        break;
-    }
-
-    return true;
-  },
-
-  getParameter: function(aName) {
-    if (!this._availableParameters.hasOwnProperty(aName)) {
-      return null;
-    }
-
-    return this._availableParameters[aName];
-  },
-
-  setListener: function(aListener) {
-    this._systemUpdateListener = aListener;
-
-    // If an update is available or ready, trigger the event right away at this point.
-    if (this._pendingUpdateAvailablePackageInfo) {
-      this._systemUpdateListener.onUpdateAvailable(this._pendingUpdateAvailablePackageInfo.type,
-                                             this._pendingUpdateAvailablePackageInfo.version,
-                                             this._pendingUpdateAvailablePackageInfo.description,
-                                             this._pendingUpdateAvailablePackageInfo.buildDate,
-                                             this._pendingUpdateAvailablePackageInfo.size);
-      // Set null when the listener is attached.
-      this._pendingUpdateAvailablePackageInfo = null;
-    }
-
-    if (this._isPendingUpdateReady) {
-      this._systemUpdateListener.onUpdateReady();
-      this._isPendingUpdateReady = false;
-    }
-  },
-
-  unsetListener: function(aListener) {
-    this._systemUpdateListener = null;
-  },
-
-  get applyPromptTimeout() {
-    return Services.prefs.getIntPref(PREF_APPLY_PROMPT_TIMEOUT);
-  },
-
-  get applyIdleTimeout() {
-    return Services.prefs.getIntPref(PREF_APPLY_IDLE_TIMEOUT);
-  },
-
-  handleContentStart: function UP_handleContentStart() {
-    SystemAppProxy.addEventListener("mozContentEvent", this);
-  },
-
-  // nsIUpdatePrompt
-
-  // FIXME/bug 737601: we should have users opt-in to downloading
-  // updates when on a billed pipe.  Initially, opt-in for 3g, but
-  // that doesn't cover all cases.
-  checkForUpdates: function UP_checkForUpdates() { },
-
-  showUpdateAvailable: function UP_showUpdateAvailable(aUpdate) {
-    let packageInfo = {};
-    packageInfo.version = aUpdate.displayVersion;
-    packageInfo.description = aUpdate.statusText;
-    packageInfo.buildDate = aUpdate.buildID;
-
-    let patch = aUpdate.selectedPatch;
-    if (!patch && aUpdate.patchCount > 0) {
-      // For now we just check the first patch to get size information if a
-      // patch hasn't been selected yet.
-      patch = aUpdate.getPatchAt(0);
-    }
-
-    if (patch) {
-      packageInfo.size = patch.size;
-      packageInfo.type = patch.type;
-    } else {
-      log("Warning: no patches available in update");
-    }
-
-    this._pendingUpdateAvailablePackageInfo = packageInfo;
-
-    if (this._systemUpdateListener) {
-      this._systemUpdateListener.onUpdateAvailable(packageInfo.type,
-                                             packageInfo.version,
-                                             packageInfo.description,
-                                             packageInfo.buildDate,
-                                             packageInfo.size);
-      // Set null since the event is fired.
-      this._pendingUpdateAvailablePackageInfo = null;
-    }
-
-    if (!this.sendUpdateEvent("update-available", aUpdate)) {
-
-      log("Unable to prompt for available update, forcing download");
-      this.downloadUpdate(aUpdate);
-    }
-  },
-
-  showUpdateDownloaded: function UP_showUpdateDownloaded(aUpdate, aBackground) {
-    if (this._systemUpdateListener) {
-      this._systemUpdateListener.onUpdateReady();
-    } else {
-      this._isPendingUpdateReady = true;
-    }
-
-    // The update has been downloaded and staged. We send the update-downloaded
-    // event right away. After the user has been idle for a while, we send the
-    // update-prompt-restart event, increasing the chances that we can apply the
-    // update quietly without user intervention.
-    this.sendUpdateEvent("update-downloaded", aUpdate);
-
-    if (Services.idle.idleTime >= this.applyIdleTimeout) {
-      this.showApplyPrompt(aUpdate);
-      return;
-    }
-
-    let applyIdleTimeoutSeconds = this.applyIdleTimeout / 1000;
-    // We haven't been idle long enough, so register an observer
-    log("Update is ready to apply, registering idle timeout of " +
-        applyIdleTimeoutSeconds + " seconds before prompting.");
-
-    this._update = aUpdate;
-    this.waitForIdle();
-  },
-
-  storeUpdateError: function UP_storeUpdateError(aUpdate) {
-    log("Storing update error for later use");
-    this._updateErrorQueue.push(aUpdate);
-  },
-
-  sendStoredUpdateError: function UP_sendStoredUpdateError() {
-    log("Sending stored update error");
-    this._updateErrorQueue.forEach(aUpdate => {
-      this.sendUpdateEvent("update-error", aUpdate);
-    });
-    this._updateErrorQueue = [ ];
-  },
-
-  showUpdateError: function UP_showUpdateError(aUpdate) {
-    log("Update error, state: " + aUpdate.state + ", errorCode: " +
-        aUpdate.errorCode);
-    if (this._systemUpdateListener) {
-      this._systemUpdateListener.onError("update-error: " + aUpdate.errorCode + " " + aUpdate.statusText);
-    }
-
-    if (!this._receivedUpdatePromptReady) {
-      this.storeUpdateError(aUpdate);
-    } else {
-      this.sendUpdateEvent("update-error", aUpdate);
-    }
-
-    this.setUpdateStatus(aUpdate.statusText);
-  },
-
-  showUpdateHistory: function UP_showUpdateHistory(aParent) { },
-  showUpdateInstalled: function UP_showUpdateInstalled() {
-    this.setParameter("deviceinfo.last_updated", Date.now());
-
-    if (useSettings()) {
-      let lock = Services.settings.createLock();
-      lock.set("deviceinfo.last_updated", Date.now(), null, null);
-    }
-  },
-
-  // Custom functions
-
-  waitForIdle: function UP_waitForIdle() {
-    if (this._waitingForIdle) {
-      return;
-    }
-
-    this._waitingForIdle = true;
-    Services.idle.addIdleObserver(this, this.applyIdleTimeout / 1000);
-    Services.obs.addObserver(this, "quit-application", false);
-  },
-
-  setUpdateStatus: function UP_setUpdateStatus(aStatus) {
-     this.setParameter("gecko.updateStatus", aStatus);
-
-     if (useSettings()) {
-       log("Setting gecko.updateStatus: " + aStatus);
-
-       let lock = Services.settings.createLock();
-       lock.set("gecko.updateStatus", aStatus, null);
-     }
-  },
-
-  showApplyPrompt: function UP_showApplyPrompt(aUpdate) {
-    // Notify update package is ready to apply
-    if (this._systemUpdateListener) {
-      this._systemUpdateListener.onUpdateReady();
-    } else {
-      // Set the flag to true and fire the onUpdateReady event when the listener is attached.
-      this._isPendingUpdateReady = true;
-    }
-
-    if (!this.sendUpdateEvent("update-prompt-apply", aUpdate)) {
-      log("Unable to prompt, forcing restart");
-      this.restartProcess();
-      return;
-    }
-
-    if (AppConstants.MOZ_B2G_RIL) {
-      let window = Services.wm.getMostRecentWindow("navigator:browser");
-      let pinReq = window.navigator.mozIccManager.getCardLock("pin");
-      pinReq.onsuccess = function(e) {
-        if (e.target.result.enabled) {
-          // The SIM is pin locked. Don't use a fallback timer. This means that
-          // the user has to press Install to apply the update. If we use the
-          // timer, and the timer reboots the phone, then the phone will be
-          // unusable until the SIM is unlocked.
-          log("SIM is pin locked. Not starting fallback timer.");
-        } else {
-          // This means that no pin lock is enabled, so we go ahead and start
-          // the fallback timer.
-          this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
-        }
-      }.bind(this);
-      pinReq.onerror = function(e) {
-        this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
-      }.bind(this);
-    } else {
-      // Schedule a fallback timeout in case the UI is unable to respond or show
-      // a prompt for some reason.
-      this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
-    }
-  },
-
-  _copyProperties: ["appVersion", "buildID", "detailsURL", "displayVersion",
-                    "errorCode", "isOSUpdate", "platformVersion",
-                    "previousAppVersion", "state", "statusText"],
-
-  sendUpdateEvent: function UP_sendUpdateEvent(aType, aUpdate) {
-    let detail = {};
-    for (let property of this._copyProperties) {
-      detail[property] = aUpdate[property];
-    }
-
-    let patch = aUpdate.selectedPatch;
-    if (!patch && aUpdate.patchCount > 0) {
-      // For now we just check the first patch to get size information if a
-      // patch hasn't been selected yet.
-      patch = aUpdate.getPatchAt(0);
-    }
-
-    if (patch) {
-      detail.size = patch.size;
-      detail.updateType = patch.type;
-    } else {
-      log("Warning: no patches available in update");
-    }
-
-    this._update = aUpdate;
-    return this.sendChromeEvent(aType, detail);
-  },
-
-  sendChromeEvent: function UP_sendChromeEvent(aType, aDetail) {
-    let detail = aDetail || {};
-    detail.type = aType;
-
-    let sent = SystemAppProxy.dispatchEvent(detail);
-    if (!sent) {
-      log("Warning: Couldn't send update event " + aType +
-          ": no content browser. Will send again when content becomes available.");
-      return false;
-    }
-    return true;
-  },
-
-  handleAvailableResult: function UP_handleAvailableResult(aDetail) {
-    // If the user doesn't choose "download", the updater will implicitly call
-    // showUpdateAvailable again after a certain period of time
-    switch (aDetail.result) {
-      case "download":
-        this.downloadUpdate(this._update);
-        break;
-    }
-  },
-
-  handleApplyPromptResult: function UP_handleApplyPromptResult(aDetail) {
-    if (this._applyPromptTimer) {
-      this._applyPromptTimer.cancel();
-      this._applyPromptTimer = null;
-    }
-
-    switch (aDetail.result) {
-      // Battery not okay, do not wait for idle to re-prompt
-      case "low-battery":
-        break;
-      case "wait":
-        // Wait until the user is idle before prompting to apply the update
-        this.waitForIdle();
-        break;
-      case "restart":
-        this.finishUpdate();
-        this._update = null;
-        break;
-    }
-  },
-
-  downloadUpdate: function UP_downloadUpdate(aUpdate) {
-    if (!aUpdate) {
-      aUpdate = Services.um.activeUpdate;
-      if (!aUpdate) {
-        log("No active update found to download");
-        return;
-      }
-    }
-
-    let status = Services.aus.downloadUpdate(aUpdate, true);
-    if (status == STATE_DOWNLOADING) {
-      Services.aus.addDownloadListener(this);
-      return;
-    }
-
-    // If the update has already been downloaded and applied, then
-    // Services.aus.downloadUpdate will return immediately and not
-    // call showUpdateDownloaded, so we detect this.
-    if (aUpdate.state == "applied" && aUpdate.errorCode == 0) {
-      this.showUpdateDownloaded(aUpdate, true);
-      return;
-    }
-
-    log("Error downloading update " + aUpdate.name + ": " + aUpdate.errorCode);
-    let errorCode = aUpdate.errorCode >>> 0;
-    if (errorCode == Cr.NS_ERROR_FILE_TOO_BIG) {
-      aUpdate.statusText = "file-too-big";
-    }
-    this.showUpdateError(aUpdate);
-  },
-
-  handleDownloadCancel: function UP_handleDownloadCancel() {
-    log("Pausing download");
-    Services.aus.pauseDownload();
-  },
-
-  finishUpdate: function UP_finishUpdate() {
-    if (!this._update.isOSUpdate) {
-      // Standard gecko+gaia updates will just need to restart the process
-      this.restartProcess();
-      return;
-    }
- 
-    try {
-      Services.aus.applyOsUpdate(this._update);
-    }
-    catch (e) {
-      this._update.errorCode = Cr.NS_ERROR_FAILURE;
-      this.showUpdateError(this._update);
-    }
-  },
-
-  restartProcess: function UP_restartProcess() {
-    log("Update downloaded, restarting to apply it");
-
-    let callbackAfterSet = function() {
-      if (AppConstants.platform !== "gonk") {
-        let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
-                         .getService(Ci.nsIAppStartup);
-        appStartup.quit(appStartup.eForceQuit | appStartup.eRestart);
-      } else {
-        // NB: on Gonk, we rely on the system process manager to restart us.
-        let pmService = Cc["@mozilla.org/power/powermanagerservice;1"]
-                        .getService(Ci.nsIPowerManagerService);
-        pmService.restart();
-      }
-    }
-
-    if (useSettings()) {
-      // Save current os version in deviceinfo.previous_os
-      let lock = Services.settings.createLock({
-        handle: callbackAfterSet,
-        handleAbort: function(error) {
-          log("Abort callback when trying to set previous_os: " + error);
-          callbackAfterSet();
-        }
-      });
-      lock.get("deviceinfo.os", {
-        handle: function(name, value) {
-          log("Set previous_os to: " + value);
-          lock.set("deviceinfo.previous_os", value, null, null);
-        }
-      });
-    }
-  },
-
-  forceUpdateCheck: function UP_forceUpdateCheck() {
-    log("Forcing update check");
-
-    let checker = Cc["@mozilla.org/updates/update-checker;1"]
-                    .createInstance(Ci.nsIUpdateChecker);
-    checker.checkForUpdates(this._updateCheckListener, true);
-  },
-
-  handleEvent: function UP_handleEvent(evt) {
-    if (evt.type !== "mozContentEvent") {
-      return;
-    }
-
-    let detail = evt.detail;
-    if (!detail) {
-      return;
-    }
-
-    switch (detail.type) {
-      case "force-update-check":
-        this.forceUpdateCheck();
-        break;
-      case "update-available-result":
-        this.handleAvailableResult(detail);
-        // If we started the apply prompt timer, this means that we're waiting
-        // for the user to press Later or Install Now. In this situation we
-        // don't want to clear this._update, becuase handleApplyPromptResult
-        // needs it.
-        if (this._applyPromptTimer == null && !this._waitingForIdle) {
-          this._update = null;
-        }
-        break;
-      case "update-download-cancel":
-        this.handleDownloadCancel();
-        break;
-      case "update-prompt-apply-result":
-        this.handleApplyPromptResult(detail);
-        break;
-      case "update-prompt-ready":
-        this._receivedUpdatePromptReady = true;
-        this.sendStoredUpdateError();
-        break;
-    }
-  },
-
-  // nsIObserver
-
-  observe: function UP_observe(aSubject, aTopic, aData) {
-    switch (aTopic) {
-      case "idle":
-        this._waitingForIdle = false;
-        this.showApplyPrompt(this._update);
-        // Fall through
-      case "quit-application":
-        Services.idle.removeIdleObserver(this, this.applyIdleTimeout / 1000);
-        Services.obs.removeObserver(this, "quit-application");
-        break;
-    }
-  },
-
-  // nsITimerCallback
-
-  notify: function UP_notify(aTimer) {
-    if (aTimer == this._applyPromptTimer) {
-      log("Timed out waiting for result, restarting");
-      this._applyPromptTimer = null;
-      this.finishUpdate();
-      this._update = null;
-      return;
-    }
-    if (aTimer == this._watchdogTimer) {
-      log("Download watchdog fired");
-      this._watchdogTimer = null;
-      this._autoRestartDownload = true;
-      Services.aus.pauseDownload();
-      return;
-    }
-  },
-
-  createTimer: function UP_createTimer(aTimeoutMs) {
-    let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-    timer.initWithCallback(this, aTimeoutMs, timer.TYPE_ONE_SHOT);
-    return timer;
-  },
-
-  // nsIRequestObserver
-
-  _startedSent: false,
-
-  _watchdogTimer: null,
-
-  _autoRestartDownload: false,
-  _autoRestartCount: 0,
-
-  startWatchdogTimer: function UP_startWatchdogTimer() {
-    let watchdogTimeout = 120000;  // 120 seconds
-    try {
-      watchdogTimeout = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_TIMEOUT);
-    } catch (e) {
-      // This means that the preference doesn't exist. watchdogTimeout will
-      // retain its default assigned above.
-    }
-    if (watchdogTimeout <= 0) {
-      // 0 implies don't bother using the watchdog timer at all.
-      this._watchdogTimer = null;
-      return;
-    }
-    if (this._watchdogTimer) {
-      this._watchdogTimer.cancel();
-    } else {
-      this._watchdogTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-    }
-    this._watchdogTimer.initWithCallback(this, watchdogTimeout,
-                                         Ci.nsITimer.TYPE_ONE_SHOT);
-  },
-
-  stopWatchdogTimer: function UP_stopWatchdogTimer() {
-    if (this._watchdogTimer) {
-      this._watchdogTimer.cancel();
-      this._watchdogTimer = null;
-    }
-  },
-
-  touchWatchdogTimer: function UP_touchWatchdogTimer() {
-    this.startWatchdogTimer();
-  },
-
-  onStartRequest: function UP_onStartRequest(aRequest, aContext) {
-    // Wait until onProgress to send the update-download-started event, in case
-    // this request turns out to fail for some reason
-    this._startedSent = false;
-    this.startWatchdogTimer();
-  },
-
-  onStopRequest: function UP_onStopRequest(aRequest, aContext, aStatusCode) {
-    this.stopWatchdogTimer();
-    Services.aus.removeDownloadListener(this);
-    let paused = !Components.isSuccessCode(aStatusCode);
-    if (!paused) {
-      // The download was successful, no need to restart
-      this._autoRestartDownload = false;
-    }
-    if (this._autoRestartDownload) {
-      this._autoRestartDownload = false;
-      let watchdogMaxRetries = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_MAX_RETRIES);
-      this._autoRestartCount++;
-      if (this._autoRestartCount > watchdogMaxRetries) {
-        log("Download - retry count exceeded - error");
-        // We exceeded the max retries. Treat the download like an error,
-        // which will give the user a chance to restart manually later.
-        this._autoRestartCount = 0;
-        if (Services.um.activeUpdate) {
-          this.showUpdateError(Services.um.activeUpdate);
-        }
-        return;
-      }
-      log("Download - restarting download - attempt " + this._autoRestartCount);
-      this.downloadUpdate(null);
-      return;
-    }
-    this._autoRestartCount = 0;
-    this.sendChromeEvent("update-download-stopped", {
-      paused: paused
-    });
-  },
-
-  // nsIProgressEventSink
-
-  onProgress: function UP_onProgress(aRequest, aContext, aProgress,
-                                     aProgressMax) {
-    if (this._systemUpdateListener) {
-      this._systemUpdateListener.onProgress(aProgress, aProgressMax);
-    }
-
-    if (aProgress == aProgressMax) {
-      // The update.mar validation done by onStopRequest may take
-      // a while before the onStopRequest callback is made, so stop
-      // the timer now.
-      this.stopWatchdogTimer();
-    } else {
-      this.touchWatchdogTimer();
-    }
-    if (!this._startedSent) {
-      this.sendChromeEvent("update-download-started", {
-        total: aProgressMax
-      });
-      this._startedSent = true;
-    }
-
-    this.sendChromeEvent("update-download-progress", {
-      progress: aProgress,
-      total: aProgressMax
-    });
-  },
-
-  onStatus: function UP_onStatus(aRequest, aUpdate, aStatus, aStatusArg) { }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([UpdatePrompt]);
--- a/b2g/components/moz.build
+++ b/b2g/components/moz.build
@@ -36,21 +36,16 @@ EXTRA_PP_COMPONENTS += [
 ]
 
 if CONFIG['MOZ_B2G']:
     EXTRA_COMPONENTS += [
         'DirectoryProvider.js',
         'RecoveryService.js',
     ]
 
-if CONFIG['MOZ_UPDATER']:
-    EXTRA_COMPONENTS += [
-        'UpdatePrompt.js',
-    ]
-
 EXTRA_JS_MODULES += [
     'AboutServiceWorkers.jsm',
     'ActivityChannel.jsm',
     'AlertsHelper.jsm',
     'Bootstraper.jsm',
     'ContentRequestHelper.jsm',
     'DebuggerActors.js',
     'ErrorPage.jsm',
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -774,19 +774,16 @@ bin/libfreebl_32int64_3.so
 #if defined(ENABLE_MARIONETTE) || !defined(MOZ_WIDGET_GONK)
 @RESPATH@/chrome/marionette@JAREXT@
 @RESPATH@/chrome/marionette.manifest
 @RESPATH@/components/MarionetteComponents.manifest
 @RESPATH@/components/marionettecomponent.js
 #endif
 @RESPATH@/components/AlertsService.js
 @RESPATH@/components/ContentPermissionPrompt.js
-#ifdef MOZ_UPDATER
-@RESPATH@/components/UpdatePrompt.js
-#endif
 @RESPATH@/components/DirectoryProvider.js
 @RESPATH@/components/ProcessGlobal.js
 @RESPATH@/components/OMAContentHandler.js
 @RESPATH@/components/RecoveryService.js
 @RESPATH@/components/MailtoProtocolHandler.js
 @RESPATH@/components/SmsProtocolHandler.js
 @RESPATH@/components/TelProtocolHandler.js
 @RESPATH@/components/B2GAboutRedirector.js
--- a/build/autoconf/nspr-build.m4
+++ b/build/autoconf/nspr-build.m4
@@ -151,16 +151,18 @@ if test -n "$MOZ_SYSTEM_NSPR" -o -n "$NS
                 AC_MSG_ERROR([system NSPR does not support PR_STATIC_ASSERT or including prtypes.h does not provide it]))
     AC_TRY_COMPILE([#include "prtypes.h"],
                 [#ifndef PR_UINT64
                  #error PR_UINT64 not defined or requires including prtypes.h
                  #endif],
                 ,
                 AC_MSG_ERROR([system NSPR does not support PR_UINT64 or including prtypes.h does not provide it]))
     CFLAGS=$_SAVE_CFLAGS
+    NSPR_INCLUDE_DIR=`echo ${NSPR_CFLAGS} | sed -e 's/.*-I\([^ ]*\).*/\1/'`
+    NSPR_LIB_DIR=`echo ${NSPR_LIBS} | sed -e 's/.*-L\([^ ]*\).*/\1/'`
 elif test -z "$JS_POSIX_NSPR"; then
     NSPR_INCLUDE_DIR="${DIST}/include/nspr"
     NSPR_CFLAGS="-I${NSPR_INCLUDE_DIR}"
     if test -n "$GNU_CC"; then
         if test -n "$MOZ_FOLD_LIBS"; then
            NSPR_LIB_DIR=${DIST}/lib
         else
            NSPR_LIB_DIR=${DIST}/bin
--- a/build/gyp.mozbuild
+++ b/build/gyp.mozbuild
@@ -1,15 +1,17 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
-gyp_vars = {
+include('gyp_base.mozbuild')
+
+gyp_vars.update({
     'lsan': 0,
     'asan': 0,
     'build_with_mozilla': 1,
     'build_with_chromium': 0,
     'use_official_google_api_keys': 0,
     'have_clock_monotonic': 1 if CONFIG['HAVE_CLOCK_MONOTONIC'] else 0,
     'have_ethtool_cmd_speed_hi': 1 if CONFIG['MOZ_WEBRTC_HAVE_ETHTOOL_SPEED_HI'] else 0,
     'include_alsa_audio': 1 if CONFIG['MOZ_ALSA'] else 0,
@@ -64,61 +66,32 @@ gyp_vars = {
     'include_g711': 1,
     'include_opus': 1,
     'include_g722': 1,
     'include_ilbc': 0,
     # We turn on ISAC because the AGC uses parts of it, and depend on the
     # linker to throw away uneeded bits.
     'include_isac': 1,
     'include_pcm16b': 1,
-}
-
-os = CONFIG['OS_TARGET']
+})
 
-if os == 'WINNT':
-    gyp_vars.update(
-        MSVS_VERSION=CONFIG['_MSVS_VERSION'],
-        MSVS_OS_BITS=64 if CONFIG['HAVE_64BIT_BUILD'] else 32,
-    )
-elif os == 'Android':
+if os == 'Android':
     if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
         gyp_vars['build_with_gonk'] = 1
         gyp_vars['moz_widget_toolkit_gonk'] = 1
         gyp_vars['opus_complexity'] = 1
         if int(CONFIG['ANDROID_VERSION']) >= 18:
           gyp_vars['moz_webrtc_omx'] = 1
     else:
         gyp_vars.update(
             gtest_target_type='executable',
             moz_webrtc_mediacodec=1,
             android_toolchain=CONFIG.get('ANDROID_TOOLCHAIN', ''),
         )
 
-flavors = {
-    'WINNT': 'win',
-    'Android': 'linux' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' else 'android',
-    'Linux': 'linux',
-    'Darwin': 'mac' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa' else 'ios',
-    'SunOS': 'solaris',
-    'GNU/kFreeBSD': 'freebsd',
-    'DragonFly': 'dragonfly',
-    'FreeBSD': 'freebsd',
-    'NetBSD': 'netbsd',
-    'OpenBSD': 'openbsd',
-}
-gyp_vars['OS'] = flavors.get(os)
-
-arches = {
-    'x86_64': 'x64',
-    'x86': 'ia32',
-    'aarch64': 'arm64',
-}
-
-gyp_vars['target_arch'] = arches.get(CONFIG['CPU_ARCH'], CONFIG['CPU_ARCH'])
-
 if CONFIG['ARM_ARCH']:
     if int(CONFIG['ARM_ARCH']) < 7:
         gyp_vars['armv7'] = 0
         gyp_vars['arm_neon_optional'] = 0
     elif os == 'Android':
         gyp_vars['armv7'] = 1
     else:
         # CPU detection for ARM works on Android only.  armv7 always uses CPU
new file mode 100644
--- /dev/null
+++ b/build/gyp_base.mozbuild
@@ -0,0 +1,38 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+gyp_vars = {}
+
+os = CONFIG['OS_TARGET']
+
+if os == 'WINNT':
+    gyp_vars.update(
+        MSVS_VERSION=CONFIG['_MSVS_VERSION'],
+        MSVS_OS_BITS=64 if CONFIG['HAVE_64BIT_BUILD'] else 32,
+    )
+
+flavors = {
+    'WINNT': 'win',
+    'Android': 'linux' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' else 'android',
+    'Linux': 'linux',
+    'Darwin': 'mac' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa' else 'ios',
+    'SunOS': 'solaris',
+    'GNU/kFreeBSD': 'freebsd',
+    'DragonFly': 'dragonfly',
+    'FreeBSD': 'freebsd',
+    'NetBSD': 'netbsd',
+    'OpenBSD': 'openbsd',
+}
+gyp_vars['OS'] = flavors.get(os)
+
+arches = {
+    'x86_64': 'x64',
+    'x86': 'ia32',
+    'aarch64': 'arm64',
+}
+
+gyp_vars['host_arch'] = arches.get(CONFIG['HOST_CPU_ARCH'], CONFIG['HOST_CPU_ARCH'])
+gyp_vars['target_arch'] = arches.get(CONFIG['CPU_ARCH'], CONFIG['CPU_ARCH'])
--- a/build/moz.configure/init.configure
+++ b/build/moz.configure/init.configure
@@ -515,16 +515,17 @@ def host_variables(host):
     if host.kernel == 'kFreeBSD':
         os_arch = 'GNU_kFreeBSD'
     else:
         os_arch = host.kernel
     return namespace(
         HOST_OS_ARCH=os_arch,
     )
 
+set_config('HOST_CPU_ARCH', delayed_getattr(host, 'cpu'))
 set_config('HOST_OS_ARCH', delayed_getattr(host_variables, 'HOST_OS_ARCH'))
 add_old_configure_assignment('HOST_OS_ARCH',
                              delayed_getattr(host_variables, 'HOST_OS_ARCH'))
 
 @depends(target)
 def target_is_windows(target):
     if target.kernel == 'WINNT':
         return True
deleted file mode 100644
--- a/config/external/nss/Makefile.in
+++ /dev/null
@@ -1,485 +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/.
-
-ifndef MOZ_SYSTEM_NSS
-
-CC_WRAPPER =
-CXX_WRAPPER =
-
-default::
-
-include $(topsrcdir)/config/makefiles/functions.mk
-
-NSS_LIBS = \
-  nss3 \
-  nssutil3 \
-  smime3 \
-  ssl3 \
-  $(NULL)
-
-ifdef MOZ_FOLD_LIBS
-NSS_DLLS = $(LIBRARY_NAME)
-else
-NSS_DLLS = $(NSS_LIBS)
-endif
-
-NSS_EXTRA_DLLS = \
-  nssckbi \
-  softokn3 \
-  $(NULL)
-
-ifndef NSS_DISABLE_DBM
-NSS_EXTRA_DLLS += nssdbm3
-endif
-
-SDK_LIBS = crmf
-
-ifneq (,$(filter WINNT,$(OS_ARCH)))
-SDK_LIBS += $(NSS_DLLS)
-endif
-
-# Default
-HAVE_FREEBL_LIBS = 1
-
-# 32-bit HP-UX PA-RISC
-ifeq ($(OS_ARCH), HP-UX)
-ifneq ($(OS_TEST), ia64)
-ifndef HAVE_64BIT_BUILD
-HAVE_FREEBL_LIBS =
-HAVE_FREEBL_LIBS_32INT32 = 1
-HAVE_FREEBL_LIBS_32FPU = 1
-endif
-endif
-endif
-
-# SunOS SPARC
-ifeq ($(OS_ARCH), SunOS)
-ifneq (86,$(findstring 86,$(OS_TEST)))
-ifdef HAVE_64BIT_BUILD
-HAVE_FREEBL_LIBS =
-HAVE_FREEBL_LIBS_64 = 1
-else
-HAVE_FREEBL_LIBS =
-HAVE_FREEBL_LIBS_32FPU = 1
-HAVE_FREEBL_LIBS_32INT64 = 1
-endif
-endif
-endif
-
-ifeq ($(OS_TARGET),Linux)
-HAVE_FREEBL_LIBS = 
-HAVE_FREEBL_LIBS_PRIV = 1
-FREEBL_LOWHASH_FLAG = FREEBL_LOWHASH=1
-endif
-
-ifdef HAVE_FREEBL_LIBS
-NSS_EXTRA_DLLS += freebl3
-endif
-ifdef HAVE_FREEBL_LIBS_PRIV
-NSS_EXTRA_DLLS += freeblpriv3
-endif
-ifdef HAVE_FREEBL_LIBS_32INT32
-NSS_EXTRA_DLLS += freebl_32int_3
-endif
-ifdef HAVE_FREEBL_LIBS_32FPU
-NSS_EXTRA_DLLS += freebl_32fpu_3
-endif
-ifdef HAVE_FREEBL_LIBS_32INT64
-NSS_EXTRA_DLLS += freebl_32int64_3
-endif
-ifdef HAVE_FREEBL_LIBS_64
-NSS_EXTRA_DLLS += freebl_64int_3
-NSS_EXTRA_DLLS += freebl_64fpu_3
-endif
-
-# For all variables such as DLLFLAGS, that may contain $(DIST)
-DIST := $(ABS_DIST)
-# TODO: move this all to configure, but in Python
-ifndef MOZ_BUILD_NSPR
-NSPR_INCLUDE_DIR = $(firstword $(filter -I%,$(NSPR_CFLAGS)))
-ifneq (,$(strip $(NSPR_INCLUDE_DIR)))
-NSPR_INCLUDE_DIR := $(subst -I,,$(subst -I$(DIST),-I$(ABS_DIST),$(NSPR_INCLUDE_DIR)))
-else
-$(error Your NSPR CFLAGS are broken!)
-endif
-NSPR_LIB_DIR = $(firstword $(filter -L%,$(NSPR_LIBS)))
-ifneq (,$(strip $(NSPR_LIB_DIR)))
-NSPR_LIB_DIR := $(subst -L,,$(subst -L$(DIST),-L$(ABS_DIST),$(NSPR_LIB_DIR)))
-else
-$(error Your NSPR LDFLAGS are broken!)
-endif
-endif
-
-# To get debug symbols from NSS
-export MOZ_DEBUG_SYMBOLS
-
-DEFAULT_GMAKE_FLAGS =
-DEFAULT_GMAKE_FLAGS += CC='$(CC)'
-DEFAULT_GMAKE_FLAGS += MT='$(MT)'
-DEFAULT_GMAKE_FLAGS += LD='$(LD)'
-DEFAULT_GMAKE_FLAGS += SOURCE_MD_DIR=$(ABS_DIST)
-DEFAULT_GMAKE_FLAGS += SOURCE_MDHEADERS_DIR=$(NSPR_INCLUDE_DIR)
-DEFAULT_GMAKE_FLAGS += DIST=$(ABS_DIST)
-DEFAULT_GMAKE_FLAGS += NSPR_INCLUDE_DIR=$(NSPR_INCLUDE_DIR)
-DEFAULT_GMAKE_FLAGS += NSPR_LIB_DIR=$(NSPR_LIB_DIR)
-DEFAULT_GMAKE_FLAGS += MOZILLA_CLIENT=1
-DEFAULT_GMAKE_FLAGS += NO_MDUPDATE=1
-DEFAULT_GMAKE_FLAGS += NSS_ENABLE_ECC=1
-DEFAULT_GMAKE_FLAGS += NSS_ENABLE_TLS_1_3=1
-ifeq ($(OS_ARCH)_$(GNU_CC),WINNT_1)
-DEFAULT_GMAKE_FLAGS += OS_DLLFLAGS='-static-libgcc' NSPR31_LIB_PREFIX=lib
-endif
-ifndef MOZ_SYSTEM_SQLITE
-ifdef MOZ_FOLD_LIBS
-DEFAULT_GMAKE_FLAGS += SQLITE_LIB_NAME=nss3
-else
-DEFAULT_GMAKE_FLAGS += SQLITE_LIB_NAME=mozsqlite3
-DEFAULT_GMAKE_FLAGS += SQLITE_LIB_DIR=$(ABS_DIST)/../config/external/sqlite
-endif # MOZ_FOLD_LIBS
-DEFAULT_GMAKE_FLAGS += SQLITE_INCLUDE_DIR=$(ABS_DIST)/include
-endif
-ifdef NSS_DISABLE_DBM 
-DEFAULT_GMAKE_FLAGS += NSS_DISABLE_DBM=1
-endif
-# Hack to force NSS build system to use "normal" object directories
-DEFAULT_GMAKE_FLAGS += topsrcdir='$(topsrcdir)'
-# topsrcdir can't be expanded here because msys path mangling likes to break
-# paths in that case.
-DEFAULT_GMAKE_FLAGS += BUILD='$(MOZ_BUILD_ROOT)/security/$$(subst $$(topsrcdir)/security/,,$$(CURDIR))'
-DEFAULT_GMAKE_FLAGS += BUILD_TREE='$$(BUILD)' OBJDIR='$$(BUILD)' DEPENDENCIES='$$(BUILD)/.deps' SINGLE_SHLIB_DIR='$$(BUILD)'
-DEFAULT_GMAKE_FLAGS += SOURCE_XP_DIR=$(ABS_DIST)
-ifndef MOZ_DEBUG
-DEFAULT_GMAKE_FLAGS += BUILD_OPT=1 OPT_CODE_SIZE=1
-endif
-ifdef GNU_CC
-DEFAULT_GMAKE_FLAGS += NS_USE_GCC=1
-else
-DEFAULT_GMAKE_FLAGS += NS_USE_GCC=
-endif
-ifdef USE_N32
-# It is not really necessary to specify USE_PTHREADS=1.  USE_PTHREADS
-# merely adds _PTH to coreconf's OBJDIR name.
-DEFAULT_GMAKE_FLAGS += USE_N32=1 USE_PTHREADS=1
-endif
-ifdef HAVE_64BIT_BUILD
-DEFAULT_GMAKE_FLAGS += USE_64=1
-endif
-ifeq ($(OS_ARCH),WINNT)
-DEFAULT_GMAKE_FLAGS += OS_TARGET=WIN95
-ifdef MOZ_DEBUG
-ifndef MOZ_NO_DEBUG_RTL
-DEFAULT_GMAKE_FLAGS += USE_DEBUG_RTL=1
-endif
-endif
-endif # WINNT
-ifeq ($(OS_ARCH),Darwin)
-# Make nsinstall use absolute symlinks by default when building NSS
-# for Mozilla on Mac OS X. (Bugzilla bug 193164)
-ifndef NSDISTMODE
-DEFAULT_GMAKE_FLAGS += NSDISTMODE=absolute_symlink
-endif
-ifdef MACOS_SDK_DIR
-DEFAULT_GMAKE_FLAGS += MACOS_SDK_DIR=$(MACOS_SDK_DIR)
-endif
-endif
-
-# Turn off TLS compression support because it requires system zlib.
-# See bug 580679 comment 18.
-DEFAULT_GMAKE_FLAGS += NSS_SSL_ENABLE_ZLIB=
-
-# Disable building of the test programs in security/nss/lib/zlib
-DEFAULT_GMAKE_FLAGS += PROGRAMS=
-
-# Disable creating .chk files. They will be generated from packager.mk
-# When bug 681624 lands, we can replace CHECKLOC= with SKIP_SHLIBSIGN=1
-DEFAULT_GMAKE_FLAGS += CHECKLOC=
-
-ifdef CROSS_COMPILE
-
-DEFAULT_GMAKE_FLAGS += \
-	NATIVE_CC='$(HOST_CC)' \
-	CC='$(CC)' \
-	CCC='$(CXX)' \
-	AS='$(AS)' \
-	AR='$(AR) $(AR_FLAGS:$@=$$@)' \
-	RANLIB='$(RANLIB)' \
-	RC='$(RC) $(RCFLAGS)' \
-	OS_ARCH='$(OS_ARCH)' \
-	OS_TEST='$(OS_TEST)' \
-	CPU_ARCH='$(TARGET_CPU)' \
-	$(NULL)
-
-# Android has pthreads integrated into -lc, so OS_PTHREAD is set to nothing
-ifeq ($(OS_TARGET), Android)
-DEFAULT_GMAKE_FLAGS += \
-	OS_RELEASE='2.6' \
-	OS_PTHREAD= \
-	$(NULL)
-
-DEFAULT_GMAKE_FLAGS += ARCHFLAG='$(filter-out -W%,$(CFLAGS)) -DCHECK_FORK_GETPID $(addprefix -DANDROID_VERSION=,$(ANDROID_VERSION)) -include $(topsrcdir)/security/manager/android_stub.h'
-endif
-endif
-
-ifdef WRAP_LDFLAGS
-NSS_EXTRA_LDFLAGS += $(WRAP_LDFLAGS)
-endif
-
-# The SHARED_LIBS part is needed unconditionally on Android.  It's not
-# clear why this is the case, but see bug 1133073 (starting around
-# comment #8) for context.
-ifneq (,$(or $(MOZ_GLUE_WRAP_LDFLAGS), $(filter Android, $(OS_TARGET))))
-NSS_EXTRA_LDFLAGS += $(SHARED_LIBS:$(DEPTH)%=$(MOZ_BUILD_ROOT)%) $(MOZ_GLUE_WRAP_LDFLAGS)
-endif
-
-ifneq (,$(NSS_EXTRA_LDFLAGS))
-DEFAULT_GMAKE_FLAGS += \
-	LDFLAGS='$(LDFLAGS) $(NSS_EXTRA_LDFLAGS)' \
-	DSO_LDOPTS='$(DSO_LDOPTS) $(LDFLAGS) $(NSS_EXTRA_LDFLAGS)' \
-	$(NULL)
-endif
-
-DEFAULT_GMAKE_FLAGS += FREEBL_NO_DEPEND=0 $(FREEBL_LOWHASH_FLAG)
-DEFAULT_GMAKE_FLAGS += NSS_ALLOW_SSLKEYLOGFILE=1
-
-ifdef MOZ_NO_WLZDEFS
-DEFAULT_GMAKE_FLAGS += ZDEFS_FLAG=
-endif
-ifdef MOZ_CFLAGS_NSS
-NSS_XCFLAGS += $(filter-out -W%,$(CFLAGS))
-DEFAULT_GMAKE_FLAGS += DARWIN_DYLIB_VERSIONS='-compatibility_version 1 -current_version 1 $(LDFLAGS)'
-endif
-ifeq (1_1,$(CLANG_CL)_$(MOZ_ASAN))
-XLDFLAGS := $(OS_LDFLAGS)
-DEFAULT_GMAKE_FLAGS += XLDFLAGS='$(XLDFLAGS)'
-endif
-
-DEFAULT_GMAKE_FLAGS += NSS_NO_PKCS11_BYPASS=1
-
-# Put NSS headers directly under $(DIST)/include
-DEFAULT_GMAKE_FLAGS += PUBLIC_EXPORT_DIR='$(ABS_DIST)/include/$$(MODULE)'
-DEFAULT_GMAKE_FLAGS += SOURCE_XPHEADERS_DIR='$$(SOURCE_XP_DIR)/include/$$(MODULE)'
-DEFAULT_GMAKE_FLAGS += MODULE_INCLUDES='$$(addprefix -I$$(SOURCE_XP_DIR)/include/,$$(REQUIRES))'
-
-# Work around NSS's MAKE_OBJDIR being racy. See bug #836220
-DEFAULT_GMAKE_FLAGS += MAKE_OBJDIR='$$(INSTALL) -D $$(OBJDIR)'
-
-# Work around NSS adding IMPORT_LIBRARY to TARGETS with no rule for
-# it, creating race conditions. See bug #836220
-DEFAULT_GMAKE_FLAGS += TARGETS='$$(LIBRARY) $$(SHARED_LIBRARY) $$(PROGRAM)'
-
-ifdef MOZ_FOLD_LIBS_FLAGS
-NSS_XCFLAGS += $(MOZ_FOLD_LIBS_FLAGS)
-endif
-
-# Pass on the MSVC target arch from the main build system.
-# Note this is case- and switch-character sensitive, while
-# the MSVC option is not.
-ifeq (WINNT,$(OS_TARGET))
-NSS_XCFLAGS += $(filter -arch:%,$(CFLAGS))
-endif
-
-# Export accumulated XCFLAGS to modify nss defaults.
-DEFAULT_GMAKE_FLAGS += XCFLAGS='$(NSS_XCFLAGS)'
-
-NSS_SRCDIR = $(topsrcdir)
-
-NSS_DIRS =
-ifndef MOZ_FOLD_LIBS
-NSS_DIRS += nss/lib
-else
-ifndef NSS_DISABLE_DBM
-NSS_DIRS += nss/lib/dbm
-endif
-endif
-NSS_DIRS += \
-  nss/cmd/lib \
-  nss/cmd/shlibsign \
-  $(NULL)
-
-ifdef ENABLE_TESTS
-NSS_DIRS += \
-  nss/cmd/certutil \
-  nss/cmd/pk12util \
-  nss/cmd/modutil \
-  $(NULL)
-endif
-
-ifneq (,$(filter %--build-id,$(LDFLAGS)))
-DEFAULT_GMAKE_ENV = LDFLAGS=-Wl,--build-id
-endif
-
-ifdef MOZ_FOLD_LIBS
-# TODO: The following can be replaced by something simpler when bug 844880
-# is fixed.
-# All static libraries required for nss, smime, ssl and nssutil.
-# The strip is needed to remove potential linefeed characters, since they hang
-# around in some cases on Windows.
-NSS_STATIC_LIBS := $(strip $(shell $(MAKE) --no-print-directory -f $(srcdir)/nss.mk DEPTH='$(DEPTH)' topsrcdir='$(topsrcdir)' srcdir='$(srcdir)' echo-variable-libs))
-# Corresponding build directories
-NSS_STATIC_DIRS := $(foreach lib,$(NSS_STATIC_LIBS),$(patsubst %/,%,$(dir $(lib))))
-NSS_DIRS += $(NSS_STATIC_DIRS)
-
-# TODO: The following can be replaced by something simpler when bug 844884
-# is fixed.
-# Remaining nss/lib directories
-NSS_DIRS += nss/lib/freebl nss/lib/softoken nss/lib/jar nss/lib/crmf nss/lib/ckfw
-
-DEFAULT_GMAKE_FLAGS += NSS_DISABLE_LIBPKIX=1
-
-ifeq (WINNT,$(OS_TARGET))
-NSS_DIRS += nss/lib/zlib
-endif
-endif # MOZ_FOLD_LIBS
-
-# Filter-out $(LIBRARY_NAME) because it's already handled in config/rules.mk.
-NSS_DIST_DLL_FILES := $(addprefix $(DIST)/lib/$(DLL_PREFIX),$(addsuffix $(DLL_SUFFIX),$(filter-out $(LIBRARY_NAME),$(NSS_DLLS)) $(NSS_EXTRA_DLLS)))
-NSS_DIST_DLL_DEST := $(DIST)/bin
-NSS_DIST_DLL_TARGET := target
-INSTALL_TARGETS += NSS_DIST_DLL
-
-ifeq ($(OS_ARCH)_$(1), SunOS_softokn3)
-# has to use copy mode on Solaris, see #665509
-$(DIST)/bin/$(DLL_PREFIX)softokn3$(DLL_SUFFIX): INSTALL := $(INSTALL) -t
-endif
-
-NSS_SDK_LIB_FILES := \
-  $(addprefix $(DIST)/lib/$(LIB_PREFIX),$(addsuffix .$(LIB_SUFFIX),$(SDK_LIBS))) \
-  $(addprefix $(DIST)/bin/$(DLL_PREFIX),$(addsuffix $(DLL_SUFFIX),$(NSS_DLLS))) \
-  $(NULL)
-NSS_SDK_LIB_DEST := $(DIST)/sdk/lib
-NSS_SDK_LIB_TARGET := target
-INSTALL_TARGETS += NSS_SDK_LIB
-
-ifdef MOZ_FOLD_LIBS
-# Add all static libraries for nss, smime, ssl and nssutil
-STATIC_LIBS += $(addprefix $(DEPTH)/security/,$(NSS_STATIC_LIBS))
-
-IMPORT_LIB_FILES = $(IMPORT_LIBRARY)
-IMPORT_LIB_DEST ?= $(DIST)/lib
-IMPORT_LIB_TARGET = target
-INSTALL_TARGETS += IMPORT_LIB
-
-endif # MOZ_FOLD_LIBS
-
-include $(topsrcdir)/config/rules.mk
-
-ifeq (1,$(ALLOW_COMPILER_WARNINGS))
-DEFAULT_GMAKE_FLAGS += NSS_ENABLE_WERROR=0
-endif
-
-# Can't pass this in DEFAULT_GMAKE_FLAGS because that overrides
-# definitions in NSS, so just export it into the sub-make's environment.
-ifeq (WINNT_1,$(OS_TARGET)_$(MOZ_MEMORY))
-DLLFLAGS := -LIBPATH:$(ABS_DIST)/../mozglue/build -DEFAULTLIB:mozglue
-export DLLFLAGS
-endif
-
-ifdef MOZ_FOLD_LIBS
-# Force the linker to include everything from the static libraries.
-EXPAND_LIBS_EXEC += --extract
-
-$(SHARED_LIBRARY): $(addprefix $(DEPTH)/security/,$(NSS_STATIC_LIBS))
-
-ifdef IMPORT_LIB_SUFFIX
-IMPORT_PREFIX = $(LIB_PREFIX)
-IMPORT_SUFFIX = .$(IMPORT_LIB_SUFFIX)
-else
-IMPORT_PREFIX = $(DLL_PREFIX)
-IMPORT_SUFFIX = $(DLL_SUFFIX)
-endif
-
-NSPR_IMPORT_LIBS = $(addprefix $(DIST)/lib/$(IMPORT_PREFIX),$(addsuffix $(IMPORT_SUFFIX),nspr4 plc4 plds4))
-SQLITE_IMPORT_LIB = $(DIST)/lib/$(IMPORT_PREFIX)mozsqlite3$(IMPORT_SUFFIX)
-
-# TODO: The following can be replaced by something simpler when bug 844884
-# is fixed.
-# Associate target files with the rules that build them.
-$(DIST)/lib/$(LIB_PREFIX)crmf.$(LIB_SUFFIX): libs-nss/lib/crmf
-$(DIST)/lib/$(DLL_PREFIX)freebl3$(DLL_SUFFIX): libs-nss/lib/freebl
-$(DIST)/lib/$(DLL_PREFIX)nssckbi$(DLL_SUFFIX): libs-nss/lib/ckfw
-$(DIST)/lib/$(DLL_PREFIX)softokn3$(DLL_SUFFIX): libs-nss/lib/softoken
-$(DIST)/lib/$(DLL_PREFIX)nssdbm3$(DLL_SUFFIX): libs-nss/lib/softoken
-$(foreach lib,$(NSS_STATIC_LIBS),$(eval $(DEPTH)/security/$(lib): libs-$(patsubst %/,%,$(dir $(lib)))))
-
-# Create fake import libraries for the folded libraries, so that linking
-# against them works both for the NSS build system (see dependencies below)
-# and for the rest of the mozilla build system.
-$(NSPR_IMPORT_LIBS) \
-$(SQLITE_IMPORT_LIB) \
-$(DIST)/lib/$(IMPORT_PREFIX)nssutil3$(IMPORT_SUFFIX) \
-$(DIST)/lib/$(IMPORT_PREFIX)ssl3$(IMPORT_SUFFIX) \
-$(DIST)/lib/$(IMPORT_PREFIX)smime3$(IMPORT_SUFFIX): $(DIST)/lib/$(IMPORT_PREFIX)nss3$(IMPORT_SUFFIX)
-ifeq (WINNT,$(OS_TARGET))
-	cp $< $@
-else
-	ln -sf $< $@
-endif
-
-# Interdependencies between nss sub-directories, and dependencies on NSPR/SQLite
-libs-nss/lib/ckfw: libs-nss/lib/nss/../base $(NSPR_IMPORT_LIBS)
-libs-nss/lib/softoken: $(NSPR_IMPORT_LIBS) $(SQLITE_IMPORT_LIB)
-libs-nss/lib/softoken: libs-nss/lib/freebl
-ifndef NSS_DISABLE_DBM
-libs-nss/lib/softoken: libs-nss/lib/dbm
-endif
-libs-nss/lib/softoken: $(DIST)/lib/$(IMPORT_PREFIX)nssutil3$(IMPORT_SUFFIX)
-libs-nss/lib/freebl: $(DIST)/lib/$(IMPORT_PREFIX)nssutil3$(IMPORT_SUFFIX) $(NSPR_IMPORT_LIBS)
-
-# For each directory where we build static libraries, force the NSS build system
-# to only build static libraries.
-$(addprefix libs-,$(NSS_STATIC_DIRS)): DEFAULT_GMAKE_FLAGS += SHARED_LIBRARY= IMPORT_LIBRARY=
-else
-$(STATIC_LIBS) $(NSS_DIST_DLL_FILES) $(NSS_SDK_LIB_FILES): libs-nss/lib
-endif # MOZ_FOLD_LIBS
-
-ifeq ($(NSINSTALL_PY),$(NSINSTALL))
-DEFAULT_GMAKE_FLAGS += PYTHON='$(PYTHON)'
-DEFAULT_GMAKE_FLAGS += NSINSTALL_PY='$(abspath $(topsrcdir)/config/nsinstall.py)'
-DEFAULT_GMAKE_FLAGS += NSINSTALL='$$(PYTHON) $$(NSINSTALL_PY)'
-else
-DEFAULT_GMAKE_FLAGS += NSINSTALL='$(abspath $(NSINSTALL))'
-endif
-ifeq ($(OS_ARCH),WINNT)
-DEFAULT_GMAKE_FLAGS += INSTALL='$$(NSINSTALL) -t'
-endif
-DEFAULT_GMAKE_FLAGS += $(EXTRA_GMAKE_FLAGS)
-
-$(addprefix libs-,$(NSS_DIRS)): libs-%:
-# Work around NSS's export rule being racy when recursing for private_export
-# See bug #836220.
-$(addprefix export-,$(NSS_DIRS)): EXTRA_GMAKE_FLAGS = PRIVATE_EXPORTS=
-$(addprefix export-,$(NSS_DIRS)): export-%: private_export-%
-$(addprefix private_export-,$(NSS_DIRS)): EXTRA_GMAKE_FLAGS =
-$(addprefix private_export-,$(NSS_DIRS)): private_export-%:
-
-$(foreach p,libs export private_export,$(addprefix $(p)-,$(NSS_DIRS))):
-	$(DEFAULT_GMAKE_ENV) $(MAKE) -C $(NSS_SRCDIR)/security/$* $(@:-$*=) $(DEFAULT_GMAKE_FLAGS)
-
-export:: $(addprefix export-,$(NSS_DIRS))
-
-$(addprefix clean-,$(NSS_DIRS)): clean-%:
-	$(MAKE) -C $(NSS_SRCDIR)/security/$* $(DEFAULT_GMAKE_FLAGS) clean
-
-clean clobber clobber_all realclean distclean depend:: $(addprefix clean-,$(NSS_DIRS))
-
-NSS_CMD_TARGETS := $(addprefix libs-,$(filter-out nss/cmd/lib,$(filter nss/cmd/%,$(NSS_DIRS))))
-target:: $(NSS_CMD_TARGETS)
-
-ifdef MOZ_FOLD_LIBS
-$(NSS_CMD_TARGETS): $(addprefix $(DIST)/lib/$(IMPORT_PREFIX),$(addsuffix $(IMPORT_SUFFIX),$(NSS_LIBS)))
-libs-nss/cmd/modutil: libs-nss/lib/jar
-ifeq (WINNT,$(OS_TARGET))
-libs-nss/cmd/modutil: libs-nss/lib/zlib
-endif
-$(NSS_CMD_TARGETS): libs-nss/cmd/lib
-else
-$(NSS_CMD_TARGETS): libs-nss/lib libs-nss/cmd/lib
-endif # MOZ_FOLD_LIBS
-
-# Work around NSS build system race condition creating certdata.c in
-# security/nss/lib/ckfw/builtins. See bug #836220.
-libs-nss/lib$(if $(MOZ_FOLD_LIBS),/ckfw): $(call mkdir_deps,$(DEPTH)/security/nss/lib/ckfw/builtins)
-
-endif
deleted file mode 100644
--- a/config/external/nss/crmf/moz.build
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-Library('crmf')
-
-if CONFIG['MOZ_SYSTEM_NSS']:
-    OS_LIBS += [l for l in CONFIG['NSS_LIBS'] if l.startswith('-L')]
-    OS_LIBS += ['-lcrmf']
-else:
-    USE_LIBS += [
-        # The dependency on nss is not real, but is required to force the
-        # parent directory being built before this one. This has no
-        # practical effect on linkage, since the only thing linking crmf
-        # will need nss anyways.
-        'nss',
-        'static:/security/nss/lib/crmf/crmf',
-    ]
deleted file mode 100644
--- a/config/external/nss/nss.mk
+++ /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/.
-
-include $(DEPTH)/config/autoconf.mk
-
-include $(topsrcdir)/config/config.mk
-
-dirs :=
-
-define add_dirs
-SHARED_LIBRARY_DIRS :=
-include $(topsrcdir)/security/$(1)/config.mk
-dirs += $$(addprefix $(1)/,$$(SHARED_LIBRARY_DIRS)) $(1)
-endef
-$(foreach dir,util nss ssl smime,$(eval $(call add_dirs,nss/lib/$(dir))))
-
-libs :=
-define add_lib
-LIBRARY_NAME :=
-include $(topsrcdir)/security/$(1)/manifest.mn
-libs += $$(addprefix $(1)/,$(LIB_PREFIX)$$(LIBRARY_NAME).$(LIB_SUFFIX))
-endef
-$(foreach dir,$(dirs),$(eval $(call add_lib,$(dir))))
-
-echo-variable-%:
-	@echo $($*)
--- a/devtools/client/locales/en-US/webide.dtd
+++ b/devtools/client/locales/en-US/webide.dtd
@@ -27,18 +27,16 @@
 <!ENTITY projectMenu_manageComponents_label "Manage Extra Components">
 <!ENTITY projectMenu_manageComponents_accesskey "M">
 <!ENTITY projectMenu_refreshTabs_label "Refresh Tabs">
 
 <!ENTITY runtimeMenu_label "Runtime">
 <!ENTITY runtimeMenu_accesskey "R">
 <!ENTITY runtimeMenu_disconnect_label "Disconnect">
 <!ENTITY runtimeMenu_disconnect_accesskey "D">
-<!ENTITY runtimeMenu_showPermissionTable_label "Permissions Table">
-<!ENTITY runtimeMenu_showPermissionTable_accesskey "P">
 <!ENTITY runtimeMenu_takeScreenshot_label "Screenshot">
 <!ENTITY runtimeMenu_takeScreenshot_accesskey "S">
 <!ENTITY runtimeMenu_showDetails_label "Runtime Info">
 <!ENTITY runtimeMenu_showDetails_accesskey "E">
 <!ENTITY runtimeMenu_showMonitor_label "Monitor">
 <!ENTITY runtimeMenu_showMonitor_accesskey "M">
 <!ENTITY runtimeMenu_showDevicePrefs_label "Device Preferences">
 <!ENTITY runtimeMenu_showDevicePrefs_accesskey "D">
@@ -136,20 +134,16 @@
 <!ENTITY prefs_options_autocomplete_tooltip "Enable code autocompletion">
 <!ENTITY prefs_options_autoclosebrackets "Autoclose brackets">
 <!ENTITY prefs_options_autoclosebrackets_tooltip "Automatically insert closing brackets">
 <!ENTITY prefs_options_keybindings "Keybindings">
 <!ENTITY prefs_options_keybindings_default "Default">
 <!ENTITY prefs_options_autosavefiles "Autosave files">
 <!ENTITY prefs_options_autosavefiles_tooltip "Automatically save edited files before running project">
 
-<!-- Permissions Table -->
-<!ENTITY permissionstable_title "Permissions Table">
-<!ENTITY permissionstable_name_header "Name">
-
 <!-- Runtime Details -->
 <!ENTITY runtimedetails_title "Runtime Info">
 <!ENTITY runtimedetails_adbIsRoot "ADB is root: ">
 <!ENTITY runtimedetails_summonADBRoot "root device">
 <!ENTITY runtimedetails_ADBRootWarning "(requires unlocked bootloader)">
 <!ENTITY runtimedetails_unrestrictedPrivileges "Unrestricted DevTools privileges: ">
 <!ENTITY runtimedetails_requestPrivileges "request higher privileges">
 <!ENTITY runtimedetails_privilegesWarning "(Will reboot device. Requires root access.)">
--- a/devtools/client/webide/content/jar.mn
+++ b/devtools/client/webide/content/jar.mn
@@ -7,18 +7,16 @@ webide.jar:
     content/webide.xul                (webide.xul)
     content/webide.js                 (webide.js)
     content/newapp.xul                (newapp.xul)
     content/newapp.js                 (newapp.js)
     content/details.xhtml             (details.xhtml)
     content/details.js                (details.js)
     content/addons.js                 (addons.js)
     content/addons.xhtml              (addons.xhtml)
-    content/permissionstable.js       (permissionstable.js)
-    content/permissionstable.xhtml    (permissionstable.xhtml)
     content/runtimedetails.js         (runtimedetails.js)
     content/runtimedetails.xhtml      (runtimedetails.xhtml)
     content/prefs.js                  (prefs.js)
     content/prefs.xhtml               (prefs.xhtml)
     content/monitor.xhtml             (monitor.xhtml)
     content/monitor.js                (monitor.js)
     content/devicepreferences.js      (devicepreferences.js)
     content/devicepreferences.xhtml   (devicepreferences.xhtml)
deleted file mode 100644
--- a/devtools/client/webide/content/permissionstable.js
+++ /dev/null
@@ -1,78 +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/. */
-
-var Cu = Components.utils;
-const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
-const Services = require("Services");
-const {AppManager} = require("devtools/client/webide/modules/app-manager");
-const {Connection} = require("devtools/shared/client/connection-manager");
-
-window.addEventListener("load", function onLoad() {
-  window.removeEventListener("load", onLoad);
-  document.querySelector("#close").onclick = CloseUI;
-  AppManager.on("app-manager-update", OnAppManagerUpdate);
-  BuildUI();
-}, true);
-
-window.addEventListener("unload", function onUnload() {
-  window.removeEventListener("unload", onUnload);
-  AppManager.off("app-manager-update", OnAppManagerUpdate);
-});
-
-function CloseUI() {
-  window.parent.UI.openProject();
-}
-
-function OnAppManagerUpdate(event, what) {
-  if (what == "connection" || what == "runtime-global-actors") {
-    BuildUI();
-  }
-}
-
-function generateFields(json) {
-  let table = document.querySelector("table");
-  let permissionsTable = json.rawPermissionsTable;
-  for (let name in permissionsTable) {
-    let tr = document.createElement("tr");
-    tr.className = "line";
-    let td = document.createElement("td");
-    td.textContent = name;
-    tr.appendChild(td);
-    for (let type of ["app", "privileged", "certified"]) {
-      let td = document.createElement("td");
-      if (permissionsTable[name][type] == json.ALLOW_ACTION) {
-        td.textContent = "✓";
-        td.className = "permallow";
-      }
-      if (permissionsTable[name][type] == json.PROMPT_ACTION) {
-        td.textContent = "!";
-        td.className = "permprompt";
-      }
-      if (permissionsTable[name][type] == json.DENY_ACTION) {
-        td.textContent = "✕";
-        td.className = "permdeny";
-      }
-      tr.appendChild(td);
-    }
-    table.appendChild(tr);
-  }
-}
-
-var getRawPermissionsTablePromise; // Used by tests
-function BuildUI() {
-  let table = document.querySelector("table");
-  let lines = table.querySelectorAll(".line");
-  for (let line of lines) {
-    line.remove();
-  }
-
-  if (AppManager.connection &&
-      AppManager.connection.status == Connection.Status.CONNECTED &&
-      AppManager.deviceFront) {
-    getRawPermissionsTablePromise = AppManager.deviceFront.getRawPermissionsTable()
-                                    .then(json => generateFields(json));
-  } else {
-    CloseUI();
-  }
-}
deleted file mode 100644
--- a/devtools/client/webide/content/permissionstable.xhtml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!-- 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/. -->
-
-<!DOCTYPE html [
-  <!ENTITY % webideDTD SYSTEM "chrome://devtools/locale/webide.dtd" >
-  %webideDTD;
-]>
-
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <meta charset="utf8"/>
-    <link rel="stylesheet" href="chrome://webide/skin/deck.css" type="text/css"/>
-    <link rel="stylesheet" href="chrome://webide/skin/permissionstable.css" type="text/css"/>
-    <script type="application/javascript;version=1.8" src="chrome://webide/content/permissionstable.js"></script>
-  </head>
-  <body>
-
-    <div id="controls">
-      <a id="close">&deck_close;</a>
-    </div>
-
-    <h1>&permissionstable_title;</h1>
-
-    <table class="permissionstable">
-      <tr>
-        <th>&permissionstable_name_header;</th>
-        <th>type:web</th>
-        <th>type:privileged</th>
-        <th>type:certified</th>
-      </tr>
-    </table>
-  </body>
-</html>
--- a/devtools/client/webide/content/runtime-listing.js
+++ b/devtools/client/webide/content/runtime-listing.js
@@ -6,17 +6,16 @@ var Cu = Components.utils;
 const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
 const RuntimeList = require("devtools/client/webide/modules/runtime-list");
 
 var runtimeList = new RuntimeList(window, window.parent);
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad, true);
   document.getElementById("runtime-screenshot").onclick = TakeScreenshot;
-  document.getElementById("runtime-permissions").onclick = ShowPermissionsTable;
   document.getElementById("runtime-details").onclick = ShowRuntimeDetails;
   document.getElementById("runtime-disconnect").onclick = DisconnectRuntime;
   document.getElementById("runtime-preferences").onclick = ShowDevicePreferences;
   document.getElementById("runtime-settings").onclick = ShowSettings;
   document.getElementById("runtime-panel-installsimulator").onclick = ShowAddons;
   document.getElementById("runtime-panel-noadbhelper").onclick = ShowAddons;
   document.getElementById("runtime-panel-nousbdevice").onclick = ShowTroubleShooting;
   document.getElementById("refresh-devices").onclick = RefreshScanners;
@@ -32,20 +31,16 @@ window.addEventListener("unload", functi
 function TakeScreenshot() {
   runtimeList.takeScreenshot();
 }
 
 function ShowRuntimeDetails() {
   runtimeList.showRuntimeDetails();
 }
 
-function ShowPermissionsTable() {
-  runtimeList.showPermissionsTable();
-}
-
 function ShowDevicePreferences() {
   runtimeList.showDevicePreferences();
 }
 
 function ShowSettings() {
   runtimeList.showSettings();
 }
 
--- a/devtools/client/webide/content/runtime-listing.xhtml
+++ b/devtools/client/webide/content/runtime-listing.xhtml
@@ -28,17 +28,16 @@
         <div id="runtime-panel-wifi"></div>
         <label class="panel-header">&runtimePanel_simulator;</label>
         <div id="runtime-panel-simulator"></div>
         <button class="panel-item" id="runtime-panel-installsimulator">&runtimePanel_installsimulator;</button>
         <label class="panel-header">&runtimePanel_other;</label>
         <div id="runtime-panel-other"></div>
         <div id="runtime-actions">
           <button class="panel-item" id="runtime-details">&runtimeMenu_showDetails_label;</button>
-          <button class="panel-item" id="runtime-permissions">&runtimeMenu_showPermissionTable_label;</button>
           <button class="panel-item" id="runtime-preferences">&runtimeMenu_showDevicePrefs_label;</button>
           <button class="panel-item" id="runtime-settings">&runtimeMenu_showSettings_label;</button>
           <button class="panel-item" id="runtime-screenshot">&runtimeMenu_takeScreenshot_label;</button>
           <button class="panel-item" id="runtime-disconnect">&runtimeMenu_disconnect_label;</button>
         </div>
       </div>
     </div>
   </body>
--- a/devtools/client/webide/content/webide.js
+++ b/devtools/client/webide/content/webide.js
@@ -435,40 +435,37 @@ var UI = {
           playCmd.setAttribute("disabled", "true");
         }
       }
     }
 
     // Runtime commands
     let monitorCmd = document.querySelector("#cmd_showMonitor");
     let screenshotCmd = document.querySelector("#cmd_takeScreenshot");
-    let permissionsCmd = document.querySelector("#cmd_showPermissionsTable");
     let detailsCmd = document.querySelector("#cmd_showRuntimeDetails");
     let disconnectCmd = document.querySelector("#cmd_disconnectRuntime");
     let devicePrefsCmd = document.querySelector("#cmd_showDevicePrefs");
     let settingsCmd = document.querySelector("#cmd_showSettings");
 
     if (AppManager.connected) {
       if (AppManager.deviceFront) {
         monitorCmd.removeAttribute("disabled");
         detailsCmd.removeAttribute("disabled");
-        permissionsCmd.removeAttribute("disabled");
         screenshotCmd.removeAttribute("disabled");
       }
       if (AppManager.preferenceFront) {
         devicePrefsCmd.removeAttribute("disabled");
       }
       if (AppManager.settingsFront) {
         settingsCmd.removeAttribute("disabled");
       }
       disconnectCmd.removeAttribute("disabled");
     } else {
       monitorCmd.setAttribute("disabled", "true");
       detailsCmd.setAttribute("disabled", "true");
-      permissionsCmd.setAttribute("disabled", "true");
       screenshotCmd.setAttribute("disabled", "true");
       disconnectCmd.setAttribute("disabled", "true");
       devicePrefsCmd.setAttribute("disabled", "true");
       settingsCmd.setAttribute("disabled", "true");
     }
 
     let runtimePanelButton = document.querySelector("#runtime-panel-button");
 
@@ -1042,20 +1039,16 @@ var Cmds = {
     return UI.busyUntil(url.then(longstr => {
       return longstr.string().then(dataURL => {
         longstr.release().then(null, console.error);
         UI.openInBrowser(dataURL);
       });
     }), "taking screenshot");
   },
 
-  showPermissionsTable: function () {
-    UI.selectDeckPanel("permissionstable");
-  },
-
   showRuntimeDetails: function () {
     UI.selectDeckPanel("runtimedetails");
   },
 
   showDevicePrefs: function () {
     UI.selectDeckPanel("devicepreferences");
   },
 
--- a/devtools/client/webide/content/webide.xul
+++ b/devtools/client/webide/content/webide.xul
@@ -40,17 +40,16 @@
       <command id="cmd_importHostedApp" oncommand="Cmds.importHostedApp()" label="&projectMenu_importHostedApp_label;"/>
       <command id="cmd_showDevicePrefs" label="&runtimeMenu_showDevicePrefs_label;" oncommand="Cmds.showDevicePrefs()"/>
       <command id="cmd_showSettings" label="&runtimeMenu_showSettings_label;" oncommand="Cmds.showSettings()"/>
       <command id="cmd_removeProject" oncommand="Cmds.removeProject()" label="&projectMenu_remove_label;"/>
       <command id="cmd_showProjectPanel" oncommand="Cmds.showProjectPanel()"/>
       <command id="cmd_showRuntimePanel" oncommand="Cmds.showRuntimePanel()"/>
       <command id="cmd_disconnectRuntime" oncommand="Cmds.disconnectRuntime()" label="&runtimeMenu_disconnect_label;"/>
       <command id="cmd_showMonitor" oncommand="Cmds.showMonitor()" label="&runtimeMenu_showMonitor_label;"/>
-      <command id="cmd_showPermissionsTable" oncommand="Cmds.showPermissionsTable()" label="&runtimeMenu_showPermissionTable_label;"/>
       <command id="cmd_showRuntimeDetails" oncommand="Cmds.showRuntimeDetails()" label="&runtimeMenu_showDetails_label;"/>
       <command id="cmd_takeScreenshot" oncommand="Cmds.takeScreenshot()" label="&runtimeMenu_takeScreenshot_label;"/>
       <command id="cmd_toggleEditor" oncommand="Cmds.toggleEditors()" label="&viewMenu_toggleEditor_label;"/>
       <command id="cmd_showAddons" oncommand="Cmds.showAddons()"/>
       <command id="cmd_showPrefs" oncommand="Cmds.showPrefs()"/>
       <command id="cmd_showTroubleShooting" oncommand="Cmds.showTroubleShooting()"/>
       <command id="cmd_play" oncommand="Cmds.play()"/>
       <command id="cmd_stop" oncommand="Cmds.stop()" label="&projectMenu_stop_label;"/>
@@ -79,17 +78,16 @@
         <menuitem command="cmd_showAddons" label="&projectMenu_manageComponents_label;" accesskey="&projectMenu_manageComponents_accesskey;"/>
       </menupopup>
     </menu>
 
     <menu id="menu-runtime" label="&runtimeMenu_label;" accesskey="&runtimeMenu_accesskey;">
       <menupopup id="menu-runtime-popup">
         <menuitem command="cmd_showMonitor" accesskey="&runtimeMenu_showMonitor_accesskey;"/>
         <menuitem command="cmd_takeScreenshot" accesskey="&runtimeMenu_takeScreenshot_accesskey;"/>
-        <menuitem command="cmd_showPermissionsTable" accesskey="&runtimeMenu_showPermissionTable_accesskey;"/>
         <menuitem command="cmd_showRuntimeDetails" accesskey="&runtimeMenu_showDetails_accesskey;"/>
         <menuitem command="cmd_showDevicePrefs" accesskey="&runtimeMenu_showDevicePrefs_accesskey;"/>
         <menuitem command="cmd_showSettings" accesskey="&runtimeMenu_showSettings_accesskey;"/>
         <menuseparator/>
         <menuitem command="cmd_disconnectRuntime" accesskey="&runtimeMenu_disconnect_accesskey;"/>
       </menupopup>
     </menu>
 
@@ -151,17 +149,16 @@
         </div>
       </vbox>
       <splitter class="devtools-side-splitter" id="project-listing-splitter"/>
       <deck flex="1" id="deck" selectedIndex="-1">
         <iframe id="deck-panel-details" flex="1" src="details.xhtml"/>
         <iframe id="deck-panel-projecteditor" flex="1"/>
         <iframe id="deck-panel-addons" flex="1" src="addons.xhtml"/>
         <iframe id="deck-panel-prefs" flex="1" src="prefs.xhtml"/>
-        <iframe id="deck-panel-permissionstable" flex="1" lazysrc="permissionstable.xhtml"/>
         <iframe id="deck-panel-runtimedetails" flex="1" lazysrc="runtimedetails.xhtml"/>
         <iframe id="deck-panel-monitor" flex="1" lazysrc="monitor.xhtml"/>
         <iframe id="deck-panel-devicepreferences" flex="1" lazysrc="devicepreferences.xhtml"/>
         <iframe id="deck-panel-devicesettings" flex="1" lazysrc="devicesettings.xhtml"/>
         <iframe id="deck-panel-logs" flex="1" src="logs.xhtml"/>
         <iframe id="deck-panel-simulator" flex="1" lazysrc="simulator.xhtml"/>
       </deck>
       <splitter class="devtools-side-splitter" id="runtime-listing-splitter"/>
--- a/devtools/client/webide/modules/runtime-list.js
+++ b/devtools/client/webide/modules/runtime-list.js
@@ -61,20 +61,16 @@ RuntimeList.prototype = {
   takeScreenshot: function () {
     this._Cmds.takeScreenshot();
   },
 
   showRuntimeDetails: function () {
     this._Cmds.showRuntimeDetails();
   },
 
-  showPermissionsTable: function () {
-    this._Cmds.showPermissionsTable();
-  },
-
   showDevicePreferences: function () {
     this._Cmds.showDevicePrefs();
   },
 
   showSettings: function () {
     this._Cmds.showSettings();
   },
 
@@ -90,38 +86,35 @@ RuntimeList.prototype = {
     RuntimeScanners.scan();
   },
 
   updateCommands: function () {
     let doc = this._doc;
 
     // Runtime commands
     let screenshotCmd = doc.querySelector("#runtime-screenshot");
-    let permissionsCmd = doc.querySelector("#runtime-permissions");
     let detailsCmd = doc.querySelector("#runtime-details");
     let disconnectCmd = doc.querySelector("#runtime-disconnect");
     let devicePrefsCmd = doc.querySelector("#runtime-preferences");
     let settingsCmd = doc.querySelector("#runtime-settings");
 
     if (AppManager.connected) {
       if (AppManager.deviceFront) {
         detailsCmd.removeAttribute("disabled");
-        permissionsCmd.removeAttribute("disabled");
         screenshotCmd.removeAttribute("disabled");
       }
       if (AppManager.preferenceFront) {
         devicePrefsCmd.removeAttribute("disabled");
       }
       if (AppManager.settingsFront) {
         settingsCmd.removeAttribute("disabled");
       }
       disconnectCmd.removeAttribute("disabled");
     } else {
       detailsCmd.setAttribute("disabled", "true");
-      permissionsCmd.setAttribute("disabled", "true");
       screenshotCmd.setAttribute("disabled", "true");
       disconnectCmd.setAttribute("disabled", "true");
       devicePrefsCmd.setAttribute("disabled", "true");
       settingsCmd.setAttribute("disabled", "true");
     }
   },
 
   update: function () {
--- a/devtools/client/webide/test/chrome.ini
+++ b/devtools/client/webide/test/chrome.ini
@@ -49,17 +49,16 @@ support-files =
 skip-if = (os == "win" && os_version == "10.0") # Bug 1197053
 [test_import.html]
 [test_duplicate_import.html]
 [test_runtime.html]
 [test_manifestUpdate.html]
 [test_addons.html]
 skip-if = true # Bug 1201392 - Update add-ons after migration
 [test_device_runtime.html]
-[test_device_permissions.html]
 [test_autoconnect_runtime.html]
 [test_autoselect_project.html]
 [test_telemetry.html]
 skip-if = true # Bug 1201392 - Update add-ons after migration
 [test_device_preferences.html]
 [test_device_settings.html]
 [test_fullscreenToolbox.html]
 [test_zoom.html]
deleted file mode 100644
--- a/devtools/client/webide/test/test_device_permissions.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-
-  <head>
-    <meta charset="utf8">
-    <title></title>
-
-    <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-    <script type="application/javascript" src="chrome://mochikit/content/chrome-harness.js"></script>
-    <script type="application/javascript;version=1.8" src="head.js"></script>
-    <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
-  </head>
-
-  <body>
-
-    <script type="application/javascript;version=1.8">
-      window.onload = function() {
-        SimpleTest.waitForExplicitFinish();
-
-        Task.spawn(function* () {
-          if (!DebuggerServer.initialized) {
-            DebuggerServer.init();
-            DebuggerServer.addBrowserActors();
-          }
-
-          let win = yield openWebIDE();
-
-          let permIframe = win.document.querySelector("#deck-panel-permissionstable");
-          let docRuntime = getRuntimeDocument(win);
-          let winRuntime = getRuntimeWindow(win);
-
-          yield connectToLocalRuntime(win);
-
-          let perm = docRuntime.querySelector("#runtime-permissions");
-
-          ok(!perm.hasAttribute("disabled"), "perm cmd enabled");
-
-          let deck = win.document.querySelector("#deck");
-
-          winRuntime.runtimeList.showPermissionsTable();
-          is(deck.selectedPanel, permIframe, "permission iframe selected");
-
-          yield nextTick();
-
-          yield lazyIframeIsLoaded(permIframe);
-
-          yield permIframe.contentWindow.getRawPermissionsTablePromise;
-
-          doc = permIframe.contentWindow.document;
-          trs = doc.querySelectorAll(".line");
-          found = false;
-          for (let tr of trs) {
-            let [name,v1,v2,v3] = tr.querySelectorAll("td");
-            if (name.textContent == "geolocation") {
-              found = true;
-              is(v1.className, "permprompt", "geolocation perm is valid");
-              is(v2.className, "permprompt", "geolocation perm is valid");
-              is(v3.className, "permprompt", "geolocation perm is valid");
-              break;
-            }
-          }
-          ok(found, "Found geolocation line");
-
-          doc.querySelector("#close").click();
-
-          ok(!deck.selectedPanel, "No panel selected");
-
-          DebuggerServer.destroy();
-
-          yield closeWebIDE(win);
-
-          SimpleTest.finish();
-        }).then(null, e => {
-          ok(false, "Exception: " + e);
-          SimpleTest.finish();
-        });
-      }
-    </script>
-  </body>
-</html>
--- a/devtools/client/webide/themes/jar.mn
+++ b/devtools/client/webide/themes/jar.mn
@@ -7,17 +7,16 @@ webide.jar:
 * skin/webide.css              (webide.css)
   skin/icons.png               (icons.png)
   skin/details.css             (details.css)
   skin/newapp.css              (newapp.css)
   skin/throbber.svg            (throbber.svg)
   skin/deck.css                (deck.css)
   skin/addons.css              (addons.css)
   skin/runtimedetails.css      (runtimedetails.css)
-  skin/permissionstable.css    (permissionstable.css)
   skin/monitor.css             (monitor.css)
   skin/config-view.css         (config-view.css)
   skin/wifi-auth.css           (wifi-auth.css)
   skin/logs.css                (logs.css)
   skin/panel-listing.css       (panel-listing.css)
   skin/simulator.css           (simulator.css)
   skin/rocket.svg              (rocket.svg)
   skin/noise.png               (noise.png)
--- a/devtools/client/webide/themes/panel-listing.css
+++ b/devtools/client/webide/themes/panel-listing.css
@@ -125,17 +125,16 @@ button.panel-item:not(:disabled):hover {
 
 .configure-button:hover {
   cursor: pointer;
 }
 
 .project-panel-item-openpackaged  { background-image: -moz-image-rect(url("icons.png"), 260, 438, 286, 412); }
 .runtime-panel-item-simulator     { background-image: -moz-image-rect(url("icons.png"), 0, 438, 26, 412); }
 .runtime-panel-item-other         { background-image: -moz-image-rect(url("icons.png"), 26, 438, 52, 412); }
-#runtime-permissions              { background-image: -moz-image-rect(url("icons.png"), 105, 438, 131, 412); }
 #runtime-screenshot               { background-image: -moz-image-rect(url("icons.png"), 131, 438, 156, 412); }
 
 #runtime-preferences,
 #runtime-settings                 { background-image: -moz-image-rect(url("icons.png"), 105, 464, 131, 438); }
 
 #runtime-panel-nousbdevice,
 #runtime-details                  { background-image: -moz-image-rect(url("icons.png"), 156, 438, 182, 412);  }
 
deleted file mode 100644
--- a/devtools/client/webide/themes/permissionstable.css
+++ /dev/null
@@ -1,23 +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/. */
-
-html, body {
-  background: white;
-}
-
-.permissionstable td {
-  text-align: center;
-}
-
-.permallow {
-  color: rgb(152,207,57);
-}
-
-.permprompt {
-  color: rgb(0,158,237);
-}
-
-.permdeny {
-  color: rgb(204,73,8);
-}
--- a/devtools/server/actors/device.js
+++ b/devtools/server/actors/device.js
@@ -8,17 +8,16 @@ const {Ci} = require("chrome");
 const Services = require("Services");
 const protocol = require("devtools/shared/protocol");
 const promise = require("promise");
 const {LongStringActor} = require("devtools/server/actors/string");
 const {DebuggerServer} = require("devtools/server/main");
 const {getSystemInfo, getSetting} = require("devtools/shared/system");
 const {deviceSpec} = require("devtools/shared/specs/device");
 const FileReader = require("FileReader");
-const {PermissionsTable} = require("resource://gre/modules/PermissionsTable.jsm");
 
 var DeviceActor = exports.DeviceActor = protocol.ActorClassWithSpec(deviceSpec, {
   _desc: null,
 
   getDescription: function () {
     return getSystemInfo();
   },
 
@@ -51,20 +50,10 @@ var DeviceActor = exports.DeviceActor = 
     let flags =
           context.DRAWWINDOW_DRAW_CARET |
           context.DRAWWINDOW_DRAW_VIEW |
           context.DRAWWINDOW_USE_WIDGET_LAYERS;
     context.scale(devicePixelRatio, devicePixelRatio);
     context.drawWindow(window, 0, 0, width, height, "rgb(255,255,255)", flags);
     let dataURL = canvas.toDataURL("image/png");
     return new LongStringActor(this.conn, dataURL);
-  },
-
-  getRawPermissionsTable: function () {
-    return {
-      rawPermissionsTable: PermissionsTable,
-      UNKNOWN_ACTION: Ci.nsIPermissionManager.UNKNOWN_ACTION,
-      ALLOW_ACTION: Ci.nsIPermissionManager.ALLOW_ACTION,
-      DENY_ACTION: Ci.nsIPermissionManager.DENY_ACTION,
-      PROMPT_ACTION: Ci.nsIPermissionManager.PROMPT_ACTION
-    };
   }
 });
--- a/devtools/server/tests/mochitest/test_device.html
+++ b/devtools/server/tests/mochitest/test_device.html
@@ -13,17 +13,16 @@ Bug 895360 - [app manager] Device meta d
 <pre id="test">
 <script>
 
 window.onload = function() {
   var Cu = Components.utils;
   var Cc = Components.classes;
   var Ci = Components.interfaces;
 
-  Cu.import("resource://gre/modules/PermissionsTable.jsm");
   var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
   var {DebuggerClient} = require("devtools/shared/client/main");
   var {DebuggerServer} = require("devtools/server/main");
   var Services = require("Services");
 
   SimpleTest.waitForExplicitFinish();
 
   var {getDeviceFront} = require("devtools/shared/fronts/device");
@@ -33,17 +32,17 @@ window.onload = function() {
     DebuggerServer.addBrowserActors();
   }
 
   var client = new DebuggerClient(DebuggerServer.connectPipe());
   client.connect().then(function onConnect() {
     client.listTabs(function onListTabs(aResponse) {
       var d = getDeviceFront(client, aResponse);
 
-      var desc, permissions;
+      var desc;
       var appInfo = Services.appinfo;
       var utils = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
 
 
       var localDesc = {
         appid: appInfo.ID,
         vendor: appInfo.vendor,
         name: appInfo.name,
@@ -67,31 +66,24 @@ window.onload = function() {
         for (var key in localDesc) {
           is(desc[key], localDesc[key], "valid field (" + key + ")");
         }
 
         var currProfD = Services.dirsvc.get("ProfD", Ci.nsIFile);
         var profileDir = currProfD.path;
         ok(profileDir.indexOf(desc.profile.length > 0 && desc.profile) != -1, "valid profile name");
 
-        var a = JSON.stringify(PermissionsTable);
-        var b = JSON.stringify(permissions.rawPermissionsTable);
-
-        is(a, b, "Permissions Tables is valid");
-
         client.close().then(() => {
           DebuggerServer.destroy();
           SimpleTest.finish()
         });
       }
 
 
       d.getDescription().then((v) => desc = v)
-      .then(() => d.getRawPermissionsTable())
-      .then((json) => permissions = json)
       .then(checkValues);
 
     });
   });
 
 }
 </script>
 </pre>
--- a/devtools/shared/specs/device.js
+++ b/devtools/shared/specs/device.js
@@ -7,13 +7,12 @@ const {RetVal, generateActorSpec} = requ
 
 const deviceSpec = generateActorSpec({
   typeName: "device",
 
   methods: {
     getDescription: {request: {}, response: { value: RetVal("json")}},
     getWallpaper: {request: {}, response: { value: RetVal("longstring")}},
     screenshotToDataURL: {request: {}, response: { value: RetVal("longstring")}},
-    getRawPermissionsTable: {request: {}, response: { value: RetVal("json")}},
   },
 });
 
 exports.deviceSpec = deviceSpec;
deleted file mode 100644
--- a/dom/apps/PermissionsTable.jsm
+++ /dev/null
@@ -1,583 +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 = Components.interfaces;
-const Cu = Components.utils;
-
-this.EXPORTED_SYMBOLS = [
-  "PermissionsTable",
-  "PermissionsReverseTable",
-  "expandPermissions",
-  "appendAccessToPermName",
-  "isExplicitInPermissionsTable",
-  "AllPossiblePermissions"
-];
-
-// Permission access flags
-const READONLY = "readonly";
-const CREATEONLY = "createonly";
-const READCREATE = "readcreate";
-const READWRITE = "readwrite";
-
-const UNKNOWN_ACTION = Ci.nsIPermissionManager.UNKNOWN_ACTION;
-const ALLOW_ACTION = Ci.nsIPermissionManager.ALLOW_ACTION;
-const DENY_ACTION = Ci.nsIPermissionManager.DENY_ACTION;
-const PROMPT_ACTION = Ci.nsIPermissionManager.PROMPT_ACTION;
-
-// Permissions Matrix: https://docs.google.com/spreadsheet/ccc?key=0Akyz_Bqjgf5pdENVekxYRjBTX0dCXzItMnRyUU1RQ0E#gid=0
-
-// Permissions that are implicit:
-// battery-status, network-information, vibration,
-// device-capabilities
-
-this.PermissionsTable =  { geolocation: {
-                             app: PROMPT_ACTION,
-                             privileged: PROMPT_ACTION,
-                             certified: PROMPT_ACTION
-                           },
-                           "geolocation-noprompt": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION,
-                             substitute: ["geolocation"]
-                           },
-                           camera: {
-                             app: DENY_ACTION,
-                             privileged: PROMPT_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           alarms: {
-                             app: ALLOW_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "tcp-socket": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "udp-socket": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "network-events": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           contacts: {
-                             app: DENY_ACTION,
-                             privileged: PROMPT_ACTION,
-                             certified: ALLOW_ACTION,
-                             access: ["read", "write", "create"]
-                           },
-                           "device-storage:apps": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION,
-                             access: ["read"]
-                           },
-                           "device-storage:crashes": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION,
-                             access: ["read"]
-                           },
-                           "device-storage:pictures": {
-                             app: DENY_ACTION,
-                             privileged: PROMPT_ACTION,
-                             certified: ALLOW_ACTION,
-                             access: ["read", "write", "create"]
-                           },
-                           "device-storage:videos": {
-                             app: DENY_ACTION,
-                             privileged: PROMPT_ACTION,
-                             certified: ALLOW_ACTION,
-                             access: ["read", "write", "create"]
-                           },
-                           "device-storage:music": {
-                             app: DENY_ACTION,
-                             privileged: PROMPT_ACTION,
-                             certified: ALLOW_ACTION,
-                             access: ["read", "write", "create"]
-                           },
-                           "device-storage:sdcard": {
-                             app: DENY_ACTION,
-                             privileged: PROMPT_ACTION,
-                             certified: ALLOW_ACTION,
-                             access: ["read", "write", "create"]
-                           },
-                           sms: {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "speech-recognition": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           browser: {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "browser:universalxss": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           mobilenetwork: {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           power: {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           push: {
-                            app: ALLOW_ACTION,
-                            privileged: ALLOW_ACTION,
-                            certified: ALLOW_ACTION
-                           },
-                           settings: {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION,
-                             access: ["read", "write"],
-                             additional: ["indexedDB-chrome-settings", "settings-api"]
-                           },
-                           // This exists purely for tests, no app
-                           // should ever use it. It can only be
-                           // handed out by SpecialPowers.
-                           "settings-clear": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: DENY_ACTION,
-                             additional: ["indexedDB-chrome-settings", "settings-api"]
-                           },
-                           permissions: {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           attention: {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "global-clickthrough-overlay": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "moz-attention": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION,
-                             substitute: ["attention"]
-                           },
-                           "webapps-manage": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "homescreen-webapps-manage": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "backgroundservice": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "desktop-notification": {
-                             app: ALLOW_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "networkstats-manage": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "wifi-manage": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "systemXHR": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "idle": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "time": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "background-sensors": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "audio-channel-normal": {
-                             app: ALLOW_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "audio-channel-content": {
-                             app: ALLOW_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "audio-channel-notification": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "audio-channel-alarm": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "audio-channel-system": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "audio-channel-telephony": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "moz-audio-channel-telephony": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION,
-                             substitute: ["audio-channel-telephony"]
-                           },
-                           "audio-channel-ringer": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "moz-audio-channel-ringer": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION,
-                             substitute: ["audio-channel-ringer"]
-                           },
-                           "audio-channel-publicnotification": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "open-remote-window": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "input": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "input-manage": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "audio-capture": {
-                             app: PROMPT_ACTION,
-                             privileged: PROMPT_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "audio-capture:3gpp": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "audio-capture:3gpp2": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "speaker-control": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "downloads": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "video-capture": {
-                             app: PROMPT_ACTION,
-                             privileged: PROMPT_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "feature-detection": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           // This permission doesn't actually grant access to
-                           // anything. It exists only to check the correctness
-                           // of web prompt composed permissions in tests.
-                           "test-permission": {
-                             app: PROMPT_ACTION,
-                             privileged: PROMPT_ACTION,
-                             certified: ALLOW_ACTION,
-                             access: ["read", "write", "create"]
-                           },
-                           "firefox-accounts": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "moz-firefox-accounts": {
-                             app: DENY_ACTION,
-                             privileged: PROMPT_ACTION,
-                             certified: ALLOW_ACTION,
-                             substitute: ["firefox-accounts"]
-                           },
-                           "themeable": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "settings:wallpaper.image": {
-                             app: DENY_ACTION,
-                             privileged: ALLOW_ACTION,
-                             certified: ALLOW_ACTION,
-                             access: ["read", "write"],
-                             additional: ["settings-api"]
-                           },
-                           "tv": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "before-after-keyboard-event": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "presentation-device-manage": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "secureelement-manage": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "inputport": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "system-update": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "open-hidden-window": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "moz-extremely-unstable-and-will-change-webcomponents": {
-                              app: DENY_ACTION,
-                              trusted: DENY_ACTION,
-                              privileged: ALLOW_ACTION,
-                              certified: ALLOW_ACTION
-                           },
-                           "system-app-only-audio-channels-in-app": {
-                             app: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           },
-                           "previously-certified-app": {
-                             app: DENY_ACTION,
-                             trusted: DENY_ACTION,
-                             privileged: DENY_ACTION,
-                             certified: ALLOW_ACTION
-                           }
-                         };
-
-/**
- * Append access modes to the permission name as suffixes.
- *   e.g. permission name 'contacts' with ['read', 'write'] =
- *   ['contacts-read', contacts-write']
- * @param string aPermName
- * @param array aAccess
- * @returns array containing access-appended permission names.
- **/
-this.appendAccessToPermName = function appendAccessToPermName(aPermName, aAccess) {
-  if (aAccess.length == 0) {
-    return [aPermName];
-  }
-  return aAccess.map(function(aMode) {
-    return aPermName + "-" + aMode;
-  });
-};
-
-/**
- * Expand an access string into multiple permission names,
- *   e.g: permission name 'contacts' with 'readwrite' =
- *   ['contacts-read', 'contacts-create', 'contacts-write']
- * @param string aPermName
- * @param string aAccess (optional)
- * @returns array containing expanded permission names.
- **/
-this.expandPermissions = function expandPermissions(aPermName, aAccess) {
-  if (!PermissionsTable[aPermName]) {
-    let errorMsg =
-      "PermissionsTable.jsm: expandPermissions: Unknown Permission: " + aPermName;
-    Cu.reportError(errorMsg);
-    dump(errorMsg);
-    return [];
-  }
-
-  const tableEntry = PermissionsTable[aPermName];
-
-  if (tableEntry.substitute && tableEntry.additional) {
-    let errorMsg =
-      "PermissionsTable.jsm: expandPermissions: Can't handle both 'substitute' " +
-      "and 'additional' entries for permission: " + aPermName;
-    Cu.reportError(errorMsg);
-    dump(errorMsg);
-    return [];
-  }
-
-  if (!aAccess && tableEntry.access ||
-      aAccess && !tableEntry.access) {
-    let errorMsg =
-      "PermissionsTable.jsm: expandPermissions: Invalid access for permission " +
-      aPermName + ": " + aAccess + "\n";
-    Cu.reportError(errorMsg);
-    dump(errorMsg);
-    return [];
-  }
-
-  let expandedPermNames = [];
-
-  if (tableEntry.access && aAccess) {
-    let requestedSuffixes = [];
-    switch (aAccess) {
-    case READONLY:
-      requestedSuffixes.push("read");
-      break;
-    case CREATEONLY:
-      requestedSuffixes.push("create");
-      break;
-    case READCREATE:
-      requestedSuffixes.push("read", "create");
-      break;
-    case READWRITE:
-      requestedSuffixes.push("read", "create", "write");
-      break;
-    default:
-      return [];
-    }
-
-    let permArr = appendAccessToPermName(aPermName, requestedSuffixes);
-
-    // Add the same suffix to each of the additions.
-    if (tableEntry.additional) {
-      for (let additional of tableEntry.additional) {
-        permArr = permArr.concat(appendAccessToPermName(additional, requestedSuffixes));
-      }
-    }
-
-    // Only add the suffixed version if the suffix exists in the table.
-    for (let idx in permArr) {
-      let suffix = requestedSuffixes[idx % requestedSuffixes.length];
-      if (tableEntry.access.indexOf(suffix) != -1) {
-        expandedPermNames.push(permArr[idx]);
-      }
-    }
-  } else if (tableEntry.substitute) {
-    expandedPermNames = expandedPermNames.concat(tableEntry.substitute);
-  } else {
-    expandedPermNames.push(aPermName);
-    // Include each of the additions exactly as they appear in the table.
-    if (tableEntry.additional) {
-      expandedPermNames = expandedPermNames.concat(tableEntry.additional);
-    }
-  }
-
-  return expandedPermNames;
-};
-
-this.PermissionsReverseTable = {};
-this.AllPossiblePermissions = [];
-
-(function () {
-  // PermissionsTable as it is works well for direct searches, but not
-  // so well for reverse ones (that is, if I get something like
-  // device-storage:music-read or indexedDB-chrome-settings-read how
-  // do I know which permission it really is? Hence this table is
-  // born. The idea is that
-  // reverseTable[device-storage:music-read] should return
-  // device-storage:music
-  //
-  // We also need a list of all the possible permissions for things like the
-  // settingsmanager, so construct that while we're at it.
-  for (let permName in PermissionsTable) {
-    let permAliases = [];
-    if (PermissionsTable[permName].access) {
-      permAliases = expandPermissions(permName, "readwrite");
-    } else if (!PermissionsTable[permName].substitute) {
-      permAliases = expandPermissions(permName);
-    }
-    for (let i = 0; i < permAliases.length; i++) {
-      PermissionsReverseTable[permAliases[i]] = permName;
-      AllPossiblePermissions.push(permAliases[i]);
-    }
-  }
-  AllPossiblePermissions =
-    AllPossiblePermissions.concat(["indexedDB", "offline-app", "pin-app"]);
-})();
-
-this.isExplicitInPermissionsTable = function(aPermName, aIntStatus) {
-
-  // Check to see if the 'webapp' is app/privileged/certified.
-  let appStatus;
-  switch (aIntStatus) {
-    case Ci.nsIPrincipal.APP_STATUS_CERTIFIED:
-      appStatus = "certified";
-      break;
-    case Ci.nsIPrincipal.APP_STATUS_PRIVILEGED:
-      appStatus = "privileged";
-      break;
-    default: // If it isn't certified or privileged, it's app
-      appStatus = "app";
-      break;
-  }
-
-  let realPerm = PermissionsReverseTable[aPermName];
-
-  if (realPerm) {
-    return (PermissionsTable[realPerm][appStatus] ==
-            Ci.nsIPermissionManager.PROMPT_ACTION);
-  } else {
-    return false;
-  }
-}
deleted file mode 100644
--- a/dom/apps/moz.build
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-EXTRA_JS_MODULES += [
-    'PermissionsTable.jsm',
-]
deleted file mode 100755
--- a/dom/apps/tests/create_test_receipts.py
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/env python
-
-import jwt
-
-receipt1 = {
-  "typ": "purchase-receipt",
-  "product": {
-    "url": "https://www.mozilla.org",
-    "storedata": "5169314356"
-  },
-  "user": {
-    "type": "directed-identifier",
-    "value": "4fb35151-2b9b-4ba2-8283-c49d381640bd"
-  },
-  "iss": "http://mochi.test:8888",
-  "nbf": 131360185,
-  "iat": 131360188,
-  "detail": "http://mochi.test:8888/receipt/5169314356",
-  "verify": "http://mochi.test:8888/verify/5169314356",
-  "reissue": "http://mochi.test:8888/reissue/5169314356"
-}
-
-receipt2 = {
-  "typ": "purchase-receipt",
-  "product": {
-    "url": "https://www.mozilla.org",
-    "storedata": "5169314357"
-  },
-  "user": {
-    "type": "directed-identifier",
-    "value": "4fb35151-2b9b-4ba2-8283-c49d381640bd"
-  },
-  "iss": "http://mochi.test:8888",
-  "nbf": 131360185,
-  "iat": 131360188,
-  "detail": "http://mochi.test:8888/receipt/5169314356",
-  "verify": "http://mochi.test:8888/verify/5169314356",
-  "reissue": "http://mochi.test:8888/reissue/5169314356"
-}
-
-receipt_without_typ = {
-  "product": {
-    "url": "https://www.mozilla.org",
-    "storedata": "5169314358"
-  },
-  "user": {
-    "type": "directed-identifier",
-    "value": "4fb35151-2b9b-4ba2-8283-c49d381640bd"
-  },
-  "iss": "http://mochi.test:8888",
-  "nbf": 131360185,
-  "iat": 131360188,
-  "detail": "http://mochi.test:8888/receipt/5169314356",
-  "verify": "http://mochi.test:8888/verify/5169314356",
-  "reissue": "http://mochi.test:8888/reissue/5169314356"
-}
-
-receipt_without_product = {
-  "typ": "purchase-receipt",
-  "user": {
-    "type": "directed-identifier",
-    "value": "4fb35151-2b9b-4ba2-8283-c49d381640bd"
-  },
-  "iss": "http://mochi.test:8888",
-  "nbf": 131360185,
-  "iat": 131360188,
-  "detail": "http://mochi.test:8888/receipt/5169314356",
-  "verify": "http://mochi.test:8888/verify/5169314356",
-  "reissue": "http://mochi.test:8888/reissue/5169314356"
-}
-
-receipt_without_user = {
-  "typ": "purchase-receipt",
-  "product": {
-    "url": "https://www.mozilla.org",
-    "storedata": "5169314358"
-  },
-  "iss": "http://mochi.test:8888",
-  "nbf": 131360185,
-  "iat": 131360188,
-  "detail": "http://mochi.test:8888/receipt/5169314356",
-  "verify": "http://mochi.test:8888/verify/5169314356",
-  "reissue": "http://mochi.test:8888/reissue/5169314356"
-}
-
-receipt_without_iss = {
-  "typ": "purchase-receipt",
-  "product": {
-    "url": "https://www.mozilla.org",
-    "storedata": "5169314358"
-  },
-  "user": {
-    "type": "directed-identifier",
-    "value": "4fb35151-2b9b-4ba2-8283-c49d381640bd"
-  },
-  "nbf": 131360185,
-  "iat": 131360188,
-  "detail": "http://mochi.test:8888/receipt/5169314356",
-  "verify": "http://mochi.test:8888/verify/5169314356",
-  "reissue": "http://mochi.test:8888/reissue/5169314356"
-}
-
-receipt_without_nbf = {
-  "typ": "purchase-receipt",
-  "product": {
-    "url": "https://www.mozilla.org",
-    "storedata": "5169314358"
-  },
-  "user": {
-    "type": "directed-identifier",
-    "value": "4fb35151-2b9b-4ba2-8283-c49d381640bd"
-  },
-  "iss": "http://mochi.test:8888",
-  "iat": 131360188,
-  "detail": "http://mochi.test:8888/receipt/5169314356",
-  "verify": "http://mochi.test:8888/verify/5169314356",
-  "reissue": "http://mochi.test:8888/reissue/5169314356"
-}
-
-receipt_without_iat = {
-  "typ": "purchase-receipt",
-  "product": {
-    "url": "https://www.mozilla.org",
-    "storedata": "5169314358"
-  },
-  "user": {
-    "type": "directed-identifier",
-    "value": "4fb35151-2b9b-4ba2-8283-c49d381640bd"
-  },
-  "iss": "http://mochi.test:8888",
-  "nbf": 131360185,
-  "detail": "http://mochi.test:8888/receipt/5169314356",
-  "verify": "http://mochi.test:8888/verify/5169314356",
-  "reissue": "http://mochi.test:8888/reissue/5169314356"
-}
-
-receipt_with_wrong_typ = {
-  "typ": "fake",
-  "product": {
-    "url": "https://www.mozilla.org",
-    "storedata": "5169314358"
-  },
-  "user": {
-    "type": "directed-identifier",
-    "value": "4fb35151-2b9b-4ba2-8283-c49d381640bd"
-  },
-  "iss": "http://mochi.test:8888",
-  "nbf": 131360185,
-  "iat": 131360188,
-  "detail": "http://mochi.test:8888/receipt/5169314356",
-  "verify": "http://mochi.test:8888/verify/5169314356",
-  "reissue": "http://mochi.test:8888/reissue/5169314356"
-}
-
-print("let valid_receipt1 = \"" + jwt.encode(receipt1, "") + "\";\n")
-print("let valid_receipt2 = \"" + jwt.encode(receipt2, "") + "\";\n")
-print("let receipt_without_typ = \"" + jwt.encode(receipt_without_typ, "") + "\";\n")
-print("let receipt_without_product = \"" + jwt.encode(receipt_without_product, "") + "\";\n")
-print("let receipt_without_user = \"" + jwt.encode(receipt_without_user, "") + "\";\n")
-print("let receipt_without_iss = \"" + jwt.encode(receipt_without_iss, "") + "\";\n")
-print("let receipt_without_nbf = \"" + jwt.encode(receipt_without_nbf, "") + "\";\n")
-print("let receipt_without_iat = \"" + jwt.encode(receipt_without_iat, "") + "\";\n")
-print("let receipt_with_wrong_typ = \"" + jwt.encode(receipt_with_wrong_typ, "") + "\";\n")
deleted file mode 100644
--- a/dom/apps/tests/head.js
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-function runAll(steps) {
-  SimpleTest.waitForExplicitFinish();
-
-  // Clone the array so we don't modify the original.
-  steps = steps.concat();
-  function next() {
-    if (steps.length) {
-      steps.shift()(next);
-    }
-    else {
-      SimpleTest.finish();
-    }
-  }
-  next();
-}
-
-function confirmNextPopup() {
-  var Ci = SpecialPowers.Ci;
-
-  var popupNotifications = SpecialPowers.wrap(window).top.
-                           QueryInterface(Ci.nsIInterfaceRequestor).
-                           getInterface(Ci.nsIWebNavigation).
-                           QueryInterface(Ci.nsIDocShell).
-                           chromeEventHandler.ownerDocument.defaultView.
-                           PopupNotifications;
-
-  var popupPanel = popupNotifications.panel;
-
-  function onPopupShown() {
-    popupPanel.removeEventListener("popupshown", onPopupShown, false);
-    SpecialPowers.wrap(this).childNodes[0].button.doCommand();
-    popupNotifications._dismiss();
-  }
-  popupPanel.addEventListener("popupshown", onPopupShown, false);
-}
-
-function promiseNoPopup() {
-  var Ci = SpecialPowers.Ci;
-
-  var popupNotifications = SpecialPowers.wrap(window).top.
-                           QueryInterface(Ci.nsIInterfaceRequestor).
-                           getInterface(Ci.nsIWebNavigation).
-                           QueryInterface(Ci.nsIDocShell).
-                           chromeEventHandler.ownerDocument.defaultView.
-                           PopupNotifications;
-
-  return new Promise((resolve) => {
-    var tries = 0;
-    var interval = setInterval(function() {
-      if (tries >= 30) {
-        ok(true, "The webapps-install notification didn't appear");
-        moveOn();
-      }
-
-      if (popupNotifications.getNotification("webapps-install")) {
-        ok(false, "Found the webapps-install notification");
-        moveOn();
-      }
-      tries++;
-    }, 100);
-
-    var moveOn = () => {
-      clearInterval(interval);
-      resolve();
-    };
-  });
-}
-
-// We need to mock the Alerts service, otherwise the alert that is shown
-// at the end of an installation makes the test leak the app's icon.
-
-const CID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID();
-const ALERTS_SERVICE_CONTRACT_ID = "@mozilla.org/alerts-service;1";
-const ALERTS_SERVICE_CID = Components.ID(Cc[ALERTS_SERVICE_CONTRACT_ID].number);
-
-var AlertsService = {
-  classID: Components.ID(CID),
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory,
-                                         Ci.nsIAlertsService]),
-
-  createInstance: function(aOuter, aIID) {
-    if (aOuter) {
-      throw Cr.NS_ERROR_NO_AGGREGATION;
-    }
-
-    return this.QueryInterface(aIID);
-  },
-
-  init: function() {
-    Components.manager.nsIComponentRegistrar.registerFactory(this.classID,
-      "", ALERTS_SERVICE_CONTRACT_ID, this);
-  },
-
-  restore: function() {
-    Components.manager.nsIComponentRegistrar.registerFactory(ALERTS_SERVICE_CID,
-      "", ALERTS_SERVICE_CONTRACT_ID, null);
-  },
-
-  showAlert: function() {
-  },
-
-  showAlertNotification: function() {
-  },
-};
-
-AlertsService.init();
-
-SimpleTest.registerCleanupFunction(() => {
-  AlertsService.restore();
-});
--- a/dom/media/MediaRecorder.cpp
+++ b/dom/media/MediaRecorder.cpp
@@ -98,18 +98,32 @@ private:
   static RecordersArray& GetRecorders()
   {
     return UniqueInstance()->mRecorders;
   }
   RecordersArray mRecorders;
 };
 NS_IMPL_ISUPPORTS(MediaRecorderReporter, nsIMemoryReporter);
 
-NS_IMPL_CYCLE_COLLECTION_INHERITED(MediaRecorder, DOMEventTargetHelper,
-                                   mDOMStream, mAudioNode)
+NS_IMPL_CYCLE_COLLECTION_CLASS(MediaRecorder)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaRecorder,
+                                                  DOMEventTargetHelper)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMStream)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioNode)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaRecorder,
+                                                DOMEventTargetHelper)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMStream)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioNode)
+  tmp->UnRegisterActivityObserver();
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaRecorder)
   NS_INTERFACE_MAP_ENTRY(nsIDocumentActivity)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(MediaRecorder, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(MediaRecorder, DOMEventTargetHelper)
 
@@ -1019,33 +1033,30 @@ MediaRecorder::MediaRecorder(AudioNode& 
 
   RegisterActivityObserver();
 }
 
 void
 MediaRecorder::RegisterActivityObserver()
 {
   if (nsPIDOMWindowInner* window = GetOwner()) {
-    nsIDocument* doc = window->GetExtantDoc();
-    if (doc) {
-      doc->RegisterActivityObserver(
+    mDocument = window->GetExtantDoc();
+    if (mDocument) {
+      mDocument->RegisterActivityObserver(
         NS_ISUPPORTS_CAST(nsIDocumentActivity*, this));
     }
   }
 }
 
 void
 MediaRecorder::UnRegisterActivityObserver()
 {
-  if (nsPIDOMWindowInner* window = GetOwner()) {
-    nsIDocument* doc = window->GetExtantDoc();
-    if (doc) {
-      doc->UnregisterActivityObserver(
-        NS_ISUPPORTS_CAST(nsIDocumentActivity*, this));
-    }
+  if (mDocument) {
+    mDocument->UnregisterActivityObserver(
+      NS_ISUPPORTS_CAST(nsIDocumentActivity*, this));
   }
 }
 
 void
 MediaRecorder::SetMimeType(const nsString &aMimeType)
 {
   mMimeType = aMimeType;
 }
--- a/dom/media/MediaRecorder.h
+++ b/dom/media/MediaRecorder.h
@@ -143,16 +143,19 @@ protected:
   // Connect source node to the pipe stream.
   RefPtr<MediaInputPort> mInputPort;
 
   // The current state of the MediaRecorder object.
   RecordingState mState;
   // Hold the sessions reference and clean it when the DestroyRunnable for a
   // session is running.
   nsTArray<RefPtr<Session> > mSessions;
+
+  nsCOMPtr<nsIDocument> mDocument;
+
   // It specifies the container format as well as the audio and video capture formats.
   nsString mMimeType;
 
   uint32_t mAudioBitsPerSecond;
   uint32_t mVideoBitsPerSecond;
   uint32_t mBitsPerSecond;
 private:
   // Register MediaRecorder into Document to listen the activity changes.
--- a/dom/moz.build
+++ b/dom/moz.build
@@ -31,17 +31,16 @@ interfaces = [
     'smil',
     'push',
 ]
 
 DIRS += ['interfaces/' + i for i in interfaces]
 
 DIRS += [
     'animation',
-    'apps',
     'base',
     'archivereader',
     'bindings',
     'battery',
     'browser-element',
     'cache',
     'canvas',
     'crypto',
--- a/dom/permission/moz.build
+++ b/dom/permission/moz.build
@@ -11,18 +11,13 @@ EXPORTS.mozilla.dom += [
 
 UNIFIED_SOURCES += [
     'PermissionObserver.cpp',
     'Permissions.cpp',
     'PermissionStatus.cpp',
     'PermissionUtils.cpp',
 ]
 
-XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
-
 MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
 
-if CONFIG['MOZ_TIME_MANAGER']:
-    MOCHITEST_MANIFESTS += ['tests/mochitest-time.ini']
-
 FINAL_LIBRARY = 'xul'
 
 include('/ipc/chromium/chromium-config.mozbuild')
deleted file mode 100644
--- a/dom/permission/tests/file_framework.js
+++ /dev/null
@@ -1,224 +0,0 @@
-/** Test for Bug 815105 **/
-/*
- * gData is an array of object that tests using this framework must pass in
- * The current tests only pass in a single element array. Each test in
- * gData is executed by the framework for a given file
- *
- * Fields in gData object
- * perms   (required) Array of Strings
- *         list of permissions that this test will need. See
- *         http://dxr.mozilla.org/mozilla-central/source/dom/apps/src/PermissionsTable.jsm
- *         These permissions are added after a sanity check and removed at
- *         test conclusion
- *
- * obj     (required for default verifier) String
- *         The name of the window.navigator object used for accessing the
- *         WebAPI during the tests
- *
- * webidl  (required for default verifier) String
- * idl     (required for default verifier) String
- *         Only one of webidl / idl is required
- *         The IDL describing the navigator object. The returned object
- *         during tests /must/ be an instanceof this
- *
- * skip    (optional) Array of Strings
- *         A list of navigator.userAgent's to skip the second part of tests
- *         on. The tests still verify that you can't get obj on those
- *         platforms without permissions, however it is expected that adding
- *         the permission still won't allow access to those objects
- *
- * settings (optional) Array of preference tuples
- *         A list of settings that need to be set before this API is
- *         enabled. Note the settings are set before the sanity check is
- *         performed. If an API gates access only by preferences, then it
- *         will fail the initial test
- *
- * verifier (optional) Function
- *         A function used to test whether a WebAPI is accessible or not.
- *         The function takes a success and failure callback which both
- *         accept a msg argument. msg is surfaced up to the top level tests
- *         A default verifier is provided which only attempts to access
- *         the navigator object.
- *
- * needParentPerm (optional) Boolean
- *         Whether or not the parent frame requires these permissions as
- *         well. Otherwise the test process may be killed.
- */
-
-SimpleTest.waitForExplicitFinish();
-var expand = SpecialPowers.Cu.import("resource://gre/modules/PermissionsTable.jsm").expandPermissions;
-const permTable = SpecialPowers.Cu.import("resource://gre/modules/PermissionsTable.jsm").PermissionsTable;
-
-const TEST_DOMAIN = "http://example.org";
-const SHIM_PATH = "/tests/dom/permission/tests/file_shim.html"
-var gContent = document.getElementById('content');
-
-//var gData; defined in external files
-var gCurrentTest = 0;
-var gRemainingTests;
-var pendingTests = {};
-
-function PermTest(aData) {
-  var self = this;
-  var skip = aData.skip || false;
-  this.step = 0;
-  this.data = aData;
-  this.isSkip = skip &&
-                skip.some(function (el) {
-                          return navigator.
-                                 userAgent.toLowerCase().
-                                 indexOf(el.toLowerCase()) != -1;
-                        });
-
-  this.setupParent = false;
-  this.perms = expandPermissions(aData.perm);
-  this.id = gCurrentTest++;
-  this.iframe = null;
-
-  // keep a reference to this for eventhandler
-  pendingTests[this.id] = this;
-
-  this.createFrame = function() {
-    if (self.iframe) {
-      gContent.removeChild(self.iframe);
-    }
-    var iframe = document.createElement('iframe');
-    iframe.setAttribute('id', 'testframe' + self.step + self.perms)
-    iframe.setAttribute('remote', true);
-    iframe.src = TEST_DOMAIN + SHIM_PATH;
-    iframe.addEventListener('load', function _iframeLoad() {
-      iframe.removeEventListener('load', _iframeLoad);
-
-      // check permissions are correct
-      var allow = (self.step == 0 ? false : true);
-      self.perms.forEach(function (el) {
-        try {
-        var res = SpecialPowers.hasPermission(el, SpecialPowers.wrap(iframe)
-                                                  .contentDocument);
-        is(res, allow, (allow ? "Has " : "Doesn't have ") + el);
-        } catch(e) {
-          ok(false, "failed " + e);
-        }
-      });
-
-      var msg = {
-        id: self.id,
-        step: self.step++,
-        testdata: self.data,
-      }
-      // start the tests
-      iframe.contentWindow.postMessage(msg, "*");
-    });
-
-    self.iframe = iframe;
-    gContent.appendChild(iframe);
-  }
-
-  this.next = function () {
-    switch(self.step) {
-    case 0:
-      self.createFrame();
-    break;
-    case 1:
-      // add permissions
-      addPermissions(self.perms, SpecialPowers.
-                                 wrap(self.iframe).
-                                 contentDocument,
-                     self.createFrame.bind(self));
-    break;
-    case 2:
-      if (self.iframe) {
-        gContent.removeChild(self.iframe);
-      }
-      checkFinish();
-    break;
-    default:
-      ok(false, "Should not be reached");
-    break
-    }
-  }
-
-  this.start = function() {
-    // some permissions need parent to have permission as well
-    if (!self.setupParent && self.data.needParentPerm &&
-        !SpecialPowers.isMainProcess()) {
-      self.setupParent = true;
-      addPermissions(self.perms, window.document, self.start.bind(self));
-    } else if (self.data.settings && self.data.settings.length) {
-      SpecialPowers.pushPrefEnv({'set': self.data.settings.slice(0)},
-                                self.next.bind(self));
-    } else {
-      self.next();
-    }
-  }
-}
-
-function addPermissions(aPerms, aDoc, aCallback) {
-  var permList = [];
-  aPerms.forEach(function (el) {
-    var obj = {'type': el,
-               'allow': 1,
-               'context': aDoc};
-    permList.push(obj);
-  });
-  SpecialPowers.pushPermissions(permList, aCallback);
-}
-
-function expandPermissions(aPerms) {
-  var perms = [];
-  aPerms.forEach(function(el) {
-    var access = permTable[el].access ? "readwrite" : null;
-    var expanded = expand(el, access);
-    for (let i = 0; i < expanded.length; i++) {
-      perms.push(SpecialPowers.unwrap(expanded[i]));
-    }
-  });
-
-  return perms;
-}
-
-function msgHandler(evt) {
-  var data = evt.data;
-  var test = pendingTests[data.id];
-
-  /*
-   * step 2 of tests should fail on
-   * platforms which are skipped
-   */
-  if (test.isSkip && test.step == 2) {
-    todo(data.result, data.msg);
-  } else {
-    ok(data.result, data.msg);
-  }
-
-  if (test) {
-    test.next();
-  } else {
-    ok(false, "Received unknown id " + data.id);
-    checkFinish();
-  }
-}
-
-function checkFinish() {
-  if (--gRemainingTests) {
-    gTestRunner.next();
-  } else {
-    window.removeEventListener('message', msgHandler);
-    SimpleTest.finish();
-  }
-}
-
-function runTest() {
-  gRemainingTests = Object.keys(gData).length;
-
-  for (var test in gData) {
-    var test = new PermTest(gData[test]);
-    test.start();
-    yield undefined;
-  }
-}
-
-var gTestRunner = runTest();
-
-window.addEventListener('load', function() { gTestRunner.next(); }, false);
-window.addEventListener('message', msgHandler, false);
deleted file mode 100644
--- a/dom/permission/tests/file_shim.html
+++ /dev/null
@@ -1,99 +0,0 @@
-<html>
-<head>
-<script type="application/javascript;version=1.8">
-function TestData(aOpts) {
-  for (var opt in aOpts) {
-    if (aOpts.hasOwnProperty(opt)) {
-      this[opt] = aOpts[opt];
-    }
-  }
-}
-
-TestData.prototype = {
-  getObj: function() {
-    if (!this.obj) {
-      return null;
-    }
-
-    // only one of the 2 should be set
-    if ((this.idl && this.webidl) ||
-        (!this.idl && !this.webidl)) {
-      return null;
-    }
-
-    // split on . to allow nested props
-    var props = this.obj.split(".");
-    var obj = window.navigator;
-
-    for (var i = 0; i < props.length && obj !== undefined; i++) {
-      obj = obj[props[i]];
-    }
-
-    if ((this.webidl && obj instanceof window[this.webidl]) ||
-        (this.idl && obj instanceof SpecialPowers.Ci[this.idl])) {
-      return obj;
-    } else {
-      return null;
-    }
-  },
-
-  // default verifier
-  verifier: function(success, failure) {
-    try {
-      if (this.getObj()) {
-        success(this.perm);
-      } else {
-        failure("Did not receive proper object");
-      }
-    } catch (e) {
-      failure("Received exception!: " + e);
-    }
-  },
-}
-
-function receiveMessage(e) {
-  var src = e.source;
-  var step = e.data.step;
-  var id = e.data.id;
-  var data = new TestData(e.data.testdata);
-  var success, failure;
-
-  function reply(res, msg) {
-    window.removeEventListener("message", receiveMessage, false);
-    src.postMessage({result: res, msg: msg,
-                     id: id}, "*");
-  }
-
-  function _success(msg) {
-    reply(true, msg);
-  }
-
-  function _failure(msg) {
-    reply(false, msg);
-  }
-
-  // flip success and failure around for precheck
-  if (step == 0) {
-    success = _failure;
-    failure = _success;
-  } else {
-    success = _success;
-    failure = _failure;
-  }
-
-  if (data.verifier instanceof Function) {
-    data.verifier(success, failure);
-  } else {
-    // import toSource() function to global
-    eval(data.verifier);
-    verifier.bind(data, success, failure)();
-  }
-}
-
-window.addEventListener("message", receiveMessage, false);
-</script>
-</head>
-<body>
-<div id="content" style="display: none"></div>
-</body>
-</html>
deleted file mode 100644
--- a/dom/permission/tests/mochitest-time.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-[test_time.html]
--- a/dom/permission/tests/mochitest.ini
+++ b/dom/permission/tests/mochitest.ini
@@ -1,27 +1,5 @@
 [DEFAULT]
 support-files =
-  file_framework.js
-  file_shim.html
   file_empty.html
 
-[test_browser.html]
-skip-if = true
-[test_idle.html]
-# skip-if = (toolkit == 'gonk' && debug) #debug-only failure
-skip-if = true
 [test_permissions_api.html]
-[test_power.html]
-skip-if = true
-[test_presentation-device-manage.html]
-skip-if = true
-[test_systemXHR.html]
-[test_tcp-socket.html]
-skip-if = true
-[test_udp-socket.html]
-skip-if = true
-[test_keyboard.html]
-# skip-if = toolkit == 'android'
-skip-if = true
-[test_input-manage.html]
-# skip-if = toolkit == 'android'
-skip-if = true
deleted file mode 100644
--- a/dom/permission/tests/test_browser.html
+++ /dev/null
@@ -1,49 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=815105
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 815105 </title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=815105">Mozilla Bug 815105 </a>
-<p id="display"></p>
-<div id="content" style="display: none"></div>
-<pre id="test">
-<script type="application/javascript;version=1.8" src="file_framework.js"></script>
-<script type="application/javascript;version=1.8">
-function verifier(success, failure) {
-  var iframe = document.createElement('iframe');
-  iframe.setAttribute('mozbrowser', 'true');
-  iframe.src = "http://example.org/";
-  iframe.addEventListener('load', function() {
-    iframe.removeEventListener('load', arguments.callee);
-
-    if (iframe.getScreenshot && typeof iframe.getScreenshot == "function") {
-      success("Got mozbrowser");
-    } else {
-      failure("Didn't get mozbrowser") ;
-    }
-  });
-
-  document.getElementById('content').appendChild(iframe);
-}
-
-var gData = [
-  {
-    perm: ["browser"],
-    needParentPerm: true,
-    settings: [["dom.mozBrowserFramesEnabled", true],
-               ["network.disable.ipc.security", true]],
-    verifier: verifier.toSource(),
-  }
-]
-</script>
-</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/dom/permission/tests/test_idle.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=815105
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 815105 </title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=815105">Mozilla Bug 815105 </a>
-<p id="display"></p>
-<div id="content" style="display: none"></div>
-<pre id="test">
-<script type="application/javascript;version=1.8" src="file_framework.js"></script>
-<script type="application/javascript;version=1.8">
-function verifier(success, failure) {
-  try {
-    var obs = {
-      time: 1,
-      onidle: function() {
-        window.navigator.removeIdleObserver(obs);
-      },
-    }
-
-    // addIdleObserver throws if prinicpal doesn't have the permission
-    window.navigator.addIdleObserver(obs);
-    success("idle");
-  } catch (e) {
-    failure("Got an exception " + e);
-  }
-}
-
-var gData = [
-  {
-    perm: ["idle"],
-    verifier: verifier.toSource(),
-  }
-]
-</script>
-</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/dom/permission/tests/test_input-manage.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=920977
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 920977 </title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=920977">Mozilla Bug 920977 </a>
-<p id="display"></p>
-<div id="content" style="display: none"></div>
-<pre id="test">
-<script type="application/javascript;version=1.8" src="file_framework.js"></script>
-<script type="application/javascript;version=1.8">
-function verifier(success, failure) {
-  try {
-    if (!this.getObj()) {
-      failure("Did not receive proper object");
-      return;
-    }
-  } catch (e) {
-    failure("Received exception!: " + e);
-    return;
-  }
-
-  try {
-    this.getObj().removeFocus();
-  } catch (e) {
-    failure("Received exception!: " + e);
-    return;
-  }
-
-  var iframe = document.createElement("iframe");
-  iframe.setAttribute("mozbrowser", true);
-  iframe.src = "http://example.org/";
-  iframe.addEventListener("load", function() {
-    iframe.removeEventListener("load", arguments.callee);
-    if (iframe.setInputMethodActive &&
-        typeof iframe.setInputMethodActive == "function") {
-      success("Got setInputMethodActive");
-    } else {
-      failure("Didn't get setInputMethodActive") ;
-    }
-  });
-
-  document.getElementById('content').appendChild(iframe);
-}
-
-var gData = [
-  {
-    perm: ["input-manage", "browser"],
-    needParentPerm: true,
-    obj: "mozInputMethod",
-    webidl: "MozInputMethod",
-    settings: [["dom.mozInputMethod.enabled", true],
-               ["dom.mozBrowserFramesEnabled", true],
-               ["network.disable.ipc.security", true]],
-    verifier: verifier.toSource()
-  }
-]
-</script>
-</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/dom/permission/tests/test_keyboard.html
+++ /dev/null
@@ -1,51 +0,0 @@
--<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=920977
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 920977 </title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=920977">Mozilla Bug 920977 </a>
-<p id="display"></p>
-<div id="content" style="display: none"></div>
-<pre id="test">
-<script type="application/javascript;version=1.8" src="file_framework.js"></script>
-<script type="application/javascript;version=1.8">
-function verifier(success, failure) {
-  try {
-    if (!this.getObj()) {
-      failure("Did not receive proper object");
-      return;
-    }
-  } catch (e) {
-    failure("Received exception!: " + e);
-    return;
-  }
-
-  try {
-    this.getObj().removeFocus();
-    failure("Should receive exception when accessing system only method.!");
-  } catch (e) {
-    success(this.perm);
-  }
-}
-
-var gData = [
-  {
-    perm: ["input"],
-    obj: "mozInputMethod",
-    webidl: "MozInputMethod",
-    settings: [["dom.mozInputMethod.enabled", true]],
-    verifier: verifier.toSource()
-  }
-]
-</script>
-</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/dom/permission/tests/test_networkstats-manage.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=815105
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 815105 </title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=815105">Mozilla Bug 815105 </a>
-<p id="display"></p>
-<div id="content" style="display: none"></div>
-<pre id="test">
-<script type="application/javascript;version=1.8" src="file_framework.js"></script>
-<script type="application/javascript;version=1.8">
-var gData = [
-  {
-    perm: ["networkstats-manage"],
-    obj: "mozNetworkStats",
-    webidl: "MozNetworkStatsManager",
-    settings: [["dom.mozNetworkStats.enabled", true]],
-  },
-]
-</script>
-</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/dom/permission/tests/test_power.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=815105
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 815105 </title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=815105">Mozilla Bug 815105 </a>
-<p id="display"></p>
-<div id="content" style="display: none"></div>
-<pre id="test">
-<script type="application/javascript;version=1.8" src="file_framework.js"></script>
-<script type="application/javascript;version=1.8">
-var gData = [
-  {
-    perm: ["power"],
-    obj: "mozPower",
-    webidl: "MozPowerManager",
-  },
-]
-</script>
-</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/dom/permission/tests/test_presentation-device-manage.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=1080474
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for presentation-device-manage permission</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1080474">test presentation-device-manage</a>
-<p id="display"></p>
-<div id="content" style="display: none"></div>
-<pre id="test">
-<script type="application/javascript;version=1.8" src="file_framework.js"></script>
-<script type="application/javascript;version=1.8">
-function verifier(success, failure) {
-  if (window.navigator.mozPresentationDeviceInfo) {
-    success("Got mozPresentationDeviceInfo object!");
-  } else {
-    failure("Failed to get mozPresentationDeviceInfo object!");
-  }
-}
-var gData = [
-  {
-    perm: ["presentation-device-manage"],
-    settings: [["dom.presentation.enabled", true]],
-    obj: "mozPresentationDeviceInfo",
-    webidl: "PresentationDeviceInfoManager"
-  }
-]
-</script>
-</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/dom/permission/tests/test_systemXHR.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=815105
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 815105 </title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=815105">Mozilla Bug 815105 </a>
-<p id="display"></p>
-<div id="content" style="display: none"></div>
-<pre id="test">
-<script type="application/javascript;version=1.8" src="file_framework.js"></script>
-<script type="application/javascript;version=1.8">
-function verifier(success, failure) {
-  var xhr = new XMLHttpRequest({mozSystem: true});
-  if (xhr.mozSystem === true) {
-    success("systemXHR");
-  } else {
-    failure("Couldn't create systemXHR");
-  }
-}
-
-var gData = [
-  {
-    perm: ["systemXHR"],
-    verifier: verifier.toSource(),
-  }
-]
-</script>
-</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/dom/permission/tests/test_tcp-socket.html
+++ /dev/null
@@ -1,52 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=815105
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 815105 </title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=815105">Mozilla Bug 815105 </a>
-<p id="display"></p>
-<div id="content" style="display: none"></div>
-<pre id="test">
-<script type="application/javascript;version=1.8" src="file_framework.js"></script>
-<script type="application/javascript;version=1.8">
-/* mozTCPSocket only returns null on window init
- * if the permission isn't set
- */
-function verifier(success, failure) {
-  try {
-    var conn = navigator.mozTCPSocket.open("http://mochi.test/", 80);
-
-    if (conn) {
-      if (conn instanceof window.TCPSocket) {
-        success("Opened connection");
-      } else {
-        failure("connection didn't match interface");
-      }
-    } else {
-      failure("failed to open connection");
-    }
-  } catch (e) {
-    failure("Got an exception " + e);
-  }
-}
-
-var gData = [
-  {
-    perm: ["tcp-socket"],
-    needParentPerm: true,
-    settings: [["dom.mozTCPSocket.enabled", true]],
-    verifier: verifier.toSource(),
-  }
-]
-</script>
-</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/dom/permission/tests/test_time.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=815105
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 815105 </title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=815105">Mozilla Bug 815105 </a>
-<p id="display"></p>
-<div id="content" style="display: none"></div>
-<pre id="test">
-<script type="application/javascript;version=1.8" src="file_framework.js"></script>
-<script type="application/javascript;version=1.8">
-var gData = [
-  {
-    perm: ["time"],
-    obj: "mozTime",
-    webidl: "MozTimeManager",
-  },
-]
-</script>
-</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/dom/permission/tests/test_udp-socket.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=745283
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 745283 </title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=745283">Mozilla Bug 745283 </a>
-<p id="display"></p>
-<div id="content" style="display: none"></div>
-<pre id="test">
-<script type="application/javascript;version=1.8" src="file_framework.js"></script>
-<script type="application/javascript;version=1.8">
-function verifier(success, failure) {
-  try {
-    var socket = new UDPSocket();
-
-    if (socket) {
-      success("Opened socket");
-    } else {
-      failure("failed to open socket");
-    }
-  } catch (e) {
-    failure("Got an exception " + e);
-  }
-}
-
-var gData = [
-  {
-    perm: ["udp-socket"],
-    needParentPerm: true,
-    obj: "UDPSocket",
-    webidl: "UDPSocket",
-    settings: [["dom.udpsocket.enabled", true]],
-    verifier: verifier.toSource(),
-  }
-]
-</script>
-</pre>
-</body>
-</html>
-
deleted file mode 100644
--- a/dom/permission/tests/unit/test_bug808734.js
+++ /dev/null
@@ -1,73 +0,0 @@
-var Cu = Components.utils;
-const READWRITE = "readwrite";
-const UNKNOWN = "foobar";
-
-var gData = [
-// test normal expansion
-{
-  permission: "contacts",
-  access: READWRITE,
-  expected: ["contacts-read", "contacts-create",
-             "contacts-write"]
-},
-// test additional expansion and access not having read+create+write
-{
-  permission: "settings",
-  access: READWRITE,
-  expected: ["settings-read", "settings-write",
-             "settings-api-read", "settings-api-write",
-             "indexedDB-chrome-settings-read",
-             "indexedDB-chrome-settings-write"]
-},
-// test unknown access
-{
-  permission: "contacts",
-  access: UNKNOWN,
-  expected: []
-},
-// test unknown permission
-{
-  permission: UNKNOWN,
-  access: READWRITE,
-  expected: []
-}
-];
-
-// check if 2 arrays contain the same elements
-function do_check_set_eq(a1, a2) {
-  do_check_eq(a1.length, a2.length)
-
-  Array.sort(a1);
-  Array.sort(a2);
-
-  for (let i = 0; i < a1.length; ++i) {
-    do_check_eq(a1[i], a2[i])
-  }
-}
-
-function test_substitute_does_not_break_substituted(scope) {
-  const Ci = Components.interfaces;
-
-  // geolocation-noprompt substitutes for geolocation ...
-  do_check_eq(scope.PermissionsTable["geolocation-noprompt"].substitute[0],
-              "geolocation");
-  // ... and sets silent allow ...
-  do_check_eq(scope.PermissionsTable["geolocation-noprompt"].certified,
-              Ci.nsIPermissionManager.ALLOW_ACTION)
-  // ... which works ...
-  do_check_false(scope.isExplicitInPermissionsTable("geolocation-noprompt", Ci.nsIPrincipal.APP_STATUS_CERTIFIED));
-  // ... but does not interfere with geolocation's PROMPT value
-  do_check_true(scope.isExplicitInPermissionsTable("geolocation", Ci.nsIPrincipal.APP_STATUS_CERTIFIED));
-}
-
-function run_test() {
-  var scope = {};
-  Cu.import("resource://gre/modules/PermissionsTable.jsm", scope);
-
-  for (var i = 0; i < gData.length; i++) {
-    var perms = scope.expandPermissions(gData[i].permission,
-                                        gData[i].access);
-    do_check_set_eq(perms, gData[i].expected);
-  }
-  test_substitute_does_not_break_substituted(scope);
-}
deleted file mode 100644
--- a/dom/permission/tests/unit/xpcshell.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[DEFAULT]
-head =
-tail =
-
-[test_bug808734.js]
--- a/dom/settings/SettingsRequestManager.jsm
+++ b/dom/settings/SettingsRequestManager.jsm
@@ -11,17 +11,16 @@ const Cu = Components.utils;
 
 Cu.importGlobalProperties(['File']);
 
 this.EXPORTED_SYMBOLS = ["SettingsRequestManager"];
 
 Cu.import("resource://gre/modules/SettingsDB.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/PermissionsTable.jsm");
 
 var DEBUG = false;
 var VERBOSE = false;
 var TRACK = false;
 
 try {
   DEBUG   =
     Services.prefs.getBoolPref("dom.mozSettings.SettingsRequestManager.debug.enabled");
deleted file mode 100644
--- a/dom/system/SystemUpdate.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-component {e8530001-ba5b-46ab-a306-7fbeb692d0fe} SystemUpdateManager.js
-contract @mozilla.org/system-update-manager;1 {e8530001-ba5b-46ab-a306-7fbeb692d0fe}
deleted file mode 100644
--- a/dom/system/SystemUpdateManager.js
+++ /dev/null
@@ -1,253 +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 {classes: Cc, interfaces: Ci, utils: Cu} = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
-
-var debug = Services.prefs.getBoolPref("dom.system_update.debug")
-              ? (aMsg) => dump("-*- SystemUpdateManager.js : " + aMsg + "\n")
-              : (aMsg) => {};
-
-const SYSTEMUPDATEPROVIDER_CID = Components.ID("{11fbea3d-fd94-459a-b8fb-557fe19e473a}");
-const SYSTEMUPDATEMANAGER_CID = Components.ID("{e8530001-ba5b-46ab-a306-7fbeb692d0fe}");
-const SYSTEMUPDATEMANAGER_CONTRACTID = "@mozilla.org/system-update-manager;1";
-
-XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
-                                   "@mozilla.org/childprocessmessagemanager;1",
-                                   "nsISyncMessageSender");
-
-function SystemUpdateProvider(win, provider) {
-  this.initDOMRequestHelper(win, [
-    {name: "SystemUpdate:OnUpdateAvailable", weakRef: true},
-    {name: "SystemUpdate:OnProgress", weakRef: true},
-    {name: "SystemUpdate:OnUpdateReady", weakRef: true},
-    {name: "SystemUpdate:OnError", weakRef: true},
-  ]);
-  this._provider = Cu.cloneInto(provider, win);
-}
-
-SystemUpdateProvider.prototype = {
-  __proto__: DOMRequestIpcHelper.prototype,
-
-  classID: SYSTEMUPDATEPROVIDER_CID,
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference,
-                                         Ci.nsIObserver]),
-
-  receiveMessage: function(aMsg) {
-    if (!aMsg || !aMsg.json) {
-      return;
-    }
-
-    let json = aMsg.json;
-
-    if (json.uuid !== this._provider.uuid) {
-      return;
-    }
-
-    debug("receive msg: " + aMsg.name);
-    switch (aMsg.name) {
-      case "SystemUpdate:OnUpdateAvailable": {
-        let detail = {
-          detail: {
-            packageInfo: json.packageInfo
-          }
-        };
-        let event = new this._window.CustomEvent("updateavailable",
-                                                  Cu.cloneInto(detail, this._window));
-        this.__DOM_IMPL__.dispatchEvent(event);
-        break;
-      }
-      case "SystemUpdate:OnProgress": {
-        let event = new this._window.ProgressEvent("progress", {lengthComputable: true,
-                                                                loaded: json.loaded,
-                                                                total: json.total});
-        this.__DOM_IMPL__.dispatchEvent(event);
-        break;
-      }
-      case "SystemUpdate:OnUpdateReady": {
-        let event = new this._window.Event("updateready");
-        this.__DOM_IMPL__.dispatchEvent(event);
-        break;
-      }
-      case "SystemUpdate:OnError": {
-        let event = new this._window.ErrorEvent("error", {message: json.message});
-        this.__DOM_IMPL__.dispatchEvent(event);
-        break;
-      }
-    }
-  },
-
-  destroy: function() {
-    this.destroyDOMRequestHelper();
-  },
-
-  get name() {
-    return this._provider.name;
-  },
-
-  get uuid() {
-    return this._provider.uuid;
-  },
-
-  get onupdateavailable() {
-    return this.__DOM_IMPL__.getEventHandler("onupdateavailable");
-  },
-  set onupdateavailable(aHandler) {
-    this.__DOM_IMPL__.setEventHandler("onupdateavailable", aHandler);
-  },
-  get onprogress() {
-    return this.__DOM_IMPL__.getEventHandler("onprogress");
-  },
-  set onprogress(aHandler) {
-    this.__DOM_IMPL__.setEventHandler("onprogress", aHandler);
-  },
-  get onupdateready() {
-    return this.__DOM_IMPL__.getEventHandler("onupdateready");
-  },
-  set onupdateready(aHandler) {
-    this.__DOM_IMPL__.setEventHandler("onupdateready", aHandler);
-  },
-  get onerror() {
-    return this.__DOM_IMPL__.getEventHandler("onerror");
-  },
-  set onerror(aHandler) {
-    this.__DOM_IMPL__.setEventHandler("onerror", aHandler);
-  },
-
-  checkForUpdate: function() {
-    let self = this;
-    cpmm.sendAsyncMessage("SystemUpdate:CheckForUpdate", {
-      uuid: self._provider.uuid
-    });
-  },
-  startDownload: function() {
-    let self = this;
-    cpmm.sendAsyncMessage("SystemUpdate:StartDownload", {
-      uuid: self._provider.uuid
-    });
-  },
-  stopDownload: function() {
-    let self = this;
-    cpmm.sendAsyncMessage("SystemUpdate:StopDownload", {
-      uuid: self._provider.uuid
-    });
-  },
-  applyUpdate: function() {
-    let self = this;
-    cpmm.sendAsyncMessage("SystemUpdate:ApplyUpdate", {
-      uuid: self._provider.uuid
-    });
-  },
-  setParameter: function(aName, aValue) {
-    let self = this;
-    return cpmm.sendSyncMessage("SystemUpdate:SetParameter", {
-      uuid: self._provider.uuid,
-      name: aName,
-      value: aValue
-    })[0];
-  },
-  getParameter: function(aName) {
-    let self = this;
-    return cpmm.sendSyncMessage("SystemUpdate:GetParameter", {
-      uuid: self._provider.uuid,
-      name: aName
-    })[0];
-  },
-};
-
-function SystemUpdateManager() {}
-
-SystemUpdateManager.prototype = {
-  __proto__: DOMRequestIpcHelper.prototype,
-
-  classID: SYSTEMUPDATEMANAGER_CID,
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference,
-                                         Ci.nsIObserver,
-                                         Ci.nsIDOMGlobalPropertyInitializer]),
-
-  receiveMessage: function(aMsg) {
-    if (!aMsg || !aMsg.json) {
-      return;
-    }
-
-    let json = aMsg.json;
-    let resolver = this.takePromiseResolver(json.requestId);
-
-    if (!resolver) {
-      return;
-    }
-
-    debug("receive msg: " + aMsg.name);
-    switch (aMsg.name) {
-      case "SystemUpdate:GetProviders:Result:OK": {
-        resolver.resolve(Cu.cloneInto(json.providers, this._window));
-        break;
-      }
-      case "SystemUpdate:SetActiveProvider:Result:OK":
-      case "SystemUpdate:GetActiveProvider:Result:OK": {
-        let updateProvider = new SystemUpdateProvider(this._window, json.provider);
-        resolver.resolve(this._window.SystemUpdateProvider._create(this._window,
-                                                                   updateProvider));
-        break;
-      }
-      case "SystemUpdate:GetProviders:Result:Error":
-      case "SystemUpdate:GetActiveProvider:Result:Error":
-      case "SystemUpdate:SetActiveProvider:Result:Error": {
-        resolver.reject(json.error);
-        break;
-      }
-    }
-  },
-
-  init: function(aWindow) {
-    this.initDOMRequestHelper(aWindow, [
-      {name: "SystemUpdate:GetProviders:Result:OK", weakRef: true},
-      {name: "SystemUpdate:GetProviders:Result:Error", weakRef: true},
-      {name: "SystemUpdate:GetActiveProvider:Result:OK", weakRef: true},
-      {name: "SystemUpdate:GetActiveProvider:Result:Error", weakRef: true},
-      {name: "SystemUpdate:SetActiveProvider:Result:OK", weakRef: true},
-      {name: "SystemUpdate:SetActiveProvider:Result:Error", weakRef: true},
-    ]);
-  },
-
-  uninit: function() {
-    let self = this;
-
-    this.forEachPromiseResolver(function(aKey) {
-      self.takePromiseResolver(aKey).reject("SystemUpdateManager got destroyed");
-    });
-  },
-
-  getProviders: function() {
-    return this.createPromiseWithId(function(aResolverId) {
-      cpmm.sendAsyncMessage("SystemUpdate:GetProviders", {
-        requestId: aResolverId,
-      });
-    });
-  },
-
-  getActiveProvider: function() {
-    return this.createPromiseWithId(function(aResolverId) {
-      cpmm.sendAsyncMessage("SystemUpdate:GetActiveProvider", {
-        requestId: aResolverId,
-      });
-    });
-  },
-
-  setActiveProvider: function(aUuid) {
-    return this.createPromiseWithId(function(aResolverId) {
-      cpmm.sendAsyncMessage("SystemUpdate:SetActiveProvider", {
-        requestId: aResolverId,
-        uuid: aUuid
-      });
-    });
-  }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SystemUpdateManager]);
deleted file mode 100644
--- a/dom/system/SystemUpdateService.jsm
+++ /dev/null
@@ -1,376 +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 {classes: Cc, interfaces: Ci, utils: Cu} = Components;
-
-this.EXPORTED_SYMBOLS = ["SystemUpdateService"];
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-const CATEGORY_SYSTEM_UPDATE_PROVIDER = "system-update-provider";
-const PROVIDER_ACTIVITY_IDLE = 0;
-const PROVIDER_ACTIVITY_CHECKING = 1;
-const PROVIDER_ACTIVITY_DOWNLOADING = 1 << 1;
-const PROVIDER_ACTIVITY_APPLYING = 1 << 2;
-
-var debug = Services.prefs.getBoolPref("dom.system_update.debug")
-              ? (aMsg) => dump("-*- SystemUpdateService.jsm : " + aMsg + "\n")
-              : (aMsg) => {};
-
-XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
-                                   "@mozilla.org/parentprocessmessagemanager;1",
-                                   "nsIMessageBroadcaster");
-
-function ActiveProvider(aProvider) {
-  this.id = aProvider.id;
-  this._instance = Components.classesByID[aProvider.id].getService(Ci.nsISystemUpdateProvider);
-  this._instance.setListener(this);
-}
-
-ActiveProvider.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsISystemUpdateListener]),
-
-  _activity: PROVIDER_ACTIVITY_IDLE,
-
-  destroy: function() {
-    if (this._instance) {
-      this._instance.unsetListener();
-      this._instance = null;
-    }
-
-    this.id = null;
-  },
-
-  checkForUpdate: function() {
-    this._execFuncIfNotInActivity(PROVIDER_ACTIVITY_CHECKING,
-                                  this._instance.checkForUpdate);
-  },
-
-  startDownload: function() {
-    this._execFuncIfNotInActivity(PROVIDER_ACTIVITY_DOWNLOADING,
-                                  this._instance.startDownload);
-  },
-
-  stopDownload: function() {
-    this._execFuncIfNotInActivity(PROVIDER_ACTIVITY_DOWNLOADING,
-                                  this._instance.stopDownload);
-  },
-
-  applyUpdate: function() {
-    this._execFuncIfNotInActivity(PROVIDER_ACTIVITY_APPLYING,
-                                  this._instance.applyUpdate);
-  },
-
-  setParameter: function(aName, aValue) {
-    return this._instance.setParameter(aName, aValue);
-  },
-
-  getParameter: function(aName) {
-    return this._instance.getParameter(aName);
-  },
-
-  // nsISystemUpdateListener
-  onUpdateAvailable: function(aType, aVersion, aDescription, aBuildDate, aSize) {
-    this._execFuncIfActiveAndInAction(PROVIDER_ACTIVITY_CHECKING, function() {
-      ppmm.broadcastAsyncMessage("SystemUpdate:OnUpdateAvailable", {
-        uuid: this.id,
-        packageInfo: {
-          type: aType,
-          version: aVersion,
-          description: aDescription,
-          buildDate: aBuildDate,
-          size: aSize,
-        }
-      });
-
-      this._unsetActivity(PROVIDER_ACTIVITY_CHECKING);
-    }.bind(this));
-  },
-
-  onProgress: function(aLoaded, aTotal) {
-    this._execFuncIfActiveAndInAction(PROVIDER_ACTIVITY_DOWNLOADING, function() {
-      ppmm.broadcastAsyncMessage("SystemUpdate:OnProgress", {
-        uuid: this.id,
-        loaded: aLoaded,
-        total: aTotal,
-      });
-    }.bind(this));
-  },
-
-  onUpdateReady: function() {
-    this._execFuncIfActiveAndInAction(PROVIDER_ACTIVITY_DOWNLOADING, function() {
-      ppmm.broadcastAsyncMessage("SystemUpdate:OnUpdateReady", {
-        uuid: this.id,
-      });
-
-      this._unsetActivity(PROVIDER_ACTIVITY_DOWNLOADING);
-    }.bind(this));
-  },
-
-  onError: function(aErrMsg) {
-    if (!SystemUpdateService._isActiveProviderId(this.id)) {
-      return;
-    }
-
-    ppmm.broadcastAsyncMessage("SystemUpdate:OnError", {
-      uuid: this.id,
-      message: aErrMsg,
-    });
-
-    this._activity = PROVIDER_ACTIVITY_IDLE;
-  },
-
-  isIdle: function() {
-    return this._activity === PROVIDER_ACTIVITY_IDLE;
-  },
-
-  _isInActivity: function(aActivity) {
-    return (this._activity & aActivity) !== PROVIDER_ACTIVITY_IDLE;
-  },
-
-  _setActivity: function(aActivity) {
-    this._activity |= aActivity;
-  },
-
-  _unsetActivity: function(aActivity) {
-    this._activity &= ~aActivity;
-  },
-
-  _execFuncIfNotInActivity: function(aActivity, aFunc) {
-    if (!this._isInActivity(aActivity)) {
-      this._setActivity(aActivity);
-      aFunc();
-    }
-  },
-
-  _execFuncIfActiveAndInAction: function(aActivity, aFunc) {
-    if (!SystemUpdateService._isActiveProviderId(this.id)) {
-      return;
-    }
-    if (this._isInActivity(aActivity)) {
-      aFunc();
-    }
-  },
-
-};
-
-this.SystemUpdateService = {
-  _providers: [],
-  _activeProvider: null,
-
-  _updateActiveProvider: function(aProvider) {
-    if (this._activeProvider) {
-      this._activeProvider.destroy();
-    }
-
-    this._activeProvider = new ActiveProvider(aProvider);
-  },
-
-  _isActiveProviderId: function(aId) {
-    return (this._activeProvider && this._activeProvider.id === aId);
-  },
-
-  init: function() {
-    debug("init");
-
-    let messages = ["SystemUpdate:GetProviders",
-                    "SystemUpdate:GetActiveProvider",
-                    "SystemUpdate:SetActiveProvider",
-                    "SystemUpdate:CheckForUpdate",
-                    "SystemUpdate:StartDownload",
-                    "SystemUpdate:StopDownload",
-                    "SystemUpdate:ApplyUpdate",
-                    "SystemUpdate:SetParameter",
-                    "SystemUpdate:GetParameter"];
-    messages.forEach((function(aMsgName) {
-      ppmm.addMessageListener(aMsgName, this);
-    }).bind(this));
-
-    // load available provider list
-    let catMan = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
-    let entries = catMan.enumerateCategory(CATEGORY_SYSTEM_UPDATE_PROVIDER);
-    while (entries.hasMoreElements()) {
-      let name = entries.getNext().QueryInterface(Ci.nsISupportsCString).data;
-      let [contractId, id] = catMan.getCategoryEntry(CATEGORY_SYSTEM_UPDATE_PROVIDER, name).split(",");
-      this._providers.push({
-        id: id,
-        name: name,
-        contractId: contractId
-      });
-    }
-    debug("available providers: " + JSON.stringify(this._providers));
-
-    // setup default active provider
-    let defaultActive;
-    try {
-      defaultActive = Services.prefs.getCharPref("dom.system_update.active");
-    } catch (e) {}
-
-    if (defaultActive) {
-      let defaultProvider = this._providers.find(function(aProvider) {
-        return aProvider.contractId === defaultActive;
-      });
-
-      if (defaultProvider) {
-        this._updateActiveProvider(defaultProvider);
-      }
-    }
-  },
-
-  addProvider: function(aClassId, aContractId, aName) {
-    debug("addProvider");
-
-    //did not allow null or empty string to add.
-    if(!aClassId || !aContractId || !aName) {
-      return;
-    }
-
-    let existedProvider = this._providers.find(function(provider) {
-      return provider.id === aClassId;
-    });
-
-    //skip if adding the existed provider.
-    if (existedProvider) {
-      debug("existing providers: " + JSON.stringify(existedProvider));
-      return;
-    }
-
-    //dynamically add the provider info to list.
-    this._providers.push({
-        id: aClassId,
-        name: aName,
-        contractId: aContractId
-    });
-    debug("available providers: " + JSON.stringify(this._providers));
-  },
-
-  getProviders: function(aData, aMm) {
-    debug("getProviders");
-
-    aData.providers = [];
-    for (let provider of this._providers) {
-      aData.providers.push({
-        name: provider.name,
-        uuid: provider.id
-      });
-    }
-    aMm.sendAsyncMessage("SystemUpdate:GetProviders:Result:OK", aData);
-  },
-
-  getActiveProvider: function(aData, aMm) {
-    debug("getActiveProvider");
-
-    let self = this;
-    let providerInfo = this._providers.find(function(provider) {
-      return self._isActiveProviderId(provider.id);
-    });
-
-    if (!providerInfo) {
-      aData.error = "NotFoundError";
-      aMm.sendAsyncMessage("SystemUpdate:GetActiveProvider:Result:Error", aData);
-      return;
-    }
-
-    aData.provider = {
-      name: providerInfo.name,
-      uuid: providerInfo.id
-    };
-    aMm.sendAsyncMessage("SystemUpdate:GetActiveProvider:Result:OK", aData);
-  },
-
-  setActiveProvider: function(aData, aMm) {
-    debug("setActiveProvider");
-
-    let self = this;
-    let selectedProvider = this._providers.find(function(provider) {
-      return provider.id === aData.uuid;
-    });
-
-    if (!selectedProvider) {
-      aData.error = "DataError";
-      aMm.sendAsyncMessage("SystemUpdate:SetActiveProvider:Result:Error", aData);
-      return;
-    }
-
-    if (!this._isActiveProviderId(selectedProvider.id)) {
-      // not allow changing active provider while there is an ongoing update activity
-      if (this.activeProvider && !this._activeProvider.isIdle()) {
-        aData.error = "DataError";
-        aMm.sendAsyncMessage("SystemUpdate:SetActiveProvider:Result:Error", aData);
-        return;
-      }
-
-      this._updateActiveProvider(selectedProvider);
-      Services.prefs.setCharPref("dom.system_update.active", selectedProvider.contractId);
-    }
-
-    aData.provider = {
-      name: selectedProvider.name,
-      uuid: selectedProvider.id
-    };
-    aMm.sendAsyncMessage("SystemUpdate:SetActiveProvider:Result:OK", aData);
-  },
-
-  receiveMessage: function(aMessage) {
-    let msg = aMessage.data || {};
-    let mm = aMessage.target;
-
-    switch (aMessage.name) {
-      case "SystemUpdate:GetProviders": {
-        this.getProviders(msg, mm);
-        break;
-      }
-      case "SystemUpdate:GetActiveProvider": {
-        this.getActiveProvider(msg, mm);
-        break;
-      }
-      case "SystemUpdate:SetActiveProvider": {
-        this.setActiveProvider(msg, mm);
-        break;
-      }
-      case "SystemUpdate:CheckForUpdate": {
-        if (this._isActiveProviderId(msg.uuid)) {
-          this._activeProvider.checkForUpdate();
-        }
-        break;
-      }
-      case "SystemUpdate:StartDownload": {
-        if (this._isActiveProviderId(msg.uuid)) {
-          this._activeProvider.startDownload();
-        }
-        break;
-      }
-      case "SystemUpdate:StopDownload": {
-        if (this._isActiveProviderId(msg.uuid)) {
-          this._activeProvider.stopDownload();
-        }
-        break;
-      }
-      case "SystemUpdate:ApplyUpdate": {
-        if (this._isActiveProviderId(msg.uuid)) {
-          this._activeProvider.applyUpdate();
-        }
-        break;
-      }
-      case "SystemUpdate:SetParameter": {
-        if (this._isActiveProviderId(msg.uuid)) {
-          return this._activeProvider.setParameter(msg.name, msg.value);
-        }
-        break;
-      }
-      case "SystemUpdate:GetParameter": {
-        if (this._isActiveProviderId(msg.uuid)) {
-          return this._activeProvider.getParameter(msg.name);
-        }
-        break;
-      }
-    }
-  },
-
-};
-
-SystemUpdateService.init();
--- a/dom/system/moz.build
+++ b/dom/system/moz.build
@@ -14,17 +14,16 @@ elif toolkit == 'android':
     DIRS += ['android']
 elif toolkit == 'gonk':
     DIRS += ['gonk']
 elif toolkit in ('gtk2', 'gtk3'):
     DIRS += ['linux']
 
 XPIDL_SOURCES += [
     'nsIOSFileConstantsService.idl',
-    'nsISystemUpdateProvider.idl',
 ]
 
 XPIDL_MODULE = 'dom_system'
 
 EXPORTS += [
     'nsDeviceSensors.h',
 ]
 
@@ -35,22 +34,16 @@ EXPORTS.mozilla += [
 UNIFIED_SOURCES += [
     'nsDeviceSensors.cpp',
     'OSFileConstants.cpp',
 ]
 
 EXTRA_COMPONENTS += [
     'NetworkGeolocationProvider.js',
     'NetworkGeolocationProvider.manifest',
-    'SystemUpdate.manifest',
-    'SystemUpdateManager.js',
-]
-
-EXTRA_JS_MODULES += [
-    'SystemUpdateService.jsm',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 # We fire the nsDOMDeviceAcceleration
 LOCAL_INCLUDES += [
     '/dom/base',
deleted file mode 100644
--- a/dom/system/nsISystemUpdateProvider.idl
+++ /dev/null
@@ -1,73 +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/. */
-
-#include "nsISupports.idl"
-
-[scriptable, uuid(775edbf5-b4a9-400c-b0ad-ea3c3a027097)]
-interface nsISystemUpdateListener : nsISupports
-{
-  /**
-   * callback for notifying an update package is available for download.
-   */
-  void onUpdateAvailable(in DOMString type,
-                         in DOMString version,
-                         in DOMString description,
-                         in unsigned long long buildDate,
-                         in unsigned long long size);
-
-  /**
-   * callback for notifying the download progress.
-   */
-  void onProgress(in unsigned long long loaded, in unsigned long long total);
-
-  /**
-   * callback for notifying an update package is ready to apply.
-   */
-  void onUpdateReady();
-
-  /**
-   * callback for notifying any error while
-   * checking/downloading/applying an update package.
-   */
-  void onError(in DOMString errMsg);
-};
-
-[scriptable, uuid(c9b7c166-b9cf-4396-a6de-39275e1c0a36)]
-interface nsISystemUpdateProvider : nsISupports
-{
-  void checkForUpdate();
-  void startDownload();
-  void stopDownload();
-  void applyUpdate();
-
-  /**
-   * Set the available parameter to the update provider.
-   * The available parameter is implementation-dependent.
-   * e.g. "update-url", "last-update-date", "update-status", "update-interval"
-   *
-   * @param  name      The number of languages.
-   * @param  languages An array of languages.
-   * @return true when setting an available parameter,
-   *         false when setting an unavailable parameter.
-   */
-  bool setParameter(in DOMString name, in DOMString value);
-  /**
-   * Get the available parameter from the update provider.
-   * The available parameter is implementation-dependent.
-   *
-   * @param  name The available parameter.
-   * @return The corresponding value to the name.
-   *         Return null if try to get unavailable parameter.
-   */
-  DOMString getParameter(in DOMString name);
-
-  /**
-   * NOTE TO IMPLEMENTORS:
-   *   Need to consider if it is necessary to fire the pending event when 
-   *   registering the listener.
-   *   (E.g. UpdateAvailable or UpdateReady event.)
-   */
-  void setListener(in nsISystemUpdateListener listener);
-  void unsetListener();
-};
--- a/dom/system/tests/mochitest.ini
+++ b/dom/system/tests/mochitest.ini
@@ -1,8 +1,5 @@
 [DEFAULT]
 support-files =
-  preload-SystemUpdateManager-jsm.js
   file_bug1197901.html
 
 [test_bug1197901.html]
-[test_system_update_enabled.html]
-skip-if = true # Tests only ran on B2G
deleted file mode 100644
--- a/dom/system/tests/preload-SystemUpdateManager-jsm.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 {classes: Cc, interfaces: Ci, utils: Cu, manager: Cm} = Components;
-
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-
-const cid = '{17a84227-28f4-453d-9b80-9ae75a5682e0}';
-const contractId = '@mozilla.org/test-update-provider;1';
-
-function TestUpdateProvider() {}
-TestUpdateProvider.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsISystemUpdateProvider]),
-
-  checkForUpdate: function() {
-    dump('check for update');
-    this._listener.onUpdateAvailable('test-type', 'test-version', 'test-description', Date.now().valueOf(), 5566);
-  },
-
-  startDownload: function() {
-    dump('test start download');
-    this._listener.onProgress(10, 100);
-  },
-
-  stopDownload: function() {
-    dump('test stop download');
-  },
-
-  applyUpdate: function() {
-    dump('apply update');
-  },
-
-  setParameter: function(name, value) {
-    dump('set parameter');
-    return (name === 'dummy' && value === 'dummy-value');
-  },
-
-  getParameter: function(name) {
-    dump('get parameter');
-    if (name === 'dummy') {
-      return 'dummy-value';
-    }
-  },
-
-  setListener: function(listener) {
-    this._listener = listener;
-  },
-
-  unsetListener: function() {
-    this._listener = null;
-  },
-};
-
-var factory = {
-  createInstance: function(outer, iid) {
-    if (outer) {
-      throw Components.results.NS_ERROR_NO_AGGREGATION;
-    }
-
-    return new TestUpdateProvider().QueryInterface(iid);
-  },
-  lockFactory: function(aLock) {
-    throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-  },
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory])
-};
-
-Cm.nsIComponentRegistrar.registerFactory(Components.ID(cid), '', contractId, factory);
-
-var cm = Cc['@mozilla.org/categorymanager;1'].getService(Ci.nsICategoryManager);
-cm.addCategoryEntry('system-update-provider', 'DummyProvider',
-                    contractId + ',' + cid, false, true);
-
-Cu.import('resource://gre/modules/SystemUpdateService.jsm');
-this.SystemUpdateService.addProvider('{17a84227-28f4-453d-9b80-9ae75a5682e0}',
-                                     '@mozilla.org/test-update-provider;1',
-                                     'DummyProvider');
\ No newline at end of file
deleted file mode 100644
--- a/dom/system/tests/test_system_update_enabled.html
+++ /dev/null
@@ -1,175 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=1037329
--->
-<head>
-  <meta charset="utf-8">
-  <title>System Update API Test</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1037329">Test System Update API</a>
-<script type="application/javascript;version=1.8">
-
-'use strict';
-
-SimpleTest.waitForExplicitFinish();
-
-function setup() {
-  window.gUrl = SimpleTest.getTestFileURL('preload-SystemUpdateManager-jsm.js');
-  window.gScript = SpecialPowers.loadChromeScript(gUrl);
-  return Promise.resolve();
-}
-
-function testGetProviders() {
-  return new Promise(function(resolve, reject) {
-    navigator.updateManager.getProviders().then(function(providerInfos) {
-      info('num of providers: ' + providerInfos.length);
-      for (let providerInfo of providerInfos) {
-        info('provider info: ' + JSON.stringify(providerInfo));
-      }
-      resolve(providerInfos);
-    });
-  });
-}
-
-function testSetActiveProvider(providerInfos) {
-  return new Promise(function(resolve, reject) {
-    //Find the mock provider for our testing provider instead.
-    //Set the mock provider as active provider.
-    let targetProvider = providerInfos[0];
-    for(let provider of providerInfos) {
-      if(provider.uuid == "{17a84227-28f4-453d-9b80-9ae75a5682e0}") {
-        info('target provider uuid: ' + provider.uuid);
-        targetProvider = provider;
-        break;
-      }
-    }
-    is("{17a84227-28f4-453d-9b80-9ae75a5682e0}", targetProvider.uuid, 'get the dynamically added provider');
-    navigator.updateManager.setActiveProvider(targetProvider.uuid).then(function(activeProvider) {
-      info('active provider info: ' + JSON.stringify(activeProvider.info));
-      is(activeProvider.name, targetProvider.name, 'expected name of active provider');
-      is(activeProvider.uuid, targetProvider.uuid, 'expected uuid of active provider');
-      resolve({name : activeProvider.name, uuid : activeProvider.uuid});
-    });
-  });
-}
-
-function testGetActiveProvider(providerInfo) {
-  info('test GetActiveProvider');
-  return new Promise(function(resolve, reject) {
-    navigator.updateManager.getActiveProvider().then(function(activeProvider) {
-      is(activeProvider.name, providerInfo.name, 'expected name of active provider');
-      is(activeProvider.uuid, providerInfo.uuid, 'expected uuid of active provider');
-      resolve(activeProvider);
-    });
-  });
-}
-
-function testCheckForUpdate(provider) {
-  info('test CheckForUpdate');
-  return new Promise(function(resolve, reject) {
-    provider.addEventListener('updateavailable', function(event) {
-      ok(true, 'receive updateavailable event');
-      info('event: ' + JSON.stringify(event.detail));
-      resolve(provider);
-    });
-    provider.checkForUpdate();
-  });
-}
-
-function testStartDownload(provider) {
-  info('test StartDownload');
-  return new Promise(function(resolve, reject) {
-    provider.addEventListener('progress', function(event) {
-      ok(true, 'receive progress event');
-      is(event.loaded, 10, 'expected loaded');
-      is(event.total, 100, 'expected total');
-      resolve(provider);
-    });
-    provider.startDownload();
-  });
-}
-function testStopDownload(provider) {
-  info('test StopDownload');
-  return new Promise(function(resolve, reject) {
-    provider.stopDownload();
-    resolve(provider);
-  });
-}
-function testApplyUpdate(provider) {
-  info('test ApplyUpdate');
-  return new Promise(function(resolve, reject) {
-    provider.applyUpdate();
-    resolve(provider);
-  });
-}
-function testGetParameter(provider) {
-  info('test GetParameter');
-  return new Promise(function(resolve, reject) {
-    let dummy = provider.getParameter('dummy');
-    is(dummy, 'dummy-value', 'expected parameter');
-    resolve(provider);
-  });
-}
-function testSetParameter(provider) {
-  info('test SetParameter');
-  return new Promise(function(resolve, reject) {
-    provider.setParameter('dummy', 'dummy-value');
-    resolve();
-  });
-}
-function testSetActiveProviderError() {
-  info('test setActiveProvider error');
-  return new Promise(function(resolve, reject) {
-    navigator.updateManager.setActiveProvider('something not exsited').then(function(provider) {
-      ok(false, 'should not success');
-      resolve();
-    }, function(reason) {
-      info('error message: ' + reason);
-      ok(true, 'expected error while setActiveProvider');
-      resolve();
-    });
-  });
-}
-
-
-function runTest() {
-  ok(navigator.updateManager, 'should have navigator.updateManager');
-
-  setup()
-  .then(testGetProviders)
-  .then(testSetActiveProvider)
-  .then(testGetActiveProvider)
-  .then(testCheckForUpdate)
-  .then(testStartDownload)
-  .then(testStopDownload)
-  .then(testApplyUpdate)
-  .then(testGetParameter)
-  .then(testSetParameter)
-  .then(testSetActiveProviderError)
-  .then(function() {
-    info('test finished');
-    gScript.destroy();
-    SimpleTest.finish();
-  });
-}
-
-SpecialPowers.pushPermissions([
-    {type: 'system-update', allow: true, context: document},
-  ], function() {
-    SpecialPowers.pushPrefEnv({
-        'set': [
-          ['dom.system_update.enabled', true],
-          ['dom.system_update.debug', true],
-          ['dom.system_update.active', '@mozilla.org/test-update-provider;1'],
-        ]
-      }, runTest);
-  }
-);
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/webidl/SystemUpdate.webidl
+++ /dev/null
@@ -1,48 +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/. */
-
-dictionary SystemUpdateProviderInfo {
-  DOMString name = "";
-  DOMString uuid = "";
-};
-
-dictionary SystemUpdatePackageInfo {
-  DOMString type = "";
-  DOMString version = "";
-  DOMString description = "";
-  DOMTimeStamp buildDate = 0;
-  unsigned long long size = 0;
-};
-
-[JSImplementation="@mozilla.org/system-update-provider;1",
- ChromeOnly,
- Pref="dom.system_update.enabled"]
-interface SystemUpdateProvider : EventTarget {
-  readonly attribute DOMString name;
-  readonly attribute DOMString uuid;
-
-  attribute EventHandler onupdateavailable;
-  attribute EventHandler onprogress;
-  attribute EventHandler onupdateready;
-  attribute EventHandler onerror;
-
-  void checkForUpdate();
-  void startDownload();
-  void stopDownload();
-  void applyUpdate();
-  boolean setParameter(DOMString name, DOMString value);
-  DOMString getParameter(DOMString name);
-};
-
-[NavigatorProperty="updateManager",
- JSImplementation="@mozilla.org/system-update-manager;1",
- ChromeOnly,
- Pref="dom.system_update.enabled"]
-interface SystemUpdateManager {
-  Promise<sequence<SystemUpdateProviderInfo>> getProviders();
-
-  Promise<SystemUpdateProvider> setActiveProvider(DOMString uuid);
-
-  Promise<SystemUpdateProvider> getActiveProvider();
-};
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -514,17 +514,16 @@ WEBIDL_FILES = [
     'SVGUnitTypes.webidl',
     'SVGUnitTypeValues.webidl',
     'SVGURIReference.webidl',
     'SVGUseElement.webidl',
     'SVGViewElement.webidl',
     'SVGZoomAndPan.webidl',
     'SVGZoomAndPanValues.webidl',
     'SVGZoomEvent.webidl',
-    'SystemUpdate.webidl',
     'TCPServerSocket.webidl',
     'TCPServerSocketEvent.webidl',
     'TCPSocket.webidl',
     'TCPSocketErrorEvent.webidl',
     'TCPSocketEvent.webidl',
     'Text.webidl',
     'TextClause.webidl',
     'TextDecoder.webidl',
--- a/js/ipc/JavaScriptShared.cpp
+++ b/js/ipc/JavaScriptShared.cpp
@@ -56,16 +56,25 @@ JSObject*
 IdToObjectMap::find(ObjectId id)
 {
     Table::Ptr p = table_.lookup(id);
     if (!p)
         return nullptr;
     return p->value();
 }
 
+JSObject*
+IdToObjectMap::findPreserveColor(ObjectId id)
+{
+    Table::Ptr p = table_.lookup(id);
+    if (!p)
+        return nullptr;
+    return p->value().unbarrieredGet();
+}
+
 bool
 IdToObjectMap::add(ObjectId id, JSObject* obj)
 {
     return table_.put(id, obj);
 }
 
 void
 IdToObjectMap::remove(ObjectId id)
--- a/js/ipc/JavaScriptShared.h
+++ b/js/ipc/JavaScriptShared.h
@@ -91,16 +91,17 @@ class IdToObjectMap
     IdToObjectMap();
 
     bool init();
     void trace(JSTracer* trc, uint64_t minimumId = 0);
     void sweep();
 
     bool add(ObjectId id, JSObject* obj);
     JSObject* find(ObjectId id);
+    JSObject* findPreserveColor(ObjectId id);
     void remove(ObjectId id);
 
     void clear();
     bool empty() const;
 
 #ifdef DEBUG
     bool has(const ObjectId& id, const JSObject* obj) const;
 #endif
--- a/js/ipc/WrapperAnswer.cpp
+++ b/js/ipc/WrapperAnswer.cpp
@@ -784,15 +784,15 @@ WrapperAnswer::RecvDOMInstanceOf(const O
     *instanceof = tmp;
 
     return ok(rs);
 }
 
 bool
 WrapperAnswer::RecvDropObject(const ObjectId& objId)
 {
-    JSObject* obj = objects_.find(objId);
+    JSObject* obj = objects_.findPreserveColor(objId);
     if (obj) {
         objectIdMap(objId.hasXrayWaiver()).remove(obj);
         objects_.remove(objId);
     }
     return true;
 }
--- a/js/src/builtin/Intl.cpp
+++ b/js/src/builtin/Intl.cpp
@@ -763,95 +763,84 @@ static const JSFunctionSpec collator_met
     JS_SELF_HOSTED_FN("resolvedOptions", "Intl_Collator_resolvedOptions", 0, 0),
 #if JS_HAS_TOSOURCE
     JS_FN(js_toSource_str, collator_toSource, 0, 0),
 #endif
     JS_FS_END
 };
 
 /**
- * 10.1.2 Intl.Collator([ locales [, options]])
- *
- * ES2017 Intl draft rev 94045d234762ad107a3d09bb6f7381a65f1a2f9b
+ * Collator constructor.
+ * Spec: ECMAScript Internationalization API Specification, 10.1
  */
 static bool
 Collator(JSContext* cx, const CallArgs& args, bool construct)
 {
     RootedObject obj(cx);
 
-    // We're following ECMA-402 1st Edition when Collator is called because of
-    // backward compatibility issues.
-    // See https://github.com/tc39/ecma402/issues/57
     if (!construct) {
-        // ES Intl 1st ed., 10.1.2.1 step 3
+        // 10.1.2.1 step 3
         JSObject* intl = cx->global()->getOrCreateIntlObject(cx);
         if (!intl)
             return false;
         RootedValue self(cx, args.thisv());
         if (!self.isUndefined() && (!self.isObject() || self.toObject() != *intl)) {
-            // ES Intl 1st ed., 10.1.2.1 step 4
+            // 10.1.2.1 step 4
             obj = ToObject(cx, self);
             if (!obj)
                 return false;
 
-            // ES Intl 1st ed., 10.1.2.1 step 5
+            // 10.1.2.1 step 5
             bool extensible;
             if (!IsExtensible(cx, obj, &extensible))
                 return false;
             if (!extensible)
                 return Throw(cx, obj, JSMSG_OBJECT_NOT_EXTENSIBLE);
         } else {
-            // ES Intl 1st ed., 10.1.2.1 step 3.a
+            // 10.1.2.1 step 3.a
             construct = true;
         }
     }
-
     if (construct) {
-        // Steps 2-5 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
-        RootedObject proto(cx);
-        if (args.isConstructing() && !GetPrototypeFromCallableConstructor(cx, args, &proto))
+        // 10.1.3.1 paragraph 2
+        RootedObject proto(cx, cx->global()->getOrCreateCollatorPrototype(cx));
+        if (!proto)
             return false;
-
-        if (!proto) {
-            proto = cx->global()->getOrCreateCollatorPrototype(cx);
-            if (!proto)
-                return false;
-        }
-
         obj = NewObjectWithGivenProto(cx, &CollatorClass, proto);
         if (!obj)
             return false;
 
         obj->as<NativeObject>().setReservedSlot(UCOLLATOR_SLOT, PrivateValue(nullptr));
     }
 
+    // 10.1.2.1 steps 1 and 2; 10.1.3.1 steps 1 and 2
     RootedValue locales(cx, args.length() > 0 ? args[0] : UndefinedValue());
     RootedValue options(cx, args.length() > 1 ? args[1] : UndefinedValue());
 
-    // Step 6.
+    // 10.1.2.1 step 6; 10.1.3.1 step 3
     if (!IntlInitialize(cx, obj, cx->names().InitializeCollator, locales, options))
         return false;
 
+    // 10.1.2.1 steps 3.a and 7
     args.rval().setObject(*obj);
     return true;
 }
 
 static bool
 Collator(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return Collator(cx, args, args.isConstructing());
 }
 
 bool
 js::intl_Collator(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 2);
-    MOZ_ASSERT(!args.isConstructing());
     // intl_Collator is an intrinsic for self-hosted JavaScript, so it cannot
     // be used with "new", but it still has to be treated as a constructor.
     return Collator(cx, args, true);
 }
 
 static void
 collator_finalize(FreeOp* fop, JSObject* obj)
 {
@@ -1266,95 +1255,84 @@ static const JSFunctionSpec numberFormat
     JS_SELF_HOSTED_FN("resolvedOptions", "Intl_NumberFormat_resolvedOptions", 0, 0),
 #if JS_HAS_TOSOURCE
     JS_FN(js_toSource_str, numberFormat_toSource, 0, 0),
 #endif
     JS_FS_END
 };
 
 /**
- * 11.2.1 Intl.NumberFormat([ locales [, options]])
- *
- * ES2017 Intl draft rev 94045d234762ad107a3d09bb6f7381a65f1a2f9b
+ * NumberFormat constructor.
+ * Spec: ECMAScript Internationalization API Specification, 11.1
  */
 static bool
 NumberFormat(JSContext* cx, const CallArgs& args, bool construct)
 {
     RootedObject obj(cx);
 
-    // We're following ECMA-402 1st Edition when NumberFormat is called
-    // because of backward compatibility issues.
-    // See https://github.com/tc39/ecma402/issues/57
     if (!construct) {
-        // ES Intl 1st ed., 11.1.2.1 step 3
+        // 11.1.2.1 step 3
         JSObject* intl = cx->global()->getOrCreateIntlObject(cx);
         if (!intl)
             return false;
         RootedValue self(cx, args.thisv());
         if (!self.isUndefined() && (!self.isObject() || self.toObject() != *intl)) {
-            // ES Intl 1st ed., 11.1.2.1 step 4
+            // 11.1.2.1 step 4
             obj = ToObject(cx, self);
             if (!obj)
                 return false;
 
-            // ES Intl 1st ed., 11.1.2.1 step 5
+            // 11.1.2.1 step 5
             bool extensible;
             if (!IsExtensible(cx, obj, &extensible))
                 return false;
             if (!extensible)
                 return Throw(cx, obj, JSMSG_OBJECT_NOT_EXTENSIBLE);
         } else {
-            // ES Intl 1st ed., 11.1.2.1 step 3.a
+            // 11.1.2.1 step 3.a
             construct = true;
         }
     }
-
     if (construct) {
-        // Step 2 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
-        RootedObject proto(cx);
-        if (args.isConstructing() && !GetPrototypeFromCallableConstructor(cx, args, &proto))
+        // 11.1.3.1 paragraph 2
+        RootedObject proto(cx, cx->global()->getOrCreateNumberFormatPrototype(cx));
+        if (!proto)
             return false;
-
-        if (!proto) {
-            proto = cx->global()->getOrCreateNumberFormatPrototype(cx);
-            if (!proto)
-                return false;
-        }
-
         obj = NewObjectWithGivenProto(cx, &NumberFormatClass, proto);
         if (!obj)
             return false;
 
         obj->as<NativeObject>().setReservedSlot(UNUMBER_FORMAT_SLOT, PrivateValue(nullptr));
     }
 
+    // 11.1.2.1 steps 1 and 2; 11.1.3.1 steps 1 and 2
     RootedValue locales(cx, args.length() > 0 ? args[0] : UndefinedValue());
     RootedValue options(cx, args.length() > 1 ? args[1] : UndefinedValue());
 
-    // Step 3.
+    // 11.1.2.1 step 6; 11.1.3.1 step 3
     if (!IntlInitialize(cx, obj, cx->names().InitializeNumberFormat, locales, options))
         return false;
 
+    // 11.1.2.1 steps 3.a and 7
     args.rval().setObject(*obj);
     return true;
 }
 
 static bool
 NumberFormat(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return NumberFormat(cx, args, args.isConstructing());
 }
 
 bool
 js::intl_NumberFormat(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 2);
-    MOZ_ASSERT(!args.isConstructing());
     // intl_NumberFormat is an intrinsic for self-hosted JavaScript, so it
     // cannot be used with "new", but it still has to be treated as a
     // constructor.
     return NumberFormat(cx, args, true);
 }
 
 static void
 numberFormat_finalize(FreeOp* fop, JSObject* obj)
@@ -1745,95 +1723,84 @@ static const JSFunctionSpec dateTimeForm
     JS_SELF_HOSTED_FN("formatToParts", "Intl_DateTimeFormat_formatToParts", 0, 0),
 #if JS_HAS_TOSOURCE
     JS_FN(js_toSource_str, dateTimeFormat_toSource, 0, 0),
 #endif
     JS_FS_END
 };
 
 /**
- * 12.2.1 Intl.DateTimeFormat([ locales [, options]])
- *
- * ES2017 Intl draft rev 94045d234762ad107a3d09bb6f7381a65f1a2f9b
+ * DateTimeFormat constructor.
+ * Spec: ECMAScript Internationalization API Specification, 12.1
  */
 static bool
 DateTimeFormat(JSContext* cx, const CallArgs& args, bool construct)
 {
     RootedObject obj(cx);
 
-    // We're following ECMA-402 1st Edition when DateTimeFormat is called
-    // because of backward compatibility issues.
-    // See https://github.com/tc39/ecma402/issues/57
     if (!construct) {
-        // ES Intl 1st ed., 12.1.2.1 step 3
+        // 12.1.2.1 step 3
         JSObject* intl = cx->global()->getOrCreateIntlObject(cx);
         if (!intl)
             return false;
         RootedValue self(cx, args.thisv());
         if (!self.isUndefined() && (!self.isObject() || self.toObject() != *intl)) {
-            // ES Intl 1st ed., 12.1.2.1 step 4
+            // 12.1.2.1 step 4
             obj = ToObject(cx, self);
             if (!obj)
                 return false;
 
-            // ES Intl 1st ed., 12.1.2.1 step 5
+            // 12.1.2.1 step 5
             bool extensible;
             if (!IsExtensible(cx, obj, &extensible))
                 return false;
             if (!extensible)
                 return Throw(cx, obj, JSMSG_OBJECT_NOT_EXTENSIBLE);
         } else {
-            // ES Intl 1st ed., 12.1.2.1 step 3.a
+            // 12.1.2.1 step 3.a
             construct = true;
         }
     }
-
     if (construct) {
-        // Step 2 (Inlined 9.1.14, OrdinaryCreateFromConstructor).
-        RootedObject proto(cx);
-        if (args.isConstructing() && !GetPrototypeFromCallableConstructor(cx, args, &proto))
+        // 12.1.3.1 paragraph 2
+        RootedObject proto(cx, cx->global()->getOrCreateDateTimeFormatPrototype(cx));
+        if (!proto)
             return false;
-
-        if (!proto) {
-            proto = cx->global()->getOrCreateDateTimeFormatPrototype(cx);
-            if (!proto)
-                return false;
-        }
-
         obj = NewObjectWithGivenProto(cx, &DateTimeFormatClass, proto);
         if (!obj)
             return false;
 
         obj->as<NativeObject>().setReservedSlot(UDATE_FORMAT_SLOT, PrivateValue(nullptr));
     }
 
+    // 12.1.2.1 steps 1 and 2; 12.1.3.1 steps 1 and 2
     RootedValue locales(cx, args.length() > 0 ? args[0] : UndefinedValue());
     RootedValue options(cx, args.length() > 1 ? args[1] : UndefinedValue());
 
-    // Step 3.
+    // 12.1.2.1 step 6; 12.1.3.1 step 3
     if (!IntlInitialize(cx, obj, cx->names().InitializeDateTimeFormat, locales, options))
         return false;
 
+    // 12.1.2.1 steps 3.a and 7
     args.rval().setObject(*obj);
     return true;
 }
 
 static bool
 DateTimeFormat(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return DateTimeFormat(cx, args, args.isConstructing());
 }
 
 bool
 js::intl_DateTimeFormat(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 2);
-    MOZ_ASSERT(!args.isConstructing());
     // intl_DateTimeFormat is an intrinsic for self-hosted JavaScript, so it
     // cannot be used with "new", but it still has to be treated as a
     // constructor.
     return DateTimeFormat(cx, args, true);
 }
 
 static void
 dateTimeFormat_finalize(FreeOp* fop, JSObject* obj)
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -1625,19 +1625,21 @@ const JSFunctionSpec js::function_method
     JS_FN(js_call_str,       fun_call,       1,0),
     JS_FN("isGenerator",     fun_isGenerator,0,0),
     JS_SELF_HOSTED_FN("bind", "FunctionBind", 2, JSFUN_HAS_REST),
     JS_SYM_FN(hasInstance, fun_symbolHasInstance, 1, JSPROP_READONLY | JSPROP_PERMANENT),
     JS_FS_END
 };
 
 static bool
-FunctionConstructor(JSContext* cx, const CallArgs& args, GeneratorKind generatorKind,
+FunctionConstructor(JSContext* cx, unsigned argc, Value* vp, GeneratorKind generatorKind,
                     FunctionAsyncKind asyncKind)
 {
+    CallArgs args = CallArgsFromVp(argc, vp);
+
     /* Block this call if security callbacks forbid it. */
     Rooted<GlobalObject*> global(cx, &args.callee().global());
     if (!GlobalObject::isRuntimeCodeGenEnabled(cx, global)) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_FUNCTION);
         return false;
     }
 
     bool isStarGenerator = generatorKind == StarGenerator;
@@ -1744,33 +1746,26 @@ FunctionConstructor(JSContext* cx, const
 
     /*
      * NB: (new Function) is not lexically closed by its caller, it's just an
      * anonymous function in the top-level scope that its constructor inhabits.
      * Thus 'var x = 42; f = new Function("return x"); print(f())' prints 42,
      * and so would a call to f from another top-level's script or function.
      */
     RootedAtom anonymousAtom(cx, cx->names().anonymous);
-
-    // ES2017, draft rev 0f10dba4ad18de92d47d421f378233a2eae8f077
-    // 19.2.1.1.1 Runtime Semantics: CreateDynamicFunction, step 24.
     RootedObject proto(cx);
-    if (!isAsync) {
-        if (!GetPrototypeFromCallableConstructor(cx, args, &proto))
-            return false;
-    }
-
-    // 19.2.1.1.1, step 4.d, use %Generator% as the fallback prototype.
-    // Also use %Generator% for the unwrapped function of async functions.
-    if (!proto && isStarGenerator) {
+    if (isStarGenerator) {
         // Unwrapped function of async function should use GeneratorFunction,
         // while wrapped function isn't generator.
         proto = GlobalObject::getOrCreateStarGeneratorFunctionPrototype(cx, global);
         if (!proto)
             return false;
+    } else {
+        if (!GetPrototypeFromCallableConstructor(cx, args, &proto))
+            return false;
     }
 
     RootedObject globalLexical(cx, &global->lexicalEnvironment());
     AllocKind allocKind = isAsync ? AllocKind::FUNCTION_EXTENDED : AllocKind::FUNCTION;
     RootedFunction fun(cx, NewFunctionWithProto(cx, nullptr, 0,
                                                 JSFunction::INTERPRETED_LAMBDA, globalLexical,
                                                 anonymousAtom, proto,
                                                 allocKind, TenuredObject));
@@ -1869,57 +1864,34 @@ FunctionConstructor(JSContext* cx, const
         ok = frontend::CompileFunctionBody(cx, &fun, options, formals, srcBuf);
     args.rval().setObject(*fun);
     return ok;
 }
 
 bool
 js::Function(JSContext* cx, unsigned argc, Value* vp)
 {
-    CallArgs args = CallArgsFromVp(argc, vp);
-    return FunctionConstructor(cx, args, NotGenerator, SyncFunction);
+    return FunctionConstructor(cx, argc, vp, NotGenerator, SyncFunction);
 }
 
 bool
 js::Generator(JSContext* cx, unsigned argc, Value* vp)
 {
-    CallArgs args = CallArgsFromVp(argc, vp);
-    return FunctionConstructor(cx, args, StarGenerator, SyncFunction);
+    return FunctionConstructor(cx, argc, vp, StarGenerator, SyncFunction);
 }
 
 bool
 js::AsyncFunctionConstructor(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-
-    // Save the callee before its reset in FunctionConstructor().
-    RootedObject newTarget(cx);
-    if (args.isConstructing())
-        newTarget = &args.newTarget().toObject();
-    else
-        newTarget = &args.callee();
-
-    if (!FunctionConstructor(cx, args, StarGenerator, AsyncFunction))
+    if (!FunctionConstructor(cx, argc, vp, StarGenerator, AsyncFunction))
         return false;
 
-    // ES2017, draft rev 0f10dba4ad18de92d47d421f378233a2eae8f077
-    // 19.2.1.1.1 Runtime Semantics: CreateDynamicFunction, step 24.
-    RootedObject proto(cx);
-    if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
-        return false;
-
-    // 19.2.1.1.1, step 4.d, use %AsyncFunctionPrototype% as the fallback.
-    if (!proto) {
-        proto = GlobalObject::getOrCreateAsyncFunctionPrototype(cx, cx->global());
-        if (!proto)
-            return false;
-    }
-
     RootedFunction unwrapped(cx, &args.rval().toObject().as<JSFunction>());
-    RootedObject wrapped(cx, WrapAsyncFunctionWithProto(cx, unwrapped, proto));
+    RootedObject wrapped(cx, WrapAsyncFunction(cx, unwrapped));
     if (!wrapped)
         return false;
 
     args.rval().setObject(*wrapped);
     return true;
 }
 
 bool
--- a/js/src/jswatchpoint.cpp
+++ b/js/src/jswatchpoint.cpp
@@ -179,27 +179,28 @@ WatchpointMap::markIteratively(JSTracer*
     return marked;
 }
 
 void
 WatchpointMap::markAll(JSTracer* trc)
 {
     for (Map::Enum e(map); !e.empty(); e.popFront()) {
         Map::Entry& entry = e.front();
-        WatchKey key = entry.key();
-        WatchKey prior = key;
-        MOZ_ASSERT(JSID_IS_STRING(prior.id) || JSID_IS_INT(prior.id) || JSID_IS_SYMBOL(prior.id));
+        JSObject* object = entry.key().object;
+        jsid id = entry.key().id;
+        JSObject* priorObject = object;
+        jsid priorId = id;
+        MOZ_ASSERT(JSID_IS_STRING(priorId) || JSID_IS_INT(priorId) || JSID_IS_SYMBOL(priorId));
 
-        TraceEdge(trc, const_cast<PreBarrieredObject*>(&key.object),
-                   "held Watchpoint object");
-        TraceEdge(trc, const_cast<PreBarrieredId*>(&key.id), "WatchKey::id");
+        TraceManuallyBarrieredEdge(trc, &object, "held Watchpoint object");
+        TraceManuallyBarrieredEdge(trc, &id, "WatchKey::id");
         TraceEdge(trc, &entry.value().closure, "Watchpoint::closure");
 
-        if (prior.object != key.object || prior.id != key.id)
-            e.rekeyFront(key);
+        if (priorObject != object || priorId != id)
+            e.rekeyFront(WatchKey(object, id));
     }
 }
 
 void
 WatchpointMap::sweepAll(JSRuntime* rt)
 {
     for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
         if (WatchpointMap* wpmap = c->watchpointMap)
deleted file mode 100644
--- a/js/src/tests/Intl/Collator/construct-newtarget.js
+++ /dev/null
@@ -1,79 +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/. */
-
-
-// Test subclassing %Intl.Collator% works correctly.
-class MyCollator extends Intl.Collator {}
-
-var obj = new MyCollator();
-assertEq(obj instanceof MyCollator, true);
-assertEq(obj instanceof Intl.Collator, true);
-assertEq(Object.getPrototypeOf(obj), MyCollator.prototype);
-
-obj = Reflect.construct(MyCollator, []);
-assertEq(obj instanceof MyCollator, true);
-assertEq(obj instanceof Intl.Collator, true);
-assertEq(Object.getPrototypeOf(obj), MyCollator.prototype);
-
-obj = Reflect.construct(MyCollator, [], MyCollator);
-assertEq(obj instanceof MyCollator, true);
-assertEq(obj instanceof Intl.Collator, true);
-assertEq(Object.getPrototypeOf(obj), MyCollator.prototype);
-
-obj = Reflect.construct(MyCollator, [], Intl.Collator);
-assertEq(obj instanceof MyCollator, false);
-assertEq(obj instanceof Intl.Collator, true);
-assertEq(Object.getPrototypeOf(obj), Intl.Collator.prototype);
-
-
-// Set a different constructor as NewTarget.
-obj = Reflect.construct(MyCollator, [], Array);
-assertEq(obj instanceof MyCollator, false);
-assertEq(obj instanceof Intl.Collator, false);
-assertEq(obj instanceof Array, true);
-assertEq(Object.getPrototypeOf(obj), Array.prototype);
-
-obj = Reflect.construct(Intl.Collator, [], Array);
-assertEq(obj instanceof Intl.Collator, false);
-assertEq(obj instanceof Array, true);
-assertEq(Object.getPrototypeOf(obj), Array.prototype);
-
-
-// The prototype defaults to %CollatorPrototype% if null.
-function NewTargetNullPrototype() {}
-NewTargetNullPrototype.prototype = null;
-
-obj = Reflect.construct(Intl.Collator, [], NewTargetNullPrototype);
-assertEq(obj instanceof Intl.Collator, true);
-assertEq(Object.getPrototypeOf(obj), Intl.Collator.prototype);
-
-obj = Reflect.construct(MyCollator, [], NewTargetNullPrototype);
-assertEq(obj instanceof MyCollator, false);
-assertEq(obj instanceof Intl.Collator, true);
-assertEq(Object.getPrototypeOf(obj), Intl.Collator.prototype);
-
-
-// "prototype" property is retrieved exactly once.
-var trapLog = [], getLog = [];
-var ProxiedConstructor = new Proxy(Intl.Collator, new Proxy({
-    get(target, propertyKey, receiver) {
-        getLog.push(propertyKey);
-        return Reflect.get(target, propertyKey, receiver);
-    }
-}, {
-    get(target, propertyKey, receiver) {
-        trapLog.push(propertyKey);
-        return Reflect.get(target, propertyKey, receiver);
-    }
-}));
-
-obj = Reflect.construct(Intl.Collator, [], ProxiedConstructor);
-assertEqArray(trapLog, ["get"]);
-assertEqArray(getLog, ["prototype"]);
-assertEq(obj instanceof Intl.Collator, true);
-assertEq(Object.getPrototypeOf(obj), Intl.Collator.prototype);
-
-
-if (typeof reportCompare === "function")
-    reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/Intl/DateTimeFormat/construct-newtarget.js
+++ /dev/null
@@ -1,79 +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/. */
-
-
-// Test subclassing %Intl.DateTimeFormat% works correctly.
-class MyDateTimeFormat extends Intl.DateTimeFormat {}
-
-var obj = new MyDateTimeFormat();
-assertEq(obj instanceof MyDateTimeFormat, true);
-assertEq(obj instanceof Intl.DateTimeFormat, true);
-assertEq(Object.getPrototypeOf(obj), MyDateTimeFormat.prototype);
-
-obj = Reflect.construct(MyDateTimeFormat, []);
-assertEq(obj instanceof MyDateTimeFormat, true);
-assertEq(obj instanceof Intl.DateTimeFormat, true);
-assertEq(Object.getPrototypeOf(obj), MyDateTimeFormat.prototype);
-
-obj = Reflect.construct(MyDateTimeFormat, [], MyDateTimeFormat);
-assertEq(obj instanceof MyDateTimeFormat, true);
-assertEq(obj instanceof Intl.DateTimeFormat, true);
-assertEq(Object.getPrototypeOf(obj), MyDateTimeFormat.prototype);
-
-obj = Reflect.construct(MyDateTimeFormat, [], Intl.DateTimeFormat);
-assertEq(obj instanceof MyDateTimeFormat, false);
-assertEq(obj instanceof Intl.DateTimeFormat, true);
-assertEq(Object.getPrototypeOf(obj), Intl.DateTimeFormat.prototype);
-
-
-// Set a different constructor as NewTarget.
-obj = Reflect.construct(MyDateTimeFormat, [], Array);
-assertEq(obj instanceof MyDateTimeFormat, false);
-assertEq(obj instanceof Intl.DateTimeFormat, false);
-assertEq(obj instanceof Array, true);
-assertEq(Object.getPrototypeOf(obj), Array.prototype);
-
-obj = Reflect.construct(Intl.DateTimeFormat, [], Array);
-assertEq(obj instanceof Intl.DateTimeFormat, false);
-assertEq(obj instanceof Array, true);
-assertEq(Object.getPrototypeOf(obj), Array.prototype);
-
-
-// The prototype defaults to %DateTimeFormatPrototype% if null.
-function NewTargetNullPrototype() {}
-NewTargetNullPrototype.prototype = null;
-
-obj = Reflect.construct(Intl.DateTimeFormat, [], NewTargetNullPrototype);
-assertEq(obj instanceof Intl.DateTimeFormat, true);
-assertEq(Object.getPrototypeOf(obj), Intl.DateTimeFormat.prototype);
-
-obj = Reflect.construct(MyDateTimeFormat, [], NewTargetNullPrototype);
-assertEq(obj instanceof MyDateTimeFormat, false);
-assertEq(obj instanceof Intl.DateTimeFormat, true);
-assertEq(Object.getPrototypeOf(obj), Intl.DateTimeFormat.prototype);
-
-
-// "prototype" property is retrieved exactly once.
-var trapLog = [], getLog = [];
-var ProxiedConstructor = new Proxy(Intl.DateTimeFormat, new Proxy({
-    get(target, propertyKey, receiver) {
-        getLog.push(propertyKey);
-        return Reflect.get(target, propertyKey, receiver);
-    }
-}, {
-    get(target, propertyKey, receiver) {
-        trapLog.push(propertyKey);
-        return Reflect.get(target, propertyKey, receiver);
-    }
-}));
-
-obj = Reflect.construct(Intl.DateTimeFormat, [], ProxiedConstructor);
-assertEqArray(trapLog, ["get"]);
-assertEqArray(getLog, ["prototype"]);
-assertEq(obj instanceof Intl.DateTimeFormat, true);
-assertEq(Object.getPrototypeOf(obj), Intl.DateTimeFormat.prototype);
-
-
-if (typeof reportCompare === "function")
-    reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/Intl/NumberFormat/construct-newtarget.js
+++ /dev/null
@@ -1,79 +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/. */
-
-
-// Test subclassing %Intl.NumberFormat% works correctly.
-class MyNumberFormat extends Intl.NumberFormat {}
-
-var obj = new MyNumberFormat();
-assertEq(obj instanceof MyNumberFormat, true);
-assertEq(obj instanceof Intl.NumberFormat, true);
-assertEq(Object.getPrototypeOf(obj), MyNumberFormat.prototype);
-
-obj = Reflect.construct(MyNumberFormat, []);
-assertEq(obj instanceof MyNumberFormat, true);
-assertEq(obj instanceof Intl.NumberFormat, true);
-assertEq(Object.getPrototypeOf(obj), MyNumberFormat.prototype);
-
-obj = Reflect.construct(MyNumberFormat, [], MyNumberFormat);
-assertEq(obj instanceof MyNumberFormat, true);
-assertEq(obj instanceof Intl.NumberFormat, true);
-assertEq(Object.getPrototypeOf(obj), MyNumberFormat.prototype);
-
-obj = Reflect.construct(MyNumberFormat, [], Intl.NumberFormat);
-assertEq(obj instanceof MyNumberFormat, false);
-assertEq(obj instanceof Intl.NumberFormat, true);
-assertEq(Object.getPrototypeOf(obj), Intl.NumberFormat.prototype);
-
-
-// Set a different constructor as NewTarget.
-obj = Reflect.construct(MyNumberFormat, [], Array);
-assertEq(obj instanceof MyNumberFormat, false);
-assertEq(obj instanceof Intl.NumberFormat, false);
-assertEq(obj instanceof Array, true);
-assertEq(Object.getPrototypeOf(obj), Array.prototype);
-
-obj = Reflect.construct(Intl.NumberFormat, [], Array);
-assertEq(obj instanceof Intl.NumberFormat, false);
-assertEq(obj instanceof Array, true);
-assertEq(Object.getPrototypeOf(obj), Array.prototype);
-
-
-// The prototype defaults to %NumberFormatPrototype% if null.
-function NewTargetNullPrototype() {}
-NewTargetNullPrototype.prototype = null;
-
-obj = Reflect.construct(Intl.NumberFormat, [], NewTargetNullPrototype);
-assertEq(obj instanceof Intl.NumberFormat, true);
-assertEq(Object.getPrototypeOf(obj), Intl.NumberFormat.prototype);
-
-obj = Reflect.construct(MyNumberFormat, [], NewTargetNullPrototype);
-assertEq(obj instanceof MyNumberFormat, false);
-assertEq(obj instanceof Intl.NumberFormat, true);
-assertEq(Object.getPrototypeOf(obj), Intl.NumberFormat.prototype);
-
-
-// "prototype" property is retrieved exactly once.
-var trapLog = [], getLog = [];
-var ProxiedConstructor = new Proxy(Intl.NumberFormat, new Proxy({
-    get(target, propertyKey, receiver) {
-        getLog.push(propertyKey);
-        return Reflect.get(target, propertyKey, receiver);
-    }
-}, {
-    get(target, propertyKey, receiver) {
-        trapLog.push(propertyKey);
-        return Reflect.get(target, propertyKey, receiver);
-    }
-}));
-
-obj = Reflect.construct(Intl.NumberFormat, [], ProxiedConstructor);
-assertEqArray(trapLog, ["get"]);
-assertEqArray(getLog, ["prototype"]);
-assertEq(obj instanceof Intl.NumberFormat, true);
-assertEq(Object.getPrototypeOf(obj), Intl.NumberFormat.prototype);
-
-
-if (typeof reportCompare === "function")
-    reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/ecma_2017/AsyncFunctions/construct-newtarget.js
+++ /dev/null
@@ -1,79 +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/. */
-
-const AsyncFunction = async function(){}.constructor;
-
-
-// Test subclassing %AsyncFunction% works correctly.
-class MyAsync extends AsyncFunction {}
-
-var fn = new MyAsync();
-assertEq(fn instanceof MyAsync, true);
-assertEq(fn instanceof AsyncFunction, true);
-assertEq(Object.getPrototypeOf(fn), MyAsync.prototype);
-
-fn = Reflect.construct(MyAsync, []);
-assertEq(fn instanceof MyAsync, true);
-assertEq(fn instanceof AsyncFunction, true);
-assertEq(Object.getPrototypeOf(fn), MyAsync.prototype);
-
-fn = Reflect.construct(MyAsync, [], MyAsync);
-assertEq(fn instanceof MyAsync, true);
-assertEq(fn instanceof AsyncFunction, true);
-assertEq(Object.getPrototypeOf(fn), MyAsync.prototype);
-
-fn = Reflect.construct(MyAsync, [], AsyncFunction);
-assertEq(fn instanceof MyAsync, false);
-assertEq(fn instanceof AsyncFunction, true);
-assertEq(Object.getPrototypeOf(fn), AsyncFunction.prototype);
-
-
-// Set a different constructor as NewTarget.
-fn = Reflect.construct(MyAsync, [], Array);
-assertEq(fn instanceof MyAsync, false);
-assertEq(fn instanceof AsyncFunction, false);
-assertEq(Object.getPrototypeOf(fn), Array.prototype);
-
-fn = Reflect.construct(AsyncFunction, [], Array);
-assertEq(fn instanceof AsyncFunction, false);
-assertEq(Object.getPrototypeOf(fn), Array.prototype);
-
-
-// The prototype defaults to %AsyncFunctionPrototype% if null.
-function NewTargetNullPrototype() {}
-NewTargetNullPrototype.prototype = null;
-
-fn = Reflect.construct(AsyncFunction, [], NewTargetNullPrototype);
-assertEq(fn instanceof AsyncFunction, true);
-assertEq(Object.getPrototypeOf(fn), AsyncFunction.prototype);
-
-fn = Reflect.construct(MyAsync, [], NewTargetNullPrototype);
-assertEq(fn instanceof MyAsync, false);
-assertEq(fn instanceof AsyncFunction, true);
-assertEq(Object.getPrototypeOf(fn), AsyncFunction.prototype);
-
-
-// "prototype" property is retrieved exactly once.
-var trapLog = [], getLog = [];
-var ProxiedConstructor = new Proxy(AsyncFunction, new Proxy({
-    get(target, propertyKey, receiver) {
-        getLog.push(propertyKey);
-        return Reflect.get(target, propertyKey, receiver);
-    }
-}, {
-    get(target, propertyKey, receiver) {
-        trapLog.push(propertyKey);
-        return Reflect.get(target, propertyKey, receiver);
-    }
-}));
-
-fn = Reflect.construct(AsyncFunction, [], ProxiedConstructor);
-assertEqArray(trapLog, ["get"]);
-assertEqArray(getLog, ["prototype"]);
-assertEq(fn instanceof AsyncFunction, true);
-assertEq(Object.getPrototypeOf(fn), AsyncFunction.prototype);
-
-
-if (typeof reportCompare === "function")
-    reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/ecma_2017/AsyncFunctions/subclass.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// |reftest| skip-if(!xulRuntime.shell) -- needs drainJobQueue
-/* 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/. */
-
-const AsyncFunction = async function(){}.constructor;
-
-class MyAsync extends AsyncFunction {}
-
-// MyGen inherits from %AsyncFunction%.
-assertEq(Object.getPrototypeOf(MyAsync), AsyncFunction);
-
-// MyGen.prototype inherits from %AsyncFunctionPrototype%.
-assertEq(Object.getPrototypeOf(MyAsync.prototype), AsyncFunction.prototype);
-
-var fn = new MyAsync("return await 'ok';");
-
-// fn inherits from MyAsync.prototype.
-assertEq(Object.getPrototypeOf(fn), MyAsync.prototype);
-
-// Ensure the new async function can be executed.
-var promise = fn();
-
-// promise inherits from %Promise.prototype%.
-assertEq(Object.getPrototypeOf(promise), Promise.prototype);
-
-// Computes the expected result.
-assertEventuallyEq(promise, "ok");
-
-if (typeof reportCompare === "function")
-    reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/ecma_6/Generators/construct-newtarget.js
+++ /dev/null
@@ -1,79 +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/. */
-
-const GeneratorFunction = function*(){}.constructor;
-
-
-// Test subclassing %GeneratorFunction% works correctly.
-class MyGenerator extends GeneratorFunction {}
-
-var fn = new MyGenerator();
-assertEq(fn instanceof MyGenerator, true);
-assertEq(fn instanceof GeneratorFunction, true);
-assertEq(Object.getPrototypeOf(fn), MyGenerator.prototype);
-
-fn = Reflect.construct(MyGenerator, []);
-assertEq(fn instanceof MyGenerator, true);
-assertEq(fn instanceof GeneratorFunction, true);
-assertEq(Object.getPrototypeOf(fn), MyGenerator.prototype);
-
-fn = Reflect.construct(MyGenerator, [], MyGenerator);
-assertEq(fn instanceof MyGenerator, true);
-assertEq(fn instanceof GeneratorFunction, true);
-assertEq(Object.getPrototypeOf(fn), MyGenerator.prototype);
-
-fn = Reflect.construct(MyGenerator, [], GeneratorFunction);
-assertEq(fn instanceof MyGenerator, false);
-assertEq(fn instanceof GeneratorFunction, true);
-assertEq(Object.getPrototypeOf(fn), GeneratorFunction.prototype);
-
-
-// Set a different constructor as NewTarget.
-fn = Reflect.construct(MyGenerator, [], Array);
-assertEq(fn instanceof MyGenerator, false);
-assertEq(fn instanceof GeneratorFunction, false);
-assertEq(Object.getPrototypeOf(fn), Array.prototype);
-
-fn = Reflect.construct(GeneratorFunction, [], Array);
-assertEq(fn instanceof GeneratorFunction, false);
-assertEq(Object.getPrototypeOf(fn), Array.prototype);
-
-
-// The prototype defaults to %GeneratorFunctionPrototype% if null.
-function NewTargetNullPrototype() {}
-NewTargetNullPrototype.prototype = null;
-
-fn = Reflect.construct(GeneratorFunction, [], NewTargetNullPrototype);
-assertEq(fn instanceof GeneratorFunction, true);
-assertEq(Object.getPrototypeOf(fn), GeneratorFunction.prototype);
-
-fn = Reflect.construct(MyGenerator, [], NewTargetNullPrototype);
-assertEq(fn instanceof MyGenerator, false);
-assertEq(fn instanceof GeneratorFunction, true);
-assertEq(Object.getPrototypeOf(fn), GeneratorFunction.prototype);
-
-
-// "prototype" property is retrieved exactly once.
-var trapLog = [], getLog = [];
-var ProxiedConstructor = new Proxy(GeneratorFunction, new Proxy({
-    get(target, propertyKey, receiver) {
-        getLog.push(propertyKey);
-        return Reflect.get(target, propertyKey, receiver);
-    }
-}, {
-    get(target, propertyKey, receiver) {
-        trapLog.push(propertyKey);
-        return Reflect.get(target, propertyKey, receiver);
-    }
-}));
-
-fn = Reflect.construct(GeneratorFunction, [], ProxiedConstructor);
-assertEqArray(trapLog, ["get"]);
-assertEqArray(getLog, ["prototype"]);
-assertEq(fn instanceof GeneratorFunction, true);
-assertEq(Object.getPrototypeOf(fn), GeneratorFunction.prototype);
-
-
-if (typeof reportCompare === "function")
-    reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/ecma_6/Generators/subclass.js
+++ /dev/null
@@ -1,33 +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/. */
-
-const GeneratorFunction = function*(){}.constructor;
-
-class MyGen extends GeneratorFunction {}
-
-// MyGen inherits from %GeneratorFunction%.
-assertEq(Object.getPrototypeOf(MyGen), GeneratorFunction);
-
-// MyGen.prototype inherits from %Generator%.
-assertEq(Object.getPrototypeOf(MyGen.prototype), GeneratorFunction.prototype);
-
-var fn = new MyGen("yield* [1, 2, 3]");
-
-// fn inherits from MyGen.prototype.
-assertEq(Object.getPrototypeOf(fn), MyGen.prototype);
-
-// fn.prototype inherits from %GeneratorPrototype%.
-assertEq(Object.getPrototypeOf(fn.prototype), GeneratorFunction.prototype.prototype);
-
-// Ensure the new generator function can be executed.
-var it = fn();
-
-// it inherits from fn.prototype.
-assertEq(Object.getPrototypeOf(it), fn.prototype);
-
-// Computes the expected result.
-assertEqArray([...it], [1, 2, 3]);
-
-if (typeof reportCompare === "function")
-    reportCompare(0, 0);
--- a/js/src/vm/AsyncFunction.cpp
+++ b/js/src/vm/AsyncFunction.cpp
@@ -105,25 +105,28 @@ WrappedAsyncFunction(JSContext* cx, unsi
 }
 
 // Async Functions proposal 2.1 steps 1, 3 (partially).
 // In the spec it creates a function, but we create 2 functions `unwrapped` and
 // `wrapped`.  `unwrapped` is a generator that corresponds to
 //  the async function's body, replacing `await` with `yield`.  `wrapped` is a
 // function that is visible to the outside, and handles yielded values.
 JSObject*
-js::WrapAsyncFunctionWithProto(JSContext* cx, HandleFunction unwrapped, HandleObject proto)
+js::WrapAsyncFunction(JSContext* cx, HandleFunction unwrapped)
 {
     MOZ_ASSERT(unwrapped->isStarGenerator());
-    MOZ_ASSERT(proto, "We need an explicit prototype to avoid the default"
-                      "%FunctionPrototype% fallback in NewFunctionWithProto().");
 
     // Create a new function with AsyncFunctionPrototype, reusing the name and
     // the length of `unwrapped`.
 
+    // Step 1.
+    RootedObject proto(cx, GlobalObject::getOrCreateAsyncFunctionPrototype(cx, cx->global()));
+    if (!proto)
+        return nullptr;
+
     RootedAtom funName(cx, unwrapped->name());
     uint16_t length;
     if (!unwrapped->getLength(cx, &length))
         return nullptr;
 
     // Steps 3 (partially).
     RootedFunction wrapped(cx, NewFunctionWithProto(cx, WrappedAsyncFunction, length,
                                                     JSFunction::NATIVE_FUN, nullptr,
@@ -136,26 +139,16 @@ js::WrapAsyncFunctionWithProto(JSContext
     // Link them to each other to make GetWrappedAsyncFunction and
     // GetUnwrappedAsyncFunction work.
     unwrapped->setExtendedSlot(UNWRAPPED_ASYNC_WRAPPED_SLOT, ObjectValue(*wrapped));
     wrapped->setExtendedSlot(WRAPPED_ASYNC_UNWRAPPED_SLOT, ObjectValue(*unwrapped));
 
     return wrapped;
 }
 
-JSObject*
-js::WrapAsyncFunction(JSContext* cx, HandleFunction unwrapped)
-{
-    RootedObject proto(cx, GlobalObject::getOrCreateAsyncFunctionPrototype(cx, cx->global()));
-    if (!proto)
-        return nullptr;
-
-    return WrapAsyncFunctionWithProto(cx, unwrapped, proto);
-}
-
 enum class ResumeKind {
     Normal,
     Throw
 };
 
 // Async Functions proposal 2.2 steps 3.f, 3.g.
 // Async Functions proposal 2.2 steps 3.d-e, 3.g.
 // Implemented in js/src/builtin/Promise.cpp
--- a/js/src/vm/AsyncFunction.h
+++ b/js/src/vm/AsyncFunction.h
@@ -17,19 +17,16 @@ GetWrappedAsyncFunction(JSFunction* unwr
 
 JSFunction*
 GetUnwrappedAsyncFunction(JSFunction* wrapped);
 
 bool
 IsWrappedAsyncFunction(JSFunction* fun);
 
 JSObject*
-WrapAsyncFunctionWithProto(JSContext* cx, HandleFunction unwrapped, HandleObject proto);
-
-JSObject*
 WrapAsyncFunction(JSContext* cx, HandleFunction unwrapped);
 
 MOZ_MUST_USE bool
 AsyncFunctionAwaitedFulfilled(JSContext* cx, Handle<PromiseObject*> resultPromise,
                               HandleValue generatorVal, HandleValue value);
 
 MOZ_MUST_USE bool
 AsyncFunctionAwaitedRejected(JSContext* cx, Handle<PromiseObject*> resultPromise,
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5226,20 +5226,16 @@ pref("dom.caches.enabled", true);
 // Empirically, this is the value returned by hal::GetTotalSystemMemory()
 // when Flame's memory is limited to 512MiB. If the camera stack determines
 // it is running on a low memory platform, features that can be reliably
 // supported will be disabled. This threshold can be adjusted to suit other
 // platforms; and set to 0 to disable the low-memory check altogether.
 pref("camera.control.low_memory_thresholdMB", 404);
 #endif
 
-// SystemUpdate API
-pref("dom.system_update.enabled", false);
-pref("dom.system_update.debug", false);
-
 // UDPSocket API
 pref("dom.udpsocket.enabled", false);
 
 // Disable before keyboard events and after keyboard events by default.
 pref("dom.beforeAfterKeyboardEvent.enabled", false);
 
 // Presentation API
 pref("dom.presentation.enabled", false);
--- a/moz.build
+++ b/moz.build
@@ -65,17 +65,17 @@ if not CONFIG['JS_STANDALONE']:
 if CONFIG['USE_ICU']:
     DIRS += ['config/external/icu']
 
 if CONFIG['COMPILE_ENVIRONMENT']:
 
     if not CONFIG['JS_STANDALONE']:
         DIRS += [
             'config/external',
-            'config/external/nss',
+            'security',
         ]
 
     if CONFIG['BUILD_CTYPES']:
         DIRS += ['config/external/ffi']
 
     DIRS += ['js/src']
 else:
     TEST_DIRS += ['js/src/tests']
--- a/netwerk/base/security-prefs.js
+++ b/netwerk/base/security-prefs.js
@@ -9,17 +9,16 @@ pref("security.tls.insecure_fallback_hos
 pref("security.tls.unrestricted_rc4_fallback", false);
 pref("security.tls.enable_0rtt_data", false);
 
 pref("security.ssl.treat_unsafe_negotiation_as_broken", false);
 pref("security.ssl.require_safe_negotiation",  false);
 pref("security.ssl.enable_ocsp_stapling", true);
 pref("security.ssl.enable_false_start", true);
 pref("security.ssl.false_start.require-npn", false);
-pref("security.ssl.enable_npn", true);
 pref("security.ssl.enable_alpn", true);
 
 pref("security.ssl3.ecdhe_rsa_aes_128_gcm_sha256", true);
 pref("security.ssl3.ecdhe_ecdsa_aes_128_gcm_sha256", true);
 pref("security.ssl3.ecdhe_ecdsa_chacha20_poly1305_sha256", true);
 pref("security.ssl3.ecdhe_rsa_chacha20_poly1305_sha256", true);
 pref("security.ssl3.ecdhe_ecdsa_aes_256_gcm_sha384", true);
 pref("security.ssl3.ecdhe_rsa_aes_256_gcm_sha384", true);
--- a/old-configure.in
+++ b/old-configure.in
@@ -2125,16 +2125,25 @@ MOZ_ARG_WITH_BOOL(system-nss,
 if test -n "$_USE_SYSTEM_NSS"; then
     AM_PATH_NSS(3.28, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
 fi
 
 if test -n "$MOZ_SYSTEM_NSS"; then
    NSS_LIBS="$NSS_LIBS -lcrmf"
 else
    NSS_CFLAGS="-I${DIST}/include/nss"
+   case "${OS_ARCH}" in
+        # This is to match the conditions in security/generate_mapfile.py,
+        # plus Windows which doesn't run that script.
+        WINNT|Darwin|Linux)
+            ;;
+        *)
+            AC_MSG_ERROR([building in-tree NSS is not supported on this platform. Use --with-system-nss])
+            ;;
+   esac
 fi
 
 if test -z "$SKIP_LIBRARY_CHECKS"; then
 dnl system JPEG support
 dnl ========================================================
 MOZ_ARG_WITH_STRING(system-jpeg,
 [  --with-system-jpeg[=PFX]
                           Use system libjpeg [installed at prefix PFX]],
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -1619,34 +1619,43 @@ VARIABLES = {
         files are elsehwere (jar.mn, for instance) and this state of affairs
         is OK.
         """),
 
     'GYP_DIRS': (StrictOrderingOnAppendListWithFlagsFactory({
             'variables': dict,
             'input': unicode,
             'sandbox_vars': dict,
+            'no_chromium': bool,
+            'no_unified': bool,
             'non_unified_sources': StrictOrderingOnAppendList,
+            'action_overrides': dict,
         }), list,
         """Defines a list of object directories handled by gyp configurations.
 
         Elements of this list give the relative object directory. For each
         element of the list, GYP_DIRS may be accessed as a dictionary
         (GYP_DIRS[foo]). The object this returns has attributes that need to be
         set to further specify gyp processing:
             - input, gives the path to the root gyp configuration file for that
               object directory.
             - variables, a dictionary containing variables and values to pass
               to the gyp processor.
             - sandbox_vars, a dictionary containing variables and values to
               pass to the mozbuild processor on top of those derived from gyp
               configuration.
+            - no_chromium, a boolean which if set to True disables some
+              special handling that emulates gyp_chromium.
+            - no_unified, a boolean which if set to True disables source
+              file unification entirely.
             - non_unified_sources, a list containing sources files, relative to
               the current moz.build, that should be excluded from source file
               unification.
+            - action_overrides, a dict of action_name to values of the `script`
+              attribute to use for GENERATED_FILES for the specified action.
 
         Typical use looks like:
             GYP_DIRS += ['foo', 'bar']
             GYP_DIRS['foo'].input = 'foo/foo.gyp'
             GYP_DIRS['foo'].variables = {
                 'foo': 'bar',
                 (...)
             }
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -179,18 +179,16 @@ class TreeMetadataEmitter(LoggingMixin):
         # Keep track of external paths (third party build systems), starting
         # from what we run a subconfigure in. We'll eliminate some directories
         # as we traverse them with moz.build (e.g. js/src).
         subconfigures = os.path.join(self.config.topobjdir, 'subconfigures')
         paths = []
         if os.path.exists(subconfigures):
             paths = open(subconfigures).read().splitlines()
         self._external_paths = set(mozpath.normsep(d) for d in paths)
-        # Add security/nss manually, since it doesn't have a subconfigure.
-        self._external_paths.add('security/nss')
 
         self._emitter_time = 0.0
         self._object_count = 0
         self._test_files_converter = SupportFilesConverter()
 
     def summary(self):
         return ExecutionSummary(
             'Processed into {object_count:d} build config descriptors in '
--- a/python/mozbuild/mozbuild/frontend/gyp_reader.py
+++ b/python/mozbuild/mozbuild/frontend/gyp_reader.py
@@ -1,22 +1,24 @@
 # 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/.
 
 from __future__ import absolute_import, unicode_literals
 
 import gyp
+import gyp.msvs_emulation
 import sys
 import os
 import types
 import mozpack.path as mozpath
 from mozpack.files import FileFinder
 from .sandbox import alphabetical_sorted
 from .context import (
+    ObjDirPath,
     SourcePath,
     TemplateContext,
     VARIABLES,
 )
 from mozbuild.util import (
     expand_variables,
     List,
     memoize,
@@ -33,23 +35,30 @@ sys.modules['gyp.generator.mozbuild'] = 
 #   sys.path.insert(0, os.path.join(chrome_src, 'tools', 'gyp', 'pylib'))
 # We're not importing gyp_chromium, but we want both script_dir and
 # chrome_src for the default includes, so go backwards from the pylib
 # directory, which is the parent directory of gyp module.
 chrome_src = mozpath.abspath(mozpath.join(mozpath.dirname(gyp.__file__),
     '../../../..'))
 script_dir = mozpath.join(chrome_src, 'build')
 
+
+def encode(value):
+    if isinstance(value, unicode):
+        return value.encode('utf-8')
+    return value
+
+
 # Default variables gyp uses when evaluating gyp files.
 generator_default_variables = {
 }
-for dirname in ['INTERMEDIATE_DIR', 'SHARED_INTERMEDIATE_DIR', 'PRODUCT_DIR',
-                'LIB_DIR', 'SHARED_LIB_DIR']:
+for dirname in [b'INTERMEDIATE_DIR', b'SHARED_INTERMEDIATE_DIR', b'PRODUCT_DIR',
+                b'LIB_DIR', b'SHARED_LIB_DIR']:
   # Some gyp steps fail if these are empty(!).
-  generator_default_variables[dirname] = b'dir'
+  generator_default_variables[dirname] = b'$' + dirname
 
 for unused in ['RULE_INPUT_PATH', 'RULE_INPUT_ROOT', 'RULE_INPUT_NAME',
                'RULE_INPUT_DIRNAME', 'RULE_INPUT_EXT',
                'EXECUTABLE_PREFIX', 'EXECUTABLE_SUFFIX',
                'STATIC_LIB_PREFIX', 'STATIC_LIB_SUFFIX',
                'SHARED_LIB_PREFIX', 'SHARED_LIB_SUFFIX',
                'LINKER_SUPPORTS_ICF']:
   generator_default_variables[unused] = b''
@@ -63,56 +72,92 @@ class GypContext(TemplateContext):
     relative to the topobjdir defined in the ConfigEnvironment.
     """
     def __init__(self, config, relobjdir):
         self._relobjdir = relobjdir
         TemplateContext.__init__(self, template='Gyp',
             allowed_variables=VARIABLES, config=config)
 
 
-def encode(value):
-    if isinstance(value, unicode):
-        return value.encode('utf-8')
-    return value
+def handle_actions(actions, context, action_overrides):
+  idir = '$INTERMEDIATE_DIR/'
+  for action in actions:
+    name = action['action_name']
+    if name not in action_overrides:
+      raise RuntimeError('GYP action %s not listed in action_overrides' % name)
+    outputs = action['outputs']
+    if len(outputs) > 1:
+      raise NotImplementedError('GYP actions with more than one output not supported: %s' % name)
+    output = outputs[0]
+    if not output.startswith(idir):
+      raise NotImplementedError('GYP actions outputting to somewhere other than <(INTERMEDIATE_DIR) not supported: %s' % output)
+    output = output[len(idir):]
+    context['GENERATED_FILES'] += [output]
+    g = context['GENERATED_FILES'][output]
+    g.script = action_overrides[name]
+    g.inputs = action['inputs']
 
+def handle_copies(copies, context):
+  dist = '$PRODUCT_DIR/dist/'
+  for copy in copies:
+    dest = copy['destination']
+    if not dest.startswith(dist):
+      raise NotImplementedError('GYP copies to somewhere other than <(PRODUCT_DIR)/dist not supported: %s' % dest)
+    dest_paths = dest[len(dist):].split('/')
+    exports = context['EXPORTS']
+    while dest_paths:
+      exports = getattr(exports, dest_paths.pop(0))
+    exports += sorted(copy['files'], key=lambda x: x.lower())
 
-def read_from_gyp(config, path, output, vars, non_unified_sources = set()):
+def read_from_gyp(config, path, output, vars, no_chromium, no_unified, action_overrides, non_unified_sources = set()):
     """Read a gyp configuration and emits GypContexts for the backend to
     process.
 
     config is a ConfigEnvironment, path is the path to a root gyp configuration
     file, output is the base path under which the objdir for the various gyp
     dependencies will be, and vars a dict of variables to pass to the gyp
     processor.
     """
 
+    is_win = config.substs['OS_TARGET'] == 'WINNT'
+    is_msvc = bool(config.substs['_MSC_VER'])
     # gyp expects plain str instead of unicode. The frontend code gives us
     # unicode strings, so convert them.
     path = encode(path)
     str_vars = dict((name, encode(value)) for name, value in vars.items())
+    if is_msvc:
+        # This isn't actually used anywhere in this generator, but it's needed
+        # to override the registry detection of VC++ in gyp.
+        os.environ['GYP_MSVS_OVERRIDE_PATH'] = 'fake_path'
+        os.environ['GYP_MSVS_VERSION'] = config.substs['MSVS_VERSION']
 
     params = {
         b'parallel': False,
         b'generator_flags': {},
         b'build_files': [path],
         b'root_targets': None,
     }
 
-    # Files that gyp_chromium always includes
-    includes = [encode(mozpath.join(script_dir, 'common.gypi'))]
-    finder = FileFinder(chrome_src, find_executables=False)
-    includes.extend(encode(mozpath.join(chrome_src, name))
-        for name, _ in finder.find('*/supplement.gypi'))
+    if no_chromium:
+      includes = []
+      depth = mozpath.dirname(path)
+    else:
+      depth = chrome_src
+      # Files that gyp_chromium always includes
+      includes = [encode(mozpath.join(script_dir, 'common.gypi'))]
+      finder = FileFinder(chrome_src, find_executables=False)
+      includes.extend(encode(mozpath.join(chrome_src, name))
+          for name, _ in finder.find('*/supplement.gypi'))
 
     # Read the given gyp file and its dependencies.
     generator, flat_list, targets, data = \
         gyp.Load([path], format=b'mozbuild',
             default_variables=str_vars,
             includes=includes,
-            depth=encode(chrome_src),
+            depth=encode(depth),
             params=params)
 
     # Process all targets from the given gyp files and its dependencies.
     # The path given to AllTargets needs to use os.sep, while the frontend code
     # gives us paths normalized with forward slash separator.
     for target in gyp.common.AllTargets(flat_list, targets, path.replace(b'/', os.sep)):
         build_file, target_name, toolset = gyp.common.ParseQualifiedTarget(target)
 
@@ -141,70 +186,144 @@ def read_from_gyp(config, path, output, 
 
         # Derive which gyp configuration to use based on MOZ_DEBUG.
         c = 'Debug' if config.substs['MOZ_DEBUG'] else 'Release'
         if c not in spec['configurations']:
             raise RuntimeError('Missing %s gyp configuration for target %s '
                                'in %s' % (c, target_name, build_file))
         target_conf = spec['configurations'][c]
 
+        if 'actions' in spec:
+          handle_actions(spec['actions'], context, action_overrides)
+        if 'copies' in spec:
+          handle_copies(spec['copies'], context)
+
+        use_libs = []
+        libs = []
+        def add_deps(s):
+            for t in s.get('dependencies', []) + s.get('dependencies_original', []):
+                ty = targets[t]['type']
+                if ty in ('static_library', 'shared_library'):
+                    use_libs.append(targets[t]['target_name'])
+                # Manually expand out transitive dependencies--
+                # gyp won't do this for static libs or none targets.
+                if ty in ('static_library', 'none'):
+                    add_deps(targets[t])
+            libs.extend(spec.get('libraries', []))
+        #XXX: this sucks, but webrtc breaks with this right now because
+        # it builds a library called 'gtest' and we just get lucky
+        # that it isn't in USE_LIBS by that name anywhere.
+        if no_chromium:
+            add_deps(spec)
+
+        os_libs = []
+        for l in libs:
+          if l.startswith('-'):
+              os_libs.append(l)
+          elif l.endswith('.lib'):
+              os_libs.append(l[:-4])
+          elif l:
+            # For library names passed in from moz.build.
+            use_libs.append(os.path.basename(l))
+
         if spec['type'] == 'none':
+          if not ('actions' in spec or 'copies' in spec):
             continue
-        elif spec['type'] == 'static_library':
+        elif spec['type'] in ('static_library', 'shared_library', 'executable'):
             # Remove leading 'lib' from the target_name if any, and use as
             # library name.
             name = spec['target_name']
-            if name.startswith('lib'):
-                name = name[3:]
-            # The context expects an unicode string.
-            context['LIBRARY_NAME'] = name.decode('utf-8')
+            if spec['type'] in ('static_library', 'shared_library'):
+                if name.startswith('lib'):
+                    name = name[3:]
+                # The context expects an unicode string.
+                context['LIBRARY_NAME'] = name.decode('utf-8')
+            else:
+                context['PROGRAM'] = name.decode('utf-8')
+            if spec['type'] == 'shared_library':
+                context['FORCE_SHARED_LIB'] = True
+            elif spec['type'] == 'static_library' and spec.get('variables', {}).get('no_expand_libs', '0') == '1':
+                # PSM links a NSS static library, but our folded libnss
+                # doesn't actually export everything that all of the
+                # objects within would need, so that one library
+                # should be built as a real static library.
+                context['NO_EXPAND_LIBS'] = True
+            if use_libs:
+                context['USE_LIBS'] = sorted(use_libs, key=lambda s: s.lower())
+            if os_libs:
+                context['OS_LIBS'] = os_libs
             # gyp files contain headers and asm sources in sources lists.
             sources = []
             unified_sources = []
             extensions = set()
+            use_defines_in_asflags = False
             for f in spec.get('sources', []):
                 ext = mozpath.splitext(f)[-1]
                 extensions.add(ext)
-                s = SourcePath(context, f)
+                if f.startswith('$INTERMEDIATE_DIR/'):
+                  s = ObjDirPath(context, f.replace('$INTERMEDIATE_DIR/', '!'))
+                else:
+                  s = SourcePath(context, f)
                 if ext == '.h':
                     continue
-                if ext != '.S' and s not in non_unified_sources:
+                if ext == '.def':
+                    context['SYMBOLS_FILE'] = s
+                elif ext != '.S' and not no_unified and s not in non_unified_sources:
                     unified_sources.append(s)
                 else:
                     sources.append(s)
+                # The Mozilla build system doesn't use DEFINES for building
+                # ASFILES.
+                if ext == '.s':
+                    use_defines_in_asflags = True
 
             # The context expects alphabetical order when adding sources
             context['SOURCES'] = alphabetical_sorted(sources)
             context['UNIFIED_SOURCES'] = alphabetical_sorted(unified_sources)
 
-            for define in target_conf.get('defines', []):
+            defines = target_conf.get('defines', [])
+            if is_msvc and no_chromium:
+                msvs_settings = gyp.msvs_emulation.MsvsSettings(spec, {})
+                defines.extend(msvs_settings.GetComputedDefines(c))
+            for define in defines:
                 if '=' in define:
                     name, value = define.split('=', 1)
                     context['DEFINES'][name] = value
                 else:
                     context['DEFINES'][define] = True
 
+            product_dir_dist = '$PRODUCT_DIR/dist/'
             for include in target_conf.get('include_dirs', []):
-                # moz.build expects all LOCAL_INCLUDES to exist, so ensure they do.
-                #
-                # NB: gyp files sometimes have actual absolute paths (e.g.
-                # /usr/include32) and sometimes paths that moz.build considers
-                # absolute, i.e. starting from topsrcdir. There's no good way
-                # to tell them apart here, and the actual absolute paths are
-                # likely bogus. In any event, actual absolute paths will be
-                # filtered out by trying to find them in topsrcdir.
-                if include.startswith('/'):
-                    resolved = mozpath.abspath(mozpath.join(config.topsrcdir, include[1:]))
+                if include.startswith(product_dir_dist):
+                    # special-case includes of <(PRODUCT_DIR)/dist/ to match
+                    # handle_copies above. This is used for NSS' exports.
+                    include = '!/dist/include/' + include[len(product_dir_dist):]
+                elif include.startswith(config.topobjdir):
+                    # NSPR_INCLUDE_DIR gets passed into the NSS build this way.
+                    include = '!/' + mozpath.relpath(include, config.topobjdir)
                 else:
-                    resolved = mozpath.abspath(mozpath.join(mozpath.dirname(build_file), include))
-                if not os.path.exists(resolved):
-                    continue
+                  # moz.build expects all LOCAL_INCLUDES to exist, so ensure they do.
+                  #
+                  # NB: gyp files sometimes have actual absolute paths (e.g.
+                  # /usr/include32) and sometimes paths that moz.build considers
+                  # absolute, i.e. starting from topsrcdir. There's no good way
+                  # to tell them apart here, and the actual absolute paths are
+                  # likely bogus. In any event, actual absolute paths will be
+                  # filtered out by trying to find them in topsrcdir.
+                  if include.startswith('/'):
+                      resolved = mozpath.abspath(mozpath.join(config.topsrcdir, include[1:]))
+                  else:
+                      resolved = mozpath.abspath(mozpath.join(mozpath.dirname(build_file), include))
+                  if not os.path.exists(resolved):
+                      continue
                 context['LOCAL_INCLUDES'] += [include]
 
             context['ASFLAGS'] = target_conf.get('asflags_mozilla', [])
+            if use_defines_in_asflags and defines:
+                context['ASFLAGS'] += ['-D' + d for d in defines]
             flags = target_conf.get('cflags_mozilla', [])
             if flags:
                 suffix_map = {
                     '.c': 'CFLAGS',
                     '.cpp': 'CXXFLAGS',
                     '.cc': 'CXXFLAGS',
                     '.m': 'CMFLAGS',
                     '.mm': 'CMMFLAGS',
@@ -222,27 +341,28 @@ def read_from_gyp(config, path, output, 
                         if not f:
                             continue
                         # the result may be a string or a list.
                         if isinstance(f, types.StringTypes):
                             context[var].append(f)
                         else:
                             context[var].extend(f)
         else:
-            # Ignore other types than static_library because we don't have
+            # Ignore other types because we don't have
             # anything using them, and we're not testing them. They can be
             # added when that becomes necessary.
             raise NotImplementedError('Unsupported gyp target type: %s' % spec['type'])
 
-        # Add some features to all contexts. Put here in case LOCAL_INCLUDES
-        # order matters.
-        context['LOCAL_INCLUDES'] += [
-            '!/ipc/ipdl/_ipdlheaders',
-            '/ipc/chromium/src',
-            '/ipc/glue',
-        ]
-        # These get set via VC project file settings for normal GYP builds.
-        if config.substs['OS_TARGET'] == 'WINNT':
-            context['DEFINES']['UNICODE'] = True
-            context['DEFINES']['_UNICODE'] = True
+        if not no_chromium:
+          # Add some features to all contexts. Put here in case LOCAL_INCLUDES
+          # order matters.
+          context['LOCAL_INCLUDES'] += [
+              '!/ipc/ipdl/_ipdlheaders',
+              '/ipc/chromium/src',
+              '/ipc/glue',
+          ]
+          # These get set via VC project file settings for normal GYP builds.
+          if is_win:
+              context['DEFINES']['UNICODE'] = True
+              context['DEFINES']['_UNICODE'] = True
         context['DISABLE_STL_WRAPPING'] = True
 
         yield context
--- a/python/mozbuild/mozbuild/frontend/reader.py
+++ b/python/mozbuild/mozbuild/frontend/reader.py
@@ -1152,22 +1152,28 @@ class BuildReader(object):
             from .gyp_reader import read_from_gyp
             non_unified_sources = set()
             for s in gyp_dir.non_unified_sources:
                 source = SourcePath(context, s)
                 if not self._finder.get(source.full_path):
                     raise SandboxValidationError('Cannot find %s.' % source,
                         context)
                 non_unified_sources.add(source)
+            action_overrides = {}
+            for action, script in gyp_dir.action_overrides.iteritems():
+                action_overrides[action] = SourcePath(context, script)
             time_start = time.time()
             for gyp_context in read_from_gyp(context.config,
                                              mozpath.join(curdir, gyp_dir.input),
                                              mozpath.join(context.objdir,
                                                           target_dir),
                                              gyp_dir.variables,
+                                             gyp_dir.no_chromium,
+                                             gyp_dir.no_unified,
+                                             action_overrides,
                                              non_unified_sources = non_unified_sources):
                 gyp_context.update(gyp_dir.sandbox_vars)
                 gyp_contexts.append(gyp_context)
                 self._file_count += len(gyp_context.all_paths)
             self._execution_time += time.time() - time_start
 
         for gyp_context in gyp_contexts:
             context['DIRS'].append(mozpath.relpath(gyp_context.objdir, context.objdir))
new file mode 100644
--- /dev/null
+++ b/security/generate_certdata.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+#
+# This exists to paper over differences between gyp's `action` definitions
+# and moz.build `GENERATED_FILES` semantics.
+
+import buildconfig
+import subprocess
+
+def main(output, *inputs):
+    output.write(subprocess.check_output([buildconfig.substs['PERL']] + list(inputs)))
+    return None
new file mode 100644
--- /dev/null
+++ b/security/generate_mapfile.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+# 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/.
+
+# This script processes NSS .def files according to the rules defined in
+# a comment at the top of each one. The files are used to define the
+# exports from NSS shared libraries, with -DEFFILE on Windows, a linker
+# script on Linux, or with -exported_symbols_list on OS X.
+#
+# The NSS build system processes them using a series of sed replacements,
+# but the Mozilla build system is already running a Python script to generate
+# the file so it's simpler to just do the replacement in Python.
+
+import buildconfig
+
+
+def main(output, input):
+    # There's a check in old-configure.in under the system-nss handling
+    # that should match this.
+    if buildconfig.substs['OS_ARCH'] not in ('Linux', 'Darwin'):
+        print "Error: unhandled OS_ARCH %s" % buildconfig.substs['OS_ARCH']
+        return 1
+    is_linux = buildconfig.substs['OS_ARCH'] == 'Linux'
+
+    with open(input, 'rb') as f:
+        for line in f:
+            line = line.rstrip()
+            # Remove all lines containing ';-'
+            if ';-' in line:
+                continue
+            # On non-Linux, remove all lines containing ';+'
+            if not is_linux and ';+' in line:
+                continue
+            # Remove the string ' DATA '.
+            line = line.replace(' DATA ', '')
+            # Remove the string ';+'
+            line = line.replace(';+', '')
+            # Remove the string ';;'
+            line = line.replace(';;', '')
+            # If a ';' is present, remove everything after it,
+            # and on non-Linux, remove it as well.
+            i = line.find(';')
+            if i != -1:
+                if is_linux:
+                    line = line[:i+1]
+                else:
+                    line = line[:i]
+            # On non-Linux, symbols get an underscore in front.
+            if line and not is_linux:
+                output.write('_')
+            output.write(line)
+            output.write('\n')
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -1424,17 +1424,16 @@ nsNSSComponent::FillTLSVersionRange(SSLV
   // fill out rangeOut
   rangeOut.min = (uint16_t) minFromPrefs;
   rangeOut.max = (uint16_t) maxFromPrefs;
 }
 
 static const int32_t OCSP_ENABLED_DEFAULT = 1;
 static const bool REQUIRE_SAFE_NEGOTIATION_DEFAULT = false;
 static const bool FALSE_START_ENABLED_DEFAULT = true;
-static const bool NPN_ENABLED_DEFAULT = true;
 static const bool ALPN_ENABLED_DEFAULT = false;
 static const bool ENABLED_0RTT_DATA_DEFAULT = false;
 
 static void
 ConfigureTLSSessionIdentifiers()
 {
   bool disableSessionIdentifiers =
     Preferences::GetBool("security.ssl.disable_session_identifiers", false);
@@ -1880,23 +1879,20 @@ nsNSSComponent::InitializeNSS()
   SSL_OptionSetDefault(SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_REQUIRES_XTN);
 
   SSL_OptionSetDefault(SSL_ENABLE_EXTENDED_MASTER_SECRET, true);
 
   SSL_OptionSetDefault(SSL_ENABLE_FALSE_START,
                        Preferences::GetBool("security.ssl.enable_false_start",
                                             FALSE_START_ENABLED_DEFAULT));
 
-  // SSL_ENABLE_NPN and SSL_ENABLE_ALPN also require calling
-  // SSL_SetNextProtoNego in order for the extensions to be negotiated.
-  // WebRTC does not do that so it will not use NPN or ALPN even when these
-  // preferences are true.
-  SSL_OptionSetDefault(SSL_ENABLE_NPN,
-                       Preferences::GetBool("security.ssl.enable_npn",
-                                            NPN_ENABLED_DEFAULT));
+  // SSL_ENABLE_ALPN also requires calling SSL_SetNextProtoNego in order for
+  // the extensions to be negotiated.
+  // WebRTC does not do that so it will not use ALPN even when this preference
+  // is true.
   SSL_OptionSetDefault(SSL_ENABLE_ALPN,
                        Preferences::GetBool("security.ssl.enable_alpn",
                                             ALPN_ENABLED_DEFAULT));
 
   SSL_OptionSetDefault(SSL_ENABLE_0RTT_DATA,
                        Preferences::GetBool("security.tls.enable_0rtt_data",
                                             ENABLED_0RTT_DATA_DEFAULT));
 
@@ -2091,20 +2087,16 @@ nsNSSComponent::Observe(nsISupports* aSu
       bool requireSafeNegotiation =
         Preferences::GetBool("security.ssl.require_safe_negotiation",
                              REQUIRE_SAFE_NEGOTIATION_DEFAULT);
       SSL_OptionSetDefault(SSL_REQUIRE_SAFE_NEGOTIATION, requireSafeNegotiation);
     } else if (prefName.EqualsLiteral("security.ssl.enable_false_start")) {
       SSL_OptionSetDefault(SSL_ENABLE_FALSE_START,
                            Preferences::GetBool("security.ssl.enable_false_start",
                                                 FALSE_START_ENABLED_DEFAULT));
-    } else if (prefName.EqualsLiteral("security.ssl.enable_npn")) {
-      SSL_OptionSetDefault(SSL_ENABLE_NPN,
-                           Preferences::GetBool("security.ssl.enable_npn",
-                                                NPN_ENABLED_DEFAULT));
     } else if (prefName.EqualsLiteral("security.ssl.enable_alpn")) {
       SSL_OptionSetDefault(SSL_ENABLE_ALPN,
                            Preferences::GetBool("security.ssl.enable_alpn",
                                                 ALPN_ENABLED_DEFAULT));
     } else if (prefName.EqualsLiteral("security.tls.enable_0rtt_data")) {
       SSL_OptionSetDefault(SSL_ENABLE_0RTT_DATA,
                            Preferences::GetBool("security.tls.enable_0rtt_data",
                                                 ENABLED_0RTT_DATA_DEFAULT));
rename from config/external/nss/moz.build
rename to security/moz.build
--- a/config/external/nss/moz.build
+++ b/security/moz.build
@@ -1,42 +1,125 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
-DIRS += ['crmf']
-
 if CONFIG['MOZ_SYSTEM_NSS']:
     Library('nss')
     OS_LIBS += CONFIG['NSS_LIBS']
-elif CONFIG['MOZ_FOLD_LIBS']:
-    GeckoSharedLibrary('nss', linkage=None)
-    # TODO: The library name can be changed when bug 845217 is fixed.
-    SHARED_LIBRARY_NAME = 'nss3'
+else:
+    include('/build/gyp_base.mozbuild')
+    if CONFIG['MOZ_FOLD_LIBS']:
+        GeckoSharedLibrary('nss', linkage=None)
+        # TODO: The library name can be changed when bug 845217 is fixed.
+        SHARED_LIBRARY_NAME = 'nss3'
+
+        SDK_LIBRARY = True
+
+        USE_LIBS += [
+            'nspr4',
+            'nss3_static',
+            'nssutil',
+            'plc4',
+            'plds4',
+            'smime3_static',
+            'ssl',
+        ]
+
+        OS_LIBS += CONFIG['REALTIME_LIBS']
 
-    SDK_LIBRARY = True
-
-    USE_LIBS += [
-        'nspr4',
-        'plc4',
-        'plds4',
-    ]
+        SYMBOLS_FILE = 'nss.symbols'
+        # This changes the default targets in the NSS build, among
+        # other things.
+        gyp_vars['moz_fold_libs'] = 1
+        # Some things in NSS need to link against nssutil, which
+        # gets folded, so this tells them what to link against.
+        gyp_vars['moz_folded_library_name'] = 'nss'
+        # Force things in NSS that want to link against NSPR to link
+        # against the folded library.
+        gyp_vars['nspr_libs'] = 'nss'
+    else:
+        Library('nss')
+        USE_LIBS += [
+            'nss3',
+            'nssutil3',
+            'smime3',
+            'sqlite',
+            'ssl3',
+        ]
+        gyp_vars['nspr_libs'] = 'nspr4 plc4 plds4'
 
-    OS_LIBS += CONFIG['REALTIME_LIBS']
+    # This disables building some NSS tools.
+    gyp_vars['mozilla_client'] = 1
+    # We run shlibsign as part of packaging, not build.
+    gyp_vars['sign_libs'] = 0
+    gyp_vars['python'] = CONFIG['PYTHON']
+    # The NSS gyp files do not have a default for this.
+    gyp_vars['nss_dist_dir'] = '$PRODUCT_DIR/dist'
+    # NSS wants to put public headers in $nss_dist_dir/public/nss by default,
+    # which would wind up being mapped to dist/include/public/nss (by
+    # gyp_reader's `handle_copies`).
+    # This forces it to put them in dist/include/nss.
+    gyp_vars['nss_public_dist_dir'] = '$PRODUCT_DIR/dist'
+    gyp_vars['nss_dist_obj_dir'] = '$PRODUCT_DIR/dist/bin'
+    # We don't currently build NSS tests.
+    gyp_vars['disable_tests'] = 1
+    if CONFIG['NSS_DISABLE_DBM']:
+        gyp_vars['disable_dbm'] = 1
+    gyp_vars['disable_libpkix'] = 1
+    # pkg-config won't reliably find zlib on our builders, so just force it.
+    # System zlib is only used for modutil and signtool unless
+    # SSL zlib is enabled, which we are disabling immediately below this.
+    gyp_vars['zlib_libs'] = '-lz'
+    gyp_vars['ssl_enable_zlib'] = 0
+    # System sqlite here is the in-tree mozsqlite.
+    gyp_vars['use_system_sqlite'] = 1
+    gyp_vars['sqlite_libs'] = 'sqlite'
+    gyp_vars['nspr_include_dir'] = CONFIG['NSPR_INCLUDE_DIR']
+    gyp_vars['nspr_lib_dir'] = CONFIG['NSPR_LIB_DIR']
+    # The Python scripts that detect clang need it to be set as CC
+    # in the environment, which isn't true here. I don't know that
+    # setting that would be harmful, but we already have this information
+    # anyway.
+    if CONFIG['CLANG_CXX']:
+        gyp_vars['cc_is_clang'] = 1
 
-    SYMBOLS_FILE = 'nss.symbols'
-else:
-    Library('nss')
-    USE_LIBS += [
-        '/security/nss/lib/nss/nss3',
-        '/security/nss/lib/smime/smime3',
-        '/security/nss/lib/ssl/ssl3',
-        '/security/nss/lib/util/nssutil3',
-        'sqlite',
-    ]
+    GYP_DIRS += ['nss']
+    GYP_DIRS['nss'].input = 'nss/nss.gyp'
+    GYP_DIRS['nss'].variables = gyp_vars
 
-# XXX: We should fix these warnings.
-ALLOW_COMPILER_WARNINGS = True
+    sandbox_vars = {
+        # NSS explicitly exports its public symbols
+        # with linker scripts.
+        'NO_VISIBILITY_FLAGS': True,
+        # XXX: We should fix these warnings.
+        'ALLOW_COMPILER_WARNINGS': True,
+        # NSS' build system doesn't currently build NSS with PGO.
+        # We could probably do so, but not without a lot of
+        # careful consideration.
+        'NO_PGO': True,
+    }
+    if CONFIG['OS_TARGET'] == 'WINNT':
+        if CONFIG['CPU_ARCH'] == 'x86':
+            # This should really be the default.
+            sandbox_vars['ASFLAGS'] = ['-safeseh']
+    if CONFIG['OS_TARGET'] == 'Android':
+        sandbox_vars['CFLAGS'] = [
+            '-include', TOPSRCDIR + '/security/manager/android_stub.h',
+            # Setting sandbox_vars['DEFINES'] is broken currently.
+            '-DCHECK_FORK_GETPID',
+        ]
+        if CONFIG['ANDROID_VERSION']:
+            sandbox_vars['CFLAGS'] += ['-DANDROID_VERSION=' + CONFIG['ANDROID_VERSION']]
+    GYP_DIRS['nss'].sandbox_vars = sandbox_vars
+    GYP_DIRS['nss'].no_chromium = True
+    GYP_DIRS['nss'].no_unified = True
+    # This maps action names from gyp files to
+    # Python scripts that can be used in moz.build GENERATED_FILES.
+    GYP_DIRS['nss'].action_overrides = {
+        'generate_certdata_c': 'generate_certdata.py',
+        'generate_mapfile': 'generate_mapfile.py',
+    }
 
 if CONFIG['NSS_EXTRA_SYMBOLS_FILE']:
     DEFINES['NSS_EXTRA_SYMBOLS_FILE'] = CONFIG['NSS_EXTRA_SYMBOLS_FILE']
rename from config/external/nss/nss.symbols
rename to security/nss.symbols
--- a/config/external/nss/nss.symbols
+++ b/security/nss.symbols
@@ -8,17 +8,17 @@
 # specify that NSPR's symbols should be globally visible.  Otherwise, NSPR's
 # exported symbols would be hidden.
 # .def files on Windows don't allow wildcards, of course, which is why this is
 # excluded on Windows, but it doesn't matter because the symbols are already
 # exported in NSPR (Windows peculiarity).
 PR_*
 PL_*
 #endif
-#include ../../../db/sqlite3/src/sqlite.symbols
+#include ../db/sqlite3/src/sqlite.symbols
 ATOB_AsciiToData
 ATOB_AsciiToData_Util
 ATOB_ConvertAsciiToItem
 ATOB_ConvertAsciiToItem_Util
 BTOA_ConvertItemToAscii_Util
 BTOA_DataToAscii
 BTOA_DataToAscii_Util
 CERT_AddCertToListHead
--- a/toolkit/mozapps/update/common/errors.h
+++ b/toolkit/mozapps/update/common/errors.h
@@ -5,18 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef Errors_h__
 #define Errors_h__
 
 #define OK 0
 
 // Error codes that are no longer used should not be used again unless they
-// aren't used in client code (e.g. nsUpdateService.js, updates.js,
-// UpdatePrompt.js, etc.).
+// aren't used in client code (e.g. nsUpdateService.js, updates.js, etc.).
 
 #define MAR_ERROR_EMPTY_ACTION_LIST 1
 #define LOADSOURCE_ERROR_WRONG_SIZE 2
 
 // Error codes 3-16 are for general update problems.
 #define USAGE_ERROR 3
 #define CRC_ERROR 4
 #define PARSE_ERROR 5
--- a/tools/lint/eslint/modules.json
+++ b/tools/lint/eslint/modules.json
@@ -162,17 +162,16 @@
   "OutputGenerator.jsm": ["UtteranceGenerator", "BrailleGenerator"],
   "PageMenu.jsm": ["PageMenuParent", "PageMenuChild"],
   "PageThumbs.jsm": ["PageThumbs", "PageThumbsStorage"],
   "Parser.jsm": ["Parser", "ParserHelpers", "SyntaxTreeVisitor"],
   "parsingTestHelpers.jsm": ["generateURIsFromDirTree"],
   "passwords.js": ["PasswordEngine", "LoginRec", "PasswordValidator"],
   "passwords.jsm": ["Password", "DumpPasswords"],
   "PdfJsNetwork.jsm": ["NetworkManager"],
-  "PermissionsTable.jsm": ["PermissionsTable", "PermissionsReverseTable", "expandPermissions", "appendAccessToPermName", "isExplicitInPermissionsTable", "AllPossiblePermissions"],
   "PhoneNumberMetaData.jsm": ["PHONE_NUMBER_META_DATA"],
   "PlacesUtils.jsm": ["PlacesUtils", "PlacesAggregatedTransaction", "PlacesCreateFolderTransaction", "PlacesCreateBookmarkTransaction", "PlacesCreateSeparatorTransaction", "PlacesCreateLivemarkTransaction", "PlacesMoveItemTransaction", "PlacesRemoveItemTransaction", "PlacesEditItemTitleTransaction", "PlacesEditBookmarkURITransaction", "PlacesSetItemAnnotationTransaction", "PlacesSetPageAnnotationTransaction", "PlacesEditBookmarkKeywordTransaction", "PlacesEditBookmarkPostDataTransaction", "PlacesEditItemDateAddedTransaction", "PlacesEditItemLastModifiedTransaction", "PlacesSortFolderByNameTransaction", "PlacesTagURITransaction", "PlacesUntagURITransaction"],
   "PluginProvider.jsm": [],
   "PointerAdapter.jsm": ["PointerRelay", "PointerAdapter"],
   "policies.js": ["ErrorHandler", "SyncScheduler"],
   "prefs.js": ["PrefsEngine", "PrefRec"],
   "prefs.jsm": ["Preference"],
   "PresentationDeviceInfoManager.jsm": ["PresentationDeviceInfoService"],