Merge mozilla-central to fx-team
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 04 Jun 2014 15:54:11 +0200
changeset 205791 f54eeeffe2a2317e81bbf39e5a844e6a29255d49
parent 205790 035c1df29690b37ecd5baaf8bf24138bbf0fb491 (current diff)
parent 205737 c7fdd7e755cdea42b483ea570cf4c77b7c40b2a9 (diff)
child 205792 2fbb4b93bce197cc81dc3d02c8289392cc47ba76
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to fx-team
dom/datastore/tests/test_basic.html
dom/interfaces/events/nsIDOMProgressEvent.idl
netwerk/base/public/nsINetworkSeer.idl
netwerk/base/public/nsINetworkSeerVerifier.idl
netwerk/base/src/Seer.cpp
netwerk/base/src/Seer.h
netwerk/test/unit/test_seer.js
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -83,19 +83,19 @@ pref("network.cookie.cookieBehavior", 0)
 // spdy
 pref("network.http.spdy.push-allowance", 32768);
 
 // See bug 545869 for details on why these are set the way they are
 pref("network.buffer.cache.count", 24);
 pref("network.buffer.cache.size",  16384);
 
 // predictive actions
-pref("network.seer.enable", false); // disabled on b2g
-pref("network.seer.max-db-size", 2097152); // bytes
-pref("network.seer.preserve", 50); // percentage of seer data to keep when cleaning up
+pref("network.predictor.enable", false); // disabled on b2g
+pref("network.predictor.max-db-size", 2097152); // bytes
+pref("network.predictor.preserve", 50); // percentage of predictor data to keep when cleaning up
 
 /* session history */
 pref("browser.sessionhistory.max_total_viewers", 1);
 pref("browser.sessionhistory.max_entries", 50);
 
 /* session store */
 pref("browser.sessionstore.resume_session_once", false);
 pref("browser.sessionstore.resume_from_crash", true);
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -365,20 +365,16 @@ var shell = {
     window.removeEventListener('keydown', this, true);
     window.removeEventListener('keypress', this, true);
     window.removeEventListener('keyup', this, true);
     window.removeEventListener('MozApplicationManifest', this);
     window.removeEventListener('mozfullscreenchange', this);
     window.removeEventListener('sizemodechange', this);
     this.contentBrowser.removeEventListener('mozbrowserloadstart', this, true);
     ppmm.removeMessageListener("content-handler", this);
-    if (this.timer) {
-      this.timer.cancel();
-      this.timer = null;
-    }
 
     UserAgentOverrides.uninit();
     IndexedDBPromptHelper.uninit();
   },
 
   // If this key event actually represents a hardware button, filter it here
   // and send a mozChromeEvent with detail.type set to xxx-button-press or
   // xxx-button-release instead.
@@ -470,19 +466,16 @@ var shell = {
     // FIXME: https://bugzilla.mozilla.org/show_bug.cgi?id=761067
     if (type !== this.lastHardwareButtonEventType) {
       this.lastHardwareButtonEventType = type;
       this.sendChromeEvent({type: type});
     }
   },
 
   lastHardwareButtonEventType: null, // property for the hack above
-  needBufferOpenAppReq: true,
-  bufferedOpenAppReqs: [],
-  timer: null,
   visibleNormalAudioActive: false,
 
   handleEvent: function shell_handleEvent(evt) {
     let content = this.contentBrowser.contentWindow;
     switch (evt.type) {
       case 'keydown':
       case 'keyup':
       case 'keypress':
@@ -590,30 +583,16 @@ var shell = {
       this.pendingChromeEvents.push(details);
       return;
     }
 
     this.sendEvent(getContentWindow(), "mozChromeEvent",
                    Cu.cloneInto(details, getContentWindow()));
   },
 
-  openAppForSystemMessage: function shell_openAppForSystemMessage(msg) {
-    let payload = {
-      url: msg.pageURL,
-      manifestURL: msg.manifestURL,
-      isActivity: (msg.type == 'activity'),
-      onlyShowApp: msg.onlyShowApp,
-      showApp: msg.showApp,
-      target: msg.target,
-      expectingSystemMessage: true,
-      extra: msg.extra
-    }
-    this.sendCustomEvent('open-app', payload);
-  },
-
   receiveMessage: function shell_receiveMessage(message) {
     var activities = { 'content-handler': { name: 'view', response: null },
                        'dial-handler':    { name: 'dial', response: null },
                        'mail-handler':    { name: 'new',  response: null },
                        'sms-handler':     { name: 'new',  response: null },
                        'file-picker':     { name: 'pick', response: 'file-picked' } };
 
     if (!(message.name in activities))
@@ -672,28 +651,16 @@ var shell = {
       if ('pendingChromeEvents' in shell) {
         shell.pendingChromeEvents.forEach((shell.sendChromeEvent).bind(shell));
       }
       delete shell.pendingChromeEvents;
     });
   }
 };
 
-// Listen for the request of opening app and relay them to Gaia.
-Services.obs.addObserver(function onSystemMessageOpenApp(subject, topic, data) {
-  let msg = JSON.parse(data);
-  // Buffer non-activity request until content starts to load for 10 seconds.
-  // We'll revisit this later if new kind of requests don't need to be cached.
-  if (shell.needBufferOpenAppReq && msg.type !== 'activity') {
-    shell.bufferedOpenAppReqs.push(msg);
-    return;
-  }
-  shell.openAppForSystemMessage(msg);
-}, 'system-messages-open-app', false);
-
 Services.obs.addObserver(function onFullscreenOriginChange(subject, topic, data) {
   shell.sendChromeEvent({ type: "fullscreenoriginchange",
                           fullscreenorigin: data });
 }, "fullscreen-origin-change", false);
 
 DOMApplicationRegistry.registryStarted.then(function () {
   shell.sendChromeEvent({ type: 'webapps-registry-start' });
 });
@@ -712,31 +679,16 @@ Services.obs.addObserver(function(subjec
   shell.sendCustomEvent('mozmemorypressure');
 }, 'memory-pressure', false);
 
 var CustomEventManager = {
   init: function custevt_init() {
     window.addEventListener("ContentStart", (function(evt) {
       let content = shell.contentBrowser.contentWindow;
       content.addEventListener("mozContentEvent", this, false, true);
-
-      // After content starts to load for 10 seconds, send and
-      // clean up the buffered open-app requests if there is any.
-      //
-      // TODO: Bug 793420 - Remove the waiting timer for the 'open-app'
-      //                    mozChromeEvents requested by System Message
-      shell.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-      shell.timer.initWithCallback(function timerCallback() {
-        shell.bufferedOpenAppReqs.forEach(function bufferOpenAppReq(msg) {
-          shell.openAppForSystemMessage(msg);
-        });
-        shell.bufferedOpenAppReqs.length = 0;
-        shell.needBufferOpenAppReq = false;
-        shell.timer = null;
-      }, 10000, Ci.nsITimer.TYPE_ONE_SHOT);
     }).bind(this), false);
   },
 
   handleEvent: function custevt_handleEvent(evt) {
     let detail = evt.detail;
     dump('XXX FIXME : Got a mozContentEvent: ' + detail.type + "\n");
 
     switch(detail.type) {
--- a/b2g/components/B2GComponents.manifest
+++ b/b2g/components/B2GComponents.manifest
@@ -23,16 +23,20 @@ category xpcom-directory-providers b2g-d
 # ActivitiesGlue.js
 component {3a54788b-48cc-4ab4-93d6-0d6a8ef74f8e} ActivitiesGlue.js
 contract @mozilla.org/dom/activities/ui-glue;1 {3a54788b-48cc-4ab4-93d6-0d6a8ef74f8e}
 
 # InterAppCommUIGlue.js
 component {879ee66c-e246-11e3-9910-74d02b97e723} InterAppCommUIGlue.js
 contract @mozilla.org/dom/apps/inter-app-comm-ui-glue;1 {879ee66c-e246-11e3-9910-74d02b97e723}
 
+# SystemMessageGlue.js
+component {2846f034-e614-11e3-93cd-74d02b97e723} SystemMessageGlue.js
+contract @mozilla.org/dom/messages/system-message-glue;1 {2846f034-e614-11e3-93cd-74d02b97e723}
+
 # ProcessGlobal.js
 component {1a94c87a-5ece-4d11-91e1-d29c29f21b28} ProcessGlobal.js
 contract @mozilla.org/b2g-process-global;1 {1a94c87a-5ece-4d11-91e1-d29c29f21b28}
 category app-startup ProcessGlobal service,@mozilla.org/b2g-process-global;1
 
 # PaymentGlue.js
 component {8b83eabc-7929-47f4-8b48-4dea8d887e4b} PaymentGlue.js
 contract @mozilla.org/payment/ui-glue;1 {8b83eabc-7929-47f4-8b48-4dea8d887e4b}
--- a/b2g/components/SystemAppProxy.jsm
+++ b/b2g/components/SystemAppProxy.jsm
@@ -47,23 +47,28 @@ let SystemAppProxy = {
    * Common way to send an event to the system app.
    *
    * // In gecko code:
    *   SystemAppProxy.sendCustomEvent('foo', { data: 'bar' });
    * // In system app:
    *   window.addEventListener('foo', function (event) {
    *     event.details == 'bar'
    *   });
+   *
+   *   @param type      The custom event type.
+   *   @param details   The event details.
+   *   @param noPending Set to true to emit this event even before the system
+   *                    app is ready.
    */
-  _sendCustomEvent: function systemApp_sendCustomEvent(type, details) {
+  _sendCustomEvent: function systemApp_sendCustomEvent(type, details, noPending) {
     let content = this._frame ? this._frame.contentWindow : null;
 
     // If the system app isn't ready yet,
-    // queue events until someone calls setIsLoaded
-    if (!this._isReady || !content) {
+    // queue events until someone calls setIsReady
+    if (!content || (!this._isReady && !noPending)) {
       this._pendingEvents.push([type, details]);
       return null;
     }
 
     let event = content.document.createEvent('CustomEvent');
 
     let payload;
     // If the root object already has __exposedProps__,
new file mode 100644
--- /dev/null
+++ b/b2g/components/SystemMessageGlue.js
@@ -0,0 +1,42 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict"
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
+                                  "resource://gre/modules/SystemAppProxy.jsm");
+
+function SystemMessageGlue() {
+}
+
+SystemMessageGlue.prototype = {
+  openApp: function(aPageURL, aManifestURL, aType, aTarget, aShowApp,
+                    aOnlyShowApp, aExtra) {
+    let payload = { url: aPageURL,
+                    manifestURL: aManifestURL,
+                    isActivity: (aType == "activity"),
+                    target: aTarget,
+                    showApp: aShowApp,
+                    onlyShowApp: aOnlyShowApp,
+                    expectingSystemMessage: true,
+                    extra: aExtra };
+
+    // |SystemAppProxy| will queue "open-app" events for non-activity system
+    // messages without actually sending them until the system app is ready.
+    SystemAppProxy._sendCustomEvent("open-app", payload, (aType == "activity"));
+  },
+
+  classID: Components.ID("{2846f034-e614-11e3-93cd-74d02b97e723}"),
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISystemMessageGlue])
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SystemMessageGlue]);
--- a/b2g/components/moz.build
+++ b/b2g/components/moz.build
@@ -13,16 +13,17 @@ EXTRA_COMPONENTS += [
     'ContentPermissionPrompt.js',
     'FilePicker.js',
     'HelperAppDialog.js',
     'InterAppCommUIGlue.js',
     'MailtoProtocolHandler.js',
     'PaymentGlue.js',
     'ProcessGlobal.js',
     'SmsProtocolHandler.js',
+    'SystemMessageGlue.js',
     'TelProtocolHandler.js',
     'WebappsUpdateTimer.js',
     'YoutubeProtocolHandler.js',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
     EXTRA_COMPONENTS += [
       'OopCommandLine.js',
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8e4420c0c5c8e8c8e58a000278a7129403769f96"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9100fa82fc355f5201e23e400fc6b40e875304ed"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="6e2a3b589d1e8cc1d9df25f5e630ce30a0aa39f3">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="276ce45e78b09c4a4ee643646f691d22804754c1">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8e4420c0c5c8e8c8e58a000278a7129403769f96"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9100fa82fc355f5201e23e400fc6b40e875304ed"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="6e2a3b589d1e8cc1d9df25f5e630ce30a0aa39f3">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
         "git_revision": "", 
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "33a8ca00e3128502d0c4c834236be335c0060f43", 
+    "revision": "cd1a16d6212a1867ecf1d1cfcd62f80abf9ae0b1", 
     "repo_path": "/integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="6e2a3b589d1e8cc1d9df25f5e630ce30a0aa39f3">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d4f6f7312882e78b57971152de75d1281a26187"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="a38a6a5c6fabc97dd16d5360632b5ac5c7e06241"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="994fa9a1f7ce0e63c880a48d571c3ab3e01884a3"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -797,16 +797,17 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DL
 @BINPATH@/components/MailtoProtocolHandler.js
 @BINPATH@/components/SmsProtocolHandler.js
 @BINPATH@/components/TelProtocolHandler.js
 @BINPATH@/components/B2GAboutRedirector.js
 @BINPATH@/components/FilePicker.js
 @BINPATH@/components/HelperAppDialog.js
 @BINPATH@/components/DownloadsUI.js
 @BINPATH@/components/InterAppCommUIGlue.js
+@BINPATH@/components/SystemMessageGlue.js
 
 #ifndef MOZ_WIDGET_GONK
 @BINPATH@/components/SimulatorScreen.js
 #endif
 
 #ifdef MOZ_SERVICES_FXACCOUNTS
 @BINPATH@/components/FxAccountsUIGlue.js
 @BINPATH@/components/services_fxaccounts.xpt
--- a/browser/base/content/sanitize.js
+++ b/browser/base/content/sanitize.js
@@ -216,19 +216,19 @@ Sanitizer.prototype = {
         try {
           var os = Components.classes["@mozilla.org/observer-service;1"]
                              .getService(Components.interfaces.nsIObserverService);
           os.notifyObservers(null, "browser:purge-session-history", "");
         }
         catch (e) { }
 
         try {
-          var seer = Components.classes["@mozilla.org/network/seer;1"]
-                               .getService(Components.interfaces.nsINetworkSeer);
-          seer.reset();
+          var predictor = Components.classes["@mozilla.org/network/predictor;1"]
+                                    .getService(Components.interfaces.nsINetworkPredictor);
+          predictor.reset();
         } catch (e) { }
       },
 
       get canClear()
       {
         // bug 347231: Always allow clearing history due to dependencies on
         // the browser:purge-session-history notification. (like error console)
         return true;
--- a/content/base/src/FileIOObject.cpp
+++ b/content/base/src/FileIOObject.cpp
@@ -3,17 +3,17 @@
  * 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 "FileIOObject.h"
 #include "mozilla/EventDispatcher.h"
 #include "nsDOMFile.h"
 #include "nsError.h"
 #include "nsIDOMEvent.h"
-#include "nsIDOMProgressEvent.h"
+#include "mozilla/dom/ProgressEvent.h"
 #include "nsComponentManagerUtils.h"
 
 #define ERROR_STR "error"
 #define ABORT_STR "abort"
 #define PROGRESS_STR "progress"
 
 namespace mozilla {
 namespace dom {
@@ -100,37 +100,31 @@ FileIOObject::DispatchError(nsresult rv,
   // Dispatch error event to signify load failure
   DispatchProgressEvent(NS_LITERAL_STRING(ERROR_STR));
   DispatchProgressEvent(finalEvent);
 }
 
 nsresult
 FileIOObject::DispatchProgressEvent(const nsAString& aType)
 {
-  nsCOMPtr<nsIDOMEvent> event;
-  nsresult rv = NS_NewDOMProgressEvent(getter_AddRefs(event), this,
-                                       nullptr, nullptr);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  event->SetTrusted(true);
-  nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event);
-  NS_ENSURE_TRUE(progress, NS_ERROR_UNEXPECTED);
+  ProgressEventInit init;
+  init.mBubbles = false;
+  init.mCancelable = false;
+  init.mLoaded = mTransferred;
 
-  bool known;
-  uint64_t size;
   if (mTotal != kUnknownSize) {
-    known = true;
-    size = mTotal;
+    init.mLengthComputable = true;
+    init.mTotal = mTotal;
   } else {
-    known = false;
-    size = 0;
+    init.mLengthComputable = false;
+    init.mTotal = 0;
   }
-  rv = progress->InitProgressEvent(aType, false, false, known,
-                                   mTransferred, size);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsRefPtr<ProgressEvent> event =
+    ProgressEvent::Constructor(this, aType, init);
+  event->SetTrusted(true);
 
   return DispatchDOMEvent(nullptr, event, nullptr, nullptr);
 }
 
 // nsITimerCallback
 NS_IMETHODIMP
 FileIOObject::Notify(nsITimer* aTimer)
 {
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -4634,16 +4634,26 @@ nsContentUtils::GetAccelKeyCandidates(ns
           continue;
 
         // Setting the alternative charCode candidates for retry without shift
         // key state only when the shift key is pressed.
         nsShortcutCandidate key(ch, true);
         aCandidates.AppendElement(key);
       }
     }
+
+    // Special case for "Space" key.  With some keyboard layouts, "Space" with
+    // or without Shift key causes non-ASCII space.  For such keyboard layouts,
+    // we should guarantee that the key press works as an ASCII white space key
+    // press.
+    if (nativeKeyEvent->mCodeNameIndex == CODE_NAME_INDEX_Space &&
+        nativeKeyEvent->charCode != static_cast<uint32_t>(' ')) {
+      nsShortcutCandidate spaceKey(static_cast<uint32_t>(' '), false);
+      aCandidates.AppendElement(spaceKey);
+    }
   } else {
     uint32_t charCode;
     aDOMKeyEvent->GetCharCode(&charCode);
     if (charCode) {
       nsShortcutCandidate key(charCode, false);
       aCandidates.AppendElement(key);
     }
   }
@@ -4676,16 +4686,24 @@ nsContentUtils::GetAccessKeyCandidates(W
         continue;
       if (IS_IN_BMP(ch[j]))
         ch[j] = ToLowerCase(char16_t(ch[j]));
       // Don't append the charCode that was already appended.
       if (aCandidates.IndexOf(ch[j]) == aCandidates.NoIndex)
         aCandidates.AppendElement(ch[j]);
     }
   }
+  // Special case for "Space" key.  With some keyboard layouts, "Space" with
+  // or without Shift key causes non-ASCII space.  For such keyboard layouts,
+  // we should guarantee that the key press works as an ASCII white space key
+  // press.
+  if (aNativeKeyEvent->mCodeNameIndex == CODE_NAME_INDEX_Space &&
+      aNativeKeyEvent->charCode != static_cast<uint32_t>(' ')) {
+    aCandidates.AppendElement(static_cast<uint32_t>(' '));
+  }
   return;
 }
 
 /* static */
 void
 nsContentUtils::AddScriptBlocker()
 {
   if (!sScriptBlockerCount) {
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -44,17 +44,17 @@
 #include "prlog.h"
 #include "nsIChannelPolicy.h"
 #include "nsChannelPolicy.h"
 #include "nsCRT.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsCrossSiteListenerProxy.h"
 #include "nsSandboxFlags.h"
 #include "nsContentTypeParser.h"
-#include "nsINetworkSeer.h"
+#include "nsINetworkPredictor.h"
 #include "mozilla/dom/EncodingUtils.h"
 
 #include "mozilla/CORSMode.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/unused.h"
 
 #ifdef PR_LOGGING
@@ -340,18 +340,18 @@ nsScriptLoader::StartLoad(nsScriptLoadRe
     // HTTP content negotation has little value in this context.
     httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
                                   NS_LITERAL_CSTRING("*/*"),
                                   false);
     httpChannel->SetReferrer(mDocument->GetDocumentURI());
   }
 
   nsCOMPtr<nsILoadContext> loadContext(do_QueryInterface(docshell));
-  mozilla::net::SeerLearn(aRequest->mURI, mDocument->GetDocumentURI(),
-      nsINetworkSeer::LEARN_LOAD_SUBRESOURCE, loadContext);
+  mozilla::net::PredictorLearn(aRequest->mURI, mDocument->GetDocumentURI(),
+      nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE, loadContext);
 
   // Set the initiator type
   nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(httpChannel));
   if (timedChannel) {
     timedChannel->SetInitiatorType(NS_LITERAL_STRING("script"));
   }
 
   nsCOMPtr<nsIStreamLoader> loader;
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -11,17 +11,17 @@
 #endif
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/dom/XMLHttpRequestUploadBinding.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventListenerManager.h"
 #include "mozilla/MemoryReporting.h"
 #include "nsDOMBlobBuilder.h"
 #include "nsIDOMDocument.h"
-#include "nsIDOMProgressEvent.h"
+#include "mozilla/dom/ProgressEvent.h"
 #include "nsIJARChannel.h"
 #include "nsIJARURI.h"
 #include "nsLayoutCID.h"
 #include "nsReadableUtils.h"
 
 #include "nsIURI.h"
 #include "nsILoadGroup.h"
 #include "nsNetUtil.h"
@@ -1460,31 +1460,25 @@ nsXMLHttpRequest::DispatchProgressEvent(
     return;
   }
 
   bool dispatchLoadend = aType.EqualsLiteral(LOAD_STR) ||
                          aType.EqualsLiteral(ERROR_STR) ||
                          aType.EqualsLiteral(TIMEOUT_STR) ||
                          aType.EqualsLiteral(ABORT_STR);
 
-  nsCOMPtr<nsIDOMEvent> event;
-  nsresult rv = NS_NewDOMProgressEvent(getter_AddRefs(event), this,
-                                       nullptr, nullptr);
-  if (NS_FAILED(rv)) {
-    return;
-  }
-
-  nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event);
-  if (!progress) {
-    return;
-  }
-
-  progress->InitProgressEvent(aType, false, false, aLengthComputable,
-                              aLoaded, (aTotal == UINT64_MAX) ? 0 : aTotal);
-
+  ProgressEventInit init;
+  init.mBubbles = false;
+  init.mCancelable = false;
+  init.mLengthComputable = aLengthComputable;
+  init.mLoaded = aLoaded;
+  init.mTotal = (aTotal == UINT64_MAX) ? 0 : aTotal;
+
+  nsRefPtr<ProgressEvent> event =
+    ProgressEvent::Constructor(aTarget, aType, init);
   event->SetTrusted(true);
 
   aTarget->DispatchDOMEvent(nullptr, event, nullptr, nullptr);
 
   if (dispatchLoadend) {
     DispatchProgressEvent(aTarget, NS_LITERAL_STRING(LOADEND_STR),
                           aLengthComputable, aLoaded, aTotal);
   }
--- a/content/html/content/src/HTMLInputElement.cpp
+++ b/content/html/content/src/HTMLInputElement.cpp
@@ -22,17 +22,17 @@
 #include "nsFocusManager.h"
 #include "nsColorControlFrame.h"
 #include "nsNumberControlFrame.h"
 #include "nsPIDOMWindow.h"
 #include "nsRepeatService.h"
 #include "nsContentCID.h"
 #include "nsIComponentManager.h"
 #include "nsIDOMHTMLFormElement.h"
-#include "nsIDOMProgressEvent.h"
+#include "mozilla/dom/ProgressEvent.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsMappedAttributes.h"
 #include "nsIFormControl.h"
 #include "nsIForm.h"
 #include "nsFormSubmission.h"
 #include "nsFormSubmissionConstants.h"
@@ -2720,35 +2720,29 @@ HTMLInputElement::MaybeDispatchProgressE
 
 void
 HTMLInputElement::DispatchProgressEvent(const nsAString& aType,
                                         bool aLengthComputable,
                                         uint64_t aLoaded, uint64_t aTotal)
 {
   NS_ASSERTION(!aType.IsEmpty(), "missing event type");
 
-  nsCOMPtr<nsIDOMEvent> event;
-  nsresult rv = NS_NewDOMProgressEvent(getter_AddRefs(event), this,
-                                       nullptr, nullptr);
-  if (NS_FAILED(rv)) {
-    return;
-  }
-
-  nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event);
-  if (!progress) {
-    return;
-  }
-
-  progress->InitProgressEvent(aType, false, true, aLengthComputable,
-                              aLoaded, (aTotal == UINT64_MAX) ? 0 : aTotal);
-
+  ProgressEventInit init;
+  init.mBubbles = false;
+  init.mCancelable = true; // XXXkhuey why?
+  init.mLengthComputable = aLengthComputable;
+  init.mLoaded = aLoaded;
+  init.mTotal = (aTotal == UINT64_MAX) ? 0 : aTotal;
+
+  nsRefPtr<ProgressEvent> event =
+    ProgressEvent::Constructor(this, aType, init);
   event->SetTrusted(true);
 
   bool doDefaultAction;
-  rv = DispatchEvent(event, &doDefaultAction);
+  nsresult rv = DispatchEvent(event, &doDefaultAction);
   if (NS_SUCCEEDED(rv) && !doDefaultAction) {
     CancelDirectoryPickerScanIfRunning();
   }
 }
 
 nsresult
 HTMLInputElement::UpdateFileList()
 {
--- a/content/html/content/src/HTMLVideoElement.cpp
+++ b/content/html/content/src/HTMLVideoElement.cpp
@@ -20,17 +20,16 @@
 #include "nsThreadUtils.h"
 #include "ImageContainer.h"
 
 #include "nsIScriptSecurityManager.h"
 #include "nsIXPConnect.h"
 
 #include "nsITimer.h"
 
-#include "nsIDOMProgressEvent.h"
 #include "MediaError.h"
 #include "MediaDecoder.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/WakeLock.h"
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "nsPerformance.h"
 #include "mozilla/dom/VideoPlaybackQuality.h"
 
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -115,17 +115,17 @@
 #include "nsITabChild.h"
 #include "nsISiteSecurityService.h"
 #include "nsStructuredCloneContainer.h"
 #include "nsIStructuredCloneContainer.h"
 #ifdef MOZ_PLACES
 #include "nsIFaviconService.h"
 #include "mozIAsyncFavicons.h"
 #endif
-#include "nsINetworkSeer.h"
+#include "nsINetworkPredictor.h"
 
 // Editor-related
 #include "nsIEditingSession.h"
 
 #include "nsPIDOMWindow.h"
 #include "nsGlobalWindow.h"
 #include "nsPIWindowRoot.h"
 #include "nsICachingChannel.h"
@@ -7206,17 +7206,17 @@ nsDocShell::EndPageLoad(nsIWebProgress *
             // Caching channels would have to look at their flags to work
             // out which error to return. Or we can fix up the error here.
             if (!(mLoadType & LOAD_CMD_HISTORY))
                 aStatus = NS_ERROR_OFFLINE;
             DisplayLoadError(aStatus, url, nullptr, aChannel);
         }
     } // if we have a host
     else if (url && NS_SUCCEEDED(aStatus)) {
-        mozilla::net::SeerLearnRedirect(url, aChannel, this);
+        mozilla::net::PredictorLearnRedirect(url, aChannel, this);
     }
 
     return NS_OK;
 }
 
 
 //*****************************************************************************
 // nsDocShell: Content Viewer Management
@@ -9598,18 +9598,19 @@ nsDocShell::InternalLoad(nsIURI * aURI,
     }
 
     nsAutoString srcdoc;
     if (aFlags & INTERNAL_LOAD_FLAGS_IS_SRCDOC)
       srcdoc = aSrcdoc;
     else
       srcdoc = NullString();
 
-    mozilla::net::SeerPredict(aURI, nullptr, nsINetworkSeer::PREDICT_LOAD,
-                              this, nullptr);
+    mozilla::net::PredictorPredict(aURI, nullptr,
+                                   nsINetworkPredictor::PREDICT_LOAD,
+                                   this, nullptr);
 
     nsCOMPtr<nsIRequest> req;
     rv = DoURILoad(aURI, aReferrer,
                    !(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER),
                    owner, aTypeHint, aFileName, aPostData, aHeadersData,
                    aFirstParty, aDocShell, getter_AddRefs(req),
                    (aFlags & INTERNAL_LOAD_FLAGS_FIRST_LOAD) != 0,
                    (aFlags & INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER) != 0,
@@ -12728,18 +12729,19 @@ nsDocShell::OnOverLink(nsIContent* aCont
   nsAutoCString spec;
   rv = aURI->GetSpec(spec);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString uStr;
   rv = textToSubURI->UnEscapeURIForUI(charset, spec, uStr);    
   NS_ENSURE_SUCCESS(rv, rv);
 
-  mozilla::net::SeerPredict(aURI, mCurrentURI, nsINetworkSeer::PREDICT_LINK,
-                            this, nullptr);
+  mozilla::net::PredictorPredict(aURI, mCurrentURI,
+                                 nsINetworkPredictor::PREDICT_LINK,
+                                 this, nullptr);
 
   if (browserChrome2) {
     nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aContent);
     rv = browserChrome2->SetStatusWithContext(nsIWebBrowserChrome::STATUS_LINK,
                                               uStr, element);
   } else {
     rv = browserChrome->SetStatus(nsIWebBrowserChrome::STATUS_LINK, uStr.get());
   }
--- a/dom/events/Event.h
+++ b/dom/events/Event.h
@@ -24,16 +24,17 @@ class nsIContent;
 class nsIDOMEventTarget;
 class nsPresContext;
 
 namespace mozilla {
 namespace dom {
 
 class EventTarget;
 class ErrorEvent;
+class ProgressEvent;
 
 // Dummy class so we can cast through it to get from nsISupports to
 // Event subclasses with only two non-ambiguous static casts.
 class EventBase : public nsIDOMEvent
 {
 };
 
 class Event : public EventBase,
@@ -92,16 +93,21 @@ public:
     return EventBinding::Wrap(aCx, this);
   }
 
   virtual ErrorEvent* AsErrorEvent()
   {
     return nullptr;
   }
 
+  virtual ProgressEvent* AsProgressEvent()
+  {
+    return nullptr;
+  }
+
   // nsIDOMEvent Interface
   NS_DECL_NSIDOMEVENT
 
   void InitPresContextData(nsPresContext* aPresContext);
 
   // Returns true if the event should be trusted.
   bool Init(EventTarget* aGlobal);
 
--- a/dom/filehandle/FileRequest.cpp
+++ b/dom/filehandle/FileRequest.cpp
@@ -13,17 +13,17 @@
 #include "MainThreadUtils.h"
 #include "mozilla/dom/FileRequestBinding.h"
 #include "mozilla/EventDispatcher.h"
 #include "nsCOMPtr.h"
 #include "nsCxPusher.h"
 #include "nsDebug.h"
 #include "nsError.h"
 #include "nsIDOMEvent.h"
-#include "nsIDOMProgressEvent.h"
+#include "mozilla/dom/ProgressEvent.h"
 #include "nsIScriptContext.h"
 #include "nsLiteralString.h"
 
 namespace mozilla {
 namespace dom {
 
 FileRequest::FileRequest(nsPIDOMWindow* aWindow)
   : DOMRequest(aWindow), mWrapAsDOMRequest(false)
@@ -130,28 +130,22 @@ FileRequest::GetLockedFile() const
 
 void
 FileRequest::FireProgressEvent(uint64_t aLoaded, uint64_t aTotal)
 {
   if (NS_FAILED(CheckInnerWindowCorrectness())) {
     return;
   }
 
-  nsCOMPtr<nsIDOMEvent> event;
-  nsresult rv = NS_NewDOMProgressEvent(getter_AddRefs(event), this,
-                                       nullptr, nullptr);
-  if (NS_FAILED(rv)) {
-    return;
-  }
+  ProgressEventInit init;
+  init.mBubbles = false;
+  init.mCancelable = false;
+  init.mLengthComputable = false;
+  init.mLoaded = aLoaded;
+  init.mTotal = aTotal;
 
-  nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event);
-  MOZ_ASSERT(progress);
-  rv = progress->InitProgressEvent(NS_LITERAL_STRING("progress"), false, false,
-                                   false, aLoaded, aTotal);
-  if (NS_FAILED(rv)) {
-    return;
-  }
-
+  nsRefPtr<ProgressEvent> event =
+    ProgressEvent::Constructor(this, NS_LITERAL_STRING("progress"), init);
   DispatchTrustedEvent(event);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/interfaces/events/moz.build
+++ b/dom/interfaces/events/moz.build
@@ -29,17 +29,16 @@ XPIDL_SOURCES += [
     'nsIDOMMouseScrollEvent.idl',
     'nsIDOMMutationEvent.idl',
     'nsIDOMNotifyPaintEvent.idl',
     'nsIDOMNSEvent.idl',
     'nsIDOMPageTransitionEvent.idl',
     'nsIDOMPaintRequest.idl',
     'nsIDOMPopStateEvent.idl',
     'nsIDOMPopupBlockedEvent.idl',
-    'nsIDOMProgressEvent.idl',
     'nsIDOMRecordErrorEvent.idl',
     'nsIDOMScrollAreaEvent.idl',
     'nsIDOMSimpleGestureEvent.idl',
     'nsIDOMSmartCardEvent.idl',
     'nsIDOMStyleRuleChangeEvent.idl',
     'nsIDOMStyleSheetApplicableStateChangeEvent.idl',
     'nsIDOMStyleSheetChangeEvent.idl',
     'nsIDOMTouchEvent.idl',
--- a/dom/interfaces/events/nsIDOMEvent.idl
+++ b/dom/interfaces/events/nsIDOMEvent.idl
@@ -322,21 +322,16 @@ NS_NewDOMCommandEvent(nsIDOMEvent** aIns
                       mozilla::dom::EventTarget* aOwner,
                       nsPresContext* aPresContext,
                       mozilla::WidgetCommandEvent* aEvent);
 nsresult
 NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult,
                       mozilla::dom::EventTarget* aOwner,
                       nsPresContext* aPresContext,
                       mozilla::WidgetEvent* aEvent);
-nsresult
-NS_NewDOMProgressEvent(nsIDOMEvent** aInstancePtrResult,
-                       mozilla::dom::EventTarget* aOwner,
-                       nsPresContext* aPresContext,
-                       mozilla::WidgetEvent* aEvent);
 // This empties aInvalidateRequests.
 nsresult
 NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aResult,
                           mozilla::dom::EventTarget* aOwner,
                           nsPresContext* aPresContext,
                           mozilla::WidgetEvent* aEvent,
                           uint32_t aEventType = 0,
                           nsInvalidateRequestList* aInvalidateRequests = nullptr);
deleted file mode 100644
--- a/dom/interfaces/events/nsIDOMProgressEvent.idl
+++ /dev/null
@@ -1,26 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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 "nsIDOMEvent.idl"
-
-/**
- * ProgressEvent can be used for measuring progress.
- */
-
-[builtinclass, uuid(e0682338-4c3f-4d3a-9487-d7492ea76335)]
-interface nsIDOMProgressEvent : nsIDOMEvent
-{
-  readonly attribute boolean lengthComputable;
-  readonly attribute unsigned long long loaded;
-  readonly attribute unsigned long long total;
-  [noscript]
-  void initProgressEvent(in DOMString typeArg,
-                         in boolean canBubbleArg,
-                         in boolean cancelableArg,
-                         in boolean lengthComputableArg,
-                         in unsigned long long loadedArg,
-                         in unsigned long long totalArg);
-};
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -543,26 +543,25 @@ ContentChild::Init(MessageLoop* aIOLoop,
 
 #ifdef MOZ_CRASHREPORTER
     SendPCrashReporterConstructor(CrashReporter::CurrentThreadId(),
                                   XRE_GetProcessType());
 #endif
 
     GetCPOWManager();
 
+    SendGetProcessAttributes(&mID, &mIsForApp, &mIsForBrowser);
     InitProcessAttributes();
 
     return true;
 }
 
 void
 ContentChild::InitProcessAttributes()
 {
-    SendGetProcessAttributes(&mID, &mIsForApp, &mIsForBrowser);
-
 #ifdef MOZ_NUWA_PROCESS
     if (IsNuwaProcess()) {
         SetProcessName(NS_LITERAL_STRING("(Nuwa)"), false);
         return;
     }
 #endif
     if (mIsForApp && !mIsForBrowser) {
         SetProcessName(NS_LITERAL_STRING("(Preallocated app)"), false);
@@ -920,17 +919,20 @@ bool
 ContentChild::DeallocPJavaScriptChild(PJavaScriptChild *child)
 {
     static_cast<mozilla::jsipc::JavaScriptChild *>(child)->decref();
     return true;
 }
 
 PBrowserChild*
 ContentChild::AllocPBrowserChild(const IPCTabContext& aContext,
-                                 const uint32_t& aChromeFlags)
+                                 const uint32_t& aChromeFlags,
+                                 const uint64_t& aId,
+                                 const bool& aIsForApp,
+                                 const bool& aIsForBrowser)
 {
     // We'll happily accept any kind of IPCTabContext here; we don't need to
     // check that it's of a certain type for security purposes, because we
     // believe whatever the parent process tells us.
 
     MaybeInvalidTabContext tc(aContext);
     if (!tc.IsValid()) {
         NS_ERROR(nsPrintfCString("Received an invalid TabContext from "
@@ -941,40 +943,46 @@ ContentChild::AllocPBrowserChild(const I
 
     nsRefPtr<TabChild> child = TabChild::Create(this, tc.GetTabContext(), aChromeFlags);
 
     // The ref here is released in DeallocPBrowserChild.
     return child.forget().take();
 }
 
 bool
-ContentChild::RecvPBrowserConstructor(PBrowserChild* actor,
-                                      const IPCTabContext& context,
-                                      const uint32_t& chromeFlags)
+ContentChild::RecvPBrowserConstructor(PBrowserChild* aActor,
+                                      const IPCTabContext& aContext,
+                                      const uint32_t& aChromeFlags,
+                                      const uint64_t& aID,
+                                      const bool& aIsForApp,
+                                      const bool& aIsForBrowser)
 {
     // This runs after AllocPBrowserChild() returns and the IPC machinery for this
     // PBrowserChild has been set up.
 
     nsCOMPtr<nsIObserverService> os = services::GetObserverService();
     if (os) {
         nsITabChild* tc =
-            static_cast<nsITabChild*>(static_cast<TabChild*>(actor));
+            static_cast<nsITabChild*>(static_cast<TabChild*>(aActor));
         os->NotifyObservers(tc, "tab-child-created", nullptr);
     }
 
     static bool hasRunOnce = false;
     if (!hasRunOnce) {
         hasRunOnce = true;
 
         MOZ_ASSERT(!sFirstIdleTask);
         sFirstIdleTask = NewRunnableFunction(FirstIdle);
         MessageLoop::current()->PostIdleTask(FROM_HERE, sFirstIdleTask);
 
         // Redo InitProcessAttributes() when the app or browser is really
         // launching so the attributes will be correct.
+        mID = aID;
+        mIsForApp = aIsForApp;
+        mIsForBrowser = aIsForBrowser;
         InitProcessAttributes();
     }
 
     return true;
 }
 
 PFileDescriptorSetChild*
 ContentChild::AllocPFileDescriptorSetChild(const FileDescriptor& aFD)
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -99,18 +99,21 @@ public:
                            base::ProcessId aOtherProcess) MOZ_OVERRIDE;
 
     virtual bool RecvSetProcessSandbox() MOZ_OVERRIDE;
 
     PBackgroundChild*
     AllocPBackgroundChild(Transport* aTransport, ProcessId aOtherProcess)
                           MOZ_OVERRIDE;
 
-    virtual PBrowserChild* AllocPBrowserChild(const IPCTabContext &aContext,
-                                              const uint32_t &chromeFlags);
+    virtual PBrowserChild* AllocPBrowserChild(const IPCTabContext& aContext,
+                                              const uint32_t& aChromeFlags,
+                                              const uint64_t& aID,
+                                              const bool& aIsForApp,
+                                              const bool& aIsForBrowser);
     virtual bool DeallocPBrowserChild(PBrowserChild*);
 
     virtual PDeviceStorageRequestChild* AllocPDeviceStorageRequestChild(const DeviceStorageParams&);
     virtual bool DeallocPDeviceStorageRequestChild(PDeviceStorageRequestChild*);
 
     virtual PFileSystemRequestChild* AllocPFileSystemRequestChild(const FileSystemParams&);
     virtual bool DeallocPFileSystemRequestChild(PFileSystemRequestChild*);
 
@@ -300,19 +303,22 @@ public:
 
     virtual PFileDescriptorSetChild*
     AllocPFileDescriptorSetChild(const FileDescriptor&) MOZ_OVERRIDE;
 
     virtual bool
     DeallocPFileDescriptorSetChild(PFileDescriptorSetChild*) MOZ_OVERRIDE;
 
 protected:
-    virtual bool RecvPBrowserConstructor(PBrowserChild* actor,
-                                         const IPCTabContext& context,
-                                         const uint32_t& chromeFlags) MOZ_OVERRIDE;
+    virtual bool RecvPBrowserConstructor(PBrowserChild* aCctor,
+                                         const IPCTabContext& aContext,
+                                         const uint32_t& aChromeFlags,
+                                         const uint64_t& aID,
+                                         const bool& aIsForApp,
+                                         const bool& aIsForBrowser) MOZ_OVERRIDE;
 
 private:
     virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
 
     virtual void ProcessingError(Result what) MOZ_OVERRIDE;
 
     /**
      * Exit *now*.  Do not shut down XPCOM, do not pass Go, do not run
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -795,17 +795,20 @@ ContentParent::CreateBrowserOrApp(const 
 
             nsRefPtr<TabParent> tp(new TabParent(cp, aContext, chromeFlags));
             tp->SetOwnerElement(aFrameElement);
 
             PBrowserParent* browser = cp->SendPBrowserConstructor(
                 // DeallocPBrowserParent() releases this ref.
                 tp.forget().take(),
                 aContext.AsIPCTabContext(),
-                chromeFlags);
+                chromeFlags,
+                cp->ChildID(),
+                cp->IsForApp(),
+                cp->IsForBrowser());
             return static_cast<TabParent*>(browser);
         }
         return nullptr;
     }
 
     // If we got here, we have an app and we're not a browser element.  ownApp
     // shouldn't be null, because we otherwise would have gone into the
     // !HasOwnApp() branch above.
@@ -893,17 +896,20 @@ ContentParent::CreateBrowserOrApp(const 
     uint32_t chromeFlags = 0;
 
     nsRefPtr<TabParent> tp = new TabParent(p, aContext, chromeFlags);
     tp->SetOwnerElement(aFrameElement);
     PBrowserParent* browser = p->SendPBrowserConstructor(
         // DeallocPBrowserParent() releases this ref.
         nsRefPtr<TabParent>(tp).forget().take(),
         aContext.AsIPCTabContext(),
-        chromeFlags);
+        chromeFlags,
+        p->ChildID(),
+        p->IsForApp(),
+        p->IsForBrowser());
 
     p->MaybeTakeCPUWakeLock(aFrameElement);
 
     return static_cast<TabParent*>(browser);
 }
 
 void
 ContentParent::GetAll(nsTArray<ContentParent*>& aArray)
@@ -2411,17 +2417,20 @@ bool
 ContentParent::DeallocPJavaScriptParent(PJavaScriptParent *parent)
 {
     static_cast<mozilla::jsipc::JavaScriptParent *>(parent)->decref();
     return true;
 }
 
 PBrowserParent*
 ContentParent::AllocPBrowserParent(const IPCTabContext& aContext,
-                                   const uint32_t &aChromeFlags)
+                                   const uint32_t& aChromeFlags,
+                                   const uint64_t& aId,
+                                   const bool& aIsForApp,
+                                   const bool& aIsForBrowser)
 {
     unused << aChromeFlags;
 
     const IPCTabAppBrowserContext& appBrowser = aContext.appBrowserContext();
 
     // We don't trust the IPCTabContext we receive from the child, so we'll bail
     // if we receive an IPCTabContext that's not a PopupIPCTabContext.
     // (PopupIPCTabContext lets the child process prove that it has access to
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -147,16 +147,20 @@ public:
     TestShellParent* GetTestShellSingleton();
     jsipc::JavaScriptParent *GetCPOWManager();
 
     void ReportChildAlreadyBlocked();
     bool RequestRunToCompletion();
 
     bool IsAlive();
     bool IsForApp();
+    bool IsForBrowser()
+    {
+      return mIsForBrowser;
+    }
 #ifdef MOZ_NUWA_PROCESS
     bool IsNuwaProcess();
 #endif
 
     GeckoChildProcessHost* Process() {
         return mSubprocess;
     }
 
@@ -355,17 +359,20 @@ private:
     virtual bool RecvGetProcessAttributes(uint64_t* aId,
                                           bool* aIsForApp,
                                           bool* aIsForBrowser) MOZ_OVERRIDE;
     virtual bool RecvGetXPCOMProcessAttributes(bool* aIsOffline) MOZ_OVERRIDE;
 
     virtual bool DeallocPJavaScriptParent(mozilla::jsipc::PJavaScriptParent*) MOZ_OVERRIDE;
 
     virtual PBrowserParent* AllocPBrowserParent(const IPCTabContext& aContext,
-                                                const uint32_t& aChromeFlags) MOZ_OVERRIDE;
+                                                const uint32_t& aChromeFlags,
+                                                const uint64_t& aId,
+                                                const bool& aIsForApp,
+                                                const bool& aIsForBrowser) MOZ_OVERRIDE;
     virtual bool DeallocPBrowserParent(PBrowserParent* frame) MOZ_OVERRIDE;
 
     virtual PDeviceStorageRequestParent*
     AllocPDeviceStorageRequestParent(const DeviceStorageParams&) MOZ_OVERRIDE;
     virtual bool DeallocPDeviceStorageRequestParent(PDeviceStorageRequestParent*) MOZ_OVERRIDE;
 
     virtual PFileSystemRequestParent*
     AllocPFileSystemRequestParent(const FileSystemParams&) MOZ_OVERRIDE;
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -318,17 +318,20 @@ both:
     // the opener PBrowser's app-id and containing-app-id.  The parent checks
     // that if the opener is a browser element, the context is also for a
     // browser element.
     //
     // This allows the parent to prevent a malicious child from escalating its
     // privileges by requesting a PBrowser corresponding to a highly-privileged
     // app; the child can only request privileges for an app which the child has
     // access to (in the form of a TabChild).
-    async PBrowser(IPCTabContext context, uint32_t chromeFlags);
+    //
+    // Keep the last 3 attributes in sync with GetProcessAttributes!
+    async PBrowser(IPCTabContext context, uint32_t chromeFlags,
+                   uint64_t id, bool isForApp, bool isForBrowser);
 
     async PBlob(BlobConstructorParams params);
 
     PFileDescriptorSet(FileDescriptor fd);
 
 child:
     /**
      * Enable system-level sandboxing features, if available.  Can
@@ -427,16 +430,18 @@ parent:
      * among the first information queried by content processes after
      * startup.  (The message is sync to allow the content process to
      * control when it receives the information.)
      *
      * |id| is a unique ID among all subprocesses.  When |isForApp &&
      * isForBrowser|, we're loading <browser> for an app.  When
      * |isForBrowser|, we're loading <browser>.  When |!isForApp &&
      * !isForBrowser|, we're probably loading <xul:browser remote>.
+     *
+     * Keep the return values in sync with PBrowser()!
      */
     sync GetProcessAttributes()
         returns (uint64_t id, bool isForApp, bool isForBrowser);
     sync GetXPCOMProcessAttributes()
         returns (bool isOffline);
 
     async PJavaScript();
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -1252,20 +1252,22 @@ TabChild::BrowserFrameProvideWindow(nsID
   // We must use PopupIPCTabContext here; ContentParent will not accept the
   // result of this->AsIPCTabContext() (which will be a
   // BrowserFrameIPCTabContext or an AppFrameIPCTabContext), for security
   // reasons.
   PopupIPCTabContext context;
   context.openerChild() = this;
   context.isBrowserElement() = IsBrowserElement();
 
+  ContentChild* cc = static_cast<ContentChild*>(Manager());
   unused << Manager()->SendPBrowserConstructor(
       // We release this ref in DeallocPBrowserChild
       nsRefPtr<TabChild>(newChild).forget().take(),
-      IPCTabContext(context, mScrolling), /* chromeFlags */ 0);
+      IPCTabContext(context, mScrolling), /* chromeFlags */ 0,
+      cc->GetID(), cc->IsForApp(), cc->IsForBrowser());
 
   nsAutoCString spec;
   if (aURI) {
     aURI->GetSpec(spec);
   }
 
   NS_ConvertUTF8toUTF16 url(spec);
   nsString name(aName);
--- a/dom/messages/SystemMessageInternal.js
+++ b/dom/messages/SystemMessageInternal.js
@@ -580,28 +580,30 @@ SystemMessageInternal.prototype = {
     if ((aMsgSentStatus === MSG_SENT_SUCCESS) && !showApp) {
       return;
     }
 
     // This flag means the app must *only* be brought to the foreground
     // and we don't need to load the app to handle messages.
     let onlyShowApp = (aMsgSentStatus === MSG_SENT_SUCCESS) && showApp;
 
-    // We don't need to send the full object to observers.
-    let page = { pageURL: aPage.pageURL,
-                 manifestURL: aPage.manifestURL,
-                 type: aPage.type,
-                 extra: aExtra,
-                 target: aMessage.target,
-                 onlyShowApp: onlyShowApp,
-                 showApp: showApp };
-    debug("Asking to open " + JSON.stringify(page));
-    Services.obs.notifyObservers(this,
-                                 "system-messages-open-app",
-                                 JSON.stringify(page));
+    debug("Asking to open pageURL: " + aPage.pageURL +
+          ", manifestURL: " + aPage.manifestURL + ", type: " + aPage.type +
+          ", target: " + JSON.stringify(aMessage.target) +
+          ", showApp: " + showApp + ", onlyShowApp: " + onlyShowApp +
+          ", extra: " + JSON.stringify(aExtra));
+
+    let glue = Cc["@mozilla.org/dom/messages/system-message-glue;1"]
+                 .createInstance(Ci.nsISystemMessageGlue);
+    if (glue) {
+      glue.openApp(aPage.pageURL, aPage.manifestURL, aPage.type, aMessage.target,
+                   showApp, onlyShowApp, aExtra);
+    } else {
+      debug("Error! The UI glue component is not implemented.");
+    }
   },
 
   _isPageMatched: function(aPage, aType, aPageURL, aManifestURL) {
     return (aPage.type === aType &&
             aPage.manifestURL === aManifestURL &&
             aPage.pageURL === aPageURL)
   },
 
--- a/dom/messages/interfaces/moz.build
+++ b/dom/messages/interfaces/moz.build
@@ -1,13 +1,14 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPIDL_SOURCES += [
     'nsIDOMNavigatorSystemMessages.idl',
+    'nsISystemMessageGlue.idl',
     'nsISystemMessagesInternal.idl',
 ]
 
 XPIDL_MODULE = 'dom_messages'
 
new file mode 100644
--- /dev/null
+++ b/dom/messages/interfaces/nsISystemMessageGlue.idl
@@ -0,0 +1,31 @@
+/* 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 "domstubs.idl"
+
+// Implemented by the contract id @mozilla.org/dom/messages/system-message-glue;1
+
+[scriptable, uuid(b5d98286-e7cc-11e3-92fb-74d02b97e723)]
+interface nsISystemMessageGlue : nsISupports
+{
+    /* Notify the system app to open the target app.
+     *
+     * @param pageURL     The URL of the page that will be opened.
+     * @param manifestURL The webapp's manifest URL.
+     * @param type        The message type.
+     * @param target      The target which the message is associated with.
+     * @param showApp     This flag indicates the app must be brought to the
+     *                    foreground.
+     * @param onlyShowApp This flag indicates the app must be *only* brought to
+     *                    the foreground without loading to handle messages.
+     * @param extra       Extra opaque info to pass around for opening the page.
+     */
+    void openApp(in DOMString pageURL,
+                 in DOMString manifestURL,
+                 in DOMString type,
+                 in jsval target,
+                 in boolean showApp,
+                 in boolean onlyShowApp,
+                 [optional] in jsval extra);
+};
--- a/dom/tests/mochitest/general/mochitest.ini
+++ b/dom/tests/mochitest/general/mochitest.ini
@@ -48,16 +48,17 @@ skip-if = (buildapp == 'b2g' && toolkit 
 [test_offsets.html]
 [test_offsets.js]
 [test_outerHTML.html]
 [test_outerHTML.xhtml]
 [test_paste_selection.html]
 [test_resource_timing.html]
 skip-if = buildapp == 'b2g' # b2g(No clipboard) b2g-debug(No clipboard) b2g-desktop(No clipboard)
 [test_performance_now.html]
+[test_srcset_pref.html]
 [test_showModalDialog.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' #Don't run modal tests on Android # b2g(showmodaldialog) b2g-debug(showmodaldialog) b2g-desktop(showmodaldialog)
 [test_stylesheetPI.html]
 [test_vibrator.html]
 skip-if = toolkit == 'android' #CRASH_SUTAGENT
 [test_windowProperties.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
 [test_windowedhistoryframes.html]
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/general/test_srcset_pref.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=870021
+-->
+<head>
+  <title>Test for dom.image.srcset.enabled (Bug 870021)</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="runTest()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=870021">Mozilla Bug 870021</a>
+
+<img src="http://example.com/tests/image/test/mochitest/blue.png"
+     srcset="http://example.com/tests/image/test/mochitest/big.png">
+
+<script type="application/javascript">
+
+  const srcsetPref = 'dom.image.srcset.enabled';
+
+  SimpleTest.waitForExplicitFinish();
+
+  is(SpecialPowers.getBoolPref(srcsetPref), false, "srcset should be disabled pending bug 1018389");
+
+  function runTest() {
+    var img = document.querySelector("img");
+    is(img.currentSrc, undefined, "currentSrc should not be visible");
+    is(img.srcset, undefined, "srcset should not be visible");
+
+    var currentSrcDesc = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, "currentSrc");
+    var srcsetDesc = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, "srcset");
+    is(currentSrcDesc, undefined, "HTMLImageElement should know nothing of currentSrc");
+    is(srcsetDesc, undefined, "HTMLImageElement should know nothing of srcset");
+
+    // Make sure the test image loaded the src image, which is 1x1, not the srcset image
+    is(img.naturalWidth, 1, "Image should have loaded small source");
+    SimpleTest.finish();
+  }
+
+</script>
+
+</body>
+</html>
--- a/dom/webidl/HTMLImageElement.webidl
+++ b/dom/webidl/HTMLImageElement.webidl
@@ -53,19 +53,19 @@ partial interface HTMLImageElement {
            [SetterThrows]
            attribute DOMString longDesc;
 
   [TreatNullAs=EmptyString,SetterThrows] attribute DOMString border;
 };
 
 // [Update me: not in whatwg spec yet]
 // http://picture.responsiveimages.org/#the-img-element
-[Pref="dom.image.srcset.enabled"]
 partial interface HTMLImageElement {
-           readonly attribute DOMString? currentSrc;
+           [Pref="dom.image.srcset.enabled"]
+  readonly attribute DOMString? currentSrc;
 };
 
 // Mozilla extensions.
 partial interface HTMLImageElement {
            attribute DOMString lowsrc;
 
   // These attributes are offsets from the closest view (to mimic
   // NS4's "offset-from-layer" behavior).
--- a/dom/webidl/ProgressEvent.webidl
+++ b/dom/webidl/ProgressEvent.webidl
@@ -1,15 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  */
 
-[Constructor(DOMString type, optional ProgressEventInit eventInitDict), HeaderFile="GeneratedEventClasses.h"]
+[Constructor(DOMString type, optional ProgressEventInit eventInitDict)]
 interface ProgressEvent : Event
 {
   readonly attribute boolean lengthComputable;
   readonly attribute unsigned long long loaded;
   readonly attribute unsigned long long total;
 };
 
 dictionary ProgressEventInit : EventInit
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -635,16 +635,17 @@ GENERATED_EVENTS_WEBIDL_FILES = [
     'IccChangeEvent.webidl',
     'MediaStreamEvent.webidl',
     'MozClirModeEvent.webidl',
     'MozContactChangeEvent.webidl',
     'MozEmergencyCbModeEvent.webidl',
     'MozInterAppMessageEvent.webidl',
     'MozOtaStatusEvent.webidl',
     'MozStkCommandEvent.webidl',
+    'ProgressEvent.webidl',
     'RTCDataChannelEvent.webidl',
     'RTCPeerConnectionIceEvent.webidl',
     'RTCPeerConnectionIdentityErrorEvent.webidl',
     'RTCPeerConnectionIdentityEvent.webidl',
     'TrackEvent.webidl',
     'UserProximityEvent.webidl',
     'USSDReceivedEvent.webidl',
 ]
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -2,25 +2,25 @@
 /* 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 "XMLHttpRequest.h"
 
 #include "nsIDOMEvent.h"
 #include "nsIDOMEventListener.h"
-#include "nsIDOMProgressEvent.h"
 #include "nsIRunnable.h"
 #include "nsIVariant.h"
 #include "nsIXMLHttpRequest.h"
 #include "nsIXPConnect.h"
 
 #include "jsfriendapi.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/dom/Exceptions.h"
+#include "mozilla/dom/ProgressEvent.h"
 #include "nsComponentManagerUtils.h"
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
 #include "nsJSUtils.h"
 #include "nsThreadUtils.h"
 
 #include "File.h"
 #include "RuntimeService.h"
@@ -1035,39 +1035,33 @@ Proxy::HandleEvent(nsIDOMEvent* aEvent)
 
   nsCOMPtr<nsIDOMEventTarget> target;
   if (NS_FAILED(aEvent->GetTarget(getter_AddRefs(target)))) {
     NS_WARNING("Failed to get target!");
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIXMLHttpRequestUpload> uploadTarget = do_QueryInterface(target);
-  nsCOMPtr<nsIDOMProgressEvent> progressEvent = do_QueryInterface(aEvent);
+  ProgressEvent* progressEvent = aEvent->InternalDOMEvent()->AsProgressEvent();
 
   nsRefPtr<EventRunnable> runnable;
 
   if (mInOpen && type.EqualsASCII(sEventStrings[STRING_readystatechange])) {
     uint16_t readyState = 0;
     if (NS_SUCCEEDED(mXHR->GetReadyState(&readyState)) &&
         readyState == nsIXMLHttpRequest::OPENED) {
       mInnerEventStreamId++;
     }
   }
 
   if (progressEvent) {
-    bool lengthComputable;
-    uint64_t loaded, total;
-    if (NS_FAILED(progressEvent->GetLengthComputable(&lengthComputable)) ||
-        NS_FAILED(progressEvent->GetLoaded(&loaded)) ||
-        NS_FAILED(progressEvent->GetTotal(&total))) {
-      NS_WARNING("Bad progress event!");
-      return NS_ERROR_FAILURE;
-    }
-    runnable = new EventRunnable(this, !!uploadTarget, type, lengthComputable,
-                                 loaded, total);
+    runnable = new EventRunnable(this, !!uploadTarget, type,
+                                 progressEvent->LengthComputable(),
+                                 progressEvent->Loaded(),
+                                 progressEvent->Total());
   }
   else {
     runnable = new EventRunnable(this, !!uploadTarget, type);
   }
 
   {
     AutoSafeJSContext cx;
     JSAutoRequest ar(cx);
@@ -1338,23 +1332,24 @@ EventRunnable::WorkerRun(JSContext* aCx,
   else {
     target = xhr;
   }
 
   MOZ_ASSERT(target);
 
   nsCOMPtr<nsIDOMEvent> event;
   if (mProgressEvent) {
-    NS_NewDOMProgressEvent(getter_AddRefs(event), target, nullptr, nullptr);
-    nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event);
+    ProgressEventInit init;
+    init.mBubbles = false;
+    init.mCancelable = false;
+    init.mLengthComputable = mLengthComputable;
+    init.mLoaded = mLoaded;
+    init.mTotal = mTotal;
 
-    if (progress) {
-      progress->InitProgressEvent(mType, false, false, mLengthComputable,
-                                  mLoaded, mTotal);
-    }
+    event = ProgressEvent::Constructor(target, mType, init);
   }
   else {
     NS_NewDOMEvent(getter_AddRefs(event), target, nullptr, nullptr);
 
     if (event) {
       event->InitEvent(mType, false, false);
     }
   }
@@ -1734,33 +1729,30 @@ XMLHttpRequest::DispatchPrematureAbortEv
   if (aEventType.EqualsLiteral("readystatechange")) {
     NS_NewDOMEvent(getter_AddRefs(event), aTarget, nullptr, nullptr);
 
     if (event) {
       event->InitEvent(aEventType, false, false);
     }
   }
   else {
-    NS_NewDOMProgressEvent(getter_AddRefs(event), aTarget, nullptr, nullptr);
-
-    nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event);
-    if (progress) {
-      if (aUploadTarget) {
-        progress->InitProgressEvent(aEventType, false, false,
-                                    mProxy->mLastUploadLengthComputable,
-                                    mProxy->mLastUploadLoaded,
-                                    mProxy->mLastUploadTotal);
-      }
-      else {
-        progress->InitProgressEvent(aEventType, false, false,
-                                    mProxy->mLastLengthComputable,
-                                    mProxy->mLastLoaded,
-                                    mProxy->mLastTotal);
-      }
+    ProgressEventInit init;
+    init.mBubbles = false;
+    init.mCancelable = false;
+    if (aUploadTarget) {
+      init.mLengthComputable = mProxy->mLastUploadLengthComputable;
+      init.mLoaded = mProxy->mLastUploadLoaded;
+      init.mTotal = mProxy->mLastUploadTotal;
     }
+    else {
+      init.mLengthComputable = mProxy->mLastLengthComputable;
+      init.mLoaded = mProxy->mLastLoaded;
+      init.mTotal = mProxy->mLastTotal;
+    }
+    event = ProgressEvent::Constructor(aTarget, aEventType, init);
   }
 
   if (!event) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   event->SetTrusted(true);
--- a/gfx/gl/TextureImageCGL.h
+++ b/gfx/gl/TextureImageCGL.h
@@ -26,27 +26,23 @@ public:
                     ContentType aContentType,
                     GLContext* aContext,
                     TextureImage::Flags aFlags = TextureImage::NoFlags,
                     TextureImage::ImageFormat aImageFormat = gfxImageFormat::Unknown);
 
     ~TextureImageCGL();
 
 protected:
-    already_AddRefed<gfxASurface>
-    GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt);
-
     bool FinishedSurfaceUpdate();
 
     void FinishedSurfaceUpload();
 
 private:
 
     GLuint mPixelBuffer;
-    int32_t mPixelBufferSize;
     bool mBoundPixelBuffer;
 };
 
 already_AddRefed<TextureImage>
 CreateTextureImageCGL(GLContext *gl,
                       const gfx::IntSize& aSize,
                       TextureImage::ContentType aContentType,
                       GLenum aWrapMode,
--- a/gfx/gl/TextureImageCGL.mm
+++ b/gfx/gl/TextureImageCGL.mm
@@ -21,78 +21,27 @@ TextureImageCGL::TextureImageCGL(GLuint 
                 GLenum aWrapMode,
                 ContentType aContentType,
                 GLContext* aContext,
                 TextureImage::Flags aFlags,
                 TextureImage::ImageFormat aImageFormat)
     : BasicTextureImage(aTexture, aSize, aWrapMode, aContentType,
                         aContext, aFlags, aImageFormat)
     , mPixelBuffer(0)
-    , mPixelBufferSize(0)
     , mBoundPixelBuffer(false)
 {}
 
 TextureImageCGL::~TextureImageCGL()
 {
     if (mPixelBuffer) {
         mGLContext->MakeCurrent();
         mGLContext->fDeleteBuffers(1, &mPixelBuffer);
     }
 }
 
-already_AddRefed<gfxASurface>
-TextureImageCGL::GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt)
-{
-    IntSize size(aSize.width + 1, aSize.height + 1);
-    mGLContext->MakeCurrent();
-    if (!mGLContext->
-        IsExtensionSupported(GLContext::ARB_pixel_buffer_object))
-    {
-        return gfxPlatform::GetPlatform()->
-            CreateOffscreenSurface(size,
-                                    gfxASurface::ContentFromFormat(aFmt));
-    }
-
-    if (!mPixelBuffer) {
-        mGLContext->fGenBuffers(1, &mPixelBuffer);
-    }
-    mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, mPixelBuffer);
-    int32_t length = size.width * 4 * size.height;
-
-    if (length > mPixelBufferSize) {
-        mGLContext->fBufferData(LOCAL_GL_PIXEL_UNPACK_BUFFER, length,
-                                NULL, LOCAL_GL_STREAM_DRAW);
-        mPixelBufferSize = length;
-    }
-    unsigned char* data =
-        (unsigned char*)mGLContext->
-            fMapBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER,
-                        LOCAL_GL_WRITE_ONLY);
-
-    mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
-
-    if (!data) {
-        nsAutoCString failure;
-        failure += "Pixel buffer binding failed: ";
-        failure.AppendPrintf("%dx%d\n", size.width, size.height);
-        gfx::LogFailure(failure);
-
-        mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
-        return gfxPlatform::GetPlatform()->
-            CreateOffscreenSurface(size,
-                                    gfxASurface::ContentFromFormat(aFmt));
-    }
-
-    nsRefPtr<gfxQuartzSurface> surf =
-        new gfxQuartzSurface(data, ThebesIntSize(size), size.width * 4, aFmt);
-
-    mBoundPixelBuffer = true;
-    return surf.forget();
-}
-
 bool
 TextureImageCGL::FinishedSurfaceUpdate()
 {
     if (mBoundPixelBuffer) {
         mGLContext->MakeCurrent();
         mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, mPixelBuffer);
         mGLContext->fUnmapBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER);
         return true;
--- a/gfx/layers/LayerTreeInvalidation.cpp
+++ b/gfx/layers/LayerTreeInvalidation.cpp
@@ -64,24 +64,16 @@ AddTransformedRegion(nsIntRegion& aDest,
 
 static void
 AddRegion(nsIntRegion& aDest, const nsIntRegion& aSource)
 {
   aDest.Or(aDest, aSource);
   aDest.SimplifyOutward(20);
 }
 
-
-static nsIntRegion
-TransformRegion(nsIntRegion& aRegion, const gfx3DMatrix& aTransform)
-{
-  aRegion.Transform(aTransform);
-  return aRegion;
-}
-
 /**
  * Walks over this layer, and all descendant layers.
  * If any of these are a ContainerLayer that reports invalidations to a PresShell,
  * then report that the entire bounds have changed.
  */
 static void
 NotifySubdocumentInvalidationRecursive(Layer* aLayer, NotifySubDocInvalidationFunc aCallback)
 {
@@ -320,17 +312,18 @@ struct ContainerLayerProperties : public
     }
 
     if (aCallback) {
       aCallback(container, result);
     }
 
     gfx3DMatrix transform;
     gfx::To3DMatrix(mLayer->GetTransform(), transform);
-    return TransformRegion(result, transform);
+    result.Transform(transform);
+    return result;
   }
 
   // The old list of children:
   nsAutoTArray<nsAutoPtr<LayerPropertiesBase>,1> mChildren;
   float mPreXScale;
   float mPreYScale;
 };
 
--- a/gfx/layers/composite/ContainerLayerComposite.cpp
+++ b/gfx/layers/composite/ContainerLayerComposite.cpp
@@ -385,17 +385,19 @@ ContainerRender(ContainerT* aContainer,
     // assert it though
   }
 
   if (needsSurface) {
     // Unbind the current surface and rebind the previous one.
 #ifdef MOZ_DUMP_PAINTING
     if (gfxUtils::sDumpPainting) {
       RefPtr<gfx::DataSourceSurface> surf = surface->Dump(aManager->GetCompositor());
-      WriteSnapshotToDumpFile(aContainer, surf);
+      if (surf) {
+        WriteSnapshotToDumpFile(aContainer, surf);
+      }
     }
 #endif
 
     compositor->SetRenderTarget(previousTarget);
     EffectChain effectChain(aContainer);
     LayerManagerComposite::AutoAddMaskEffect autoMaskEffect(aContainer->GetMaskLayer(),
                                                             effectChain,
                                                             !aContainer->GetTransform().CanDraw2D());
--- a/gfx/tests/gtest/gfxFontSelectionTest.cpp
+++ b/gfx/tests/gtest/gfxFontSelectionTest.cpp
@@ -1,29 +1,32 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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 "gtest/gtest.h"
 
+#include "mozilla/gfx/2D.h"
+#include "mozilla/RefPtr.h"
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
 #include "nsString.h"
 #include "nsDependentString.h"
 
 #include "mozilla/Preferences.h"
 
 #include "gfxContext.h"
 #include "gfxFont.h"
 #include "gfxPlatform.h"
 
 #include "gfxFontTest.h"
 
 using namespace mozilla;
+using namespace mozilla::gfx;
 
 enum {
     S_UTF8 = 0,
     S_ASCII = 1
 };
 
 class FrameTextRunCache;
 
@@ -180,22 +183,21 @@ struct TestEntry {
     nsTArray<ExpectItem> expectItems;
 };
 
 static already_AddRefed<gfxContext>
 MakeContext ()
 {
     const int size = 200;
 
-    nsRefPtr<gfxASurface> surface;
+    RefPtr<DrawTarget> drawTarget = gfxPlatform::GetPlatform()->
+        CreateOffscreenContentDrawTarget(IntSize(size, size),
+                                         SurfaceFormat::B8G8R8X8);
+    nsRefPtr<gfxContext> ctx = new gfxContext(drawTarget);
 
-    surface = gfxPlatform::GetPlatform()->
-        CreateOffscreenSurface(IntSize(size, size),
-                               gfxASurface::ContentFromFormat(gfxImageFormat::RGB24));
-    nsRefPtr<gfxContext> ctx = new gfxContext(surface);
     return ctx.forget();
 }
 
 TestEntry*
 AddTest (nsTArray<TestEntry>& testList,
          const char *utf8FamilyString,
          const gfxFontStyle& fontStyle,
          int stringType,
--- a/gfx/tests/gtest/gfxTextRunPerfTest.cpp
+++ b/gfx/tests/gtest/gfxTextRunPerfTest.cpp
@@ -1,53 +1,55 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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 "gtest/gtest.h"
 
 #include "mozilla/ArrayUtils.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/RefPtr.h"
 
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
 #include "nsString.h"
 #include "nsDependentString.h"
 
 #include "prinrval.h"
 
 #include "gfxContext.h"
 #include "gfxFont.h"
 #include "gfxPlatform.h"
 
 #include "gfxFontTest.h"
 
 using namespace mozilla;
+using namespace mozilla::gfx;
 
 struct TestEntry {
   const char* mFamilies;
   const char* mString;
 };
 
 TestEntry testList[] = {
 #include "per-word-runs.h"
 { nullptr, nullptr } // terminator
 };
 
 static already_AddRefed<gfxContext>
 MakeContext ()
 {
     const int size = 200;
 
-    nsRefPtr<gfxASurface> surface;
+    RefPtr<DrawTarget> drawTarget = gfxPlatform::GetPlatform()->
+        CreateOffscreenContentDrawTarget(IntSize(size, size),
+                                         SurfaceFormat::B8G8R8X8);
+    nsRefPtr<gfxContext> ctx = new gfxContext(drawTarget);
 
-    surface = gfxPlatform::GetPlatform()->
-        CreateOffscreenSurface(IntSize(size, size),
-                               gfxASurface::ContentFromFormat(gfxImageFormat::RGB24));
-    nsRefPtr<gfxContext> ctx = new gfxContext(surface);
     return ctx.forget();
 }
 
 const char* lastFamilies = nullptr;
 
 static void
 RunTest (TestEntry *test, gfxContext *ctx) {
     nsRefPtr<gfxFontGroup> fontGroup;
--- a/gfx/tests/gtest/gfxWordCacheTest.cpp
+++ b/gfx/tests/gtest/gfxWordCacheTest.cpp
@@ -1,29 +1,34 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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 "gtest/gtest.h"
 
+#include "mozilla/gfx/2D.h"
+#include "mozilla/RefPtr.h"
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
 #include "nsString.h"
 #include "nsDependentString.h"
 
 #include "prinrval.h"
 
 #include "gfxContext.h"
 #include "gfxFont.h"
 #include "gfxPlatform.h"
 
 #include "gfxFontTest.h"
 #include "mozilla/Attributes.h"
 
+using namespace mozilla;
+using namespace mozilla::gfx;
+
 class FrameTextRunCache;
 
 static FrameTextRunCache *gTextRuns = nullptr;
 
 /*
  * Cache textruns and expire them after 3*10 seconds of no use.
  */
 class FrameTextRunCache MOZ_FINAL : public nsExpirationTracker<gfxTextRun,3> {
@@ -73,23 +78,22 @@ MakeTextRun(const char16_t *aText, uint3
    return textRun.forget();
 }
 
 static already_AddRefed<gfxContext>
 MakeContext ()
 {
    const int size = 200;
 
-   nsRefPtr<gfxASurface> surface;
+    RefPtr<DrawTarget> drawTarget = gfxPlatform::GetPlatform()->
+        CreateOffscreenContentDrawTarget(IntSize(size, size),
+                                         SurfaceFormat::B8G8R8X8);
+    nsRefPtr<gfxContext> ctx = new gfxContext(drawTarget);
 
-   surface = gfxPlatform::GetPlatform()->
-       CreateOffscreenSurface(IntSize(size, size),
-                              gfxASurface::ContentFromFormat(gfxImageFormat::RGB24));
-   nsRefPtr<gfxContext> ctx = new gfxContext(surface);
-   return ctx.forget();
+    return ctx.forget();
 }
 
 TEST(Gfx, WordCache) {
    gTextRuns = new FrameTextRunCache();
 
    nsRefPtr<gfxContext> ctx = MakeContext();
    {
        gfxFontStyle style (mozilla::gfx::FontStyle::NORMAL,
--- a/image/src/imgLoader.cpp
+++ b/image/src/imgLoader.cpp
@@ -24,17 +24,17 @@
 #include "nsICachingChannel.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIProgressEventSink.h"
 #include "nsIChannelEventSink.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsIFileURL.h"
 #include "nsCRT.h"
 #include "nsIDocument.h"
-#include "nsINetworkSeer.h"
+#include "nsINetworkPredictor.h"
 
 #include "nsIApplicationCache.h"
 #include "nsIApplicationCacheContainer.h"
 
 #include "nsIMemoryReporter.h"
 #include "Image.h"
 #include "DiscardTracker.h"
 
@@ -1424,18 +1424,18 @@ bool imgLoader::ValidateRequestWithNewCh
     // In the mean time, we must defer notifications because we are added to
     // the imgRequest's proxy list, and we can get extra notifications
     // resulting from methods such as RequestDecode(). See bug 579122.
     proxy->SetNotificationsDeferred(true);
 
     // Add the proxy without notifying
     hvc->AddProxy(proxy);
 
-    mozilla::net::SeerLearn(aURI, aInitialDocumentURI,
-        nsINetworkSeer::LEARN_LOAD_SUBRESOURCE, aLoadGroup);
+    mozilla::net::PredictorLearn(aURI, aInitialDocumentURI,
+        nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE, aLoadGroup);
 
     rv = newChannel->AsyncOpen(listener, nullptr);
     if (NS_SUCCEEDED(rv))
       NS_ADDREF(*aProxyRequest = req.get());
 
     return NS_SUCCEEDED(rv);
   }
 }
@@ -1923,18 +1923,18 @@ nsresult imgLoader::LoadImage(nsIURI *aU
       }
 
       listener = corsproxy;
     }
 
     PR_LOG(GetImgLog(), PR_LOG_DEBUG,
            ("[this=%p] imgLoader::LoadImage -- Calling channel->AsyncOpen()\n", this));
 
-    mozilla::net::SeerLearn(aURI, aInitialDocumentURI,
-        nsINetworkSeer::LEARN_LOAD_SUBRESOURCE, aLoadGroup);
+    mozilla::net::PredictorLearn(aURI, aInitialDocumentURI,
+        nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE, aLoadGroup);
 
     nsresult openRes = newChannel->AsyncOpen(listener, nullptr);
 
     if (NS_FAILED(openRes)) {
       PR_LOG(GetImgLog(), PR_LOG_DEBUG,
              ("[this=%p] imgLoader::LoadImage -- AsyncOpen() failed: 0x%x\n",
               this, openRes));
       request->CancelAndAbort(openRes);
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -21,16 +21,17 @@
 #include "frontend/BytecodeCompiler.h"
 #include "gc/GCInternals.h"
 #include "gc/Marking.h"
 #ifdef JS_ION
 # include "jit/IonMacroAssembler.h"
 #endif
 #include "js/HashTable.h"
 #include "vm/Debugger.h"
+#include "vm/PropDesc.h"
 
 #include "jsgcinlines.h"
 #include "jsobjinlines.h"
 
 using namespace js;
 using namespace js::gc;
 
 using mozilla::ArrayEnd;
@@ -59,16 +60,17 @@ MarkExactStackRoot(JSTracer *trc, Rooted
       case THING_ROOT_BASE_SHAPE:  MarkBaseShapeRoot(trc, (BaseShape **)addr, "exact-baseshape"); break;
       case THING_ROOT_TYPE:        MarkTypeRoot(trc, (types::Type *)addr, "exact-type"); break;
       case THING_ROOT_TYPE_OBJECT: MarkTypeObjectRoot(trc, (types::TypeObject **)addr, "exact-typeobject"); break;
       case THING_ROOT_JIT_CODE:    MarkJitCodeRoot(trc, (jit::JitCode **)addr, "exact-jitcode"); break;
       case THING_ROOT_VALUE:       MarkValueRoot(trc, (Value *)addr, "exact-value"); break;
       case THING_ROOT_ID:          MarkIdRoot(trc, (jsid *)addr, "exact-id"); break;
       case THING_ROOT_BINDINGS:    ((Bindings *)addr)->trace(trc); break;
       case THING_ROOT_PROPERTY_DESCRIPTOR: ((JSPropertyDescriptor *)addr)->trace(trc); break;
+      case THING_ROOT_PROP_DESC:   ((PropDesc *)addr)->trace(trc); break;
       case THING_ROOT_CUSTOM: {
           // 'rooter' is a member within a class containing a vtable. Back up
           // to the vtable and call trace() through it.
           const size_t rooterOffset = offsetof(RootedGeneric<void*>, rooter);
           reinterpret_cast< RootedGeneric<void*>* >(uintptr_t(rooter) - rooterOffset)->trace(trc);
           break;
       }
       default: MOZ_ASSUME_UNREACHABLE("Invalid THING_ROOT kind"); break;
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -258,18 +258,17 @@ bool
 js::NewPropertyDescriptorObject(JSContext *cx, Handle<PropertyDescriptor> desc,
                                 MutableHandleValue vp)
 {
     if (!desc.object()) {
         vp.setUndefined();
         return true;
     }
 
-    /* We have our own property, so start creating the descriptor. */
-    AutoPropDescRooter d(cx);
+    Rooted<PropDesc> d(cx);
 
     d.initFromPropertyDescriptor(desc);
     if (!d.makeObject(cx))
         return false;
     vp.set(d.pd());
     return true;
 }
 
@@ -1057,41 +1056,37 @@ js::DefineProperty(JSContext *cx, Handle
 
     return DefinePropertyOnObject(cx, obj, id, desc, throwError, rval);
 }
 
 bool
 js::DefineOwnProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue descriptor,
                       bool *bp)
 {
-    AutoPropDescArrayRooter descs(cx);
-    PropDesc *desc = descs.append();
-    if (!desc || !desc->initialize(cx, descriptor))
+    Rooted<PropDesc> desc(cx);
+    if (!desc.initialize(cx, descriptor))
         return false;
 
     bool rval;
-    if (!DefineProperty(cx, obj, id, *desc, true, &rval))
+    if (!DefineProperty(cx, obj, id, desc, true, &rval))
         return false;
     *bp = !!rval;
     return true;
 }
 
 bool
 js::DefineOwnProperty(JSContext *cx, HandleObject obj, HandleId id,
                       Handle<PropertyDescriptor> descriptor, bool *bp)
 {
-    AutoPropDescArrayRooter descs(cx);
-    PropDesc *desc = descs.append();
-    if (!desc)
-        return false;
-
-    desc->initFromPropertyDescriptor(descriptor);
+    Rooted<PropDesc> desc(cx);
+
+    desc.initFromPropertyDescriptor(descriptor);
 
     bool rval;
-    if (!DefineProperty(cx, obj, id, *desc, true, &rval))
+    if (!DefineProperty(cx, obj, id, desc, true, &rval))
         return false;
     *bp = !!rval;
     return true;
 }
 
 
 bool
 js::ReadPropertyDescriptors(JSContext *cx, HandleObject props, bool checkAccessors,
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -673,27 +673,26 @@ Trap2(JSContext *cx, HandleObject handle
     argv[1].set(v);
     return Trap(cx, handler, fval, 2, argv.begin(), rval);
 }
 
 static bool
 ParsePropertyDescriptorObject(JSContext *cx, HandleObject obj, const Value &v,
                               MutableHandle<PropertyDescriptor> desc, bool complete = false)
 {
-    AutoPropDescArrayRooter descs(cx);
-    PropDesc *d = descs.append();
-    if (!d || !d->initialize(cx, v))
+    Rooted<PropDesc> d(cx);
+    if (!d.initialize(cx, v))
         return false;
     if (complete)
-        d->complete();
+        d.complete();
     desc.object().set(obj);
-    desc.value().set(d->hasValue() ? d->value() : UndefinedValue());
-    desc.setAttributes(d->attributes());
-    desc.setGetter(d->getter());
-    desc.setSetter(d->setter());
+    desc.value().set(d.hasValue() ? d.value() : UndefinedValue());
+    desc.setAttributes(d.attributes());
+    desc.setGetter(d.getter());
+    desc.setSetter(d.setter());
     return true;
 }
 
 static bool
 IndicatePropertyNotFound(MutableHandle<PropertyDescriptor> desc)
 {
     desc.object().set(nullptr);
     return true;
@@ -1096,28 +1095,28 @@ class ScriptedDirectProxyHandler : publi
     static ScriptedDirectProxyHandler singleton;
 };
 
 // This variable exists solely to provide a unique address for use as an identifier.
 static const char sScriptedDirectProxyHandlerFamily = 0;
 
 // Aux.2 FromGenericPropertyDescriptor(Desc)
 static bool
-FromGenericPropertyDescriptor(JSContext *cx, PropDesc *desc, MutableHandleValue rval)
+FromGenericPropertyDescriptor(JSContext *cx, MutableHandle<PropDesc> desc, MutableHandleValue rval)
 {
     // Aux.2 step 1
-    if (desc->isUndefined()) {
+    if (desc.isUndefined()) {
         rval.setUndefined();
         return true;
     }
 
     // steps 3-9
-    if (!desc->makeObject(cx))
+    if (!desc.makeObject(cx))
         return false;
-    rval.set(desc->pd());
+    rval.set(desc.pd());
     return true;
 }
 
 /*
  * Aux.3 NormalizePropertyDescriptor(Attributes)
  *
  * NOTE: to minimize code duplication, the code for this function is shared with
  * that for Aux.4 NormalizeAndCompletePropertyDescriptor (see below). The
@@ -1126,35 +1125,34 @@ FromGenericPropertyDescriptor(JSContext 
 static bool
 NormalizePropertyDescriptor(JSContext *cx, MutableHandleValue vp, bool complete = false)
 {
     // Aux.4 step 1
     if (complete && vp.isUndefined())
         return true;
 
     // Aux.3 steps 1-2 / Aux.4 steps 2-3
-    AutoPropDescArrayRooter descs(cx);
-    PropDesc *desc = descs.append();
-    if (!desc || !desc->initialize(cx, vp.get()))
+    Rooted<PropDesc> desc(cx);
+    if (!desc.initialize(cx, vp.get()))
         return false;
     if (complete)
-        desc->complete();
+        desc.complete();
     JS_ASSERT(vp.isObject()); // due to desc->initialize
     RootedObject attributes(cx, &vp.toObject());
 
     /*
      * Aux.3 step 3 / Aux.4 step 4
      *
      * NOTE: Aux.4 step 4 actually specifies FromPropertyDescriptor here.
      * However, the way FromPropertyDescriptor is implemented (PropDesc::
      * makeObject) is actually closer to FromGenericPropertyDescriptor,
      * and is in fact used to implement the latter, so we might as well call it
      * directly.
      */
-    if (!FromGenericPropertyDescriptor(cx, desc, vp))
+    if (!FromGenericPropertyDescriptor(cx, &desc, vp))
         return false;
     if (vp.isUndefined())
         return true;
     RootedObject descObj(cx, &vp.toObject());
 
     // Aux.3 steps 4-5 / Aux.4 steps 5-6
     AutoIdVector props(cx);
     if (!GetPropertyNames(cx, attributes, 0, &props))
@@ -1198,114 +1196,114 @@ IsDataDescriptor(const PropertyDescripto
 static inline bool
 IsAccessorDescriptor(const PropertyDescriptor &desc)
 {
     return desc.obj && desc.attrs & (JSPROP_GETTER | JSPROP_SETTER);
 }
 
 // Aux.5 ValidateProperty(O, P, Desc)
 static bool
-ValidateProperty(JSContext *cx, HandleObject obj, HandleId id, PropDesc *desc, bool *bp)
+ValidateProperty(JSContext *cx, HandleObject obj, HandleId id, Handle<PropDesc> desc, bool *bp)
 {
     // step 1
     Rooted<PropertyDescriptor> current(cx);
     if (!GetOwnPropertyDescriptor(cx, obj, id, &current))
         return false;
 
     /*
      * steps 2-4 are redundant since ValidateProperty is never called unless
      * target.[[HasOwn]](P) is true
      */
     JS_ASSERT(current.object());
 
     // step 5
-    if (!desc->hasValue() && !desc->hasWritable() && !desc->hasGet() && !desc->hasSet() &&
-        !desc->hasEnumerable() && !desc->hasConfigurable())
+    if (!desc.hasValue() && !desc.hasWritable() && !desc.hasGet() && !desc.hasSet() &&
+        !desc.hasEnumerable() && !desc.hasConfigurable())
     {
         *bp = true;
         return true;
     }
 
     // step 6
-    if ((!desc->hasWritable() || desc->writable() == !current.isReadonly()) &&
-        (!desc->hasGet() || desc->getter() == current.getter()) &&
-        (!desc->hasSet() || desc->setter() == current.setter()) &&
-        (!desc->hasEnumerable() || desc->enumerable() == current.isEnumerable()) &&
-        (!desc->hasConfigurable() || desc->configurable() == !current.isPermanent()))
+    if ((!desc.hasWritable() || desc.writable() == !current.isReadonly()) &&
+        (!desc.hasGet() || desc.getter() == current.getter()) &&
+        (!desc.hasSet() || desc.setter() == current.setter()) &&
+        (!desc.hasEnumerable() || desc.enumerable() == current.isEnumerable()) &&
+        (!desc.hasConfigurable() || desc.configurable() == !current.isPermanent()))
     {
-        if (!desc->hasValue()) {
+        if (!desc.hasValue()) {
             *bp = true;
             return true;
         }
         bool same = false;
-        if (!SameValue(cx, desc->value(), current.value(), &same))
+        if (!SameValue(cx, desc.value(), current.value(), &same))
             return false;
         if (same) {
             *bp = true;
             return true;
         }
     }
 
     // step 7
     if (current.isPermanent()) {
-        if (desc->hasConfigurable() && desc->configurable()) {
+        if (desc.hasConfigurable() && desc.configurable()) {
             *bp = false;
             return true;
         }
 
-        if (desc->hasEnumerable() &&
-            desc->enumerable() != current.isEnumerable())
+        if (desc.hasEnumerable() &&
+            desc.enumerable() != current.isEnumerable())
         {
             *bp = false;
             return true;
         }
     }
 
     // step 8
-    if (desc->isGenericDescriptor()) {
+    if (desc.isGenericDescriptor()) {
         *bp = true;
         return true;
     }
 
     // step 9
-    if (IsDataDescriptor(current) != desc->isDataDescriptor()) {
+    if (IsDataDescriptor(current) != desc.isDataDescriptor()) {
         *bp = !current.isPermanent();
         return true;
     }
 
     // step 10
     if (IsDataDescriptor(current)) {
-        JS_ASSERT(desc->isDataDescriptor()); // by step 9
+        JS_ASSERT(desc.isDataDescriptor()); // by step 9
         if (current.isPermanent() && current.isReadonly()) {
-            if (desc->hasWritable() && desc->writable()) {
+            if (desc.hasWritable() && desc.writable()) {
                 *bp = false;
                 return true;
             }
 
-            if (desc->hasValue()) {
+            if (desc.hasValue()) {
                 bool same;
-                if (!SameValue(cx, desc->value(), current.value(), &same))
+                if (!SameValue(cx, desc.value(), current.value(), &same))
                     return false;
                 if (!same) {
                     *bp = false;
                     return true;
                 }
             }
         }
 
         *bp = true;
         return true;
     }
 
     // steps 11-12
     JS_ASSERT(IsAccessorDescriptor(current)); // by step 10
-    JS_ASSERT(desc->isAccessorDescriptor()); // by step 9
+    JS_ASSERT(desc.isAccessorDescriptor()); // by step 9
     *bp = (!current.isPermanent() ||
-           ((!desc->hasSet() || desc->setter() == current.setter()) &&
-            (!desc->hasGet() || desc->getter() == current.getter())));
+           ((!desc.hasSet() || desc.setter() == current.setter()) &&
+            (!desc.hasGet() || desc.getter() == current.getter())));
     return true;
 }
 
 // Aux.6 IsSealed(O, P)
 static bool
 IsSealed(JSContext* cx, HandleObject obj, HandleId id, bool *bp)
 {
     // step 1
@@ -1424,35 +1422,34 @@ TrapGetOwnProperty(JSContext *cx, Handle
     bool extensible;
     if (!JSObject::isExtensible(cx, target, &extensible))
         return false;
     if (!extensible && !isFixed) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_REPORT_NEW);
         return false;
     }
 
-    AutoPropDescArrayRooter descs(cx);
-    PropDesc *desc = descs.append();
-    if (!desc || !desc->initialize(cx, trapResult))
+    Rooted<PropDesc> desc(cx);
+    if (!desc.initialize(cx, trapResult))
         return false;
 
     /* step 10 */
     if (isFixed) {
         bool valid;
         if (!ValidateProperty(cx, target, id, desc, &valid))
             return false;
 
         if (!valid) {
             JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_REPORT_INVALID);
             return false;
         }
     }
 
     // step 11
-    if (!desc->configurable() && !isFixed) {
+    if (!desc.configurable() && !isFixed) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_REPORT_NE_AS_NC);
         return false;
     }
 
     // step 12
     rval.set(trapResult);
     return true;
 }
@@ -1508,32 +1505,31 @@ TrapDefineOwnProperty(JSContext *cx, Han
         bool extensible;
         if (!JSObject::isExtensible(cx, target, &extensible))
             return false;
         if (!extensible && !isFixed) {
             JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_DEFINE_NEW);
             return false;
         }
 
-        AutoPropDescArrayRooter descs(cx);
-        PropDesc *desc = descs.append();
-        if (!desc || !desc->initialize(cx, normalizedDesc))
+        Rooted<PropDesc> desc(cx);
+        if (!desc.initialize(cx, normalizedDesc))
             return false;
 
         if (isFixed) {
             bool valid;
             if (!ValidateProperty(cx, target, id, desc, &valid))
                 return false;
             if (!valid) {
                 JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_DEFINE_INVALID);
                 return false;
             }
         }
 
-        if (!desc->configurable() && !isFixed) {
+        if (!desc.configurable() && !isFixed) {
             JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_DEFINE_NE_AS_NC);
             return false;
         }
 
         vp.set(BooleanValue(true));
         return true;
     }
 
@@ -1748,21 +1744,20 @@ ScriptedDirectProxyHandler::getOwnProper
     return ParsePropertyDescriptorObject(cx, proxy, v, desc, true);
 }
 
 bool
 ScriptedDirectProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
                                            MutableHandle<PropertyDescriptor> desc)
 {
     // step 1
-    AutoPropDescArrayRooter descs(cx);
-    PropDesc *d = descs.append();
-    d->initFromPropertyDescriptor(desc);
+    Rooted<PropDesc> d(cx);
+    d.initFromPropertyDescriptor(desc);
     RootedValue v(cx);
-    if (!FromGenericPropertyDescriptor(cx, d, &v))
+    if (!FromGenericPropertyDescriptor(cx, &d, &v))
         return false;
 
     // step 2
     return TrapDefineOwnProperty(cx, proxy, id, &v);
 }
 
 bool
 ScriptedDirectProxyHandler::getOwnPropertyNames(JSContext *cx, HandleObject proxy,
--- a/js/src/jspubtd.h
+++ b/js/src/jspubtd.h
@@ -274,16 +274,17 @@ enum ThingRootKind
     THING_ROOT_JIT_CODE,
     THING_ROOT_SCRIPT,
     THING_ROOT_LAZY_SCRIPT,
     THING_ROOT_ID,
     THING_ROOT_VALUE,
     THING_ROOT_TYPE,
     THING_ROOT_BINDINGS,
     THING_ROOT_PROPERTY_DESCRIPTOR,
+    THING_ROOT_PROP_DESC,
     THING_ROOT_CUSTOM,
     THING_ROOT_LIMIT
 };
 
 /*
  * This list enumerates the different types of conceptual stacks we have in
  * SpiderMonkey. In reality, they all share the C stack, but we allow different
  * stack limits depending on the type of code running.
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -5252,44 +5252,37 @@ DebuggerObject_defineProperty(JSContext 
 {
     THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "defineProperty", args, dbg, obj);
     REQUIRE_ARGC("Debugger.Object.defineProperty", 2);
 
     RootedId id(cx);
     if (!ValueToId<CanGC>(cx, args[0], &id))
         return false;
 
-    AutoPropDescArrayRooter descs(cx);
-    if (!descs.reserve(3)) // desc, unwrappedDesc, rewrappedDesc
-        return false;
-    PropDesc *desc = descs.append();
-    if (!desc || !desc->initialize(cx, args[1], false))
+    Rooted<PropDesc> desc(cx);
+    if (!desc.initialize(cx, args[1], false))
         return false;
-    desc->clearPd();
-
-    PropDesc *unwrappedDesc = descs.append();
-    if (!unwrappedDesc || !desc->unwrapDebuggerObjectsInto(cx, dbg, obj, unwrappedDesc))
+    desc.clearPd();
+
+    if (!desc.get().unwrapDebuggerObjectsInto(cx, dbg, obj, desc.address()))
         return false;
-    if (!unwrappedDesc->checkGetter(cx) || !unwrappedDesc->checkSetter(cx))
+    if (!desc.checkGetter(cx) || !desc.checkSetter(cx))
         return false;
 
     {
-        PropDesc *rewrappedDesc = descs.append();
-        if (!rewrappedDesc)
-            return false;
         RootedId wrappedId(cx);
 
         Maybe<AutoCompartment> ac;
         ac.construct(cx, obj);
-        if (!unwrappedDesc->wrapInto(cx, obj, id, wrappedId.address(), rewrappedDesc))
+        if (!desc.get().wrapInto(cx, obj, id, wrappedId.address(), desc.address()))
             return false;
 
         ErrorCopier ec(ac, dbg->toJSObject());
         bool dummy;
-        if (!DefineProperty(cx, obj, wrappedId, *rewrappedDesc, true, &dummy))
+        if (!DefineProperty(cx, obj, wrappedId, desc, true, &dummy))
             return false;
     }
 
     args.rval().setUndefined();
     return true;
 }
 
 static bool
--- a/js/src/vm/ObjectImpl.cpp
+++ b/js/src/vm/ObjectImpl.cpp
@@ -375,15 +375,15 @@ js::ObjectImpl::markChildren(JSTracer *t
 
     if (shape_->isNative()) {
         MarkObjectSlots(trc, obj, 0, obj->slotSpan());
         gc::MarkArraySlots(trc, obj->getDenseInitializedLength(), obj->getDenseElements(), "objectElements");
     }
 }
 
 void
-AutoPropDescRooter::trace(JSTracer *trc)
+PropDesc::trace(JSTracer *trc)
 {
-    gc::MarkValueRoot(trc, &propDesc.pd_, "AutoPropDescRooter pd");
-    gc::MarkValueRoot(trc, &propDesc.value_, "AutoPropDescRooter value");
-    gc::MarkValueRoot(trc, &propDesc.get_, "AutoPropDescRooter get");
-    gc::MarkValueRoot(trc, &propDesc.set_, "AutoPropDescRooter set");
+    gc::MarkValueRoot(trc, &pd_, "PropDesc pd");
+    gc::MarkValueRoot(trc, &value_, "PropDesc value");
+    gc::MarkValueRoot(trc, &get_, "PropDesc get");
+    gc::MarkValueRoot(trc, &set_, "PropDesc set");
 }
new file mode 100644
--- /dev/null
+++ b/js/src/vm/PropDesc.h
@@ -0,0 +1,366 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * 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_PropDesc_h
+#define vm_PropDesc_h
+
+#include "jsapi.h"
+#include "NamespaceImports.h"
+
+namespace js {
+
+class Debugger;
+
+static inline JSPropertyOp
+CastAsPropertyOp(JSObject *object)
+{
+    return JS_DATA_TO_FUNC_PTR(JSPropertyOp, object);
+}
+
+static inline JSStrictPropertyOp
+CastAsStrictPropertyOp(JSObject *object)
+{
+    return JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, object);
+}
+
+/*
+ * A representation of ECMA-262 ed. 5's internal Property Descriptor data
+ * structure.
+ */
+struct PropDesc {
+  private:
+    /*
+     * Original object from which this descriptor derives, passed through for
+     * the benefit of proxies.
+     */
+    Value pd_;
+
+    Value value_, get_, set_;
+
+    /* Property descriptor boolean fields. */
+    uint8_t attrs;
+
+    /* Bits indicating which values are set. */
+    bool hasGet_ : 1;
+    bool hasSet_ : 1;
+    bool hasValue_ : 1;
+    bool hasWritable_ : 1;
+    bool hasEnumerable_ : 1;
+    bool hasConfigurable_ : 1;
+
+    /* Or maybe this represents a property's absence, and it's undefined. */
+    bool isUndefined_ : 1;
+
+    explicit PropDesc(const Value &v)
+      : pd_(UndefinedValue()),
+        value_(v),
+        get_(UndefinedValue()), set_(UndefinedValue()),
+        attrs(0),
+        hasGet_(false), hasSet_(false),
+        hasValue_(true), hasWritable_(false), hasEnumerable_(false), hasConfigurable_(false),
+        isUndefined_(false)
+    {
+    }
+
+  public:
+    friend void JS::AutoGCRooter::trace(JSTracer *trc);
+    friend struct GCMethods<PropDesc>;
+
+    void trace(JSTracer *trc);
+
+    enum Enumerability { Enumerable = true, NonEnumerable = false };
+    enum Configurability { Configurable = true, NonConfigurable = false };
+    enum Writability { Writable = true, NonWritable = false };
+
+    PropDesc();
+
+    static PropDesc undefined() { return PropDesc(); }
+    static PropDesc valueOnly(const Value &v) { return PropDesc(v); }
+
+    PropDesc(const Value &v, Writability writable,
+             Enumerability enumerable, Configurability configurable)
+      : pd_(UndefinedValue()),
+        value_(v),
+        get_(UndefinedValue()), set_(UndefinedValue()),
+        attrs((writable ? 0 : JSPROP_READONLY) |
+              (enumerable ? JSPROP_ENUMERATE : 0) |
+              (configurable ? 0 : JSPROP_PERMANENT)),
+        hasGet_(false), hasSet_(false),
+        hasValue_(true), hasWritable_(true), hasEnumerable_(true), hasConfigurable_(true),
+        isUndefined_(false)
+    {}
+
+    inline PropDesc(const Value &getter, const Value &setter,
+                    Enumerability enumerable, Configurability configurable);
+
+    /*
+     * 8.10.5 ToPropertyDescriptor(Obj)
+     *
+     * If checkAccessors is false, skip steps 7.b and 8.b, which throw a
+     * TypeError if .get or .set is neither a callable object nor undefined.
+     *
+     * (DebuggerObject_defineProperty uses this: the .get and .set properties
+     * are expected to be Debugger.Object wrappers of functions, which are not
+     * themselves callable.)
+     */
+    bool initialize(JSContext *cx, const Value &v, bool checkAccessors = true);
+
+    /*
+     * If IsGenericDescriptor(desc) or IsDataDescriptor(desc) is true, then if
+     * the value of an attribute field of desc, considered as a data
+     * descriptor, is absent, set it to its default value. Else if the value of
+     * an attribute field of desc, considered as an attribute descriptor, is
+     * absent, set it to its default value.
+     */
+    void complete();
+
+    /*
+     * 8.10.4 FromPropertyDescriptor(Desc)
+     *
+     * initFromPropertyDescriptor sets pd to undefined and populates all the
+     * other fields of this PropDesc from desc.
+     *
+     * makeObject populates pd based on the other fields of *this, creating a
+     * new property descriptor JSObject and defining properties on it.
+     */
+    void initFromPropertyDescriptor(Handle<JSPropertyDescriptor> desc);
+    bool makeObject(JSContext *cx);
+
+    void setUndefined() { isUndefined_ = true; }
+
+    bool isUndefined() const { return isUndefined_; }
+
+    bool hasGet() const { MOZ_ASSERT(!isUndefined()); return hasGet_; }
+    bool hasSet() const { MOZ_ASSERT(!isUndefined()); return hasSet_; }
+    bool hasValue() const { MOZ_ASSERT(!isUndefined()); return hasValue_; }
+    bool hasWritable() const { MOZ_ASSERT(!isUndefined()); return hasWritable_; }
+    bool hasEnumerable() const { MOZ_ASSERT(!isUndefined()); return hasEnumerable_; }
+    bool hasConfigurable() const { MOZ_ASSERT(!isUndefined()); return hasConfigurable_; }
+
+    Value pd() const { MOZ_ASSERT(!isUndefined()); return pd_; }
+    void clearPd() { pd_ = UndefinedValue(); }
+
+    uint8_t attributes() const { MOZ_ASSERT(!isUndefined()); return attrs; }
+
+    /* 8.10.1 IsAccessorDescriptor(desc) */
+    bool isAccessorDescriptor() const {
+        return !isUndefined() && (hasGet() || hasSet());
+    }
+
+    /* 8.10.2 IsDataDescriptor(desc) */
+    bool isDataDescriptor() const {
+        return !isUndefined() && (hasValue() || hasWritable());
+    }
+
+    /* 8.10.3 IsGenericDescriptor(desc) */
+    bool isGenericDescriptor() const {
+        return !isUndefined() && !isAccessorDescriptor() && !isDataDescriptor();
+    }
+
+    bool configurable() const {
+        MOZ_ASSERT(!isUndefined());
+        MOZ_ASSERT(hasConfigurable());
+        return (attrs & JSPROP_PERMANENT) == 0;
+    }
+
+    bool enumerable() const {
+        MOZ_ASSERT(!isUndefined());
+        MOZ_ASSERT(hasEnumerable());
+        return (attrs & JSPROP_ENUMERATE) != 0;
+    }
+
+    bool writable() const {
+        MOZ_ASSERT(!isUndefined());
+        MOZ_ASSERT(hasWritable());
+        return (attrs & JSPROP_READONLY) == 0;
+    }
+
+    HandleValue value() const {
+        MOZ_ASSERT(hasValue());
+        return HandleValue::fromMarkedLocation(&value_);
+    }
+
+    JSObject * getterObject() const {
+        MOZ_ASSERT(!isUndefined());
+        MOZ_ASSERT(hasGet());
+        return get_.isUndefined() ? nullptr : &get_.toObject();
+    }
+    JSObject * setterObject() const {
+        MOZ_ASSERT(!isUndefined());
+        MOZ_ASSERT(hasSet());
+        return set_.isUndefined() ? nullptr : &set_.toObject();
+    }
+
+    HandleValue getterValue() const {
+        MOZ_ASSERT(!isUndefined());
+        MOZ_ASSERT(hasGet());
+        return HandleValue::fromMarkedLocation(&get_);
+    }
+    HandleValue setterValue() const {
+        MOZ_ASSERT(!isUndefined());
+        MOZ_ASSERT(hasSet());
+        return HandleValue::fromMarkedLocation(&set_);
+    }
+
+    /*
+     * Unfortunately the values produced by these methods are used such that
+     * we can't assert anything here.  :-(
+     */
+    JSPropertyOp getter() const {
+        return CastAsPropertyOp(get_.isUndefined() ? nullptr : &get_.toObject());
+    }
+    JSStrictPropertyOp setter() const {
+        return CastAsStrictPropertyOp(set_.isUndefined() ? nullptr : &set_.toObject());
+    }
+
+    /*
+     * Throw a TypeError if a getter/setter is present and is neither callable
+     * nor undefined. These methods do exactly the type checks that are skipped
+     * by passing false as the checkAccessors parameter of initialize.
+     */
+    bool checkGetter(JSContext *cx);
+    bool checkSetter(JSContext *cx);
+
+    bool unwrapDebuggerObjectsInto(JSContext *cx, Debugger *dbg, HandleObject obj,
+                                   PropDesc *unwrapped) const;
+
+    bool wrapInto(JSContext *cx, HandleObject obj, const jsid &id, jsid *wrappedId,
+                  PropDesc *wrappedDesc) const;
+};
+
+} /* namespace js */
+
+namespace JS {
+
+template <typename Outer>
+class PropDescOperations
+{
+    const js::PropDesc * desc() const { return static_cast<const Outer*>(this)->extract(); }
+
+  public:
+    bool isUndefined() const { return desc()->isUndefined(); }
+
+    bool hasGet() const { return desc()->hasGet(); }
+    bool hasSet() const { return desc()->hasSet(); }
+    bool hasValue() const { return desc()->hasValue(); }
+    bool hasWritable() const { return desc()->hasWritable(); }
+    bool hasEnumerable() const { return desc()->hasEnumerable(); }
+    bool hasConfigurable() const { return desc()->hasConfigurable(); }
+
+    Value pd() const { return desc()->pd(); }
+
+    uint8_t attributes() const { return desc()->attributes(); }
+
+    bool isAccessorDescriptor() const { return desc()->isAccessorDescriptor(); }
+    bool isDataDescriptor() const { return desc()->isDataDescriptor(); }
+    bool isGenericDescriptor() const { return desc()->isGenericDescriptor(); }
+    bool configurable() const { return desc()->configurable(); }
+    bool enumerable() const { return desc()->enumerable(); }
+    bool writable() const { return desc()->writable(); }
+
+    HandleValue value() const { return desc()->value(); }
+    JSObject *getterObject() const { return desc()->getterObject(); }
+    JSObject *setterObject() const { return desc()->setterObject(); }
+    HandleValue getterValue() const { return desc()->getterValue(); }
+    HandleValue setterValue() const { return desc()->setterValue(); }
+
+    JSPropertyOp getter() const { return desc()->getter(); }
+    JSStrictPropertyOp setter() const { return desc()->setter(); }
+
+    // We choose not to expose the debugger-specific parts of PropDesc, both
+    // because they are not really general use, but also because they are a
+    // pain to expose.
+};
+
+template <typename Outer>
+class MutablePropDescOperations : public PropDescOperations<Outer>
+{
+    js::PropDesc * desc() { return static_cast<Outer*>(this)->extractMutable(); }
+
+  public:
+
+    bool initialize(JSContext *cx, const Value &v, bool checkAccessors = true) {
+        return desc()->initialize(cx, v, checkAccessors);
+    }
+    void complete() {
+        desc()->complete();
+    }
+
+    bool checkGetter(JSContext *cx) { return desc()->checkGetter(cx); }
+    bool checkSetter(JSContext *cx) { return desc()->checkSetter(cx); }
+
+    void initFromPropertyDescriptor(Handle<JSPropertyDescriptor> descriptor) {
+        desc()->initFromPropertyDescriptor(descriptor);
+    }
+    bool makeObject(JSContext *cx) {
+        return desc()->makeObject(cx);
+    }
+
+    void setUndefined() { desc()->setUndefined(); }
+    void clearPd() { desc()->clearPd(); }
+};
+
+} /* namespace JS */
+
+namespace js {
+
+template <>
+struct GCMethods<PropDesc> {
+    static PropDesc initial() { return PropDesc(); }
+    static ThingRootKind kind() { return THING_ROOT_PROP_DESC; }
+    static bool poisoned(const PropDesc &desc) {
+        return (desc.pd_.isGCThing() &&
+                JS::IsPoisonedPtr(desc.pd_.toGCThing())) ||
+               (desc.value_.isGCThing() &&
+                JS::IsPoisonedPtr(desc.value_.toGCThing())) ||
+               (desc.get_.isGCThing() &&
+                JS::IsPoisonedPtr(desc.get_.toGCThing())) ||
+               (desc.set_.isGCThing() &&
+                JS::IsPoisonedPtr(desc.set_.toGCThing()));
+    }
+};
+
+template <>
+class RootedBase<PropDesc>
+  : public JS::MutablePropDescOperations<JS::Rooted<PropDesc> >
+{
+    friend class JS::PropDescOperations<JS::Rooted<PropDesc> >;
+    friend class JS::MutablePropDescOperations<JS::Rooted<PropDesc> >;
+    const PropDesc *extract() const {
+        return static_cast<const JS::Rooted<PropDesc>*>(this)->address();
+    }
+    PropDesc *extractMutable() {
+        return static_cast<JS::Rooted<PropDesc>*>(this)->address();
+    }
+};
+
+template <>
+class HandleBase<PropDesc>
+  : public JS::PropDescOperations<JS::Handle<PropDesc> >
+{
+    friend class JS::PropDescOperations<JS::Handle<PropDesc> >;
+    const PropDesc *extract() const {
+        return static_cast<const JS::Handle<PropDesc>*>(this)->address();
+    }
+};
+
+template <>
+class MutableHandleBase<PropDesc>
+  : public JS::MutablePropDescOperations<JS::MutableHandle<PropDesc> >
+{
+    friend class JS::PropDescOperations<JS::MutableHandle<PropDesc> >;
+    friend class JS::MutablePropDescOperations<JS::MutableHandle<PropDesc> >;
+    const PropDesc *extract() const {
+        return static_cast<const JS::MutableHandle<PropDesc>*>(this)->address();
+    }
+    PropDesc *extractMutable() {
+        return static_cast<JS::MutableHandle<PropDesc>*>(this)->address();
+    }
+};
+
+} /* namespace js */
+
+#endif /* vm_PropDesc_h */
--- a/js/src/vm/Shape.h
+++ b/js/src/vm/Shape.h
@@ -22,16 +22,17 @@
 #include "NamespaceImports.h"
 
 #include "gc/Barrier.h"
 #include "gc/Heap.h"
 #include "gc/Marking.h"
 #include "gc/Rooting.h"
 #include "js/HashTable.h"
 #include "js/RootingAPI.h"
+#include "vm/PropDesc.h"
 
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable:4800)
 #pragma warning(push)
 #pragma warning(disable:4100) /* Silence unreferenced formal parameter warnings */
 #endif
 
@@ -113,289 +114,16 @@ class StaticBlockObject;
 typedef JSPropertyOp         PropertyOp;
 typedef JSStrictPropertyOp   StrictPropertyOp;
 typedef JSPropertyDescriptor PropertyDescriptor;
 
 /* Limit on the number of slotful properties in an object. */
 static const uint32_t SHAPE_INVALID_SLOT = JS_BIT(24) - 1;
 static const uint32_t SHAPE_MAXIMUM_SLOT = JS_BIT(24) - 2;
 
-static inline PropertyOp
-CastAsPropertyOp(JSObject *object)
-{
-    return JS_DATA_TO_FUNC_PTR(PropertyOp, object);
-}
-
-static inline StrictPropertyOp
-CastAsStrictPropertyOp(JSObject *object)
-{
-    return JS_DATA_TO_FUNC_PTR(StrictPropertyOp, object);
-}
-
-/*
- * A representation of ECMA-262 ed. 5's internal Property Descriptor data
- * structure.
- */
-struct PropDesc {
-  private:
-    /*
-     * Original object from which this descriptor derives, passed through for
-     * the benefit of proxies.  FIXME: Remove this when direct proxies happen.
-     */
-    Value pd_;
-
-    Value value_, get_, set_;
-
-    /* Property descriptor boolean fields. */
-    uint8_t attrs;
-
-    /* Bits indicating which values are set. */
-    bool hasGet_ : 1;
-    bool hasSet_ : 1;
-    bool hasValue_ : 1;
-    bool hasWritable_ : 1;
-    bool hasEnumerable_ : 1;
-    bool hasConfigurable_ : 1;
-
-    /* Or maybe this represents a property's absence, and it's undefined. */
-    bool isUndefined_ : 1;
-
-    explicit PropDesc(const Value &v)
-      : pd_(UndefinedValue()),
-        value_(v),
-        get_(UndefinedValue()), set_(UndefinedValue()),
-        attrs(0),
-        hasGet_(false), hasSet_(false),
-        hasValue_(true), hasWritable_(false), hasEnumerable_(false), hasConfigurable_(false),
-        isUndefined_(false)
-    {
-    }
-
-  public:
-    friend class AutoPropDescRooter;
-    friend void JS::AutoGCRooter::trace(JSTracer *trc);
-
-    enum Enumerability { Enumerable = true, NonEnumerable = false };
-    enum Configurability { Configurable = true, NonConfigurable = false };
-    enum Writability { Writable = true, NonWritable = false };
-
-    PropDesc();
-
-    static PropDesc undefined() { return PropDesc(); }
-    static PropDesc valueOnly(const Value &v) { return PropDesc(v); }
-
-    PropDesc(const Value &v, Writability writable,
-             Enumerability enumerable, Configurability configurable)
-      : pd_(UndefinedValue()),
-        value_(v),
-        get_(UndefinedValue()), set_(UndefinedValue()),
-        attrs((writable ? 0 : JSPROP_READONLY) |
-              (enumerable ? JSPROP_ENUMERATE : 0) |
-              (configurable ? 0 : JSPROP_PERMANENT)),
-        hasGet_(false), hasSet_(false),
-        hasValue_(true), hasWritable_(true), hasEnumerable_(true), hasConfigurable_(true),
-        isUndefined_(false)
-    {}
-
-    inline PropDesc(const Value &getter, const Value &setter,
-                    Enumerability enumerable, Configurability configurable);
-
-    /*
-     * 8.10.5 ToPropertyDescriptor(Obj)
-     *
-     * If checkAccessors is false, skip steps 7.b and 8.b, which throw a
-     * TypeError if .get or .set is neither a callable object nor undefined.
-     *
-     * (DebuggerObject_defineProperty uses this: the .get and .set properties
-     * are expected to be Debugger.Object wrappers of functions, which are not
-     * themselves callable.)
-     */
-    bool initialize(JSContext *cx, const Value &v, bool checkAccessors = true);
-
-    /*
-     * If IsGenericDescriptor(desc) or IsDataDescriptor(desc) is true, then if
-     * the value of an attribute field of desc, considered as a data
-     * descriptor, is absent, set it to its default value. Else if the value of
-     * an attribute field of desc, considered as an attribute descriptor, is
-     * absent, set it to its default value.
-     */
-    void complete();
-
-    /*
-     * 8.10.4 FromPropertyDescriptor(Desc)
-     *
-     * initFromPropertyDescriptor sets pd to undefined and populates all the
-     * other fields of this PropDesc from desc.
-     *
-     * makeObject populates pd based on the other fields of *this, creating a
-     * new property descriptor JSObject and defining properties on it.
-     */
-    void initFromPropertyDescriptor(Handle<PropertyDescriptor> desc);
-    bool makeObject(JSContext *cx);
-
-    void setUndefined() { isUndefined_ = true; }
-
-    bool isUndefined() const { return isUndefined_; }
-
-    bool hasGet() const { MOZ_ASSERT(!isUndefined()); return hasGet_; }
-    bool hasSet() const { MOZ_ASSERT(!isUndefined()); return hasSet_; }
-    bool hasValue() const { MOZ_ASSERT(!isUndefined()); return hasValue_; }
-    bool hasWritable() const { MOZ_ASSERT(!isUndefined()); return hasWritable_; }
-    bool hasEnumerable() const { MOZ_ASSERT(!isUndefined()); return hasEnumerable_; }
-    bool hasConfigurable() const { MOZ_ASSERT(!isUndefined()); return hasConfigurable_; }
-
-    Value pd() const { MOZ_ASSERT(!isUndefined()); return pd_; }
-    void clearPd() { pd_ = UndefinedValue(); }
-
-    uint8_t attributes() const { MOZ_ASSERT(!isUndefined()); return attrs; }
-
-    /* 8.10.1 IsAccessorDescriptor(desc) */
-    bool isAccessorDescriptor() const {
-        return !isUndefined() && (hasGet() || hasSet());
-    }
-
-    /* 8.10.2 IsDataDescriptor(desc) */
-    bool isDataDescriptor() const {
-        return !isUndefined() && (hasValue() || hasWritable());
-    }
-
-    /* 8.10.3 IsGenericDescriptor(desc) */
-    bool isGenericDescriptor() const {
-        return !isUndefined() && !isAccessorDescriptor() && !isDataDescriptor();
-    }
-
-    bool configurable() const {
-        MOZ_ASSERT(!isUndefined());
-        MOZ_ASSERT(hasConfigurable());
-        return (attrs & JSPROP_PERMANENT) == 0;
-    }
-
-    bool enumerable() const {
-        MOZ_ASSERT(!isUndefined());
-        MOZ_ASSERT(hasEnumerable());
-        return (attrs & JSPROP_ENUMERATE) != 0;
-    }
-
-    bool writable() const {
-        MOZ_ASSERT(!isUndefined());
-        MOZ_ASSERT(hasWritable());
-        return (attrs & JSPROP_READONLY) == 0;
-    }
-
-    HandleValue value() const {
-        MOZ_ASSERT(hasValue());
-        return HandleValue::fromMarkedLocation(&value_);
-    }
-
-    JSObject * getterObject() const {
-        MOZ_ASSERT(!isUndefined());
-        MOZ_ASSERT(hasGet());
-        return get_.isUndefined() ? nullptr : &get_.toObject();
-    }
-    JSObject * setterObject() const {
-        MOZ_ASSERT(!isUndefined());
-        MOZ_ASSERT(hasSet());
-        return set_.isUndefined() ? nullptr : &set_.toObject();
-    }
-
-    HandleValue getterValue() const {
-        MOZ_ASSERT(!isUndefined());
-        MOZ_ASSERT(hasGet());
-        return HandleValue::fromMarkedLocation(&get_);
-    }
-    HandleValue setterValue() const {
-        MOZ_ASSERT(!isUndefined());
-        MOZ_ASSERT(hasSet());
-        return HandleValue::fromMarkedLocation(&set_);
-    }
-
-    /*
-     * Unfortunately the values produced by these methods are used such that
-     * we can't assert anything here.  :-(
-     */
-    PropertyOp getter() const {
-        return CastAsPropertyOp(get_.isUndefined() ? nullptr : &get_.toObject());
-    }
-    StrictPropertyOp setter() const {
-        return CastAsStrictPropertyOp(set_.isUndefined() ? nullptr : &set_.toObject());
-    }
-
-    /*
-     * Throw a TypeError if a getter/setter is present and is neither callable
-     * nor undefined. These methods do exactly the type checks that are skipped
-     * by passing false as the checkAccessors parameter of initialize.
-     */
-    bool checkGetter(JSContext *cx);
-    bool checkSetter(JSContext *cx);
-
-    bool unwrapDebuggerObjectsInto(JSContext *cx, Debugger *dbg, HandleObject obj,
-                                   PropDesc *unwrapped) const;
-
-    bool wrapInto(JSContext *cx, HandleObject obj, const jsid &id, jsid *wrappedId,
-                  PropDesc *wrappedDesc) const;
-};
-
-class AutoPropDescRooter : private JS::CustomAutoRooter
-{
-  public:
-    explicit AutoPropDescRooter(JSContext *cx
-                                MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-      : CustomAutoRooter(cx)
-    {
-        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-    }
-
-    PropDesc& getPropDesc() { return propDesc; }
-
-    void initFromPropertyDescriptor(Handle<PropertyDescriptor> desc) {
-        propDesc.initFromPropertyDescriptor(desc);
-    }
-
-    bool makeObject(JSContext *cx) {
-        return propDesc.makeObject(cx);
-    }
-
-    void setUndefined() { propDesc.setUndefined(); }
-    bool isUndefined() const { return propDesc.isUndefined(); }
-
-    bool hasGet() const { return propDesc.hasGet(); }
-    bool hasSet() const { return propDesc.hasSet(); }
-    bool hasValue() const { return propDesc.hasValue(); }
-    bool hasWritable() const { return propDesc.hasWritable(); }
-    bool hasEnumerable() const { return propDesc.hasEnumerable(); }
-    bool hasConfigurable() const { return propDesc.hasConfigurable(); }
-
-    Value pd() const { return propDesc.pd(); }
-    void clearPd() { propDesc.clearPd(); }
-
-    uint8_t attributes() const { return propDesc.attributes(); }
-
-    bool isAccessorDescriptor() const { return propDesc.isAccessorDescriptor(); }
-    bool isDataDescriptor() const { return propDesc.isDataDescriptor(); }
-    bool isGenericDescriptor() const { return propDesc.isGenericDescriptor(); }
-    bool configurable() const { return propDesc.configurable(); }
-    bool enumerable() const { return propDesc.enumerable(); }
-    bool writable() const { return propDesc.writable(); }
-
-    HandleValue value() const { return propDesc.value(); }
-    JSObject *getterObject() const { return propDesc.getterObject(); }
-    JSObject *setterObject() const { return propDesc.setterObject(); }
-    HandleValue getterValue() const { return propDesc.getterValue(); }
-    HandleValue setterValue() const { return propDesc.setterValue(); }
-
-    PropertyOp getter() const { return propDesc.getter(); }
-    StrictPropertyOp setter() const { return propDesc.setter(); }
-
-  private:
-    virtual void trace(JSTracer *trc);
-
-    PropDesc propDesc;
-    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
-};
-
 /*
  * Shapes use multiplicative hashing, but specialized to
  * minimize footprint.
  */
 struct ShapeTable {
     static const uint32_t HASH_BITS     = mozilla::tl::BitSize<HashNumber>::value;
     static const uint32_t MIN_ENTRIES   = 7;
     static const uint32_t MIN_SIZE_LOG2 = 4;
--- a/js/xpconnect/src/event_impl_gen.conf.in
+++ b/js/xpconnect/src/event_impl_gen.conf.in
@@ -3,17 +3,16 @@
  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/.
 
  The name of the event which real interface should have nsIDOM-prefix,
  and should be in nsIDOM<name>.idl file and which should have
  <name>Init dictionary for the event constructor. """
 
 simple_events = [
-    'ProgressEvent',
     'MozSettingsEvent',
     'CustomEvent',
     'PageTransitionEvent',
     'DOMTransactionEvent',
     'PopStateEvent',
     'HashChangeEvent',
     'CloseEvent',
     'DeviceOrientationEvent',
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -6657,16 +6657,21 @@ nsLayoutUtils::DoLogTestDataForPaint(nsI
 {
   nsRefPtr<LayerManager> lm = aPresShell->GetPresContext()->GetRootPresContext()
       ->GetPresShell()->GetLayerManager();
   if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
     static_cast<ClientLayerManager*>(lm.get())->LogTestDataForCurrentPaint(aScrollId, aKey, aValue);
   }
 }
 
+/* static */ bool
+nsLayoutUtils::IsAPZTestLoggingEnabled()
+{
+  return gfxPrefs::APZTestLoggingEnabled();
+}
 
 nsLayoutUtils::SurfaceFromElementResult::SurfaceFromElementResult()
   // Use safe default values here
   : mIsWriteOnly(true)
   , mIsStillLoading(false)
   , mCORSUsed(false)
   , mIsPremultiplied(true)
 {
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -22,17 +22,16 @@
 #include "nsStyleCoord.h"
 #include "nsStyleConsts.h"
 #include "nsGkAtoms.h"
 #include "nsRuleNode.h"
 #include "imgIContainer.h"
 #include "mozilla/gfx/2D.h"
 #include "Units.h"
 #include "mozilla/ToString.h"
-#include "gfxPrefs.h"
 
 #include <limits>
 #include <algorithm>
 
 class nsIFormControlFrame;
 class nsPresContext;
 class nsIContent;
 class nsIAtom;
@@ -2197,32 +2196,32 @@ public:
    * @param aScrollId Identifies the scroll frame to which the data pertains.
    * @param aKey The key under which to log the data.
    * @param aValue The value of the data to be logged.
    */
   static void LogTestDataForPaint(nsIPresShell* aPresShell,
                                   ViewID aScrollId,
                                   const std::string& aKey,
                                   const std::string& aValue) {
-    if (gfxPrefs::APZTestLoggingEnabled()) {
+    if (IsAPZTestLoggingEnabled()) {
       DoLogTestDataForPaint(aPresShell, aScrollId, aKey, aValue);
     }
   }
 
   /**
    * A convenience overload of LogTestDataForPaint() that accepts any type
    * as the value, and passes it through mozilla::ToString() to obtain a string
    * value. The type passed must support streaming to an std::ostream.
    */
   template <typename Value>
   static void LogTestDataForPaint(nsIPresShell* aPresShell,
                                   ViewID aScrollId,
                                   const std::string& aKey,
                                   const Value& aValue) {
-    if (gfxPrefs::APZTestLoggingEnabled()) {
+    if (IsAPZTestLoggingEnabled()) {
       DoLogTestDataForPaint(aPresShell, aScrollId, aKey,
           mozilla::ToString(aValue));
     }
   }
 
  /**
    * Get the display port for |aScrollFrame|'s content. If |aScrollFrame|
    * WantsAsyncScroll() and we don't have a scrollable displayport yet (as
@@ -2257,16 +2256,18 @@ private:
 
   /**
    * Helper function for LogTestDataForPaint().
    */
   static void DoLogTestDataForPaint(nsIPresShell* aPresShell,
                                     ViewID aScrollId,
                                     const std::string& aKey,
                                     const std::string& aValue);
+
+  static bool IsAPZTestLoggingEnabled();
 };
 
 MOZ_FINISH_NESTED_ENUM_CLASS(nsLayoutUtils::RepaintMode)
 
 template<typename PointType, typename RectType, typename CoordType>
 /* static */ bool
 nsLayoutUtils::PointIsCloserToRect(PointType aPoint, const RectType& aRect,
                                    CoordType& aClosestXDistance,
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -13,16 +13,17 @@
 #include "nsRenderingContext.h"
 #include "nsGkAtoms.h"
 #include "nsPresShell.h"
 #include "nsIPresShell.h"
 #include "nsDisplayList.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsFrameManager.h"
 #include "gfxPlatform.h"
+#include "nsPrintfCString.h"
 // for touchcaret
 #include "nsContentList.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentUtils.h"
 #include "nsStyleSet.h"
 // for focus
 #include "nsIScrollableFrame.h"
 #ifdef DEBUG_CANVAS_FOCUS
@@ -203,16 +204,26 @@ nsDisplayCanvasBackgroundColor::Paint(ns
   nsPoint offset = ToReferenceFrame();
   nsRect bgClipRect = frame->CanvasArea() + offset;
   if (NS_GET_A(mColor) > 0) {
     aCtx->SetColor(mColor);
     aCtx->FillRect(bgClipRect);
   }
 }
 
+#ifdef MOZ_DUMP_PAINTING
+void
+nsDisplayCanvasBackgroundColor::WriteDebugInfo(nsACString& aTo)
+{
+  aTo += nsPrintfCString(" (rgba %d,%d,%d,%d)",
+          NS_GET_R(mColor), NS_GET_G(mColor),
+          NS_GET_B(mColor), NS_GET_A(mColor));
+}
+#endif
+
 static void BlitSurface(gfxContext* aDest, const gfxRect& aRect, gfxASurface* aSource)
 {
   aDest->Translate(gfxPoint(aRect.x, aRect.y));
   aDest->SetSource(aSource);
   aDest->NewPath();
   aDest->Rectangle(gfxRect(0, 0, aRect.width, aRect.height));
   aDest->Fill();
   aDest->Translate(-gfxPoint(aRect.x, aRect.y));
--- a/layout/generic/nsCanvasFrame.h
+++ b/layout/generic/nsCanvasFrame.h
@@ -190,16 +190,19 @@ public:
                      nsRenderingContext* aCtx) MOZ_OVERRIDE;
 
   void SetExtraBackgroundColor(nscolor aColor)
   {
     mColor = aColor;
   }
 
   NS_DISPLAY_DECL_NAME("CanvasBackgroundColor", TYPE_CANVAS_BACKGROUND_COLOR)
+#ifdef MOZ_DUMP_PAINTING
+  virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
+#endif
 
 private:
   nscolor mColor;
 };
 
 class nsDisplayCanvasBackgroundImage : public nsDisplayBackgroundImage {
 public:
   nsDisplayCanvasBackgroundImage(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -1471,18 +1471,18 @@ nsLineLayout::BlockDirAlignLine()
                       psd->mICoord - psd->mIStart, lineBSize,
                       mContainerWidth);
 
   mFinalLineBSize = lineBSize;
   mLineBox->SetAscent(baselineBCoord - mBStartEdge);
 #ifdef NOISY_BLOCKDIR_ALIGN
   printf(
     "  [line]==> bounds{x,y,w,h}={%d,%d,%d,%d} lh=%d a=%d\n",
-    mLineBox->mBounds.IStart(lineWM), mLineBox->mBounds.BStart(lineWM),
-    mLineBox->mBounds.ISize(lineWM), mLineBox->mBounds.BSize(lineWM),
+    mLineBox->GetBounds().IStart(lineWM), mLineBox->GetBounds().BStart(lineWM),
+    mLineBox->GetBounds().ISize(lineWM), mLineBox->GetBounds().BSize(lineWM),
     mFinalLineBSize, mLineBox->GetAscent());
 #endif
 
   // Undo root-span mFrame pointer to prevent brane damage later on...
   mRootSpan->mFrame = nullptr;
 }
 
 void
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -42,17 +42,17 @@
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsICSSLoaderObserver.h"
 #include "nsCSSParser.h"
 #include "mozilla/css/ImportRule.h"
 #include "nsThreadUtils.h"
 #include "nsGkAtoms.h"
 #include "nsIThreadInternal.h"
 #include "nsCrossSiteListenerProxy.h"
-#include "nsINetworkSeer.h"
+#include "nsINetworkPredictor.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/dom/URL.h"
 
 #ifdef MOZ_XUL
 #include "nsXULPrototypeCache.h"
 #endif
 
 #include "nsIMediaList.h"
@@ -1418,19 +1418,19 @@ Loader::LoadSheet(SheetLoadData* aLoadDa
     rv = NS_NewUnicharStreamLoader(getter_AddRefs(streamLoader), aLoadData);
     if (NS_FAILED(rv)) {
       LOG_ERROR(("  Failed to create stream loader for sync load"));
       SheetComplete(aLoadData, rv);
       return rv;
     }
 
     if (mDocument) {
-      mozilla::net::SeerLearn(aLoadData->mURI, mDocument->GetDocumentURI(),
-                              nsINetworkSeer::LEARN_LOAD_SUBRESOURCE,
-                              mDocument);
+      mozilla::net::PredictorLearn(aLoadData->mURI, mDocument->GetDocumentURI(),
+                                   nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE,
+                                   mDocument);
     }
 
     // Just load it
     nsCOMPtr<nsIInputStream> stream;
     nsCOMPtr<nsIChannel> channel;
     rv = NS_OpenURI(getter_AddRefs(stream), aLoadData->mURI, nullptr,
                     nullptr, nullptr, nsIRequest::LOAD_NORMAL,
                     getter_AddRefs(channel));
@@ -1607,18 +1607,19 @@ Loader::LoadSheet(SheetLoadData* aLoadDa
       return rv;
     }
     channelListener = corsListener;
   } else {
     channelListener = streamLoader;
   }
 
   if (mDocument) {
-    mozilla::net::SeerLearn(aLoadData->mURI, mDocument->GetDocumentURI(),
-                            nsINetworkSeer::LEARN_LOAD_SUBRESOURCE, mDocument);
+    mozilla::net::PredictorLearn(aLoadData->mURI, mDocument->GetDocumentURI(),
+                                 nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE,
+                                 mDocument);
   }
 
   rv = channel->AsyncOpen(channelListener, nullptr);
 
 #ifdef DEBUG
   mSyncCallback = false;
 #endif
 
--- a/layout/style/nsFontFaceLoader.cpp
+++ b/layout/style/nsFontFaceLoader.cpp
@@ -25,17 +25,17 @@
 
 #include "nsIContentPolicy.h"
 #include "nsContentPolicyUtils.h"
 #include "nsCrossSiteListenerProxy.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIDocShell.h"
 #include "nsIWebNavigation.h"
 #include "nsISupportsPriority.h"
-#include "nsINetworkSeer.h"
+#include "nsINetworkPredictor.h"
 
 #include "nsIConsoleService.h"
 
 #include "nsStyleSet.h"
 #include "nsPrintfCString.h"
 #include "mozilla/gfx/2D.h"
 
 using namespace mozilla;
@@ -378,18 +378,19 @@ nsUserFontSet::StartLoad(gfxMixedFontFam
   if (priorityChannel) {
     priorityChannel->AdjustPriority(nsISupportsPriority::PRIORITY_HIGH);
   }
 
   rv = NS_NewStreamLoader(getter_AddRefs(streamLoader), fontLoader);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsIDocument *document = ps->GetDocument();
-  mozilla::net::SeerLearn(aFontFaceSrc->mURI, document->GetDocumentURI(),
-                          nsINetworkSeer::LEARN_LOAD_SUBRESOURCE, loadGroup);
+  mozilla::net::PredictorLearn(aFontFaceSrc->mURI, document->GetDocumentURI(),
+                               nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE,
+                               loadGroup);
 
   bool inherits = false;
   rv = NS_URIChainHasFlags(aFontFaceSrc->mURI,
                            nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
                            &inherits);
   if (NS_SUCCEEDED(rv) && inherits) {
     // allow data, javascript, etc URI's
     rv = channel->AsyncOpen(streamLoader, nullptr);
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -98,19 +98,19 @@ pref("network.http.max-persistent-connec
 // spdy
 pref("network.http.spdy.push-allowance", 32768);
 
 // See bug 545869 for details on why these are set the way they are
 pref("network.buffer.cache.count", 24);
 pref("network.buffer.cache.size",  16384);
 
 // predictive actions
-pref("network.seer.enabled", false);
-pref("network.seer.max-db-size", 2097152); // bytes
-pref("network.seer.preserve", 50); // percentage of seer data to keep when cleaning up
+pref("network.predictor.enabled", false);
+pref("network.predictor.max-db-size", 2097152); // bytes
+pref("network.predictor.preserve", 50); // percentage of predictor data to keep when cleaning up
 
 /* history max results display */
 pref("browser.display.history.maxresults", 100);
 
 /* How many times should have passed before the remote tabs list is refreshed */
 pref("browser.display.remotetabs.timeout", 10);
 
 /* session history */
--- a/mobile/android/modules/Sanitizer.jsm
+++ b/mobile/android/modules/Sanitizer.jsm
@@ -141,18 +141,18 @@ Sanitizer.prototype = {
         sendMessageToJava({ type: "Sanitize:ClearHistory" });
 
         try {
           Services.obs.notifyObservers(null, "browser:purge-session-history", "");
         }
         catch (e) { }
 
         try {
-          var seer = Cc["@mozilla.org/network/seer;1"].getService(Ci.nsINetworkSeer);
-          seer.reset();
+          var predictor = Cc["@mozilla.org/network/predictor;1"].getService(Ci.nsINetworkPredictor);
+          predictor.reset();
         } catch (e) { }
       },
 
       get canClear()
       {
         // bug 347231: Always allow clearing history due to dependencies on
         // the browser:purge-session-history notification. (like error console)
         return true;
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -1322,34 +1322,34 @@ pref("network.ftp.idleConnectionTimeout"
 // 3: XUL directory viewer
 // all other values are treated like 2
 pref("network.dir.format", 2);
 
 // enables the prefetch service (i.e., prefetching of <link rel="next"> URLs).
 pref("network.prefetch-next", true);
 
 // enables the predictive service
-pref("network.seer.enabled", false);
-pref("network.seer.enable-hover-on-ssl", false);
-pref("network.seer.page-degradation.day", 0);
-pref("network.seer.page-degradation.week", 5);
-pref("network.seer.page-degradation.month", 10);
-pref("network.seer.page-degradation.year", 25);
-pref("network.seer.page-degradation.max", 50);
-pref("network.seer.subresource-degradation.day", 1);
-pref("network.seer.subresource-degradation.week", 10);
-pref("network.seer.subresource-degradation.month", 25);
-pref("network.seer.subresource-degradation.year", 50);
-pref("network.seer.subresource-degradation.max", 100);
-pref("network.seer.preconnect-min-confidence", 90);
-pref("network.seer.preresolve-min-confidence", 60);
-pref("network.seer.redirect-likely-confidence", 75);
-pref("network.seer.max-queue-size", 50);
-pref("network.seer.max-db-size", 157286400); // bytes
-pref("network.seer.preserve", 80); // percentage of seer data to keep when cleaning up
+pref("network.predictor.enabled", false);
+pref("network.predictor.enable-hover-on-ssl", false);
+pref("network.predictor.page-degradation.day", 0);
+pref("network.predictor.page-degradation.week", 5);
+pref("network.predictor.page-degradation.month", 10);
+pref("network.predictor.page-degradation.year", 25);
+pref("network.predictor.page-degradation.max", 50);
+pref("network.predictor.subresource-degradation.day", 1);
+pref("network.predictor.subresource-degradation.week", 10);
+pref("network.predictor.subresource-degradation.month", 25);
+pref("network.predictor.subresource-degradation.year", 50);
+pref("network.predictor.subresource-degradation.max", 100);
+pref("network.predictor.preconnect-min-confidence", 90);
+pref("network.predictor.preresolve-min-confidence", 60);
+pref("network.predictor.redirect-likely-confidence", 75);
+pref("network.predictor.max-queue-size", 50);
+pref("network.predictor.max-db-size", 157286400); // bytes
+pref("network.predictor.preserve", 80); // percentage of predictor data to keep when cleaning up
 
 
 // The following prefs pertain to the negotiate-auth extension (see bug 17578),
 // which provides transparent Kerberos or NTLM authentication using the SPNEGO
 // protocol.  Each pref is a comma-separated list of keys, where each key has
 // the format:
 //   [scheme "://"] [host [":" port]]
 // For example, "foo.com" would match "http://www.foo.com/bar", etc.
--- a/netwerk/base/public/moz.build
+++ b/netwerk/base/public/moz.build
@@ -52,19 +52,19 @@ XPIDL_SOURCES += [
     'nsILoadGroup.idl',
     'nsILoadGroupChild.idl',
     'nsIMIMEInputStream.idl',
     'nsIMultiPartChannel.idl',
     'nsINestedURI.idl',
     'nsINetAddr.idl',
     'nsINetUtil.idl',
     'nsINetworkLinkService.idl',
+    'nsINetworkPredictor.idl',
+    'nsINetworkPredictorVerifier.idl',
     'nsINetworkProperties.idl',
-    'nsINetworkSeer.idl',
-    'nsINetworkSeerVerifier.idl',
     'nsINSSErrorsService.idl',
     'nsIParentChannel.idl',
     'nsIParentRedirectingChannel.idl',
     'nsIPermission.idl',
     'nsIPermissionManager.idl',
     'nsIPrivateBrowsingChannel.idl',
     'nsIProgressEventSink.idl',
     'nsIPrompt.idl',
rename from netwerk/base/public/nsINetworkSeer.idl
rename to netwerk/base/public/nsINetworkPredictor.idl
--- a/netwerk/base/public/nsINetworkSeer.idl
+++ b/netwerk/base/public/nsINetworkPredictor.idl
@@ -2,49 +2,50 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIURI;
 interface nsILoadContext;
-interface nsINetworkSeerVerifier;
+interface nsINetworkPredictorVerifier;
 
-typedef unsigned long SeerPredictReason;
-typedef unsigned long SeerLearnReason;
+typedef unsigned long PredictorPredictReason;
+typedef unsigned long PredictorLearnReason;
 
 /**
- * nsINetworkSeer - learn about pages users visit, and allow us to take
- *                  predictive actions upon future visits.
- *                  NOTE: nsINetworkSeer should only be used on the main thread
+ * nsINetworkPredictor - learn about pages users visit, and allow us to take
+ *                       predictive actions upon future visits.
+ *                       NOTE: nsINetworkPredictor should only
+ *                       be used on the main thread.
  */
-[scriptable, uuid(25e323b6-99e0-4274-b5b3-1a9eb56e28ac)]
-interface nsINetworkSeer : nsISupports
+[scriptable, uuid(980f70bc-0487-4b22-a4c1-bf1185c8ae1f)]
+interface nsINetworkPredictor : nsISupports
 {
   /**
    * Prediction reasons
    *
    * PREDICT_LINK - we are being asked to take predictive action because
    * the user is hovering over a link.
    *
    * PREDICT_LOAD - we are being asked to take predictive action because
    * the user has initiated a pageload.
    *
    * PREDICT_STARTUP - we are being asked to take predictive action
    * because the browser is starting up.
    */
-  const SeerPredictReason PREDICT_LINK = 0;
-  const SeerPredictReason PREDICT_LOAD = 1;
-  const SeerPredictReason PREDICT_STARTUP = 2;
+  const PredictorPredictReason PREDICT_LINK = 0;
+  const PredictorPredictReason PREDICT_LOAD = 1;
+  const PredictorPredictReason PREDICT_STARTUP = 2;
 
   /**
    * Start taking predictive actions
    *
-   * Calling this will cause the seer to (possibly) start
+   * Calling this will cause the predictor to (possibly) start
    * taking actions such as DNS prefetch and/or TCP preconnect based on
    * (1) the host name that we are given, and (2) the reason we are being
    * asked to take actions.
    *
    * @param targetURI - The URI we are being asked to take actions based on.
    * @param sourceURI - The URI that is currently loaded. This is so we can
    *   avoid doing predictive actions for link hover on an HTTPS page (for
    *   example).
@@ -54,43 +55,43 @@ interface nsINetworkSeer : nsISupports
    *   that is being hovered over, and sourceURI should be the URI of the page
    *   on which the link appears.
    *   In the case of PREDICT_LOAD, targetURI should be the URI of the page that
    *   is being loaded and sourceURI should be null.
    *   In the case of PREDICT_STARTUP, both targetURI and sourceURI should be
    *   null.
    * @param loadContext - The nsILoadContext of the page load we are predicting
    *   about.
-   * @param verifier - An nsINetworkSeerVerifier used in testing to ensure we're
-   *   predicting the way we expect to. Not necessary (or desired) for normal
-   *   operation.
+   * @param verifier - An nsINetworkPredictorVerifier used in testing to ensure
+   *   we're predicting the way we expect to. Not necessary (or desired) for
+   *   normal operation.
    */
   void predict(in nsIURI targetURI,
                in nsIURI sourceURI,
-               in SeerPredictReason reason,
+               in PredictorPredictReason reason,
                in nsILoadContext loadContext,
-               in nsINetworkSeerVerifier verifier);
+               in nsINetworkPredictorVerifier verifier);
 
 
   /*
    * Reasons we are learning something
    *
    * LEARN_LOAD_TOPLEVEL - we are learning about the toplevel resource of a
    *                       pageload (NOTE: this should ONLY be used by tests)
    *
    * LEARN_LOAD_SUBRESOURCE - we are learning a subresource from a pageload
    *
    * LEARN_LOAD_REDIRECT - we are learning about the re-direct of a URI
    *
    * LEARN_STARTUP - we are learning about a page loaded during startup
    */
-  const SeerLearnReason LEARN_LOAD_TOPLEVEL = 0;
-  const SeerLearnReason LEARN_LOAD_SUBRESOURCE = 1;
-  const SeerLearnReason LEARN_LOAD_REDIRECT = 2;
-  const SeerLearnReason LEARN_STARTUP = 3;
+  const PredictorLearnReason LEARN_LOAD_TOPLEVEL = 0;
+  const PredictorLearnReason LEARN_LOAD_SUBRESOURCE = 1;
+  const PredictorLearnReason LEARN_LOAD_REDIRECT = 2;
+  const PredictorLearnReason LEARN_STARTUP = 3;
 
   /**
    * Add to our compendium of knowledge
    *
    * This adds to our prediction database to make things (hopefully)
    * smarter next time we predict something.
    *
    * @param targetURI - The URI that was loaded that we are keeping track of.
@@ -106,17 +107,17 @@ interface nsINetworkSeer : nsISupports
    *   In the case of LEARN_STARTUP, targetURI should be the URI of a page
    *   that was loaded immediately after browser startup, and sourceURI should
    *   be null.
    * @param loadContext - The nsILoadContext for the page load that we are
    *   learning about.
    */
   void learn(in nsIURI targetURI,
              in nsIURI sourceURI,
-             in SeerLearnReason reason,
+             in PredictorLearnReason reason,
              in nsILoadContext loadContext);
 
   /**
    * Clear out all our learned knowledge
    *
    * This removes everything from our database so that any predictions begun
    * after this completes will start from a blank slate.
    */
@@ -125,46 +126,46 @@ interface nsINetworkSeer : nsISupports
   /**
    * @deprecated THIS API IS FOR TESTING ONLY. IF YOU DON'T KNOW WHAT IT DOES,
    * DON'T USE IT
    */
   void prepareForDnsTest(in long long timestamp, in string uri);
 };
 
 %{C++
-// Wrapper functions to make use of the seer easier and less invasive
+// Wrapper functions to make use of the predictor easier and less invasive
 class nsIChannel;
 class nsIDocument;
 class nsILoadContext;
 class nsILoadGroup;
-class nsINetworkSeerVerifier;
+class nsINetworkPredictorVerifier;
 
 namespace mozilla {
 namespace net {
 
-nsresult SeerPredict(nsIURI *targetURI,
-                     nsIURI *sourceURI,
-                     SeerPredictReason reason,
-                     nsILoadContext *loadContext,
-                     nsINetworkSeerVerifier *verifier);
+nsresult PredictorPredict(nsIURI *targetURI,
+                          nsIURI *sourceURI,
+                          PredictorPredictReason reason,
+                          nsILoadContext *loadContext,
+                          nsINetworkPredictorVerifier *verifier);
 
-nsresult SeerLearn(nsIURI *targetURI,
-                   nsIURI *sourceURI,
-                   SeerLearnReason reason,
-                   nsILoadContext *loadContext);
+nsresult PredictorLearn(nsIURI *targetURI,
+                        nsIURI *sourceURI,
+                        PredictorLearnReason reason,
+                        nsILoadContext *loadContext);
 
-nsresult SeerLearn(nsIURI *targetURI,
-                   nsIURI *sourceURI,
-                   SeerLearnReason reason,
-                   nsILoadGroup *loadGroup);
+nsresult PredictorLearn(nsIURI *targetURI,
+                        nsIURI *sourceURI,
+                        PredictorLearnReason reason,
+                        nsILoadGroup *loadGroup);
 
-nsresult SeerLearn(nsIURI *targetURI,
-                   nsIURI *sourceURI,
-                   SeerLearnReason reason,
-                   nsIDocument *document);
+nsresult PredictorLearn(nsIURI *targetURI,
+                        nsIURI *sourceURI,
+                        PredictorLearnReason reason,
+                        nsIDocument *document);
 
-nsresult SeerLearnRedirect(nsIURI *targetURI,
-                           nsIChannel *channel,
-                           nsILoadContext *loadContext);
+nsresult PredictorLearnRedirect(nsIURI *targetURI,
+                                nsIChannel *channel,
+                                nsILoadContext *loadContext);
 
 } // mozilla::net
 } // mozilla
 %}
rename from netwerk/base/public/nsINetworkSeerVerifier.idl
rename to netwerk/base/public/nsINetworkPredictorVerifier.idl
--- a/netwerk/base/public/nsINetworkSeerVerifier.idl
+++ b/netwerk/base/public/nsINetworkPredictorVerifier.idl
@@ -1,24 +1,24 @@
 /* vim: set ts=2 sts=2 et sw=2: */
 /* 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/. */
 
 /**
- * nsINetworkSeerVerifier - used for testing the network seer to ensure it
- *                          does what we expect it to do.
+ * nsINetworkPredictorVerifier - used for testing the network predictor to
+ *                               ensure it does what we expect it to do.
  */
 
 #include "nsISupports.idl"
 
 interface nsIURI;
 
-[scriptable, uuid(ea273653-43a8-4632-8b30-4032e0918e8b)]
-interface nsINetworkSeerVerifier : nsISupports
+[scriptable, uuid(00360c7d-a046-4f8d-a1fc-8bdc0f0fb444)]
+interface nsINetworkPredictorVerifier : nsISupports
 {
     /**
      * Callback for when we do a predictive preconnect
      *
      * @param uri - The URI that was preconnected to
      */
     void onPredictPreconnect(in nsIURI uri);
 
rename from netwerk/base/src/Seer.cpp
rename to netwerk/base/src/Predictor.cpp
--- a/netwerk/base/src/Seer.cpp
+++ b/netwerk/base/src/Predictor.cpp
@@ -1,27 +1,27 @@
 /* vim: set ts=2 sts=2 et sw=2: */
 /* 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 <algorithm>
 
-#include "Seer.h"
+#include "Predictor.h"
 
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsICancelable.h"
 #include "nsIChannel.h"
 #include "nsIDNSListener.h"
 #include "nsIDNSService.h"
 #include "nsIDocument.h"
 #include "nsIFile.h"
 #include "nsILoadContext.h"
 #include "nsILoadGroup.h"
-#include "nsINetworkSeerVerifier.h"
+#include "nsINetworkPredictorVerifier.h"
 #include "nsIObserverService.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
 #include "nsISpeculativeConnect.h"
 #include "nsITimer.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 #include "nsServiceManagerUtils.h"
@@ -53,186 +53,191 @@ namespace net {
 
 #define RETURN_IF_FAILED(_rv) \
   do { \
     if (NS_FAILED(_rv)) { \
       return; \
     } \
   } while (0)
 
-const char SEER_ENABLED_PREF[] = "network.seer.enabled";
-const char SEER_SSL_HOVER_PREF[] = "network.seer.enable-hover-on-ssl";
-
-const char SEER_PAGE_DELTA_DAY_PREF[] = "network.seer.page-degradation.day";
-const int SEER_PAGE_DELTA_DAY_DEFAULT = 0;
-const char SEER_PAGE_DELTA_WEEK_PREF[] = "network.seer.page-degradation.week";
-const int SEER_PAGE_DELTA_WEEK_DEFAULT = 5;
-const char SEER_PAGE_DELTA_MONTH_PREF[] = "network.seer.page-degradation.month";
-const int SEER_PAGE_DELTA_MONTH_DEFAULT = 10;
-const char SEER_PAGE_DELTA_YEAR_PREF[] = "network.seer.page-degradation.year";
-const int SEER_PAGE_DELTA_YEAR_DEFAULT = 25;
-const char SEER_PAGE_DELTA_MAX_PREF[] = "network.seer.page-degradation.max";
-const int SEER_PAGE_DELTA_MAX_DEFAULT = 50;
-const char SEER_SUB_DELTA_DAY_PREF[] =
-  "network.seer.subresource-degradation.day";
-const int SEER_SUB_DELTA_DAY_DEFAULT = 1;
-const char SEER_SUB_DELTA_WEEK_PREF[] =
-  "network.seer.subresource-degradation.week";
-const int SEER_SUB_DELTA_WEEK_DEFAULT = 10;
-const char SEER_SUB_DELTA_MONTH_PREF[] =
-  "network.seer.subresource-degradation.month";
-const int SEER_SUB_DELTA_MONTH_DEFAULT = 25;
-const char SEER_SUB_DELTA_YEAR_PREF[] =
-  "network.seer.subresource-degradation.year";
-const int SEER_SUB_DELTA_YEAR_DEFAULT = 50;
-const char SEER_SUB_DELTA_MAX_PREF[] =
-  "network.seer.subresource-degradation.max";
-const int SEER_SUB_DELTA_MAX_DEFAULT = 100;
-
-const char SEER_PRECONNECT_MIN_PREF[] =
-  "network.seer.preconnect-min-confidence";
+const char PREDICTOR_ENABLED_PREF[] = "network.predictor.enabled";
+const char PREDICTOR_SSL_HOVER_PREF[] = "network.predictor.enable-hover-on-ssl";
+
+const char PREDICTOR_PAGE_DELTA_DAY_PREF[] =
+  "network.predictor.page-degradation.day";
+const int PREDICTOR_PAGE_DELTA_DAY_DEFAULT = 0;
+const char PREDICTOR_PAGE_DELTA_WEEK_PREF[] =
+  "network.predictor.page-degradation.week";
+const int PREDICTOR_PAGE_DELTA_WEEK_DEFAULT = 5;
+const char PREDICTOR_PAGE_DELTA_MONTH_PREF[] =
+  "network.predictor.page-degradation.month";
+const int PREDICTOR_PAGE_DELTA_MONTH_DEFAULT = 10;
+const char PREDICTOR_PAGE_DELTA_YEAR_PREF[] =
+  "network.predictor.page-degradation.year";
+const int PREDICTOR_PAGE_DELTA_YEAR_DEFAULT = 25;
+const char PREDICTOR_PAGE_DELTA_MAX_PREF[] =
+  "network.predictor.page-degradation.max";
+const int PREDICTOR_PAGE_DELTA_MAX_DEFAULT = 50;
+const char PREDICTOR_SUB_DELTA_DAY_PREF[] =
+  "network.predictor.subresource-degradation.day";
+const int PREDICTOR_SUB_DELTA_DAY_DEFAULT = 1;
+const char PREDICTOR_SUB_DELTA_WEEK_PREF[] =
+  "network.predictor.subresource-degradation.week";
+const int PREDICTOR_SUB_DELTA_WEEK_DEFAULT = 10;
+const char PREDICTOR_SUB_DELTA_MONTH_PREF[] =
+  "network.predictor.subresource-degradation.month";
+const int PREDICTOR_SUB_DELTA_MONTH_DEFAULT = 25;
+const char PREDICTOR_SUB_DELTA_YEAR_PREF[] =
+  "network.predictor.subresource-degradation.year";
+const int PREDICTOR_SUB_DELTA_YEAR_DEFAULT = 50;
+const char PREDICTOR_SUB_DELTA_MAX_PREF[] =
+  "network.predictor.subresource-degradation.max";
+const int PREDICTOR_SUB_DELTA_MAX_DEFAULT = 100;
+
+const char PREDICTOR_PRECONNECT_MIN_PREF[] =
+  "network.predictor.preconnect-min-confidence";
 const int PRECONNECT_MIN_DEFAULT = 90;
-const char SEER_PRERESOLVE_MIN_PREF[] =
-  "network.seer.preresolve-min-confidence";
+const char PREDICTOR_PRERESOLVE_MIN_PREF[] =
+  "network.predictor.preresolve-min-confidence";
 const int PRERESOLVE_MIN_DEFAULT = 60;
-const char SEER_REDIRECT_LIKELY_PREF[] =
-  "network.seer.redirect-likely-confidence";
+const char PREDICTOR_REDIRECT_LIKELY_PREF[] =
+  "network.predictor.redirect-likely-confidence";
 const int REDIRECT_LIKELY_DEFAULT = 75;
 
-const char SEER_MAX_QUEUE_SIZE_PREF[] = "network.seer.max-queue-size";
-const uint32_t SEER_MAX_QUEUE_SIZE_DEFAULT = 50;
-
-const char SEER_MAX_DB_SIZE_PREF[] = "network.seer.max-db-size";
-const int32_t SEER_MAX_DB_SIZE_DEFAULT_BYTES = 150 * 1024 * 1024;
-const char SEER_PRESERVE_PERCENTAGE_PREF[] = "network.seer.preserve";
-const int32_t SEER_PRESERVE_PERCENTAGE_DEFAULT = 80;
+const char PREDICTOR_MAX_QUEUE_SIZE_PREF[] = "network.predictor.max-queue-size";
+const uint32_t PREDICTOR_MAX_QUEUE_SIZE_DEFAULT = 50;
+
+const char PREDICTOR_MAX_DB_SIZE_PREF[] = "network.predictor.max-db-size";
+const int32_t PREDICTOR_MAX_DB_SIZE_DEFAULT_BYTES = 150 * 1024 * 1024;
+const char PREDICTOR_PRESERVE_PERCENTAGE_PREF[] = "network.predictor.preserve";
+const int32_t PREDICTOR_PRESERVE_PERCENTAGE_DEFAULT = 80;
 
 // All these time values are in usec
 const long long ONE_DAY = 86400LL * 1000000LL;
 const long long ONE_WEEK = 7LL * ONE_DAY;
 const long long ONE_MONTH = 30LL * ONE_DAY;
 const long long ONE_YEAR = 365LL * ONE_DAY;
 
 const long STARTUP_WINDOW = 5L * 60L * 1000000L; // 5min
 
 // Version for the database schema
-static const int32_t SEER_SCHEMA_VERSION = 1;
-
-struct SeerTelemetryAccumulators {
-  Telemetry::AutoCounter<Telemetry::SEER_PREDICT_ATTEMPTS> mPredictAttempts;
-  Telemetry::AutoCounter<Telemetry::SEER_LEARN_ATTEMPTS> mLearnAttempts;
-  Telemetry::AutoCounter<Telemetry::SEER_PREDICT_FULL_QUEUE> mPredictFullQueue;
-  Telemetry::AutoCounter<Telemetry::SEER_LEARN_FULL_QUEUE> mLearnFullQueue;
-  Telemetry::AutoCounter<Telemetry::SEER_TOTAL_PREDICTIONS> mTotalPredictions;
-  Telemetry::AutoCounter<Telemetry::SEER_TOTAL_PRECONNECTS> mTotalPreconnects;
-  Telemetry::AutoCounter<Telemetry::SEER_TOTAL_PRERESOLVES> mTotalPreresolves;
-  Telemetry::AutoCounter<Telemetry::SEER_PREDICTIONS_CALCULATED> mPredictionsCalculated;
-  Telemetry::AutoCounter<Telemetry::SEER_LOAD_COUNT_IS_ZERO> mLoadCountZeroes;
-  Telemetry::AutoCounter<Telemetry::SEER_LOAD_COUNT_OVERFLOWS> mLoadCountOverflows;
-  Telemetry::AutoCounter<Telemetry::SEER_STARTUP_COUNT_IS_ZERO> mStartupCountZeroes;
-  Telemetry::AutoCounter<Telemetry::SEER_STARTUP_COUNT_OVERFLOWS> mStartupCountOverflows;
+static const int32_t PREDICTOR_SCHEMA_VERSION = 1;
+
+struct PredictorTelemetryAccumulators {
+  Telemetry::AutoCounter<Telemetry::PREDICTOR_PREDICT_ATTEMPTS> mPredictAttempts;
+  Telemetry::AutoCounter<Telemetry::PREDICTOR_LEARN_ATTEMPTS> mLearnAttempts;
+  Telemetry::AutoCounter<Telemetry::PREDICTOR_PREDICT_FULL_QUEUE> mPredictFullQueue;
+  Telemetry::AutoCounter<Telemetry::PREDICTOR_LEARN_FULL_QUEUE> mLearnFullQueue;
+  Telemetry::AutoCounter<Telemetry::PREDICTOR_TOTAL_PREDICTIONS> mTotalPredictions;
+  Telemetry::AutoCounter<Telemetry::PREDICTOR_TOTAL_PRECONNECTS> mTotalPreconnects;
+  Telemetry::AutoCounter<Telemetry::PREDICTOR_TOTAL_PRERESOLVES> mTotalPreresolves;
+  Telemetry::AutoCounter<Telemetry::PREDICTOR_PREDICTIONS_CALCULATED> mPredictionsCalculated;
+  Telemetry::AutoCounter<Telemetry::PREDICTOR_LOAD_COUNT_IS_ZERO> mLoadCountZeroes;
+  Telemetry::AutoCounter<Telemetry::PREDICTOR_LOAD_COUNT_OVERFLOWS> mLoadCountOverflows;
+  Telemetry::AutoCounter<Telemetry::PREDICTOR_STARTUP_COUNT_IS_ZERO> mStartupCountZeroes;
+  Telemetry::AutoCounter<Telemetry::PREDICTOR_STARTUP_COUNT_OVERFLOWS> mStartupCountOverflows;
 };
 
 // Listener for the speculative DNS requests we'll fire off, which just ignores
 // the result (since we're just trying to warm the cache). This also exists to
-// reduce round-trips to the main thread, by being something threadsafe the Seer
-// can use.
-
-class SeerDNSListener : public nsIDNSListener
+// reduce round-trips to the main thread, by being something threadsafe the
+// Predictor can use.
+
+class PredictorDNSListener : public nsIDNSListener
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIDNSLISTENER
 
-  SeerDNSListener()
+  PredictorDNSListener()
   { }
 
-  virtual ~SeerDNSListener()
+  virtual ~PredictorDNSListener()
   { }
 };
 
-NS_IMPL_ISUPPORTS(SeerDNSListener, nsIDNSListener);
+NS_IMPL_ISUPPORTS(PredictorDNSListener, nsIDNSListener);
 
 NS_IMETHODIMP
-SeerDNSListener::OnLookupComplete(nsICancelable *request,
-                                  nsIDNSRecord *rec,
-                                  nsresult status)
+PredictorDNSListener::OnLookupComplete(nsICancelable *request,
+                                       nsIDNSRecord *rec,
+                                       nsresult status)
 {
   return NS_OK;
 }
 
-// Are you ready for the fun part? Because here comes the fun part. The seer,
-// which will do awesome stuff as you browse to make your browsing experience
-// faster.
-
-static Seer *gSeer = nullptr;
+// Are you ready for the fun part? Because here comes the fun part. The
+// predictor, which will do awesome stuff as you browse to make your
+// browsing experience faster.
+
+static Predictor *gPredictor = nullptr;
 
 #if defined(PR_LOGGING)
-static PRLogModuleInfo *gSeerLog = nullptr;
-#define SEER_LOG(args) PR_LOG(gSeerLog, 4, args)
+static PRLogModuleInfo *gPredictorLog = nullptr;
+#define PREDICTOR_LOG(args) PR_LOG(gPredictorLog, 4, args)
 #else
-#define SEER_LOG(args)
+#define PREDICTOR_LOG(args)
 #endif
 
-NS_IMPL_ISUPPORTS(Seer,
-                  nsINetworkSeer,
+NS_IMPL_ISUPPORTS(Predictor,
+                  nsINetworkPredictor,
                   nsIObserver,
                   nsISpeculativeConnectionOverrider,
                   nsIInterfaceRequestor)
 
-Seer::Seer()
+Predictor::Predictor()
   :mInitialized(false)
   ,mEnabled(true)
   ,mEnableHoverOnSSL(false)
-  ,mPageDegradationDay(SEER_PAGE_DELTA_DAY_DEFAULT)
-  ,mPageDegradationWeek(SEER_PAGE_DELTA_WEEK_DEFAULT)
-  ,mPageDegradationMonth(SEER_PAGE_DELTA_MONTH_DEFAULT)
-  ,mPageDegradationYear(SEER_PAGE_DELTA_YEAR_DEFAULT)
-  ,mPageDegradationMax(SEER_PAGE_DELTA_MAX_DEFAULT)
-  ,mSubresourceDegradationDay(SEER_SUB_DELTA_DAY_DEFAULT)
-  ,mSubresourceDegradationWeek(SEER_SUB_DELTA_WEEK_DEFAULT)
-  ,mSubresourceDegradationMonth(SEER_SUB_DELTA_MONTH_DEFAULT)
-  ,mSubresourceDegradationYear(SEER_SUB_DELTA_YEAR_DEFAULT)
-  ,mSubresourceDegradationMax(SEER_SUB_DELTA_MAX_DEFAULT)
+  ,mPageDegradationDay(PREDICTOR_PAGE_DELTA_DAY_DEFAULT)
+  ,mPageDegradationWeek(PREDICTOR_PAGE_DELTA_WEEK_DEFAULT)
+  ,mPageDegradationMonth(PREDICTOR_PAGE_DELTA_MONTH_DEFAULT)
+  ,mPageDegradationYear(PREDICTOR_PAGE_DELTA_YEAR_DEFAULT)
+  ,mPageDegradationMax(PREDICTOR_PAGE_DELTA_MAX_DEFAULT)
+  ,mSubresourceDegradationDay(PREDICTOR_SUB_DELTA_DAY_DEFAULT)
+  ,mSubresourceDegradationWeek(PREDICTOR_SUB_DELTA_WEEK_DEFAULT)
+  ,mSubresourceDegradationMonth(PREDICTOR_SUB_DELTA_MONTH_DEFAULT)
+  ,mSubresourceDegradationYear(PREDICTOR_SUB_DELTA_YEAR_DEFAULT)
+  ,mSubresourceDegradationMax(PREDICTOR_SUB_DELTA_MAX_DEFAULT)
   ,mPreconnectMinConfidence(PRECONNECT_MIN_DEFAULT)
   ,mPreresolveMinConfidence(PRERESOLVE_MIN_DEFAULT)
   ,mRedirectLikelyConfidence(REDIRECT_LIKELY_DEFAULT)
-  ,mMaxQueueSize(SEER_MAX_QUEUE_SIZE_DEFAULT)
+  ,mMaxQueueSize(PREDICTOR_MAX_QUEUE_SIZE_DEFAULT)
   ,mStatements(mDB)
   ,mLastStartupTime(0)
   ,mStartupCount(0)
   ,mQueueSize(0)
-  ,mQueueSizeLock("Seer.mQueueSizeLock")
+  ,mQueueSizeLock("Predictor.mQueueSizeLock")
   ,mCleanupScheduled(false)
-  ,mMaxDBSize(SEER_MAX_DB_SIZE_DEFAULT_BYTES)
-  ,mPreservePercentage(SEER_PRESERVE_PERCENTAGE_DEFAULT)
+  ,mMaxDBSize(PREDICTOR_MAX_DB_SIZE_DEFAULT_BYTES)
+  ,mPreservePercentage(PREDICTOR_PRESERVE_PERCENTAGE_DEFAULT)
   ,mLastCleanupTime(0)
 {
 #if defined(PR_LOGGING)
-  gSeerLog = PR_NewLogModule("NetworkSeer");
+  gPredictorLog = PR_NewLogModule("NetworkPredictor");
 #endif
 
-  MOZ_ASSERT(!gSeer, "multiple Seer instances!");
-  gSeer = this;
+  MOZ_ASSERT(!gPredictor, "multiple Predictor instances!");
+  gPredictor = this;
 }
 
-Seer::~Seer()
+Predictor::~Predictor()
 {
   if (mInitialized)
     Shutdown();
 
   RemoveObserver();
 
-  gSeer = nullptr;
+  gPredictor = nullptr;
 }
 
-// Seer::nsIObserver
+// Predictor::nsIObserver
 
 nsresult
-Seer::InstallObserver()
+Predictor::InstallObserver()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Installing observer off main thread");
 
   nsresult rv = NS_OK;
   nsCOMPtr<nsIObserverService> obs =
     mozilla::services::GetObserverService();
   if (!obs) {
     return NS_ERROR_NOT_AVAILABLE;
@@ -241,226 +246,234 @@ Seer::InstallObserver()
   rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
   if (!prefs) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  Preferences::AddBoolVarCache(&mEnabled, SEER_ENABLED_PREF, true);
-  Preferences::AddBoolVarCache(&mEnableHoverOnSSL, SEER_SSL_HOVER_PREF, false);
-  Preferences::AddIntVarCache(&mPageDegradationDay, SEER_PAGE_DELTA_DAY_PREF,
-                              SEER_PAGE_DELTA_DAY_DEFAULT);
-  Preferences::AddIntVarCache(&mPageDegradationWeek, SEER_PAGE_DELTA_WEEK_PREF,
-                              SEER_PAGE_DELTA_WEEK_DEFAULT);
+  Preferences::AddBoolVarCache(&mEnabled, PREDICTOR_ENABLED_PREF, true);
+  Preferences::AddBoolVarCache(&mEnableHoverOnSSL,
+                               PREDICTOR_SSL_HOVER_PREF, false);
+  Preferences::AddIntVarCache(&mPageDegradationDay,
+                              PREDICTOR_PAGE_DELTA_DAY_PREF,
+                              PREDICTOR_PAGE_DELTA_DAY_DEFAULT);
+  Preferences::AddIntVarCache(&mPageDegradationWeek,
+                              PREDICTOR_PAGE_DELTA_WEEK_PREF,
+                              PREDICTOR_PAGE_DELTA_WEEK_DEFAULT);
   Preferences::AddIntVarCache(&mPageDegradationMonth,
-                              SEER_PAGE_DELTA_MONTH_PREF,
-                              SEER_PAGE_DELTA_MONTH_DEFAULT);
-  Preferences::AddIntVarCache(&mPageDegradationYear, SEER_PAGE_DELTA_YEAR_PREF,
-                              SEER_PAGE_DELTA_YEAR_DEFAULT);
-  Preferences::AddIntVarCache(&mPageDegradationMax, SEER_PAGE_DELTA_MAX_PREF,
-                              SEER_PAGE_DELTA_MAX_DEFAULT);
+                              PREDICTOR_PAGE_DELTA_MONTH_PREF,
+                              PREDICTOR_PAGE_DELTA_MONTH_DEFAULT);
+  Preferences::AddIntVarCache(&mPageDegradationYear,
+                              PREDICTOR_PAGE_DELTA_YEAR_PREF,
+                              PREDICTOR_PAGE_DELTA_YEAR_DEFAULT);
+  Preferences::AddIntVarCache(&mPageDegradationMax,
+                              PREDICTOR_PAGE_DELTA_MAX_PREF,
+                              PREDICTOR_PAGE_DELTA_MAX_DEFAULT);
 
   Preferences::AddIntVarCache(&mSubresourceDegradationDay,
-                              SEER_SUB_DELTA_DAY_PREF,
-                              SEER_SUB_DELTA_DAY_DEFAULT);
+                              PREDICTOR_SUB_DELTA_DAY_PREF,
+                              PREDICTOR_SUB_DELTA_DAY_DEFAULT);
   Preferences::AddIntVarCache(&mSubresourceDegradationWeek,
-                              SEER_SUB_DELTA_WEEK_PREF,
-                              SEER_SUB_DELTA_WEEK_DEFAULT);
+                              PREDICTOR_SUB_DELTA_WEEK_PREF,
+                              PREDICTOR_SUB_DELTA_WEEK_DEFAULT);
   Preferences::AddIntVarCache(&mSubresourceDegradationMonth,
-                              SEER_SUB_DELTA_MONTH_PREF,
-                              SEER_SUB_DELTA_MONTH_DEFAULT);
+                              PREDICTOR_SUB_DELTA_MONTH_PREF,
+                              PREDICTOR_SUB_DELTA_MONTH_DEFAULT);
   Preferences::AddIntVarCache(&mSubresourceDegradationYear,
-                              SEER_SUB_DELTA_YEAR_PREF,
-                              SEER_SUB_DELTA_YEAR_DEFAULT);
+                              PREDICTOR_SUB_DELTA_YEAR_PREF,
+                              PREDICTOR_SUB_DELTA_YEAR_DEFAULT);
   Preferences::AddIntVarCache(&mSubresourceDegradationMax,
-                              SEER_SUB_DELTA_MAX_PREF,
-                              SEER_SUB_DELTA_MAX_DEFAULT);
+                              PREDICTOR_SUB_DELTA_MAX_PREF,
+                              PREDICTOR_SUB_DELTA_MAX_DEFAULT);
 
   Preferences::AddIntVarCache(&mPreconnectMinConfidence,
-                              SEER_PRECONNECT_MIN_PREF,
+                              PREDICTOR_PRECONNECT_MIN_PREF,
                               PRECONNECT_MIN_DEFAULT);
   Preferences::AddIntVarCache(&mPreresolveMinConfidence,
-                              SEER_PRERESOLVE_MIN_PREF,
+                              PREDICTOR_PRERESOLVE_MIN_PREF,
                               PRERESOLVE_MIN_DEFAULT);
   Preferences::AddIntVarCache(&mRedirectLikelyConfidence,
-                              SEER_REDIRECT_LIKELY_PREF,
+                              PREDICTOR_REDIRECT_LIKELY_PREF,
                               REDIRECT_LIKELY_DEFAULT);
 
-  Preferences::AddIntVarCache(&mMaxQueueSize, SEER_MAX_QUEUE_SIZE_PREF,
-                              SEER_MAX_QUEUE_SIZE_DEFAULT);
-
-  Preferences::AddIntVarCache(&mMaxDBSize, SEER_MAX_DB_SIZE_PREF,
-                              SEER_MAX_DB_SIZE_DEFAULT_BYTES);
+  Preferences::AddIntVarCache(&mMaxQueueSize, PREDICTOR_MAX_QUEUE_SIZE_PREF,
+                              PREDICTOR_MAX_QUEUE_SIZE_DEFAULT);
+
+  Preferences::AddIntVarCache(&mMaxDBSize, PREDICTOR_MAX_DB_SIZE_PREF,
+                              PREDICTOR_MAX_DB_SIZE_DEFAULT_BYTES);
   Preferences::AddIntVarCache(&mPreservePercentage,
-                              SEER_PRESERVE_PERCENTAGE_PREF,
-                              SEER_PRESERVE_PERCENTAGE_DEFAULT);
+                              PREDICTOR_PRESERVE_PERCENTAGE_PREF,
+                              PREDICTOR_PRESERVE_PERCENTAGE_DEFAULT);
 
   return rv;
 }
 
 void
-Seer::RemoveObserver()
+Predictor::RemoveObserver()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Removing observer off main thread");
 
   nsCOMPtr<nsIObserverService> obs =
     mozilla::services::GetObserverService();
   if (obs) {
     obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
   }
 }
 
 static const uint32_t COMMIT_TIMER_DELTA_MS = 5 * 1000;
 
-class SeerCommitTimerInitEvent : public nsRunnable
+class PredictorCommitTimerInitEvent : public nsRunnable
 {
 public:
   NS_IMETHOD Run() MOZ_OVERRIDE
   {
     nsresult rv = NS_OK;
 
-    if (!gSeer->mCommitTimer) {
-      gSeer->mCommitTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
+    if (!gPredictor->mCommitTimer) {
+      gPredictor->mCommitTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
     } else {
-      gSeer->mCommitTimer->Cancel();
+      gPredictor->mCommitTimer->Cancel();
     }
     if (NS_SUCCEEDED(rv)) {
-      gSeer->mCommitTimer->Init(gSeer, COMMIT_TIMER_DELTA_MS,
-                                nsITimer::TYPE_ONE_SHOT);
+      gPredictor->mCommitTimer->Init(gPredictor, COMMIT_TIMER_DELTA_MS,
+                                     nsITimer::TYPE_ONE_SHOT);
     }
 
     return NS_OK;
   }
 };
 
-class SeerNewTransactionEvent : public nsRunnable
+class PredictorNewTransactionEvent : public nsRunnable
 {
   NS_IMETHODIMP Run() MOZ_OVERRIDE
   {
-    gSeer->CommitTransaction();
-    gSeer->BeginTransaction();
-    gSeer->MaybeScheduleCleanup();
-    nsRefPtr<SeerCommitTimerInitEvent> event = new SeerCommitTimerInitEvent();
+    gPredictor->CommitTransaction();
+    gPredictor->BeginTransaction();
+    gPredictor->MaybeScheduleCleanup();
+    nsRefPtr<PredictorCommitTimerInitEvent> event =
+      new PredictorCommitTimerInitEvent();
     NS_DispatchToMainThread(event);
     return NS_OK;
   }
 };
 
 NS_IMETHODIMP
-Seer::Observe(nsISupports *subject, const char *topic,
-              const char16_t *data_unicode)
+Predictor::Observe(nsISupports *subject, const char *topic,
+                   const char16_t *data_unicode)
 {
   nsresult rv = NS_OK;
-  MOZ_ASSERT(NS_IsMainThread(), "Seer observing something off main thread!");
+  MOZ_ASSERT(NS_IsMainThread(),
+             "Predictor observing something off main thread!");
 
   if (!strcmp(NS_XPCOM_SHUTDOWN_OBSERVER_ID, topic)) {
     Shutdown();
   } else if (!strcmp(NS_TIMER_CALLBACK_TOPIC, topic)) {
     if (mInitialized) { // Can't access io thread if we're not initialized!
-      nsRefPtr<SeerNewTransactionEvent> event = new SeerNewTransactionEvent();
+      nsRefPtr<PredictorNewTransactionEvent> event =
+        new PredictorNewTransactionEvent();
       mIOThread->Dispatch(event, NS_DISPATCH_NORMAL);
     }
   }
 
   return rv;
 }
 
-// Seer::nsISpeculativeConnectionOverrider
+// Predictor::nsISpeculativeConnectionOverrider
 
 NS_IMETHODIMP
-Seer::GetIgnoreIdle(bool *ignoreIdle)
+Predictor::GetIgnoreIdle(bool *ignoreIdle)
 {
   *ignoreIdle = true;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-Seer::GetIgnorePossibleSpdyConnections(bool *ignorePossibleSpdyConnections)
+Predictor::GetIgnorePossibleSpdyConnections(bool *ignorePossibleSpdyConnections)
 {
   *ignorePossibleSpdyConnections = true;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-Seer::GetParallelSpeculativeConnectLimit(
+Predictor::GetParallelSpeculativeConnectLimit(
     uint32_t *parallelSpeculativeConnectLimit)
 {
   *parallelSpeculativeConnectLimit = 6;
   return NS_OK;
 }
 
-// Seer::nsIInterfaceRequestor
+// Predictor::nsIInterfaceRequestor
 
 NS_IMETHODIMP
-Seer::GetInterface(const nsIID &iid, void **result)
+Predictor::GetInterface(const nsIID &iid, void **result)
 {
   return QueryInterface(iid, result);
 }
 
 #ifdef MOZ_NUWA_PROCESS
-class NuwaMarkSeerThreadRunner : public nsRunnable
+class NuwaMarkPredictorThreadRunner : public nsRunnable
 {
   NS_IMETHODIMP Run() MOZ_OVERRIDE
   {
     if (IsNuwaProcess()) {
       NS_ASSERTION(NuwaMarkCurrentThread != nullptr,
                    "NuwaMarkCurrentThread is undefined!");
       NuwaMarkCurrentThread(nullptr, nullptr);
     }
     return NS_OK;
   }
 };
 #endif
 
-// Seer::nsINetworkSeer
+// Predictor::nsINetworkPredictor
 
 nsresult
-Seer::Init()
+Predictor::Init()
 {
   if (!NS_IsMainThread()) {
-    MOZ_ASSERT(false, "Seer::Init called off the main thread!");
+    MOZ_ASSERT(false, "Predictor::Init called off the main thread!");
     return NS_ERROR_UNEXPECTED;
   }
 
   nsresult rv = NS_OK;
 
 #if defined(ANDROID) && !defined(MOZ_WIDGET_GONK)
-  // This is an ugly hack to disable the seer on android < 2.3, as it doesn't
-  // play nicely with those android versions, at least on our infra. Causes
-  // timeouts in reftests. See bug 881804 comment 86.
+  // This is an ugly hack to disable the predictor on android < 2.3, as it
+  // doesn't play nicely with those android versions, at least on our infra.
+  // Causes timeouts in reftests. See bug 881804 comment 86.
   nsCOMPtr<nsIPropertyBag2> infoService =
     do_GetService("@mozilla.org/system-info;1");
   if (infoService) {
     int32_t androidVersion = -1;
     rv = infoService->GetPropertyAsInt32(NS_LITERAL_STRING("version"),
                                          &androidVersion);
     if (NS_SUCCEEDED(rv) && (androidVersion < ANDROID_23_VERSION)) {
       return NS_ERROR_NOT_AVAILABLE;
     }
   }
 #endif
 
   mStartupTime = PR_Now();
 
-  mAccumulators = new SeerTelemetryAccumulators();
+  mAccumulators = new PredictorTelemetryAccumulators();
 
   rv = InstallObserver();
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!mDNSListener) {
-    mDNSListener = new SeerDNSListener();
+    mDNSListener = new PredictorDNSListener();
   }
 
-  rv = NS_NewNamedThread("Network Seer", getter_AddRefs(mIOThread));
+  rv = NS_NewNamedThread("Net Predictor", getter_AddRefs(mIOThread));
   NS_ENSURE_SUCCESS(rv, rv);
 
 #ifdef MOZ_NUWA_PROCESS
-  nsCOMPtr<nsIRunnable> runner = new NuwaMarkSeerThreadRunner();
+  nsCOMPtr<nsIRunnable> runner = new NuwaMarkPredictorThreadRunner();
   mIOThread->Dispatch(runner, NS_DISPATCH_NORMAL);
 #endif
 
   mSpeculativeService = do_GetService("@mozilla.org/network/io-service;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mDnsService = do_GetService("@mozilla.org/network/dns-service;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -475,17 +488,17 @@ Seer::Init()
   NS_ENSURE_SUCCESS(rv, rv);
 
   mInitialized = true;
 
   return rv;
 }
 
 void
-Seer::CheckForAndDeleteOldDBFile()
+Predictor::CheckForAndDeleteOldDBFile()
 {
   nsCOMPtr<nsIFile> oldDBFile;
   nsresult rv = mDBFile->GetParent(getter_AddRefs(oldDBFile));
   RETURN_IF_FAILED(rv);
 
   rv = oldDBFile->AppendNative(NS_LITERAL_CSTRING("seer.sqlite"));
   RETURN_IF_FAILED(rv);
 
@@ -498,19 +511,20 @@ Seer::CheckForAndDeleteOldDBFile()
   oldDBFile->Remove(false);
 }
 
 // Make sure that our sqlite storage is all set up with all the tables we need
 // to do the work. It isn't the end of the world if this fails, since this is
 // all an optimization, anyway.
 
 nsresult
-Seer::EnsureInitStorage()
+Predictor::EnsureInitStorage()
 {
-  MOZ_ASSERT(!NS_IsMainThread(), "Initializing seer storage on main thread");
+  MOZ_ASSERT(!NS_IsMainThread(),
+             "Initializing predictor storage on main thread");
 
   if (mDB) {
     return NS_OK;
   }
 
   nsresult rv;
 
   CheckForAndDeleteOldDBFile();
@@ -528,52 +542,52 @@ Seer::EnsureInitStorage()
 
   mDB->ExecuteSimpleSQL(NS_LITERAL_CSTRING("PRAGMA synchronous = OFF;"));
   mDB->ExecuteSimpleSQL(NS_LITERAL_CSTRING("PRAGMA foreign_keys = ON;"));
 
   BeginTransaction();
 
   // A table to make sure we're working with the database layout we expect
   rv = mDB->ExecuteSimpleSQL(
-      NS_LITERAL_CSTRING("CREATE TABLE IF NOT EXISTS moz_seer_version (\n"
+      NS_LITERAL_CSTRING("CREATE TABLE IF NOT EXISTS moz_predictor_version (\n"
                          "  version INTEGER NOT NULL\n"
                          ");\n"));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<mozIStorageStatement> stmt;
   rv = mDB->CreateStatement(
-      NS_LITERAL_CSTRING("SELECT version FROM moz_seer_version;\n"),
+      NS_LITERAL_CSTRING("SELECT version FROM moz_predictor_version;\n"),
       getter_AddRefs(stmt));
   NS_ENSURE_SUCCESS(rv, rv);
 
   bool hasRows;
   rv = stmt->ExecuteStep(&hasRows);
   NS_ENSURE_SUCCESS(rv, rv);
   if (hasRows) {
     int32_t currentVersion;
     rv = stmt->GetInt32(0, &currentVersion);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // This is what we do while we only have one schema version. Later, we'll
     // have to change this to actually upgrade things as appropriate.
-    MOZ_ASSERT(currentVersion == SEER_SCHEMA_VERSION,
-               "Invalid seer schema version!");
-    if (currentVersion != SEER_SCHEMA_VERSION) {
+    MOZ_ASSERT(currentVersion == PREDICTOR_SCHEMA_VERSION,
+               "Invalid predictor schema version!");
+    if (currentVersion != PREDICTOR_SCHEMA_VERSION) {
       return NS_ERROR_UNEXPECTED;
     }
   } else {
     stmt = nullptr;
     rv = mDB->CreateStatement(
-        NS_LITERAL_CSTRING("INSERT INTO moz_seer_version (version) VALUES "
-                           "(:seer_version);"),
+        NS_LITERAL_CSTRING("INSERT INTO moz_predictor_version (version) VALUES "
+                           "(:predictor_version);"),
         getter_AddRefs(stmt));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("seer_version"),
-                               SEER_SCHEMA_VERSION);
+    rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("predictor_version"),
+                               PREDICTOR_SCHEMA_VERSION);
     NS_ENSURE_SUCCESS(rv, rv);
 
     stmt->Execute();
   }
 
   stmt = nullptr;
 
   // This table keeps track of the hosts we've seen at the top level of a
@@ -655,17 +669,17 @@ Seer::EnsureInitStorage()
     rv = mDB->CreateStatement(
         NS_LITERAL_CSTRING("UPDATE moz_startups SET startups = :startup_count, "
                            "last_startup = :startup_time;\n"),
         getter_AddRefs(stmt));
     NS_ENSURE_SUCCESS(rv, rv);
 
     int32_t newStartupCount = mStartupCount + 1;
     if (newStartupCount <= 0) {
-      SEER_LOG(("Seer::EnsureInitStorage startup count overflow\n"));
+      PREDICTOR_LOG(("Predictor::EnsureInitStorage startup count overflow\n"));
       newStartupCount = mStartupCount;
       ++mAccumulators->mStartupCountOverflows;
     }
 
     rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("startup_count"),
                                mStartupCount + 1);
     NS_ENSURE_SUCCESS(rv, rv);
 
@@ -782,116 +796,118 @@ Seer::EnsureInitStorage()
   rv = mDB->ExecuteSimpleSQL(
       NS_LITERAL_CSTRING("CREATE INDEX IF NOT EXISTS redirect_id_index "
                          "ON moz_redirects (id);"));
   NS_ENSURE_SUCCESS(rv, rv);
 
   CommitTransaction();
   BeginTransaction();
 
-  nsRefPtr<SeerCommitTimerInitEvent> event = new SeerCommitTimerInitEvent();
+  nsRefPtr<PredictorCommitTimerInitEvent> event =
+    new PredictorCommitTimerInitEvent();
   NS_DispatchToMainThread(event);
 
   return NS_OK;
 }
 
-class SeerThreadShutdownRunner : public nsRunnable
+class PredictorThreadShutdownRunner : public nsRunnable
 {
 public:
-  SeerThreadShutdownRunner(nsIThread *ioThread)
+  PredictorThreadShutdownRunner(nsIThread *ioThread)
     :mIOThread(ioThread)
   { }
 
   NS_IMETHODIMP Run() MOZ_OVERRIDE
   {
-    MOZ_ASSERT(NS_IsMainThread(), "Shut down seer io thread off main thread");
+    MOZ_ASSERT(NS_IsMainThread(),
+               "Shut down predictor io thread off main thread");
     mIOThread->Shutdown();
     return NS_OK;
   }
 
 private:
   nsCOMPtr<nsIThread> mIOThread;
 };
 
-class SeerDBShutdownRunner : public nsRunnable
+class PredictorDBShutdownRunner : public nsRunnable
 {
 public:
-  SeerDBShutdownRunner(nsIThread *ioThread, nsINetworkSeer *seer)
+  PredictorDBShutdownRunner(nsIThread *ioThread, nsINetworkPredictor *predictor)
     :mIOThread(ioThread)
   {
-    mSeer = new nsMainThreadPtrHolder<nsINetworkSeer>(seer);
+    mPredictor = new nsMainThreadPtrHolder<nsINetworkPredictor>(predictor);
   }
 
   NS_IMETHODIMP Run() MOZ_OVERRIDE
   {
     MOZ_ASSERT(!NS_IsMainThread(), "Shutting down DB on main thread");
 
     // Ensure everything is written to disk before we shut down the db
-    gSeer->CommitTransaction();
-
-    gSeer->mStatements.FinalizeStatements();
-    gSeer->mDB->Close();
-    gSeer->mDB = nullptr;
-
-    nsRefPtr<SeerThreadShutdownRunner> runner =
-      new SeerThreadShutdownRunner(mIOThread);
+    gPredictor->CommitTransaction();
+
+    gPredictor->mStatements.FinalizeStatements();
+    gPredictor->mDB->Close();
+    gPredictor->mDB = nullptr;
+
+    nsRefPtr<PredictorThreadShutdownRunner> runner =
+      new PredictorThreadShutdownRunner(mIOThread);
     NS_DispatchToMainThread(runner);
 
     return NS_OK;
   }
 
 private:
   nsCOMPtr<nsIThread> mIOThread;
 
-  // Death grip to keep seer alive while we cleanly close its DB connection
-  nsMainThreadPtrHandle<nsINetworkSeer> mSeer;
+  // Death grip to keep predictor alive while we cleanly close its DB connection
+  nsMainThreadPtrHandle<nsINetworkPredictor> mPredictor;
 };
 
 void
-Seer::Shutdown()
+Predictor::Shutdown()
 {
   if (!NS_IsMainThread()) {
-    MOZ_ASSERT(false, "Seer::Shutdown called off the main thread!");
+    MOZ_ASSERT(false, "Predictor::Shutdown called off the main thread!");
     return;
   }
 
   mInitialized = false;
 
   if (mCommitTimer) {
     mCommitTimer->Cancel();
   }
 
   if (mIOThread) {
     if (mDB) {
-      nsRefPtr<SeerDBShutdownRunner> runner =
-        new SeerDBShutdownRunner(mIOThread, this);
+      nsRefPtr<PredictorDBShutdownRunner> runner =
+        new PredictorDBShutdownRunner(mIOThread, this);
       mIOThread->Dispatch(runner, NS_DISPATCH_NORMAL);
     } else {
-      nsRefPtr<SeerThreadShutdownRunner> runner =
-        new SeerThreadShutdownRunner(mIOThread);
+      nsRefPtr<PredictorThreadShutdownRunner> runner =
+        new PredictorThreadShutdownRunner(mIOThread);
       NS_DispatchToMainThread(runner);
     }
   }
 }
 
 nsresult
-Seer::Create(nsISupports *aOuter, const nsIID& aIID,
-             void **aResult)
+Predictor::Create(nsISupports *aOuter, const nsIID& aIID,
+                  void **aResult)
 {
   nsresult rv;
 
   if (aOuter != nullptr) {
     return NS_ERROR_NO_AGGREGATION;
   }
 
-  nsRefPtr<Seer> svc = new Seer();
+  nsRefPtr<Predictor> svc = new Predictor();
 
   rv = svc->Init();
   if (NS_FAILED(rv)) {
-    SEER_LOG(("Failed to initialize seer, seer will be a noop"));
+    PREDICTOR_LOG(("Failed to initialize predictor, predictor will be a noop"));
   }
 
   // We treat init failure the same as the service being disabled, since this
   // is all an optimization anyway. No need to freak people out. That's why we
   // gladly continue on QI'ing here.
   rv = svc->QueryInterface(aIID, aResult);
 
   return rv;
@@ -922,118 +938,120 @@ ExtractOrigin(nsIURI *uri, nsAutoCString
   if (port != -1) {
     s.Append(':');
     s.AppendInt(port);
   }
 }
 
 // An event to do the work for a prediction that needs to hit the sqlite
 // database. These events should be created on the main thread, and run on
-// the seer thread.
-class SeerPredictionEvent : public nsRunnable
+// the predictor thread.
+class PredictionEvent : public nsRunnable
 {
 public:
-  SeerPredictionEvent(nsIURI *targetURI, nsIURI *sourceURI,
-                      SeerPredictReason reason,
-                      nsINetworkSeerVerifier *verifier)
+  PredictionEvent(nsIURI *targetURI, nsIURI *sourceURI,
+                  PredictorPredictReason reason,
+                  nsINetworkPredictorVerifier *verifier)
     :mReason(reason)
   {
     MOZ_ASSERT(NS_IsMainThread(), "Creating prediction event off main thread");
 
     mEnqueueTime = TimeStamp::Now();
 
     if (verifier) {
-      mVerifier = new nsMainThreadPtrHolder<nsINetworkSeerVerifier>(verifier);
+      mVerifier =
+        new nsMainThreadPtrHolder<nsINetworkPredictorVerifier>(verifier);
     }
     if (targetURI) {
       targetURI->GetAsciiSpec(mTargetURI.spec);
       ExtractOrigin(targetURI, mTargetURI.origin);
     }
     if (sourceURI) {
       sourceURI->GetAsciiSpec(mSourceURI.spec);
       ExtractOrigin(sourceURI, mSourceURI.origin);
     }
   }
 
   NS_IMETHOD Run() MOZ_OVERRIDE
   {
     MOZ_ASSERT(!NS_IsMainThread(), "Running prediction event on main thread");
 
-    Telemetry::AccumulateTimeDelta(Telemetry::SEER_PREDICT_WAIT_TIME,
+    Telemetry::AccumulateTimeDelta(Telemetry::PREDICTOR_PREDICT_WAIT_TIME,
                                    mEnqueueTime);
 
     TimeStamp startTime = TimeStamp::Now();
 
     nsresult rv = NS_OK;
 
     switch (mReason) {
-      case nsINetworkSeer::PREDICT_LOAD:
-        gSeer->PredictForPageload(mTargetURI, mVerifier, 0, mEnqueueTime);
+      case nsINetworkPredictor::PREDICT_LOAD:
+        gPredictor->PredictForPageload(mTargetURI, mVerifier, 0, mEnqueueTime);
         break;
-      case nsINetworkSeer::PREDICT_STARTUP:
-        gSeer->PredictForStartup(mVerifier, mEnqueueTime);
+      case nsINetworkPredictor::PREDICT_STARTUP:
+        gPredictor->PredictForStartup(mVerifier, mEnqueueTime);
         break;
       default:
         MOZ_ASSERT(false, "Got unexpected value for predict reason");
         rv = NS_ERROR_UNEXPECTED;
     }
 
-    gSeer->FreeSpaceInQueue();
-
-    Telemetry::AccumulateTimeDelta(Telemetry::SEER_PREDICT_WORK_TIME,
+    gPredictor->FreeSpaceInQueue();
+
+    Telemetry::AccumulateTimeDelta(Telemetry::PREDICTOR_PREDICT_WORK_TIME,
                                    startTime);
 
-    gSeer->MaybeScheduleCleanup();
+    gPredictor->MaybeScheduleCleanup();
 
     return rv;
   }
 
 private:
-  Seer::UriInfo mTargetURI;
-  Seer::UriInfo mSourceURI;
-  SeerPredictReason mReason;
-  SeerVerifierHandle mVerifier;
+  Predictor::UriInfo mTargetURI;
+  Predictor::UriInfo mSourceURI;
+  PredictorPredictReason mReason;
+  PredictorVerifierHandle mVerifier;
   TimeStamp mEnqueueTime;
 };
 
 // Predicting for a link is easy, and doesn't require the round-trip to the
-// seer thread and back to the main thread, since we don't have to hit the db
-// for that.
+// predictor thread and back to the main thread, since we don't have to hit the
+// db for that.
 void
-Seer::PredictForLink(nsIURI *targetURI, nsIURI *sourceURI,
-                     nsINetworkSeerVerifier *verifier)
+Predictor::PredictForLink(nsIURI *targetURI, nsIURI *sourceURI,
+                          nsINetworkPredictorVerifier *verifier)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Predicting for link off main thread");
 
   if (!mSpeculativeService) {
     return;
   }
 
   if (!mEnableHoverOnSSL) {
     bool isSSL = false;
     sourceURI->SchemeIs("https", &isSSL);
     if (isSSL) {
       // We don't want to predict from an HTTPS page, to avoid info leakage
-      SEER_LOG(("Not predicting for link hover - on an SSL page"));
+      PREDICTOR_LOG(("Not predicting for link hover - on an SSL page"));
       return;
     }
   }
 
   mSpeculativeService->SpeculativeConnect(targetURI, nullptr);
   if (verifier) {
     verifier->OnPredictPreconnect(targetURI);
   }
 }
 
 // This runnable runs on the main thread, and is responsible for actually
 // firing off predictive actions (such as TCP/TLS preconnects and DNS lookups)
-class SeerPredictionRunner : public nsRunnable
+class PredictionRunner : public nsRunnable
 {
 public:
-  SeerPredictionRunner(SeerVerifierHandle &verifier, TimeStamp predictStartTime)
+  PredictionRunner(PredictorVerifierHandle &verifier,
+                   TimeStamp predictStartTime)
     :mVerifier(verifier)
     ,mPredictStartTime(predictStartTime)
   { }
 
   void AddPreconnect(const nsACString &uri)
   {
     mPreconnects.AppendElement(uri);
   }
@@ -1047,114 +1065,115 @@ public:
   {
     return !(mPreconnects.IsEmpty() && mPreresolves.IsEmpty());
   }
 
   NS_IMETHOD Run() MOZ_OVERRIDE
   {
     MOZ_ASSERT(NS_IsMainThread(), "Running prediction off main thread");
 
-    Telemetry::AccumulateTimeDelta(Telemetry::SEER_PREDICT_TIME_TO_ACTION,
+    Telemetry::AccumulateTimeDelta(Telemetry::PREDICTOR_PREDICT_TIME_TO_ACTION,
                                    mPredictStartTime);
 
     uint32_t len, i;
 
     len = mPreconnects.Length();
     for (i = 0; i < len; ++i) {
       nsCOMPtr<nsIURI> uri;
       nsresult rv = NS_NewURI(getter_AddRefs(uri), mPreconnects[i]);
       if (NS_FAILED(rv)) {
         continue;
       }
 
-      ++gSeer->mAccumulators->mTotalPredictions;
-      ++gSeer->mAccumulators->mTotalPreconnects;
-      gSeer->mSpeculativeService->SpeculativeConnect(uri, gSeer);
+      ++gPredictor->mAccumulators->mTotalPredictions;
+      ++gPredictor->mAccumulators->mTotalPreconnects;
+      gPredictor->mSpeculativeService->SpeculativeConnect(uri, gPredictor);
       if (mVerifier) {
         mVerifier->OnPredictPreconnect(uri);
       }
     }
 
     len = mPreresolves.Length();
     nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
     for (i = 0; i < len; ++i) {
       nsCOMPtr<nsIURI> uri;
       nsresult rv = NS_NewURI(getter_AddRefs(uri), mPreresolves[i]);
       if (NS_FAILED(rv)) {
         continue;
       }
 
-      ++gSeer->mAccumulators->mTotalPredictions;
-      ++gSeer->mAccumulators->mTotalPreresolves;
+      ++gPredictor->mAccumulators->mTotalPredictions;
+      ++gPredictor->mAccumulators->mTotalPreresolves;
       nsAutoCString hostname;
       uri->GetAsciiHost(hostname);
       nsCOMPtr<nsICancelable> tmpCancelable;
-      gSeer->mDnsService->AsyncResolve(hostname,
-                                       (nsIDNSService::RESOLVE_PRIORITY_MEDIUM |
-                                        nsIDNSService::RESOLVE_SPECULATE),
-                                       gSeer->mDNSListener, nullptr,
-                                       getter_AddRefs(tmpCancelable));
+      gPredictor->mDnsService->AsyncResolve(hostname,
+                                            (nsIDNSService::RESOLVE_PRIORITY_MEDIUM |
+                                             nsIDNSService::RESOLVE_SPECULATE),
+                                            gPredictor->mDNSListener, nullptr,
+                                            getter_AddRefs(tmpCancelable));
       if (mVerifier) {
         mVerifier->OnPredictDNS(uri);
       }
     }
 
     mPreconnects.Clear();
     mPreresolves.Clear();
 
     return NS_OK;
   }
 
 private:
   nsTArray<nsCString> mPreconnects;
   nsTArray<nsCString> mPreresolves;
-  SeerVerifierHandle mVerifier;
+  PredictorVerifierHandle mVerifier;
   TimeStamp mPredictStartTime;
 };
 
 // This calculates how much to degrade our confidence in our data based on
 // the last time this top-level resource was loaded. This "global degradation"
 // applies to *all* subresources we have associated with the top-level
 // resource. This will be in addition to any reduction in confidence we have
 // associated with a particular subresource.
 int
-Seer::CalculateGlobalDegradation(PRTime now, PRTime lastLoad)
+Predictor::CalculateGlobalDegradation(PRTime now, PRTime lastLoad)
 {
   int globalDegradation;
   PRTime delta = now - lastLoad;
   if (delta < ONE_DAY) {
     globalDegradation = mPageDegradationDay;
   } else if (delta < ONE_WEEK) {
     globalDegradation = mPageDegradationWeek;
   } else if (delta < ONE_MONTH) {
     globalDegradation = mPageDegradationMonth;
   } else if (delta < ONE_YEAR) {
     globalDegradation = mPageDegradationYear;
   } else {
     globalDegradation = mPageDegradationMax;
   }
 
-  Telemetry::Accumulate(Telemetry::SEER_GLOBAL_DEGRADATION, globalDegradation);
+  Telemetry::Accumulate(Telemetry::PREDICTOR_GLOBAL_DEGRADATION,
+                        globalDegradation);
   return globalDegradation;
 }
 
 // This calculates our overall confidence that a particular subresource will be
 // loaded as part of a top-level load.
 // @param baseConfidence - the basic confidence we have for this subresource,
 //                         which is the percentage of time this top-level load
 //                         loads the subresource in question
 // @param lastHit - the timestamp of the last time we loaded this subresource as
 //                  part of this top-level load
 // @param lastPossible - the timestamp of the last time we performed this
 //                       top-level load
 // @param globalDegradation - the degradation for this top-level load as
 //                            determined by CalculateGlobalDegradation
 int
-Seer::CalculateConfidence(int baseConfidence, PRTime lastHit,
-                          PRTime lastPossible, int globalDegradation)
+Predictor::CalculateConfidence(int baseConfidence, PRTime lastHit,
+                               PRTime lastPossible, int globalDegradation)
 {
   ++mAccumulators->mPredictionsCalculated;
 
   int maxConfidence = 100;
   int confidenceDegradation = 0;
 
   if (lastHit < lastPossible) {
     // We didn't load this subresource the last time this top-level load was
@@ -1182,42 +1201,42 @@ Seer::CalculateConfidence(int baseConfid
   }
 
   // Calculate our confidence and clamp it to between 0 and maxConfidence
   // (<= 100)
   int confidence = baseConfidence - confidenceDegradation - globalDegradation;
   confidence = std::max(confidence, 0);
   confidence = std::min(confidence, maxConfidence);
 
-  Telemetry::Accumulate(Telemetry::SEER_BASE_CONFIDENCE, baseConfidence);
-  Telemetry::Accumulate(Telemetry::SEER_SUBRESOURCE_DEGRADATION,
+  Telemetry::Accumulate(Telemetry::PREDICTOR_BASE_CONFIDENCE, baseConfidence);
+  Telemetry::Accumulate(Telemetry::PREDICTOR_SUBRESOURCE_DEGRADATION,
                         confidenceDegradation);
-  Telemetry::Accumulate(Telemetry::SEER_CONFIDENCE, confidence);
+  Telemetry::Accumulate(Telemetry::PREDICTOR_CONFIDENCE, confidence);
   return confidence;
 }
 
 // (Maybe) adds a predictive action to the prediction runner, based on our
 // calculated confidence for the subresource in question.
 void
-Seer::SetupPrediction(int confidence, const nsACString &uri,
-                      SeerPredictionRunner *runner)
+Predictor::SetupPrediction(int confidence, const nsACString &uri,
+                           PredictionRunner *runner)
 {
     if (confidence >= mPreconnectMinConfidence) {
       runner->AddPreconnect(uri);
     } else if (confidence >= mPreresolveMinConfidence) {
       runner->AddPreresolve(uri);
     }
 }
 
 // This gets the data about the top-level load from our database, either from
 // the pages table (which is specific to a particular URI), or from the hosts
 // table (which is for a particular origin).
 bool
-Seer::LookupTopLevel(QueryType queryType, const nsACString &key,
-                     TopLevelInfo &info)
+Predictor::LookupTopLevel(QueryType queryType, const nsACString &key,
+                          TopLevelInfo &info)
 {
   MOZ_ASSERT(!NS_IsMainThread(), "LookupTopLevel called on main thread.");
 
   nsCOMPtr<mozIStorageStatement> stmt;
   if (queryType == QUERY_PAGE) {
     stmt = mStatements.GetCachedStatement(
         NS_LITERAL_CSTRING("SELECT id, loads, last_load FROM moz_pages WHERE "
                            "uri = :key;"));
@@ -1250,17 +1269,17 @@ Seer::LookupTopLevel(QueryType queryType
   NS_ENSURE_SUCCESS(rv, false);
 
   return true;
 }
 
 // Insert data about either a top-level page or a top-level origin into
 // the database.
 void
-Seer::AddTopLevel(QueryType queryType, const nsACString &key, PRTime now)
+Predictor::AddTopLevel(QueryType queryType, const nsACString &key, PRTime now)
 {
   MOZ_ASSERT(!NS_IsMainThread(), "AddTopLevel called on main thread.");
 
   nsCOMPtr<mozIStorageStatement> stmt;
   if (queryType == QUERY_PAGE) {
     stmt = mStatements.GetCachedStatement(
         NS_LITERAL_CSTRING("INSERT INTO moz_pages (uri, loads, last_load) "
                            "VALUES (:key, 1, :now);"));
@@ -1269,31 +1288,32 @@ Seer::AddTopLevel(QueryType queryType, c
         NS_LITERAL_CSTRING("INSERT INTO moz_hosts (origin, loads, last_load) "
                            "VALUES (:key, 1, :now);"));
   }
   if (!stmt) {
     return;
   }
   mozStorageStatementScoper scope(stmt);
 
-  // Loading a page implicitly makes the seer learn about the page,
+  // Loading a page implicitly makes the predictor learn about the page,
   // so since we don't have it already, let's add it.
   nsresult rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("key"), key);
   RETURN_IF_FAILED(rv);
 
   rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("now"), now);
   RETURN_IF_FAILED(rv);
 
   rv = stmt->Execute();
 }
 
 // Update data about either a top-level page or a top-level origin in the
 // database.
 void
-Seer::UpdateTopLevel(QueryType queryType, const TopLevelInfo &info, PRTime now)
+Predictor::UpdateTopLevel(QueryType queryType, const TopLevelInfo &info,
+                          PRTime now)
 {
   MOZ_ASSERT(!NS_IsMainThread(), "UpdateTopLevel called on main thread.");
 
   nsCOMPtr<mozIStorageStatement> stmt;
   if (queryType == QUERY_PAGE) {
     stmt = mStatements.GetCachedStatement(
         NS_LITERAL_CSTRING("UPDATE moz_pages SET loads = :load_count, "
                            "last_load = :now WHERE id = :id;"));
@@ -1304,18 +1324,18 @@ Seer::UpdateTopLevel(QueryType queryType
   }
   if (!stmt) {
     return;
   }
   mozStorageStatementScoper scope(stmt);
 
   int32_t newLoadCount = info.loadCount + 1;
   if (newLoadCount <= 0) {
-    SEER_LOG(("Seer::UpdateTopLevel type %d id %d load count overflow\n",
-              queryType, info.id));
+    PREDICTOR_LOG(("Predictor::UpdateTopLevel type %d id %d load count "
+                   "overflow\n", queryType, info.id));
     newLoadCount = info.loadCount;
     ++mAccumulators->mLoadCountOverflows;
   }
 
   // First, let's update the page in the database, since loading a page
   // implicitly learns about the page.
   nsresult rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("load_count"),
                                       newLoadCount);
@@ -1331,23 +1351,24 @@ Seer::UpdateTopLevel(QueryType queryType
 }
 
 // Tries to predict for a top-level load (either page-based or origin-based).
 // Returns false if it failed to predict at all, true if it did some sort of
 // prediction.
 // @param queryType - whether to predict based on page or origin
 // @param info - the db info about the top-level resource
 bool
-Seer::TryPredict(QueryType queryType, const TopLevelInfo &info, PRTime now,
-                 SeerVerifierHandle &verifier, TimeStamp &predictStartTime)
+Predictor::TryPredict(QueryType queryType, const TopLevelInfo &info, PRTime now,
+                      PredictorVerifierHandle &verifier,
+                      TimeStamp &predictStartTime)
 {
   MOZ_ASSERT(!NS_IsMainThread(), "TryPredict called on main thread.");
 
   if (!info.loadCount) {
-    SEER_LOG(("Seer::TryPredict info.loadCount is zero!\n"));
+    PREDICTOR_LOG(("Predictor::TryPredict info.loadCount is zero!\n"));
     ++mAccumulators->mLoadCountZeroes;
     return false;
   }
 
   int globalDegradation = CalculateGlobalDegradation(now, info.lastLoad);
 
   // Now let's look up the subresources we know about for this page
   nsCOMPtr<mozIStorageStatement> stmt;
@@ -1367,18 +1388,18 @@ Seer::TryPredict(QueryType queryType, co
   NS_ENSURE_SUCCESS(rv, false);
 
   bool hasRows;
   rv = stmt->ExecuteStep(&hasRows);
   if (NS_FAILED(rv) || !hasRows) {
     return false;
   }
 
-  nsRefPtr<SeerPredictionRunner> runner =
-    new SeerPredictionRunner(verifier, predictStartTime);
+  nsRefPtr<PredictionRunner> runner =
+    new PredictionRunner(verifier, predictStartTime);
 
   while (hasRows) {
     int32_t hitCount;
     PRTime lastHit;
     nsAutoCString subresource;
     int baseConfidence, confidence;
 
     // We use goto nextrow here instead of just failing, because we want
@@ -1418,22 +1439,22 @@ nextrow:
     predicted = true;
   }
 
   return predicted;
 }
 
 // Find out if a top-level page is likely to redirect.
 bool
-Seer::WouldRedirect(const TopLevelInfo &info, PRTime now, UriInfo &newUri)
+Predictor::WouldRedirect(const TopLevelInfo &info, PRTime now, UriInfo &newUri)
 {
   MOZ_ASSERT(!NS_IsMainThread(), "WouldRedirect called on main thread.");
 
   if (!info.loadCount) {
-    SEER_LOG(("Seer::WouldRedirect info.loadCount is zero!\n"));
+    PREDICTOR_LOG(("Predictor::WouldRedirect info.loadCount is zero!\n"));
     ++mAccumulators->mLoadCountZeroes;
     return false;
   }
 
   nsCOMPtr<mozIStorageStatement> stmt = mStatements.GetCachedStatement(
       NS_LITERAL_CSTRING("SELECT uri, origin, hits, last_hit "
                          "FROM moz_redirects WHERE pid = :id;"));
   NS_ENSURE_TRUE(stmt, false);
@@ -1472,36 +1493,37 @@ Seer::WouldRedirect(const TopLevelInfo &
   }
 
   return false;
 }
 
 // This will add a page to our list of startup pages if it's being loaded
 // before our startup window has expired.
 void
-Seer::MaybeLearnForStartup(const UriInfo &uri, const PRTime now)
+Predictor::MaybeLearnForStartup(const UriInfo &uri, const PRTime now)
 {
   MOZ_ASSERT(!NS_IsMainThread(), "MaybeLearnForStartup called on main thread.");
 
   if ((now - mStartupTime) < STARTUP_WINDOW) {
     LearnForStartup(uri);
   }
 }
 
 const int MAX_PAGELOAD_DEPTH = 10;
 
 // This is the driver for prediction based on a new pageload.
 void
-Seer::PredictForPageload(const UriInfo &uri, SeerVerifierHandle &verifier,
-                         int stackCount, TimeStamp &predictStartTime)
+Predictor::PredictForPageload(const UriInfo &uri,
+                              PredictorVerifierHandle &verifier,
+                              int stackCount, TimeStamp &predictStartTime)
 {
   MOZ_ASSERT(!NS_IsMainThread(), "PredictForPageload called on main thread.");
 
   if (stackCount > MAX_PAGELOAD_DEPTH) {
-    SEER_LOG(("Too deep into pageload prediction"));
+    PREDICTOR_LOG(("Too deep into pageload prediction"));
     return;
   }
 
   if (NS_FAILED(EnsureInitStorage())) {
     return;
   }
 
   PRTime now = PR_Now();
@@ -1522,18 +1544,18 @@ Seer::PredictForPageload(const UriInfo &
   if (!haveOrigin) {
     AddTopLevel(QUERY_ORIGIN, uri.origin, now);
   } else {
     UpdateTopLevel(QUERY_ORIGIN, originInfo, now);
   }
 
   UriInfo newUri;
   if (havePage && WouldRedirect(pageInfo, now, newUri)) {
-    nsRefPtr<SeerPredictionRunner> runner =
-      new SeerPredictionRunner(verifier, predictStartTime);
+    nsRefPtr<PredictionRunner> runner =
+      new PredictionRunner(verifier, predictStartTime);
     runner->AddPreconnect(newUri.spec);
     NS_DispatchToMainThread(runner);
     PredictForPageload(newUri, verifier, stackCount + 1, predictStartTime);
     return;
   }
 
   bool predicted = false;
 
@@ -1545,31 +1567,32 @@ Seer::PredictForPageload(const UriInfo &
   }
 
   if (!predicted && haveOrigin) {
     predicted = TryPredict(QUERY_ORIGIN, originInfo, now, verifier,
                            predictStartTime);
   }
 
   if (!predicted) {
-    Telemetry::AccumulateTimeDelta(Telemetry::SEER_PREDICT_TIME_TO_INACTION,
-                                   predictStartTime);
+    Telemetry::AccumulateTimeDelta(
+      Telemetry::PREDICTOR_PREDICT_TIME_TO_INACTION,
+      predictStartTime);
   }
 }
 
 // This is the driver for predicting at browser startup time based on pages that
 // have previously been loaded close to startup.
 void
-Seer::PredictForStartup(SeerVerifierHandle &verifier,
-                        TimeStamp &predictStartTime)
+Predictor::PredictForStartup(PredictorVerifierHandle &verifier,
+                             TimeStamp &predictStartTime)
 {
   MOZ_ASSERT(!NS_IsMainThread(), "PredictForStartup called on main thread");
 
   if (!mStartupCount) {
-    SEER_LOG(("Seer::PredictForStartup mStartupCount is zero!\n"));
+    PREDICTOR_LOG(("Predictor::PredictForStartup mStartupCount is zero!\n"));
     ++mAccumulators->mStartupCountZeroes;
     return;
   }
 
   if (NS_FAILED(EnsureInitStorage())) {
     return;
   }
 
@@ -1577,18 +1600,18 @@ Seer::PredictForStartup(SeerVerifierHand
       NS_LITERAL_CSTRING("SELECT uri, hits, last_hit FROM moz_startup_pages;"));
   if (!stmt) {
     return;
   }
   mozStorageStatementScoper scope(stmt);
   nsresult rv;
   bool hasRows;
 
-  nsRefPtr<SeerPredictionRunner> runner =
-    new SeerPredictionRunner(verifier, predictStartTime);
+  nsRefPtr<PredictionRunner> runner =
+    new PredictionRunner(verifier, predictStartTime);
 
   rv = stmt->ExecuteStep(&hasRows);
   RETURN_IF_FAILED(rv);
 
   while (hasRows) {
     nsAutoCString uri;
     int32_t hitCount;
     PRTime lastHit;
@@ -1622,18 +1645,19 @@ Seer::PredictForStartup(SeerVerifierHand
 nextrow:
     rv = stmt->ExecuteStep(&hasRows);
     RETURN_IF_FAILED(rv);
   }
 
   if (runner->HasWork()) {
     NS_DispatchToMainThread(runner);
   } else {
-    Telemetry::AccumulateTimeDelta(Telemetry::SEER_PREDICT_TIME_TO_INACTION,
-                                   predictStartTime);
+    Telemetry::AccumulateTimeDelta(
+      Telemetry::PREDICTOR_PREDICT_TIME_TO_INACTION,
+      predictStartTime);
   }
 }
 
 // All URIs we get passed *must* be http or https if they're not null. This
 // helps ensure that.
 static bool
 IsNullOrHttp(nsIURI *uri)
 {
@@ -1646,44 +1670,46 @@ IsNullOrHttp(nsIURI *uri)
   if (!isHTTP) {
     uri->SchemeIs("https", &isHTTP);
   }
 
   return isHTTP;
 }
 
 nsresult
-Seer::ReserveSpaceInQueue()
+Predictor::ReserveSpaceInQueue()
 {
   MutexAutoLock lock(mQueueSizeLock);
 
   if (mQueueSize >= mMaxQueueSize) {
-    SEER_LOG(("Not enqueuing event - queue too large"));
+    PREDICTOR_LOG(("Not enqueuing event - queue too large"));
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   mQueueSize++;
   return NS_OK;
 }
 
 void
-Seer::FreeSpaceInQueue()
+Predictor::FreeSpaceInQueue()
 {
   MutexAutoLock lock(mQueueSizeLock);
   MOZ_ASSERT(mQueueSize > 0, "unexpected mQueueSize");
   mQueueSize--;
 }
 
 // Called from the main thread to initiate predictive actions
 NS_IMETHODIMP
-Seer::Predict(nsIURI *targetURI, nsIURI *sourceURI, SeerPredictReason reason,
-              nsILoadContext *loadContext, nsINetworkSeerVerifier *verifier)
+Predictor::Predict(nsIURI *targetURI, nsIURI *sourceURI,
+                   PredictorPredictReason reason,
+                   nsILoadContext *loadContext,
+                   nsINetworkPredictorVerifier *verifier)
 {
   MOZ_ASSERT(NS_IsMainThread(),
-             "Seer interface methods must be called on the main thread");
+             "Predictor interface methods must be called on the main thread");
 
   if (!mInitialized) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   if (!mEnabled) {
     return NS_ERROR_NOT_AVAILABLE;
   }
@@ -1696,58 +1722,58 @@ Seer::Predict(nsIURI *targetURI, nsIURI 
   if (!IsNullOrHttp(targetURI) || !IsNullOrHttp(sourceURI)) {
     // Nothing we can do for non-HTTP[S] schemes
     return NS_OK;
   }
 
   // Ensure we've been given the appropriate arguments for the kind of
   // prediction we're being asked to do
   switch (reason) {
-    case nsINetworkSeer::PREDICT_LINK:
+    case nsINetworkPredictor::PREDICT_LINK:
       if (!targetURI || !sourceURI) {
         return NS_ERROR_INVALID_ARG;
       }
       // Link hover is a special case where we can predict without hitting the
       // db, so let's go ahead and fire off that prediction here.
       PredictForLink(targetURI, sourceURI, verifier);
       return NS_OK;
-    case nsINetworkSeer::PREDICT_LOAD:
+    case nsINetworkPredictor::PREDICT_LOAD:
       if (!targetURI || sourceURI) {
         return NS_ERROR_INVALID_ARG;
       }
       break;
-    case nsINetworkSeer::PREDICT_STARTUP:
+    case nsINetworkPredictor::PREDICT_STARTUP:
       if (targetURI || sourceURI) {
         return NS_ERROR_INVALID_ARG;
       }
       break;
     default:
       return NS_ERROR_INVALID_ARG;
   }
 
   ++mAccumulators->mPredictAttempts;
   nsresult rv = ReserveSpaceInQueue();
   if (NS_FAILED(rv)) {
     ++mAccumulators->mPredictFullQueue;
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  nsRefPtr<SeerPredictionEvent> event = new SeerPredictionEvent(targetURI,
-                                                                sourceURI,
-                                                                reason,
-                                                                verifier);
+  nsRefPtr<PredictionEvent> event = new PredictionEvent(targetURI,
+                                                        sourceURI,
+                                                        reason,
+                                                        verifier);
   return mIOThread->Dispatch(event, NS_DISPATCH_NORMAL);
 }
 
 // A runnable for updating our information in the database. This must always
-// be dispatched to the seer thread.
-class SeerLearnEvent : public nsRunnable
+// be dispatched to the predictor thread.
+class LearnEvent : public nsRunnable
 {
 public:
-  SeerLearnEvent(nsIURI *targetURI, nsIURI *sourceURI, SeerLearnReason reason)
+  LearnEvent(nsIURI *targetURI, nsIURI *sourceURI, PredictorLearnReason reason)
     :mReason(reason)
   {
     MOZ_ASSERT(NS_IsMainThread(), "Creating learn event off main thread");
 
     mEnqueueTime = TimeStamp::Now();
 
     targetURI->GetAsciiSpec(mTargetURI.spec);
     ExtractOrigin(targetURI, mTargetURI.origin);
@@ -1758,56 +1784,57 @@ public:
   }
 
   NS_IMETHOD Run() MOZ_OVERRIDE
   {
     MOZ_ASSERT(!NS_IsMainThread(), "Running learn off main thread");
 
     nsresult rv = NS_OK;
 
-    Telemetry::AccumulateTimeDelta(Telemetry::SEER_LEARN_WAIT_TIME,
+    Telemetry::AccumulateTimeDelta(Telemetry::PREDICTOR_LEARN_WAIT_TIME,
                                    mEnqueueTime);
 
     TimeStamp startTime = TimeStamp::Now();
 
     switch (mReason) {
-    case nsINetworkSeer::LEARN_LOAD_TOPLEVEL:
-      gSeer->LearnForToplevel(mTargetURI);
+    case nsINetworkPredictor::LEARN_LOAD_TOPLEVEL:
+      gPredictor->LearnForToplevel(mTargetURI);
       break;
-    case nsINetworkSeer::LEARN_LOAD_REDIRECT:
-      gSeer->LearnForRedirect(mTargetURI, mSourceURI);
+    case nsINetworkPredictor::LEARN_LOAD_REDIRECT:
+      gPredictor->LearnForRedirect(mTargetURI, mSourceURI);
       break;
-    case nsINetworkSeer::LEARN_LOAD_SUBRESOURCE:
-      gSeer->LearnForSubresource(mTargetURI, mSourceURI);
+    case nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE:
+      gPredictor->LearnForSubresource(mTargetURI, mSourceURI);
       break;
-    case nsINetworkSeer::LEARN_STARTUP:
-      gSeer->LearnForStartup(mTargetURI);
+    case nsINetworkPredictor::LEARN_STARTUP:
+      gPredictor->LearnForStartup(mTargetURI);
       break;
     default:
       MOZ_ASSERT(false, "Got unexpected value for learn reason");
       rv = NS_ERROR_UNEXPECTED;
     }
 
-    gSeer->FreeSpaceInQueue();
-
-    Telemetry::AccumulateTimeDelta(Telemetry::SEER_LEARN_WORK_TIME, startTime);
-
-    gSeer->MaybeScheduleCleanup();
+    gPredictor->FreeSpaceInQueue();
+
+    Telemetry::AccumulateTimeDelta(Telemetry::PREDICTOR_LEARN_WORK_TIME,
+                                   startTime);
+
+    gPredictor->MaybeScheduleCleanup();
 
     return rv;
   }
 private:
-  Seer::UriInfo mTargetURI;
-  Seer::UriInfo mSourceURI;
-  SeerLearnReason mReason;
+  Predictor::UriInfo mTargetURI;
+  Predictor::UriInfo mSourceURI;
+  PredictorLearnReason mReason;
   TimeStamp mEnqueueTime;
 };
 
 void
-Seer::LearnForToplevel(const UriInfo &uri)
+Predictor::LearnForToplevel(const UriInfo &uri)
 {
   MOZ_ASSERT(!NS_IsMainThread(), "LearnForToplevel called on main thread.");
 
   if (NS_FAILED(EnsureInitStorage())) {
     return;
   }
 
   PRTime now = PR_Now();
@@ -1830,18 +1857,18 @@ Seer::LearnForToplevel(const UriInfo &ur
   } else {
     UpdateTopLevel(QUERY_ORIGIN, originInfo, now);
   }
 }
 
 // Queries to look up information about a *specific* subresource associated
 // with a *specific* top-level load.
 bool
-Seer::LookupSubresource(QueryType queryType, const int32_t parentId,
-                        const nsACString &key, SubresourceInfo &info)
+Predictor::LookupSubresource(QueryType queryType, const int32_t parentId,
+                             const nsACString &key, SubresourceInfo &info)
 {
   MOZ_ASSERT(!NS_IsMainThread(), "LookupSubresource called on main thread.");
 
   nsCOMPtr<mozIStorageStatement> stmt;
   if (queryType == QUERY_PAGE) {
     stmt = mStatements.GetCachedStatement(
         NS_LITERAL_CSTRING("SELECT id, hits, last_hit FROM moz_subresources "
                            "WHERE pid = :parent_id AND uri = :key;"));
@@ -1876,18 +1903,18 @@ Seer::LookupSubresource(QueryType queryT
   rv = stmt->GetInt64(2, &info.lastHit);
   NS_ENSURE_SUCCESS(rv, false);
 
   return true;
 }
 
 // Add information about a new subresource associated with a top-level load.
 void
-Seer::AddSubresource(QueryType queryType, const int32_t parentId,
-                     const nsACString &key, const PRTime now)
+Predictor::AddSubresource(QueryType queryType, const int32_t parentId,
+                          const nsACString &key, const PRTime now)
 {
   MOZ_ASSERT(!NS_IsMainThread(), "AddSubresource called on main thread.");
 
   nsCOMPtr<mozIStorageStatement> stmt;
   if (queryType == QUERY_PAGE) {
     stmt = mStatements.GetCachedStatement(
         NS_LITERAL_CSTRING("INSERT INTO moz_subresources "
                            "(pid, uri, hits, last_hit) VALUES "
@@ -1914,18 +1941,18 @@ Seer::AddSubresource(QueryType queryType
   RETURN_IF_FAILED(rv);
 
   rv = stmt->Execute();
 }
 
 // Update the information about a particular subresource associated with a
 // top-level load
 void
-Seer::UpdateSubresource(QueryType queryType, const SubresourceInfo &info,
-                        const PRTime now, const int32_t parentCount)
+Predictor::UpdateSubresource(QueryType queryType, const SubresourceInfo &info,
+                             const PRTime now, const int32_t parentCount)
 {
   MOZ_ASSERT(!NS_IsMainThread(), "UpdateSubresource called on main thread.");
 
   nsCOMPtr<mozIStorageStatement> stmt;
   if (queryType == QUERY_PAGE) {
     stmt = mStatements.GetCachedStatement(
         NS_LITERAL_CSTRING("UPDATE moz_subresources SET hits = :hit_count, "
                            "last_hit = :now WHERE id = :id;"));
@@ -1954,17 +1981,18 @@ Seer::UpdateSubresource(QueryType queryT
   RETURN_IF_FAILED(rv);
 
   rv = stmt->Execute();
 }
 
 // Called when a subresource has been hit from a top-level load. Uses the two
 // helper functions above to update the database appropriately.
 void
-Seer::LearnForSubresource(const UriInfo &targetURI, const UriInfo &sourceURI)
+Predictor::LearnForSubresource(const UriInfo &targetURI,
+                               const UriInfo &sourceURI)
 {
   MOZ_ASSERT(!NS_IsMainThread(), "LearnForSubresource called on main thread.");
 
   if (NS_FAILED(EnsureInitStorage())) {
     return;
   }
 
   TopLevelInfo pageInfo, originInfo;
@@ -2004,17 +2032,17 @@ Seer::LearnForSubresource(const UriInfo 
     AddSubresource(QUERY_ORIGIN, originInfo.id, targetURI.origin, originInfo.lastLoad);
   }
   // Can't add a subhost to a host we don't have in our db
 }
 
 // This is called when a top-level loaded ended up redirecting to a different
 // URI so we can keep track of that fact.
 void
-Seer::LearnForRedirect(const UriInfo &targetURI, const UriInfo &sourceURI)
+Predictor::LearnForRedirect(const UriInfo &targetURI, const UriInfo &sourceURI)
 {
   MOZ_ASSERT(!NS_IsMainThread(), "LearnForRedirect called on main thread.");
 
   if (NS_FAILED(EnsureInitStorage())) {
     return;
   }
 
   PRTime now = PR_Now();
@@ -2114,17 +2142,17 @@ Seer::LearnForRedirect(const UriInfo &ta
     RETURN_IF_FAILED(rv);
 
     updateRedirect->Execute();
   }
 }
 
 // Add information about a top-level load to our list of startup pages
 void
-Seer::LearnForStartup(const UriInfo &uri)
+Predictor::LearnForStartup(const UriInfo &uri)
 {
   MOZ_ASSERT(!NS_IsMainThread(), "LearnForStartup called on main thread.");
 
   if (NS_FAILED(EnsureInitStorage())) {
     return;
   }
 
   nsCOMPtr<mozIStorageStatement> getPage = mStatements.GetCachedStatement(
@@ -2191,21 +2219,22 @@ Seer::LearnForStartup(const UriInfo &uri
     RETURN_IF_FAILED(rv);
 
     addPage->Execute();
   }
 }
 
 // Called from the main thread to update the database
 NS_IMETHODIMP
-Seer::Learn(nsIURI *targetURI, nsIURI *sourceURI, SeerLearnReason reason,
-            nsILoadContext *loadContext)
+Predictor::Learn(nsIURI *targetURI, nsIURI *sourceURI,
+                 PredictorLearnReason reason,
+                 nsILoadContext *loadContext)
 {
   MOZ_ASSERT(NS_IsMainThread(),
-             "Seer interface methods must be called on the main thread");
+             "Predictor interface methods must be called on the main thread");
 
   if (!mInitialized) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   if (!mEnabled) {
     return NS_ERROR_NOT_AVAILABLE;
   }
@@ -2215,65 +2244,64 @@ Seer::Learn(nsIURI *targetURI, nsIURI *s
     return NS_OK;
   }
 
   if (!IsNullOrHttp(targetURI) || !IsNullOrHttp(sourceURI)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   switch (reason) {
-  case nsINetworkSeer::LEARN_LOAD_TOPLEVEL:
-  case nsINetworkSeer::LEARN_STARTUP:
+  case nsINetworkPredictor::LEARN_LOAD_TOPLEVEL:
+  case nsINetworkPredictor::LEARN_STARTUP:
     if (!targetURI || sourceURI) {
       return NS_ERROR_INVALID_ARG;
     }
     break;
-  case nsINetworkSeer::LEARN_LOAD_REDIRECT:
-  case nsINetworkSeer::LEARN_LOAD_SUBRESOURCE:
+  case nsINetworkPredictor::LEARN_LOAD_REDIRECT:
+  case nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE:
     if (!targetURI || !sourceURI) {
       return NS_ERROR_INVALID_ARG;
     }
     break;
   default:
     return NS_ERROR_INVALID_ARG;
   }
 
   ++mAccumulators->mLearnAttempts;
   nsresult rv = ReserveSpaceInQueue();
   if (NS_FAILED(rv)) {
     ++mAccumulators->mLearnFullQueue;
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  nsRefPtr<SeerLearnEvent> event = new SeerLearnEvent(targetURI, sourceURI,
-                                                      reason);
+  nsRefPtr<LearnEvent> event = new LearnEvent(targetURI, sourceURI, reason);
   return mIOThread->Dispatch(event, NS_DISPATCH_NORMAL);
 }
 
 // Runnable to clear out the database. Dispatched from the main thread to the
-// seer thread
-class SeerResetEvent : public nsRunnable
+// predictor thread
+class PredictorResetEvent : public nsRunnable
 {
 public:
-  SeerResetEvent()
+  PredictorResetEvent()
   { }
 
   NS_IMETHOD Run() MOZ_OVERRIDE
   {
     MOZ_ASSERT(!NS_IsMainThread(), "Running reset on main thread");
 
-    gSeer->ResetInternal();
+    gPredictor->ResetInternal();
 
     return NS_OK;
   }
 };
 
 // Helper that actually does the database wipe.
 void
-Seer::ResetInternal()
+Predictor::ResetInternal()
 {
   MOZ_ASSERT(!NS_IsMainThread(), "Resetting db on main thread");
 
   nsresult rv = EnsureInitStorage();
   RETURN_IF_FAILED(rv);
 
   mDB->ExecuteSimpleSQL(NS_LITERAL_CSTRING("DELETE FROM moz_redirects;"));
   mDB->ExecuteSimpleSQL(NS_LITERAL_CSTRING("DELETE FROM moz_startup_pages;"));
@@ -2287,53 +2315,53 @@ Seer::ResetInternal()
 
   // Go ahead and ensure this is flushed to disk
   CommitTransaction();
   BeginTransaction();
 }
 
 // Called on the main thread to clear out all our knowledge. Tabula Rasa FTW!
 NS_IMETHODIMP
-Seer::Reset()
+Predictor::Reset()
 {
   MOZ_ASSERT(NS_IsMainThread(),
-             "Seer interface methods must be called on the main thread");
+             "Predictor interface methods must be called on the main thread");
 
   if (!mInitialized) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   if (!mEnabled) {
     return NS_OK;
   }
 
-  nsRefPtr<SeerResetEvent> event = new SeerResetEvent();
+  nsRefPtr<PredictorResetEvent> event = new PredictorResetEvent();
   return mIOThread->Dispatch(event, NS_DISPATCH_NORMAL);
 }
 
-class SeerCleanupEvent : public nsRunnable
+class PredictorCleanupEvent : public nsRunnable
 {
 public:
   NS_IMETHOD Run() MOZ_OVERRIDE
   {
-    gSeer->Cleanup();
-    gSeer->mCleanupScheduled = false;
+    gPredictor->Cleanup();
+    gPredictor->mCleanupScheduled = false;
     return NS_OK;
   }
 };
 
 // Returns the current size (in bytes) of the db file on disk
 int64_t
-Seer::GetDBFileSize()
+Predictor::GetDBFileSize()
 {
   MOZ_ASSERT(!NS_IsMainThread(), "GetDBFileSize called on main thread!");
 
   nsresult rv = EnsureInitStorage();
   if (NS_FAILED(rv)) {
-    SEER_LOG(("GetDBFileSize called without db available!"));
+    PREDICTOR_LOG(("GetDBFileSize called without db available!"));
     return 0;
   }
 
   CommitTransaction();
 
   nsCOMPtr<mozIStorageStatement> countStmt = mStatements.GetCachedStatement(
       NS_LITERAL_CSTRING("PRAGMA page_count;"));
   if (!countStmt) {
@@ -2370,19 +2398,20 @@ Seer::GetDBFileSize()
   BeginTransaction();
 
   return pageCount * pageSize;
 }
 
 // Returns the size (in bytes) that the db file will consume on disk AFTER we
 // vacuum the db.
 int64_t
-Seer::GetDBFileSizeAfterVacuum()
+Predictor::GetDBFileSizeAfterVacuum()
 {
-  MOZ_ASSERT(!NS_IsMainThread(), "GetDBFileSizeAfterVacuum called on main thread!");
+  MOZ_ASSERT(!NS_IsMainThread(),
+             "GetDBFileSizeAfterVacuum called on main thread!");
 
   CommitTransaction();
 
   nsCOMPtr<mozIStorageStatement> countStmt = mStatements.GetCachedStatement(
       NS_LITERAL_CSTRING("PRAGMA page_count;"));
   if (!countStmt) {
     return 0;
   }
@@ -2431,57 +2460,57 @@ Seer::GetDBFileSizeAfterVacuum()
   }
 
   BeginTransaction();
 
   return (pageCount - freelistCount) * pageSize;
 }
 
 void
-Seer::MaybeScheduleCleanup()
+Predictor::MaybeScheduleCleanup()
 {
   MOZ_ASSERT(!NS_IsMainThread(), "MaybeScheduleCleanup called on main thread!");
 
   // This is a little racy, but it's a nice little shutdown optimization if the
   // race works out the right way.
   if (!mInitialized) {
     return;
   }
 
   if (mCleanupScheduled) {
-    Telemetry::Accumulate(Telemetry::SEER_CLEANUP_SCHEDULED, false);
+    Telemetry::Accumulate(Telemetry::PREDICTOR_CLEANUP_SCHEDULED, false);
     return;
   }
 
   int64_t dbFileSize = GetDBFileSize();
   if (dbFileSize < mMaxDBSize) {
-    Telemetry::Accumulate(Telemetry::SEER_CLEANUP_SCHEDULED, false);
+    Telemetry::Accumulate(Telemetry::PREDICTOR_CLEANUP_SCHEDULED, false);
     return;
   }
 
   mCleanupScheduled = true;
 
-  nsRefPtr<SeerCleanupEvent> event = new SeerCleanupEvent();
+  nsRefPtr<PredictorCleanupEvent> event = new PredictorCleanupEvent();
   nsresult rv = mIOThread->Dispatch(event, NS_DISPATCH_NORMAL);
   if (NS_FAILED(rv)) {
     mCleanupScheduled = false;
-    Telemetry::Accumulate(Telemetry::SEER_CLEANUP_SCHEDULED, false);
+    Telemetry::Accumulate(Telemetry::PREDICTOR_CLEANUP_SCHEDULED, false);
   } else {
-    Telemetry::Accumulate(Telemetry::SEER_CLEANUP_SCHEDULED, true);
+    Telemetry::Accumulate(Telemetry::PREDICTOR_CLEANUP_SCHEDULED, true);
   }
 }
 
 #ifndef ANDROID
 static const long long CLEANUP_CUTOFF = ONE_MONTH;
 #else
 static const long long CLEANUP_CUTOFF = ONE_WEEK;
 #endif
 
 void
-Seer::CleanupOrigins(PRTime now)
+Predictor::CleanupOrigins(PRTime now)
 {
   PRTime cutoff = now - CLEANUP_CUTOFF;
 
   nsCOMPtr<mozIStorageStatement> deleteOrigins = mStatements.GetCachedStatement(
       NS_LITERAL_CSTRING("DELETE FROM moz_hosts WHERE last_load <= :cutoff"));
   if (!deleteOrigins) {
     return;
   }
@@ -2490,17 +2519,17 @@ Seer::CleanupOrigins(PRTime now)
   nsresult rv = deleteOrigins->BindInt32ByName(NS_LITERAL_CSTRING("cutoff"),
                                                cutoff);
   RETURN_IF_FAILED(rv);
 
   deleteOrigins->Execute();
 }
 
 void
-Seer::CleanupStartupPages(PRTime now)
+Predictor::CleanupStartupPages(PRTime now)
 {
   PRTime cutoff = now - ONE_WEEK;
 
   nsCOMPtr<mozIStorageStatement> deletePages = mStatements.GetCachedStatement(
       NS_LITERAL_CSTRING("DELETE FROM moz_startup_pages WHERE "
                          "last_hit <= :cutoff"));
   if (!deletePages) {
     return;
@@ -2510,17 +2539,17 @@ Seer::CleanupStartupPages(PRTime now)
   nsresult rv = deletePages->BindInt32ByName(NS_LITERAL_CSTRING("cutoff"),
                                              cutoff);
   RETURN_IF_FAILED(rv);
 
   deletePages->Execute();
 }
 
 int32_t
-Seer::GetSubresourceCount()
+Predictor::GetSubresourceCount()
 {
   nsCOMPtr<mozIStorageStatement> count = mStatements.GetCachedStatement(
       NS_LITERAL_CSTRING("SELECT COUNT(id) FROM moz_subresources"));
   if (!count) {
     return 0;
   }
   mozStorageStatementScoper scopedCount(count);
 
@@ -2532,52 +2561,53 @@ Seer::GetSubresourceCount()
 
   int32_t subresourceCount = 0;
   count->GetInt32(0, &subresourceCount);
 
   return subresourceCount;
 }
 
 void
-Seer::Cleanup()
+Predictor::Cleanup()
 {
-  MOZ_ASSERT(!NS_IsMainThread(), "Seer::Cleanup called on main thread!");
+  MOZ_ASSERT(!NS_IsMainThread(), "Predictor::Cleanup called on main thread!");
 
   nsresult rv = EnsureInitStorage();
   if (NS_FAILED(rv)) {
     return;
   }
 
   int64_t dbFileSize = GetDBFileSize();
   float preservePercentage = static_cast<float>(mPreservePercentage) / 100.0;
-  int64_t evictionCutoff = static_cast<int64_t>(mMaxDBSize) * preservePercentage;
+  int64_t evictionCutoff =
+    static_cast<int64_t>(mMaxDBSize) * preservePercentage;
   if (dbFileSize < evictionCutoff) {
     return;
   }
 
   CommitTransaction();
   BeginTransaction();
 
   PRTime now = PR_Now();
   if (mLastCleanupTime) {
-    Telemetry::Accumulate(Telemetry::SEER_CLEANUP_DELTA,
+    Telemetry::Accumulate(Telemetry::PREDICTOR_CLEANUP_DELTA,
                           (now - mLastCleanupTime) / 1000);
   }
   mLastCleanupTime = now;
 
   CleanupOrigins(now);
   CleanupStartupPages(now);
 
   dbFileSize = GetDBFileSizeAfterVacuum();
   if (dbFileSize < evictionCutoff) {
     // We've deleted enough stuff, time to free up the disk space and be on
     // our way.
     VacuumDatabase();
-    Telemetry::Accumulate(Telemetry::SEER_CLEANUP_SUCCEEDED, true);
-    Telemetry::Accumulate(Telemetry::SEER_CLEANUP_TIME,
+    Telemetry::Accumulate(Telemetry::PREDICTOR_CLEANUP_SUCCEEDED, true);
+    Telemetry::Accumulate(Telemetry::PREDICTOR_CLEANUP_TIME,
                           (PR_Now() - mLastCleanupTime) / 1000);
     return;
   }
 
   bool canDelete = true;
   while (canDelete && (dbFileSize >= evictionCutoff)) {
     int32_t subresourceCount = GetSubresourceCount();
     if (!subresourceCount) {
@@ -2637,59 +2667,59 @@ Seer::Cleanup()
     if (canDelete) {
       dbFileSize = GetDBFileSizeAfterVacuum();
     }
   }
 
   if (!canDelete || (dbFileSize >= evictionCutoff)) {
     // Last-ditch effort to free up space
     ResetInternal();
-    Telemetry::Accumulate(Telemetry::SEER_CLEANUP_SUCCEEDED, false);
+    Telemetry::Accumulate(Telemetry::PREDICTOR_CLEANUP_SUCCEEDED, false);
   } else {
     // We do this to actually free up the space on disk
     VacuumDatabase();
-    Telemetry::Accumulate(Telemetry::SEER_CLEANUP_SUCCEEDED, true);
+    Telemetry::Accumulate(Telemetry::PREDICTOR_CLEANUP_SUCCEEDED, true);
   }
-  Telemetry::Accumulate(Telemetry::SEER_CLEANUP_TIME,
+  Telemetry::Accumulate(Telemetry::PREDICTOR_CLEANUP_TIME,
                         (PR_Now() - mLastCleanupTime) / 1000);
 }
 
 void
-Seer::VacuumDatabase()
+Predictor::VacuumDatabase()
 {
   MOZ_ASSERT(!NS_IsMainThread(), "VacuumDatabase called on main thread!");
 
   CommitTransaction();
   mDB->ExecuteSimpleSQL(NS_LITERAL_CSTRING("VACUUM;"));
   BeginTransaction();
 }
 
-#ifdef SEER_TESTS
-class SeerPrepareForDnsTestEvent : public nsRunnable
+#ifdef PREDICTOR_TESTS
+class PredictorPrepareForDnsTestEvent : public nsRunnable
 {
 public:
-  SeerPrepareForDnsTestEvent(int64_t timestamp, const char *uri)
+  PredictorPrepareForDnsTestEvent(int64_t timestamp, const char *uri)
     :mTimestamp(timestamp)
     ,mUri(uri)
   { }
 
   NS_IMETHOD Run() MOZ_OVERRIDE
   {
     MOZ_ASSERT(!NS_IsMainThread(), "Preparing for DNS Test on main thread!");
-    gSeer->PrepareForDnsTestInternal(mTimestamp, mUri);
+    gPredictor->PrepareForDnsTestInternal(mTimestamp, mUri);
     return NS_OK;
   }
 
 private:
   int64_t mTimestamp;
   nsAutoCString mUri;
 };
 
 void
-Seer::PrepareForDnsTestInternal(int64_t timestamp, const nsACString &uri)
+Predictor::PrepareForDnsTestInternal(int64_t timestamp, const nsACString &uri)
 {
   nsCOMPtr<mozIStorageStatement> update = mStatements.GetCachedStatement(
       NS_LITERAL_CSTRING("UPDATE moz_subresources SET last_hit = :timestamp, "
                           "hits = 2 WHERE uri = :uri;"));
   if (!update) {
     return;
   }
   mozStorageStatementScoper scopedUpdate(update);
@@ -2701,127 +2731,133 @@ Seer::PrepareForDnsTestInternal(int64_t 
   rv = update->BindUTF8StringByName(NS_LITERAL_CSTRING("uri"), uri);
   RETURN_IF_FAILED(rv);
 
   update->Execute();
 }
 #endif
 
 NS_IMETHODIMP
-Seer::PrepareForDnsTest(int64_t timestamp, const char *uri)
+Predictor::PrepareForDnsTest(int64_t timestamp, const char *uri)
 {
-#ifdef SEER_TESTS
+#ifdef PREDICTOR_TESTS
   MOZ_ASSERT(NS_IsMainThread(),
-             "Seer interface methods must be called on the main thread");
+             "Predictor interface methods must be called on the main thread");
 
   if (!mInitialized) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  nsRefPtr<SeerPrepareForDnsTestEvent> event =
-    new SeerPrepareForDnsTestEvent(timestamp, uri);
+  nsRefPtr<PredictorPrepareForDnsTestEvent> event =
+    new PredictorPrepareForDnsTestEvent(timestamp, uri);
   return mIOThread->Dispatch(event, NS_DISPATCH_NORMAL);
 #else
   return NS_ERROR_NOT_IMPLEMENTED;
 #endif
 }
 
-// Helper functions to make using the seer easier from native code
+// Helper functions to make using the predictor easier from native code
 
 static nsresult
-EnsureGlobalSeer(nsINetworkSeer **aSeer)
+EnsureGlobalPredictor(nsINetworkPredictor **aPredictor)
 {
   nsresult rv;
-  nsCOMPtr<nsINetworkSeer> seer = do_GetService("@mozilla.org/network/seer;1",
-                                                &rv);
+  nsCOMPtr<nsINetworkPredictor> predictor =
+    do_GetService("@mozilla.org/network/predictor;1",
+                  &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  NS_IF_ADDREF(*aSeer = seer);
+  NS_IF_ADDREF(*aPredictor = predictor);
   return NS_OK;
 }
 
 nsresult
-SeerPredict(nsIURI *targetURI, nsIURI *sourceURI, SeerPredictReason reason,
-            nsILoadContext *loadContext, nsINetworkSeerVerifier *verifier)
+PredictorPredict(nsIURI *targetURI, nsIURI *sourceURI,
+                 PredictorPredictReason reason, nsILoadContext *loadContext,
+                 nsINetworkPredictorVerifier *verifier)
 {
   if (!IsNullOrHttp(targetURI) || !IsNullOrHttp(sourceURI)) {
     return NS_OK;
   }
 
-  nsCOMPtr<nsINetworkSeer> seer;
-  nsresult rv = EnsureGlobalSeer(getter_AddRefs(seer));
+  nsCOMPtr<nsINetworkPredictor> predictor;
+  nsresult rv = EnsureGlobalPredictor(getter_AddRefs(predictor));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return seer->Predict(targetURI, sourceURI, reason, loadContext, verifier);
+  return predictor->Predict(targetURI, sourceURI, reason,
+                            loadContext, verifier);
 }
 
 nsresult
-SeerLearn(nsIURI *targetURI, nsIURI *sourceURI, SeerLearnReason reason,
-          nsILoadContext *loadContext)
+PredictorLearn(nsIURI *targetURI, nsIURI *sourceURI,
+               PredictorLearnReason reason,
+               nsILoadContext *loadContext)
 {
   if (!IsNullOrHttp(targetURI) || !IsNullOrHttp(sourceURI)) {
     return NS_OK;
   }
 
-  nsCOMPtr<nsINetworkSeer> seer;
-  nsresult rv = EnsureGlobalSeer(getter_AddRefs(seer));
+  nsCOMPtr<nsINetworkPredictor> predictor;
+  nsresult rv = EnsureGlobalPredictor(getter_AddRefs(predictor));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return seer->Learn(targetURI, sourceURI, reason, loadContext);
+  return predictor->Learn(targetURI, sourceURI, reason, loadContext);
 }
 
 nsresult
-SeerLearn(nsIURI *targetURI, nsIURI *sourceURI, SeerLearnReason reason,
-          nsILoadGroup *loadGroup)
+PredictorLearn(nsIURI *targetURI, nsIURI *sourceURI,
+               PredictorLearnReason reason,
+               nsILoadGroup *loadGroup)
 {
   if (!IsNullOrHttp(targetURI) || !IsNullOrHttp(sourceURI)) {
     return NS_OK;
   }
 
-  nsCOMPtr<nsINetworkSeer> seer;
-  nsresult rv = EnsureGlobalSeer(getter_AddRefs(seer));
+  nsCOMPtr<nsINetworkPredictor> predictor;
+  nsresult rv = EnsureGlobalPredictor(getter_AddRefs(predictor));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsILoadContext> loadContext;
 
   if (loadGroup) {
     nsCOMPtr<nsIInterfaceRequestor> callbacks;
     loadGroup->GetNotificationCallbacks(getter_AddRefs(callbacks));
     if (callbacks) {
       loadContext = do_GetInterface(callbacks);
     }
   }
 
-  return seer->Learn(targetURI, sourceURI, reason, loadContext);
+  return predictor->Learn(targetURI, sourceURI, reason, loadContext);
 }
 
 nsresult
-SeerLearn(nsIURI *targetURI, nsIURI *sourceURI, SeerLearnReason reason,
-          nsIDocument *document)
+PredictorLearn(nsIURI *targetURI, nsIURI *sourceURI,
+               PredictorLearnReason reason,
+               nsIDocument *document)
 {
   if (!IsNullOrHttp(targetURI) || !IsNullOrHttp(sourceURI)) {
     return NS_OK;
   }
 
-  nsCOMPtr<nsINetworkSeer> seer;
-  nsresult rv = EnsureGlobalSeer(getter_AddRefs(seer));
+  nsCOMPtr<nsINetworkPredictor> predictor;
+  nsresult rv = EnsureGlobalPredictor(getter_AddRefs(predictor));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsILoadContext> loadContext;
 
   if (document) {
     loadContext = document->GetLoadContext();
   }
 
-  return seer->Learn(targetURI, sourceURI, reason, loadContext);
+  return predictor->Learn(targetURI, sourceURI, reason, loadContext);
 }
 
 nsresult
-SeerLearnRedirect(nsIURI *targetURI, nsIChannel *channel,
-                  nsILoadContext *loadContext)
+PredictorLearnRedirect(nsIURI *targetURI, nsIChannel *channel,
+                       nsILoadContext *loadContext)
 {
   nsCOMPtr<nsIURI> sourceURI;
   nsresult rv = channel->GetOriginalURI(getter_AddRefs(sourceURI));
   NS_ENSURE_SUCCESS(rv, rv);
 
   bool sameUri;
   rv = targetURI->Equals(sourceURI, &sameUri);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -2829,18 +2865,19 @@ SeerLearnRedirect(nsIURI *targetURI, nsI
   if (sameUri) {
     return NS_OK;
   }
 
   if (!IsNullOrHttp(targetURI) || !IsNullOrHttp(sourceURI)) {
     return NS_OK;
   }
 
-  nsCOMPtr<nsINetworkSeer> seer;
-  rv = EnsureGlobalSeer(getter_AddRefs(seer));
+  nsCOMPtr<nsINetworkPredictor> predictor;
+  rv = EnsureGlobalPredictor(getter_AddRefs(predictor));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return seer->Learn(targetURI, sourceURI,
-                     nsINetworkSeer::LEARN_LOAD_REDIRECT, loadContext);
+  return predictor->Learn(targetURI, sourceURI,
+                          nsINetworkPredictor::LEARN_LOAD_REDIRECT,
+                          loadContext);
 }
 
 } // ::mozilla::net
 } // ::mozilla
rename from netwerk/base/src/Seer.h
rename to netwerk/base/src/Predictor.h
--- a/netwerk/base/src/Seer.h
+++ b/netwerk/base/src/Predictor.h
@@ -1,93 +1,92 @@
 /* vim: set ts=2 sts=2 et sw=2: */
 /* 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 mozilla_net_Seer_h
-#define mozilla_net_Seer_h
+#ifndef mozilla_net_Predictor_h
+#define mozilla_net_Predictor_h
 
-#include "nsINetworkSeer.h"
+#include "nsINetworkPredictor.h"
 
 #include "nsCOMPtr.h"
 #include "nsIDNSListener.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIObserver.h"
 #include "nsISpeculativeConnect.h"
 #include "nsProxyRelease.h"
-
 #include "mozilla/Mutex.h"
 #include "mozilla/storage/StatementCache.h"
 #include "mozilla/TimeStamp.h"
 
 class nsIDNSService;
-class nsINetworkSeerVerifier;
+class nsINetworkPredictorVerifier;
 class nsIThread;
 class nsITimer;
 
 class mozIStorageConnection;
 class mozIStorageService;
 class mozIStorageStatement;
 
 namespace mozilla {
 namespace net {
 
-typedef nsMainThreadPtrHandle<nsINetworkSeerVerifier> SeerVerifierHandle;
+typedef nsMainThreadPtrHandle<nsINetworkPredictorVerifier> PredictorVerifierHandle;
 
-class SeerPredictionRunner;
-struct SeerTelemetryAccumulators;
-class SeerDNSListener;
+class PredictionRunner;
+struct PredictorTelemetryAccumulators;
+class PredictorDNSListener;
 
-class Seer : public nsINetworkSeer
-           , public nsIObserver
-           , public nsISpeculativeConnectionOverrider
-           , public nsIInterfaceRequestor
+class Predictor : public nsINetworkPredictor
+                , public nsIObserver
+                , public nsISpeculativeConnectionOverrider
+                , public nsIInterfaceRequestor
 {
 public:
   NS_DECL_ISUPPORTS
-  NS_DECL_NSINETWORKSEER
+  NS_DECL_NSINETWORKPREDICTOR
   NS_DECL_NSIOBSERVER
   NS_DECL_NSISPECULATIVECONNECTIONOVERRIDER
   NS_DECL_NSIINTERFACEREQUESTOR
 
-  Seer();
-  virtual ~Seer();
+  Predictor();
+  virtual ~Predictor();
 
   nsresult Init();
   void Shutdown();
   static nsresult Create(nsISupports *outer, const nsIID& iid, void **result);
 
 private:
-  friend class SeerPredictionEvent;
-  friend class SeerLearnEvent;
-  friend class SeerResetEvent;
-  friend class SeerPredictionRunner;
-  friend class SeerDBShutdownRunner;
-  friend class SeerCommitTimerInitEvent;
-  friend class SeerNewTransactionEvent;
-  friend class SeerCleanupEvent;
+  friend class PredictionEvent;
+  friend class LearnEvent;
+  friend class PredictorResetEvent;
+  friend class PredictionRunner;
+  friend class PredictorDBShutdownRunner;
+  friend class PredictorCommitTimerInitEvent;
+  friend class PredictorNewTransactionEvent;
+  friend class PredictorCleanupEvent;
 
   void CheckForAndDeleteOldDBFile();
   nsresult EnsureInitStorage();
 
   // This is a proxy for the information we need from an nsIURI
   struct UriInfo {
     nsAutoCString spec;
     nsAutoCString origin;
   };
 
   void PredictForLink(nsIURI *targetURI,
                       nsIURI *sourceURI,
-                      nsINetworkSeerVerifier *verifier);
+                      nsINetworkPredictorVerifier *verifier);
   void PredictForPageload(const UriInfo &dest,
-                          SeerVerifierHandle &verifier,
+                          PredictorVerifierHandle &verifier,
                           int stackCount,
                           TimeStamp &predictStartTime);
-  void PredictForStartup(SeerVerifierHandle &verifier,
+  void PredictForStartup(PredictorVerifierHandle &verifier,
                          TimeStamp &predictStartTime);
 
   // Whether we're working on a page or an origin
   enum QueryType {
     QUERY_PAGE = 0,
     QUERY_ORIGIN
   };
 
@@ -111,31 +110,31 @@ private:
   int CalculateGlobalDegradation(PRTime now,
                                  PRTime lastLoad);
   int CalculateConfidence(int baseConfidence,
                           PRTime lastHit,
                           PRTime lastPossible,
                           int globalDegradation);
   void SetupPrediction(int confidence,
                        const nsACString &uri,
-                       SeerPredictionRunner *runner);
+                       PredictionRunner *runner);
 
   bool LookupTopLevel(QueryType queryType,
                       const nsACString &key,
                       TopLevelInfo &info);
   void AddTopLevel(QueryType queryType,
                    const nsACString &key,
                    PRTime now);
   void UpdateTopLevel(QueryType queryType,
                       const TopLevelInfo &info,
                       PRTime now);
   bool TryPredict(QueryType queryType,
                   const TopLevelInfo &info,
                   PRTime now,
-                  SeerVerifierHandle &verifier,
+                  PredictorVerifierHandle &verifier,
                   TimeStamp &predictStartTime);
   bool WouldRedirect(const TopLevelInfo &info,
                      PRTime now,
                      UriInfo &newUri);
 
   bool LookupSubresource(QueryType queryType,
                          const int32_t parentId,
                          const nsACString &key,
@@ -217,29 +216,29 @@ private:
   PRTime mLastStartupTime;
   int32_t mStartupCount;
 
   nsCOMPtr<nsIDNSService> mDnsService;
 
   int32_t mQueueSize;
   mozilla::Mutex mQueueSizeLock;
 
-  nsAutoPtr<SeerTelemetryAccumulators> mAccumulators;
+  nsAutoPtr<PredictorTelemetryAccumulators> mAccumulators;
 
-  nsRefPtr<SeerDNSListener> mDNSListener;
+  nsRefPtr<PredictorDNSListener> mDNSListener;
 
   nsCOMPtr<nsITimer> mCommitTimer;
 
-#ifdef SEER_TESTS
-  friend class SeerPrepareForDnsTestEvent;
+#ifdef PREDICTOR_TESTS
+  friend class PredictorPrepareForDnsTestEvent;
   void PrepareForDnsTestInternal(int64_t timestamp, const nsACString &uri);
 #endif
 
   bool mCleanupScheduled;
   int32_t mMaxDBSize;
   int32_t mPreservePercentage;
   PRTime mLastCleanupTime;
 };
 
 } // ::mozilla::net
 } // ::mozilla
 
-#endif // mozilla_net_Seer_h
+#endif // mozilla_net_Predictor_h
--- a/netwerk/base/src/moz.build
+++ b/netwerk/base/src/moz.build
@@ -65,19 +65,19 @@ UNIFIED_SOURCES += [
     'nsSyncStreamListener.cpp',
     'nsTemporaryFileInputStream.cpp',
     'nsTransportUtils.cpp',
     'nsUDPSocket.cpp',
     'nsUnicharStreamLoader.cpp',
     'nsURIChecker.cpp',
     'nsURLHelper.cpp',
     'nsURLParsers.cpp',
+    'Predictor.cpp',
     'ProxyAutoConfig.cpp',
     'RedirectChannelRegistrar.cpp',
-    'Seer.cpp',
     'StreamingProtocolService.cpp',
     'Tickler.cpp',
 ]
 
 # These files cannot be built in unified mode because they force NSPR logging.
 SOURCES += [
     'nsAsyncRedirectVerifyHelper.cpp',
     'nsSocketTransport2.cpp',
@@ -127,9 +127,9 @@ if 'rtsp' in CONFIG['NECKO_PROTOCOLS']:
     ]
 
 if CONFIG['MOZ_ENABLE_QTNETWORK']:
     LOCAL_INCLUDES += [
         '/netwerk/system/qt',
     ]
 
 if CONFIG['ENABLE_TESTS']:
-    DEFINES['SEER_TESTS'] = True
+    DEFINES['PREDICTOR_TESTS'] = True
--- a/netwerk/build/nsNetCID.h
+++ b/netwerk/build/nsNetCID.h
@@ -441,25 +441,25 @@
 #define NS_REDIRECTCHANNELREGISTRAR_CID \
 { /* {b69043a6-8929-4d60-8d17-a27e44a8393e} */ \
     0xb69043a6, \
     0x8929, \
     0x4d60, \
     { 0x8d, 0x17, 0xa2, 0x7e, 0x44, 0xa8, 0x39, 0x3e } \
 }
 
-// service implementing nsINetworkSeer
-#define NS_NETWORKSEER_CONTRACTID \
-    "@mozilla.org/network/seer;1"
-#define NS_NETWORKSEER_CID \
-{ /* {1C218009-A531-46AD-8351-1E7F45D5A3C4} */ \
-    0x1C218009, \
-    0xA531, \
-    0x46AD, \
-    { 0x83, 0x51, 0x1E, 0x7F, 0x45, 0xD5, 0xA3, 0xC4 } \
+// service implementing nsINetworkPredictor
+#define NS_NETWORKPREDICTOR_CONTRACTID \
+    "@mozilla.org/network/predictor;1"
+#define NS_NETWORKPREDICTOR_CID \
+{ /* {969adfdf-7221-4419-aecf-05f8faf00c9b} */ \
+    0x969adfdf, \
+    0x7221, \
+    0x4419, \
+    { 0xae, 0xcf, 0x05, 0xf8, 0xfa, 0xf0, 0x0c, 0x9b } \
 }
 
 /******************************************************************************
  * netwerk/cache/ classes
  */
 
 // service implementing nsICacheService.
 #define NS_CACHESERVICE_CONTRACTID \
@@ -922,17 +922,17 @@
 
 // service implementing nsINetworkLinkService
 #define NS_NETWORK_LINK_SERVICE_CID    \
   { 0x75a500a2,                                        \
     0x0030,                                            \
     0x40f7,                                            \
     { 0x86, 0xf8, 0x63, 0xf2, 0x25, 0xb9, 0x40, 0xae } \
   }
-  
+
 /******************************************************************************
  * Contracts that can be implemented by necko users.
  */
 
 /**
  * This contract ID will be gotten as a service and gets the opportunity to look
  * at and veto all redirects that are processed by necko.
  *
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -32,17 +32,17 @@
 #include "nsApplicationCacheService.h"
 #include "nsMimeTypes.h"
 #include "nsNetStrings.h"
 #include "nsDNSPrefetch.h"
 #include "nsAboutProtocolHandler.h"
 #include "nsXULAppAPI.h"
 #include "nsCategoryCache.h"
 #include "nsIContentSniffer.h"
-#include "Seer.h"
+#include "Predictor.h"
 #include "nsNetUtil.h"
 #include "nsIThreadPool.h"
 #include "mozilla/net/NeckoChild.h"
 
 #include "nsNetCID.h"
 
 #ifndef XP_MACOSX
 #define BUILD_BINHEX_DECODER 1
@@ -817,17 +817,17 @@ NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERV
 #elif defined(MOZ_ENABLE_QTNETWORK)
 NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
 #elif defined(MOZ_WIDGET_ANDROID)
 NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
 #endif
 NS_DEFINE_NAMED_CID(NS_SERIALIZATION_HELPER_CID);
 NS_DEFINE_NAMED_CID(NS_REDIRECTCHANNELREGISTRAR_CID);
 NS_DEFINE_NAMED_CID(NS_CACHE_STORAGE_SERVICE_CID);
-NS_DEFINE_NAMED_CID(NS_NETWORKSEER_CID);
+NS_DEFINE_NAMED_CID(NS_NETWORKPREDICTOR_CID);
 
 static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
     { &kNS_IOSERVICE_CID, false, nullptr, nsIOServiceConstructor },
     { &kNS_STREAMTRANSPORTSERVICE_CID, false, nullptr, nsStreamTransportServiceConstructor },
     { &kNS_SOCKETTRANSPORTSERVICE_CID, false, nullptr, nsSocketTransportServiceConstructor },
     { &kNS_SERVERSOCKET_CID, false, nullptr, nsServerSocketConstructor },
     { &kNS_UDPSOCKET_CID, false, nullptr, nsUDPSocketConstructor },
     { &kNS_SOCKETPROVIDERSERVICE_CID, false, nullptr, nsSocketProviderService::Create },
@@ -960,17 +960,17 @@ static const mozilla::Module::CIDEntry k
 #elif defined(MOZ_ENABLE_QTNETWORK)
     { &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsQtNetworkLinkServiceConstructor },
 #elif defined(MOZ_WIDGET_ANDROID)
     { &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsAndroidNetworkLinkServiceConstructor },
 #endif
     { &kNS_SERIALIZATION_HELPER_CID, false, nullptr, nsSerializationHelperConstructor },
     { &kNS_REDIRECTCHANNELREGISTRAR_CID, false, nullptr, RedirectChannelRegistrarConstructor },
     { &kNS_CACHE_STORAGE_SERVICE_CID, false, nullptr, CacheStorageServiceConstructor },
-    { &kNS_NETWORKSEER_CID, false, nullptr, mozilla::net::Seer::Create },
+    { &kNS_NETWORKPREDICTOR_CID, false, nullptr, mozilla::net::Predictor::Create },
     { nullptr }
 };
 
 static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
     { NS_IOSERVICE_CONTRACTID, &kNS_IOSERVICE_CID },
     { NS_NETUTIL_CONTRACTID, &kNS_IOSERVICE_CID },
     { NS_STREAMTRANSPORTSERVICE_CONTRACTID, &kNS_STREAMTRANSPORTSERVICE_CID },
     { NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &kNS_SOCKETTRANSPORTSERVICE_CID },
@@ -1106,17 +1106,17 @@ static const mozilla::Module::ContractID
 #elif defined(MOZ_ENABLE_QTNETWORK)
     { NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
 #elif defined(MOZ_WIDGET_ANDROID)
     { NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
 #endif
     { NS_SERIALIZATION_HELPER_CONTRACTID, &kNS_SERIALIZATION_HELPER_CID },
     { NS_REDIRECTCHANNELREGISTRAR_CONTRACTID, &kNS_REDIRECTCHANNELREGISTRAR_CID },
     { NS_CACHE_STORAGE_SERVICE_CONTRACTID, &kNS_CACHE_STORAGE_SERVICE_CID },
-    { NS_NETWORKSEER_CONTRACTID, &kNS_NETWORKSEER_CID },
+    { NS_NETWORKPREDICTOR_CONTRACTID, &kNS_NETWORKPREDICTOR_CID },
     { nullptr }
 };
 
 static const mozilla::Module kNeckoModule = {
     mozilla::Module::kVersion,
     kNeckoCIDs,
     kNeckoContracts,
     kNeckoCategories,
--- a/netwerk/protocol/http/Http2Compression.cpp
+++ b/netwerk/protocol/http/Http2Compression.cpp
@@ -1465,20 +1465,27 @@ Http2Compressor::ProcessHeader(const nvP
         mImpliedReferenceSet.AppendElement(matchedIndex);
       mAlternateReferenceSet.AppendElement(matchedIndex);
       LOG(("Compressor state after NOP index"));
     }
     DumpState();
     return;
   }
 
+  // Need to ensure we have room for a new static entry before emitting
+  // anything, see bug 1019577
+  bool isStatic = (matchedIndex >= mHeaderTable.VariableLength());
+  if (isStatic) {
+    MakeRoom(newSize);
+  }
+
   // emit an index to add to reference set
   DoOutput(kToggleOn, &inputPair, matchedIndex);
-  if (matchedIndex >= mHeaderTable.VariableLength()) {
-    MakeRoom(newSize);
+
+  if (isStatic) {
     mHeaderTable.AddElement(inputPair.mName, inputPair.mValue);
     IncrementReferenceSetIndices();
     mAlternateReferenceSet.AppendElement(0);
   } else {
     mAlternateReferenceSet.AppendElement(matchedIndex);
   }
   LOG(("Compressor state after index"));
   DumpState();
--- a/netwerk/protocol/http/Http2Session.cpp
+++ b/netwerk/protocol/http/Http2Session.cpp
@@ -2733,17 +2733,22 @@ Http2Session::OnWriteSegment(char *buf,
 
     mInputFrameDataRead += *countWritten;
     if (mPaddingLength && (mInputFrameDataSize - mInputFrameDataRead <= mPaddingLength)) {
       // We are crossing from real HTTP data into the realm of padding. If
       // we've actually crossed the line, we need to munge countWritten for the
       // sake of goodness and sanity. No matter what, any future calls to
       // WriteSegments need to just discard data until we reach the end of this
       // frame.
-      ChangeDownstreamState(DISCARDING_DATA_FRAME_PADDING);
+      if (mInputFrameDataSize != mInputFrameDataRead) {
+        // Only change state if we still have padding to read. If we don't do
+        // this, we can end up hanging on frames that combine real data,
+        // padding, and END_STREAM (see bug 1019921)
+        ChangeDownstreamState(DISCARDING_DATA_FRAME_PADDING);
+      }
       uint32_t paddingRead = mPaddingLength - (mInputFrameDataSize - mInputFrameDataRead);
       LOG3(("Http2Session::OnWriteSegment %p stream 0x%X len=%d read=%d "
             "crossed from HTTP data into padding (%d of %d) countWritten=%d",
             this, mInputFrameID, mInputFrameDataSize, mInputFrameDataRead,
             paddingRead, mPaddingLength, *countWritten));
       *countWritten -= paddingRead;
       LOG3(("Http2Session::OnWriteSegment %p stream 0x%X new countWritten=%d",
             this, mInputFrameID, *countWritten));
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -2937,16 +2937,21 @@ WebSocketChannel::OnTransportAvailable(n
                                                                 aTransport,
                                                                 aSocketIn,
                                                                 aSocketOut));
   }
 
   LOG(("WebSocketChannel::OnTransportAvailable %p [%p %p %p] rcvdonstart=%d\n",
        this, aTransport, aSocketIn, aSocketOut, mGotUpgradeOK));
 
+  if (mStopped) {
+    LOG(("WebSocketChannel::OnTransportAvailable: Already stopped"));
+    return NS_OK;
+  }
+
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
   NS_ABORT_IF_FALSE(!mRecvdHttpUpgradeTransport, "OTA duplicated");
   NS_ABORT_IF_FALSE(aSocketIn, "OTA with invalid socketIn");
 
   mTransport = aTransport;
   mSocketIn = aSocketIn;
   mSocketOut = aSocketOut;
 
rename from netwerk/test/unit/test_seer.js
rename to netwerk/test/unit/test_predictor.js
--- a/netwerk/test/unit/test_seer.js
+++ b/netwerk/test/unit/test_predictor.js
@@ -1,17 +1,17 @@
 var Cc = Components.classes;
 var Ci = Components.interfaces;
 var Cu = Components.utils;
 var Cr = Components.results;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/FileUtils.jsm");
 
-var seer = null;
+var predictor = null;
 var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
 var profile = null;
 
 function extract_origin(uri) {
   var o = uri.scheme + "://" + uri.asciiHost;
   if (uri.port !== -1) {
     o = o + ":" + uri.port;
   }
@@ -24,17 +24,17 @@ var LoadContext = function _loadContext(
 LoadContext.prototype = {
   usePrivateBrowsing: false,
 
   getInterface: function loadContext_getInterface(iid) {
     return this.QueryInterface(iid);
   },
 
   QueryInterface: function loadContext_QueryInterface(iid) {
-    if (iid.equals(Ci.nsINetworkSeerVerifier) ||
+    if (iid.equals(Ci.nsINetworkPredictorVerifier) ||
         iid.equals(Ci.nsILoadContext)) {
       return this;
     }
 
     throw Cr.NS_ERROR_NO_INTERFACE;
   }
 };
 
@@ -51,17 +51,17 @@ Verifier.prototype = {
   expected_preconnects: null,
   expected_preresolves: null,
 
   getInterface: function verifier_getInterface(iid) {
     return this.QueryInterface(iid);
   },
 
   QueryInterface: function verifier_QueryInterface(iid) {
-    if (iid.equals(Ci.nsINetworkSeerVerifier) ||
+    if (iid.equals(Ci.nsINetworkPredictorVerifier) ||
         iid.equals(Ci.nsISupports)) {
       return this;
     }
 
     throw Cr.NS_ERROR_NO_INTERFACE;
   },
 
   maybe_run_next_test: function verifier_maybe_run_next_test() {
@@ -90,103 +90,103 @@ Verifier.prototype = {
       do_check_true(false, "Got preresolve for unexpected uri " + origin);
     } else {
       this.expected_preresolves.splice(index, 1);
     }
     this.maybe_run_next_test();
   }
 };
 
-function reset_seer() {
-  seer.reset();
+function reset_predictor() {
+  predictor.reset();
 }
 
 function newURI(s) {
   return ios.newURI(s, null, null);
 }
 
 function test_link_hover() {
-  reset_seer();
+  reset_predictor();
   var uri = newURI("http://localhost:4444/foo/bar");
   var referrer = newURI("http://localhost:4444/foo");
   var preconns = ["http://localhost:4444"];
 
   var verifier = new Verifier("hover", preconns, []);
-  seer.predict(uri, referrer, seer.PREDICT_LINK, load_context, verifier);
+  predictor.predict(uri, referrer, predictor.PREDICT_LINK, load_context, verifier);
 }
 
 function test_pageload() {
-  reset_seer();
+  reset_predictor();
   var toplevel = "http://localhost:4444/index.html";
   var subresources = [
     "http://localhost:4444/style.css",
     "http://localhost:4443/jquery.js",
     "http://localhost:4444/image.png"
   ];
 
   var tluri = newURI(toplevel);
-  seer.learn(tluri, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
+  predictor.learn(tluri, null, predictor.LEARN_LOAD_TOPLEVEL, load_context);
   var preconns = [];
   for (var i = 0; i < subresources.length; i++) {
     var sruri = newURI(subresources[i]);
-    seer.learn(sruri, tluri, seer.LEARN_LOAD_SUBRESOURCE, load_context);
+    predictor.learn(sruri, tluri, predictor.LEARN_LOAD_SUBRESOURCE, load_context);
     preconns.push(extract_origin(sruri));
   }
 
   var verifier = new Verifier("pageload", preconns, []);
-  seer.predict(tluri, null, seer.PREDICT_LOAD, load_context, verifier);
+  predictor.predict(tluri, null, predictor.PREDICT_LOAD, load_context, verifier);
 }
 
 function test_redirect() {
-  reset_seer();
+  reset_predictor();
   var initial = "http://localhost:4443/redirect";
   var target = "http://localhost:4444/index.html";
   var subresources = [
     "http://localhost:4444/style.css",
     "http://localhost:4443/jquery.js",
     "http://localhost:4444/image.png"
   ];
 
   var inituri = newURI(initial);
   var targeturi = newURI(target);
-  seer.learn(inituri, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
-  seer.learn(targeturi, inituri, seer.LEARN_LOAD_REDIRECT, load_context);
-  seer.learn(targeturi, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
+  predictor.learn(inituri, null, predictor.LEARN_LOAD_TOPLEVEL, load_context);
+  predictor.learn(targeturi, inituri, predictor.LEARN_LOAD_REDIRECT, load_context);
+  predictor.learn(targeturi, null, predictor.LEARN_LOAD_TOPLEVEL, load_context);
 
   var preconns = [];
   preconns.push(extract_origin(targeturi));
   for (var i = 0; i < subresources.length; i++) {
     var sruri = newURI(subresources[i]);
-    seer.learn(sruri, targeturi, seer.LEARN_LOAD_SUBRESOURCE, load_context);
+    predictor.learn(sruri, targeturi, predictor.LEARN_LOAD_SUBRESOURCE, load_context);
     preconns.push(extract_origin(sruri));
   }
 
   var verifier = new Verifier("redirect", preconns, []);
-  seer.predict(inituri, null, seer.PREDICT_LOAD, load_context, verifier);
+  predictor.predict(inituri, null, predictor.PREDICT_LOAD, load_context, verifier);
 }
 
 function test_startup() {
-  reset_seer();
+  reset_predictor();
   var uris = [
     "http://localhost:4444/startup",
     "http://localhost:4443/startup"
   ];
   var preconns = [];
   for (var i = 0; i < uris.length; i++) {
     var uri = newURI(uris[i]);
-    seer.learn(uri, null, seer.LEARN_STARTUP, load_context);
+    predictor.learn(uri, null, predictor.LEARN_STARTUP, load_context);
     preconns.push(extract_origin(uri));
   }
 
   var verifier = new Verifier("startup", preconns, []);
-  seer.predict(null, null, seer.PREDICT_STARTUP, load_context, verifier);
+  predictor.predict(null, null, predictor.PREDICT_STARTUP, load_context, verifier);
 }
 
 // A class used to guarantee serialization of SQL queries so we can properly
-// update last hit times on subresources to ensure the seer tries to do DNS
+// update last hit times on subresources to ensure the predictor tries to do DNS
 // preresolve on them instead of preconnecting
 var DnsContinueVerifier = function _dnsContinueVerifier(subresource, tluri, preresolves) {
   this.subresource = subresource;
   this.tluri = tluri;
   this.preresolves = preresolves;
 };
 
 DnsContinueVerifier.prototype = {
@@ -195,105 +195,105 @@ DnsContinueVerifier.prototype = {
   preresolves: null,
 
   getInterface: function _dnsContinueVerifier_getInterface(iid) {
     return this.QueryInterface(iid);
   },
 
   QueryInterface: function _dnsContinueVerifier_QueryInterface(iid) {
     if (iid.equals(Ci.nsISupports) ||
-        iid.equals(Ci.nsINetworkSeerVerifier)) {
+        iid.equals(Ci.nsINetworkPredictorVerifier)) {
       return this;
     }
 
     throw Cr.NS_ERROR_NO_INTERFACE;
   },
 
   onPredictPreconnect: function _dnsContinueVerifier_onPredictPreconnect() {
-    // This means that the seer has learned and done our "checkpoint" prediction
+    // This means that the predictor has learned and done our "checkpoint" prediction
     // Now we can get on with the prediction we actually want to test
 
     // tstamp is 10 days older than now - just over 1 week, which will ensure we
     // hit our cutoff for dns vs. preconnect. This is all in usec, hence the
     // x1000 on the Date object value.
     var tstamp = (new Date().valueOf() * 1000) - (10 * 86400 * 1000000);
 
-    seer.prepareForDnsTest(tstamp, this.subresource);
+    predictor.prepareForDnsTest(tstamp, this.subresource);
 
     var verifier = new Verifier("dns", [], this.preresolves);
-    seer.predict(this.tluri, null, seer.PREDICT_LOAD, load_context, verifier);
+    predictor.predict(this.tluri, null, predictor.PREDICT_LOAD, load_context, verifier);
   },
 
   onPredictDNS: function _dnsContinueVerifier_onPredictDNS() {
     do_check_true(false, "Shouldn't have gotten a preresolve prediction here!");
   }
 };
 
 function test_dns() {
-  reset_seer();
+  reset_predictor();
   var toplevel = "http://localhost:4444/index.html";
   var subresource = "http://localhost:4443/jquery.js";
 
   var tluri = newURI(toplevel);
-  seer.learn(tluri, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
+  predictor.learn(tluri, null, predictor.LEARN_LOAD_TOPLEVEL, load_context);
   var sruri = newURI(subresource);
-  seer.learn(sruri, tluri, seer.LEARN_LOAD_SUBRESOURCE, load_context);
+  predictor.learn(sruri, tluri, predictor.LEARN_LOAD_SUBRESOURCE, load_context);
 
   var preresolves = [extract_origin(sruri)];
   var continue_verifier = new DnsContinueVerifier(subresource, tluri, preresolves);
-  // Fire off a prediction that will do preconnects so we know when the seer
+  // Fire off a prediction that will do preconnects so we know when the predictor
   // thread has gotten to the point where we can update the database manually
-  seer.predict(tluri, null, seer.PREDICT_LOAD, load_context, continue_verifier);
+  predictor.predict(tluri, null, predictor.PREDICT_LOAD, load_context, continue_verifier);
 }
 
 function test_origin() {
-  reset_seer();
+  reset_predictor();
   var toplevel = "http://localhost:4444/index.html";
   var subresources = [
     "http://localhost:4444/style.css",
     "http://localhost:4443/jquery.js",
     "http://localhost:4444/image.png"
   ];
 
   var tluri = newURI(toplevel);
-  seer.learn(tluri, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
+  predictor.learn(tluri, null, predictor.LEARN_LOAD_TOPLEVEL, load_context);
   var preconns = [];
   for (var i = 0; i < subresources.length; i++) {
     var sruri = newURI(subresources[i]);
-    seer.learn(sruri, tluri, seer.LEARN_LOAD_SUBRESOURCE, load_context);
+    predictor.learn(sruri, tluri, predictor.LEARN_LOAD_SUBRESOURCE, load_context);
     var origin = extract_origin(sruri);
     if (preconns.indexOf(origin) === -1) {
       preconns.push(origin);
     }
   }
 
   var loaduri = newURI("http://localhost:4444/anotherpage.html");
   var verifier = new Verifier("origin", preconns, []);
-  seer.predict(loaduri, null, seer.PREDICT_LOAD, load_context, verifier);
+  predictor.predict(loaduri, null, predictor.PREDICT_LOAD, load_context, verifier);
 }
 
 var prefs;
-var seer_pref;
+var predictor_pref;
 
 function cleanup() {
-  reset_seer();
-  prefs.setBoolPref("network.seer.enabled", seer_pref);
+  reset_predictor();
+  prefs.setBoolPref("network.predictor.enabled", predictor_pref);
 }
 
 var tests = [
   test_link_hover,
   test_pageload,
   test_redirect,
   test_startup,
   test_dns,
   test_origin
 ];
 
 function run_test() {
   tests.forEach(add_test);
   profile = do_get_profile();
   prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
-  seer_pref = prefs.getBoolPref("network.seer.enabled");
-  prefs.setBoolPref("network.seer.enabled", true);
-  seer = Cc["@mozilla.org/network/seer;1"].getService(Ci.nsINetworkSeer);
+  predictor_pref = prefs.getBoolPref("network.predictor.enabled");
+  prefs.setBoolPref("network.predictor.enabled", true);
+  predictor = Cc["@mozilla.org/network/predictor;1"].getService(Ci.nsINetworkPredictor);
   do_register_cleanup(cleanup);
   run_next_test();
 }
--- a/netwerk/test/unit/xpcshell.ini
+++ b/netwerk/test/unit/xpcshell.ini
@@ -311,17 +311,17 @@ skip-if = os == "android"
 [test_unix_domain.js]
 # The xpcshell temp directory on Android doesn't seem to let us create
 # Unix domain sockets. (Perhaps it's a FAT filesystem?)
 skip-if = os == "android"
 [test_addr_in_use_error.js]
 [test_about_networking.js]
 [test_ping_aboutnetworking.js]
 [test_referrer.js]
-[test_seer.js]
+[test_predictor.js]
 # Android version detection w/in gecko does not work right on infra, so we just
 # disable this test on all android versions, even though it's enabled on 2.3+ in
 # the wild.
 skip-if = os == "android"
 [test_signature_extraction.js]
 run-if = os == "win"
 [test_udp_multicast.js]
 [test_redirect_history.js]
--- a/security/apps/AppTrustDomain.cpp
+++ b/security/apps/AppTrustDomain.cpp
@@ -99,35 +99,46 @@ AppTrustDomain::FindPotentialIssuers(con
   results = CERT_CreateSubjectCertList(nullptr, CERT_GetDefaultCertDB(),
                                        encodedIssuerName, time, true);
   return SECSuccess;
 }
 
 SECStatus
 AppTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
                              const CertPolicyId& policy,
-                             const CERTCertificate* candidateCert,
+                             const SECItem& candidateCertDER,
                      /*out*/ TrustLevel* trustLevel)
 {
   MOZ_ASSERT(policy.IsAnyPolicy());
-  MOZ_ASSERT(candidateCert);
   MOZ_ASSERT(trustLevel);
   MOZ_ASSERT(mTrustedRoot);
-  if (!candidateCert || !trustLevel || !policy.IsAnyPolicy()) {
+  if (!trustLevel || !policy.IsAnyPolicy()) {
     PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
     return SECFailure;
   }
   if (!mTrustedRoot) {
     PR_SetError(PR_INVALID_STATE_ERROR, 0);
     return SECFailure;
   }
 
   // Handle active distrust of the certificate.
+
+  // XXX: This would be cleaner and more efficient if we could get the trust
+  // information without constructing a CERTCertificate here, but NSS doesn't
+  // expose it in any other easy-to-use fashion.
+  ScopedCERTCertificate candidateCert(
+    CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
+                            const_cast<SECItem*>(&candidateCertDER), nullptr,
+                            false, true));
+  if (!candidateCert) {
+    return SECFailure;
+  }
+
   CERTCertTrust trust;
-  if (CERT_GetCertTrust(candidateCert, &trust) == SECSuccess) {
+  if (CERT_GetCertTrust(candidateCert.get(), &trust) == SECSuccess) {
     PRUint32 flags = SEC_GET_TRUST_FLAGS(&trust, trustObjectSigning);
 
     // For DISTRUST, we use the CERTDB_TRUSTED or CERTDB_TRUSTED_CA bit,
     // because we can have active distrust for either type of cert. Note that
     // CERTDB_TERMINAL_RECORD means "stop trying to inherit trust" so if the
     // relevant trust bit isn't set then that means the cert must be considered
     // distrusted.
     PRUint32 relevantTrustBit = endEntityOrCA == EndEntityOrCA::MustBeCA
@@ -136,17 +147,17 @@ AppTrustDomain::GetCertTrust(EndEntityOr
     if (((flags & (relevantTrustBit | CERTDB_TERMINAL_RECORD)))
             == CERTDB_TERMINAL_RECORD) {
       *trustLevel = TrustLevel::ActivelyDistrusted;
       return SECSuccess;
     }
   }
 
   // mTrustedRoot is the only trust anchor for this validation.
-  if (CERT_CompareCerts(mTrustedRoot.get(), candidateCert)) {
+  if (CERT_CompareCerts(mTrustedRoot.get(), candidateCert.get())) {
     *trustLevel = TrustLevel::TrustAnchor;
     return SECSuccess;
   }
 
   *trustLevel = TrustLevel::InheritsTrust;
   return SECSuccess;
 }
 
--- a/security/apps/AppTrustDomain.h
+++ b/security/apps/AppTrustDomain.h
@@ -17,17 +17,17 @@ class AppTrustDomain MOZ_FINAL : public 
 {
 public:
   AppTrustDomain(void* pinArg);
 
   SECStatus SetTrustedRoot(AppTrustedRoot trustedRoot);
 
   SECStatus GetCertTrust(mozilla::pkix::EndEntityOrCA endEntityOrCA,
                          const mozilla::pkix::CertPolicyId& policy,
-                         const CERTCertificate* candidateCert,
+                         const SECItem& candidateCertDER,
                  /*out*/ mozilla::pkix::TrustLevel* trustLevel) MOZ_OVERRIDE;
   SECStatus FindPotentialIssuers(const SECItem* encodedIssuerName,
                                  PRTime time,
                          /*out*/ mozilla::pkix::ScopedCERTCertList& results)
                                  MOZ_OVERRIDE;
   SECStatus VerifySignedData(const CERTSignedData* signedData,
                              const CERTCertificate* cert) MOZ_OVERRIDE;
   SECStatus CheckRevocation(mozilla::pkix::EndEntityOrCA endEntityOrCA,
--- a/security/certverifier/NSSCertDBTrustDomain.cpp
+++ b/security/certverifier/NSSCertDBTrustDomain.cpp
@@ -67,41 +67,54 @@ NSSCertDBTrustDomain::FindPotentialIssue
   results = CERT_CreateSubjectCertList(nullptr, CERT_GetDefaultCertDB(),
                                        encodedIssuerName, time, true);
   return SECSuccess;
 }
 
 SECStatus
 NSSCertDBTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
                                    const CertPolicyId& policy,
-                                   const CERTCertificate* candidateCert,
+                                   const SECItem& candidateCertDER,
                                    /*out*/ TrustLevel* trustLevel)
 {
-  PR_ASSERT(candidateCert);
   PR_ASSERT(trustLevel);
 
-  if (!candidateCert || !trustLevel) {
+  if (!trustLevel) {
     PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
     return SECFailure;
   }
 
 #ifdef MOZ_NO_EV_CERTS
   if (!policy.IsAnyPolicy()) {
     PR_SetError(SEC_ERROR_POLICY_VALIDATION_FAILED, 0);
     return SECFailure;
   }
 #endif
 
+  // XXX: This would be cleaner and more efficient if we could get the trust
+  // information without constructing a CERTCertificate here, but NSS doesn't
+  // expose it in any other easy-to-use fashion. The use of
+  // CERT_NewTempCertificate to get a CERTCertificate shouldn't be a
+  // performance problem because NSS will just find the existing
+  // CERTCertificate in its in-memory cache and return it.
+  ScopedCERTCertificate candidateCert(
+    CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
+                            const_cast<SECItem*>(&candidateCertDER), nullptr,
+                            false, true));
+  if (!candidateCert) {
+    return SECFailure;
+  }
+
   // XXX: CERT_GetCertTrust seems to be abusing SECStatus as a boolean, where
   // SECSuccess means that there is a trust record and SECFailure means there
   // is not a trust record. I looked at NSS's internal uses of
   // CERT_GetCertTrust, and all that code uses the result as a boolean meaning
   // "We have a trust record."
   CERTCertTrust trust;
-  if (CERT_GetCertTrust(candidateCert, &trust) == SECSuccess) {
+  if (CERT_GetCertTrust(candidateCert.get(), &trust) == SECSuccess) {
     PRUint32 flags = SEC_GET_TRUST_FLAGS(&trust, mCertDBTrustType);
 
     // For DISTRUST, we use the CERTDB_TRUSTED or CERTDB_TRUSTED_CA bit,
     // because we can have active distrust for either type of cert. Note that
     // CERTDB_TERMINAL_RECORD means "stop trying to inherit trust" so if the
     // relevant trust bit isn't set then that means the cert must be considered
     // distrusted.
     PRUint32 relevantTrustBit =
@@ -117,17 +130,17 @@ NSSCertDBTrustDomain::GetCertTrust(EndEn
     // needed to consider end-entity certs to be their own trust anchors since
     // Gecko implemented nsICertOverrideService.
     if (flags & CERTDB_TRUSTED_CA) {
       if (policy.IsAnyPolicy()) {
         *trustLevel = TrustLevel::TrustAnchor;
         return SECSuccess;
       }
 #ifndef MOZ_NO_EV_CERTS
-      if (CertIsAuthoritativeForEVPolicy(candidateCert, policy)) {
+      if (CertIsAuthoritativeForEVPolicy(candidateCert.get(), policy)) {
         *trustLevel = TrustLevel::TrustAnchor;
         return SECSuccess;
       }
 #endif
     }
   }
 
   *trustLevel = TrustLevel::InheritsTrust;
--- a/security/certverifier/NSSCertDBTrustDomain.h
+++ b/security/certverifier/NSSCertDBTrustDomain.h
@@ -63,17 +63,17 @@ public:
 
   virtual SECStatus FindPotentialIssuers(
                         const SECItem* encodedIssuerName,
                         PRTime time,
                 /*out*/ mozilla::pkix::ScopedCERTCertList& results);
 
   virtual SECStatus GetCertTrust(mozilla::pkix::EndEntityOrCA endEntityOrCA,
                                  const mozilla::pkix::CertPolicyId& policy,
-                                 const CERTCertificate* candidateCert,
+                                 const SECItem& candidateCertDER,
                          /*out*/ mozilla::pkix::TrustLevel* trustLevel);
 
   virtual SECStatus VerifySignedData(const CERTSignedData* signedData,
                                      const CERTCertificate* cert);
 
   virtual SECStatus CheckRevocation(mozilla::pkix::EndEntityOrCA endEntityOrCA,
                                     const CERTCertificate* cert,
                           /*const*/ CERTCertificate* issuerCert,
--- a/security/manager/boot/src/StaticHPKPins.h
+++ b/security/manager/boot/src/StaticHPKPins.h
@@ -656,18 +656,18 @@ struct TransportSecurityPreload {
   const bool mIsMoz;
   const int32_t mId;
   const StaticPinset *pinset;
 };
 
 /* Sort hostnames for binary search. */
 static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
   { "accounts.google.com", true, true, false, -1, &kPinset_google_root_pems },
-  { "addons.mozilla.net", true, true, true, 2, &kPinset_mozilla },
-  { "addons.mozilla.org", true, true, true, 1, &kPinset_mozilla },
+  { "addons.mozilla.net", true, false, true, 2, &kPinset_mozilla },
+  { "addons.mozilla.org", true, false, true, 1, &kPinset_mozilla },
   { "admin.google.com", true, true, false, -1, &kPinset_google_root_pems },
   { "android.com", true, true, false, -1, &kPinset_google_root_pems },
   { "api.twitter.com", true, false, false, -1, &kPinset_twitterCDN },
   { "apis.google.com", true, true, false, -1, &kPinset_google_root_pems },
   { "appengine.google.com", true, true, false, -1, &kPinset_google_root_pems },
   { "appspot.com", true, true, false, -1, &kPinset_google_root_pems },
   { "aus4.mozilla.org", true, true, true, 3, &kPinset_mozilla },
   { "blog.torproject.org", true, true, false, -1, &kPinset_tor },
@@ -983,9 +983,9 @@ static const TransportSecurityPreload kP
   { "youtube.com", true, true, false, -1, &kPinset_google_root_pems },
   { "ytimg.com", true, true, false, -1, &kPinset_google_root_pems },
 };
 
 static const int kPublicKeyPinningPreloadListLength = 322;
 
 static const int32_t kUnknownId = -1;
 
-static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1412099175458000);
+static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1412704831237000);
--- a/security/manager/ssl/src/nsNSSCertHelper.cpp
+++ b/security/manager/ssl/src/nsNSSCertHelper.cpp
@@ -840,19 +840,16 @@ ProcessName(CERTName *name, nsINSSCompon
   CERTRDN** rdns;
   CERTRDN** rdn;
   nsString finalString;
 
   rdns = name->rdns;
 
   nsresult rv;
   CERTRDN **lastRdn;
-  lastRdn = rdns;
-
-
   /* find last RDN */
   lastRdn = rdns;
   while (*lastRdn) lastRdn++;
   // The above whille loop will put us at the last member
   // of the array which is a nullptr pointer.  So let's back
   // up one spot so that we have the last non-nullptr entry in 
   // the array in preparation for traversing the 
   // RDN's (Relative Distinguished Name) in reverse oder.
--- a/security/manager/ssl/tests/unit/head_psm.js
+++ b/security/manager/ssl/tests/unit/head_psm.js
@@ -427,67 +427,75 @@ function getFailingHttpServer(serverPort
   });
   httpServer.start(serverPort);
   return httpServer;
 }
 
 // Starts an http OCSP responder that serves good OCSP responses and
 // returns an object with a method stop that should be called to stop
 // the http server.
+// NB: Because generating OCSP responses inside the HTTP request
+// handler can cause timeouts, the expected responses are pre-generated
+// all at once before starting the server. This means that their producedAt
+// times will all be the same. If a test depends on this not being the case,
+// perhaps calling startOCSPResponder twice (at different times) will be
+// necessary.
 //
 // serverPort is the port of the http OCSP responder
 // identity is the http hostname that will answer the OCSP requests
 // invalidIdentities is an array of identities that if used an
 //   will cause a test failure
 // nssDBlocaion is the location of the NSS database from where the OCSP
 //   responses will be generated (assumes appropiate keys are present)
 // expectedCertNames is an array of nicks of the certs to be responsed
 // expectedBasePaths is an optional array that is used to indicate
 //   what is the expected base path of the OCSP request.
 function startOCSPResponder(serverPort, identity, invalidIdentities,
                             nssDBLocation, expectedCertNames,
                             expectedBasePaths, expectedMethods,
                             expectedResponseTypes) {
+  let ocspResponseGenerationArgs = expectedCertNames.map(
+    function(expectedNick) {
+      let responseType = "good";
+      if (expectedResponseTypes && expectedResponseTypes.length >= 1) {
+        responseType = expectedResponseTypes.shift();
+      }
+      return [responseType, expectedNick, "unused"];
+    }
+  );
+  let ocspResponses = generateOCSPResponses(ocspResponseGenerationArgs,
+                                            nssDBLocation);
   let httpServer = new HttpServer();
   httpServer.registerPrefixHandler("/",
     function handleServerCallback(aRequest, aResponse) {
       invalidIdentities.forEach(function(identity) {
         do_check_neq(aRequest.host, identity)
       });
       do_print("got request for: " + aRequest.path);
       let basePath = aRequest.path.slice(1).split("/")[0];
       if (expectedBasePaths.length >= 1) {
         do_check_eq(basePath, expectedBasePaths.shift());
       }
       do_check_true(expectedCertNames.length >= 1);
       if (expectedMethods && expectedMethods.length >= 1) {
         do_check_eq(aRequest.method, expectedMethods.shift());
       }
-      let responseType = "good";
-      if (expectedResponseTypes && expectedResponseTypes.length >= 1) {
-        responseType = expectedResponseTypes.shift();
-      }
-      let expectedNick = expectedCertNames.shift();
-      do_print("Generating ocsp response(" + responseType + ") for '" +
-               expectedNick + "(" + basePath + ")'");
       aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
       aResponse.setHeader("Content-Type", "application/ocsp-response");
-      let args = [ [responseType, expectedNick, "unused" ] ];
-      let retArray = generateOCSPResponses(args, nssDBLocation);
-      let responseBody = retArray[0];
-      aResponse.bodyOutputStream.write(responseBody, responseBody.length);
+      aResponse.write(ocspResponses.shift());
     });
   httpServer.identity.setPrimary("http", identity, serverPort);
   invalidIdentities.forEach(function(identity) {
     httpServer.identity.add("http", identity, serverPort);
   });
   httpServer.start(serverPort);
   return {
     stop: function(callback) {
-      do_check_eq(expectedCertNames.length, 0);
+      // make sure we consumed each expected response
+      do_check_eq(ocspResponses.length, 0);
       if (expectedMethods) {
         do_check_eq(expectedMethods.length, 0);
       }
       if (expectedBasePaths) {
         do_check_eq(expectedBasePaths.length, 0);
       }
       if (expectedResponseTypes) {
         do_check_eq(expectedResponseTypes.length, 0);
--- a/security/manager/ssl/tests/unit/test_ocsp_caching.js
+++ b/security/manager/ssl/tests/unit/test_ocsp_caching.js
@@ -1,15 +1,22 @@
 // -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 "use strict";
 
 let gFetchCount = 0;
+let gGoodOCSPResponse = null;
+
+function generateGoodOCSPResponse() {
+  let args = [ ["good", "localhostAndExampleCom", "unused" ] ];
+  let responses = generateOCSPResponses(args, "tlsserver");
+  return responses[0];
+}
 
 function run_test() {
   do_get_profile();
   Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true);
   add_tls_server_setup("OCSPStaplingServer");
 
   let ocspResponder = new HttpServer();
   ocspResponder.registerPrefixHandler("/", function(request, response) {
@@ -22,26 +29,19 @@ function run_test() {
 
       response.setStatusLine(request.httpVersion, 500, "Internal Server Error");
       let body = "Refusing to return a response";
       response.bodyOutputStream.write(body, body.length);
       return;
     }
 
     do_print("returning 200 OK");
-
-    let nickname = "localhostAndExampleCom";
-    do_print("Generating ocsp response for '" + nickname + "'");
-    let args = [ ["good", nickname, "unused" ] ];
-    let ocspResponses = generateOCSPResponses(args, "tlsserver");
-    let goodResponse = ocspResponses[0];
-
     response.setStatusLine(request.httpVersion, 200, "OK");
     response.setHeader("Content-Type", "application/ocsp-response");
-    response.bodyOutputStream.write(goodResponse, goodResponse.length);
+    response.write(gGoodOCSPResponse);
   });
   ocspResponder.start(8080);
 
   add_tests_in_mode(true);
   add_tests_in_mode(false);
 
   add_test(function() { ocspResponder.stop(run_next_test); });
   run_next_test();
@@ -79,16 +79,20 @@ function add_tests_in_mode(useMozillaPKI
   // response will be seen as "not newer" and it won't replace the existing
   // entry.
   add_test(function() {
     let duration = 1200;
     do_print("Sleeping for " + duration + "ms");
     let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
     timer.initWithCallback(run_next_test, duration, Ci.nsITimer.TYPE_ONE_SHOT);
   });
+  add_test(function() {
+    gGoodOCSPResponse = generateGoodOCSPResponse();
+    run_next_test();
+  });
   add_connection_test("ocsp-stapling-none.example.com", Cr.NS_OK,
                       clearSessionCache);
   add_test(function() { do_check_eq(gFetchCount, 2); run_next_test(); });
 
   // The Good response retrieved from the previous fetch must have replaced
   // the Unknown response in the cache, resulting in the catched Good response
   // being returned and no fetch.
   add_connection_test("ocsp-stapling-none.example.com", Cr.NS_OK,
--- a/security/manager/tools/PreloadedHPKPins.json
+++ b/security/manager/tools/PreloadedHPKPins.json
@@ -166,19 +166,19 @@
       ]
     }
   ],
 
   "entries": [
     // Only domains that are operationally crucial to Firefox can have per-host
     // telemetry reporting (the "id") field
     { "name": "addons.mozilla.org", "include_subdomains": true,
-      "pins": "mozilla", "test_mode": true, "id": 1 },
+      "pins": "mozilla", "test_mode": false, "id": 1 },
     { "name": "addons.mozilla.net", "include_subdomains": true,
-      "pins": "mozilla", "test_mode": true, "id": 2 },
+      "pins": "mozilla", "test_mode": false, "id": 2 },
     { "name": "aus4.mozilla.org", "include_subdomains": true,
       "pins": "mozilla", "test_mode": true, "id": 3 },
     { "name": "cdn.mozilla.net", "include_subdomains": true,
       "pins": "mozilla", "test_mode": false },
     { "name": "cdn.mozilla.org", "include_subdomains": true,
       "pins": "mozilla", "test_mode": false },
     { "name": "media.mozilla.com", "include_subdomains": true,
       "pins": "mozilla", "test_mode": false },
--- a/security/pkix/include/pkix/pkixtypes.h
+++ b/security/pkix/include/pkix/pkixtypes.h
@@ -90,17 +90,17 @@ public:
   // *trustLevel == TrustAnchor unless the given cert is considered a trust
   // anchor *for that policy*. In particular, if the user has marked an
   // intermediate certificate as trusted, but that intermediate isn't in the
   // list of EV roots, then GetCertTrust must result in
   // *trustLevel == InheritsTrust instead of *trustLevel == TrustAnchor
   // (assuming the candidate cert is not actively distrusted).
   virtual SECStatus GetCertTrust(EndEntityOrCA endEntityOrCA,
                                  const CertPolicyId& policy,
-                                 const CERTCertificate* candidateCert,
+                                 const SECItem& candidateCertDER,
                          /*out*/ TrustLevel* trustLevel) = 0;
 
   // Find all certificates (intermediate and/or root) in the certificate
   // database that have a subject name matching |encodedIssuerName| at
   // the given time. Certificates where the given time is not within the
   // certificate's validity period may be excluded. On input, |results|
   // will be null on input. If no potential issuers are found, then this
   // function should return SECSuccess with results being either null or
--- a/security/pkix/lib/pkixcheck.cpp
+++ b/security/pkix/lib/pkixcheck.cpp
@@ -553,20 +553,18 @@ CheckIssuerIndependentProperties(TrustDo
                                  KeyPurposeId requiredEKUIfPresent,
                                  const CertPolicyId& requiredPolicy,
                                  unsigned int subCACount,
                 /*optional out*/ TrustLevel* trustLevelOut)
 {
   Result rv;
 
   TrustLevel trustLevel;
-  rv = MapSECStatus(trustDomain.GetCertTrust(endEntityOrCA,
-                                             requiredPolicy,
-                                             cert.GetNSSCert(),
-                                             &trustLevel));
+  rv = MapSECStatus(trustDomain.GetCertTrust(endEntityOrCA, requiredPolicy,
+                                             cert.GetDER(), &trustLevel));
   if (rv != Success) {
     return rv;
   }
   if (trustLevel == TrustLevel::ActivelyDistrusted) {
     return Fail(RecoverableError, SEC_ERROR_UNTRUSTED_CERT);
   }
   if (trustLevel != TrustLevel::TrustAnchor &&
       trustLevel != TrustLevel::InheritsTrust) {
--- a/security/pkix/lib/pkixutil.h
+++ b/security/pkix/lib/pkixutil.h
@@ -106,16 +106,18 @@ public:
     , nssCert(nssCert)
     , constrainedNames(nullptr)
     , includeCN(includeCN)
   {
   }
 
   Result Init();
 
+  const SECItem& GetDER() const { return nssCert->derCert; }
+
   const SECItem* encodedBasicConstraints;
   const SECItem* encodedCertificatePolicies;
   const SECItem* encodedExtendedKeyUsage;
   const SECItem* encodedKeyUsage;
   const SECItem* encodedNameConstraints;
   const SECItem* encodedInhibitAnyPolicy;
 
   BackCert* const childCert;
--- a/security/pkix/test/gtest/pkix_cert_chain_length_tests.cpp
+++ b/security/pkix/test/gtest/pkix_cert_chain_length_tests.cpp
@@ -110,20 +110,20 @@ public:
     }
 
     return true;
   }
 
 private:
   SECStatus GetCertTrust(EndEntityOrCA,
                          const CertPolicyId&,
-                         const CERTCertificate* candidateCert,
+                         const SECItem& candidateCert,
                          /*out*/ TrustLevel* trustLevel)
   {
-    if (candidateCert == certChainTail[0].get()) {
+    if (SECITEM_ItemsAreEqual(&candidateCert, &certChainTail[0]->derCert)) {
       *trustLevel = TrustLevel::TrustAnchor;
     } else {
       *trustLevel = TrustLevel::InheritsTrust;
     }
     return SECSuccess;
   }
 
   SECStatus FindPotentialIssuers(const SECItem* encodedIssuerName,
new file mode 100644
--- /dev/null
+++ b/security/pkix/tools/DottedOIDToCode.py
@@ -0,0 +1,113 @@
+# This code is made available to you under your choice of the following sets
+# of licensing terms:
+###############################################################################
+# 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/.
+###############################################################################
+# Copyright 2013 Mozilla Contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import print_function
+import sys
+
+def base128Stringified(value):
+    """
+    Encodes the given integral value into a string that is an encoded comma-
+    separated series of bytes, base-128, with all but the last byte having
+    the high bit set, in C++ hex notation, as required by the DER rules for the
+    nodes of an OID after the first two.
+
+    >>> base128Stringified(1)
+    '0x01'
+    >>> base128Stringified(10045)
+    '0xce, 0x3d'
+    """
+    if value < 0:
+        raise ValueError("An OID must have only positive-value nodes.")
+
+    format = "0x%.2x"
+
+    # least significant byte has highest bit unset
+    result = format % (value % 0x80)
+    value /= 0x80
+
+    while value != 0:
+        # other bytes have highest bit set
+        result = (format % (0x80 | (value % 0x80))) + ", " + result
+        value /= 0x80
+
+    return result
+    
+def dottedOIDToCEncoding(dottedOID):
+    """
+    Takes a dotted OID string (e.g. '1.2.840.10045.4.3.4') as input, and
+    returns a string that contains the hex encoding of the OID in C++ literal
+    notation, e.g. '0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04'. Note that
+    the ASN.1 tag and length are *not* included in the result.
+    """
+    nodes = [int(x) for x in dottedOID.strip().split(".")]
+    if len(nodes) < 2:
+        raise ValueError("An OID must have at least two nodes.")
+    if not (0 <= nodes[0] <= 2):
+        raise ValueError("The first node of an OID must be 0, 1, or 2.")
+    if not (0 <= nodes[1] <= 39):
+        # XXX: Does this restriction apply when the first part is 2?
+        raise ValueError("The second node of an OID must be 0-39.")
+    firstByte = (40 * nodes[0]) + nodes[1]
+    allStringified = [base128Stringified(x) for x in [firstByte] + nodes[2:]]
+    return ", ".join(allStringified)
+
+def specNameToCName(specName):
+    """
+    Given an string containing an ASN.1 name, returns a string that is a valid
+    C++ identifier that is as similar to that name as possible. Since most
+    ASN.1 identifiers used in PKIX specifications are legal C++ names except
+    for containing hyphens, this function just converts the hyphens to
+    underscores. This may need to be improved in the future if we encounter
+    names with other funny characters.
+    """
+    return specName.replace("-", "_")
+
+def toCode(programName, specName, dottedOID):
+    """
+    Given an ASN.1 name and a string containing the dotted representation of an
+    OID, returns a string that contains a C++ declaration for a named constant
+    that contains that OID value. Note that the ASN.1 tag and length are *not*
+    included in the result.
+
+    This:
+        toCode("DottedOIDToCode.py", "ecdsa-with-SHA512", "1.2.840.10045.4.3.4")
+    would result in a string like:
+      // python DottedOIDToCode.py ecdsa-with-SHA512 1.2.840.10045.4.3.4
+      static const uint8_t ecdsa_with_SHA512[] = {
+        0x2a, 0x86,0x48, 0xce,0x3d, 0x04, 0x03, 0x04
+      };
+    """
+    return ("  // python %s %s %s\n" +
+            "  static const uint8_t %s[] = {\n" +
+            "    %s\n" +
+            "  };\n") % (programName, specName, dottedOID,
+                         specNameToCName(specName),
+                         dottedOIDToCEncoding(dottedOID))
+
+if __name__ == "__main__":
+    if len(sys.argv) != 3:
+        print("usage:   python %s <name> <dotted-oid>" % sys.argv[0],
+              file=sys.stderr)
+        print("example: python %s ecdsa-with-SHA1 1.2.840.10045.4.1" %
+                  sys.argv[0], file=sys.stderr)
+        sys.exit(1)
+
+    print(toCode(sys.argv[0], sys.argv[1], sys.argv[2]))
--- a/security/sandbox/linux/SandboxFilter.cpp
+++ b/security/sandbox/linux/SandboxFilter.cpp
@@ -147,16 +147,17 @@ SandboxFilterImpl::Build() {
   Allow(SYSCALL(brk));
 #if SYSCALL_EXISTS(set_thread_area)
   Allow(SYSCALL(set_thread_area));
 #endif
 
   Allow(SYSCALL(getpid));
   Allow(SYSCALL(gettid));
   Allow(SYSCALL(getrusage));
+  Allow(SYSCALL(times));
   Allow(SYSCALL(madvise));
   Allow(SYSCALL(dup));
   Allow(SYSCALL(nanosleep));
   Allow(SYSCALL(poll));
   // select()'s arguments used to be passed by pointer as a struct.
 #if SYSCALL_EXISTS(_newselect)
   Allow(SYSCALL(_newselect));
 #else
--- a/testing/config/mozharness/linux_config.py
+++ b/testing/config/mozharness/linux_config.py
@@ -7,17 +7,18 @@ config = {
         "--appname=%(binary_path)s", "--utility-path=tests/bin",
         "--extra-profile-file=tests/bin/plugins", "--symbols-path=%(symbols_path)s"
     ],
     "mochitest_options": [
         "--appname=%(binary_path)s", "--utility-path=tests/bin",
         "--extra-profile-file=tests/bin/plugins", "--symbols-path=%(symbols_path)s",
         "--certificate-path=tests/certs", "--autorun", "--close-when-done",
         "--console-level=INFO", "--setpref=webgl.force-enabled=true",
-        "--quiet"
+        "--quiet",
+        "--use-test-media-devices"
     ],
     "webapprt_options": [
         "--app=%(app_path)s", "--utility-path=tests/bin",
         "--extra-profile-file=tests/bin/plugins", "--symbols-path=%(symbols_path)s",
         "--certificate-path=tests/certs", "--autorun", "--close-when-done",
         "--console-level=INFO", "--testing-modules-dir=tests/modules",
         "--quiet"
     ],
--- a/testing/marionette/client/setup.py
+++ b/testing/marionette/client/setup.py
@@ -1,13 +1,13 @@
 import os
 from setuptools import setup, find_packages
 import sys
 
-version = '0.7.7'
+version = '0.7.8'
 
 # dependencies
 with open('requirements.txt') as f:
     deps = f.read().splitlines()
 
 # Requirements.txt contains a pointer to the local copy of marionette_transport;
 # if we're installing using setup.py, handle this locally or replace with a valid
 # pypi package reference.
--- a/testing/mozbase/mozlog/mozlog/structured/structuredlog.py
+++ b/testing/mozbase/mozlog/mozlog/structured/structuredlog.py
@@ -162,17 +162,17 @@ class StructuredLogger(object):
         """
         if status.upper() not in ["PASS", "FAIL", "OK", "ERROR", "TIMEOUT",
                                   "CRASH", "ASSERT", "SKIP"]:
             raise ValueError("Unrecognised status %s" % status)
         data = {"test": test,
                 "status": status.upper()}
         if message is not None:
             data["message"] = message
-        if expected != data["status"]:
+        if expected != data["status"] and status != "SKIP":
             data["expected"] = expected
         if extra is not None:
             data["extra"] = extra
         self._log_data("test_end", data)
 
     def process_output(self, process, data, command=None):
         """Log output from a managed process.
 
--- a/testing/mozbase/mozversion/setup.py
+++ b/testing/mozbase/mozversion/setup.py
@@ -1,15 +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/.
 
 from setuptools import setup
 
-PACKAGE_VERSION = '0.4'
+PACKAGE_VERSION = '0.5'
 
 dependencies = ['mozdevice >= 0.29',
                 'mozfile >= 1.0',
                 'mozlog >= 1.5']
 
 setup(name='mozversion',
       version=PACKAGE_VERSION,
       description='Library to get version information for applications',
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -2085,200 +2085,200 @@
   "DNS_FAILED_LOOKUP_TIME": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": "60000",
     "n_buckets": 50,
     "extended_statistics_ok": true,
     "description": "Time for an unsuccessful DNS OS resolution (msec)"
   },
-  "SEER_PREDICT_ATTEMPTS": {
+  "PREDICTOR_PREDICT_ATTEMPTS": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": "1000 * 1000",
     "n_buckets": 50,
     "extended_statistics_ok": true,
-    "description": "Number of times nsINetworkSeer::Predict is called and attempts to predict"
-  },
-  "SEER_LEARN_ATTEMPTS": {
+    "description": "Number of times nsINetworkPredictor::Predict is called and attempts to predict"
+  },
+  "PREDICTOR_LEARN_ATTEMPTS": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": "1000 * 1000",
     "n_buckets": 50,
     "extended_statistics_ok": true,
-    "description": "Number of times nsINetworkSeer::Learn is called and attempts to learn"
-  },
-  "SEER_PREDICT_FULL_QUEUE": {
+    "description": "Number of times nsINetworkPredictor::Learn is called and attempts to learn"
+  },
+  "PREDICTOR_PREDICT_FULL_QUEUE": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": "60000",
     "n_buckets": 50,
     "extended_statistics_ok": true,
-    "description": "Number of times nsINetworkSeer::Predict doesn't continue because the queue is full"
-  },
-  "SEER_LEARN_FULL_QUEUE": {
+    "description": "Number of times nsINetworkPredictor::Predict doesn't continue because the queue is full"
+  },
+  "PREDICTOR_LEARN_FULL_QUEUE": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": "60000",
     "n_buckets": 50,
     "extended_statistics_ok": true,
-    "description": "Number of times nsINetworkSeer::Learn doesn't continue because the queue is full"
-  },
-  "SEER_PREDICT_WAIT_TIME": {
+    "description": "Number of times nsINetworkPredictor::Learn doesn't continue because the queue is full"
+  },
+  "PREDICTOR_PREDICT_WAIT_TIME": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": "3000",
     "n_buckets": 10,
     "extended_statistics_ok": true,
     "description": "Amount of time a predict event waits in the queue (ms)"
   },
-  "SEER_PREDICT_WORK_TIME": {
+  "PREDICTOR_PREDICT_WORK_TIME": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": "3000",
     "n_buckets": 10,
     "extended_statistics_ok": true,
     "description": "Amount of time spent doing the work for predict (ms)"
   },
-  "SEER_LEARN_WAIT_TIME": {
+  "PREDICTOR_LEARN_WAIT_TIME": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": "3000",
     "n_buckets": 10,
     "extended_statistics_ok": true,
     "description": "Amount of time a learn event waits in the queue (ms)"
   },
-  "SEER_LEARN_WORK_TIME": {
+  "PREDICTOR_LEARN_WORK_TIME": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": "3000",
     "n_buckets": 10,
     "extended_statistics_ok": true,
     "description": "Amount of time spent doing the work for learn (ms)"
   },
-  "SEER_TOTAL_PREDICTIONS": {
+  "PREDICTOR_TOTAL_PREDICTIONS": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": "1000 * 1000",
     "n_buckets": 50,
     "extended_statistics_ok": true,
     "description": "How many actual predictions (preresolves, preconnects, ...) happen"
   },
-  "SEER_TOTAL_PRECONNECTS": {
+  "PREDICTOR_TOTAL_PRECONNECTS": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": "1000 * 1000",
     "n_buckets": 50,
     "extended_statistics_ok": true,
     "description": "How many actual preconnects happen"
   },
-  "SEER_TOTAL_PRERESOLVES": {
+  "PREDICTOR_TOTAL_PRERESOLVES": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": "1000 * 1000",
     "n_buckets": 50,
     "extended_statistics_ok": true,
     "description": "How many actual preresolves happen"
   },
-  "SEER_PREDICTIONS_CALCULATED": {
+  "PREDICTOR_PREDICTIONS_CALCULATED": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": "1000 * 1000",
     "n_buckets": 50,
     "extended_statistics_ok": true,
     "description": "How many prediction calculations are performed"
   },
-  "SEER_GLOBAL_DEGRADATION": {
+  "PREDICTOR_GLOBAL_DEGRADATION": {
     "expires_in_version": "never",
     "kind": "linear",
     "high": "100",
     "n_buckets": 50,
     "description": "The global degradation calculated"
   },
-  "SEER_SUBRESOURCE_DEGRADATION": {
+  "PREDICTOR_SUBRESOURCE_DEGRADATION": {
     "expires_in_version": "never",
     "kind": "linear",
     "high": "100",
     "n_buckets": 50,
     "description": "The degradation calculated for a subresource"
   },
-  "SEER_BASE_CONFIDENCE": {
+  "PREDICTOR_BASE_CONFIDENCE": {
     "expires_in_version": "never",
     "kind": "linear",
     "high": "100",
     "n_buckets": 50,
     "description": "The base confidence calculated for a subresource"
   },
-  "SEER_CONFIDENCE": {
+  "PREDICTOR_CONFIDENCE": {
     "expires_in_version": "never",
     "kind": "linear",
     "high": "100",
     "n_buckets": 50,
     "description": "The final confidence calculated for a subresource"
   },
-  "SEER_PREDICT_TIME_TO_ACTION": {
+  "PREDICTOR_PREDICT_TIME_TO_ACTION": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": "3000",
     "n_buckets": 10,
     "description": "How long it takes from the time Predict() is called to the time we take action"
   },
-  "SEER_PREDICT_TIME_TO_INACTION": {
+  "PREDICTOR_PREDICT_TIME_TO_INACTION": {
     "expires_in_version": "never",
     "kind": "exponential",
     "high": "3000",
     "n_buckets": 10,
     "description": "How long it takes from the time Predict() is called to the time we figure out there's nothing to do"
   },
-  "SEER_CLEANUP_DELTA": {
+  "PREDICTOR_CLEANUP_DELTA": {
       "expires_in_version": "never",
       "kind": "exponential",
       "high": "60000",
       "n_buckets": 50,
-      "description": "How long between seer db cleanups, in ms"
-  },
-  "SEER_CLEANUP_SUCCEEDED": {
+      "description": "How long between predictor db cleanups, in ms"
+  },
+  "PREDICTOR_CLEANUP_SUCCEEDED": {
       "expires_in_version": "never",
       "kind": "boolean",
-      "description": "Whether or not the seer cleanup succeeded"
-  },
-  "SEER_CLEANUP_TIME": {
+      "description": "Whether or not the predictor cleanup succeeded"
+  },
+  "PREDICTOR_CLEANUP_TIME": {
       "expires_in_version": "never",
       "kind": "exponential",
       "high": "5000",
       "n_buckets": 10,
-      "description": "How long it takes to run the seer cleanup"
-  },
-  "SEER_CLEANUP_SCHEDULED": {
+      "description": "How long it takes to run the predictor cleanup"
+  },
+  "PREDICTOR_CLEANUP_SCHEDULED": {
       "expires_in_version": "never",
       "kind": "boolean",
       "description": "Whether or not we actually try the cleanup method when we think about it"
   },
-  "SEER_LOAD_COUNT_IS_ZERO": {
+  "PREDICTOR_LOAD_COUNT_IS_ZERO": {
       "expires_in_version": "never",
       "kind": "linear",
       "high": "100",
       "n_buckets": 50,
       "description": "Number of times load count is zero"
   },
-  "SEER_LOAD_COUNT_OVERFLOWS": {
+  "PREDICTOR_LOAD_COUNT_OVERFLOWS": {
       "expires_in_version": "never",
       "kind": "linear",
       "high": "100",
       "n_buckets": 50,
       "description": "Number of times load count overflowed"
   },
-  "SEER_STARTUP_COUNT_IS_ZERO": {
+  "PREDICTOR_STARTUP_COUNT_IS_ZERO": {
       "expires_in_version": "never",
       "kind": "linear",
       "high": "100",
       "n_buckets": 50,
       "description": "Number of times startup count is zero"
   },
-  "SEER_STARTUP_COUNT_OVERFLOWS": {
+  "PREDICTOR_STARTUP_COUNT_OVERFLOWS": {
       "expires_in_version": "never",
       "kind": "linear",
       "high": "100",
       "n_buckets": 50,
       "description": "Number of times startup count overflowed"
   },
   "FIND_PLUGINS": {
     "expires_in_version": "never",
--- a/toolkit/forgetaboutsite/ForgetAboutSite.jsm
+++ b/toolkit/forgetaboutsite/ForgetAboutSite.jsm
@@ -217,13 +217,13 @@ this.ForgetAboutSite = {
                getService(Ci.nsIContentPrefService2);
     cps2.removeBySubdomain(aDomain, null, {
       handleCompletion: function() onContentPrefsRemovalFinished(),
       handleError: function() {}
     });
 
     // Predictive network data - like cache, no way to clear this per
     // domain, so just trash it all
-    let ns = Cc["@mozilla.org/network/seer;1"].
-             getService(Ci.nsINetworkSeer);
-    ns.reset();
+    let np = Cc["@mozilla.org/network/predictor;1"].
+             getService(Ci.nsINetworkPredictor);
+    np.reset();
   }
 };
--- a/widget/gonk/HwcComposer2D.cpp
+++ b/widget/gonk/HwcComposer2D.cpp
@@ -254,25 +254,30 @@ HwcComposer2D::PrepareLayerList(Layer* a
                 return false;
             }
         }
         return true;
     }
 
     LayerRenderState state = aLayer->GetRenderState();
     nsIntSize surfaceSize;
+    bool skipLayer = false;
 
     if (state.mSurface.get()) {
         surfaceSize = state.mSize;
     } else {
         if (aLayer->AsColorLayer() && mColorFill) {
             fillColor = true;
         } else {
             LOGD("%s Layer doesn't have a gralloc buffer", aLayer->Name());
+#if ANDROID_VERSION >= 18
+            skipLayer = true;
+#else
             return false;
+#endif
         }
     }
     // Buffer rotation is not to be confused with the angled rotation done by a transform matrix
     // It's a fancy ThebesLayer feature used for scrolling
     if (state.BufferRotated()) {
         LOGD("%s Layer has a rotated buffer", aLayer->Name());
         return false;
     }
@@ -330,18 +335,18 @@ HwcComposer2D::PrepareLayerList(Layer* a
     }
 
     HwcLayer& hwcLayer = mList->hwLayers[current];
     hwcLayer.displayFrame = displayFrame;
     setCrop(&hwcLayer, sourceCrop);
     buffer_handle_t handle = fillColor ? nullptr : state.mSurface->getNativeBuffer()->handle;
     hwcLayer.handle = handle;
 
-    hwcLayer.flags = 0;
     hwcLayer.hints = 0;
+    hwcLayer.flags = skipLayer ? HWC_SKIP_LAYER : 0;
     hwcLayer.blending = isOpaque ? HWC_BLENDING_NONE : HWC_BLENDING_PREMULT;
 #if ANDROID_VERSION >= 17
     hwcLayer.compositionType = HWC_FRAMEBUFFER;
 
     hwcLayer.acquireFenceFd = -1;
     hwcLayer.releaseFenceFd = -1;
 #if ANDROID_VERSION >= 18
     hwcLayer.planeAlpha = opacity;
--- a/widget/windows/GfxInfo.cpp
+++ b/widget/windows/GfxInfo.cpp
@@ -940,27 +940,27 @@ GfxInfo::GetGfxDriverInfo()
     /* Disable D2D on Win8 on Intel HD Graphics on driver <= 8.15.10.2302
      * See bug 804144 and 863683
      */
     APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_WINDOWS_8,
         (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(IntelMobileHDGraphics),
       nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
       DRIVER_LESS_THAN_OR_EQUAL, V(8,15,10,2302) );
 
-    /* Disable D2D on AMD Catalyst 14.4+
+    /* Disable D2D on AMD Catalyst 14.4 until 14.6
      * See bug 984488
      */
-    APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
+    APPEND_TO_DRIVER_BLOCKLIST_RANGE( DRIVER_OS_ALL,
         (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorATI), GfxDriverInfo::allDevices,
       nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
-      DRIVER_GREATER_THAN_OR_EQUAL, V(14,1,0,0) );
-    APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
+      DRIVER_BETWEEN_INCLUSIVE_START, V(14,1,0,0), V(14,2,0,0), "ATI Catalyst 14.6+");
+    APPEND_TO_DRIVER_BLOCKLIST_RANGE( DRIVER_OS_ALL,
         (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAMD), GfxDriverInfo::allDevices,
       nsIGfxInfo::FEATURE_DIRECT2D, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
-      DRIVER_GREATER_THAN_OR_EQUAL, V(14,1,0,0) );
+      DRIVER_BETWEEN_INCLUSIVE_START, V(14,1,0,0), V(14,2,0,0), "ATI Catalyst 14.6+");
 
     /* Disable D3D9 layers on NVIDIA 6100/6150/6200 series due to glitches
      * whilst scrolling. See bugs: 612007, 644787 & 645872.
      */
     APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
       (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(NvidiaBlockD3D9Layers),
       nsIGfxInfo::FEATURE_DIRECT3D_9_LAYERS, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
       DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions );
--- a/xpcom/base/nsStackWalk.cpp
+++ b/xpcom/base/nsStackWalk.cpp
@@ -1195,17 +1195,16 @@ FramePointerStackWalk(NS_WalkStackCallba
     // 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)) {
-      printf("Aborting stack trace, PC is critical\n");
       return NS_ERROR_UNEXPECTED;
     }
     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.
       (*aCallback)(pc, bp, aClosure);
@@ -1272,17 +1271,16 @@ struct unwind_info
 
 static _Unwind_Reason_Code
 unwind_callback(struct _Unwind_Context* context, void* closure)
 {
   unwind_info* info = static_cast<unwind_info*>(closure);
   void* pc = reinterpret_cast<void*>(_Unwind_GetIP(context));
   // TODO Use something like '_Unwind_GetGR()' to get the stack pointer.
   if (IsCriticalAddress(pc)) {
-    printf("Aborting stack trace, PC is critical\n");
     info->isCriticalAbort = true;
     // We just want to stop the walk, so any error code will do.  Using
     // _URC_NORMAL_STOP would probably be the most accurate, but it is not
     // defined on Android for ARM.
     return _URC_FOREIGN_EXCEPTION_CAUGHT;
   }
   if (--info->skip < 0) {
     (*info->callback)(pc, nullptr, info->closure);
--- a/xpcom/reflect/xptinfo/src/ShimInterfaceInfo.cpp
+++ b/xpcom/reflect/xptinfo/src/ShimInterfaceInfo.cpp
@@ -134,17 +134,16 @@
 #include "nsIDOMNSEvent.h"
 #include "nsIDOMOfflineResourceList.h"
 #include "nsIDOMPageTransitionEvent.h"
 #include "nsIDOMPaintRequest.h"
 #include "nsIDOMParser.h"
 #include "nsIDOMPopStateEvent.h"
 #include "nsIDOMPopupBlockedEvent.h"
 #include "nsIDOMProcessingInstruction.h"
-#include "nsIDOMProgressEvent.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMRecordErrorEvent.h"
 #include "nsIDOMRect.h"
 #include "nsIDOMScreen.h"
 #include "nsIDOMScrollAreaEvent.h"
 #include "nsIDOMSerializer.h"
 #include "nsIDOMSimpleGestureEvent.h"
 #include "nsIDOMSmartCardEvent.h"
@@ -304,17 +303,16 @@
 #include "mozilla/dom/EventBinding.h"
 #include "mozilla/dom/OfflineResourceListBinding.h"
 #include "mozilla/dom/PageTransitionEventBinding.h"
 #include "mozilla/dom/PaintRequestBinding.h"
 #include "mozilla/dom/PopStateEventBinding.h"
 #include "mozilla/dom/PopupBlockedEventBinding.h"
 #include "mozilla/dom/PositionErrorBinding.h"
 #include "mozilla/dom/ProcessingInstructionBinding.h"
-#include "mozilla/dom/ProgressEventBinding.h"
 #include "mozilla/dom/RangeBinding.h"
 #include "mozilla/dom/RecordErrorEventBinding.h"
 #include "mozilla/dom/RectBinding.h"
 #include "mozilla/dom/ScreenBinding.h"
 #include "mozilla/dom/SelectionBinding.h"
 #include "mozilla/dom/ScrollAreaEventBinding.h"
 #include "mozilla/dom/SimpleGestureEventBinding.h"
 #include "mozilla/dom/SmartCardEventBinding.h"
@@ -525,17 +523,16 @@ const ComponentsInterfaceShimEntry kComp
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIDOMNSEvent, Event),
   DEFINE_SHIM(OfflineResourceList),
   DEFINE_SHIM(PageTransitionEvent),
   DEFINE_SHIM(PaintRequest),
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIDOMParser, DOMParser),
   DEFINE_SHIM(PopStateEvent),
   DEFINE_SHIM(PopupBlockedEvent),
   DEFINE_SHIM(ProcessingInstruction),
-  DEFINE_SHIM(ProgressEvent),
   DEFINE_SHIM(Range),
   DEFINE_SHIM(RecordErrorEvent),
   DEFINE_SHIM(Rect),
   DEFINE_SHIM(Screen),
   DEFINE_SHIM(ScrollAreaEvent),
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIDOMSerializer, XMLSerializer),
   DEFINE_SHIM(SimpleGestureEvent),
   DEFINE_SHIM(SmartCardEvent),