Merge m-c to fig.
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 20 Aug 2013 16:33:28 -0400
changeset 143570 7e83ba2dfb5154d03ba3071c1f0476cb132b3fff
parent 143569 37e17d2fe8a7de9b9af6e2b031492fee818dc7b6 (current diff)
parent 143295 d136c8999d967cb04004373ba80420217e1a8ce4 (diff)
child 143571 6cd2461aa319baac1dee58ab3f67eb23ff3a2721
push id25130
push userlrocha@mozilla.com
push dateWed, 21 Aug 2013 09:41:27 +0000
treeherdermozilla-central@b2486721572e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone26.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 m-c to fig.
mobile/android/base/PageActionLayout.java
mobile/android/chrome/content/browser.js
toolkit/devtools/apps/tests/Makefile.in
xpcom/ds/nsByteBuffer.cpp
xpcom/ds/nsByteBuffer.h
xpcom/ds/nsIByteBuffer.h
xpcom/ds/nsIUnicharBuffer.h
xpcom/ds/nsUnicharBuffer.cpp
xpcom/ds/nsUnicharBuffer.h
--- a/Makefile.in
+++ b/Makefile.in
@@ -89,16 +89,19 @@ export::
 	$(MAKE) -C config export
 	$(MAKE) tier_nspr
 
 ifdef ENABLE_TESTS
 # Additional makefile targets to call automated test suites
 include $(topsrcdir)/testing/testsuite-targets.mk
 endif
 
+# Hacky way for precompile tier to bypass default tier traversal mechanism.
+TIER_precompile_CUSTOM := 1
+
 include $(topsrcdir)/config/rules.mk
 
 distclean::
 	cat unallmakefiles | $(XARGS) rm -f
 	$(RM) unallmakefiles $(DIST_GARBAGE)
 
 ifeq ($(OS_ARCH),WINNT)
 # we want to copy PDB files on Windows
--- a/b2g/components/UpdatePrompt.js
+++ b/b2g/components/UpdatePrompt.js
@@ -504,50 +504,61 @@ UpdatePrompt.prototype = {
   // nsITimerCallback
 
   notify: function UP_notify(aTimer) {
     if (aTimer == this._applyPromptTimer) {
       log("Timed out waiting for result, restarting");
       this._applyPromptTimer = null;
       this.finishUpdate();
       this._update = null;
+      return;
+    }
+    if (aTimer == this._watchdogTimer) {
+      log("Download watchdog fired");
+      this._watchdogTimer = null;
+      this._autoRestartDownload = true;
+      Services.aus.pauseDownload();
+      return;
     }
   },
 
   createTimer: function UP_createTimer(aTimeoutMs) {
     let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
     timer.initWithCallback(this, aTimeoutMs, timer.TYPE_ONE_SHOT);
     return timer;
   },
 
   // nsIRequestObserver
 
   _startedSent: false,
 
   _watchdogTimer: null,
-  _watchdogTimeout: 0,
 
   _autoRestartDownload: false,
   _autoRestartCount: 0,
 
-  watchdogTimerFired: function UP_watchdogTimerFired() {
-    log("Download watchdog fired");
-    this._autoRestartDownload = true;
-    Services.aus.pauseDownload();
-  },
-
   startWatchdogTimer: function UP_startWatchdogTimer() {
+    let watchdogTimeout = 120000;  // 120 seconds
+    try {
+      watchdogTimeout = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_TIMEOUT);
+    } catch (e) {
+      // This means that the preference doesn't exist. watchdogTimeout will
+      // retain its default assigned above.
+    }
+    if (watchdogTimeout <= 0) {
+      // 0 implies don't bother using the watchdog timer at all.
+      this._watchdogTimer = null;
+      return;
+    }
     if (this._watchdogTimer) {
       this._watchdogTimer.cancel();
     } else {
       this._watchdogTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-      this._watchdogTimeout = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_TIMEOUT);
     }
-    this._watchdogTimer.initWithCallback(this.watchdogTimerFired.bind(this),
-                                         this._watchdogTimeout,
+    this._watchdogTimer.initWithCallback(this, watchdogTimeout,
                                          Ci.nsITimer.TYPE_ONE_SHOT);
   },
 
   stopWatchdogTimer: function UP_stopWatchdogTimer() {
     if (this._watchdogTimer) {
       this._watchdogTimer.cancel();
       this._watchdogTimer = null;
     }
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "f98ec5e292dffd144f0a6520cc18ff5cb7762d09", 
+    "revision": "dbaee540a7d23d271e62e7da80d7db226be8860b", 
     "repo_path": "/integration/gaia-central"
 }
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -331,17 +331,17 @@ pref("browser.download.manager.closeWhen
 pref("browser.download.manager.focusWhenStarting", false);
 pref("browser.download.manager.flashCount", 2);
 pref("browser.download.manager.addToRecentDocs", true);
 pref("browser.download.manager.quitBehavior", 0);
 pref("browser.download.manager.scanWhenDone", true);
 pref("browser.download.manager.resumeOnWakeDelay", 10000);
 
 // Enables the asynchronous Downloads API in the Downloads Panel.
-pref("browser.download.useJSTransfer", true);
+pref("browser.download.useJSTransfer", false);
 
 // This allows disabling the Downloads Panel in favor of the old interface.
 pref("browser.download.useToolkitUI", false);
 
 // This allows disabling the animated notifications shown by
 // the Downloads Indicator when a download starts or completes.
 pref("browser.download.animateNotifications", true);
 
--- a/browser/base/content/sanitize.js
+++ b/browser/base/content/sanitize.js
@@ -82,18 +82,17 @@ Sanitizer.prototype = {
           // Callers should check returned errors and give user feedback
           // about items that could not be sanitized
           let item = this.items[itemName];
           try {
             if (aCanClear)
               item.clear();
           } catch(er) {
             seenError = true;
-            Components.utils.reportError("Error sanitizing " + itemName +
-                                         ": " + er + "\n");
+            Cu.reportError("Error sanitizing " + itemName + ": " + er + "\n");
           }
           onItemComplete();
         };
         this.canClearItem(itemName, clearCallback);
       } else {
         onItemComplete();
       }
     }
@@ -317,17 +316,17 @@ Sanitizer.prototype = {
                             download.startTime <= this.range[1]) : null;
 
             // Clear all completed/cancelled downloads
             let publicList = yield Downloads.getPublicDownloadList();
             publicList.removeFinished(filterByTime);
 
             let privateList = yield Downloads.getPrivateDownloadList();
             privateList.removeFinished(filterByTime);
-          }.bind(this)).then(null, Components.utils.reportError);
+          }.bind(this)).then(null, Cu.reportError);
         }
         else {
           var dlMgr = Components.classes["@mozilla.org/download-manager;1"]
                                 .getService(Components.interfaces.nsIDownloadManager);
 
           if (this.range) {
             // First, remove the completed/cancelled downloads
             dlMgr.removeDownloadsByTimeframe(this.range[0], this.range[1]);
--- a/browser/base/content/test/browser_sanitize-timespans.js
+++ b/browser/base/content/test/browser_sanitize-timespans.js
@@ -1,53 +1,39 @@
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 // Bug 453440 - Test the timespan-based logic of the sanitizer code
 var now_uSec = Date.now() * 1000;
 
+const dm = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager);
+
 const kUsecPerMin = 60 * 1000000;
 
 let tempScope = {};
 Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
                                            .loadSubScript("chrome://browser/content/sanitize.js", tempScope);
 let Sanitizer = tempScope.Sanitizer;
 
 let FormHistory = (Components.utils.import("resource://gre/modules/FormHistory.jsm", {})).FormHistory;
-let Downloads = (Components.utils.import("resource://gre/modules/Downloads.jsm", {})).Downloads;
 
 function promiseFormHistoryRemoved() {
   let deferred = Promise.defer();
   Services.obs.addObserver(function onfh() {
     Services.obs.removeObserver(onfh, "satchel-storage-changed", false);
     deferred.resolve();
   }, "satchel-storage-changed", false);
   return deferred.promise;
 }
 
-function promiseDownloadRemoved(list) {
-  let deferred = Promise.defer();
-
-  let view = {
-    onDownloadRemoved: function(download) {
-      list.removeView(view);
-      deferred.resolve();
-    }
-  };
-
-  list.addView(view);
-  
-  return deferred.promise;
-}
-
 function test() {
   waitForExplicitFinish();
 
   Task.spawn(function() {
-    yield setupDownloads();
+    setupDownloads();
     yield setupFormHistory();
     yield setupHistory();
     yield onHistoryReady();
   }).then(finish);
 }
 
 function countEntries(name, message, check) {
   let deferred = Promise.defer();
@@ -89,26 +75,22 @@ function onHistoryReady() {
   itemPrefs.setBoolPref("cache", false);
   itemPrefs.setBoolPref("cookies", false);
   itemPrefs.setBoolPref("formdata", true);
   itemPrefs.setBoolPref("offlineApps", false);
   itemPrefs.setBoolPref("passwords", false);
   itemPrefs.setBoolPref("sessions", false);
   itemPrefs.setBoolPref("siteSettings", false);
 
-  let publicList = yield Downloads.getPublicDownloadList();
-  let downloadPromise = promiseDownloadRemoved(publicList);
-
   // Clear 10 minutes ago
   s.range = [now_uSec - 10*60*1000000, now_uSec];
   s.sanitize();
   s.range = null;
 
   yield promiseFormHistoryRemoved();
-  yield downloadPromise;
 
   ok(!(yield promiseIsURIVisited(makeURI("http://10minutes.com"))),
      "Pretend visit to 10minutes.com should now be deleted");
   ok((yield promiseIsURIVisited(makeURI("http://1hour.com"))),
      "Pretend visit to 1hour.com should should still exist");
   ok((yield promiseIsURIVisited(makeURI("http://1hour10minutes.com"))),
      "Pretend visit to 1hour10minutes.com should should still exist");
   ok((yield promiseIsURIVisited(makeURI("http://2hour.com"))),
@@ -135,37 +117,33 @@ function onHistoryReady() {
   yield countEntries("2hour", "2hour form entry should still exist", checkOne);
   yield countEntries("2hour10minutes", "2hour10minutes form entry should still exist", checkOne);
   yield countEntries("4hour", "4hour form entry should still exist", checkOne);
   yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne);
   if (minutesSinceMidnight > 10)
     yield countEntries("today", "today form entry should still exist", checkOne);
   yield countEntries("b4today", "b4today form entry should still exist", checkOne);
 
-  let downloads = yield publicList.getAll();
-  ok(!(yield downloadExists(publicList, "fakefile-10-minutes")), "10 minute download should now be deleted");
-  ok((yield downloadExists(publicList, "fakefile-1-hour")), "<1 hour download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-1-hour-10-minutes")), "1 hour 10 minute download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-2-hour")), "<2 hour old download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "2 hour 10 minute download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present");
+  ok(!downloadExists(5555555), "10 minute download should now be deleted");
+  ok(downloadExists(5555551), "<1 hour download should still be present");
+  ok(downloadExists(5555556), "1 hour 10 minute download should still be present");
+  ok(downloadExists(5555550), "Year old download should still be present");
+  ok(downloadExists(5555552), "<2 hour old download should still be present");
+  ok(downloadExists(5555557), "2 hour 10 minute download should still be present");
+  ok(downloadExists(5555553), "<4 hour old download should still be present");
+  ok(downloadExists(5555558), "4 hour 10 minute download should still be present");
 
   if (minutesSinceMidnight > 10)
-    ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present");
-
-  downloadPromise = promiseDownloadRemoved(publicList);
+    ok(downloadExists(5555554), "'Today' download should still be present");
 
   // Clear 1 hour
   Sanitizer.prefs.setIntPref("timeSpan", 1);
   s.sanitize();
 
   yield promiseFormHistoryRemoved();
-  yield downloadPromise;
 
   ok(!(yield promiseIsURIVisited(makeURI("http://1hour.com"))),
      "Pretend visit to 1hour.com should now be deleted");
   ok((yield promiseIsURIVisited(makeURI("http://1hour10minutes.com"))),
      "Pretend visit to 1hour10minutes.com should should still exist");
   ok((yield promiseIsURIVisited(makeURI("http://2hour.com"))),
      "Pretend visit to 2hour.com should should still exist");
   ok((yield promiseIsURIVisited(makeURI("http://2hour10minutes.com"))),
@@ -186,36 +164,33 @@ function onHistoryReady() {
   yield countEntries("2hour", "2hour form entry should still exist", checkOne);
   yield countEntries("2hour10minutes", "2hour10minutes form entry should still exist", checkOne);
   yield countEntries("4hour", "4hour form entry should still exist", checkOne);
   yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne);
   if (hoursSinceMidnight > 1)
     yield countEntries("today", "today form entry should still exist", checkOne);
   yield countEntries("b4today", "b4today form entry should still exist", checkOne);
 
-  ok(!(yield downloadExists(publicList, "fakefile-1-hour")), "<1 hour download should now be deleted");
-  ok((yield downloadExists(publicList, "fakefile-1-hour-10-minutes")), "1 hour 10 minute download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-2-hour")), "<2 hour old download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "2 hour 10 minute download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present");
+  ok(!downloadExists(5555551), "<1 hour download should now be deleted");
+  ok(downloadExists(5555556), "1 hour 10 minute download should still be present");
+  ok(downloadExists(5555550), "Year old download should still be present");
+  ok(downloadExists(5555552), "<2 hour old download should still be present");
+  ok(downloadExists(5555557), "2 hour 10 minute download should still be present");
+  ok(downloadExists(5555553), "<4 hour old download should still be present");
+  ok(downloadExists(5555558), "4 hour 10 minute download should still be present");
 
   if (hoursSinceMidnight > 1)
-    ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present");
+    ok(downloadExists(5555554), "'Today' download should still be present");
   
-  downloadPromise = promiseDownloadRemoved(publicList);
-
   // Clear 1 hour 10 minutes
   s.range = [now_uSec - 70*60*1000000, now_uSec];
   s.sanitize();
   s.range = null;
 
   yield promiseFormHistoryRemoved();
-  yield downloadPromise;
 
   ok(!(yield promiseIsURIVisited(makeURI("http://1hour10minutes.com"))),
      "Pretend visit to 1hour10minutes.com should now be deleted");
   ok((yield promiseIsURIVisited(makeURI("http://2hour.com"))),
      "Pretend visit to 2hour.com should should still exist");
   ok((yield promiseIsURIVisited(makeURI("http://2hour10minutes.com"))),
      "Pretend visit to 2hour10minutes.com should should still exist");
   ok((yield promiseIsURIVisited(makeURI("http://4hour.com"))),
@@ -233,33 +208,30 @@ function onHistoryReady() {
   yield countEntries("2hour", "2hour form entry should still exist", checkOne);
   yield countEntries("2hour10minutes", "2hour10minutes form entry should still exist", checkOne);
   yield countEntries("4hour", "4hour form entry should still exist", checkOne);
   yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne);
   if (minutesSinceMidnight > 70)
     yield countEntries("today", "today form entry should still exist", checkOne);
   yield countEntries("b4today", "b4today form entry should still exist", checkOne);
 
-  ok(!(yield downloadExists(publicList, "fakefile-1-hour-10-minutes")), "1 hour 10 minute old download should now be deleted");
-  ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-2-hour")), "<2 hour old download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "2 hour 10 minute download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present");
+  ok(!downloadExists(5555556), "1 hour 10 minute old download should now be deleted");
+  ok(downloadExists(5555550), "Year old download should still be present");
+  ok(downloadExists(5555552), "<2 hour old download should still be present");
+  ok(downloadExists(5555557), "2 hour 10 minute download should still be present");
+  ok(downloadExists(5555553), "<4 hour old download should still be present");
+  ok(downloadExists(5555558), "4 hour 10 minute download should still be present");
   if (minutesSinceMidnight > 70)
-    ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present");
-
-  downloadPromise = promiseDownloadRemoved(publicList);
+    ok(downloadExists(5555554), "'Today' download should still be present");
 
   // Clear 2 hours
   Sanitizer.prefs.setIntPref("timeSpan", 2);
   s.sanitize();
 
   yield promiseFormHistoryRemoved();
-  yield downloadPromise;
 
   ok(!(yield promiseIsURIVisited(makeURI("http://2hour.com"))),
      "Pretend visit to 2hour.com should now be deleted");
   ok((yield promiseIsURIVisited(makeURI("http://2hour10minutes.com"))),
      "Pretend visit to 2hour10minutes.com should should still exist");
   ok((yield promiseIsURIVisited(makeURI("http://4hour.com"))),
      "Pretend visit to 4hour.com should should still exist");
   ok((yield promiseIsURIVisited(makeURI("http://4hour10minutes.com"))),
@@ -274,33 +246,30 @@ function onHistoryReady() {
   yield countEntries("2hour", "2hour form entry should be deleted", checkZero);
   yield countEntries("2hour10minutes", "2hour10minutes form entry should still exist", checkOne);
   yield countEntries("4hour", "4hour form entry should still exist", checkOne);
   yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne);
   if (hoursSinceMidnight > 2)
     yield countEntries("today", "today form entry should still exist", checkOne);
   yield countEntries("b4today", "b4today form entry should still exist", checkOne);
 
-  ok(!(yield downloadExists(publicList, "fakefile-2-hour")), "<2 hour old download should now be deleted");
-  ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "2 hour 10 minute download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present");
+  ok(!downloadExists(5555552), "<2 hour old download should now be deleted");
+  ok(downloadExists(5555550), "Year old download should still be present");
+  ok(downloadExists(5555557), "2 hour 10 minute download should still be present");
+  ok(downloadExists(5555553), "<4 hour old download should still be present");
+  ok(downloadExists(5555558), "4 hour 10 minute download should still be present");
   if (hoursSinceMidnight > 2)
-    ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present");
+    ok(downloadExists(5555554), "'Today' download should still be present");
   
-  downloadPromise = promiseDownloadRemoved(publicList);
-
   // Clear 2 hours 10 minutes
   s.range = [now_uSec - 130*60*1000000, now_uSec];
   s.sanitize();
   s.range = null;
 
   yield promiseFormHistoryRemoved();
-  yield downloadPromise;
 
   ok(!(yield promiseIsURIVisited(makeURI("http://2hour10minutes.com"))),
      "Pretend visit to 2hour10minutes.com should now be deleted");
   ok((yield promiseIsURIVisited(makeURI("http://4hour.com"))),
      "Pretend visit to 4hour.com should should still exist");
   ok((yield promiseIsURIVisited(makeURI("http://4hour10minutes.com"))),
      "Pretend visit to 4hour10minutes.com should should still exist");
   if (minutesSinceMidnight > 130) {
@@ -312,31 +281,28 @@ function onHistoryReady() {
 
   yield countEntries("2hour10minutes", "2hour10minutes form entry should be deleted", checkZero);
   yield countEntries("4hour", "4hour form entry should still exist", checkOne);
   yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne);
   if (minutesSinceMidnight > 130)
     yield countEntries("today", "today form entry should still exist", checkOne);
   yield countEntries("b4today", "b4today form entry should still exist", checkOne);
 
-  ok(!(yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "2 hour 10 minute old download should now be deleted");
-  ok((yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present");
+  ok(!downloadExists(5555557), "2 hour 10 minute old download should now be deleted");
+  ok(downloadExists(5555553), "<4 hour old download should still be present");
+  ok(downloadExists(5555558), "4 hour 10 minute download should still be present");
+  ok(downloadExists(5555550), "Year old download should still be present");
   if (minutesSinceMidnight > 130)
-    ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present");
-
-  downloadPromise = promiseDownloadRemoved(publicList);
+    ok(downloadExists(5555554), "'Today' download should still be present");
 
   // Clear 4 hours
   Sanitizer.prefs.setIntPref("timeSpan", 3);
   s.sanitize();
 
   yield promiseFormHistoryRemoved();
-  yield downloadPromise;
 
   ok(!(yield promiseIsURIVisited(makeURI("http://4hour.com"))),
      "Pretend visit to 4hour.com should now be deleted");
   ok((yield promiseIsURIVisited(makeURI("http://4hour10minutes.com"))),
      "Pretend visit to 4hour10minutes.com should should still exist");
   if (hoursSinceMidnight > 4) {
     ok((yield promiseIsURIVisited(makeURI("http://today.com"))),
        "Pretend visit to today.com should still exist");
@@ -345,94 +311,85 @@ function onHistoryReady() {
     "Pretend visit to before-today.com should still exist");
 
   yield countEntries("4hour", "4hour form entry should be deleted", checkZero);
   yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne);
   if (hoursSinceMidnight > 4)
     yield countEntries("today", "today form entry should still exist", checkOne);
   yield countEntries("b4today", "b4today form entry should still exist", checkOne);
 
-  ok(!(yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should now be deleted");
-  ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present");
-  ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present");
+  ok(!downloadExists(5555553), "<4 hour old download should now be deleted");
+  ok(downloadExists(5555558), "4 hour 10 minute download should still be present");
+  ok(downloadExists(5555550), "Year old download should still be present");
   if (hoursSinceMidnight > 4)
-    ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present");
-
-  downloadPromise = promiseDownloadRemoved(publicList);
+    ok(downloadExists(5555554), "'Today' download should still be present");
 
   // Clear 4 hours 10 minutes
   s.range = [now_uSec - 250*60*1000000, now_uSec];
   s.sanitize();
   s.range = null;
 
   yield promiseFormHistoryRemoved();
-  yield downloadPromise;
 
   ok(!(yield promiseIsURIVisited(makeURI("http://4hour10minutes.com"))),
      "Pretend visit to 4hour10minutes.com should now be deleted");
   if (minutesSinceMidnight > 250) {
     ok((yield promiseIsURIVisited(makeURI("http://today.com"))),
        "Pretend visit to today.com should still exist");
   }
   ok((yield promiseIsURIVisited(makeURI("http://before-today.com"))),
     "Pretend visit to before-today.com should still exist");
 
   yield countEntries("4hour10minutes", "4hour10minutes form entry should be deleted", checkZero);
   if (minutesSinceMidnight > 250)
     yield countEntries("today", "today form entry should still exist", checkOne);
   yield countEntries("b4today", "b4today form entry should still exist", checkOne);
   
-  ok(!(yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should now be deleted");
-  ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present");
+  ok(!downloadExists(5555558), "4 hour 10 minute download should now be deleted");
+  ok(downloadExists(5555550), "Year old download should still be present");
   if (minutesSinceMidnight > 250)
-    ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present");
-
-  downloadPromise = promiseDownloadRemoved(publicList);
+    ok(downloadExists(5555554), "'Today' download should still be present");
 
   // Clear Today
   Sanitizer.prefs.setIntPref("timeSpan", 4);
   s.sanitize();
 
   yield promiseFormHistoryRemoved();
-  yield downloadPromise;
 
   // Be careful.  If we add our objectss just before midnight, and sanitize
   // runs immediately after, they won't be expired.  This is expected, but
   // we should not test in that case.  We cannot just test for opposite
   // condition because we could cross midnight just one moment after we
   // cache our time, then we would have an even worse random failure.
   var today = isToday(new Date(now_uSec/1000));
   if (today) {
     ok(!(yield promiseIsURIVisited(makeURI("http://today.com"))),
        "Pretend visit to today.com should now be deleted");
 
     yield countEntries("today", "today form entry should be deleted", checkZero);
-    ok(!(yield downloadExists(publicList, "fakefile-today")), "'Today' download should now be deleted");
+    ok(!downloadExists(5555554), "'Today' download should now be deleted");
   }
 
   ok((yield promiseIsURIVisited(makeURI("http://before-today.com"))),
      "Pretend visit to before-today.com should still exist");
   yield countEntries("b4today", "b4today form entry should still exist", checkOne);
-  ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present");
-
-  downloadPromise = promiseDownloadRemoved(publicList);
+  ok(downloadExists(5555550), "Year old download should still be present");
 
   // Choose everything
   Sanitizer.prefs.setIntPref("timeSpan", 0);
   s.sanitize();
 
   yield promiseFormHistoryRemoved();
-  yield downloadPromise;
 
   ok(!(yield promiseIsURIVisited(makeURI("http://before-today.com"))),
      "Pretend visit to before-today.com should now be deleted");
 
   yield countEntries("b4today", "b4today form entry should be deleted", checkZero);
 
-  ok(!(yield downloadExists(publicList, "fakefile-old")), "Year old download should now be deleted");
+  ok(!downloadExists(5555550), "Year old download should now be deleted");
 }
 
 function setupHistory() {
   let deferred = Promise.defer();
 
   let places = [];
 
   function addPlace(aURI, aTitle, aVisitDate) {
@@ -600,124 +557,254 @@ function setupFormHistory() {
   yield countEntries("4hour10minutes", "Checking for 4hour10minutes form history entry creation", checkOne);
   yield countEntries("today", "Checking for today form history entry creation", checkOne);
   yield countEntries("b4today", "Checking for b4today form history entry creation", checkOne);
   is(checks, 9, "9 checks made");
 }
 
 function setupDownloads() {
 
-  let publicList = yield Downloads.getPublicDownloadList();
-
-  let download = yield Downloads.createDownload({
+  // Add 10-minutes download to DB
+  let data = {
+    id:   "5555555",
+    name: "fakefile-10-minutes",
     source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
-    target: "fakefile-10-minutes"
-  });
-  download.startTime = new Date(now_uSec - 10 * kUsecPerMin), // 10 minutes ago, in uSec
-  download.canceled = true;
-  publicList.add(download);
+    target: "fakefile-10-minutes",
+    startTime: now_uSec - 10 * kUsecPerMin, // 10 minutes ago, in uSec
+    endTime: now_uSec - 11 * kUsecPerMin, // 1 minute later
+    state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
+    currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0,
+    guid: "a1bcD23eF4g5"
+  };
 
-  download = yield Downloads.createDownload({
+  let db = dm.DBConnection;
+  let stmt = db.createStatement(
+    "INSERT INTO moz_downloads (id, name, source, target, startTime, endTime, " +
+      "state, currBytes, maxBytes, preferredAction, autoResume, guid) " +
+    "VALUES (:id, :name, :source, :target, :startTime, :endTime, :state, " +
+      ":currBytes, :maxBytes, :preferredAction, :autoResume, :guid)");
+  try {
+    for (let prop in data)
+      stmt.params[prop] = data[prop];
+    stmt.execute();
+  }
+  finally {
+    stmt.reset();
+  }
+  
+  // Add within-1-hour download to DB
+  data = {
+    id:   "5555551",
+    name: "fakefile-1-hour",
     source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
-    target: "fakefile-1-hour"
-  });
-  download.startTime = new Date(now_uSec - 45 * kUsecPerMin), // 45 minutes ago, in uSec
-  download.canceled = true;
-  publicList.add(download);
+    target: "fakefile-1-hour",
+    startTime: now_uSec - 45 * kUsecPerMin, // 45 minutes ago, in uSec
+    endTime: now_uSec - 44 * kUsecPerMin, // 1 minute later
+    state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
+    currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0,
+    guid: "1bcD23eF4g5a"
+  };
 
-  download = yield Downloads.createDownload({
+  try {
+    for (let prop in data)
+      stmt.params[prop] = data[prop];
+    stmt.execute();
+  }
+  finally {
+    stmt.reset();
+  }
+  
+  // Add 1-hour-10-minutes download to DB
+  data = {
+    id:   "5555556",
+    name: "fakefile-1-hour-10-minutes",
     source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
-    target: "fakefile-1-hour-10-minutes"
-  });
-  download.startTime = new Date(now_uSec - 70 * kUsecPerMin), // 70 minutes ago, in uSec
-  download.canceled = true;
-  publicList.add(download);
+    target: "fakefile-1-hour-10-minutes",
+    startTime: now_uSec - 70 * kUsecPerMin, // 70 minutes ago, in uSec
+    endTime: now_uSec - 71 * kUsecPerMin, // 1 minute later
+    state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
+    currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0,
+    guid: "a1cbD23e4Fg5"
+  };
 
-  download = yield Downloads.createDownload({
+  try {
+    for (let prop in data)
+      stmt.params[prop] = data[prop];
+    stmt.execute();
+  }
+  finally {
+    stmt.reset();
+  }
+
+  // Add within-2-hour download  
+  data = {
+    id:   "5555552",
+    name: "fakefile-2-hour",
     source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
-    target: "fakefile-2-hour"
-  });
-  download.startTime = new Date(now_uSec - 90 * kUsecPerMin), // 90 minutes ago, in uSec
-  download.canceled = true;
-  publicList.add(download);
+    target: "fakefile-2-hour",
+    startTime: now_uSec - 90 * kUsecPerMin, // 90 minutes ago, in uSec
+    endTime: now_uSec - 89 * kUsecPerMin, // 1 minute later
+    state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
+    currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0,
+    guid: "b1aDc23eFg54"
+  };
 
-  download = yield Downloads.createDownload({
+  try {
+    for (let prop in data)
+      stmt.params[prop] = data[prop];
+    stmt.execute();
+  }
+  finally {
+    stmt.reset();
+  }
+  
+  // Add 2-hour-10-minutes download  
+  data = {
+    id:   "5555557",
+    name: "fakefile-2-hour-10-minutes",
     source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
-    target: "fakefile-2-hour-10-minutes"
-  });
-  download.startTime = new Date(now_uSec - 130 * kUsecPerMin), // 130 minutes ago, in uSec
-  download.canceled = true;
-  publicList.add(download);
+    target: "fakefile-2-hour-10-minutes",
+    startTime: now_uSec - 130 * kUsecPerMin, // 130 minutes ago, in uSec
+    endTime: now_uSec - 131 * kUsecPerMin, // 1 minute later
+    state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
+    currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0,
+    guid: "z1bcD23eF4g5"
+  };
+
+  try {
+    for (let prop in data)
+      stmt.params[prop] = data[prop];
+    stmt.execute();
+  }
+  finally {
+    stmt.reset();
+  }
 
-  download = yield Downloads.createDownload({
+  // Add within-4-hour download
+  data = {
+    id:   "5555553",
+    name: "fakefile-4-hour",
     source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
-    target: "fakefile-4-hour"
-  });
-  download.startTime = new Date(now_uSec - 180 * kUsecPerMin), // 180 minutes ago, in uSec
-  download.canceled = true;
-  publicList.add(download);
-
-  download = yield Downloads.createDownload({
+    target: "fakefile-4-hour",
+    startTime: now_uSec - 180 * kUsecPerMin, // 180 minutes ago, in uSec
+    endTime: now_uSec - 179 * kUsecPerMin, // 1 minute later
+    state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
+    currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0,
+    guid: "zzzcD23eF4g5"
+  };
+  
+  try {
+    for (let prop in data)
+      stmt.params[prop] = data[prop];
+    stmt.execute();
+  }
+  finally {
+    stmt.reset();
+  }
+  
+  // Add 4-hour-10-minutes download
+  data = {
+    id:   "5555558",
+    name: "fakefile-4-hour-10-minutes",
     source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
-    target: "fakefile-4-hour-10-minutes"
-  });
-  download.startTime = new Date(now_uSec - 250 * kUsecPerMin), // 250 minutes ago, in uSec
-  download.canceled = true;
-  publicList.add(download);
+    target: "fakefile-4-hour-10-minutes",
+    startTime: now_uSec - 250 * kUsecPerMin, // 250 minutes ago, in uSec
+    endTime: now_uSec - 251 * kUsecPerMin, // 1 minute later
+    state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
+    currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0,
+    guid: "z1bzz23eF4gz"
+  };
+  
+  try {
+    for (let prop in data)
+      stmt.params[prop] = data[prop];
+    stmt.execute();
+  }
+  finally {
+    stmt.reset();
+  }
 
   // Add "today" download
   let today = new Date();
   today.setHours(0);
   today.setMinutes(0);
   today.setSeconds(1);
-
-  download = yield Downloads.createDownload({
+  
+  data = {
+    id:   "5555554",
+    name: "fakefile-today",
     source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
-    target: "fakefile-today"
-  });
-  download.startTime = new Date(today.getTime() * 1000), // 12:00:30am this morning, in uSec
-  download.canceled = true;
-  publicList.add(download);
+    target: "fakefile-today",
+    startTime: today.getTime() * 1000,  // 12:00:30am this morning, in uSec
+    endTime: (today.getTime() + 1000) * 1000, // 1 second later
+    state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
+    currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0,
+    guid: "ffffD23eF4g5"
+  };
+  
+  try {
+    for (let prop in data)
+      stmt.params[prop] = data[prop];
+    stmt.execute();
+  }
+  finally {
+    stmt.reset();
+  }
   
   // Add "before today" download
   let lastYear = new Date();
   lastYear.setFullYear(lastYear.getFullYear() - 1);
-
-  download = yield Downloads.createDownload({
+  data = {
+    id:   "5555550",
+    name: "fakefile-old",
     source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
-    target: "fakefile-old"
-  });
-  download.startTime = new Date(lastYear.getTime() * 1000), // 1 year ago, in uSec
-  download.canceled = true;
-  publicList.add(download);
+    target: "fakefile-old",
+    startTime: lastYear.getTime() * 1000, // 1 year ago, in uSec
+    endTime: (lastYear.getTime() + 1000) * 1000, // 1 second later
+    state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
+    currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0,
+    guid: "ggggg23eF4g5"
+  };
+  
+  try {
+    for (let prop in data)
+      stmt.params[prop] = data[prop];
+    stmt.execute();
+  }
+  finally {
+    stmt.finalize();
+  }
   
   // Confirm everything worked
-  let downloads = yield publicList.getAll();
-  is(downloads.length, 9, "9 Pretend downloads added");
-
-  ok((yield downloadExists(publicList, "fakefile-old")), "Pretend download for everything case should exist");
-  ok((yield downloadExists(publicList, "fakefile-10-minutes")), "Pretend download for 10-minutes case should exist");
-  ok((yield downloadExists(publicList, "fakefile-1-hour")), "Pretend download for 1-hour case should exist");
-  ok((yield downloadExists(publicList, "fakefile-1-hour-10-minutes")), "Pretend download for 1-hour-10-minutes case should exist");
-  ok((yield downloadExists(publicList, "fakefile-2-hour")), "Pretend download for 2-hour case should exist");
-  ok((yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "Pretend download for 2-hour-10-minutes case should exist");
-  ok((yield downloadExists(publicList, "fakefile-4-hour")), "Pretend download for 4-hour case should exist");
-  ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "Pretend download for 4-hour-10-minutes case should exist");
-  ok((yield downloadExists(publicList, "fakefile-today")), "Pretend download for Today case should exist");
+  ok(downloadExists(5555550), "Pretend download for everything case should exist");
+  ok(downloadExists(5555555), "Pretend download for 10-minutes case should exist");
+  ok(downloadExists(5555551), "Pretend download for 1-hour case should exist");
+  ok(downloadExists(5555556), "Pretend download for 1-hour-10-minutes case should exist");
+  ok(downloadExists(5555552), "Pretend download for 2-hour case should exist");
+  ok(downloadExists(5555557), "Pretend download for 2-hour-10-minutes case should exist");
+  ok(downloadExists(5555553), "Pretend download for 4-hour case should exist");
+  ok(downloadExists(5555558), "Pretend download for 4-hour-10-minutes case should exist");
+  ok(downloadExists(5555554), "Pretend download for Today case should exist");
 }
 
 /**
  * Checks to see if the downloads with the specified id exists.
  *
  * @param aID
  *        The ids of the downloads to check.
  */
-function downloadExists(list, path)
+function downloadExists(aID)
 {
-  return Task.spawn(function() {
-    let listArray = yield list.getAll();
-    throw new Task.Result(listArray.some(i => i.target.path == path));
-  });
+  let db = dm.DBConnection;
+  let stmt = db.createStatement(
+    "SELECT * " +
+    "FROM moz_downloads " +
+    "WHERE id = :id"
+  );
+  stmt.params.id = aID;
+  var rows = stmt.executeStep();
+  stmt.finalize();
+  return rows;
 }
 
 function isToday(aDate) {
   return aDate.getDate() == new Date().getDate();
 }
--- a/browser/base/content/test/browser_sanitizeDialog.js
+++ b/browser/base/content/test/browser_sanitizeDialog.js
@@ -16,27 +16,28 @@
  * Some of this code, especially the history creation parts, was taken from
  * browser/base/content/test/browser_sanitize-timespans.js.
  */
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "FormHistory",
                                   "resource://gre/modules/FormHistory.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
-                                  "resource://gre/modules/Downloads.jsm");
 
 let tempScope = {};
 Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
                                            .loadSubScript("chrome://browser/content/sanitize.js", tempScope);
 let Sanitizer = tempScope.Sanitizer;
 
+const dm = Cc["@mozilla.org/download-manager;1"].
+           getService(Ci.nsIDownloadManager);
+
 const kUsecPerMin = 60 * 1000000;
 
-let formEntries, downloadIDs, olderDownloadIDs;
+let formEntries;
 
 // Add tests here.  Each is a function that's called by doNextTest().
 var gAllTests = [
 
   /**
    * Initializes the dialog to its default state.
    */
   function () {
@@ -86,33 +87,16 @@ var gAllTests = [
         yield promiseHistoryClearedState(uris, false);
         yield blankSlate();
         yield promiseHistoryClearedState(uris, true);
       };
       wh.open();
     });
   },
 
-  function () {
-    // Add downloads (within the past hour).
-    Task.spawn(function () {
-      downloadIDs = [];
-      for (let i = 0; i < 5; i++) {
-        yield addDownloadWithMinutesAgo(downloadIDs, i);
-      }
-      // Add downloads (over an hour ago).
-      olderDownloadIDs = [];
-      for (let i = 0; i < 5; i++) {
-        yield addDownloadWithMinutesAgo(olderDownloadIDs, 61 + i);
-      }
-
-      doNextTest();
-    }).then(null, Components.utils.reportError);
-  },
-
   /**
    * Ensures that the combined history-downloads checkbox clears both history
    * visits and downloads when checked; the dialog respects simple timespan.
    */
   function () {
     // Add history (within the past hour).
     let uris = [];
     let places = [];
@@ -126,16 +110,26 @@ var gAllTests = [
     let olderURIs = [];
     for (let i = 0; i < 5; i++) {
       pURI = makeURI("http://" + (61 + i) + "-minutes-ago.com/");
       places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(61 + i)});
       olderURIs.push(pURI);
     }
 
     addVisits(places, function() {
+      // Add downloads (within the past hour).
+      let downloadIDs = [];
+      for (let i = 0; i < 5; i++) {
+        downloadIDs.push(addDownloadWithMinutesAgo(i));
+      }
+      // Add downloads (over an hour ago).
+      let olderDownloadIDs = [];
+      for (let i = 0; i < 5; i++) {
+        olderDownloadIDs.push(addDownloadWithMinutesAgo(61 + i));
+      }
       let totalHistoryVisits = uris.length + olderURIs.length;
 
       let wh = new WindowHelper();
       wh.onload = function () {
         this.selectDuration(Sanitizer.TIMESPAN_HOUR);
         this.checkPrefCheckbox("history", true);
         this.acceptDialog();
 
@@ -147,26 +141,26 @@ var gAllTests = [
                    "history checkbox checked");
         boolPrefIs("cpd.downloads", true,
                    "downloads pref should be true after accepting dialog with " +
                    "history checkbox checked");
       };
       wh.onunload = function () {
         // History visits and downloads within one hour should be cleared.
         yield promiseHistoryClearedState(uris, true);
-        yield ensureDownloadsClearedState(downloadIDs, true);
+        ensureDownloadsClearedState(downloadIDs, true);
 
         // Visits and downloads > 1 hour should still exist.
         yield promiseHistoryClearedState(olderURIs, false);
-        yield ensureDownloadsClearedState(olderDownloadIDs, false);
+        ensureDownloadsClearedState(olderDownloadIDs, false);
 
         // OK, done, cleanup after ourselves.
         yield blankSlate();
         yield promiseHistoryClearedState(olderURIs, true);
-        yield ensureDownloadsClearedState(olderDownloadIDs, true);
+        ensureDownloadsClearedState(olderDownloadIDs, true);
       };
       wh.open();
     });
   },
 
   /**
    * Add form history entries for the next test.
    */
@@ -179,44 +173,37 @@ var gAllTests = [
         yield undefined;
       }
       doNextTest();
     }();
 
     iter.next();
   },
 
-  function () {
-    // Add downloads (within the past hour).
-    Task.spawn(function () {
-      downloadIDs = [];
-      for (let i = 0; i < 5; i++) {
-        yield addDownloadWithMinutesAgo(downloadIDs, i);
-      }
-
-      doNextTest();
-    }).then(null, Components.utils.reportError);
-  },
-
   /**
    * Ensures that the combined history-downloads checkbox removes neither
    * history visits nor downloads when not checked.
    */
   function () {
     // Add history, downloads, form entries (within the past hour).
     let uris = [];
     let places = [];
     let pURI;
     for (let i = 0; i < 5; i++) {
       pURI = makeURI("http://" + i + "-minutes-ago.com/");
       places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)});
       uris.push(pURI);
     }
 
     addVisits(places, function() {
+      let downloadIDs = [];
+      for (let i = 0; i < 5; i++) {
+        downloadIDs.push(addDownloadWithMinutesAgo(i));
+      }
+
       let wh = new WindowHelper();
       wh.onload = function () {
         is(this.isWarningPanelVisible(), false,
            "Warning panel should be hidden after previously accepting dialog " +
            "with a predefined timespan");
         this.selectDuration(Sanitizer.TIMESPAN_HOUR);
 
         // Remove only form entries, leave history (including downloads).
@@ -232,27 +219,27 @@ var gAllTests = [
                    "history checkbox unchecked");
         boolPrefIs("cpd.downloads", false,
                    "downloads pref should be false after accepting dialog with " +
                    "history checkbox unchecked");
       };
       wh.onunload = function () {
         // Of the three only form entries should be cleared.
         yield promiseHistoryClearedState(uris, false);
-        yield ensureDownloadsClearedState(downloadIDs, false);
+        ensureDownloadsClearedState(downloadIDs, false);
 
         formEntries.forEach(function (entry) {
           let exists = yield formNameExists(entry);
           is(exists, false, "form entry " + entry + " should no longer exist");
         });
 
         // OK, done, cleanup after ourselves.
         yield blankSlate();
         yield promiseHistoryClearedState(uris, true);
-        yield ensureDownloadsClearedState(downloadIDs, true);
+        ensureDownloadsClearedState(downloadIDs, true);
       };
       wh.open();
     });
   },
 
   /**
    * Ensures that the "Everything" duration option works.
    */
@@ -647,16 +634,20 @@ var gAllTests = [
       var pm = Cc["@mozilla.org/permissionmanager;1"]
                .getService(Ci.nsIPermissionManager);
       is(pm.testPermissionFromPrincipal(principal, "offline-app"), 0, "offline-app permissions removed");
     };
     wh.open();
   }
 ];
 
+// Used as the download database ID for a new download.  Incremented for each
+// new download.  See addDownloadWithMinutesAgo().
+var gDownloadId = 5555551;
+
 // Index in gAllTests of the test currently being run.  Incremented for each
 // test run.  See doNextTest().
 var gCurrTest = 0;
 
 var now_uSec = Date.now() * 1000;
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -851,17 +842,17 @@ WindowHelper.prototype = {
 
         executeSoon(function () {
           // Some exceptions that reach here don't reach the test harness, but
           // ok()/is() do...
           try {
             if (wh.onunload) {
               Task.spawn(wh.onunload).then(function() {
                 waitForAsyncUpdates(doNextTest);
-              }).then(null, Components.utils.reportError);
+              });
             } else {
               waitForAsyncUpdates(doNextTest);
             }
           }
           catch (exc) {
             win.close();
             ok(false, "Unexpected exception: " + exc + "\n" + exc.stack);
             finish();
@@ -904,33 +895,50 @@ WindowHelper.prototype = {
 };
 
 /**
  * Adds a download to history.
  *
  * @param aMinutesAgo
  *        The download will be downloaded this many minutes ago
  */
-function addDownloadWithMinutesAgo(aExpectedPathList, aMinutesAgo) {
-  let publicList = yield Downloads.getPublicDownloadList();
-
+function addDownloadWithMinutesAgo(aMinutesAgo) {
   let name = "fakefile-" + aMinutesAgo + "-minutes-ago";
-  let download = yield Downloads.createDownload({
-    source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
-    target: name
-  });
-  download.startTime = now_uSec - (aMinutesAgo * kUsecPerMin);
-  download.canceled = true;
-  publicList.add(download);
+  let data = {
+    id:        gDownloadId,
+    name:      name,
+    source:   "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
+    target:    name,
+    startTime: now_uSec - (aMinutesAgo * kUsecPerMin),
+    endTime:   now_uSec - ((aMinutesAgo + 1) * kUsecPerMin),
+    state:     Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
+    currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
+  };
 
-  ok((yield downloadExists(name)),
-     "Sanity check: download " + name +
+  let db = dm.DBConnection;
+  let stmt = db.createStatement(
+    "INSERT INTO moz_downloads (id, name, source, target, startTime, endTime, " +
+      "state, currBytes, maxBytes, preferredAction, autoResume) " +
+    "VALUES (:id, :name, :source, :target, :startTime, :endTime, :state, " +
+      ":currBytes, :maxBytes, :preferredAction, :autoResume)");
+  try {
+    for (let prop in data) {
+      stmt.params[prop] = data[prop];
+    }
+    stmt.execute();
+  }
+  finally {
+    stmt.reset();
+  }
+
+  is(downloadExists(gDownloadId), true,
+     "Sanity check: download " + gDownloadId +
      " should exist after creating it");
 
-  aExpectedPathList.push(name);
+  return gDownloadId++;
 }
 
 /**
  * Adds a form entry to history.
  *
  * @param aMinutesAgo
  *        The entry will be added this many minutes ago
  */
@@ -971,47 +979,25 @@ function formNameExists(name)
   return deferred.promise;
 }
 
 /**
  * Removes all history visits, downloads, and form entries.
  */
 function blankSlate() {
   PlacesUtils.bhistory.removeAllPages();
-
-  // The promise is resolved only when removing both downloads and form history are done.
-  let deferred = Promise.defer();
-  let formHistoryDone = false, downloadsDone = false;
+  dm.cleanUp();
 
-  Task.spawn(function deleteAllDownloads() {
-    let publicList = yield Downloads.getPublicDownloadList();
-    let downloads = yield publicList.getAll();
-    for (let download of downloads) {
-      publicList.remove(download);
-      yield download.finalize(true);
-    }
-    downloadsDone = true;
-    if (formHistoryDone) {
-      deferred.resolve();
-    }
-  }).then(null, Components.utils.reportError);
-
+  let deferred = Promise.defer();
   FormHistory.update({ op: "remove" },
                      { handleError: function (error) {
                          do_throw("Error occurred updating form history: " + error);
                          deferred.reject(error);
                        },
-                       handleCompletion: function (reason) {
-                         if (!reason) {
-                           formHistoryDone = true;
-                           if (downloadsDone) {
-                             deferred.resolve();
-                           }
-                         }
-                       }
+                       handleCompletion: function (reason) { if (!reason) deferred.resolve(); }
                      });
   return deferred.promise;
 }
 
 /**
  * Ensures that the given pref is the expected value.
  *
  * @param aPrefName
@@ -1021,29 +1007,34 @@ function blankSlate() {
  * @param aMsg
  *        Passed to is()
  */
 function boolPrefIs(aPrefName, aExpectedVal, aMsg) {
   is(gPrefService.getBoolPref("privacy." + aPrefName), aExpectedVal, aMsg);
 }
 
 /**
- * Checks to see if the download with the specified path exists.
+ * Checks to see if the download with the specified ID exists.
  *
- * @param  aPath
- *         The path of the download to check
+ * @param  aID
+ *         The ID of the download to check
  * @return True if the download exists, false otherwise
  */
-function downloadExists(aPath)
+function downloadExists(aID)
 {
-  return Task.spawn(function() {
-    let publicList = yield Downloads.getPublicDownloadList();
-    let listArray = yield publicList.getAll();
-    throw new Task.Result(listArray.some(i => i.target.path == aPath));
-  });
+  let db = dm.DBConnection;
+  let stmt = db.createStatement(
+    "SELECT * " +
+    "FROM moz_downloads " +
+    "WHERE id = :id"
+  );
+  stmt.params.id = aID;
+  let rows = stmt.executeStep();
+  stmt.finalize();
+  return !!rows;
 }
 
 /**
  * Runs the next test in the gAllTests array.  If all tests have been run,
  * finishes the entire suite.
  */
 function doNextTest() {
   if (gAllTests.length <= gCurrTest) {
@@ -1063,17 +1054,17 @@ function doNextTest() {
  * @param aDownloadIDs
  *        Array of download database IDs
  * @param aShouldBeCleared
  *        True if each download should be cleared, false otherwise
  */
 function ensureDownloadsClearedState(aDownloadIDs, aShouldBeCleared) {
   let niceStr = aShouldBeCleared ? "no longer" : "still";
   aDownloadIDs.forEach(function (id) {
-    is((yield downloadExists(id)), !aShouldBeCleared,
+    is(downloadExists(id), !aShouldBeCleared,
        "download " + id + " should " + niceStr + " exist");
   });
 }
 
 /**
  * Ensures that the given pref is the expected value.
  *
  * @param aPrefName
--- a/browser/base/content/test/browser_tabopen_reflows.js
+++ b/browser/base/content/test/browser_tabopen_reflows.js
@@ -44,17 +44,21 @@ const EXPECTED_REFLOWS = [
   // SessionStore.getWindowDimensions()
   "ssi_getWindowDimension@resource:///modules/sessionstore/SessionStore.jsm|" +
     "@resource:///modules/sessionstore/SessionStore.jsm|" +
     "ssi_updateWindowFeatures@resource:///modules/sessionstore/SessionStore.jsm|" +
     "ssi_collectWindowData@resource:///modules/sessionstore/SessionStore.jsm|",
 
   // tabPreviews.capture()
   "tabPreviews_capture@chrome://browser/content/browser.js|" +
-    "tabPreviews_handleEvent/<@chrome://browser/content/browser.js|"
+    "tabPreviews_handleEvent/<@chrome://browser/content/browser.js|",
+
+  // tabPreviews.capture()
+  "tabPreviews_capture@chrome://browser/content/browser.js|" +
+    "@chrome://browser/content/browser.js|"
 ];
 
 const PREF_PRELOAD = "browser.newtab.preload";
 
 /*
  * This test ensures that there are no unexpected
  * uninterruptible reflows when opening new tabs.
  */
--- a/browser/components/downloads/test/browser/browser_basic_functionality.js
+++ b/browser/components/downloads/test/browser/browser_basic_functionality.js
@@ -2,53 +2,61 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Make sure the downloads panel can display items in the right order and
  * contains the expected data.
  */
-function test_task()
+function gen_test()
 {
   // Display one of each download state.
   const DownloadData = [
-    { state: nsIDM.DOWNLOAD_NOTSTARTED },
-    { state: nsIDM.DOWNLOAD_PAUSED },
-    { state: nsIDM.DOWNLOAD_FINISHED },
-    { state: nsIDM.DOWNLOAD_FAILED },
-    { state: nsIDM.DOWNLOAD_CANCELED },
+    { endTime: 1180493839859239, state: nsIDM.DOWNLOAD_NOTSTARTED },
+    { endTime: 1180493839859238, state: nsIDM.DOWNLOAD_DOWNLOADING },
+    { endTime: 1180493839859237, state: nsIDM.DOWNLOAD_PAUSED },
+    { endTime: 1180493839859236, state: nsIDM.DOWNLOAD_SCANNING },
+    { endTime: 1180493839859235, state: nsIDM.DOWNLOAD_QUEUED },
+    { endTime: 1180493839859234, state: nsIDM.DOWNLOAD_FINISHED },
+    { endTime: 1180493839859233, state: nsIDM.DOWNLOAD_FAILED },
+    { endTime: 1180493839859232, state: nsIDM.DOWNLOAD_CANCELED },
+    { endTime: 1180493839859231, state: nsIDM.DOWNLOAD_BLOCKED_PARENTAL },
+    { endTime: 1180493839859230, state: nsIDM.DOWNLOAD_DIRTY },
+    { endTime: 1180493839859229, state: nsIDM.DOWNLOAD_BLOCKED_POLICY },
   ];
 
+  // For testing purposes, show all the download items at once.
+  var originalCountLimit = DownloadsView.kItemCountLimit;
+  DownloadsView.kItemCountLimit = DownloadData.length;
+  registerCleanupFunction(function () {
+    DownloadsView.kItemCountLimit = originalCountLimit;
+  });
+
   try {
     // Ensure that state is reset in case previous tests didn't finish.
-    yield task_resetState();
-
-    // For testing purposes, show all the download items at once.
-    var originalCountLimit = DownloadsView.kItemCountLimit;
-    DownloadsView.kItemCountLimit = DownloadData.length;
-    registerCleanupFunction(function () {
-      DownloadsView.kItemCountLimit = originalCountLimit;
-    });
+    for (let yy in gen_resetState(DownloadsCommon.getData(window))) yield undefined;
 
     // Populate the downloads database with the data required by this test.
-    yield task_addDownloads(DownloadData);
+    for (let yy in gen_addDownloadRows(DownloadData)) yield undefined;
 
     // Open the user interface and wait for data to be fully loaded.
-    yield task_openPanel();
+    for (let yy in gen_openPanel(DownloadsCommon.getData(window))) yield undefined;
 
     // Test item data and count.  This also tests the ordering of the display.
     let richlistbox = document.getElementById("downloadsListBox");
 /* disabled for failing intermittently (bug 767828)
     is(richlistbox.children.length, DownloadData.length,
        "There is the correct number of richlistitems");
 */
-    let itemCount = richlistbox.children.length;
-    for (let i = 0; i < itemCount; i++) {
-      let element = richlistbox.children[itemCount - i - 1];
+    for (let i = 0; i < richlistbox.children.length; i++) {
+      let element = richlistbox.children[i];
       let dataItem = new DownloadsViewItemController(element).dataItem;
+      is(dataItem.target, DownloadData[i].name, "Download names match up");
       is(dataItem.state, DownloadData[i].state, "Download states match up");
+      is(dataItem.file, DownloadData[i].target, "Download targets match up");
+      is(dataItem.uri, DownloadData[i].source, "Download sources match up");
     }
   } finally {
     // Clean up when the test finishes.
-    yield task_resetState();
+    for (let yy in gen_resetState(DownloadsCommon.getData(window))) yield undefined;
   }
 }
--- a/browser/components/downloads/test/browser/browser_first_download_panel.js
+++ b/browser/components/downloads/test/browser/browser_first_download_panel.js
@@ -3,51 +3,54 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Make sure the downloads panel only opens automatically on the first
  * download it notices. All subsequent downloads, even across sessions, should
  * not open the panel automatically.
  */
-function test_task()
+function gen_test()
 {
   try {
     // Ensure that state is reset in case previous tests didn't finish.
-    yield task_resetState();
+    for (let yy in gen_resetState(DownloadsCommon.getData(window))) yield undefined;
 
-    // With this set to false, we should automatically open the panel the first
-    // time a download is started.
+    // With this set to false, we should automatically open the panel
+    // the first time a download is started.
     DownloadsCommon.getData(window).panelHasShownBefore = false;
 
-    let promise = promisePanelOpened();
+    prepareForPanelOpen();
     DownloadsCommon.getData(window)._notifyDownloadEvent("start");
-    yield promise;
+    yield undefined;
 
     // If we got here, that means the panel opened.
     DownloadsPanel.hidePanel();
 
     ok(DownloadsCommon.getData(window).panelHasShownBefore,
        "Should have recorded that the panel was opened on a download.")
 
-    // Next, make sure that if we start another download, we don't open the
-    // panel automatically.
-    let originalOnPopupShown = DownloadsPanel.onPopupShown;
-    DownloadsPanel.onPopupShown = function () {
-      originalOnPopupShown.apply(this, arguments);
-      ok(false, "Should not have opened the downloads panel.");
-    };
-
-    try {
-      DownloadsCommon.getData(window)._notifyDownloadEvent("start");
-
-      // Wait 2 seconds to ensure that the panel does not open.
-      let deferTimeout = Promise.defer();
-      setTimeout(deferTimeout.resolve, 2000);
-      yield deferTimeout.promise;
-    } finally {
-      DownloadsPanel.onPopupShown = originalOnPopupShown;
-    }
+    // Next, make sure that if we start another download, we don't open
+    // the panel automatically.
+    panelShouldNotOpen();
+    DownloadsCommon.getData(window)._notifyDownloadEvent("start");
+    yield waitFor(2);
+  } catch(e) {
+    ok(false, e);
   } finally {
     // Clean up when the test finishes.
-    yield task_resetState();
+    for (let yy in gen_resetState(DownloadsCommon.getData(window))) yield undefined;
   }
 }
+
+/**
+ * Call this to record a test failure for the next time the downloads panel
+ * opens.
+ */
+function panelShouldNotOpen()
+{
+  // Hook to wait until the test data has been loaded.
+  let originalOnViewLoadCompleted = DownloadsPanel.onViewLoadCompleted;
+  DownloadsPanel.onViewLoadCompleted = function () {
+    DownloadsPanel.onViewLoadCompleted = originalOnViewLoadCompleted;
+    ok(false, "Should not have opened the downloads panel.");
+  };
+}
--- a/browser/components/downloads/test/browser/head.js
+++ b/browser/components/downloads/test/browser/head.js
@@ -5,108 +5,270 @@
 
 /**
  * Provides infrastructure for automated download components tests.
  */
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Globals
 
-XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
-                                  "resource://gre/modules/Downloads.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
+                                  "resource://gre/modules/FileUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
                                   "resource:///modules/DownloadsCommon.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
-                                  "resource://gre/modules/FileUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Promise",
-                                  "resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
-                                  "resource://gre/modules/Task.jsm");
 const nsIDM = Ci.nsIDownloadManager;
 
 let gTestTargetFile = FileUtils.getFile("TmpD", ["dm-ui-test.file"]);
 gTestTargetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
 registerCleanupFunction(function () {
   gTestTargetFile.remove(false);
 });
 
+/**
+ * This objects contains a property for each column in the downloads table.
+ */
+let gDownloadRowTemplate = {
+  name: "test-download.txt",
+  source: "http://www.example.com/test-download.txt",
+  target: NetUtil.newURI(gTestTargetFile).spec,
+  startTime: 1180493839859230,
+  endTime: 1180493839859234,
+  state: nsIDM.DOWNLOAD_FINISHED,
+  currBytes: 0,
+  maxBytes: -1,
+  preferredAction: 0,
+  autoResume: 0
+};
+
 ////////////////////////////////////////////////////////////////////////////////
 //// Infrastructure
 
+// All test are run through the test runner.
 function test()
 {
-  waitForExplicitFinish();
-  Task.spawn(test_task).then(null, ex => ok(false, ex)).then(finish);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//// Asynchronous support subroutines
-
-function promiseFocus()
-{
-  let deferred = Promise.defer();
-  waitForFocus(deferred.resolve);
-  return deferred.promise;
+  testRunner.runTest(this.gen_test);
 }
 
-function promisePanelOpened()
-{
-  let deferred = Promise.defer();
+/**
+ * Runs a browser-chrome test defined through a generator function.
+ *
+ * This object is a singleton, initialized automatically when this script is
+ * included.  Every browser-chrome test file includes a new copy of this object.
+ */
+var testRunner = {
+  _testIterator: null,
+  _lastEventResult: undefined,
+  _testRunning: false,
+  _eventRaised: false,
+
+  // --- Main test runner ---
 
-  // Hook to wait until the panel is shown.
-  let originalOnPopupShown = DownloadsPanel.onPopupShown;
-  DownloadsPanel.onPopupShown = function () {
-    DownloadsPanel.onPopupShown = originalOnPopupShown;
-    originalOnPopupShown.apply(this, arguments);
+  /**
+   * Runs the test described by the provided generator function asynchronously.
+   *
+   * Calling yield in the generator will cause it to wait until continueTest is
+   * called.  The parameter provided to continueTest will be the return value of
+   * the yield operator.
+   *
+   * @param aGenerator
+   *        Test generator function.  The function will be called with no
+   *        arguments to retrieve its iterator.
+   */
+  runTest: function TR_runTest(aGenerator) {
+    waitForExplicitFinish();
+    testRunner._testIterator = aGenerator();
+    testRunner.continueTest();
+  },
+
+  /**
+   * Continues the currently running test.
+   *
+   * @param aEventResult
+   *        This will be the return value of the yield operator in the test.
+   */
+  continueTest: function TR_continueTest(aEventResult) {
+    // Store the last event result, or set it to undefined.
+    testRunner._lastEventResult = aEventResult;
+
+    // Never reenter the main loop, but notify that the event has been raised.
+    if (testRunner._testRunning) {
+      testRunner._eventRaised = true;
+      return;
+    }
 
-    // Defer to the next tick of the event loop so that we don't continue
-    // processing during the DOM event handler itself.
-    setTimeout(deferred.resolve, 0);
-  };
+    // Enter the main iteration loop.
+    testRunner._testRunning = true;
+    try {
+      do {
+        // Call the iterator, but don't leave the loop if the expected event is
+        // raised during the execution of the generator.
+        testRunner._eventRaised = false;
+        testRunner._testIterator.send(testRunner._lastEventResult);
+      } while (testRunner._eventRaised);
+    }
+    catch (e) {
+      // This block catches exceptions raised by the generator, including the
+      // normal StopIteration exception.  Unexpected exceptions are reported as
+      // test failures.
+      if (!(e instanceof StopIteration))
+        ok(false, e);
+      // In any case, stop the tests in this file.
+      finish();
+    }
 
-  return deferred.promise;
-}
+    // Wait for the next event or finish.
+    testRunner._testRunning = false;
+  }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//// Asynchronous generator-based support subroutines
 
-function task_resetState()
+//
+// The following functions are all generators that can be used inside the main
+// test generator to perform specific tasks asynchronously.  To invoke these
+// subroutines correctly, an iteration syntax should be used:
+//
+//   for (let yy in gen_example("Parameter")) yield undefined;
+//
+
+function gen_resetState(aData)
 {
-  // Remove all downloads.
-  let publicList = yield Downloads.getPublicDownloadList();
-  let downloads = yield publicList.getAll();
-  for (let download of downloads) {
-    publicList.remove(download);
-    yield download.finalize(true);
+  let statement = Services.downloads.DBConnection.createAsyncStatement(
+                  "DELETE FROM moz_downloads");
+  try {
+    statement.executeAsync({
+      handleResult: function(aResultSet) { },
+      handleError: function(aError)
+      {
+        Cu.reportError(aError);
+      },
+      handleCompletion: function(aReason)
+      {
+        testRunner.continueTest();
+      }
+    });
+    yield undefined;
+  } finally {
+    statement.finalize();
   }
 
   // Reset any prefs that might have been changed.
   Services.prefs.clearUserPref("browser.download.panel.shown");
 
+  // Ensure that the panel is closed and data is unloaded.
+  aData.clear();
+  aData._loadState = aData.kLoadNone;
   DownloadsPanel.hidePanel();
 
-  yield promiseFocus();
+  // Wait for focus on the main window.
+  waitForFocus(testRunner.continueTest);
+  yield undefined;
 }
 
-function task_addDownloads(aItems)
+function gen_addDownloadRows(aDataRows)
 {
-  let startTimeMs = Date.now();
+  let columnNames = Object.keys(gDownloadRowTemplate).join(", ");
+  let parameterNames = Object.keys(gDownloadRowTemplate)
+                             .map(function(n) ":" + n)
+                             .join(", ");
+  let statement = Services.downloads.DBConnection.createAsyncStatement(
+                  "INSERT INTO moz_downloads (" + columnNames +
+                  ", guid) VALUES(" + parameterNames + ", GENERATE_GUID())");
+  try {
+    // Execute the statement for each of the provided downloads in reverse.
+    for (let i = aDataRows.length - 1; i >= 0; i--) {
+      let dataRow = aDataRows[i];
 
-  let publicList = yield Downloads.getPublicDownloadList();
-  for (let item of aItems) {
-    publicList.add(yield Downloads.createDownload({
-      source: "http://www.example.com/test-download.txt",
-      target: gTestTargetFile,
-      succeeded: item.state == nsIDM.DOWNLOAD_FINISHED,
-      canceled: item.state == nsIDM.DOWNLOAD_CANCELED ||
-                item.state == nsIDM.DOWNLOAD_PAUSED,
-      error: item.state == nsIDM.DOWNLOAD_FAILED ? new Error("Failed.") : null,
-      hasPartialData: item.state == nsIDM.DOWNLOAD_PAUSED,
-      startTime: new Date(startTimeMs++),
-    }));
+      // Populate insert parameters from the provided data.
+      for (let columnName in gDownloadRowTemplate) {
+        if (!(columnName in dataRow)) {
+          // Update the provided row object with data from the global template,
+          // for columns whose value is not provided explicitly.
+          dataRow[columnName] = gDownloadRowTemplate[columnName];
+        }
+        statement.params[columnName] = dataRow[columnName];
+      }
+
+      // Run the statement asynchronously and wait.
+      statement.executeAsync({
+        handleResult: function(aResultSet) { },
+        handleError: function(aError)
+        {
+          Cu.reportError(aError.message + " (Result = " + aError.result + ")");
+        },
+        handleCompletion: function(aReason)
+        {
+          testRunner.continueTest();
+        }
+      });
+      yield undefined;
+
+      // At each iteration, ensure that the start and end time in the global
+      // template is distinct, as these column are used to sort each download
+      // in its category.
+      gDownloadRowTemplate.startTime++;
+      gDownloadRowTemplate.endTime++;
+    }
+  } finally {
+    statement.finalize();
   }
 }
 
-function task_openPanel()
+function gen_openPanel(aData)
 {
-  yield promiseFocus();
+  // Hook to wait until the test data has been loaded.
+  let originalOnViewLoadCompleted = DownloadsPanel.onViewLoadCompleted;
+  DownloadsPanel.onViewLoadCompleted = function () {
+    DownloadsPanel.onViewLoadCompleted = originalOnViewLoadCompleted;
+    originalOnViewLoadCompleted.apply(this);
+    testRunner.continueTest();
+  };
+
+  // Start loading all the downloads from the database asynchronously.
+  aData.ensurePersistentDataLoaded(false);
+
+  // Wait for focus on the main window.
+  waitForFocus(testRunner.continueTest);
+  yield undefined;
+
+  // Open the downloads panel, waiting until loading is completed.
+  DownloadsPanel.showPanel();
+  yield undefined;
+}
 
-  let promise = promisePanelOpened();
-  DownloadsPanel.showPanel();
-  yield promise;
+/**
+ * Spin the event loop for aSeconds seconds, and then signal the test to
+ * continue.
+ *
+ * @param aSeconds the number of seconds to wait.
+ * @note This helper should _only_ be used when there's no valid event to
+ *       listen to and one can't be made.
+ */
+function waitFor(aSeconds)
+{
+  setTimeout(function() {
+    testRunner.continueTest();
+  }, aSeconds * 1000);
 }
+
+/**
+ * Make it so that the next time the downloads panel opens, we signal to
+ * continue the test. This function needs to be called each time you want
+ * to wait for the panel to open.
+ *
+ * Example usage:
+ *
+ * prepareForPanelOpen();
+ * // Do something to open the panel
+ * yield undefined;
+ * // We can assume the panel is open now.
+ */
+function prepareForPanelOpen()
+{
+  // Hook to wait until the test data has been loaded.
+  let originalOnPopupShown = DownloadsPanel.onPopupShown;
+  DownloadsPanel.onPopupShown = function (aEvent) {
+    DownloadsPanel.onPopupShown = originalOnPopupShown;
+    DownloadsPanel.onPopupShown.apply(this, [aEvent]);
+    testRunner.continueTest();
+  };
+}
--- a/browser/components/sessionstore/src/SessionStore.jsm
+++ b/browser/components/sessionstore/src/SessionStore.jsm
@@ -72,16 +72,19 @@ const MESSAGES = [
 ];
 
 // These are tab events that we listen to.
 const TAB_EVENTS = [
   "TabOpen", "TabClose", "TabSelect", "TabShow", "TabHide", "TabPinned",
   "TabUnpinned"
 ];
 
+// The number of milliseconds in a day
+const MS_PER_DAY = 1000.0 * 60.0 * 60.0 * 24.0;
+
 #ifndef XP_WIN
 #define BROKEN_WM_Z_ORDER
 #endif
 
 Cu.import("resource://gre/modules/Services.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 // debug.js adds NS_ASSERT. cf. bug 669196
 Cu.import("resource://gre/modules/debug.js", this);
@@ -459,20 +462,18 @@ let SessionStoreInternal = {
             } else if (this._hasSingleTabWithURL(state.windows,
                                                  "about:welcomeback")) {
               // On a single about:welcomeback URL that crashed, replace about:welcomeback
               // with about:sessionrestore, to make clear to the user that we crashed.
               state.windows[0].tabs[0].entries[0].url = "about:sessionrestore";
             }
           }
 
-          // Load the session start time from the previous state
-          this._sessionStartTime = state.session &&
-                                   state.session.startTime ||
-                                   this._sessionStartTime;
+          // Update the session start time using the restored session state.
+          this._updateSessionStartTime(state);
 
           // make sure that at least the first window doesn't have anything hidden
           delete state.windows[0].hidden;
           // Since nothing is hidden in the first window, it cannot be a popup
           delete state.windows[0].isPopup;
           // We don't want to minimize and then open a window at startup.
           if (state.windows[0].sizemode == "minimized")
             state.windows[0].sizemode = "normal";
@@ -1796,19 +1797,19 @@ let SessionStoreInternal = {
 
     if (lastSessionState.scratchpads) {
       ScratchpadManager.restoreSession(lastSessionState.scratchpads);
     }
 
     // Set data that persists between sessions
     this._recentCrashes = lastSessionState.session &&
                           lastSessionState.session.recentCrashes || 0;
-    this._sessionStartTime = lastSessionState.session &&
-                             lastSessionState.session.startTime ||
-                             this._sessionStartTime;
+
+    // Update the session start time using the restored session state.
+    this._updateSessionStartTime(lastSessionState);
 
     this._lastSessionState = null;
   },
 
   /**
    * See if aWindow is usable for use when restoring a previous session via
    * restoreLastSession. If usable, prepare it for use.
    *
@@ -3631,16 +3632,38 @@ let SessionStoreInternal = {
     }
 
     SessionSaver.runDelayed();
   },
 
   /* ........ Auxiliary Functions .............. */
 
   /**
+   * Update the session start time and send a telemetry measurement
+   * for the number of days elapsed since the session was started.
+   *
+   * @param state
+   *        The session state.
+   */
+  _updateSessionStartTime: function ssi_updateSessionStartTime(state) {
+    // Attempt to load the session start time from the session state
+    if (state.session && state.session.startTime) {
+      this._sessionStartTime = state.session.startTime;
+
+      // ms to days
+      let sessionLength = (Date.now() - this._sessionStartTime) / MS_PER_DAY;
+
+      if (sessionLength > 0) {
+        // Submit the session length telemetry measurement
+        Services.telemetry.getHistogramById("FX_SESSION_RESTORE_SESSION_LENGTH").add(sessionLength);
+      }
+    }
+  },
+
+  /**
    * call a callback for all currently opened browser windows
    * (might miss the most recent one)
    * @param aFunc
    *        Callback each window is passed to
    */
   _forEachBrowserWindow: function ssi_forEachBrowserWindow(aFunc) {
     var windowsEnum = Services.wm.getEnumerator("navigator:browser");
 
--- a/browser/devtools/markupview/markup-view.js
+++ b/browser/devtools/markupview/markup-view.js
@@ -1214,90 +1214,111 @@ ElementEditor.prototype = {
       }
     }
   },
 
   _startModifyingAttributes: function() {
     return this.node.startModifyingAttributes();
   },
 
-  _createAttribute: function EE_createAttribute(aAttr, aBefore)
+  _createAttribute: function EE_createAttribute(aAttr, aBefore = null)
   {
-    if (this.attrs.hasOwnProperty(aAttr.name)) {
-      var attr = this.attrs[aAttr.name];
-      var name = attr.querySelector(".attrname");
-      var val = attr.querySelector(".attrvalue");
-    } else {
-      // Create the template editor, which will save some variables here.
-      let data = {
-        attrName: aAttr.name,
-      };
-      this.template("attribute", data);
-      var {attr, inner, name, val} = data;
+    // Create the template editor, which will save some variables here.
+    let data = {
+      attrName: aAttr.name,
+    };
+    this.template("attribute", data);
+    var {attr, inner, name, val} = data;
 
-      // Figure out where we should place the attribute.
-      let before = aBefore || null;
-      if (aAttr.name == "id") {
-        before = this.attrList.firstChild;
-      } else if (aAttr.name == "class") {
-        let idNode = this.attrs["id"];
-        before = idNode ? idNode.nextSibling : this.attrList.firstChild;
-      }
-      this.attrList.insertBefore(attr, before);
+    // Double quotes need to be handled specially to prevent DOMParser failing.
+    // name="v"a"l"u"e" when editing -> name='v"a"l"u"e"'
+    // name="v'a"l'u"e" when editing -> name="v'a&quot;l'u&quot;e"
+    let editValueDisplayed = aAttr.value;
+    let hasDoubleQuote = editValueDisplayed.contains('"');
+    let hasSingleQuote = editValueDisplayed.contains("'");
+    let initial = aAttr.name + '="' + editValueDisplayed + '"';
+
+    // Can't just wrap value with ' since the value contains both " and '.
+    if (hasDoubleQuote && hasSingleQuote) {
+        editValueDisplayed = editValueDisplayed.replace(/\"/g, "&quot;");
+        initial = aAttr.name + '="' + editValueDisplayed + '"';
+    }
+
+    // Wrap with ' since there are no single quotes in the attribute value.
+    if (hasDoubleQuote && !hasSingleQuote) {
+        initial = aAttr.name + "='" + editValueDisplayed + "'";
+    }
 
-      // Make the attribute editable.
-      editableField({
-        element: inner,
-        trigger: "dblclick",
-        stopOnReturn: true,
-        selectAll: false,
-        contentType: InplaceEditor.CONTENT_TYPES.CSS_MIXED,
-        popup: this.markup.popup,
-        start: (aEditor, aEvent) => {
-          // If the editing was started inside the name or value areas,
-          // select accordingly.
-          if (aEvent && aEvent.target === name) {
-            aEditor.input.setSelectionRange(0, name.textContent.length);
-          } else if (aEvent && aEvent.target === val) {
-            let length = val.textContent.length;
-            let editorLength = aEditor.input.value.length;
-            let start = editorLength - (length + 1);
-            aEditor.input.setSelectionRange(start, start + length);
-          } else {
-            aEditor.input.select();
-          }
-        },
-        done: (aVal, aCommit) => {
-          if (!aCommit) {
-            return;
-          }
+    // Make the attribute editable.
+    editableField({
+      element: inner,
+      trigger: "dblclick",
+      stopOnReturn: true,
+      selectAll: false,
+      initial: initial,
+      contentType: InplaceEditor.CONTENT_TYPES.CSS_MIXED,
+      popup: this.markup.popup,
+      start: (aEditor, aEvent) => {
+        // If the editing was started inside the name or value areas,
+        // select accordingly.
+        if (aEvent && aEvent.target === name) {
+          aEditor.input.setSelectionRange(0, name.textContent.length);
+        } else if (aEvent && aEvent.target === val) {
+          let length = editValueDisplayed.length;
+          let editorLength = aEditor.input.value.length;
+          let start = editorLength - (length + 1);
+          aEditor.input.setSelectionRange(start, start + length);
+        } else {
+          aEditor.input.select();
+        }
+      },
+      done: (aVal, aCommit) => {
+        if (!aCommit) {
+          return;
+        }
+
+        let doMods = this._startModifyingAttributes();
+        let undoMods = this._startModifyingAttributes();
 
-          let doMods = this._startModifyingAttributes();
-          let undoMods = this._startModifyingAttributes();
+        // Remove the attribute stored in this editor and re-add any attributes
+        // parsed out of the input element. Restore original attribute if
+        // parsing fails.
+        try {
+          this._saveAttribute(aAttr.name, undoMods);
+          doMods.removeAttribute(aAttr.name);
+          this._applyAttributes(aVal, attr, doMods, undoMods);
+          this.undo.do(() => {
+            doMods.apply();
+          }, () => {
+            undoMods.apply();
+          })
+        } catch(ex) {
+          console.error(ex);
+        }
+      }
+    });
 
-          // Remove the attribute stored in this editor and re-add any attributes
-          // parsed out of the input element. Restore original attribute if
-          // parsing fails.
-          try {
-            this._saveAttribute(aAttr.name, undoMods);
-            doMods.removeAttribute(aAttr.name);
-            this._applyAttributes(aVal, attr, doMods, undoMods);
-            this.undo.do(() => {
-              doMods.apply();
-            }, () => {
-              undoMods.apply();
-            })
-          } catch(ex) {
-            console.error(ex);
-          }
-        }
-      });
 
-      this.attrs[aAttr.name] = attr;
+    // Figure out where we should place the attribute.
+    let before = aBefore;
+    if (aAttr.name == "id") {
+      before = this.attrList.firstChild;
+    } else if (aAttr.name == "class") {
+      let idNode = this.attrs["id"];
+      before = idNode ? idNode.nextSibling : this.attrList.firstChild;
     }
+    this.attrList.insertBefore(attr, before);
+
+    // Remove the old version of this attribute from the DOM.
+    let oldAttr = this.attrs[aAttr.name];
+    if (oldAttr && oldAttr.parentNode) {
+      oldAttr.parentNode.removeChild(oldAttr);
+    }
+
+    this.attrs[aAttr.name] = attr;
 
     name.textContent = aAttr.name;
     val.textContent = aAttr.value;
 
     return attr;
   },
 
   /**
--- a/browser/devtools/markupview/test/browser_inspector_markup_edit.html
+++ b/browser/devtools/markupview/test/browser_inspector_markup_edit.html
@@ -35,10 +35,12 @@
     </div>
     <div id="node22" class="unchanged"></div>
     <div id="node23"></div>
     <div id="node24"></div>
     <div id="retag-me">
       <div id="retag-me-2"></div>
     </div>
     <div id="node25"></div>
+    <div id="node26" style='background-image: url("moz-page-thumb://thumbnail?url=http%3A%2F%2Fwww.mozilla.org%2F");'></div>
+    <div id="node27" class="Double &quot; and single &apos;"></div>
   </body>
 </html>
--- a/browser/devtools/markupview/test/browser_inspector_markup_edit.js
+++ b/browser/devtools/markupview/test/browser_inspector_markup_edit.js
@@ -234,16 +234,89 @@ function test() {
       },
       after: function() {
         assertAttributes(doc.querySelector("#node25"), {
           id: "node25",
           src: "somefile.html?param1=<a>&param2=\xfc&param3='\"'"
         });
       }
     },
+
+    {
+      desc: "Modify inline style containing \"",
+      before: function() {
+        assertAttributes(doc.querySelector("#node26"), {
+          id: "node26",
+          style: 'background-image: url("moz-page-thumb://thumbnail?url=http%3A%2F%2Fwww.mozilla.org%2F");'
+        });
+      },
+      execute: function(after) {
+        inspector.once("markupmutation", after);
+        let editor = getContainerForRawNode(markup, doc.querySelector("#node26")).editor;
+        let attr = editor.attrs["style"].querySelector(".editable");
+
+
+        attr.focus();
+        EventUtils.sendKey("return", inspector.panelWin);
+
+        let input = inplaceEditor(attr).input;
+        let value = input.value;
+
+        is (value,
+          "style='background-image: url(\"moz-page-thumb://thumbnail?url=http%3A%2F%2Fwww.mozilla.org%2F\");'",
+          "Value contains actual double quotes"
+        );
+
+        value = value.replace(/mozilla\.org/, "mozilla.com");
+        input.value = value;
+
+        EventUtils.sendKey("return", inspector.panelWin);
+      },
+      after: function() {
+        assertAttributes(doc.querySelector("#node26"), {
+          id: "node26",
+          style: 'background-image: url("moz-page-thumb://thumbnail?url=http%3A%2F%2Fwww.mozilla.com%2F");'
+        });
+      }
+    },
+
+    {
+      desc: "Modify inline style containing \" and \'",
+      before: function() {
+        assertAttributes(doc.querySelector("#node27"), {
+          id: "node27",
+          class: 'Double " and single \''
+        });
+      },
+      execute: function(after) {
+        inspector.once("markupmutation", after);
+        let editor = getContainerForRawNode(markup, doc.querySelector("#node27")).editor;
+        let attr = editor.attrs["class"].querySelector(".editable");
+
+        attr.focus();
+        EventUtils.sendKey("return", inspector.panelWin);
+
+        let input = inplaceEditor(attr).input;
+        let value = input.value;
+
+        is (value, "class=\"Double &quot; and single '\"", "Value contains &quot;");
+
+        value = value.replace(/Double/, "&quot;").replace(/single/, "'");
+        input.value = value;
+
+        EventUtils.sendKey("return", inspector.panelWin);
+      },
+      after: function() {
+        assertAttributes(doc.querySelector("#node27"), {
+          id: "node27",
+          class: '" " and \' \''
+        });
+      }
+    },
+
     {
       desc: "Add an attribute value without closing \"",
       enteredText: 'style="display: block;',
       expectedAttributes: {
         style: "display: block;"
       }
     },
     {
--- a/browser/devtools/responsivedesign/responsivedesign.jsm
+++ b/browser/devtools/responsivedesign/responsivedesign.jsm
@@ -682,16 +682,17 @@ ResponsiveUI.prototype = {
 
     this.saveCustomSize();
 
     delete this._resizing;
     if (this.transitionsEnabled) {
       this.stack.removeAttribute("notransition");
     }
     this.ignoreY = false;
+    this.ignoreX = false;
     this.isResizing = false;
   },
 
   /**
    * Store the custom size as a pref.
    */
    saveCustomSize: function RUI_saveCustomSize() {
      Services.prefs.setIntPref("devtools.responsiveUI.customWidth", this.customPreset.width);
--- a/browser/devtools/styleinspector/test/browser_ruleview_inherit.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_inherit.js
@@ -37,17 +37,17 @@ function simpleInherit(aInspector, aRule
     ok(!!inheritRule.inherited, "Rule should consider itself inherited.");
     is(inheritRule.textProps.length, 1, "Should only display one inherited style");
     let inheritProp = inheritRule.textProps[0];
     is(inheritProp.name, "color", "color should have been inherited.");
 
     styleNode.parentNode.removeChild(styleNode);
 
     emptyInherit();
-  }).then(null, console.error);
+  });
 }
 
 function emptyInherit()
 {
   // No inheritable styles, this rule shouldn't show up.
   let style = '' +
     '#test2 {' +
     '  background-color: green;' +
@@ -63,17 +63,17 @@ function emptyInherit()
     is(elementStyle.rules.length, 1, "Should have 1 rule.");
 
     let elementRule = elementStyle.rules[0];
     ok(!elementRule.inherited, "Element style attribute should not consider itself inherited.");
 
     styleNode.parentNode.removeChild(styleNode);
 
     elementStyleInherit();
-  }).then(null, console.error);
+  });
 }
 
 function elementStyleInherit()
 {
   doc.body.innerHTML = '<div id="test2" style="color: red"><div id="test1">Styled Node</div></div>';
 
   inspector.selection.setNode(doc.getElementById("test1"));
   inspector.once("inspector-updated", () => {
@@ -87,17 +87,17 @@ function elementStyleInherit()
     let inheritRule = elementStyle.rules[1];
     is(inheritRule.domRule.type, ELEMENT_STYLE, "Inherited rule should be an element style, not a rule.");
     ok(!!inheritRule.inherited, "Rule should consider itself inherited.");
     is(inheritRule.textProps.length, 1, "Should only display one inherited style");
     let inheritProp = inheritRule.textProps[0];
     is(inheritProp.name, "color", "color should have been inherited.");
 
     finishTest();
-  }).then(null, console.error);
+  });
 }
 
 function finishTest()
 {
   doc = null;
   gBrowser.removeCurrentTab();
   finish();
 }
--- a/browser/devtools/styleinspector/test/browser_styleinspector_bug_672744_search_filter.js
+++ b/browser/devtools/styleinspector/test/browser_styleinspector_bug_672744_search_filter.js
@@ -32,17 +32,17 @@ function SI_inspectNode()
   var span = doc.querySelector("#matches");
   ok(span, "captain, we have the matches span");
 
   inspector.selection.setNode(span);
   inspector.once("inspector-updated", () => {
     is(span, computedView.viewedElement.rawNode(),
       "style inspector node matches the selected node");
     SI_toggleDefaultStyles();
-  }).then(null, (err) => console.error(err));
+  });
 }
 
 function SI_toggleDefaultStyles()
 {
   info("checking \"Browser styles\" checkbox");
 
   let doc = computedView.styleDocument;
   let checkbox = doc.querySelector(".includebrowserstyles");
--- a/browser/locales/en-US/chrome/browser/devtools/webConsole.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/webConsole.dtd
@@ -55,17 +55,17 @@
 <!ENTITY btnPageCSS.label   "CSS">
 <!ENTITY btnPageCSS.tooltip "Log CSS parsing errors">
 <!ENTITY btnPageCSS.accesskey "C">
 <!ENTITY btnPageJS.label    "JS">
 <!ENTITY btnPageJS.tooltip  "Log JavaScript exceptions">
 <!ENTITY btnPageJS.accesskey  "J">
 <!ENTITY btnPageSecurity.label "Security">
 <!ENTITY btnPageSecurity.tooltip "Log security errors and warnings">
-<!ENTITY btnPageSecurity.accesskey "S">
+<!ENTITY btnPageSecurity.accesskey "u">
 
 <!-- LOCALIZATION NOTE (btnPageLogging): This is used as the text of the
   -  the toolbar. It shows or hides messages that the web developer inserted on
   -  the page for debugging purposes, using calls such console.log() and
   -  console.error(). -->
 <!ENTITY btnPageLogging.label   "Logging">
 <!ENTITY btnPageLogging.tooltip "Log messages sent to the window.console object">
 <!ENTITY btnPageLogging.accesskey2 "R">
--- a/browser/themes/shared/devtools/markup-view.css
+++ b/browser/themes/shared/devtools/markup-view.css
@@ -4,22 +4,16 @@
 
 * {
   padding: 0;
   margin: 0;
 }
 
 .newattr {
   cursor: pointer;
-}
-
-/* Give some padding to focusable elements to match the editor input
- * that will replace them. */
-span[tabindex] {
-  display: inline-block;
   padding: 1px 0;
 }
 
 li.container {
   padding: 2px 0 0 2px;
 }
 
 .codebox {
--- a/build/autoconf/hooks.m4
+++ b/build/autoconf/hooks.m4
@@ -14,17 +14,40 @@ dnl Wrap AC_INIT_PREPARE to add the abov
 define([_MOZ_AC_INIT_PREPARE], defn([AC_INIT_PREPARE]))
 define([AC_INIT_PREPARE],
 [_MOZ_AC_INIT_PREPARE($1)
 MOZ_CONFIG_LOG_TRAP
 ])
 
 dnl Disable the trap when running sub-configures.
 define([_MOZ_AC_OUTPUT_SUBDIRS], defn([AC_OUTPUT_SUBDIRS]))
+define([MOZ_SUBCONFIGURE_WRAP],
+[ _CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+case "$host" in
+*-mingw*)
+    _CONFIG_SHELL=$(cd $(dirname $_CONFIG_SHELL); pwd -W)/$(basename $_CONFIG_SHELL)
+    if test ! -e "$_CONFIG_SHELL" -a -e "${_CONFIG_SHELL}.exe"; then
+        _CONFIG_SHELL="${_CONFIG_SHELL}.exe"
+    fi
+    ;;
+esac
+
+if test -d "$1"; then
+    (cd "$1"; $PYTHON $_topsrcdir/build/subconfigure.py dump "$_CONFIG_SHELL")
+fi
+$2
+(cd "$1"; $PYTHON $_topsrcdir/build/subconfigure.py adjust)
+])
+
 define([AC_OUTPUT_SUBDIRS],
 [trap '' EXIT
-_MOZ_AC_OUTPUT_SUBDIRS($1)
+for moz_config_dir in $1; do
+  MOZ_SUBCONFIGURE_WRAP([$moz_config_dir],[
+    _MOZ_AC_OUTPUT_SUBDIRS($moz_config_dir)
+  ])
+done
+
 MOZ_CONFIG_LOG_TRAP
 ])
 
 dnl Print error messages in config.log as well as stderr
 define([AC_MSG_ERROR],
 [{ echo "configure: error: $1" 1>&2; echo "configure: error: $1" 1>&5; exit 1; }])
new file mode 100644
--- /dev/null
+++ b/build/subconfigure.py
@@ -0,0 +1,124 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# This script is used to capture the content of config.status-generated
+# files and subsequently restore their timestamp if they haven't changed.
+
+import os
+import re
+import subprocess
+import sys
+import pickle
+
+class File(object):
+    def __init__(self, path):
+        self._path = path
+        self._content = open(path, 'rb').read()
+        stat = os.stat(path)
+        self._times = (stat.st_atime, stat.st_mtime)
+
+    def update_time(self):
+        '''If the file hasn't changed since the instance was created,
+           restore its old modification time.'''
+        if not os.path.exists(self._path):
+            return
+        if open(self._path, 'rb').read() == self._content:
+            os.utime(self._path, self._times)
+
+
+# As defined in the various sub-configures in the tree
+PRECIOUS_VARS = set([
+    'build_alias',
+    'host_alias',
+    'target_alias',
+    'CC',
+    'CFLAGS',
+    'LDFLAGS',
+    'LIBS',
+    'CPPFLAGS',
+    'CPP',
+    'CCC',
+    'CXXFLAGS',
+    'CXX',
+    'CCASFLAGS',
+    'CCAS',
+])
+
+
+# Autoconf, in some of the sub-configures used in the tree, likes to error
+# out when "precious" variables change in value. The solution it gives to
+# straighten things is to either run make distclean or remove config.cache.
+# There's no reason not to do the latter automatically instead of failing,
+# doing the cleanup (which, on buildbots means a full clobber), and
+# restarting from scratch.
+def maybe_clear_cache():
+    comment = re.compile(r'^\s+#')
+    cache = {}
+    with open('config.cache') as f:
+        for line in f.readlines():
+            if not comment.match(line) and '=' in line:
+                key, value = line.split('=', 1)
+                cache[key] = value
+    for precious in PRECIOUS_VARS:
+        entry = 'ac_cv_env_%s_value' % precious
+        if entry in cache and (not precious in os.environ or os.environ[precious] != cache[entry]):
+            os.remove('config.cache')
+            return
+
+
+def dump(dump_file, shell):
+    if os.path.exists('config.cache'):
+        maybe_clear_cache()
+    if not os.path.exists('config.status'):
+        if os.path.exists(dump_file):
+            os.remove(dump_file)
+        return
+
+    config_files = [File('config.status')]
+
+    # Scan the config.status output for information about configuration files
+    # it generates.
+    config_status_output = subprocess.check_output(
+        [shell, '-c', './config.status --help'],
+        stderr=subprocess.STDOUT).splitlines()
+    state = None
+    for line in config_status_output:
+        if line.startswith('Configuration') and line.endswith(':'):
+            state = 'config'
+        elif not line.startswith(' '):
+            state = None
+        elif state == 'config':
+            for f in (couple.split(':')[0] for couple in line.split()):
+                if os.path.isfile(f):
+                    config_files.append(File(f))
+
+    with open(dump_file, 'wb') as f:
+        pickle.dump(config_files, f)
+
+
+def adjust(dump_file):
+    if not os.path.exists(dump_file):
+        return
+
+    config_files = []
+
+    try:
+        with open(dump_file, 'rb') as f:
+            config_files = pickle.load(f)
+    except Exception:
+        pass
+
+    for f in config_files:
+        f.update_time()
+
+    os.remove(dump_file)
+
+
+CONFIG_DUMP = 'config_files.pkl'
+
+if __name__ == '__main__':
+    if sys.argv[1] == 'dump':
+        dump(CONFIG_DUMP, sys.argv[2])
+    elif sys.argv[1] == 'adjust':
+        adjust(CONFIG_DUMP)
--- a/config/makefiles/precompile/Makefile.in
+++ b/config/makefiles/precompile/Makefile.in
@@ -19,25 +19,27 @@ include $(topsrcdir)/config/rules.mk
 # otherwise the output is unexpected and it confuses downstream parsers.
 define make_subtier_dir
 $(call BUILDSTATUS,SUBTIER_START precompile $(1))
 +$(MAKE) -C $(2) $(3)
 $(call BUILDSTATUS,SUBTIER_FINISH precompile $(1))
 
 endef
 
-export::
-	$(call BUILDSTATUS,SUBTIERS IPDL WebIDL XPIDL XPIDLParser)
+default::
+	$(call BUILDSTATUS,TIER_START  precompile IPDL WebIDL XPIDL)
+	+$(MAKE) export
+	$(call BUILDSTATUS,TIER_FINISH precompile)
 
-export:: ipdl webidl xpidl-parser xpidl
+export:: ipdl webidl xpidl
 
 ipdl:
 	$(call make_subtier_dir,IPDL,$(DEPTH)/ipc/ipdl,ipdl)
 
 webidl:
 	$(call make_subtier_dir,WebIDL,$(DEPTH)/dom/bindings,webidl)
 
-xpidl-parser:
-	$(call make_subtier_dir,XPIDLParser,$(DEPTH)/xpcom/idl-parser,xpidl-parser)
-
-xpidl: xpidl-parser
+xpidl:
+	$(call BUILDSTATUS,SUBTIER_START  precompile XPIDL)
+	+$(MAKE) -C $(DEPTH)/xpcom/idl-parser xpidl-parser
 	$(call py_action,process_install_manifest,$(DIST)/idl $(DEPTH)/_build_manifests/install/dist_idl)
-	$(call make_subtier_dir,XPIDL,$(DEPTH)/config/makefiles/xpidl,xpidl)
+	+$(MAKE) -C $(DEPTH)/config/makefiles/xpidl xpidl
+	$(call BUILDSTATUS,SUBTIER_FINISH precompile XPIDL)
--- a/config/makefiles/target_export.mk
+++ b/config/makefiles/target_export.mk
@@ -7,19 +7,19 @@
 
 PARALLEL_DIRS_export = $(addsuffix _export,$(PARALLEL_DIRS))
 
 .PHONY: export $(PARALLEL_DIRS_export)
 
 ###############
 ## TIER targets
 ###############
-export_tier_%:
+$(addprefix export_tier_,$(TIERS)): export_tier_%:
 	@$(ECHO) "$@"
-	$(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,export,$(dir)))
+	$(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,$*,export,$(dir),export))
 
 #################
 ## Common targets
 #################
 ifdef PARALLEL_DIRS
 export:: $(PARALLEL_DIRS_export)
 
 $(PARALLEL_DIRS_export): %_export: %/Makefile
--- a/config/makefiles/target_libs.mk
+++ b/config/makefiles/target_libs.mk
@@ -7,19 +7,19 @@
 
 PARALLEL_DIRS_libs = $(addsuffix _libs,$(PARALLEL_DIRS))
 
 .PHONY: libs $(PARALLEL_DIRS_libs)
 
 ###############
 ## TIER targets
 ###############
-libs_tier_%:
+$(addprefix libs_tier_,$(TIERS)): libs_tier_%:
 	@$(ECHO) "$@"
-	$(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,libs,$(dir)))
+	$(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,$*,libs,$(dir),libs))
 
 #################
 ## Common targets
 #################
 ifdef PARALLEL_DIRS
 libs:: $(PARALLEL_DIRS_libs)
 
 $(PARALLEL_DIRS_libs): %_libs: %/Makefile
@@ -38,17 +38,17 @@ else
 EXPORT_LIBRARY = $(DEPTH)/staticlib
 endif
 else
 # If EXPORT_LIBRARY has a value, we'll be installing there. We also need to cleanup there
 GARBAGE += $(foreach lib,$(LIBRARY),$(EXPORT_LIBRARY)/$(lib))
 endif
 endif # EXPORT_LIBRARY
 
-libs:: $(SUBMAKEFILES) $(MAKE_DIRS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS) $(JAVA_LIBRARY)
+libs:: $(SUBMAKEFILES) $(MAKE_DIRS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS)
 ifndef NO_DIST_INSTALL
 ifdef SHARED_LIBRARY
 ifdef IS_COMPONENT
 	$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)/components
 	$(ELF_DYNSTR_GC) $(FINAL_TARGET)/components/$(SHARED_LIBRARY)
 ifndef NO_COMPONENTS_MANIFEST
 	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/chrome.manifest "manifest components/components.manifest"
 	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/components.manifest "binary-component $(SHARED_LIBRARY)"
@@ -113,21 +113,11 @@ INSTALL_TARGETS += HOST_PROGRAMS
 endif
 
 ifdef HOST_LIBRARY
 HOST_LIBRARY_FILES = $(HOST_LIBRARY)
 HOST_LIBRARY_DEST ?= $(DIST)/host/lib
 INSTALL_TARGETS += HOST_LIBRARY
 endif
 
-ifdef JAVA_LIBRARY
-JAVA_LIBRARY_FILES = $(JAVA_LIBRARY)
-ifdef IS_COMPONENT
-JAVA_LIBRARY_DEST ?= $(FINAL_TARGET)/components
-else
-JAVA_LIBRARY_DEST ?= $(FINAL_TARGET)
-endif
-INSTALL_TARGETS += JAVA_LIBRARY
-endif
-
 endif # !NO_DIST_INSTALL
 
 # EOF
--- a/config/makefiles/target_tools.mk
+++ b/config/makefiles/target_tools.mk
@@ -7,19 +7,19 @@
 
 PARALLEL_DIRS_tools = $(addsuffix _tools,$(PARALLEL_DIRS))
 
 .PHONY: tools $(PARALLEL_DIRS_tools)
 
 ###############
 ## TIER targets
 ###############
-tools_tier_%:
+$(addprefix tools_tier_,$(TIERS)): tools_tier_%:
 	@$(ECHO) "$@"
-	$(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,tools,$(dir)))
+	$(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,$*,tools,$(dir),tools))
 
 #################
 ## Common targets
 #################
 ifdef PARALLEL_DIRS
 tools:: $(PARALLEL_DIRS_tools)
 
 $(PARALLEL_DIRS_tools): %_tools: %/Makefile
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -25,16 +25,17 @@ endif
   HOST_CSRCS \
   HOST_LIBRARY_NAME \
   MODULE \
   NO_DIST_INSTALL \
   PARALLEL_DIRS \
   TEST_DIRS \
   TIERS \
   TOOL_DIRS \
+  XPCSHELL_TESTS \
   XPIDL_MODULE \
   $(NULL)
 
 _DEPRECATED_VARIABLES := \
   XPIDL_FLAGS \
   $(NULL)
 
 ifndef EXTERNALLY_MANAGED_MAKE_FILE
@@ -298,20 +299,16 @@ endif
 endif
 
 ifdef FORCE_SHARED_LIB
 ifndef FORCE_STATIC_LIB
 LIBRARY := $(NULL)
 endif
 endif
 
-ifdef JAVA_LIBRARY_NAME
-JAVA_LIBRARY := $(JAVA_LIBRARY_NAME).jar
-endif
-
 ifeq ($(OS_ARCH),WINNT)
 ifndef GNU_CC
 
 #
 # Unless we're building SIMPLE_PROGRAMS, all C++ files share a PDB file per
 # directory. For parallel builds, this PDB file is shared and locked by
 # MSPDBSRV.EXE, starting with MSVC8 SP1. If you're using MSVC 7.1 or MSVC8
 # without SP1, don't do parallel builds.
@@ -428,33 +425,34 @@ endif
 ifdef MOZ_UPDATE_XTERM
 # Its good not to have a newline at the end of the titlebar string because it
 # makes the make -s output easier to read.  Echo -n does not work on all
 # platforms, but we can trick printf into doing it.
 UPDATE_TITLE = printf "\033]0;%s in %s\007" $(1) $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$(2) ;
 endif
 
 ifdef MACH
-BUILDSTATUS=@echo BUILDSTATUS $1
+BUILDSTATUS=@echo "BUILDSTATUS $1"
 endif
+
 # Static directories are largely independent of our build system. But, they
 # could share the same build mechanism (like moz.build files). We need to
 # prevent leaking of our backend state to these independent build systems. This
 # is why MOZBUILD_BACKEND_CHECKED isn't exported to make invocations for static
 # directories.
 define SUBMAKE # $(call SUBMAKE,target,directory,static)
 +@$(UPDATE_TITLE)
 +$(if $(3), MOZBUILD_BACKEND_CHECKED=,) $(MAKE) $(if $(2),-C $(2)) $(1)
 
 endef # The extra line is important here! don't delete it
 
 define TIER_DIR_SUBMAKE
-$(call BUILDSTATUS,TIERDIR_START  $(2))
-$(call SUBMAKE,$(1),$(2),$(3))
-$(call BUILDSTATUS,TIERDIR_FINISH $(2))
+$(call BUILDSTATUS,TIERDIR_START  $(1) $(2) $(3))
+$(call SUBMAKE,$(4),$(3),$(5))
+$(call BUILDSTATUS,TIERDIR_FINISH $(1) $(2) $(3))
 
 endef # Ths empty line is important.
 
 
 ifneq (,$(strip $(DIRS)))
 LOOP_OVER_DIRS = \
   $(foreach dir,$(DIRS),$(call SUBMAKE,$@,$(dir)))
 endif
@@ -702,51 +700,57 @@ alldep::
 	$(MAKE) export
 	$(MAKE) depend
 	$(MAKE) libs
 	$(MAKE) tools
 
 endif # TIERS
 endif # SUPPRESS_DEFAULT_RULES
 
-ifeq ($(filter s,$(MAKEFLAGS)),)
+ifeq ($(findstring s,$(filter-out --%, $(MAKEFLAGS))),)
 ECHO := echo
 QUIET :=
 else
 ECHO := true
 QUIET := -q
 endif
 
 # This function is called and evaluated to produce the rule to build the
-# specified tier. Each tier begins by building the "static" directories.
-# The BUILDSTATUS echo commands are used to faciliate easier parsing
-# of build output. Build drivers are encouraged to filter these lines
-# from the user.
+# specified tier.
+#
+# Tiers are traditionally composed of directories that are invoked either
+# once (so-called "static" directories) or 3 times with the export, libs, and
+# tools sub-tiers.
+#
+# If the TIER_$(tier)_CUSTOM variable is defined, then these traditional
+# tier rules are ignored and each directory in the tier is executed via a
+# sub-make invocation (make -C).
 define CREATE_TIER_RULE
 tier_$(1)::
-	$(call BUILDSTATUS,TIER_START $(1))
-	$(call BUILDSTATUS,SUBTIERS $(if $(tier_$(1)_staticdirs),static )$(if $(tier_$(1)_dirs),export libs tools))
-	$(call BUILDSTATUS,STATICDIRS $$($$@_staticdirs))
-	$(call BUILDSTATUS,DIRS $$($$@_dirs))
+ifdef TIER_$(1)_CUSTOM
+	$$(foreach dir,$$($$@_dirs),$$(call SUBMAKE,,$$(dir)))
+else
+	$(call BUILDSTATUS,TIER_START $(1) $(if $(tier_$(1)_staticdirs),static )$(if $(tier_$(1)_dirs),export libs tools))
 ifneq (,$(tier_$(1)_staticdirs))
-	$(call BUILDSTATUS,SUBTIER_START $(1) static)
-	$$(foreach dir,$$($$@_staticdirs),$$(call TIER_DIR_SUBMAKE,,$$(dir),1))
+	$(call BUILDSTATUS,SUBTIER_START  $(1) static $$($$@_staticdirs))
+	$$(foreach dir,$$($$@_staticdirs),$$(call TIER_DIR_SUBMAKE,$(1),static,$$(dir),,1))
 	$(call BUILDSTATUS,SUBTIER_FINISH $(1) static)
 endif
 ifneq (,$(tier_$(1)_dirs))
-	$(call BUILDSTATUS,SUBTIER_START $(1) export)
+	$(call BUILDSTATUS,SUBTIER_START  $(1) export $$($$@_dirs))
 	$$(MAKE) export_$$@
 	$(call BUILDSTATUS,SUBTIER_FINISH $(1) export)
-	$(call BUILDSTATUS,SUBTIER_START $(1) libs)
+	$(call BUILDSTATUS,SUBTIER_START  $(1) libs $$($$@_dirs))
 	$$(MAKE) libs_$$@
 	$(call BUILDSTATUS,SUBTIER_FINISH $(1) libs)
-	$(call BUILDSTATUS,SUBTIER_START $(1) tools)
+	$(call BUILDSTATUS,SUBTIER_START  $(1) tools $$($$@_dirs))
 	$$(MAKE) tools_$$@
 	$(call BUILDSTATUS,SUBTIER_FINISH $(1) tools)
-	$(call BUILDSTATUS TIER_FINISH $(1))
+endif
+	$(call BUILDSTATUS,TIER_FINISH $(1))
 endif
 endef
 
 $(foreach tier,$(TIERS),$(eval $(call CREATE_TIER_RULE,$(tier))))
 
 # Do everything from scratch
 everything::
 	$(MAKE) clean
@@ -1131,25 +1135,25 @@ endef
 $(COBJS):
 	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 # DEFINES and ACDEFINES are needed here to enable conditional compilation of Q_OBJECTs:
 # 'moc' only knows about #defines it gets on the command line (-D...), not in
 # included headers like mozilla-config.h
-moc_%.cpp: %.h
+$(filter moc_%.cpp,$(CPPSRCS)): moc_%.cpp: %.h
 	$(REPORT_BUILD)
 	$(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $< $(OUTOPTION)$@
 
-moc_%.cc: %.cc
+$(filter moc_%.cc,$(CPPSRCS)): moc_%.cc: %.cc
 	$(REPORT_BUILD)
 	$(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $(_VPATH_SRCS:.cc=.h) $(OUTOPTION)$@
 
-qrc_%.cpp: %.qrc
+$(filter qrc_%.cpp,$(CPPSRCS)): qrc_%.cpp: %.qrc
 	$(REPORT_BUILD)
 	$(ELOG) $(RCC) -name $* $< $(OUTOPTION)$@
 
 ifdef ASFILES
 # The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept
 # a '-c' flag.
 $(ASOBJS):
 	$(REPORT_BUILD)
@@ -1170,72 +1174,62 @@ endif
 	@$(MAKE_DEPS_AUTO_CXX)
 	$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 $(CMOBJS):
 	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
-%.s: %.cpp $(call mkdir_deps,$(MDDEPDIR))
+$(filter %.s,$(CPPSRCS:%.cpp=%.s)): %.s: %.cpp $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
 	$(CCC) -S $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
-%.s: %.cc $(call mkdir_deps,$(MDDEPDIR))
+$(filter %.s,$(CPPSRCS:%.cc=%.s)): %.s: %.cc $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
 	$(CCC) -S $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
-%.s: %.c $(call mkdir_deps,$(MDDEPDIR))
+$(filter %.s,$(CSRCS:%.c=%.s)): %.s: %.c $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
 	$(CC) -S $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
-%.i: %.cpp $(call mkdir_deps,$(MDDEPDIR))
+$(filter %.i,$(CPPSRCS:%.cpp=%.i)): %.i: %.cpp $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
 	$(CCC) -C -E $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) > $*.i
 
-%.i: %.cc $(call mkdir_deps,$(MDDEPDIR))
+$(filter %.i,$(CPPSRCS:%.cc=%.i)): %.i: %.cc $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
 	$(CCC) -C -E $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) > $*.i
 
-%.i: %.c $(call mkdir_deps,$(MDDEPDIR))
+$(filter %.i,$(CSRCS:%.c=%.i)): %.i: %.c $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
 	$(CC) -C -E $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) > $*.i
 
-%.i: %.mm $(call mkdir_deps,$(MDDEPDIR))
+$(filter %.i,$(CMMSRCS:%.mm=%.i)): %.i: %.mm $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
 	$(CCC) -C -E $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) > $*.i
 
-%.res: %.rc
+$(RESFILE): %.res: %.rc
 	$(REPORT_BUILD)
 	@echo Creating Resource file: $@
 ifeq ($(OS_ARCH),OS2)
 	$(RC) $(RCFLAGS:-D%=-d %) -i $(subst /,\,$(srcdir)) -r $< $@
 else
 ifdef GNU_CC
 	$(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES:-I%=--include-dir %) $(OUTOPTION)$@ $(_VPATH_SRCS)
 else
 	$(RC) $(RCFLAGS) -r $(DEFINES) $(INCLUDES) $(OUTOPTION)$@ $(_VPATH_SRCS)
 endif
 endif
 
-# Cancel these implicit rules
-#
-%: %,v
-
-%: RCS/%,v
-
-%: RCS/%
+# Cancel GNU make built-in implicit rules
+ifndef .PYMAKE
+MAKEFLAGS += -r
+endif
 
-%: s.%
-
-%: SCCS/s.%
-
-###############################################################################
-# Java rules
-###############################################################################
 ifneq (,$(filter OS2 WINNT,$(OS_ARCH)))
 SEP := ;
 else
 SEP := :
 endif
 
 EMPTY :=
 SPACE := $(EMPTY) $(EMPTY)
@@ -1250,50 +1244,23 @@ ifeq ($(HOST_OS_ARCH),WINNT)
 #  on it, then merge with the rest of the path.
 root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\1|")
 non-root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\2|")
 normalizepath = $(foreach p,$(1),$(if $(filter /%,$(1)),$(patsubst %/,%,$(shell cd $(call root-path,$(1)) && pwd -W))/$(call non-root-path,$(1)),$(1)))
 else
 normalizepath = $(1)
 endif
 
+###############################################################################
+# Java rules
+###############################################################################
 ifneq (,$(value JAVAFILES)$(value RESFILES))
   include $(topsrcdir)/config/makefiles/java-build.mk
 endif
 
-_srcdir = $(call normalizepath,$(srcdir))
-ifdef JAVA_SOURCEPATH
-SP = $(subst $(SPACE),$(SEP),$(call normalizepath,$(strip $(JAVA_SOURCEPATH))))
-_JAVA_SOURCEPATH = ".$(SEP)$(_srcdir)$(SEP)$(SP)"
-else
-_JAVA_SOURCEPATH = ".$(SEP)$(_srcdir)"
-endif
-
-ifdef JAVA_CLASSPATH
-CP = $(subst $(SPACE),$(SEP),$(call normalizepath,$(strip $(JAVA_CLASSPATH))))
-_JAVA_CLASSPATH = ".$(SEP)$(CP)"
-else
-_JAVA_CLASSPATH = .
-endif
-
-_JAVA_DIR = _java
-$(_JAVA_DIR)::
-	$(NSINSTALL) -D $@
-
-$(_JAVA_DIR)/%.class: %.java $(GLOBAL_DEPS) $(_JAVA_DIR)
-	$(REPORT_BUILD)
-	$(JAVAC) $(JAVAC_FLAGS) -classpath $(_JAVA_CLASSPATH) \
-			-sourcepath $(_JAVA_SOURCEPATH) -d $(_JAVA_DIR) $(_VPATH_SRCS)
-
-$(JAVA_LIBRARY): $(addprefix $(_JAVA_DIR)/,$(JAVA_SRCS:.java=.class)) $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	$(JAR) cf $@ -C $(_JAVA_DIR) .
-
-GARBAGE_DIRS += $(_JAVA_DIR)
-
 ###############################################################################
 # Update Files Managed by Build Backend
 ###############################################################################
 
 ifndef NO_MAKEFILE_RULE
 Makefile: Makefile.in
 	@$(PYTHON) $(DEPTH)/config.status -n --file=Makefile
 	@$(TOUCH) $@
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -165,16 +165,17 @@ WebGLContext::WebGLContext()
     mGLMaxRenderbufferSize = 0;
     mGLMaxTextureImageUnits = 0;
     mGLMaxVertexTextureImageUnits = 0;
     mGLMaxVaryingVectors = 0;
     mGLMaxFragmentUniformVectors = 0;
     mGLMaxVertexUniformVectors = 0;
     mGLMaxColorAttachments = 1;
     mGLMaxDrawBuffers = 1;
+    mGLMaxTransformFeedbackSeparateAttribs = 0;
 
     // See OpenGL ES 2.0.25 spec, 6.2 State Tables, table 6.13
     mPixelStorePackAlignment = 4;
     mPixelStoreUnpackAlignment = 4;
 
     WebGLMemoryMultiReporterWrapper::AddWebGLContext(this);
 
     mAllowRestore = true;
@@ -230,16 +231,17 @@ WebGLContext::DestroyResourcesAndContext
     if (!gl)
         return;
 
     gl->MakeCurrent();
 
     mBound2DTextures.Clear();
     mBoundCubeMapTextures.Clear();
     mBoundArrayBuffer = nullptr;
+    mBoundTransformFeedbackBuffer = nullptr;
     mCurrentProgram = nullptr;
     mBoundFramebuffer = nullptr;
     mActiveOcclusionQuery = nullptr;
     mBoundRenderbuffer = nullptr;
     mBoundVertexArray = nullptr;
     mDefaultVertexArray = nullptr;
 
     while (!mTextures.isEmpty())
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -317,42 +317,31 @@ public:
     void GetContextAttributes(dom::Nullable<dom::WebGLContextAttributesInitializer>& retval);
     bool IsContextLost() const { return !IsContextStable(); }
     void GetSupportedExtensions(JSContext *cx, dom::Nullable< nsTArray<nsString> > &retval);
     JSObject* GetExtension(JSContext* cx, const nsAString& aName, ErrorResult& rv);
     void ActiveTexture(WebGLenum texture);
     void AttachShader(WebGLProgram* program, WebGLShader* shader);
     void BindAttribLocation(WebGLProgram* program, WebGLuint location,
                             const nsAString& name);
-    void BindBuffer(WebGLenum target, WebGLBuffer* buf);
     void BindFramebuffer(WebGLenum target, WebGLFramebuffer* wfb);
     void BindRenderbuffer(WebGLenum target, WebGLRenderbuffer* wrb);
     void BindTexture(WebGLenum target, WebGLTexture *tex);
     void BindVertexArray(WebGLVertexArray *vao);
     void BlendColor(WebGLclampf r, WebGLclampf g, WebGLclampf b, WebGLclampf a) {
         if (!IsContextStable())
             return;
         MakeContextCurrent();
         gl->fBlendColor(r, g, b, a);
     }
     void BlendEquation(WebGLenum mode);
     void BlendEquationSeparate(WebGLenum modeRGB, WebGLenum modeAlpha);
     void BlendFunc(WebGLenum sfactor, WebGLenum dfactor);
     void BlendFuncSeparate(WebGLenum srcRGB, WebGLenum dstRGB,
                            WebGLenum srcAlpha, WebGLenum dstAlpha);
-    void BufferData(WebGLenum target, WebGLsizeiptr size, WebGLenum usage);
-    void BufferData(WebGLenum target, const dom::ArrayBufferView &data,
-                    WebGLenum usage);
-    void BufferData(WebGLenum target,
-                    const Nullable<dom::ArrayBuffer> &maybeData,
-                    WebGLenum usage);
-    void BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
-                       const dom::ArrayBufferView &data);
-    void BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
-                       const Nullable<dom::ArrayBuffer> &maybeData);
     WebGLenum CheckFramebufferStatus(WebGLenum target);
     void Clear(WebGLbitfield mask);
     void ClearColor(WebGLclampf r, WebGLclampf g, WebGLclampf b, WebGLclampf a);
     void ClearDepth(WebGLclampf v);
     void ClearStencil(WebGLint v);
     void ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboolean a);
     void CompileShader(WebGLShader *shader);
     void CompressedTexImage2D(WebGLenum target, WebGLint level,
@@ -365,25 +354,23 @@ public:
                                  WebGLenum format,
                                  const dom::ArrayBufferView& view);
     void CopyTexImage2D(WebGLenum target, WebGLint level,
                         WebGLenum internalformat, WebGLint x, WebGLint y,
                         WebGLsizei width, WebGLsizei height, WebGLint border);
     void CopyTexSubImage2D(WebGLenum target, WebGLint level, WebGLint xoffset,
                            WebGLint yoffset, WebGLint x, WebGLint y,
                            WebGLsizei width, WebGLsizei height);
-    already_AddRefed<WebGLBuffer> CreateBuffer();
     already_AddRefed<WebGLFramebuffer> CreateFramebuffer();
     already_AddRefed<WebGLProgram> CreateProgram();
     already_AddRefed<WebGLRenderbuffer> CreateRenderbuffer();
     already_AddRefed<WebGLTexture> CreateTexture();
     already_AddRefed<WebGLShader> CreateShader(WebGLenum type);
     already_AddRefed<WebGLVertexArray> CreateVertexArray();
     void CullFace(WebGLenum face);
-    void DeleteBuffer(WebGLBuffer *buf);
     void DeleteFramebuffer(WebGLFramebuffer *fbuf);
     void DeleteProgram(WebGLProgram *prog);
     void DeleteRenderbuffer(WebGLRenderbuffer *rbuf);
     void DeleteShader(WebGLShader *shader);
     void DeleteVertexArray(WebGLVertexArray *vao);
     void DeleteTexture(WebGLTexture *tex);
     void DepthFunc(WebGLenum func);
     void DepthMask(WebGLboolean b);
@@ -454,17 +441,16 @@ public:
                               WebGLenum pname) {
         return GetTexParameter(target, pname);
     }
     JS::Value GetUniform(JSContext* cx, WebGLProgram *prog,
                          WebGLUniformLocation *location, ErrorResult& rv);
     already_AddRefed<WebGLUniformLocation>
       GetUniformLocation(WebGLProgram *prog, const nsAString& name);
     void Hint(WebGLenum target, WebGLenum mode);
-    bool IsBuffer(WebGLBuffer *buffer);
     bool IsFramebuffer(WebGLFramebuffer *fb);
     bool IsProgram(WebGLProgram *prog);
     bool IsRenderbuffer(WebGLRenderbuffer *rb);
     bool IsShader(WebGLShader *shader);
     bool IsTexture(WebGLTexture *tex);
     bool IsVertexArray(WebGLVertexArray *vao);
     void LineWidth(WebGLfloat width) {
         if (!IsContextStable())
@@ -750,21 +736,55 @@ public:
     already_AddRefed<WebGLQuery> GetQuery(WebGLenum target, WebGLenum pname);
     JS::Value GetQueryObject(JSContext* cx, WebGLQuery *query, WebGLenum pname);
 
 private:
     bool ValidateTargetParameter(WebGLenum target, const char* infos);
     WebGLRefPtr<WebGLQuery>& GetActiveQueryByTarget(WebGLenum target);
 
 // -----------------------------------------------------------------------------
+// Buffer Objects (WebGLContextBuffers.cpp)
+public:
+    void BindBuffer(WebGLenum target, WebGLBuffer* buf);
+    void BindBufferBase(WebGLenum target, WebGLuint index, WebGLBuffer* buffer);
+    void BindBufferRange(WebGLenum target, WebGLuint index, WebGLBuffer* buffer,
+                         WebGLintptr offset, WebGLsizeiptr size);
+    void BufferData(WebGLenum target, WebGLsizeiptr size, WebGLenum usage);
+    void BufferData(WebGLenum target, const dom::ArrayBufferView &data,
+                    WebGLenum usage);
+    void BufferData(WebGLenum target,
+                    const Nullable<dom::ArrayBuffer> &maybeData,
+                    WebGLenum usage);
+    void BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
+                       const dom::ArrayBufferView &data);
+    void BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
+                       const Nullable<dom::ArrayBuffer> &maybeData);
+    already_AddRefed<WebGLBuffer> CreateBuffer();
+    void DeleteBuffer(WebGLBuffer *buf);
+    bool IsBuffer(WebGLBuffer *buffer);
+
+private:
+    // ARRAY_BUFFER slot
+    WebGLRefPtr<WebGLBuffer> mBoundArrayBuffer;
+
+    // TRANSFORM_FEEDBACK_BUFFER slot
+    WebGLRefPtr<WebGLBuffer> mBoundTransformFeedbackBuffer;
+
+    // these two functions emit INVALID_ENUM for invalid `target`.
+    WebGLRefPtr<WebGLBuffer>* GetBufferSlotByTarget(GLenum target, const char* infos);
+    WebGLRefPtr<WebGLBuffer>* GetBufferSlotByTargetIndexed(GLenum target, GLuint index, const char* infos);
+    bool ValidateBufferUsageEnum(WebGLenum target, const char* infos);
+
+// -----------------------------------------------------------------------------
 // State and State Requests (WebGLContextState.cpp)
 public:
     void Disable(WebGLenum cap);
     void Enable(WebGLenum cap);
     JS::Value GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv);
+    JS::Value GetParameterIndexed(JSContext* cx, WebGLenum pname, WebGLuint index);
     bool IsEnabled(WebGLenum cap);
 
 private:
     bool ValidateCapabilityEnum(WebGLenum cap, const char* info);
 
 // -----------------------------------------------------------------------------
 // Vertices Feature (WebGLContextVertices.cpp)
 public:
@@ -911,16 +931,17 @@ protected:
     int32_t mGLMaxRenderbufferSize;
     int32_t mGLMaxTextureImageUnits;
     int32_t mGLMaxVertexTextureImageUnits;
     int32_t mGLMaxVaryingVectors;
     int32_t mGLMaxFragmentUniformVectors;
     int32_t mGLMaxVertexUniformVectors;
     int32_t mGLMaxColorAttachments;
     int32_t mGLMaxDrawBuffers;
+    uint32_t mGLMaxTransformFeedbackSeparateAttribs;
 
     // Represents current status, or state, of the context. That is, is it lost
     // or stable and what part of the context lost process are we currently at.
     // This is used to support the WebGL spec's asyncronous nature in handling
     // context loss.
     enum ContextStatus {
         // The context is stable; there either are none or we don't know of any.
         ContextStable,
@@ -974,17 +995,16 @@ protected:
     bool ValidateBlendEquationEnum(WebGLenum cap, const char *info);
     bool ValidateBlendFuncDstEnum(WebGLenum mode, const char *info);
     bool ValidateBlendFuncSrcEnum(WebGLenum mode, const char *info);
     bool ValidateBlendFuncEnumsCompatibility(WebGLenum sfactor, WebGLenum dfactor, const char *info);
     bool ValidateTextureTargetEnum(WebGLenum target, const char *info);
     bool ValidateComparisonEnum(WebGLenum target, const char *info);
     bool ValidateStencilOpEnum(WebGLenum action, const char *info);
     bool ValidateFaceEnum(WebGLenum face, const char *info);
-    bool ValidateBufferUsageEnum(WebGLenum target, const char *info);
     bool ValidateTexFormatAndType(WebGLenum format, WebGLenum type, int jsArrayType,
                                       uint32_t *texelSize, const char *info);
     bool ValidateDrawModeEnum(WebGLenum mode, const char *info);
     bool ValidateAttribIndex(WebGLuint index, const char *info);
     bool ValidateStencilParamsForDrawCall();
     
     bool ValidateGLSLVariableName(const nsAString& name, const char *info);
     bool ValidateGLSLCharacter(PRUnichar c);
@@ -1105,18 +1125,16 @@ protected:
         return mContextStatus == ContextStable;
     }
     void ForceLoseContext();
     void ForceRestoreContext();
 
     nsTArray<WebGLRefPtr<WebGLTexture> > mBound2DTextures;
     nsTArray<WebGLRefPtr<WebGLTexture> > mBoundCubeMapTextures;
 
-    WebGLRefPtr<WebGLBuffer> mBoundArrayBuffer;
-
     WebGLRefPtr<WebGLProgram> mCurrentProgram;
 
     uint32_t mMaxFramebufferColorAttachments;
 
     WebGLRefPtr<WebGLFramebuffer> mBoundFramebuffer;
     WebGLRefPtr<WebGLRenderbuffer> mBoundRenderbuffer;
     WebGLRefPtr<WebGLVertexArray> mBoundVertexArray;
     WebGLRefPtr<WebGLQuery> mActiveOcclusionQuery;
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/WebGLContextBuffers.cpp
@@ -0,0 +1,432 @@
+/* -*- Mode: C++; tab-width: 4; 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 "WebGLContext.h"
+#include "WebGLBuffer.h"
+#include "WebGLVertexArray.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+void
+WebGLContext::BindBuffer(WebGLenum target, WebGLBuffer *buffer)
+{
+    if (!IsContextStable())
+        return;
+
+    if (!ValidateObjectAllowDeletedOrNull("bindBuffer", buffer))
+        return;
+
+    // silently ignore a deleted buffer
+    if (buffer && buffer->IsDeleted())
+        return;
+
+    WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bindBuffer");
+
+    if (!bufferSlot) {
+        return;
+    }
+
+    if (buffer) {
+        if (!buffer->Target()) {
+            buffer->SetTarget(target);
+            buffer->SetHasEverBeenBound(true);
+        } else if (target != buffer->Target()) {
+            return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target");
+        }
+    }
+
+    *bufferSlot = buffer;
+
+    MakeContextCurrent();
+
+    gl->fBindBuffer(target, buffer ? buffer->GLName() : 0);
+}
+
+void
+WebGLContext::BindBufferBase(WebGLenum target, WebGLuint index, WebGLBuffer* buffer)
+{
+    if (!IsContextStable())
+        return;
+
+    if (!ValidateObjectAllowDeletedOrNull("bindBufferBase", buffer))
+        return;
+
+    // silently ignore a deleted buffer
+    if (buffer && buffer->IsDeleted()) {
+        return;
+    }
+
+    WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTargetIndexed(target, index, "bindBufferBase");
+
+    if (!bufferSlot) {
+        return;
+    }
+
+    if (buffer) {
+        if (!buffer->Target()) {
+            buffer->SetTarget(target);
+            buffer->SetHasEverBeenBound(true);
+        } else if (target != buffer->Target()) {
+            return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target");
+        }
+    }
+
+    *bufferSlot = buffer;
+
+    MakeContextCurrent();
+
+    gl->fBindBufferBase(target, index, buffer ? buffer->GLName() : 0);
+}
+
+void
+WebGLContext::BindBufferRange(WebGLenum target, WebGLuint index, WebGLBuffer* buffer,
+                              WebGLintptr offset, WebGLsizeiptr size)
+{
+    if (!IsContextStable())
+        return;
+
+    if (!ValidateObjectAllowDeletedOrNull("bindBufferRange", buffer))
+        return;
+
+    // silently ignore a deleted buffer
+    if (buffer && buffer->IsDeleted())
+        return;
+
+    WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTargetIndexed(target, index, "bindBufferBase");
+
+    if (!bufferSlot) {
+        return;
+    }
+
+    if (buffer) {
+        if (!buffer->Target()) {
+            buffer->SetTarget(target);
+            buffer->SetHasEverBeenBound(true);
+        } else if (target != buffer->Target()) {
+            return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target");
+        }
+    }
+
+    *bufferSlot = buffer;
+
+    MakeContextCurrent();
+
+    gl->fBindBufferRange(target, index, buffer ? buffer->GLName() : 0, offset, size);
+}
+
+void
+WebGLContext::BufferData(WebGLenum target, WebGLsizeiptr size,
+                         WebGLenum usage)
+{
+    if (!IsContextStable())
+        return;
+
+    WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferData");
+
+    if (!bufferSlot) {
+        return;
+    }
+
+    if (size < 0)
+        return ErrorInvalidValue("bufferData: negative size");
+
+    if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
+        return;
+
+    WebGLBuffer* boundBuffer = bufferSlot->get();
+
+    if (!boundBuffer)
+        return ErrorInvalidOperation("bufferData: no buffer bound!");
+
+    void* zeroBuffer = calloc(size, 1);
+    if (!zeroBuffer)
+        return ErrorOutOfMemory("bufferData: out of memory");
+
+    MakeContextCurrent();
+    InvalidateBufferFetching();
+
+    GLenum error = CheckedBufferData(target, size, zeroBuffer, usage);
+    free(zeroBuffer);
+
+    if (error) {
+        GenerateWarning("bufferData generated error %s", ErrorName(error));
+        return;
+    }
+
+    boundBuffer->SetByteLength(size);
+    if (!boundBuffer->ElementArrayCacheBufferData(nullptr, size)) {
+        return ErrorOutOfMemory("bufferData: out of memory");
+    }
+}
+
+void
+WebGLContext::BufferData(WebGLenum target,
+                         const Nullable<ArrayBuffer> &maybeData,
+                         WebGLenum usage)
+{
+    if (!IsContextStable())
+        return;
+
+    if (maybeData.IsNull()) {
+        // see http://www.khronos.org/bugzilla/show_bug.cgi?id=386
+        return ErrorInvalidValue("bufferData: null object passed");
+    }
+
+    WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferData");
+
+    if (!bufferSlot) {
+        return;
+    }
+
+    const ArrayBuffer& data = maybeData.Value();
+
+    if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
+        return;
+
+    WebGLBuffer* boundBuffer = bufferSlot->get();
+
+    if (!boundBuffer)
+        return ErrorInvalidOperation("bufferData: no buffer bound!");
+
+    MakeContextCurrent();
+    InvalidateBufferFetching();
+
+    GLenum error = CheckedBufferData(target, data.Length(), data.Data(), usage);
+
+    if (error) {
+        GenerateWarning("bufferData generated error %s", ErrorName(error));
+        return;
+    }
+
+    boundBuffer->SetByteLength(data.Length());
+    if (!boundBuffer->ElementArrayCacheBufferData(data.Data(), data.Length())) {
+        return ErrorOutOfMemory("bufferData: out of memory");
+    }
+}
+
+void
+WebGLContext::BufferData(WebGLenum target, const ArrayBufferView& data,
+                         WebGLenum usage)
+{
+    if (!IsContextStable())
+        return;
+
+    WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferSubData");
+
+    if (!bufferSlot) {
+        return;
+    }
+
+    if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
+        return;
+
+    WebGLBuffer* boundBuffer = bufferSlot->get();
+
+    if (!boundBuffer)
+        return ErrorInvalidOperation("bufferData: no buffer bound!");
+
+    InvalidateBufferFetching();
+    MakeContextCurrent();
+
+    GLenum error = CheckedBufferData(target, data.Length(), data.Data(), usage);
+    if (error) {
+        GenerateWarning("bufferData generated error %s", ErrorName(error));
+        return;
+    }
+
+    boundBuffer->SetByteLength(data.Length());
+    if (!boundBuffer->ElementArrayCacheBufferData(data.Data(), data.Length())) {
+        return ErrorOutOfMemory("bufferData: out of memory");
+    }
+}
+
+void
+WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
+                            const Nullable<ArrayBuffer> &maybeData)
+{
+    if (!IsContextStable())
+        return;
+
+    if (maybeData.IsNull()) {
+        // see http://www.khronos.org/bugzilla/show_bug.cgi?id=386
+        return;
+    }
+
+    WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferSubData");
+
+    if (!bufferSlot) {
+        return;
+    }
+
+    const ArrayBuffer& data = maybeData.Value();
+
+    if (byteOffset < 0)
+        return ErrorInvalidValue("bufferSubData: negative offset");
+
+    WebGLBuffer* boundBuffer = bufferSlot->get();
+
+    if (!boundBuffer)
+        return ErrorInvalidOperation("bufferData: no buffer bound!");
+
+    CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.Length();
+    if (!checked_neededByteLength.isValid())
+        return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length");
+
+    if (checked_neededByteLength.value() > boundBuffer->ByteLength())
+        return ErrorInvalidValue("bufferSubData: not enough data - operation requires %d bytes, but buffer only has %d bytes",
+                                 checked_neededByteLength.value(), boundBuffer->ByteLength());
+
+    MakeContextCurrent();
+
+    boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(), data.Length());
+
+    gl->fBufferSubData(target, byteOffset, data.Length(), data.Data());
+}
+
+void
+WebGLContext::BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
+                            const ArrayBufferView& data)
+{
+    if (!IsContextStable())
+        return;
+
+    WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferSubData");
+
+    if (!bufferSlot) {
+        return;
+    }
+
+    if (byteOffset < 0)
+        return ErrorInvalidValue("bufferSubData: negative offset");
+
+    WebGLBuffer* boundBuffer = bufferSlot->get();
+
+    if (!boundBuffer)
+        return ErrorInvalidOperation("bufferSubData: no buffer bound!");
+
+    CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.Length();
+    if (!checked_neededByteLength.isValid())
+        return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length");
+
+    if (checked_neededByteLength.value() > boundBuffer->ByteLength())
+        return ErrorInvalidValue("bufferSubData: not enough data -- operation requires %d bytes, but buffer only has %d bytes",
+                                 checked_neededByteLength.value(), boundBuffer->ByteLength());
+
+    boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(), data.Length());
+
+    MakeContextCurrent();
+    gl->fBufferSubData(target, byteOffset, data.Length(), data.Data());
+}
+
+already_AddRefed<WebGLBuffer>
+WebGLContext::CreateBuffer()
+{
+    if (!IsContextStable())
+        return nullptr;
+
+    nsRefPtr<WebGLBuffer> globj = new WebGLBuffer(this);
+    return globj.forget();
+}
+
+void
+WebGLContext::DeleteBuffer(WebGLBuffer *buffer)
+{
+    if (!IsContextStable())
+        return;
+
+    if (!ValidateObjectAllowDeletedOrNull("deleteBuffer", buffer))
+        return;
+
+    if (!buffer || buffer->IsDeleted())
+        return;
+
+    if (mBoundArrayBuffer == buffer) {
+        BindBuffer(LOCAL_GL_ARRAY_BUFFER,
+                   static_cast<WebGLBuffer*>(nullptr));
+    }
+
+    if (mBoundVertexArray->mBoundElementArrayBuffer == buffer) {
+        BindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER,
+                   static_cast<WebGLBuffer*>(nullptr));
+    }
+
+    for (int32_t i = 0; i < mGLMaxVertexAttribs; i++) {
+        if (mBoundVertexArray->mAttribBuffers[i].buf == buffer)
+            mBoundVertexArray->mAttribBuffers[i].buf = nullptr;
+    }
+
+    buffer->RequestDelete();
+}
+
+bool
+WebGLContext::IsBuffer(WebGLBuffer *buffer)
+{
+    if (!IsContextStable())
+        return false;
+
+    return ValidateObjectAllowDeleted("isBuffer", buffer) &&
+           !buffer->IsDeleted() &&
+           buffer->HasEverBeenBound();
+}
+
+bool
+WebGLContext::ValidateBufferUsageEnum(WebGLenum target, const char *infos)
+{
+    switch (target) {
+        case LOCAL_GL_STREAM_DRAW:
+        case LOCAL_GL_STATIC_DRAW:
+        case LOCAL_GL_DYNAMIC_DRAW:
+            return true;
+        default:
+            break;
+    }
+
+    ErrorInvalidEnumInfo(infos, target);
+    return false;
+}
+
+WebGLRefPtr<WebGLBuffer>*
+WebGLContext::GetBufferSlotByTarget(GLenum target, const char* infos)
+{
+    switch (target) {
+        case LOCAL_GL_ARRAY_BUFFER:
+            return &mBoundArrayBuffer;
+
+        case LOCAL_GL_ELEMENT_ARRAY_BUFFER:
+            return &mBoundVertexArray->mBoundElementArrayBuffer;
+
+        case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
+            if (!IsWebGL2()) {
+                break;
+            }
+            return &mBoundTransformFeedbackBuffer;
+
+        default:
+            break;
+    }
+
+    ErrorInvalidEnum("%s: target: invalid enum value 0x%x", infos, target);
+    return nullptr;
+}
+
+WebGLRefPtr<WebGLBuffer>*
+WebGLContext::GetBufferSlotByTargetIndexed(GLenum target, GLuint index, const char* infos)
+{
+    switch (target) {
+        case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER:
+            if (index >= mGLMaxTransformFeedbackSeparateAttribs) {
+                ErrorInvalidValue("%s: index should be less than MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", infos, index);
+                return nullptr;
+            }
+            return nullptr; // See bug 903594
+
+        default:
+            break;
+    }
+
+    ErrorInvalidEnum("%s: target: invalid enum value 0x%x", infos, target);
+    return nullptr;
+}
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -123,57 +123,16 @@ WebGLContext::BindAttribLocation(WebGLPr
     nsCString mappedName;
     prog->MapIdentifier(cname, &mappedName);
     
     MakeContextCurrent();
     gl->fBindAttribLocation(progname, location, mappedName.get());
 }
 
 void
-WebGLContext::BindBuffer(WebGLenum target, WebGLBuffer *buf)
-{
-    if (!IsContextStable())
-        return;
-
-    if (!ValidateObjectAllowDeletedOrNull("bindBuffer", buf))
-        return;
-
-    WebGLuint bufname = buf ? buf->GLName() : 0;
-
-    // silently ignore a deleted buffer
-    if (buf && buf->IsDeleted())
-        return;
-
-    if (target != LOCAL_GL_ARRAY_BUFFER &&
-        target != LOCAL_GL_ELEMENT_ARRAY_BUFFER)
-    {
-        return ErrorInvalidEnumInfo("bindBuffer: target", target);
-    }
-
-    if (buf) {
-        if ((buf->Target() != LOCAL_GL_NONE) && (target != buf->Target()))
-            return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target");
-        buf->SetTarget(target);
-        buf->SetHasEverBeenBound(true);
-    }
-
-    // we really want to do this AFTER all the validation is done, otherwise our bookkeeping could get confused.
-    // see bug 656752
-    if (target == LOCAL_GL_ARRAY_BUFFER) {
-        mBoundArrayBuffer = buf;
-    } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
-        mBoundVertexArray->mBoundElementArrayBuffer = buf;
-    }
-
-    MakeContextCurrent();
-
-    gl->fBindBuffer(target, bufname);
-}
-
-void
 WebGLContext::BindFramebuffer(WebGLenum target, WebGLFramebuffer *wfb)
 {
     if (!IsContextStable())
         return;
 
     if (target != LOCAL_GL_FRAMEBUFFER)
         return ErrorInvalidEnum("bindFramebuffer: target must be GL_FRAMEBUFFER");
 
@@ -347,230 +306,16 @@ GLenum WebGLContext::CheckedBufferData(G
         UpdateWebGLErrorAndClearGLError(&error);
         return error;
     } else {
         gl->fBufferData(target, size, data, usage);
         return LOCAL_GL_NO_ERROR;
     }
 }
 
-void
-WebGLContext::BufferData(WebGLenum target, WebGLsizeiptr size,
-                         WebGLenum usage)
-{
-    if (!IsContextStable())
-        return;
-
-    WebGLBuffer *boundBuffer = nullptr;
-
-    if (target == LOCAL_GL_ARRAY_BUFFER) {
-        boundBuffer = mBoundArrayBuffer;
-    } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
-        boundBuffer = mBoundVertexArray->mBoundElementArrayBuffer;
-    } else {
-        return ErrorInvalidEnumInfo("bufferData: target", target);
-    }
-
-    if (size < 0)
-        return ErrorInvalidValue("bufferData: negative size");
-
-    if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
-        return;
-
-    if (!boundBuffer)
-        return ErrorInvalidOperation("bufferData: no buffer bound!");
-
-    void* zeroBuffer = calloc(size, 1);
-    if (!zeroBuffer)
-        return ErrorOutOfMemory("bufferData: out of memory");
-
-    MakeContextCurrent();
-    InvalidateBufferFetching();
-
-    GLenum error = CheckedBufferData(target, size, zeroBuffer, usage);
-    free(zeroBuffer);
-
-    if (error) {
-        GenerateWarning("bufferData generated error %s", ErrorName(error));
-        return;
-    }
-
-    boundBuffer->SetByteLength(size);
-    if (!boundBuffer->ElementArrayCacheBufferData(nullptr, size)) {
-        return ErrorOutOfMemory("bufferData: out of memory");
-    }
-}
-
-void
-WebGLContext::BufferData(WebGLenum target,
-                         const Nullable<ArrayBuffer> &maybeData,
-                         WebGLenum usage)
-{
-    if (!IsContextStable())
-        return;
-
-    if (maybeData.IsNull()) {
-        // see http://www.khronos.org/bugzilla/show_bug.cgi?id=386
-        return ErrorInvalidValue("bufferData: null object passed");
-    }
-
-    const ArrayBuffer& data = maybeData.Value();
-
-    WebGLBuffer *boundBuffer = nullptr;
-
-    if (target == LOCAL_GL_ARRAY_BUFFER) {
-        boundBuffer = mBoundArrayBuffer;
-    } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
-        boundBuffer = mBoundVertexArray->mBoundElementArrayBuffer;
-    } else {
-        return ErrorInvalidEnumInfo("bufferData: target", target);
-    }
-
-    if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
-        return;
-
-    if (!boundBuffer)
-        return ErrorInvalidOperation("bufferData: no buffer bound!");
-
-    MakeContextCurrent();
-    InvalidateBufferFetching();
-
-    GLenum error = CheckedBufferData(target, data.Length(), data.Data(), usage);
-
-    if (error) {
-        GenerateWarning("bufferData generated error %s", ErrorName(error));
-        return;
-    }
-
-    boundBuffer->SetByteLength(data.Length());
-    if (!boundBuffer->ElementArrayCacheBufferData(data.Data(), data.Length())) {
-        return ErrorOutOfMemory("bufferData: out of memory");
-    }
-}
-
-void
-WebGLContext::BufferData(WebGLenum target, const ArrayBufferView& data,
-                         WebGLenum usage)
-{
-    if (!IsContextStable())
-        return;
-
-    WebGLBuffer *boundBuffer = nullptr;
-
-    if (target == LOCAL_GL_ARRAY_BUFFER) {
-        boundBuffer = mBoundArrayBuffer;
-    } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
-        boundBuffer = mBoundVertexArray->mBoundElementArrayBuffer;
-    } else {
-        return ErrorInvalidEnumInfo("bufferData: target", target);
-    }
-
-    if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
-        return;
-
-    if (!boundBuffer)
-        return ErrorInvalidOperation("bufferData: no buffer bound!");
-
-    InvalidateBufferFetching();
-    MakeContextCurrent();
-
-    GLenum error = CheckedBufferData(target, data.Length(), data.Data(), usage);
-    if (error) {
-        GenerateWarning("bufferData generated error %s", ErrorName(error));
-        return;
-    }
-
-    boundBuffer->SetByteLength(data.Length());
-    if (!boundBuffer->ElementArrayCacheBufferData(data.Data(), data.Length())) {
-        return ErrorOutOfMemory("bufferData: out of memory");
-    }
-}
-
-void
-WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
-                            const Nullable<ArrayBuffer> &maybeData)
-{
-    if (!IsContextStable())
-        return;
-
-    if (maybeData.IsNull()) {
-        // see http://www.khronos.org/bugzilla/show_bug.cgi?id=386
-        return;
-    }
-
-    const ArrayBuffer& data = maybeData.Value();
-
-    WebGLBuffer *boundBuffer = nullptr;
-
-    if (target == LOCAL_GL_ARRAY_BUFFER) {
-        boundBuffer = mBoundArrayBuffer;
-    } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
-        boundBuffer = mBoundVertexArray->mBoundElementArrayBuffer;
-    } else {
-        return ErrorInvalidEnumInfo("bufferSubData: target", target);
-    }
-
-    if (byteOffset < 0)
-        return ErrorInvalidValue("bufferSubData: negative offset");
-
-    if (!boundBuffer)
-        return ErrorInvalidOperation("bufferData: no buffer bound!");
-
-    CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.Length();
-    if (!checked_neededByteLength.isValid())
-        return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length");
-
-    if (checked_neededByteLength.value() > boundBuffer->ByteLength())
-        return ErrorInvalidValue("bufferSubData: not enough data - operation requires %d bytes, but buffer only has %d bytes",
-                                     checked_neededByteLength.value(), boundBuffer->ByteLength());
-
-    MakeContextCurrent();
-
-    boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(), data.Length());
-
-    gl->fBufferSubData(target, byteOffset, data.Length(), data.Data());
-}
-
-void
-WebGLContext::BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
-                            const ArrayBufferView& data)
-{
-    if (!IsContextStable())
-        return;
-
-    WebGLBuffer *boundBuffer = nullptr;
-
-    if (target == LOCAL_GL_ARRAY_BUFFER) {
-        boundBuffer = mBoundArrayBuffer;
-    } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
-        boundBuffer = mBoundVertexArray->mBoundElementArrayBuffer;
-    } else {
-        return ErrorInvalidEnumInfo("bufferSubData: target", target);
-    }
-
-    if (byteOffset < 0)
-        return ErrorInvalidValue("bufferSubData: negative offset");
-
-    if (!boundBuffer)
-        return ErrorInvalidOperation("bufferSubData: no buffer bound!");
-
-    CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.Length();
-    if (!checked_neededByteLength.isValid())
-        return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length");
-
-    if (checked_neededByteLength.value() > boundBuffer->ByteLength())
-        return ErrorInvalidValue("bufferSubData: not enough data -- operation requires %d bytes, but buffer only has %d bytes",
-                                     checked_neededByteLength.value(), boundBuffer->ByteLength());
-
-    boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(), data.Length());
-
-    MakeContextCurrent();
-    gl->fBufferSubData(target, byteOffset, data.Length(), data.Data());
-}
-
 WebGLenum
 WebGLContext::CheckFramebufferStatus(WebGLenum target)
 {
     if (!IsContextStable())
     {
         return LOCAL_GL_FRAMEBUFFER_UNSUPPORTED;
     }
 
@@ -940,44 +685,16 @@ WebGLContext::CullFace(WebGLenum face)
     if (!ValidateFaceEnum(face, "cullFace"))
         return;
 
     MakeContextCurrent();
     gl->fCullFace(face);
 }
 
 void
-WebGLContext::DeleteBuffer(WebGLBuffer *buf)
-{
-    if (!IsContextStable())
-        return;
-
-    if (!ValidateObjectAllowDeletedOrNull("deleteBuffer", buf))
-        return;
-
-    if (!buf || buf->IsDeleted())
-        return;
-
-    if (mBoundArrayBuffer == buf)
-        BindBuffer(LOCAL_GL_ARRAY_BUFFER,
-                   static_cast<WebGLBuffer*>(nullptr));
-
-    if (mBoundVertexArray->mBoundElementArrayBuffer == buf)
-        BindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER,
-                   static_cast<WebGLBuffer*>(nullptr));
-
-    for (int32_t i = 0; i < mGLMaxVertexAttribs; i++) {
-        if (mBoundVertexArray->mAttribBuffers[i].buf == buf)
-            mBoundVertexArray->mAttribBuffers[i].buf = nullptr;
-    }
-
-    buf->RequestDelete();
-}
-
-void
 WebGLContext::DeleteFramebuffer(WebGLFramebuffer* fbuf)
 {
     if (!IsContextStable())
         return;
 
     if (!ValidateObjectAllowDeletedOrNull("deleteFramebuffer", fbuf))
         return;
 
@@ -1726,25 +1443,16 @@ WebGLContext::GetRenderbufferParameter(W
         }
         default:
             ErrorInvalidEnumInfo("getRenderbufferParameter: parameter", pname);
     }
 
     return JS::NullValue();
 }
 
-already_AddRefed<WebGLBuffer>
-WebGLContext::CreateBuffer()
-{
-    if (!IsContextStable())
-        return nullptr;
-    nsRefPtr<WebGLBuffer> globj = new WebGLBuffer(this);
-    return globj.forget();
-}
-
 already_AddRefed<WebGLTexture>
 WebGLContext::CreateTexture()
 {
     if (!IsContextStable())
         return nullptr;
     nsRefPtr<WebGLTexture> globj = new WebGLTexture(this);
     return globj.forget();
 }
@@ -2201,27 +1909,16 @@ WebGLContext::Hint(WebGLenum target, Web
 
     if (!isValid)
         return ErrorInvalidEnum("hint: invalid hint");
 
     gl->fHint(target, mode);
 }
 
 bool
-WebGLContext::IsBuffer(WebGLBuffer *buffer)
-{
-    if (!IsContextStable())
-        return false;
-
-    return ValidateObjectAllowDeleted("isBuffer", buffer) &&
-        !buffer->IsDeleted() &&
-        buffer->HasEverBeenBound();
-}
-
-bool
 WebGLContext::IsFramebuffer(WebGLFramebuffer *fb)
 {
     if (!IsContextStable())
         return false;
 
     return ValidateObjectAllowDeleted("isFramebuffer", fb) &&
         !fb->IsDeleted() &&
         fb->HasEverBeenBound();
--- a/content/canvas/src/WebGLContextState.cpp
+++ b/content/canvas/src/WebGLContextState.cpp
@@ -297,16 +297,23 @@ WebGLContext::GetParameter(JSContext* cx
         {
             uint32_t length = mCompressedTextureFormats.Length();
             JSObject* obj = Uint32Array::Create(cx, this, length, mCompressedTextureFormats.Elements());
             if (!obj) {
                 rv = NS_ERROR_OUT_OF_MEMORY;
             }
             return JS::ObjectOrNullValue(obj);
         }
+        case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
+        {
+            if (!IsWebGL2()) {
+                break;
+            }
+            return JS::Int32Value(mGLMaxTransformFeedbackSeparateAttribs);
+        }
 
         // unsigned int. here we may have to return very large values like 2^32-1 that can't be represented as
         // javascript integer values. We just return them as doubles and javascript doesn't care.
         case LOCAL_GL_STENCIL_BACK_VALUE_MASK:
         case LOCAL_GL_STENCIL_BACK_WRITEMASK:
         case LOCAL_GL_STENCIL_VALUE_MASK:
         case LOCAL_GL_STENCIL_WRITEMASK:
         {
@@ -430,16 +437,24 @@ WebGLContext::GetParameter(JSContext* cx
             return JS::ObjectOrNullValue(obj);
         }
 
         case LOCAL_GL_ARRAY_BUFFER_BINDING:
         {
             return WebGLObjectAsJSValue(cx, mBoundArrayBuffer.get(), rv);
         }
 
+        case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+        {
+            if (!IsWebGL2()) {
+                break;
+            }
+            return WebGLObjectAsJSValue(cx, mBoundTransformFeedbackBuffer.get(), rv);
+        }
+
         case LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING:
         {
             return WebGLObjectAsJSValue(cx, mBoundVertexArray->mBoundElementArrayBuffer.get(), rv);
         }
 
         case LOCAL_GL_RENDERBUFFER_BINDING:
         {
             return WebGLObjectAsJSValue(cx, mBoundRenderbuffer.get(), rv);
@@ -467,16 +482,42 @@ WebGLContext::GetParameter(JSContext* cx
 
         default:
             ErrorInvalidEnumInfo("getParameter: parameter", pname);
     }
 
     return JS::NullValue();
 }
 
+JS::Value
+WebGLContext::GetParameterIndexed(JSContext* cx, WebGLenum pname, WebGLuint index)
+{
+    if (!IsContextStable())
+        return JS::NullValue();
+
+    MakeContextCurrent();
+
+    switch (pname) {
+        case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+        {
+            if (index >= mGLMaxTransformFeedbackSeparateAttribs) {
+                ErrorInvalidValue("getParameterIndexed: index should be less than MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", index);
+                return JS::NullValue();
+            }
+            return JS::NullValue(); // See bug 903594
+        }
+
+        default:
+            break;
+    }
+
+    ErrorInvalidEnumInfo("getParameterIndexed: parameter", pname);
+    return JS::NullValue();
+}
+
 bool
 WebGLContext::IsEnabled(WebGLenum cap)
 {
     if (!IsContextStable())
         return false;
 
     if (!ValidateCapabilityEnum(cap, "isEnabled"))
         return false;
--- a/content/canvas/src/WebGLContextValidate.cpp
+++ b/content/canvas/src/WebGLContextValidate.cpp
@@ -218,29 +218,16 @@ bool WebGLContext::ValidateFaceEnum(WebG
         case LOCAL_GL_FRONT_AND_BACK:
             return true;
         default:
             ErrorInvalidEnumInfo(info, face);
             return false;
     }
 }
 
-bool WebGLContext::ValidateBufferUsageEnum(WebGLenum target, const char *info)
-{
-    switch (target) {
-        case LOCAL_GL_STREAM_DRAW:
-        case LOCAL_GL_STATIC_DRAW:
-        case LOCAL_GL_DYNAMIC_DRAW:
-            return true;
-        default:
-            ErrorInvalidEnumInfo(info, target);
-            return false;
-    }
-}
-
 bool WebGLContext::ValidateDrawModeEnum(WebGLenum mode, const char *info)
 {
     switch (mode) {
         case LOCAL_GL_TRIANGLES:
         case LOCAL_GL_TRIANGLE_STRIP:
         case LOCAL_GL_TRIANGLE_FAN:
         case LOCAL_GL_POINTS:
         case LOCAL_GL_LINE_STRIP:
@@ -815,16 +802,17 @@ WebGLContext::InitAndValidateGL()
 
     mActiveTexture = 0;
     mWebGLError = LOCAL_GL_NO_ERROR;
 
     mBound2DTextures.Clear();
     mBoundCubeMapTextures.Clear();
 
     mBoundArrayBuffer = nullptr;
+    mBoundTransformFeedbackBuffer = nullptr;
     mCurrentProgram = nullptr;
 
     mBoundFramebuffer = nullptr;
     mBoundRenderbuffer = nullptr;
 
     MakeContextCurrent();
 
     // on desktop OpenGL, we always keep vertex attrib 0 array enabled
@@ -914,20 +902,24 @@ WebGLContext::InitAndValidateGL()
                     mGLMaxVaryingVectors = std::min(maxVertexOutputComponents, minFragmentInputComponents) / 4;
                     break;
                 case LOCAL_GL_INVALID_ENUM:
                     mGLMaxVaryingVectors = 16; // = 64/4, 64 is the min value for maxVertexOutputComponents in OpenGL 3.2 spec
                     break;
                 default:
                     GenerateWarning("GL error 0x%x occurred during WebGL context initialization!", error);
                     return false;
-            }   
+            }
         }
     }
 
+    if (IsWebGL2()) {
+        gl->GetUIntegerv(LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &mGLMaxTransformFeedbackSeparateAttribs);
+    }
+
     // Always 1 for GLES2
     mMaxFramebufferColorAttachments = 1;
 
     if (!gl->IsGLES2()) {
         // gl_PointSize is always available in ES2 GLSL, but has to be
         // specifically enabled on desktop GLSL.
         gl->fEnable(LOCAL_GL_VERTEX_PROGRAM_POINT_SIZE);
 
--- a/content/canvas/src/moz.build
+++ b/content/canvas/src/moz.build
@@ -27,16 +27,17 @@ CPP_SOURCES += [
 if CONFIG['MOZ_WEBGL']:
     CPP_SOURCES += [
         'WebGLActiveInfo.cpp',
         'WebGLBuffer.cpp',
         'WebGL1Context.cpp',
         'WebGL2Context.cpp',
         'WebGLContext.cpp',
         'WebGLContextAsyncQueries.cpp',
+        'WebGLContextBuffers.cpp',
         'WebGLContextGL.cpp',
         'WebGLContextUtils.cpp',
         'WebGLContextReporter.cpp',
         'WebGLContextState.cpp',
         'WebGLContextValidate.cpp',
         'WebGLContextFramebufferOperations.cpp',
         'WebGLContextVertexArray.cpp',
         'WebGLContextVertices.cpp',
--- a/content/media/TextTrack.cpp
+++ b/content/media/TextTrack.cpp
@@ -5,20 +5,21 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/TextTrack.h"
 #include "mozilla/dom/TextTrackBinding.h"
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_3(TextTrack,
-                                        mParent,
-                                        mCueList,
-                                        mActiveCueList)
+NS_IMPL_CYCLE_COLLECTION_INHERITED_3(TextTrack,
+                                     nsDOMEventTargetHelper,
+                                     mParent,
+                                     mCueList,
+                                     mActiveCueList)
 
 NS_IMPL_ADDREF_INHERITED(TextTrack, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(TextTrack, nsDOMEventTargetHelper)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TextTrack)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 TextTrack::TextTrack(nsISupports* aParent,
                      TextTrackKind aKind,
--- a/content/media/TextTrack.h
+++ b/content/media/TextTrack.h
@@ -21,18 +21,17 @@ namespace dom {
 
 class TextTrackCue;
 class TextTrackCueList;
 
 class TextTrack MOZ_FINAL : public nsDOMEventTargetHelper
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(TextTrack,
-                                                         nsDOMEventTargetHelper)
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TextTrack, nsDOMEventTargetHelper)
 
   TextTrack(nsISupports* aParent);
   TextTrack(nsISupports* aParent,
             TextTrackKind aKind,
             const nsAString& aLabel,
             const nsAString& aLanguage);
 
   virtual JSObject* WrapObject(JSContext* aCx,
--- a/content/media/TextTrackCue.cpp
+++ b/content/media/TextTrackCue.cpp
@@ -12,21 +12,22 @@
 #include "nsVideoFrame.h"
 
 // Alternate value for the 'auto' keyword.
 #define WEBVTT_AUTO -1
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_4(TextTrackCue,
-                                        mDocument,
-                                        mTrack,
-                                        mTrackElement,
-                                        mDisplayState)
+NS_IMPL_CYCLE_COLLECTION_INHERITED_4(TextTrackCue,
+                                     nsDOMEventTargetHelper,
+                                     mDocument,
+                                     mTrack,
+                                     mTrackElement,
+                                     mDisplayState)
 
 NS_IMPL_ADDREF_INHERITED(TextTrackCue, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(TextTrackCue, nsDOMEventTargetHelper)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TextTrackCue)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 // Set cue setting defaults based on step 19 & seq.
 // in http://dev.w3.org/html5/webvtt/#parsing
--- a/content/media/TextTrackCue.h
+++ b/content/media/TextTrackCue.h
@@ -21,18 +21,17 @@ namespace dom {
 
 class HTMLTrackElement;
 class TextTrack;
 
 class TextTrackCue MOZ_FINAL : public nsDOMEventTargetHelper
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(TextTrackCue,
-                                                         nsDOMEventTargetHelper)
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TextTrackCue, nsDOMEventTargetHelper)
 
   // TextTrackCue WebIDL
   // See bug 868509 about splitting out the WebVTT-specific interfaces.
   static already_AddRefed<TextTrackCue>
   Constructor(GlobalObject& aGlobal,
               double aStartTime,
               double aEndTime,
               const nsAString& aText,
--- a/content/media/TextTrackList.cpp
+++ b/content/media/TextTrackList.cpp
@@ -4,17 +4,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/TextTrackList.h"
 #include "mozilla/dom/TextTrackListBinding.h"
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(TextTrackList, mGlobal, mTextTracks)
+NS_IMPL_CYCLE_COLLECTION_INHERITED_2(TextTrackList,
+                                     nsDOMEventTargetHelper,
+                                     mGlobal,
+                                     mTextTracks)
 
 NS_IMPL_ADDREF_INHERITED(TextTrackList, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(TextTrackList, nsDOMEventTargetHelper)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TextTrackList)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 TextTrackList::TextTrackList(nsISupports* aGlobal) : mGlobal(aGlobal)
 {
--- a/content/media/TextTrackList.h
+++ b/content/media/TextTrackList.h
@@ -15,18 +15,17 @@ namespace mozilla {
 namespace dom {
 
 class TextTrack;
 
 class TextTrackList MOZ_FINAL : public nsDOMEventTargetHelper
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(TextTrackList,
-                                                         nsDOMEventTargetHelper)
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TextTrackList, nsDOMEventTargetHelper)
 
   TextTrackList(nsISupports* aGlobal);
 
   virtual JSObject* WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   nsISupports* GetParentObject() const
   {
--- a/content/media/moz.build
+++ b/content/media/moz.build
@@ -38,18 +38,17 @@ if CONFIG['MOZ_WMF']:
     PARALLEL_DIRS += ['wmf']
 
 PARALLEL_DIRS += ['webrtc']
 
 if CONFIG['MOZ_OMX_DECODER']:
     PARALLEL_DIRS += ['omx']
     PARALLEL_DIRS += ['omx/mediaresourcemanager']
 
-if CONFIG['MOZ_WEBSPEECH']:
-    PARALLEL_DIRS += ['webspeech']
+PARALLEL_DIRS += ['webspeech']
 
 TEST_DIRS += ['test']
 
 MODULE = 'content'
 
 EXPORTS += [
     'AbstractMediaDecoder.h',
     'AudioAvailableEventManager.h',
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -140,16 +140,17 @@ MOCHITEST_FILES = \
 		test_texttrack.html \
 		test_texttrackcue.html \
 		test_timeupdate_small_files.html \
 		test_unseekable.html \
 		test_VideoPlaybackQuality.html \
 		test_VideoPlaybackQuality_disabled.html \
 		test_webvtt_disabled.html \
 		test_playback_rate_playpause.html \
+		test_bug895305.html \
 		$(NULL)
 
 # Disabled on Windows for frequent intermittent failures
 ifneq ($(OS_ARCH), WINNT)
 MOCHITEST_FILES += \
 		test_streams_element_capture.html \
 		test_streams_element_capture_reset.html \
 		test_streams_element_capture_createObjectURL.html \
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_bug895305.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=895305
+https://bugzilla.mozilla.org/show_bug.cgi?id=905320
+-->
+<head>
+  <meta charset='utf-8'>
+  <title>Regression test for bug 895305 and 905320 - TextTrack* leaks</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true]]},
+  function() {
+    var audio = document.createElement("audio");
+    // Check leaking on TextTrackList objects.
+    window.ttl = audio.textTracks;
+    ttl.addEventListener("click", function(){}, false);
+
+    // Check leaking on TextTrackCue objects.
+    window.ttc = new TextTrackCue(3, 4, "Test.");
+    ttc.addEventListener("click", function() {}, false);
+
+    // Check leaking on TextTrack objects.
+    audio.addTextTrack("subtitles", "label", "en-CA");
+    ttl[0].addEventListener("click", function() {}, false);
+
+    ok(true); // Need to have at least one assertion for Mochitest to be happy.
+    SimpleTest.finish();
+  }
+);
+</script>
+</pre>
+</body>
+</html>
--- a/content/media/webspeech/moz.build
+++ b/content/media/webspeech/moz.build
@@ -1,6 +1,9 @@
 # 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/.
 
-PARALLEL_DIRS = ['recognition', 'synth']
+PARALLEL_DIRS = ['synth']
+
+if CONFIG['MOZ_WEBSPEECH']:
+    PARALLEL_DIRS += ['recognition']
--- a/content/media/webspeech/synth/moz.build
+++ b/content/media/webspeech/synth/moz.build
@@ -1,43 +1,44 @@
 # 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/.
 
-MODULE = 'content'
+if CONFIG['MOZ_WEBSPEECH']:
+    MODULE = 'content'
 
-TEST_DIRS += ['test', 'ipc/test']
+    TEST_DIRS += ['test', 'ipc/test']
 
-XPIDL_MODULE = 'dom_webspeechsynth'
+    XPIDL_MODULE = 'dom_webspeechsynth'
 
-XPIDL_SOURCES += [
-    'nsIDOMSpeechSynthesisEvent.idl',
-    'nsISpeechService.idl',
-    'nsISynthVoiceRegistry.idl'
+    XPIDL_SOURCES += [
+        'nsIDOMSpeechSynthesisEvent.idl',
+        'nsISpeechService.idl',
+        'nsISynthVoiceRegistry.idl'
     ]
 
-EXPORTS.mozilla.dom += [
-    'EnableSpeechSynthesisCheck.h',
-    'SpeechSynthesis.h',
-    'SpeechSynthesisUtterance.h',
-    'SpeechSynthesisVoice.h',
-    'ipc/SpeechSynthesisChild.h',
-    'ipc/SpeechSynthesisParent.h',
-    'nsSpeechTask.h',
-    'nsSynthVoiceRegistry.h',
-]
+    EXPORTS.mozilla.dom += [
+        'EnableSpeechSynthesisCheck.h',
+        'SpeechSynthesis.h',
+        'SpeechSynthesisUtterance.h',
+        'SpeechSynthesisVoice.h',
+        'ipc/SpeechSynthesisChild.h',
+        'ipc/SpeechSynthesisParent.h',
+        'nsSpeechTask.h',
+        'nsSynthVoiceRegistry.h',
+    ]
 
-CPP_SOURCES += [
-    'EnableSpeechSynthesisCheck.cpp',
-    'SpeechSynthesis.cpp',
-    'SpeechSynthesisChild.cpp',
-    'SpeechSynthesisParent.cpp',
-    'SpeechSynthesisUtterance.cpp',
-    'SpeechSynthesisVoice.cpp',
-    'nsSpeechTask.cpp',
-    'nsSynthVoiceRegistry.cpp',
-]
+    CPP_SOURCES += [
+        'EnableSpeechSynthesisCheck.cpp',
+        'SpeechSynthesis.cpp',
+        'SpeechSynthesisChild.cpp',
+        'SpeechSynthesisParent.cpp',
+        'SpeechSynthesisUtterance.cpp',
+        'SpeechSynthesisVoice.cpp',
+        'nsSpeechTask.cpp',
+        'nsSynthVoiceRegistry.cpp',
+    ]
 
 IPDL_SOURCES += [
     'ipc/PSpeechSynthesis.ipdl',
     'ipc/PSpeechSynthesisRequest.ipdl',
 ]
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -31,16 +31,17 @@
 #include "nsViewManager.h"
 #include "nsFrameSelection.h"
 #include "mozilla/Selection.h"
 #include "nsXULPopupManager.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIPrincipal.h"
 #include "nsIObserverService.h"
 #include "nsIObjectFrame.h"
+#include "nsBindingManager.h"
 
 #include "mozilla/dom/Element.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/Preferences.h"
 #include <algorithm>
 
 #ifdef MOZ_XUL
 #include "nsIDOMXULTextboxElement.h"
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -608,9 +608,52 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperC
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field7)                  \
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field8)                  \
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field9)                  \
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field10)                 \
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS            \
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END                         \
   NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
 
+#define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_11(_class,        \
+                                                 _field1,       \
+                                                 _field2,       \
+                                                 _field3,       \
+                                                 _field4,       \
+                                                 _field5,       \
+                                                 _field6,       \
+                                                 _field7,       \
+                                                 _field8,       \
+                                                 _field9,       \
+                                                 _field10,      \
+                                                 _field11)      \
+  NS_IMPL_CYCLE_COLLECTION_CLASS(_class)                        \
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class)                 \
+    NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1)                    \
+    NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2)                    \
+    NS_IMPL_CYCLE_COLLECTION_UNLINK(_field3)                    \
+    NS_IMPL_CYCLE_COLLECTION_UNLINK(_field4)                    \
+    NS_IMPL_CYCLE_COLLECTION_UNLINK(_field5)                    \
+    NS_IMPL_CYCLE_COLLECTION_UNLINK(_field6)                    \
+    NS_IMPL_CYCLE_COLLECTION_UNLINK(_field7)                    \
+    NS_IMPL_CYCLE_COLLECTION_UNLINK(_field8)                    \
+    NS_IMPL_CYCLE_COLLECTION_UNLINK(_field9)                    \
+    NS_IMPL_CYCLE_COLLECTION_UNLINK(_field10)                   \
+    NS_IMPL_CYCLE_COLLECTION_UNLINK(_field11)                   \
+    NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER           \
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_END                           \
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class)               \
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1)                  \
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2)                  \
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field3)                  \
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field4)                  \
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field5)                  \
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field6)                  \
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field7)                  \
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field8)                  \
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field9)                  \
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field10)                 \
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field11)                 \
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS            \
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END                         \
+  NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
+
 #endif /* nsWrapperCache_h___ */
--- a/dom/indexedDB/ipc/IndexedDBParent.cpp
+++ b/dom/indexedDB/ipc/IndexedDBParent.cpp
@@ -77,17 +77,19 @@ IndexedDBParent::IndexedDBParent(TabPare
 IndexedDBParent::~IndexedDBParent()
 {
   MOZ_COUNT_DTOR(IndexedDBParent);
 }
 
 void
 IndexedDBParent::Disconnect()
 {
-  MOZ_ASSERT(!mDisconnected);
+  if (mDisconnected) {
+    return;
+  }
 
   mDisconnected = true;
 
   const InfallibleTArray<PIndexedDBDatabaseParent*>& databases =
     ManagedPIndexedDBDatabaseParent();
   for (uint32_t i = 0; i < databases.Length(); ++i) {
     static_cast<IndexedDBDatabaseParent*>(databases[i])->Disconnect();
   }
--- a/dom/locales/en-US/chrome/layout/HtmlForm.properties
+++ b/dom/locales/en-US/chrome/layout/HtmlForm.properties
@@ -23,13 +23,16 @@ NoFileSelected=No file selected.
 # LOCALIZATION NOTE (NoFilesSelected): this string is shown on a
 # <input type='file' multiple> when there is no file selected yet.
 NoFilesSelected=No files selected.
 # LOCALIZATION NOTE (XFilesSelected): this string is shown on a
 # <input type='file' multiple> when there are more than one selected file.
 # %S will be a number greater or equal to 2.
 XFilesSelected=%S files selected.
 ColorPicker=Choose a color
-# LOCALIZATION NOTE (AndXMoreFiles): this string is shown at the end of the
-# tooltip text for <input type='file' multiple> when there are more than 21
-# files selected (when we will only list the first 20, plus an "and X more"
-# line). %S will be the number of files minus 20. 
-AndXMoreFiles=and %S more
+# LOCALIZATION NOTE (AndNMoreFiles): Semi-colon list of plural forms. 
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals 
+# This string is shown at the end of the tooltip text for <input type='file'
+# multiple> when there are more than 21 files selected (when we will only list
+# the first 20, plus an "and X more" line). #1 represents the number of files
+# minus 20 and will always be a number equal to or greater than 2. So the
+# singular case will never be used.
+AndNMoreFiles=and one more;and #1 more
--- a/dom/mobilemessage/src/gonk/MmsService.js
+++ b/dom/mobilemessage/src/gonk/MmsService.js
@@ -2013,19 +2013,29 @@ MmsService.prototype = {
       };
       // Update the delivery status to pending in DB.
       gMobileMessageDatabaseService
         .setMessageDeliveryByMessageId(aMessageId,
                                        null,
                                        null,
                                        DELIVERY_STATUS_PENDING,
                                        null,
-                                       this.retrieveMessage(url,
-                                                            responseNotify.bind(this),
-                                                            aDomMessage));
+                                       (function (rv) {
+          let success = Components.isSuccessCode(rv);
+          if (!success) {
+            if (DEBUG) debug("Could not change the delivery status: MMS " +
+                             domMessage.id + ", error code " + rv);
+            aRequest.notifyGetMessageFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
+            return;
+          }
+
+          this.retrieveMessage(url,
+                               responseNotify.bind(this),
+                               aDomMessage);
+        }).bind(this));
     }).bind(this));
   },
 
   // nsIWapPushApplication
 
   receiveWapPush: function receiveWapPush(array, length, offset, options) {
     let data = {array: array, offset: offset};
     let msg = MMS.PduHelper.parse(data, null);
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -52,16 +52,17 @@ using mozilla::DefaultXDisplay;
 #include "nsIObjectLoadingContent.h"
 #include "nsAttrName.h"
 #include "nsIFocusManager.h"
 #include "nsFocusManager.h"
 #include "nsIDOMDragEvent.h"
 #include "nsIScrollableFrame.h"
 #include "nsIDocShell.h"
 #include "ImageContainer.h"
+#include "nsIDOMHTMLCollection.h"
 
 #include "nsContentCID.h"
 #include "nsWidgetsCID.h"
 static NS_DEFINE_CID(kWidgetCID, NS_CHILD_CID);
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 #ifdef XP_WIN
 #include <wtypes.h>
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -3227,16 +3227,18 @@ RadioInterface.prototype = {
     this.workerMessenger.send("deactivateDataCall", { cid: cid,
                                                       reason: reason });
   },
 };
 
 function RILNetworkInterface(radioInterface, apnSetting) {
   this.radioInterface = radioInterface;
   this.apnSetting = apnSetting;
+
+  this.connectedTypes = [];
 }
 
 RILNetworkInterface.prototype = {
   classID:   RILNETWORKINTERFACE_CID,
   classInfo: XPCOMUtils.generateCI({classID: RILNETWORKINTERFACE_CID,
                                     classDescription: "RILNetworkInterface",
                                     interfaces: [Ci.nsINetworkInterface,
                                                  Ci.nsIRILDataCallback]}),
@@ -3397,22 +3399,22 @@ RILNetworkInterface.prototype = {
   },
 
   // Helpers
 
   cid: null,
   registeredAsDataCallCallback: false,
   registeredAsNetworkInterface: false,
   connecting: false,
-  apnSetting: {},
+  apnSetting: null,
 
   // APN failed connections. Retry counter
   apnRetryCounter: 0,
 
-  connectedTypes: [],
+  connectedTypes: null,
 
   inConnectedTypes: function inConnectedTypes(type) {
     return this.connectedTypes.indexOf(type) != -1;
   },
 
   get connected() {
     return this.state == RIL.GECKO_NETWORK_STATE_CONNECTED;
   },
--- a/dom/webidl/WebGL2RenderingContext.webidl
+++ b/dom/webidl/WebGL2RenderingContext.webidl
@@ -65,17 +65,30 @@ interface WebGL2RenderingContext : WebGL
     const GLenum QUERY_RESULT_AVAILABLE      = 0x8867;
 
     /* instanced array */
     const GLenum VERTEX_ATTRIB_ARRAY_DIVISOR = 0x88FE;
 
     void vertexAttribDivisor(GLuint index, GLuint divisor);
 
     /* transform feedback */
-    const GLenum RASTERIZER_DISCARD          = 0x8C89;
+    const GLenum RASTERIZER_DISCARD                      = 0x8C89;
+    const GLenum TRANSFORM_FEEDBACK_BUFFER               = 0x8C8E;
+    const GLenum TRANSFORM_FEEDBACK_BUFFER_BINDING       = 0x8C8F;
+    const GLenum TRANSFORM_FEEDBACK_BUFFER_START         = 0x8C84;
+    const GLenum TRANSFORM_FEEDBACK_BUFFER_SIZE          = 0x8C85;
+    const GLenum MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8C8B;
+
+    /* buffer objects */
+    void bindBufferBase(GLenum target, GLuint index, WebGLBuffer? buffer);
+    void bindBufferRange(GLenum target, GLuint index, WebGLBuffer? buffer,
+                         GLintptr offset, GLsizeiptr size);
+
+    /* state requests */
+    any getParameterIndexed(GLenum pname, GLuint index);
 
 
     void beginQuery(GLenum target, WebGLQuery? queryObject);
     void bindVertexArray(WebGLVertexArray? arrayObject);
     WebGLQuery? createQuery();
     WebGLVertexArray? createVertexArray();
     void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
     void drawBuffers(sequence<GLenum> buffers);
--- a/dom/wifi/WifiWorker.js
+++ b/dom/wifi/WifiWorker.js
@@ -159,17 +159,21 @@ var WifiManager = (function() {
   function voidControlMessage(cmd, callback) {
     controlMessage({ cmd: cmd }, function (data) {
       callback(data.status);
     });
   }
 
   var driverLoaded = false;
 
-  manager.getDriverLoaded = function() { return driverLoaded; }
+  manager.checkDriverState = function(expectState) {
+    if (!unloadDriverEnabled)
+      return true;
+    return (expectState === driverLoaded);
+  }
 
   function loadDriver(callback) {
     if (driverLoaded) {
       callback(0);
       return;
     }
 
     voidControlMessage("load_driver", function(status) {
@@ -2838,59 +2842,59 @@ WifiWorker.prototype = {
   },
 
   _notifyAfterStateChange: function(success, newState) {
     if (!this._stateRequests.length)
       return;
 
     // First, notify all of the requests that were trying to make this change.
     let state = this._stateRequests[0].enabled;
-    let driverLoaded = WifiManager.getDriverLoaded();
+    let driverReady = WifiManager.checkDriverState(newState);
 
     // It is callback function's responsibility to handle the pending request.
     // So we just return here.
     if (this._stateRequests.length > 0
         && ("callback" in this._stateRequests[0])) {
       return;
     }
 
     // If the new state is not the same as state or new state is not the same as
     // driver loaded state, then we weren't processing the first request (we
     // were racing somehow) so don't notify.
     // For newState is false(disable), we expect driverLoaded is false(driver unloaded)
     // to proceed, and vice versa.
-    if (!success || (newState === driverLoaded && state === newState)) {
+    if (!success || (driverReady && state === newState)) {
       do {
         if (!("callback" in this._stateRequests[0])) {
           this._stateRequests.shift();
         }
         // Don't remove more than one request if the previous one failed.
       } while (success &&
                this._stateRequests.length &&
                !("callback" in this._stateRequests[0]) &&
                this._stateRequests[0].enabled === state);
     }
     // If there were requests queued after this one, run them.
     if (this._stateRequests.length > 0) {
       let self = this;
       let callback = null;
       this._callbackTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-      if (newState === driverLoaded) {
-        // Driver status is as same as new state, proceed next request.
+      if (driverReady) {
+        // Driver is ready for next request.
         callback = function(timer) {
           if ("callback" in self._stateRequests[0]) {
             self._stateRequests[0].callback.call(self, self._stateRequests[0].enabled);
           } else {
             WifiManager.setWifiEnabled(self._stateRequests[0].enabled,
                                        self._setWifiEnabledCallback.bind(self));
           }
           timer = null;
         };
       } else {
-        // Driver status is not as same as new state, wait driver.
+        // Wait driver until it's ready.
         callback = function(timer) {
           self._notifyAfterStateChange(success, newState);
           timer = null;
         };
       }
       this._callbackTimer.initWithCallback(callback, 1000, Ci.nsITimer.TYPE_ONE_SHOT);
     }
   },
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -649,16 +649,105 @@ GLContext::InitWithPrefix(const char *pr
             if (!LoadSymbols(instancedArraySymbols, trygl, prefix)) {
                 NS_ERROR("GL supports array instanced without supplying it function.");
 
                 mInitialized &= MarkExtensionGroupUnsupported(XXX_instanced_arrays);
                 mSymbols.fVertexAttribDivisor = nullptr;
             }
         }
 
+        if (IsExtensionSupported(XXX_transform_feedback)) {
+            SymLoadStruct transformFeedbackSymbols[] = {
+                { (PRFuncPtr*) &mSymbols.fBindBufferBase,
+                  { "BindBufferBase",
+                    "BindBufferBaseEXT",
+                    "BindBufferBaseNV",
+                    nullptr
+                  }
+                },
+                { (PRFuncPtr*) &mSymbols.fBindBufferRange,
+                  { "BindBufferRange",
+                    "BindBufferRangeEXT",
+                    "BindBufferRangeNV",
+                    nullptr
+                  }
+                },
+                { (PRFuncPtr*) &mSymbols.fBeginTransformFeedback,
+                  { "BeginTransformFeedback",
+                    "BeginTransformFeedbackEXT",
+                    "BeginTransformFeedbackNV",
+                    nullptr
+                  }
+                },
+                { (PRFuncPtr*) &mSymbols.fEndTransformFeedback,
+                  { "EndTransformFeedback",
+                    "EndTransformFeedbackEXT",
+                    "EndTransformFeedbackNV",
+                    nullptr
+                  }
+                },
+                { (PRFuncPtr*) &mSymbols.fTransformFeedbackVaryings,
+                  { "TransformFeedbackVaryings",
+                    "TransformFeedbackVaryingsEXT",
+                    "TransformFeedbackVaryingsNV",
+                    nullptr
+                  }
+                },
+                { (PRFuncPtr*) &mSymbols.fGetTransformFeedbackVarying,
+                  { "GetTransformFeedbackVarying",
+                    "GetTransformFeedbackVaryingEXT",
+                    "GetTransformFeedbackVaryingNV",
+                    nullptr
+                  }
+                },
+                { (PRFuncPtr*) &mSymbols.fGetIntegeri_v,
+                  { "GetIntegeri_v",
+                    "GetIntegerIndexedvEXT",
+                    "GetIntegerIndexedvNV",
+                    nullptr
+                  }
+                },
+                { nullptr, { nullptr } },
+            };
+
+            if (!LoadSymbols(transformFeedbackSymbols, trygl, prefix)) {
+                NS_ERROR("GL supports transform feedback without supplying its functions.");
+
+                MarkExtensionGroupUnsupported(XXX_transform_feedback);
+                MarkExtensionGroupUnsupported(XXX_bind_buffer_offset);
+                mSymbols.fBindBufferBase = nullptr;
+                mSymbols.fBindBufferRange = nullptr;
+                mSymbols.fBeginTransformFeedback = nullptr;
+                mSymbols.fEndTransformFeedback = nullptr;
+                mSymbols.fTransformFeedbackVaryings = nullptr;
+                mSymbols.fGetTransformFeedbackVarying = nullptr;
+                mSymbols.fGetIntegeri_v = nullptr;
+            }
+        }
+
+        if (IsExtensionSupported(XXX_bind_buffer_offset)) {
+            SymLoadStruct bindBufferOffsetSymbols[] = {
+                { (PRFuncPtr*) &mSymbols.fBindBufferOffset,
+                  { "BindBufferOffset",
+                    "BindBufferOffsetEXT",
+                    "BindBufferOffsetNV",
+                    nullptr
+                  }
+                },
+                { nullptr, { nullptr } },
+            };
+
+            if (!LoadSymbols(bindBufferOffsetSymbols, trygl, prefix)) {
+                NS_ERROR("GL supports BindBufferOffset without supplying its function.");
+
+                MarkExtensionGroupUnsupported(XXX_bind_buffer_offset);
+                mSymbols.fBindBufferOffset = nullptr;
+            }
+        }
+
         if (IsExtensionSupported(XXX_query_objects)) {
             SymLoadStruct queryObjectsSymbols[] = {
                 { (PRFuncPtr*) &mSymbols.fBeginQuery, { "BeginQuery", "BeginQueryEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fGenQueries, { "GenQueries", "GenQueriesEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fDeleteQueries, { "DeleteQueries", "DeleteQueriesEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fEndQuery, { "EndQuery", "EndQueryEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fGetQueryiv, { "GetQueryiv", "GetQueryivEXT", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fGetQueryObjectuiv, { "GetQueryObjectuiv", "GetQueryObjectuivEXT", nullptr } },
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -469,16 +469,17 @@ protected:
  * regardless if it is an ARB, EXT, OES, etc.
  */
 public:
 
     /**
      * This enum should be sorted by name.
      */
     enum GLExtensionGroup {
+        XXX_bind_buffer_offset,
         XXX_depth_texture,
         XXX_draw_buffers,
         XXX_draw_instanced,
         XXX_element_index_uint,
         XXX_ES2_compatibility,
         XXX_ES3_compatibility,
         XXX_framebuffer_blit,
         XXX_framebuffer_multisample,
@@ -2030,16 +2031,28 @@ public:
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fEGLImageTargetRenderbufferStorage);
         mSymbols.fEGLImageTargetRenderbufferStorage(target, image);
         AFTER_GL_CALL;
     }
 
 
 // -----------------------------------------------------------------------------
+// Package XXX_bind_buffer_offset
+public:
+    void fBindBufferOffset(GLenum target, GLuint index, GLuint buffer, GLintptr offset)
+    {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fBindBufferOffset);
+        mSymbols.fBindBufferOffset(target, index, buffer, offset);
+        AFTER_GL_CALL;
+    }
+
+
+// -----------------------------------------------------------------------------
 // Package XXX_draw_buffers
 public:
     void fDrawBuffers(GLsizei n, const GLenum* bufs) {
         BEFORE_GL_CALL;
         mSymbols.fDrawBuffers(n, bufs);
         AFTER_GL_CALL;
     }
 
@@ -2183,16 +2196,76 @@ public:
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fGetQueryObjectiv);
         mSymbols.fGetQueryObjectiv(id, pname, params);
         AFTER_GL_CALL;
     }
 
 
 // -----------------------------------------------------------------------------
+// Package XXX_transform_feedback
+public:
+    void fBindBufferBase(GLenum target, GLuint index, GLuint buffer)
+    {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fBindBufferBase);
+        mSymbols.fBindBufferBase(target, index, buffer);
+        AFTER_GL_CALL;
+    }
+
+    void fBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
+    {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fBindBufferRange);
+        mSymbols.fBindBufferRange(target, index, buffer, offset, size);
+        AFTER_GL_CALL;
+    }
+
+    void fBeginTransformFeedback(GLenum primitiveMode)
+    {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fBeginTransformFeedback);
+        mSymbols.fBeginTransformFeedback(primitiveMode);
+        AFTER_GL_CALL;
+    }
+
+    void fEndTransformFeedback()
+    {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fEndTransformFeedback);
+        mSymbols.fEndTransformFeedback();
+        AFTER_GL_CALL;
+    }
+
+    void fTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode)
+    {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fTransformFeedbackVaryings);
+        mSymbols.fTransformFeedbackVaryings(program, count, varyings, bufferMode);
+        AFTER_GL_CALL;
+    }
+
+    void fGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
+    {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fGetTransformFeedbackVarying);
+        mSymbols.fGetTransformFeedbackVarying(program, index, bufSize, length, size, type, name);
+        AFTER_GL_CALL;
+    }
+
+    void fGetIntegeri_v(GLenum param, GLuint index, GLint* values)
+    {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fGetIntegeri_v);
+        mSymbols.fGetIntegeri_v(param, index, values);
+        AFTER_GL_CALL;
+    }
+
+
+// -----------------------------------------------------------------------------
 // Package XXX_vertex_array_object
 public:
     void GLAPIENTRY fBindVertexArray(GLuint array)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fBindVertexArray);
         mSymbols.fBindVertexArray(array);
         AFTER_GL_CALL;
--- a/gfx/gl/GLContextExtensionGroupQueries.cpp
+++ b/gfx/gl/GLContextExtensionGroupQueries.cpp
@@ -23,16 +23,26 @@ struct ExtensionGroupInfo
     const char* mName;
     unsigned int mOpenGLVersion;
     unsigned int mOpenGLESVersion;
     GLContext::GLExtensions mExtensions[kMAX_EXTENSION_GROUP_SIZE];
 };
 
 static const ExtensionGroupInfo sExtensionGroupInfoArr[] = {
     {
+        "XXX_bind_buffer_offset",
+        0,   // OpenGL version
+        0,   // OpenGL ES version
+        {
+            GLContext::EXT_transform_feedback,
+            GLContext::NV_transform_feedback,
+            GLContext::Extensions_End
+        }
+    },
+    {
         "XXX_depth_texture",
         200, // OpenGL version
         300, // OpenGL ES version
         {
             GLContext::ARB_depth_texture,
             GLContext::OES_depth_texture,
             GLContext::Extensions_End
         }
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -258,16 +258,17 @@ GLXLibrary::EnsureInitialized(LibType li
     }
 
     if (HasExtension(extensionsStr, "GLX_ARB_create_context_robustness") &&
         GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_robustness)) {
         mHasRobustness = true;
     }
 
     mIsATI = serverVendor && DoesStringMatch(serverVendor, "ATI");
+    mIsNVIDIA = serverVendor && DoesStringMatch(serverVendor, "NVIDIA Corporation");
     mClientIsMesa = clientVendor && DoesStringMatch(clientVendor, "Mesa");
 
     mInitialized = true;
     mLibType = libType;
 
     return true;
 }
 
@@ -362,17 +363,20 @@ GLXLibrary::CreatePixmap(gfxASurface* aS
         // Usually GLX counts only color bits in the Visual depth, but the
         // depth of Composite's ARGB Visual includes alpha bits.  However,
         // bits not in the color masks are not necessarily alpha bits because
         // sometimes (NVIDIA) 32 bit Visuals are added for fbconfigs with 32
         // bit BUFFER_SIZE but zero alpha bits and 24 color bits (NVIDIA
         // again).
         //
         // This checks that the depth matches in one of the two ways.
-        if (depth != format->depth && depth != format->depth - alphaSize) {
+        // NVIDIA now forces format->depth == depth so only the first way
+        // is checked for NVIDIA
+        if (depth != format->depth &&
+            (mIsNVIDIA || depth != format->depth - alphaSize) ) {
             continue;
         }
 
         // If all bits of the Pixmap are color bits and the Pixmap depth
         // matches the depth of the fbconfig visual, then we can assume that
         // the driver will do whatever is necessary to ensure that any
         // GLXPixmap alpha bits are treated as set.  We can skip the
         // ALPHA_SIZE check in this situation.  We need to skip this check for
--- a/gfx/gl/GLContextSymbols.h
+++ b/gfx/gl/GLContextSymbols.h
@@ -414,14 +414,37 @@ struct GLContextSymbols
     typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCED) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
     PFNGLDRAWARRAYSINSTANCED fDrawArraysInstanced;
     typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCED) (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount);
     PFNGLDRAWELEMENTSINSTANCED fDrawElementsInstanced;
 
     // ARB_instanced_array
     typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISOR) (GLuint index, GLuint divisor);
     PFNGLVERTEXATTRIBDIVISOR fVertexAttribDivisor;
+
+    // EXT_transform_feedback / OpenGL (ES) 3.0
+    typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASE) (GLenum target, GLuint index, GLuint buffer);
+    PFNGLBINDBUFFERBASE fBindBufferBase;
+    typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGE) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+    PFNGLBINDBUFFERRANGE fBindBufferRange;
+
+    typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACK) (GLenum primitiveMode);
+    PFNGLBEGINTRANSFORMFEEDBACK fBeginTransformFeedback;
+    typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACK) (void);
+    PFNGLENDTRANSFORMFEEDBACK fEndTransformFeedback;
+
+    typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGS) (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode);
+    PFNGLTRANSFORMFEEDBACKVARYINGS fTransformFeedbackVaryings;
+    typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYING) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name);
+    PFNGLGETTRANSFORMFEEDBACKVARYING fGetTransformFeedbackVarying;
+
+    typedef void (GLAPIENTRY * PFNGLGETINTEGERI_V) (GLenum param, GLuint index, GLint* values);
+    PFNGLGETINTEGERI_V fGetIntegeri_v;
+
+    // EXT_transform_feedback only
+    typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSET) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+    PFNGLBINDBUFFEROFFSET fBindBufferOffset;
 };
 
 }
 }
 
 #endif /* GLCONTEXTSYMBOLS_H_ */
--- a/gfx/gl/GLXLibrary.h
+++ b/gfx/gl/GLXLibrary.h
@@ -13,17 +13,17 @@ typedef realGLboolean GLboolean;
 namespace mozilla {
 namespace gl {
 
 class GLXLibrary
 {
 public:
     GLXLibrary() : mInitialized(false), mTriedInitializing(false),
                    mUseTextureFromPixmap(false), mDebug(false),
-                   mHasRobustness(false), mIsATI(false),
+                   mHasRobustness(false), mIsATI(false), mIsNVIDIA(false),
                    mClientIsMesa(false), mGLXMajorVersion(0),
                    mGLXMinorVersion(0), mLibType(OPENGL_LIB),
                    mOGLLibrary(nullptr) {}
 
     void xDestroyContext(Display* display, GLXContext context);
     Bool xMakeCurrent(Display* display, 
                       GLXDrawable drawable, 
                       GLXContext context);
@@ -197,16 +197,17 @@ private:
 #endif
 
     bool mInitialized;
     bool mTriedInitializing;
     bool mUseTextureFromPixmap;
     bool mDebug;
     bool mHasRobustness;
     bool mIsATI;
+    bool mIsNVIDIA;
     bool mClientIsMesa;
     int mGLXMajorVersion;
     int mGLXMinorVersion;
     LibraryType mLibType;
     PRLibrary *mOGLLibrary;
 };
 
 // a global GLXLibrary instance
--- a/image/src/Decoder.cpp
+++ b/image/src/Decoder.cpp
@@ -338,16 +338,17 @@ Decoder::PostFrameStop(FrameBlender::Fra
 
   if (aFrameAlpha == FrameBlender::kFrameOpaque) {
     mCurrentFrame->SetHasNoAlpha();
   }
 
   mCurrentFrame->SetFrameDisposalMethod(aDisposalMethod);
   mCurrentFrame->SetTimeout(aTimeout);
   mCurrentFrame->SetBlendMethod(aBlendMethod);
+  mCurrentFrame->ImageUpdated(mCurrentFrame->GetRect());
 
   // Flush any invalidations before we finish the frame
   FlushInvalidations();
 
   // Fire notifications
   if (mObserver) {
     mObserver->OnStopFrame();
     if (mFrameCount > 1 && !mIsAnimated) {
--- a/intl/uconv/src/nsConverterInputStream.cpp
+++ b/intl/uconv/src/nsConverterInputStream.cpp
@@ -3,16 +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 "nsConverterInputStream.h"
 #include "nsIInputStream.h"
 #include "nsICharsetConverterManager.h"
 #include "nsIServiceManager.h"
 #include "nsReadLine.h"
+#include "nsStreamUtils.h"
 #include <algorithm>
 
 #define CONVERTER_BUFFER_SIZE 8192
 
 NS_IMPL_ISUPPORTS3(nsConverterInputStream, nsIConverterInputStream,
                    nsIUnicharInputStream, nsIUnicharLineInputStream)
     
 static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
@@ -34,21 +35,20 @@ nsConverterInputStream::Init(nsIInputStr
     nsCOMPtr<nsICharsetConverterManager> ccm =
         do_GetService(kCharsetConverterManagerCID, &rv);
     if (NS_FAILED(rv)) return rv;
 
     rv = ccm->GetUnicodeDecoder(aCharset ? aCharset : "ISO-8859-1", getter_AddRefs(mConverter));
     if (NS_FAILED(rv)) return rv;
  
     // set up our buffers
-    rv = NS_NewByteBuffer(getter_AddRefs(mByteData), nullptr, aBufferSize);
-    if (NS_FAILED(rv)) return rv;
-
-    rv = NS_NewUnicharBuffer(getter_AddRefs(mUnicharData), nullptr, aBufferSize);
-    if (NS_FAILED(rv)) return rv;
+    if (!mByteData.SetCapacity(aBufferSize) ||
+        !mUnicharData.SetCapacity(aBufferSize)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
 
     mInput = aStream;
     mReplacementChar = aReplacementChar;
     if (!aReplacementChar ||
         aReplacementChar != mConverter->GetCharacterForUnMapped()) {
         mConverter->SetInputErrorBehavior(nsIUnicodeDecoder::kOnError_Signal);
     }
 
@@ -57,18 +57,18 @@ nsConverterInputStream::Init(nsIInputStr
 
 NS_IMETHODIMP
 nsConverterInputStream::Close()
 {
     nsresult rv = mInput ? mInput->Close() : NS_OK;
     mLineBuffer = nullptr;
     mInput = nullptr;
     mConverter = nullptr;
-    mByteData = nullptr;
-    mUnicharData = nullptr;
+    mByteData.Clear();
+    mUnicharData.Clear();
     return rv;
 }
 
 NS_IMETHODIMP
 nsConverterInputStream::Read(PRUnichar* aBuf,
                              uint32_t aCount,
                              uint32_t *aReadCount)
 {
@@ -80,17 +80,17 @@ nsConverterInputStream::Read(PRUnichar* 
     if (readCount == 0) {
       *aReadCount = 0;
       return mLastErrorCode;
     }
   }
   if (readCount > aCount) {
     readCount = aCount;
   }
-  memcpy(aBuf, mUnicharData->GetBuffer() + mUnicharDataOffset,
+  memcpy(aBuf, mUnicharData.Elements() + mUnicharDataOffset,
          readCount * sizeof(PRUnichar));
   mUnicharDataOffset += readCount;
   *aReadCount = readCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsConverterInputStream::ReadSegments(nsWriteUnicharSegmentFun aWriter,
@@ -112,17 +112,17 @@ nsConverterInputStream::ReadSegments(nsW
   if (bytesToWrite > aCount)
     bytesToWrite = aCount;
   
   uint32_t bytesWritten;
   uint32_t totalBytesWritten = 0;
 
   while (bytesToWrite) {
     rv = aWriter(this, aClosure,
-                 mUnicharData->GetBuffer() + mUnicharDataOffset,
+                 mUnicharData.Elements() + mUnicharDataOffset,
                  totalBytesWritten, bytesToWrite, &bytesWritten);
     if (NS_FAILED(rv)) {
       // don't propagate errors to the caller
       break;
     }
     
     bytesToWrite -= bytesWritten;
     totalBytesWritten += bytesWritten;
@@ -147,18 +147,17 @@ nsConverterInputStream::ReadString(uint3
     if (readCount == 0) {
       *aReadCount = 0;
       return mLastErrorCode;
     }
   }
   if (readCount > aCount) {
     readCount = aCount;
   }
-  const PRUnichar* buf = reinterpret_cast<const PRUnichar*>(mUnicharData->GetBuffer() +
-                                             mUnicharDataOffset);
+  const PRUnichar* buf = mUnicharData.Elements() + mUnicharDataOffset;
   aString.Assign(buf, readCount);
   mUnicharDataOffset += readCount;
   *aReadCount = readCount;
   return NS_OK;
 }
 
 uint32_t
 nsConverterInputStream::Fill(nsresult * aErrorCode)
@@ -177,66 +176,61 @@ nsConverterInputStream::Fill(nsresult * 
   }
   
   // We assume a many to one conversion and are using equal sizes for
   // the two buffers.  However if an error happens at the very start
   // of a byte buffer we may end up in a situation where n bytes lead
   // to n+1 unicode chars.  Thus we need to keep track of the leftover
   // bytes as we convert.
   
-  int32_t nb = mByteData->Fill(aErrorCode, mInput, mLeftOverBytes);
-#if defined(DEBUG_bzbarsky) && 0
-  for (unsigned int foo = 0; foo < mByteData->GetLength(); ++foo) {
-    fprintf(stderr, "%c", mByteData->GetBuffer()[foo]);
-  }
-  fprintf(stderr, "\n");
-#endif
-  if (nb <= 0 && mLeftOverBytes == 0) {
+  uint32_t nb;
+  *aErrorCode = NS_FillArray(mByteData, mInput, mLeftOverBytes, &nb);
+  if (nb == 0 && mLeftOverBytes == 0) {
     // No more data 
     *aErrorCode = NS_OK;
     return 0;
   }
 
-  NS_ASSERTION(uint32_t(nb) + mLeftOverBytes == mByteData->GetLength(),
+  NS_ASSERTION(uint32_t(nb) + mLeftOverBytes == mByteData.Length(),
                "mByteData is lying to us somewhere");
-  
+
   // Now convert as much of the byte buffer to unicode as possible
   mUnicharDataOffset = 0;
   mUnicharDataLength = 0;
   uint32_t srcConsumed = 0;
   do {
-    int32_t srcLen = mByteData->GetLength() - srcConsumed;
-    int32_t dstLen = mUnicharData->GetBufferSize() - mUnicharDataLength;
-    *aErrorCode = mConverter->Convert(mByteData->GetBuffer()+srcConsumed,
+    int32_t srcLen = mByteData.Length() - srcConsumed;
+    int32_t dstLen = mUnicharData.Capacity() - mUnicharDataLength;
+    *aErrorCode = mConverter->Convert(mByteData.Elements()+srcConsumed,
                                       &srcLen,
-                                      mUnicharData->GetBuffer()+mUnicharDataLength,
+                                      mUnicharData.Elements()+mUnicharDataLength,
                                       &dstLen);
     mUnicharDataLength += dstLen;
     // XXX if srcLen is negative, we want to drop the _first_ byte in
     // the erroneous byte sequence and try again.  This is not quite
     // possible right now -- see bug 160784
     srcConsumed += srcLen;
     if (NS_FAILED(*aErrorCode) && mReplacementChar) {
-      NS_ASSERTION(0 < mUnicharData->GetBufferSize() - mUnicharDataLength,
+      NS_ASSERTION(0 < mUnicharData.Capacity() - mUnicharDataLength,
                    "Decoder returned an error but filled the output buffer! "
                    "Should not happen.");
-      mUnicharData->GetBuffer()[mUnicharDataLength++] = mReplacementChar;
+      mUnicharData.Elements()[mUnicharDataLength++] = mReplacementChar;
       ++srcConsumed;
       // XXX this is needed to make sure we don't underrun our buffer;
       // bug 160784 again
       srcConsumed = std::max<uint32_t>(srcConsumed, 0);
       mConverter->Reset();
     }
-    NS_ASSERTION(srcConsumed <= mByteData->GetLength(),
+    NS_ASSERTION(srcConsumed <= mByteData.Length(),
                  "Whoa.  The converter should have returned NS_OK_UDEC_MOREINPUT before this point!");
   } while (mReplacementChar &&
            NS_FAILED(*aErrorCode) &&
-           uint32_t(mUnicharData->GetBufferSize()) > mUnicharDataLength);
+           mUnicharData.Capacity() > mUnicharDataLength);
 
-  mLeftOverBytes = mByteData->GetLength() - srcConsumed;
+  mLeftOverBytes = mByteData.Length() - srcConsumed;
 
   return mUnicharDataLength;
 }
 
 NS_IMETHODIMP
 nsConverterInputStream::ReadLine(nsAString& aLine, bool* aResult)
 {
   if (!mLineBuffer) {
--- a/intl/uconv/src/nsConverterInputStream.h
+++ b/intl/uconv/src/nsConverterInputStream.h
@@ -2,22 +2,20 @@
 /* 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 "nsIInputStream.h"
 #include "nsIConverterInputStream.h"
 #include "nsIUnicharLineInputStream.h"
 #include "nsString.h"
-
+#include "nsTArray.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsIUnicodeDecoder.h"
-#include "nsIByteBuffer.h"
-#include "nsIUnicharBuffer.h"
 #include "nsReadLine.h"
 
 #define NS_CONVERTERINPUTSTREAM_CONTRACTID "@mozilla.org/intl/converter-input-stream;1"
 
 // {2BC2AD62-AD5D-4b7b-A9DB-F74AE203C527}
 #define NS_CONVERTERINPUTSTREAM_CID \
   { 0x2bc2ad62, 0xad5d, 0x4b7b, \
    { 0xa9, 0xdb, 0xf7, 0x4a, 0xe2, 0x3, 0xc5, 0x27 } }
@@ -44,18 +42,18 @@ class nsConverterInputStream : public ns
     virtual ~nsConverterInputStream() { Close(); }
 
  private:
 
 
     uint32_t Fill(nsresult *aErrorCode);
     
     nsCOMPtr<nsIUnicodeDecoder> mConverter;
-    nsCOMPtr<nsIByteBuffer> mByteData;
-    nsCOMPtr<nsIUnicharBuffer> mUnicharData;
+    FallibleTArray<char> mByteData;
+    FallibleTArray<PRUnichar> mUnicharData;
     nsCOMPtr<nsIInputStream> mInput;
 
     nsresult  mLastErrorCode;
     uint32_t  mLeftOverBytes;
     uint32_t  mUnicharDataOffset;
     uint32_t  mUnicharDataLength;
     PRUnichar mReplacementChar;
 
--- a/js/src/build/autoconf/hooks.m4
+++ b/js/src/build/autoconf/hooks.m4
@@ -14,17 +14,40 @@ dnl Wrap AC_INIT_PREPARE to add the abov
 define([_MOZ_AC_INIT_PREPARE], defn([AC_INIT_PREPARE]))
 define([AC_INIT_PREPARE],
 [_MOZ_AC_INIT_PREPARE($1)
 MOZ_CONFIG_LOG_TRAP
 ])
 
 dnl Disable the trap when running sub-configures.
 define([_MOZ_AC_OUTPUT_SUBDIRS], defn([AC_OUTPUT_SUBDIRS]))
+define([MOZ_SUBCONFIGURE_WRAP],
+[ _CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+case "$host" in
+*-mingw*)
+    _CONFIG_SHELL=$(cd $(dirname $_CONFIG_SHELL); pwd -W)/$(basename $_CONFIG_SHELL)
+    if test ! -e "$_CONFIG_SHELL" -a -e "${_CONFIG_SHELL}.exe"; then
+        _CONFIG_SHELL="${_CONFIG_SHELL}.exe"
+    fi
+    ;;
+esac
+
+if test -d "$1"; then
+    (cd "$1"; $PYTHON $_topsrcdir/build/subconfigure.py dump "$_CONFIG_SHELL")
+fi
+$2
+(cd "$1"; $PYTHON $_topsrcdir/build/subconfigure.py adjust)
+])
+
 define([AC_OUTPUT_SUBDIRS],
 [trap '' EXIT
-_MOZ_AC_OUTPUT_SUBDIRS($1)
+for moz_config_dir in $1; do
+  MOZ_SUBCONFIGURE_WRAP([$moz_config_dir],[
+    _MOZ_AC_OUTPUT_SUBDIRS($moz_config_dir)
+  ])
+done
+
 MOZ_CONFIG_LOG_TRAP
 ])
 
 dnl Print error messages in config.log as well as stderr
 define([AC_MSG_ERROR],
 [{ echo "configure: error: $1" 1>&2; echo "configure: error: $1" 1>&5; exit 1; }])
new file mode 100644
--- /dev/null
+++ b/js/src/build/subconfigure.py
@@ -0,0 +1,124 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# This script is used to capture the content of config.status-generated
+# files and subsequently restore their timestamp if they haven't changed.
+
+import os
+import re
+import subprocess
+import sys
+import pickle
+
+class File(object):
+    def __init__(self, path):
+        self._path = path
+        self._content = open(path, 'rb').read()
+        stat = os.stat(path)
+        self._times = (stat.st_atime, stat.st_mtime)
+
+    def update_time(self):
+        '''If the file hasn't changed since the instance was created,
+           restore its old modification time.'''
+        if not os.path.exists(self._path):
+            return
+        if open(self._path, 'rb').read() == self._content:
+            os.utime(self._path, self._times)
+
+
+# As defined in the various sub-configures in the tree
+PRECIOUS_VARS = set([
+    'build_alias',
+    'host_alias',
+    'target_alias',
+    'CC',
+    'CFLAGS',
+    'LDFLAGS',
+    'LIBS',
+    'CPPFLAGS',
+    'CPP',
+    'CCC',
+    'CXXFLAGS',
+    'CXX',
+    'CCASFLAGS',
+    'CCAS',
+])
+
+
+# Autoconf, in some of the sub-configures used in the tree, likes to error
+# out when "precious" variables change in value. The solution it gives to
+# straighten things is to either run make distclean or remove config.cache.
+# There's no reason not to do the latter automatically instead of failing,
+# doing the cleanup (which, on buildbots means a full clobber), and
+# restarting from scratch.
+def maybe_clear_cache():
+    comment = re.compile(r'^\s+#')
+    cache = {}
+    with open('config.cache') as f:
+        for line in f.readlines():
+            if not comment.match(line) and '=' in line:
+                key, value = line.split('=', 1)
+                cache[key] = value
+    for precious in PRECIOUS_VARS:
+        entry = 'ac_cv_env_%s_value' % precious
+        if entry in cache and (not precious in os.environ or os.environ[precious] != cache[entry]):
+            os.remove('config.cache')
+            return
+
+
+def dump(dump_file, shell):
+    if os.path.exists('config.cache'):
+        maybe_clear_cache()
+    if not os.path.exists('config.status'):
+        if os.path.exists(dump_file):
+            os.remove(dump_file)
+        return
+
+    config_files = [File('config.status')]
+
+    # Scan the config.status output for information about configuration files
+    # it generates.
+    config_status_output = subprocess.check_output(
+        [shell, '-c', './config.status --help'],
+        stderr=subprocess.STDOUT).splitlines()
+    state = None
+    for line in config_status_output:
+        if line.startswith('Configuration') and line.endswith(':'):
+            state = 'config'
+        elif not line.startswith(' '):
+            state = None
+        elif state == 'config':
+            for f in (couple.split(':')[0] for couple in line.split()):
+                if os.path.isfile(f):
+                    config_files.append(File(f))
+
+    with open(dump_file, 'wb') as f:
+        pickle.dump(config_files, f)
+
+
+def adjust(dump_file):
+    if not os.path.exists(dump_file):
+        return
+
+    config_files = []
+
+    try:
+        with open(dump_file, 'rb') as f:
+            config_files = pickle.load(f)
+    except Exception:
+        pass
+
+    for f in config_files:
+        f.update_time()
+
+    os.remove(dump_file)
+
+
+CONFIG_DUMP = 'config_files.pkl'
+
+if __name__ == '__main__':
+    if sys.argv[1] == 'dump':
+        dump(CONFIG_DUMP, sys.argv[2])
+    elif sys.argv[1] == 'adjust':
+        adjust(CONFIG_DUMP)
--- a/js/src/config/makefiles/target_export.mk
+++ b/js/src/config/makefiles/target_export.mk
@@ -7,19 +7,19 @@
 
 PARALLEL_DIRS_export = $(addsuffix _export,$(PARALLEL_DIRS))
 
 .PHONY: export $(PARALLEL_DIRS_export)
 
 ###############
 ## TIER targets
 ###############
-export_tier_%:
+$(addprefix export_tier_,$(TIERS)): export_tier_%:
 	@$(ECHO) "$@"
-	$(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,export,$(dir)))
+	$(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,$*,export,$(dir),export))
 
 #################
 ## Common targets
 #################
 ifdef PARALLEL_DIRS
 export:: $(PARALLEL_DIRS_export)
 
 $(PARALLEL_DIRS_export): %_export: %/Makefile
--- a/js/src/config/makefiles/target_libs.mk
+++ b/js/src/config/makefiles/target_libs.mk
@@ -7,19 +7,19 @@
 
 PARALLEL_DIRS_libs = $(addsuffix _libs,$(PARALLEL_DIRS))
 
 .PHONY: libs $(PARALLEL_DIRS_libs)
 
 ###############
 ## TIER targets
 ###############
-libs_tier_%:
+$(addprefix libs_tier_,$(TIERS)): libs_tier_%:
 	@$(ECHO) "$@"
-	$(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,libs,$(dir)))
+	$(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,$*,libs,$(dir),libs))
 
 #################
 ## Common targets
 #################
 ifdef PARALLEL_DIRS
 libs:: $(PARALLEL_DIRS_libs)
 
 $(PARALLEL_DIRS_libs): %_libs: %/Makefile
@@ -38,17 +38,17 @@ else
 EXPORT_LIBRARY = $(DEPTH)/staticlib
 endif
 else
 # If EXPORT_LIBRARY has a value, we'll be installing there. We also need to cleanup there
 GARBAGE += $(foreach lib,$(LIBRARY),$(EXPORT_LIBRARY)/$(lib))
 endif
 endif # EXPORT_LIBRARY
 
-libs:: $(SUBMAKEFILES) $(MAKE_DIRS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS) $(JAVA_LIBRARY)
+libs:: $(SUBMAKEFILES) $(MAKE_DIRS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS)
 ifndef NO_DIST_INSTALL
 ifdef SHARED_LIBRARY
 ifdef IS_COMPONENT
 	$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)/components
 	$(ELF_DYNSTR_GC) $(FINAL_TARGET)/components/$(SHARED_LIBRARY)
 ifndef NO_COMPONENTS_MANIFEST
 	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/chrome.manifest "manifest components/components.manifest"
 	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/components.manifest "binary-component $(SHARED_LIBRARY)"
@@ -113,21 +113,11 @@ INSTALL_TARGETS += HOST_PROGRAMS
 endif
 
 ifdef HOST_LIBRARY
 HOST_LIBRARY_FILES = $(HOST_LIBRARY)
 HOST_LIBRARY_DEST ?= $(DIST)/host/lib
 INSTALL_TARGETS += HOST_LIBRARY
 endif
 
-ifdef JAVA_LIBRARY
-JAVA_LIBRARY_FILES = $(JAVA_LIBRARY)
-ifdef IS_COMPONENT
-JAVA_LIBRARY_DEST ?= $(FINAL_TARGET)/components
-else
-JAVA_LIBRARY_DEST ?= $(FINAL_TARGET)
-endif
-INSTALL_TARGETS += JAVA_LIBRARY
-endif
-
 endif # !NO_DIST_INSTALL
 
 # EOF
--- a/js/src/config/makefiles/target_tools.mk
+++ b/js/src/config/makefiles/target_tools.mk
@@ -7,19 +7,19 @@
 
 PARALLEL_DIRS_tools = $(addsuffix _tools,$(PARALLEL_DIRS))
 
 .PHONY: tools $(PARALLEL_DIRS_tools)
 
 ###############
 ## TIER targets
 ###############
-tools_tier_%:
+$(addprefix tools_tier_,$(TIERS)): tools_tier_%:
 	@$(ECHO) "$@"
-	$(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,tools,$(dir)))
+	$(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,$*,tools,$(dir),tools))
 
 #################
 ## Common targets
 #################
 ifdef PARALLEL_DIRS
 tools:: $(PARALLEL_DIRS_tools)
 
 $(PARALLEL_DIRS_tools): %_tools: %/Makefile
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -25,16 +25,17 @@ endif
   HOST_CSRCS \
   HOST_LIBRARY_NAME \
   MODULE \
   NO_DIST_INSTALL \
   PARALLEL_DIRS \
   TEST_DIRS \
   TIERS \
   TOOL_DIRS \
+  XPCSHELL_TESTS \
   XPIDL_MODULE \
   $(NULL)
 
 _DEPRECATED_VARIABLES := \
   XPIDL_FLAGS \
   $(NULL)
 
 ifndef EXTERNALLY_MANAGED_MAKE_FILE
@@ -298,20 +299,16 @@ endif
 endif
 
 ifdef FORCE_SHARED_LIB
 ifndef FORCE_STATIC_LIB
 LIBRARY := $(NULL)
 endif
 endif
 
-ifdef JAVA_LIBRARY_NAME
-JAVA_LIBRARY := $(JAVA_LIBRARY_NAME).jar
-endif
-
 ifeq ($(OS_ARCH),WINNT)
 ifndef GNU_CC
 
 #
 # Unless we're building SIMPLE_PROGRAMS, all C++ files share a PDB file per
 # directory. For parallel builds, this PDB file is shared and locked by
 # MSPDBSRV.EXE, starting with MSVC8 SP1. If you're using MSVC 7.1 or MSVC8
 # without SP1, don't do parallel builds.
@@ -428,33 +425,34 @@ endif
 ifdef MOZ_UPDATE_XTERM
 # Its good not to have a newline at the end of the titlebar string because it
 # makes the make -s output easier to read.  Echo -n does not work on all
 # platforms, but we can trick printf into doing it.
 UPDATE_TITLE = printf "\033]0;%s in %s\007" $(1) $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$(2) ;
 endif
 
 ifdef MACH
-BUILDSTATUS=@echo BUILDSTATUS $1
+BUILDSTATUS=@echo "BUILDSTATUS $1"
 endif
+
 # Static directories are largely independent of our build system. But, they
 # could share the same build mechanism (like moz.build files). We need to
 # prevent leaking of our backend state to these independent build systems. This
 # is why MOZBUILD_BACKEND_CHECKED isn't exported to make invocations for static
 # directories.
 define SUBMAKE # $(call SUBMAKE,target,directory,static)
 +@$(UPDATE_TITLE)
 +$(if $(3), MOZBUILD_BACKEND_CHECKED=,) $(MAKE) $(if $(2),-C $(2)) $(1)
 
 endef # The extra line is important here! don't delete it
 
 define TIER_DIR_SUBMAKE
-$(call BUILDSTATUS,TIERDIR_START  $(2))
-$(call SUBMAKE,$(1),$(2),$(3))
-$(call BUILDSTATUS,TIERDIR_FINISH $(2))
+$(call BUILDSTATUS,TIERDIR_START  $(1) $(2) $(3))
+$(call SUBMAKE,$(4),$(3),$(5))
+$(call BUILDSTATUS,TIERDIR_FINISH $(1) $(2) $(3))
 
 endef # Ths empty line is important.
 
 
 ifneq (,$(strip $(DIRS)))
 LOOP_OVER_DIRS = \
   $(foreach dir,$(DIRS),$(call SUBMAKE,$@,$(dir)))
 endif
@@ -702,51 +700,57 @@ alldep::
 	$(MAKE) export
 	$(MAKE) depend
 	$(MAKE) libs
 	$(MAKE) tools
 
 endif # TIERS
 endif # SUPPRESS_DEFAULT_RULES
 
-ifeq ($(filter s,$(MAKEFLAGS)),)
+ifeq ($(findstring s,$(filter-out --%, $(MAKEFLAGS))),)
 ECHO := echo
 QUIET :=
 else
 ECHO := true
 QUIET := -q
 endif
 
 # This function is called and evaluated to produce the rule to build the
-# specified tier. Each tier begins by building the "static" directories.
-# The BUILDSTATUS echo commands are used to faciliate easier parsing
-# of build output. Build drivers are encouraged to filter these lines
-# from the user.
+# specified tier.
+#
+# Tiers are traditionally composed of directories that are invoked either
+# once (so-called "static" directories) or 3 times with the export, libs, and
+# tools sub-tiers.
+#
+# If the TIER_$(tier)_CUSTOM variable is defined, then these traditional
+# tier rules are ignored and each directory in the tier is executed via a
+# sub-make invocation (make -C).
 define CREATE_TIER_RULE
 tier_$(1)::
-	$(call BUILDSTATUS,TIER_START $(1))
-	$(call BUILDSTATUS,SUBTIERS $(if $(tier_$(1)_staticdirs),static )$(if $(tier_$(1)_dirs),export libs tools))
-	$(call BUILDSTATUS,STATICDIRS $$($$@_staticdirs))
-	$(call BUILDSTATUS,DIRS $$($$@_dirs))
+ifdef TIER_$(1)_CUSTOM
+	$$(foreach dir,$$($$@_dirs),$$(call SUBMAKE,,$$(dir)))
+else
+	$(call BUILDSTATUS,TIER_START $(1) $(if $(tier_$(1)_staticdirs),static )$(if $(tier_$(1)_dirs),export libs tools))
 ifneq (,$(tier_$(1)_staticdirs))
-	$(call BUILDSTATUS,SUBTIER_START $(1) static)
-	$$(foreach dir,$$($$@_staticdirs),$$(call TIER_DIR_SUBMAKE,,$$(dir),1))
+	$(call BUILDSTATUS,SUBTIER_START  $(1) static $$($$@_staticdirs))
+	$$(foreach dir,$$($$@_staticdirs),$$(call TIER_DIR_SUBMAKE,$(1),static,$$(dir),,1))
 	$(call BUILDSTATUS,SUBTIER_FINISH $(1) static)
 endif
 ifneq (,$(tier_$(1)_dirs))
-	$(call BUILDSTATUS,SUBTIER_START $(1) export)
+	$(call BUILDSTATUS,SUBTIER_START  $(1) export $$($$@_dirs))
 	$$(MAKE) export_$$@
 	$(call BUILDSTATUS,SUBTIER_FINISH $(1) export)
-	$(call BUILDSTATUS,SUBTIER_START $(1) libs)
+	$(call BUILDSTATUS,SUBTIER_START  $(1) libs $$($$@_dirs))
 	$$(MAKE) libs_$$@
 	$(call BUILDSTATUS,SUBTIER_FINISH $(1) libs)
-	$(call BUILDSTATUS,SUBTIER_START $(1) tools)
+	$(call BUILDSTATUS,SUBTIER_START  $(1) tools $$($$@_dirs))
 	$$(MAKE) tools_$$@
 	$(call BUILDSTATUS,SUBTIER_FINISH $(1) tools)
-	$(call BUILDSTATUS TIER_FINISH $(1))
+endif
+	$(call BUILDSTATUS,TIER_FINISH $(1))
 endif
 endef
 
 $(foreach tier,$(TIERS),$(eval $(call CREATE_TIER_RULE,$(tier))))
 
 # Do everything from scratch
 everything::
 	$(MAKE) clean
@@ -1131,25 +1135,25 @@ endef
 $(COBJS):
 	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 # DEFINES and ACDEFINES are needed here to enable conditional compilation of Q_OBJECTs:
 # 'moc' only knows about #defines it gets on the command line (-D...), not in
 # included headers like mozilla-config.h
-moc_%.cpp: %.h
+$(filter moc_%.cpp,$(CPPSRCS)): moc_%.cpp: %.h
 	$(REPORT_BUILD)
 	$(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $< $(OUTOPTION)$@
 
-moc_%.cc: %.cc
+$(filter moc_%.cc,$(CPPSRCS)): moc_%.cc: %.cc
 	$(REPORT_BUILD)
 	$(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $(_VPATH_SRCS:.cc=.h) $(OUTOPTION)$@
 
-qrc_%.cpp: %.qrc
+$(filter qrc_%.cpp,$(CPPSRCS)): qrc_%.cpp: %.qrc
 	$(REPORT_BUILD)
 	$(ELOG) $(RCC) -name $* $< $(OUTOPTION)$@
 
 ifdef ASFILES
 # The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept
 # a '-c' flag.
 $(ASOBJS):
 	$(REPORT_BUILD)
@@ -1170,72 +1174,62 @@ endif
 	@$(MAKE_DEPS_AUTO_CXX)
 	$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 $(CMOBJS):
 	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
 	$(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
-%.s: %.cpp $(call mkdir_deps,$(MDDEPDIR))
+$(filter %.s,$(CPPSRCS:%.cpp=%.s)): %.s: %.cpp $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
 	$(CCC) -S $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
-%.s: %.cc $(call mkdir_deps,$(MDDEPDIR))
+$(filter %.s,$(CPPSRCS:%.cc=%.s)): %.s: %.cc $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
 	$(CCC) -S $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
-%.s: %.c $(call mkdir_deps,$(MDDEPDIR))
+$(filter %.s,$(CSRCS:%.c=%.s)): %.s: %.c $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
 	$(CC) -S $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
-%.i: %.cpp $(call mkdir_deps,$(MDDEPDIR))
+$(filter %.i,$(CPPSRCS:%.cpp=%.i)): %.i: %.cpp $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
 	$(CCC) -C -E $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) > $*.i
 
-%.i: %.cc $(call mkdir_deps,$(MDDEPDIR))
+$(filter %.i,$(CPPSRCS:%.cc=%.i)): %.i: %.cc $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
 	$(CCC) -C -E $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) > $*.i
 
-%.i: %.c $(call mkdir_deps,$(MDDEPDIR))
+$(filter %.i,$(CSRCS:%.c=%.i)): %.i: %.c $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
 	$(CC) -C -E $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) > $*.i
 
-%.i: %.mm $(call mkdir_deps,$(MDDEPDIR))
+$(filter %.i,$(CMMSRCS:%.mm=%.i)): %.i: %.mm $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
 	$(CCC) -C -E $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) > $*.i
 
-%.res: %.rc
+$(RESFILE): %.res: %.rc
 	$(REPORT_BUILD)
 	@echo Creating Resource file: $@
 ifeq ($(OS_ARCH),OS2)
 	$(RC) $(RCFLAGS:-D%=-d %) -i $(subst /,\,$(srcdir)) -r $< $@
 else
 ifdef GNU_CC
 	$(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES:-I%=--include-dir %) $(OUTOPTION)$@ $(_VPATH_SRCS)
 else
 	$(RC) $(RCFLAGS) -r $(DEFINES) $(INCLUDES) $(OUTOPTION)$@ $(_VPATH_SRCS)
 endif
 endif
 
-# Cancel these implicit rules
-#
-%: %,v
-
-%: RCS/%,v
-
-%: RCS/%
+# Cancel GNU make built-in implicit rules
+ifndef .PYMAKE
+MAKEFLAGS += -r
+endif
 
-%: s.%
-
-%: SCCS/s.%
-
-###############################################################################
-# Java rules
-###############################################################################
 ifneq (,$(filter OS2 WINNT,$(OS_ARCH)))
 SEP := ;
 else
 SEP := :
 endif
 
 EMPTY :=
 SPACE := $(EMPTY) $(EMPTY)
@@ -1250,50 +1244,23 @@ ifeq ($(HOST_OS_ARCH),WINNT)
 #  on it, then merge with the rest of the path.
 root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\1|")
 non-root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\2|")
 normalizepath = $(foreach p,$(1),$(if $(filter /%,$(1)),$(patsubst %/,%,$(shell cd $(call root-path,$(1)) && pwd -W))/$(call non-root-path,$(1)),$(1)))
 else
 normalizepath = $(1)
 endif
 
+###############################################################################
+# Java rules
+###############################################################################
 ifneq (,$(value JAVAFILES)$(value RESFILES))
   include $(topsrcdir)/config/makefiles/java-build.mk
 endif
 
-_srcdir = $(call normalizepath,$(srcdir))
-ifdef JAVA_SOURCEPATH
-SP = $(subst $(SPACE),$(SEP),$(call normalizepath,$(strip $(JAVA_SOURCEPATH))))
-_JAVA_SOURCEPATH = ".$(SEP)$(_srcdir)$(SEP)$(SP)"
-else
-_JAVA_SOURCEPATH = ".$(SEP)$(_srcdir)"
-endif
-
-ifdef JAVA_CLASSPATH
-CP = $(subst $(SPACE),$(SEP),$(call normalizepath,$(strip $(JAVA_CLASSPATH))))
-_JAVA_CLASSPATH = ".$(SEP)$(CP)"
-else
-_JAVA_CLASSPATH = .
-endif
-
-_JAVA_DIR = _java
-$(_JAVA_DIR)::
-	$(NSINSTALL) -D $@
-
-$(_JAVA_DIR)/%.class: %.java $(GLOBAL_DEPS) $(_JAVA_DIR)
-	$(REPORT_BUILD)
-	$(JAVAC) $(JAVAC_FLAGS) -classpath $(_JAVA_CLASSPATH) \
-			-sourcepath $(_JAVA_SOURCEPATH) -d $(_JAVA_DIR) $(_VPATH_SRCS)
-
-$(JAVA_LIBRARY): $(addprefix $(_JAVA_DIR)/,$(JAVA_SRCS:.java=.class)) $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	$(JAR) cf $@ -C $(_JAVA_DIR) .
-
-GARBAGE_DIRS += $(_JAVA_DIR)
-
 ###############################################################################
 # Update Files Managed by Build Backend
 ###############################################################################
 
 ifndef NO_MAKEFILE_RULE
 Makefile: Makefile.in
 	@$(PYTHON) $(DEPTH)/config.status -n --file=Makefile
 	@$(TOUCH) $@
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -4356,25 +4356,27 @@ if test -n "$ENABLE_INTL_API" ; then
         ICU_BUILD_OPTS="$ICU_BUILD_OPTS --enable-debug"
     fi
     if test -z "$MOZ_OPTIMIZE"; then
         ICU_BUILD_OPTS="$ICU_BUILD_OPTS --disable-release"
     fi
 
     abs_srcdir=`(cd $srcdir; pwd)`
     mkdir -p $_objdir/intl/icu
-    (cd $_objdir/intl/icu; \
+    (cd $_objdir/intl/icu
+     MOZ_SUBCONFIGURE_WRAP([.],[
      CC="$CC" CXX="$CXX" \
      CFLAGS="$ICU_CFLAGS" CPPFLAGS="$ICU_CPPFLAGS" CXXFLAGS="$ICU_CXXFLAGS" \
             $SHELL $abs_srcdir/../../intl/icu/source/runConfigureICU \
             $ICU_BUILD_OPTS \
             $ICU_TARGET \
             $ICU_LINK_OPTS \
             --enable-extras=no --enable-icuio=no  --enable-layout=no \
             --enable-tests=no --enable-samples=no || exit 1
+     ])
     ) || exit 1
 fi
 
 
 dnl ========================================================
 dnl JavaScript shell
 dnl ========================================================
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/asm.js/testBug907085.js
@@ -0,0 +1,22 @@
+try {
+    s.e
+} catch (e) {}
+o = o = s2 = /x/
+for (let e in []);
+x = s2
+schedulegc(21)
+eval("x.e=x.t")
+try {
+    (function() {
+        this.eval("\
+            (function(stdlib,fgn,heap) {\
+                \"use asm\";\
+                var Vie = new stdlib.Float64Array(heap);\
+                var Iew = new stdlib.Int8Array(heap);\
+                function f(){\
+                    ent\
+                }\
+            })()\
+        ")
+    })()
+} catch (e) {}
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug905989.js
@@ -0,0 +1,10 @@
+function TestCase(n, d, e, a) {};
+function reportCompare() {
+  new TestCase();
+}
+reportCompare();
+TestCase = ParallelArray;
+try {
+  reportCompare();
+} catch(exc1) {}
+reportCompare();
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug906284.js
@@ -0,0 +1,15 @@
+"use strict"
+function f() {
+    h = {}
+}
+var c = 0;
+for (var i=0; i<3; i++) {
+    try {
+	new f();
+	assertEq(0, 1);
+    } catch(e) {
+	c++;
+	assertEq(e.message.contains("undeclared variable"), true);
+    }
+}
+assertEq(c, 3);
--- a/js/src/jit/BaselineJIT.cpp
+++ b/js/src/jit/BaselineJIT.cpp
@@ -887,47 +887,37 @@ ion::ToggleBaselineSPS(JSRuntime *runtim
             if (!script->hasBaselineScript())
                 continue;
             script->baselineScript()->toggleSPS(enable);
         }
     }
 }
 
 static void
-MarkActiveBaselineScripts(JSContext *cx, const JitActivationIterator &activation)
+MarkActiveBaselineScripts(JSRuntime *rt, const JitActivationIterator &activation)
 {
     for (ion::IonFrameIterator iter(activation); !iter.done(); ++iter) {
         switch (iter.type()) {
           case IonFrame_BaselineJS:
             iter.script()->baselineScript()->setActive();
             break;
           case IonFrame_OptimizedJS: {
             // Keep the baseline script around, since bailouts from the ion
             // jitcode might need to re-enter into the baseline jitcode.
             iter.script()->baselineScript()->setActive();
-            for (InlineFrameIterator inlineIter(cx, &iter); inlineIter.more(); ++inlineIter)
+            for (InlineFrameIterator inlineIter(rt, &iter); inlineIter.more(); ++inlineIter)
                 inlineIter.script()->baselineScript()->setActive();
             break;
           }
           default:;
         }
     }
 }
 
 void
 ion::MarkActiveBaselineScripts(Zone *zone)
 {
-    // First check if there is a JitActivation on the stack, so that there
-    // must be a valid IonContext.
-    JitActivationIterator iter(zone->runtimeFromMainThread());
-    if (iter.done())
-        return;
-
-    // If baseline is disabled, there are no baseline scripts on the stack.
-    JSContext *cx = GetIonContext()->cx;
-    if (!ion::IsBaselineEnabled(cx))
-        return;
-
-    for (; !iter.done(); ++iter) {
+    JSRuntime *rt = zone->runtimeFromMainThread();
+    for (JitActivationIterator iter(rt); !iter.done(); ++iter) {
         if (iter.activation()->compartment()->zone() == zone)
-            MarkActiveBaselineScripts(cx, iter);
+            MarkActiveBaselineScripts(rt, iter);
     }
 }
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -6166,29 +6166,28 @@ CodeGenerator::visitBindNameIC(OutOfLine
     StoreRegisterTo(ic->outputReg()).generate(this);
     restoreLiveIgnore(lir, StoreRegisterTo(ic->outputReg()).clobbered());
 
     masm.jump(ool->rejoin());
     return true;
 }
 
 typedef bool (*SetPropertyFn)(JSContext *, HandleObject,
-                              HandlePropertyName, const HandleValue, bool, int);
+                              HandlePropertyName, const HandleValue, bool, jsbytecode *);
 static const VMFunction SetPropertyInfo =
     FunctionInfo<SetPropertyFn>(SetProperty);
 
 bool
 CodeGenerator::visitCallSetProperty(LCallSetProperty *ins)
 {
     ConstantOrRegister value = TypedOrValueRegister(ToValue(ins, LCallSetProperty::Value));
 
     const Register objReg = ToRegister(ins->getOperand(0));
-    JSOp op = JSOp(*ins->mir()->resumePoint()->pc());
-
-    pushArg(Imm32(op));
+
+    pushArg(ImmWord(ins->mir()->resumePoint()->pc()));
     pushArg(Imm32(ins->mir()->strict()));
 
     pushArg(value);
     pushArg(ImmGCPtr(ins->mir()->name()));
     pushArg(objReg);
 
     return callVM(SetPropertyInfo, ins);
 }
@@ -6212,40 +6211,34 @@ CodeGenerator::visitCallDeleteProperty(L
 }
 
 bool
 CodeGenerator::visitSetPropertyCacheV(LSetPropertyCacheV *ins)
 {
     RegisterSet liveRegs = ins->safepoint()->liveRegs();
     Register objReg = ToRegister(ins->getOperand(0));
     ConstantOrRegister value = TypedOrValueRegister(ToValue(ins, LSetPropertyCacheV::Value));
-    jsbytecode *pc = ins->mir()->resumePoint()->pc();
-    bool isSetName = JSOp(*pc) == JSOP_SETNAME || JSOp(*pc) == JSOP_SETGNAME;
-
-    SetPropertyIC cache(liveRegs, objReg, ins->mir()->name(), value,
-                        isSetName, ins->mir()->strict());
+
+    SetPropertyIC cache(liveRegs, objReg, ins->mir()->name(), value, ins->mir()->strict());
     return addCache(ins, allocateCache(cache));
 }
 
 bool
 CodeGenerator::visitSetPropertyCacheT(LSetPropertyCacheT *ins)
 {
     RegisterSet liveRegs = ins->safepoint()->liveRegs();
     Register objReg = ToRegister(ins->getOperand(0));
     ConstantOrRegister value;
-    jsbytecode *pc = ins->mir()->resumePoint()->pc();
-    bool isSetName = JSOp(*pc) == JSOP_SETNAME || JSOp(*pc) == JSOP_SETGNAME;
 
     if (ins->getOperand(1)->isConstant())
         value = ConstantOrRegister(*ins->getOperand(1)->toConstant());
     else
         value = TypedOrValueRegister(ins->valueType(), ToAnyRegister(ins->getOperand(1)));
 
-    SetPropertyIC cache(liveRegs, objReg, ins->mir()->name(), value,
-                        isSetName, ins->mir()->strict());
+    SetPropertyIC cache(liveRegs, objReg, ins->mir()->name(), value, ins->mir()->strict());
     return addCache(ins, allocateCache(cache));
 }
 
 typedef bool (*SetPropertyICFn)(JSContext *, size_t, HandleObject, HandleValue);
 const VMFunction SetPropertyIC::UpdateInfo =
     FunctionInfo<SetPropertyICFn>(SetPropertyIC::update);
 
 bool
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -154,20 +154,18 @@ IonBuilder::getSingleCallTarget(types::S
     JSObject *obj = calleeTypes->getSingleton();
     if (!obj || !obj->is<JSFunction>())
         return NULL;
 
     return &obj->as<JSFunction>();
 }
 
 bool
-IonBuilder::getPolyCallTargets(types::StackTypeSet *calleeTypes,
-                               AutoObjectVector &targets,
-                               uint32_t maxTargets,
-                               bool *gotLambda)
+IonBuilder::getPolyCallTargets(types::StackTypeSet *calleeTypes, bool constructing,
+                               AutoObjectVector &targets, uint32_t maxTargets, bool *gotLambda)
 {
     JS_ASSERT(targets.length() == 0);
     JS_ASSERT(gotLambda);
     *gotLambda = false;
 
     if (!calleeTypes)
         return true;
 
@@ -178,42 +176,48 @@ IonBuilder::getPolyCallTargets(types::St
 
     if (objCount == 0 || objCount > maxTargets)
         return true;
 
     if (!targets.reserve(objCount))
         return false;
     for(unsigned i = 0; i < objCount; i++) {
         JSObject *obj = calleeTypes->getSingleObject(i);
+        JSFunction *fun;
         if (obj) {
             if (!obj->is<JSFunction>()) {
                 targets.clear();
                 return true;
             }
-            if (obj->as<JSFunction>().isInterpreted() &&
-                !obj->as<JSFunction>().getOrCreateScript(cx))
-            {
-                return false;
-            }
-            DebugOnly<bool> appendOk = targets.append(obj);
-            JS_ASSERT(appendOk);
+            fun = &obj->as<JSFunction>();
         } else {
             types::TypeObject *typeObj = calleeTypes->getTypeObject(i);
             JS_ASSERT(typeObj);
             if (!typeObj->isFunction() || !typeObj->interpretedFunction) {
                 targets.clear();
                 return true;
             }
-            if (!typeObj->interpretedFunction->getOrCreateScript(cx))
-                return false;
-            DebugOnly<bool> appendOk = targets.append(typeObj->interpretedFunction);
-            JS_ASSERT(appendOk);
-
+
+            fun = typeObj->interpretedFunction;
             *gotLambda = true;
         }
+
+        if (fun->isInterpreted() && !fun->getOrCreateScript(cx))
+            return false;
+
+        // Don't optimize if we're constructing and the callee is not a
+        // constructor, so that CallKnown does not have to handle this case
+        // (it should always throw).
+        if (constructing && !fun->isInterpretedConstructor() && !fun->isNativeConstructor()) {
+            targets.clear();
+            return true;
+        }
+
+        DebugOnly<bool> appendOk = targets.append(fun);
+        JS_ASSERT(appendOk);
     }
 
     // For now, only inline "singleton" lambda calls
     if (*gotLambda && targets.length() > 1)
         targets.clear();
 
     return true;
 }
@@ -4942,17 +4946,17 @@ IonBuilder::jsop_call(uint32_t argc, boo
 
     int calleeDepth = -((int)argc + 2);
 
     // Acquire known call target if existent.
     AutoObjectVector originals(cx);
     bool gotLambda = false;
     types::StackTypeSet *calleeTypes = current->peek(calleeDepth)->resultTypeSet();
     if (calleeTypes) {
-        if (!getPolyCallTargets(calleeTypes, originals, 4, &gotLambda))
+        if (!getPolyCallTargets(calleeTypes, constructing, originals, 4, &gotLambda))
             return false;
     }
     JS_ASSERT_IF(gotLambda, originals.length() <= 1);
 
     // If any call targets need to be cloned, clone them. Keep track of the
     // originals as we need to case on them for poly inline.
     bool hasClones = false;
     AutoObjectVector targets(cx);
@@ -4978,26 +4982,19 @@ IonBuilder::jsop_call(uint32_t argc, boo
     InliningStatus status = inlineCallsite(targets, originals, gotLambda, callInfo);
     if (status == InliningStatus_Inlined)
         return true;
     if (status == InliningStatus_Error)
         return false;
 
     // No inline, just make the call.
     RootedFunction target(cx, NULL);
-    if (targets.length() == 1) {
+    if (targets.length() == 1)
         target = &targets[0]->as<JSFunction>();
 
-        // Don't optimize if we're constructing and the callee is not an
-        // interpreted constructor, so that CallKnown does not have to
-        // handle this case (it should always throw).
-        if (constructing && !target->isInterpretedConstructor())
-            target = NULL;
-    }
-
     return makeCall(target, callInfo, hasClones);
 }
 
 MDefinition *
 IonBuilder::makeCallsiteClone(HandleFunction target, MDefinition *fun)
 {
     // Bake in the clone eagerly if we have a known target. We have arrived here
     // because TI told us that the known target is a should-clone-at-callsite
@@ -5261,17 +5258,18 @@ DOMCallNeedsBarrier(const JSJitInfo* jit
     return jitinfo->returnType != types->getKnownTypeTag();
 }
 
 bool
 IonBuilder::makeCall(HandleFunction target, CallInfo &callInfo, bool cloneAtCallsite)
 {
     // Constructor calls to non-constructors should throw. We don't want to use
     // CallKnown in this case.
-    JS_ASSERT_IF(callInfo.constructing() && target, target->isInterpretedConstructor());
+    JS_ASSERT_IF(callInfo.constructing() && target,
+                 target->isInterpretedConstructor() || target->isNativeConstructor());
 
     MCall *call = makeCallHelper(target, callInfo, cloneAtCallsite);
     if (!call)
         return false;
 
     current->push(call);
     if (!resumeAfter(call))
         return false;
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -220,20 +220,18 @@ class IonBuilder : public MIRGenerator
     bool abort(const char *message, ...);
     void spew(const char *message);
 
     static bool inliningEnabled() {
         return js_IonOptions.inlining;
     }
 
     JSFunction *getSingleCallTarget(types::StackTypeSet *calleeTypes);
-    bool getPolyCallTargets(types::StackTypeSet *calleeTypes,
-                            AutoObjectVector &targets,
-                            uint32_t maxTargets,
-                            bool *gotLambda);
+    bool getPolyCallTargets(types::StackTypeSet *calleeTypes, bool constructing,
+                            AutoObjectVector &targets, uint32_t maxTargets, bool *gotLambda);
     bool canInlineTarget(JSFunction *target, bool constructing);
 
     void popCfgStack();
     DeferredEdge *filterDeadDeferredEdges(DeferredEdge *edge);
     bool processDeferredContinues(CFGState &state);
     ControlStatus processControlEnd();
     ControlStatus processCfgStack();
     ControlStatus processCfgEntry(CFGState &state);
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -392,19 +392,19 @@ IonCache::linkAndAttachStub(JSContext *c
 {
     Rooted<IonCode *> code(cx);
     LinkStatus status = linkCode(cx, masm, ion, code.address());
     if (status != LINK_GOOD)
         return status != LINK_ERROR;
 
     attachStub(masm, attacher, code);
 
-    if (pc) {
+    if (pc_) {
         IonSpew(IonSpew_InlineCaches, "Cache %p(%s:%d/%d) generated %s %s stub at %p",
-                this, script->filename(), script->lineno, pc - script->code,
+                this, script_->filename(), script_->lineno, pc_ - script_->code,
                 attachKind, CacheName(kind()), code->raw());
     } else {
         IonSpew(IonSpew_InlineCaches, "Cache %p generated %s %s stub at %p",
                 this, attachKind, CacheName(kind()), code->raw());
     }
     return true;
 }
 
@@ -2282,17 +2282,17 @@ SetPropertyIC::update(JSContext *cx, siz
             }
         }
     }
 
     uint32_t oldSlots = obj->numDynamicSlots();
     RootedShape oldShape(cx, obj->lastProperty());
 
     // Set/Add the property on the object, the inlined cache are setup for the next execution.
-    if (!SetProperty(cx, obj, name, value, cache.strict(), cache.isSetName()))
+    if (!SetProperty(cx, obj, name, value, cache.strict(), cache.pc()))
         return false;
 
     // The property did not exist before, now we can try to inline the property add.
     if (inlinable && !addedSetterStub && obj->lastProperty() != oldShape &&
         IsPropertyAddInlineable(cx, obj, id, oldSlots, &shape))
     {
         RootedShape newShape(cx, obj->lastProperty());
         if (!cache.attachNativeAdding(cx, ion, obj, oldShape, newShape, shape))
--- a/js/src/jit/IonCaches.h
+++ b/js/src/jit/IonCaches.h
@@ -160,18 +160,18 @@ class IonCache
     bool pure_ : 1;
     bool idempotent_ : 1;
     bool disabled_ : 1;
     size_t stubCount_ : 5;
 
     CodeLocationLabel fallbackLabel_;
 
     // Location of this operation, NULL for idempotent caches.
-    JSScript *script;
-    jsbytecode *pc;
+    JSScript *script_;
+    jsbytecode *pc_;
 
   private:
     static const size_t MAX_STUBS;
     void incrementStubCount() {
         // The IC should stop generating stubs before wrapping stubCount.
         stubCount_++;
         JS_ASSERT(stubCount_);
     }
@@ -179,18 +179,18 @@ class IonCache
   public:
 
     IonCache()
       : pure_(false),
         idempotent_(false),
         disabled_(false),
         stubCount_(0),
         fallbackLabel_(),
-        script(NULL),
-        pc(NULL)
+        script_(NULL),
+        pc_(NULL)
     {
     }
 
     virtual void disable();
     inline bool isDisabled() const {
         return disabled_;
     }
 
@@ -251,30 +251,35 @@ class IonCache
     bool pure() const {
         return pure_;
     }
     bool idempotent() const {
         return idempotent_;
     }
     void setIdempotent() {
         JS_ASSERT(!idempotent_);
-        JS_ASSERT(!script);
-        JS_ASSERT(!pc);
+        JS_ASSERT(!script_);
+        JS_ASSERT(!pc_);
         idempotent_ = true;
     }
 
     void setScriptedLocation(JSScript *script, jsbytecode *pc) {
         JS_ASSERT(!idempotent_);
-        this->script = script;
-        this->pc = pc;
+        script_ = script;
+        pc_ = pc;
     }
 
     void getScriptedLocation(MutableHandleScript pscript, jsbytecode **ppc) const {
-        pscript.set(script);
-        *ppc = pc;
+        pscript.set(script_);
+        *ppc = pc_;
+    }
+
+    jsbytecode *pc() const {
+        JS_ASSERT(pc_);
+        return pc_;
     }
 };
 
 //
 // Repatch caches initially generate a patchable jump to an out of line call
 // to the cache function. Stubs are attached by appending: when attaching a
 // new stub, we patch the any failure conditions in last generated stub to
 // jump to the new stub. Failure conditions in the new stub jump to the cache
@@ -600,45 +605,40 @@ class SetPropertyIC : public RepatchIonC
   protected:
     // Registers live after the cache, excluding output registers. The initial
     // value of these registers must be preserved by the cache.
     RegisterSet liveRegs_;
 
     Register object_;
     PropertyName *name_;
     ConstantOrRegister value_;
-    bool isSetName_;
     bool strict_;
 
   public:
     SetPropertyIC(RegisterSet liveRegs, Register object, PropertyName *name,
-                  ConstantOrRegister value, bool isSetName, bool strict)
+                  ConstantOrRegister value, bool strict)
       : liveRegs_(liveRegs),
         object_(object),
         name_(name),
         value_(value),
-        isSetName_(isSetName),
         strict_(strict)
     {
     }
 
     CACHE_HEADER(SetProperty)
 
     Register object() const {
         return object_;
     }
     PropertyName *name() const {
         return name_;
     }
     ConstantOrRegister value() const {
         return value_;
     }
-    bool isSetName() const {
-        return isSetName_;
-    }
     bool strict() const {
         return strict_;
     }
 
     bool attachNativeExisting(JSContext *cx, IonScript *ion, HandleObject obj, HandleShape shape);
     bool attachSetterCall(JSContext *cx, IonScript *ion, HandleObject obj,
                           HandleObject holder, HandleShape shape, void *returnAddr);
     bool attachNativeAdding(JSContext *cx, IonScript *ion, JSObject *obj, HandleShape oldshape,
@@ -773,17 +773,17 @@ class SetElementIC : public RepatchIonCa
     CACHE_HEADER(SetElement)
 
     void reset();
 
     Register object() const {
         return object_;
     }
     Register tempToUnboxIndex() const {
-        return temp_;
+        return tempToUnboxIndex_;
     }
     Register temp() const {
         return temp_;
     }
     ValueOperand index() const {
         return index_;
     }
     ConstantOrRegister value() const {
--- a/js/src/jit/IonFrameIterator.h
+++ b/js/src/jit/IonFrameIterator.h
@@ -334,16 +334,23 @@ class InlineFrameIteratorMaybeGC
   public:
     InlineFrameIteratorMaybeGC(JSContext *cx, const IonFrameIterator *iter)
       : callee_(cx),
         script_(cx)
     {
         resetOn(iter);
     }
 
+    InlineFrameIteratorMaybeGC(JSRuntime *rt, const IonFrameIterator *iter)
+      : callee_(rt),
+        script_(rt)
+    {
+        resetOn(iter);
+    }
+
     InlineFrameIteratorMaybeGC(JSContext *cx, const IonBailoutIterator *iter);
 
     InlineFrameIteratorMaybeGC(JSContext *cx, const InlineFrameIteratorMaybeGC *iter)
       : frame_(iter ? iter->frame_ : NULL),
         framesRead_(0),
         callee_(cx),
         script_(cx)
     {
--- a/js/src/jit/ParallelFunctions.cpp
+++ b/js/src/jit/ParallelFunctions.cpp
@@ -509,23 +509,29 @@ ion::PropagateAbortPar(JSScript *outermo
     outermostScript->parallelIonScript()->setHasUncompiledCallTarget();
 
     ForkJoinSlice *slice = ForkJoinSlice::Current();
     if (currentScript)
         slice->bailoutRecord->addTrace(currentScript, NULL);
 }
 
 void
-ion::CallToUncompiledScriptPar(JSFunction *func)
+ion::CallToUncompiledScriptPar(JSObject *obj)
 {
     JS_ASSERT(InParallelSection());
 
 #ifdef DEBUG
     static const int max_bound_function_unrolling = 5;
 
+    if (!obj->is<JSFunction>()) {
+        Spew(SpewBailouts, "Call to non-function");
+        return;
+    }
+
+    JSFunction *func = &obj->as<JSFunction>();
     if (func->hasScript()) {
         JSScript *script = func->nonLazyScript();
         Spew(SpewBailouts, "Call to uncompiled script: %p:%s:%d",
              script, script->filename(), script->lineno);
     } else if (func->isInterpretedLazy()) {
         Spew(SpewBailouts, "Call to uncompiled lazy script");
     } else if (func->isBoundFunction()) {
         int depth = 0;
--- a/js/src/jit/ParallelFunctions.h
+++ b/js/src/jit/ParallelFunctions.h
@@ -78,14 +78,14 @@ ParallelResult InitRestParameterPar(Fork
 void AbortPar(ParallelBailoutCause cause, JSScript *outermostScript, JSScript *currentScript,
               jsbytecode *bytecode);
 void PropagateAbortPar(JSScript *outermostScript, JSScript *currentScript);
 
 void TraceLIR(uint32_t bblock, uint32_t lir, uint32_t execModeInt,
               const char *lirOpName, const char *mirOpName,
               JSScript *script, jsbytecode *pc);
 
-void CallToUncompiledScriptPar(JSFunction *func);
+void CallToUncompiledScriptPar(JSObject *obj);
 
 } // namespace ion
 } // namespace js
 
 #endif /* jit_ParallelFunctions_h */
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -392,32 +392,34 @@ StringFromCharCode(JSContext *cx, int32_
     if (StaticStrings::hasUnit(c))
         return cx->runtime()->staticStrings.getUnit(c);
 
     return js_NewStringCopyN<CanGC>(cx, &c, 1);
 }
 
 bool
 SetProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, HandleValue value,
-            bool strict, int jsop)
+            bool strict, jsbytecode *pc)
 {
     RootedValue v(cx, value);
     RootedId id(cx, NameToId(name));
 
-    if (jsop == JSOP_SETALIASEDVAR) {
+    JSOp op = JSOp(*pc);
+
+    if (op == JSOP_SETALIASEDVAR) {
         // Aliased var assigns ignore readonly attributes on the property, as
         // required for initializing 'const' closure variables.
         Shape *shape = obj->nativeLookup(cx, name);
         JS_ASSERT(shape && shape->hasSlot());
         JSObject::nativeSetSlotWithType(cx, obj, shape, value);
         return true;
     }
 
     if (JS_LIKELY(!obj->getOps()->setProperty)) {
-        unsigned defineHow = (jsop == JSOP_SETNAME || jsop == JSOP_SETGNAME) ? DNP_UNQUALIFIED : 0;
+        unsigned defineHow = (op == JSOP_SETNAME || op == JSOP_SETGNAME) ? DNP_UNQUALIFIED : 0;
         return baseops::SetPropertyHelper(cx, obj, obj, id, defineHow, &v, strict);
     }
 
     return JSObject::setGeneric(cx, obj, obj, id, &v, strict);
 }
 
 bool
 InterruptCheck(JSContext *cx)
--- a/js/src/jit/VMFunctions.h
+++ b/js/src/jit/VMFunctions.h
@@ -609,17 +609,17 @@ bool ArrayPopDense(JSContext *cx, Handle
 bool ArrayPushDense(JSContext *cx, HandleObject obj, HandleValue v, uint32_t *length);
 bool ArrayShiftDense(JSContext *cx, HandleObject obj, MutableHandleValue rval);
 JSObject *ArrayConcatDense(JSContext *cx, HandleObject obj1, HandleObject obj2, HandleObject res);
 
 bool CharCodeAt(JSContext *cx, HandleString str, int32_t index, uint32_t *code);
 JSFlatString *StringFromCharCode(JSContext *cx, int32_t code);
 
 bool SetProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, HandleValue value,
-                 bool strict, int jsop);
+                 bool strict, jsbytecode *pc);
 
 bool InterruptCheck(JSContext *cx);
 
 HeapSlot *NewSlots(JSRuntime *rt, unsigned nslots);
 JSObject *NewCallObject(JSContext *cx, HandleScript script,
                         HandleShape shape, HandleTypeObject type, HeapSlot *slots);
 JSObject *NewStringObject(JSContext *cx, HandleString str);
 
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -630,17 +630,17 @@ js::XDRScript(XDRState<mode> *xdr, Handl
     SharedScriptData *ssd;
     if (mode == XDR_DECODE) {
         ssd = SharedScriptData::new_(cx, length, nsrcnotes, natoms);
         if (!ssd)
             return false;
         code = ssd->data;
         if (natoms != 0) {
             script->natoms = natoms;
-            script->atoms = ssd->atoms(length, nsrcnotes);
+            script->atoms = ssd->atoms();
         }
     }
 
     if (!xdr->codeBytes(code, length) || !xdr->codeBytes(code + length, nsrcnotes)) {
         if (mode == XDR_DECODE)
             js_free(ssd);
         return false;
     }
@@ -1511,25 +1511,36 @@ ScriptSource::sourceMap()
 
 SharedScriptData *
 js::SharedScriptData::new_(ExclusiveContext *cx, uint32_t codeLength,
                            uint32_t srcnotesLength, uint32_t natoms)
 {
     uint32_t baseLength = codeLength + srcnotesLength;
     uint32_t padding = sizeof(JSAtom *) - baseLength % sizeof(JSAtom *);
     uint32_t length = baseLength + padding + sizeof(JSAtom *) * natoms;
+    JS_ASSERT(length % sizeof(JSAtom *) == 0);
 
     SharedScriptData *entry = (SharedScriptData *)cx->malloc_(length +
                                                               offsetof(SharedScriptData, data));
 
     if (!entry)
         return NULL;
+    entry->length = length;
+    entry->natoms = natoms;
     entry->marked = false;
-    entry->length = length;
     memset(entry->data + baseLength, 0, padding);
+
+    /*
+     * Call constructors to initialize the storage that will be accessed as a
+     * HeapPtrAtom array via atoms().
+     */
+    HeapPtrAtom *atoms = entry->atoms();
+    for (unsigned i = 0; i < natoms; ++i)
+        new (&atoms[i]) HeapPtrAtom();
+
     return entry;
 }
 
 /*
  * Takes ownership of its *ssd parameter and either adds it into the runtime's
  * ScriptDataTable or frees it if a matching entry already exists.
  *
  * Sets the |code| and |atoms| fields on the given JSScript.
@@ -1567,17 +1578,17 @@ SaveSharedScriptData(ExclusiveContext *c
     if (cx->isJSContext()) {
         JSRuntime *rt = cx->asJSContext()->runtime();
         if (JS::IsIncrementalGCInProgress(rt) && rt->gcIsFull)
             ssd->marked = true;
     }
 #endif
 
     script->code = ssd->data;
-    script->atoms = ssd->atoms(script->length, nsrcnotes);
+    script->atoms = ssd->atoms();
     return true;
 }
 
 static inline void
 MarkScriptData(JSRuntime *rt, const jsbytecode *bytecode)
 {
     /*
      * As an invariant, a ScriptBytecodeEntry should not be 'marked' outside of
@@ -1911,17 +1922,17 @@ JSScript::fullyInitFromEmitter(Exclusive
     if (!ssd)
         return false;
 
     jsbytecode *code = ssd->data;
     PodCopy<jsbytecode>(code, bce->prolog.code.begin(), prologLength);
     PodCopy<jsbytecode>(code + prologLength, bce->code().begin(), mainLength);
     if (!FinishTakingSrcNotes(cx, bce, (jssrcnote *)(code + script->length)))
         return false;
-    InitAtomMap(bce->atomIndices.getMap(), ssd->atoms(script->length, nsrcnotes));
+    InitAtomMap(bce->atomIndices.getMap(), ssd->atoms());
 
     if (!SaveSharedScriptData(cx, script, ssd, nsrcnotes))
         return false;
 
     uint32_t nfixed = bce->sc->isFunctionBox() ? script->bindings.numVars() : 0;
     JS_ASSERT(nfixed < SLOTNO_LIMIT);
     script->nfixed = uint16_t(nfixed);
     if (script->nfixed + bce->maxStackDepth >= JS_BIT(16)) {
@@ -2789,17 +2800,17 @@ JSScript::markChildren(JSTracer *trc)
         MarkObject(trc, &function_, "function");
 
     if (enclosingScopeOrOriginalFunction_)
         MarkObject(trc, &enclosingScopeOrOriginalFunction_, "enclosing");
 
     if (IS_GC_MARKING_TRACER(trc)) {
         compartment()->mark();
 
-        if (code)
+        if (code || natoms)
             MarkScriptData(trc->runtime, code);
     }
 
     bindings.trace(trc);
 
     if (hasAnyBreakpointsOrStepMode()) {
         for (unsigned i = 0; i < length; i++) {
             BreakpointSite *site = debugScript()->breakpoints[i];
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -1380,32 +1380,37 @@ struct SourceCompressionToken
 extern void
 CallNewScriptHook(JSContext *cx, JS::HandleScript script, JS::HandleFunction fun);
 
 extern void
 CallDestroyScriptHook(FreeOp *fop, JSScript *script);
 
 struct SharedScriptData
 {
+    uint32_t length;
+    uint32_t natoms;
     bool marked;
-    uint32_t length;
     jsbytecode data[1];
 
     static SharedScriptData *new_(ExclusiveContext *cx, uint32_t codeLength,
                                   uint32_t srcnotesLength, uint32_t natoms);
 
-    HeapPtrAtom *atoms(uint32_t codeLength, uint32_t srcnotesLength) {
-        uint32_t length = codeLength + srcnotesLength;
-        return reinterpret_cast<HeapPtrAtom *>(data + length + sizeof(JSAtom *) -
-                                               length % sizeof(JSAtom *));
+    HeapPtrAtom *atoms() {
+        if (!natoms)
+            return NULL;
+        return reinterpret_cast<HeapPtrAtom *>(data + length - sizeof(JSAtom *) * natoms);
     }
 
     static SharedScriptData *fromBytecode(const jsbytecode *bytecode) {
         return (SharedScriptData *)(bytecode - offsetof(SharedScriptData, data));
     }
+
+  private:
+    SharedScriptData() MOZ_DELETE;
+    SharedScriptData(const SharedScriptData&) MOZ_DELETE;
 };
 
 struct ScriptBytecodeHasher
 {
     struct Lookup
     {
         jsbytecode          *code;
         uint32_t            length;
--- a/js/src/tests/browser.js
+++ b/js/src/tests/browser.js
@@ -341,17 +341,17 @@ function jsTestDriverBrowserInit()
     if (properties.test.match(/^js1_6/))
     {
       properties.version = '1.6';
     }
     else if (properties.test.match(/^js1_7/))
     {
       properties.version = '1.7';
     }
-    else if (properties.test.match(/^js1_8|^ecma_6/))
+    else if (properties.test.match(/^js1_8/))
     {
       properties.version = '1.8';
     }
   }
 
   // default to language=type;text/javascript. required for
   // reftest style manifests.
   if (!properties.language)
--- a/js/src/tests/ecma_6/Math/acosh-approx.js
+++ b/js/src/tests/ecma_6/Math/acosh-approx.js
@@ -257,17 +257,17 @@ var cosh_data = [
     [48862560256, 25.305424481799395],
     [113763549184, 26.150535181949436],
     [161334755328, 26.499894449532565],
     [321933279232, 27.19075733422632],
     [715734122496, 27.989721778208146],
     [1875817529344, 28.953212876533797]
 ];
 
-for (let [x, y] of cosh_data)
+for (var [x, y] of cosh_data)
     assertNear(Math.acosh(x), y);
 
 for (var i = 0; i <= 100; i++) {
     var x = (i - 50) / 5;
     var y = Math.cosh(x);
     var z = Math.acosh(y);
     assertNear(z, Math.abs(x));
 }
--- a/js/src/tests/ecma_6/Math/asinh-approx.js
+++ b/js/src/tests/ecma_6/Math/asinh-approx.js
@@ -277,17 +277,17 @@ var sinh_data = [
     [60601991168, 25.520740767599584],
     [134018236416, 26.31438890085422],
     [204864946176, 26.73876398039979],
     [284346286080, 27.06660583008718],
     [914576637952, 28.234874284944635],
     [1581915832320, 28.78280496108106]
 ];
 
-for (let [x, y] of sinh_data)
+for (var [x, y] of sinh_data)
     assertNear(Math.asinh(x), y);
 
 for (var i = 0; i <= 80; i++) {
     var x = (i - 40) / 4;
     var y = Math.sinh(x);
     var z = Math.asinh(y);
     assertNear(z, x);
 }
--- a/js/src/tests/ecma_6/Math/atanh-approx.js
+++ b/js/src/tests/ecma_6/Math/atanh-approx.js
@@ -264,15 +264,15 @@ var tanh_data = [
     [0.9928233623504639, 2.8132383539094192],
     [1e-300, 1e-300],
     [0.00001, 0.000010000000000333334],
     [0.3, 0.3095196042031117],
     [1e-30, 1e-30],
     [1e-10, 1e-10],
 ];
 
-for (let [x, y] of tanh_data)
+for (var [x, y] of tanh_data)
     assertNear(Math.atanh(x), y);
 
 assertNear(Math.atanh(+3 / 5), +Math.log(2));
 assertNear(Math.atanh(-3 / 5), -Math.log(2));
 
 reportCompare(0, 0, "ok");
--- a/js/src/tests/ecma_6/Math/cbrt-approx.js
+++ b/js/src/tests/ecma_6/Math/cbrt-approx.js
@@ -6,13 +6,13 @@ assertNear(Math.cbrt(-1e-300), -1e-100);
 
 var cbrt_data = [
     [ Math.E, 1.3956124250860895 ], 
     [ Math.PI, 1.4645918875615231 ], 
     [ Math.LN2, 0.8849970445005177 ], 
     [ Math.SQRT2, 1.1224620483093728 ]
 ];
 
-for (let [x, y] of cbrt_data)
+for (var [x, y] of cbrt_data)
     assertNear(Math.cbrt(x), y);
 
 reportCompare(0, 0, "ok");
 
--- a/js/src/tests/ecma_6/Math/cosh-approx.js
+++ b/js/src/tests/ecma_6/Math/cosh-approx.js
@@ -264,12 +264,12 @@ var cosh_data = [
     [25.305424481799395, 48862560256.00005],
     [26.150535181949436, 113763549183.99998],
     [26.499894449532565, 161334755328.00018],
     [27.19075733422632,  321933279232.0004],
     [27.989721778208146, 715734122496],
     [28.953212876533797, 1875817529343.9976],
 ];
 
-for (let [x, y] of cosh_data)
+for (var [x, y] of cosh_data)
     assertNear(Math.cosh(x), y);
 
 reportCompare(0, 0, "ok");
--- a/js/src/tests/ecma_6/Math/expm1-approx.js
+++ b/js/src/tests/ecma_6/Math/expm1-approx.js
@@ -13,12 +13,12 @@ var expm1_data = [
     [ 6.261923313140869e-30, 6.261923313140869e-30 ],
     [ 7.09962844069878e-15, 7.099628440698805e-15 ],
     [ 1.3671879628418538e-12, 1.3671879628427884e-12 ],
     [ 2.114990849122478e-10, 2.1149908493461373e-10 ],
     [ 1.6900931765206906e-8, 1.6900931908027652e-8 ],
     [ 0.0000031404608812881633, 0.0000031404658125405988 ]
 ];
 
-for (let [x, y] of expm1_data)
+for (var [x, y] of expm1_data)
     assertNear(Math.expm1(x), y);
 
 reportCompare(0, 0, "ok");
--- a/js/src/tests/ecma_6/Math/hypot-exact.js
+++ b/js/src/tests/ecma_6/Math/hypot-exact.js
@@ -1,13 +1,13 @@
 // Properties of Math.hypot that are guaranteed by the spec.
 
 // If any argument is +∞, the result is +∞.
 // If any argument is −∞, the result is +∞.
-for (let inf of [Infinity, -Infinity]) {
+for (var inf of [Infinity, -Infinity]) {
     assertEq(Math.hypot(inf, 0), Infinity);
     assertEq(Math.hypot(0, inf), Infinity);
     assertEq(Math.hypot(inf, inf), Infinity);
     assertEq(Math.hypot(inf, -inf), Infinity);
 
     assertEq(Math.hypot(inf, -0), Infinity);
     assertEq(Math.hypot(-0, inf), Infinity);
     assertEq(Math.hypot(inf, Math.MIN_VALUE), Infinity);
--- a/js/src/tests/ecma_6/Math/log1p-approx.js
+++ b/js/src/tests/ecma_6/Math/log1p-approx.js
@@ -9,12 +9,12 @@ var log1p_data = [
     [ 1.3671879628418538e-12, 1.3671879628409192e-12 ],
     [ 2.114990849122478e-10, 2.1149908488988187e-10 ],
     [ 1.6900931765206906e-8, 1.690093162238616e-8 ],
     [ 0.0000709962844069878, 0.00007099376429006658 ],
     [ 0.0016793412882520897, 0.00167793277137076 ],
     [ 0.011404608812881634, 0.011340066517988035 ],
 ];
 
-for (let [x, y] of log1p_data)
+for (var [x, y] of log1p_data)
     assertNear(Math.log1p(x), y);
 
 reportCompare(0, 0, "ok");
--- a/js/src/tests/ecma_6/Math/sinh-approx.js
+++ b/js/src/tests/ecma_6/Math/sinh-approx.js
@@ -284,13 +284,13 @@ var sinh_data = [
     [25.520740767599584, 60601991168.00004],
     [26.31438890085422,  134018236416.00002],
     [26.73876398039979,  204864946175.99973],
     [27.06660583008718,  284346286080.00024],
     [28.234874284944635, 914576637951.9989],
     [28.78280496108106,  1581915832319.9973]
 ];
 
-for (let [x, y] of sinh_data)
+for (var [x, y] of sinh_data)
     assertNear(Math.sinh(x), y);
 
 reportCompare(0, 0, "ok");
 
--- a/js/src/tests/ecma_6/Math/tanh-approx.js
+++ b/js/src/tests/ecma_6/Math/tanh-approx.js
@@ -266,12 +266,12 @@ var tanh_data = [
     [0.9928233623504639, 2.8132383539094192],
     [1e-300, 1e-300],
     [0.00001, 0.000010000000000333334],
     [0.3, 0.3095196042031117],
     [1e-30, 1e-30],
     [1e-10, 1e-10],
 ];
 
-for (let [x, y] of tanh_data)
+for (var [x, y] of tanh_data)
     assertNear(Math.tanh(y), x);
 
 reportCompare(0, 0, "ok");
--- a/js/src/tests/ecma_6/shell.js
+++ b/js/src/tests/ecma_6/shell.js
@@ -1,12 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- */
-
-// explicitly turn on js185
-if (typeof version != 'undefined')
-{
-  version(185);
-}
-
--- a/layout/base/DisplayItemClip.cpp
+++ b/layout/base/DisplayItemClip.cpp
@@ -2,17 +2,16 @@
  * 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 "DisplayItemClip.h"
 
 #include "gfxContext.h"
 #include "nsPresContext.h"
-#include "nsDisplayList.h"
 #include "nsCSSRendering.h"
 #include "nsLayoutUtils.h"
 
 namespace mozilla {
 
 void
 DisplayItemClip::SetTo(const nsRect& aRect)
 {
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -7,40 +7,29 @@
 
 #include "FrameLayerBuilder.h"
 
 #include "nsDisplayList.h"
 #include "nsPresContext.h"
 #include "nsLayoutUtils.h"
 #include "Layers.h"
 #include "BasicLayers.h"
-#include "nsSubDocumentFrame.h"
-#include "nsCSSRendering.h"
-#include "nsCSSFrameConstructor.h"
 #include "gfxUtils.h"
 #include "nsRenderingContext.h"
 #include "MaskLayerImageCache.h"
 #include "nsIScrollableFrame.h"
 #include "nsPrintfCString.h"
 #include "LayerTreeInvalidation.h"
 #include "nsSVGIntegrationUtils.h"
 
-#include "mozilla/Preferences.h"
 #include "GeckoProfiler.h"
 #include "mozilla/gfx/Tools.h"
 
-#include "nsAnimationManager.h"
-#include "nsTransitionManager.h"
 #include <algorithm>
 
-#ifdef DEBUG
-#include <stdio.h>
-//#define DEBUG_DISPLAY_ITEM_DATA
-#endif
-
 using namespace mozilla::layers;
 using namespace mozilla::gfx;
 
 namespace mozilla {
 
 FrameLayerBuilder::DisplayItemData::DisplayItemData(LayerManagerData* aParent, uint32_t aKey, 
                                                     Layer* aLayer, LayerState aLayerState, uint32_t aGeneration)
 
--- a/layout/base/FrameLayerBuilder.h
+++ b/layout/base/FrameLayerBuilder.h
@@ -6,26 +6,24 @@
 #ifndef FRAMELAYERBUILDER_H_
 #define FRAMELAYERBUILDER_H_
 
 #include "nsTHashtable.h"
 #include "nsHashKeys.h"
 #include "nsTArray.h"
 #include "nsRegion.h"
 #include "nsIFrame.h"
-#include "nsDisplayListInvalidation.h"
-#include "LayerTreeInvalidation.h"
 #include "ImageLayers.h"
 #include "DisplayItemClip.h"
 
 class nsDisplayListBuilder;
 class nsDisplayList;
 class nsDisplayItem;
 class gfxContext;
-class nsRootPresContext;
+class nsDisplayItemGeometry;
 
 namespace mozilla {
 namespace layers {
 class ContainerLayer;
 class LayerManager;
 class ThebesLayer;
 }
 
--- a/layout/base/FramePropertyTable.cpp
+++ b/layout/base/FramePropertyTable.cpp
@@ -2,18 +2,16 @@
  * 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 "FramePropertyTable.h"
 
 #include "mozilla/MemoryReporting.h"
 
-#include "prlog.h"
-
 namespace mozilla {
 
 void
 FramePropertyTable::Set(nsIFrame* aFrame, const FramePropertyDescriptor* aProperty,
                         void* aValue)
 {
   NS_ASSERTION(aFrame, "Null frame?");
   NS_ASSERTION(aProperty, "Null property?");
--- a/layout/base/MaskLayerImageCache.h
+++ b/layout/base/MaskLayerImageCache.h
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 20; 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/. */
 
 #ifndef MASKLAYERIMAGECACHE_H_
 #define MASKLAYERIMAGECACHE_H_
 
-#include "FrameLayerBuilder.h"
+#include "gfxMatrix.h"
 #include "DisplayItemClip.h"
 #include "nsPresContext.h"
 
 namespace mozilla {
 
 namespace layers {
 class ImageContainer;
 }
--- a/layout/base/PaintTracker.h
+++ b/layout/base/PaintTracker.h
@@ -1,16 +1,16 @@
 /* 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_PaintTracker_h
 #define mozilla_PaintTracker_h
 
-#include "nscore.h"
+#include "mozilla/Attributes.h"
 #include "nsDebug.h"
 
 namespace mozilla {
 
 class MOZ_STACK_CLASS PaintTracker
 {
 public:
   PaintTracker() {
--- a/layout/base/PositionedEventTargeting.h
+++ b/layout/base/PositionedEventTargeting.h
@@ -1,19 +1,20 @@
 /* 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_PositionedEventTargeting_h
 #define mozilla_PositionedEventTargeting_h
 
-#include "nsPoint.h"
-#include "nsGUIEvent.h"
+#include <stdint.h>
 
 class nsIFrame;
+class nsGUIEvent;
+struct nsPoint;
 
 namespace mozilla {
 
 enum {
   INPUT_IGNORE_ROOT_SCROLL_FRAME = 0x01
 };
 /**
  * Finds the target frame for a pointer event given the event type and location.
--- a/layout/base/RestyleTracker.cpp
+++ b/layout/base/RestyleTracker.cpp
@@ -4,18 +4,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * A class which manages pending restyles.  This handles keeping track
  * of what nodes restyles need to happen on and so forth.
  */
 
 #include "RestyleTracker.h"
-#include "nsCSSFrameConstructor.h"
 #include "nsStyleChangeList.h"
+#include "RestyleManager.h"
 #include "GeckoProfiler.h"
 
 namespace mozilla {
 
 inline nsIDocument*
 RestyleTracker::Document() const {
   return mRestyleManager->PresContext()->Document();
 }
--- a/layout/base/RestyleTracker.h
+++ b/layout/base/RestyleTracker.h
@@ -9,17 +9,16 @@
  */
 
 #ifndef mozilla_RestyleTracker_h
 #define mozilla_RestyleTracker_h
 
 #include "mozilla/dom/Element.h"
 #include "nsDataHashtable.h"
 #include "nsIFrame.h"
-#include "nsTPriorityQueue.h"
 #include "mozilla/SplayTree.h"
 
 namespace mozilla {
 
 class RestyleManager;
 
 /** 
  * Helper class that collects a list of frames that need
--- a/layout/base/StackArena.cpp
+++ b/layout/base/StackArena.cpp
@@ -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/. */
 
 #include "StackArena.h"
-
-#include "mozilla/MemoryReporting.h"
+#include "nsAlgorithm.h"
+#include "nsDebug.h"
 
 namespace mozilla {
 
 #define STACK_ARENA_MARK_INCREMENT 50
 /* a bit under 4096, for malloc overhead */
 #define STACK_ARENA_BLOCK_INCREMENT 4044
 
 /**A block of memory that the stack will 
--- a/layout/base/StackArena.h
+++ b/layout/base/StackArena.h
@@ -1,16 +1,16 @@
 /* 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 "nsError.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/MemoryReporting.h"
-#include "nsAlgorithm.h"
-#include "nsDebug.h"
+#include "mozilla/NullPtr.h"
 
 namespace mozilla {
 
 struct StackBlock;
 struct StackMark;
 class AutoStackArena;
  
 /**
--- a/layout/base/nsBidi.cpp
+++ b/layout/base/nsBidi.cpp
@@ -2,17 +2,17 @@
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifdef IBMBIDI
 
 #include "nsBidi.h"
 #include "nsUnicodeProperties.h"
-#include "nsCRT.h"
+#include "nsCRTGlue.h"
 
 using namespace mozilla::unicode;
 
 // These are #defined in <sys/regset.h> under Solaris 10 x86
 #undef CS
 #undef ES
 
 /*  Comparing the description of the Bidi algorithm with this implementation
--- a/layout/base/nsBidi.h
+++ b/layout/base/nsBidi.h
@@ -2,18 +2,16 @@
  *
  * 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 nsBidi_h__
 #define nsBidi_h__
 
-#include "nsCOMPtr.h"
-#include "nsString.h"
 #include "nsBidiUtils.h"
 
 // Bidi reordering engine from ICU
 /*
  * javadoc-style comments are intended to be transformed into HTML
  * using DOC++ - see
  * http://www.zib.de/Visual/software/doc++/index.html .
  *
--- a/layout/base/nsBidiPresUtils.cpp
+++ b/layout/base/nsBidiPresUtils.cpp
@@ -1,31 +1,28 @@
 /* -*- Mode: C++; 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/. */
 
 #ifdef IBMBIDI
 
 #include "nsBidiPresUtils.h"
-#include "nsTextFragment.h"
 #include "nsGkAtoms.h"
 #include "nsPresContext.h"
 #include "nsRenderingContext.h"
-#include "nsIServiceManager.h"
-#include "nsFrameManager.h"
 #include "nsBidiUtils.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsContainerFrame.h"
 #include "nsInlineFrame.h"
 #include "nsPlaceholderFrame.h"
 #include "nsFirstLetterFrame.h"
 #include "nsUnicodeProperties.h"
 #include "nsTextFrame.h"
-#include "nsStyleStructInlines.h"
+#include "nsBlockFrame.h"
 #include <algorithm>
 
 #undef NOISY_BIDI
 #undef REALLY_NOISY_BIDI
 
 using namespace mozilla;
 
 static const PRUnichar kSpace            = 0x0020;
--- a/layout/base/nsBidiPresUtils.h
+++ b/layout/base/nsBidiPresUtils.h
@@ -1,34 +1,36 @@
 /* -*- Mode: C++; 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/. */
 
-#ifdef IBMBIDI
-
 #ifndef nsBidiPresUtils_h___
 #define nsBidiPresUtils_h___
 
-#include "nsTArray.h"
+#ifdef IBMBIDI
+
 #include "nsBidi.h"
 #include "nsBidiUtils.h"
-#include "nsCOMPtr.h"
-#include "nsDataHashtable.h"
-#include "nsBlockFrame.h"
-#include "nsTHashtable.h"
+#include "nsHashKeys.h"
+#include "nsCoord.h"
 
 #ifdef DrawText
 #undef DrawText
 #endif
 
 struct BidiParagraphData;
 struct BidiLineData;
 class nsIFrame;
+class nsBlockFrame;
+class nsPresContext;
+class nsRenderingContext;
+class nsBlockInFlowLineIterator;
+template<class T> class nsTHashtable;
 
 /**
  * A structure representing some continuation state for each frame on the line,
  * used to determine the first and the last continuation frame for each
  * continuation chain on the line.
  */
 struct nsFrameContinuationState : public nsVoidPtrHashKey
 {
@@ -468,11 +470,11 @@ private:
                                      nsBidiLevel aBaseDirection,
                                      nsBidi* aBidiEngine);
 
   static void WriteReverse(const PRUnichar* aSrc,
                            uint32_t aSrcLength,
                            PRUnichar* aDest);
 };
 
-#endif /* nsBidiPresUtils_h___ */
+#endif // IBMBIDI
 
-#endif // IBMBIDI
+#endif /* nsBidiPresUtils_h___ */
--- a/layout/base/nsCSSColorUtils.h
+++ b/layout/base/nsCSSColorUtils.h
@@ -3,18 +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/. */
 
 /* functions that manipulate colors */
 
 #ifndef __nsCSSColorUtils_h
 #define __nsCSSColorUtils_h
 
-#include "mozilla/MathAlgorithms.h"
-
 #include "nsColor.h"
 
 // "Sufficient contrast" is determined by
 // "Techniques For Accessibility Evalution And Repair Tools".
 // See http://www.w3.org/TR/AERT#color-contrast
 #define NS_SUFFICIENT_LUMINOSITY_DIFFERENCE 125000
 #define NS_LUMINOSITY_DIFFERENCE(a, b) \
           int32_t(mozilla::Abs(NS_GetLuminosity(a) - NS_GetLuminosity(b)))
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -12,119 +12,88 @@
 #include "nsCSSFrameConstructor.h"
 
 #include "mozilla/AutoRestore.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/dom/HTMLSelectElement.h"
 #include "mozilla/Likely.h"
 #include "mozilla/LinkedList.h"
 #include "nsAbsoluteContainingBlock.h"
-#include "nsCRT.h"
 #include "nsIAtom.h"
-#include "nsIURL.h"
-#include "nsIHTMLDocument.h"
-#include "nsIStyleRule.h"
 #include "nsIFrame.h"
 #include "nsGkAtoms.h"
 #include "nsPresContext.h"
-#include "nsILinkHandler.h"
 #include "nsIDocument.h"
 #include "nsTableFrame.h"
-#include "nsTableColGroupFrame.h"
 #include "nsTableColFrame.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsHTMLParts.h"
 #include "nsIPresShell.h"
 #include "nsUnicharUtils.h"
 #include "nsStyleSet.h"
 #include "nsViewManager.h"
 #include "nsEventStates.h"
 #include "nsStyleConsts.h"
-#include "nsTableOuterFrame.h"
 #include "nsIDOMXULElement.h"
 #include "nsContainerFrame.h"
 #include "nsINameSpaceManager.h"
 #include "nsIComboboxControlFrame.h"
 #include "nsIListControlFrame.h"
-#include "nsISelectControlFrame.h"
 #include "nsIDOMCharacterData.h"
-#include "nsIDOMHTMLImageElement.h"
 #include "nsPlaceholderFrame.h"
 #include "nsTableRowGroupFrame.h"
 #include "nsIFormControl.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsTextFragment.h"
 #include "nsIAnonymousContentCreator.h"
-#include "nsLegendFrame.h"
-#include "nsIContentIterator.h"
-#include "nsBoxLayoutState.h"
 #include "nsBindingManager.h"
 #include "nsXBLBinding.h"
-#include "nsITheme.h"
-#include "nsContentCID.h"
 #include "nsContentUtils.h"
 #include "nsIScriptError.h"
-#include "nsIDocShell.h"
+#ifdef XP_MACOSX
 #include "nsIDocShellTreeItem.h"
-#include "nsObjectFrame.h"
-#include "nsRuleNode.h"
-#include "nsIDOMMutationEvent.h"
+#endif
 #include "ChildIterator.h"
-#include "nsCSSRendering.h"
 #include "nsError.h"
 #include "nsLayoutUtils.h"
 #include "nsAutoPtr.h"
 #include "nsBoxFrame.h"
 #include "nsBoxLayout.h"
 #include "nsFlexContainerFrame.h"
 #include "nsImageFrame.h"
 #include "nsIObjectLoadingContent.h"
-#include "nsIPrincipal.h"
-#include "nsBox.h"
 #include "nsTArray.h"
 #include "nsGenericDOMDataNode.h"
 #include "mozilla/dom/Element.h"
-#include "FrameLayerBuilder.h"
 #include "nsAutoLayoutPhase.h"
-#include "nsCSSRenderingBorders.h"
-#include "nsRenderingContext.h"
 #include "nsStyleStructInlines.h"
-#include "nsViewportFrame.h"
 #include "nsPageContentFrame.h"
-#include <algorithm>
+#include "RestyleManager.h"
 
 #ifdef MOZ_XUL
 #include "nsIRootBox.h"
-#include "nsIDOMXULCommandDispatcher.h"
-#include "nsIDOMXULDocument.h"
-#include "nsIXULDocument.h"
 #endif
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
-#include "nsInlineFrame.h"
 #include "nsBlockFrame.h"
 
 #include "nsIScrollableFrame.h"
 
 #include "nsXBLService.h"
 
 #undef NOISY_FIRST_LETTER
 
 #include "nsMathMLParts.h"
 #include "mozilla/dom/SVGTests.h"
-#include "nsSVGEffects.h"
-#include "nsSVGTextFrame2.h"
-#include "nsSVGTextPathFrame.h"
 #include "nsSVGUtils.h"
 
 #include "nsRefreshDriver.h"
 #include "nsRuleProcessorData.h"
-#include "GeckoProfiler.h"
 #include "nsTextNode.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // An alias for convenience.
 static const nsIFrame::ChildListID kPrincipalList = nsIFrame::kPrincipalList;
 
@@ -192,23 +161,20 @@ nsIFrame*
 NS_NewSVGFEContainerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewSVGFELeafFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewSVGFEImageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 nsIFrame*
 NS_NewSVGFEUnstyledLeafFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
-#include "nsIScrollable.h"
 #include "nsINodeInfo.h"
 #include "prenv.h"
-#include "nsWidgetsCID.h"
 #include "nsNodeInfoManager.h"
 #include "nsContentCreatorFunctions.h"
-#include "nsIServiceManager.h"
 
 #ifdef DEBUG
 // Set the environment variable GECKO_FRAMECTOR_DEBUG_FLAGS to one or
 // more of the following flags (comma separated) for handy debug
 // output.
 static bool gNoisyContentUpdates = false;
 static bool gReallyNoisyContentUpdates = false;
 static bool gNoisyInlineConstruction = false;
@@ -225,17 +191,16 @@ static FrameCtorDebugFlags gFlags[] = {
 };
 
 #define NUM_DEBUG_FLAGS (sizeof(gFlags) / sizeof(gFlags[0]))
 #endif
 
 
 #ifdef MOZ_XUL
 #include "nsMenuFrame.h"
-#include "nsMenuPopupFrame.h"
 #include "nsPopupSetFrame.h"
 #include "nsTreeColFrame.h"
 #include "nsIBoxObject.h"
 #include "nsPIListBoxObject.h"
 #include "nsListBoxBodyFrame.h"
 #include "nsListItemFrame.h"
 #include "nsXULLabelFrame.h"
 
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -12,34 +12,25 @@
 #define nsCSSFrameConstructor_h___
 
 #include "mozilla/Attributes.h"
 
 #include "nsCOMPtr.h"
 #include "nsILayoutHistoryState.h"
 #include "nsQuoteList.h"
 #include "nsCounterManager.h"
-#include "nsHashKeys.h"
-#include "nsThreadUtils.h"
 #include "nsCSSPseudoElements.h"
 #include "nsIAnonymousContentCreator.h"
 #include "nsFrameManager.h"
-#include "RestyleManager.h"
 
-class nsIDocument;
 struct nsFrameItems;
 struct nsAbsoluteItems;
 class nsStyleContext;
-struct nsStyleContent;
 struct nsStyleDisplay;
-class nsIPresShell;
 class nsIDOMHTMLSelectElement;
-class nsPresContext;
-class nsStyleChangeList;
-class nsIFrame;
 struct nsGenConInitializer;
 
 class nsICSSAnonBoxPseudo;
 class nsPageContentFrame;
 struct PendingBinding;
 
 class nsFrameConstructorState;
 class nsFrameConstructorSaveState;
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -6,49 +6,40 @@
 
 /* utility functions for drawing borders and backgrounds */
 
 #include <ctime>
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/HashFunctions.h"
 #include "mozilla/MathAlgorithms.h"
-#include "mozilla/Types.h"
 
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsIFrame.h"
 #include "nsPoint.h"
 #include "nsRect.h"
-#include "nsViewManager.h"
 #include "nsIPresShell.h"
 #include "nsFrameManager.h"
 #include "nsStyleContext.h"
 #include "nsGkAtoms.h"
 #include "nsCSSAnonBoxes.h"
-#include "nsTransform2D.h"
 #include "nsIContent.h"
 #include "nsIDocumentInlines.h"
 #include "nsIScrollableFrame.h"
 #include "imgIRequest.h"
 #include "imgIContainer.h"
 #include "ImageOps.h"
 #include "nsCSSRendering.h"
 #include "nsCSSColorUtils.h"
 #include "nsITheme.h"
-#include "nsThemeConstants.h"
-#include "nsIServiceManager.h"
 #include "nsLayoutUtils.h"
-#include "nsINameSpaceManager.h"
 #include "nsBlockFrame.h"
 #include "gfxContext.h"
 #include "nsRenderingContext.h"
-#include "nsIInterfaceRequestorUtils.h"
-#include "gfxPlatform.h"
-#include "gfxImageSurface.h"
 #include "nsStyleStructInlines.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsCSSProps.h"
 #include "nsContentUtils.h"
 #include "nsSVGEffects.h"
 #include "nsSVGIntegrationUtils.h"
 #include "gfxDrawable.h"
 #include "GeckoProfiler.h"
--- a/layout/base/nsCSSRendering.h
+++ b/layout/base/nsCSSRendering.h
@@ -3,23 +3,20 @@
  * 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/. */
 
 /* utility functions for drawing borders and backgrounds */
 
 #ifndef nsCSSRendering_h___
 #define nsCSSRendering_h___
 
-#include "nsStyleConsts.h"
 #include "gfxBlur.h"
 #include "gfxContext.h"
-#include "gfxImageSurface.h"
 #include "nsLayoutUtils.h"
 
-struct nsPoint;
 class nsStyleContext;
 class nsPresContext;
 class nsRenderingContext;
 
 namespace mozilla {
 
 // A CSSSizeOrRatio represents a (possibly partially specified) size for use
 // in computing image sizes. Either or both of the width and height might be
--- a/layout/base/nsCSSRenderingBorders.cpp
+++ b/layout/base/nsCSSRenderingBorders.cpp
@@ -1,38 +1,21 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 // vim:cindent:ts=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 "nsStyleConsts.h"
-#include "nsPoint.h"
-#include "nsRect.h"
-#include "nsViewManager.h"
-#include "nsFrameManager.h"
-#include "nsStyleContext.h"
-#include "nsGkAtoms.h"
-#include "nsCSSAnonBoxes.h"
-#include "nsTransform2D.h"
-#include "nsIContent.h"
-#include "nsIScrollableFrame.h"
-#include "imgIRequest.h"
-#include "imgIContainer.h"
-#include "nsCSSRendering.h"
 #include "nsCSSColorUtils.h"
-#include "nsITheme.h"
-#include "nsThemeConstants.h"
-#include "nsIServiceManager.h"
-#include "nsLayoutUtils.h"
-#include "nsINameSpaceManager.h"
-#include "nsBlockFrame.h"
 #include "GeckoProfiler.h"
 #include "nsExpirationTracker.h"
 #include "RoundedRect.h"
+#include "nsClassHashtable.h"
+#include "nsStyleStruct.h"
 
 #include "gfxContext.h"
 
 #include "nsCSSRenderingBorders.h"
 
 #include "mozilla/gfx/2D.h"
 #include "gfx2DGlue.h"
 #include <algorithm>
--- a/layout/base/nsCSSRenderingBorders.h
+++ b/layout/base/nsCSSRenderingBorders.h
@@ -3,20 +3,18 @@
 /* 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 NS_CSS_RENDERING_BORDERS_H
 #define NS_CSS_RENDERING_BORDERS_H
 
 #include "nsColor.h"
-#include "nsStyleStruct.h"
 
-#include "gfxContext.h"
-#include "mozilla/gfx/2D.h"
+class gfxContext;
 
 // define this to enable a bunch of debug dump info
 #undef DEBUG_NEW_BORDERS
 
 //thickness of dashed line relative to dotted line
 #define DOT_LENGTH  1           //square
 #define DASH_LENGTH 3           //3 times longer than dot
 
--- a/layout/base/nsCaret.cpp
+++ b/layout/base/nsCaret.cpp
@@ -5,33 +5,28 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* the caret is the text cursor used, e.g., when editing */
 
 #include "nsCOMPtr.h"
 
 #include "nsITimer.h"
 
-#include "nsIComponentManager.h"
-#include "nsIServiceManager.h"
 #include "nsFrameSelection.h"
 #include "nsIFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsIDOMNode.h"
-#include "nsIDOMRange.h"
 #include "nsISelection.h"
 #include "nsISelectionPrivate.h"
-#include "nsIDOMCharacterData.h"
 #include "nsIContent.h"
 #include "nsIPresShell.h"
 #include "nsRenderingContext.h"
 #include "nsPresContext.h"
 #include "nsBlockFrame.h"
 #include "nsISelectionController.h"
-#include "nsDisplayList.h"
 #include "nsCaret.h"
 #include "nsTextFrame.h"
 #include "nsXULPopupManager.h"
 #include "nsMenuPopupFrame.h"
 #include "nsTextFragment.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/Selection.h"
--- a/layout/base/nsCaret.h
+++ b/layout/base/nsCaret.h
@@ -6,22 +6,22 @@
 
 /* the caret is the text cursor used, e.g., when editing */
 
 #ifndef nsCaret_h__
 #define nsCaret_h__
 
 #include "nsCoord.h"
 #include "nsISelectionListener.h"
-#include "nsITimer.h"
-#include "nsWeakPtr.h"
+#include "nsIWeakReferenceUtils.h"
 #include "nsFrameSelection.h"
 
 class nsRenderingContext;
 class nsDisplayListBuilder;
+class nsITimer;
 
 //-----------------------------------------------------------------------------
 class nsCaret : public nsISelectionListener
 {
   public:
 
                   nsCaret();
     virtual       ~nsCaret();
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -5,43 +5,36 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
 /*
  * structures that represent things to be painted (ordered in z-order),
  * used during painting and hit testing
  */
 
-// include PBrowserChild explicitly because TabChild won't include it
-// because we're in layout :(
-#include "mozilla/dom/PBrowserChild.h"
 #include "mozilla/dom/TabChild.h"
-
 #include "mozilla/layers/PLayerTransaction.h"
 
 #include "nsDisplayList.h"
 
 #include "nsCSSRendering.h"
 #include "nsRenderingContext.h"
 #include "nsISelectionController.h"
 #include "nsIPresShell.h"
 #include "nsRegion.h"
-#include "nsFrameManager.h"
-#include "gfxContext.h"
 #include "nsStyleStructInlines.h"
 #include "nsStyleTransformMatrix.h"
 #include "gfxMatrix.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsIScrollableFrame.h"
 #include "nsThemeConstants.h"
 #include "LayerTreeInvalidation.h"
 
 #include "imgIContainer.h"
-#include "nsIInterfaceRequestorUtils.h"
 #include "BasicLayers.h"
 #include "nsBoxFrame.h"
 #include "nsViewportFrame.h"
 #include "nsSubDocumentFrame.h"
 #include "nsSVGEffects.h"
 #include "nsSVGElement.h"
 #include "nsSVGClipPathFrame.h"
 #include "GeckoProfiler.h"
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -13,37 +13,33 @@
 #ifndef NSDISPLAYLIST_H_
 #define NSDISPLAYLIST_H_
 
 #include "mozilla/Attributes.h"
 #include "nsCOMPtr.h"
 #include "nsIFrame.h"
 #include "nsPoint.h"
 #include "nsRect.h"
-#include "nsISelection.h"
 #include "nsCaret.h"
 #include "plarena.h"
 #include "nsRegion.h"
 #include "FrameLayerBuilder.h"
-#include "nsThemeConstants.h"
 #include "nsLayoutUtils.h"
 #include "nsDisplayListInvalidation.h"
 #include "DisplayListClipState.h"
 
 #include <stdint.h>
 
 #include <stdlib.h>
 #include <algorithm>
 
-class nsIPresShell;
 class nsIContent;
 class nsRenderingContext;
-class nsDeviceContext;
 class nsDisplayTableItem;
-class nsDisplayItem;
+class nsISelection;
 
 namespace mozilla {
 namespace layers {
 class ImageLayer;
 class ImageContainer;
 } //namepsace
 } //namepsace
 
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -6,69 +6,57 @@
 
 /* container for a document and its presentation */
 
 #include "nscore.h"
 #include "nsCOMPtr.h"
 #include "nsCRT.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
-#include "nsISupports.h"
 #include "nsIContent.h"
 #include "nsIContentViewerContainer.h"
 #include "nsIContentViewer.h"
 #include "nsIDocumentViewerPrint.h"
 #include "nsIDOMBeforeUnloadEvent.h"
 #include "nsIDocument.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsStyleSet.h"
-#include "nsIStyleSheet.h"
 #include "nsCSSStyleSheet.h"
 #include "nsIFrame.h"
 #include "nsSubDocumentFrame.h"
 
 #include "nsILinkHandler.h"
 #include "nsIDOMDocument.h"
 #include "nsISelectionListener.h"
 #include "nsISelectionPrivate.h"
 #include "nsIDOMHTMLDocument.h"
-#include "nsIDOMHTMLCollection.h"
 #include "nsIDOMHTMLElement.h"
-#include "nsIDOMRange.h"
-#include "nsContentCID.h"
-#include "nsLayoutCID.h"
 #include "nsContentUtils.h"
 #include "nsLayoutStylesheetCache.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/EncodingUtils.h"
 
-#include "nsIDeviceContextSpec.h"
 #include "nsViewManager.h"
 #include "nsView.h"
 
 #include "nsIPageSequenceFrame.h"
-#include "nsIURL.h"
 #include "nsNetUtil.h"
 #include "nsIContentViewerEdit.h"
 #include "nsIContentViewerFile.h"
 #include "mozilla/css/Loader.h"
 #include "nsIMarkupDocumentViewer.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
-#include "nsIDocShellTreeOwner.h"
 #include "nsIDocShell.h"
 #include "nsIBaseWindow.h"
 #include "nsILayoutHistoryState.h"
 #include "nsCharsetSource.h"
 #include "nsGUIEvent.h"
 #include "nsHTMLReflowState.h"
-#include "nsIDOMHTMLAnchorElement.h"
-#include "nsIDOMHTMLAreaElement.h"
-#include "nsIDOMHTMLLinkElement.h"
 #include "nsIImageLoadingContent.h"
 #include "nsCopySupport.h"
 #include "nsIDOMHTMLFrameSetElement.h"
 #ifdef MOZ_XUL
 #include "nsIXULDocument.h"
 #include "nsXULPopupManager.h"
 #endif
 
@@ -76,20 +64,17 @@
 
 #include "nsPIDOMWindow.h"
 #include "nsDOMNavigationTiming.h"
 #include "nsPIWindowRoot.h"
 #include "nsJSEnvironment.h"
 #include "nsFocusManager.h"
 
 #include "nsIScrollableFrame.h"
-#include "nsIHTMLDocument.h"
-#include "nsGfxCIID.h"
 #include "nsStyleSheetService.h"
-#include "nsURILoader.h"
 #include "nsRenderingContext.h"
 #include "nsILoadContext.h"
 
 #include "nsIPrompt.h"
 #include "imgIContainer.h" // image animation mode constants
 
 //--------------------------
 // Printing Include
@@ -97,69 +82,43 @@
 #ifdef NS_PRINTING
 
 #include "nsIWebBrowserPrint.h"
 
 #include "nsPrintEngine.h"
 
 // Print Options
 #include "nsIPrintSettings.h"
-#include "nsIPrintSettingsService.h"
 #include "nsIPrintOptions.h"
-#include "nsIServiceManager.h"
 #include "nsISimpleEnumerator.h"
-#include "nsXPCOM.h"
-#include "nsISupportsPrimitives.h"
 
 // PrintOptions is now implemented by PrintSettingsService
 static const char sPrintOptionsContractID[]         = "@mozilla.org/gfx/printsettings-service;1";
 
-// Printing Events
-#include "nsPrintPreviewListener.h"
-
-#include "nsIDOMHTMLFrameElement.h"
-#include "nsIDOMHTMLIFrameElement.h"
-#include "nsIDOMHTMLObjectElement.h"
 #include "nsIPluginDocument.h"
 
-// Print Progress
-#include "nsIPrintProgress.h"
-#include "nsIPrintProgressParams.h"
-
-// Print error dialog
-#include "nsIWindowWatcher.h"
-
-// Printing 
-#include "nsPagePrintTimer.h"
-
 #endif // NS_PRINTING
 
 //focus
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMEventListener.h"
 #include "nsISelectionController.h"
 
 #include "nsBidiUtils.h"
 #include "nsISHEntry.h"
 #include "nsISHistory.h"
 #include "nsISHistoryInternal.h"
 #include "nsIWebNavigation.h"
-#include "nsWeakPtr.h"
 #include "nsEventDispatcher.h"
 
 //paint forcing
-#include "prenv.h"
 #include <stdio.h>
 
-#include "nsObserverService.h"
-
 #include "mozilla/dom/Element.h"
 
-#include "jsfriendapi.h"
-
 using namespace mozilla;
 using namespace mozilla::dom;
 
 #ifdef DEBUG
 
 #undef NOISY_VIEWER
 #else
 #undef NOISY_VIEWER
--- a/layout/base/nsFrameManager.cpp
+++ b/layout/base/nsFrameManager.cpp
@@ -10,60 +10,37 @@
  * Modifications to Mozilla code or documentation identified per MPL Section 3.3
  *
  * Date             Modified by     Description of modification
  * 04/20/2000       IBM Corp.      OS/2 VisualAge build.
  */
 
 /* storage of the frame tree and information about it */
 
-#include "mozilla/DebugOnly.h"
-
 #include "nscore.h"
-#include "nsPresContext.h"
 #include "nsIPresShell.h"
-#include "nsStyleSet.h"
-#include "nsCSSFrameConstructor.h"
 #include "nsStyleContext.h"
-#include "nsStyleChangeList.h"
-#include "nsIServiceManager.h"
 #include "nsCOMPtr.h"
-#include "prthread.h"
 #include "plhash.h"
 #include "nsPlaceholderFrame.h"
 #include "nsGkAtoms.h"
-#include "nsCSSPseudoElements.h"
-#ifdef DEBUG
-#include "nsIStyleRule.h"
-#endif
 #include "nsILayoutHistoryState.h"
 #include "nsPresState.h"
-#include "nsIContent.h"
-#include "nsINameSpaceManager.h"
+#include "mozilla/dom/Element.h"
 #include "nsIDocument.h"
-#include "nsIScrollableFrame.h"
 
-#include "nsIDOMNodeList.h"
-#include "nsIDOMHTMLCollection.h"
-#include "nsIFormControl.h"
-#include "nsIDOMElement.h"
-#include "nsIDOMHTMLFormElement.h"
-#include "nsIForm.h"
 #include "nsContentUtils.h"
-#include "nsReadableUtils.h"
-#include "nsUnicharUtils.h"
 #include "nsError.h"
-#include "nsLayoutUtils.h"
 #include "nsAutoPtr.h"
-#include "imgIRequest.h"
 #include "nsAbsoluteContainingBlock.h"
 #include "ChildIterator.h"
 
 #include "nsFrameManager.h"
 #include "GeckoProfiler.h"
+#include "nsIStatefulFrame.h"
 
   #ifdef DEBUG
     //#define DEBUG_UNDISPLAYED_MAP
   #else
     #undef DEBUG_UNDISPLAYED_MAP
   #endif
 
 using namespace mozilla;
--- a/layout/base/nsFrameManager.h
+++ b/layout/base/nsFrameManager.h
@@ -15,18 +15,16 @@
  */
 
 /* storage of the frame tree and information about it */
 
 #ifndef _nsFrameManager_h_
 #define _nsFrameManager_h_
 
 #include "nsIFrame.h"
-#include "nsIStatefulFrame.h"
-#include "nsChangeHint.h"
 #include "nsFrameManagerBase.h"
 
 namespace mozilla {
 /**
  * Node in a linked list, containing the style for an element that
  * does not have a frame but whose parent does have a frame.
  */
 struct UndisplayedNode {
--- a/layout/base/nsFrameTraversal.h
+++ b/layout/base/nsFrameTraversal.h
@@ -1,19 +1,20 @@
 /* -*- Mode: C++; 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/. */
 #ifndef NSFRAMETRAVERSAL_H
 #define NSFRAMETRAVERSAL_H
 
 #include "mozilla/Attributes.h"
-#include "nsIFrame.h"
 #include "nsIFrameTraversal.h"
 
+class nsIFrame;
+
 nsresult NS_NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
                               nsPresContext* aPresContext,
                               nsIFrame *aStart,
                               nsIteratorType aType,
                               bool aVisual,
                               bool aLockInScrollView,
                               bool aFollowOOFs);
 
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1,34 +1,31 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 sw=2 et tw=78: */
 /* 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 "nsLayoutUtils.h"
 
-#include "base/basictypes.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Util.h"
-#include "nsIFormControlFrame.h"
 #include "nsPresContext.h"
 #include "nsIContent.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsFrameList.h"
 #include "nsGkAtoms.h"
 #include "nsIAtom.h"
 #include "nsCSSPseudoElements.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsCSSColorUtils.h"
 #include "nsView.h"
 #include "nsPlaceholderFrame.h"
 #include "nsIScrollableFrame.h"
-#include "nsCSSFrameConstructor.h"
 #include "nsIDOMEvent.h"
 #include "nsGUIEvent.h"
 #include "nsDisplayList.h"
 #include "nsRegion.h"
 #include "nsFrameManager.h"
 #include "nsBlockFrame.h"
 #include "nsBidiPresUtils.h"
 #include "imgIContainer.h"
@@ -36,66 +33,57 @@
 #include "gfxContext.h"
 #include "gfxFont.h"
 #include "nsRenderingContext.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsCSSRendering.h"
 #include "nsCxPusher.h"
 #include "nsThemeConstants.h"
 #include "nsPIDOMWindow.h"
-#include "nsIBaseWindow.h"
 #include "nsIDocShell.h"
 #include "nsIWidget.h"
 #include "gfxMatrix.h"
 #include "gfxPoint3D.h"
 #include "gfxTypes.h"
-#include "gfxUserFontSet.h"
 #include "nsTArray.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "nsICanvasRenderingContextInternal.h"
 #include "gfxPlatform.h"
 #include "nsClientRect.h"
 #include <algorithm>
 #include "mozilla/dom/HTMLVideoElement.h"
 #include "mozilla/dom/HTMLImageElement.h"
 #include "imgIRequest.h"
 #include "nsIImageLoadingContent.h"
 #include "nsCOMPtr.h"
 #include "nsCSSProps.h"
 #include "nsListControlFrame.h"
-#include "ImageLayers.h"
-#include "mozilla/arm.h"
 #include "mozilla/dom/Element.h"
 #include "nsCanvasFrame.h"
 #include "gfxDrawable.h"
 #include "gfxUtils.h"
 #include "nsDataHashtable.h"
 #include "nsTextFrame.h"
 #include "nsFontFaceList.h"
 #include "nsFontInflationData.h"
 #include "nsSVGUtils.h"
-#include "nsSVGIntegrationUtils.h"
-#include "nsSVGForeignObjectFrame.h"
-#include "nsSVGOuterSVGFrame.h"
 #include "nsSVGTextFrame2.h"
 #include "nsStyleStructInlines.h"
 #include "nsStyleTransformMatrix.h"
 
-#include "mozilla/dom/PBrowserChild.h"
-#include "mozilla/dom/TabChild.h"
 #include "mozilla/Preferences.h"
 
 #ifdef MOZ_XUL
 #include "nsXULPopupManager.h"
 #endif
 
 #include "GeckoProfiler.h"
 #include "nsAnimationManager.h"
 #include "nsTransitionManager.h"
-#include "nsViewportInfo.h"
+#include "RestyleManager.h"
 
 using namespace mozilla;
 using namespace mozilla::css;
 using namespace mozilla::dom;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
 
 #define FLEXBOX_ENABLED_PREF_NAME "layout.css.flexbox.enabled"
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -14,41 +14,38 @@ class nsIScrollableFrame;
 class nsIDOMEvent;
 class nsRegion;
 class nsDisplayListBuilder;
 class nsDisplayItem;
 class nsFontMetrics;
 class nsClientRectList;
 class nsFontFaceList;
 class nsIImageLoadingContent;
+class nsStyleContext;
+class nsBlockFrame;
+class gfxDrawable;
+class nsView;
+class imgIContainer;
 
 #include "mozilla/MemoryReporting.h"
 #include "nsChangeHint.h"
-#include "nsStyleContext.h"
 #include "nsAutoPtr.h"
-#include "nsStyleSet.h"
 #include "nsIFrame.h"
 #include "nsThreadUtils.h"
 #include "nsIPresShell.h"
 #include "nsIPrincipal.h"
 #include "gfxPattern.h"
-#include "imgIContainer.h"
 #include "nsCSSPseudoElements.h"
 #include "nsHTMLReflowState.h"
-#include "nsIFrameLoader.h"
 #include "FrameMetrics.h"
 #include "gfx3DMatrix.h"
 
 #include <limits>
 #include <algorithm>
 
-class nsBlockFrame;
-class gfxDrawable;
-class nsView;
-
 namespace mozilla {
 class SVGImageContext;
 namespace dom {
 class Element;
 class HTMLImageElement;
 class HTMLCanvasElement;
 class HTMLVideoElement;
 } // namespace dom
--- a/layout/base/nsPresArena.cpp
+++ b/layout/base/nsPresArena.cpp
@@ -14,19 +14,19 @@
 #define ALIGN_SHIFT 3
 #define PL_ARENA_CONST_ALIGN_MASK ((uintptr_t(1) << ALIGN_SHIFT) - 1)
 #include "plarena.h"
 // plarena.h needs to be included first to make it use the above
 // PL_ARENA_CONST_ALIGN_MASK in this file.
 
 #include "nsPresArena.h"
 
+#include "mozilla/MemoryChecking.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Poison.h"
-#include "nsCRT.h"
 #include "nsDebug.h"
 #include "nsArenaMemoryStats.h"
 #include "nsPrintfCString.h"
 
 // Size to use for PLArena block allocations.
 static const size_t ARENA_PAGE_SIZE = 8192;
 
 nsPresArena::nsPresArena()
--- a/layout/base/nsPresArena.h
+++ b/layout/base/nsPresArena.h
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
 /* arena allocation for the frame tree and closely-related objects */
 
 #ifndef nsPresArena_h___
 #define nsPresArena_h___
 
-#include "mozilla/MemoryChecking.h"
 #include "mozilla/MemoryReporting.h"
 #include <stdint.h>
 #include "nscore.h"
 #include "nsQueryFrame.h"
 #include "nsTArray.h"
 #include "nsTHashtable.h"
 #include "plarena.h"
 
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -7,92 +7,65 @@
 
 #include "mozilla/DebugOnly.h"
 
 #include "base/basictypes.h"
 
 #include "nsCOMPtr.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
-#include "nsILinkHandler.h"
 #include "nsIDocShell.h"
 #include "nsIContentViewer.h"
 #include "nsPIDOMWindow.h"
 #include "nsStyleSet.h"
 #include "nsIContent.h"
 #include "nsIFrame.h"
-#include "nsIURL.h"
 #include "nsIDocument.h"
 #include "nsIPrintSettings.h"
 #include "nsILanguageAtomService.h"
-#include "nsStyleContext.h"
 #include "mozilla/LookAndFeel.h"
-#include "nsIComponentManager.h"
-#include "nsIURIContentListener.h"
-#include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
-#include "nsIServiceManager.h"
-#include "nsIDOMElement.h"
-#include "nsContentPolicyUtils.h"
-#include "nsIDOMWindow.h"
-#include "nsXPIDLString.h"
 #include "nsIWeakReferenceUtils.h"
-#include "nsCSSRendering.h"
-#include "prprf.h"
 #include "nsAutoPtr.h"
 #include "nsEventStateManager.h"
 #include "nsThreadUtils.h"
 #include "nsFrameManager.h"
 #include "nsLayoutUtils.h"
 #include "nsViewManager.h"
 #include "RestyleManager.h"
 #include "nsCSSRuleProcessor.h"
-#include "nsStyleChangeList.h"
 #include "nsRuleNode.h"
 #include "nsEventDispatcher.h"
-#include "gfxUserFontSet.h"
 #include "gfxPlatform.h"
 #include "nsCSSRules.h"
 #include "nsFontFaceLoader.h"
 #include "nsEventListenerManager.h"
-#include "nsStyleStructInlines.h"
-#include "nsIAppShell.h"
 #include "prenv.h"
 #include "nsObjectFrame.h"
 #include "nsTransitionManager.h"
 #include "nsAnimationManager.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/Element.h"
 #include "nsIMessageManager.h"
-#include "FrameLayerBuilder.h"
 #include "nsDOMMediaQueryList.h"
 #include "nsSMILAnimationController.h"
 #include "mozilla/css/ImageLoader.h"
-#include "mozilla/dom/PBrowserChild.h"
 #include "mozilla/dom/TabChild.h"
-#include "RestyleManager.h"
 #include "nsRefreshDriver.h"
 #include "Layers.h"
 
-#ifdef IBMBIDI
-#include "nsBidiPresUtils.h"
-#endif // IBMBIDI
-
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
 #include "nsPIWindowRoot.h"
 #include "mozilla/Preferences.h"
 
 // Needed for Start/Stop of Image Animation
 #include "imgIContainer.h"
 #include "nsIImageLoadingContent.h"
 
-//needed for resetting of image service color
-#include "nsLayoutCID.h"
-
 #include "nsCSSParser.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::layers;
 
 uint8_t gNotifySubDocInvalidationData;
 
@@ -195,18 +168,16 @@ IsVisualCharset(const nsCString& aCharse
     return true; // visual text type
   }
   else {
     return false; // logical text type
   }
 }
 #endif // IBMBIDI
 
-#include "nsContentCID.h"
-
   // NOTE! nsPresContext::operator new() zeroes out all members, so don't
   // bother initializing members to 0.
 
 nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType)
   : mType(aType), mDocument(aDocument), mMinFontSize(0),
     mTextZoom(1.0), mFullZoom(1.0), mLastFontInflationScreenWidth(-1.0),
     mPageSize(-1, -1), mPPScale(1.0f),
     mViewportStyleOverflow(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO),
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -4,82 +4,68 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* a presentation of a document, part 1 */
 
 #ifndef nsPresContext_h___
 #define nsPresContext_h___
 
 #include "mozilla/Attributes.h"
-#include "nsISupports.h"
 #include "nsColor.h"
 #include "nsCoord.h"
 #include "nsCOMPtr.h"
 #include "nsIPresShell.h"
 #include "nsRect.h"
 #include "nsDeviceContext.h"
 #include "nsFont.h"
 #include "nsIObserver.h"
 #include "nsITimer.h"
 #include "nsCRT.h"
 #include "FramePropertyTable.h"
 #include "nsGkAtoms.h"
-#include "nsRefPtrHashtable.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsChangeHint.h"
 #include <algorithm>
 // This also pulls in gfxTypes.h, which we cannot include directly.
 #include "gfxRect.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
-#include "nsIWidget.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/TimeStamp.h"
 #include "prclist.h"
 #include "nsThreadUtils.h"
 
 #ifdef IBMBIDI
 class nsBidiPresUtils;
 #endif // IBMBIDI
 
-struct nsRect;
-
-class imgIRequest;
-
 class nsAString;
 class nsIPrintSettings;
 class nsIDocument;
 class nsILanguageAtomService;
 class nsITheme;
 class nsIContent;
-class nsFontMetrics;
 class nsIFrame;
 class nsFrameManager;
 class nsILinkHandler;
-class nsStyleContext;
 class nsIAtom;
 class nsEventStateManager;
-class nsIURI;
 class nsICSSPseudoComparator;
 struct nsStyleBackground;
 struct nsStyleBorder;
 class nsIRunnable;
 class gfxUserFontSet;
 class nsUserFontSet;
 struct nsFontFaceRuleContainer;
 class nsObjectFrame;
 class nsTransitionManager;
 class nsAnimationManager;
-class imgIContainer;
 class nsIDOMMediaQueryList;
 class nsRefreshDriver;
-
-#ifdef MOZ_REFLOW_PERF
-class nsRenderingContext;
-#endif
+class nsIWidget;
 
 namespace mozilla {
 class RestyleManager;
 namespace layers {
 class ContainerLayer;
 }
 }
 
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -14,138 +14,111 @@
  *
  * Date         Modified by     Description of modification
  * 05/03/2000   IBM Corp.       Observer events for reflow states
  */
 
 /* a presentation of a document, part 2 */
 
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/dom/PBrowserChild.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/Likely.h"
 #include "mozilla/Util.h"
 #include <algorithm>
 
 #ifdef XP_WIN
 #include "winuser.h"
 #endif
 
 #include "nsPresShell.h"
 #include "nsPresContext.h"
 #include "nsIContent.h"
 #include "mozilla/dom/Element.h"
 #include "nsIDocument.h"
-#include "nsIDOMXULDocument.h"
 #include "nsCSSStyleSheet.h"
-#include "nsIDOMCSSStyleSheet.h"  // for Pref-related rule management (bugs 22963,20760,31816)
 #include "nsAnimationManager.h"
 #include "nsINameSpaceManager.h"  // for Pref-related rule management (bugs 22963,20760,31816)
-#include "nsIServiceManager.h"
 #include "nsFrame.h"
 #include "FrameLayerBuilder.h"
 #include "nsViewManager.h"
 #include "nsView.h"
 #include "nsCRTGlue.h"
 #include "prlog.h"
 #include "prprf.h"
 #include "prinrval.h"
 #include "nsTArray.h"
 #include "nsCOMArray.h"
 #include "nsContainerFrame.h"
 #include "nsDOMEvent.h"
-#include "nsHTMLParts.h"
 #include "nsISelection.h"
-#include "nsISelectionPrivate.h"
 #include "mozilla/Selection.h"
-#include "nsLayoutCID.h"
 #include "nsGkAtoms.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMElement.h"
 #include "nsRange.h"
-#include "nsCSSPseudoElements.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsReadableUtils.h"
-#include "nsUnicharUtils.h"
 #include "nsIPageSequenceFrame.h"
 #include "nsCaret.h"
 #include "nsIDOMHTMLDocument.h"
-#include "nsIDOMXMLDocument.h"
 #include "nsFrameManager.h"
 #include "nsEventStateManager.h"
 #include "nsIMEStateManager.h"
 #include "nsXPCOM.h"
-#include "nsISupportsPrimitives.h"
 #include "nsILayoutHistoryState.h"
 #include "nsILineIterator.h" // for ScrollContentIntoView
-#include "nsWeakPtr.h"
 #include "pldhash.h"
 #include "mozilla/dom/Touch.h"
 #include "nsIObserverService.h"
 #include "nsIDocShell.h"        // for reflow observation
 #include "nsIBaseWindow.h"
 #include "nsError.h"
 #include "nsLayoutUtils.h"
 #include "nsViewportInfo.h"
 #include "nsCSSRendering.h"
   // for |#ifdef DEBUG| code
 #include "prenv.h"
-#include "nsAlgorithm.h"
-#include "nsIAttribute.h"
-#include "nsIGlobalHistory2.h"
 #include "nsDisplayList.h"
 #include "nsRegion.h"
 #include "nsRenderingContext.h"
 #include "nsAutoLayoutPhase.h"
 #ifdef MOZ_REFLOW_PERF
 #include "nsFontMetrics.h"
 #endif
 #include "PositionedEventTargeting.h"
 
 #include "nsIReflowCallback.h"
 
 #include "nsPIDOMWindow.h"
 #include "nsFocusManager.h"
-#include "nsNPAPIPluginInstance.h"
 #include "nsIObjectFrame.h"
 #include "nsIObjectLoadingContent.h"
 #include "nsNetUtil.h"
 #include "nsEventDispatcher.h"
 #include "nsThreadUtils.h"
 #include "nsStyleSheetService.h"
 #include "gfxImageSurface.h"
 #include "gfxContext.h"
-#include "mozilla/dom/HTMLMediaElement.h"
 #include "nsSMILAnimationController.h"
 #include "SVGContentUtils.h"
-#include "nsSVGUtils.h"
 #include "nsSVGEffects.h"
 #include "SVGFragmentIdentifier.h"
 
 #include "nsPerformance.h"
 #include "nsRefreshDriver.h"
 #include "nsDOMNavigationTiming.h"
 
 // Drag & Drop, Clipboard
-#include "nsWidgetsCID.h"
-#include "nsIClipboard.h"
-#include "nsIClipboardHelper.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIURI.h"
 #include "nsIScrollableFrame.h"
-#include "prtime.h"
-#include "nsIDragService.h"
-#include "nsCopySupport.h"
-#include "nsIDOMHTMLAnchorElement.h"
-#include "nsIDOMHTMLAreaElement.h"
-#include "nsIDOMHTMLLinkElement.h"
 #include "nsITimer.h"
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #include "mozilla/a11y/DocAccessible.h"
 #ifdef DEBUG
 #include "mozilla/a11y/Logging.h"
 #endif
 #endif
@@ -163,31 +136,30 @@
 #include "nsIDOMXULMultSelectCntrlEl.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
 #include "nsIDOMXULMenuListElement.h"
 
 #endif
 
 #include "GeckoProfiler.h"
 #include "gfxPlatform.h"
-#include "imgIEncoder.h"
 #include "Layers.h"
 #include "LayerTreeInvalidation.h"
 #include "mozilla/css/ImageLoader.h"
-#include "mozilla/layers/Compositor.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
-#include "nsAsyncDOMEvent.h"
 #include "nsCanvasFrame.h"
-#include "nsIContentViewer.h"
 #include "nsIImageLoadingContent.h"
 #include "nsIScreen.h"
 #include "nsIScreenManager.h"
 #include "nsPlaceholderFrame.h"
 #include "nsTransitionManager.h"
+#include "RestyleManager.h"
+#include "nsIDOMHTMLElement.h"
+#include "nsIDragSession.h"
 
 #define ANCHOR_SCROLL_FLAGS \
   (nsIPresShell::SCROLL_OVERFLOW_HIDDEN | nsIPresShell::SCROLL_NO_PARENT_FRAMES)
 
 using namespace mozilla;
 using namespace mozilla::css;
 using namespace mozilla::dom;
 using namespace mozilla::layers;
@@ -8280,18 +8252,16 @@ nsIPresShell::RemoveRefreshObserverExter
 
 //------------------------------------------------------
 // End of protected and private methods on the PresShell
 //------------------------------------------------------
 
 // Start of DEBUG only code
 
 #ifdef DEBUG
-#include "nsIURL.h"
-#include "nsILinkHandler.h"
 
 static void
 LogVerifyMessage(nsIFrame* k1, nsIFrame* k2, const char* aMsg)
 {
   nsAutoString n1, n2;
   if (k1) {
     k1->GetFrameName(n1);
   } else {
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -25,17 +25,16 @@
 #include "nsStubDocumentObserver.h"
 #include "nsISelectionController.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
 #include "nsCRT.h"
 #include "nsAutoPtr.h"
 #include "nsIWidget.h"
 #include "nsStyleSet.h"
-#include "nsPresArena.h"
 #include "nsFrameSelection.h"
 #include "nsGUIEvent.h"
 #include "nsContentUtils.h" // For AddScriptBlocker().
 #include "nsRefreshDriver.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/MemoryReporting.h"
 
 class nsRange;
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -30,18 +30,16 @@
 #include "nsRefreshDriver.h"
 #include "nsITimer.h"
 #include "nsLayoutUtils.h"
 #include "nsPresContext.h"
 #include "nsComponentManagerUtils.h"
 #include "prlog.h"
 #include "nsAutoPtr.h"
 #include "nsIDocument.h"
-#include "nsGUIEvent.h"
-#include "nsEventDispatcher.h"
 #include "jsapi.h"
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
 #include "mozilla/Preferences.h"
 #include "nsViewManager.h"
 #include "GeckoProfiler.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsPerformance.h"
--- a/layout/base/nsRefreshDriver.h
+++ b/layout/base/nsRefreshDriver.h
@@ -9,20 +9,18 @@
  * refresh rate.  (Perhaps temporary, until replaced by compositor.)
  */
 
 #ifndef nsRefreshDriver_h_
 #define nsRefreshDriver_h_
 
 #include "mozilla/TimeStamp.h"
 #include "mozFlushType.h"
-#include "nsCOMPtr.h"
 #include "nsTObserverArray.h"
 #include "nsTArray.h"
-#include "nsAutoPtr.h"
 #include "nsTHashtable.h"
 #include "nsClassHashtable.h"
 #include "nsHashKeys.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Util.h"
 
 class nsPresContext;
 class nsIPresShell;
--- a/layout/base/nsStyleChangeList.cpp
+++ b/layout/base/nsStyleChangeList.cpp
@@ -4,20 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * a list of the recomputation that needs to be done in response to a
  * style change
  */
 
 #include "nsStyleChangeList.h"
-#include "nsStyleConsts.h"
-#include "nsIFrame.h"
 #include "nsIContent.h"
-#include "nsCRT.h"
 
 static const uint32_t kGrowArrayBy = 10;
 
 nsStyleChangeList::nsStyleChangeList()
   : mArray(mBuffer),
     mArraySize(kStyleChangeBufferSize),
     mCount(0)
 {
--- a/layout/base/nsStyleSheetService.cpp
+++ b/layout/base/nsStyleSheetService.cpp
@@ -1,25 +1,22 @@
 /* -*- Mode: C++; 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/. */
 
 /* implementation of interface for managing user and user-agent style sheets */
 
-#include "prlog.h"
 #include "nsStyleSheetService.h"
 #include "nsIStyleSheet.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/css/Loader.h"
 #include "nsCSSStyleSheet.h"
 #include "nsIURI.h"
-#include "nsContentCID.h"
 #include "nsCOMPtr.h"
-#include "nsIServiceManager.h"
 #include "nsICategoryManager.h"
 #include "nsISupportsPrimitives.h"
 #include "nsNetUtil.h"
 #include "nsIObserverService.h"
 #include "nsLayoutStatics.h"
 #include "nsIMemoryReporter.h"
 
 NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(LayoutStyleSheetServiceMallocSizeOf)
--- a/layout/base/nsStyleSheetService.h
+++ b/layout/base/nsStyleSheetService.h
@@ -5,22 +5,22 @@
 
 /* implementation of interface for managing user and user-agent style sheets */
 
 #ifndef nsStyleSheetService_h_
 #define nsStyleSheetService_h_
 
 #include "nsIStyleSheetService.h"
 #include "nsCOMArray.h"
-#include "nsIStyleSheet.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/MemoryReporting.h"
 
 class nsISimpleEnumerator;
 class nsICategoryManager;
+class nsIStyleSheet;
 
 #define NS_STYLESHEETSERVICE_CID \
 {0xfcca6f83, 0x9f7d, 0x44e4, {0xa7, 0x4b, 0xb5, 0x94, 0x33, 0xe6, 0xc8, 0xc3}}
 
 #define NS_STYLESHEETSERVICE_CONTRACTID \
   "@mozilla.org/content/style-sheet-service;1"
 
 class nsIMemoryReporter;
--- a/layout/forms/nsMeterFrame.cpp
+++ b/layout/forms/nsMeterFrame.cpp
@@ -16,16 +16,18 @@
 #include "nsContentCreatorFunctions.h"
 #include "nsContentUtils.h"
 #include "nsFormControlFrame.h"
 #include "nsFontMetrics.h"
 #include "nsContentList.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLMeterElement.h"
 #include "nsContentList.h"
+#include "nsStyleSet.h"
+#include "nsThemeConstants.h"
 #include <algorithm>
 
 using mozilla::dom::HTMLMeterElement;
 
 nsIFrame*
 NS_NewMeterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsMeterFrame(aContext);
--- a/layout/forms/nsProgressFrame.cpp
+++ b/layout/forms/nsProgressFrame.cpp
@@ -16,16 +16,18 @@
 #include "nsContentCreatorFunctions.h"
 #include "nsContentUtils.h"
 #include "nsFormControlFrame.h"
 #include "nsContentList.h"
 #include "nsFontMetrics.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLProgressElement.h"
 #include "nsContentList.h"
+#include "nsStyleSet.h"
+#include "nsThemeConstants.h"
 #include <algorithm>
 
 using namespace mozilla::dom;
 
 nsIFrame*
 NS_NewProgressFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsProgressFrame(aContext);
--- a/layout/forms/nsRangeFrame.cpp
+++ b/layout/forms/nsRangeFrame.cpp
@@ -19,16 +19,18 @@
 #include "nsIPresShell.h"
 #include "nsGkAtoms.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "nsPresContext.h"
 #include "nsNodeInfoManager.h"
 #include "nsRenderingContext.h"
 #include "mozilla/dom/Element.h"
 #include "prtypes.h"
+#include "nsStyleSet.h"
+#include "nsThemeConstants.h"
 
 #include <algorithm>
 
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
 #define LONG_SIDE_TO_SHORT_SIDE_RATIO 10
--- a/layout/forms/test/Makefile.in
+++ b/layout/forms/test/Makefile.in
@@ -39,26 +39,21 @@ MOCHITEST_FILES =	test_bug231389.html \
 		test_bug572406.html \
 		test_bug572649.html \
 		test_bug620936.html \
 		test_bug595310.html \
 		test_bug644542.html \
 		test_bug672810.html \
 		test_bug704049.html \
 		test_bug869314.html \
+		test_bug903715.html \
 		test_listcontrol_search.html \
 		test_select_prevent_default.html \
 		$(NULL)
 
-ifneq ($(OS_TARGET),Android)
-MOCHITEST_FILES += \
-		test_bug903715.html \
-		$(NULL)
-endif
-
 MOCHITEST_CHROME_FILES = \
 		     bug536567_iframe.html \
 		test_bug536567_perwindowpb.html \
 		     bug536567_subframe.html \
 		test_bug665540.html \
 		     bug665540_window.xul \
 		$(NULL)
 
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -50,16 +50,17 @@
 #include "FrameLayerBuilder.h"
 #include "nsSMILKeySpline.h"
 #include "nsSubDocumentFrame.h"
 #include "nsSVGOuterSVGFrame.h"
 #include "mozilla/Attributes.h"
 #include "ScrollbarActivity.h"
 #include "nsRefreshDriver.h"
 #include "nsContentList.h"
+#include "nsThemeConstants.h"
 #include <algorithm>
 #include <cstdlib> // for std::abs(int/long)
 #include <cmath> // for std::abs(float/double)
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::layout;
 
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -63,16 +63,18 @@
 #include "nsEventStates.h"
 #include "nsError.h"
 #include "nsBidiUtils.h"
 #include "nsBidiPresUtils.h"
 
 #include "gfxRect.h"
 #include "ImageLayers.h"
 #include "ImageContainer.h"
+#include "nsStyleSet.h"
+#include "nsBlockFrame.h"
 
 #include "mozilla/Preferences.h"
 
 #include "mozilla/dom/Link.h"
 
 using namespace mozilla;
 
 // sizes (pixels) for image icon, padding and border frame
--- a/layout/mathml/nsMathMLTokenFrame.cpp
+++ b/layout/mathml/nsMathMLTokenFrame.cpp
@@ -7,16 +7,17 @@
 #include "nsFrame.h"
 #include "nsPresContext.h"
 #include "nsStyleContext.h"
 #include "nsStyleConsts.h"
 #include "nsContentUtils.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsMathMLTokenFrame.h"
 #include "nsTextFrame.h"
+#include "RestyleManager.h"
 #include <algorithm>
 
 nsIFrame*
 NS_NewMathMLTokenFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsMathMLTokenFrame(aContext);
 }
 
--- a/layout/mathml/nsMathMLmtableFrame.cpp
+++ b/layout/mathml/nsMathMLmtableFrame.cpp
@@ -16,16 +16,17 @@
 #include "nsTArray.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsTableOuterFrame.h"
 #include "nsTableFrame.h"
 #include "nsTableCellFrame.h"
 #include "celldata.h"
 
 #include "nsMathMLmtableFrame.h"
+#include "RestyleManager.h"
 #include <algorithm>
 
 using namespace mozilla;
 
 //
 // <mtable> -- table or matrix - implementation
 //
 
--- a/layout/style/AnimationCommon.cpp
+++ b/layout/style/AnimationCommon.cpp
@@ -12,16 +12,17 @@
 #include "nsIFrame.h"
 #include "nsLayoutUtils.h"
 #include "mozilla/LookAndFeel.h"
 #include "Layers.h"
 #include "FrameLayerBuilder.h"
 #include "nsDisplayList.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Preferences.h"
+#include "RestyleManager.h"
 
 using namespace mozilla::layers;
 
 namespace mozilla {
 namespace css {
 
 /* static */ bool
 IsGeometricProperty(nsCSSProperty aProperty)
--- a/layout/style/nsHTMLStyleSheet.cpp
+++ b/layout/style/nsHTMLStyleSheet.cpp
@@ -29,16 +29,17 @@
 #include "nsRuleData.h"
 #include "nsError.h"
 #include "nsRuleProcessorData.h"
 #include "nsCSSRuleProcessor.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/Element.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsHashKeys.h"
+#include "RestyleManager.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_ISUPPORTS1(nsHTMLStyleSheet::HTMLColorRule, nsIStyleRule)
 
 /* virtual */ void
 nsHTMLStyleSheet::HTMLColorRule::MapRuleInfoInto(nsRuleData* aRuleData)
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -25,16 +25,18 @@
 #include "nsGUIEvent.h"
 #include "mozilla/dom/Element.h"
 #include "nsIFrame.h"
 #include "nsCSSFrameConstructor.h"
 #include "Layers.h"
 #include "FrameLayerBuilder.h"
 #include "nsDisplayList.h"
 #include "nsStyleChangeList.h"
+#include "nsStyleSet.h"
+#include "RestyleManager.h"
 
 using mozilla::TimeStamp;
 using mozilla::TimeDuration;
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::css;
 
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -4264,17 +4264,17 @@ if (SpecialPowers.getBoolPref("layout.cs
 		},
 		"text-combine-horizontal": {
 			domProp: "textCombineHorizontal",
 			inherited: true,
 			type: CSS_TYPE_LONGHAND,
 			initial_values: [ "none" ],
 			other_values: [ "all", "digits", "digits 2", "digits 3", "digits 4", "digits     3" ],
 			invalid_values: [ "auto", "all 2", "none all", "digits -3", "digits 0",
-			                  "digits 12", "none 3", "digits 3.1415", "digits3",
+			                  "digits 12", "none 3", "digits 3.1415", "digits3", "digits 1",
 			                  "digits 3 all", "digits foo", "digits all", "digits 3.0" ]
 		}
 	};
 	for (var prop in verticalTextProperties) {
 		gCSSProperties[prop] = verticalTextProperties[prop];
 	}
 }
 
--- a/layout/svg/nsSVGContainerFrame.cpp
+++ b/layout/svg/nsSVGContainerFrame.cpp
@@ -8,16 +8,17 @@
 
 // Keep others in (case-insensitive) order:
 #include "nsCSSFrameConstructor.h"
 #include "nsSVGEffects.h"
 #include "nsSVGElement.h"
 #include "nsSVGUtils.h"
 #include "nsSVGAnimatedTransformList.h"
 #include "nsSVGTextFrame2.h"
+#include "RestyleManager.h"
 
 using namespace mozilla;
 
 NS_QUERYFRAME_HEAD(nsSVGContainerFrame)
   NS_QUERYFRAME_ENTRY(nsSVGContainerFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsSVGContainerFrameBase)
 
 NS_QUERYFRAME_HEAD(nsSVGDisplayContainerFrame)
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -11,16 +11,17 @@
 #include "nsISupportsImpl.h"
 #include "nsSVGClipPathFrame.h"
 #include "nsSVGPaintServerFrame.h"
 #include "nsSVGPathGeometryElement.h"
 #include "nsSVGFilterFrame.h"
 #include "nsSVGMaskFrame.h"
 #include "nsSVGTextPathFrame.h"
 #include "nsIReflowCallback.h"
+#include "RestyleManager.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // nsSVGRenderingObserver impl
 NS_IMPL_ISUPPORTS1(nsSVGRenderingObserver, nsIMutationObserver)
 
 void
--- a/layout/xul/base/src/nsBoxFrame.cpp
+++ b/layout/xul/base/src/nsBoxFrame.cpp
@@ -56,16 +56,17 @@
 #include "nsIDOMElement.h"
 #include "nsITheme.h"
 #include "nsTransform2D.h"
 #include "nsEventStateManager.h"
 #include "nsEventDispatcher.h"
 #include "nsIDOMEvent.h"
 #include "nsDisplayList.h"
 #include "mozilla/Preferences.h"
+#include "nsThemeConstants.h"
 #include <algorithm>
 
 // Needed for Print Preview
 #include "nsIURI.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
--- a/layout/xul/base/src/nsMenuFrame.cpp
+++ b/layout/xul/base/src/nsMenuFrame.cpp
@@ -37,16 +37,17 @@
 #include "nsISound.h"
 #include "nsEventStateManager.h"
 #include "nsIDOMXULMenuListElement.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Likely.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
+#include "mozilla/dom/Element.h"
 #include <algorithm>
 
 using namespace mozilla;
 
 #define NS_MENU_POPUP_LIST_INDEX 0
 
 #if defined(XP_WIN) || defined(XP_OS2)
 #define NSCONTEXTMENUISMOUSEUP 1
--- a/layout/xul/base/src/nsMenuPopupFrame.cpp
+++ b/layout/xul/base/src/nsMenuPopupFrame.cpp
@@ -44,16 +44,17 @@
 #include "nsIBaseWindow.h"
 #include "nsISound.h"
 #include "nsIScreenManager.h"
 #include "nsIServiceManager.h"
 #include "nsThemeConstants.h"
 #include "nsDisplayList.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
+#include "mozilla/dom/Element.h"
 #include <algorithm>
 
 using namespace mozilla;
 
 int8_t nsMenuPopupFrame::sDefaultLevelIsTop = -1;
 
 // NS_NewMenuPopupFrame
 //
--- a/media/libvpx/Makefile.in
+++ b/media/libvpx/Makefile.in
@@ -425,26 +425,37 @@ else
 
 # We can extract the asm offsets directly from generated assembly using inline
 # asm. This is the preferred method.
 
 asm_com_offsets.s: CFLAGS += -DINLINE_ASM
 
 OFFSET_PATTERN := '^[a-zA-Z0-9_]* EQU'
 
+# This rule, as well as the rule for asm_enc_offsets.s further below are here
+# because the generic rule in rules.mk was made to not be implicit, and we
+# can't put the C files in CSRCS.
+asm_com_offsets.s: asm_com_offsets.c
+	$(REPORT_BUILD)
+	$(CC) -S $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
+
 asm_com_offsets.asm: asm_com_offsets.s
 	grep $(OFFSET_PATTERN) $< | sed -e 's/[$$\#]//g' \
 	    $(if $(VPX_AS_CONVERSION),| $(VPX_AS_CONVERSION)) > $@
 
 GARBAGE += asm_com_offsets.s asm_com_offsets.asm
 
 ifdef MOZ_VP8_ENCODER
 
 asm_enc_offsets.s: CFLAGS += -DINLINE_ASM
 
+asm_enc_offsets.s: asm_enc_offsets.c
+	$(REPORT_BUILD)
+	$(CC) -S $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
+
 asm_enc_offsets.asm: asm_enc_offsets.s
 	grep $(OFFSET_PATTERN) $< | sed -e 's/[$$\#]//g' \
 	    $(if $(VPX_AS_CONVERSION),| $(VPX_AS_CONVERSION)) > $@
 
 GARBAGE += asm_enc_offsets.s asm_enc_offsets.asm
 
 endif
 
--- a/mobile/android/base/PageActionLayout.java
+++ b/mobile/android/base/PageActionLayout.java
@@ -26,39 +26,39 @@ import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
 import android.widget.Button;
 import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
 import java.util.UUID;
-import java.util.LinkedHashMap;
+import java.util.ArrayList;
 
 public class PageActionLayout extends LinearLayout implements GeckoEventListener,
                                                               View.OnClickListener,
                                                               View.OnLongClickListener {
     private final String LOGTAG = "GeckoPageActionLayout";
     private final String MENU_BUTTON_KEY = "MENU_BUTTON_KEY";
     private final int DEFAULT_PAGE_ACTIONS_SHOWN = 2;
 
-    private LinkedHashMap<String, PageAction> mPageActionList;
+    private ArrayList<PageAction> mPageActionList;
     private GeckoPopupMenu mPageActionsMenu;
     private Context mContext;
     private LinearLayout mLayout;
 
     // By default it's two, can be changed by calling setNumberShown(int)
     private int mMaxVisiblePageActions;
 
     public PageActionLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
         mContext = context;
         mLayout = this;
 
-        mPageActionList = new LinkedHashMap<String, PageAction>();
+        mPageActionList = new ArrayList<PageAction>();
         setNumberShown(DEFAULT_PAGE_ACTIONS_SHOWN);
         refreshPageActionIcons();
 
         registerEventListener("PageActions:Add");
         registerEventListener("PageActions:Remove");
     }
 
     public void setNumberShown(int count) {
@@ -86,57 +86,68 @@ public class PageActionLayout extends Li
 
     @Override
     public void handleMessage(String event, JSONObject message) {
         try {
             if (event.equals("PageActions:Add")) {
                 final String id = message.getString("id");
                 final String title = message.getString("title");
                 final String imageURL = message.optString("icon");
+                final boolean mImportant = message.getBoolean("important");
 
                 addPageAction(id, title, imageURL, new OnPageActionClickListeners() {
                     @Override
                     public void onClick(String id) {
                         GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("PageActions:Clicked", id));
                     }
 
                     @Override
                     public boolean onLongClick(String id) {
                         GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("PageActions:LongClicked", id));
                         return true;
                     }
-                });
+                }, mImportant);
             } else if (event.equals("PageActions:Remove")) {
                 final String id = message.getString("id");
 
                 removePageAction(id);
             }
         } catch(JSONException ex) {
             Log.e(LOGTAG, "Error deocding", ex);
         }
     }
 
-    public void addPageAction(final String id, final String title, final String imageData, final OnPageActionClickListeners mOnPageActionClickListeners) {
-        final PageAction pageAction = new PageAction(id, title, null, mOnPageActionClickListeners);
-        mPageActionList.put(id, pageAction);
+    public void addPageAction(final String id, final String title, final String imageData, final OnPageActionClickListeners mOnPageActionClickListeners, boolean mImportant) {
+        final PageAction pageAction = new PageAction(id, title, null, mOnPageActionClickListeners, mImportant);
+
+        int insertAt = mPageActionList.size();
+        while(insertAt > 0 && mPageActionList.get(insertAt-1).isImportant()) {
+          insertAt--;
+        }
+        mPageActionList.add(insertAt, pageAction);
 
         BitmapUtils.getDrawable(mContext, imageData, new BitmapUtils.BitmapLoader() {
             @Override
             public void onBitmapFound(final Drawable d) {
-                if (mPageActionList.containsKey(id)) {
+                if (mPageActionList.contains(pageAction)) {
                     pageAction.setDrawable(d);
                     refreshPageActionIcons();
                 }
             }
         });
     }
 
     public void removePageAction(String id) {
-        mPageActionList.remove(id);
-        refreshPageActionIcons();
+        for(int i = 0; i < mPageActionList.size(); i++) {
+            if (mPageActionList.get(i).getID().equals(id)) {
+                mPageActionList.remove(i);
+                refreshPageActionIcons();
+                return;
+            }
+        }
     }
 
     private ImageButton createImageButton() {
         ImageButton imageButton = new ImageButton(mContext, null, R.style.UrlBar_ImageButton_Icon);
         imageButton.setLayoutParams(new LayoutParams(mContext.getResources().getDimensionPixelSize(R.dimen.page_action_button_width), LayoutParams.MATCH_PARENT));
         imageButton.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
         imageButton.setOnClickListener(this);
         imageButton.setOnLongClickListener(this);
@@ -145,29 +156,29 @@ public class PageActionLayout extends Li
 
     @Override
     public void onClick(View v) {
         String buttonClickedId = (String)v.getTag();
         if (buttonClickedId != null) {
             if (buttonClickedId.equals(MENU_BUTTON_KEY)) {
                 showMenu(v, mPageActionList.size() - mMaxVisiblePageActions + 1);
             } else {
-                mPageActionList.get(buttonClickedId).onClick();
+                getPageActionWithId(buttonClickedId).onClick();
             }
         }
     }
 
     @Override
     public boolean onLongClick(View v) {
         String buttonClickedId = (String)v.getTag();
         if (buttonClickedId.equals(MENU_BUTTON_KEY)) {
             showMenu(v, mPageActionList.size() - mMaxVisiblePageActions + 1);
             return true;
         } else {
-            return mPageActionList.get(buttonClickedId).onLongClick();
+            return getPageActionWithId(buttonClickedId).onLongClick();
         }
     }
 
     private void setActionForView(final ImageButton view, final PageAction pageAction) {
         if (pageAction == null) {
             view.setTag(null);
             ThreadUtils.postToUiThread(new Runnable() {
                 @Override
@@ -225,79 +236,86 @@ public class PageActionLayout extends Li
          * and hence we maintain the insertion order of the child Views which is essentially the reverse of their index
          */
 
         int buttonIndex = (this.getChildCount() - 1) - index;
         int totalVisibleButtons = ((mPageActionList.size() < this.getChildCount()) ? mPageActionList.size() : this.getChildCount());
 
         if (mPageActionList.size() > buttonIndex) {
             // Return the pageactions starting from the end of the list for the number of visible pageactions.
-            return getPageActionAt((mPageActionList.size() - totalVisibleButtons) + buttonIndex);
+            return mPageActionList.get((mPageActionList.size() - totalVisibleButtons) + buttonIndex);
         }
         return null;
     }
 
-    private PageAction getPageActionAt(int index) {
-        int count = 0;
-        for(PageAction pageAction : mPageActionList.values()) {
-            if (count == index) {
+    private PageAction getPageActionWithId(String id) {
+        for(int i = 0; i < mPageActionList.size(); i++) {
+            PageAction pageAction = mPageActionList.get(i);
+            if (pageAction.getID().equals(id)) {
                 return pageAction;
             }
-            count++;
         }
         return null;
     }
 
     private void showMenu(View mPageActionButton, int toShow) {
         if (mPageActionsMenu == null) {
             mPageActionsMenu = new GeckoPopupMenu(mPageActionButton.getContext(), mPageActionButton);
             mPageActionsMenu.inflate(0);
             mPageActionsMenu.setOnMenuItemClickListener(new GeckoPopupMenu.OnMenuItemClickListener() {
                 @Override
                 public boolean onMenuItemClick(MenuItem item) {
-                    for(PageAction pageAction : mPageActionList.values()) {
-                        if (pageAction.key() == item.getItemId()) {
+                    int id = item.getItemId();
+                    for(int i = 0; i < mPageActionList.size(); i++) {
+                        PageAction pageAction = mPageActionList.get(i);
+                        if (pageAction.key() == id) {
                             pageAction.onClick();
+                            return true;
                         }
                     }
-                    return true;
+                    return false;
                 }
             });
         }
         Menu menu = mPageActionsMenu.getMenu();
         menu.clear();
 
-        int count = 0;
-        for(PageAction pageAction : mPageActionList.values()) {
-            if (count < toShow) {
+        for(int i = 0; i < mPageActionList.size(); i++) {
+            if (i < toShow) {
+                PageAction pageAction = mPageActionList.get(i);
                 MenuItem item = menu.add(Menu.NONE, pageAction.key(), Menu.NONE, pageAction.getTitle());
                 item.setIcon(pageAction.getDrawable());
             }
-            count++;
         }
         mPageActionsMenu.show();
     }
 
     public static interface OnPageActionClickListeners {
         public void onClick(String id);
         public boolean onLongClick(String id);
     }
 
     private static class PageAction {
         private OnPageActionClickListeners mOnPageActionClickListeners;
         private Drawable mDrawable;
         private String mTitle;
         private String mId;
         private int key;
+        private boolean mImportant;
 
-        public PageAction(String id, String title, Drawable image, OnPageActionClickListeners mOnPageActionClickListeners) {
+        public PageAction(String id,
+                          String title,
+                          Drawable image,
+                          OnPageActionClickListeners mOnPageActionClickListeners,
+                          boolean mImportant) {
             this.mId = id;
             this.mTitle = title;
             this.mDrawable = image;
             this.mOnPageActionClickListeners = mOnPageActionClickListeners;
+            this.mImportant = mImportant;
 
             this.key = UUID.fromString(mId.subSequence(1, mId.length() - 2).toString()).hashCode();
         }
 
         public Drawable getDrawable() {
             return mDrawable;
         }
 
@@ -312,16 +330,20 @@ public class PageActionLayout extends Li
         public String getID() {
             return mId;
         }
 
         public int key() {
             return key;
         }
 
+        public boolean isImportant() {
+            return mImportant;
+        }
+
         public void onClick() {
             if (mOnPageActionClickListeners != null) {
                 mOnPageActionClickListeners.onClick(mId);
             }
         }
 
         public boolean onLongClick() {
             if (mOnPageActionClickListeners != null) {
--- a/mobile/android/chrome/content/SelectionHandler.js
+++ b/mobile/android/chrome/content/SelectionHandler.js
@@ -69,23 +69,27 @@ var SelectionHandler = {
     switch (aTopic) {
       case "Gesture:SingleTap": {
         if (this._activeType == this.TYPE_SELECTION) {
           let data = JSON.parse(aData);
           if (this._pointInSelection(data.x, data.y))
             this.copySelection();
           else
             this._closeSelection();
+        } else if (this._activeType == this.TYPE_CURSOR) {
+          // attachCaret() is called in the "Gesture:SingleTap" handler in BrowserEventHandler
+          // We're guaranteed to call this first, because this observer was added last
+          this._closeSelection();
         }
         break;
       }
       case "Tab:Selected":
         this._closeSelection();
         break;
-  
+
       case "Window:Resize": {
         if (this._activeType == this.TYPE_SELECTION) {
           // Knowing when the page is done drawing is hard, so let's just cancel
           // the selection when the window changes. We should fix this later.
           this._closeSelection();
         }
         break;
       }
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1622,17 +1622,18 @@ var NativeWindow = {
   pageactions: {
     _items: { },
     add: function(aOptions) {
       let id = uuidgen.generateUUID().toString();
       sendMessageToJava({
         type: "PageActions:Add",
         id: id,
         title: aOptions.title,
-        icon: resolveGeckoURI(aOptions.icon)
+        icon: resolveGeckoURI(aOptions.icon),
+        important: "important" in aOptions ? aOptions.important : false
       });
       this._items[id] = {
         clickCallback: aOptions.clickCallback,
         longClickCallback: aOptions.longClickCallback
       };
       return id;
     },
     remove: function(id) {
@@ -7153,24 +7154,26 @@ let Reader = {
       NativeWindow.pageactions.remove(this.pageAction.id);
       delete this.pageAction.id;
     }
 
     if (tab.readerActive) {
       this.pageAction.id = NativeWindow.pageactions.add({
         title: Strings.browser.GetStringFromName("readerMode.exit"),
         icon: "drawable://reader_active",
-        clickCallback: this.pageAction.readerModeCallback
+        clickCallback: this.pageAction.readerModeCallback,
+        important: true
       });
     } else if (tab.readerEnabled) {
       this.pageAction.id = NativeWindow.pageactions.add({
         title: Strings.browser.GetStringFromName("readerMode.enter"),
         icon: "drawable://reader",
         clickCallback:this.pageAction.readerModeCallback,
-        longClickCallback: this.pageAction.readerModeActiveCallback
+        longClickCallback: this.pageAction.readerModeActiveCallback,
+        important: true
       });
     }
   },
 
   observe: function(aMessage, aTopic, aData) {
     switch(aTopic) {
       case "Reader:Add": {
         let args = JSON.parse(aData);
--- a/modules/libjar/nsJAR.cpp
+++ b/modules/libjar/nsJAR.cpp
@@ -218,21 +218,16 @@ nsJAR::Extract(const nsACString &aEntryN
 
   nsZipItem *item = mZip->GetItem(PromiseFlatCString(aEntryName).get());
   NS_ENSURE_TRUE(item, NS_ERROR_FILE_TARGET_DOES_NOT_EXIST);
 
   // Remove existing file or directory so we set permissions correctly.
   // If it's a directory that already exists and contains files, throw
   // an exception and return.
 
-  //XXX Bug 332139:
-  //XXX If we guarantee that rv in the case of a non-empty directory
-  //XXX is always FILE_DIR_NOT_EMPTY, we can remove
-  //XXX |rv == NS_ERROR_FAILURE| - bug 322183 needs to be completely
-  //XXX fixed before that can happen
   nsresult rv = outFile->Remove(false);
   if (rv == NS_ERROR_FILE_DIR_NOT_EMPTY ||
       rv == NS_ERROR_FAILURE)
     return rv;
 
   if (item->IsDirectory())
   {
     rv = outFile->Create(nsIFile::DIRECTORY_TYPE, item->Mode());
--- a/python/mozbuild/mozbuild/controller/building.py
+++ b/python/mozbuild/mozbuild/controller/building.py
@@ -4,68 +4,196 @@
 
 from __future__ import unicode_literals
 
 import getpass
 import os
 import sys
 import time
 
-from collections import namedtuple
+from collections import (
+    namedtuple,
+    OrderedDict,
+)
 
 # keep in sync with psutil os support, see psutil/__init__.py
 if sys.platform.startswith("freebsd") or sys.platform.startswith("darwin") or sys.platform.startswith("win32") or sys.platform.startswith("linux"):
     try:
         import psutil
     except ImportError:
         psutil = None
 else:
     psutil = None
 
+from ..base import MozbuildObject
+
 from ..compilation.warnings import (
     WarningsCollector,
     WarningsDatabase,
 )
 
 
 BuildOutputResult = namedtuple('BuildOutputResult',
     ('warning', 'state_changed', 'for_display'))
 
 
-class BuildMonitor(object):
+class TierStatus(object):
+    """Represents the state and progress of tier traversal.
+
+    The build system is organized into linear phases called tiers. Each tier
+    executes in the order it was defined, 1 at a time.
+
+    Tiers can have subtiers. Subtiers can execute in any order. Some subtiers
+    execute sequentially. Others are concurrent.
+
+    Subtiers can have directories. Directories can execute in any order, just
+    like subtiers.
+    """
+
+    def __init__(self):
+        self.tiers = OrderedDict()
+        self.active_tier = None
+        self.active_subtiers = set()
+
+    def set_tiers(self, tiers):
+        """Record the set of known tiers."""
+        for tier in tiers:
+            self.tiers[tier] = dict(
+                begin_time=None,
+                finish_time=None,
+                duration=None,
+                subtiers=OrderedDict(),
+            )
+
+    def begin_tier(self, tier, subtiers):
+        """Record that execution of a tier has begun."""
+        t = self.tiers[tier]
+        # We should ideally use a monotonic clock here. Unfortunately, we won't
+        # have one until Python 3.
+        t['begin_time'] = time.time()
+        for subtier in subtiers:
+            t['subtiers'][subtier] = dict(
+                begin_time=None,
+                finish_time=None,
+                duration=None,
+                concurrent=False,
+                dirs=OrderedDict(),
+                dirs_complete=0,
+            )
+
+        self.active_tier = tier
+        self.active_subtiers = set()
+        self.active_dirs = {}
+
+    def finish_tier(self, tier):
+        """Record that execution of a tier has finished."""
+        t = self.tiers[tier]
+        t['finish_time'] = time.time()
+        t['duration'] = t['finish_time'] - t['begin_time']
+
+    def begin_subtier(self, tier, subtier, dirs):
+        """Record that execution of a subtier has begun."""
+        st = self.tiers[tier]['subtiers'][subtier]
+        st['begin_time'] = time.time()
+
+        for d in dirs:
+            st['dirs'][d] = dict(
+                begin_time=None,
+                finish_time=None,
+                duration=None,
+                concurrent=False,
+            )
+
+        if self.active_subtiers:
+            st['concurrent'] = True
+
+        self.active_subtiers.add(subtier)
+
+    def finish_subtier(self, tier, subtier):
+        """Record that execution of a subtier has finished."""
+        st = self.tiers[tier]['subtiers'][subtier]
+        st['finish_time'] = time.time()
+
+        self.active_subtiers.remove(subtier)
+        if self.active_subtiers:
+            st['concurrent'] = True
+
+        # A subtier may not have directories.
+        try:
+            del self.active_dirs[subtier]
+        except KeyError:
+            pass
+
+        st['duration'] = st['finish_time'] - st['begin_time']
+
+    def begin_dir(self, tier, subtier, d):
+        """Record that execution of a directory has begun."""
+        entry = self.tiers[tier]['subtiers'][subtier]['dirs'][d]
+        entry['begin_time'] = time.time()
+
+        self.active_dirs.setdefault(subtier, set()).add(d)
+
+        if len(self.active_dirs[subtier]) > 1:
+            entry['concurrent'] = True
+
+    def finish_dir(self, tier, subtier, d):
+        """Record that execution of a directory has finished."""
+        st = self.tiers[tier]['subtiers'][subtier]
+        st['dirs_complete'] += 1
+
+        entry = st['dirs'][d]
+        entry['finish_time'] = time.time()
+
+        self.active_dirs[subtier].remove(d)
+        entry['duration'] = entry['finish_time'] - entry['begin_time']
+
+        if self.active_dirs[subtier]:
+            entry['concurrent'] = True
+
+    def tier_status(self):
+        for tier, state in self.tiers.items():
+            active = self.active_tier == tier
+            finished = state['finish_time'] is not None
+
+            yield tier, active, finished
+
+    def current_subtier_status(self):
+        for subtier, state in self.tiers[self.active_tier]['subtiers'].items():
+            active = subtier in self.active_subtiers
+            finished = state['finish_time'] is not None
+
+            yield subtier, active, finished
+
+    def current_dirs_status(self):
+        for subtier, dirs in self.active_dirs.items():
+            st = self.tiers[self.active_tier]['subtiers'][subtier]
+            yield subtier, st['dirs'].keys(), dirs, st['dirs_complete']
+
+
+class BuildMonitor(MozbuildObject):
     """Monitors the output of the build."""
 
-    def __init__(self, topobjdir, warnings_path):
+    def init(self, warnings_path):
         """Create a new monitor.
 
         warnings_path is a path of a warnings database to use.
         """
         self._warnings_path = warnings_path
 
-        self.tiers = []
-        self.subtiers = []
-        self.current_tier = None
-        self.current_subtier = None
-        self.current_tier_dirs = []
-        self.current_tier_static_dirs = []
-        self.current_subtier_dirs = []
-        self.current_subtier_started = set()
-        self.current_subtier_finished = set()
-        self.current_tier_dir = None
-        self.current_tier_dir_index = 0
+        self.tiers = TierStatus()
 
         self.warnings_database = WarningsDatabase()
         if os.path.exists(warnings_path):
             try:
                 self.warnings_database.load_from_file(warnings_path)
             except ValueError:
                 os.remove(warnings_path)
 
         self._warnings_collector = WarningsCollector(
-            database=self.warnings_database, objdir=topobjdir)
+            database=self.warnings_database, objdir=self.topobjdir)
 
     def start(self):
         """Record the start of the build."""
         self.start_time = time.time()
         self._finder_start_cpu = self._get_finder_cpu_usage()
 
     def on_line(self, line):
         """Consume a line of output from the build system.
@@ -88,61 +216,38 @@ class BuildMonitor(object):
         """
         if line.startswith('BUILDSTATUS'):
             args = line.split()[1:]
 
             action = args.pop(0)
             update_needed = True
 
             if action == 'TIERS':
-                self.tiers = args
-                update_needed = False
-            elif action == 'SUBTIERS':
-                self.subtiers = args
-                update_needed = False
-            elif action == 'STATICDIRS':
-                self.current_tier_static_dirs = args
-                update_needed = False
-            elif action == 'DIRS':
-                self.current_tier_dirs = args
+                self.tiers.set_tiers(args)
                 update_needed = False
             elif action == 'TIER_START':
-                assert len(args) == 1
-                self.current_tier = args[0]
-                self.current_subtier = None
-                self.current_tier_dirs = []
-                self.current_subtier_started = set()
-                self.current_subtier_finished = set()
-                self.current_tier_dir = None
+                tier = args[0]
+                subtiers = args[1:]
+                self.tiers.begin_tier(tier, subtiers)
             elif action == 'TIER_FINISH':
-                assert len(args) == 1
-                assert args[0] == self.current_tier
+                tier, = args
+                self.tiers.finish_tier(tier)
             elif action == 'SUBTIER_START':
-                assert len(args) == 2
+                tier, subtier = args[0:2]
+                dirs = args[2:]
+                self.tiers.begin_subtier(tier, subtier, dirs)
+            elif action == 'SUBTIER_FINISH':
                 tier, subtier = args
-                assert tier == self.current_tier
-                self.current_subtier = subtier
-                if subtier == 'static':
-                    self.current_subtier_dirs = self.current_tier_static_dirs
-                else:
-                    self.current_subtier_dirs = self.current_tier_dirs
-                self.current_tier_dir_index = 0
-                self.current_subtier_started.add(subtier)
-            elif action == 'SUBTIER_FINISH':
-                assert len(args) == 2
-                tier, subtier = args
-                assert tier == self.current_tier
-                self.current_subtier_finished.add(subtier)
+                self.tiers.finish_subtier(tier, subtier)
             elif action == 'TIERDIR_START':
-                assert len(args) == 1
-                self.current_tier_dir = args[0]
-                self.current_tier_dir_index += 1
+                tier, subtier, d = args
+                self.tiers.begin_dir(tier, subtier, d)
             elif action == 'TIERDIR_FINISH':
-                assert len(args) == 1
-                assert self.current_tier_dir == args[0]
+                tier, subtier, d = args
+                self.tiers.finish_dir(tier, subtier, d)
             else:
                 raise Exception('Unknown build status: %s' % action)
 
             return BuildOutputResult(None, update_needed, False)
 
         warning = None
 
         try:
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -99,64 +99,80 @@ class BuildProgressFooter(object):
 
     def __init__(self, terminal, monitor):
         # terminal is a blessings.Terminal.
         self._t = terminal
         self._fh = sys.stdout
         self._monitor = monitor
 
     def _clear_lines(self, n):
-        self._fh.write(self._t.move(self._t.height - n, 0))
+        self._fh.write(self._t.move_x(0))
         self._fh.write(self._t.clear_eos())
 
     def clear(self):
         """Removes the footer from the current terminal."""
         self._clear_lines(1)
 
     def draw(self):
         """Draws this footer in the terminal."""
-        if not self._monitor.tiers:
+        tiers = self._monitor.tiers
+
+        if not tiers.tiers:
             return
 
         # The drawn terminal looks something like:
         # TIER: base nspr nss js platform app SUBTIER: static export libs tools DIRECTORIES: 06/09 (memory)
 
         # This is a list of 2-tuples of (encoding function, input). None means
         # no encoding. For a full reason on why we do things this way, read the
         # big comment below.
         parts = [('bold', 'TIER'), ':', ' ']
 
-        current_encountered = False
-        for tier in self._monitor.tiers:
-            if tier == self._monitor.current_tier:
+        for tier, active, finished in tiers.tier_status():
+            if active:
                 parts.extend([('underline_yellow', tier), ' '])
-                current_encountered = True
-            elif not current_encountered:
+            elif finished:
                 parts.extend([('green', tier), ' '])
             else:
                 parts.extend([tier, ' '])
 
         parts.extend([('bold', 'SUBTIER'), ':', ' '])
-        for subtier in self._monitor.subtiers:
-            if subtier in self._monitor.current_subtier_finished:
+        for subtier, active, finished in tiers.current_subtier_status():
+            if active:
+                parts.extend([('underline_yellow', subtier), ' '])
+            elif finished:
                 parts.extend([('green', subtier), ' '])
-            elif subtier in self._monitor.current_subtier_started:
-                parts.extend([('underline_yellow', subtier), ' '])
             else:
                 parts.extend([subtier, ' '])
 
-        if self._monitor.current_subtier_dirs and self._monitor.current_tier_dir:
-            parts.extend([
-                ('bold', 'DIRECTORIES'), ': ',
-                '%02d' % self._monitor.current_tier_dir_index,
-                '/',
-                '%02d' % len(self._monitor.current_subtier_dirs),
-                ' ',
-                '(', ('magenta', self._monitor.current_tier_dir), ')',
-            ])
+        if tiers.active_dirs:
+            parts.extend([('bold', 'DIRECTORIES'), ': '])
+            have_dirs = False
+
+            for subtier, all_dirs, active_dirs, complete in tiers.current_dirs_status():
+                if len(all_dirs) < 2:
+                    continue
+
+                have_dirs = True
+
+                parts.extend([
+                    '%02d' % (complete + 1),
+                    '/',
+                    '%02d' % len(all_dirs),
+                    ' ',
+                    '(',
+                ])
+                for d in active_dirs:
+                    parts.extend([
+                        ('magenta', d), ' ,'
+                    ])
+                parts[-1] = ')'
+
+            if not have_dirs:
+                parts = parts[0:-2]
 
         # We don't want to write more characters than the current width of the
         # terminal otherwise wrapping may result in weird behavior. We can't
         # simply truncate the line at terminal width characters because a)
         # non-viewable escape characters count towards the limit and b) we
         # don't want to truncate in the middle of an escape sequence because
         # subsequent output would inherit the escape sequence.
         max_width = self._t.width
@@ -178,18 +194,19 @@ class BuildProgressFooter(object):
             else:
                 if written + len(part) > max_width:
                     write_pieces.append(part[0:max_width - written])
                     written += len(part)
                     break
 
                 write_pieces.append(part)
                 written += len(part)
-
-        self._fh.write(''.join(write_pieces))
+        with self._t.location():
+            self._t.move(self._t.height-1,0)
+            self._fh.write(''.join(write_pieces))
         self._fh.flush()
 
 
 class BuildOutputManager(LoggingMixin):
     """Handles writing build output to a terminal, to logs, etc."""
 
     def __init__(self, log_manager, monitor):
         self.populate_logger()
@@ -269,17 +286,18 @@ class Build(MachCommandBase):
                      help='Do not add extra make dependencies.')
     @CommandArgument('-v', '--verbose', action='store_true',
         help='Verbose output for what commands the build is running.')
     def build(self, what=None, disable_extra_make_dependencies=None, jobs=0, verbose=False):
         from mozbuild.controller.building import BuildMonitor
         from mozbuild.util import resolve_target_to_make
 
         warnings_path = self._get_state_filename('warnings.json')
-        monitor = BuildMonitor(self.topobjdir, warnings_path)
+        monitor = self._spawn(BuildMonitor)
+        monitor.init(warnings_path)
 
         with BuildOutputManager(self.log_manager, monitor) as output:
             monitor.start()
 
             if what:
                 top_make = os.path.join(self.topobjdir, 'Makefile')
                 if not os.path.exists(top_make):
                     print('Your tree has not been configured yet. Please run '
--- a/security/manager/pki/resources/content/createCertInfo.xul
+++ b/security/manager/pki/resources/content/createCertInfo.xul
@@ -4,27 +4,27 @@
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
 
 <!DOCTYPE window SYSTEM "chrome://pippki/locale/pippki.dtd">
 
 <window
   id="domainMismatch" title="&createCertInfo.title;"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"      
+  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
   onload="onLoad();"
   onclose="onClose();"
 >
 
 <stringbundle id="pippki_bundle" src="chrome://pippki/locale/pippki.properties"/>
 
 <script type="application/javascript" src="pippki.js" />
 <script type="application/javascript" src="createCertInfo.js" />
 
 <vbox style="margin: 5px; max-width: 50em;">
 
   <description>&createCertInfo.msg1;</description>
   <separator/>
-  <description style="font-weight: bold; text-align: center; text-decoration: blink;">&createCertInfo.msg2;</description>
+  <description style="font-weight: bold; text-align: center;">&createCertInfo.msg2;</description>
   <separator/>
 
 </vbox>
 </window>
--- a/services/common/tests/unit/test_storage_server.js
+++ b/services/common/tests/unit/test_storage_server.js
@@ -341,17 +341,17 @@ add_test(function test_bso_if_unmodified
   server.createContents("123", {
     test: {bso: {foo: "bar"}}
   });
   server.startSynchronous();
 
   let coll = server.user("123").collection("test");
   do_check_neq(coll, null);
 
-  let time = coll.timestamp;
+  let time = coll.bso("bso").modified;
 
   _("Ensure we get a 412 for specified times older than server time.");
   let request = localRequest(server, "/2.0/123/storage/test/bso",
                              "123", "password");
   request.setHeader("X-If-Unmodified-Since", time - 5000);
   request.setHeader("Content-Type", "application/json");
   let payload = JSON.stringify({"payload": "foobar"});
   let error = doPutRequest(request, payload);
--- a/testing/marionette/atoms/atoms.js
+++ b/testing/marionette/atoms/atoms.js
@@ -122,58 +122,59 @@ 0:parseInt(B[1],10))?1:0)||((0==A[2].len
 //isElementSelected
 var isElementSelected = function(){return function(){var f=!1,g=this;function h(a,b){function c(){}c.prototype=b.prototype;a.d=b.prototype;a.prototype=new c};function i(a,b){for(var c=1;c<arguments.length;c++)var d=(""+arguments[c]).replace(/\$/g,"$$$$"),a=a.replace(/\%s/,d);return a};var k,l="",m=/rv\:([^\);]+)(\)|;)/.exec(g.navigator?g.navigator.userAgent:null);k=l=m?m[1]:"";var n={};function o(a,b){this.code=a;this.message=b||"";this.name=p[a]||p[13];var c=Error(this.message);c.name=this.name;this.stack=c.stack||""}h(o,Error);
 var p={7:"NoSuchElementError",8:"NoSuchFrameError",9:"UnknownCommandError",10:"StaleElementReferenceError",11:"ElementNotVisibleError",12:"InvalidElementStateError",13:"UnknownError",15:"ElementNotSelectableError",19:"XPathLookupError",23:"NoSuchWindowError",24:"InvalidCookieDomainError",25:"UnableToSetCookieError",26:"ModalDialogOpenedError",27:"NoModalDialogOpenError",28:"ScriptTimeoutError",32:"InvalidSelectorError",33:"SqlDatabaseError",34:"MoveTargetOutOfBoundsError"};
 o.prototype.toString=function(){return"["+this.name+"] "+this.message};function q(a){this.stack=Error().stack||"";a&&(this.message=""+a)}h(q,Error);q.prototype.name="CustomError";function r(a,b){b.unshift(a);q.call(this,i.apply(null,b));b.shift()}h(r,q);r.prototype.name="AssertionError";if(!n["1.9.1"]){for(var s=0,t=(""+k).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),u="1.9.1".replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),v=Math.max(t.length,u.length),w=0;0==s&&w<v;w++){var x=t[w]||"",y=u[w]||"",z=RegExp("(\\d*)(\\D*)","g"),A=RegExp("(\\d*)(\\D*)","g");do{var B=z.exec(x)||["","",""],C=A.exec(y)||["","",""];if(0==B[0].length&&0==C[0].length)break;s=((0==B[1].length?0:parseInt(B[1],10))<(0==C[1].length?0:parseInt(C[1],10))?-1:(0==B[1].length?0:parseInt(B[1],10))>(0==C[1].length?
 0:parseInt(C[1],10))?1:0)||((0==B[2].length)<(0==C[2].length)?-1:(0==B[2].length)>(0==C[2].length)?1:0)||(B[2]<C[2]?-1:B[2]>C[2]?1:0)}while(0==s)}n["1.9.1"]=0<=s};var D={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1},E={IMG:" ",BR:"\n"};function F(a,b,c){if(!(a.nodeName in D))if(3==a.nodeType)c?b.push((""+a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):b.push(a.nodeValue);else if(a.nodeName in E)b.push(E[a.nodeName]);else for(a=a.firstChild;a;)F(a,b,c),a=a.nextSibling};(function(){var a=g.Components;if(!a)return f;try{if(!a.classes)return f}catch(b){return f}var c=a.classes,a=a.interfaces;c["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator);c["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo);return!0})();function G(a,b,c,d,e){this.b=!!b;if(a&&(this.a=a))this.c="number"==typeof d?d:1!=this.a.nodeType?0:this.b?-1:1;this.depth=void 0!=e?e:this.c||0;this.b&&(this.depth*=-1)}h(G,function(){});G.prototype.a=null;G.prototype.c=0;h(function(a,b,c,d){G.call(this,a,b,0,null,d)},G);function H(a,b){return!!a&&1==a.nodeType&&(!b||a.tagName.toUpperCase()==b)}function I(a){return H(a,"OPTION")?!0:H(a,"INPUT")?(a=a.type.toLowerCase(),"checkbox"==a||"radio"==a):f}var J={"class":"className",readonly:"readOnly"},K=["checked","disabled","draggable","hidden"];function L(a){if(I(a)){if(!I(a))throw new o(15,"Element is not selectable");var b="selected",c=a.type&&a.type.toLowerCase();if("checkbox"==c||"radio"==c)b="checked";var c=b,d=J[c]||c,b=a[d],e;if(e=void 0===b){b:if("string"==typeof K)d="string"!=typeof d||1!=d.length?-1:K.indexOf(d,0);else{for(e=0;e<K.length;e++)if(e in K&&K[e]===d){d=e;break b}d=-1}e=0<=d}if(e)a=f;else{if(d="value"==c)if(d=H(a,"OPTION")){var j;c=c.toLowerCase();if(a.hasAttribute)j=a.hasAttribute(c);else try{j=a.attributes[c].specified}catch(P){j=
 f}d=!j}d&&(j=[],F(a,j,f),b=j.join(""));a=b}a=!!a}else a=f;return a}var M=["_"],N=g;!(M[0]in N)&&N.execScript&&N.execScript("var "+M[0]);for(var O;M.length&&(O=M.shift());)!M.length&&void 0!==L?N[O]=L:N=N[O]?N[O]:N[O]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);}
 
 // isElementDisplayed
-var isElementDisplayed = function(){return function(){function g(a){return function(){return a}}var h=this;
+var isElementDisplayed = function(){return function(){function h(a){return function(){return a}}var k=this;
 function m(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
-else if("function"==b&&"undefined"==typeof a.call)return"object";return b}function n(a){return"string"==typeof a};function q(a){var b=0,c=String(r).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split(".");a=String(a).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split(".");for(var d=Math.max(c.length,a.length),e=0;0==b&&e<d;e++){var f=c[e]||"",k=a[e]||"",w=RegExp("(\\d*)(\\D*)","g"),p=RegExp("(\\d*)(\\D*)","g");do{var l=w.exec(f)||["","",""],v=p.exec(k)||["","",""];if(0==l[0].length&&0==v[0].length)break;b=((0==l[1].length?0:parseInt(l[1],10))<(0==v[1].length?0:parseInt(v[1],10))?-1:(0==l[1].length?0:parseInt(l[1],10))>(0==v[1].length?
+else if("function"==b&&"undefined"==typeof a.call)return"object";return b}function n(a){return"string"==typeof a};function q(a){var b=0,c=String(r).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split(".");a=String(a).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split(".");for(var d=Math.max(c.length,a.length),e=0;0==b&&e<d;e++){var f=c[e]||"",g=a[e]||"",w=RegExp("(\\d*)(\\D*)","g"),p=RegExp("(\\d*)(\\D*)","g");do{var l=w.exec(f)||["","",""],v=p.exec(g)||["","",""];if(0==l[0].length&&0==v[0].length)break;b=((0==l[1].length?0:parseInt(l[1],10))<(0==v[1].length?0:parseInt(v[1],10))?-1:(0==l[1].length?0:parseInt(l[1],10))>(0==v[1].length?
 0:parseInt(v[1],10))?1:0)||((0==l[2].length)<(0==v[2].length)?-1:(0==l[2].length)>(0==v[2].length)?1:0)||(l[2]<v[2]?-1:l[2]>v[2]?1:0)}while(0==b)}return b}function aa(a){return String(a).replace(/\-([a-z])/g,function(a,c){return c.toUpperCase()})};var s=Array.prototype;function t(a,b){for(var c=a.length,d=n(a)?a.split(""):a,e=0;e<c;e++)e in d&&b.call(void 0,d[e],e,a)}function ba(a,b){if(a.reduce)return a.reduce(b,"");var c="";t(a,function(d,e){c=b.call(void 0,c,d,e,a)});return c}function ca(a,b){for(var c=a.length,d=n(a)?a.split(""):a,e=0;e<c;e++)if(e in d&&b.call(void 0,d[e],e,a))return!0;return!1}
 function da(a,b){var c;a:if(n(a))c=n(b)&&1==b.length?a.indexOf(b,0):-1;else{for(c=0;c<a.length;c++)if(c in a&&a[c]===b)break a;c=-1}return 0<=c}function ea(a,b,c){return 2>=arguments.length?s.slice.call(a,b):s.slice.call(a,b,c)};var u={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",
 darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",
 ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",
 lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",
 moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",
 seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};var fa="background-color border-top-color border-right-color border-bottom-color border-left-color color outline-color".split(" "),ga=/#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/;function ha(a){if(!x.test(a))throw Error("'"+a+"' is not a valid hex color");4==a.length&&(a=a.replace(ga,"#$1$1$2$2$3$3"));return a.toLowerCase()}var x=/^#(?:[0-9a-f]{3}){1,2}$/i,ia=/^(?:rgba)?\((\d{1,3}),\s?(\d{1,3}),\s?(\d{1,3}),\s?(0|1|0\.\d*)\)$/i;
 function ja(a){var b=a.match(ia);if(b){a=Number(b[1]);var c=Number(b[2]),d=Number(b[3]),b=Number(b[4]);if(0<=a&&255>=a&&0<=c&&255>=c&&0<=d&&255>=d&&0<=b&&1>=b)return[a,c,d,b]}return[]}var ka=/^(?:rgb)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\)$/i;function la(a){var b=a.match(ka);if(b){a=Number(b[1]);var c=Number(b[2]),b=Number(b[3]);if(0<=a&&255>=a&&0<=c&&255>=c&&0<=b&&255>=b)return[a,c,b]}return[]};function y(a,b){this.code=a;this.state=z[a]||ma;this.message=b||"";var c=this.state.replace(/((?:^|\s+)[a-z])/g,function(a){return a.toUpperCase().replace(/^[\s\xa0]+/g,"")}),d=c.length-5;if(0>d||c.indexOf("Error",d)!=d)c+="Error";this.name=c;c=Error(this.message);c.name=this.name;this.stack=c.stack||""}(function(){var a=Error;function b(){}b.prototype=a.prototype;y.I=a.prototype;y.prototype=new b})();
 var ma="unknown error",z={15:"element not selectable",11:"element not visible",31:"ime engine activation failed",30:"ime not available",24:"invalid cookie domain",29:"invalid element coordinates",12:"invalid element state",32:"invalid selector",51:"invalid selector",52:"invalid selector",17:"javascript error",405:"unsupported operation",34:"move target out of bounds",27:"no such alert",7:"no such element",8:"no such frame",23:"no such window",28:"script timeout",33:"session not created",10:"stale element reference",
-0:"success",21:"timeout",25:"unable to set cookie",26:"unexpected alert open"};z[13]=ma;z[9]="unknown command";y.prototype.toString=function(){return this.name+": "+this.message};var r,na="",oa=/rv\:([^\);]+)(\)|;)/.exec(h.navigator?h.navigator.userAgent:null);r=na=oa?oa[1]:"";var A={};var B;A["1.9.1"]||(A["1.9.1"]=0<=q("1.9.1"));function C(a,b){this.x=void 0!==a?a:0;this.y=void 0!==b?b:0}C.prototype.toString=function(){return"("+this.x+", "+this.y+")"};C.prototype.ceil=function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this};C.prototype.floor=function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};C.prototype.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};function D(a,b){this.width=a;this.height=b}D.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};D.prototype.ceil=function(){this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};D.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};D.prototype.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this};var pa=3;function E(a,b){if(a.contains&&1==b.nodeType)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||Boolean(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a}
+0:"success",21:"timeout",25:"unable to set cookie",26:"unexpected alert open"};z[13]=ma;z[9]="unknown command";y.prototype.toString=function(){return this.name+": "+this.message};var r,na="",oa=/rv\:([^\);]+)(\)|;)/.exec(k.navigator?k.navigator.userAgent:null);r=na=oa?oa[1]:"";var A={};var B;A["1.9.1"]||(A["1.9.1"]=0<=q("1.9.1"));function C(a,b){this.x=void 0!==a?a:0;this.y=void 0!==b?b:0}C.prototype.toString=function(){return"("+this.x+", "+this.y+")"};C.prototype.ceil=function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this};C.prototype.floor=function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};C.prototype.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};function D(a,b){this.width=a;this.height=b}D.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};D.prototype.ceil=function(){this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};D.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};D.prototype.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this};var pa=3;function E(a,b){if(a.contains&&1==b.nodeType)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||Boolean(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a}
 function qa(a,b){if(a==b)return 0;if(a.compareDocumentPosition)return a.compareDocumentPosition(b)&2?1:-1;if("sourceIndex"in a||a.parentNode&&"sourceIndex"in a.parentNode){var c=1==a.nodeType,d=1==b.nodeType;if(c&&d)return a.sourceIndex-b.sourceIndex;var e=a.parentNode,f=b.parentNode;return e==f?ra(a,b):!c&&E(e,b)?-1*sa(a,b):!d&&E(f,a)?sa(b,a):(c?a.sourceIndex:e.sourceIndex)-(d?b.sourceIndex:f.sourceIndex)}d=F(a);c=d.createRange();c.selectNode(a);c.collapse(!0);d=d.createRange();d.selectNode(b);d.collapse(!0);
-return c.compareBoundaryPoints(h.Range.START_TO_END,d)}function sa(a,b){var c=a.parentNode;if(c==b)return-1;for(var d=b;d.parentNode!=c;)d=d.parentNode;return ra(d,a)}function ra(a,b){for(var c=b;c=c.previousSibling;)if(c==a)return-1;return 1}function F(a){return 9==a.nodeType?a:a.ownerDocument||a.document}function ta(a,b){a=a.parentNode;for(var c=0;a;){if(b(a))return a;a=a.parentNode;c++}return null}function G(a){this.p=a||h.document||document}
+return c.compareBoundaryPoints(k.Range.START_TO_END,d)}function sa(a,b){var c=a.parentNode;if(c==b)return-1;for(var d=b;d.parentNode!=c;)d=d.parentNode;return ra(d,a)}function ra(a,b){for(var c=b;c=c.previousSibling;)if(c==a)return-1;return 1}function F(a){return 9==a.nodeType?a:a.ownerDocument||a.document}function ta(a,b){a=a.parentNode;for(var c=0;a;){if(b(a))return a;a=a.parentNode;c++}return null}function G(a){this.p=a||k.document||document}
 function ua(a){var b=a.p;a="CSS1Compat"==b.compatMode?b.documentElement:b.body;b=b.parentWindow||b.defaultView;return new C(b.pageXOffset||a.scrollLeft,b.pageYOffset||a.scrollTop)}G.prototype.contains=E;function H(a){var b=null,c=a.nodeType;1==c&&(b=a.textContent,b=void 0==b||null==b?a.innerText:b,b=void 0==b||null==b?"":b);if("string"!=typeof b)if(9==c||1==c){a=9==c?a.documentElement:a.firstChild;for(var c=0,d=[],b="";a;){do 1!=a.nodeType&&(b+=a.nodeValue),d[c++]=a;while(a=a.firstChild);for(;c&&!(a=d[--c].nextSibling););}}else b=a.nodeValue;return""+b}
 function I(a,b,c){if(null===b)return!0;try{if(!a.getAttribute)return!1}catch(d){return!1}return null==c?!!a.getAttribute(b):a.getAttribute(b,2)==c}function J(a,b,c,d,e){return va.call(null,a,b,n(c)?c:null,n(d)?d:null,e||new K)}
 function va(a,b,c,d,e){b.getElementsByName&&d&&"name"==c?(b=b.getElementsByName(d),t(b,function(b){a.matches(b)&&e.add(b)})):b.getElementsByClassName&&d&&"class"==c?(b=b.getElementsByClassName(d),t(b,function(b){b.className==d&&a.matches(b)&&e.add(b)})):b.getElementsByTagName&&(b=b.getElementsByTagName(a.getName()),t(b,function(a){I(a,c,d)&&e.add(a)}));return e}function wa(a,b,c,d,e){for(b=b.firstChild;b;b=b.nextSibling)I(b,c,d)&&a.matches(b)&&e.add(b);return e};function K(){this.d=this.c=null;this.g=0}function xa(a){this.m=a;this.next=this.i=null}K.prototype.unshift=function(a){a=new xa(a);a.next=this.c;this.d?this.c.i=a:this.c=this.d=a;this.c=a;this.g++};K.prototype.add=function(a){a=new xa(a);a.i=this.d;this.c?this.d.next=a:this.c=this.d=a;this.d=a;this.g++};function ya(a){return(a=a.c)?a.m:null}function L(a){return new za(a,!1)}function za(a,b){this.F=a;this.j=(this.n=b)?a.d:a.c;this.r=null}
 za.prototype.next=function(){var a=this.j;if(null==a)return null;var b=this.r=a;this.j=this.n?a.i:a.next;return b.m};function M(a,b,c,d,e){b=b.evaluate(d);c=c.evaluate(d);var f;if(b instanceof K&&c instanceof K){e=L(b);for(d=e.next();d;d=e.next())for(b=L(c),f=b.next();f;f=b.next())if(a(H(d),H(f)))return!0;return!1}if(b instanceof K||c instanceof K){b instanceof K?e=b:(e=c,c=b);e=L(e);b=typeof c;for(d=e.next();d;d=e.next()){switch(b){case "number":d=+H(d);break;case "boolean":d=!!H(d);break;case "string":d=H(d);break;default:throw Error("Illegal primitive type for comparison.");}if(a(d,c))return!0}return!1}return e?
 "boolean"==typeof b||"boolean"==typeof c?a(!!b,!!c):"number"==typeof b||"number"==typeof c?a(+b,+c):a(b,c):a(+b,+c)}function Aa(a,b,c,d){this.s=a;this.H=b;this.o=c;this.q=d}Aa.prototype.toString=function(){return this.s};var Ba={};function N(a,b,c,d){if(a in Ba)throw Error("Binary operator already created: "+a);a=new Aa(a,b,c,d);Ba[a.toString()]=a}N("div",6,1,function(a,b,c){return a.b(c)/b.b(c)});N("mod",6,1,function(a,b,c){return a.b(c)%b.b(c)});N("*",6,1,function(a,b,c){return a.b(c)*b.b(c)});
 N("+",5,1,function(a,b,c){return a.b(c)+b.b(c)});N("-",5,1,function(a,b,c){return a.b(c)-b.b(c)});N("<",4,2,function(a,b,c){return M(function(a,b){return a<b},a,b,c)});N(">",4,2,function(a,b,c){return M(function(a,b){return a>b},a,b,c)});N("<=",4,2,function(a,b,c){return M(function(a,b){return a<=b},a,b,c)});N(">=",4,2,function(a,b,c){return M(function(a,b){return a>=b},a,b,c)});N("=",3,2,function(a,b,c){return M(function(a,b){return a==b},a,b,c,!0)});
-N("!=",3,2,function(a,b,c){return M(function(a,b){return a!=b},a,b,c,!0)});N("and",2,2,function(a,b,c){return a.f(c)&&b.f(c)});N("or",1,2,function(a,b,c){return a.f(c)||b.f(c)});function Ca(a,b,c,d,e,f,k,w,p){this.h=a;this.o=b;this.D=c;this.C=d;this.B=e;this.q=f;this.A=k;this.w=void 0!==w?w:k;this.G=!!p}Ca.prototype.toString=function(){return this.h};var Da={};function O(a,b,c,d,e,f,k,w){if(a in Da)throw Error("Function already created: "+a+".");Da[a]=new Ca(a,b,c,d,!1,e,f,k,w)}O("boolean",2,!1,!1,function(a,b){return b.f(a)},1);O("ceiling",1,!1,!1,function(a,b){return Math.ceil(b.b(a))},1);
-O("concat",3,!1,!1,function(a,b){var c=ea(arguments,1);return ba(c,function(b,c){return b+c.a(a)})},2,null);O("contains",2,!1,!1,function(a,b,c){b=b.a(a);a=c.a(a);return-1!=b.indexOf(a)},2);O("count",1,!1,!1,function(a,b){return b.evaluate(a).g},1,1,!0);O("false",2,!1,!1,g(!1),0);O("floor",1,!1,!1,function(a,b){return Math.floor(b.b(a))},1);
-O("id",4,!1,!1,function(a,b){var c=a.e(),d=9==c.nodeType?c:c.ownerDocument,c=b.a(a).split(/\s+/),e=[];t(c,function(a){(a=d.getElementById(a))&&!da(e,a)&&e.push(a)});e.sort(qa);var f=new K;t(e,function(a){f.add(a)});return f},1);O("lang",2,!1,!1,g(!1),1);O("last",1,!0,!1,function(a){if(1!=arguments.length)throw Error("Function last expects ()");return a.u()},0);O("local-name",3,!1,!0,function(a,b){var c=b?ya(b.evaluate(a)):a.e();return c?c.nodeName.toLowerCase():""},0,1,!0);
-O("name",3,!1,!0,function(a,b){var c=b?ya(b.evaluate(a)):a.e();return c?c.nodeName.toLowerCase():""},0,1,!0);O("namespace-uri",3,!0,!1,g(""),0,1,!0);O("normalize-space",3,!1,!0,function(a,b){return(b?b.a(a):H(a.e())).replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,"")},0,1);O("not",2,!1,!1,function(a,b){return!b.f(a)},1);O("number",1,!1,!0,function(a,b){return b?b.b(a):+H(a.e())},0,1);O("position",1,!0,!1,function(a){return a.v()},0);O("round",1,!1,!1,function(a,b){return Math.round(b.b(a))},1);
+N("!=",3,2,function(a,b,c){return M(function(a,b){return a!=b},a,b,c,!0)});N("and",2,2,function(a,b,c){return a.f(c)&&b.f(c)});N("or",1,2,function(a,b,c){return a.f(c)||b.f(c)});function Ca(a,b,c,d,e,f,g,w,p){this.h=a;this.o=b;this.D=c;this.C=d;this.B=e;this.q=f;this.A=g;this.w=void 0!==w?w:g;this.G=!!p}Ca.prototype.toString=function(){return this.h};var Da={};function O(a,b,c,d,e,f,g,w){if(a in Da)throw Error("Function already created: "+a+".");Da[a]=new Ca(a,b,c,d,!1,e,f,g,w)}O("boolean",2,!1,!1,function(a,b){return b.f(a)},1);O("ceiling",1,!1,!1,function(a,b){return Math.ceil(b.b(a))},1);
+O("concat",3,!1,!1,function(a,b){var c=ea(arguments,1);return ba(c,function(b,c){return b+c.a(a)})},2,null);O("contains",2,!1,!1,function(a,b,c){b=b.a(a);a=c.a(a);return-1!=b.indexOf(a)},2);O("count",1,!1,!1,function(a,b){return b.evaluate(a).g},1,1,!0);O("false",2,!1,!1,h(!1),0);O("floor",1,!1,!1,function(a,b){return Math.floor(b.b(a))},1);
+O("id",4,!1,!1,function(a,b){var c=a.e(),d=9==c.nodeType?c:c.ownerDocument,c=b.a(a).split(/\s+/),e=[];t(c,function(a){(a=d.getElementById(a))&&!da(e,a)&&e.push(a)});e.sort(qa);var f=new K;t(e,function(a){f.add(a)});return f},1);O("lang",2,!1,!1,h(!1),1);O("last",1,!0,!1,function(a){if(1!=arguments.length)throw Error("Function last expects ()");return a.u()},0);O("local-name",3,!1,!0,function(a,b){var c=b?ya(b.evaluate(a)):a.e();return c?c.nodeName.toLowerCase():""},0,1,!0);
+O("name",3,!1,!0,function(a,b){var c=b?ya(b.evaluate(a)):a.e();return c?c.nodeName.toLowerCase():""},0,1,!0);O("namespace-uri",3,!0,!1,h(""),0,1,!0);O("normalize-space",3,!1,!0,function(a,b){return(b?b.a(a):H(a.e())).replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,"")},0,1);O("not",2,!1,!1,function(a,b){return!b.f(a)},1);O("number",1,!1,!0,function(a,b){return b?b.b(a):+H(a.e())},0,1);O("position",1,!0,!1,function(a){return a.v()},0);O("round",1,!1,!1,function(a,b){return Math.round(b.b(a))},1);
 O("starts-with",2,!1,!1,function(a,b,c){b=b.a(a);a=c.a(a);return 0==b.lastIndexOf(a,0)},2);O("string",3,!1,!0,function(a,b){return b?b.a(a):H(a.e())},0,1);O("string-length",1,!1,!0,function(a,b){return(b?b.a(a):H(a.e())).length},0,1);
 O("substring",3,!1,!1,function(a,b,c,d){c=c.b(a);if(isNaN(c)||Infinity==c||-Infinity==c)return"";d=d?d.b(a):Infinity;if(isNaN(d)||-Infinity===d)return"";c=Math.round(c)-1;var e=Math.max(c,0);a=b.a(a);if(Infinity==d)return a.substring(e);b=Math.round(d);return a.substring(e,c+b)},2,3);O("substring-after",3,!1,!1,function(a,b,c){b=b.a(a);a=c.a(a);c=b.indexOf(a);return-1==c?"":b.substring(c+a.length)},2);
-O("substring