Merge m-i to m-c, a=merge
authorPhil Ringnalda <philringnalda@gmail.com>
Sat, 14 Nov 2015 13:22:10 -0800
changeset 272620 51fa3e0d4f7bb2bf3457261091b1cb7a75e1255d
parent 272501 bbeaf161feb415b87fca25bd2a25e9d31f3d7c46 (current diff)
parent 272619 d69c292db762bcff2ee05c9f57ae08e59c2ece41 (diff)
child 272621 41b5c629c4a00f41b9b85a4521cf62a726bf4c7f
child 272635 3d7e82332a6d7157f7ecfac851755bf10bf1340e
push id18671
push userphilringnalda@gmail.com
push dateMon, 16 Nov 2015 03:17:44 +0000
treeherderb2g-inbound@91245e946494 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone45.0a1
Merge m-i to m-c, a=merge
js/src/frontend/BytecodeEmitter.cpp
js/src/jit-test/tests/TypedObject/bug976697.js
mobile/android/chrome/content/browser.js
testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
--- a/accessible/generic/HyperTextAccessible.cpp
+++ b/accessible/generic/HyperTextAccessible.cpp
@@ -1489,44 +1489,44 @@ HyperTextAccessible::CaretLineNumber()
 
     caretFrame = parentFrame;
   }
 
   NS_NOTREACHED("DOM ancestry had this hypertext but frame ancestry didn't");
   return lineNumber;
 }
 
-nsIntRect
+LayoutDeviceIntRect
 HyperTextAccessible::GetCaretRect(nsIWidget** aWidget)
 {
   *aWidget = nullptr;
 
   RefPtr<nsCaret> caret = mDoc->PresShell()->GetCaret();
-  NS_ENSURE_TRUE(caret, nsIntRect());
+  NS_ENSURE_TRUE(caret, LayoutDeviceIntRect());
 
   bool isVisible = caret->IsVisible();
   if (!isVisible)
-    return nsIntRect();
+    return LayoutDeviceIntRect();
 
   nsRect rect;
   nsIFrame* frame = caret->GetGeometry(&rect);
   if (!frame || rect.IsEmpty())
-    return nsIntRect();
+    return LayoutDeviceIntRect();
 
   nsPoint offset;
   // Offset from widget origin to the frame origin, which includes chrome
   // on the widget.
   *aWidget = frame->GetNearestWidget(offset);
-  NS_ENSURE_TRUE(*aWidget, nsIntRect());
+  NS_ENSURE_TRUE(*aWidget, LayoutDeviceIntRect());
   rect.MoveBy(offset);
 
-  nsIntRect caretRect;
-  caretRect = rect.ToOutsidePixels(frame->PresContext()->AppUnitsPerDevPixel());
+  LayoutDeviceIntRect caretRect = LayoutDeviceIntRect::FromUnknownRect(
+    rect.ToOutsidePixels(frame->PresContext()->AppUnitsPerDevPixel()));
   // ((content screen origin) - (content offset in the widget)) = widget origin on the screen
-  caretRect.MoveBy((*aWidget)->WidgetToScreenOffsetUntyped() - (*aWidget)->GetClientOffset());
+  caretRect.MoveBy((*aWidget)->WidgetToScreenOffset() - (*aWidget)->GetClientOffset());
 
   // Correct for character size, so that caret always matches the size of
   // the character. This is important for font size transitions, and is
   // necessary because the Gecko caret uses the previous character's size as
   // the user moves forward in the text by character.
   nsIntRect charRect = CharBounds(CaretOffset(),
                                   nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE);
   if (!charRect.IsEmpty()) {
--- a/accessible/generic/HyperTextAccessible.h
+++ b/accessible/generic/HyperTextAccessible.h
@@ -330,17 +330,17 @@ public:
 
   /**
    * Return the caret rect and the widget containing the caret within this
    * text accessible.
    *
    * @param [out] the widget containing the caret
    * @return      the caret rect
    */
-  nsIntRect GetCaretRect(nsIWidget** aWidget);
+  mozilla::LayoutDeviceIntRect GetCaretRect(nsIWidget** aWidget);
 
   /**
    * Return selected regions count within the accessible.
    */
   int32_t SelectionCount();
 
   /**
    * Return the start and end offset of the specified selection.
--- a/accessible/windows/msaa/AccessibleWrap.cpp
+++ b/accessible/windows/msaa/AccessibleWrap.cpp
@@ -1628,17 +1628,17 @@ AccessibleWrap::UpdateSystemCaretFor(Acc
   // off-screen model can follow the caret
   ::DestroyCaret();
 
   HyperTextAccessible* text = aAccessible->AsHyperText();
   if (!text)
     return;
 
   nsIWidget* widget = nullptr;
-  nsIntRect caretRect = text->GetCaretRect(&widget);
+  LayoutDeviceIntRect caretRect = text->GetCaretRect(&widget);
   HWND caretWnd;
   if (caretRect.IsEmpty() || !(caretWnd = (HWND)widget->GetNativeData(NS_NATIVE_WINDOW))) {
     return;
   }
 
   // Create invisible bitmap for caret, otherwise its appearance interferes
   // with Gecko caret
   HBITMAP caretBitMap = CreateBitmap(1, caretRect.height, 1, 1, nullptr);
new file mode 100644
--- /dev/null
+++ b/browser/components/newtab/NewTabPrefsProvider.jsm
@@ -0,0 +1,84 @@
+/* global Services, Preferences, EventEmitter, XPCOMUtils */
+/* exported NewTabPrefsProvider */
+
+"use strict";
+
+this.EXPORTED_SYMBOLS = ["NewTabPrefsProvider"];
+
+const {interfaces: Ci, utils: Cu} = Components;
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/Preferences.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "EventEmitter", function() {
+  const {EventEmitter} = Cu.import("resource://gre/modules/devtools/event-emitter.js", {});
+  return EventEmitter;
+});
+
+// Supported prefs and data type
+const gPrefsMap = new Map([
+  ["browser.newtabpage.enabled", "bool"],
+  ["browser.newtabpage.enhanced", "bool"],
+  ["browser.newtabpage.pinned", "str"],
+  ["intl.locale.matchOS", "bool"],
+  ["general.useragent.locale", "localized"],
+]);
+
+let PrefsProvider = function PrefsProvider() {
+  EventEmitter.decorate(this);
+};
+
+PrefsProvider.prototype = {
+
+  observe(subject, topic, data) { // jshint ignore:line
+    if (topic === "nsPref:changed") {
+      if (gPrefsMap.has(data)) {
+        switch (gPrefsMap.get(data)) {
+          case "bool":
+            this.emit(data, Preferences.get(data, false));
+            break;
+          case "str":
+            this.emit(data, Preferences.get(data, ""));
+            break;
+          case "localized":
+            try {
+              this.emit(data, Preferences.get(data, "", Ci.nsIPrefLocalizedString));
+            } catch (e) {
+              this.emit(data, Preferences.get(data, ""));
+            }
+            break;
+          default:
+            this.emit(data);
+            break;
+        }
+      }
+    } else {
+      Cu.reportError(new Error("NewTabPrefsProvider observing unknown topic"));
+    }
+  },
+
+  get prefsMap() {
+    return gPrefsMap;
+  },
+
+  init() {
+    for (let pref of gPrefsMap.keys()) {
+      Services.prefs.addObserver(pref, this, false);
+    }
+  },
+
+  uninit() {
+    for (let pref of gPrefsMap.keys()) {
+      Services.prefs.removeObserver(pref, this, false);
+    }
+  }
+};
+
+/**
+ * Singleton that serves as the default new tab pref provider for the grid.
+ */
+const gPrefs = new PrefsProvider();
+
+let NewTabPrefsProvider = {
+  prefs: gPrefs,
+};
--- a/browser/components/newtab/RemoteAboutNewTab.jsm
+++ b/browser/components/newtab/RemoteAboutNewTab.jsm
@@ -1,14 +1,13 @@
 /* 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/. */
-
 /* globals Services, XPCOMUtils, RemotePages, RemoteNewTabLocation, RemoteNewTabUtils, Task  */
-/* globals BackgroundPageThumbs, PageThumbs, DirectoryLinksProvider */
+/* globals BackgroundPageThumbs, PageThumbs, DirectoryLinksProvider, PlacesProvider, NewTabPrefsProvider */
 /* exported RemoteAboutNewTab */
 
 "use strict";
 
 let Ci = Components.interfaces;
 let Cu = Components.utils;
 const XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
 
@@ -26,36 +25,78 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "BackgroundPageThumbs",
   "resource://gre/modules/BackgroundPageThumbs.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PageThumbs",
   "resource://gre/modules/PageThumbs.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "DirectoryLinksProvider",
   "resource:///modules/DirectoryLinksProvider.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "RemoteNewTabLocation",
   "resource:///modules/RemoteNewTabLocation.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PlacesProvider",
+  "resource:///modules/PlacesProvider.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
+  "resource:///modules/NewTabPrefsProvider.jsm");
 
 let RemoteAboutNewTab = {
 
   pageListener: null,
 
   /**
    * Initialize the RemotePageManager and add all message listeners for this page
    */
   init: function() {
     this.pageListener = new RemotePages("about:remote-newtab");
     this.pageListener.addMessageListener("NewTab:InitializeGrid", this.initializeGrid.bind(this));
     this.pageListener.addMessageListener("NewTab:UpdateGrid", this.updateGrid.bind(this));
+    this.pageListener.addMessageListener("NewTab:Customize", this.customize.bind(this));
     this.pageListener.addMessageListener("NewTab:CaptureBackgroundPageThumbs",
         this.captureBackgroundPageThumb.bind(this));
     this.pageListener.addMessageListener("NewTab:PageThumbs", this.createPageThumb.bind(this));
     this.pageListener.addMessageListener("NewTabFrame:GetInit", this.initContentFrame.bind(this));
 
     this._addObservers();
   },
 
+  customize: function(message) {
+    if (message.data.enabled !== undefined) {
+      Services.prefs.setBoolPref("browser.newtabpage.enabled", message.data.enabled);
+    }
+    if (message.data.enhanced !== undefined) {
+      Services.prefs.setBoolPref("browser.newtabpage.enhanced", message.data.enhanced);
+    }
+  },
+
+  /**
+   * Notifies when history is cleared
+   */
+  placesClearHistory: function() {
+    this.pageListener.sendAsyncMessage("NewTab:PlacesClearHistory");
+  },
+
+  /**
+   * Notifies when a link has changed
+   */
+  placesLinkChanged: function(name, data) { // jshint ignore:line
+    this.pageListener.sendAsyncMessage("NewTab:PlacesLinkChanged", data);
+  },
+
+  /**
+   * Notifies when many links have changed
+   */
+  placesManyLinksChanged: function() {
+    this.pageListener.sendAsyncMessage("NewTab:PlacesManyLinksChanged");
+  },
+
+  /**
+   * Notifies when one URL has been deleted
+   */
+  placesDeleteURI: function(name, data) { // jshint ignore:line
+    this.pageListener.sendAsyncMessage("NewTab:PlacesDeleteURI", data.url);
+  },
+
   /**
    * Initializes the grid for the first time when the page loads.
    * Fetch all the links and send them down to the child to populate
    * the grid with.
    *
    * @param {Object} message
    *        A RemotePageManager message.
    */
@@ -181,17 +222,16 @@ let RemoteAboutNewTab = {
   /**
    * Listens for a preference change or session purge for all pages and sends
    * a message to update the pages that are open. If a session purge occured,
    * also clear the links cache and update the set of links to display, as they
    * may have changed, then proceed with the page update.
    */
   observe: function(aSubject, aTopic, aData) { // jshint ignore:line
     let extraData;
-    let refreshPage = false;
     if (aTopic === "browser:purge-session-history") {
       RemoteNewTabUtils.links.resetCache();
       RemoteNewTabUtils.links.populateCache(() => {
         this.pageListener.sendAsyncMessage("NewTab:UpdateLinks", {
           links: RemoteNewTabUtils.links.getLinks(),
           enhancedLinks: this.getEnhancedLinks(),
         });
       });
@@ -201,30 +241,56 @@ let RemoteAboutNewTab = {
       if (aTopic !== "page-thumbnail:create") {
         // Change the topic for enhanced and enabled observers.
         aTopic = aData;
       }
       this.pageListener.sendAsyncMessage("NewTab:Observe", {topic: aTopic, data: extraData});
     }
   },
 
+  setEnabled: function(name, data) { // jshint ignore:line
+    this.pageListener.sendAsyncMessage("NewTab:setEnabled", data);
+  },
+
+  setEnhanced: function(name, data) { // jshint ignore:line
+    this.pageListener.sendAsyncMessage("NewTab:setEnhanced", data);
+  },
+
+  setPinned: function(name, data) { // jshint ignore:line
+    this.pageListener.sendAsyncMessage("NewTab:setPinnedLinks", data);
+  },
+
   /**
    * Add all observers that about:newtab page must listen for.
    */
   _addObservers: function() {
     Services.obs.addObserver(this, "page-thumbnail:create", true);
     Services.obs.addObserver(this, "browser:purge-session-history", true);
+    PlacesProvider.links.on("deleteURI", this.placesDeleteURI.bind(this));
+    PlacesProvider.links.on("clearHistory", this.placesClearHistory.bind(this));
+    PlacesProvider.links.on("linkChanged", this.placesLinkChanged.bind(this));
+    PlacesProvider.links.on("manyLinksChanged", this.placesManyLinksChanged.bind(this));
+    NewTabPrefsProvider.prefs.on("browser.newtabpage.enabled", this.setEnabled.bind(this));
+    NewTabPrefsProvider.prefs.on("browser.newtabpage.enhanced", this.setEnhanced.bind(this));
+    NewTabPrefsProvider.prefs.on("browser.newtabpage.pinned", this.setPinned.bind(this));
   },
 
   /**
    * Remove all observers on the page.
    */
   _removeObservers: function() {
     Services.obs.removeObserver(this, "page-thumbnail:create");
     Services.obs.removeObserver(this, "browser:purge-session-history");
+    PlacesProvider.links.off("deleteURI", this.placesDeleteURI);
+    PlacesProvider.links.off("clearHistory", this.placesClearHistory);
+    PlacesProvider.links.off("linkChanged", this.placesLinkChanged);
+    PlacesProvider.links.off("manyLinksChanged", this.placesManyLinksChanged);
+    NewTabPrefsProvider.prefs.off("browser.newtabpage.enabled", this.setEnabled.bind(this));
+    NewTabPrefsProvider.prefs.off("browser.newtabpage.enhanced", this.setEnhanced.bind(this));
+    NewTabPrefsProvider.prefs.off("browser.newtabpage.pinned", this.setPinned.bind(this));
   },
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
                                          Ci.nsISupportsWeakReference]),
 
   uninit: function() {
     this._removeObservers();
     this.pageListener.destroy();
--- a/browser/components/newtab/moz.build
+++ b/browser/components/newtab/moz.build
@@ -6,14 +6,15 @@
 
 BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
 
 XPCSHELL_TESTS_MANIFESTS += [
     'tests/xpcshell/xpcshell.ini',
 ]
 
 EXTRA_JS_MODULES += [
+    'NewTabPrefsProvider.jsm',
     'NewTabURL.jsm',
     'PlacesProvider.jsm',
     'RemoteAboutNewTab.jsm',
     'RemoteNewTabLocation.jsm',
     'RemoteNewTabUtils.jsm',
 ]
new file mode 100644
--- /dev/null
+++ b/browser/components/newtab/tests/xpcshell/test_NewTabPrefsProvider.js
@@ -0,0 +1,51 @@
+"use strict";
+
+/* global XPCOMUtils, equal, Preferences, NewTabPrefsProvider, run_next_test */
+/* exported run_test */
+/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
+
+const Cu = Components.utils;
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Preferences.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
+    "resource:///modules/NewTabPrefsProvider.jsm");
+
+function run_test() {
+  run_next_test();
+}
+
+add_task(function* test_observe() {
+  let prefsMap = NewTabPrefsProvider.prefs.prefsMap;
+  for (let prefName of prefsMap.keys()) {
+    let prefValueType = prefsMap.get(prefName);
+
+    let beforeVal;
+    let afterVal;
+
+    switch (prefValueType) {
+      case "bool":
+        beforeVal = false;
+        afterVal = true;
+        Preferences.set(prefName, beforeVal);
+        break;
+      case "localized":
+      case "str":
+        beforeVal = "";
+        afterVal = "someStr";
+        Preferences.set(prefName, beforeVal);
+        break;
+    }
+    NewTabPrefsProvider.prefs.init();
+    let promise = new Promise(resolve => {
+      NewTabPrefsProvider.prefs.once(prefName, (name, data) => { // jshint ignore:line
+        resolve([name, data]);
+      });
+    });
+    Preferences.set(prefName, afterVal);
+    let [actualName, actualData] = yield promise;
+    equal(prefName, actualName, `emitter sent the correct pref: ${prefName}`);
+    equal(afterVal, actualData, `emitter collected correct pref data for ${prefName}`);
+    NewTabPrefsProvider.prefs.uninit();
+  }
+});
--- a/browser/components/newtab/tests/xpcshell/xpcshell.ini
+++ b/browser/components/newtab/tests/xpcshell/xpcshell.ini
@@ -1,11 +1,12 @@
 [DEFAULT]
 head =
 tail =
 firefox-appdir = browser
 skip-if = toolkit == 'android' || toolkit == 'gonk'
 
 [test_AboutNewTabService.js]
+[test_NewTabPrefsProvider.js]
 [test_NewTabURL.js]
 [test_PlacesProvider.js]
 [test_RemoteNewTabLocation.js]
 [test_RemoteNewTabUtils.js]
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -27,16 +27,19 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://gre/modules/NewTabUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "RemoteAboutNewTab",
                                   "resource:///modules/RemoteAboutNewTab.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "RemoteNewTabUtils",
                                   "resource:///modules/RemoteNewTabUtils.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
+                                  "resource:///modules/NewTabPrefsProvider.jsm");
+
 XPCOMUtils.defineLazyModuleGetter(this, "UITour",
                                   "resource:///modules/UITour.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
                                   "resource://gre/modules/AddonManager.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "ContentClick",
                                   "resource:///modules/ContentClick.jsm");
@@ -844,16 +847,17 @@ BrowserGlue.prototype = {
     DirectoryLinksProvider.init();
     NewTabUtils.init();
     NewTabUtils.links.addProvider(DirectoryLinksProvider);
     AboutNewTab.init();
 
     RemoteNewTabUtils.init();
     RemoteNewTabUtils.links.addProvider(DirectoryLinksProvider);
     RemoteAboutNewTab.init();
+    NewTabPrefsProvider.prefs.init();
 
     SessionStore.init();
     BrowserUITelemetry.init();
     ContentSearch.init();
     FormValidationHandler.init();
 
     ContentClick.init();
     RemotePrompt.init();
@@ -1165,16 +1169,17 @@ BrowserGlue.prototype = {
     }
 
     SelfSupportBackend.uninit();
 
     CustomizationTabPreloader.uninit();
     WebappManager.uninit();
 
     RemoteAboutNewTab.uninit();
+    NewTabPrefsProvider.prefs.uninit();
     AboutNewTab.uninit();
 #ifdef NIGHTLY_BUILD
     if (Services.prefs.getBoolPref("dom.identity.enabled")) {
       SignInToWebsiteUX.uninit();
     }
 #endif
     webrtcUI.uninit();
     FormValidationHandler.uninit();
--- a/browser/extensions/pdfjs/test/browser.ini
+++ b/browser/extensions/pdfjs/test/browser.ini
@@ -1,12 +1,10 @@
 [DEFAULT]
-support-files = file_pdfjs_test.pdf
+support-files =
+  file_pdfjs_test.pdf
+  head.js
 
 [browser_pdfjs_main.js]
-skip-if = e10s # Bug 1159385
 [browser_pdfjs_navigation.js]
-skip-if = e10s # Bug 1159385
 [browser_pdfjs_savedialog.js]
 [browser_pdfjs_views.js]
-skip-if = e10s # Bug 1159385
 [browser_pdfjs_zoom.js]
-skip-if = e10s # Bug 1159385
--- a/browser/extensions/pdfjs/test/browser_pdfjs_main.js
+++ b/browser/extensions/pdfjs/test/browser_pdfjs_main.js
@@ -1,98 +1,67 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const RELATIVE_DIR = "browser/extensions/pdfjs/test/";
 const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
 
-function test() {
-  var tab;
-
+add_task(function* test() {
   let handlerService = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
   let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
   let handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
 
   // Make sure pdf.js is the default handler.
   is(handlerInfo.alwaysAskBeforeHandling, false, 'pdf handler defaults to always-ask is false');
   is(handlerInfo.preferredAction, Ci.nsIHandlerInfo.handleInternally, 'pdf handler defaults to internal');
 
   info('Pref action: ' + handlerInfo.preferredAction);
 
-  waitForExplicitFinish();
-  registerCleanupFunction(function() {
-    gBrowser.removeTab(tab);
-  });
+  yield BrowserTestUtils.withNewTab({ gBrowser: gBrowser, url: TESTROOT + "file_pdfjs_test.pdf" },
+    function* (newTabBrowser) {
+      ok(gBrowser.isFindBarInitialized(), "Browser FindBar initialized!");
 
-  tab = gBrowser.addTab(TESTROOT + "file_pdfjs_test.pdf");
-  var newTabBrowser = gBrowser.getBrowserForTab(tab);
-  newTabBrowser.addEventListener("load", function eventHandler() {
-    newTabBrowser.removeEventListener("load", eventHandler, true);
-
-    var document = newTabBrowser.contentDocument,
-        window = newTabBrowser.contentWindow;
+      yield waitForPdfJS(newTabBrowser);
 
-    // Runs tests after all 'load' event handlers have fired off
-    window.addEventListener("documentload", function() {
-      runTests(document, window, tab, function () {
-        closePDFViewer(window, finish);
-      });
-    }, false, true);
-  }, true);
-}
-
-
-function runTests(document, window, tab, callback) {
+      yield ContentTask.spawn(newTabBrowser, null, function* () {
+        //
+        // Overall sanity tests
+        //
+        ok(content.document.querySelector('div#viewer'), "document content has viewer UI");
+        ok('PDFJS' in content.wrappedJSObject, "window content has PDFJS object");
 
-  //
-  // Overall sanity tests
-  //
-  ok(document.querySelector('div#viewer'), "document content has viewer UI");
-  ok('PDFJS' in window.wrappedJSObject, "window content has PDFJS object");
-  ok('PDFViewerApplication' in window.wrappedJSObject,
-     "window content has viewer object");
+        //
+        // Sidebar: open
+        //
+        var sidebar = content.document.querySelector('button#sidebarToggle'),
+            outerContainer = content.document.querySelector('div#outerContainer');
 
-  //
-  // Browser Find
-  //
-  ok(gBrowser.isFindBarInitialized(tab), "Browser FindBar initialized!");
+        sidebar.click();
+        ok(outerContainer.classList.contains('sidebarOpen'), "sidebar opens on click");
 
-  //
-  // Sidebar: open
-  //
-  var sidebar = document.querySelector('button#sidebarToggle'),
-      outerContainer = document.querySelector('div#outerContainer');
-
-  sidebar.click();
-  ok(outerContainer.classList.contains('sidebarOpen'), 'sidebar opens on click');
+        //
+        // Sidebar: close
+        //
+        sidebar.click();
+        ok(!outerContainer.classList.contains('sidebarOpen'), "sidebar closes on click");
 
-  //
-  // Sidebar: close
-  //
-  sidebar.click();
-  ok(!outerContainer.classList.contains('sidebarOpen'), 'sidebar closes on click');
-
-  //
-  // Page change from prev/next buttons
-  //
-  var prevPage = document.querySelector('button#previous'),
-      nextPage = document.querySelector('button#next');
+        //
+        // Page change from prev/next buttons
+        //
+        var prevPage = content.document.querySelector('button#previous'),
+            nextPage = content.document.querySelector('button#next');
 
-  var pageNumber = document.querySelector('input#pageNumber');
-  is(parseInt(pageNumber.value), 1, 'initial page is 1');
-
-  //
-  // Bookmark button
-  //
-  var viewBookmark = document.querySelector('a#viewBookmark');
-  viewBookmark.click();
-  ok(viewBookmark.href.length > 0, 'viewBookmark button has href');
+        var pgNumber = content.document.querySelector('input#pageNumber').value;
+        is(parseInt(pgNumber, 10), 1, 'initial page is 1');
 
-  callback();
-}
+        //
+        // Bookmark button
+        //
+        var viewBookmark = content.document.querySelector('a#viewBookmark');
+        viewBookmark.click();
 
-/**
- * Destroys PDF.js viewer opened document.
- */
-function closePDFViewer(window, callback) {
-  var viewer = window.wrappedJSObject.PDFViewerApplication;
-  viewer.close().then(callback);
-}
+        ok(viewBookmark.href.length > 0, "viewBookmark button has href");
+
+        var viewer = content.wrappedJSObject.PDFViewerApplication;
+        yield viewer.close();
+      });
+    });
+});
--- a/browser/extensions/pdfjs/test/browser_pdfjs_navigation.js
+++ b/browser/extensions/pdfjs/test/browser_pdfjs_navigation.js
@@ -134,172 +134,148 @@ const TESTS = [
       value: 5,
       event: "change"
     },
     expectedPage: 5,
     message: "navigated to 5th page using pagenumber"
   }
 ];
 
-function test() {
-  var tab;
-
+add_task(function* test() {
   let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
   let handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
 
   // Make sure pdf.js is the default handler.
   is(handlerInfo.alwaysAskBeforeHandling, false, 'pdf handler defaults to always-ask is false');
   is(handlerInfo.preferredAction, Ci.nsIHandlerInfo.handleInternally, 'pdf handler defaults to internal');
 
   info('Pref action: ' + handlerInfo.preferredAction);
 
-  waitForExplicitFinish();
-  registerCleanupFunction(function() {
-    gBrowser.removeTab(tab);
-  });
-
-  tab = gBrowser.addTab(TESTROOT + "file_pdfjs_test.pdf");
-  gBrowser.selectedTab = tab;
+  yield BrowserTestUtils.withNewTab({ gBrowser, url: TESTROOT + "file_pdfjs_test.pdf" },
+    function* (newTabBrowser) {
+      yield waitForPdfJS(newTabBrowser);
 
-  var newTabBrowser = gBrowser.getBrowserForTab(tab);
-  newTabBrowser.addEventListener("load", function eventHandler() {
-    newTabBrowser.removeEventListener("load", eventHandler, true);
-
-    var document = newTabBrowser.contentDocument,
-        window = newTabBrowser.contentWindow;
+      yield ContentTask.spawn(newTabBrowser, null, function* () {
+        // Check if PDF is opened with internal viewer
+        ok(content.document.querySelector('div#viewer'), "document content has viewer UI");
+        ok('PDFJS' in content.wrappedJSObject, "window content has PDFJS object");
+      });
 
-    // Runs tests after all 'load' event handlers have fired off
-    window.addEventListener("documentload", function() {
-      runTests(document, window, function () {
-        var pageNumber = document.querySelector('input#pageNumber');
+      yield ContentTask.spawn(newTabBrowser, null, contentSetUp);
+
+      yield Task.spawn(runTests(newTabBrowser));
+
+      yield ContentTask.spawn(newTabBrowser, null, function*() {
+        let pageNumber = content.document.querySelector('input#pageNumber');
         is(pageNumber.value, pageNumber.max, "Document is left on the last page");
-        finish();
       });
-    }, false, true);
-  }, true);
-}
+    });
+});
 
-function runTests(document, window, finish) {
-  // Check if PDF is opened with internal viewer
-  ok(document.querySelector('div#viewer'), "document content has viewer UI");
-  ok('PDFJS' in window.wrappedJSObject, "window content has PDFJS object");
+function* contentSetUp() {
+  /**
+   * Outline Items gets appended to the document later on we have to
+   * wait for them before we start to navigate though document
+   *
+   * @param document
+   * @returns {deferred.promise|*}
+   */
+  function waitForOutlineItems(document) {
+    return new Promise((resolve, reject) => {
+      document.addEventListener("outlineloaded", function outlineLoaded(evt) {
+        document.removeEventListener("outlineloaded", outlineLoaded);
+        var outlineCount = evt.detail.outlineCount;
 
-  // Wait for outline items, the start the navigation actions
-  waitForOutlineItems(document).then(function () {
-    // The key navigation has to happen in page-fit, otherwise it won't scroll
-    // trough a complete page
-    setZoomToPageFit(document).then(function () {
-      runNextTest(document, window, finish);
-    }, function () {
-      ok(false, "Current scale has been set to 'page-fit'");
-      finish();
+        if (document.querySelectorAll(".outlineItem").length === outlineCount) {
+          resolve();
+        } else {
+          reject();
+        }
+      });
     });
-  }, function () {
-    ok(false, "Outline items have been found");
-    finish();
-  });
+  }
+
+  /**
+   * The key navigation has to happen in page-fit, otherwise it won't scroll
+   * through a complete page
+   *
+   * @param document
+   * @returns {deferred.promise|*}
+   */
+  function setZoomToPageFit(document) {
+    return new Promise((resolve) => {
+      document.addEventListener("pagerendered", function onZoom(e) {
+        document.removeEventListener("pagerendered", onZoom);
+        document.querySelector("#viewer").click();
+        resolve();
+      });
+
+      var select = document.querySelector("select#scaleSelect");
+      select.selectedIndex = 2;
+      select.dispatchEvent(new Event("change"));
+    });
+  }
+
+  yield waitForOutlineItems(content.document);
+  yield setZoomToPageFit(content.document);
 }
 
 /**
  * As the page changes asynchronously, we have to wait for the event after
  * we trigger the action so we will be at the expected page number after each action
  *
  * @param document
  * @param window
  * @param test
  * @param callback
  */
-function runNextTest(document, window, endCallback) {
-  var test = TESTS.shift(),
-      deferred = Promise.defer(),
-      pageNumber = document.querySelector('input#pageNumber');
+function* runTests(browser) {
+  yield ContentTask.spawn(browser, TESTS, function* (TESTS) {
+    let window = content;
+    let document = window.document;
+
+    for (let test of TESTS) {
+      let deferred = {};
+      deferred.promise = new Promise((resolve, reject) => {
+        deferred.resolve = resolve;
+        deferred.reject = reject;
+      });
 
-  // Add an event-listener to wait for page to change, afterwards resolve the promise
-  var timeout = window.setTimeout(() => deferred.reject(), 5000);
-  window.addEventListener('pagechange', function pageChange() {
-    if (pageNumber.value == test.expectedPage) {
-      window.removeEventListener('pagechange', pageChange);
-      window.clearTimeout(timeout);
-      deferred.resolve(pageNumber.value);
-    }
-  });
+      let pageNumber = document.querySelector('input#pageNumber');
 
-  // Get the element and trigger the action for changing the page
-  var el = document.querySelector(test.action.selector);
-  ok(el, "Element '" + test.action.selector + "' has been found");
-
-  // The value option is for input case
-  if (test.action.value)
-    el.value = test.action.value;
+      // Add an event-listener to wait for page to change, afterwards resolve the promise
+      let timeout = window.setTimeout(() => deferred.reject(), 5000);
+      window.addEventListener('pagechange', function pageChange() {
+        if (pageNumber.value == test.expectedPage) {
+          window.removeEventListener('pagechange', pageChange);
+          window.clearTimeout(timeout);
+          deferred.resolve(+pageNumber.value);
+        }
+      });
 
-  // Dispatch the event for changing the page
-  if (test.action.event == "keydown") {
-    var ev = document.createEvent("KeyboardEvent");
-        ev.initKeyEvent("keydown", true, true, null, false, false, false, false,
-                        test.action.keyCode, 0);
-    el.dispatchEvent(ev);
-  }
-  else {
-    var ev = new Event(test.action.event);
-  }
-  el.dispatchEvent(ev);
+      // Get the element and trigger the action for changing the page
+      var el = document.querySelector(test.action.selector);
+      ok(el, "Element '" + test.action.selector + "' has been found");
 
+      // The value option is for input case
+      if (test.action.value)
+        el.value = test.action.value;
 
-  // When the promise gets resolved we call the next test if there are any left
-  // or else we call the final callback which will end the test
-  deferred.promise.then(function (pgNumber) {
-    is(pgNumber, test.expectedPage, test.message);
+      // Dispatch the event for changing the page
+      if (test.action.event == "keydown") {
+        var ev = document.createEvent("KeyboardEvent");
+            ev.initKeyEvent("keydown", true, true, null, false, false, false, false,
+                            test.action.keyCode, 0);
+        el.dispatchEvent(ev);
+      }
+      else {
+        var ev = new Event(test.action.event);
+      }
+      el.dispatchEvent(ev);
 
-    if (TESTS.length)
-      runNextTest(document, window, endCallback);
-    else
-      endCallback();
-  }, function () {
-    ok(false, "Test '" + test.message + "' failed with timeout.");
-    endCallback();
+      let pgNumber = yield deferred.promise;
+      is(pgNumber, test.expectedPage, test.message);
+    }
+
+    var viewer = content.wrappedJSObject.PDFViewerApplication;
+    yield viewer.close();
   });
 }
-
-/**
- * Outline Items gets appended to the document latter on we have to
- * wait for them before we start to navigate though document
- *
- * @param document
- * @returns {deferred.promise|*}
- */
-function waitForOutlineItems(document) {
-  var deferred = Promise.defer();
-  document.addEventListener("outlineloaded", function outlineLoaded(evt) {
-    document.removeEventListener("outlineloaded", outlineLoaded);
-    var outlineCount = evt.detail.outlineCount;
-
-    if (document.querySelectorAll(".outlineItem").length === outlineCount) {
-      deferred.resolve();
-    } else {
-      deferred.reject();
-    }
-  });
-
-  return deferred.promise;
-}
-
-/**
- * The key navigation has to happen in page-fit, otherwise it won't scroll
- * trough a complete page
- *
- * @param document
- * @returns {deferred.promise|*}
- */
-function setZoomToPageFit(document) {
-  var deferred = Promise.defer();
-  document.addEventListener("pagerendered", function onZoom(e) {
-    document.removeEventListener("pagerendered", onZoom);
-    document.querySelector("#viewer").click();
-    deferred.resolve();
-  });
-
-  var select = document.querySelector("select#scaleSelect");
-  select.selectedIndex = 2;
-  select.dispatchEvent(new Event("change"));
-
-  return deferred.promise;
-}
-
--- a/browser/extensions/pdfjs/test/browser_pdfjs_views.js
+++ b/browser/extensions/pdfjs/test/browser_pdfjs_views.js
@@ -1,86 +1,61 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const RELATIVE_DIR = "browser/extensions/pdfjs/test/";
 const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
 
-function test() {
-  var tab;
-
+add_task(function* test() {
   let handlerService = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
   let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
   let handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
 
   // Make sure pdf.js is the default handler.
   is(handlerInfo.alwaysAskBeforeHandling, false, 'pdf handler defaults to always-ask is false');
   is(handlerInfo.preferredAction, Ci.nsIHandlerInfo.handleInternally, 'pdf handler defaults to internal');
 
   info('Pref action: ' + handlerInfo.preferredAction);
 
-  waitForExplicitFinish();
-  registerCleanupFunction(function() {
-    gBrowser.removeTab(tab);
-  });
+  yield BrowserTestUtils.withNewTab({ gBrowser, url: TESTROOT + "file_pdfjs_test.pdf" },
+    function* (browser) {
+      // check that PDF is opened with internal viewer
+      yield waitForPdfJS(browser);
 
-  tab = gBrowser.addTab(TESTROOT + "file_pdfjs_test.pdf");
-  var newTabBrowser = gBrowser.getBrowserForTab(tab);
-  newTabBrowser.addEventListener("load", function eventHandler() {
-    newTabBrowser.removeEventListener("load", eventHandler, true);
-
-    var document = newTabBrowser.contentDocument,
-        window = newTabBrowser.contentWindow;
+      yield ContentTask.spawn(browser, null, function* () {
+        ok(content.document.querySelector('div#viewer'), "document content has viewer UI");
+        ok('PDFJS' in content.wrappedJSObject, "window content has PDFJS object");
 
-    // Runs tests after all 'load' event handlers have fired off
-    window.addEventListener("documentload", function() {
-      runTests(document, window, function () {
-        closePDFViewer(window, finish);
-      });
-    }, false, true);
-  }, true);
-}
+        //open sidebar
+        var sidebar = content.document.querySelector('button#sidebarToggle');
+        var outerContainer = content.document.querySelector('div#outerContainer');
 
-function runTests(document, window, callback) {
-  // check that PDF is opened with internal viewer
-  ok(document.querySelector('div#viewer'), "document content has viewer UI");
-  ok('PDFJS' in window.wrappedJSObject, "window content has PDFJS object");
+        sidebar.click();
+        ok(outerContainer.classList.contains('sidebarOpen'), 'sidebar opens on click');
 
-  //open sidebar
-  var sidebar = document.querySelector('button#sidebarToggle');
-  var outerContainer = document.querySelector('div#outerContainer');
-
-  sidebar.click();
-  ok(outerContainer.classList.contains('sidebarOpen'), 'sidebar opens on click');
+        // check that thumbnail view is open
+        var thumbnailView = content.document.querySelector('div#thumbnailView');
+        var outlineView = content.document.querySelector('div#outlineView');
 
-  // check that thumbnail view is open
-  var thumbnailView = document.querySelector('div#thumbnailView');
-  var outlineView = document.querySelector('div#outlineView');
-
-  is(thumbnailView.getAttribute('class'), null, 'Initial view is thumbnail view');
-  is(outlineView.getAttribute('class'), 'hidden', 'Outline view is hidden initially');
+        is(thumbnailView.getAttribute('class'), null, 'Initial view is thumbnail view');
+        is(outlineView.getAttribute('class'), 'hidden', 'Outline view is hidden initially');
 
-  //switch to outline view
-  var viewOutlineButton = document.querySelector('button#viewOutline');
-  viewOutlineButton.click();
+        //switch to outline view
+        var viewOutlineButton = content.document.querySelector('button#viewOutline');
+        viewOutlineButton.click();
 
-  is(outlineView.getAttribute('class'), '', 'Outline view is visible when selected');
-  is(thumbnailView.getAttribute('class'), 'hidden', 'Thumbnail view is hidden when outline is selected');
+        is(thumbnailView.getAttribute('class'), 'hidden', 'Thumbnail view is hidden when outline is selected');
+        is(outlineView.getAttribute('class'), '', 'Outline view is visible when selected');
 
-  //switch back to thumbnail view
-  var viewThumbnailButton = document.querySelector('button#viewThumbnail');
-  viewThumbnailButton.click();
+        //switch back to thumbnail view
+        var viewThumbnailButton = content.document.querySelector('button#viewThumbnail');
+        viewThumbnailButton.click();
 
-  is(thumbnailView.getAttribute('class'), '', 'Thumbnail view is visible when selected');
-  is(outlineView.getAttribute('class'), 'hidden', 'Outline view is hidden when thumbnail is selected');
-
-  sidebar.click();
+        is(thumbnailView.getAttribute('class'), '', 'Thumbnail view is visible when selected');
+        is(outlineView.getAttribute('class'), 'hidden', 'Outline view is hidden when thumbnail is selected');
 
-  callback();
-}
+        sidebar.click();
 
-/**
- * Destroys PDF.js viewer opened document.
- */
-function closePDFViewer(window, callback) {
-  var viewer = window.wrappedJSObject.PDFViewerApplication;
-  viewer.close().then(callback);
-}
+        var viewer = content.wrappedJSObject.PDFViewerApplication;
+        yield viewer.close();
+      });
+    });
+});
--- a/browser/extensions/pdfjs/test/browser_pdfjs_zoom.js
+++ b/browser/extensions/pdfjs/test/browser_pdfjs_zoom.js
@@ -23,25 +23,27 @@ const TESTS = [
     },
     expectedZoom: -1, // -1 - zoom out
     message: "Zoomed out using the '-' (zoom out) button"
   },
 
   {
     action: {
       keyboard: true,
+      keyCode: 61,
       event: "+"
     },
     expectedZoom: 1, // 1 - zoom in
     message: "Zoomed in using the CTRL++ keys"
   },
 
   {
     action: {
       keyboard: true,
+      keyCode: 109,
       event: "-"
     },
     expectedZoom: -1, // -1 - zoom out
     message: "Zoomed out using the CTRL+- keys"
   },
 
   {
     action: {
@@ -49,137 +51,102 @@ const TESTS = [
       index: 5,
       event: "change"
     },
     expectedZoom: -1, // -1 - zoom out
     message: "Zoomed using the zoom picker"
   }
 ];
 
-var initialWidth; // the initial width of the PDF document
-var previousWidth; // the width of the PDF document at previous step/test
-
-function test() {
-  var tab;
+add_task(function* test() {
   let handlerService = Cc["@mozilla.org/uriloader/handler-service;1"]
                        .getService(Ci.nsIHandlerService);
   let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
   let handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
 
   // Make sure pdf.js is the default handler.
   is(handlerInfo.alwaysAskBeforeHandling, false,
      'pdf handler defaults to always-ask is false');
   is(handlerInfo.preferredAction, Ci.nsIHandlerInfo.handleInternally,
     'pdf handler defaults to internal');
 
   info('Pref action: ' + handlerInfo.preferredAction);
 
-  waitForExplicitFinish();
-  registerCleanupFunction(function() {
-    gBrowser.removeTab(tab);
-  });
+  yield BrowserTestUtils.withNewTab({ gBrowser, url: TESTROOT + "file_pdfjs_test.pdf" + "#zoom=100" },
+    function* (newTabBrowser) {
+      yield waitForPdfJS(newTabBrowser);
 
-  tab = gBrowser.selectedTab = gBrowser.addTab(TESTROOT + "file_pdfjs_test.pdf");
-  var newTabBrowser = gBrowser.getBrowserForTab(tab);
-
-  newTabBrowser.addEventListener("load", function eventHandler() {
-    newTabBrowser.removeEventListener("load", eventHandler, true);
+      yield ContentTask.spawn(newTabBrowser, TESTS, function* (TESTS) {
+        let document = content.document;
 
-    var document = newTabBrowser.contentDocument,
-        window = newTabBrowser.contentWindow;
+        function waitForRender() {
+          return new Promise((resolve) => {
+            document.addEventListener("pagerendered", function onPageRendered(e) {
+              if(e.detail.pageNumber !== 1) {
+                return;
+              }
 
-    // Runs tests after all 'load' event handlers have fired off
-    window.addEventListener("documentload", function() {
-      initialWidth = parseInt(document.querySelector("div#pageContainer1").style.width);
-      previousWidth = initialWidth;
-      runTests(document, window, function () {
-        closePDFViewer(window, finish);
-      });
-    }, false, true);
-  }, true);
-}
+              document.removeEventListener("pagerendered", onPageRendered, true);
+              resolve();
+            }, true);
+          });
+        }
 
-function runTests(document, window, callback) {
-  // check that PDF is opened with internal viewer
-  ok(document.querySelector('div#viewer'), "document content has viewer UI");
-  ok('PDFJS' in window.wrappedJSObject, "window content has PDFJS object");
+        // check that PDF is opened with internal viewer
+        ok(content.document.querySelector('div#viewer'), "document content has viewer UI");
+        ok('PDFJS' in content.wrappedJSObject, "window content has PDFJS object");
 
-  // Start the zooming tests after the document is loaded
-  waitForDocumentLoad(document).then(function () {
-    zoomPDF(document, window, TESTS.shift(), callback);
-  });
-}
+        let initialWidth, previousWidth;
+        initialWidth = previousWidth =
+          parseInt(content.document.querySelector("div#pageContainer1").style.width);
 
-function waitForDocumentLoad(document) {
-  var deferred = Promise.defer();
-  var interval = setInterval(function () {
-    if (document.querySelector("div#pageContainer1") != null){
-      clearInterval(interval);
-      deferred.resolve();
-    }
-  }, 500);
+        for (let test of TESTS) {
+          // We zoom using an UI element
+          var ev;
+          if (test.action.selector) {
+            // Get the element and trigger the action for changing the zoom
+            var el = document.querySelector(test.action.selector);
+            ok(el, "Element '" + test.action.selector + "' has been found");
 
-  return deferred.promise;
-}
-
-function zoomPDF(document, window, test, endCallback) {
-  var renderedPage;
-
-  document.addEventListener("pagerendered", function onPageRendered(e) {
-    if(e.detail.pageNumber !== 1) {
-      return;
-    }
+            if (test.action.index){
+              el.selectedIndex = test.action.index;
+            }
 
-    document.removeEventListener("pagerendered", onPageRendered, true);
-
-    var pageZoomScale = document.querySelector('select#scaleSelect');
-
-    // The zoom value displayed in the zoom select
-    var zoomValue = pageZoomScale.options[pageZoomScale.selectedIndex].innerHTML;
-
-    let pageContainer = document.querySelector('div#pageContainer1');
-    let actualWidth  = parseInt(pageContainer.style.width);
-
-    // the actual zoom of the PDF document
-    let computedZoomValue = parseInt(((actualWidth/initialWidth).toFixed(2))*100) + "%";
-    is(computedZoomValue, zoomValue, "Content has correct zoom");
+            // Dispatch the event for changing the zoom
+            ev = new Event(test.action.event);
+          }
+          // We zoom using keyboard
+          else {
+            // Simulate key press
+            ev = new content.KeyboardEvent("keydown",
+                                           { key: test.action.event,
+                                             keyCode: test.action.keyCode,
+                                             ctrlKey: true });
+            el = content;
+          }
 
-    // Check that document zooms in the expected way (in/out)
-    let zoom = (actualWidth - previousWidth) * test.expectedZoom;
-    ok(zoom > 0, test.message);
+          el.dispatchEvent(ev);
+          yield waitForRender();
 
-    // Go to next test (if there is any) or finish
-    var nextTest = TESTS.shift();
-    if (nextTest) {
-      previousWidth = actualWidth;
-      zoomPDF(document, window, nextTest, endCallback);
-    }
-    else
-      endCallback();
-  }, true);
+          var pageZoomScale = content.document.querySelector('select#scaleSelect');
 
-  // We zoom using an UI element
-  if (test.action.selector) {
-    // Get the element and trigger the action for changing the zoom
-    var el = document.querySelector(test.action.selector);
-    ok(el, "Element '" + test.action.selector + "' has been found");
+          // The zoom value displayed in the zoom select
+          var zoomValue = pageZoomScale.options[pageZoomScale.selectedIndex].innerHTML;
 
-    if (test.action.index){
-      el.selectedIndex = test.action.index;
-    }
+          let pageContainer = content.document.querySelector('div#pageContainer1');
+          let actualWidth = parseInt(pageContainer.style.width);
+
+          // the actual zoom of the PDF document
+          let computedZoomValue = parseInt(((actualWidth/initialWidth).toFixed(2))*100) + "%";
+          is(computedZoomValue, zoomValue, "Content has correct zoom");
 
-    // Dispatch the event for changing the zoom
-    el.dispatchEvent(new Event(test.action.event));
-  }
-  // We zoom using keyboard
-  else {
-    // Simulate key press
-    EventUtils.synthesizeKey(test.action.event, { ctrlKey: true });
-  }
-}
+          // Check that document zooms in the expected way (in/out)
+          let zoom = (actualWidth - previousWidth) * test.expectedZoom;
+          ok(zoom > 0, test.message);
 
-/**
- * Destroys PDF.js viewer opened document.
- */
-function closePDFViewer(window, callback) {
-  var viewer = window.wrappedJSObject.PDFViewerApplication;
-  viewer.close().then(callback);
-}
+          previousWidth = actualWidth;
+        }
+
+        var viewer = content.wrappedJSObject.PDFViewerApplication;
+        yield viewer.close();
+      });
+    });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/pdfjs/test/head.js
@@ -0,0 +1,11 @@
+function waitForPdfJS(browser) {
+  // Runs tests after all 'load' event handlers have fired off
+  return ContentTask.spawn(browser, null, function* () {
+    yield new Promise((resolve) => {
+      content.addEventListener("documentload", function listener() {
+        content.removeEventListener("documentload", listener, false);
+        resolve();
+      }, false, true);
+    });
+  });
+}
--- a/browser/extensions/shumway/chrome/ShumwayCom.jsm
+++ b/browser/extensions/shumway/chrome/ShumwayCom.jsm
@@ -344,17 +344,17 @@ var ShumwayCom = {
 
       createSpecialStorage: function () {
         var environment = callbacks.getEnvironment();
         return SpecialStorageUtils.createWrappedSpecialStorage(content,
           environment.swfUrl, environment.privateBrowsing);
       },
 
       getWeakMapKeys: function (weakMap) {
-        var keys = Components.utils.nondeterministicGetWeakMapKeys(weakMap);
+        var keys = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(weakMap);
         var result = new content.Array();
         keys.forEach(function (key) {
           result.push(key);
         });
         return result;
       },
 
       setLoadFileCallback: function (callback) {
--- a/config/config.mk
+++ b/config/config.mk
@@ -96,17 +96,17 @@ LIBXUL_DIST ?= $(DIST)
 # instead of $(DIST)/bin. In both cases, if DIST_SUBDIR is set, the files will be
 # shipped to a $(DIST_SUBDIR) subdirectory.
 FINAL_TARGET ?= $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(DIST)/bin)$(DIST_SUBDIR:%=/%)
 # Override the stored value for the check to make sure that the variable is not
 # redefined in the Makefile.in value.
 FINAL_TARGET_FROZEN := '$(FINAL_TARGET)'
 
 ifdef XPI_NAME
-DEFINES += -DXPI_NAME=$(XPI_NAME)
+ACDEFINES += -DXPI_NAME=$(XPI_NAME)
 endif
 
 # The VERSION_NUMBER is suffixed onto the end of the DLLs we ship.
 VERSION_NUMBER		= 50
 
 ifeq ($(HOST_OS_ARCH),WINNT)
   ifeq ($(MOZILLA_DIR),$(topsrcdir))
     win_srcdir := $(subst $(topsrcdir),$(WIN_TOP_SRC),$(srcdir))
@@ -528,17 +528,17 @@ sysinstall_cmd = install_cmd
 # Localization build automation
 #
 
 # Because you might wish to "make locales AB_CD=ab-CD", we don't hardcode
 # MOZ_UI_LOCALE directly, but use an intermediate variable that can be
 # overridden by the command line. (Besides, AB_CD is prettier).
 AB_CD = $(MOZ_UI_LOCALE)
 # Many locales directories want this definition.
-DEFINES += -DAB_CD=$(AB_CD)
+ACDEFINES += -DAB_CD=$(AB_CD)
 
 ifndef L10NBASEDIR
   L10NBASEDIR = $(error L10NBASEDIR not defined by configure)
 else
   IS_LANGUAGE_REPACK = 1
 endif
 
 EXPAND_LOCALE_SRCDIR = $(if $(filter en-US,$(AB_CD)),$(topsrcdir)/$(1)/en-US,$(or $(realpath $(L10NBASEDIR)),$(abspath $(L10NBASEDIR)))/$(AB_CD)/$(subst /locales,,$(1)))
@@ -684,10 +684,8 @@ endif
 
 PLY_INCLUDE = -I$(MOZILLA_DIR)/other-licenses/ply
 
 export CL_INCLUDES_PREFIX
 # Make sure that the build system can handle non-ASCII characters
 # in environment variables to prevent it from breking silently on
 # non-English systems.
 export NONASCII
-
-DEFINES += -DNO_NSPR_10_SUPPORT
--- a/config/external/nss/Makefile.in
+++ b/config/external/nss/Makefile.in
@@ -208,17 +208,17 @@ DEFAULT_GMAKE_FLAGS += \
 
 # 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='$(CFLAGS) -DCHECK_FORK_GETPID $(addprefix -DANDROID_VERSION=,$(ANDROID_VERSION)) -include $(topsrcdir)/security/manager/android_stub.h'
+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
 
 ifdef MOZ_GLUE_WRAP_LDFLAGS
@@ -236,17 +236,17 @@ DEFAULT_GMAKE_FLAGS += FREEBL_NO_DEPEND=
 ifeq ($(OS_TARGET),Linux)
 DEFAULT_GMAKE_FLAGS += FREEBL_LOWHASH=1
 endif
 
 ifdef MOZ_NO_WLZDEFS
 DEFAULT_GMAKE_FLAGS += ZDEFS_FLAG=
 endif
 ifdef MOZ_CFLAGS_NSS
-DEFAULT_GMAKE_FLAGS += XCFLAGS='$(CFLAGS)'
+DEFAULT_GMAKE_FLAGS += 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
@@ -262,17 +262,20 @@ DEFAULT_GMAKE_FLAGS += MAKE_OBJDIR='$$(I
 # 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
 DEFAULT_GMAKE_FLAGS += XCFLAGS='$(MOZ_FOLD_LIBS_FLAGS)'
 endif
 
-ifeq (1,$(ALLOW_COMPILER_WARNINGS))
+ifndef WARNINGS_AS_ERRORS
+DEFAULT_GMAKE_FLAGS += NSS_ENABLE_WERROR=0
+endif
+ifeq ($(OS_TARGET),Android)
 DEFAULT_GMAKE_FLAGS += NSS_ENABLE_WERROR=0
 endif
 
 NSS_SRCDIR = $(topsrcdir)
 
 NSS_DIRS =
 ifndef MOZ_FOLD_LIBS
 NSS_DIRS += nss/lib
--- a/config/makefiles/xpidl/Makefile.in
+++ b/config/makefiles/xpidl/Makefile.in
@@ -30,18 +30,18 @@ dist_idl_dir := $(DIST)/idl
 dist_include_dir := $(DIST)/include
 process_py := $(topsrcdir)/python/mozbuild/mozbuild/action/xpidl-process.py
 
 # TODO we should use py_action, but that would require extra directories to be
 # in the virtualenv.
 %.xpt:
 	@echo "$(@F)"
 	$(PYTHON_PATH) $(PLY_INCLUDE) -I$(IDL_PARSER_DIR) -I$(IDL_PARSER_CACHE_DIR) \
-		$(process_py) --cache-dir $(IDL_PARSER_CACHE_DIR) $(dist_idl_dir) \
-		$(dist_include_dir) $(@D) $(idl_deps_dir) $(libxul_sdk_includes) \
+		$(process_py) --cache-dir $(IDL_PARSER_CACHE_DIR) --depsdir $(idl_deps_dir) \
+		$(dist_idl_dir) $(dist_include_dir) $(@D) $(libxul_sdk_includes) \
 		$(basename $(notdir $@)) $($(basename $(notdir $@))_deps)
 # When some IDL is added or removed, if the actual IDL file was already, or
 # still is, in the tree, simple dependencies can't detect that the XPT needs
 # to be rebuilt.
 # Add the current value of $($(xpidl_module)_deps) in the depend file, such that
 # we can later check if the value has changed since last build, which will
 # indicate whether IDLs were added or removed.
 # Note that removing previously built files is not covered.
--- a/config/tests/src-simple/Makefile.in
+++ b/config/tests/src-simple/Makefile.in
@@ -8,17 +8,17 @@ LOCALE_SRCDIR = $(srcdir)/l10n
 EXTERNALLY_MANAGED_MAKE_FILE := 1
 STANDALONE_MAKEFILE := 1
 JAR_MANIFEST := $(srcdir)/jar.mn
 
 include $(topsrcdir)/config/config.mk
 
 XPI_NAME = test_jar_mn
 
-DEFINES += \
+ACDEFINES += \
 	-DAB_CD=ab-X-stuff \
 	$(NULL)
 
 MY_MANIFEST = $(if $(USE_EXTENSION_MANIFEST), $(FINAL_TARGET)/chrome.manifest, $(FINAL_TARGET)/chrome/test.manifest)
 REF_MANIFEST = $(if $(USE_EXTENSION_MANIFEST),chrome.manifest,test.manifest)
 
 check-%::
 	if test -d $(FINAL_TARGET); then rm -rf $(FINAL_TARGET); fi;
--- a/configure.in
+++ b/configure.in
@@ -9167,16 +9167,19 @@ fi
 
 MOZ_CONFIG_ICU()
 
 if test -z "$JS_SHARED_LIBRARY"; then
   AC_DEFINE(MOZ_STATIC_JS)
 fi
 AC_SUBST(JS_SHARED_LIBRARY)
 
+# Avoid using obsolete NSPR features
+AC_DEFINE(NO_NSPR_10_SUPPORT)
+
 MOZ_CREATE_CONFIG_STATUS()
 
 if test "$COMPILE_ENVIRONMENT"; then
   MOZ_SUBCONFIGURE_ICU()
   MOZ_SUBCONFIGURE_FFI()
   MOZ_SUBCONFIGURE_JEMALLOC()
 fi
 
--- a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-04.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-04.js
@@ -133,18 +133,18 @@ function test() {
        "Child element should not have a parent.")
     is([...parent].length, 0,
        "Parent should have zero children.");
 
     testScope.remove();
 
     is([...variables].length, 0,
        "VariablesView should have been emptied.");
-    is(Cu.nondeterministicGetWeakMapKeys(variables._itemsByElement).length, 0,
-       "VariablesView _itemsByElement map has been emptied.");
+    is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(variables._itemsByElement).length,
+       0, "VariablesView _itemsByElement map has been emptied.");
     is(variables._currHierarchy.size, 0,
        "VariablesView _currHierarchy map has been emptied.");
     is(variables._list.children.length, 0,
        "VariablesView element should have no children.");
 
     closeDebuggerAndFinish(aPanel);
   });
 }
--- a/devtools/shared/heapsnapshot/HeapSnapshot.cpp
+++ b/devtools/shared/heapsnapshot/HeapSnapshot.cpp
@@ -86,17 +86,17 @@ HeapSnapshot::WrapObject(JSContext* aCx,
 /* static */ already_AddRefed<HeapSnapshot>
 HeapSnapshot::Create(JSContext* cx,
                      GlobalObject& global,
                      const uint8_t* buffer,
                      uint32_t size,
                      ErrorResult& rv)
 {
   RefPtr<HeapSnapshot> snapshot = new HeapSnapshot(cx, global.GetAsSupports());
-  if (!snapshot->init(buffer, size)) {
+  if (!snapshot->init(cx, buffer, size)) {
     rv.Throw(NS_ERROR_UNEXPECTED);
     return nullptr;
   }
   return snapshot.forget();
 }
 
 template<typename MessageType>
 static bool
@@ -198,17 +198,17 @@ HeapSnapshot::getOrInternString(Interned
 #define GET_STRING_OR_REF(msg, property)      \
   (msg.has_##property##ref()                  \
      ? Some(StringOrRef(msg.property##ref())) \
      : msg.has_##property()                   \
        ? Some(StringOrRef(&msg.property()))   \
        : Nothing())
 
 bool
-HeapSnapshot::saveNode(const protobuf::Node& node)
+HeapSnapshot::saveNode(const protobuf::Node& node, NodeIdSet& edgeReferents)
 {
   // NB: de-duplicated string properties must be read back and interned in the
   // same order here as they are written and serialized in
   // `CoreDumpWriter::writeNode` or else indices in references to already
   // serialized strings will be off.
 
   if (NS_WARN_IF(!node.has_id()))
     return false;
@@ -243,16 +243,19 @@ HeapSnapshot::saveNode(const protobuf::N
     return false;
   for (decltype(edgesLength) i = 0; i < edgesLength; i++) {
     auto& protoEdge = node.edges(i);
 
     if (NS_WARN_IF(!protoEdge.has_referent()))
       return false;
     NodeId referent = protoEdge.referent();
 
+    if (NS_WARN_IF(!edgeReferents.put(referent)))
+      return false;
+
     const char16_t* edgeName = nullptr;
     if (protoEdge.EdgeNameOrRef_case() != protobuf::Edge::EDGENAMEORREF_NOT_SET) {
       Maybe<StringOrRef> edgeNameOrRef = GET_STRING_OR_REF(protoEdge, name);
       edgeName = getOrInternString<char16_t>(internedTwoByteStrings, edgeNameOrRef);
       if (NS_WARN_IF(!edgeName))
         return false;
     }
 
@@ -397,17 +400,17 @@ StreamHasData(GzipInputStream& stream)
 
   // There is more data still available in the stream. Return the data we read
   // to the stream and let the parser get at it.
   stream.BackUp(size);
   return true;
 }
 
 bool
-HeapSnapshot::init(const uint8_t* buffer, uint32_t size)
+HeapSnapshot::init(JSContext* cx, const uint8_t* buffer, uint32_t size)
 {
   if (!nodes.init() || !frames.init())
     return false;
 
   ArrayInputStream stream(buffer, size);
   GzipInputStream gzipStream(&stream);
 
   // First is the metadata.
@@ -425,26 +428,39 @@ HeapSnapshot::init(const uint8_t* buffer
     return false;
 
   // Although the id is optional in the protobuf format for future proofing, we
   // can't currently do anything without it.
   if (NS_WARN_IF(!root.has_id()))
     return false;
   rootId = root.id();
 
-  if (NS_WARN_IF(!saveNode(root)))
+  // The set of all node ids we've found edges pointing to.
+  NodeIdSet edgeReferents(cx);
+  if (NS_WARN_IF(!edgeReferents.init()))
+    return false;
+
+  if (NS_WARN_IF(!saveNode(root, edgeReferents)))
     return false;
 
   // Finally, the rest of the nodes in the core dump.
 
   while (StreamHasData(gzipStream)) {
     protobuf::Node node;
     if (!parseMessage(gzipStream, node))
       return false;
-    if (NS_WARN_IF(!saveNode(node)))
+    if (NS_WARN_IF(!saveNode(node, edgeReferents)))
+      return false;
+  }
+
+  // Check the set of node ids referred to by edges we found and ensure that we
+  // have the node corresponding to each id. If we don't have all of them, it is
+  // unsafe to perform analyses of this heap snapshot.
+  for (auto range = edgeReferents.all(); !range.empty(); range.popFront()) {
+    if (NS_WARN_IF(!nodes.has(range.front())))
       return false;
   }
 
   return true;
 }
 
 
 /*** Heap Snapshot Analyses ***********************************************************************/
--- a/devtools/shared/heapsnapshot/HeapSnapshot.h
+++ b/devtools/shared/heapsnapshot/HeapSnapshot.h
@@ -54,21 +54,23 @@ class HeapSnapshot final : public nsISup
     , mParent(aParent)
   {
     MOZ_ASSERT(aParent);
   };
 
   // Initialize this HeapSnapshot from the given buffer that contains a
   // serialized core dump. Do NOT take ownership of the buffer, only borrow it
   // for the duration of the call. Return false on failure.
-  bool init(const uint8_t* buffer, uint32_t size);
+  bool init(JSContext* cx, const uint8_t* buffer, uint32_t size);
+
+  using NodeIdSet = js::HashSet<NodeId>;
 
   // Save the given `protobuf::Node` message in this `HeapSnapshot` as a
   // `DeserializedNode`.
-  bool saveNode(const protobuf::Node& node);
+  bool saveNode(const protobuf::Node& node, NodeIdSet& edgeReferents);
 
   // Save the given `protobuf::StackFrame` message in this `HeapSnapshot` as a
   // `DeserializedStackFrame`. The saved stack frame's id is returned via the
   // out parameter.
   bool saveStackFrame(const protobuf::StackFrame& frame,
                       StackFrameId& outFrameId);
 
 public:
--- a/docshell/resources/content/netError.xhtml
+++ b/docshell/resources/content/netError.xhtml
@@ -1,15 +1,18 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
 <!DOCTYPE html [
   <!ENTITY % htmlDTD
     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     "DTD/xhtml1-strict.dtd">
   %htmlDTD;
+  <!ENTITY % netErrorAppDTD
+    SYSTEM "chrome://global/locale/netErrorApp.dtd">
+  %netErrorAppDTD;
   <!ENTITY % netErrorDTD
     SYSTEM "chrome://global/locale/netError.dtd">
   %netErrorDTD;
   <!ENTITY % globalDTD
     SYSTEM "chrome://global/locale/global.dtd">
   %globalDTD;
 ]>
 
--- a/dom/base/ChromeUtils.cpp
+++ b/dom/base/ChromeUtils.cpp
@@ -6,16 +6,36 @@
 #include "ChromeUtils.h"
 
 #include "mozilla/BasePrincipal.h"
 
 namespace mozilla {
 namespace dom {
 
 /* static */ void
+ThreadSafeChromeUtils::NondeterministicGetWeakMapKeys(GlobalObject& aGlobal,
+                                                      JS::Handle<JS::Value> aMap,
+                                                      JS::MutableHandle<JS::Value> aRetval,
+                                                      ErrorResult& aRv)
+{
+  if (!aMap.isObject()) {
+    aRetval.setUndefined();
+  } else {
+    JSContext* cx = aGlobal.Context();
+    JS::Rooted<JSObject*> objRet(cx);
+    JS::Rooted<JSObject*> mapObj(cx, &aMap.toObject());
+    if (!JS_NondeterministicGetWeakMapKeys(cx, mapObj, &objRet)) {
+      aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
+    } else {
+      aRetval.set(objRet ? JS::ObjectValue(*objRet) : JS::UndefinedValue());
+    }
+  }
+}
+
+  /* static */ void
 ChromeUtils::OriginAttributesToSuffix(dom::GlobalObject& aGlobal,
                                       const dom::OriginAttributesDictionary& aAttrs,
                                       nsCString& aSuffix)
 
 {
   OriginAttributes attrs(aAttrs);
   attrs.CreateSuffix(aSuffix);
 }
--- a/dom/base/ChromeUtils.h
+++ b/dom/base/ChromeUtils.h
@@ -30,16 +30,21 @@ public:
                                nsAString& filePath,
                                ErrorResult& rv);
 
   // Implemented in devtools/shared/heapsnapshot/HeapSnapshot.cpp
   static already_AddRefed<devtools::HeapSnapshot> ReadHeapSnapshot(GlobalObject& global,
                                                                    JSContext* cx,
                                                                    const nsAString& filePath,
                                                                    ErrorResult& rv);
+
+  static void NondeterministicGetWeakMapKeys(GlobalObject& aGlobal,
+                                             JS::Handle<JS::Value> aMap,
+                                             JS::MutableHandle<JS::Value> aRetval,
+                                             ErrorResult& aRv);
 };
 
 class ChromeUtils : public ThreadSafeChromeUtils
 {
 public:
   static void
   OriginAttributesToSuffix(dom::GlobalObject& aGlobal,
                            const dom::OriginAttributesDictionary& aAttrs,
--- a/dom/base/nsContentList.cpp
+++ b/dom/base/nsContentList.cpp
@@ -522,18 +522,19 @@ nsContentList::NamedItem(const nsAString
   // Typically IDs and names are atomized
   nsCOMPtr<nsIAtom> name = do_GetAtom(aName);
   NS_ENSURE_TRUE(name, nullptr);
 
   for (i = 0; i < count; i++) {
     nsIContent *content = mElements[i];
     // XXX Should this pass eIgnoreCase?
     if (content &&
-        (content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
-                              name, eCaseMatters) ||
+        ((content->IsHTMLElement() &&
+          content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
+                               name, eCaseMatters)) ||
          content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::id,
                               name, eCaseMatters))) {
       return content->AsElement();
     }
   }
 
   return nullptr;
 }
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3636,17 +3636,17 @@ nsDOMWindowUtils::SetChromeMargin(int32_
 {
   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   if (window) {
     nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(window->GetDocShell());
     if (baseWindow) {
       nsCOMPtr<nsIWidget> widget;
       baseWindow->GetMainWidget(getter_AddRefs(widget));
       if (widget) {
-        nsIntMargin margins(aTop, aRight, aBottom, aLeft);
+        LayoutDeviceIntMargin margins(aTop, aRight, aBottom, aLeft);
         return widget->SetNonClientMargins(margins);
       }
     }
   }
 
   return NS_OK;
 }
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -13320,26 +13320,27 @@ nsGlobalWindow::NotifyDefaultButtonLoade
   }
 
   // Get the button rect in screen coordinates.
   nsIFrame *frame = aDefaultButton.GetPrimaryFrame();
   if (!frame) {
     aError.Throw(NS_ERROR_FAILURE);
     return;
   }
-  nsIntRect buttonRect = frame->GetScreenRect();
+  LayoutDeviceIntRect buttonRect =
+    LayoutDeviceIntRect::FromUnknownRect(frame->GetScreenRect());
 
   // Get the widget rect in screen coordinates.
   nsIWidget *widget = GetNearestWidget();
   if (!widget) {
     aError.Throw(NS_ERROR_FAILURE);
     return;
   }
-  nsIntRect widgetRect;
-  aError = widget->GetScreenBoundsUntyped(widgetRect);
+  LayoutDeviceIntRect widgetRect;
+  aError = widget->GetScreenBounds(widgetRect);
   if (aError.Failed()) {
     return;
   }
 
   // Convert the buttonRect coordinates from screen to the widget.
   buttonRect -= widgetRect.TopLeft();
   nsresult rv = widget->OnDefaultButtonLoaded(buttonRect);
   if (NS_FAILED(rv) && rv != NS_ERROR_NOT_IMPLEMENTED) {
--- a/dom/browser-element/BrowserElementParent.js
+++ b/dom/browser-element/BrowserElementParent.js
@@ -37,17 +37,17 @@ function getIntPref(prefName, def) {
   }
   catch(err) {
     return def;
   }
 }
 
 function handleWindowEvent(e) {
   if (this._browserElementParents) {
-    let beps = Cu.nondeterministicGetWeakMapKeys(this._browserElementParents);
+    let beps = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(this._browserElementParents);
     beps.forEach(bep => bep._handleOwnerEvent(e));
   }
 }
 
 function defineNoReturnMethod(fn) {
   return function method() {
     if (!this._domRequestReady) {
       // Remote browser haven't been created, we just queue the API call.
--- a/dom/canvas/ImageBitmap.cpp
+++ b/dom/canvas/ImageBitmap.cpp
@@ -928,44 +928,47 @@ protected:
     mCropRect(aCropRect)
   {
   }
 
   virtual ~CreateImageBitmapFromBlob()
   {
   }
 
-  void DoCreateImageBitmapFromBlob(ErrorResult& aRv)
+  // Returns true on success, false on failure.
+  bool DoCreateImageBitmapFromBlob()
   {
-    RefPtr<ImageBitmap> imageBitmap = CreateImageBitmap(aRv);
+    RefPtr<ImageBitmap> imageBitmap = CreateImageBitmap();
 
     // handle errors while creating ImageBitmap
     // (1) error occurs during reading of the object
     // (2) the image data is not in a supported file format
     // (3) the image data is corrupted
     // All these three cases should reject promise with null value
-    if (aRv.Failed()) {
-      mPromise->MaybeReject(aRv);
-      return;
+    if (!imageBitmap) {
+      return false;
     }
 
     if (imageBitmap && mCropRect.isSome()) {
-      imageBitmap->SetPictureRect(mCropRect.ref(), aRv);
+      ErrorResult rv;
+      imageBitmap->SetPictureRect(mCropRect.ref(), rv);
 
-      if (aRv.Failed()) {
-        mPromise->MaybeReject(aRv);
-        return;
+      if (rv.Failed()) {
+        mPromise->MaybeReject(rv);
+        return false;
       }
     }
 
     mPromise->MaybeResolve(imageBitmap);
-    return;
+    return true;
   }
 
-  virtual already_AddRefed<ImageBitmap> CreateImageBitmap(ErrorResult& aRv) = 0;
+  // Will return null on failure.  In that case, mPromise will already
+  // be rejected with the right thing.
+  virtual already_AddRefed<ImageBitmap> CreateImageBitmap() = 0;
 
   RefPtr<Promise> mPromise;
   nsCOMPtr<nsIGlobalObject> mGlobalObject;
   RefPtr<mozilla::dom::Blob> mBlob;
   Maybe<IntRect> mCropRect;
 };
 
 class CreateImageBitmapFromBlobTask final : public nsRunnable,
@@ -977,27 +980,28 @@ public:
                                 Blob& aBlob,
                                 const Maybe<IntRect>& aCropRect)
   :CreateImageBitmapFromBlob(aPromise, aGlobal, aBlob, aCropRect)
   {
   }
 
   NS_IMETHOD Run() override
   {
-    ErrorResult error;
-    DoCreateImageBitmapFromBlob(error);
+    DoCreateImageBitmapFromBlob();
     return NS_OK;
   }
 
 private:
-  already_AddRefed<ImageBitmap> CreateImageBitmap(ErrorResult& aRv) override
+  already_AddRefed<ImageBitmap> CreateImageBitmap() override
   {
-    RefPtr<layers::Image> data = DecodeAndCropBlob(*mBlob, mCropRect, aRv);
+    ErrorResult rv;
+    RefPtr<layers::Image> data = DecodeAndCropBlob(*mBlob, mCropRect, rv);
 
-    if (NS_WARN_IF(aRv.Failed())) {
+    if (NS_WARN_IF(rv.Failed())) {
+      mPromise->MaybeReject(rv);
       return nullptr;
     }
 
     // Create ImageBitmap object.
     RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, data);
     return imageBitmap.forget();
   }
 };
@@ -1049,33 +1053,32 @@ public:
                                   const Maybe<IntRect>& aCropRect)
   : WorkerSameThreadRunnable(GetCurrentThreadWorkerPrivate()),
     CreateImageBitmapFromBlob(aPromise, aGlobal, aBlob, aCropRect)
   {
   }
 
   bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
   {
-    ErrorResult error;
-    DoCreateImageBitmapFromBlob(error);
-    return !(error.Failed());
+    return DoCreateImageBitmapFromBlob();
   }
 
 private:
-  already_AddRefed<ImageBitmap> CreateImageBitmap(ErrorResult& aRv) override
+  already_AddRefed<ImageBitmap> CreateImageBitmap() override
   {
     RefPtr<layers::Image> data;
 
+    ErrorResult rv;
     RefPtr<DecodeBlobInMainThreadSyncTask> task =
       new DecodeBlobInMainThreadSyncTask(mWorkerPrivate, *mBlob, mCropRect,
-                                         aRv, getter_AddRefs(data));
+                                         rv, getter_AddRefs(data));
     task->Dispatch(mWorkerPrivate->GetJSContext()); // This is a synchronous call.
 
-    if (NS_WARN_IF(aRv.Failed())) {
-      mPromise->MaybeReject(aRv);
+    if (NS_WARN_IF(rv.Failed())) {
+      mPromise->MaybeReject(rv);
       return nullptr;
     }
 
     // Create ImageBitmap object.
     RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, data);
     return imageBitmap.forget();
   }
 
--- a/dom/geolocation/nsGeolocationSettings.cpp
+++ b/dom/geolocation/nsGeolocationSettings.cpp
@@ -255,50 +255,58 @@ nsGeolocationSettings::HandleGeolocation
   // go through all of the objects in the exceptions dictionary
   for (size_t i = 0; i < ids.length(); i++) {
     JS::RootedId id(cx);
     id = ids[i];
 
     // if it is an app that is always precise, skip it
     nsAutoJSString origin;
     if (!origin.init(cx, id)) {
+      JS_ClearPendingException(cx); // catch and ignore any exceptions
       continue;
     }
     if (mAlwaysPreciseApps.Contains(origin)) {
       continue;
     }
 
     // get the app setting object
     JS::RootedValue propertyValue(cx);
-    if (!JS_GetPropertyById(cx, obj, id, &propertyValue) || !propertyValue.isObject()) {
+    if (!JS_GetPropertyById(cx, obj, id, &propertyValue)) {
+      JS_ClearPendingException(cx); // catch and ignore any exceptions
       continue;
     }
     JS::RootedObject settingObj(cx, &propertyValue.toObject());
 
     GeolocationSetting *settings = new GeolocationSetting(origin);
     GPSLOG("adding exception for %s", NS_ConvertUTF16toUTF8(origin).get());
 
     // get the geolocation type
     JS::RootedValue fm(cx);
     if (JS_GetProperty(cx, settingObj, "type", &fm)) {
       settings->HandleTypeChange(fm);
+    } else {
+      JS_ClearPendingException(cx); // catch and ignore any exceptions
     }
 
 #ifdef MOZ_APPROX_LOCATION
     // get the approximate distance if there is one
     JS::RootedValue distance(cx);
     if (JS_GetProperty(cx, settingObj, "distance", &distance)) {
       settings->HandleApproxDistanceChange(distance);
+    } else {
+      JS_ClearPendingException(cx); // catch and ignore any exceptions
     }
 #endif
 
     // get and parse the coords, if any
     JS::RootedValue coords(cx);
     if (JS_GetProperty(cx, settingObj, "coords", &coords)) {
       settings->HandleFixedCoordsChange(coords);
+    } else {
+      JS_ClearPendingException(cx); // catch and ignore any exceptions
     }
 
     // add the per-app setting object to the hashtable
     mPerOriginSettings.Put(origin, settings);
   }
 }
 
 void
@@ -332,21 +340,23 @@ nsGeolocationSettings::HandleGeolocation
     return;
   }
 
   // process the list of apps...
   for (uint32_t i = 0; i < length; ++i) {
     JS::RootedValue value(cx);
 
     if (!JS_GetElement(cx, obj, i, &value) || !value.isString()) {
+      JS_ClearPendingException(cx); // catch and ignore any exceptions
       continue;
     }
 
     nsAutoJSString origin;
     if (!origin.init(cx, value)) {
+      JS_ClearPendingException(cx); // catch and ignore any exceptions
       continue;
     }
 
     GPSLOG("adding always precise for %s", NS_ConvertUTF16toUTF8(origin).get());
 
     // add the origin to the list of apps that will always receive
     // precise location information
     mAlwaysPreciseApps.AppendElement(origin);
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -1230,17 +1230,17 @@ nsresult HTMLMediaElement::LoadResource(
     return NS_ERROR_FAILURE;
   }
 
   // Set the media element's CORS mode only when loading a resource
   mCORSMode = AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
 
 #ifdef MOZ_EME
   if (mMediaKeys &&
-      !IsMediaStreamURI(mLoadingSrc) &&
+      !IsMediaSourceURI(mLoadingSrc) &&
       Preferences::GetBool("media.eme.mse-only", true)) {
     return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
   }
 #endif
 
   HTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc);
   if (other && other->mDecoder) {
     // Clone it.
--- a/dom/interfaces/base/nsIServiceWorkerManager.idl
+++ b/dom/interfaces/base/nsIServiceWorkerManager.idl
@@ -23,27 +23,37 @@ interface nsIServiceWorkerUnregisterCall
 
 [scriptable, builtinclass, uuid(1a1e71dd-0f78-4e2e-a2db-a946fe02cddf)]
 interface nsIServiceWorkerInfo : nsISupports
 {
   readonly attribute DOMString scriptSpec;
   readonly attribute DOMString cacheName;
 };
 
-[scriptable, builtinclass, uuid(e908bc07-0a4c-443f-a546-2109bf1f4A01)]
+[scriptable, uuid(87e63548-d440-4b8a-b158-65ad1de0211E)]
+interface nsIServiceWorkerRegistrationInfoListener : nsISupports
+{
+  void onChange();
+};
+
+[scriptable, builtinclass, uuid(72faba24-0a1b-4284-bad3-d44c044d6d95)]
 interface nsIServiceWorkerRegistrationInfo : nsISupports
 {
   readonly attribute nsIPrincipal principal;
 
   readonly attribute DOMString scope;
   readonly attribute DOMString scriptSpec;
 
   readonly attribute nsIServiceWorkerInfo installingWorker;
   readonly attribute nsIServiceWorkerInfo waitingWorker;
   readonly attribute nsIServiceWorkerInfo activeWorker;
+
+  void addListener(in nsIServiceWorkerRegistrationInfoListener listener);
+
+  void removeListener(in nsIServiceWorkerRegistrationInfoListener listener);
 };
 
 [scriptable, uuid(9e523e7c-ad6f-4df0-8077-c74aebbc679d)]
 interface nsIServiceWorkerManagerListener : nsISupports
 {
   void onRegister(in nsIServiceWorkerRegistrationInfo aInfo);
 
   void onUnregister(in nsIServiceWorkerRegistrationInfo aInfo);
--- a/dom/locales/en-US/chrome/netError.dtd
+++ b/dom/locales/en-US/chrome/netError.dtd
@@ -87,23 +87,22 @@
 ">
 
 <!ENTITY phishingBlocked.title "Suspected Web Forgery!">
 <!ENTITY phishingBlocked.longDesc "
 <p>Entering any personal information on this page may result in identity theft or other fraud.</p>
 <p>These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.</p>
 ">
 
+<!ENTITY securityOverride.linkText "Or you can add an exception…">
+<!ENTITY securityOverride.warningContent "
+<p>You should not add an exception if you are using an internet connection that you do not trust completely or if you are not used to seeing a warning for this server.</p>
+<p>If you still wish to add an exception for this site, you can do so in your advanced encryption settings.</p>
+">
+
 <!ENTITY cspBlocked.title "Blocked by Content Security Policy">
 <!ENTITY cspBlocked.longDesc "<p>The browser prevented this page from loading in this way because the page has a content security policy that disallows it.</p>">
 
 <!ENTITY corruptedContentError.title "Corrupted Content Error">
 <!ENTITY corruptedContentError.longDesc "<p>The page you are trying to view cannot be shown because an error in the data transmission was detected.</p><ul><li>Please contact the website owners to inform them of this problem.</li></ul>">
 
 <!ENTITY remoteXUL.title "Remote XUL">
 <!ENTITY remoteXUL.longDesc "<p><ul><li>Please contact the website owners to inform them of this problem.</li></ul></p>">
-
-<!-- Include app-specific error messages - do not change this in localization!
-     Some applications might override netErrorApp.dtd with their specific version,
-     this inclusion needs to be intact for that approach to work correctly.
-     Please, try to keep this at the end of the file. -->
-<!ENTITY % netErrorAppDTD SYSTEM "chrome://global/locale/netErrorApp.dtd">
-%netErrorAppDTD;
--- a/dom/locales/en-US/chrome/netErrorApp.dtd
+++ b/dom/locales/en-US/chrome/netErrorApp.dtd
@@ -1,13 +1,23 @@
 <!-- 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/. -->
 
-<!-- Error messages that are likely to be overridden by applications go in this
-     file, all messages that likely don't need to tie into app-specific UI
-     should go into netError.dtd -->
+<!-- This file exists to allow applications to override one or more messages
+     from netError.dtd; Applications which want to do this should override
+     this file with their own version of netErrorApp.dtd -->
+
+<!-- An example (from Firefox):
 
 <!ENTITY securityOverride.linkText "Or you can add an exception…">
+<!ENTITY securityOverride.getMeOutOfHereButton "Get me out of here!">
+<!ENTITY securityOverride.exceptionButtonLabel "Add Exception…">
+
 <!ENTITY securityOverride.warningContent "
 <p>You should not add an exception if you are using an internet connection that you do not trust completely or if you are not used to seeing a warning for this server.</p>
 <p>If you still wish to add an exception for this site, you can do so in your advanced encryption settings.</p>
+
+<button id='getMeOutOfHereButton'>&securityOverride.getMeOutOfHereButton;</button>
+<button id='exceptionDialogButton'>&securityOverride.exceptionButtonLabel;</button>
 ">
+
+-->
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -624,16 +624,18 @@ skip-if = toolkit == 'android' # bug 114
 [test_eme_request_notifications.html]
 skip-if = toolkit == 'android' # bug 1149374
 [test_eme_persistent_sessions.html]
 skip-if = toolkit == 'android' # bug 1149374
 [test_eme_playback.html]
 skip-if = toolkit == 'android' || toolkit == 'gonk' # android: bug 1149374; gonk: bug 1193351
 [test_eme_requestKeySystemAccess.html]
 skip-if = toolkit == 'android' # bug 1149374
+[test_eme_setMediaKeys_before_attach_MediaSource.html]
+skip-if = toolkit == 'android' # bug 1149374
 [test_eme_stream_capture_blocked_case1.html]
 tags=msg capturestream
 skip-if = toolkit == 'android' || toolkit == 'gonk' # android: bug 1149374; gonk: bug 1193351
 [test_eme_stream_capture_blocked_case2.html]
 tags=msg capturestream
 skip-if = toolkit == 'android' || toolkit == 'gonk' # android: bug 1149374; gonk: bug 1193351
 [test_eme_stream_capture_blocked_case3.html]
 tags=msg capturestream
new file mode 100644
--- /dev/null
+++ b/dom/media/test/test_eme_setMediaKeys_before_attach_MediaSource.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test Encrypted Media Extensions</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+  <script type="text/javascript" src="eme.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+function beginTest() {
+  var video = document.createElement("video");
+
+  navigator.requestMediaKeySystemAccess("org.w3.clearkey", [{initDataTypes: ["cenc"]}])
+    .then(function(keySystemAccess) {
+      return keySystemAccess.createMediaKeys();
+    })
+    .then(mediaKeys => {
+      return video.setMediaKeys(mediaKeys);
+    })
+    .then(() => {
+      var ms = new MediaSource();
+      ms.addEventListener("sourceopen", ()=>{ok(true, "MediaSource should open"); SimpleTest.finish();});
+      video.addEventListener("error", ()=>{ok(false, "Shouldn't error."); SimpleTest.finish();});
+      video.src = URL.createObjectURL(ms);
+    });
+}
+
+if (!IsMacOSSnowLeopardOrEarlier()) {
+  SimpleTest.waitForExplicitFinish();
+  SetupEMEPref(beginTest);
+} else {
+  todo(false, "Test disabled on this platform.");
+}
+</script>
+</pre>
+</body>
+</html>
--- a/dom/quota/QuotaManager.cpp
+++ b/dom/quota/QuotaManager.cpp
@@ -2521,45 +2521,40 @@ QuotaManager::UpdateOriginAccessTime(Per
 
     RefPtr<SaveOriginAccessTimeOp> op =
       new SaveOriginAccessTimeOp(aPersistenceType, aOrigin, timestamp);
 
     op->RunImmediately();
   }
 }
 
-// static
-PLDHashOperator
-QuotaManager::RemoveQuotaCallback(const nsACString& aKey,
-                                  nsAutoPtr<GroupInfoPair>& aValue,
-                                  void* aUserArg)
-{
-  NS_ASSERTION(!aKey.IsEmpty(), "Empty key!");
-  NS_ASSERTION(aValue, "Null pointer!");
-
-  RefPtr<GroupInfo> groupInfo =
-    aValue->LockedGetGroupInfo(PERSISTENCE_TYPE_TEMPORARY);
-  if (groupInfo) {
-    groupInfo->LockedRemoveOriginInfos();
-  }
-
-  groupInfo = aValue->LockedGetGroupInfo(PERSISTENCE_TYPE_DEFAULT);
-  if (groupInfo) {
-    groupInfo->LockedRemoveOriginInfos();
-  }
-
-  return PL_DHASH_REMOVE;
-}
-
 void
 QuotaManager::RemoveQuota()
 {
   MutexAutoLock lock(mQuotaMutex);
 
-  mGroupInfoPairs.Enumerate(RemoveQuotaCallback, nullptr);
+  for (auto iter = mGroupInfoPairs.Iter(); !iter.Done(); iter.Next()) {
+    nsAutoPtr<GroupInfoPair>& pair = iter.Data();
+
+    MOZ_ASSERT(!iter.Key().IsEmpty(), "Empty key!");
+    MOZ_ASSERT(pair, "Null pointer!");
+
+    RefPtr<GroupInfo> groupInfo =
+      pair->LockedGetGroupInfo(PERSISTENCE_TYPE_TEMPORARY);
+    if (groupInfo) {
+      groupInfo->LockedRemoveOriginInfos();
+    }
+
+    groupInfo = pair->LockedGetGroupInfo(PERSISTENCE_TYPE_DEFAULT);
+    if (groupInfo) {
+      groupInfo->LockedRemoveOriginInfos();
+    }
+
+    iter.Remove();
+  }
 
   NS_ASSERTION(mTemporaryStorageUsage == 0, "Should be zero!");
 }
 
 already_AddRefed<QuotaObject>
 QuotaManager::GetQuotaObject(PersistenceType aPersistenceType,
                              const nsACString& aGroup,
                              const nsACString& aOrigin,
--- a/dom/quota/QuotaManager.h
+++ b/dom/quota/QuotaManager.h
@@ -456,21 +456,16 @@ private:
   GetDirectoryLockTable(PersistenceType aPersistenceType);
 
   static void
   GetOriginPatternString(uint32_t aAppId,
                          MozBrowserPatternFlag aBrowserFlag,
                          const nsACString& aOrigin,
                          nsAutoCString& _retval);
 
-  static PLDHashOperator
-  RemoveQuotaCallback(const nsACString& aKey,
-                      nsAutoPtr<GroupInfoPair>& aValue,
-                      void* aUserArg);
-
   mozilla::Mutex mQuotaMutex;
 
   nsClassHashtable<nsCStringHashKey, GroupInfoPair> mGroupInfoPairs;
 
   // Maintains a list of directory locks that are queued.
   nsTArray<RefPtr<DirectoryLockImpl>> mPendingDirectoryLocks;
 
   // Maintains a list of directory locks that are acquired or queued.
--- a/dom/webidl/ThreadSafeChromeUtils.webidl
+++ b/dom/webidl/ThreadSafeChromeUtils.webidl
@@ -26,16 +26,28 @@ interface ThreadSafeChromeUtils {
 
   /**
    * Deserialize a core dump into a HeapSnapshot.
    *
    * @param filePath          The file path to read the heap snapshot from.
    */
   [Throws, NewObject]
   static HeapSnapshot readHeapSnapshot(DOMString filePath);
+
+  /**
+   * Return the keys in a weak map.  This operation is
+   * non-deterministic because it is affected by the scheduling of the
+   * garbage collector and the cycle collector.
+   *
+   * @param aMap weak map or other JavaScript value
+   * @returns If aMap is a weak map object, return the keys of the weak
+   *          map as an array.  Otherwise, return undefined.
+   */
+  [Throws, NewObject]
+  static any nondeterministicGetWeakMapKeys(any map);
 };
 
 /**
  * A JS object whose properties specify what portion of the heap graph to
  * write. The recognized properties are:
  *
  * * globals: [ global, ... ]
  *   Dump only nodes that either:
--- a/dom/workers/ServiceWorkerContainer.cpp
+++ b/dom/workers/ServiceWorkerContainer.cpp
@@ -153,22 +153,16 @@ ServiceWorkerContainer::Register(const n
     nsCOMPtr<nsPIDOMWindow> window = GetOwner();
     nsCOMPtr<nsPIDOMWindow> outerWindow;
     if (window && (outerWindow = window->GetOuterWindow()) &&
         outerWindow->GetServiceWorkersTestingEnabled()) {
       baseURI = window->GetDocBaseURI();
     }
   }
 
-
-  if (!baseURI) {
-    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
-    return nullptr;
-  }
-
   nsresult rv;
   nsCOMPtr<nsIURI> scriptURI;
   rv = NS_NewURI(getter_AddRefs(scriptURI), aScriptURL, nullptr, baseURI);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aRv.ThrowTypeError<MSG_INVALID_URL>(&aScriptURL);
     return nullptr;
   }
 
--- a/dom/workers/ServiceWorkerManager.cpp
+++ b/dom/workers/ServiceWorkerManager.cpp
@@ -431,16 +431,46 @@ NS_IMETHODIMP
 ServiceWorkerRegistrationInfo::GetActiveWorker(nsIServiceWorkerInfo **aResult)
 {
   AssertIsOnMainThread();
   nsCOMPtr<nsIServiceWorkerInfo> info = do_QueryInterface(mActiveWorker);
   info.forget(aResult);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+ServiceWorkerRegistrationInfo::AddListener(
+                            nsIServiceWorkerRegistrationInfoListener *aListener)
+{
+  AssertIsOnMainThread();
+
+  if (!aListener || mListeners.Contains(aListener)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  mListeners.AppendElement(aListener);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+ServiceWorkerRegistrationInfo::RemoveListener(
+                            nsIServiceWorkerRegistrationInfoListener *aListener)
+{
+  AssertIsOnMainThread();
+
+  if (!aListener || !mListeners.Contains(aListener)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  mListeners.RemoveElement(aListener);
+
+  return NS_OK;
+}
+
 already_AddRefed<ServiceWorkerInfo>
 ServiceWorkerRegistrationInfo::GetServiceWorkerInfoById(uint64_t aId)
 {
   RefPtr<ServiceWorkerInfo> serviceWorker;
   if (mInstallingWorker && mInstallingWorker->ID() == aId) {
     serviceWorker = mInstallingWorker;
   } else if (mWaitingWorker && mWaitingWorker->ID() == aId) {
     serviceWorker = mWaitingWorker;
@@ -965,16 +995,17 @@ public:
 
           return;
         }
       } else {
         mRegistration = swm->CreateNewRegistration(mScope, mPrincipal);
       }
 
       mRegistration->mScriptSpec = mScriptSpec;
+      mRegistration->NotifyListenersOnChange();
       swm->StoreRegistration(mPrincipal, mRegistration);
     } else {
       MOZ_ASSERT(mJobType == UPDATE_JOB);
     }
 
     Update();
   }
 
@@ -1157,16 +1188,17 @@ public:
       mRegistration->mInstallingWorker->WorkerPrivate()->TerminateWorker();
     }
 
     swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
                                                    WhichServiceWorker::INSTALLING_WORKER);
 
     mRegistration->mInstallingWorker = mUpdateAndInstallInfo.forget();
     mRegistration->mInstallingWorker->UpdateState(ServiceWorkerState::Installing);
+    mRegistration->NotifyListenersOnChange();
 
     Succeed();
     // The job should NOT call fail from this point on.
 
     // Step 4.6 "Queue a task..." for updatefound.
     nsCOMPtr<nsIRunnable> upr =
       NS_NewRunnableMethodWithArg<ServiceWorkerRegistrationInfo*>(
         swm,
@@ -1324,16 +1356,17 @@ private:
                                                          mRegistration->mWaitingWorker->CacheName());
       if (NS_FAILED(rv)) {
         NS_WARNING("Failed to purge the old waiting cache.");
       }
     }
 
     mRegistration->mWaitingWorker = mRegistration->mInstallingWorker.forget();
     mRegistration->mWaitingWorker->UpdateState(ServiceWorkerState::Installed);
+    mRegistration->NotifyListenersOnChange();
     swm->InvalidateServiceWorkerRegistrationWorker(mRegistration,
                                                    WhichServiceWorker::INSTALLING_WORKER | WhichServiceWorker::WAITING_WORKER);
 
     // "If registration's waiting worker's skip waiting flag is set"
     if (mRegistration->mWaitingWorker->SkipWaitingFlag()) {
       mRegistration->PurgeActiveWorker();
     }
 
@@ -1643,16 +1676,17 @@ ServiceWorkerRegistrationInfo::Activate(
   PurgeActiveWorker();
 
   RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
   swm->InvalidateServiceWorkerRegistrationWorker(this, WhichServiceWorker::WAITING_WORKER);
 
   mActiveWorker = activatingWorker.forget();
   mWaitingWorker = nullptr;
   mActiveWorker->UpdateState(ServiceWorkerState::Activating);
+  NotifyListenersOnChange();
 
   // FIXME(nsm): Unlink appcache if there is one.
 
   swm->CheckPendingReadyPromises();
 
   // "Queue a task to fire a simple event named controllerchange..."
   nsCOMPtr<nsIRunnable> controllerChangeRunnable =
     NS_NewRunnableMethodWithArg<ServiceWorkerRegistrationInfo*>(swm,
@@ -2458,16 +2492,25 @@ ServiceWorkerRegistrationInfo::IsLastUpd
   if ((mLastUpdateCheckTime != 0) &&
       (now - mLastUpdateCheckTime > kSecondsPerDay)) {
     return true;
   }
   return false;
 }
 
 void
+ServiceWorkerRegistrationInfo::NotifyListenersOnChange()
+{
+  nsTArray<nsCOMPtr<nsIServiceWorkerRegistrationInfoListener>> listeners(mListeners);
+  for (size_t index = 0; index < listeners.Length(); ++index) {
+    listeners[index]->OnChange();
+  }
+}
+
+void
 ServiceWorkerManager::LoadRegistration(
                              const ServiceWorkerRegistrationData& aRegistration)
 {
   AssertIsOnMainThread();
 
   nsCOMPtr<nsIPrincipal> principal =
     PrincipalInfoToPrincipal(aRegistration.principal());
   if (!principal) {
@@ -3878,31 +3921,31 @@ ServiceWorkerManager::RemoveAllRegistrat
   }
 }
 
 NS_IMETHODIMP
 ServiceWorkerManager::AddListener(nsIServiceWorkerManagerListener* aListener)
 {
   AssertIsOnMainThread();
 
-  if (mListeners.Contains(aListener)) {
+  if (!aListener || mListeners.Contains(aListener)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   mListeners.AppendElement(aListener);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 ServiceWorkerManager::RemoveListener(nsIServiceWorkerManagerListener* aListener)
 {
   AssertIsOnMainThread();
 
-  if (!mListeners.Contains(aListener)) {
+  if (!aListener || !mListeners.Contains(aListener)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   mListeners.RemoveElement(aListener);
 
   return NS_OK;
 }
 
--- a/dom/workers/ServiceWorkerManager.h
+++ b/dom/workers/ServiceWorkerManager.h
@@ -67,16 +67,18 @@ public:
   nsCString mScriptSpec;
 
   nsCOMPtr<nsIPrincipal> mPrincipal;
 
   RefPtr<ServiceWorkerInfo> mActiveWorker;
   RefPtr<ServiceWorkerInfo> mWaitingWorker;
   RefPtr<ServiceWorkerInfo> mInstallingWorker;
 
+  nsTArray<nsCOMPtr<nsIServiceWorkerRegistrationInfoListener>> mListeners;
+
   uint64_t mLastUpdateCheckTime;
 
   // When unregister() is called on a registration, it is not immediately
   // removed since documents may be controlled. It is marked as
   // pendingUninstall and when all controlling documents go away, removed.
   bool mPendingUninstall;
 
   ServiceWorkerRegistrationInfo(const nsACString& aScope,
@@ -133,16 +135,19 @@ public:
   void
   FinishActivate(bool aSuccess);
 
   void
   RefreshLastUpdateCheckTime();
 
   bool
   IsLastUpdateCheckTimeOverOneDay() const;
+
+  void
+  NotifyListenersOnChange();
 };
 
 class ServiceWorkerUpdateFinishCallback
 {
 protected:
   virtual ~ServiceWorkerUpdateFinishCallback()
   { }
 
--- a/dom/workers/test/serviceworkers/chrome.ini
+++ b/dom/workers/test/serviceworkers/chrome.ini
@@ -1,13 +1,17 @@
 [DEFAULT]
 skip-if = buildapp == 'b2g' || os == 'android'
 support-files =
   app/*
   app2/*
+  chrome_helpers.js
   serviceworkermanager_iframe.html
+  serviceworkerregistrationinfo_iframe.html
   worker.js
+  worker2.js
 
 [test_aboutserviceworkers.html]
 skip-if = true #bug 1193319
 [test_app_installation.html]
 [test_privateBrowsing.html]
 [test_serviceworkermanager.xul]
+[test_serviceworkerregistrationinfo.xul]
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/serviceworkers/chrome_helpers.js
@@ -0,0 +1,59 @@
+let { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+
+Cu.import("resource://gre/modules/Task.jsm");
+
+let swm = Cc["@mozilla.org/serviceworkers/manager;1"].
+          getService(Ci.nsIServiceWorkerManager);
+
+let EXAMPLE_URL = "https://example.com/chrome/dom/workers/test/serviceworkers/";
+
+function waitForIframeLoad(iframe) {
+  return new Promise(function (resolve) {
+    iframe.onload = resolve;
+  });
+}
+
+function waitForRegister(scope, callback) {
+  return new Promise(function (resolve) {
+    let listener = {
+      onRegister: function (registration) {
+        if (registration.scope !== scope) {
+          return;
+        }
+        swm.removeListener(listener);
+        resolve(callback ? callback(registration) : registration);
+      }
+    };
+    swm.addListener(listener);
+  });
+}
+
+function waitForUnregister(scope) {
+  return new Promise(function (resolve) {
+    let listener = {
+      onUnregister: function (registration) {
+        if (registration.scope !== scope) {
+          return;
+        }
+        swm.removeListener(listener);
+        resolve(registration);
+      }
+    };
+    swm.addListener(listener);
+  });
+}
+
+function waitForServiceWorkerRegistrationChange(registration, callback) {
+  return new Promise(function (resolve) {
+    let listener = {
+      onChange: function () {
+        registration.removeListener(listener);
+        if (callback) {
+          callback();
+        }
+        resolve(callback ? callback() : undefined);
+      }
+    };
+    registration.addListener(listener);
+  });
+}
--- a/dom/workers/test/serviceworkers/serviceworkermanager_iframe.html
+++ b/dom/workers/test/serviceworkers/serviceworkermanager_iframe.html
@@ -4,23 +4,31 @@
     <meta charset="utf-8">
     <script>
       window.onmessage = function (event) {
         if (event.data !== "register") {
           return;
         }
         var promise = navigator.serviceWorker.register("worker.js");
         window.onmessage = function (event) {
-          if (event.data !== "unregister") {
+          if (event.data !== "register") {
             return;
           }
-          promise.then(function (registration) {
-            registration.unregister();
+          promise = promise.then(function (registration) {
+            return navigator.serviceWorker.register("worker2.js");
           });
-          window.onmessage = null;
+          window.onmessage = function (event) {
+            if (event.data !== "unregister") {
+              return;
+            }
+            promise.then(function (registration) {
+              registration.unregister();
+            });
+            window.onmessage = null;
+          };
         };
       };
     </script>
   </head>
   <body>
     This is a test page.
   </body>
 <html>
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/serviceworkers/serviceworkerregistrationinfo_iframe.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <script>
+      window.onmessage = function (event) {
+        if (event.data !== "register") {
+          return;
+        }
+        var promise = navigator.serviceWorker.register("worker.js");
+        window.onmessage = function (event) {
+          if (event.data !== "register") {
+            return;
+          }
+          promise.then(function (registration) {
+            return navigator.serviceWorker.register("worker2.js");
+          });
+        };
+      };
+    </script>
+  </head>
+  <body>
+    This is a test page.
+  </body>
+<html>
--- a/dom/workers/test/serviceworkers/test_serviceworkermanager.xul
+++ b/dom/workers/test/serviceworkers/test_serviceworkermanager.xul
@@ -3,73 +3,30 @@
   Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/
 -->
 <window title="Test for ServiceWorkerManager"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         onload="test();">
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+  <script type="application/javascript" src="chrome_helpers.js"/>
   <script type="application/javascript">
   <![CDATA[
 
-    let { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-    Cu.import("resource://gre/modules/Task.jsm");
-
-    let swm = Cc["@mozilla.org/serviceworkers/manager;1"].
-              getService(Ci.nsIServiceWorkerManager);
-
-    function waitForIframeLoad(iframe) {
-      return new Promise(function (resolve) {
-        iframe.onload = resolve;
-      });
-    }
-
-    function waitForRegister(scope) {
-      return new Promise(function (resolve) {
-        let listener = {
-          onRegister: function (registration) {
-            if (registration.scope !== scope) {
-              return;
-            }
-            swm.removeListener(listener);
-            resolve(registration);
-          }
-        };
-        swm.addListener(listener);
-      });
-    }
-
-    function waitForUnregister(scope) {
-      return new Promise(function (resolve) {
-        let listener = {
-          onUnregister: function (registration) {
-            if (registration.scope !== scope) {
-              return;
-            }
-            swm.removeListener(listener);
-            resolve(registration);
-          }
-        };
-        swm.addListener(listener);
-      });
-    }
-
-    let EXAMPLE_URL = "https://example.com/chrome/dom/workers/test/serviceworkers/";
     let IFRAME_URL = EXAMPLE_URL + "serviceworkermanager_iframe.html";
 
     function test() {
       SimpleTest.waitForExplicitFinish();
 
       SpecialPowers.pushPrefEnv({'set': [
         ["dom.serviceWorkers.enabled", true],
         ["dom.serviceWorkers.testing.enabled", true],
       ]}, function () {
-        Task.spawn(function *() {
+        Task.spawn(function* () {
           let registrations = swm.getAllRegistrations();
           is(registrations.length, 0);
 
           let iframe = $("iframe");
           let promise = waitForIframeLoad(iframe);
           iframe.src = IFRAME_URL;
           yield promise;
 
@@ -79,21 +36,33 @@
           iframe.contentWindow.postMessage("register", "*");
           let registration = yield promise;
 
           registrations = swm.getAllRegistrations();
           is(registrations.length, 1);
           is(registrations.queryElementAt(0, Ci.nsIServiceWorkerRegistrationInfo),
              registration);
 
+          info("Check that the service worker manager does not notify its " +
+               "listeners when a service worker is registered with the same " +
+               "scope as an existing registration.");
+          let listener = {
+            onRegister: function () {
+              ok(false, "Listener should not have been notified.");
+            }
+          };
+          swm.addListener(listener);
+          iframe.contentWindow.postMessage("register", "*");
+
           info("Check that the service worker manager notifies its listeners " +
                "when a service worker is unregistered.");
           promise = waitForUnregister(EXAMPLE_URL);
           iframe.contentWindow.postMessage("unregister", "*");
           registration = yield promise;
+          swm.removeListener(listener);
 
           registrations = swm.getAllRegistrations();
           is(registrations.length, 0);
 
           SimpleTest.finish();
         });
       }); 
     }
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/serviceworkers/test_serviceworkerregistrationinfo.xul
@@ -0,0 +1,117 @@
+<?xml version="1.0"?>
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<window title="Test for ServiceWorkerRegistrationInfo"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        onload="test();">
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+  <script type="application/javascript" src="chrome_helpers.js"/>
+  <script type="application/javascript">
+  <![CDATA[
+
+    let IFRAME_URL = EXAMPLE_URL + "serviceworkerregistrationinfo_iframe.html";
+
+    function test() {
+      SimpleTest.waitForExplicitFinish();
+
+      SpecialPowers.pushPrefEnv({'set': [
+        ["dom.serviceWorkers.enabled", true],
+        ["dom.serviceWorkers.testing.enabled", true],
+      ]}, function () {
+        Task.spawn(function* () {
+          let iframe = $("iframe");
+          let promise = waitForIframeLoad(iframe);
+          iframe.src = IFRAME_URL;
+          yield promise;
+
+          // The change handler is not guaranteed to be called within the same
+          // tick of the event loop as the one in which the change happened.
+          // Because of this, the exact state of the service worker registration
+          // is only known until the handler returns.
+          //
+          // Because then-handlers are resolved asynchronously, the following
+          // checks are done using callbacks, which are called synchronously
+          // when then handler is called. These callbacks can return a promise,
+          // which is used to resolve the promise returned by the function.
+
+          info("Check that a service worker registration notifies its " +
+               "listeners when its state changes.");
+          promise = waitForRegister(EXAMPLE_URL, function (registration) {
+            is(registration.scriptSpec, "");
+            ok(registration.installingWorker === null);
+            ok(registration.waitingWorker === null);
+            ok(registration.activeWorker === null);
+
+            return waitForServiceWorkerRegistrationChange(registration, function  () {
+              is(registration.scriptSpec, EXAMPLE_URL + "worker.js");
+
+              return waitForServiceWorkerRegistrationChange(registration, function () {
+                ok(registration.installingWorker !== null);
+                ok(registration.waitingWorker === null);
+                ok(registration.activeWorker === null);
+
+                return waitForServiceWorkerRegistrationChange(registration, function () {
+                  ok(registration.installingWorker === null);
+                  ok(registration.waitingWorker !== null);
+                  ok(registration.activeWorker === null);
+
+                  return waitForServiceWorkerRegistrationChange(registration, function () {
+                    ok(registration.installingWorker === null);
+                    ok(registration.waitingWorker === null);
+                    ok(registration.activeWorker !== null);
+
+                    return registration;
+                  });
+                });
+              });
+            });
+          });
+          iframe.contentWindow.postMessage("register", "*");
+          let registration = yield promise;
+
+          promise = waitForServiceWorkerRegistrationChange(registration, function () {
+            is(registration.scriptSpec, EXAMPLE_URL + "worker2.js");
+
+            return waitForServiceWorkerRegistrationChange(registration, function () {
+              ok(registration.installingWorker !== null);
+              ok(registration.waitingWorker === null);
+              ok(registration.activeWorker !== null);
+
+              return waitForServiceWorkerRegistrationChange(registration, function () {
+                ok(registration.installingWorker === null);
+                ok(registration.waitingWorker !== null);
+                ok(registration.activeWorker !== null);
+
+                return waitForServiceWorkerRegistrationChange(registration, function () {
+                  ok(registration.installingWorker === null);
+                  ok(registration.waitingWorker === null);
+                  ok(registration.activeWorker !== null);
+
+                  return registration;
+                });
+              });
+
+            });
+          });
+          iframe.contentWindow.postMessage("register", "*");
+          yield promise;
+
+          SimpleTest.finish();
+        });
+      });
+    }
+
+  ]]>
+  </script>
+
+  <body xmlns="http://www.w3.org/1999/xhtml">
+    <p id="display"></p>
+    <div id="content" style="display:none;"></div>
+    <pre id="test"></pre>
+    <iframe id="iframe"></iframe>
+  </body>
+  <label id="test-result"/>
+</window>
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -2002,31 +2002,31 @@ nsXULElement::UpdateBrightTitlebarForegr
 }
 
 class MarginSetter : public nsRunnable
 {
 public:
     explicit MarginSetter(nsIWidget* aWidget) :
         mWidget(aWidget), mMargin(-1, -1, -1, -1)
     {}
-    MarginSetter(nsIWidget *aWidget, const nsIntMargin& aMargin) :
+    MarginSetter(nsIWidget *aWidget, const LayoutDeviceIntMargin& aMargin) :
         mWidget(aWidget), mMargin(aMargin)
     {}
 
     NS_IMETHOD Run()
     {
         // SetNonClientMargins can dispatch native events, hence doing
         // it off a script runner.
         mWidget->SetNonClientMargins(mMargin);
         return NS_OK;
     }
 
 private:
     nsCOMPtr<nsIWidget> mWidget;
-    nsIntMargin mMargin;
+    LayoutDeviceIntMargin mMargin;
 };
 
 void
 nsXULElement::SetChromeMargins(const nsAttrValue* aValue)
 {
     if (!aValue)
         return;
 
@@ -2041,17 +2041,19 @@ nsXULElement::SetChromeMargins(const nsA
     if (aValue->Type() == nsAttrValue::eIntMarginValue) {
         gotMargins = aValue->GetIntMarginValue(margins);
     } else {
         nsAutoString tmp;
         aValue->ToString(tmp);
         gotMargins = nsContentUtils::ParseIntMarginValue(tmp, margins);
     }
     if (gotMargins) {
-        nsContentUtils::AddScriptRunner(new MarginSetter(mainWidget, margins));
+        nsContentUtils::AddScriptRunner(
+            new MarginSetter(
+                mainWidget, LayoutDeviceIntMargin::FromUnknownMargin(margins)));
     }
 }
 
 void
 nsXULElement::ResetChromeMargins()
 {
     nsIWidget* mainWidget = GetWindowWidget();
     if (!mainWidget)
--- a/gfx/2d/Rect.h
+++ b/gfx/2d/Rect.h
@@ -27,16 +27,29 @@ struct IntMarginTyped:
     static_assert(IsPixel<units>::value,
                   "'units' must be a coordinate system tag");
 
     typedef BaseMargin<int32_t, IntMarginTyped<units> > Super;
 
     IntMarginTyped() : Super() {}
     IntMarginTyped(int32_t aTop, int32_t aRight, int32_t aBottom, int32_t aLeft) :
         Super(aTop, aRight, aBottom, aLeft) {}
+
+    // XXX When all of the code is ported, the following functions to convert
+    // to and from unknown types should be removed.
+
+    static IntMarginTyped<units> FromUnknownMargin(const IntMarginTyped<UnknownUnits>& aMargin) {
+        return IntMarginTyped<units>(aMargin.top, aMargin.right,
+                                     aMargin.bottom, aMargin.left);
+    }
+
+    IntMarginTyped<UnknownUnits> ToUnknownMargin() const {
+        return IntMarginTyped<UnknownUnits>(this->top, this->right,
+                                            this->bottom, this->left);
+    }
 };
 typedef IntMarginTyped<UnknownUnits> IntMargin;
 
 template<class units, class F = Float>
 struct MarginTyped:
     public BaseMargin<F, MarginTyped<units> >,
     public units {
     static_assert(IsPixel<units>::value,
@@ -78,18 +91,18 @@ struct IntRectTyped :
     IntRectTyped(int32_t _x, int32_t _y, int32_t _width, int32_t _height) :
         Super(_x, _y, _width, _height) {}
 
     // Rounding isn't meaningful on an integer rectangle.
     void Round() {}
     void RoundIn() {}
     void RoundOut() {}
 
-    // XXX When all of the code is ported, the following functions to convert to and from
-    // unknown types should be removed.
+    // XXX When all of the code is ported, the following functions to convert
+    // to and from unknown types should be removed.
 
     static IntRectTyped<units> FromUnknownRect(const IntRectTyped<UnknownUnits>& rect) {
         return IntRectTyped<units>(rect.x, rect.y, rect.width, rect.height);
     }
 
     IntRectTyped<UnknownUnits> ToUnknownRect() const {
         return IntRectTyped<UnknownUnits>(this->x, this->y, this->width, this->height);
     }
--- a/gfx/gl/GLBlitHelper.cpp
+++ b/gfx/gl/GLBlitHelper.cpp
@@ -7,16 +7,17 @@
 #include "GLBlitHelper.h"
 #include "GLContext.h"
 #include "GLScreenBuffer.h"
 #include "ScopedGLHelpers.h"
 #include "mozilla/Preferences.h"
 #include "ImageContainer.h"
 #include "HeapCopyOfStackArray.h"
 #include "mozilla/gfx/Matrix.h"
+#include "mozilla/UniquePtr.h"
 
 #ifdef MOZ_WIDGET_GONK
 #include "GrallocImages.h"
 #include "GLLibraryEGL.h"
 #endif
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidSurfaceTexture.h"
@@ -325,18 +326,18 @@ GLBlitHelper::InitTexQuadProgram(BlitTyp
 
                 GLint length = 0;
                 mGL->fGetShaderiv(mTexBlit_VertShader, LOCAL_GL_INFO_LOG_LENGTH, &length);
                 if (!length) {
                     printf_stderr("No shader info log available.\n");
                     break;
                 }
 
-                nsAutoArrayPtr<char> buffer(new char[length]);
-                mGL->fGetShaderInfoLog(mTexBlit_VertShader, length, nullptr, buffer);
+                auto buffer = MakeUnique<char[]>(length);
+                mGL->fGetShaderInfoLog(mTexBlit_VertShader, length, nullptr, buffer.get());
 
                 printf_stderr("Shader info log (%d bytes): %s\n", length, buffer.get());
                 break;
             }
 
             status = 0;
             mGL->fGetShaderiv(fragShader, LOCAL_GL_COMPILE_STATUS, &status);
             if (status != LOCAL_GL_TRUE) {
@@ -344,18 +345,18 @@ GLBlitHelper::InitTexQuadProgram(BlitTyp
 
                 GLint length = 0;
                 mGL->fGetShaderiv(fragShader, LOCAL_GL_INFO_LOG_LENGTH, &length);
                 if (!length) {
                     printf_stderr("No shader info log available.\n");
                     break;
                 }
 
-                nsAutoArrayPtr<char> buffer(new char[length]);
-                mGL->fGetShaderInfoLog(fragShader, length, nullptr, buffer);
+                auto buffer = MakeUnique<char[]>(length);
+                mGL->fGetShaderInfoLog(fragShader, length, nullptr, buffer.get());
 
                 printf_stderr("Shader info log (%d bytes): %s\n", length, buffer.get());
                 break;
             }
         }
 
         GLint status = 0;
         mGL->fGetProgramiv(program, LOCAL_GL_LINK_STATUS, &status);
@@ -364,18 +365,18 @@ GLBlitHelper::InitTexQuadProgram(BlitTyp
                 NS_ERROR("Linking blit program failed.");
                 GLint length = 0;
                 mGL->fGetProgramiv(program, LOCAL_GL_INFO_LOG_LENGTH, &length);
                 if (!length) {
                     printf_stderr("No program info log available.\n");
                     break;
                 }
 
-                nsAutoArrayPtr<char> buffer(new char[length]);
-                mGL->fGetProgramInfoLog(program, length, nullptr, buffer);
+                auto buffer = MakeUnique<char[]>(length);
+                mGL->fGetProgramInfoLog(program, length, nullptr, buffer.get());
 
                 printf_stderr("Program info log (%d bytes): %s\n", length, buffer.get());
             }
             break;
         }
 
         // Cache and set attribute and uniform
         mGL->fUseProgram(program);
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -111,37 +111,37 @@ ImageFactory::CreateImage(ImageFormat aF
 }
 
 BufferRecycleBin::BufferRecycleBin()
   : mLock("mozilla.layers.BufferRecycleBin.mLock")
 {
 }
 
 void
-BufferRecycleBin::RecycleBuffer(uint8_t* aBuffer, uint32_t aSize)
+BufferRecycleBin::RecycleBuffer(UniquePtr<uint8_t[]> aBuffer, uint32_t aSize)
 {
   MutexAutoLock lock(mLock);
 
   if (!mRecycledBuffers.IsEmpty() && aSize != mRecycledBufferSize) {
     mRecycledBuffers.Clear();
   }
   mRecycledBufferSize = aSize;
-  mRecycledBuffers.AppendElement(aBuffer);
+  mRecycledBuffers.AppendElement(Move(aBuffer));
 }
 
-uint8_t*
+UniquePtr<uint8_t[]>
 BufferRecycleBin::GetBuffer(uint32_t aSize)
 {
   MutexAutoLock lock(mLock);
 
   if (mRecycledBuffers.IsEmpty() || mRecycledBufferSize != aSize)
-    return new uint8_t[aSize];
+    return MakeUnique<uint8_t[]>(aSize);
 
   uint32_t last = mRecycledBuffers.Length() - 1;
-  uint8_t* result = mRecycledBuffers[last].forget();
+  UniquePtr<uint8_t[]> result = Move(mRecycledBuffers[last]);
   mRecycledBuffers.RemoveElementAt(last);
   return result;
 }
 
 /**
  * The child side of PImageContainer. It's best to avoid ImageContainer filling
  * this role since IPDL objects should be associated with a single thread and
  * ImageContainer definitely isn't. This object belongs to (and is always
@@ -434,40 +434,40 @@ PlanarYCbCrImage::PlanarYCbCrImage()
   , mOffscreenFormat(gfxImageFormat::Unknown)
   , mBufferSize(0)
 {
 }
 
 RecyclingPlanarYCbCrImage::~RecyclingPlanarYCbCrImage()
 {
   if (mBuffer) {
-    mRecycleBin->RecycleBuffer(mBuffer.forget(), mBufferSize);
+    mRecycleBin->RecycleBuffer(Move(mBuffer), mBufferSize);
   }
 }
 
 size_t
 RecyclingPlanarYCbCrImage::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
 {
   // Ignoring:
   // - mData - just wraps mBuffer
   // - Surfaces should be reported under gfx-surfaces-*:
   //   - mSourceSurface
   // - Base class:
   //   - mImplData is not used
   // Not owned:
   // - mRecycleBin
-  size_t size = mBuffer.SizeOfExcludingThis(aMallocSizeOf);
+  size_t size = aMallocSizeOf(mBuffer.get());
 
   // Could add in the future:
   // - mBackendData (from base class)
 
   return size;
 }
 
-uint8_t*
+UniquePtr<uint8_t[]>
 RecyclingPlanarYCbCrImage::AllocateBuffer(uint32_t aSize)
 {
   return mRecycleBin->GetBuffer(aSize);
 }
 
 static void
 CopyPlane(uint8_t *aDst, const uint8_t *aSrc,
           const gfx::IntSize &aSize, int32_t aStride, int32_t aSkip)
@@ -504,17 +504,17 @@ RecyclingPlanarYCbCrImage::CopyData(cons
   // get new buffer
   mBuffer = AllocateBuffer(size);
   if (!mBuffer)
     return false;
 
   // update buffer size
   mBufferSize = size;
 
-  mData.mYChannel = mBuffer;
+  mData.mYChannel = mBuffer.get();
   mData.mCbChannel = mData.mYChannel + mData.mYStride * mData.mYSize.height;
   mData.mCrChannel = mData.mCbChannel + mData.mCbCrStride * mData.mCbCrSize.height;
 
   CopyPlane(mData.mYChannel, aData.mYChannel,
             mData.mYSize, mData.mYStride, mData.mYSkip);
   CopyPlane(mData.mCbChannel, aData.mCbChannel,
             mData.mCbCrSize, mData.mCbCrStride, mData.mCbSkip);
   CopyPlane(mData.mCrChannel, aData.mCrChannel,
@@ -550,17 +550,17 @@ uint8_t*
 RecyclingPlanarYCbCrImage::AllocateAndGetNewBuffer(uint32_t aSize)
 {
   // get new buffer
   mBuffer = AllocateBuffer(aSize);
   if (mBuffer) {
     // update buffer size
     mBufferSize = aSize;
   }
-  return mBuffer;
+  return mBuffer.get();
 }
 
 already_AddRefed<gfx::SourceSurface>
 PlanarYCbCrImage::GetAsSourceSurface()
 {
   if (mSourceSurface) {
     RefPtr<gfx::SourceSurface> surface(mSourceSurface);
     return surface.forget();
--- a/gfx/layers/ImageContainer.h
+++ b/gfx/layers/ImageContainer.h
@@ -25,16 +25,17 @@
 #include "nsRect.h"                     // for mozilla::gfx::IntRect
 #include "nsTArray.h"                   // for nsTArray
 #include "mozilla/Atomics.h"
 #include "mozilla/WeakPtr.h"
 #include "nsThreadUtils.h"
 #include "mozilla/gfx/2D.h"
 #include "nsDataHashtable.h"
 #include "mozilla/EnumeratedArray.h"
+#include "mozilla/UniquePtr.h"
 
 #ifndef XPCOM_GLUE_AVOID_NSPR
 /**
  * We need to be able to hold a reference to a Moz2D SourceSurface from Image
  * subclasses. This is potentially a problem since Images can be addrefed
  * or released off the main thread. We can ensure that we never AddRef
  * a SourceSurface off the main thread, but we might want to Release due
  * to an Image being destroyed off the main thread.
@@ -198,35 +199,35 @@ protected:
 class BufferRecycleBin final {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BufferRecycleBin)
 
   //typedef mozilla::gl::GLContext GLContext;
 
 public:
   BufferRecycleBin();
 
-  void RecycleBuffer(uint8_t* aBuffer, uint32_t aSize);
+  void RecycleBuffer(mozilla::UniquePtr<uint8_t[]> aBuffer, uint32_t aSize);
   // Returns a recycled buffer of the right size, or allocates a new buffer.
-  uint8_t* GetBuffer(uint32_t aSize);
+  mozilla::UniquePtr<uint8_t[]> GetBuffer(uint32_t aSize);
 
 private:
   typedef mozilla::Mutex Mutex;
 
   // Private destructor, to discourage deletion outside of Release():
   ~BufferRecycleBin()
   {
   }
 
   // This protects mRecycledBuffers, mRecycledBufferSize, mRecycledTextures
   // and mRecycledTextureSizes
   Mutex mLock;
 
   // We should probably do something to prune this list on a timer so we don't
   // eat excess memory while video is paused...
-  nsTArray<nsAutoArrayPtr<uint8_t> > mRecycledBuffers;
+  nsTArray<mozilla::UniquePtr<uint8_t[]>> mRecycledBuffers;
   // This is only valid if mRecycledBuffers is non-empty
   uint32_t mRecycledBufferSize;
 };
 
 /**
  * A class that manages Image creation for a LayerManager. The only reason
  * we need a separate class here is that LayerManagers aren't threadsafe
  * (because layers can only be used on the main thread) and we want to
@@ -728,23 +729,21 @@ protected:
    * Make a copy of the YCbCr data into local storage.
    *
    * @param aData           Input image data.
    */
   bool CopyData(const Data& aData);
 
   /**
    * Return a buffer to store image data in.
-   * The default implementation returns memory that can
-   * be freed wit delete[]
    */
-  uint8_t* AllocateBuffer(uint32_t aSize);
+  mozilla::UniquePtr<uint8_t[]> AllocateBuffer(uint32_t aSize);
 
   RefPtr<BufferRecycleBin> mRecycleBin;
-  nsAutoArrayPtr<uint8_t> mBuffer;
+  mozilla::UniquePtr<uint8_t[]> mBuffer;
 };
 
 /**
  * Currently, the data in a CairoImage surface is treated as being in the
  * device output color space. This class is very simple as all backends
  * have to know about how to deal with drawing a cairo image.
  */
 class CairoImage final : public Image {
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -1909,18 +1909,19 @@ Layer::PrintInfo(std::stringstream& aStr
   if (GetScrollbarDirection() == VERTICAL) {
     aStream << nsPrintfCString(" [vscrollbar=%lld]", GetScrollbarTargetContainerId()).get();
   }
   if (GetScrollbarDirection() == HORIZONTAL) {
     aStream << nsPrintfCString(" [hscrollbar=%lld]", GetScrollbarTargetContainerId()).get();
   }
   if (GetIsFixedPosition()) {
     LayerPoint anchor = GetFixedPositionAnchor();
-    aStream << nsPrintfCString(" [isFixedPosition scrollId=%lld anchor=%s%s]",
+    aStream << nsPrintfCString(" [isFixedPosition scrollId=%lld sides=0x%x anchor=%s%s]",
                      GetFixedPositionScrollContainerId(),
+                     GetFixedPositionSides(),
                      ToString(anchor).c_str(),
                      IsClipFixed() ? "" : " scrollingClip").get();
   }
   if (GetIsStickyPosition()) {
     aStream << nsPrintfCString(" [isStickyPosition scrollId=%d outer=%f,%f %fx%f "
                      "inner=%f,%f %fx%f]", mStickyPositionData->mScrollId,
                      mStickyPositionData->mOuter.x, mStickyPositionData->mOuter.y,
                      mStickyPositionData->mOuter.width, mStickyPositionData->mOuter.height,
--- a/gfx/layers/MacIOSurfaceImage.cpp
+++ b/gfx/layers/MacIOSurfaceImage.cpp
@@ -2,16 +2,17 @@
  * 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 "MacIOSurfaceImage.h"
 #include "mozilla/layers/CompositableClient.h"
 #include "mozilla/layers/CompositableForwarder.h"
 #include "mozilla/layers/MacIOSurfaceTextureClientOGL.h"
+#include "mozilla/UniquePtr.h"
 #include "YCbCrUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::gfx;
 
 TextureClient*
 MacIOSurfaceImage::GetTextureClient(CompositableClient* aClient)
@@ -50,22 +51,22 @@ MacIOSurfaceImage::GetAsSourceSurface()
       return nullptr;
     }
 
     /* Extract and separate the CbCr planes */
     size_t cbCrStride = mSurface->GetBytesPerRow(1);
     size_t cbCrWidth = mSurface->GetDevicePixelWidth(1);
     size_t cbCrHeight = mSurface->GetDevicePixelHeight(1);
 
-    nsAutoArrayPtr<uint8_t> cbPlane(new uint8_t[cbCrWidth * cbCrHeight]);
-    nsAutoArrayPtr<uint8_t> crPlane(new uint8_t[cbCrWidth * cbCrHeight]);
+    auto cbPlane = MakeUnique<uint8_t[]>(cbCrWidth * cbCrHeight);
+    auto crPlane = MakeUnique<uint8_t[]>(cbCrWidth * cbCrHeight);
 
     uint8_t* src = (uint8_t*)mSurface->GetBaseAddressOfPlane(1);
-    uint8_t* cbDest = cbPlane;
-    uint8_t* crDest = crPlane;
+    uint8_t* cbDest = cbPlane.get();
+    uint8_t* crDest = crPlane.get();
 
     for (size_t i = 0; i < cbCrHeight; i++) {
       uint8_t* rowSrc = src + cbCrStride * i;
       for (size_t j = 0; j < cbCrWidth; j++) {
         *cbDest = *rowSrc;
         cbDest++;
         rowSrc++;
         *crDest = *rowSrc;
@@ -74,18 +75,18 @@ MacIOSurfaceImage::GetAsSourceSurface()
       }
     }
 
     /* Convert to RGB */
     PlanarYCbCrData data;
     data.mYChannel = (uint8_t*)mSurface->GetBaseAddressOfPlane(0);
     data.mYStride = mSurface->GetBytesPerRow(0);
     data.mYSize = IntSize(mSurface->GetDevicePixelWidth(0), mSurface->GetDevicePixelHeight(0));
-    data.mCbChannel = cbPlane;
-    data.mCrChannel = crPlane;
+    data.mCbChannel = cbPlane.get();
+    data.mCrChannel = crPlane.get();
     data.mCbCrStride = cbCrWidth;
     data.mCbCrSize = IntSize(cbCrWidth, cbCrHeight);
     data.mPicSize = data.mYSize;
 
     ConvertYCbCrToRGB(data, SurfaceFormat::B8G8R8X8, IntSize(ioWidth, ioHeight), mappedSurface.mData, mappedSurface.mStride);
   } else {
     unsigned char* ioData = (unsigned char*)mSurface->GetBaseAddress();
 
--- a/gfx/layers/apz/util/APZEventState.cpp
+++ b/gfx/layers/apz/util/APZEventState.cpp
@@ -226,19 +226,22 @@ APZEventState::ProcessLongTap(const nsCO
   // including in JS code, so it's not trivial to change.
   bool eventHandled =
       APZCCallbackHelper::DispatchMouseEvent(aPresShell, NS_LITERAL_STRING("contextmenu"),
                          APZCCallbackHelper::ApplyCallbackTransform(aPoint, aGuid),
                          2, 1, WidgetModifiersToDOMModifiers(aModifiers), true,
                          nsIDOMMouseEvent::MOZ_SOURCE_TOUCH);
 
   APZES_LOG("Contextmenu event handled: %d\n", eventHandled);
-
-  // If no one handle context menu, fire MOZLONGTAP event
-  if (!eventHandled) {
+  if (eventHandled) {
+    // If the contextmenu event was handled then we're showing a contextmenu,
+    // and so we should remove any activation
+    mActiveElementManager->ClearActivation();
+  } else {
+    // If no one handle context menu, fire MOZLONGTAP event
     LayoutDevicePoint currentPoint =
         APZCCallbackHelper::ApplyCallbackTransform(aPoint, aGuid)
       * widget->GetDefaultScale();
     int time = 0;
     nsEventStatus status =
         APZCCallbackHelper::DispatchSynthesizedMouseEvent(eMouseLongTap, time,
                                                           currentPoint,
                                                           aModifiers, widget);
@@ -402,32 +405,44 @@ APZEventState::ProcessAPZStateChange(con
   }
   case APZStateChange::StartTouch:
   {
     mActiveElementManager->HandleTouchStart(aArg);
     break;
   }
   case APZStateChange::StartPanning:
   {
-    mActiveElementManager->HandlePanStart();
+    // The user started to pan, so we don't want anything to be :active.
+    mActiveElementManager->ClearActivation();
     break;
   }
   case APZStateChange::EndTouch:
   {
     mEndTouchIsClick = aArg;
     mActiveElementManager->HandleTouchEnd();
     break;
   }
   default:
     // APZStateChange has a 'sentinel' value, and the compiler complains
     // if an enumerator is not handled and there is no 'default' case.
     break;
   }
 }
 
+void
+APZEventState::ProcessClusterHit()
+{
+  // If we hit a cluster of links then we shouldn't activate any of them,
+  // as we will be showing the zoomed view. (This is only called on Fennec).
+#ifndef MOZ_ANDROID_APZ
+  MOZ_ASSERT(false);
+#endif
+  mActiveElementManager->ClearActivation();
+}
+
 bool
 APZEventState::SendPendingTouchPreventedResponse(bool aPreventDefault)
 {
   if (mPendingTouchPreventedResponse) {
     APZES_LOG("Sending response %d for pending guid: %s\n", aPreventDefault,
       Stringify(mPendingTouchPreventedGuid).c_str());
     mContentReceivedInputBlockCallback(mPendingTouchPreventedGuid,
         mPendingTouchPreventedBlockId, aPreventDefault);
--- a/gfx/layers/apz/util/APZEventState.h
+++ b/gfx/layers/apz/util/APZEventState.h
@@ -64,16 +64,17 @@ public:
                          uint64_t aInputBlockId);
   void ProcessMouseEvent(const WidgetMouseEvent& aEvent,
                          const ScrollableLayerGuid& aGuid,
                          uint64_t aInputBlockId);
   void ProcessAPZStateChange(const nsCOMPtr<nsIDocument>& aDocument,
                              ViewID aViewId,
                              APZStateChange aChange,
                              int aArg);
+  void ProcessClusterHit();
 private:
   ~APZEventState();
   bool SendPendingTouchPreventedResponse(bool aPreventDefault);
   already_AddRefed<nsIWidget> GetWidget() const;
 private:
   nsWeakPtr mWidget;
   RefPtr<ActiveElementManager> mActiveElementManager;
   ContentReceivedInputBlockCallback mContentReceivedInputBlockCallback;
--- a/gfx/layers/apz/util/ActiveElementManager.cpp
+++ b/gfx/layers/apz/util/ActiveElementManager.cpp
@@ -96,22 +96,19 @@ ActiveElementManager::TriggerElementActi
         this, &ActiveElementManager::SetActiveTask, mTarget);
     MessageLoop::current()->PostDelayedTask(
         FROM_HERE, mSetActiveTask, sActivationDelayMs);
     AEM_LOG("Scheduling mSetActiveTask %p\n", mSetActiveTask);
   }
 }
 
 void
-ActiveElementManager::HandlePanStart()
+ActiveElementManager::ClearActivation()
 {
-  AEM_LOG("Handle pan start\n");
-
-  // The user started to pan, so we don't want mTarget to be :active.
-  // Make it not :active, and clear any pending task to make it :active.
+  AEM_LOG("Clearing element activation\n");
   CancelTask();
   ResetActive();
 }
 
 void
 ActiveElementManager::HandleTouchEndEvent(bool aWasClick)
 {
   AEM_LOG("Touch end event, aWasClick: %d\n", aWasClick);
--- a/gfx/layers/apz/util/ActiveElementManager.h
+++ b/gfx/layers/apz/util/ActiveElementManager.h
@@ -40,19 +40,19 @@ public:
   void SetTargetElement(dom::EventTarget* aTarget);
   /**
    * Handle a touch-start state notification from APZ. This notification
    * may be delayed until after touch listeners have responded to the APZ.
    * @param aCanBePan whether the touch can be a pan
    */
   void HandleTouchStart(bool aCanBePan);
   /**
-   * Handle the start of panning.
+   * Clear the active element.
    */
-  void HandlePanStart();
+  void ClearActivation();
   /**
    * Handle a touch-end or touch-cancel event.
    * @param aWasClick whether the touch was a click
    */
   void HandleTouchEndEvent(bool aWasClick);
   /**
    * Handle a touch-end state notification from APZ. This notification may be
    * delayed until after touch listeners have responded to the APZ.
--- a/gfx/layers/apz/util/ChromeProcessController.h
+++ b/gfx/layers/apz/util/ChromeProcessController.h
@@ -23,16 +23,17 @@ namespace layers {
 
 class APZCTreeManager;
 class APZEventState;
 
 // A ChromeProcessController is attached to the root of a compositor's layer
 // tree.
 class ChromeProcessController : public mozilla::layers::GeckoContentController
 {
+protected:
   typedef mozilla::layers::FrameMetrics FrameMetrics;
   typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
 
 public:
   explicit ChromeProcessController(nsIWidget* aWidget, APZEventState* aAPZEventState, APZCTreeManager* aAPZCTreeManager);
   ~ChromeProcessController();
   virtual void Destroy() override;
 
--- a/gfx/layers/basic/BasicImages.cpp
+++ b/gfx/layers/basic/BasicImages.cpp
@@ -7,17 +7,18 @@
 #include "BasicLayers.h"                // for BasicLayerManager
 #include "ImageContainer.h"             // for PlanarYCbCrImage, etc
 #include "ImageTypes.h"                 // for ImageFormat, etc
 #include "cairo.h"                      // for cairo_user_data_key_t
 #include "gfxASurface.h"                // for gfxASurface, etc
 #include "gfxPlatform.h"                // for gfxPlatform, gfxImageFormat
 #include "gfxUtils.h"                   // for gfxUtils
 #include "mozilla/mozalloc.h"           // for operator delete[], etc
-#include "nsAutoPtr.h"                  // for nsRefPtr, nsAutoArrayPtr
+#include "mozilla/RefPtr.h"
+#include "mozilla/UniquePtr.h"
 #include "nsAutoRef.h"                  // for nsCountedRef
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_ERROR, NS_ASSERTION
 #include "nsISupportsImpl.h"            // for Image::Release, etc
 #include "nsThreadUtils.h"              // for NS_IsMainThread
 #include "mozilla/gfx/Point.h"          // for IntSize
 #include "gfx2DGlue.h"
 #include "YCbCrUtils.h"                 // for YCbCr conversions
@@ -39,39 +40,39 @@ public:
     SetOffscreenFormat(aOffscreenFormat);
   }
 
   ~BasicPlanarYCbCrImage()
   {
     if (mDecodedBuffer) {
       // Right now this only happens if the Image was never drawn, otherwise
       // this will have been tossed away at surface destruction.
-      mRecycleBin->RecycleBuffer(mDecodedBuffer.forget(), mSize.height * mStride);
+      mRecycleBin->RecycleBuffer(Move(mDecodedBuffer), mSize.height * mStride);
     }
   }
 
   virtual bool SetData(const Data& aData) override;
   virtual void SetDelayedConversion(bool aDelayed) override { mDelayedConversion = aDelayed; }
 
   already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
 
   virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
   {
     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   }
 
   virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
   {
     size_t size = RecyclingPlanarYCbCrImage::SizeOfExcludingThis(aMallocSizeOf);
-    size += mDecodedBuffer.SizeOfExcludingThis(aMallocSizeOf);
+    size += aMallocSizeOf(mDecodedBuffer.get());
     return size;
   }
 
 private:
-  nsAutoArrayPtr<uint8_t> mDecodedBuffer;
+  UniquePtr<uint8_t[]> mDecodedBuffer;
   gfx::IntSize mScaleHint;
   int mStride;
   bool mDelayedConversion;
 };
 
 class BasicImageFactory : public ImageFactory
 {
 public:
@@ -120,17 +121,17 @@ BasicPlanarYCbCrImage::SetData(const Dat
   gfxImageFormat iFormat = gfx::SurfaceFormatToImageFormat(format);
   mStride = gfxASurface::FormatStrideForWidth(iFormat, size.width);
   mDecodedBuffer = AllocateBuffer(size.height * mStride);
   if (!mDecodedBuffer) {
     // out of memory
     return false;
   }
 
-  gfx::ConvertYCbCrToRGB(aData, format, size, mDecodedBuffer, mStride);
+  gfx::ConvertYCbCrToRGB(aData, format, size, mDecodedBuffer.get(), mStride);
   SetOffscreenFormat(iFormat);
   mSize = size;
 
   return true;
 }
 
 already_AddRefed<gfx::SourceSurface>
 BasicPlanarYCbCrImage::GetAsSourceSurface()
@@ -149,28 +150,28 @@ BasicPlanarYCbCrImage::GetAsSourceSurfac
   gfxImageFormat format = GetOffscreenFormat();
 
   RefPtr<gfx::SourceSurface> surface;
   {
     // Create a DrawTarget so that we can own the data inside mDecodeBuffer.
     // We create the target out of mDecodedBuffer, and get a snapshot from it.
     // The draw target is destroyed on scope exit and the surface owns the data.
     RefPtr<gfx::DrawTarget> drawTarget
-      = gfxPlatform::GetPlatform()->CreateDrawTargetForData(mDecodedBuffer,
+      = gfxPlatform::GetPlatform()->CreateDrawTargetForData(mDecodedBuffer.get(),
                                                             mSize,
                                                             mStride,
                                                             gfx::ImageFormatToSurfaceFormat(format));
     if (!drawTarget) {
       return nullptr;
     }
 
     surface = drawTarget->Snapshot();
   }
 
-  mRecycleBin->RecycleBuffer(mDecodedBuffer.forget(), mSize.height * mStride);
+  mRecycleBin->RecycleBuffer(Move(mDecodedBuffer), mSize.height * mStride);
 
   mSourceSurface = surface;
   return surface.forget();
 }
 
 
 ImageFactory*
 BasicLayerManager::GetImageFactory()
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -971,17 +971,17 @@ LayerManagerComposite::RenderToPresentat
     surface = mirrorScreen->GetEGLSurface();
     if (surface == LOCAL_EGL_NO_SURFACE) {
       // Failed to create EGLSurface
       return;
     }
   }
   GLContext* gl = compositor->gl();
   GLContextEGL* egl = GLContextEGL::Cast(gl);
-  const IntSize windowSize = mirrorScreen->GetNaturalBoundsUntyped().Size();
+  const IntSize windowSize = mirrorScreen->GetNaturalBounds().Size().ToUnknownSize();
 #endif
 
   if ((windowSize.width <= 0) || (windowSize.height <= 0)) {
     return;
   }
 
   ScreenRotation rotation = compositor->GetScreenRotation();
 
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -144,16 +144,17 @@ private:
   bool mInitOkay;
 };
 
 CompositorD3D11::CompositorD3D11(nsIWidget* aWidget)
   : mAttachments(nullptr)
   , mWidget(aWidget)
   , mHwnd(nullptr)
   , mDisableSequenceForNextFrame(false)
+  , mVerifyBuffersFailed(false)
 {
 }
 
 CompositorD3D11::~CompositorD3D11()
 {
   if (mDevice) {
     int referenceCount = 0;
     UINT size = sizeof(referenceCount);
@@ -1214,19 +1215,20 @@ CompositorD3D11::VerifyBufferSize()
   HRESULT hr;
 
   hr = mSwapChain->GetDesc(&swapDesc);
   if (Failed(hr)) {
     gfxCriticalError() << "Failed to get the description " << hexa(hr);
     return false;
   }
 
-  if ((swapDesc.BufferDesc.Width == mSize.width &&
+  if (((swapDesc.BufferDesc.Width == mSize.width &&
        swapDesc.BufferDesc.Height == mSize.height) ||
-      mSize.width <= 0 || mSize.height <= 0) {
+       mSize.width <= 0 || mSize.height <= 0) &&
+      !mVerifyBuffersFailed) {
     return true;
   }
 
   if (mDefaultRT) {
     // Make sure the texture, which belongs to the swapchain, is destroyed
     // before resizing the swapchain.
     if (mCurrentRT == mDefaultRT) {
       mCurrentRT = nullptr;
@@ -1236,16 +1238,17 @@ CompositorD3D11::VerifyBufferSize()
   }
 
   hr = mSwapChain->ResizeBuffers(1, mSize.width, mSize.height,
                                  DXGI_FORMAT_B8G8R8A8_UNORM,
                                  0);
   if (Failed(hr)) {
     gfxCriticalNote << "D3D11 swap resize buffers failed " << hexa(hr) << " on " << mSize;
   }
+  mVerifyBuffersFailed = FAILED(hr);
 
   return Succeeded(hr);
 }
 
 bool
 CompositorD3D11::UpdateRenderTarget()
 {
   if (mDevice != gfxWindowsPlatform::GetPlatform()->GetD3D11Device()) {
--- a/gfx/layers/d3d11/CompositorD3D11.h
+++ b/gfx/layers/d3d11/CompositorD3D11.h
@@ -194,14 +194,16 @@ private:
   VertexShaderConstants mVSConstants;
   PixelShaderConstants mPSConstants;
   bool mDisableSequenceForNextFrame;
 
   gfx::IntRect mInvalidRect;
   // This is the clip rect applied to the default DrawTarget (i.e. the window)
   gfx::IntRect mCurrentClip;
   nsIntRegion mInvalidRegion;
+
+  bool mVerifyBuffersFailed;
 };
 
 }
 }
 
 #endif
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -508,17 +508,17 @@ ShadowLayerForwarder::StorePluginWidgetC
 {
   // Cache new plugin widget configs here until we call update, at which
   // point this data will get shipped over to chrome.
   mPluginWindowData.Clear();
   for (uint32_t idx = 0; idx < aConfigurations.Length(); idx++) {
     const nsIWidget::Configuration& configuration = aConfigurations[idx];
     mPluginWindowData.AppendElement(PluginWindowData(configuration.mWindowID,
                                                      configuration.mClipRegion,
-                                                     configuration.mBounds,
+                                                     configuration.mBounds.ToUnknownRect(),
                                                      configuration.mVisible));
   }
 }
 
 bool
 ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies,
                                      const nsIntRegion& aRegionToClear,
                                      uint64_t aId,
@@ -593,16 +593,17 @@ ShadowLayerForwarder::EndTransaction(Inf
     common.opacity() = mutant->GetOpacity();
     common.useClipRect() = !!mutant->GetClipRect();
     common.clipRect() = (common.useClipRect() ?
                          *mutant->GetClipRect() : ParentLayerIntRect());
     common.isFixedPosition() = mutant->GetIsFixedPosition();
     if (mutant->GetIsFixedPosition()) {
       common.fixedPositionScrollContainerId() = mutant->GetFixedPositionScrollContainerId();
       common.fixedPositionAnchor() = mutant->GetFixedPositionAnchor();
+      common.fixedPositionSides() = mutant->GetFixedPositionSides();
       common.isClipFixed() = mutant->IsClipFixed();
     }
     common.isStickyPosition() = mutant->GetIsStickyPosition();
     if (mutant->GetIsStickyPosition()) {
       common.stickyScrollContainerId() = mutant->GetStickyScrollContainerId();
       common.stickyScrollRangeOuter() = mutant->GetStickyScrollRangeOuter();
       common.stickyScrollRangeInner() = mutant->GetStickyScrollRangeInner();
     } else {
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -735,31 +735,31 @@ CompositorOGL::CreateFBOWithTexture(cons
                                   clampedRect.x, FlipY(clampedRect.y + clampedRect.height),
                                   clampedRect.width, clampedRect.height,
                                   0);
     } else {
       // Curses, incompatible formats.  Take a slow path.
 
       // RGBA
       size_t bufferSize = clampedRect.width * clampedRect.height * 4;
-      nsAutoArrayPtr<uint8_t> buf(new uint8_t[bufferSize]);
+      auto buf = MakeUnique<uint8_t[]>(bufferSize);
 
       mGLContext->fReadPixels(clampedRect.x, clampedRect.y,
                               clampedRect.width, clampedRect.height,
                               LOCAL_GL_RGBA,
                               LOCAL_GL_UNSIGNED_BYTE,
-                              buf);
+                              buf.get());
       mGLContext->fTexImage2D(mFBOTextureTarget,
                               0,
                               LOCAL_GL_RGBA,
                               clampedRect.width, clampedRect.height,
                               0,
                               LOCAL_GL_RGBA,
                               LOCAL_GL_UNSIGNED_BYTE,
-                              buf);
+                              buf.get());
     }
     GLenum error = mGLContext->fGetError();
     if (error != LOCAL_GL_NO_ERROR) {
       nsAutoCString msg;
       msg.AppendPrintf("Texture initialization failed! -- error 0x%x, Source %d, Source format %d,  RGBA Compat %d",
                        error, aSourceFrameBuffer, format, isFormatCompatibleWithRGBA);
       NS_ERROR(msg.get());
     }
--- a/gfx/thebes/gfxCoreTextShaper.cpp
+++ b/gfx/thebes/gfxCoreTextShaper.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ArrayUtils.h"
 #include "gfxCoreTextShaper.h"
 #include "gfxMacFont.h"
 #include "gfxFontUtils.h"
 #include "gfxTextRun.h"
 #include "mozilla/gfx/2D.h"
+#include "mozilla/UniquePtrExtensions.h"
 
 #include <algorithm>
 
 using namespace mozilla;
 
 // standard font descriptors that we construct the first time they're needed
 CTFontDescriptorRef gfxCoreTextShaper::sDefaultFeaturesDescriptor = nullptr;
 CTFontDescriptorRef gfxCoreTextShaper::sDisableLigaturesDescriptor = nullptr;
@@ -242,57 +243,57 @@ gfxCoreTextShaper::SetGlyphsFromRun(gfxS
     CFRange stringRange = ::CTRunGetStringRange(aCTRun);
     // skip the run if it is entirely outside the actual range of the font run
     if (stringRange.location - aStringOffset + stringRange.length <= 0 ||
         stringRange.location - aStringOffset >= wordLength) {
         return NS_OK;
     }
 
     // retrieve the laid-out glyph data from the CTRun
-    nsAutoArrayPtr<CGGlyph> glyphsArray;
-    nsAutoArrayPtr<CGPoint> positionsArray;
-    nsAutoArrayPtr<CFIndex> glyphToCharArray;
+    UniquePtr<CGGlyph[]> glyphsArray;
+    UniquePtr<CGPoint[]> positionsArray;
+    UniquePtr<CFIndex[]> glyphToCharArray;
     const CGGlyph* glyphs = nullptr;
     const CGPoint* positions = nullptr;
     const CFIndex* glyphToChar = nullptr;
 
     // Testing indicates that CTRunGetGlyphsPtr (almost?) always succeeds,
     // and so allocating a new array and copying data with CTRunGetGlyphs
     // will be extremely rare.
     // If this were not the case, we could use an nsAutoTArray<> to
     // try and avoid the heap allocation for small runs.
     // It's possible that some future change to CoreText will mean that
     // CTRunGetGlyphsPtr fails more often; if this happens, nsAutoTArray<>
     // may become an attractive option.
     glyphs = ::CTRunGetGlyphsPtr(aCTRun);
     if (!glyphs) {
-        glyphsArray = new (std::nothrow) CGGlyph[numGlyphs];
+        glyphsArray = MakeUniqueFallible<CGGlyph[]>(numGlyphs);
         if (!glyphsArray) {
             return NS_ERROR_OUT_OF_MEMORY;
         }
         ::CTRunGetGlyphs(aCTRun, ::CFRangeMake(0, 0), glyphsArray.get());
         glyphs = glyphsArray.get();
     }
 
     positions = ::CTRunGetPositionsPtr(aCTRun);
     if (!positions) {
-        positionsArray = new (std::nothrow) CGPoint[numGlyphs];
+        positionsArray = MakeUniqueFallible<CGPoint[]>(numGlyphs);
         if (!positionsArray) {
             return NS_ERROR_OUT_OF_MEMORY;
         }
         ::CTRunGetPositions(aCTRun, ::CFRangeMake(0, 0), positionsArray.get());
         positions = positionsArray.get();
     }
 
     // Remember that the glyphToChar indices relate to the CoreText line,
     // not to the beginning of the textRun, the font run,
     // or the stringRange of the glyph run
     glyphToChar = ::CTRunGetStringIndicesPtr(aCTRun);
     if (!glyphToChar) {
-        glyphToCharArray = new (std::nothrow) CFIndex[numGlyphs];
+        glyphToCharArray = MakeUniqueFallible<CFIndex[]>(numGlyphs);
         if (!glyphToCharArray) {
             return NS_ERROR_OUT_OF_MEMORY;
         }
         ::CTRunGetStringIndices(aCTRun, ::CFRangeMake(0, 0), glyphToCharArray.get());
         glyphToChar = glyphToCharArray.get();
     }
 
     double runWidth = ::CTRunGetTypographicBounds(aCTRun, ::CFRangeMake(0, 0),
--- a/gfx/thebes/gfxFT2FontList.cpp
+++ b/gfx/thebes/gfxFT2FontList.cpp
@@ -5,17 +5,18 @@
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Base64.h"
 #include "mozilla/MemoryReporting.h"
 
 #include "mozilla/dom/ContentChild.h"
 #include "gfxAndroidPlatform.h"
 #include "mozilla/Omnijar.h"
-#include "nsAutoPtr.h"
+#include "mozilla/UniquePtr.h"
+#include "mozilla/UniquePtrExtensions.h"
 #include "nsIInputStream.h"
 #define gfxToolkitPlatform gfxAndroidPlatform
 
 #include "nsXULAppAPI.h"
 #include <dirent.h>
 #include <android/log.h>
 #define ALOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gecko" , ## args)
 
@@ -1064,39 +1065,39 @@ gfxFT2FontList::AppendFacesFromOmnijarEn
     }
 
     nsZipItem *item = aArchive->GetItem(aEntryName.get());
     NS_ASSERTION(item, "failed to find zip entry");
 
     uint32_t bufSize = item->RealSize();
     // We use fallible allocation here; if there's not enough RAM, we'll simply
     // ignore the bundled fonts and fall back to the device's installed fonts.
-    nsAutoArrayPtr<uint8_t> buf(new (fallible) uint8_t[bufSize]);
+    auto buf = MakeUniqueFallible<uint8_t[]>(bufSize);
     if (!buf) {
         return;
     }
 
-    nsZipCursor cursor(item, aArchive, buf, bufSize);
+    nsZipCursor cursor(item, aArchive, buf.get(), bufSize);
     uint8_t* data = cursor.Copy(&bufSize);
     NS_ASSERTION(data && bufSize == item->RealSize(),
                  "error reading bundled font");
     if (!data) {
         return;
     }
 
     FT_Library ftLibrary = gfxAndroidPlatform::GetPlatform()->GetFTLibrary();
 
     FT_Face dummy;
-    if (FT_Err_Ok != FT_New_Memory_Face(ftLibrary, buf, bufSize, 0, &dummy)) {
+    if (FT_Err_Ok != FT_New_Memory_Face(ftLibrary, buf.get(), bufSize, 0, &dummy)) {
         return;
     }
 
     for (FT_Long i = 0; i < dummy->num_faces; i++) {
         FT_Face face;
-        if (FT_Err_Ok != FT_New_Memory_Face(ftLibrary, buf, bufSize, i, &face)) {
+        if (FT_Err_Ok != FT_New_Memory_Face(ftLibrary, buf.get(), bufSize, i, &face)) {
             continue;
         }
         AddFaceToList(aEntryName, i, kStandard, FT2FontFamily::kVisible,
                       face, faceList);
         FT_Done_Face(face);
     }
 
     FT_Done_Face(dummy);
--- a/gfx/thebes/gfxFontEntry.cpp
+++ b/gfx/thebes/gfxFontEntry.cpp
@@ -206,40 +206,40 @@ nsresult gfxFontEntry::InitializeUVSMap(
     if (!mUVSData) {
         const uint32_t kCmapTag = TRUETYPE_TAG('c','m','a','p');
         AutoTable cmapTable(this, kCmapTag);
         if (!cmapTable) {
             mUVSOffset = 0; // don't bother to read the table again
             return NS_ERROR_FAILURE;
         }
 
-        uint8_t* uvsData;
+        UniquePtr<uint8_t[]> uvsData;
         unsigned int cmapLen;
         const char* cmapData = hb_blob_get_data(cmapTable, &cmapLen);
         nsresult rv = gfxFontUtils::ReadCMAPTableFormat14(
                           (const uint8_t*)cmapData + mUVSOffset,
                           cmapLen - mUVSOffset, uvsData);
 
         if (NS_FAILED(rv)) {
             mUVSOffset = 0; // don't bother to read the table again
             return rv;
         }
 
-        mUVSData = uvsData;
+        mUVSData = Move(uvsData);
     }
 
     return NS_OK;
 }
 
 uint16_t gfxFontEntry::GetUVSGlyph(uint32_t aCh, uint32_t aVS)
 {
     InitializeUVSMap();
 
     if (mUVSData) {
-        return gfxFontUtils::MapUVSToGlyphFormat14(mUVSData, aCh, aVS);
+        return gfxFontUtils::MapUVSToGlyphFormat14(mUVSData.get(), aCh, aVS);
     }
 
     return 0;
 }
 
 bool gfxFontEntry::SupportsScriptInGSUB(const hb_tag_t* aScriptTags)
 {
     hb_face_t *face = GetHBFace();
--- a/gfx/thebes/gfxFontEntry.h
+++ b/gfx/thebes/gfxFontEntry.h
@@ -15,16 +15,17 @@
 #include "nsTHashtable.h"
 #include "mozilla/HashFunctions.h"
 #include "mozilla/MemoryReporting.h"
 #include "DrawMode.h"
 #include "nsUnicodeScriptCodes.h"
 #include "nsDataHashtable.h"
 #include "harfbuzz/hb.h"
 #include "mozilla/gfx/2D.h"
+#include "mozilla/UniquePtr.h"
 
 typedef struct gr_face gr_face;
 
 #ifdef DEBUG
 #include <stdio.h>
 #endif
 
 struct gfxFontStyle;
@@ -424,17 +425,17 @@ public:
     uint32_t         mDefaultSubSpaceFeatures[(MOZ_NUM_SCRIPT_CODES + 31) / 32];
     uint32_t         mNonDefaultSubSpaceFeatures[(MOZ_NUM_SCRIPT_CODES + 31) / 32];
 
     uint16_t         mWeight;
     int16_t          mStretch;
 
     RefPtr<gfxCharacterMap> mCharacterMap;
     uint32_t         mUVSOffset;
-    nsAutoArrayPtr<uint8_t> mUVSData;
+    mozilla::UniquePtr<uint8_t[]> mUVSData;
     nsAutoPtr<gfxUserFontData> mUserFontData;
     nsAutoPtr<gfxSVGGlyphs> mSVGGlyphs;
     // list of gfxFonts that are using SVG glyphs
     nsTArray<gfxFont*> mFontsUsingSVGGlyphs;
     nsAutoPtr<gfxMathTable> mMathTable;
     nsTArray<gfxFontFeature> mFeatureSettings;
     nsAutoPtr<nsDataHashtable<nsUint32HashKey,bool>> mSupportedFeatures;
     nsAutoPtr<nsDataHashtable<nsUint32HashKey,hb_set_t*>> mFeatureInputs;
--- a/gfx/thebes/gfxFontUtils.cpp
+++ b/gfx/thebes/gfxFontUtils.cpp
@@ -284,17 +284,17 @@ gfxFontUtils::ReadCMAPTableFormat4(const
 
     aCharacterMap.Compact();
 
     return NS_OK;
 }
 
 nsresult
 gfxFontUtils::ReadCMAPTableFormat14(const uint8_t *aBuf, uint32_t aLength,
-                                    uint8_t*& aTable)
+                                    UniquePtr<uint8_t[]>& aTable)
 {
     enum {
         OffsetFormat = 0,
         OffsetTableLength = 2,
         OffsetNumVarSelectorRecords = 6,
         OffsetVarSelectorRecords = 10,
 
         SizeOfVarSelectorRecord = 11,
@@ -366,18 +366,18 @@ gfxFontUtils::ReadCMAPTableFormat14(cons
                 NS_ENSURE_TRUE((prevUnicode < unicodeValue || j == 0) &&
                                unicodeValue <= CMAP_MAX_CODEPOINT, 
                                NS_ERROR_GFX_CMAP_MALFORMED);
                 prevUnicode = unicodeValue;
             }
         }
     }
 
-    aTable = new uint8_t[tablelen];
-    memcpy(aTable, aBuf, tablelen);
+    aTable = MakeUnique<uint8_t[]>(tablelen);
+    memcpy(aTable.get(), aBuf, tablelen);
 
     return NS_OK;
 }
 
 // Windows requires fonts to have a format-4 cmap with a Microsoft ID (3).  On the Mac, fonts either have
 // a format-4 cmap with Microsoft platform/encoding id or they have one with a platformID == Unicode (0)
 // For fonts with two format-4 tables, the first one (Unicode platform) is preferred on the Mac.
 
--- a/gfx/thebes/gfxFontUtils.h
+++ b/gfx/thebes/gfxFontUtils.h
@@ -8,16 +8,17 @@
 
 #include "gfxPlatform.h"
 #include "nsComponentManagerUtils.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
 #include "mozilla/Likely.h"
 #include "mozilla/Endian.h"
 #include "mozilla/MemoryReporting.h"
+#include "mozilla/UniquePtr.h"
 
 #include "zlib.h"
 #include <algorithm>
 
 /* Bug 341128 - w32api defines min/max which causes problems with <bitset> */
 #ifdef __MINGW32__
 #undef min
 #undef max
@@ -781,17 +782,17 @@ public:
                           gfxSparseBitSet& aCharacterMap);
 
     static nsresult 
     ReadCMAPTableFormat4(const uint8_t *aBuf, uint32_t aLength, 
                          gfxSparseBitSet& aCharacterMap);
 
     static nsresult
     ReadCMAPTableFormat14(const uint8_t *aBuf, uint32_t aLength, 
-                          uint8_t*& aTable);
+                          mozilla::UniquePtr<uint8_t[]>& aTable);
 
     static uint32_t
     FindPreferredSubtable(const uint8_t *aBuf, uint32_t aBufLength,
                           uint32_t *aTableOffset, uint32_t *aUVSTableOffset,
                           bool *aSymbolEncoding);
 
     static nsresult
     ReadCMAP(const uint8_t *aBuf, uint32_t aBufLength,
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -19,16 +19,17 @@
 #include "gfxFontMissingGlyphs.h"
 #include "gfxScriptItemizer.h"
 #include "nsUnicodeProperties.h"
 #include "nsUnicodeRange.h"
 #include "nsStyleConsts.h"
 #include "mozilla/Likely.h"
 #include "gfx2DGlue.h"
 #include "mozilla/gfx/Logging.h"        // for gfxCriticalError
+#include "mozilla/UniquePtr.h"
 
 #if defined(MOZ_WIDGET_GTK)
 #include "gfxPlatformGtk.h" // xxx - for UseFcFontList
 #endif
 
 #ifdef XP_WIN
 #include "gfxWindowsPlatform.h"
 #endif
@@ -2102,29 +2103,29 @@ gfxFontGroup::InitTextRun(gfxContext *aC
                           uint32_t aLength,
                           gfxMissingFontRecorder *aMFR)
 {
     NS_ASSERTION(aLength > 0, "don't call InitTextRun for a zero-length run");
 
     // we need to do numeral processing even on 8-bit text,
     // in case we're converting Western to Hindi/Arabic digits
     int32_t numOption = gfxPlatform::GetPlatform()->GetBidiNumeralOption();
-    nsAutoArrayPtr<char16_t> transformedString;
+    UniquePtr<char16_t[]> transformedString;
     if (numOption != IBMBIDI_NUMERAL_NOMINAL) {
         // scan the string for numerals that may need to be transformed;
         // if we find any, we'll make a local copy here and use that for
         // font matching and glyph generation/shaping
         bool prevIsArabic =
             (aTextRun->GetFlags() & gfxTextRunFactory::TEXT_INCOMING_ARABICCHAR) != 0;
         for (uint32_t i = 0; i < aLength; ++i) {
             char16_t origCh = aString[i];
             char16_t newCh = HandleNumberInChar(origCh, prevIsArabic, numOption);
             if (newCh != origCh) {
                 if (!transformedString) {
-                    transformedString = new char16_t[aLength];
+                    transformedString = MakeUnique<char16_t[]>(aLength);
                     if (sizeof(T) == sizeof(char16_t)) {
                         memcpy(transformedString.get(), aString, i * sizeof(char16_t));
                     } else {
                         for (uint32_t j = 0; j < i; ++j) {
                             transformedString[j] = aString[j];
                         }
                     }
                 }
--- a/js/public/Id.h
+++ b/js/public/Id.h
@@ -163,17 +163,18 @@ JSID_IS_EMPTY(const jsid id)
 extern JS_PUBLIC_DATA(const jsid) JSID_VOID;
 extern JS_PUBLIC_DATA(const jsid) JSID_EMPTY;
 
 extern JS_PUBLIC_DATA(const JS::HandleId) JSID_VOIDHANDLE;
 extern JS_PUBLIC_DATA(const JS::HandleId) JSID_EMPTYHANDLE;
 
 namespace js {
 
-template <> struct GCMethods<jsid>
+template <>
+struct GCMethods<jsid>
 {
     static jsid initial() { return JSID_VOID; }
     static void postBarrier(jsid* idp, jsid prev, jsid next) {}
 };
 
 // If the jsid is a GC pointer type, convert to that type and call |f| with
 // the pointer. If the jsid is not a GC type, calls F::defaultValue.
 template <typename F, typename... Args>
--- a/js/src/builtin/WeakMapObject.cpp
+++ b/js/src/builtin/WeakMapObject.cpp
@@ -143,23 +143,16 @@ TryPreserveReflector(JSContext* cx, Hand
         if (!cx->runtime()->preserveWrapperCallback(cx, obj)) {
             JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_BAD_WEAKMAP_KEY);
             return false;
         }
     }
     return true;
 }
 
-static inline void
-WeakMapPostWriteBarrier(JSRuntime* rt, ObjectValueMap* weakMap, JSObject* key)
-{
-    if (key && IsInsideNursery(key))
-        rt->gc.storeBuffer.putGeneric(gc::HashKeyRef<ObjectValueMap, JSObject*>(weakMap, key));
-}
-
 static MOZ_ALWAYS_INLINE bool
 SetWeakMapEntryInternal(JSContext* cx, Handle<WeakMapObject*> mapObj,
                         HandleObject key, HandleValue value)
 {
     ObjectValueMap* map = mapObj->getMap();
     if (!map) {
         AutoInitGCManagedObject<ObjectValueMap> newMap(
             cx->make_unique<ObjectValueMap>(cx, mapObj.get()));
@@ -184,17 +177,16 @@ SetWeakMapEntryInternal(JSContext* cx, H
     }
 
     MOZ_ASSERT(key->compartment() == mapObj->compartment());
     MOZ_ASSERT_IF(value.isObject(), value.toObject().compartment() == mapObj->compartment());
     if (!map->put(key, value)) {
         JS_ReportOutOfMemory(cx);
         return false;
     }
-    WeakMapPostWriteBarrier(cx->runtime(), map, key.get());
     return true;
 }
 
 MOZ_ALWAYS_INLINE bool
 WeakMap_set_impl(JSContext* cx, const CallArgs& args)
 {
     MOZ_ASSERT(IsWeakMap(args.thisv()));
 
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -3876,15 +3876,18 @@ AC_SUBST(JS_CONFIG_MOZ_JS_LIBS)
 AC_SUBST(JS_CONFIG_LIBS)
 
 if test -n "$MOZ_BUILD_NSPR"; then
     MOZ_SUBCONFIGURE_NSPR()
 fi
 MOZ_SUBCONFIGURE_FFI()
 MOZ_SUBCONFIGURE_JEMALLOC()
 
+# Avoid using obsolete NSPR features
+AC_DEFINE(NO_NSPR_10_SUPPORT)
+
 dnl Spit out some output
 dnl ========================================================
 MOZ_CREATE_CONFIG_STATUS()
 
 if test "$JS_STANDALONE"; then
   MOZ_RUN_CONFIG_STATUS()
 fi
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -7121,34 +7121,49 @@ BytecodeEmitter::emitPropertyList(ParseN
         if (propdef->pn_right->isKind(PNK_FUNCTION) &&
             propdef->pn_right->pn_funbox->needsHomeObject())
         {
             MOZ_ASSERT(propdef->pn_right->pn_funbox->function()->allowSuperProperty());
             if (!emit2(JSOP_INITHOMEOBJECT, isIndex))
                 return false;
         }
 
+        // Class methods are not enumerable.
+        if (type == ClassBody) {
+            switch (op) {
+              case JSOP_INITPROP:        op = JSOP_INITHIDDENPROP;          break;
+              case JSOP_INITPROP_GETTER: op = JSOP_INITHIDDENPROP_GETTER;   break;
+              case JSOP_INITPROP_SETTER: op = JSOP_INITHIDDENPROP_SETTER;   break;
+              default: MOZ_CRASH("Invalid op");
+            }
+        }
+
         if (isIndex) {
             objp.set(nullptr);
             switch (op) {
-              case JSOP_INITPROP:        op = JSOP_INITELEM;        break;
-              case JSOP_INITPROP_GETTER: op = JSOP_INITELEM_GETTER; break;
-              case JSOP_INITPROP_SETTER: op = JSOP_INITELEM_SETTER; break;
+              case JSOP_INITPROP:               op = JSOP_INITELEM;              break;
+              case JSOP_INITHIDDENPROP:         op = JSOP_INITHIDDENELEM;        break;
+              case JSOP_INITPROP_GETTER:        op = JSOP_INITELEM_GETTER;       break;
+              case JSOP_INITHIDDENPROP_GETTER:  op = JSOP_INITHIDDENELEM_GETTER; break;
+              case JSOP_INITPROP_SETTER:        op = JSOP_INITELEM_SETTER;       break;
+              case JSOP_INITHIDDENPROP_SETTER:  op = JSOP_INITHIDDENELEM_SETTER; break;
               default: MOZ_CRASH("Invalid op");
             }
             if (!emit1(op))
                 return false;
         } else {
             MOZ_ASSERT(key->isKind(PNK_OBJECT_PROPERTY_NAME) || key->isKind(PNK_STRING));
 
             jsatomid index;
             if (!makeAtomIndex(key->pn_atom, &index))
                 return false;
 
             if (objp) {
+                MOZ_ASSERT(type == ObjectLiteral);
+                MOZ_ASSERT(!IsHiddenInitOp(op));
                 MOZ_ASSERT(!objp->inDictionaryMode());
                 Rooted<jsid> id(cx, AtomToId(key->pn_atom));
                 RootedValue undefinedValue(cx, UndefinedValue());
                 if (!NativeDefineProperty(cx, objp, id, undefinedValue, nullptr, nullptr,
                                           JSPROP_ENUMERATE))
                 {
                     return false;
                 }
@@ -8461,21 +8476,19 @@ CGBlockScopeList::findEnclosingScope(uin
     DebugOnly<uint32_t> pos = list[index].start;
     while (index--) {
         MOZ_ASSERT_IF(inPrologue == list[index].startInPrologue, list[index].start <= pos);
         if (list[index].end == 0) {
             // We are looking for the nearest enclosing live scope.  If the
             // scope contains POS, it should still be open, so its length should
             // be zero.
             return list[index].index;
-        } else {
-            // Conversely, if the length is not zero, it should not contain
-            // POS.
-            MOZ_ASSERT_IF(inPrologue == list[index].endInPrologue, list[index].end <= pos);
-        }
+        }
+        // Conversely, if the length is not zero, it should not contain POS.
+        MOZ_ASSERT_IF(inPrologue == list[index].endInPrologue, list[index].end <= pos);
     }
 
     return BlockScopeNote::NoBlockScopeIndex;
 }
 
 void
 CGBlockScopeList::recordEnd(uint32_t index, uint32_t offset, bool inPrologue)
 {
--- a/js/src/gc/Barrier.cpp
+++ b/js/src/gc/Barrier.cpp
@@ -157,17 +157,18 @@ MovableCellHasher<T>::match(const Key& k
     MOZ_ALWAYS_TRUE(zone->getUniqueId(k, &uidK));
     MOZ_ALWAYS_TRUE(zone->getUniqueId(l, &uidL));
     return uidK == uidL;
 }
 
 template struct MovableCellHasher<JSObject*>;
 template struct MovableCellHasher<GlobalObject*>;
 template struct MovableCellHasher<SavedFrame*>;
-template struct MovableCellHasher<ReadBarriered<ScopeObject*>>;
+template struct MovableCellHasher<ScopeObject*>;
+template struct MovableCellHasher<JSScript*>;
 
 } // namespace js
 
 JS_PUBLIC_API(void)
 JS::HeapObjectPostBarrier(JSObject** objp, JSObject* prev, JSObject* next)
 {
     MOZ_ASSERT(objp);
     js::InternalGCMethods<JSObject*>::postBarrier(objp, prev, next);
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -477,17 +477,19 @@ class HeapPtr : public WriteBarrieredBas
  * i.e. in C++ containers.  It is, however, somewhat slower, so should only be
  * used in contexts where this ability is necessary.
  */
 template <class T>
 class RelocatablePtr : public WriteBarrieredBase<T>
 {
   public:
     RelocatablePtr() : WriteBarrieredBase<T>(GCMethods<T>::initial()) {}
-    explicit RelocatablePtr(T v) : WriteBarrieredBase<T>(v) {
+
+    // Implicitly adding barriers is a reasonable default.
+    MOZ_IMPLICIT RelocatablePtr(const T& v) : WriteBarrieredBase<T>(v) {
         this->post(GCMethods<T>::initial(), this->value);
     }
 
     /*
      * For RelocatablePtr, move semantics are equivalent to copy semantics. In
      * C++, a copy constructor taking const-ref is the way to get a single
      * function that will be used for both lvalue and rvalue copies, so we can
      * simply omit the rvalue variant.
@@ -555,24 +557,28 @@ class ReadBarrieredBase : public Barrier
 // insert manual post-barriers on the table for rekeying if the key is based in
 // any way on the address of the object.
 template <typename T>
 class ReadBarriered : public ReadBarrieredBase<T>
 {
   public:
     ReadBarriered() : ReadBarrieredBase<T>(GCMethods<T>::initial()) {}
 
+    // It is okay to add barriers implicitly.
     MOZ_IMPLICIT ReadBarriered(const T& v) : ReadBarrieredBase<T>(v) {
         this->post(GCMethods<T>::initial(), v);
     }
 
+    // Copy is creating a new edge, so we must read barrier the source edge.
     explicit ReadBarriered(const ReadBarriered& v) : ReadBarrieredBase<T>(v) {
         this->post(GCMethods<T>::initial(), v.get());
     }
 
+    // Move retains the lifetime status of the source edge, so does not fire
+    // the read barrier of the defunct edge.
     ReadBarriered(ReadBarriered&& v)
       : ReadBarrieredBase<T>(mozilla::Forward<ReadBarriered<T>>(v))
     {
         this->post(GCMethods<T>::initial(), v.value);
     }
 
     ~ReadBarriered() {
         this->post(this->value, GCMethods<T>::initial());
@@ -599,16 +605,17 @@ class ReadBarriered : public ReadBarrier
     explicit operator bool() const {
         return bool(this->value);
     }
 
     operator const T() const { return get(); }
 
     const T operator->() const { return get(); }
 
+    T* unsafeGet() { return &this->value; }
     T const* unsafeGet() const { return &this->value; }
 
     void set(const T& v)
     {
         T tmp = this->value;
         this->value = v;
         this->post(tmp, v);
     }
@@ -794,16 +801,51 @@ struct MovableCellHasher
     using Key = T;
     using Lookup = T;
 
     static HashNumber hash(const Lookup& l);
     static bool match(const Key& k, const Lookup& l);
     static void rekey(Key& k, const Key& newKey) { k = newKey; }
 };
 
+template <typename T>
+struct MovableCellHasher<PreBarriered<T>>
+{
+    using Key = PreBarriered<T>;
+    using Lookup = T;
+
+    static HashNumber hash(const Lookup& l) { return MovableCellHasher<T>::hash(l); }
+    static bool match(const Key& k, const Lookup& l) { return MovableCellHasher<T>::match(k, l); }
+    static void rekey(Key& k, const Key& newKey) { k.unsafeSet(newKey); }
+};
+
+template <typename T>
+struct MovableCellHasher<RelocatablePtr<T>>
+{
+    using Key = RelocatablePtr<T>;
+    using Lookup = T;
+
+    static HashNumber hash(const Lookup& l) { return MovableCellHasher<T>::hash(l); }
+    static bool match(const Key& k, const Lookup& l) { return MovableCellHasher<T>::match(k, l); }
+    static void rekey(Key& k, const Key& newKey) { k.unsafeSet(newKey); }
+};
+
+template <typename T>
+struct MovableCellHasher<ReadBarriered<T>>
+{
+    using Key = ReadBarriered<T>;
+    using Lookup = T;
+
+    static HashNumber hash(const Lookup& l) { return MovableCellHasher<T>::hash(l); }
+    static bool match(const Key& k, const Lookup& l) {
+        return MovableCellHasher<T>::match(k.unbarrieredGet(), l);
+    }
+    static void rekey(Key& k, const Key& newKey) { k.unsafeSet(newKey); }
+};
+
 /* Useful for hashtables with a HeapPtr as key. */
 template <class T>
 struct HeapPtrHasher
 {
     typedef HeapPtr<T> Key;
     typedef T Lookup;
 
     static HashNumber hash(Lookup obj) { return DefaultHasher<T>::hash(obj); }
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -1959,16 +1959,22 @@ BaselineCompiler::emit_JSOP_INITELEM()
     if (!emitOpIC(stubCompiler.getStub(&stubSpace_)))
         return false;
 
     // Pop the rhs, so that the object is on the top of the stack.
     frame.pop();
     return true;
 }
 
+bool
+BaselineCompiler::emit_JSOP_INITHIDDENELEM()
+{
+    return emit_JSOP_INITELEM();
+}
+
 typedef bool (*MutateProtoFn)(JSContext* cx, HandlePlainObject obj, HandleValue newProto);
 static const VMFunction MutateProtoInfo = FunctionInfo<MutateProtoFn>(MutatePrototype);
 
 bool
 BaselineCompiler::emit_JSOP_MUTATEPROTO()
 {
     // Keep values on the stack for the decompiler.
     frame.syncStack(0);
@@ -2564,17 +2570,19 @@ typedef bool (*InitPropGetterSetterFn)(J
                                        HandleObject);
 static const VMFunction InitPropGetterSetterInfo =
     FunctionInfo<InitPropGetterSetterFn>(InitGetterSetterOperation);
 
 bool
 BaselineCompiler::emitInitPropGetterSetter()
 {
     MOZ_ASSERT(JSOp(*pc) == JSOP_INITPROP_GETTER ||
-               JSOp(*pc) == JSOP_INITPROP_SETTER);
+               JSOp(*pc) == JSOP_INITHIDDENPROP_GETTER ||
+               JSOp(*pc) == JSOP_INITPROP_SETTER ||
+               JSOp(*pc) == JSOP_INITHIDDENPROP_SETTER);
 
     // Keep values on the stack for the decompiler.
     frame.syncStack(0);
 
     prepareVMCall();
 
     masm.extractObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg());
     masm.extractObject(frame.addressOfStackValue(frame.peek(-2)), R1.scratchReg());
@@ -2593,31 +2601,45 @@ BaselineCompiler::emitInitPropGetterSett
 
 bool
 BaselineCompiler::emit_JSOP_INITPROP_GETTER()
 {
     return emitInitPropGetterSetter();
 }
 
 bool
+BaselineCompiler::emit_JSOP_INITHIDDENPROP_GETTER()
+{
+    return emitInitPropGetterSetter();
+}
+
+bool
 BaselineCompiler::emit_JSOP_INITPROP_SETTER()
 {
     return emitInitPropGetterSetter();
 }
 
+bool
+BaselineCompiler::emit_JSOP_INITHIDDENPROP_SETTER()
+{
+    return emitInitPropGetterSetter();
+}
+
 typedef bool (*InitElemGetterSetterFn)(JSContext*, jsbytecode*, HandleObject, HandleValue,
                                        HandleObject);
 static const VMFunction InitElemGetterSetterInfo =
     FunctionInfo<InitElemGetterSetterFn>(InitGetterSetterOperation);
 
 bool
 BaselineCompiler::emitInitElemGetterSetter()
 {
     MOZ_ASSERT(JSOp(*pc) == JSOP_INITELEM_GETTER ||
-               JSOp(*pc) == JSOP_INITELEM_SETTER);
+               JSOp(*pc) == JSOP_INITHIDDENELEM_GETTER ||
+               JSOp(*pc) == JSOP_INITELEM_SETTER ||
+               JSOp(*pc) == JSOP_INITHIDDENELEM_SETTER);
 
     // Load index and value in R0 and R1, but keep values on the stack for the
     // decompiler.
     frame.syncStack(0);
     masm.loadValue(frame.addressOfStackValue(frame.peek(-2)), R0);
     masm.extractObject(frame.addressOfStackValue(frame.peek(-1)), R1.scratchReg());
 
     prepareVMCall();
@@ -2637,22 +2659,34 @@ BaselineCompiler::emitInitElemGetterSett
 
 bool
 BaselineCompiler::emit_JSOP_INITELEM_GETTER()
 {
     return emitInitElemGetterSetter();
 }
 
 bool
+BaselineCompiler::emit_JSOP_INITHIDDENELEM_GETTER()
+{
+    return emitInitElemGetterSetter();
+}
+
+bool
 BaselineCompiler::emit_JSOP_INITELEM_SETTER()
 {
     return emitInitElemGetterSetter();
 }
 
 bool
+BaselineCompiler::emit_JSOP_INITHIDDENELEM_SETTER()
+{
+    return emitInitElemGetterSetter();
+}
+
+bool
 BaselineCompiler::emit_JSOP_INITELEM_INC()
 {
     // Keep the object and rhs on the stack.
     frame.syncStack(0);
 
     // Load object in R0, index in R1.
     masm.loadValue(frame.addressOfStackValue(frame.peek(-3)), R0);
     masm.loadValue(frame.addressOfStackValue(frame.peek(-2)), R1);
--- a/js/src/jit/BaselineCompiler.h
+++ b/js/src/jit/BaselineCompiler.h
@@ -203,17 +203,22 @@ namespace jit {
     _(JSOP_GETRVAL)            \
     _(JSOP_SETRVAL)            \
     _(JSOP_RETRVAL)            \
     _(JSOP_RETURN)             \
     _(JSOP_NEWTARGET)          \
     _(JSOP_SUPERCALL)          \
     _(JSOP_SPREADSUPERCALL)    \
     _(JSOP_THROWSETCONST)      \
-    _(JSOP_THROWSETALIASEDCONST)
+    _(JSOP_THROWSETALIASEDCONST) \
+    _(JSOP_INITHIDDENPROP_GETTER) \
+    _(JSOP_INITHIDDENPROP_SETTER) \
+    _(JSOP_INITHIDDENELEM)     \
+    _(JSOP_INITHIDDENELEM_GETTER) \
+    _(JSOP_INITHIDDENELEM_SETTER)
 
 class BaselineCompiler : public BaselineCompilerSpecific
 {
     FixedList<Label>            labels_;
     NonAssertingLabel           return_;
     NonAssertingLabel           postBarrierSlot_;
 
     // Native code offset right before the scope chain is initialized.
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -3472,16 +3472,17 @@ DoSetElemFallback(JSContext* cx, Baselin
     RootedScript script(cx, frame->script());
     jsbytecode* pc = stub->icEntry()->pc(script);
     JSOp op = JSOp(*pc);
     FallbackICSpew(cx, stub, "SetElem(%s)", js_CodeName[JSOp(*pc)]);
 
     MOZ_ASSERT(op == JSOP_SETELEM ||
                op == JSOP_STRICTSETELEM ||
                op == JSOP_INITELEM ||
+               op == JSOP_INITHIDDENELEM ||
                op == JSOP_INITELEM_ARRAY ||
                op == JSOP_INITELEM_INC);
 
     RootedObject obj(cx, ToObjectFromStack(cx, objv));
     if (!obj)
         return false;
 
     RootedShape oldShape(cx, obj->maybeShape());
@@ -3489,18 +3490,18 @@ DoSetElemFallback(JSContext* cx, Baselin
     // Check the old capacity
     uint32_t oldCapacity = 0;
     uint32_t oldInitLength = 0;
     if (index.isInt32() && index.toInt32() >= 0) {
         oldCapacity = GetAnyBoxedOrUnboxedCapacity(obj);
         oldInitLength = GetAnyBoxedOrUnboxedInitializedLength(obj);
     }
 
-    if (op == JSOP_INITELEM) {
-        if (!InitElemOperation(cx, obj, index, rhs))
+    if (op == JSOP_INITELEM || op == JSOP_INITHIDDENELEM) {
+        if (!InitElemOperation(cx, pc, obj, index, rhs))
             return false;
     } else if (op == JSOP_INITELEM_ARRAY) {
         MOZ_ASSERT(uint32_t(index.toInt32()) <= INT32_MAX,
                    "the bytecode emitter must fail to compile code that would "
                    "produce JSOP_INITELEM_ARRAY with an index exceeding "
                    "int32_t range");
         MOZ_ASSERT(uint32_t(index.toInt32()) == GET_UINT32(pc));
         if (!InitArrayElemOperation(cx, pc, obj, index.toInt32(), rhs))
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -4843,29 +4843,30 @@ CodeGenerator::visitNewStringObject(LNew
     masm.loadStringLength(input, temp);
 
     masm.storeValue(JSVAL_TYPE_STRING, input, Address(output, StringObject::offsetOfPrimitiveValue()));
     masm.storeValue(JSVAL_TYPE_INT32, temp, Address(output, StringObject::offsetOfLength()));
 
     masm.bind(ool->rejoin());
 }
 
-typedef bool(*InitElemFn)(JSContext* cx, HandleObject obj,
+typedef bool(*InitElemFn)(JSContext* cx, jsbytecode* pc, HandleObject obj,
                           HandleValue id, HandleValue value);
 static const VMFunction InitElemInfo =
     FunctionInfo<InitElemFn>(InitElemOperation);
 
 void
 CodeGenerator::visitInitElem(LInitElem* lir)
 {
     Register objReg = ToRegister(lir->getObject());
 
     pushArg(ToValue(lir, LInitElem::ValueIndex));
     pushArg(ToValue(lir, LInitElem::IdIndex));
     pushArg(objReg);
+    pushArg(ImmPtr(lir->mir()->resumePoint()->pc()));
 
     callVM(InitElemInfo, lir);
 }
 
 typedef bool (*InitElemGetterSetterFn)(JSContext*, jsbytecode*, HandleObject, HandleValue,
                                        HandleObject);
 static const VMFunction InitElemGetterSetterInfo =
     FunctionInfo<InitElemGetterSetterFn>(InitGetterSetterOperation);
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -156,16 +156,17 @@ IonBuilder::IonBuilder(JSContext* analys
     failedShapeGuard_(info->script()->failedShapeGuard()),
     failedLexicalCheck_(info->script()->failedLexicalCheck()),
     nonStringIteration_(false),
     lazyArguments_(nullptr),
     inlineCallInfo_(nullptr),
     maybeFallbackFunctionGetter_(nullptr)
 {
     script_ = info->script();
+    scriptHasIonScript_ = script_->hasIonScript();
     pc = info->startPC();
     abortReason_ = AbortReason_Disable;
 
     MOZ_ASSERT(script()->hasBaselineScript() == (info->analysisMode() != Analysis_ArgumentsUsage));
     MOZ_ASSERT(!!analysisContext == (info->analysisMode() == Analysis_DefiniteProperties));
 
     if (!info->isAnalysis())
         script()->baselineScript()->setIonCompiledOrInlined();
@@ -1833,16 +1834,17 @@ IonBuilder::inspectOpcode(JSOp op)
 
       case JSOP_NEWARRAY_COPYONWRITE:
         return jsop_newarray_copyonwrite();
 
       case JSOP_NEWOBJECT:
         return jsop_newobject();
 
       case JSOP_INITELEM:
+      case JSOP_INITHIDDENELEM:
         return jsop_initelem();
 
       case JSOP_INITELEM_ARRAY:
         return jsop_initelem_array();
 
       case JSOP_INITPROP:
       case JSOP_INITLOCKEDPROP:
       case JSOP_INITHIDDENPROP:
@@ -1852,23 +1854,27 @@ IonBuilder::inspectOpcode(JSOp op)
       }
 
       case JSOP_MUTATEPROTO:
       {
         return jsop_mutateproto();
       }
 
       case JSOP_INITPROP_GETTER:
-      case JSOP_INITPROP_SETTER: {
+      case JSOP_INITHIDDENPROP_GETTER:
+      case JSOP_INITPROP_SETTER:
+      case JSOP_INITHIDDENPROP_SETTER: {
         PropertyName* name = info().getAtom(pc)->asPropertyName();
         return jsop_initprop_getter_setter(name);
       }
 
       case JSOP_INITELEM_GETTER:
+      case JSOP_INITHIDDENELEM_GETTER:
       case JSOP_INITELEM_SETTER:
+      case JSOP_INITHIDDENELEM_SETTER:
         return jsop_initelem_getter_setter();
 
       case JSOP_FUNCALL:
         return jsop_funcall(GET_ARGC(pc));
 
       case JSOP_FUNAPPLY:
         return jsop_funapply(GET_ARGC(pc));
 
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -1011,16 +1011,20 @@ class IonBuilder
 
     void setCurrent(MBasicBlock* block) {
         current = block;
     }
 
     // A builder is inextricably tied to a particular script.
     JSScript* script_;
 
+    // script->hasIonScript() at the start of the compilation. Used to avoid
+    // calling hasIonScript() from background compilation threads.
+    bool scriptHasIonScript_;
+
     // If off thread compilation is successful, the final code generator is
     // attached here. Code has been generated, but not linked (there is not yet
     // an IonScript). This is heap allocated, and must be explicitly destroyed,
     // performed by FinishOffThreadBuilder().
     CodeGenerator* backgroundCodegen_;
 
     // Some aborts are actionable (e.g., using an unsupported bytecode). When
     // optimization tracking is enabled, the location and message of the abort
@@ -1030,16 +1034,17 @@ class IonBuilder
     jsbytecode* actionableAbortPc_;
     const char* actionableAbortMessage_;
 
   public:
     void clearForBackEnd();
     JSObject* checkNurseryObject(JSObject* obj);
 
     JSScript* script() const { return script_; }
+    bool scriptHasIonScript() const { return scriptHasIonScript_; }
 
     CodeGenerator* backgroundCodegen() const { return backgroundCodegen_; }
     void setBackgroundCodegen(CodeGenerator* codegen) { backgroundCodegen_ = codegen; }
 
     CompilerConstraintList* constraints() {
         return constraints_;
     }
 
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -131,29 +131,29 @@ namespace {
 class StringifyContext
 {
   public:
     StringifyContext(JSContext* cx, StringBuffer& sb, const StringBuffer& gap,
                      HandleObject replacer, const AutoIdVector& propertyList)
       : sb(sb),
         gap(gap),
         replacer(cx, replacer),
-        stack(cx, TraceableHashSet<JSObject*>(cx)),
+        stack(cx, TraceableHashSet<JSObject*, MovableCellHasher<JSObject*>>(cx)),
         propertyList(propertyList),
         depth(0)
     {}
 
     bool init() {
         return stack.init(8);
     }
 
     StringBuffer& sb;
     const StringBuffer& gap;
     RootedObject replacer;
-    Rooted<TraceableHashSet<JSObject*>> stack;
+    Rooted<TraceableHashSet<JSObject*, MovableCellHasher<JSObject*>>> stack;
     const AutoIdVector& propertyList;
     uint32_t depth;
 };
 
 } /* anonymous namespace */
 
 static bool Str(JSContext* cx, const Value& v, StringifyContext* scx);
 
@@ -319,17 +319,17 @@ class CycleDetector
         return stack.add(addPtr, obj_);
     }
 
     ~CycleDetector() {
         stack.remove(obj_);
     }
 
   private:
-    MutableHandle<TraceableHashSet<JSObject*>> stack;
+    MutableHandle<TraceableHashSet<JSObject*, MovableCellHasher<JSObject*>>> stack;
     HandleObject obj_;
 };
 
 /* ES5 15.12.3 JO. */
 static bool
 JO(JSContext* cx, HandleObject obj, StringifyContext* scx)
 {
     /*
--- a/js/src/jsopcode.h
+++ b/js/src/jsopcode.h
@@ -699,16 +699,24 @@ IsCheckSloppyOp(JSOp op)
 inline bool
 IsGetPropPC(jsbytecode* pc)
 {
     JSOp op = JSOp(*pc);
     return op == JSOP_LENGTH  || op == JSOP_GETPROP || op == JSOP_CALLPROP;
 }
 
 inline bool
+IsHiddenInitOp(JSOp op)
+{
+    return op == JSOP_INITHIDDENPROP || op == JSOP_INITHIDDENELEM ||
+           op == JSOP_INITHIDDENPROP_GETTER || op == JSOP_INITHIDDENELEM_GETTER ||
+           op == JSOP_INITHIDDENPROP_SETTER || op == JSOP_INITHIDDENELEM_SETTER;
+}
+
+inline bool
 IsStrictSetPC(jsbytecode* pc)
 {
     JSOp op = JSOp(*pc);
     return op == JSOP_STRICTSETPROP ||
            op == JSOP_STRICTSETNAME ||
            op == JSOP_STRICTSETGNAME ||
            op == JSOP_STRICTSETELEM;
 }
--- a/js/src/jswatchpoint.cpp
+++ b/js/src/jswatchpoint.cpp
@@ -13,19 +13,19 @@
 #include "gc/Marking.h"
 
 #include "jsgcinlines.h"
 
 using namespace js;
 using namespace js::gc;
 
 inline HashNumber
-DefaultHasher<WatchKey>::hash(const Lookup& key)
+WatchKeyHasher::hash(const Lookup& key)
 {
-    return DefaultHasher<JSObject*>::hash(key.object.get()) ^ HashId(key.id.get());
+    return MovableCellHasher<PreBarrieredObject>::hash(key.object) ^ HashId(key.id);
 }
 
 namespace {
 
 class AutoEntryHolder {
     typedef WatchpointMap::Map Map;
     Map& map;
     Map::Ptr p;
--- a/js/src/jswatchpoint.h
+++ b/js/src/jswatchpoint.h
@@ -15,16 +15,19 @@
 namespace js {
 
 struct WeakMapTracer;
 
 struct WatchKey {
     WatchKey() {}
     WatchKey(JSObject* obj, jsid id) : object(obj), id(id) {}
     WatchKey(const WatchKey& key) : object(key.object.get()), id(key.id.get()) {}
+
+    // These are traced unconditionally during minor GC, so do not require
+    // post-barriers.
     PreBarrieredObject object;
     PreBarrieredId id;
 
     bool operator!=(const WatchKey& other) const {
         return object != other.object || id != other.id;
     }
 };
 
@@ -35,35 +38,35 @@ typedef bool
 struct Watchpoint {
     JSWatchPointHandler handler;
     PreBarrieredObject closure;  /* This is always marked in minor GCs and so doesn't require a postbarrier. */
     bool held;  /* true if currently running handler */
     Watchpoint(JSWatchPointHandler handler, JSObject* closure, bool held)
       : handler(handler), closure(closure), held(held) {}
 };
 
-template <>
-struct DefaultHasher<WatchKey>
+struct WatchKeyHasher
 {
     typedef WatchKey Lookup;
     static inline js::HashNumber hash(const Lookup& key);
 
     static bool match(const WatchKey& k, const Lookup& l) {
-        return k.object == l.object && k.id.get() == l.id.get();
+        return MovableCellHasher<PreBarrieredObject>::match(k.object, l.object) &&
+               DefaultHasher<PreBarrieredId>::match(k.id, l.id);
     }
 
     static void rekey(WatchKey& k, const WatchKey& newKey) {
         k.object.unsafeSet(newKey.object);
         k.id.unsafeSet(newKey.id);
     }
 };
 
 class WatchpointMap {
   public:
-    typedef HashMap<WatchKey, Watchpoint, DefaultHasher<WatchKey>, SystemAllocPolicy> Map;
+    typedef HashMap<WatchKey, Watchpoint, WatchKeyHasher, SystemAllocPolicy> Map;
 
     bool init();
     bool watch(JSContext* cx, HandleObject obj, HandleId id,
                JSWatchPointHandler handler, HandleObject closure);
     void unwatch(JSObject* obj, jsid id,
                  JSWatchPointHandler* handlerp, JSObject** closurep);
     void unwatchObject(JSObject* obj);
     void clear();
--- a/js/src/jsweakmap.cpp
+++ b/js/src/jsweakmap.cpp
@@ -183,18 +183,16 @@ ObjectWeakMap::add(JSContext* cx, JSObje
     MOZ_ASSERT(obj && target);
     MOZ_ASSERT(map.initialized());
 
     MOZ_ASSERT(!map.has(obj));
     if (!map.put(obj, ObjectValue(*target))) {
         ReportOutOfMemory(cx);
         return false;
     }
-    if (IsInsideNursery(obj))
-        cx->runtime()->gc.storeBuffer.putGeneric(StoreBufferRef(&map, obj));
 
     return true;
 }
 
 void
 ObjectWeakMap::clear()
 {
     MOZ_ASSERT(map.initialized());
--- a/js/src/jsweakmap.h
+++ b/js/src/jsweakmap.h
@@ -387,32 +387,33 @@ WeakMap_delete(JSContext* cx, unsigned a
 
 extern bool
 WeakMap_clear(JSContext* cx, unsigned argc, Value* vp);
 
 extern JSObject*
 InitWeakMapClass(JSContext* cx, HandleObject obj);
 
 
-class ObjectValueMap : public WeakMap<PreBarrieredObject, RelocatableValue>
+class ObjectValueMap : public WeakMap<RelocatablePtrObject, RelocatableValue,
+                                      MovableCellHasher<RelocatablePtrObject>>
 {
   public:
     ObjectValueMap(JSContext* cx, JSObject* obj)
-      : WeakMap<PreBarrieredObject, RelocatableValue>(cx, obj) {}
+      : WeakMap<RelocatablePtrObject, RelocatableValue,
+                MovableCellHasher<RelocatablePtrObject>>(cx, obj)
+    {}
 
     virtual bool findZoneEdges();
 };
 
 
 // Generic weak map for mapping objects to other objects.
 class ObjectWeakMap
 {
-  private:
     ObjectValueMap map;
-    typedef gc::HashKeyRef<ObjectValueMap, JSObject*> StoreBufferRef;
 
   public:
     explicit ObjectWeakMap(JSContext* cx);
     bool init();
 
     JSObject* lookup(const JSObject* obj);
     bool add(JSContext* cx, JSObject* obj, JSObject* target);
     void clear();
--- a/js/src/tests/ecma_6/Class/methodInstallation.js
+++ b/js/src/tests/ecma_6/Class/methodInstallation.js
@@ -47,56 +47,56 @@ for (let a of [testClass,
     new aConstDesc.value();
     assertEq(constructorCalled, true);
 
     // __proto__ is just an identifier for classes. No prototype changes are made.
     assertEq(Object.getPrototypeOf(a.prototype), Object.prototype);
     var aMethDesc = Object.getOwnPropertyDescriptor(a.prototype, \"__proto__\");
     assertEq(aMethDesc.writable, true);
     assertEq(aMethDesc.configurable, true);
-    assertEq(aMethDesc.enumerable, true);
+    assertEq(aMethDesc.enumerable, false);
     aMethDesc.value();
     assertEq(methodCalled, true);
 
     var aGetDesc = Object.getOwnPropertyDescriptor(a.prototype, \"getter\");
     assertEq(aGetDesc.configurable, true);
-    assertEq(aGetDesc.enumerable, true);
+    assertEq(aGetDesc.enumerable, false);
     aGetDesc.get();
     assertThrowsInstanceOf(() => new aGetDesc.get, TypeError);
     assertEq(getterCalled, true);
 
     var aSetDesc = Object.getOwnPropertyDescriptor(a.prototype, \"setter\");
     assertEq(aSetDesc.configurable, true);
-    assertEq(aSetDesc.enumerable, true);
+    assertEq(aSetDesc.enumerable, false);
     aSetDesc.set();
     assertThrowsInstanceOf(() => new aSetDesc.set, TypeError);
     assertEq(setterCalled, true);
     assertDeepEq(aSetDesc, Object.getOwnPropertyDescriptor(a.prototype, \"setter\"));
 
     assertEq(Object.getOwnPropertyDescriptor(new a(), \"staticMethod\"), undefined);
     var aStaticMethDesc = Object.getOwnPropertyDescriptor(a, \"staticMethod\");
     assertEq(aStaticMethDesc.configurable, true);
-    assertEq(aStaticMethDesc.enumerable, true);
+    assertEq(aStaticMethDesc.enumerable, false);
     assertEq(aStaticMethDesc.writable, true);
     aStaticMethDesc.value();
     assertThrowsInstanceOf(() => new aStaticMethDesc.value, TypeError);
     assertEq(staticMethodCalled, true);
 
     assertEq(Object.getOwnPropertyDescriptor(new a(), \"staticGetter\"), undefined);
     var aStaticGetDesc = Object.getOwnPropertyDescriptor(a, \"staticGetter\");
     assertEq(aStaticGetDesc.configurable, true);
-    assertEq(aStaticGetDesc.enumerable, true);
+    assertEq(aStaticGetDesc.enumerable, false);
     aStaticGetDesc.get();
     assertThrowsInstanceOf(() => new aStaticGetDesc.get, TypeError);
     assertEq(staticGetterCalled, true);
 
     assertEq(Object.getOwnPropertyDescriptor(new a(), \"staticSetter\"), undefined);
     var aStaticSetDesc = Object.getOwnPropertyDescriptor(a, \"staticSetter\");
     assertEq(aStaticSetDesc.configurable, true);
-    assertEq(aStaticSetDesc.enumerable, true);
+    assertEq(aStaticSetDesc.enumerable, false);
     aStaticSetDesc.set();
     assertThrowsInstanceOf(() => new aStaticSetDesc.set, TypeError);
     assertEq(staticSetterCalled, true);
 
     assertEq([...new a()].join(), "cow,pig");
 }
 `;
 
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -1077,16 +1077,18 @@ InnerViewTable::addView(JSContext* cx, A
             ReportOutOfMemory(cx);
             return false;
         }
     } else {
         if (!map.add(p, buffer, ViewVector())) {
             ReportOutOfMemory(cx);
             return false;
         }
+        // ViewVector has one inline element, so the first insertion is
+        // guaranteed to succeed.
         MOZ_ALWAYS_TRUE(p->value().append(view));
     }
 
     if (addToNursery && !nurseryKeys.append(buffer))
         nurseryKeysValid = false;
 
     return true;
 }
@@ -1133,40 +1135,35 @@ void
 InnerViewTable::sweep(JSRuntime* rt)
 {
     MOZ_ASSERT(nurseryKeys.empty());
 
     if (!map.initialized())
         return;
 
     for (Map::Enum e(map); !e.empty(); e.popFront()) {
-        JSObject* key = e.front().key();
-        if (sweepEntry(&key, e.front().value()))
+        if (sweepEntry(&e.front().mutableKey(), e.front().value()))
             e.removeFront();
-        else if (key != e.front().key())
-            e.rekeyFront(key);
     }
 }
 
 void
 InnerViewTable::sweepAfterMinorGC(JSRuntime* rt)
 {
     MOZ_ASSERT(needsSweepAfterMinorGC());
 
     if (nurseryKeysValid) {
         for (size_t i = 0; i < nurseryKeys.length(); i++) {
-            JSObject* key = nurseryKeys[i];
-            Map::Ptr p = map.lookup(key);
+            JSObject* buffer = MaybeForwarded(nurseryKeys[i]);
+            Map::Ptr p = map.lookup(buffer);
             if (!p)
                 continue;
 
-            if (sweepEntry(&key, p->value()))
-                map.remove(nurseryKeys[i]);
-            else
-                map.rekeyIfMoved(nurseryKeys[i], key);
+            if (sweepEntry(&p->mutableKey(), p->value()))
+                map.remove(buffer);
         }
         nurseryKeys.clear();
     } else {
         // Do the required sweeping by looking at every map entry.
         nurseryKeys.clear();
         sweep(rt);
 
         nurseryKeysValid = true;
--- a/js/src/vm/ArrayBufferObject.h
+++ b/js/src/vm/ArrayBufferObject.h
@@ -496,27 +496,38 @@ template<> inline bool TypeIsUnsigned<ui
 class InnerViewTable
 {
   public:
     typedef Vector<ArrayBufferViewObject*, 1, SystemAllocPolicy> ViewVector;
 
     friend class ArrayBufferObject;
 
   private:
+    // This key is a raw pointer and not a ReadBarriered because the post-
+    // barrier would hold nursery-allocated entries live unconditionally. It is
+    // a very common pattern in low-level and performance-oriented JavaScript
+    // to create hundreds or thousands of very short lived temporary views on a
+    // larger buffer; having to tenured all of these would be a catastrophic
+    // performance regression. Thus, it is vital that nursery pointers in this
+    // map not be held live. Special support is required in the minor GC,
+    // implemented in sweepAfterMinorGC.
     typedef HashMap<JSObject*,
                     ViewVector,
-                    DefaultHasher<JSObject*>,
+                    MovableCellHasher<JSObject*>,
                     SystemAllocPolicy> Map;
 
     // For all objects sharing their storage with some other view, this maps
     // the object to the list of such views. All entries in this map are weak.
     Map map;
 
     // List of keys from innerViews where either the source or at least one
-    // target is in the nursery.
+    // target is in the nursery. The raw pointer to a JSObject is allowed here
+    // because this vector is cleared after every minor collection. Users in
+    // sweepAfterMinorCollection must be careful to use MaybeForwarded before
+    // touching these pointers.
     Vector<JSObject*, 0, SystemAllocPolicy> nurseryKeys;
 
     // Whether nurseryKeys is a complete list.
     bool nurseryKeysValid;
 
     // Sweep an entry during GC, returning whether the entry should be removed.
     bool sweepEntry(JSObject** pkey, ViewVector& views);
 
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -1457,17 +1457,18 @@ Debugger::onTrap(JSContext* cx, MutableH
          * One is just that one breakpoint handler can disable other Debuggers
          * or remove debuggees.
          *
          * The other has to do with non-compile-and-go scripts, which have no
          * specific global--until they are executed. Only now do we know which
          * global the script is running against.
          */
         Debugger* dbg = bp->debugger;
-        if (dbg->enabled && dbg->debuggees.lookup(scriptGlobal)) {
+        bool hasDebuggee = dbg->enabled && dbg->debuggees.has(scriptGlobal);
+        if (hasDebuggee) {
             Maybe<AutoCompartment> ac;
             ac.emplace(cx, dbg->object);
 
             RootedValue scriptFrame(cx);
             if (!dbg->getScriptFrame(cx, iter, &scriptFrame))
                 return dbg->handleUncaughtException(ac, false);
             RootedValue rv(cx);
             Rooted<JSObject*> handler(cx, bp->handler);
@@ -2531,23 +2532,18 @@ Debugger::markAllIteratively(GCMarker* t
  * GC: the minor GC cannot apply the weak constraints of the full GC because it
  * visits only part of the heap.
  */
 /* static */ void
 Debugger::markAll(JSTracer* trc)
 {
     JSRuntime* rt = trc->runtime();
     for (Debugger* dbg : rt->debuggerList) {
-        WeakGlobalObjectSet& debuggees = dbg->debuggees;
-        for (WeakGlobalObjectSet::Enum e(debuggees); !e.empty(); e.popFront()) {
-            GlobalObject* global = e.front().unbarrieredGet();
-            TraceManuallyBarrieredEdge(trc, &global, "Global Object");
-            if (global != e.front().unbarrieredGet())
-                e.rekeyFront(global, ReadBarrieredGlobalObject(global));
-        }
+        for (WeakGlobalObjectSet::Enum e(dbg->debuggees); !e.empty(); e.popFront())
+            TraceManuallyBarrieredEdge(trc, e.mutableFront().unsafeGet(), "Global Object");
 
         HeapPtrNativeObject& dbgobj = dbg->toJSObjectRef();
         TraceEdge(trc, &dbgobj, "Debugger Object");
 
         dbg->scripts.trace(trc);
         dbg->sources.trace(trc);
         dbg->objects.trace(trc);
         dbg->environments.trace(trc);
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -37,17 +37,17 @@ enum JSTrapStatus {
 namespace js {
 
 class LSprinter;
 
 class Breakpoint;
 class DebuggerMemory;
 
 typedef HashSet<ReadBarrieredGlobalObject,
-                DefaultHasher<ReadBarrieredGlobalObject>,
+                MovableCellHasher<ReadBarrieredGlobalObject>,
                 SystemAllocPolicy> WeakGlobalObjectSet;
 
 /*
  * A weakmap from GC thing keys to JSObject values that supports the keys being
  * in different compartments to the values. All values must be in the same
  * compartment.
  *
  * The purpose of this is to allow the garbage collector to easily find edges
@@ -65,32 +65,33 @@ typedef HashSet<ReadBarrieredGlobalObjec
  * created.
  *
  * Also note that keys in these weakmaps can be in any compartment, debuggee or
  * not, because they cannot be deleted when a compartment is no longer a
  * debuggee: the values need to maintain object identity across add/remove/add
  * transitions.
  */
 template <class UnbarrieredKey, bool InvisibleKeysOk=false>
-class DebuggerWeakMap : private WeakMap<PreBarriered<UnbarrieredKey>, RelocatablePtrObject>
+class DebuggerWeakMap : private WeakMap<RelocatablePtr<UnbarrieredKey>, RelocatablePtrObject,
+                                        MovableCellHasher<RelocatablePtr<UnbarrieredKey>>>
 {
   private:
-    typedef PreBarriered<UnbarrieredKey> Key;
+    typedef RelocatablePtr<UnbarrieredKey> Key;
     typedef RelocatablePtrObject Value;
 
     typedef HashMap<JS::Zone*,
                     uintptr_t,
                     DefaultHasher<JS::Zone*>,
                     RuntimeAllocPolicy> CountMap;
 
     CountMap zoneCounts;
     JSCompartment* compartment;
 
   public:
-    typedef WeakMap<Key, Value, DefaultHasher<Key> > Base;
+    typedef WeakMap<Key, Value, MovableCellHasher<Key>> Base;
 
     explicit DebuggerWeakMap(JSContext* cx)
         : Base(cx),
           zoneCounts(cx->runtime()),
           compartment(cx->compartment())
     { }
 
   public:
@@ -151,23 +152,19 @@ class DebuggerWeakMap : private WeakMap<
         MOZ_ASSERT_IF(p.found(), p->value() > 0);
         return p.found();
     }
 
   private:
     /* Override sweep method to also update our edge cache. */
     void sweep() {
         for (Enum e(*static_cast<Base*>(this)); !e.empty(); e.popFront()) {
-            Key k(e.front().key());
-            if (gc::IsAboutToBeFinalized(&k)) {
+            if (gc::IsAboutToBeFinalized(&e.front().mutableKey())) {
+                decZoneCount(e.front().key()->zone());
                 e.removeFront();
-                decZoneCount(k->zone());
-            } else {
-                // markKeys() should have done any necessary relocation.
-                MOZ_ASSERT(k == e.front().key());
             }
         }
         Base::assertEntriesNotAboutToBeFinalized();
     }
 
     bool incZoneCount(JS::Zone* zone) {
         CountMap::Ptr p = zoneCounts.lookupWithDefault(zone, 0);
         if (!p)
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -757,18 +757,18 @@ IonBuilderHasHigherPriority(jit::IonBuil
     // This method can return whatever it wants, though it really ought to be a
     // total order. The ordering is allowed to race (change on the fly), however.
 
     // A lower optimization level indicates a higher priority.
     if (first->optimizationInfo().level() != second->optimizationInfo().level())
         return first->optimizationInfo().level() < second->optimizationInfo().level();
 
     // A script without an IonScript has precedence on one with.
-    if (first->script()->hasIonScript() != second->script()->hasIonScript())
-        return !first->script()->hasIonScript();
+    if (first->scriptHasIonScript() != second->scriptHasIonScript())
+        return !first->scriptHasIonScript();
 
     // A higher warm-up counter indicates a higher priority.
     return first->script()->getWarmUpCount() / first->script()->length() >
            second->script()->getWarmUpCount() / second->script()->length();
 }
 
 bool
 GlobalHelperThreadState::canStartIonCompile()
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -611,27 +611,28 @@ TypeOfOperation(const Value& v, JSRuntim
 static inline JSString*
 TypeOfObjectOperation(JSObject* obj, JSRuntime* rt)
 {
     JSType type = js::TypeOfObject(obj);
     return TypeName(type, *rt->commonNames);
 }
 
 static MOZ_ALWAYS_INLINE bool
-InitElemOperation(JSContext* cx, HandleObject obj, HandleValue idval, HandleValue val)
+InitElemOperation(JSContext* cx, jsbytecode* pc, HandleObject obj, HandleValue idval, HandleValue val)
 {
     MOZ_ASSERT(!val.isMagic(JS_ELEMENTS_HOLE));
     MOZ_ASSERT(!obj->getClass()->getProperty);
     MOZ_ASSERT(!obj->getClass()->setProperty);
 
     RootedId id(cx);
     if (!ToPropertyKey(cx, idval, &id))
         return false;
 
-    return DefineProperty(cx, obj, id, val, nullptr, nullptr, JSPROP_ENUMERATE);
+    unsigned flags = JSOp(*pc) == JSOP_INITHIDDENELEM ? 0 : JSPROP_ENUMERATE;
+    return DefineProperty(cx, obj, id, val, nullptr, nullptr, flags);
 }
 
 static MOZ_ALWAYS_INLINE bool
 InitArrayElemOperation(JSContext* cx, jsbytecode* pc, HandleObject obj, uint32_t index, HandleValue val)
 {
     JSOp op = JSOp(*pc);
     MOZ_ASSERT(op == JSOP_INITELEM_ARRAY || op == JSOP_INITELEM_INC);
 
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -1688,21 +1688,16 @@ CASE(EnableInterruptsPseudoOpcode)
     DISPATCH_TO(op);
 }
 
 /* Various 1-byte no-ops. */
 CASE(JSOP_NOP)
 CASE(JSOP_UNUSED14)
 CASE(JSOP_BACKPATCH)
 CASE(JSOP_UNUSED145)
-CASE(JSOP_UNUSED171)
-CASE(JSOP_UNUSED172)
-CASE(JSOP_UNUSED173)
-CASE(JSOP_UNUSED174)
-CASE(JSOP_UNUSED175)
 CASE(JSOP_UNUSED176)
 CASE(JSOP_UNUSED177)
 CASE(JSOP_UNUSED178)
 CASE(JSOP_UNUSED179)
 CASE(JSOP_UNUSED180)
 CASE(JSOP_UNUSED181)
 CASE(JSOP_UNUSED182)
 CASE(JSOP_UNUSED183)
@@ -3200,33 +3195,37 @@ CASE(JSOP_LAMBDA_ARROW)
 END_CASE(JSOP_LAMBDA_ARROW)
 
 CASE(JSOP_CALLEE)
     MOZ_ASSERT(REGS.fp()->isNonEvalFunctionFrame());
     PUSH_COPY(REGS.fp()->calleev());
 END_CASE(JSOP_CALLEE)
 
 CASE(JSOP_INITPROP_GETTER)
+CASE(JSOP_INITHIDDENPROP_GETTER)
 CASE(JSOP_INITPROP_SETTER)
+CASE(JSOP_INITHIDDENPROP_SETTER)
 {
     MOZ_ASSERT(REGS.stackDepth() >= 2);
 
     ReservedRooted<JSObject*> obj(&rootObject0, &REGS.sp[-2].toObject());
     ReservedRooted<PropertyName*> name(&rootName0, script->getName(REGS.pc));
     ReservedRooted<JSObject*> val(&rootObject1, &REGS.sp[-1].toObject());
 
     if (!InitGetterSetterOperation(cx, REGS.pc, obj, name, val))
         goto error;
 
     REGS.sp--;
 }
 END_CASE(JSOP_INITPROP_GETTER)
 
 CASE(JSOP_INITELEM_GETTER)
+CASE(JSOP_INITHIDDENELEM_GETTER)
 CASE(JSOP_INITELEM_SETTER)
+CASE(JSOP_INITHIDDENELEM_SETTER)
 {
     MOZ_ASSERT(REGS.stackDepth() >= 3);
 
     ReservedRooted<JSObject*> obj(&rootObject0, &REGS.sp[-3].toObject());
     ReservedRooted<Value> idval(&rootValue0, REGS.sp[-2]);
     ReservedRooted<JSObject*> val(&rootObject1, &REGS.sp[-1].toObject());
 
     if (!InitGetterSetterOperation(cx, REGS.pc, obj, idval, val))
@@ -3331,24 +3330,25 @@ CASE(JSOP_INITHIDDENPROP)
     if (!InitPropertyOperation(cx, JSOp(*REGS.pc), obj, id, rval))
         goto error;
 
     REGS.sp--;
 }
 END_CASE(JSOP_INITPROP)
 
 CASE(JSOP_INITELEM)
+CASE(JSOP_INITHIDDENELEM)
 {
     MOZ_ASSERT(REGS.stackDepth() >= 3);
     HandleValue val = REGS.stackHandleAt(-1);
     HandleValue id = REGS.stackHandleAt(-2);
 
     ReservedRooted<JSObject*> obj(&rootObject0, &REGS.sp[-3].toObject());
 
-    if (!InitElemOperation(cx, obj, id, val))
+    if (!InitElemOperation(cx, REGS.pc, obj, id, val))
         goto error;
 
     REGS.sp -= 2;
 }
 END_CASE(JSOP_INITELEM)
 
 CASE(JSOP_INITELEM_ARRAY)
 {
@@ -4321,26 +4321,32 @@ js::GetInitDataPropAttrs(JSOp op)
 
 bool
 js::InitGetterSetterOperation(JSContext* cx, jsbytecode* pc, HandleObject obj, HandleId id,
                               HandleObject val)
 {
     MOZ_ASSERT(val->isCallable());
     GetterOp getter;
     SetterOp setter;
-    unsigned attrs = JSPROP_ENUMERATE | JSPROP_SHARED;
+    unsigned attrs = JSPROP_SHARED;
 
     JSOp op = JSOp(*pc);
 
-    if (op == JSOP_INITPROP_GETTER || op == JSOP_INITELEM_GETTER) {
+    if (!IsHiddenInitOp(op))
+        attrs |= JSPROP_ENUMERATE;
+
+    if (op == JSOP_INITPROP_GETTER || op == JSOP_INITELEM_GETTER ||
+        op == JSOP_INITHIDDENPROP_GETTER || op == JSOP_INITHIDDENELEM_GETTER)
+    {
         getter = CastAsGetterOp(val);
         setter = nullptr;
         attrs |= JSPROP_GETTER;
     } else {
-        MOZ_ASSERT(op == JSOP_INITPROP_SETTER || op == JSOP_INITELEM_SETTER);
+        MOZ_ASSERT(op == JSOP_INITPROP_SETTER || op == JSOP_INITELEM_SETTER ||
+                   op == JSOP_INITHIDDENPROP_SETTER || op == JSOP_INITHIDDENELEM_SETTER);
         getter = nullptr;
         setter = CastAsSetterOp(val);
         attrs |= JSPROP_SETTER;
     }
 
     RootedValue scratch(cx);
     return DefineProperty(cx, obj, id, scratch, getter, setter, attrs);
 }
--- a/js/src/vm/Opcodes.h
+++ b/js/src/vm/Opcodes.h
@@ -1739,21 +1739,73 @@ 1234567890123456789012345678901234567890
      * scope coordinate is used for better error messages.
      *
      *   Category: Variables and Scopes
      *   Type: Aliased Variables
      *   Operands: uint8_t hops, uint24_t slot
      *   Stack: =>
      */ \
     macro(JSOP_THROWSETALIASEDCONST, 170, "throwsetaliasedconst", NULL, 5,  1,  1, JOF_SCOPECOORD|JOF_NAME|JOF_SET|JOF_DETECTING) \
-    macro(JSOP_UNUSED171,     171,"unused171",  NULL,     1,  0,  0,  JOF_BYTE) \
-    macro(JSOP_UNUSED172,     172,"unused172",  NULL,     1,  0,  0,  JOF_BYTE) \
-    macro(JSOP_UNUSED173,     173,"unused173",  NULL,     1,  0,  0,  JOF_BYTE) \
-    macro(JSOP_UNUSED174,     174,"unused174",  NULL,     1,  0,  0,  JOF_BYTE) \
-    macro(JSOP_UNUSED175,     175,"unused175",  NULL,     1,  0,  0,  JOF_BYTE) \
+    /*
+     * Initialize a non-enumerable getter in an object literal.
+     *
+     * Pops the top two values on the stack as 'val' and 'obj', defines
+     * getter of 'obj' as 'val', pushes 'obj' onto the stack.
+     *   Category: Literals
+     *   Type: Object
+     *   Operands: uint32_t nameIndex
+     *   Stack: obj, val => obj
+     */ \
+    macro(JSOP_INITHIDDENPROP_GETTER,  171, "inithiddenprop_getter",   NULL, 5,  2,  1, JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING) \
+    /*
+     * Initialize a non-enumerable setter in an object literal.
+     *
+     * Pops the top two values on the stack as 'val' and 'obj', defines
+     * setter of 'obj' as 'val', pushes 'obj' onto the stack.
+     *   Category: Literals
+     *   Type: Object
+     *   Operands: uint32_t nameIndex
+     *   Stack: obj, val => obj
+     */ \
+    macro(JSOP_INITHIDDENPROP_SETTER,  172, "inithiddenprop_setter",   NULL, 5,  2,  1, JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING) \
+    /*
+     * Initialize a non-enumerable numeric getter in an object literal like
+     * '{get 2() {}}'.
+     *
+     * Pops the top three values on the stack as 'val', 'id' and 'obj', defines
+     * 'id' getter of 'obj' as 'val', pushes 'obj' onto the stack.
+     *   Category: Literals
+     *   Type: Object
+     *   Operands:
+     *   Stack: obj, id, val => obj
+     */ \
+    macro(JSOP_INITHIDDENELEM_GETTER,  173, "inithiddenelem_getter",   NULL, 1,  3,  1, JOF_BYTE|JOF_ELEM|JOF_SET|JOF_DETECTING) \
+    /*
+     * Initialize a non-enumerable numeric setter in an object literal like
+     * '{set 2(v) {}}'.
+     *
+     * Pops the top three values on the stack as 'val', 'id' and 'obj', defines
+     * 'id' setter of 'obj' as 'val', pushes 'obj' onto the stack.
+     *   Category: Literals
+     *   Type: Object
+     *   Operands:
+     *   Stack: obj, id, val => obj
+     */ \
+    macro(JSOP_INITHIDDENELEM_SETTER, 174, "inithiddenelem_setter",   NULL, 1,  3,  1, JOF_BYTE|JOF_ELEM|JOF_SET|JOF_DETECTING) \
+    /*
+     * Initialize a non-enumerable numeric property in an object literal, like '{1: x}'.
+     *
+     * Pops the top three values on the stack as 'val', 'id' and 'obj', defines
+     * 'id' property of 'obj' as 'val', pushes 'obj' onto the stack.
+     *   Category: Literals
+     *   Type: Object
+     *   Operands:
+     *   Stack: obj, id, val => obj
+     */ \
+    macro(JSOP_INITHIDDENELEM,  175, "inithiddenelem",   NULL,         1,  3,  1, JOF_BYTE|JOF_ELEM|JOF_SET|JOF_DETECTING) \
     macro(JSOP_UNUSED176,     176,"unused176",  NULL,     1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED177,     177,"unused177",  NULL,     1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED178,     178,"unused178",  NULL,     1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED179,     179,"unused179",  NULL,     1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED180,     180,"unused180",  NULL,     1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED181,     181,"unused181",  NULL,     1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED182,     182,"unused182",  NULL,     1,  0,  0,  JOF_BYTE) \
     macro(JSOP_UNUSED183,     183,"unused183",  NULL,     1,  0,  0,  JOF_BYTE) \
--- a/js/src/vm/SavedFrame.h
+++ b/js/src/vm/SavedFrame.h
@@ -180,17 +180,17 @@ class SavedFrame : public NativeObject {
 
     static bool checkThis(JSContext* cx, CallArgs& args, const char* fnName,
                           MutableHandleObject frame);
 };
 
 struct SavedFrame::HashPolicy
 {
     typedef SavedFrame::Lookup              Lookup;
-    typedef PointerHasher<SavedFrame*, 3>   SavedFramePtrHasher;
+    typedef MovableCellHasher<SavedFrame*>  SavedFramePtrHasher;
     typedef PointerHasher<JSPrincipals*, 3> JSPrincipalsPtrHasher;
 
     static HashNumber hash(const Lookup& lookup);
     static bool       match(SavedFrame* existing, const Lookup& lookup);
 
     typedef ReadBarriered<SavedFrame*> Key;
     static void rekey(Key& key, const Key& newKey);
 };
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -1032,36 +1032,18 @@ SavedStacks::copyAsyncStack(JSContext* c
     return adoptAsyncStack(cx, frame, asyncCause, adoptedStack, maxFrameCount);
 }
 
 void
 SavedStacks::sweep(JSRuntime* rt)
 {
     if (frames.initialized()) {
         for (SavedFrame::Set::Enum e(frames); !e.empty(); e.popFront()) {
-            JSObject* obj = e.front().unbarrieredGet();
-            JSObject* temp = obj;
-
-            if (IsAboutToBeFinalizedUnbarriered(&obj)) {
+            if (IsAboutToBeFinalized(&e.mutableFront()))
                 e.removeFront();
-            } else {
-                SavedFrame* frame = &obj->as<SavedFrame>();
-
-                SavedFrame* parent = frame->getParent();
-                bool parentMoved = parent && IsForwarded(parent);
-                if (parentMoved)
-                    parent = Forwarded(parent);
-
-                if (obj != temp || parentMoved) {
-                    MOZ_ASSERT(!IsForwarded(frame));
-                    SavedFrame::Lookup newLocation(*frame);
-                    newLocation.parent = parent;
-                    e.rekeyFront(newLocation, ReadBarriered<SavedFrame*>(frame));
-                }
-            }
         }
     }
 
     sweepPCLocationMap();
 }
 
 void
 SavedStacks::trace(JSTracer* trc)
--- a/js/src/vm/Stopwatch.cpp
+++ b/js/src/vm/Stopwatch.cpp
@@ -1,14 +1,23 @@
 #include "vm/Stopwatch.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/IntegerTypeTraits.h"
 #include "mozilla/unused.h"
 
+#if defined(XP_WIN)
+#include <processthreadsapi.h>
+#include <windows.h>
+#endif // defined(XP_WIN)
+
+#include "jscompartment.h"
+
+#include "gc/Zone.h"
+
 namespace js {
 
 bool
 PerformanceMonitoring::addRecentGroup(PerformanceGroup* group)
 {
   if (group->isUsedInThisIteration())
     return true;
 
--- a/js/src/vm/Stopwatch.h
+++ b/js/src/vm/Stopwatch.h
@@ -2,16 +2,21 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 vm_Stopwatch_h
 #define vm_Stopwatch_h
 
+#include "mozilla/RefPtr.h"
+#include "mozilla/Vector.h"
+
+#include "jsapi.h"
+
 /*
   An API for following in real-time the amount of CPU spent executing
   webpages, add-ons, etc.
 */
 
 namespace js {
 
 typedef mozilla::Vector<RefPtr<js::PerformanceGroup>> GroupVector;
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -337,17 +337,17 @@ struct JSStructuredCloneWriter {
     // For Map: Key followed by value
     // For Set: Key
     // For SavedFrame: parent SavedFrame
     AutoValueVector entries;
 
     // The "memory" list described in the HTML5 internal structured cloning algorithm.
     // memory is a superset of objs; items are never removed from Memory
     // until a serialization operation is finished
-    using CloneMemory = TraceableHashMap<JSObject*, uint32_t>;
+    using CloneMemory = TraceableHashMap<JSObject*, uint32_t, MovableCellHasher<JSObject*>>;
     Rooted<CloneMemory> memory;
 
     // The user defined callbacks that will be used for cloning.
     const JSStructuredCloneCallbacks* callbacks;
 
     // Any value passed to JS_WriteStructuredClone.
     void* closure;
 
--- a/js/xpconnect/idl/xpccomponents.idl
+++ b/js/xpconnect/idl/xpccomponents.idl
@@ -118,17 +118,17 @@ interface nsIXPCComponents_utils_Sandbox
 interface ScheduledGCCallback : nsISupports
 {
     void callback();
 };
 
 /**
 * interface of Components.utils
 */
-[scriptable, uuid(eaeab2c0-ada3-4c22-b36d-70320dd923ba)]
+[scriptable, uuid(3ce3a6f8-2b59-439c-a57e-74e7b122fb3c)]
 interface nsIXPCComponents_Utils : nsISupports
 {
 
     /* reportError is designed to be called from JavaScript only.
      *
      * It will report a JS Error object to the JS console, and return. It
      * is meant for use in exception handler blocks which want to "eat"
      * an exception, but still want to report it to the console.
@@ -339,31 +339,16 @@ interface nsIXPCComponents_Utils : nsISu
     void schedulePreciseShrinkingGC(in ScheduledGCCallback callback);
 
     /*
      * In a debug build, unlink any ghost windows. This is only for debugging
      * leaks, and can cause bad things to happen if called.
      */
     void unlinkGhostWindows();
 
-    /**
-     * Return the keys in a weak map.  This operation is
-     * non-deterministic because it is affected by the scheduling of the
-     * garbage collector and the cycle collector.
-     *
-     * This should only be used to write tests of the interaction of
-     * the GC and CC with weak maps.
-     *
-     * @param aMap weak map or other JavaScript value
-     * @returns If aMap is a weak map object, return the keys of the weak
-                map as an array.  Otherwise, return undefined.
-     */
-    [implicit_jscontext]
-    jsval nondeterministicGetWeakMapKeys(in jsval aMap);
-
     [implicit_jscontext]
     jsval getJSTestingFunctions();
 
     /*
      * To be called from JS only.
      *
      * Call 'function', using the provided stack as the async stack responsible
      * for the call, and propagate its return value or the exception it throws.
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -2654,33 +2654,16 @@ nsXPCComponents_Utils::UnlinkGhostWindow
     nsWindowMemoryReporter::UnlinkGhostWindows();
     return NS_OK;
 #else
     return NS_ERROR_NOT_IMPLEMENTED;
 #endif
 }
 
 NS_IMETHODIMP
-nsXPCComponents_Utils::NondeterministicGetWeakMapKeys(HandleValue aMap,
-                                                      JSContext* aCx,
-                                                      MutableHandleValue aKeys)
-{
-    if (!aMap.isObject()) {
-        aKeys.setUndefined();
-        return NS_OK;
-    }
-    RootedObject objRet(aCx);
-    RootedObject mapObj(aCx, &aMap.toObject());
-    if (!JS_NondeterministicGetWeakMapKeys(aCx, mapObj, &objRet))
-        return NS_ERROR_OUT_OF_MEMORY;
-     aKeys.set(objRet ? ObjectValue(*objRet) : UndefinedValue());
-    return NS_OK;
-}
-
-NS_IMETHODIMP
 nsXPCComponents_Utils::GetJSTestingFunctions(JSContext* cx,
                                              MutableHandleValue retval)
 {
     JSObject* obj = js::GetTestingFunctions(cx);
     if (!obj)
         return NS_ERROR_XPC_JAVASCRIPT_ERROR;
     retval.setObject(*obj);
     return NS_OK;
--- a/js/xpconnect/tests/chrome/test_getweakmapkeys.xul
+++ b/js/xpconnect/tests/chrome/test_getweakmapkeys.xul
@@ -17,26 +17,26 @@ https://bugzilla.mozilla.org/show_bug.cg
   <!-- test code goes here -->
   <script type="application/javascript">
   <![CDATA[
   /** Test for Bug 688277 **/
 
   let Cu = Components.utils;
 
   /* Fail gracefully if junk is passed in. */
-  is(Cu.nondeterministicGetWeakMapKeys(11), undefined,
+  is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(11), undefined,
     "nondeterministicGetWeakMapKeys should return undefined for non-objects");
-  is(Cu.nondeterministicGetWeakMapKeys({}), undefined,
+  is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys({}), undefined,
     "nondeterministicGetWeakMapKeys should return undefined for non-weakmap objects");
-  is(Cu.nondeterministicGetWeakMapKeys(null), undefined,
+  is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(null), undefined,
     "nondeterministicGetWeakMapKeys should return undefined for null");
 
   /* return an empty array for an empty WeakMap */
   let mempty = new WeakMap();
-  is(Cu.nondeterministicGetWeakMapKeys(mempty).length, 0,
+  is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(mempty).length, 0,
     "nondeterministicGetWeakMapKeys should return empty array for empty weakmap");
 
   /* Test freeing/nonfreeing. */
   let m = new WeakMap();
   let liveKeys = new Array();
 
   let add_elements = function () {
     let k1 = {};
@@ -48,17 +48,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 
     let k = {};
     m.set(k, k); /* simple cycle */
   };
 
   add_elements();
 
   Cu.schedulePreciseGC(function () {
-    let keys = Cu.nondeterministicGetWeakMapKeys(m);
+    let keys = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(m);
     is(liveKeys.length, 1, "Wrong number of live keys.");
     is(keys.length, 1, "Should have one weak map key.");
     is(m.get(keys[0]), "live1", "live1 should be live");
     SimpleTest.finish();
   });
 
   SimpleTest.waitForExplicitFinish();
 
--- a/js/xpconnect/tests/chrome/test_paris_weakmap_keys.xul
+++ b/js/xpconnect/tests/chrome/test_paris_weakmap_keys.xul
@@ -62,17 +62,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 
   SimpleTest.waitForExplicitFinish();
 
   Cu.schedulePreciseGC(function () {
     SpecialPowers.DOMWindowUtils.cycleCollect();
     SpecialPowers.DOMWindowUtils.garbageCollect();
     SpecialPowers.DOMWindowUtils.garbageCollect();
 
-    is(Cu.nondeterministicGetWeakMapKeys(live_map).length, 1,
+    is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(live_map).length, 1,
        "Live nsISupports new DOM bindings wrappercached native weak map key should not be removed.");
 
     is(live_map.get(get_div_style()), 12345, "Live map should have live style with right value after GC.");
 
     SimpleTest.finish();
   });
 
   ]]>
--- a/js/xpconnect/tests/chrome/test_watchpoints.xul
+++ b/js/xpconnect/tests/chrome/test_watchpoints.xul
@@ -26,17 +26,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   let make_weak_ref = function (obj) {
     let m = new WeakMap;
     m.set(obj, {});
     return m;
   };
 
   /* Check to see if a weak reference is dead. */
   let weak_ref_dead = function (r) {
-    return Cu.nondeterministicGetWeakMapKeys(r).length == 0;
+    return ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(r).length == 0;
   }
 
 
   let make_cycle = function () {
     var p = document.createElement("p");
     p.children.x = p;
     var f = function() { };
     p.watch("y", f);
--- a/js/xpconnect/tests/chrome/test_weakmap_keys_preserved2.xul
+++ b/js/xpconnect/tests/chrome/test_weakmap_keys_preserved2.xul
@@ -49,30 +49,30 @@ https://bugzilla.mozilla.org/show_bug.cg
     sandbox.wrapper = wrappee;
     sandbox.value = dead_dom;
     let map = Cu.evalInSandbox("wm = new WeakMap(); wm.set(wrapper, value); wm", sandbox);
     sandbox.wrapper = null;
     sandbox.value = null;
 
     live_dom.xyzabc = {wrappee: wrappee, m: map, sb: sandbox};
 
-    let key = Cu.nondeterministicGetWeakMapKeys(map)[0];
+    let key = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(map)[0];
     let value = map.get(key);
     is(value.children.length, 1, "children have wrong length");
   }
 
   wrappers_as_keys_test();
 
   let check_wrappers_as_keys = function () {
     let live_dom = window.eeeevent.data.dummy;
     let live_map = live_dom.xyzabc.m;
     let sandbox = live_dom.xyzabc.sb;
-    is(Cu.nondeterministicGetWeakMapKeys(live_map).length, 1,
+    is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(live_map).length, 1,
       "Map should not be empty.");
-    let key = Cu.nondeterministicGetWeakMapKeys(live_map)[0];
+    let key = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(live_map)[0];
     let value = live_map.get(key);
     is(value.children.length, 1, "children have wrong length");
   }
 
   Cu.schedulePreciseGC(function () {
     SpecialPowers.DOMWindowUtils.cycleCollect();
     SpecialPowers.DOMWindowUtils.garbageCollect();
 
--- a/js/xpconnect/tests/chrome/test_weakmaps.xul
+++ b/js/xpconnect/tests/chrome/test_weakmaps.xul
@@ -26,17 +26,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   let make_weak_ref = function (obj) {
     let m = new WeakMap;
     m.set(obj, {});
     return m;
   };
 
   /* Check to see if a weak reference is dead. */
   let weak_ref_dead = function (r) {
-    return Cu.nondeterministicGetWeakMapKeys(r).length == 0;
+    return ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(r).length == 0;
   }
 
   /* Deterministically grab an arbitrary DOM element. */
   let get_live_dom = function () {
     let elems = document.getElementsByTagName("a");
     return elems[0];
   };
 
@@ -113,25 +113,25 @@ https://bugzilla.mozilla.org/show_bug.cg
     ok(weak_ref_dead(basic_weak_ref), "Dead value was kept alive.");
     ok(weak_ref_dead(basic_map_weak_ref), "Dead map was kept alive.");
 
     // check the live gray map
     is(live_map.get(live_key).my_key, 'live_live',
       "Live key should have the same value in live map.");
     is(live_map.get(black_key).my_key, 'live_black',
       "Black key should have the same value in live map.");
-    is(Cu.nondeterministicGetWeakMapKeys(live_map).length, 2,
+    is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(live_map).length, 2,
       "Live map should have two entries.");
 
     // check the live black map
     is(black_map.get(live_key).my_key, 'black_live',
       "Live key should have the same value in black map.");
     is(black_map.get(black_key).my_key, 'black_black',
       "Black key should have the same value in black map.");
-    is(Cu.nondeterministicGetWeakMapKeys(black_map).length, 2,
+    is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(black_map).length, 2,
       "Black map should have two entries.");    
 
   };
 
 
   /* live gray chained weak map entries, involving the cycle collector. */
   let chainm = new WeakMap;
   let num_chains = 5;
@@ -245,26 +245,26 @@ https://bugzilla.mozilla.org/show_bug.cg
     SpecialPowers.DOMWindowUtils.cycleCollect();
     SpecialPowers.DOMWindowUtils.garbageCollect();
     SpecialPowers.DOMWindowUtils.garbageCollect();
 
     ok(weak_ref_dead(weakref), "Garbage gray cycle should be collected.");
 
     check_nested_cc_maps();
 
-    is(Cu.nondeterministicGetWeakMapKeys(garbage_map).length, 0, "Chained garbage weak map entries should not leak.");
+    is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(garbage_map).length, 0, "Chained garbage weak map entries should not leak.");
 
     check_basic_unit();
 
     // fixed by Bug 680937
-    is(Cu.nondeterministicGetWeakMapKeys(wn_garbage_map).length, 0,
+    is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(wn_garbage_map).length, 0,
        "Chained garbage WN weak map entries should not leak.");
 
     // fixed by Bug 680937
-    is(Cu.nondeterministicGetWeakMapKeys(wn_live_map).length, 1,
+    is(ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(wn_live_map).length, 1,
        "Live weak map wrapped native key should not be removed.");
 
     ok(wn_live_map.has(get_live_dom()), "Live map should have live dom.");
 
     SimpleTest.finish();
   });
 
   ]]>
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -3127,17 +3127,17 @@ SortConfigurations(nsTArray<nsIWidget::C
       for (uint32_t j = 0; j < pluginsToMove.Length(); ++j) {
         if (i == j)
           continue;
         nsIntRect bounds;
         pluginsToMove[j].mChild->GetBoundsUntyped(bounds);
         nsAutoTArray<nsIntRect,1> clipRects;
         pluginsToMove[j].mChild->GetWindowClipRegion(&clipRects);
         if (HasOverlap(bounds.TopLeft(), clipRects,
-                       config->mBounds.TopLeft(),
+                       config->mBounds.ToUnknownRect().TopLeft(),
                        config->mClipRegion)) {
           foundOverlap = true;
           break;
         }
       }
       if (!foundOverlap)
         break;
     }
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -723,17 +723,17 @@ nsBlockFrame::GetMinISize(nsRenderingCon
           // behavior for calc(10%-3px).
           const nsStyleCoord &indent = StyleText()->mTextIndent;
           if (indent.ConvertsToLength())
             data.currentLine += nsRuleNode::ComputeCoordPercentCalc(indent, 0);
         }
         // XXX Bug NNNNNN Should probably handle percentage text-indent.
 
         data.line = &line;
-        data.lineContainer = curFrame;
+        data.SetLineContainer(curFrame);
         nsIFrame *kid = line->mFirstChild;
         for (int32_t i = 0, i_end = line->GetChildCount(); i != i_end;
              ++i, kid = kid->GetNextSibling()) {
           kid->AddInlineMinISize(aRenderingContext, &data);
         }
       }
 #ifdef DEBUG
       if (gNoisyIntrinsic) {
@@ -808,17 +808,17 @@ nsBlockFrame::GetPrefISize(nsRenderingCo
           // behavior for calc(10%-3px).
           const nsStyleCoord &indent = StyleText()->mTextIndent;
           if (indent.ConvertsToLength())
             data.currentLine += nsRuleNode::ComputeCoordPercentCalc(indent, 0);
         }
         // XXX Bug NNNNNN Should probably handle percentage text-indent.
 
         data.line = &line;
-        data.lineContainer = curFrame;
+        data.SetLineContainer(curFrame);
         nsIFrame *kid = line->mFirstChild;
         for (int32_t i = 0, i_end = line->GetChildCount(); i != i_end;
              ++i, kid = kid->GetNextSibling()) {
           kid->AddInlinePrefISize(aRenderingContext, &data);
         }
       }
 #ifdef DEBUG
       if (gNoisyIntrinsic) {
@@ -882,17 +882,17 @@ nsBlockFrame::GetPrefWidthTightBounds(ns
           const nsStyleCoord &indent = StyleText()->mTextIndent;
           if (indent.ConvertsToLength()) {
             data.currentLine += nsRuleNode::ComputeCoordPercentCalc(indent, 0);
           }
         }
         // XXX Bug NNNNNN Should probably handle percentage text-indent.
 
         data.line = &line;
-        data.lineContainer = curFrame;
+        data.SetLineContainer(curFrame);
         nsIFrame *kid = line->mFirstChild;
         for (int32_t i = 0, i_end = line->GetChildCount(); i != i_end;
              ++i, kid = kid->GetNextSibling()) {
           rv = kid->GetPrefWidthTightBounds(aRenderingContext, &childX,
                                             &childXMost);
           NS_ENSURE_SUCCESS(rv, rv);
           *aX = std::min(*aX, data.currentLine + childX);
           *aXMost = std::max(*aXMost, data.currentLine + childXMost);
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -845,17 +845,17 @@ nsContainerFrame::DoInlineIntrinsicISize
     std::max(GetCoord(stylePadding->mPadding.Get(endSide), 0), 0) +
     styleBorder->GetComputedBorderWidth(endSide) +
     GetCoord(styleMargin->mMargin.Get(endSide), 0);
   if (MOZ_UNLIKELY(!sliceBreak)) {
     clonePBM += endPBM;
   }
 
   const nsLineList_iterator* savedLine = aData->line;
-  nsIFrame* const savedLineContainer = aData->lineContainer;
+  nsIFrame* const savedLineContainer = aData->LineContainer();
 
   nsContainerFrame *lastInFlow;
   for (nsContainerFrame *nif = this; nif;
        nif = static_cast<nsContainerFrame*>(nif->GetNextInFlow())) {
     if (aData->currentLine == 0) {
       aData->currentLine = clonePBM;
     }
     for (nsIFrame* kid : nif->mFrames) {
@@ -865,23 +865,23 @@ nsContainerFrame::DoInlineIntrinsicISize
       else
         kid->AddInlinePrefISize(aRenderingContext,
                                 static_cast<InlinePrefISizeData*>(aData));
     }
 
     // After we advance to our next-in-flow, the stored line and line container
     // may no longer be correct. Just forget them.
     aData->line = nullptr;
-    aData->lineContainer = nullptr;
+    aData->SetLineContainer(nullptr);
 
     lastInFlow = nif;
   }
 
   aData->line = savedLine;
-  aData->lineContainer = savedLineContainer;
+  aData->SetLineContainer(savedLineContainer);
 
   // This goes at the end no matter how things are broken and how
   // messy the bidi situations are, since per CSS2.1 section 8.6
   // (implemented in bug 328168), the endSide border is always on the
   // last line.
   // We reached the last-in-flow, but it might have a next bidi
   // continuation, in which case that continuation should handle
   // the endSide border.
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4110,39 +4110,37 @@ nsIFrame::InlinePrefISizeData::ForceBrea
             // preferred widths accumulated for floats that have already
             // been cleared past
     nscoord floats_done = 0,
             // preferred widths accumulated for floats that have not yet
             // been cleared past
             floats_cur_left = 0,
             floats_cur_right = 0;
 
-    WritingMode wm = lineContainer->GetWritingMode();
-
     for (uint32_t i = 0, i_end = floats.Length(); i != i_end; ++i) {
       const FloatInfo& floatInfo = floats[i];
       const nsStyleDisplay *floatDisp = floatInfo.Frame()->StyleDisplay();
-      uint8_t breakType = floatDisp->PhysicalBreakType(wm);
+      uint8_t breakType = floatDisp->PhysicalBreakType(lineContainerWM);
       if (breakType == NS_STYLE_CLEAR_LEFT ||
           breakType == NS_STYLE_CLEAR_RIGHT ||
           breakType == NS_STYLE_CLEAR_BOTH) {
         nscoord floats_cur = NSCoordSaturatingAdd(floats_cur_left,
                                                   floats_cur_right);
         if (floats_cur > floats_done) {
           floats_done = floats_cur;
         }
         if (breakType != NS_STYLE_CLEAR_RIGHT) {
           floats_cur_left = 0;
         }
         if (breakType != NS_STYLE_CLEAR_LEFT) {
           floats_cur_right = 0;
         }
       }
 
-      uint8_t floatStyle = floatDisp->PhysicalFloats(wm);
+      uint8_t floatStyle = floatDisp->PhysicalFloats(lineContainerWM);
       nscoord& floats_cur = floatStyle == NS_STYLE_FLOAT_LEFT
                               ? floats_cur_left : floats_cur_right;
       nscoord floatWidth = floatInfo.Width();
       // Negative-width floats don't change the available space so they
       // shouldn't change our intrinsic line width either.
       floats_cur =
         NSCoordSaturatingAdd(floats_cur, std::max(0, floatWidth));
     }
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3701,18 +3701,21 @@ static nsSize
 GetScrollPortSizeExcludingHeadersAndFooters(nsIFrame* aViewportFrame,
                                             const nsRect& aScrollPort)
 {
   nsTArray<TopAndBottom> list;
   nsFrameList fixedFrames = aViewportFrame->GetChildList(nsIFrame::kFixedList);
   for (nsFrameList::Enumerator iterator(fixedFrames); !iterator.AtEnd();
        iterator.Next()) {
     nsIFrame* f = iterator.get();
-    nsRect r = f->GetRect().Intersect(aScrollPort);
-    if (r.x == 0 && r.width == aScrollPort.width &&
+    nsRect r = f->GetRectRelativeToSelf();
+    r = nsLayoutUtils::TransformFrameRectToAncestor(f, r, aViewportFrame);
+    r = r.Intersect(aScrollPort);
+    if ((r.width >= aScrollPort.width / 2 ||
+         r.width >= NSIntPixelsToAppUnits(800, AppUnitsPerCSSPixel())) &&
         r.height <= aScrollPort.height/3) {
       list.AppendElement(TopAndBottom(r.y, r.YMost()));
     }
   }
 
   list.Sort(TopComparator());
   nscoord headerBottom = 0;
   for (uint32_t i = 0; i < list.Length(); ++i) {
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -1558,43 +1558,64 @@ public:
    * information about whitespace (for both collapsing and trimming).
    */
   struct InlineIntrinsicISizeData {
     InlineIntrinsicISizeData()
       : line(nullptr)
       , lineContainer(nullptr)
       , prevLines(0)
       , currentLine(0)
+      , trailingWhitespace(0)
       , skipWhitespace(true)
-      , trailingWhitespace(0)
     {}
 
     // The line. This may be null if the inlines are not associated with
     // a block or if we just don't know the line.
     const nsLineList_iterator* line;
 
-    // The line container.
+    // The line container. Private, to ensure we always use SetLineContainer
+    // to update it (so that we have a chance to store the lineContainerWM).
+    //
+    // Note that nsContainerFrame::DoInlineIntrinsicISize will clear the
+    // |line| and |lineContainer| fields when following a next-in-flow link,
+    // so we must not assume these can always be dereferenced.
+  private:
     nsIFrame* lineContainer;
 
+    // Setter and getter for the lineContainer field:
+  public:
+    void SetLineContainer(nsIFrame* aLineContainer)
+    {
+      lineContainer = aLineContainer;
+      if (lineContainer) {
+        lineContainerWM = lineContainer->GetWritingMode();
+      }
+    }
+    nsIFrame* LineContainer() const { return lineContainer; }
+
     // The maximum intrinsic width for all previous lines.
     nscoord prevLines;
 
     // The maximum intrinsic width for the current line.  At a line
     // break (mandatory for preferred width; allowed for minimum width),
     // the caller should call |Break()|.
     nscoord currentLine;
 
+    // This contains the width of the trimmable whitespace at the end of
+    // |currentLine|; it is zero if there is no such whitespace.
+    nscoord trailingWhitespace;
+
     // True if initial collapsable whitespace should be skipped.  This
     // should be true at the beginning of a block, after hard breaks
     // and when the last text ended with whitespace.
     bool skipWhitespace;
 
-    // This contains the width of the trimmable whitespace at the end of
-    // |currentLine|; it is zero if there is no such whitespace.
-    nscoord trailingWhitespace;
+    // Writing mode of the line container (stored here so that we don't
+    // lose track of it if the lineContainer field is reset).
+    mozilla::WritingMode lineContainerWM;
 
     // Floats encountered in the lines.
     class FloatInfo {
     public:
       FloatInfo(const nsIFrame* aFrame, nscoord aWidth)
         : mFrame(aFrame), mWidth(aWidth)
       { }
       const nsIFrame* Frame() const { return mFrame; }
--- a/layout/generic/nsPluginFrame.cpp
+++ b/layout/generic/nsPluginFrame.cpp
@@ -403,17 +403,18 @@ nsPluginFrame::GetWidgetConfiguration(ns
     // geometry updates and this should not be called. But apparently we
     // have bugs where mWidget sometimes is toplevel here. Bail out.
     NS_ERROR("Plugin widgets registered for geometry updates should not be toplevel");
     return;
   }
 
   nsIWidget::Configuration* configuration = aConfigurations->AppendElement();
   configuration->mChild = mWidget;
-  configuration->mBounds = mNextConfigurationBounds;
+  configuration->mBounds =
+    LayoutDeviceIntRect::FromUnknownRect(mNextConfigurationBounds);
   configuration->mClipRegion = mNextConfigurationClipRegion;
 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
   if (XRE_IsContentProcess()) {
     configuration->mWindowID = (uintptr_t)mWidget->GetNativeData(NS_NATIVE_PLUGIN_PORT);
     configuration->mVisible = mWidget->IsVisible();
   }
 #endif // defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
 }
--- a/layout/generic/nsRubyBaseContainerFrame.cpp
+++ b/layout/generic/nsRubyBaseContainerFrame.cpp
@@ -143,23 +143,23 @@ CalculateColumnPrefISize(nsRenderingCont
 {
   nscoord max = 0;
   uint32_t levelCount = aEnumerator.GetLevelCount();
   for (uint32_t i = 0; i < levelCount; i++) {
     nsIFrame* frame = aEnumerator.GetFrameAtLevel(i);
     if (frame) {
       nsIFrame::InlinePrefISizeData data;
       if (i == 0) {
-        data.lineContainer = aBaseISizeData->lineContainer;
+        data.SetLineContainer(aBaseISizeData->LineContainer());
         data.skipWhitespace = aBaseISizeData->skipWhitespace;
         data.trailingWhitespace = aBaseISizeData->trailingWhitespace;
       } else {
         // The line container of ruby text frames is their parent,
         // ruby text container frame.
-        data.lineContainer = frame->GetParent();
+        data.SetLineContainer(frame->GetParent());
       }
       frame->AddInlinePrefISize(aRenderingContext, &data);
       MOZ_ASSERT(data.prevLines == 0, "Shouldn't have prev lines");
       max = std::max(max, data.currentLine);
       if (i == 0) {
         aBaseISizeData->skipWhitespace = data.skipWhitespace;
         aBaseISizeData->trailingWhitespace = data.trailingWhitespace;
       }
@@ -177,17 +177,17 @@ nsRubyBaseContainerFrame::AddInlineMinIS
 {
   AutoRubyTextContainerArray textContainers(this);
 
   for (uint32_t i = 0, iend = textContainers.Length(); i < iend; i++) {
     if (textContainers[i]->IsSpanContainer()) {
       // Since spans are not breakable internally, use our pref isize
       // directly if there is any span.
       nsIFrame::InlinePrefISizeData data;
-      data.lineContainer = aData->lineContainer;
+      data.SetLineContainer(aData->LineContainer());
       data.skipWhitespace = aData->skipWhitespace;
       data.trailingWhitespace = aData->trailingWhitespace;
       AddInlinePrefISize(aRenderingContext, &data);
       aData->currentLine += data.currentLine;
       if (data.currentLine > 0) {
         aData->atStartOfLine = false;
       }
       aData->skipWhitespace = data.skipWhitespace;
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -7638,17 +7638,17 @@ void nsTextFrame::MarkIntrinsicISizesDir
 void
 nsTextFrame::AddInlineMinISizeForFlow(nsRenderingContext *aRenderingContext,
                                       nsIFrame::InlineMinISizeData *aData,
                                       TextRunType aTextRunType)
 {
   uint32_t flowEndInTextRun;
   gfxContext* ctx = aRenderingContext->ThebesContext();
   gfxSkipCharsIterator iter =
-    EnsureTextRun(aTextRunType, ctx, aData->lineContainer,
+    EnsureTextRun(aTextRunType, ctx, aData->LineContainer(),
                   aData->line, &flowEndInTextRun);
   gfxTextRun *textRun = GetTextRun(aTextRunType);
   if (!textRun)
     return;
 
   // Pass null for the line container. This will disable tab spacing, but that's
   // OK since we can't really handle tabs for intrinsic sizing anyway.
   const nsStyleText* textStyle = StyleText();
@@ -7787,22 +7787,22 @@ nsTextFrame::AddInlineMinISize(nsRenderi
   // nsContinuingTextFrame does nothing for AddInlineMinISize; all text frames
   // in the flow are handled right here.
   for (f = this; f; f = static_cast<nsTextFrame*>(f->GetNextContinuation())) {
     // f->GetTextRun(nsTextFrame::eNotInflated) could be null if we
     // haven't set up textruns yet for f.  Except in OOM situations,
     // lastTextRun will only be null for the first text frame.
     if (f == this || f->GetTextRun(trtype) != lastTextRun) {
       nsIFrame* lc;
-      if (aData->lineContainer &&
-          aData->lineContainer != (lc = FindLineContainer(f))) {
+      if (aData->LineContainer() &&
+          aData->LineContainer() != (lc = FindLineContainer(f))) {
         NS_ASSERTION(f != this, "wrong InlineMinISizeData container"
                                 " for first continuation");
         aData->line = nullptr;
-        aData->lineContainer = lc;
+        aData->SetLineContainer(lc);
       }
 
       // This will process all the text frames that share the same textrun as f.
       f->AddInlineMinISizeForFlow(aRenderingContext, aData, trtype);
       lastTextRun = f->GetTextRun(trtype);
     }
   }
 }
@@ -7812,17 +7812,17 @@ nsTextFrame::AddInlineMinISize(nsRenderi
 void
 nsTextFrame::AddInlinePrefISizeForFlow(nsRenderingContext *aRenderingContext,
                                        nsIFrame::InlinePrefISizeData *aData,
                                        TextRunType aTextRunType)
 {
   uint32_t flowEndInTextRun;
   gfxContext* ctx = aRenderingContext->ThebesContext();
   gfxSkipCharsIterator iter =
-    EnsureTextRun(aTextRunType, ctx, aData->lineContainer,
+    EnsureTextRun(aTextRunType, ctx, aData->LineContainer(),
                   aData->line, &flowEndInTextRun);
   gfxTextRun *textRun = GetTextRun(aTextRunType);
   if (!textRun)
     return;
 
   // Pass null for the line container. This will disable tab spacing, but that's
   // OK since we can't really handle tabs for intrinsic sizing anyway.
   
@@ -7925,22 +7925,22 @@ nsTextFrame::AddInlinePrefISize(nsRender
   // nsContinuingTextFrame does nothing for AddInlineMinISize; all text frames
   // in the flow are handled right here.
   for (f = this; f; f = static_cast<nsTextFrame*>(f->GetNextContinuation())) {
     // f->GetTextRun(nsTextFrame::eNotInflated) could be null if we
     // haven't set up textruns yet for f.  Except in OOM situations,
     // lastTextRun will only be null for the first text frame.
     if (f == this || f->GetTextRun(trtype) != lastTextRun) {
       nsIFrame* lc;
-      if (aData->lineContainer &&
-          aData->lineContainer != (lc = FindLineContainer(f))) {
+      if (aData->LineContainer() &&
+          aData->LineContainer() != (lc = FindLineContainer(f))) {
         NS_ASSERTION(f != this, "wrong InlinePrefISizeData container"
                                 " for first continuation");
         aData->line = nullptr;
-        aData->lineContainer = lc;
+        aData->SetLineContainer(lc);
       }
 
       // This will process all the text frames that share the same textrun as f.
       f->AddInlinePrefISizeForFlow(aRenderingContext, aData, trtype);
       lastTextRun = f->GetTextRun(trtype);
     }
   }
 }
--- a/layout/generic/test/mochitest.ini
+++ b/layout/generic/test/mochitest.ini
@@ -108,17 +108,17 @@ skip-if = buildapp == 'mulet' || buildap
 [test_movement_by_characters.html]
 [test_movement_by_words.html]
 # Disable the caret movement by word test on Linux because the shortcut keys
 # are defined in system level.  So, it depends on the environment.
 # Disable on Windows for too many intermittent failures (bug 916143).
 skip-if = (toolkit == "gtk2") || (toolkit == "gtk3") || (os == "win")
 [test_overflow_event.html]
 [test_page_scroll_with_fixed_pos.html]
-skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(opened window too small?) b2g-desktop(opened window too small?)
+skip-if = buildapp == 'mulet' || (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(opened window too small?) b2g-desktop(opened window too small?)
 support-files = page_scroll_with_fixed_pos_window.html
 [test_plugin_clipping.xhtml]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || e10s #Bug 931116, b2g desktop specific, initial triage
 [test_plugin_clipping2.xhtml]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || e10s #Bug 931116, b2g desktop specific, initial triage
 [test_plugin_clipping_transformed.xhtml]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || e10s #Bug 931116, b2g desktop specific, initial triage
 [test_plugin_clipping_table.xhtml]
--- a/layout/generic/test/page_scroll_with_fixed_pos_window.html
+++ b/layout/generic/test/page_scroll_with_fixed_pos_window.html
@@ -78,21 +78,38 @@ function runTest() {
           is(document.documentElement.scrollTop, fullPageScrollDown - 13,
              "Ignore elements that don't span the entire viewport side");
           document.getElementById("top").style.width = "100%";
 
           showFixedPosElements2(true);
           scrollDownOnePageWithContinuation(function() {
             is(document.documentElement.scrollTop, fullPageScrollDown - (10 + 11 + 9 + 12),
                "Combine multiple overlapping elements");
+            showFixedPosElements2(false);
 
-            // Scroll back up so test results are visible
-            document.documentElement.scrollTop = 0;
-            SimpleTest.finish();
-            window.close();
+            document.getElementById("top").style.width = "400px";
+            scrollDownOnePageWithContinuation(function() {
+              is(document.documentElement.scrollTop, fullPageScrollDown - (10 + 13),
+                 "Don't ignore elements that span more than half the viewport side");
+              document.getElementById("top").style.width = "100%";
+
+              document.getElementById("top").style.top = "-40px";
+              document.getElementById("top").style.transform = "translateY(38px)";
+              scrollDownOnePageWithContinuation(function() {
+                is(document.documentElement.scrollTop,
+                   fullPageScrollDown - (10 + 13 - 40 + 38),
+                   "Account for offset and transform");
+                document.getElementById("top").style.width = "100%";
+
+                // Scroll back up so test results are visible
+                document.documentElement.scrollTop = 0;
+                SimpleTest.finish();
+                window.close();
+              });
+            });
           });
         });
       });
     });
   });
 }
 </script>
 </pre>
--- a/layout/xul/nsMenuPopupFrame.cpp
+++ b/layout/xul/nsMenuPopupFrame.cpp
@@ -1496,17 +1496,17 @@ nsMenuPopupFrame::SetPopupPosition(nsIFr
   NS_ASSERTION(view, "popup with no view");
 
   // Offset the position by the width and height of the borders and titlebar.
   // Even though GetClientOffset should return (0, 0) when there is no
   // titlebar or borders, we skip these calculations anyway for non-panels
   // to save time since they will never have a titlebar.
   nsIWidget* widget = view->GetWidget();
   if (mPopupType == ePopupTypePanel && widget) {
-    mLastClientOffset = widget->GetClientOffset();
+    mLastClientOffset = widget->GetClientOffsetUntyped();
     viewPoint.x += presContext->DevPixelsToAppUnits(mLastClientOffset.x);
     viewPoint.y += presContext->DevPixelsToAppUnits(mLastClientOffset.y);
   }
 
   presContext->GetPresShell()->GetViewManager()->
     MoveViewTo(view, viewPoint.x, viewPoint.y);
 
   // Now that we've positioned the view, sync up the frame's origin.
@@ -2163,17 +2163,17 @@ nsMenuPopupFrame::DestroyFrom(nsIFrame* 
 }
 
 
 void
 nsMenuPopupFrame::MoveTo(const CSSIntPoint& aPos, bool aUpdateAttrs)
 {
   nsIWidget* widget = GetWidget();
   if ((mScreenRect.x == aPos.x && mScreenRect.y == aPos.y) &&
-      (!widget || widget->GetClientOffset() == mLastClientOffset)) {
+      (!widget || widget->GetClientOffsetUntyped() == mLastClientOffset)) {
     return;
   }
 
   // reposition the popup at the specified coordinates. Don't clear the anchor
   // and position, because the popup can be reset to its anchor position by
   // using (-1, -1) as coordinates. Subtract off the margin as it will be
   // added to the position when SetPopupPosition is called.
   nsMargin margin(0, 0, 0, 0);
--- a/layout/xul/nsResizerFrame.cpp
+++ b/layout/xul/nsResizerFrame.cpp
@@ -248,17 +248,17 @@ nsResizerFrame::HandleEvent(nsPresContex
         LayoutDeviceIntRect oldRect;
         nsWeakFrame weakFrame(menuPopupFrame);
         if (menuPopupFrame) {
           nsCOMPtr<nsIWidget> widget = menuPopupFrame->GetWidget();
           if (widget)
             widget->GetScreenBounds(oldRect);
 
           // convert the new rectangle into outer window coordinates
-          nsIntPoint clientOffset = widget->GetClientOffset();
+          LayoutDeviceIntPoint clientOffset = widget->GetClientOffset();
           rect.x -= clientOffset.x;
           rect.y -= clientOffset.y;
         }
 
         SizeInfo sizeInfo, originalSizeInfo;
         sizeInfo.width.AppendInt(cssRect.width);
         sizeInfo.height.AppendInt(cssRect.height);
         ResizeContent(contentToResize, direction, sizeInfo, &originalSizeInfo);
--- a/layout/xul/nsXULPopupManager.cpp
+++ b/layout/xul/nsXULPopupManager.cpp
@@ -468,17 +468,17 @@ nsXULPopupManager::PopupMoved(nsIFrame* 
   if (!view)
     return;
 
   // Don't do anything if the popup is already at the specified location. This
   // prevents recursive calls when a popup is positioned.
   nsIntRect curDevSize = view->CalcWidgetBounds(eWindowType_popup);
   nsIWidget* widget = menuPopupFrame->GetWidget();
   if (curDevSize.x == aPnt.x && curDevSize.y == aPnt.y &&
-      (!widget || widget->GetClientOffset() == menuPopupFrame->GetLastClientOffset())) {
+      (!widget || widget->GetClientOffsetUntyped() == menuPopupFrame->GetLastClientOffset())) {
     return;
   }
 
   // Update the popup's position using SetPopupPosition if the popup is
   // anchored and at the parent level as these maintain their position
   // relative to the parent window. Otherwise, just update the popup to
   // the specified screen coordinates.
   if (menuPopupFrame->IsAnchored() &&
--- a/media/libcubeb/src/cubeb_opensl.c
+++ b/media/libcubeb/src/cubeb_opensl.c
@@ -636,16 +636,19 @@ opensl_stream_init(cubeb * ctx, cubeb_st
   }
 
   res = (*stm->play)->RegisterCallback(stm->play, play_callback, stm);
   if (res != SL_RESULT_SUCCESS) {
     opensl_stream_destroy(stm);
     return CUBEB_ERROR;
   }
 
+  // Work around wilhelm/AudioTrack badness, bug 1221228
+  (*stm->play)->SetMarkerPosition(stm->play, (SLmillisecond)0);
+
   res = (*stm->play)->SetCallbackEventsMask(stm->play, (SLuint32)SL_PLAYEVENT_HEADATMARKER);
   if (res != SL_RESULT_SUCCESS) {
     opensl_stream_destroy(stm);
     return CUBEB_ERROR;
   }
 
   res = (*stm->bufq)->RegisterCallback(stm->bufq, bufferqueue_callback, stm);
   if (res != SL_RESULT_SUCCESS) {
--- a/media/libvpx/update.py
+++ b/media/libvpx/update.py
@@ -587,16 +587,18 @@ def apply_patches():
     os.system("patch -p0 < stdint.patch")
     # Patch to fix a crash caused by MSVC 2013
     os.system("patch -p3 < bug1137614.patch")
     # Bug 1176730 - Don't use pthread for libvpx in mingw builds.
     os.system("patch -p3 < disable_pthread_on_mingw.patch")
     # Cherry pick https://chromium-review.googlesource.com/#/c/276889/
     # to fix crash on 32bit
     os.system("patch -p1 < vp9_filter_restore_aligment.patch")
+    # Patch win32 vpx_once.
+    os.system("patch -p3 < vpx_once.patch")
 
 def update_readme(commit):
     with open('README_MOZILLA') as f:
         readme = f.read()
 
     if 'The git commit ID used was' in readme:
         new_readme = re.sub('The git commit ID used was [a-f0-9]+',
             'The git commit ID used was %s' % commit, readme)
new file mode 100644
--- /dev/null
+++ b/media/libvpx/vpx_once.patch
@@ -0,0 +1,145 @@
+commit 64f73cc1f7f57ca6643b027eae63041fec408ea8
+Author: Ralph Giles <giles@mozilla.com>
+Date:   Fri Nov 6 16:42:49 2015 -0800
+
+    Bug 1218124 - Use InterlockCompare in win32 vpx_once(). r=gerald
+
+diff --git a/media/libvpx/vpx_ports/vpx_once.h b/media/libvpx/vpx_ports/vpx_once.h
+index f1df394..da04db4 100644
+--- a/media/libvpx/vpx_ports/vpx_once.h
++++ b/media/libvpx/vpx_ports/vpx_once.h
+@@ -1,5 +1,5 @@
+ /*
+- *  Copyright (c) 2011 The WebM project authors. All Rights Reserved.
++ *  Copyright (c) 2015 The WebM project authors. All Rights Reserved.
+  *
+  *  Use of this source code is governed by a BSD-style license
+  *  that can be found in the LICENSE file in the root of the source
+@@ -13,63 +13,83 @@
+ 
+ #include "vpx_config.h"
+ 
++/* Implement a function wrapper to guarantee initialization
++ * thread-safety for library singletons.
++ *
++ * NOTE: These functions use static locks, and can only be
++ * used with one common argument per compilation unit. So
++ *
++ * file1.c:
++ *   vpx_once(foo);
++ *   ...
++ *   vpx_once(foo);
++ *
++ *   file2.c:
++ *     vpx_once(bar);
++ *
++ * will ensure foo() and bar() are each called only once, but in
++ *
++ * file1.c:
++ *   vpx_once(foo);
++ *   vpx_once(bar):
++ *
++ * bar() will never be called because the lock is used up
++ * by the call to foo().
++ */
++
+ #if CONFIG_MULTITHREAD && defined(_WIN32)
+ #include <windows.h>
+ #include <stdlib.h>
++/* Declare a per-compilation-unit state variable to track the progress
++ * of calling func() only once. This must be at global scope because
++ * local initializers are not thread-safe in MSVC prior to Visual
++ * Studio 2015.
++ *
++ * As a static, once_state will be zero-initialized as program start.
++ */
++static LONG once_state;
+ static void once(void (*func)(void))
+ {
+-    static CRITICAL_SECTION *lock;
+-    static LONG waiters;
+-    static int done;
+-    void *lock_ptr = &lock;
+-
+-    /* If the initialization is complete, return early. This isn't just an
+-     * optimization, it prevents races on the destruction of the global
+-     * lock.
++    /* Try to advance once_state from its initial value of 0 to 1.
++     * Only one thread can succeed in doing so.
+      */
+-    if(done)
++    if (InterlockedCompareExchange(&once_state, 1, 0) == 0) {
++        /* We're the winning thread, having set once_state to 1.
++         * Call our function. */
++        func();
++        /* Now advance once_state to 2, unblocking any other threads. */
++        InterlockedIncrement(&once_state);
+         return;
+-
+-    InterlockedIncrement(&waiters);
+-
+-    /* Get a lock. We create one and try to make it the one-true-lock,
+-     * throwing it away if we lost the race.
+-     */
+-
+-    {
+-        /* Scope to protect access to new_lock */
+-        CRITICAL_SECTION *new_lock = malloc(sizeof(CRITICAL_SECTION));
+-        InitializeCriticalSection(new_lock);
+-        if (InterlockedCompareExchangePointer(lock_ptr, new_lock, NULL) != NULL)
+-        {
+-            DeleteCriticalSection(new_lock);
+-            free(new_lock);
+-        }
+     }
+ 
+-    /* At this point, we have a lock that can be synchronized on. We don't
+-     * care which thread actually performed the allocation.
++    /* We weren't the winning thread, but we want to block on
++     * the state variable so we don't return before func()
++     * has finished executing elsewhere.
++     *
++     * Try to advance once_state from 2 to 2, which is only possible
++     * after the winning thead advances it from 1 to 2.
+      */
+-
+-    EnterCriticalSection(lock);
+-
+-    if (!done)
+-    {
+-        func();
+-        done = 1;
++    while (InterlockedCompareExchange(&once_state, 2, 2) != 2) {
++        /* State isn't yet 2. Try again.
++         *
++         * We are used for singleton initialization functions,
++         * which should complete quickly. Contention will likewise
++         * be rare, so it's worthwhile to use a simple but cpu-
++         * intensive busy-wait instead of successive backoff,
++         * waiting on a kernel object, or another heavier-weight scheme.
++         *
++         * We can at least yield our timeslice.
++         */
++        Sleep(0);
+     }
+ 
+-    LeaveCriticalSection(lock);
+-
+-    /* Last one out should free resources. The destructed objects are
+-     * protected by checking if(done) above.
++    /* We've seen once_state advance to 2, so we know func()
++     * has been called. And we've left once_state as we found it,
++     * so other threads will have the same experience.
++     *
++     * It's safe to return now.
+      */
+-    if(!InterlockedDecrement(&waiters))
+-    {
+-        DeleteCriticalSection(lock);
+-        free(lock);
+-        lock = NULL;
+-    }
++    return;
+ }
+ 
+ 
--- a/media/libvpx/vpx_ports/vpx_once.h
+++ b/media/libvpx/vpx_ports/vpx_once.h
@@ -1,80 +1,100 @@
 /*
- *  Copyright (c) 2011 The WebM project authors. All Rights Reserved.
+ *  Copyright (c) 2015 The WebM project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
  *  tree. An additional intellectual property rights grant can be found
  *  in the file PATENTS.  All contributing project authors may
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
 #ifndef VPX_PORTS_VPX_ONCE_H_
 #define VPX_PORTS_VPX_ONCE_H_
 
 #include "vpx_config.h"
 
+/* Implement a function wrapper to guarantee initialization
+ * thread-safety for library singletons.
+ *
+ * NOTE: These functions use static locks, and can only be
+ * used with one common argument per compilation unit. So
+ *
+ * file1.c:
+ *   vpx_once(foo);
+ *   ...
+ *   vpx_once(foo);
+ *
+ *   file2.c:
+ *     vpx_once(bar);
+ *
+ * will ensure foo() and bar() are each called only once, but in
+ *
+ * file1.c:
+ *   vpx_once(foo);
+ *   vpx_once(bar):
+ *
+ * bar() will never be called because the lock is used up
+ * by the call to foo().
+ */
+
 #if CONFIG_MULTITHREAD && defined(_WIN32)
 #include <windows.h>
 #include <stdlib.h>
+/* Declare a per-compilation-unit state variable to track the progress
+ * of calling func() only once. This must be at global scope because
+ * local initializers are not thread-safe in MSVC prior to Visual
+ * Studio 2015.
+ *
+ * As a static, once_state will be zero-initialized as program start.
+ */
+static LONG once_state;
 static void once(void (*func)(void))
 {
-    static CRITICAL_SECTION *lock;
-    static LONG waiters;
-    static int done;
-    void *lock_ptr = &lock;
-
-    /* If the initialization is complete, return early. This isn't just an
-     * optimization, it prevents races on the destruction of the global
-     * lock.
+    /* Try to advance once_state from its initial value of 0 to 1.
+     * Only one thread can succeed in doing so.
      */
-    if(done)
+    if (InterlockedCompareExchange(&once_state, 1, 0) == 0) {
+        /* We're the winning thread, having set once_state to 1.
+         * Call our function. */
+        func();
+        /* Now advance once_state to 2, unblocking any other threads. */
+        InterlockedIncrement(&once_state);
         return;
-
-    InterlockedIncrement(&waiters);
-
-    /* Get a lock. We create one and try to make it the one-true-lock,
-     * throwing it away if we lost the race.
-     */
-
-    {
-        /* Scope to protect access to new_lock */
-        CRITICAL_SECTION *new_lock = malloc(sizeof(CRITICAL_SECTION));
-        InitializeCriticalSection(new_lock);
-        if (InterlockedCompareExchangePointer(lock_ptr, new_lock, NULL) != NULL)
-        {
-            DeleteCriticalSection(new_lock);
-            free(new_lock);
-        }
     }
 
-    /* At this point, we have a lock that can be synchronized on. We don't
-     * care which thread actually performed the allocation.
+    /* We weren't the winning thread, but we want to block on
+     * the state variable so we don't return before func()
+     * has finished executing elsewhere.
+     *
+     * Try to advance once_state from 2 to 2, which is only possible
+     * after the winning thead advances it from 1 to 2.
      */
-
-    EnterCriticalSection(lock);
-
-    if (!done)
-    {
-        func();
-        done = 1;
+    while (InterlockedCompareExchange(&once_state, 2, 2) != 2) {
+        /* State isn't yet 2. Try again.
+         *
+         * We are used for singleton initialization functions,
+         * which should complete quickly. Contention will likewise
+         * be rare, so it's worthwhile to use a simple but cpu-
+         * intensive busy-wait instead of successive backoff,
+         * waiting on a kernel object, or another heavier-weight scheme.
+         *
+         * We can at least yield our timeslice.
+         */
+        Sleep(0);
     }
 
-    LeaveCriticalSection(lock);
-
-    /* Last one out should free resources. The destructed objects are
-     * protected by checking if(done) above.
+    /* We've seen once_state advance to 2, so we know func()
+     * has been called. And we've left once_state as we found it,
+     * so other threads will have the same experience.
+     *
+     * It's safe to return now.
      */
-    if(!InterlockedDecrement(&waiters))
-    {
-        DeleteCriticalSection(lock);
-        free(lock);
-        lock = NULL;
-    }
+    return;
 }
 
 
 #elif CONFIG_MULTITHREAD && defined(__OS2__)
 #define INCL_DOS
 #include <os2.h>
 static void once(void (*func)(void))
 {
--- a/media/webrtc/signaling/test/moz.build
+++ b/media/webrtc/signaling/test/moz.build
@@ -5,16 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # TODO: bug 1172551 - get these tests working on iOS
 if CONFIG['OS_TARGET'] != 'WINNT' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'uikit':
     GeckoCppUnitTests([
         'jsep_session_unittest',
         'mediaconduit_unittests',
         'mediapipeline_unittest',
+        'sdp_file_parser',
         'sdp_unittests',
         'signaling_unittests',
     ])
 
 include('/ipc/chromium/chromium-config.mozbuild')
 include('common.build')
 
 USE_LIBS += [
new file mode 100644
--- /dev/null
+++ b/media/webrtc/signaling/test/sdp_file_parser.cpp
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* 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 <string>
+#include <iostream>
+#include <fstream>
+
+#define GTEST_HAS_RTTI 0
+#include "gtest/gtest.h"
+#include "gtest_utils.h"
+
+// without this include linking fails
+#include "FakeMediaStreamsImpl.h"
+
+#include "signaling/src/sdp/SipccSdpParser.h"
+
+namespace mozilla {
+
+const std::string kDefaultFilename((char *)"/tmp/sdp.bin");
+std::string filename(kDefaultFilename);
+
+class SdpParseTest : public ::testing::Test
+{
+  public:
+    SdpParseTest() {}
+
+    void ParseSdp(const std::string &sdp) {
+      mSdp = mParser.Parse(sdp);
+    }
+
+    void SerializeSdp() {
+      if (mSdp) {
+          mSdp->Serialize(os);
+          std::cout << "Serialized SDP:" << std::endl <<
+            os.str() << std::endl;;
+      }
+    }
+
+    SipccSdpParser mParser;
+    mozilla::UniquePtr<Sdp> mSdp;
+    std::stringstream os;
+}; // class SdpParseTest
+
+TEST_F(SdpParseTest, parseSdpFromFile)
+{
+  std::ifstream file(filename.c_str(),
+                     std::ios::in|std::ios::binary|std::ios::ate);
+  ASSERT_TRUE(file.is_open());
+  std::streampos size = file.tellg();
+  size_t nsize = size;
+  nsize+=1;
+  char *memblock = new char [nsize];
+  memset(memblock, '\0', nsize);
+  file.seekg(0, std::ios::beg);
+  file.read(memblock, size);
+  file.close();
+  std::cout << "Read file " << filename << std::endl;
+  ParseSdp(memblock);
+  std::cout << "Parsed SDP" << std::endl;
+  SerializeSdp();
+  delete[] memblock;
+}
+
+} // End namespace mozilla.
+
+int main(int argc, char **argv)
+{
+  ::testing::InitGoogleTest(&argc, argv);
+
+  if (argc == 2) {
+    mozilla::filename = argv[1];
+  } else if (argc > 2) {
+    std::cerr << "Usage: ./sdp_file_parser [filename]" << std::endl;
+    return(1);
+  }
+
+  return RUN_ALL_TESTS();
+}
--- a/mobile/android/b2gdroid/installer/package-manifest.in
+++ b/mobile/android/b2gdroid/installer/package-manifest.in
@@ -619,18 +619,16 @@ bin/libfreebl_32int64_3.so
 @BINPATH@/components/AboutRedirector.js
 @BINPATH@/components/AddonUpdateService.js
 @BINPATH@/components/BlocklistPrompt.js
 @BINPATH@/components/BrowserCLH.js
 @BINPATH@/components/ColorPicker.js
 @BINPATH@/components/ContentDispatchChooser.js
 @BINPATH@/components/ContentPermissionPrompt.js
 @BINPATH@/components/DirectoryProvider.js
-@BINPATH@/components/FilePicker.js
-@BINPATH@/components/HelperAppDialog.js
 @BINPATH@/components/LoginManagerPrompter.js
 @BINPATH@/components/MobileComponents.manifest
 @BINPATH@/components/MobileComponents.xpt
 @BINPATH@/components/NSSDialogService.js
 @BINPATH@/components/PromptService.js
 @BINPATH@/components/SessionStore.js
 @BINPATH@/components/Sidebar.js
 @BINPATH@/components/SiteSpecificUserAgent.js
--- a/mobile/android/base/locales/Makefile.in
+++ b/mobile/android/base/locales/Makefile.in
@@ -61,16 +61,17 @@ strings-xml-preqs =\
   $(NULL)
 
 $(if $(MOZ_ANDROID_SHARED_ACCOUNT_TYPE),,$(error Missing MOZ_ANDROID_SHARED_ACCOUNT_TYPE))
 $(if $(MOZ_ANDROID_SHARED_FXACCOUNT_TYPE),,$(error Missing MOZ_ANDROID_SHARED_FXACCOUNT_TYPE))
 
 $(dir-strings-xml)/strings.xml: $(strings-xml-preqs)
 	$(call py_action,preprocessor, \
       $(DEFINES) \
+      $(ACDEFINES) \
 	  -DANDROID_PACKAGE_NAME=$(ANDROID_PACKAGE_NAME) \
 	  -DBRANDPATH='$(BRANDPATH)' \
 	  -DMOZ_ANDROID_SHARED_ACCOUNT_TYPE=$(MOZ_ANDROID_SHARED_ACCOUNT_TYPE) \
 	  -DMOZ_ANDROID_SHARED_FXACCOUNT_TYPE=$(MOZ_ANDROID_SHARED_FXACCOUNT_TYPE) \
 	  -DMOZ_APP_DISPLAYNAME='@MOZ_APP_DISPLAYNAME@' \
 	  -DSTRINGSPATH='$(STRINGSPATH)' \
 	  -DSYNCSTRINGSPATH='$(SYNCSTRINGSPATH)' \
 	  -DSEARCHSTRINGSPATH='$(SEARCHSTRINGSPATH)' \
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -416,21 +416,17 @@ var BrowserApp = {
   deck: null,
 
   startup: function startup() {
     window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow = new nsBrowserAccess();
     dump("zerdatime " + Date.now() + " - browser chrome startup finished.");
 
     this.deck = document.getElementById("browsers");
 
-    // This check and BrowserEventHandler should be removed once we have
-    // switched over to the C++ APZ code
-    if (!AppConstants.MOZ_ANDROID_APZ) {
-      BrowserEventHandler.init();
-    }
+    BrowserEventHandler.init();
 
     ViewportHandler.init();
 
     Services.androidBridge.browserApp = this;
 
     Services.obs.addObserver(this, "Locale:OS", false);
     Services.obs.addObserver(this, "Locale:Changed", false);
     Services.obs.addObserver(this, "Tab:Load", false);
@@ -4771,24 +4767,29 @@ Tab.prototype = {
     Ci.nsIBrowserTab
   ])
 };
 
 var BrowserEventHandler = {
   init: function init() {
     this._clickInZoomedView = false;
     Services.obs.addObserver(this, "Gesture:SingleTap", false);
-    Services.obs.addObserver(this, "Gesture:CancelTouch", false);
     Services.obs.addObserver(this, "Gesture:ClickInZoomedView", false);
-    Services.obs.addObserver(this, "Gesture:DoubleTap", false);
-    Services.obs.addObserver(this, "Gesture:Scroll", false);
-    Services.obs.addObserver(this, "dom-touch-listener-added", false);
+
+    if (!AppConstants.MOZ_ANDROID_APZ) {
+      Services.obs.addObserver(this, "Gesture:CancelTouch", false);
+      Services.obs.addObserver(this, "Gesture:DoubleTap", false);
+      Services.obs.addObserver(this, "Gesture:Scroll", false);
+      Services.obs.addObserver(this, "dom-touch-listener-added", false);
+      BrowserApp.deck.addEventListener("touchstart", this, true);
+    } else {
+      BrowserApp.deck.addEventListener("touchend", this, true);
+    }
 
     BrowserApp.deck.addEventListener("DOMUpdatePageReport", PopupBlockerObserver.onUpdatePageReport, false);
-    BrowserApp.deck.addEventListener("touchstart", this, true);
     BrowserApp.deck.addEventListener("MozMouseHittest", this, true);
 
     InitLater(() => BrowserApp.deck.addEventListener("click", InputWidgetHelper, true));
     InitLater(() => BrowserApp.deck.addEventListener("click", SelectHelper, true));
     if (AppConstants.NIGHTLY_BUILD) {
       InitLater(() => BrowserApp.deck.addEventListener("InsecureLoginFormsStateChange", IdentityHandler.sendLoginInsecure, true));
     }
 
@@ -4798,16 +4799,21 @@ var BrowserEventHandler = {
     }, "Browser:OnBackPressed");
   },
 
   handleEvent: function(aEvent) {
     switch (aEvent.type) {
       case 'touchstart':
         this._handleTouchStart(aEvent);
         break;
+      case 'touchend':
+        if (this._inCluster) {
+          aEvent.preventDefault();
+        }
+        break;
       case 'MozMouseHittest':
         this._handleRetargetedTouchStart(aEvent);
         break;
     }
   },
 
   _handleTouchStart: function(aEvent) {
     if (!BrowserApp.isBrowserContentDocumentDisplayed() || aEvent.touches.length > 1 || aEvent.defaultPrevented)
@@ -4982,26 +4988,30 @@ var BrowserEventHandler = {
             }
             Messaging.sendRequest({ type: "FormAssist:Hide" });
           }
           this._clusterClicked(x, y);
         } else {
           if (this._clickInZoomedView != true) {
             this._closeZoomedView();
           }
-          // The _highlightElement was chosen after fluffing the touch events
-          // that led to this SingleTap, so by fluffing the mouse events, they
-          // should find the same target since we fluff them again below.
-          this._sendMouseEvent("mousemove", x, y);
-          this._sendMouseEvent("mousedown", x, y);
-          this._sendMouseEvent("mouseup",   x, y);
+          if (!AppConstants.MOZ_ANDROID_APZ) {
+            // The _highlightElement was chosen after fluffing the touch events
+            // that led to this SingleTap, so by fluffing the mouse events, they
+            // should find the same target since we fluff them again below.
+            this._sendMouseEvent("mousemove", x, y);
+            this._sendMouseEvent("mousedown", x, y);
+            this._sendMouseEvent("mouseup",   x, y);
+          }
         }
         this._clickInZoomedView = false;
-        // scrollToFocusedInput does its own checks to find out if an element should be zoomed into
-        BrowserApp.scrollToFocusedInput(BrowserApp.selectedBrowser);
+        if (!AppConstants.MOZ_ANDROID_APZ) {
+          // scrollToFocusedInput does its own checks to find out if an element should be zoomed into
+          BrowserApp.scrollToFocusedInput(BrowserApp.selectedBrowser);
+        }
 
         this._cancelTapHighlight();
         break;
       }
 
       case"Gesture:DoubleTap":
         this._cancelTapHighlight();
         this.onDoubleTap(aData);
@@ -5066,30 +5076,35 @@ var BrowserEventHandler = {
 
   _firstScrollEvent: false,
 
   _scrollableElement: null,
 
   _highlightElement: null,
 
   _doTapHighlight: function _doTapHighlight(aElement) {
-    DOMUtils.setContentState(aElement, kStateActive);
+    if (!AppConstants.MOZ_ANDROID_APZ) {
+      DOMUtils.setContentState(aElement, kStateActive);
+    }
     this._highlightElement = aElement;
   },
 
   _cancelTapHighlight: function _cancelTapHighlight() {
     if (!this._highlightElement)
       return;
 
-    // If the active element is in a sub-frame, we need to make that frame's document
-    // active to remove the element's active state.
-    if (this._highlightElement.ownerDocument != BrowserApp.selectedBrowser.contentWindow.document)
-      DOMUtils.setContentState(this._highlightElement.ownerDocument.documentElement, kStateActive);
-
-    DOMUtils.setContentState(BrowserApp.selectedBrowser.contentWindow.document.documentElement, kStateActive);
+    if (!AppConstants.MOZ_ANDROID_APZ) {
+      // If the active element is in a sub-frame, we need to make that frame's document
+      // active to remove the element's active state.
+      if (this._highlightElement.ownerDocument != BrowserApp.selectedBrowser.contentWindow.document)
+        DOMUtils.setContentState(this._highlightElement.ownerDocument.documentElement, kStateActive);
+
+      DOMUtils.setContentState(BrowserApp.selectedBrowser.contentWindow.document.documentElement, kStateActive);
+    }
+
     this._highlightElement = null;
   },
 
   _updateLastPosition: function(x, y, dx, dy) {
     this.lastX = x;
     this.lastY = y;
     this.lastTime = Date.now();
 
--- a/mobile/android/components/moz.build
+++ b/mobile/android/components/moz.build
@@ -14,38 +14,41 @@ EXTRA_COMPONENTS += [
     'AboutRedirector.js',
     'AddonUpdateService.js',
     'AndroidActivitiesGlue.js',
     'BlocklistPrompt.js',
     'BrowserCLH.js',
     'ColorPicker.js',
     'ContentDispatchChooser.js',
     'DirectoryProvider.js',
-    'FilePicker.js',
-    'HelperAppDialog.js',
     'ImageBlockingPolicy.js',
     'LoginManagerPrompter.js',
     'NSSDialogService.js',
-    'SiteSpecificUserAgent.js',
     'Snippets.js',
     'TabSource.js',
     'XPIDialogService.js',
 ]
 
 if not CONFIG['MOZ_B2GDROID']:
     EXTRA_COMPONENTS += [
         'ContentPermissionPrompt.js',
+        'FilePicker.js',
+        'HelperAppDialog.js',
         'PromptService.js',
         'SessionStore.js',
+        'SiteSpecificUserAgent.js',
         'WebappsUpdateTimer.js',
     ]
 
 if CONFIG['MOZ_PAY']:
+    if not CONFIG['MOZ_B2GDROID']:
+        EXTRA_COMPONENTS += [
+            'PaymentProviderStrategy.js',
+        ]
     EXTRA_COMPONENTS += [
-        'PaymentProviderStrategy.js',
         'PaymentsUI.js'
     ]
 
 # Keep it this way if at all possible.  If you need preprocessing,
 # consider adding fields to AppConstants.jsm.
 EXTRA_PP_COMPONENTS += [
     'MobileComponents.manifest',
 ]
--- a/mobile/android/modules/moz.build
+++ b/mobile/android/modules/moz.build
@@ -6,17 +6,16 @@
 
 EXTRA_JS_MODULES += [
     'Accounts.jsm',
     'AndroidLog.jsm',
     'ContactService.jsm',
     'dbg-browser-actors.js',
     'DelayedInit.jsm',
     'DownloadNotifications.jsm',
-    'FxAccountsWebChannel.jsm',
     'HelperApps.jsm',
     'Home.jsm',
     'HomeProvider.jsm',
     'JavaAddonManager.jsm',
     'JNI.jsm',
     'LightweightThemeConsumer.jsm',
     'MediaPlayerApp.jsm',
     'Messaging.jsm',
@@ -29,8 +28,13 @@ EXTRA_JS_MODULES += [
     'Sanitizer.jsm',
     'SharedPreferences.jsm',
     'Snackbars.jsm',
     'SSLExceptions.jsm',
     'TabMirror.jsm',
     'WebappManager.jsm',
     'WebappManagerWorker.js',
 ]
+
+if not CONFIG['MOZ_B2GDROID']:
+    EXTRA_JS_MODULES += [
+        'FxAccountsWebChannel.jsm',
+    ]
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -466,20 +466,20 @@ pref("media.getusermedia.playout_delay",
 #endif
 #endif
 
 #if !defined(ANDROID)
 pref("media.getusermedia.screensharing.enabled", true);
 #endif
 
 #ifdef RELEASE_BUILD
-pref("media.getusermedia.screensharing.allowed_domains", "webex.com,*.webex.com,ciscospark.com,*.ciscospark.com,projectsquared.com,*.projectsquared.com,*.room.co,room.co,beta.talky.io,talky.io,*.clearslide.com,appear.in,*.appear.in,tokbox.com,*.tokbox.com,*.sso.francetelecom.fr,*.si.francetelecom.fr,*.sso.infra.ftgroup,*.multimedia-conference.orange-business.com,*.espacecollaboration.orange-business.com,free.gotomeeting.com,g2m.me,*.g2m.me,example.com,*.mypurecloud.com,*.mypurecloud.com.au,spreed.me,*.spreed.me,*.spreed.com,air.mozilla.org");
+pref("media.getusermedia.screensharing.allowed_domains", "webex.com,*.webex.com,ciscospark.com,*.ciscospark.com,projectsquared.com,*.projectsquared.com,*.room.co,room.co,beta.talky.io,talky.io,*.clearslide.com,appear.in,*.appear.in,tokbox.com,*.tokbox.com,*.sso.francetelecom.fr,*.si.francetelecom.fr,*.sso.infra.ftgroup,*.multimedia-conference.orange-business.com,*.espacecollaboration.orange-business.com,free.gotomeeting.com,g2m.me,*.g2m.me,example.com,*.mypurecloud.com,*.mypurecloud.com.au,spreed.me,*.spreed.me,*.spreed.com,air.mozilla.org,*.circuit.com,*.yourcircuit.com,circuit.siemens.com,yourcircuit.siemens.com,circuitsandbox.net,*.unify.com,tandi.circuitsandbox.net");
 #else
  // temporary value, not intended for release - bug 1049087
-pref("media.getusermedia.screensharing.allowed_domains", "mozilla.github.io,webex.com,*.webex.com,ciscospark.com,*.ciscospark.com,projectsquared.com,*.projectsquared.com,*.room.co,room.co,beta.talky.io,talky.io,*.clearslide.com,appear.in,*.appear.in,tokbox.com,*.tokbox.com,*.sso.francetelecom.fr,*.si.francetelecom.fr,*.sso.infra.ftgroup,*.multimedia-conference.orange-business.com,*.espacecollaboration.orange-business.com,free.gotomeeting.com,g2m.me,*.g2m.me,example.com,*.mypurecloud.com,*.mypurecloud.com.au,spreed.me,*.spreed.me,*.spreed.com,air.mozilla.org");
+pref("media.getusermedia.screensharing.allowed_domains", "mozilla.github.io,webex.com,*.webex.com,ciscospark.com,*.ciscospark.com,projectsquared.com,*.projectsquared.com,*.room.co,room.co,beta.talky.io,talky.io,*.clearslide.com,appear.in,*.appear.in,tokbox.com,*.tokbox.com,*.sso.francetelecom.fr,*.si.francetelecom.fr,*.sso.infra.ftgroup,*.multimedia-conference.orange-business.com,*.espacecollaboration.orange-business.com,free.gotomeeting.com,g2m.me,*.g2m.me,example.com,*.mypurecloud.com,*.mypurecloud.com.au,spreed.me,*.spreed.me,*.spreed.com,air.mozilla.org,*.circuit.com,*.yourcircuit.com,circuit.siemens.com,yourcircuit.siemens.com,circuitsandbox.net,*.unify.com,tandi.circuitsandbox.net");
 #endif
 // OS/X 10.6 and XP have screen/window sharing off by default due to various issues - Caveat emptor
 pref("media.getusermedia.screensharing.allow_on_old_platforms", false);
 
 pref("media.getusermedia.audiocapture.enabled", false);
 
 // TextTrack support
 pref("media.webvtt.enabled", true);
--- a/mozglue/misc/StackWalk.cpp
+++ b/mozglue/misc/StackWalk.cpp
@@ -49,16 +49,26 @@ static CriticalAddress gCriticalAddress;
 
 #if MOZ_STACKWALK_SUPPORTS_MACOSX
 #include <pthread.h>
 #include <sys/errno.h>
 #ifdef MOZ_WIDGET_COCOA
 #include <CoreServices/CoreServices.h>
 #endif
 
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
+#define HAVE___LIBC_STACK_END 1
+#else
+#define HAVE___LIBC_STACK_END 0
+#endif
+
+#if HAVE___LIBC_STACK_END
+extern MOZ_EXPORT void* __libc_stack_end; // from ld-linux.so
+#endif
+
 typedef void
 malloc_logger_t(uint32_t aType,
                 uintptr_t aArg1, uintptr_t aArg2, uintptr_t aArg3,
                 uintptr_t aResult, uint32_t aNumHotFramesToSkip);
 extern malloc_logger_t* malloc_logger;
 
 static void
 stack_callback(uint32_t aFrameNumber, void* aPc, void* aSp, void* aClosure)
@@ -868,77 +878,16 @@ void DemangleSymbol(const char* aSymbol,
   if (demangled) {
     strncpy(aBuffer, demangled, aBufLen);
     aBuffer[aBufLen - 1] = '\0';
     free(demangled);
   }
 #endif // MOZ_DEMANGLE_SYMBOLS
 }
 
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
-#define HAVE___LIBC_STACK_END 1
-#else
-#define HAVE___LIBC_STACK_END 0
-#endif
-
-#if HAVE___LIBC_STACK_END
-extern MOZ_EXPORT void* __libc_stack_end; // from ld-linux.so
-#endif
-namespace mozilla {
-bool
-FramePointerStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
-                      uint32_t aMaxFrames, void* aClosure, void** bp,
-                      void* aStackEnd)
-{
-  // Stack walking code courtesy Kipp's "leaky".
-
-  int32_t skip = aSkipFrames;
-  uint32_t numFrames = 0;
-  while (bp) {
-    void** next = (void**)*bp;
-    // bp may not be a frame pointer on i386 if code was compiled with
-    // -fomit-frame-pointer, so do some sanity checks.
-    // (bp should be a frame pointer on ppc(64) but checking anyway may help
-    // a little if the stack has been corrupted.)
-    // We don't need to check against the begining of the stack because
-    // we can assume that bp > sp
-    if (next <= bp ||
-        next > aStackEnd ||
-        (long(next) & 3)) {
-      break;
-    }
-#if (defined(__ppc__) && defined(XP_MACOSX)) || defined(__powerpc64__)
-    // ppc mac or powerpc64 linux
-    void* pc = *(bp + 2);
-    bp += 3;
-#else // i386 or powerpc32 linux
-    void* pc = *(bp + 1);
-    bp += 2;
-#endif
-    if (IsCriticalAddress(pc)) {
-      return false;
-    }
-    if (--skip < 0) {
-      // Assume that the SP points to the BP of the function
-      // it called. We can't know the exact location of the SP
-      // but this should be sufficient for our use the SP
-      // to order elements on the stack.
-      numFrames++;
-      (*aCallback)(numFrames, pc, bp, aClosure);
-      if (aMaxFrames != 0 && numFrames == aMaxFrames) {
-        break;
-      }
-    }
-    bp = next;
-  }
-  return numFrames != 0;
-}
-
-} // namespace mozilla
-
 #define X86_OR_PPC (defined(__i386) || defined(PPC) || defined(__ppc__))
 #if X86_OR_PPC && (MOZ_STACKWALK_SUPPORTS_MACOSX || MOZ_STACKWALK_SUPPORTS_LINUX) // i386 or PPC Linux or Mac stackwalking code
 
 MFBT_API bool
 MozStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
              uint32_t aMaxFrames, void* aClosure, uintptr_t aThread,
              void* aPlatformData)
 {
@@ -1084,39 +1033,95 @@ MozStackWalk(MozWalkStackCallback aCallb
              uint32_t aMaxFrames, void* aClosure, uintptr_t aThread,
              void* aPlatformData)
 {
   MOZ_ASSERT(!aThread);
   MOZ_ASSERT(!aPlatformData);
   return false;
 }
 
-namespace mozilla {
-MFBT_API bool
-FramePointerStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
-                      void* aClosure, void** aBp)
-{
-  return false;
-}
-}
-
 MFBT_API bool
 MozDescribeCodeAddress(void* aPC, MozCodeAddressDetails* aDetails)
 {
   aDetails->library[0] = '\0';
   aDetails->loffset = 0;
   aDetails->filename[0] = '\0';
   aDetails->lineno = 0;
   aDetails->function[0] = '\0';
   aDetails->foffset = 0;
   return false;
 }
 
 #endif
 
+#if defined(XP_WIN) || defined (XP_MACOSX) || defined (XP_LINUX)
+namespace mozilla {
+bool
+FramePointerStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
+                      uint32_t aMaxFrames, void* aClosure, void** bp,
+                      void* aStackEnd)
+{
+  // Stack walking code courtesy Kipp's "leaky".
+
+  int32_t skip = aSkipFrames;
+  uint32_t numFrames = 0;
+  while (bp) {
+    void** next = (void**)*bp;
+    // bp may not be a frame pointer on i386 if code was compiled with
+    // -fomit-frame-pointer, so do some sanity checks.
+    // (bp should be a frame pointer on ppc(64) but checking anyway may help
+    // a little if the stack has been corrupted.)
+    // We don't need to check against the begining of the stack because
+    // we can assume that bp > sp
+    if (next <= bp ||
+        next > aStackEnd ||
+        (long(next) & 3)) {
+      break;
+    }
+#if (defined(__ppc__) && defined(XP_MACOSX)) || defined(__powerpc64__)
+    // ppc mac or powerpc64 linux
+    void* pc = *(bp + 2);
+    bp += 3;
+#else // i386 or powerpc32 linux
+    void* pc = *(bp + 1);
+    bp += 2;
+#endif
+    if (IsCriticalAddress(pc)) {
+      return false;
+    }
+    if (--skip < 0) {
+      // Assume that the SP points to the BP of the function
+      // it called. We can't know the exact location of the SP
+      // but this should be sufficient for our use the SP
+      // to order elements on the stack.
+      numFrames++;
+      (*aCallback)(numFrames, pc, bp, aClosure);
+      if (aMaxFrames != 0 && numFrames == aMaxFrames) {
+        break;
+      }
+    }
+    bp = next;
+  }
+  return numFrames != 0;
+}
+} // namespace mozilla
+
+#else
+
+namespace mozilla {
+MFBT_API bool
+FramePointerStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
+                      void* aClosure, void** aBp)
+{
+  return false;
+}
+}
+
+#endif
+
 MFBT_API void
 MozFormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize,
                             uint32_t aFrameNumber, void* aPC,
                             const MozCodeAddressDetails* aDetails)
 {
   MozFormatCodeAddress(aBuffer, aBufferSize,
                        aFrameNumber, aPC, aDetails->function,
                        aDetails->library, aDetails->loffset,
--- a/netwerk/cache2/CacheIOThread.cpp
+++ b/netwerk/cache2/CacheIOThread.cpp
@@ -16,28 +16,34 @@ namespace net {
 
 CacheIOThread* CacheIOThread::sSelf = nullptr;
 
 NS_IMPL_ISUPPORTS(CacheIOThread, nsIThreadObserver)
 
 CacheIOThread::CacheIOThread()
 : mMonitor("CacheIOThread")
 , mThread(nullptr)
+, mXPCOMThread(nullptr)
 , mLowestLevelWaiting(LAST_LEVEL)
 , mCurrentlyExecutingLevel(0)
 , mHasXPCOMEvents(false)
 , mRerunCurrentEvent(false)
 , mShutdown(false)
 , mInsideLoop(true)
 {
   sSelf = this;
 }
 
 CacheIOThread::~CacheIOThread()
 {
+  if (mXPCOMThread) {
+    nsIThread *thread = mXPCOMThread;
+    thread->Release();
+  }
+
   sSelf = nullptr;
 #ifdef DEBUG
   for (uint32_t level = 0; level < LAST_LEVEL; ++level) {
     MOZ_ASSERT(!mEventQueue[level].Length());
   }
 #endif
 }
 
@@ -177,17 +183,17 @@ void CacheIOThread::ThreadFunc()
 
     // This creates nsThread for this PRThread
     nsCOMPtr<nsIThread> xpcomThread = NS_GetCurrentThread();
 
     threadInternal = do_QueryInterface(xpcomThread);
     if (threadInternal)
       threadInternal->SetObserver(this);
 
-    mXPCOMThread.swap(xpcomThread);
+    mXPCOMThread = xpcomThread.forget().take();
 
     lock.NotifyAll();
 
     do {
 loopStart:
       // Reset the lowest level now, so that we can detect a new event on
       // a lower level (i.e. higher priority) has been scheduled while
       // executing any previously scheduled event.
@@ -198,17 +204,18 @@ loopStart:
         mHasXPCOMEvents = false;
         mCurrentlyExecutingLevel = XPCOM_LEVEL;
 
         MonitorAutoUnlock unlock(mMonitor);
 
         bool processedEvent;
         nsresult rv;
         do {
-          rv = mXPCOMThread->ProcessNextEvent(false, &processedEvent);
+          nsIThread *thread = mXPCOMThread;
+          rv = thread->ProcessNextEvent(false, &processedEvent);
         } while (NS_SUCCEEDED(rv) && processedEvent);
       }
 
       uint32_t level;
       for (level = 0; level < LAST_LEVEL; ++level) {
         if (!mEventQueue[level].Length()) {
           // no events on this level, go to the next level
           continue;
--- a/netwerk/cache2/CacheIOThread.h
+++ b/netwerk/cache2/CacheIOThread.h
@@ -83,17 +83,17 @@ private:
   bool EventsPending(uint32_t aLastLevel = LAST_LEVEL);
   nsresult DispatchInternal(nsIRunnable* aRunnable, uint32_t aLevel);
   bool YieldInternal();
 
   static CacheIOThread* sSelf;
 
   mozilla::Monitor mMonitor;
   PRThread* mThread;
-  nsCOMPtr<nsIThread> mXPCOMThread;
+  Atomic<nsIThread *> mXPCOMThread;
   Atomic<uint32_t, Relaxed> mLowestLevelWaiting;
   uint32_t mCurrentlyExecutingLevel;
   nsTArray<nsCOMPtr<nsIRunnable> > mEventQueue[LAST_LEVEL];
 
   Atomic<bool, Relaxed> mHasXPCOMEvents;
   bool mRerunCurrentEvent;
   bool mShutdown;
   DebugOnly<bool> mInsideLoop;
--- a/netwerk/protocol/http/Http2Compression.cpp
+++ b/netwerk/protocol/http/Http2Compression.cpp
@@ -855,16 +855,19 @@ Http2Decompressor::DoLiteralInternal(nsA
 
   int32_t newline = 0;
   while ((newline = value.FindChar('\n', newline)) != -1) {
     if (value[newline + 1] == ' ' || value[newline + 1] == '\t') {
       LOG(("Http2Decompressor::Disallowing folded header value %s",
            value.BeginReading()));
       return NS_ERROR_ILLEGAL_VALUE;
     }
+    // Increment this to avoid always finding the same newline and looping
+    // forever
+    ++newline;
   }
 
   LOG(("Http2Decompressor::DoLiteralInternal value %s", value.BeginReading()));
   return NS_OK;
 }
 
 nsresult
 Http2Decompressor::DoLiteralWithoutIndex()
--- a/netwerk/streamconv/nsStreamConverterService.cpp
+++ b/netwerk/streamconv/nsStreamConverterService.cpp
@@ -187,29 +187,16 @@ nsStreamConverterService::ParseFromTo(co
     return NS_OK;
 }
 
 typedef nsClassHashtable<nsCStringHashKey, BFSTableData> BFSHashTable;
 
 
 // nsObjectHashtable enumerator functions.
 
-// Initializes the BFS state table.
-static PLDHashOperator
-InitBFSTable(const nsACString &aKey, nsCOMArray<nsIAtom> *aData, void* aClosure) {
-    MOZ_ASSERT(aData, "no data in the table enumeration");
-
-    BFSHashTable *bfsTable = static_cast<BFSHashTable*>(aClosure);
-    if (!bfsTable) return PL_DHASH_STOP;
-
-    BFSTableData *data = new BFSTableData(aKey);
-    bfsTable->Put(aKey, data);
-    return PL_DHASH_NEXT;
-}
-
 class CStreamConvDeallocator : public nsDequeFunctor {
 public:
     virtual void* operator()(void* anObject) {
         nsCString *string = (nsCString*)anObject;
         delete string;
         return 0;
     }
 };
@@ -227,17 +214,21 @@ nsStreamConverterService::FindConverter(
 
     // walk the graph in search of the appropriate converter.
 
     uint32_t vertexCount = mAdjacencyList.Count();
     if (0 >= vertexCount) return NS_ERROR_FAILURE;
 
     // Create a corresponding color table for each vertex in the graph.
     BFSHashTable lBFSTable;
-    mAdjacencyList.EnumerateRead(InitBFSTable, &lBFSTable);
+    for (auto iter = mAdjacencyList.Iter(); !iter.Done(); iter.Next()) {
+        const nsACString &key = iter.Key();
+        MOZ_ASSERT(iter.UserData(), "no data in the table iteration");
+        lBFSTable.Put(key, new BFSTableData(key));
+    }
 
     NS_ASSERTION(lBFSTable.Count() == vertexCount, "strmconv BFS table init problem");
 
     // This is our source vertex; our starting point.
     nsAutoCString fromC, toC;
     rv = ParseFromTo(aContractID, fromC, toC);
     if (NS_FAILED(rv)) return rv;
 
--- a/python/mozbuild/mozbuild/action/xpidl-process.py
+++ b/python/mozbuild/mozbuild/action/xpidl-process.py
@@ -40,50 +40,50 @@ def process(input_dir, inc_paths, cache_
     for stem in stems:
         path = os.path.join(input_dir, '%s.idl' % stem)
         idl_data = open(path).read()
 
         idl = p.parse(idl_data, filename=path)
         idl.resolve([input_dir] + inc_paths, p)
 
         header_path = os.path.join(header_dir, '%s.h' % stem)
-        deps_path = os.path.join(deps_dir, '%s.pp' % stem)
 
         xpt = BytesIO()
         write_typelib(idl, xpt, path)
         xpt.seek(0)
         xpts[stem] = xpt
 
         rule.add_dependencies(idl.deps)
 
         with FileAvoidWrite(header_path) as fh:
             print_header(idl, fh, path)
 
     # TODO use FileAvoidWrite once it supports binary mode.
     xpt_path = os.path.join(xpt_dir, '%s.xpt' % module)
     xpt_link(xpts.values()).write(xpt_path)
 
     rule.add_targets([xpt_path])
-    deps_path = os.path.join(deps_dir, '%s.pp' % module)
-    with FileAvoidWrite(deps_path) as fh:
-        mk.dump(fh)
+    if deps_dir:
+        deps_path = os.path.join(deps_dir, '%s.pp' % module)
+        with FileAvoidWrite(deps_path) as fh:
+            mk.dump(fh)
 
 
 def main(argv):
     parser = argparse.ArgumentParser()
     parser.add_argument('--cache-dir',
         help='Directory in which to find or write cached lexer data.')
+    parser.add_argument('--depsdir',
+        help='Directory in which to write dependency files.')
     parser.add_argument('inputdir',
         help='Directory in which to find source .idl files.')
     parser.add_argument('headerdir',
         help='Directory in which to write header files.')
     parser.add_argument('xptdir',
         help='Directory in which to write xpt file.')
-    parser.add_argument('depsdir',
-        help='Directory in which to write dependency files.')
     parser.add_argument('module',
         help='Final module name to use for linked output xpt file.')
     parser.add_argument('idls', nargs='+',
         help='Source .idl file(s). Specified as stems only.')
     parser.add_argument('-I', dest='incpath', action='append', default=[],
         help='Extra directories where to look for included .idl files.')
 
     args = parser.parse_args(argv)
--- a/python/mozbuild/mozbuild/backend/fastermake.py
+++ b/python/mozbuild/mozbuild/backend/fastermake.py
@@ -23,39 +23,26 @@ from mozbuild.util import OrderedDefault
 from mozpack.manifests import InstallManifest
 import mozpack.path as mozpath
 from collections import OrderedDict
 from itertools import chain
 import os
 import sys
 
 
-class OverwriteInstallManifest(InstallManifest):
-    def _add_entry(self, dest, entry):
-        # Because of bug 1210703, we can't let the default behavior of
-        # InstallManifest._add_entry, which is to error out.
-        # To match the current behavior of the recursive make libs tier, we
-        # keep the last one given, but still warn about it.
-        if dest in self._dests:
-            print('Warning: Item already in manifest: %s' % dest,
-                  file=sys.stderr)
-
-        self._dests[dest] = entry
-
-
 class FasterMakeBackend(CommonBackend):
     def _init(self):
         super(FasterMakeBackend, self)._init()
 
         self._seen_directories = set()
         self._defines = dict()
 
         self._manifest_entries = OrderedDefaultDict(list)
 
-        self._install_manifests = OrderedDefaultDict(OverwriteInstallManifest)
+        self._install_manifests = OrderedDefaultDict(InstallManifest)
 
         self._dependencies = OrderedDefaultDict(list)
 
     def _add_preprocess(self, obj, path, dest, target=None, **kwargs):
         if target is None:
             target = mozpath.basename(path)
             # This matches what PP_TARGETS do in config/rules.
             if target.endswith('.in'):
--- a/python/mozbuild/mozpack/copier.py
+++ b/python/mozbuild/mozpack/copier.py
@@ -30,27 +30,33 @@ class FileRegistry(object):
 
         registry = FileRegistry()
         registry.add('foo/bar', file_instance)
     '''
 
     def __init__(self):
         self._files = OrderedDict()
         self._required_directories = Counter()
+        self._partial_paths_cache = {}
 
     def _partial_paths(self, path):
         '''
         Turn "foo/bar/baz/zot" into ["foo/bar/baz", "foo/bar", "foo"].
         '''
-        partial_paths = []
-        partial_path = path
-        while partial_path:
-            partial_path = mozpath.dirname(partial_path)
-            if partial_path:
-                partial_paths.append(partial_path)
+        dir_name = path.rpartition('/')[0]
+        if not dir_name:
+            return []
+
+        partial_paths = self._partial_paths_cache.get(dir_name)
+        if partial_paths:
+            return partial_paths
+
+        partial_paths = [dir_name] + self._partial_paths(dir_name)
+
+        self._partial_paths_cache[dir_name] = partial_paths
         return partial_paths
 
     def add(self, path, content):
         '''
         Add a BaseFile instance to the container, under the given path.
         '''
         assert isinstance(content, BaseFile)
         if path in self._files:
--- a/python/mozbuild/mozpack/test/test_copier.py
+++ b/python/mozbuild/mozpack/test/test_copier.py
@@ -33,16 +33,26 @@ class TestFileRegistry(MatchTestTemplate
     def do_check(self, pattern, result):
         self.checked = True
         if result:
             self.assertTrue(self.registry.contains(pattern))
         else:
             self.assertFalse(self.registry.contains(pattern))
         self.assertEqual(self.registry.match(pattern), result)
 
+    def test_partial_paths(self):
+        cases = {
+            'foo/bar/baz/zot': ['foo/bar/baz', 'foo/bar', 'foo'],
+            'foo/bar': ['foo'],
+            'bar': [],
+        }
+        reg = FileRegistry()
+        for path, parts in cases.iteritems():
+            self.assertEqual(reg._partial_paths(path), parts)
+
     def test_file_registry(self):
         self.registry = FileRegistry()
         self.registry.add('foo', GeneratedFile('foo'))
         bar = GeneratedFile('bar')
         self.registry.add('bar', bar)
         self.assertEqual(self.registry.paths(), ['foo', 'bar'])
         self.assertEqual(self.registry['bar'], bar)
 
--- a/security/certverifier/CertVerifier.cpp
+++ b/security/certverifier/CertVerifier.cpp
@@ -23,16 +23,17 @@ using namespace mozilla::pkix;
 using namespace mozilla::psm;
 
 PRLogModuleInfo* gCertVerifierLog = nullptr;
 
 namespace mozilla { namespace psm {
 
 const CertVerifier::Flags CertVerifier::FLAG_LOCAL_ONLY = 1;
 const CertVerifier::Flags CertVerifier::FLAG_MUST_BE_EV = 2;
+const CertVerifier::Flags CertVerifier::FLAG_TLS_IGNORE_STATUS_REQUEST = 4;
 
 CertVerifier::CertVerifier(OcspDownloadConfig odc,
                            OcspStrictConfig osc,
                            OcspGetConfig ogc,
                            uint32_t certShortLifetimeInDays,
                            PinningMode pinningMode,
                            SHA1Mode sha1Mode)
   : mOCSPDownloadConfig(odc)
@@ -578,16 +579,39 @@ CertVerifier::VerifySSLServerCert(CERTCe
 
   Input peerCertInput;
   Result result = peerCertInput.Init(peerCert->derCert.data,
                                      peerCert->derCert.len);
   if (result != Success) {
     PR_SetError(MapResultToPRErrorCode(result), 0);
     return SECFailure;
   }
+
+  Input stapledOCSPResponseInput;
+  Input* responseInputPtr = nullptr;
+  if (stapledOCSPResponse) {
+    result = stapledOCSPResponseInput.Init(stapledOCSPResponse->data,
+                                           stapledOCSPResponse->len);
+    if (result != Success) {
+      // The stapled OCSP response was too big.
+      PR_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE, 0);
+      return SECFailure;
+    }
+    responseInputPtr = &stapledOCSPResponseInput;
+  }
+
+  if (!(flags & FLAG_TLS_IGNORE_STATUS_REQUEST)) {
+    result = CheckTLSFeaturesAreSatisfied(peerCertInput, responseInputPtr);
+
+    if (result != Success) {
+      PR_SetError(MapResultToPRErrorCode(result), 0);
+      return SECFailure;
+    }
+  }
+
   Input hostnameInput;
   result = hostnameInput.Init(uint8_t_ptr_cast(hostname), strlen(hostname));
   if (result != Success) {
     PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
     return SECFailure;
   }
   result = CheckCertHostname(peerCertInput, hostnameInput);
   if (result != Success) {
--- a/security/certverifier/CertVerifier.h
+++ b/security/certverifier/CertVerifier.h
@@ -49,16 +49,18 @@ public:
 class CertVerifier
 {
 public:
   typedef unsigned int Flags;
   // XXX: FLAG_LOCAL_ONLY is ignored in the classic verification case
   static const Flags FLAG_LOCAL_ONLY;
   // Don't perform fallback DV validation on EV validation failure.
   static const Flags FLAG_MUST_BE_EV;
+  // TLS feature request_status should be ignored
+  static const Flags FLAG_TLS_IGNORE_STATUS_REQUEST;
 
   // These values correspond to the SSL_OCSP_STAPLING telemetry.
   enum OCSPStaplingStatus {
     OCSP_STAPLING_NEVER_CHECKED = 0,
     OCSP_STAPLING_GOOD = 1,
     OCSP_STAPLING_NONE = 2,
     OCSP_STAPLING_EXPIRED = 3,
     OCSP_STAPLING_INVALID = 4,
--- a/security/manager/locales/en-US/chrome/pipnss/nsserrors.properties
+++ b/security/manager/locales/en-US/chrome/pipnss/nsserrors.properties
@@ -314,8 +314,9 @@ MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE=T
 MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY=The server uses a certificate with a basic constraints extension identifying it as a certificate authority. For a properly-issued certificate, this should not be the case.
 MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE=The server presented a certificate with a key size that is too small to establish a secure connection.
 MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA=An X.509 version 1 certificate that is not a trust anchor was used to issue the server's certificate. X.509 version 1 certificates are deprecated and should not be used to sign other certificates.
 MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE=The server presented a certificate that is not yet valid.
 MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE=A certificate that is not yet valid was used to issue the server's certificate.
 MOZILLA_PKIX_ERROR_SIGNATURE_ALGORITHM_MISMATCH=The signature algorithm in the signature field of the certificate does not match the algorithm in its signatureAlgorithm field.
 MOZILLA_PKIX_ERROR_OCSP_RESPONSE_FOR_CERT_MISSING=The OCSP response does not include a status for the certificate being verified.
 MOZILLA_PKIX_ERROR_VALIDITY_TOO_LONG=The server presented a certificate that is valid for too long.
+MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING=A required TLS feature is missing.
--- a/security/manager/ssl/SSLServerCertVerification.cpp
+++ b/security/manager/ssl/SSLServerCertVerification.cpp
@@ -209,17 +209,17 @@ void StopSSLServerCertVerificationThread
     delete gSSLVerificationPK11Mutex;
     gSSLVerificationPK11Mutex = nullptr;
   }
 }
 
 namespace {
 
 void
-LogInvalidCertError(TransportSecurityInfo* socketInfo,
+LogInvalidCertError(nsNSSSocketInfo* socketInfo,
                     PRErrorCode errorCode,
                     ::mozilla::psm::SSLErrorMessageType errorMessageType)
 {
   nsString message;
   socketInfo->GetErrorLogMessage(errorCode, errorMessageType, message);
   if (!message.IsEmpty()) {
     nsContentUtils::LogSimpleConsoleError(message, "SSL");
   }
@@ -231,39 +231,39 @@ LogInvalidCertError(TransportSecurityInf
 // This will cause the PR_Poll in the STS thread to return, so things work
 // correctly even if the STS thread is blocked polling (only) on the file
 // descriptor that is waiting for this result.
 class SSLServerCertVerificationResult : public nsRunnable
 {
 public:
   NS_DECL_NSIRUNNABLE
 
-  SSLServerCertVerificationResult(TransportSecurityInfo* infoObject,
+  SSLServerCertVerificationResult(nsNSSSocketInfo* infoObject,
                                   PRErrorCode errorCode,
                                   Telemetry::ID telemetryID = Telemetry::HistogramCount,
                                   uint32_t telemetryValue = -1,
                                   SSLErrorMessageType errorMessageType =
                                       PlainErrorMessage);
 
   void Dispatch();
 private:
-  const RefPtr<TransportSecurityInfo> mInfoObject;
+  const RefPtr<nsNSSSocketInfo> mInfoObject;
 public:
   const PRErrorCode mErrorCode;
   const SSLErrorMessageType mErrorMessageType;
   const Telemetry::ID mTelemetryID;
   const uint32_t mTelemetryValue;
 };
 
 class CertErrorRunnable : public SyncRunnableBase
 {
  public:
   CertErrorRunnable(const void* fdForLogging,
                     nsIX509Cert* cert,
-                    TransportSecurityInfo* infoObject,
+                    nsNSSSocketInfo* infoObject,
                     PRErrorCode defaultErrorCodeToReport,
                     uint32_t collectedErrors,
                     PRErrorCode errorCodeTrust,
                     PRErrorCode errorCodeMismatch,
                     PRErrorCode errorCodeTime,
                     uint32_t providerFlags)
     : mFdForLogging(fdForLogging), mCert(cert), mInfoObject(infoObject),
       mDefaultErrorCodeToReport(defaultErrorCodeToReport),
@@ -277,17 +277,17 @@ class CertErrorRunnable : public SyncRun
 
   virtual void RunOnTargetThread();
   RefPtr<SSLServerCertVerificationResult> mResult; // out
 private:
   SSLServerCertVerificationResult* CheckCertOverrides();
 
   const void* const mFdForLogging; // may become an invalid pointer; do not dereference
   const nsCOMPtr<nsIX509Cert> mCert;
-  const RefPtr<TransportSecurityInfo> mInfoObject;
+  const RefPtr<nsNSSSocketInfo> mInfoObject;
   const PRErrorCode mDefaultErrorCodeToReport;
   const uint32_t mCollectedErrors;
   const PRErrorCode mErrorCodeTrust;
   const PRErrorCode mErrorCodeMismatch;
   const PRErrorCode mErrorCodeTime;
   const uint32_t mProviderFlags;
 };
 
@@ -617,17 +617,17 @@ CertErrorRunnable::RunOnTargetThread()
   MOZ_ASSERT(mResult);
 }
 
 // Returns null with the error code (PR_GetError()) set if it does not create
 // the CertErrorRunnable.
 CertErrorRunnable*
 CreateCertErrorRunnable(CertVerifier& certVerifier,
                         PRErrorCode defaultErrorCodeToReport,
-                        TransportSecurityInfo* infoObject,
+                        nsNSSSocketInfo* infoObject,
                         CERTCertificate* cert,
                         const void* fdForLogging,
                         uint32_t providerFlags,
                         PRTime now)
 {
   MOZ_ASSERT(infoObject);
   MOZ_ASSERT(cert);
 
@@ -710,51 +710,51 @@ private:
 };
 
 class SSLServerCertVerificationJob : public nsRunnable
 {
 public:
   // Must be called only on the socket transport thread
   static SECStatus Dispatch(const RefPtr<SharedCertVerifier>& certVerifier,
                             const void* fdForLogging,
-                            TransportSecurityInfo* infoObject,
+                            nsNSSSocketInfo* infoObject,
                             CERTCertificate* serverCert,
                             ScopedCERTCertList& peerCertChain,
                             SECItem* stapledOCSPResponse,
                             uint32_t providerFlags,
                             Time time,
                             PRTime prtime);
 private:
   NS_DECL_NSIRUNNABLE
 
   // Must be called only on the socket transport thread
   SSLServerCertVerificationJob(const RefPtr<SharedCertVerifier>& certVerifier,
                                const void* fdForLogging,
-                               TransportSecurityInfo* infoObject,
+                               nsNSSSocketInfo* infoObject,
                                CERTCertificate* cert,
                                CERTCertList* peerCertChain,
                                SECItem* stapledOCSPResponse,
                                uint32_t providerFlags,
                                Time time,
                                PRTime prtime);
   const RefPtr<SharedCertVerifier> mCertVerifier;
   const void* const mFdForLogging;
-  const RefPtr<TransportSecurityInfo> mInfoObject;
+  const RefPtr<nsNSSSocketInfo> mInfoObject;
   const ScopedCERTCertificate mCert;
   ScopedCERTCertList mPeerCertChain;
   const uint32_t mProviderFlags;
   const Time mTime;
   const PRTime mPRTime;
   const TimeStamp mJobStartTime;
   const ScopedSECItem mStapledOCSPResponse;
 };
 
 SSLServerCertVerificationJob::SSLServerCertVerificationJob(
     const RefPtr<SharedCertVerifier>& certVerifier, const void* fdForLogging,
-    TransportSecurityInfo* infoObject, CERTCertificate* cert,
+    nsNSSSocketInfo* infoObject, CERTCertificate* cert,
     CERTCertList* peerCertChain, SECItem* stapledOCSPResponse,
     uint32_t providerFlags, Time time, PRTime prtime)
   : mCertVerifier(certVerifier)
   , mFdForLogging(fdForLogging)
   , mInfoObject(infoObject)
   , mCert(CERT_DupCertificate(cert))
   , mPeerCertChain(peerCertChain)
   , mProviderFlags(providerFlags)
@@ -1195,17 +1195,17 @@ GatherSuccessfulValidationTelemetry(cons
   GatherBaselineRequirementsTelemetry(certList);
   GatherEKUTelemetry(certList);
   GatherRootCATelemetry(certList);
   GatherEndEntityTelemetry(certList);
 }
 
 SECStatus
 AuthCertificate(CertVerifier& certVerifier,
-                TransportSecurityInfo* infoObject,
+                nsNSSSocketInfo* infoObject,
                 CERTCertificate* cert,
                 ScopedCERTCertList& peerCertChain,
                 SECItem* stapledOCSPResponse,
                 uint32_t providerFlags,
                 Time time)
 {
   MOZ_ASSERT(infoObject);
   MOZ_ASSERT(cert);
@@ -1220,20 +1220,26 @@ AuthCertificate(CertVerifier& certVerifi
   SECOidTag evOidPolicy;
   ScopedCERTCertList certList;
   CertVerifier::OCSPStaplingStatus ocspStaplingStatus =
     CertVerifier::OCSP_STAPLING_NEVER_CHECKED;
   KeySizeStatus keySizeStatus = KeySizeStatus::NeverChecked;
   SignatureDigestStatus sigDigestStatus = SignatureDigestStatus::NeverChecked;
   PinningTelemetryInfo pinningTelemetryInfo;
 
+  int flags = 0;
+  if (!infoObject->SharedState().IsOCSPStaplingEnabled() ||
+      !infoObject->SharedState().IsOCSPMustStapleEnabled()) {
+    flags |= CertVerifier::FLAG_TLS_IGNORE_STATUS_REQUEST;
+  }
+
   rv = certVerifier.VerifySSLServerCert(cert, stapledOCSPResponse,
                                         time, infoObject,
                                         infoObject->GetHostNameRaw(),
-                                        saveIntermediates, 0, &certList,
+                                        saveIntermediates, flags, &certList,
                                         &evOidPolicy, &ocspStaplingStatus,
                                         &keySizeStatus, &sigDigestStatus,
                                         &pinningTelemetryInfo);
   PRErrorCode savedErrorCode;
   if (rv != SECSuccess) {
     savedErrorCode = PR_GetError();
   }
 
@@ -1322,17 +1328,17 @@ AuthCertificate(CertVerifier& certVerifi
 
   return rv;
 }
 
 /*static*/ SECStatus
 SSLServerCertVerificationJob::Dispatch(
   const RefPtr<SharedCertVerifier>& certVerifier,
   const void* fdForLogging,
-  TransportSecurityInfo* infoObject,
+  nsNSSSocketInfo* infoObject,
   CERTCertificate* serverCert,
   ScopedCERTCertList& peerCertChain,
   SECItem* stapledOCSPResponse,
   uint32_t providerFlags,
   Time time,
   PRTime prtime)
 {
   // Runs on the socket transport thread
@@ -1657,17 +1663,17 @@ void EnsureServerVerificationInitialized
 
   RefPtr<InitializeIdentityInfo> initJob = new InitializeIdentityInfo();
   if (gCertVerificationThreadPool)
     gCertVerificationThreadPool->Dispatch(initJob, NS_DISPATCH_NORMAL);
 #endif
 }
 
 SSLServerCertVerificationResult::SSLServerCertVerificationResult(
-        TransportSecurityInfo* infoObject, PRErrorCode errorCode,
+        nsNSSSocketInfo* infoObject, PRErrorCode errorCode,
         Telemetry::ID telemetryID, uint32_t telemetryValue,
         SSLErrorMessageType errorMessageType)
   : mInfoObject(infoObject)
   , mErrorCode(errorCode)
   , mErrorMessageType(errorMessageType)
   , mTelemetryID(telemetryID)
   , mTelemetryValue(telemetryValue)
 {
--- a/security/manager/ssl/SharedSSLState.h
+++ b/security/manager/ssl/SharedSSLState.h
@@ -34,38 +34,44 @@ public:
 
   // Main-thread only
   void ResetStoredData();
   void NotePrivateBrowsingStatus();
   void SetOCSPStaplingEnabled(bool staplingEnabled)
   {
     mOCSPStaplingEnabled = staplingEnabled;
   }
+  void SetOCSPMustStapleEnabled(bool mustStapleEnabled)
+  {
+    mOCSPMustStapleEnabled = mustStapleEnabled;
+  }
 
   // The following methods may be called from any thread
   bool SocketCreated();
   void NoteSocketCreated();
   static void NoteCertOverrideServiceInstantiated();
   bool IsOCSPStaplingEnabled() const { return mOCSPStaplingEnabled; }
+  bool IsOCSPMustStapleEnabled() const { return mOCSPMustStapleEnabled; }
 
 private:
   ~SharedSSLState();
 
   void Cleanup();
 
   nsCOMPtr<nsIObserver> mObserver;
   RefPtr<nsClientAuthRememberService> mClientAuthRemember;
   nsSSLIOLayerHelpers mIOLayerHelpers;
 
   // True if any sockets have been created that use this shared data.
   // Requires synchronization between the socket and main threads for
   // reading/writing.
   Mutex mMutex;
   bool mSocketCreated;
   bool mOCSPStaplingEnabled;
+  bool mOCSPMustStapleEnabled;
 };
 
 SharedSSLState* PublicSSLState();
 SharedSSLState* PrivateSSLState();
 
 } // namespace psm
 } // namespace mozilla
 
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -223,17 +223,16 @@ nsNSSComponent::nsNSSComponent()
 {
   if (!gPIPNSSLog)
     gPIPNSSLog = PR_NewLogModule("pipnss");
   MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::ctor\n"));
 
   NS_ASSERTION( (0 == mInstanceCount), "nsNSSComponent is a singleton, but instantiated multiple times!");
   ++mInstanceCount;
   mShutdownObjectList = nsNSSShutDownList::construct();
-  mIsNetworkDown = false;
 }
 
 void
 nsNSSComponent::deleteBackgroundThreads()
 {
   if (mCertVerificationThread)
   {
     mCertVerificationThread->requestExit();
@@ -842,16 +841,21 @@ void nsNSSComponent::setValidationOption
     Telemetry::Accumulate(Telemetry::CERT_OCSP_REQUIRED, ocspRequired);
   }
 
   bool ocspStaplingEnabled = Preferences::GetBool("security.ssl.enable_ocsp_stapling",
                                                   true);
   PublicSSLState()->SetOCSPStaplingEnabled(ocspStaplingEnabled);
   PrivateSSLState()->SetOCSPStaplingEnabled(ocspStaplingEnabled);
 
+  bool ocspMustStapleEnabled = Preferences::GetBool("security.ssl.enable_ocsp_must_staple",
+                                                    false);
+  PublicSSLState()->SetOCSPMustStapleEnabled(ocspMustStapleEnabled);
+  PrivateSSLState()->SetOCSPMustStapleEnabled(ocspMustStapleEnabled);
+
   CertVerifier::PinningMode pinningMode =
     static_cast<CertVerifier::PinningMode>
       (Preferences::GetInt("security.cert_pinning.enforcement_level",
                            CertVerifier::pinningDisabled));
   if (pinningMode > CertVerifier::pinningEnforceTestMode) {
     pinningMode = CertVerifier::pinningDisabled;
   }
 
@@ -1229,43 +1233,37 @@ nsNSSComponent::RandomUpdate(void* entro
 
   if (!mNSSInitialized)
       return NS_ERROR_NOT_INITIALIZED;
 
   PK11_RandomUpdate(entropy, bufLen);
   return NS_OK;
 }
 
-static const char* const PROFILE_CHANGE_NET_TEARDOWN_TOPIC
-  = "profile-change-net-teardown";
-static const char* const PROFILE_CHANGE_NET_RESTORE_TOPIC
-  = "profile-change-net-restore";
 static const char* const PROFILE_BEFORE_CHANGE_TOPIC = "profile-before-change";
 static const char* const PROFILE_DO_CHANGE_TOPIC = "profile-do-change";
 
 NS_IMETHODIMP
 nsNSSComponent::Observe(nsISupports* aSubject, const char* aTopic,
                         const char16_t* someData)
 {
   if (nsCRT::strcmp(aTopic, PROFILE_BEFORE_CHANGE_TOPIC) == 0) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("receiving profile change topic\n"));
-    DoProfileBeforeChange(aSubject);
+    DoProfileBeforeChange();
   }
   else if (nsCRT::strcmp(aTopic, PROFILE_DO_CHANGE_TOPIC) == 0) {
     if (someData && NS_LITERAL_STRING("startup").Equals(someData)) {
       // The application is initializing against a known profile directory for
       // the first time during process execution.
       // However, earlier code execution might have already triggered NSS init.
       // We must ensure that NSS gets shut down prior to any attempt to init
       // it again. We use the same cleanup functionality used when switching
       // profiles. The order of function calls must correspond to the order
       // of notifications sent by Profile Manager (nsProfile).
-      DoProfileChangeNetTeardown();
-      DoProfileBeforeChange(aSubject);
-      DoProfileChangeNetRestore();
+      DoProfileBeforeChange();
     }
 
     bool needsInit = true;
 
     {
       MutexAutoLock lock(mutex);
 
       if (mNSSInitialized) {
@@ -1327,34 +1325,27 @@ nsNSSComponent::Observe(nsISupports* aSu
                                                 ALPN_ENABLED_DEFAULT));
     } else if (prefName.Equals("security.ssl.disable_session_identifiers")) {
       ConfigureTLSSessionIdentifiers();
     } else if (prefName.EqualsLiteral("security.OCSP.enabled") ||
                prefName.EqualsLiteral("security.OCSP.require") ||
                prefName.EqualsLiteral("security.OCSP.GET.enabled") ||
                prefName.EqualsLiteral("security.pki.cert_short_lifetime_in_days") ||
                prefName.EqualsLiteral("security.ssl.enable_ocsp_stapling") ||
+               prefName.EqualsLiteral("security.ssl.enable_ocsp_must_staple") ||
                prefName.EqualsLiteral("security.cert_pinning.enforcement_level") ||
                prefName.EqualsLiteral("security.pki.sha1_enforcement_level")) {
       MutexAutoLock lock(mutex);
       setValidationOptions(false, lock);
     } else {
       clearSessionCache = false;
     }
     if (clearSessionCache)
       SSL_ClearSessionCache();
   }
-  else if (nsCRT::strcmp(aTopic, PROFILE_CHANGE_NET_TEARDOWN_TOPIC) == 0) {
-    MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("receiving network teardown topic\n"));
-    DoProfileChangeNetTeardown();
-  }
-  else if (nsCRT::strcmp(aTopic, PROFILE_CHANGE_NET_RESTORE_TOPIC) == 0) {
-    MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("receiving network restore topic\n"));
-    DoProfileChangeNetRestore();
-  }
 
   return NS_OK;
 }
 
 /*static*/ nsresult
 nsNSSComponent::GetNewPrompter(nsIPrompt** result)
 {
   NS_ENSURE_ARG_POINTER(result);
@@ -1431,35 +1422,23 @@ nsNSSComponent::RegisterObservers()
 
   MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent: adding observers\n"));
   // Using false for the ownsweak parameter means the observer service will
   // keep a strong reference to this component. As a result, this will live at
   // least as long as the observer service.
   observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
   observerService->AddObserver(this, PROFILE_BEFORE_CHANGE_TOPIC, false);
   observerService->AddObserver(this, PROFILE_DO_CHANGE_TOPIC, false);
-  observerService->AddObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC, false);
-  observerService->AddObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC, false);
 
   return NS_OK;
 }
 
 void
-nsNSSComponent::DoProfileChangeNetTeardown()
+nsNSSComponent::DoProfileBeforeChange()
 {
-  if (mCertVerificationThread)
-    mCertVerificationThread->requestExit();
-  mIsNetworkDown = true;
-}
-
-void
-nsNSSComponent::DoProfileBeforeChange(nsISupports* aSubject)
-{
-  NS_ASSERTION(mIsNetworkDown, "nsNSSComponent relies on profile manager to wait for synchronous shutdown of all network activity");
-
   bool needsCleanup = true;
 
   {
     MutexAutoLock lock(mutex);
 
     if (!mNSSInitialized) {
       // Make sure we don't try to cleanup if we have already done so.
       // This makes sure we behave safely, in case we are notified
@@ -1468,25 +1447,16 @@ nsNSSComponent::DoProfileBeforeChange(ns
     }
   }
 
   if (needsCleanup) {
     ShutdownNSS();
   }
 }
 
-void
-nsNSSComponent::DoProfileChangeNetRestore()
-{
-  // XXX this doesn't work well, since nothing expects null pointers
-  deleteBackgroundThreads();
-  createBackgroundThreads();
-  mIsNetworkDown = false;
-}
-
 NS_IMETHODIMP
 nsNSSComponent::IsNSSInitialized(bool* initialized)
 {
   MutexAutoLock lock(mutex);
   *initialized = mNSSInitialized;
   return NS_OK;
 }
 
--- a/security/manager/ssl/nsNSSComponent.h
+++ b/security/manager/ssl/nsNSSComponent.h
@@ -155,33 +155,28 @@ private:
   void UnloadLoadableRoots();
   void setValidationOptions(bool isInitialSetting,
                             const mozilla::MutexAutoLock& lock);
   nsresult setEnabledTLSVersions();
   nsresult InitializePIPNSSBundle();
   nsresult ConfigureInternalPKCS11Token();
   nsresult RegisterObservers();
 
-  // Methods that we use to handle the profile change notifications (and to
-  // synthesize a full profile change when we're just doing a profile startup):
-  void DoProfileChangeNetTeardown();
-  void DoProfileBeforeChange(nsISupports* aSubject);
-  void DoProfileChangeNetRestore();
+  void DoProfileBeforeChange();
 
   mozilla::Mutex mutex;
 
   nsCOMPtr<nsIStringBundle> mPIPNSSBundle;
   nsCOMPtr<nsIStringBundle> mNSSErrorsBundle;
   bool mNSSInitialized;
   static int mInstanceCount;
   nsNSSShutDownList* mShutdownObjectList;
 #ifndef MOZ_NO_SMART_CARDS
   SmartCardThreadList* mThreadList;
 #endif
-  bool mIsNetworkDown;
 
   void deleteBackgroundThreads();
   void createBackgroundThreads();
   nsCertVerificationThread* mCertVerificationThread;
 
   nsNSSHttpInterface mHttpForNSS;
   RefPtr<mozilla::psm::SharedCertVerifier> mDefaultCertVerifier;
 
--- a/security/manager/ssl/tests/unit/head_psm.js
+++ b/security/manager/ssl/tests/unit/head_psm.js
@@ -70,16 +70,17 @@ const SSL_ERROR_WEAK_SERVER_CERT_KEY    
 
 const MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE            = MOZILLA_PKIX_ERROR_BASE +   0;
 const MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY     = MOZILLA_PKIX_ERROR_BASE +   1;
 const MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE            = MOZILLA_PKIX_ERROR_BASE +   2; // -16382
 const MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA             = MOZILLA_PKIX_ERROR_BASE +   3;
 const MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE      = MOZILLA_PKIX_ERROR_BASE +   5;
 const MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE = MOZILLA_PKIX_ERROR_BASE + 6;
 const MOZILLA_PKIX_ERROR_OCSP_RESPONSE_FOR_CERT_MISSING = MOZILLA_PKIX_ERROR_BASE +   8;
+const MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING   = MOZILLA_PKIX_ERROR_BASE +  10;
 
 // Supported Certificate Usages
 const certificateUsageSSLClient              = 0x0001;
 const certificateUsageSSLServer              = 0x0002;
 const certificateUsageSSLCA                  = 0x0008;
 const certificateUsageEmailSigner            = 0x0010;
 const certificateUsageEmailRecipient         = 0x0020;
 const certificateUsageObjectSigner           = 0x0040;
--- a/security/manager/ssl/tests/unit/ocsp_certs/moz.build
+++ b/security/manager/ssl/tests/unit/ocsp_certs/moz.build
@@ -8,22 +8,29 @@ test_certificates = (
     'ca-used-as-end-entity.pem',
     'default-ee.pem',
     'delegatedSHA1Signer.pem',
     'delegatedSigner.pem',
     'invalidDelegatedSignerFromIntermediate.pem',
     'invalidDelegatedSignerKeyUsageCrlSigning.pem',
     'invalidDelegatedSignerNoExtKeyUsage.pem',
     'invalidDelegatedSignerWrongExtKeyUsage.pem',
+    'multi-tls-feature-bad-ee.pem',
+    'multi-tls-feature-good-ee.pem',
+    'must-staple-ee.pem',
+    'must-staple-ee-with-must-staple-int.pem',
+    'must-staple-missing-ee.pem',
     'ocspEEWithIntermediate.pem',
     'ocspOtherEndEntity.pem',
     'other-test-ca.pem',
     'rsa-1016-keysizeDelegatedSigner.pem',
     'test-ca.pem',
     'test-int.pem',
+    'test-multi-tls-feature-int.pem',
+    'test-must-staple-int.pem',
 )
 
 for test_certificate in test_certificates:
     input_file = test_certificate + '.certspec'
     GENERATED_FILES += [test_certificate]
     props = GENERATED_FILES[test_certificate]
     props.script = '../pycert.py'
     props.inputs = [input_file]
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-bad-ee.pem.certspec
@@ -0,0 +1,4 @@
+issuer:Test Intermediate With Multiple TLS Features
+subject:Multi TLS Feature Test End-Entity
+extension:subjectAlternativeName:*.example.com
+extension:TLSFeature:OCSPMustStaple
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-good-ee.pem.certspec
@@ -0,0 +1,4 @@
+issuer:Test Intermediate With Multiple TLS Features
+subject:Multi TLS Feature Test End-Entity
+extension:subjectAlternativeName:*.example.com
+extension:TLSFeature:OCSPMustStaple,6
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee-with-must-staple-int.pem.certspec
@@ -0,0 +1,4 @@
+issuer:Test Intermediate With Must-Staple
+subject:Test End-entity
+extension:subjectAlternativeName:*.example.com
+extension:TLSFeature:OCSPMustStaple
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee.pem.certspec
@@ -0,0 +1,4 @@
+issuer:Test CA
+subject:Test End-entity
+extension:subjectAlternativeName:*.example.com
+extension:TLSFeature:OCSPMustStaple
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-missing-ee.pem.certspec
@@ -0,0 +1,3 @@
+issuer:Test Intermediate With Must-Staple
+subject:Test End-entity
+extension:subjectAlternativeName:*.example.com
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/ocsp_certs/test-multi-tls-feature-int.pem.certspec
@@ -0,0 +1,5 @@
+issuer:Test CA
+subject:Test Intermediate With Multiple TLS Features
+extension:basicConstraints:cA,
+extension:keyUsage:cRLSign,keyCertSign
+extension:TLSFeature:OCSPMustStaple,6
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/ocsp_certs/test-must-staple-int.pem.certspec
@@ -0,0 +1,5 @@
+issuer:Test CA
+subject:Test Intermediate With Must-Staple
+extension:basicConstraints:cA,
+extension:keyUsage:cRLSign,keyCertSign
+extension:TLSFeature:OCSPMustStaple
--- a/security/manager/ssl/tests/unit/pycert.py
+++ b/security/manager/ssl/tests/unit/pycert.py
@@ -28,16 +28,17 @@ keyUsage:[digitalSignature,nonRepudiatio
 extKeyUsage:[serverAuth,clientAuth,codeSigning,emailProtection
              nsSGC, # Netscape Server Gated Crypto
              OCSPSigning,timeStamping]
 subjectAlternativeName:[<dNSName>,...]
 authorityInformationAccess:<OCSP URI>
 certificatePolicies:<policy OID>
 nameConstraints:{permitted,excluded}:[<dNSName|directoryName>,...]
 nsCertType:sslServer
+TLSFeature:[<TLSFeature>,...]
 
 Where:
   [] indicates an optional field or component of a field
   <> indicates a required component of a field
   {} indicates a choice of exactly one value among a set of values
   [a,b,c] indicates a list of potential values, of which zero or more
           may be used
 
@@ -64,16 +65,20 @@ Issuer and subject distinguished name sp
 address) are currently supported. The optional stringEncoding field may
 be 'utf8String' or 'printableString'. If the given string does not
 contain a '/', it is assumed to represent a common name.
 DirectoryNames also use this format. When specifying a directoryName in
 a nameConstraints extension, the implicit form may not be used.
 
 If an extension name has '[critical]' after it, it will be marked as
 critical. Otherwise (by default), it will not be marked as critical.
+
+TLSFeature values can either consist of a named value (currently only
+'OCSPMustStaple' which corresponds to status_request) or a numeric tls feature
+value (see rfc7633 for more information).
 """
 
 from pyasn1.codec.der import decoder
 from pyasn1.codec.der import encoder
 from pyasn1.type import constraint, namedtype, tag, univ, useful
 from pyasn1_modules import rfc2459
 import base64
 import datetime
@@ -186,16 +191,23 @@ class UnknownDNTypeError(UnknownBaseErro
 
 class UnknownNSCertTypeError(UnknownBaseError):
     """Helper exception type to handle unknown nsCertType types."""
 
     def __init__(self, value):
         UnknownBaseError.__init__(self, value)
         self.category = 'nsCertType'
 
+class UnknownTLSFeature(UnknownBaseError):
+    """Helper exception type to handle unknown TLS Features."""
+
+    def __init__(self, value):
+        UnknownBaseError.__init__(self, value)
+        self.category = 'TLSFeature'
+
 
 def getASN1Tag(asn1Type):
     """Helper function for returning the base tag value of a given
     type from the pyasn1 package"""
     return asn1Type.baseTagSet.getBaseTag().asTuple()[2]
 
 def stringToAccessDescription(string):
     """Helper function that takes a string representing a URI
@@ -407,16 +419,18 @@ class Certificate(object):
         elif extensionType == 'authorityInformationAccess':
             self.addAuthorityInformationAccess(value, critical)
         elif extensionType == 'certificatePolicies':
             self.addCertificatePolicies(value, critical)
         elif extensionType == 'nameConstraints':
             self.addNameConstraints(value, critical)
         elif extensionType == 'nsCertType':
             self.addNSCertType(value, critical)
+        elif extensionType == 'TLSFeature':
+            self.addTLSFeature(value, critical)
         else:
             raise UnknownExtensionTypeError(extensionType)
 
     def setupKey(self, subjectOrIssuer, value):
         if subjectOrIssuer == 'subject':
             self.subjectKey = pykey.keyFromSpecification(value)
         elif subjectOrIssuer == 'issuer':
             self.issuerKey = pykey.keyFromSpecification(value)
@@ -531,16 +545,35 @@ class Certificate(object):
         self.addExtension(rfc2459.id_ce_nameConstraints, nameConstraints, critical)
 
     def addNSCertType(self, certType, critical):
         if certType != 'sslServer':
             raise UnknownNSCertTypeError(certType)
         self.addExtension(univ.ObjectIdentifier('2.16.840.1.113730.1.1'), univ.BitString("'01'B"),
                           critical)
 
+    def addTLSFeature(self, features, critical):
+        namedFeatures = {'OCSPMustStaple': 5}
+        featureList = [f.strip() for f in features.split(',')]
+        print "FeatureList is",featureList
+        sequence = univ.Sequence()
+        for feature in featureList:
+            featureValue = 0
+            try:
+                featureValue = int(feature)
+            except:
+                try:
+                    featureValue = namedFeatures[feature]
+                except:
+                    raise UnknownTLSFeature(feature)
+            sequence.setComponentByPosition(len(sequence),
+                                            univ.Integer(featureValue))
+        self.addExtension(univ.ObjectIdentifier('1.3.6.1.5.5.7.1.24'), sequence,
+                          critical)
+
     def getVersion(self):
         return rfc2459.Version(self.versionValue).subtype(
             explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))
 
     def getSerialNumber(self):
         return decoder.decode(self.serialNumber)[0]
 
     def getIssuer(self):
--- a/security/manager/ssl/tests/unit/test_ocsp_stapling.js
+++ b/security/manager/ssl/tests/unit/test_ocsp_stapling.js
@@ -150,16 +150,71 @@ function add_tests() {
                 SEC_ERROR_OCSP_INVALID_SIGNING_CERT, true);
   add_ocsp_test("ocsp-stapling-delegated-from-intermediate.example.com",
                 SEC_ERROR_OCSP_INVALID_SIGNING_CERT, true);
   add_ocsp_test("ocsp-stapling-delegated-keyUsage-crlSigning.example.com",
                 SEC_ERROR_OCSP_INVALID_SIGNING_CERT, true);
   add_ocsp_test("ocsp-stapling-delegated-wrong-extKeyUsage.example.com",
                 SEC_ERROR_OCSP_INVALID_SIGNING_CERT, true);
 
+  // TLS Must Staple tests
+  add_test(function() {
+    clearSessionCache();
+    Services.prefs.setBoolPref("security.ssl.enable_ocsp_must_staple", true);
+    run_next_test();
+  });
+
+  // ensure that the chain is checked for required features in children:
+  // First a case where intermediate and ee both have the extension
+  add_ocsp_test("ocsp-stapling-must-staple-ee-with-must-staple-int.example.com",
+                PRErrorCodeSuccess, true);
+
+  // Next, a case where it's present in the intermediate, not the ee
+  add_ocsp_test("ocsp-stapling-plain-ee-with-must-staple-int.example.com",
+                MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING, true);
+
+  // We disable OCSP must-staple in the next two tests so we can perform checks
+  // on TLS Features in the chain without needint to support the TLS
+  // extension values used.
+  // Test an issuer with multiple TLS features in matched in the EE
+  add_ocsp_test("multi-tls-feature-good.example.com",
+                PRErrorCodeSuccess, false);
+
+  // Finally, an inssuer with multiple TLS features not matched by the EE
+  add_ocsp_test("multi-tls-feature-bad.example.com",
+                MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING, false);
+
+
+
+  // Now a bunch of operations with only a must-staple ee
+  add_ocsp_test("ocsp-stapling-must-staple.example.com",
+                PRErrorCodeSuccess, true);
+
+  add_ocsp_test("ocsp-stapling-must-staple-revoked.example.com",
+                SEC_ERROR_REVOKED_CERTIFICATE, true);
+
+  add_ocsp_test("ocsp-stapling-must-staple-missing.example.com",
+                MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING, true);
+
+  add_ocsp_test("ocsp-stapling-must-staple-empty.example.com",
+                SEC_ERROR_OCSP_MALFORMED_RESPONSE, true);
+
+  add_ocsp_test("ocsp-stapling-must-staple-missing.example.com",
+                PRErrorCodeSuccess, false);
+
+  // check that disabling must-staple works
+  add_test(function() {
+    clearSessionCache();
+    Services.prefs.setBoolPref("security.ssl.enable_ocsp_must_staple", false);
+    run_next_test();
+  });
+
+  add_ocsp_test("ocsp-stapling-must-staple-missing.example.com",
+                PRErrorCodeSuccess, true);
+
   // ocsp-stapling-expired.example.com and
   // ocsp-stapling-expired-fresh-ca.example.com are handled in
   // test_ocsp_stapling_expired.js
 
   // Check that OCSP responder certificates with key sizes below 1024 bits are
   // rejected, even when the main certificate chain keys are at least 1024 bits.
   add_ocsp_test("keysize-ocsp-delegated.example.com",
                 SEC_ERROR_OCSP_INVALID_SIGNING_CERT, true);
@@ -170,23 +225,23 @@ function add_tests() {
 
 function check_ocsp_stapling_telemetry() {
   let histogram = Cc["@mozilla.org/base/telemetry;1"]
                     .getService(Ci.nsITelemetry)
                     .getHistogramById("SSL_OCSP_STAPLING")
                     .snapshot();
   equal(histogram.counts[0], 0,
         "Should have 0 connections for unused histogram bucket 0");
-  equal(histogram.counts[1], 5,
+  equal(histogram.counts[1], 7,
         "Actual and expected connections with a good response should match");
-  equal(histogram.counts[2], 18,
+  equal(histogram.counts[2], 22,
         "Actual and expected connections with no stapled response should match");
   equal(histogram.counts[3], 0,
         "Actual and expected connections with an expired response should match");
-  equal(histogram.counts[4], 21,
+  equal(histogram.counts[4], 23,
         "Actual and expected connections with bad responses should match");
   run_next_test();
 }
 
 function run_test() {
   do_get_profile();
 
 
--- a/security/manager/ssl/tests/unit/test_pkcs11_safe_mode.js
+++ b/security/manager/ssl/tests/unit/test_pkcs11_safe_mode.js
@@ -64,17 +64,16 @@ function testFindTestModule(shouldSuccee
     ok(module, "module should be non-null");
   } catch (e) {
     ok(!shouldSucceed, "Failure expected: findModuleByName should throw");
   }
 }
 
 function simulateShutdown() {
   let psmComponent = Cc["@mozilla.org/psm;1"].getService(Ci.nsIObserver);
-  psmComponent.observe(null, "profile-change-net-teardown", null);
   psmComponent.observe(null, "profile-before-change", null);
   psmComponent.observe(null, "xpcom-shutdown", null);
 }
 
 function simulateStartup() {
   let psmComponent = Cc["@mozilla.org/psm;1"].getService(Ci.nsIObserver);
   psmComponent.observe(null, "profile-do-change", null);
 }
--- a/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp
+++ b/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp
@@ -16,73 +16,76 @@
 #include "OCSPCommon.h"
 #include "TLSServer.h"
 
 using namespace mozilla;
 using namespace mozilla::test;
 
 const OCSPHost sOCSPHosts[] =
 {
-  { "ocsp-stapling-good.example.com", ORTGood, nullptr },
-  { "ocsp-stapling-revoked.example.com", ORTRevoked, nullptr },
-  { "ocsp-stapling-revoked-old.example.com", ORTRevokedOld, nullptr },
-  { "ocsp-stapling-unknown.example.com", ORTUnknown, nullptr },
-  { "ocsp-stapling-unknown-old.example.com", ORTUnknownOld, nullptr },
-  { "ocsp-stapling-good-other.example.com", ORTGoodOtherCert, "ocspOtherEndEntity" },
-  { "ocsp-stapling-good-other-ca.example.com", ORTGoodOtherCA, "other-test-ca" },
-  { "ocsp-stapling-expired.example.com", ORTExpired, nullptr },
-  { "ocsp-stapling-expired-fresh-ca.example.com", ORTExpiredFreshCA, nullptr },
-  { "ocsp-stapling-none.example.com", ORTNone, nullptr },
-  { "ocsp-stapling-empty.example.com", ORTEmpty, nullptr },
-  { "ocsp-stapling-malformed.example.com", ORTMalformed, nullptr },
-  { "ocsp-stapling-srverr.example.com", ORTSrverr, nullptr },
-  { "ocsp-stapling-trylater.example.com", ORTTryLater, nullptr },
-  { "ocsp-stapling-needssig.example.com", ORTNeedsSig, nullptr },
-  { "ocsp-stapling-unauthorized.example.com", ORTUnauthorized, nullptr },
-  { "ocsp-stapling-with-intermediate.example.com", ORTGood, "ocspEEWithIntermediate" },
-  { "ocsp-stapling-bad-signature.example.com", ORTBadSignature, nullptr },
-  { "ocsp-stapling-skip-responseBytes.example.com", ORTSkipResponseBytes, nullptr },
-  { "ocsp-stapling-critical-extension.example.com", ORTCriticalExtension, nullptr },
-  { "ocsp-stapling-noncritical-extension.example.com", ORTNoncriticalExtension, nullptr },
-  { "ocsp-stapling-empty-extensions.example.com", ORTEmptyExtensions, nullptr },
-  { "ocsp-stapling-delegated-included.example.com", ORTDelegatedIncluded, "delegatedSigner" },
-  { "ocsp-stapling-delegated-included-last.example.com", ORTDelegatedIncludedLast, "delegatedSigner" },
-  { "ocsp-stapling-delegated-missing.example.com", ORTDelegatedMissing, "delegatedSigner" },
-  { "ocsp-stapling-delegated-missing-multiple.example.com", ORTDelegatedMissingMultiple, "delegatedSigner" },
-  { "ocsp-stapling-delegated-no-extKeyUsage.example.com", ORTDelegatedIncluded, "invalidDelegatedSignerNoExtKeyUsage" },
-  { "ocsp-stapling-delegated-from-intermediate.example.com", ORTDelegatedIncluded, "invalidDelegatedSignerFromIntermediate" },
-  { "ocsp-stapling-delegated-keyUsage-crlSigning.example.com", ORTDelegatedIncluded, "invalidDelegatedSignerKeyUsageCrlSigning" },
-  { "ocsp-stapling-delegated-wrong-extKeyUsage.example.com", ORTDelegatedIncluded, "invalidDelegatedSignerWrongExtKeyUsage" },
-  { "ocsp-stapling-ancient-valid.example.com", ORTAncientAlmostExpired, nullptr},
-  { "keysize-ocsp-delegated.example.com", ORTDelegatedIncluded, "rsa-1016-keysizeDelegatedSigner" },
-  { "revoked-ca-cert-used-as-end-entity.example.com", ORTRevoked, "ca-used-as-end-entity" },
-  { nullptr, ORTNull, nullptr }
+  { "ocsp-stapling-good.example.com", ORTGood, nullptr, nullptr },
+  { "ocsp-stapling-revoked.example.com", ORTRevoked, nullptr, nullptr },
+  { "ocsp-stapling-revoked-old.example.com", ORTRevokedOld, nullptr, nullptr },
+  { "ocsp-stapling-unknown.example.com", ORTUnknown, nullptr, nullptr },
+  { "ocsp-stapling-unknown-old.example.com", ORTUnknownOld, nullptr, nullptr },
+  { "ocsp-stapling-good-other.example.com", ORTGoodOtherCert, "ocspOtherEndEntity", nullptr },
+  { "ocsp-stapling-good-other-ca.example.com", ORTGoodOtherCA, "other-test-ca", nullptr },
+  { "ocsp-stapling-expired.example.com", ORTExpired, nullptr, nullptr },
+  { "ocsp-stapling-expired-fresh-ca.example.com", ORTExpiredFreshCA, nullptr, nullptr },
+  { "ocsp-stapling-none.example.com", ORTNone, nullptr, nullptr },
+  { "ocsp-stapling-empty.example.com", ORTEmpty, nullptr, nullptr },
+  { "ocsp-stapling-malformed.example.com", ORTMalformed, nullptr, nullptr },
+  { "ocsp-stapling-srverr.example.com", ORTSrverr, nullptr, nullptr },
+  { "ocsp-stapling-trylater.example.com", ORTTryLater, nullptr, nullptr },
+  { "ocsp-stapling-needssig.example.com", ORTNeedsSig, nullptr, nullptr },
+  { "ocsp-stapling-unauthorized.example.com", ORTUnauthorized, nullptr, nullptr },
+  { "ocsp-stapling-with-intermediate.example.com", ORTGood, nullptr, "ocspEEWithIntermediate" },
+  { "ocsp-stapling-bad-signature.example.com", ORTBadSignature, nullptr, nullptr },
+  { "ocsp-stapling-skip-responseBytes.example.com", ORTSkipResponseBytes, nullptr, nullptr },
+  { "ocsp-stapling-critical-extension.example.com", ORTCriticalExtension, nullptr, nullptr },
+  { "ocsp-stapling-noncritical-extension.example.com", ORTNoncriticalExtension, nullptr, nullptr },
+  { "ocsp-stapling-empty-extensions.example.com", ORTEmptyExtensions, nullptr, nullptr },
+  { "ocsp-stapling-delegated-included.example.com", ORTDelegatedIncluded, "delegatedSigner", nullptr },
+  { "ocsp-stapling-delegated-included-last.example.com", ORTDelegatedIncludedLast, "delegatedSigner", nullptr },
+  { "ocsp-stapling-delegated-missing.example.com", ORTDelegatedMissing, "delegatedSigner", nullptr },
+  { "ocsp-stapling-delegated-missing-multiple.example.com", ORTDelegatedMissingMultiple, "delegatedSigner", nullptr },
+  { "ocsp-stapling-delegated-no-extKeyUsage.example.com", ORTDelegatedIncluded, "invalidDelegatedSignerNoExtKeyUsage", nullptr },
+  { "ocsp-stapling-delegated-from-intermediate.example.com", ORTDelegatedIncluded, "invalidDelegatedSignerFromIntermediate", nullptr },
+  { "ocsp-stapling-delegated-keyUsage-crlSigning.example.com", ORTDelegatedIncluded, "invalidDelegatedSignerKeyUsageCrlSigning", nullptr },
+  { "ocsp-stapling-delegated-wrong-extKeyUsage.example.com", ORTDelegatedIncluded, "invalidDelegatedSignerWrongExtKeyUsage", nullptr },
+  { "ocsp-stapling-ancient-valid.example.com", ORTAncientAlmostExpired, nullptr, nullptr },
+  { "keysize-ocsp-delegated.example.com", ORTDelegatedIncluded, "rsa-1016-keysizeDelegatedSigner", nullptr },
+  { "revoked-ca-cert-used-as-end-entity.example.com", ORTRevoked, "ca-used-as-end-entity", nullptr },
+  { "ocsp-stapling-must-staple.example.com", ORTGood, nullptr, "must-staple-ee" },
+  { "ocsp-stapling-must-staple-revoked.example.com", ORTRevoked, nullptr, "must-staple-ee" },
+  { "ocsp-stapling-must-staple-missing.example.com", ORTNone, nullptr, "must-staple-ee" },
+  { "ocsp-stapling-must-staple-empty.example.com", ORTEmpty, nullptr, "must-staple-ee" },
+  { "ocsp-stapling-must-staple-ee-with-must-staple-int.example.com", ORTGood, nullptr, "must-staple-ee-with-must-staple-int" },
+  { "ocsp-stapling-plain-ee-with-must-staple-int.example.com", ORTGood, nullptr, "must-staple-missing-ee" },
+  { "multi-tls-feature-good.example.com", ORTNone, nullptr, "multi-tls-feature-good-ee" },
+  { "multi-tls-feature-bad.example.com", ORTNone, nullptr, "multi-tls-feature-bad-ee" },
+  { nullptr, ORTNull, nullptr, nullptr }
 };
 
 int32_t
 DoSNISocketConfig(PRFileDesc *aFd, const SECItem *aSrvNameArr,
                   uint32_t aSrvNameArrSize, void *aArg)
 {
   const OCSPHost *host = GetHostForSNI(aSrvNameArr, aSrvNameArrSize,
                                        sOCSPHosts);
   if (!host) {
     return SSL_SNI_SEND_ALERT;
   }
 
   if (gDebugLevel >= DEBUG_VERBOSE) {
     fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName);
   }
 
-  const char *certNickname;
-  if (strcmp(host->mHostName,
-             "ocsp-stapling-with-intermediate.example.com") == 0) {
-    certNickname = host->mAdditionalCertName;
-  } else {
-    certNickname = DEFAULT_CERT_NICKNAME;
-  }
+  const char *certNickname = host->mServerCertName ? host->mServerCertName
+                                                   : DEFAULT_CERT_NICKNAME;
 
   ScopedCERTCertificate cert;
   SSLKEAType certKEA;
   if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, certNickname,
                                                     &cert, &certKEA)) {
     return SSL_SNI_SEND_ALERT;
   }
 
--- a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.h
+++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.h
@@ -43,15 +43,16 @@ enum OCSPResponseType
   ORTAncientAlmostExpired, // a good response, with a validity of almost two years almost expiring
 };
 
 struct OCSPHost
 {
   const char *mHostName;
   OCSPResponseType mORT;
   const char *mAdditionalCertName; // useful for ORTGoodOtherCert, etc.
+  const char *mServerCertName;
 };
 
 SECItemArray *
 GetOCSPResponseForType(OCSPResponseType aORT, CERTCertificate *aCert,
                        PLArenaPool *aArena, const char *aAdditionalCertName);
 
 #endif // OCSPCommon_h
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-NSS_3_21_Beta3
+NSS_3_21_RTM
--- a/security/nss/cmd/modutil/pk11.c
+++ b/security/nss/cmd/modutil/pk11.c
@@ -707,16 +707,18 @@ ChangePW(char *tokenName, char *pwFile, 
     if(newpwFile) {
 	newpw = SECU_FilePasswd(NULL, PR_FALSE, newpwFile);
     } else {
 	for(matching=PR_FALSE; !matching; ) {
 	    newpw = SECU_GetPasswordString(NULL, "Enter new password: ");
 	    newpw2 = SECU_GetPasswordString(NULL, "Re-enter new password: ");
 	    if(strcmp(newpw, newpw2)) {
 		PR_fprintf(PR_STDOUT, msgStrings[PW_MATCH_MSG]);
+		PORT_ZFree(newpw, strlen(newpw));
+		PORT_ZFree(newpw2, strlen(newpw2));
 	    } else {
 		matching = PR_TRUE;
 	    }
 	}
     }
 
     /* Change the password */
     if(PK11_NeedUserInit(slot)) {
@@ -733,26 +735,23 @@ ChangePW(char *tokenName, char *pwFile, 
 	}
     }
 
     PR_fprintf(PR_STDOUT, msgStrings[CHANGEPW_SUCCESS_MSG], tokenName);
     ret = SUCCESS;
 
 loser:
     if(oldpw) {
-	memset(oldpw, 0, strlen(oldpw));
-	PORT_Free(oldpw);
+	PORT_ZFree(oldpw, strlen(oldpw));
     }
     if(newpw) {
-	memset(newpw, 0, strlen(newpw));
-	PORT_Free(newpw);
+	PORT_ZFree(newpw, strlen(newpw));
     }
     if(newpw2) {
-	memset(newpw2, 0, strlen(newpw2));
-	PORT_Free(newpw2);
+	PORT_ZFree(newpw2, strlen(newpw2));
     }
     PK11_FreeSlot(slot);
 
     return ret;
 }
 
 /***********************************************************************
  *
--- a/security/nss/coreconf/Darwin.mk
+++ b/security/nss/coreconf/Darwin.mk
@@ -1,14 +1,15 @@
 #
 # 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 $(CORE_DEPTH)/coreconf/UNIX.mk
+include $(CORE_DEPTH)/coreconf/Werror.mk
 
 DEFAULT_COMPILER = gcc
 
 CC		= gcc
 CCC		= g++
 RANLIB		= ranlib
 
 ifndef CPU_ARCH
@@ -76,54 +77,17 @@ endif
 # The meaning of a common is ambiguous.  It may be a true definition:
 #     int x = 0;
 # or it may be a declaration of a symbol defined in another file:
 #     extern int x;
 # Use the -fno-common option to force all commons to become true
 # definitions so that the linker can catch multiply-defined symbols.
 # Also, common symbols are not allowed with Darwin dynamic libraries.
 
-OS_CFLAGS	= $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wall -fno-common -pipe -DDARWIN -DHAVE_STRERROR -DHAVE_BSD_FLOCK $(DARWIN_SDK_CFLAGS)
-
-# This tests to see if enabling the warning is possible before
-# setting an option to disable it.
-disable_warning=$(shell $(CC) -x c -E -Werror -W$(1) /dev/null >/dev/null 2>&1 && echo -Wno-$(1)) 
-
-COMPILER_NAME = $(shell $(CC) -? 2>&1 >/dev/null | sed -e 's/:.*//;1q')
-ifeq ($(COMPILER_NAME),clang)
-  # -Qunused-arguments : clang objects to arguments that it doesn't understand
-  #    and fixing this would require rearchitecture
-  OS_CFLAGS += -Qunused-arguments
-  # -Wno-parentheses-equality : because clang warns about macro expansions
-  OS_CFLAGS += $(call disable_warning,parentheses-equality)
-endif
-
-ifndef NSS_ENABLE_WERROR
-  ifeq ($(COMPILER_NAME),clang)
-    NSS_ENABLE_WERROR = 1
-  else
-    NSS_ENABLE_WERROR := $(shell \
-    [ `$(CC) -dumpversion | cut -f 1 -d . -` -eq 4 -a \
-      `$(CC) -dumpversion | cut -f 2 -d . -` -ge 8 -o \
-      `$(CC) -dumpversion | cut -f 1 -d . -` -ge 5 ] && \
-      echo 1 || echo 0)
-    ifneq ($(NSS_ENABLE_WERROR),1)
-      $(warning Unable to find gcc >= 4.8 disabling -Werror)
-    endif
-  endif
-  export NSS_ENABLE_WERROR
-endif
-
-ifeq ($(NSS_ENABLE_WERROR),1)
-  OS_CFLAGS += -Werror
-else
-  # Old versions of gcc (< 4.8) don't support #pragma diagnostic in functions.
-  # Use this to disable use of that #pragma and the warnings it suppresses.
-  OS_CFLAGS += -DNSS_NO_GCC48
-endif
+OS_CFLAGS	= $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(WARNING_CFLAGS) -fno-common -pipe -DDARWIN -DHAVE_STRERROR -DHAVE_BSD_FLOCK $(DARWIN_SDK_CFLAGS)
 
 ifdef BUILD_OPT
 ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE))
 	OPTIMIZER       = -Oz
 else
 	OPTIMIZER	= -O2
 endif
 ifdef MOZ_DEBUG_SYMBOLS
--- a/security/nss/coreconf/Linux.mk
+++ b/security/nss/coreconf/Linux.mk
@@ -1,14 +1,15 @@
 #
 # 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 $(CORE_DEPTH)/coreconf/UNIX.mk
+include $(CORE_DEPTH)/coreconf/Werror.mk
 
 #
 # The default implementation strategy for Linux is now pthreads
 #
 ifneq ($(OS_TARGET),Android)
 	USE_PTHREADS = 1
 endif
 
@@ -127,80 +128,26 @@ ifdef MOZ_DEBUG_SYMBOLS
 		OPTIMIZER += $(MOZ_DEBUG_FLAGS)
 	else
 		OPTIMIZER += -gdwarf-2
 	endif
 endif
 endif
 
 ifndef COMPILER_TAG
-COMPILER_TAG = _$(shell $(CC) -? 2>&1 >/dev/null | sed -e 's/:.*//;1q')
-CCC_COMPILER_TAG = _$(shell $(CCC) -? 2>&1 >/dev/null | sed -e 's/:.*//;1q')
+COMPILER_TAG := _$(CC_NAME)
 endif
 
 ifeq ($(USE_PTHREADS),1)
 OS_PTHREAD = -lpthread 
 endif
 
-OS_CFLAGS		= $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(ARCHFLAG) -Wall -pipe -ffunction-sections -fdata-sections -DLINUX -Dlinux -DHAVE_STRERROR
+OS_CFLAGS		= $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(ARCHFLAG) $(WARNING_CFLAGS) -pipe -ffunction-sections -fdata-sections -DLINUX -Dlinux -DHAVE_STRERROR
 OS_LIBS			= $(OS_PTHREAD) -ldl -lc
 
-# This tests to see if enabling the warning is possible before
-# setting an option to disable it.
-disable_warning=$(shell $(CC) -x c -E -Werror -W$(1) /dev/null >/dev/null 2>&1 && echo -Wno-$(1))
-
-ifeq ($(COMPILER_TAG),_clang)
-  # -Qunused-arguments : clang objects to arguments that it doesn't understand
-  #    and fixing this would require rearchitecture
-  OS_CFLAGS += -Qunused-arguments
-  # -Wno-parentheses-equality : because clang warns about macro expansions
-  OS_CFLAGS += $(call disable_warning,parentheses-equality)
-  ifdef BUILD_OPT
-    # clang is unable to handle glib's expansion of strcmp and similar for optimized
-    # builds, so ignore the resulting errors.
-    # See https://llvm.org/bugs/show_bug.cgi?id=20144
-    OS_CFLAGS += $(call disable_warning,array-bounds)
-    OS_CFLAGS += $(call disable_warning,unevaluated-expression)
-  endif
-endif
-
-ifndef NSS_ENABLE_WERROR
-  ifneq ($(OS_TARGET),Android)
-    # Android lollipop generates the following warning:
-    # error: call to 'sprintf' declared with attribute warning:
-    #   sprintf is often misused; please use snprintf [-Werror]
-    # So, just suppress -Werror entirely on Android
-    NSS_ENABLE_WERROR = 0
-    $(warning !!! OS_TARGET is Android, disabling -Werror)
-  else
-    ifeq ($(COMPILER_TAG),_clang)
-      # Clang reports its version as an older gcc, but it's OK
-      NSS_ENABLE_WERROR = 1
-    else
-      NSS_ENABLE_WERROR := $(shell \
-        [ `$(CC) -dumpversion | cut -f 1 -d . -` -eq 4 -a \
-          `$(CC) -dumpversion | cut -f 2 -d . -` -ge 8 -o \
-          `$(CC) -dumpversion | cut -f 1 -d . -` -ge 5 ] && \
-        echo 1 || echo 0)
-      ifneq ($(NSS_ENABLE_WERROR),1)
-        $(warning !!! Unable to find gcc 4.8 or greater, disabling -Werror)
-      endif
-    endif
-  endif
-  export NSS_ENABLE_WERROR
-endif
-
-ifeq (1,$(NSS_ENABLE_WERROR))
-  OS_CFLAGS += -Werror
-else
-  # Old versions of gcc (< 4.8) don't support #pragma diagnostic in functions.
-  # Use this to disable use of that #pragma and the warnings it suppresses.
-  OS_CFLAGS += -DNSS_NO_GCC48
-endif
-
 ifdef USE_PTHREADS
 	DEFINES		+= -D_REENTRANT
 endif
 
 ARCH			= linux
 
 DSO_CFLAGS		= -fPIC
 DSO_LDOPTS		= -shared $(ARCHFLAG) -Wl,--gc-sections
--- a/security/nss/coreconf/WIN32.mk
+++ b/security/nss/coreconf/WIN32.mk
@@ -108,29 +108,35 @@ ifdef NS_USE_GCC
     _GEN_IMPORT_LIB=-Wl,--out-implib,$(IMPORT_LIBRARY)
     DLLFLAGS  += -mwindows -o $@ -shared -Wl,--export-all-symbols $(if $(IMPORT_LIBRARY),$(_GEN_IMPORT_LIB))
     ifdef BUILD_OPT
 	ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE))
 		OPTIMIZER += -Os
 	else
 		OPTIMIZER += -O2
 	endif
-	DEFINES    += -UDEBUG -U_DEBUG -DNDEBUG
+	DEFINES    += -UDEBUG -DNDEBUG
     else
 	OPTIMIZER  += -g
 	NULLSTRING :=
 	SPACE      := $(NULLSTRING) # end of the line
 	USERNAME   := $(subst $(SPACE),_,$(USERNAME))
 	USERNAME   := $(subst -,_,$(USERNAME))
-	DEFINES    += -DDEBUG -D_DEBUG -UNDEBUG -DDEBUG_$(USERNAME)
+	DEFINES    += -DDEBUG -UNDEBUG -DDEBUG_$(USERNAME)
     endif
 else # !NS_USE_GCC
-    OS_CFLAGS += -W3 -WX -nologo -D_CRT_SECURE_NO_WARNINGS \
+    OS_CFLAGS += -W3 -nologo -D_CRT_SECURE_NO_WARNINGS \
 		 -D_CRT_NONSTDC_NO_WARNINGS
     OS_DLLFLAGS += -nologo -DLL -SUBSYSTEM:WINDOWS
+    ifndef NSS_ENABLE_WERROR
+        NSS_ENABLE_WERROR = 1
+    endif
+    ifeq ($(NSS_ENABLE_WERROR),1)
+        OS_CFLAGS += -WX
+    endif
     ifeq ($(_MSC_VER),$(_MSC_VER_6))
     ifndef MOZ_DEBUG_SYMBOLS
 	OS_DLLFLAGS += -PDB:NONE
     endif
     endif
     ifdef USE_DYNAMICBASE
 	OS_DLLFLAGS += -DYNAMICBASE
     endif
@@ -154,34 +160,34 @@ else # !NS_USE_GCC
 	endif
     endif
     ifdef BUILD_OPT
 	ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE))
 		OPTIMIZER += -O1
 	else
 		OPTIMIZER += -O2
 	endif
-	DEFINES    += -UDEBUG -U_DEBUG -DNDEBUG
+	DEFINES    += -UDEBUG -DNDEBUG
 	DLLFLAGS   += -OUT:$@
 	ifdef MOZ_DEBUG_SYMBOLS
 		ifdef MOZ_DEBUG_FLAGS
 			OPTIMIZER += $(MOZ_DEBUG_FLAGS) -Fd$(OBJDIR)/
 		else
 			OPTIMIZER += -Zi -Fd$(OBJDIR)/
 		endif
 		DLLFLAGS += -DEBUG -OPT:REF
 		LDFLAGS += -DEBUG -OPT:REF
 	endif
     else
 	OPTIMIZER += -Zi -Fd$(OBJDIR)/ -Od
 	NULLSTRING :=
 	SPACE      := $(NULLSTRING) # end of the line
 	USERNAME   := $(subst $(SPACE),_,$(USERNAME))
 	USERNAME   := $(subst -,_,$(USERNAME))
-	DEFINES    += -DDEBUG -D_DEBUG -UNDEBUG -DDEBUG_$(USERNAME)
+	DEFINES    += -DDEBUG -UNDEBUG -DDEBUG_$(USERNAME)
 	DLLFLAGS   += -DEBUG -OUT:$@
 	LDFLAGS    += -DEBUG 
 ifeq ($(_MSC_VER),$(_MSC_VER_6))
 ifndef MOZ_DEBUG_SYMBOLS
 	LDFLAGS    += -PDB:NONE 
 endif
 endif
 	# Purify requires /FIXED:NO when linking EXEs.
new file mode 100644
--- /dev/null
+++ b/security/nss/coreconf/Werror.mk
@@ -0,0 +1,70 @@
+#
+# 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 sets warning flags for unix-like operating systems.
+
+ifndef CC_NAME
+  CC_NAME := $(shell $(CC) -? 2>&1 >/dev/null | sed -e 's/:.*//;1q')
+  export CC_NAME
+endif
+
+ifndef WARNING_CFLAGS
+  # This tests to see if enabling the warning is possible before
+  # setting an option to disable it.
+  disable_warning = $(shell $(CC) -x c -E -Werror -W$(1) /dev/null >/dev/null 2>&1 && echo -Wno-$(1))
+
+  WARNING_CFLAGS = -Wall
+  ifeq ($(CC_NAME),clang)
+    # -Qunused-arguments : clang objects to arguments that it doesn't understand
+    #    and fixing this would require rearchitecture
+    WARNING_CFLAGS += -Qunused-arguments
+    # -Wno-parentheses-equality : because clang warns about macro expansions
+    OS_CFLAGS += $(call disable_warning,parentheses-equality)
+    ifdef BUILD_OPT
+      # clang is unable to handle glib's expansion of strcmp and similar for optimized
+      # builds, so ignore the resulting errors.
+      # See https://llvm.org/bugs/show_bug.cgi?id=20144
+      WARNING_CFLAGS += $(call disable_warning,array-bounds)
+      WARNING_CFLAGS += $(call disable_warning,unevaluated-expression)
+    endif
+  endif # if clang
+
+  ifndef NSS_ENABLE_WERROR
+    ifeq ($(OS_TARGET),Android)
+      # Android lollipop generates the following warning:
+      # error: call to 'sprintf' declared with attribute warning:
+      #   sprintf is often misused; please use snprintf [-Werror]
+      # So, just suppress -Werror entirely on Android
+      NSS_ENABLE_WERROR = 0
+      $(warning OS_TARGET is Android, disabling -Werror)
+    else
+      ifeq ($(CC_NAME),clang)
+        # Clang reports its version as an older gcc, but it's OK
+        NSS_ENABLE_WERROR = 1
+      else
+        CC_VERSION := $(subst ., ,$(shell $(CC) -dumpversion))
+        ifneq (,$(filter 4.8 4.9,$(word 1,$(CC_VERSION)).$(word 2,$(CC_VERSION))))
+          NSS_ENABLE_WERROR = 1
+        endif
+        ifeq (,$(filter 0 1 2 3 4,$(word 1,$(CC_VERSION))))
+          NSS_ENABLE_WERROR = 1
+        endif
+        ifndef NSS_ENABLE_WERROR
+          $(warning Unable to find gcc 4.8 or greater, disabling -Werror)
+          NSS_ENABLE_WERROR = 0
+        endif
+      endif
+    endif
+  endif #ndef NSS_ENABLE_WERROR
+
+  ifeq ($(NSS_ENABLE_WERROR),1)
+    WARNING_CFLAGS += -Werror
+  else
+    # Old versions of gcc (< 4.8) don't support #pragma diagnostic in functions.
+    # Use this to disable use of that #pragma and the warnings it suppresses.
+    WARNING_CFLAGS += -DNSS_NO_GCC48
+  endif
+  export WARNING_CFLAGS
+endif # ndef WARNING_CFLAGS
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,9 +5,8 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
-
--- a/security/nss/external_tests/google_test/Makefile
+++ b/security/nss/external_tests/google_test/Makefile
@@ -39,16 +39,14 @@ include $(CORE_DEPTH)/coreconf/rules.mk
 
 
 #######################################################################
 # (7) Execute "local" rules. (OPTIONAL).                              #
 #######################################################################
 
 MKSHLIB	= $(CCC) $(DSO_LDOPTS) $(DARWIN_SDK_SHLIBFLAGS)
 ifeq (WINNT,$(OS_ARCH))
-    # -MTd (not -MD) because that makes it link to the right library
     # -EHsc because gtest has exception handlers
-    OS_CFLAGS := $(filterout -MD,$(OS_CFLAGS))
-    OS_CFLAGS += -MTd -EHsc
+    OS_CFLAGS += -EHsc
     # On windows, we need to create the parent directory
     # Needed because we include files from a subdirectory
     MAKE_OBJDIR = $(INSTALL) -D $(dir $@)
 endif
--- a/security/nss/external_tests/ssl_gtest/Makefile
+++ b/security/nss/external_tests/ssl_gtest/Makefile
@@ -43,20 +43,18 @@ include $(CORE_DEPTH)/coreconf/rules.mk
 #######################################################################
 
 MKPROG = $(CCC)
 CFLAGS += -I$(CORE_DEPTH)/lib/ssl
 
 include ../../cmd/platrules.mk
 
 ifeq (WINNT,$(OS_ARCH))
-    # -MTd (not -MD) because that makes it link to the right library
     # -EHsc because gtest has exception handlers
-    OS_CFLAGS := $(filterout -MD,$(OS_CFLAGS))
-    OS_CFLAGS += -MTd -EHsc -nologo
+    OS_CFLAGS += -EHsc -nologo
     # http://www.suodenjoki.dk/us/archive/2010/min-max.htm
     OS_CFLAGS += -DNOMINMAX
 
     # Linking to winsock to get htonl
     OS_LIBS += Ws2_32.lib
 else
     CXXFLAGS += -std=c++0x
 endif
--- a/security/nss/external_tests/ssl_gtest/tls_agent.cc
+++ b/security/nss/external_tests/ssl_gtest/tls_agent.cc
@@ -400,17 +400,17 @@ void TlsAgent::EnableExtendedMasterSecre
   SECStatus rv = SSL_OptionSet(ssl_fd_,
                                SSL_ENABLE_EXTENDED_MASTER_SECRET,
                                PR_TRUE);
 
   ASSERT_EQ(SECSuccess, rv);
 }
 
 void TlsAgent::CheckExtendedMasterSecret(bool expected) {
-  ASSERT_EQ(expected, static_cast<bool>(info_.extendedMasterSecretUsed))
+  ASSERT_EQ(expected, info_.extendedMasterSecretUsed != PR_FALSE)
       << "unexpected extended master secret state for " << name_;
 }
 
 void TlsAgent::DisableRollbackDetection() {
   ASSERT_TRUE(EnsureTlsSetup());
 
   SECStatus rv = SSL_OptionSet(ssl_fd_,
                                SSL_ROLLBACK_DETECTION,
--- a/security/nss/lib/ckfw/builtins/certdata.txt
+++ b/security/nss/lib/ckfw/builtins/certdata.txt
@@ -182,19 +182,19 @@ CKA_ISSUER MULTILINE_OCTAL
 \020\060\016\006\003\125\004\012\023\007\105\161\165\151\146\141
 \170\061\055\060\053\006\003\125\004\013\023\044\105\161\165\151
 \146\141\170\040\123\145\143\165\162\145\040\103\145\162\164\151
 \146\151\143\141\164\145\040\101\165\164\150\157\162\151\164\171
 END
 CKA_SERIAL_NUMBER MULTILINE_OCTAL
 \002\004\065\336\364\317
 END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
 CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
 
 # Distrust "Distrust a pb.com certificate that does not comply with the baseline requirements."
 # Issuer: OU=Equifax Secure Certificate Authority,O=Equifax,C=US
 # Serial Number: 1407252 (0x157914)
 # Subject: CN=*.pb.com,OU=Meters,O=Pitney Bowes,L=Danbury,ST=Connecticut,C=US
 # Not Valid Before: Mon Feb 01 14:54:04 2010
 # Not Valid After : Tue Sep 30 00:00:00 2014
@@ -216,262 +216,16 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL
 \002\003\025\171\024
 END
 CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
 CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
 CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
 CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
 
 #
-# Certificate "Digital Signature Trust Co. Global CA 1"
-#
-# Issuer: OU=DSTCA E1,O=Digital Signature Trust Co.,C=US
-# Serial Number: 913315222 (0x36701596)
-# Subject: OU=DSTCA E1,O=Digital Signature Trust Co.,C=US
-# Not Valid Before: Thu Dec 10 18:10:23 1998
-# Not Valid After : Mon Dec 10 18:40:23 2018
-# Fingerprint (MD5): 25:7A:BA:83:2E:B6:A2:0B:DA:FE:F5:02:0F:08:D7:AD
-# Fingerprint (SHA1): 81:96:8B:3A:EF:1C:DC:70:F5:FA:32:69:C2:92:A3:63:5B:D1:23:D3
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Digital Signature Trust Co. Global CA 1"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\106\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\040\103\157\056\061\021\060\017\006\003\125\004\013\023\010
-\104\123\124\103\101\040\105\061
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\106\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\040\103\157\056\061\021\060\017\006\003\125\004\013\023\010
-\104\123\124\103\101\040\105\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\066\160\025\226
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\051\060\202\002\222\240\003\002\001\002\002\004\066
-\160\025\226\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\106\061\013\060\011\006\003\125\004\006\023\002\125
-\123\061\044\060\042\006\003\125\004\012\023\033\104\151\147\151
-\164\141\154\040\123\151\147\156\141\164\165\162\145\040\124\162
-\165\163\164\040\103\157\056\061\021\060\017\006\003\125\004\013
-\023\010\104\123\124\103\101\040\105\061\060\036\027\015\071\070
-\061\062\061\060\061\070\061\060\062\063\132\027\015\061\070\061
-\062\061\060\061\070\064\060\062\063\132\060\106\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\044\060\042\006\003\125
-\004\012\023\033\104\151\147\151\164\141\154\040\123\151\147\156
-\141\164\165\162\145\040\124\162\165\163\164\040\103\157\056\061
-\021\060\017\006\003\125\004\013\023\010\104\123\124\103\101\040
-\105\061\060\201\235\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\201\213\000\060\201\207\002\201\201\000\240
-\154\201\251\317\064\036\044\335\376\206\050\314\336\203\057\371
-\136\324\102\322\350\164\140\146\023\230\006\034\251\121\022\151
-\157\061\125\271\111\162\000\010\176\323\245\142\104\067\044\231
-\217\331\203\110\217\231\155\225\023\273\103\073\056\111\116\210
-\067\301\273\130\177\376\341\275\370\273\141\315\363\107\300\231
-\246\361\363\221\350\170\174\000\313\141\311\104\047\161\151\125
-\112\176\111\115\355\242\243\276\002\114\000\312\002\250\356\001
-\002\061\144\017\122\055\023\164\166\066\265\172\264\055\161\002
-\001\003\243\202\001\044\060\202\001\040\060\021\006\011\140\206
-\110\001\206\370\102\001\001\004\004\003\002\000\007\060\150\006
-\003\125\035\037\004\141\060\137\060\135\240\133\240\131\244\127
-\060\125\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\040\103\157\056\061\021\060\017\006\003\125\004\013\023\010
-\104\123\124\103\101\040\105\061\061\015\060\013\006\003\125\004
-\003\023\004\103\122\114\061\060\053\006\003\125\035\020\004\044
-\060\042\200\017\061\071\071\070\061\062\061\060\061\070\061\060
-\062\063\132\201\017\062\060\061\070\061\062\061\060\061\070\061
-\060\062\063\132\060\013\006\003\125\035\017\004\004\003\002\001
-\006\060\037\006\003\125\035\043\004\030\060\026\200\024\152\171
-\176\221\151\106\030\023\012\002\167\245\131\133\140\230\045\016
-\242\370\060\035\006\003\125\035\016\004\026\004\024\152\171\176
-\221\151\106\030\023\012\002\167\245\131\133\140\230\045\016\242
-\370\060\014\006\003\125\035\023\004\005\060\003\001\001\377\060
-\031\006\011\052\206\110\206\366\175\007\101\000\004\014\060\012
-\033\004\126\064\056\060\003\002\004\220\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\201\201\000\042\022\330
-\172\035\334\201\006\266\011\145\262\207\310\037\136\264\057\351
-\304\036\362\074\301\273\004\220\021\112\203\116\176\223\271\115
-\102\307\222\046\240\134\064\232\070\162\370\375\153\026\076\040
-\356\202\213\061\052\223\066\205\043\210\212\074\003\150\323\311
-\011\017\115\374\154\244\332\050\162\223\016\211\200\260\175\376
-\200\157\145\155\030\063\227\213\302\153\211\356\140\075\310\233
-\357\177\053\062\142\163\223\313\074\343\173\342\166\170\105\274
-\241\223\004\273\206\237\072\133\103\172\303\212\145
-END
-
-# Trust for Certificate "Digital Signature Trust Co. Global CA 1"
-# Issuer: OU=DSTCA E1,O=Digital Signature Trust Co.,C=US
-# Serial Number: 913315222 (0x36701596)
-# Subject: OU=DSTCA E1,O=Digital Signature Trust Co.,C=US
-# Not Valid Before: Thu Dec 10 18:10:23 1998
-# Not Valid After : Mon Dec 10 18:40:23 2018
-# Fingerprint (MD5): 25:7A:BA:83:2E:B6:A2:0B:DA:FE:F5:02:0F:08:D7:AD
-# Fingerprint (SHA1): 81:96:8B:3A:EF:1C:DC:70:F5:FA:32:69:C2:92:A3:63:5B:D1:23:D3
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Digital Signature Trust Co. Global CA 1"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\201\226\213\072\357\034\334\160\365\372\062\151\302\222\243\143
-\133\321\043\323
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\045\172\272\203\056\266\242\013\332\376\365\002\017\010\327\255
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\106\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\040\103\157\056\061\021\060\017\006\003\125\004\013\023\010
-\104\123\124\103\101\040\105\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\066\160\025\226
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Digital Signature Trust Co. Global CA 3"
-#
-# Issuer: OU=DSTCA E2,O=Digital Signature Trust Co.,C=US
-# Serial Number: 913232846 (0x366ed3ce)
-# Subject: OU=DSTCA E2,O=Digital Signature Trust Co.,C=US
-# Not Valid Before: Wed Dec 09 19:17:26 1998
-# Not Valid After : Sun Dec 09 19:47:26 2018
-# Fingerprint (MD5): 93:C2:8E:11:7B:D4:F3:03:19:BD:28:75:13:4A:45:4A
-# Fingerprint (SHA1): AB:48:F3:33:DB:04:AB:B9:C0:72:DA:5B:0C:C1:D0:57:F0:36:9B:46
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Digital Signature Trust Co. Global CA 3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\106\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\040\103\157\056\061\021\060\017\006\003\125\004\013\023\010
-\104\123\124\103\101\040\105\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\106\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\040\103\157\056\061\021\060\017\006\003\125\004\013\023\010
-\104\123\124\103\101\040\105\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\066\156\323\316
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\051\060\202\002\222\240\003\002\001\002\002\004\066
-\156\323\316\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\106\061\013\060\011\006\003\125\004\006\023\002\125
-\123\061\044\060\042\006\003\125\004\012\023\033\104\151\147\151
-\164\141\154\040\123\151\147\156\141\164\165\162\145\040\124\162
-\165\163\164\040\103\157\056\061\021\060\017\006\003\125\004\013
-\023\010\104\123\124\103\101\040\105\062\060\036\027\015\071\070
-\061\062\060\071\061\071\061\067\062\066\132\027\015\061\070\061
-\062\060\071\061\071\064\067\062\066\132\060\106\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\044\060\042\006\003\125
-\004\012\023\033\104\151\147\151\164\141\154\040\123\151\147\156
-\141\164\165\162\145\040\124\162\165\163\164\040\103\157\056\061
-\021\060\017\006\003\125\004\013\023\010\104\123\124\103\101\040
-\105\062\060\201\235\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\201\213\000\060\201\207\002\201\201\000\277
-\223\217\027\222\357\063\023\030\353\020\177\116\026\277\377\006
-\217\052\205\274\136\371\044\246\044\210\266\003\267\301\303\137
-\003\133\321\157\256\176\102\352\146\043\270\143\203\126\373\050
-\055\341\070\213\264\356\250\001\341\316\034\266\210\052\042\106
-\205\373\237\247\160\251\107\024\077\316\336\145\360\250\161\367
-\117\046\154\214\274\306\265\357\336\111\047\377\110\052\175\350
-\115\003\314\307\262\122\306\027\061\023\073\265\115\333\310\304
-\366\303\017\044\052\332\014\235\347\221\133\200\315\224\235\002
-\001\003\243\202\001\044\060\202\001\040\060\021\006\011\140\206
-\110\001\206\370\102\001\001\004\004\003\002\000\007\060\150\006
-\003\125\035\037\004\141\060\137\060\135\240\133\240\131\244\127
-\060\125\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\040\103\157\056\061\021\060\017\006\003\125\004\013\023\010
-\104\123\124\103\101\040\105\062\061\015\060\013\006\003\125\004
-\003\023\004\103\122\114\061\060\053\006\003\125\035\020\004\044
-\060\042\200\017\061\071\071\070\061\062\060\071\061\071\061\067
-\062\066\132\201\017\062\060\061\070\061\062\060\071\061\071\061
-\067\062\066\132\060\013\006\003\125\035\017\004\004\003\002\001
-\006\060\037\006\003\125\035\043\004\030\060\026\200\024\036\202
-\115\050\145\200\074\311\101\156\254\065\056\132\313\336\356\370
-\071\133\060\035\006\003\125\035\016\004\026\004\024\036\202\115
-\050\145\200\074\311\101\156\254\065\056\132\313\336\356\370\071
-\133\060\014\006\003\125\035\023\004\005\060\003\001\001\377\060
-\031\006\011\052\206\110\206\366\175\007\101\000\004\014\060\012
-\033\004\126\064\056\060\003\002\004\220\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\201\201\000\107\215\203
-\255\142\362\333\260\236\105\042\005\271\242\326\003\016\070\162
-\347\236\374\173\346\223\266\232\245\242\224\310\064\035\221\321
-\305\327\364\012\045\017\075\170\201\236\017\261\147\304\220\114
-\143\335\136\247\342\272\237\365\367\115\245\061\173\234\051\055
-\114\376\144\076\354\266\123\376\352\233\355\202\333\164\165\113
-\007\171\156\036\330\031\203\163\336\365\076\320\265\336\347\113
-\150\175\103\056\052\040\341\176\240\170\104\236\010\365\230\371
-\307\177\033\033\326\006\040\002\130\241\303\242\003
-END
-
-# Trust for Certificate "Digital Signature Trust Co. Global CA 3"
-# Issuer: OU=DSTCA E2,O=Digital Signature Trust Co.,C=US
-# Serial Number: 913232846 (0x366ed3ce)
-# Subject: OU=DSTCA E2,O=Digital Signature Trust Co.,C=US
-# Not Valid Before: Wed Dec 09 19:17:26 1998
-# Not Valid After : Sun Dec 09 19:47:26 2018
-# Fingerprint (MD5): 93:C2:8E:11:7B:D4:F3:03:19:BD:28:75:13:4A:45:4A
-# Fingerprint (SHA1): AB:48:F3:33:DB:04:AB:B9:C0:72:DA:5B:0C:C1:D0:57:F0:36:9B:46
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Digital Signature Trust Co. Global CA 3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\253\110\363\063\333\004\253\271\300\162\332\133\014\301\320\127
-\360\066\233\106
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\223\302\216\021\173\324\363\003\031\275\050\165\023\112\105\112
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\106\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\040\103\157\056\061\021\060\017\006\003\125\004\013\023\010
-\104\123\124\103\101\040\105\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\066\156\323\316
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
 # Certificate "Verisign Class 3 Public Primary Certification Authority"
 #
 # Issuer: OU=Class 3 Public Primary Certification Authority,O="VeriSign, Inc.",C=US
 # Serial Number:70:ba:e4:1d:10:d9:29:34:b6:38:ca:7b:03:cc:ba:bf
 # Subject: OU=Class 3 Public Primary Certification Authority,O="VeriSign, Inc.",C=US
 # Not Valid Before: Mon Jan 29 00:00:00 1996
 # Not Valid After : Tue Aug 01 23:59:59 2028
 # Fingerprint (MD5): 10:FC:63:5D:F6:26:3E:0D:F3:25:BE:5F:79:CD:67:67
@@ -1886,180 +1640,16 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL
 \012\166
 END
 CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
 CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
 CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
 CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
 
 #
-# Certificate "Verisign Class 4 Public Primary Certification Authority - G3"
-#
-# Issuer: CN=VeriSign Class 4 Public Primary Certification Authority - G3,OU="(c) 1999 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US
-# Serial Number:00:ec:a0:a7:8b:6e:75:6a:01:cf:c4:7c:cc:2f:94:5e:d7
-# Subject: CN=VeriSign Class 4 Public Primary Certification Authority - G3,OU="(c) 1999 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US
-# Not Valid Before: Fri Oct 01 00:00:00 1999
-# Not Valid After : Wed Jul 16 23:59:59 2036
-# Fingerprint (MD5): DB:C8:F2:27:2E:B1:EA:6A:29:23:5D:FE:56:3E:33:DF
-# Fingerprint (SHA1): C8:EC:8C:87:92:69:CB:4B:AB:39:E9:8D:7E:57:67:F3:14:95:73:9D
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 4 Public Primary Certification Authority - G3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\061\071\071\071\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\064\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\061\071\071\071\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\064\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\354\240\247\213\156\165\152\001\317\304\174\314\057
-\224\136\327
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\032\060\202\003\002\002\021\000\354\240\247\213\156
-\165\152\001\317\304\174\314\057\224\136\327\060\015\006\011\052
-\206\110\206\367\015\001\001\005\005\000\060\201\312\061\013\060
-\011\006\003\125\004\006\023\002\125\123\061\027\060\025\006\003
-\125\004\012\023\016\126\145\162\151\123\151\147\156\054\040\111
-\156\143\056\061\037\060\035\006\003\125\004\013\023\026\126\145
-\162\151\123\151\147\156\040\124\162\165\163\164\040\116\145\164
-\167\157\162\153\061\072\060\070\006\003\125\004\013\023\061\050
-\143\051\040\061\071\071\071\040\126\145\162\151\123\151\147\156
-\054\040\111\156\143\056\040\055\040\106\157\162\040\141\165\164
-\150\157\162\151\172\145\144\040\165\163\145\040\157\156\154\171
-\061\105\060\103\006\003\125\004\003\023\074\126\145\162\151\123
-\151\147\156\040\103\154\141\163\163\040\064\040\120\165\142\154
-\151\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\055\040\107\063\060\036\027\015\071\071\061\060\060
-\061\060\060\060\060\060\060\132\027\015\063\066\060\067\061\066
-\062\063\065\071\065\071\132\060\201\312\061\013\060\011\006\003
-\125\004\006\023\002\125\123\061\027\060\025\006\003\125\004\012
-\023\016\126\145\162\151\123\151\147\156\054\040\111\156\143\056
-\061\037\060\035\006\003\125\004\013\023\026\126\145\162\151\123
-\151\147\156\040\124\162\165\163\164\040\116\145\164\167\157\162
-\153\061\072\060\070\006\003\125\004\013\023\061\050\143\051\040
-\061\071\071\071\040\126\145\162\151\123\151\147\156\054\040\111
-\156\143\056\040\055\040\106\157\162\040\141\165\164\150\157\162
-\151\172\145\144\040\165\163\145\040\157\156\154\171\061\105\060
-\103\006\003\125\004\003\023\074\126\145\162\151\123\151\147\156
-\040\103\154\141\163\163\040\064\040\120\165\142\154\151\143\040
-\120\162\151\155\141\162\171\040\103\145\162\164\151\146\151\143
-\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040
-\055\040\107\063\060\202\001\042\060\015\006\011\052\206\110\206
-\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012
-\002\202\001\001\000\255\313\245\021\151\306\131\253\361\217\265
-\031\017\126\316\314\265\037\040\344\236\046\045\113\340\163\145
-\211\131\336\320\203\344\365\017\265\273\255\361\174\350\041\374
-\344\350\014\356\174\105\042\031\166\222\264\023\267\040\133\011
-\372\141\256\250\362\245\215\205\302\052\326\336\146\066\322\233
-\002\364\250\222\140\174\234\151\264\217\044\036\320\206\122\366
-\062\234\101\130\036\042\275\315\105\142\225\010\156\320\146\335
-\123\242\314\360\020\334\124\163\213\004\241\106\063\063\134\027
-\100\271\236\115\323\363\276\125\203\350\261\211\216\132\174\232
-\226\042\220\073\210\045\362\322\123\210\002\014\013\170\362\346
-\067\027\113\060\106\007\344\200\155\246\330\226\056\350\054\370
-\021\263\070\015\146\246\233\352\311\043\133\333\216\342\363\023
-\216\032\131\055\252\002\360\354\244\207\146\334\301\077\365\330
-\271\364\354\202\306\322\075\225\035\345\300\117\204\311\331\243
-\104\050\006\152\327\105\254\360\153\152\357\116\137\370\021\202
-\036\070\143\064\146\120\324\076\223\163\372\060\303\146\255\377
-\223\055\227\357\003\002\003\001\000\001\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\202\001\001\000\217\372
-\045\153\117\133\344\244\116\047\125\253\042\025\131\074\312\265
-\012\324\112\333\253\335\241\137\123\305\240\127\071\302\316\107
-\053\276\072\310\126\277\302\331\047\020\072\261\005\074\300\167
-\061\273\072\323\005\173\155\232\034\060\214\200\313\223\223\052
-\203\253\005\121\202\002\000\021\147\153\363\210\141\107\137\003
-\223\325\133\015\340\361\324\241\062\065\205\262\072\333\260\202
-\253\321\313\012\274\117\214\133\305\113\000\073\037\052\202\246
-\176\066\205\334\176\074\147\000\265\344\073\122\340\250\353\135
-\025\371\306\155\360\255\035\016\205\267\251\232\163\024\132\133
-\217\101\050\300\325\350\055\115\244\136\315\252\331\355\316\334
-\330\325\074\102\035\027\301\022\135\105\070\303\070\363\374\205
-\056\203\106\110\262\327\040\137\222\066\217\347\171\017\230\136
-\231\350\360\320\244\273\365\123\275\052\316\131\260\257\156\177
-\154\273\322\036\000\260\041\355\370\101\142\202\271\330\262\304
-\273\106\120\363\061\305\217\001\250\164\353\365\170\047\332\347
-\367\146\103\363\236\203\076\040\252\303\065\140\221\316
-END
-
-# Trust for Certificate "Verisign Class 4 Public Primary Certification Authority - G3"
-# Issuer: CN=VeriSign Class 4 Public Primary Certification Authority - G3,OU="(c) 1999 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US
-# Serial Number:00:ec:a0:a7:8b:6e:75:6a:01:cf:c4:7c:cc:2f:94:5e:d7
-# Subject: CN=VeriSign Class 4 Public Primary Certification Authority - G3,OU="(c) 1999 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US
-# Not Valid Before: Fri Oct 01 00:00:00 1999
-# Not Valid After : Wed Jul 16 23:59:59 2036
-# Fingerprint (MD5): DB:C8:F2:27:2E:B1:EA:6A:29:23:5D:FE:56:3E:33:DF
-# Fingerprint (SHA1): C8:EC:8C:87:92:69:CB:4B:AB:39:E9:8D:7E:57:67:F3:14:95:73:9D
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 4 Public Primary Certification Authority - G3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\310\354\214\207\222\151\313\113\253\071\351\215\176\127\147\363
-\024\225\163\235
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\333\310\362\047\056\261\352\152\051\043\135\376\126\076\063\337
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\061\071\071\071\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\064\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\354\240\247\213\156\165\152\001\317\304\174\314\057
-\224\136\327
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
 # Certificate "Entrust.net Premium 2048 Secure Server CA"
 #
 # Issuer: CN=Entrust.net Certification Authority (2048),OU=(c) 1999 Entrust.net Limited,OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.),O=Entrust.net
 # Serial Number: 946069240 (0x3863def8)
 # Subject: CN=Entrust.net Certification Authority (2048),OU=(c) 1999 Entrust.net Limited,OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.),O=Entrust.net
 # Not Valid Before: Fri Dec 24 17:50:51 1999
 # Not Valid After : Tue Jul 24 14:15:12 2029
 # Fingerprint (MD5): EE:29:31:BC:32:7E:9A:E6:E8:B5:F7:51:B4:34:71:90
@@ -4020,179 +3610,16 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL
 \002\001\001
 END
 CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
 CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
 CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
 CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
 
 #
-# Certificate "UTN-USER First-Network Applications"
-#
-# Issuer: CN=UTN-USERFirst-Network Applications,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US
-# Serial Number:44:be:0c:8b:50:00:24:b4:11:d3:36:30:4b:c0:33:77
-# Subject: CN=UTN-USERFirst-Network Applications,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US
-# Not Valid Before: Fri Jul 09 18:48:39 1999
-# Not Valid After : Tue Jul 09 18:57:49 2019
-# Fingerprint (MD5): BF:60:59:A3:5B:BA:F6:A7:76:42:DA:6F:1A:7B:50:CF
-# Fingerprint (SHA1): 5D:98:9C:DB:15:96:11:36:51:65:64:1B:56:0F:DB:EA:2A:C2:3E:F1
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "UTN-USER First-Network Applications"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\243\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\053\060\051\006\003\125
-\004\003\023\042\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\116\145\164\167\157\162\153\040\101\160\160\154\151\143
-\141\164\151\157\156\163
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\243\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\053\060\051\006\003\125
-\004\003\023\042\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\116\145\164\167\157\162\153\040\101\160\160\154\151\143
-\141\164\151\157\156\163
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\276\014\213\120\000\044\264\021\323\066\060\113\300
-\063\167
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\144\060\202\003\114\240\003\002\001\002\002\020\104
-\276\014\213\120\000\044\264\021\323\066\060\113\300\063\167\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\243\061\013\060\011\006\003\125\004\006\023\002\125\123\061\013
-\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025\006
-\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145\040
-\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025\124
-\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145\164
-\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030\150
-\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164\162
-\165\163\164\056\143\157\155\061\053\060\051\006\003\125\004\003
-\023\042\125\124\116\055\125\123\105\122\106\151\162\163\164\055
-\116\145\164\167\157\162\153\040\101\160\160\154\151\143\141\164
-\151\157\156\163\060\036\027\015\071\071\060\067\060\071\061\070
-\064\070\063\071\132\027\015\061\071\060\067\060\071\061\070\065
-\067\064\071\132\060\201\243\061\013\060\011\006\003\125\004\006
-\023\002\125\123\061\013\060\011\006\003\125\004\010\023\002\125
-\124\061\027\060\025\006\003\125\004\007\023\016\123\141\154\164
-\040\114\141\153\145\040\103\151\164\171\061\036\060\034\006\003
-\125\004\012\023\025\124\150\145\040\125\123\105\122\124\122\125
-\123\124\040\116\145\164\167\157\162\153\061\041\060\037\006\003
-\125\004\013\023\030\150\164\164\160\072\057\057\167\167\167\056
-\165\163\145\162\164\162\165\163\164\056\143\157\155\061\053\060
-\051\006\003\125\004\003\023\042\125\124\116\055\125\123\105\122
-\106\151\162\163\164\055\116\145\164\167\157\162\153\040\101\160
-\160\154\151\143\141\164\151\157\156\163\060\202\001\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001
-\017\000\060\202\001\012\002\202\001\001\000\263\373\221\241\344
-\066\125\205\254\006\064\133\240\232\130\262\370\265\017\005\167
-\203\256\062\261\166\222\150\354\043\112\311\166\077\343\234\266
-\067\171\003\271\253\151\215\007\045\266\031\147\344\260\033\030
-\163\141\112\350\176\315\323\057\144\343\246\174\014\372\027\200
-\243\015\107\211\117\121\161\057\356\374\077\371\270\026\200\207
-\211\223\045\040\232\103\202\151\044\166\050\131\065\241\035\300
-\177\203\006\144\026\040\054\323\111\244\205\264\300\141\177\121
-\010\370\150\025\221\200\313\245\325\356\073\072\364\204\004\136
-\140\131\247\214\064\162\356\270\170\305\321\073\022\112\157\176
-\145\047\271\244\125\305\271\157\103\244\305\035\054\231\300\122
-\244\170\114\025\263\100\230\010\153\103\306\001\260\172\173\365
-\153\034\042\077\313\357\377\250\320\072\113\166\025\236\322\321
-\306\056\343\333\127\033\062\242\270\157\350\206\246\077\160\253
-\345\160\222\253\104\036\100\120\373\234\243\142\344\154\156\240
-\310\336\342\200\102\372\351\057\350\316\062\004\217\174\215\267
-\034\243\065\074\025\335\236\303\256\227\245\002\003\001\000\001
-\243\201\221\060\201\216\060\013\006\003\125\035\017\004\004\003
-\002\001\306\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\035\006\003\125\035\016\004\026\004\024\372
-\206\311\333\340\272\351\170\365\113\250\326\025\337\360\323\341
-\152\024\074\060\117\006\003\125\035\037\004\110\060\106\060\104
-\240\102\240\100\206\076\150\164\164\160\072\057\057\143\162\154
-\056\165\163\145\162\164\162\165\163\164\056\143\157\155\057\125
-\124\116\055\125\123\105\122\106\151\162\163\164\055\116\145\164
-\167\157\162\153\101\160\160\154\151\143\141\164\151\157\156\163
-\056\143\162\154\060\015\006\011\052\206\110\206\367\015\001\001
-\005\005\000\003\202\001\001\000\244\363\045\314\321\324\221\203
-\042\320\314\062\253\233\226\116\064\221\124\040\045\064\141\137
-\052\002\025\341\213\252\377\175\144\121\317\012\377\274\175\330
-\041\152\170\313\057\121\157\370\102\035\063\275\353\265\173\224
-\303\303\251\240\055\337\321\051\037\035\376\217\077\273\250\105
-\052\177\321\156\125\044\342\273\002\373\061\077\276\350\274\354
-\100\053\370\001\324\126\070\344\312\104\202\265\141\040\041\147
-\145\366\360\013\347\064\370\245\302\234\243\134\100\037\205\223
-\225\006\336\117\324\047\251\266\245\374\026\315\163\061\077\270
-\145\047\317\324\123\032\360\254\156\237\117\005\014\003\201\247
-\204\051\304\132\275\144\127\162\255\073\317\067\030\246\230\306
-\255\006\264\334\010\243\004\325\051\244\226\232\022\147\112\214
-\140\105\235\361\043\232\260\000\234\150\265\230\120\323\357\216
-\056\222\145\261\110\076\041\276\025\060\052\015\265\014\243\153
-\077\256\177\127\365\037\226\174\337\157\335\202\060\054\145\033
-\100\112\315\150\271\162\354\161\166\354\124\216\037\205\014\001
-\152\372\246\070\254\037\304\204
-END
-
-# Trust for Certificate "UTN-USER First-Network Applications"
-# Issuer: CN=UTN-USERFirst-Network Applications,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US
-# Serial Number:44:be:0c:8b:50:00:24:b4:11:d3:36:30:4b:c0:33:77
-# Subject: CN=UTN-USERFirst-Network Applications,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US
-# Not Valid Before: Fri Jul 09 18:48:39 1999
-# Not Valid After : Tue Jul 09 18:57:49 2019
-# Fingerprint (MD5): BF:60:59:A3:5B:BA:F6:A7:76:42:DA:6F:1A:7B:50:CF
-# Fingerprint (SHA1): 5D:98:9C:DB:15:96:11:36:51:65:64:1B:56:0F:DB:EA:2A:C2:3E:F1
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "UTN-USER First-Network Applications"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\135\230\234\333\025\226\021\066\121\145\144\033\126\017\333\352
-\052\302\076\361
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\277\140\131\243\133\272\366\247\166\102\332\157\032\173\120\317
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\243\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\053\060\051\006\003\125
-\004\003\023\042\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\116\145\164\167\157\162\153\040\101\160\160\154\151\143
-\141\164\151\157\156\163
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\276\014\213\120\000\044\264\021\323\066\060\113\300
-\063\167
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
 # Certificate "Visa eCommerce Root"
 #
 # Issuer: CN=Visa eCommerce Root,OU=Visa International Service Association,O=VISA,C=US
 # Serial Number:13:86:35:4d:1d:3f:06:f2:c1:f9:65:05:d5:90:1c:62
 # Subject: CN=Visa eCommerce Root,OU=Visa International Service Association,O=VISA,C=US
 # Not Valid Before: Wed Jun 26 02:18:36 2002
 # Not Valid After : Fri Jun 24 00:16:12 2022
 # Fingerprint (MD5): FC:11:B8:D8:08:93:30:00:6D:23:F9:7E:EB:52:1E:02
@@ -5917,176 +5344,16 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL
 \002\004\000\230\226\212
 END
 CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
 CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
 CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
 CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
 
 #
-# Certificate "UTN DATACorp SGC Root CA"
-#
-# Issuer: CN=UTN - DATACorp SGC,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US
-# Serial Number:44:be:0c:8b:50:00:21:b4:11:d3:2a:68:06:a9:ad:69
-# Subject: CN=UTN - DATACorp SGC,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US
-# Not Valid Before: Thu Jun 24 18:57:21 1999
-# Not Valid After : Mon Jun 24 19:06:30 2019
-# Fingerprint (MD5): B3:A5:3E:77:21:6D:AC:4A:C0:C9:FB:D5:41:3D:CA:06
-# Fingerprint (SHA1): 58:11:9F:0E:12:82:87:EA:50:FD:D9:87:45:6F:4F:78:DC:FA:D6:D4
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "UTN DATACorp SGC Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\223\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\033\060\031\006\003\125
-\004\003\023\022\125\124\116\040\055\040\104\101\124\101\103\157
-\162\160\040\123\107\103
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\223\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\033\060\031\006\003\125
-\004\003\023\022\125\124\116\040\055\040\104\101\124\101\103\157
-\162\160\040\123\107\103
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\276\014\213\120\000\041\264\021\323\052\150\006\251
-\255\151
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\136\060\202\003\106\240\003\002\001\002\002\020\104
-\276\014\213\120\000\041\264\021\323\052\150\006\251\255\151\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\223\061\013\060\011\006\003\125\004\006\023\002\125\123\061\013
-\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025\006
-\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145\040
-\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025\124
-\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145\164
-\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030\150
-\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164\162
-\165\163\164\056\143\157\155\061\033\060\031\006\003\125\004\003
-\023\022\125\124\116\040\055\040\104\101\124\101\103\157\162\160
-\040\123\107\103\060\036\027\015\071\071\060\066\062\064\061\070
-\065\067\062\061\132\027\015\061\071\060\066\062\064\061\071\060
-\066\063\060\132\060\201\223\061\013\060\011\006\003\125\004\006
-\023\002\125\123\061\013\060\011\006\003\125\004\010\023\002\125
-\124\061\027\060\025\006\003\125\004\007\023\016\123\141\154\164
-\040\114\141\153\145\040\103\151\164\171\061\036\060\034\006\003
-\125\004\012\023\025\124\150\145\040\125\123\105\122\124\122\125
-\123\124\040\116\145\164\167\157\162\153\061\041\060\037\006\003
-\125\004\013\023\030\150\164\164\160\072\057\057\167\167\167\056
-\165\163\145\162\164\162\165\163\164\056\143\157\155\061\033\060
-\031\006\003\125\004\003\023\022\125\124\116\040\055\040\104\101
-\124\101\103\157\162\160\040\123\107\103\060\202\001\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001
-\017\000\060\202\001\012\002\202\001\001\000\337\356\130\020\242
-\053\156\125\304\216\277\056\106\011\347\340\010\017\056\053\172
-\023\224\033\275\366\266\200\216\145\005\223\000\036\274\257\342
-\017\216\031\015\022\107\354\254\255\243\372\056\160\370\336\156
-\373\126\102\025\236\056\134\357\043\336\041\271\005\166\047\031
-\017\117\326\303\234\264\276\224\031\143\362\246\021\012\353\123
-\110\234\276\362\051\073\026\350\032\240\114\246\311\364\030\131
-\150\300\160\362\123\000\300\136\120\202\245\126\157\066\371\112
-\340\104\206\240\115\116\326\107\156\111\112\313\147\327\246\304
-\005\271\216\036\364\374\377\315\347\066\340\234\005\154\262\063
-\042\025\320\264\340\314\027\300\262\300\364\376\062\077\051\052
-\225\173\330\362\247\116\017\124\174\241\015\200\263\011\003\301
-\377\134\335\136\232\076\274\256\274\107\212\152\256\161\312\037
-\261\052\270\137\102\005\013\354\106\060\321\162\013\312\351\126
-\155\365\357\337\170\276\141\272\262\245\256\004\114\274\250\254
-\151\025\227\275\357\353\264\214\277\065\370\324\303\321\050\016
-\134\072\237\160\030\063\040\167\304\242\257\002\003\001\000\001
-\243\201\253\060\201\250\060\013\006\003\125\035\017\004\004\003
-\002\001\306\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\035\006\003\125\035\016\004\026\004\024\123
-\062\321\263\317\177\372\340\361\240\135\205\116\222\322\236\105
-\035\264\117\060\075\006\003\125\035\037\004\066\060\064\060\062
-\240\060\240\056\206\054\150\164\164\160\072\057\057\143\162\154
-\056\165\163\145\162\164\162\165\163\164\056\143\157\155\057\125
-\124\116\055\104\101\124\101\103\157\162\160\123\107\103\056\143
-\162\154\060\052\006\003\125\035\045\004\043\060\041\006\010\053
-\006\001\005\005\007\003\001\006\012\053\006\001\004\001\202\067
-\012\003\003\006\011\140\206\110\001\206\370\102\004\001\060\015
-\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001
-\001\000\047\065\227\000\212\213\050\275\306\063\060\036\051\374
-\342\367\325\230\324\100\273\140\312\277\253\027\054\011\066\177
-\120\372\101\334\256\226\072\012\043\076\211\131\311\243\007\355
-\033\067\255\374\174\276\121\111\132\336\072\012\124\010\026\105
-\302\231\261\207\315\214\150\340\151\003\351\304\116\230\262\073
-\214\026\263\016\240\014\230\120\233\223\251\160\011\310\054\243
-\217\337\002\344\340\161\072\361\264\043\162\240\252\001\337\337
-\230\076\024\120\240\061\046\275\050\351\132\060\046\165\371\173
-\140\034\215\363\315\120\046\155\004\047\232\337\325\015\105\107
-\051\153\054\346\166\331\251\051\175\062\335\311\066\074\275\256
-\065\361\021\236\035\273\220\077\022\107\116\216\327\176\017\142
-\163\035\122\046\070\034\030\111\375\060\164\232\304\345\042\057
-\330\300\215\355\221\172\114\000\217\162\177\135\332\335\033\213
-\105\153\347\335\151\227\250\305\126\114\017\014\366\237\172\221
-\067\366\227\202\340\335\161\151\377\166\077\140\115\074\317\367
-\231\371\306\127\364\311\125\071\170\272\054\171\311\246\210\053
-\364\010
-END
-
-# Trust for Certificate "UTN DATACorp SGC Root CA"
-# Issuer: CN=UTN - DATACorp SGC,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US
-# Serial Number:44:be:0c:8b:50:00:21:b4:11:d3:2a:68:06:a9:ad:69
-# Subject: CN=UTN - DATACorp SGC,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US
-# Not Valid Before: Thu Jun 24 18:57:21 1999
-# Not Valid After : Mon Jun 24 19:06:30 2019
-# Fingerprint (MD5): B3:A5:3E:77:21:6D:AC:4A:C0:C9:FB:D5:41:3D:CA:06
-# Fingerprint (SHA1): 58:11:9F:0E:12:82:87:EA:50:FD:D9:87:45:6F:4F:78:DC:FA:D6:D4
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "UTN DATACorp SGC Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\130\021\237\016\022\202\207\352\120\375\331\207\105\157\117\170
-\334\372\326\324
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\263\245\076\167\041\155\254\112\300\311\373\325\101\075\312\006
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\223\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\033\060\031\006\003\125
-\004\003\023\022\125\124\116\040\055\040\104\101\124\101\103\157
-\162\160\040\123\107\103
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\276\014\213\120\000\041\264\021\323\052\150\006\251
-\255\151
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
 # Certificate "UTN USERFirst Email Root CA"
 #
 # Issuer: CN=UTN-USERFirst-Client Authentication and Email,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US
 # Serial Number:44:be:0c:8b:50:00:24:b4:11:d3:36:25:25:67:c9:89
 # Subject: CN=UTN-USERFirst-Client Authentication and Email,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US
 # Not Valid Before: Fri Jul 09 17:28:50 1999
 # Not Valid After : Tue Jul 09 17:36:58 2019
 # Fingerprint (MD5):