Merge last PGO green inbound changeset to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 16 May 2012 20:48:40 -0400
changeset 94288 762e95608da3f351e18fc649a6e3ac0dd3da5971
parent 94188 e493ce7639a3117baf534b50990660d8589c5464 (current diff)
parent 94133 b71580a40d5977a880411b4e87a6e063159a8203 (diff)
child 94289 f2b2b99108a20379283763389aae595f463aa1a4
child 94478 068b9453c49828d296f006c3186784a05d59363b
push id9557
push userryanvm@gmail.com
push dateFri, 18 May 2012 03:24:12 +0000
treeherdermozilla-inbound@a3f95b85178e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone15.0a1
first release with
nightly linux32
762e95608da3 / 15.0a1 / 20120517030523 / files
nightly linux64
762e95608da3 / 15.0a1 / 20120517030523 / files
nightly mac
762e95608da3 / 15.0a1 / 20120517030523 / files
nightly win32
762e95608da3 / 15.0a1 / 20120517030523 / files
nightly win64
762e95608da3 / 15.0a1 / 20120517030523 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge last PGO green inbound changeset to m-c.
browser/base/content/browser.js
js/src/jit-test/tests/basic/bug529130.js
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -60,16 +60,17 @@
 #include "nsFrameSelection.h"
 #include "nsILineIterator.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIPlaintextEditor.h"
 #include "nsIScrollableFrame.h"
 #include "nsISelectionPrivate.h"
 #include "nsIServiceManager.h"
 #include "nsTextFragment.h"
+#include "nsTypedSelection.h"
 #include "gfxSkipChars.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHyperTextAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -1312,19 +1312,16 @@ nsAccessibleWrap::get_groupPosition(long
 }
 
 STDMETHODIMP
 nsAccessibleWrap::get_states(AccessibleStates *aStates)
 {
 __try {
   *aStates = 0;
 
-  if (IsDefunct())
-    return CO_E_OBJNOTCONNECTED;
-
   // XXX: bug 344674 should come with better approach that we have here.
 
   PRUint64 state = State();
 
   if (state & states::INVALID)
     *aStates |= IA2_STATE_INVALID_ENTRY;
   if (state & states::REQUIRED)
     *aStates |= IA2_STATE_REQUIRED;
--- a/accessible/tests/mochitest/tree/test_img.html
+++ b/accessible/tests/mochitest/tree/test_img.html
@@ -2,16 +2,18 @@
 <html>
 <head>
   <title>HTML img tests</title>
   <link rel="stylesheet" type="text/css"
         href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
 
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../role.js"></script>
 
   <script type="application/javascript">
     function doTest()
@@ -26,16 +28,17 @@
           },
           {
             role: ROLE_LINK,
             children: []
           }
         ]
       };
 
+      ensureImageMapTree("imgmap");
       testAccessibleTree("imgmap", accTree);
 
       // img
       accTree = {
         role: ROLE_GRAPHIC,
         children: []
       };
 
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -420,20 +420,22 @@ pref("layers.acceleration.force-enabled"
 // 1=current window/tab, 2=new window, 3=new tab in most recent window
 pref("browser.link.open_newwindow", 3);
 
 // 0: no restrictions - divert everything
 // 1: don't divert window.open at all
 // 2: don't divert window.open with features
 pref("browser.link.open_newwindow.restriction", 0);
 
-// Enable browser frames, but not OOP.
+// Enable browser frames (including OOP), but make in-process browser frames
+// the default.
 pref("dom.mozBrowserFramesEnabled", true);
 pref("dom.mozBrowserFramesWhitelist", "http://homescreen.gaiamobile.org,http://browser.gaiamobile.org");
-pref("dom.ipc.tabs.disabled", true);
+pref("dom.ipc.tabs.disabled", false);
+pref("dom.ipc.browser_frames.oop_by_default", false);
 
 // Temporary permission hack for WebSMS
 pref("dom.sms.enabled", true);
 pref("dom.sms.whitelist", "file://,http://homescreen.gaiamobile.org,http://sms.gaiamobile.org");
 
 // Temporary permission hack for WebMobileConnection
 pref("dom.mobileconnection.whitelist", "http://system.gaiamobile.org,http://homescreen.gaiamobile.org,http://dialer.gaiamobile.org");
 
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -442,16 +442,18 @@
 @BINPATH@/components/Weave.js
 @BINPATH@/components/WeaveCrypto.manifest
 @BINPATH@/components/WeaveCrypto.js
 #endif
 @BINPATH@/components/TelemetryPing.js
 @BINPATH@/components/TelemetryPing.manifest
 @BINPATH@/components/Webapps.js
 @BINPATH@/components/Webapps.manifest
+@BINPATH@/components/AppsService.js
+@BINPATH@/components/AppsService.manifest
 
 ; Modules
 @BINPATH@/modules/*
 
 ; Safe Browsing
 @BINPATH@/components/nsURLClassifier.manifest
 @BINPATH@/components/nsUrlClassifierHashCompleter.js
 @BINPATH@/components/nsUrlClassifierListManager.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -7242,16 +7242,35 @@ var gPluginHandler = {
       if (!objLoadingContent.activated)
         objLoadingContent.playPlugin();
     }
     let notification = PopupNotifications.getNotification("click-to-play-plugins", browser);
     if (notification)
       notification.remove();
   },
 
+  activateSinglePlugin: function PH_activateSinglePlugin(aContentWindow, aPlugin) {
+    let objLoadingContent = aPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
+    if (!objLoadingContent.activated)
+      objLoadingContent.playPlugin();
+
+    let cwu = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+                            .getInterface(Ci.nsIDOMWindowUtils);
+    let haveUnplayedPlugins = cwu.plugins.some(function(plugin) {
+      let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+      return (plugin != aPlugin && !objLoadingContent.activated);
+    });
+    let browser = gBrowser.getBrowserForDocument(aContentWindow.document);
+    let notification = PopupNotifications.getNotification("click-to-play-plugins", browser);
+    if (notification && !haveUnplayedPlugins) {
+      browser._clickToPlayDoorhangerShown = false;
+      notification.remove();
+    }
+  },
+
   newPluginInstalled : function(event) {
     // browser elements are anonymous so we can't just use target.
     var browser = event.originalTarget;
     // clear the plugin list, now that at least one plugin has been installed
     browser.missingPlugins = null;
 
     var notificationBox = gBrowser.getNotificationBox(browser);
     var notification = notificationBox.getNotificationWithValue("missing-plugins");
@@ -7316,17 +7335,17 @@ var gPluginHandler = {
       return;
     }
 
     let overlay = doc.getAnonymousElementByAttribute(aPlugin, "class", "mainBox");
     // The overlay is null if the XBL binding is not attached (element is display:none).
     if (overlay) {
       overlay.addEventListener("click", function(aEvent) {
         if (aEvent.button == 0 && aEvent.isTrusted)
-          gPluginHandler.activatePlugins(aEvent.target.ownerDocument.defaultView.top);
+          gPluginHandler.activateSinglePlugin(aEvent.target.ownerDocument.defaultView.top, aPlugin);
       }, true);
     }
 
     if (!browser._clickToPlayDoorhangerShown)
       gPluginHandler._showClickToPlayNotification(browser);
   },
 
   reshowClickToPlayNotification: function PH_reshowClickToPlayNotification() {
--- a/browser/base/content/test/browser_bug743421.js
+++ b/browser/base/content/test/browser_bug743421.js
@@ -47,17 +47,17 @@ function test1a() {
 
 function test1b() {
   var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
   ok(popupNotification, "Test 1b, Should have a click-to-play notification");
   var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0];
   var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
   ok(!objLoadingContent.activated, "Test 1b, Plugin should not be activated");
 
-  EventUtils.synthesizeMouse(plugin, 100, 100, { });
+  popupNotification.mainAction.callback();
   setTimeout(test1c, 500);
 }
 
 function test1c() {
   var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
   ok(!popupNotification, "Test 1c, Should not have a click-to-play notification");
   var plugin = gTestBrowser.contentWindow.addPlugin();
 
--- a/browser/base/content/test/browser_pluginnotification.js
+++ b/browser/base/content/test/browser_pluginnotification.js
@@ -1,15 +1,15 @@
 var rootDir = getRootDirectory(gTestPath);
 const gTestRoot = rootDir;
 
 var gTestBrowser = null;
 var gNextTest = null;
 var gClickToPlayPluginActualEvents = 0;
-var gClickToPlayPluginExpectedEvents = 6;
+var gClickToPlayPluginExpectedEvents = 5;
 
 function get_test_plugin() {
   var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
   var tags = ph.getPluginTags();
 
   // Find the test plugin
   for (var i = 0; i < tags.length; i++) {
     if (tags[i].name == "Test Plug-in")
@@ -208,60 +208,92 @@ function test8() {
   ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 8, Should not have displayed the missing plugin notification");
   ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 8, Should not have displayed the blocked plugin notification");
   ok(!gTestBrowser.missingPlugins, "Test 8, Should not be a missing plugin list");
   ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "Test 8, Should have a click-to-play notification");
 
   prepareTest(test9a, gTestRoot + "plugin_test2.html");
 }
 
-// Tests that activating one click-to-play plugin will activate the other plugins (part 1/1)
+// Tests that activating one click-to-play plugin will activate only that plugin (part 1/3)
 function test9a() {
   var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
   ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 9a, Should not have displayed the missing plugin notification");
   ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 9a, Should not have displayed the blocked plugin notification");
   ok(!gTestBrowser.missingPlugins, "Test 9a, Should not be a missing plugin list");
   ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "Test 9a, Should have a click-to-play notification");
-  var plugin1 = gTestBrowser.contentDocument.getElementById("test");
+
   var doc = gTestBrowser.contentDocument;
-  var plugins = [];
-  plugins.push(doc.getElementById("test"));
-  plugins.push(doc.getElementById("test1"));
-  plugins.push(doc.getElementById("test2"));
-  plugins.forEach(function(plugin) {
-    var rect = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox").getBoundingClientRect();
-    ok(rect.width == 200, "Test 9a, Plugin with id=" + plugin.id + " overlay rect should have 200px width before being clicked");
-    ok(rect.height == 200, "Test 9a, Plugin with id=" + plugin.id + " overlay rect should have 200px height before being clicked");
-    var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-    ok(!objLoadingContent.activated, "Test 9a, Plugin with id=" + plugin.id + " should not be activated");
-  });
+  var plugin1 = doc.getElementById("test1");
+  var rect = doc.getAnonymousElementByAttribute(plugin1, "class", "mainBox").getBoundingClientRect();
+  ok(rect.width == 200, "Test 9a, Plugin with id=" + plugin1.id + " overlay rect should have 200px width before being clicked");
+  ok(rect.height == 200, "Test 9a, Plugin with id=" + plugin1.id + " overlay rect should have 200px height before being clicked");
+  var objLoadingContent = plugin1.QueryInterface(Ci.nsIObjectLoadingContent);
+  ok(!objLoadingContent.activated, "Test 9a, Plugin with id=" + plugin1.id + " should not be activated");
+
+  var plugin2 = doc.getElementById("test2");
+  var rect = doc.getAnonymousElementByAttribute(plugin2, "class", "mainBox").getBoundingClientRect();
+  ok(rect.width == 200, "Test 9a, Plugin with id=" + plugin2.id + " overlay rect should have 200px width before being clicked");
+  ok(rect.height == 200, "Test 9a, Plugin with id=" + plugin2.id + " overlay rect should have 200px height before being clicked");
+  var objLoadingContent = plugin2.QueryInterface(Ci.nsIObjectLoadingContent);
+  ok(!objLoadingContent.activated, "Test 9a, Plugin with id=" + plugin2.id + " should not be activated");
 
   EventUtils.synthesizeMouse(plugin1, 100, 100, { });
   setTimeout(test9b, 1000);
 }
 
-// Tests that activating one click-to-play plugin will activate the other plugins (part 2/2)
+// Tests that activating one click-to-play plugin will activate only that plugin (part 2/3)
 function test9b() {
   var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
   ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 9b, Should not have displayed the missing plugin notification");
   ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 9b, Should not have displayed the blocked plugin notification");
   ok(!gTestBrowser.missingPlugins, "Test 9b, Should not be a missing plugin list");
-  ok(!PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "Test 9b, Click to play notification should be removed now");
+  ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "Test 9b, Click to play notification should not be removed now");
+
   var doc = gTestBrowser.contentDocument;
-  var plugins = [];
-  plugins.push(doc.getElementById("test"));
-  plugins.push(doc.getElementById("test1"));
-  plugins.push(doc.getElementById("test2"));
-  plugins.forEach(function(plugin) {
-    var pluginRect = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox").getBoundingClientRect();
-    ok(pluginRect.width == 0, "Test 9b, Plugin with id=" + plugin.id + " should have click-to-play overlay with zero width");
-    ok(pluginRect.height == 0, "Test 9b, Plugin with id=" + plugin.id + " should have click-to-play overlay with zero height");
-    var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-    ok(objLoadingContent.activated, "Test 9b, Plugin with id=" + plugin.id + " should be activated");
-  });
+  var plugin1 = doc.getElementById("test1");
+  var pluginRect1 = doc.getAnonymousElementByAttribute(plugin1, "class", "mainBox").getBoundingClientRect();
+  ok(pluginRect1.width == 0, "Test 9b, Plugin with id=" + plugin1.id + " should have click-to-play overlay with zero width");
+  ok(pluginRect1.height == 0, "Test 9b, Plugin with id=" + plugin1.id + " should have click-to-play overlay with zero height");
+  var objLoadingContent = plugin1.QueryInterface(Ci.nsIObjectLoadingContent);
+  ok(objLoadingContent.activated, "Test 9b, Plugin with id=" + plugin1.id + " should be activated");
+
+  var plugin2 = doc.getElementById("test2");
+  var pluginRect2 = doc.getAnonymousElementByAttribute(plugin2, "class", "mainBox").getBoundingClientRect();
+  ok(pluginRect2.width != 0, "Test 9b, Plugin with id=" + plugin2.id + " should not have click-to-play overlay with zero width");
+  ok(pluginRect2.height != 0, "Test 9b, Plugin with id=" + plugin2.id + " should not have click-to-play overlay with zero height");
+  var objLoadingContent = plugin2.QueryInterface(Ci.nsIObjectLoadingContent);
+  ok(!objLoadingContent.activated, "Test 9b, Plugin with id=" + plugin2.id + " should not be activated");
+
+  EventUtils.synthesizeMouse(plugin2, 100, 100, { });
+  setTimeout(test9c, 1000);
+}
+//
+// Tests that activating one click-to-play plugin will activate only that plugin (part 3/3)
+function test9c() {
+  var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
+  ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 9c, Should not have displayed the missing plugin notification");
+  ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 9c, Should not have displayed the blocked plugin notification");
+  ok(!gTestBrowser.missingPlugins, "Test 9c, Should not be a missing plugin list");
+  ok(!PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "Test 9c, Click to play notification should be removed now");
+
+  var doc = gTestBrowser.contentDocument;
+  var plugin1 = doc.getElementById("test1");
+  var pluginRect1 = doc.getAnonymousElementByAttribute(plugin1, "class", "mainBox").getBoundingClientRect();
+  ok(pluginRect1.width == 0, "Test 9c, Plugin with id=" + plugin1.id + " should have click-to-play overlay with zero width");
+  ok(pluginRect1.height == 0, "Test 9c, Plugin with id=" + plugin1.id + " should have click-to-play overlay with zero height");
+  var objLoadingContent = plugin1.QueryInterface(Ci.nsIObjectLoadingContent);
+  ok(objLoadingContent.activated, "Test 9c, Plugin with id=" + plugin1.id + " should be activated");
+
+  var plugin2 = doc.getElementById("test1");
+  var pluginRect2 = doc.getAnonymousElementByAttribute(plugin2, "class", "mainBox").getBoundingClientRect();
+  ok(pluginRect2.width == 0, "Test 9c, Plugin with id=" + plugin2.id + " should have click-to-play overlay with zero width");
+  ok(pluginRect2.height == 0, "Test 9c, Plugin with id=" + plugin2.id + " should have click-to-play overlay with zero height");
+  var objLoadingContent = plugin2.QueryInterface(Ci.nsIObjectLoadingContent);
+  ok(objLoadingContent.activated, "Test 9c, Plugin with id=" + plugin2.id + " should be activated");
 
   prepareTest(test10a, gTestRoot + "plugin_test3.html");
 }
 
 // Tests that activating a hidden click-to-play plugin through the notification works (part 1/2)
 function test10a() {
   var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
   ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 10a, Should not have displayed the missing plugin notification");
@@ -318,17 +350,16 @@ function test11d() {
     ok(popupNotification, "Test 11d, Should have a click-to-play notification");
     is(gClickToPlayPluginActualEvents, gClickToPlayPluginExpectedEvents,
        "There should be a PluginClickToPlay event for each plugin that was " +
        "blocked due to the plugins.click_to_play pref");
 
     prepareTest(test12a, gTestRoot + "plugin_clickToPlayAllow.html");
   }, 1000);
 
-  
 }
 
 // Tests that the "Allow Always" permission works for click-to-play plugins (part 1/3)
 function test12a() {
   var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
   ok(popupNotification, "Test 12a, Should have a click-to-play notification");
   var plugin = gTestBrowser.contentDocument.getElementById("test");
   var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
@@ -402,17 +433,17 @@ function test13c() {
 
   Services.perms.removeAll();
   Services.prefs.setBoolPref("plugins.click_to_play", false);
   prepareTest(test14, gTestRoot + "plugin_test2.html");
 }
 
 // Tests that the plugin's "activated" property is true for working plugins with click-to-play disabled.
 function test14() {
-  var plugin = gTestBrowser.contentDocument.getElementById("test");
+  var plugin = gTestBrowser.contentDocument.getElementById("test1");
   var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
   ok(objLoadingContent.activated, "Test 14, Plugin should be activated");
 
   var plugin = get_test_plugin();
   plugin.disabled = false;
   plugin.blocklisted = false;
   Services.perms.removeAll();
   Services.prefs.setBoolPref("plugins.click_to_play", true);
@@ -422,10 +453,54 @@ function test14() {
 // Tests that the overlay is shown instead of alternate content when
 // plugins are click to play
 function test15() {
   var plugin = gTestBrowser.contentDocument.getElementById("test");
   var doc = gTestBrowser.contentDocument;
   var mainBox = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
   ok(mainBox, "Test 15, Plugin with id=" + plugin.id + " overlay should exist");
 
+  prepareTest(test16a, gTestRoot + "plugin_bug743421.html");
+}
+
+// Tests that a plugin dynamically added to a page after one plugin is clicked
+// to play (which removes the notification) gets its own notification (1/4)
+function test16a() {
+  var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
+  ok(!popupNotification, "Test 16a, Should not have a click-to-play notification");
+  var plugin = gTestBrowser.contentWindow.addPlugin();
+
+  setTimeout(test16b, 100);
+}
+
+// 2/4
+function test16b() {
+  var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
+  ok(popupNotification, "Test 16b, Should have a click-to-play notification");
+  var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0];
+  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+  ok(!objLoadingContent.activated, "Test 16b, Plugin should not be activated");
+  EventUtils.synthesizeMouse(plugin, 100, 100, { });
+  setTimeout(test16c, 100);
+}
+
+// 3/4
+function test16c() {
+  var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
+  ok(!popupNotification, "Test 16c, Should not have a click-to-play notification");
+  var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0];
+  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+  ok(objLoadingContent.activated, "Test 16c, Plugin should be activated");
+  var plugin = gTestBrowser.contentWindow.addPlugin();
+
+  setTimeout(test16d, 100);
+}
+
+// 4/4
+function test16d() {
+  var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
+  ok(popupNotification, "Test 16d, Should have a click-to-play notification");
+  var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[1];
+  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+  ok(!objLoadingContent.activated, "Test 16d, Plugin should not be activated");
+
   finishTest();
 }
--- a/browser/base/content/test/plugin_test2.html
+++ b/browser/base/content/test/plugin_test2.html
@@ -1,11 +1,10 @@
 <!DOCTYPE html>
 <html>
-<head>
-<meta charset="utf-8">
+<head>
+<meta charset="utf-8">
 </head>
 <body>
-<embed id="test" style="width: 200px; height: 200px" type="application/x-test">
 <embed id="test1" style="width: 200px; height: 200px" type="application/x-test">
 <embed id="test2" style="width: 200px; height: 200px" type="application/x-test">
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/browser/config/tooltool-manifests/linux32/releng.manifest
@@ -0,0 +1,1 @@
+[]
new file mode 100644
--- /dev/null
+++ b/browser/config/tooltool-manifests/linux64/releng.manifest
@@ -0,0 +1,1 @@
+[]
new file mode 100644
--- /dev/null
+++ b/browser/config/tooltool-manifests/macosx32/releng.manifest
@@ -0,0 +1,1 @@
+[]
new file mode 100644
--- /dev/null
+++ b/browser/config/tooltool-manifests/macosx64/releng.manifest
@@ -0,0 +1,1 @@
+[]
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -435,16 +435,18 @@
 @BINPATH@/components/TelemetryPing.js
 @BINPATH@/components/TelemetryPing.manifest
 @BINPATH@/components/messageWakeupService.js
 @BINPATH@/components/messageWakeupService.manifest
 @BINPATH@/components/SettingsManager.js
 @BINPATH@/components/SettingsManager.manifest
 @BINPATH@/components/Webapps.js
 @BINPATH@/components/Webapps.manifest
+@BINPATH@/components/AppsService.js
+@BINPATH@/components/AppsService.manifest
 
 @BINPATH@/components/ContactManager.js
 @BINPATH@/components/ContactManager.manifest
 
 ; Modules
 @BINPATH@/modules/*
 
 ; Safe Browsing
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -331,16 +331,17 @@ class Automation(object):
     self.setupPermissionsDatabase(profileDir,
       {'allowXULXBL':[(l.host, 'noxul' not in l.options) for l in locations]});
 
     part = """\
 user_pref("browser.console.showInPanel", true);
 user_pref("browser.dom.window.dump.enabled", true);
 user_pref("browser.firstrun.show.localepicker", false);
 user_pref("browser.firstrun.show.uidiscovery", false);
+user_pref("browser.startup.page", 0); // use about:blank, not browser.startup.homepage
 user_pref("browser.ui.layout.tablet", 0); // force tablet UI off
 user_pref("dom.allow_scripts_to_close_windows", true);
 user_pref("dom.disable_open_during_load", false);
 user_pref("dom.max_script_run_time", 0); // no slow script dialogs
 user_pref("hangmonitor.timeout", 0); // no hang monitor
 user_pref("dom.max_chrome_script_run_time", 0);
 user_pref("dom.popup_maximum", -1);
 user_pref("dom.send_after_paint_to_content", true);
--- a/build/unix/build-toolchain/build-gcc.py
+++ b/build/unix/build-toolchain/build-gcc.py
@@ -61,16 +61,20 @@ def build_aux_tools(base_dir):
 
     run_in(unifdef_source_dir, ["make"])
     run_in(unifdef_source_dir, ["make", "prefix=%s" % aux_inst_dir, "install"])
 
     tar_build_dir = base_dir + '/tar_build'
     build_package(tar_source_dir, tar_build_dir,
                   ["--prefix=%s" % aux_inst_dir])
 
+    gawk_build_dir = base_dir + '/gawk_build'
+    build_package(gawk_source_dir, gawk_build_dir,
+                  ["--prefix=%s" % aux_inst_dir])
+
 def with_env(env, f):
     old_env = os.environ.copy()
     os.environ.update(env)
     f()
     os.environ.clear()
     os.environ.update(old_env)
 
 def build_glibc(env, stage_dir, inst_dir):
@@ -184,74 +188,80 @@ def build_tar_package(tar, name, base, d
 
 def build_source_dir(prefix, version):
     return source_dir + '/' + prefix + version
 
 binutils_version = "2.21.1"
 glibc_version = "2.5.1"
 linux_version = "2.6.18"
 tar_version = "1.26"
+gawk_version = "3.1.5"
 make_version = "3.81"
 gcc_version = "4.5.2"
 mpfr_version = "2.4.2"
 gmp_version = "5.0.1"
 mpc_version = "0.8.1"
 unifdef_version = "2.6"
 
 binutils_source_uri = "http://ftp.gnu.org/gnu/binutils/binutils-%sa.tar.bz2" % \
     binutils_version
 glibc_source_uri = "http://ftp.gnu.org/gnu/glibc/glibc-%s.tar.bz2" % \
     glibc_version
 linux_source_uri = "http://www.kernel.org/pub/linux/kernel/v2.6/linux-%s.tar.bz2" % \
     linux_version
 tar_source_uri = "http://ftp.gnu.org/gnu/tar/tar-%s.tar.bz2" % \
     tar_version
+gawk_source_uri = "http://ftp.gnu.org/gnu/gawk/gawk-%s.tar.bz2" % \
+    gawk_version
 make_source_uri = "http://ftp.gnu.org/gnu/make/make-%s.tar.bz2" % \
     make_version
 unifdef_source_uri = "http://dotat.at/prog/unifdef/unifdef-%s.tar.gz" % \
     unifdef_version
 gcc_source_uri = "http://ftp.gnu.org/gnu/gcc/gcc-%s/gcc-%s.tar.bz2" % \
     (gcc_version, gcc_version)
 mpfr_source_uri = "http://www.mpfr.org/mpfr-%s/mpfr-%s.tar.bz2" % \
     (mpfr_version, mpfr_version)
 gmp_source_uri = "http://ftp.gnu.org/gnu/gmp/gmp-%s.tar.bz2" % gmp_version
 mpc_source_uri = "http://www.multiprecision.org/mpc/download/mpc-%s.tar.gz" % \
     mpc_version
 
 binutils_source_tar = download_uri(binutils_source_uri)
 glibc_source_tar = download_uri(glibc_source_uri)
 linux_source_tar = download_uri(linux_source_uri)
 tar_source_tar = download_uri(tar_source_uri)
+gawk_source_tar = download_uri(gawk_source_uri)
 make_source_tar = download_uri(make_source_uri)
 unifdef_source_tar = download_uri(unifdef_source_uri)
 mpc_source_tar = download_uri(mpc_source_uri)
 mpfr_source_tar = download_uri(mpfr_source_uri)
 gmp_source_tar = download_uri(gmp_source_uri)
 gcc_source_tar = download_uri(gcc_source_uri)
 
 binutils_source_dir  = build_source_dir('binutils-', binutils_version)
 glibc_source_dir  = build_source_dir('glibc-', glibc_version)
 linux_source_dir  = build_source_dir('linux-', linux_version)
 tar_source_dir  = build_source_dir('tar-', tar_version)
+gawk_source_dir  = build_source_dir('gawk-', gawk_version)
 make_source_dir  = build_source_dir('make-', make_version)
 unifdef_source_dir  = build_source_dir('unifdef-', unifdef_version)
 mpc_source_dir  = build_source_dir('mpc-', mpc_version)
 mpfr_source_dir = build_source_dir('mpfr-', mpfr_version)
 gmp_source_dir  = build_source_dir('gmp-', gmp_version)
 gcc_source_dir  = build_source_dir('gcc-', gcc_version)
 
 if not os.path.exists(source_dir):
     os.makedirs(source_dir)
     extract(binutils_source_tar, source_dir)
     patch('binutils-deterministic.patch', 1, binutils_source_dir)
     extract(glibc_source_tar, source_dir)
     extract(linux_source_tar, source_dir)
     patch('glibc-deterministic.patch', 1, glibc_source_dir)
     run_in(glibc_source_dir, ["autoconf"])
     extract(tar_source_tar, source_dir)
+    extract(gawk_source_tar, source_dir)
     extract(make_source_tar, source_dir)
     extract(unifdef_source_tar, source_dir)
     extract(mpc_source_tar, source_dir)
     extract(mpfr_source_tar, source_dir)
     extract(gmp_source_tar, source_dir)
     extract(gcc_source_tar, source_dir)
     patch('plugin_finish_decl.diff', 0, gcc_source_dir)
     patch('libtool-74c8993c178a1386ea5e2363a01d919738402f30.patch', 1, gcc_source_dir)
@@ -261,29 +271,34 @@ if not os.path.exists(source_dir):
     patch('gcc-include.patch', 1, gcc_source_dir)
 
 if os.path.exists(build_dir):
     shutil.rmtree(build_dir)
 os.makedirs(build_dir)
 
 build_aux_tools(build_dir)
 
+basic_path = aux_inst_dir + "/bin:/bin:/usr/bin"
+
 stage1_dir = build_dir + '/stage1'
-build_one_stage({"CC": "gcc", "CXX" : "g++"}, stage1_dir, True)
+build_one_stage({"PATH"   : basic_path,
+                 "CC"     : "gcc",
+                 "CXX"    : "g++" },
+                stage1_dir, True)
 
 stage1_tool_inst_dir = stage1_dir + '/inst'
 stage2_dir = build_dir + '/stage2'
-build_one_stage({"PATH"   : stage1_tool_inst_dir + "/bin:/bin:/usr/bin",
+build_one_stage({"PATH"   : stage1_tool_inst_dir + "/bin:" + basic_path,
                  "CC"     : "gcc -fgnu89-inline",
                  "CXX"    : "g++",
                  "RANLIB" : "true" },
                 stage2_dir, False)
 
 stage2_tool_inst_dir = stage2_dir + '/inst'
 stage3_dir = build_dir + '/stage3'
-build_one_stage({"PATH"   : stage2_tool_inst_dir + "/bin:/bin:/usr/bin",
+build_one_stage({"PATH"   : stage2_tool_inst_dir + "/bin:" + basic_path,
                  "CC"     : "gcc -fgnu89-inline",
                  "CXX"    : "g++",
                  "RANLIB" : "true" },
                 stage3_dir, False)
 
 build_tar_package(aux_inst_dir + "/bin/tar",
                   "toolchain.tar", stage3_dir, "inst")
new file mode 100644
--- /dev/null
+++ b/config/makefiles/debugmake.mk
@@ -0,0 +1,118 @@
+# -*- makefile -*-
+# vim:set ts=8 sw=8 sts=8 noet:
+#
+# 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/.
+#
+
+###########################################################################
+## Intent: Helper targets for displaying variables and state information
+###########################################################################
+
+# Support usage outside of config/rules.mk
+ifndef INCLUDED_DEBUGMAKE_MK #{
+
+echo-variable-%:
+	@echo "$($*)"
+
+echo-tiers:
+	@echo $(TIERS)
+
+echo-tier-dirs:
+	@$(foreach tier,$(TIERS),echo '$(tier):'; echo '  dirs: $(tier_$(tier)_dirs)'; echo '  staticdirs: $(tier_$(tier)_staticdirs)'; )
+
+echo-dirs:
+	@echo $(DIRS)
+
+echo-module:
+	@echo $(MODULE)
+
+echo-depth-path:
+	@$(topsrcdir)/build/unix/print-depth-path.sh
+
+echo-module-name:
+	@$(topsrcdir)/build/package/rpm/print-module-name.sh
+
+echo-module-filelist:
+	@$(topsrcdir)/build/package/rpm/print-module-filelist.sh
+
+showtargs:
+ifneq (,$(filter $(PROGRAM) $(HOST_PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY),$(TARGETS)))
+	@echo --------------------------------------------------------------------------------
+	@echo "PROGRAM             = $(PROGRAM)"
+	@echo "SIMPLE_PROGRAMS     = $(SIMPLE_PROGRAMS)"
+	@echo "LIBRARY             = $(LIBRARY)"
+	@echo "SHARED_LIBRARY      = $(SHARED_LIBRARY)"
+	@echo "SHARED_LIBRARY_LIBS = $(SHARED_LIBRARY_LIBS)"
+	@echo "LIBS                = $(LIBS)"
+	@echo "DEF_FILE            = $(DEF_FILE)"
+	@echo "IMPORT_LIBRARY      = $(IMPORT_LIBRARY)"
+	@echo "STATIC_LIBS         = $(STATIC_LIBS)"
+	@echo "SHARED_LIBS         = $(SHARED_LIBS)"
+	@echo "EXTRA_DSO_LIBS      = $(EXTRA_DSO_LIBS)"
+	@echo "EXTRA_DSO_LDOPTS    = $(EXTRA_DSO_LDOPTS)"
+	@echo "DEPENDENT_LIBS      = $(DEPENDENT_LIBS)"
+	@echo --------------------------------------------------------------------------------
+endif
+	$(LOOP_OVER_PARALLEL_DIRS)
+	$(LOOP_OVER_DIRS)
+
+showbuild:
+	@echo "MOZ_BUILD_ROOT     = $(MOZ_BUILD_ROOT)"
+	@echo "MOZ_WIDGET_TOOLKIT = $(MOZ_WIDGET_TOOLKIT)"
+	@echo "CC                 = $(CC)"
+	@echo "CXX                = $(CXX)"
+	@echo "CCC                = $(CCC)"
+	@echo "CPP                = $(CPP)"
+	@echo "LD                 = $(LD)"
+	@echo "AR                 = $(AR)"
+	@echo "IMPLIB             = $(IMPLIB)"
+	@echo "FILTER             = $(FILTER)"
+	@echo "MKSHLIB            = $(MKSHLIB)"
+	@echo "MKCSHLIB           = $(MKCSHLIB)"
+	@echo "RC                 = $(RC)"
+	@echo "MC                 = $(MC)"
+	@echo "CFLAGS             = $(CFLAGS)"
+	@echo "OS_CFLAGS          = $(OS_CFLAGS)"
+	@echo "COMPILE_CFLAGS     = $(COMPILE_CFLAGS)"
+	@echo "CXXFLAGS           = $(CXXFLAGS)"
+	@echo "OS_CXXFLAGS        = $(OS_CXXFLAGS)"
+	@echo "COMPILE_CXXFLAGS   = $(COMPILE_CXXFLAGS)"
+	@echo "COMPILE_CMFLAGS    = $(COMPILE_CMFLAGS)"
+	@echo "COMPILE_CMMFLAGS   = $(COMPILE_CMMFLAGS)"
+	@echo "LDFLAGS            = $(LDFLAGS)"
+	@echo "OS_LDFLAGS         = $(OS_LDFLAGS)"
+	@echo "DSO_LDOPTS         = $(DSO_LDOPTS)"
+	@echo "OS_INCLUDES        = $(OS_INCLUDES)"
+	@echo "OS_LIBS            = $(OS_LIBS)"
+	@echo "EXTRA_LIBS         = $(EXTRA_LIBS)"
+	@echo "BIN_FLAGS          = $(BIN_FLAGS)"
+	@echo "INCLUDES           = $(INCLUDES)"
+	@echo "DEFINES            = $(DEFINES)"
+	@echo "ACDEFINES          = $(ACDEFINES)"
+	@echo "BIN_SUFFIX         = $(BIN_SUFFIX)"
+	@echo "LIB_SUFFIX         = $(LIB_SUFFIX)"
+	@echo "DLL_SUFFIX         = $(DLL_SUFFIX)"
+	@echo "IMPORT_LIB_SUFFIX  = $(IMPORT_LIB_SUFFIX)"
+	@echo "INSTALL            = $(INSTALL)"
+	@echo "VPATH              = $(VPATH)"
+
+showhost:
+	@echo "HOST_CC            = $(HOST_CC)"
+	@echo "HOST_CXX           = $(HOST_CXX)"
+	@echo "HOST_CFLAGS        = $(HOST_CFLAGS)"
+	@echo "HOST_LDFLAGS       = $(HOST_LDFLAGS)"
+	@echo "HOST_LIBS          = $(HOST_LIBS)"
+	@echo "HOST_EXTRA_LIBS    = $(HOST_EXTRA_LIBS)"
+	@echo "HOST_EXTRA_DEPS    = $(HOST_EXTRA_DEPS)"
+	@echo "HOST_PROGRAM       = $(HOST_PROGRAM)"
+	@echo "HOST_OBJS          = $(HOST_OBJS)"
+	@echo "HOST_PROGOBJS      = $(HOST_PROGOBJS)"
+	@echo "HOST_LIBRARY       = $(HOST_LIBRARY)"
+
+showbuildmods::
+	@echo "Module dirs	= $(BUILD_MODULE_DIRS)"
+
+INCLUDED_DEBUGMAKE_MK = 1
+endif #}
--- a/config/makefiles/makeutils.mk
+++ b/config/makefiles/makeutils.mk
@@ -62,18 +62,21 @@ is_XinY =$(filter $(1),$(call subargv,3,
 # Provide an alternate var to support testing
 ifdef MAKEUTILS_UNIT_TEST
   mcg_goals=TEST_MAKECMDGOALS
 else
   mcg_goals=MAKECMDGOALS
 endif
 
 # Intent: Conditionals for detecting common/tier target use
-#   Todo: are check, install, test needed ?
-isTargetStem       = $(sort $(foreach pat, $(1)% %$(1), $(call is_XinY,$(pat),${$(mcg_goals)})))
+isTargetStem       = $(sort \
+  $(foreach var,$(getargv),\
+    $(foreach pat,$(var)% %$(var),\
+      $(call is_XinY,$(pat),${$(mcg_goals)})\
+  )))
 isTargetStemClean  = $(call isTargetStem,clean)
 isTargetStemExport = $(call isTargetStem,export)
 isTargetStemLibs   = $(call isTargetStem,libs)
 isTargetStemTools  = $(call isTargetStem,tools)
 
 ##################################################
 # Intent: Validation functions / unit test helpers
 
--- a/config/makefiles/test/check_XinY.mk
+++ b/config/makefiles/test/check_XinY.mk
@@ -38,8 +38,33 @@ wanted  := clean distclean clean-level-1
 #     match: clean, distclean, clean-level-1
 #   exclude: FcleanG
 TEST_MAKECMDGOALS := $(val)
 $(call errorifneq,3,$(words $(call isTargetStemClean)))
 
 TEST_MAKECMDGOALS := invalid
 $(call errorifneq,$(zero),$(words $(call isTargetStemClean)))
 
+
+#############################
+ifdef VERBOSE
+  $(call banner,Unit test: isTargetStem)
+endif
+
+# Verify list argument processing
+TEST_MAKECMDGOALS := echo
+$(call errorifneq,$(one),$(words $(call isTargetStem,echo,show)))
+
+TEST_MAKECMDGOALS := echo-123
+$(call errorifneq,$(one),$(words $(call isTargetStem,echo,show)))
+
+TEST_MAKECMDGOALS := show
+$(call errorifneq,$(one),$(words $(call isTargetStem,echo,show)))
+
+TEST_MAKECMDGOALS := show-123
+$(call errorifneq,$(one),$(words $(call isTargetStem,echo,show)))
+
+TEST_MAKECMDGOALS := show-123-echo
+$(call errorifneq,$(one),$(words $(call isTargetStem,echo,show)))
+
+TEST_MAKECMDGOALS := invalid
+$(call errorifneq,$(zero),$(words $(call isTargetStem,echo,show)))
+
new file mode 100644
--- /dev/null
+++ b/config/makefiles/xpcshell.mk
@@ -0,0 +1,128 @@
+# -*- makefile -*-
+# vim:set ts=8 sw=8 sts=8 noet:
+#
+# 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 INCLUDED_TESTS_XPCSHELL_MK #{
+
+ifdef XPCSHELL_TESTS #{
+
+ifndef relativesrcdir
+$(error Must define relativesrcdir when defining XPCSHELL_TESTS.)
+endif
+
+define _INSTALL_TESTS
+$(DIR_INSTALL) $(wildcard $(srcdir)/$(dir)/*) $(testxpcobjdir)/$(relativesrcdir)/$(dir)
+
+endef # do not remove the blank line!
+
+SOLO_FILE ?= $(error Specify a test filename in SOLO_FILE when using check-interactive or check-one)
+
+testxpcsrcdir = $(topsrcdir)/testing/xpcshell
+
+libs:: libs-xpcshell-tests
+
+###########################################################################
+libs-xpcshell-tests:
+	$(foreach dir,$(XPCSHELL_TESTS),$(_INSTALL_TESTS))
+ifndef NO_XPCSHELL_MANIFEST_CHECK #{
+	$(PYTHON) $(MOZILLA_DIR)/build/xpccheck.py \
+	  $(topsrcdir) \
+	  $(topsrcdir)/testing/xpcshell/xpcshell.ini \
+	  $(addprefix $(MOZILLA_DIR)/$(relativesrcdir)/,$(XPCSHELL_TESTS))
+endif #} NO_XPCSHELL_MANIFEST_CHECK 
+
+###########################################################################
+# Execute all tests in the $(XPCSHELL_TESTS) directories.
+# See also testsuite-targets.mk 'xpcshell-tests' target for global execution.
+xpcshell-tests:
+	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
+	  -I$(topsrcdir)/build \
+      -I$(DEPTH)/_tests/mozbase/mozinfo \
+	  $(testxpcsrcdir)/runxpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  --build-info-json=$(DEPTH)/mozinfo.json \
+	  --tests-root-dir=$(testxpcobjdir) \
+	  --testing-modules-dir=$(DEPTH)/_tests/modules \
+	  --xunit-file=$(testxpcobjdir)/$(relativesrcdir)/results.xml \
+	  --xunit-suite-name=xpcshell \
+	  $(EXTRA_TEST_ARGS) \
+	  $(LIBXUL_DIST)/bin/xpcshell \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+
+xpcshell-tests-remote: DM_TRANS?=adb
+xpcshell-tests-remote:
+	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
+	  -I$(topsrcdir)/build \
+	  -I$(topsrcdir)/build/mobile \
+	  $(topsrcdir)/testing/xpcshell/remotexpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  --build-info-json=$(DEPTH)/mozinfo.json \
+	  $(EXTRA_TEST_ARGS) \
+	  --dm_trans=$(DM_TRANS) \
+	  --deviceIP=${TEST_DEVICE} \
+	  --objdir=$(DEPTH) \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+
+###########################################################################
+# Execute a single test, specified in $(SOLO_FILE), but don't automatically
+# start the test. Instead, present the xpcshell prompt so the user can
+# attach a debugger and then start the test.
+check-interactive:
+	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
+	  -I$(topsrcdir)/build \
+      -I$(DEPTH)/_tests/mozbase/mozinfo \
+	  $(testxpcsrcdir)/runxpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  --build-info-json=$(DEPTH)/mozinfo.json \
+	  --test-path=$(SOLO_FILE) \
+	  --testing-modules-dir=$(DEPTH)/_tests/modules \
+	  --profile-name=$(MOZ_APP_NAME) \
+	  --interactive \
+	  $(LIBXUL_DIST)/bin/xpcshell \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+
+# Execute a single test, specified in $(SOLO_FILE)
+check-one:
+	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
+	  -I$(topsrcdir)/build \
+      -I$(DEPTH)/_tests/mozbase/mozinfo \
+	  $(testxpcsrcdir)/runxpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  --build-info-json=$(DEPTH)/mozinfo.json \
+	  --test-path=$(SOLO_FILE) \
+	  --testing-modules-dir=$(DEPTH)/_tests/modules \
+	  --profile-name=$(MOZ_APP_NAME) \
+	  --verbose \
+	  $(EXTRA_TEST_ARGS) \
+	  $(LIBXUL_DIST)/bin/xpcshell \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+
+check-one-remote: DM_TRANS?=adb
+check-one-remote:
+	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
+	  -I$(topsrcdir)/build \
+	  -I$(topsrcdir)/build/mobile \
+	  $(testxpcsrcdir)/remotexpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  --build-info-json=$(DEPTH)/mozinfo.json \
+	  --test-path=$(SOLO_FILE) \
+	  --profile-name=$(MOZ_APP_NAME) \
+	  --verbose \
+	  $(EXTRA_TEST_ARGS) \
+	  --dm_trans=$(DM_TRANS) \
+	  --deviceIP=${TEST_DEVICE} \
+	  --objdir=$(DEPTH) \
+          --noSetup \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+
+
+.PHONY: xpcshell-tests check-interactive check-one libs-xpcshell-tests
+
+endif #} XPCSHELL_TESTS
+
+INCLUDED_TESTS_XPCSHELL_MK = 1
+endif #} INCLUDED_TESTS_XPCSHELL_MK
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -80,118 +80,19 @@ ifdef ENABLE_TESTS
 # The current developer workflow expects tests to be updated when processing
 # the default target. If we ever change this implementation, the behavior
 # should be preserved or the change should be widely communicated. A
 # consequence of not processing test dir targets during the default target is
 # that changes to tests may not be updated and code could assume to pass
 # locally against non-current test code.
 DIRS += $(TEST_DIRS)
 
-ifdef XPCSHELL_TESTS
-ifndef relativesrcdir
-$(error Must define relativesrcdir when defining XPCSHELL_TESTS.)
-endif
-
-define _INSTALL_TESTS
-$(DIR_INSTALL) $(wildcard $(srcdir)/$(dir)/*) $(testxpcobjdir)/$(relativesrcdir)/$(dir)
-
-endef # do not remove the blank line!
-
-SOLO_FILE ?= $(error Specify a test filename in SOLO_FILE when using check-interactive or check-one)
-
-libs::
-	$(foreach dir,$(XPCSHELL_TESTS),$(_INSTALL_TESTS))
-ifndef NO_XPCSHELL_MANIFEST_CHECK
-	$(PYTHON) $(MOZILLA_DIR)/build/xpccheck.py \
-	  $(topsrcdir) \
-	  $(topsrcdir)/testing/xpcshell/xpcshell.ini \
-	  $(addprefix $(MOZILLA_DIR)/$(relativesrcdir)/,$(XPCSHELL_TESTS))
-endif
-
-testxpcsrcdir = $(topsrcdir)/testing/xpcshell
-
-# Execute all tests in the $(XPCSHELL_TESTS) directories.
-# See also testsuite-targets.mk 'xpcshell-tests' target for global execution.
-xpcshell-tests:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build -I$(DEPTH)/_tests/mozbase/mozinfo \
-	  $(testxpcsrcdir)/runxpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  --tests-root-dir=$(testxpcobjdir) \
-	  --testing-modules-dir=$(DEPTH)/_tests/modules \
-	  --xunit-file=$(testxpcobjdir)/$(relativesrcdir)/results.xml \
-	  --xunit-suite-name=xpcshell \
-	  $(EXTRA_TEST_ARGS) \
-	  $(LIBXUL_DIST)/bin/xpcshell \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-
-xpcshell-tests-remote: DM_TRANS?=adb
-xpcshell-tests-remote:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build \
-	  -I$(topsrcdir)/build/mobile \
-	  $(topsrcdir)/testing/xpcshell/remotexpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  $(EXTRA_TEST_ARGS) \
-	  --dm_trans=$(DM_TRANS) \
-	  --deviceIP=${TEST_DEVICE} \
-	  --objdir=$(DEPTH) \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-
-# Execute a single test, specified in $(SOLO_FILE), but don't automatically
-# start the test. Instead, present the xpcshell prompt so the user can
-# attach a debugger and then start the test.
-check-interactive:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build -I$(DEPTH)/_tests/mozbase/mozinfo \
-	  $(testxpcsrcdir)/runxpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  --test-path=$(SOLO_FILE) \
-	  --testing-modules-dir=$(DEPTH)/_tests/modules \
-	  --profile-name=$(MOZ_APP_NAME) \
-	  --interactive \
-	  $(LIBXUL_DIST)/bin/xpcshell \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-
-# Execute a single test, specified in $(SOLO_FILE)
-check-one:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build -I$(DEPTH)/_tests/mozbase/mozinfo \
-	  $(testxpcsrcdir)/runxpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  --test-path=$(SOLO_FILE) \
-	  --testing-modules-dir=$(DEPTH)/_tests/modules \
-	  --profile-name=$(MOZ_APP_NAME) \
-	  --verbose \
-	  $(EXTRA_TEST_ARGS) \
-	  $(LIBXUL_DIST)/bin/xpcshell \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-
-check-one-remote: DM_TRANS?=adb
-check-one-remote:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build \
-	  -I$(topsrcdir)/build/mobile \
-	  $(testxpcsrcdir)/remotexpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  --test-path=$(SOLO_FILE) \
-	  --profile-name=$(MOZ_APP_NAME) \
-	  --verbose \
-	  $(EXTRA_TEST_ARGS) \
-	  --dm_trans=$(DM_TRANS) \
-	  --deviceIP=${TEST_DEVICE} \
-	  --objdir=$(DEPTH) \
-          --noSetup \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-endif # XPCSHELL_TESTS
+ifndef INCLUDED_TESTS_XPCSHELL_MK #{
+  include $(topsrcdir)/config/makefiles/xpcshell.mk
+endif #}
 
 ifdef CPP_UNIT_TESTS
 
 # Compile the tests to $(DIST)/bin.  Make lots of niceties available by default
 # through TestHarness.h, by modifying the list of includes and the libs against
 # which stuff links.
 CPPSRCS += $(CPP_UNIT_TESTS)
 SIMPLE_PROGRAMS += $(CPP_UNIT_TESTS:.cpp=$(BIN_SUFFIX))
@@ -202,17 +103,17 @@ LIBS += $(XPCOM_GLUE_LDOPTS) $(NSPR_LIBS
 check::
 	@$(EXIT_ON_ERROR) \
 	  for f in $(subst .cpp,$(BIN_SUFFIX),$(CPP_UNIT_TESTS)); do \
 	    XPCOM_DEBUG_BREAK=stack-and-abort $(RUN_TEST_PROGRAM) $(DIST)/bin/$$f; \
 	  done
 
 endif # CPP_UNIT_TESTS
 
-.PHONY: check xpcshell-tests check-interactive check-one
+.PHONY: check
 
 endif # ENABLE_TESTS
 
 
 #
 # Library rules
 #
 # If FORCE_STATIC_LIB is set, build a static library.
@@ -1370,16 +1271,17 @@ ifneq ($(AUTOCFG_JS_EXPORTS),)
 	$(NSINSTALL) -D $@
 
 ifndef NO_DIST_INSTALL
 export:: $(AUTOCFG_JS_EXPORTS) $(FINAL_TARGET)/defaults/autoconfig
 	$(INSTALL) $(IFLAGS1) $^
 endif
 
 endif
+
 ################################################################################
 # Export the elements of $(XPIDLSRCS)
 # generating .h and .xpt files and moving them to the appropriate places.
 
 ifneq ($(XPIDLSRCS),)
 
 export:: $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.h, $(XPIDLSRCS))
 
@@ -1843,116 +1745,22 @@ FORCE:
 
 tags: TAGS
 
 TAGS: $(SUBMAKEFILES) $(CSRCS) $(CPPSRCS) $(wildcard *.h)
 	-etags $(CSRCS) $(CPPSRCS) $(wildcard *.h)
 	$(LOOP_OVER_PARALLEL_DIRS)
 	$(LOOP_OVER_DIRS)
 
-echo-variable-%:
-	@echo "$($*)"
-
-echo-tiers:
-	@echo $(TIERS)
-
-echo-tier-dirs:
-	@$(foreach tier,$(TIERS),echo '$(tier):'; echo '  dirs: $(tier_$(tier)_dirs)'; echo '  staticdirs: $(tier_$(tier)_staticdirs)'; )
-
-echo-dirs:
-	@echo $(DIRS)
-
-echo-module:
-	@echo $(MODULE)
-
-echo-depth-path:
-	@$(topsrcdir)/build/unix/print-depth-path.sh
-
-echo-module-name:
-	@$(topsrcdir)/build/package/rpm/print-module-name.sh
-
-echo-module-filelist:
-	@$(topsrcdir)/build/package/rpm/print-module-filelist.sh
-
-showtargs:
-ifneq (,$(filter $(PROGRAM) $(HOST_PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY),$(TARGETS)))
-	@echo --------------------------------------------------------------------------------
-	@echo "PROGRAM             = $(PROGRAM)"
-	@echo "SIMPLE_PROGRAMS     = $(SIMPLE_PROGRAMS)"
-	@echo "LIBRARY             = $(LIBRARY)"
-	@echo "SHARED_LIBRARY      = $(SHARED_LIBRARY)"
-	@echo "SHARED_LIBRARY_LIBS = $(SHARED_LIBRARY_LIBS)"
-	@echo "LIBS                = $(LIBS)"
-	@echo "DEF_FILE            = $(DEF_FILE)"
-	@echo "IMPORT_LIBRARY      = $(IMPORT_LIBRARY)"
-	@echo "STATIC_LIBS         = $(STATIC_LIBS)"
-	@echo "SHARED_LIBS         = $(SHARED_LIBS)"
-	@echo "EXTRA_DSO_LIBS      = $(EXTRA_DSO_LIBS)"
-	@echo "EXTRA_DSO_LDOPTS    = $(EXTRA_DSO_LDOPTS)"
-	@echo "DEPENDENT_LIBS      = $(DEPENDENT_LIBS)"
-	@echo --------------------------------------------------------------------------------
-endif
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-
-showbuild:
-	@echo "MOZ_BUILD_ROOT     = $(MOZ_BUILD_ROOT)"
-	@echo "MOZ_WIDGET_TOOLKIT = $(MOZ_WIDGET_TOOLKIT)"
-	@echo "CC                 = $(CC)"
-	@echo "CXX                = $(CXX)"
-	@echo "CCC                = $(CCC)"
-	@echo "CPP                = $(CPP)"
-	@echo "LD                 = $(LD)"
-	@echo "AR                 = $(AR)"
-	@echo "IMPLIB             = $(IMPLIB)"
-	@echo "FILTER             = $(FILTER)"
-	@echo "MKSHLIB            = $(MKSHLIB)"
-	@echo "MKCSHLIB           = $(MKCSHLIB)"
-	@echo "RC                 = $(RC)"
-	@echo "MC                 = $(MC)"
-	@echo "CFLAGS             = $(CFLAGS)"
-	@echo "OS_CFLAGS          = $(OS_CFLAGS)"
-	@echo "COMPILE_CFLAGS     = $(COMPILE_CFLAGS)"
-	@echo "CXXFLAGS           = $(CXXFLAGS)"
-	@echo "OS_CXXFLAGS        = $(OS_CXXFLAGS)"
-	@echo "COMPILE_CXXFLAGS   = $(COMPILE_CXXFLAGS)"
-	@echo "COMPILE_CMFLAGS    = $(COMPILE_CMFLAGS)"
-	@echo "COMPILE_CMMFLAGS   = $(COMPILE_CMMFLAGS)"
-	@echo "LDFLAGS            = $(LDFLAGS)"
-	@echo "OS_LDFLAGS         = $(OS_LDFLAGS)"
-	@echo "DSO_LDOPTS         = $(DSO_LDOPTS)"
-	@echo "OS_INCLUDES        = $(OS_INCLUDES)"
-	@echo "OS_LIBS            = $(OS_LIBS)"
-	@echo "EXTRA_LIBS         = $(EXTRA_LIBS)"
-	@echo "BIN_FLAGS          = $(BIN_FLAGS)"
-	@echo "INCLUDES           = $(INCLUDES)"
-	@echo "DEFINES            = $(DEFINES)"
-	@echo "ACDEFINES          = $(ACDEFINES)"
-	@echo "BIN_SUFFIX         = $(BIN_SUFFIX)"
-	@echo "LIB_SUFFIX         = $(LIB_SUFFIX)"
-	@echo "DLL_SUFFIX         = $(DLL_SUFFIX)"
-	@echo "IMPORT_LIB_SUFFIX  = $(IMPORT_LIB_SUFFIX)"
-	@echo "INSTALL            = $(INSTALL)"
-	@echo "VPATH              = $(VPATH)"
-
-showhost:
-	@echo "HOST_CC            = $(HOST_CC)"
-	@echo "HOST_CXX           = $(HOST_CXX)"
-	@echo "HOST_CFLAGS        = $(HOST_CFLAGS)"
-	@echo "HOST_LDFLAGS       = $(HOST_LDFLAGS)"
-	@echo "HOST_LIBS          = $(HOST_LIBS)"
-	@echo "HOST_EXTRA_LIBS    = $(HOST_EXTRA_LIBS)"
-	@echo "HOST_EXTRA_DEPS    = $(HOST_EXTRA_DEPS)"
-	@echo "HOST_PROGRAM       = $(HOST_PROGRAM)"
-	@echo "HOST_OBJS          = $(HOST_OBJS)"
-	@echo "HOST_PROGOBJS      = $(HOST_PROGOBJS)"
-	@echo "HOST_LIBRARY       = $(HOST_LIBRARY)"
-
-showbuildmods::
-	@echo "Module dirs	= $(BUILD_MODULE_DIRS)"
+ifndef INCLUDED_DEBUGMAKE_MK #{
+  ## Only parse when an echo* or show* target is requested
+  ifneq (,$(call isTargetStem,echo,show))
+    include $(topsrcdir)/config/makefiles/debugmake.mk
+  endif #}
+endif #}
 
 documentation:
 	@cd $(DEPTH)
 	$(DOXYGEN) $(DEPTH)/config/doxygen.cfg
 
 ifdef ENABLE_TESTS
 check:: $(SUBMAKEFILES) $(MAKE_DIRS)
 	$(LOOP_OVER_PARALLEL_DIRS)
--- a/configure.in
+++ b/configure.in
@@ -5713,33 +5713,29 @@ if test -n "$MOZ_WEBM" -a -z "$MOZ_NATIV
       VPX_ASFLAGS="-f macho32 -rnasm -pnasm -DPIC"
       VPX_X86_ASM=1
     ;;
     Darwin:x86_64)
       VPX_ASFLAGS="-f macho64 -rnasm -pnasm -DPIC"
       VPX_X86_ASM=1
     ;;
     WINNT:x86_64)
-      if test -z "$GNU_CC"; then
-        VPX_ASFLAGS="-f x64 -rnasm -pnasm"
-        VPX_X86_ASM=1
-      fi
+      VPX_ASFLAGS="-f x64 -rnasm -pnasm"
+      VPX_X86_ASM=1
     ;;
     WINNT:x86)
-      if test -z "$GNU_CC"; then
-        dnl Check for yasm 1.1 or greater.
-        if test -n "$COMPILE_ENVIRONMENT" -a -z "$YASM"; then
-          AC_MSG_ERROR([yasm 1.1 or greater is required to build libvpx on Win32, but it appears not to be installed.  Install it (included in MozillaBuild 1.5.1 and newer) or configure with --disable-webm (which disables the WebM video format). See https://developer.mozilla.org/en/YASM for more details.])
-        elif test -n "$COMPILE_ENVIRONMENT" -a "$_YASM_MAJOR_VERSION" -lt "1" -o \( "$_YASM_MAJOR_VERSION" -eq "1" -a "$_YASM_MINOR_VERSION" -lt "1" \) ; then
-          AC_MSG_ERROR([yasm 1.1 or greater is required to build libvpx on Win32, but you appear to have version $_YASM_MAJOR_VERSION.$_YASM_MINOR_VERSION.  Upgrade to the newest version (included in MozillaBuild 1.5.1 and newer) or configure with --disable-webm (which disables the WebM video format). See https://developer.mozilla.org/en/YASM for more details.])
-        else
-          VPX_ASFLAGS="-f win32 -rnasm -pnasm -DPIC"
-          VPX_X86_ASM=1
-          dnl The encoder needs obj_int_extract to get asm offsets.
-        fi
+      dnl Check for yasm 1.1 or greater.
+      if test -n "$COMPILE_ENVIRONMENT" -a -z "$YASM"; then
+        AC_MSG_ERROR([yasm 1.1 or greater is required to build libvpx on Win32, but it appears not to be installed.  Install it (included in MozillaBuild 1.5.1 and newer) or configure with --disable-webm (which disables the WebM video format). See https://developer.mozilla.org/en/YASM for more details.])
+      elif test -n "$COMPILE_ENVIRONMENT" -a "$_YASM_MAJOR_VERSION" -lt "1" -o \( "$_YASM_MAJOR_VERSION" -eq "1" -a "$_YASM_MINOR_VERSION" -lt "1" \) ; then
+        AC_MSG_ERROR([yasm 1.1 or greater is required to build libvpx on Win32, but you appear to have version $_YASM_MAJOR_VERSION.$_YASM_MINOR_VERSION.  Upgrade to the newest version (included in MozillaBuild 1.5.1 and newer) or configure with --disable-webm (which disables the WebM video format). See https://developer.mozilla.org/en/YASM for more details.])
+      else
+        VPX_ASFLAGS="-f win32 -rnasm -pnasm -DPIC"
+        VPX_X86_ASM=1
+        dnl The encoder needs obj_int_extract to get asm offsets.
       fi
     ;;
     *:arm*)
       if test -n "$GNU_AS" ; then
         VPX_AS=$AS
         dnl These flags are a lie; they're just used to enable the requisite
         dnl opcodes; actual arch detection is done at runtime.
         VPX_ASFLAGS="-march=armv7-a -mfpu=neon"
--- a/content/base/src/nsDocumentEncoder.cpp
+++ b/content/base/src/nsDocumentEncoder.cpp
@@ -125,16 +125,21 @@ protected:
   nsresult SerializeRangeNodes(nsRange* aRange, 
                                nsINode* aNode, 
                                nsAString& aString,
                                PRInt32 aDepth);
   nsresult SerializeRangeContextStart(const nsTArray<nsINode*>& aAncestorArray,
                                       nsAString& aString);
   nsresult SerializeRangeContextEnd(const nsTArray<nsINode*>& aAncestorArray,
                                     nsAString& aString);
+  virtual PRInt32
+  GetImmediateContextCount(const nsTArray<nsINode*>& aAncestorArray)
+  {
+    return -1;
+  }
 
   nsresult FlushText(nsAString& aString, bool aForce);
 
   bool IsVisibleNode(nsINode* aNode)
   {
     NS_PRECONDITION(aNode, "");
 
     if (mFlags & SkipInvisibleContent) {
@@ -180,16 +185,19 @@ protected:
   PRInt32           mStartRootIndex;
   PRInt32           mEndRootIndex;
   nsAutoTArray<nsINode*, 8>    mCommonAncestors;
   nsAutoTArray<nsIContent*, 8> mStartNodes;
   nsAutoTArray<PRInt32, 8>     mStartOffsets;
   nsAutoTArray<nsIContent*, 8> mEndNodes;
   nsAutoTArray<PRInt32, 8>     mEndOffsets;
   bool              mHaltRangeHint;  
+  // Used when context has already been serialized for
+  // table cell selections (where parent is <tr>)
+  bool              mDisableContextSerialize;
   bool              mIsCopying;  // Set to true only while copying
   bool              mNodeIsContainer;
   nsStringBuffer*   mCachedBuffer;
 };
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocumentEncoder)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDocumentEncoder)
@@ -227,16 +235,17 @@ void nsDocumentEncoder::Initialize(bool 
 {
   mFlags = 0;
   mWrapColumn = 72;
   mStartDepth = 0;
   mEndDepth = 0;
   mStartRootIndex = 0;
   mEndRootIndex = 0;
   mHaltRangeHint = false;
+  mDisableContextSerialize = false;
   mNodeIsContainer = false;
   if (aClearCachedSerializer) {
     mSerializer = nsnull;
   }
 }
 
 nsDocumentEncoder::~nsDocumentEncoder()
 {
@@ -908,51 +917,65 @@ nsDocumentEncoder::SerializeRangeNodes(n
   }
   return NS_OK;
 }
 
 nsresult
 nsDocumentEncoder::SerializeRangeContextStart(const nsTArray<nsINode*>& aAncestorArray,
                                               nsAString& aString)
 {
-  PRInt32 i = aAncestorArray.Length();
+  if (mDisableContextSerialize) {
+    return NS_OK;
+  }
+  PRInt32 i = aAncestorArray.Length(), j;
   nsresult rv = NS_OK;
 
+  // currently only for table-related elements; see Bug 137450
+  j = GetImmediateContextCount(aAncestorArray);
+
   while (i > 0) {
     nsINode *node = aAncestorArray.ElementAt(--i);
 
     if (!node)
       break;
 
-    if (IncludeInContext(node)) {
+    // Either a general inclusion or as immediate context
+    if (IncludeInContext(node) || i < j) {
       rv = SerializeNodeStart(node, 0, -1, aString);
 
       if (NS_FAILED(rv))
         break;
     }
   }
 
   return rv;
 }
 
 nsresult
 nsDocumentEncoder::SerializeRangeContextEnd(const nsTArray<nsINode*>& aAncestorArray,
                                             nsAString& aString)
 {
-  PRInt32 i = 0;
+  if (mDisableContextSerialize) {
+    return NS_OK;
+  }
+  PRInt32 i = 0, j;
   PRInt32 count = aAncestorArray.Length();
   nsresult rv = NS_OK;
 
+  // currently only for table-related elements
+  j = GetImmediateContextCount(aAncestorArray);
+
   while (i < count) {
     nsINode *node = aAncestorArray.ElementAt(i++);
 
     if (!node)
       break;
 
-    if (IncludeInContext(node)) {
+    // Either a general inclusion or as immediate context
+    if (IncludeInContext(node) || i - 1 < j) {
       rv = SerializeNodeEnd(node, aString);
 
       if (NS_FAILED(rv))
         break;
     }
   }
 
   return rv;
@@ -1078,44 +1101,75 @@ nsDocumentEncoder::EncodeToString(nsAStr
 
     nsCOMPtr<nsIDOMNode> node, prevNode;
     for (i = 0; i < count; i++) {
       mSelection->GetRangeAt(i, getter_AddRefs(range));
 
       // Bug 236546: newlines not added when copying table cells into clipboard
       // Each selected cell shows up as a range containing a row with a single cell
       // get the row, compare it to previous row and emit </tr><tr> as needed
+      // Bug 137450: Problem copying/pasting a table from a web page to Excel.
+      // Each separate block of <tr></tr> produced above will be wrapped by the
+      // immediate context. This assumes that you can't select cells that are
+      // multiple selections from two tables simultaneously.
       range->GetStartContainer(getter_AddRefs(node));
       NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
       if (node != prevNode) {
+        nsCOMPtr<nsINode> p;
         if (prevNode) {
-          nsCOMPtr<nsINode> p = do_QueryInterface(prevNode);
+          p = do_QueryInterface(prevNode);
           rv = SerializeNodeEnd(p, output);
           NS_ENSURE_SUCCESS(rv, rv);
-          prevNode = nsnull;
         }
         nsCOMPtr<nsIContent> content = do_QueryInterface(node);
-        if (content && content->Tag() == nsGkAtoms::tr) {
-          nsCOMPtr<nsINode> n = do_QueryInterface(node);
+        if (content && content->IsHTML(nsGkAtoms::tr)) {
+          nsINode* n = content;
+          if (!prevNode) {
+            // Went from a non-<tr> to a <tr>
+            mCommonAncestors.Clear();
+            nsContentUtils::GetAncestors(n->GetNodeParent(), mCommonAncestors);
+            rv = SerializeRangeContextStart(mCommonAncestors, output);
+            NS_ENSURE_SUCCESS(rv, rv);
+            // Don't let SerializeRangeToString serialize the context again
+            mDisableContextSerialize = true;
+          }
+
           rv = SerializeNodeStart(n, 0, -1, output);
           NS_ENSURE_SUCCESS(rv, rv);
           prevNode = node;
+        } else if (prevNode) {
+          // Went from a <tr> to a non-<tr>
+          mCommonAncestors.Clear();
+          nsContentUtils::GetAncestors(p->GetNodeParent(), mCommonAncestors);
+          mDisableContextSerialize = false;
+          rv = SerializeRangeContextEnd(mCommonAncestors, output);
+          NS_ENSURE_SUCCESS(rv, rv);
+          prevNode = nsnull;
         }
       }
 
       nsRange* r = static_cast<nsRange*>(range.get());
       rv = SerializeRangeToString(r, output);
       NS_ENSURE_SUCCESS(rv, rv);
     }
+
     if (prevNode) {
       nsCOMPtr<nsINode> p = do_QueryInterface(prevNode);
       rv = SerializeNodeEnd(p, output);
       NS_ENSURE_SUCCESS(rv, rv);
+      mCommonAncestors.Clear();
+      nsContentUtils::GetAncestors(p->GetNodeParent(), mCommonAncestors);
+      mDisableContextSerialize = false; 
+      rv = SerializeRangeContextEnd(mCommonAncestors, output);
+      NS_ENSURE_SUCCESS(rv, rv);
     }
 
+    // Just to be safe
+    mDisableContextSerialize = false; 
+
     mSelection = nsnull;
   } else if (mRange) {
       rv = SerializeRangeToString(mRange, output);
 
       mRange = nsnull;
   } else if (mNode) {
     if (!mNodeFixup && !(mFlags & SkipInvisibleContent) && !mStream &&
         mNodeIsContainer) {
@@ -1257,16 +1311,18 @@ protected:
   nsCOMPtr<nsIDOMNode> GetChildAt(nsIDOMNode *aParent, PRInt32 aOffset);
   bool IsMozBR(nsIDOMNode* aNode);
   nsresult GetNodeLocation(nsIDOMNode *inChild, nsCOMPtr<nsIDOMNode> *outParent, PRInt32 *outOffset);
   bool IsRoot(nsIDOMNode* aNode);
   bool IsFirstNode(nsIDOMNode *aNode);
   bool IsLastNode(nsIDOMNode *aNode);
   bool IsEmptyTextContent(nsIDOMNode* aNode);
   virtual bool IncludeInContext(nsINode *aNode);
+  virtual PRInt32
+  GetImmediateContextCount(const nsTArray<nsINode*>& aAncestorArray);
 
   bool mIsTextWidget;
 };
 
 nsHTMLCopyEncoder::nsHTMLCopyEncoder()
 {
   mIsTextWidget = false;
 }
@@ -1970,8 +2026,31 @@ nsresult
 NS_NewHTMLCopyTextEncoder(nsIDocumentEncoder** aResult)
 {
   *aResult = new nsHTMLCopyEncoder;
   if (!*aResult)
     return NS_ERROR_OUT_OF_MEMORY;
  NS_ADDREF(*aResult);
  return NS_OK;
 }
+
+PRInt32
+nsHTMLCopyEncoder::GetImmediateContextCount(const nsTArray<nsINode*>& aAncestorArray)
+{
+  PRInt32 i = aAncestorArray.Length(), j = 0;
+  while (j < i) {
+    nsINode *node = aAncestorArray.ElementAt(j);
+    if (!node) {
+      break;
+    }
+    nsCOMPtr<nsIContent> content(do_QueryInterface(node));
+    if (!content || !content->IsHTML() || content->Tag() != nsGkAtoms::tr    &&
+                                          content->Tag() != nsGkAtoms::thead &&
+                                          content->Tag() != nsGkAtoms::tbody &&
+                                          content->Tag() != nsGkAtoms::tfoot &&
+                                          content->Tag() != nsGkAtoms::table) {
+      break;
+    }
+    ++j;
+  }
+  return j;
+}
+
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -1395,21 +1395,32 @@ nsFrameLoader::OwnerIsBrowserFrame()
 bool
 nsFrameLoader::ShouldUseRemoteProcess()
 {
   if (PR_GetEnv("MOZ_DISABLE_OOP_TABS") ||
       Preferences::GetBool("dom.ipc.tabs.disabled", false)) {
     return false;
   }
 
-  return OwnerIsBrowserFrame() ||
-         (bool) mOwnerContent->AttrValueIs(kNameSpaceID_None,
-                                           nsGkAtoms::Remote,
-                                           nsGkAtoms::_true,
-                                           eCaseMatters);
+  // If we're an <iframe mozbrowser> and we don't have a "remote" attribute,
+  // fall back to the default.
+  if (OwnerIsBrowserFrame() &&
+      !mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::Remote)) {
+
+    return Preferences::GetBool("dom.ipc.browser_frames.oop_by_default", false);
+  }
+
+  // Otherwise, we're remote if we have "remote=true" and we're either a
+  // browser frame or a XUL element.
+  return (OwnerIsBrowserFrame() ||
+          mOwnerContent->GetNameSpaceID() == kNameSpaceID_XUL) &&
+         mOwnerContent->AttrValueIs(kNameSpaceID_None,
+                                    nsGkAtoms::Remote,
+                                    nsGkAtoms::_true,
+                                    eCaseMatters);
 }
 
 nsresult
 nsFrameLoader::MaybeCreateDocShell()
 {
   if (mDocShell) {
     return NS_OK;
   }
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -3627,38 +3627,41 @@ nsHTMLInputElement::IsTooLong()
   GetTextLength(&textLength);
 
   return textLength > maxLength;
 }
 
 bool
 nsHTMLInputElement::IsValueMissing() const
 {
+  // Should use UpdateValueMissingValidityStateForRadio() for type radio.
+  MOZ_ASSERT(mType != NS_FORM_INPUT_RADIO);
+
   if (!HasAttr(kNameSpaceID_None, nsGkAtoms::required) ||
       !DoesRequiredApply()) {
     return false;
   }
 
-  if (GetValueMode() == VALUE_MODE_VALUE) {
-    if (!IsMutable()) {
-      return false;
-    }
-
-    return IsValueEmpty();
+  if (!IsMutable()) {
+    return false;
   }
 
-  switch (mType)
-  {
-    case NS_FORM_INPUT_CHECKBOX:
+  switch (GetValueMode()) {
+    case VALUE_MODE_VALUE:
+      return IsValueEmpty();
+    case VALUE_MODE_FILENAME:
+    {
+      const nsCOMArray<nsIDOMFile>& files = GetFiles();
+      return !files.Count();
+    }
+    case VALUE_MODE_DEFAULT_ON:
+      // This should not be used for type radio.
+      // See the MOZ_ASSERT at the beginning of the method.
       return !mChecked;
-    case NS_FORM_INPUT_FILE:
-      {
-        const nsCOMArray<nsIDOMFile>& files = GetFiles();
-        return !files.Count();
-      }
+    case VALUE_MODE_DEFAULT:
     default:
       return false;
   }
 }
 
 bool
 nsHTMLInputElement::HasTypeMismatch() const
 {
@@ -3738,32 +3741,33 @@ nsHTMLInputElement::UpdateValueMissingVa
   // In that case, we can look for the checked state of the radio.
   bool selected = selection || (!aIgnoreSelf && mChecked);
   bool required = !aIgnoreSelf && HasAttr(kNameSpaceID_None, nsGkAtoms::required);
   bool valueMissing = false;
 
   nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
 
   if (!container) {
-    SetValidityState(VALIDITY_STATE_VALUE_MISSING, required && !selected);
+    SetValidityState(VALIDITY_STATE_VALUE_MISSING,
+                     IsMutable() && required && !selected);
     return;
   }
 
   nsAutoString name;
   GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
 
   // If the current radio is required and not ignored, we can assume the entire
   // group is required.
   if (!required) {
     required = (aIgnoreSelf && HasAttr(kNameSpaceID_None, nsGkAtoms::required))
                  ? container->GetRequiredRadioCount(name) - 1
                  : container->GetRequiredRadioCount(name);
   }
 
-  valueMissing = required && !selected;
+  valueMissing = IsMutable() && required && !selected;
 
   if (container->GetValueMissingState(name) != valueMissing) {
     container->SetValueMissingState(name, valueMissing);
 
     SetValidityState(VALIDITY_STATE_VALUE_MISSING, valueMissing);
 
     // nsRadioSetValueMissingState will call ContentStateChanged while visiting.
     nsAutoScriptBlocker scriptBlocker;
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -60,16 +60,17 @@
 #include "nsIEditorObserver.h"
 #include "nsINativeKeyBindings.h"
 #include "nsIDocumentEncoder.h"
 #include "nsISelectionPrivate.h"
 #include "nsPIDOMWindow.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIEditor.h"
 #include "nsTextEditRules.h"
+#include "nsTypedSelection.h"
 #include "nsEventListenerManager.h"
 #include "nsContentUtils.h"
 
 using namespace mozilla::dom;
 
 static NS_DEFINE_CID(kTextEditorCID, NS_TEXTEDITOR_CID);
 
 static nsINativeKeyBindings *sNativeInputBindings = nsnull;
--- a/content/html/content/test/test_bug610687.html
+++ b/content/html/content/test/test_bug610687.html
@@ -124,17 +124,17 @@ function checkRadios(r1, r2, r3, form)
   r2.required = true;
   r1.checked = r2.checked = false;
   checkPseudoClasses(r1, false, false, true);
   checkPseudoClasses(r2, false, false, true);
 
   var p = r2.parentNode;
   p.removeChild(r2);
   checkPseudoClasses(r1, true, true, false);
-  checkPseudoClasses(r2, false, false, true);
+  checkPseudoClasses(r2, true, true, false);
 
   p.appendChild(r2);
   checkPseudoClasses(r1, false, false, true);
   checkPseudoClasses(r2, false, false, true);
 
   // Adding a radio element to an invalid group should make it invalid.
   p.removeChild(r1);
   checkPseudoClasses(r1, true, true, false);
new file mode 100644
--- /dev/null
+++ b/content/smil/crashtests/720103-1.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<svg xmlns="http://www.w3.org/2000/svg">
+<animate id="a" begin="-3.1s" end="a.begin+0.2s"/>
+</svg>
--- a/content/smil/crashtests/crashtests.list
+++ b/content/smil/crashtests/crashtests.list
@@ -43,8 +43,9 @@ load 678822-1.svg
 load 678847-1.svg
 load 678938-1.svg
 load 690994-1.svg
 load 691337-1.svg
 load 691337-2.svg
 load 697640-1.svg
 load 699325-1.svg
 load 709907-1.svg
+load 720103-1.svg
--- a/dom/Makefile.in
+++ b/dom/Makefile.in
@@ -70,16 +70,17 @@ DIRS = \
   interfaces/smil \
   $(NULL)
 
 DIRS += \
   interfaces/apps \
   $(NULL)
 
 DIRS += \
+  apps \
   base \
   bindings \
   battery \
   contacts \
   power \
   settings \
   sms \
   src \
new file mode 100644
--- /dev/null
+++ b/dom/apps/Makefile.in
@@ -0,0 +1,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/.
+
+DEPTH            = ../..
+topsrcdir        = @top_srcdir@
+srcdir           = @srcdir@
+VPATH            = @srcdir@
+
+relativesrcdir   = dom/apps
+
+include $(DEPTH)/config/autoconf.mk
+
+PARALLEL_DIRS = src
+
+TEST_DIRS += tests
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/dom/apps/src/AppsService.js
@@ -0,0 +1,41 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict"
+
+function debug(s) {
+  //dump("-*- AppsService: " + s + "\n");
+}
+
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Webapps.jsm");
+
+const APPS_SERVICE_CONTRACTID = "@mozilla.org/AppsService;1";
+const APPS_SERVICE_CID        = Components.ID("{05072afa-92fe-45bf-ae22-39b69c117058}");
+
+function AppsService()
+{
+  debug("AppsService Constructor");
+}
+
+AppsService.prototype = {
+  getAppByManifestURL: function getAppByManifestURL(aManifestURL) {
+    debug("GetAppByManifestURL( " + aManifestURL + " )");
+    return DOMApplicationRegistry.getAppByManifestURL(aManifestURL)
+  },
+
+  classID : APPS_SERVICE_CID,
+  QueryInterface : XPCOMUtils.generateQI([Ci.nsIAppsService]),
+
+  classInfo : XPCOMUtils.generateCI({classID: APPS_SERVICE_CID,
+                                     contractID: APPS_SERVICE_CONTRACTID,
+                                     classDescription: "AppsService",
+                                     interfaces: [Ci.nsIAppsService],
+                                     flags: Ci.nsIClassInfo.DOM_OBJECT})
+}
+
+const NSGetFactory = XPCOMUtils.generateNSGetFactory([AppsService])
new file mode 100644
--- /dev/null
+++ b/dom/apps/src/AppsService.manifest
@@ -0,0 +1,2 @@
+component {05072afa-92fe-45bf-ae22-39b69c117058} AppsService.js
+contract @mozilla.org/AppsService;1 {05072afa-92fe-45bf-ae22-39b69c117058}
new file mode 100644
--- /dev/null
+++ b/dom/apps/src/Makefile.in
@@ -0,0 +1,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/.
+
+DEPTH     = ../../..
+topsrcdir = @top_srcdir@
+srcdir    = @srcdir@
+VPATH     = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+EXTRA_COMPONENTS = \
+  AppsService.js \
+  AppsService.manifest \
+  $(NULL)
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/dom/apps/tests/Makefile.in
@@ -0,0 +1,34 @@
+# 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/.
+
+DEPTH            = ../../..
+topsrcdir        = @top_srcdir@
+srcdir           = @srcdir@
+VPATH            = @srcdir@
+
+relativesrcdir   = dom/apps/tests
+
+include $(DEPTH)/config/autoconf.mk
+
+DIRS = \
+  $(NULL)
+
+include $(topsrcdir)/config/rules.mk
+
+_TEST_FILES = \
+  $(NULL)
+
+_CHROME_TEST_FILES = \
+  test_apps_service.xul \
+  $(NULL)
+
+ifneq (,$(_TEST_FILES))
+libs:: $(_TEST_FILES)
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
+endif
+
+ifneq (,$(_CHROME_TEST_FILES))
+libs:: $(_CHROME_TEST_FILES)
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
+endif
new file mode 100644
--- /dev/null
+++ b/dom/apps/tests/test_apps_service.xul
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=754141
+-->
+<window title="Mozilla Bug 754141"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <!-- test results are displayed in the html:body -->
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=754141"
+     target="_blank">Mozilla Bug 754141</a>
+  </body>
+
+  <!-- test code goes here -->
+  <script type="application/javascript">
+  <![CDATA[
+
+  /** Test for Bug 754141 **/
+
+  var appsService = Components.classes['@mozilla.org/AppsService;1']
+                              .getService(Components.interfaces.nsIAppsService);
+  SimpleTest.ok(appsService, "Should be able to get the Apps Service");
+
+  SimpleTest.ok('getAppByManifestURL' in appsService,
+                "getAppByManifestURL() should be a method in nsIAppsService");
+
+  SimpleTest.is(appsService.getAppByManifestURL(''), null,
+                "getAppByManifestURL() should return null for an empty string manifest url");
+
+  ]]>
+  </script>
+</window>
--- a/dom/base/BrowserElementChild.js
+++ b/dom/base/BrowserElementChild.js
@@ -49,21 +49,27 @@ BrowserElementChild.prototype = {
     // A mozbrowser iframe contained inside a mozapp iframe should return false
     // for nsWindowUtils::IsPartOfApp (unless the mozbrowser iframe is itself
     // also mozapp).  That is, mozapp is transitive down to its children, but
     // mozbrowser serves as a barrier.
     //
     // This is because mozapp iframes have some privileges which we don't want
     // to extend to untrusted mozbrowser content.
     //
-    // Set the window's isApp state by asking our parent if our iframe has the
-    // 'mozapp' attribute.
-    content.QueryInterface(Ci.nsIInterfaceRequestor)
-           .getInterface(Components.interfaces.nsIDOMWindowUtils)
-           .setIsApp(sendSyncMsg('get-mozapp')[0]);
+    // Get the app manifest from the parent, if our frame has one.
+    let appManifestURL = sendSyncMsg('get-mozapp-manifest-url')[0];
+    let windowUtils = content.QueryInterface(Ci.nsIInterfaceRequestor)
+                             .getInterface(Components.interfaces.nsIDOMWindowUtils);
+
+    if (!!appManifestURL) {
+      windowUtils.setIsApp(true);
+      windowUtils.setApp(mozApp);
+    } else {
+      windowUtils.setIsApp(false);
+    }
 
     addEventListener('DOMTitleChanged',
                      this._titleChangedHandler.bind(this),
                      /* useCapture = */ true,
                      /* wantsUntrusted = */ false);
 
     addEventListener('DOMLinkAdded',
                      this._iconChangedHandler.bind(this),
--- a/dom/base/BrowserElementParent.js
+++ b/dom/base/BrowserElementParent.js
@@ -95,17 +95,17 @@ BrowserElementParent.prototype = {
     }
 
     addMessageListener("hello", this._recvHello);
     addMessageListener("locationchange", this._fireEventFromMsg);
     addMessageListener("loadstart", this._fireEventFromMsg);
     addMessageListener("loadend", this._fireEventFromMsg);
     addMessageListener("titlechange", this._fireEventFromMsg);
     addMessageListener("iconchange", this._fireEventFromMsg);
-    addMessageListener("get-mozapp", this._sendAppState);
+    addMessageListener("get-mozapp-manifest-url", this._sendMozAppManifestURL);
 
     mm.loadFrameScript("chrome://global/content/BrowserElementChild.js",
                        /* allowDelayedLoad = */ true);
   },
 
   _recvHello: function(frameElement, data) {
     debug("recvHello " + frameElement);
   },
@@ -130,18 +130,18 @@ BrowserElementParent.prototype = {
     }
     else {
       evt = new win.Event('mozbrowser' + evtName);
     }
 
     frameElement.dispatchEvent(evt);
   },
 
-  _sendAppState: function(frameElement, data) {
-    return frameElement.hasAttribute('mozapp');
+  _sendMozAppManifestURL: function(frameElement, data) {
+    return frameElement.getAttribute('mozapp');
   },
 
   observe: function(subject, topic, data) {
     switch(topic) {
     case 'app-startup':
       this._init();
       break;
     case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID:
--- a/dom/base/Webapps.jsm
+++ b/dom/base/Webapps.jsm
@@ -341,16 +341,30 @@ let DOMApplicationRegistry = {
 
   getAppById: function(aId) {
     if (!this.webapps[aId])
       return null;
     
     let app = this._cloneAppObject(this.webapps[aId]);
     return app;
   },
+
+  getAppByManifestURL: function(aManifestURL) {
+    // This could be O(1) if |webapps| was a dictionary indexed on manifestURL
+    // which should be the unique app identifier.
+    // It's currently O(n).
+    for (let id in this.webapps) {
+      let app = this.webapps[id];
+      if (app.manifestURL == aManifestURL) {
+        return this._cloneAppObject(app);
+      }
+    }
+
+    return null;
+  },
   
   getAllWithoutManifests: function(aCallback) {
     let result = {};
     for (let id in this.webapps) {
       let app = this._cloneAppObject(this.webapps[id]);
       result[id] = app;
     }
     aCallback(result);
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2452,15 +2452,32 @@ nsDOMWindowUtils::SetScrollPositionClamp
     nsPresContext::CSSPixelsToAppUnits(aHeight));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SetIsApp(bool aValue)
 {
+  if (!IsUniversalXPConnectCapable()) {
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+
   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
 
   static_cast<nsGlobalWindow*>(window.get())->SetIsApp(aValue);
 
   return NS_OK;
 }
+
+NS_IMETHODIMP
+nsDOMWindowUtils::SetApp(const nsAString& aManifestURL)
+{
+  if (!IsUniversalXPConnectCapable()) {
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
+  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
+
+  return static_cast<nsGlobalWindow*>(window.get())->SetApp(aManifestURL);
+}
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -70,16 +70,17 @@
 #include "nsEventDispatcher.h"
 #include "nsEventStateManager.h"
 #include "nsIMEStateManager.h"
 #include "nsIWebNavigation.h"
 #include "nsCaret.h"
 #include "nsIBaseWindow.h"
 #include "nsIViewManager.h"
 #include "nsFrameSelection.h"
+#include "nsTypedSelection.h"
 #include "nsXULPopupManager.h"
 #include "nsIDOMNodeFilter.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIPrincipal.h"
 #include "mozilla/dom/Element.h"
 #include "mozAutoDocUpdate.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -255,16 +255,17 @@
 
 #include "nsRefreshDriver.h"
 #include "mozAutoDocUpdate.h"
 
 #include "mozilla/Telemetry.h"
 #include "nsLocation.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsDOMEventTargetHelper.h"
+#include "nsIAppsService.h"
 
 #ifdef ANDROID
 #include <android/log.h>
 #endif
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gDOMLeakPRLog;
 #endif
@@ -10009,38 +10010,70 @@ nsGlobalWindow::SizeOfIncludingThis(nsWi
       mNavigator->SizeOfIncludingThis(aWindowSizes->mMallocSizeOf) : 0;
 }
 
 void
 nsGlobalWindow::SetIsApp(bool aValue)
 {
   FORWARD_TO_OUTER_VOID(SetIsApp, (aValue));
 
+  // You shouldn't call SetIsApp() more than once.
+  MOZ_ASSERT(mIsApp == TriState_Unknown);
+
   mIsApp = aValue ? TriState_True : TriState_False;
 }
 
 bool
 nsGlobalWindow::IsPartOfApp()
 {
   FORWARD_TO_OUTER(IsPartOfApp, (), TriState_False);
 
   // We go trough all window parents until we find one with |mIsApp| set to
   // something. If none is found, we are not part of an application.
   for (nsGlobalWindow* w = this; w;
        w = static_cast<nsGlobalWindow*>(w->GetParentInternal())) {
     if (w->mIsApp == TriState_True) {
+      // The window should be part of an application.
+      MOZ_ASSERT(w->mApp);
       return true;
     } else if (w->mIsApp == TriState_False) {
       return false;
     }
   }
 
   return false;
 }
 
+nsresult
+nsGlobalWindow::SetApp(const nsAString& aManifestURL)
+{
+  // SetIsApp(true) should be called before calling SetApp().
+  if (mIsApp != TriState_True) {
+    MOZ_ASSERT(false);
+    return NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
+  if (!appsService) {
+    NS_ERROR("Apps Service is not available!");
+    return NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<mozIDOMApplication> app;
+  appsService->GetAppByManifestURL(aManifestURL, getter_AddRefs(app));
+  if (!app) {
+    NS_WARNING("No application found with the specified manifest URL");
+    return NS_ERROR_FAILURE;
+  }
+
+  mApp = app.forget();
+
+  return NS_OK;
+}
+
 // nsGlobalChromeWindow implementation
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalChromeWindow)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGlobalChromeWindow,
                                                   nsGlobalWindow)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mBrowserDOMWindow)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mMessageManager)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -94,16 +94,17 @@
 #include "nsIArray.h"
 #include "nsIContent.h"
 #include "nsIIDBFactory.h"
 #include "nsFrameMessageManager.h"
 #include "mozilla/TimeStamp.h"
 #include "nsIDOMTouchEvent.h"
 #include "nsIInlineEventHandlers.h"
 #include "nsWrapperCacheInlines.h"
+#include "nsIDOMApplicationRegistry.h"
 
 // JS includes
 #include "jsapi.h"
 
 #define DEFAULT_HOME_PAGE "www.mozilla.org"
 #define PREF_BROWSER_STARTUP_HOMEPAGE "browser.startup.homepage"
 
 // Amount of time allowed between alert/prompt/confirm before enabling
@@ -820,16 +821,17 @@ protected:
   inline PRInt32 DOMMinTimeoutValue() const;
 
   nsresult CreateOuterObject(nsGlobalWindow* aNewInner);
   nsresult SetOuterObject(JSContext* aCx, JSObject* aOuterObject);
   nsresult CloneStorageEvent(const nsAString& aType,
                              nsCOMPtr<nsIDOMStorageEvent>& aEvent);
 
   void SetIsApp(bool aValue);
+  nsresult SetApp(const nsAString& aManifestURL);
 
   // When adding new member variables, be careful not to create cycles
   // through JavaScript.  If there is any chance that a member variable
   // could own objects that are implemented in JavaScript, then those
   // objects will keep the global object (this object) alive.  To prevent
   // these cycles, ownership of such members must be released in
   // |CleanUp| and |SetDocShell|.
 
@@ -988,16 +990,20 @@ protected:
   bool                          mDialogDisabled;
 
   nsRefPtr<nsDOMMozURLProperty> mURLProperty;
 
   nsTHashtable<nsPtrHashKey<nsDOMEventTargetHelper> > mEventTargetObjects;
 
   nsTArray<PRUint32> mEnabledSensors;
 
+  // The application associated with this window.
+  // This should only be non-null if mIsApp's value is TriState_True.
+  nsCOMPtr<mozIDOMApplication> mApp;
+
   friend class nsDOMScriptableHelper;
   friend class nsDOMWindowUtils;
   friend class PostMessageEvent;
 
   static WindowByIdTable* sWindowsById;
   static bool sWarnedAboutWindowInternal;
 };
 
--- a/dom/interfaces/apps/Makefile.in
+++ b/dom/interfaces/apps/Makefile.in
@@ -43,11 +43,12 @@ VPATH          = @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 MODULE         = dom
 XPIDL_MODULE   = dom_apps
 GRE_MODULE     = 1
 
 XPIDLSRCS =                               \
             nsIDOMApplicationRegistry.idl \
+            nsIAppsService.idl \
             $(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/apps/nsIAppsService.idl
@@ -0,0 +1,22 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "domstubs.idl"
+
+interface mozIDOMApplication;
+
+%{C++
+#define APPS_SERVICE_CID { 0x05072afa, 0x92fe, 0x45bf, { 0xae, 0x22, 0x39, 0xb6, 0x9c, 0x11, 0x70, 0x58 } }
+#define APPS_SERVICE_CONTRACTID "@mozilla.org/AppsService;1"
+%}
+
+/*
+ * This service allows accessing some DOMApplicationRegistry methods from
+ * non-javascript code.
+ */
+[scriptable, uuid(8a4d9921-58ae-41da-a6f1-5f842c3a050f)]
+interface nsIAppsService : nsISupports
+{
+  mozIDOMApplication getAppByManifestURL(in DOMString manifestURL);
+};
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -1153,9 +1153,18 @@ interface nsIDOMWindowUtils : nsISupport
   /**
    * Mark if the window is an application window or not.
    * This should only be set for top-level mozApp or mozBrowser frames.
    * It should not be set for other frames unless you want a frame (and its
    * children) to have a different value for IsPartOfApp than the frame's
    * parent.
    */
   void setIsApp(in boolean value);
+
+  /**
+   * Associate the window with an application by passing the URL of the
+   * application's manifest.
+   *
+   * This method will throw an exception if the manifest URL isn't a valid URL
+   * or isn't the manifest URL of an installed application.
+   */
+  void setApp(in DOMString manifestURL);
 };
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -1195,26 +1195,27 @@ PluginInstanceParent::NPP_HandleEvent(vo
     if (mWindowType == NPWindowTypeDrawable) {
         if (IsAsyncDrawing()) {
             if (npevent->event == WM_PAINT || npevent->event == DoublePassRenderingEvent()) {
                 // This plugin maintains its own async drawing.
                 return handled;
             }
         }
         if (DoublePassRenderingEvent() == npevent->event) {
-            CallPaint(npremoteevent, &handled);
-            return handled;
+            return CallPaint(npremoteevent, &handled) && handled;
         }
 
         switch (npevent->event) {
             case WM_PAINT:
             {
                 RECT rect;
                 SharedSurfaceBeforePaint(rect, npremoteevent);
-                CallPaint(npremoteevent, &handled);
+                if (!CallPaint(npremoteevent, &handled)) {
+                    handled = false;
+                }
                 SharedSurfaceAfterPaint(npevent);
                 return handled;
             }
             break;
 
             case WM_KILLFOCUS:
             {
               // When the user selects fullscreen mode in Flash video players,
@@ -1232,20 +1233,17 @@ PluginInstanceParent::NPP_HandleEvent(vo
                   return 0;
               }
             }
             break;
 
             case WM_WINDOWPOSCHANGED:
             {
                 // We send this in nsObjectFrame just before painting
-                SendWindowPosChanged(npremoteevent);
-                // nsObjectFrame doesn't care whether we handle this
-                // or not, just returning 1 for good hygiene
-                return 1;
+                return SendWindowPosChanged(npremoteevent);
             }
             break;
         }
     }
 #endif
 
 #if defined(MOZ_X11)
     switch (npevent->type) {
@@ -1787,17 +1785,17 @@ PluginInstanceParent::PluginWindowHookPr
         return DefWindowProc(hWnd, message, wParam, lParam);
     }
 
     NS_ASSERTION(self->mPluginHWND == hWnd, "Wrong window!");
 
     switch (message) {
         case WM_SETFOCUS:
         // Let the child plugin window know it should take focus.
-        self->CallSetPluginFocus();
+        unused << self->CallSetPluginFocus();
         break;
 
         case WM_CLOSE:
         self->UnsubclassPluginWindow();
         break;
     }
 
     if (self->mPluginWndProc == PluginWindowHookProc) {
@@ -1816,17 +1814,17 @@ PluginInstanceParent::SubclassPluginWind
     NS_ASSERTION(!(mPluginHWND && aWnd != mPluginHWND),
       "PluginInstanceParent::SubclassPluginWindow hwnd is not our window!");
 
     if (!mPluginHWND) {
         mPluginHWND = aWnd;
         mPluginWndProc = 
             (WNDPROC)::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
                          reinterpret_cast<LONG_PTR>(PluginWindowHookProc));
-        bool bRes = ::SetPropW(mPluginHWND, kPluginInstanceParentProperty, this);
+        DebugOnly<bool> bRes = ::SetPropW(mPluginHWND, kPluginInstanceParentProperty, this);
         NS_ASSERTION(mPluginWndProc,
           "PluginInstanceParent::SubclassPluginWindow failed to set subclass!");
         NS_ASSERTION(bRes,
           "PluginInstanceParent::SubclassPluginWindow failed to set prop!");
    }
 }
 
 void
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -787,17 +787,17 @@ PluginModuleParent::NP_Initialize(NPNets
     // Send the info needed to join the chrome process's audio session to the
     // plugin process
     nsID id;
     nsString sessionName;
     nsString iconPath;
 
     if (NS_SUCCEEDED(mozilla::widget::GetAudioSessionData(id, sessionName,
                                                           iconPath)))
-        SendSetAudioSessionData(id, sessionName, iconPath);
+        unused << SendSetAudioSessionData(id, sessionName, iconPath);
 #endif
 
     return NS_OK;
 }
 #endif
 
 nsresult
 PluginModuleParent::NP_Shutdown(NPError* error)
@@ -1038,17 +1038,17 @@ PluginModuleParent::RecvProcessNativeEve
     return false;
 #endif
 }
 
 void
 PluginModuleParent::ProcessRemoteNativeEventsInRPCCall()
 {
 #if defined(OS_WIN)
-    SendProcessNativeEventsInRPCCall();
+    unused << SendProcessNativeEventsInRPCCall();
     return;
 #endif
     NS_NOTREACHED(
         "PluginModuleParent::ProcessRemoteNativeEventsInRPCCall not implemented!");
 }
 
 bool
 PluginModuleParent::RecvPluginShowWindow(const uint32_t& aWindowId, const bool& aModal,
--- a/dom/tests/mochitest/browser-frame/browserFrameHelpers.js
+++ b/dom/tests/mochitest/browser-frame/browserFrameHelpers.js
@@ -58,16 +58,24 @@ const browserFrameHelpers = {
   getOOPDisabledPref: function() {
     return this._getBoolPref('dom.ipc.tabs.disabled');
   },
 
   setOOPDisabledPref: function(value) {
     this._setBoolPref('dom.ipc.tabs.disabled', value);
   },
 
+  getOOPByDefaultPref: function() {
+    return this._getBoolPref("dom.ipc.browser_frames.oop_by_default");
+  },
+
+  setOOPByDefaultPref: function(value) {
+    return this._setBoolPref("dom.ipc.browser_frames.oop_by_default", value);
+  },
+
   getPageThumbsEnabledPref: function() {
     return this._getBoolPref('browser.pageThumbs.enabled');
   },
 
   setPageThumbsEnabledPref: function(value) {
     this._setBoolPref('browser.pageThumbs.enabled', value);
   },
 
@@ -76,45 +84,45 @@ const browserFrameHelpers = {
     whitelist += ',  http://' + window.location.host + ',  ';
     this.setWhitelistPref(whitelist);
   },
 
   restoreOriginalPrefs: function() {
     this.setEnabledPref(this.origEnabledPref);
     this.setWhitelistPref(this.origWhitelistPref);
     this.setOOPDisabledPref(this.origOOPDisabledPref);
+    this.setOOPByDefaultPref(this.origOOPByDefaultPref);
     this.setPageThumbsEnabledPref(this.origPageThumbsEnabledPref);
   },
 
   'origEnabledPref': null,
   'origWhitelistPref': null,
   'origOOPDisabledPref': null,
+  'origOOPByDefaultPref': null,
   'origPageThumbsEnabledPref': null,
 
   // Two basically-empty pages from two different domains you can load.
   'emptyPage1': 'http://example.com' +
                 window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) +
                 '/file_empty.html',
   'emptyPage2': 'http://example.org' +
                 window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) +
                 '/file_empty.html',
 };
 
 browserFrameHelpers.origEnabledPref = browserFrameHelpers.getEnabledPref();
 browserFrameHelpers.origWhitelistPref = browserFrameHelpers.getWhitelistPref();
 browserFrameHelpers.origOOPDisabledPref = browserFrameHelpers.getOOPDisabledPref();
+browserFrameHelpers.origOOPByDefaultPref = browserFrameHelpers.getOOPByDefaultPref();
 browserFrameHelpers.origPageThumbsEnabledPref = browserFrameHelpers.getPageThumbsEnabledPref();
 
 // Disable tab view; it seriously messes us up.
 browserFrameHelpers.setPageThumbsEnabledPref(false);
 
-// OOP must be disabled on Windows; it doesn't work there.  Enable it
-// everywhere else.
+// OOP by default, except on Windows, where OOP doesn't work.
+browserFrameHelpers.setOOPByDefaultPref(true);
 if (navigator.platform.indexOf('Win') != -1) {
   browserFrameHelpers.setOOPDisabledPref(true);
 }
-else {
-  browserFrameHelpers.setOOPDisabledPref(false);
-}
 
 addEventListener('unload', function() {
   browserFrameHelpers.restoreOriginalPrefs();
 });
--- a/dom/tests/mochitest/bugs/Makefile.in
+++ b/dom/tests/mochitest/bugs/Makefile.in
@@ -156,12 +156,13 @@ include $(topsrcdir)/config/rules.mk
 		test_onerror_message.html \
 		test_bug735237.html \
 		test_bug739038.html \
 		test_bug740811.html \
 		test_bug743615.html \
 		utils_bug743615.js \
 		worker_bug743615.js \
 		test_bug750051.html \
+		test_bug755320.html \
 		$(NULL)
 
 libs:: 	$(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/bugs/test_bug755320.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=755320
+-->
+<head>
+  <title>Test for Bug 755320</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=755320">Mozilla Bug 755320</a>
+
+<script type="text/javascript">
+
+/** Test for Bug 755320 **/
+
+SimpleTest.waitForExplicitFinish();
+
+function finish() {
+  ok(true, "Got onload for iframe.");
+  SimpleTest.finish();
+}
+</script>
+
+<!-- remote="true" should be ignored on vanilla iframes. -->
+<iframe remote="true" onload='finish()' src="data:text/html,It worked."></iframe>
+
+</body>
+</html>
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -90,18 +90,19 @@ HasCPUIDBit(unsigned int level, CPUIDReg
   unsigned int regs[4];
   return __get_cpuid(level, &regs[0], &regs[1], &regs[2], &regs[3]) &&
          (regs[reg] & bit);
 }
 
 #define HAVE_CPU_DETECTION
 #else
 
-#if defined(_MSC_VER) && _MSC_VER >= 1400 && (defined(_M_IX86) || defined(_M_AMD64))
-// MSVC 2005 or newer on x86-32 or x86-64
+#if defined(_MSC_VER) && _MSC_VER >= 1600 && (defined(_M_IX86) || defined(_M_AMD64))
+// MSVC 2005 or later supports __cpuid by intrin.h
+// But it does't work on MSVC 2005 with SDK 7.1 (Bug 753772)
 #include <intrin.h>
 
 #define HAVE_CPU_DETECTION
 #elif defined(__SUNPRO_CC) && (defined(__i386) || defined(__x86_64__))
 
 // Define a function identical to MSVC function.
 #ifdef __i386
 static void
@@ -167,21 +168,23 @@ int sGfxLogLevel = LOG_DEBUG;
 
 #ifdef WIN32
 ID3D10Device1 *Factory::mD3D10Device;
 #endif
 
 bool
 Factory::HasSSE2()
 {
-#if defined(HAVE_CPU_DETECTION)
+#if defined(__SSE2__) || defined(_M_X64) || \
+    (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
+  // gcc with -msse2 (default on OSX and x86-64)
+  // cl.exe with -arch:SSE2 (default on x64 compiler)
+  return true;
+#elif defined(HAVE_CPU_DETECTION)
   return HasCPUIDBit(1u, edx, (1u<<26));
-#elif defined(XP_MACOSX)
-  // Intel macs always have SSE2.
-  return true;
 #else
   return false;
 #endif
 }
 
 TemporaryRef<DrawTarget>
 Factory::CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat)
 {
--- a/gfx/cairo/README
+++ b/gfx/cairo/README
@@ -189,11 +189,13 @@ pixman-rename-and-endian.patch: include 
 NOTE: we previously supported ARM assembler on MSVC, this has been removed because of the maintenance burden
 
 pixman-export.patch: use cairo_public for PIXMAN_EXPORT to make sure pixman symbols are not exported in libxul
 
 pixman-limits.patch: include limits.h for SIZE_MAX
 
 pixman-lowres-interp.patch: Use lower quality interpolation for more speed.
 
+pixman-bilinear-fastpath.patch: Bilinear fast paths for non-neon
+
 ==== disable printing patch ====
 
 disable-printing.patch:  allows us to use NS_PRINTING to disable printing.
--- a/gfx/cairo/libpixman/src/pixman-fast-path.c
+++ b/gfx/cairo/libpixman/src/pixman-fast-path.c
@@ -1186,16 +1186,228 @@ FAST_NEAREST (8888_565_none, 8888, 0565,
 FAST_NEAREST (8888_565_pad, 8888, 0565, uint32_t, uint16_t, SRC, PAD)
 FAST_NEAREST (8888_565_normal, 8888, 0565, uint32_t, uint16_t, SRC, NORMAL)
 FAST_NEAREST (565_565_normal, 0565, 0565, uint16_t, uint16_t, SRC, NORMAL)
 FAST_NEAREST (8888_565_cover, 8888, 0565, uint32_t, uint16_t, OVER, COVER)
 FAST_NEAREST (8888_565_none, 8888, 0565, uint32_t, uint16_t, OVER, NONE)
 FAST_NEAREST (8888_565_pad, 8888, 0565, uint32_t, uint16_t, OVER, PAD)
 FAST_NEAREST (8888_565_normal, 8888, 0565, uint32_t, uint16_t, OVER, NORMAL)
 
+static force_inline void
+scaled_bilinear_scanline_8888_565_OVER (uint16_t *       dst,
+                                        const uint32_t * mask,
+                                        const uint32_t * src_top,
+                                        const uint32_t * src_bottom,
+                                        int32_t          w,
+                                        int              wt,
+                                        int              wb,
+                                        pixman_fixed_t   vx,
+                                        pixman_fixed_t   unit_x,
+                                        pixman_fixed_t   max_vx,
+                                        pixman_bool_t    zero_src)
+{
+    while ((w -= 1) >= 0)
+    {
+	uint32_t tl = src_top [pixman_fixed_to_int (vx)];
+	uint32_t tr = src_top [pixman_fixed_to_int (vx) + 1];
+	uint32_t bl = src_bottom [pixman_fixed_to_int (vx)];
+	uint32_t br = src_bottom [pixman_fixed_to_int (vx) + 1];
+	uint32_t src, result;
+	uint16_t d;
+	d = *dst;
+	src = bilinear_interpolation (tl, tr,
+				      bl, br,
+				      interpolation_coord(vx),
+				      wb >> (8 - INTERPOLATION_PRECISION_BITS));
+	vx += unit_x;
+	result = over (src, CONVERT_0565_TO_0888 (d));
+	*dst++ = CONVERT_8888_TO_0565(result);
+    }
+}
+
+static force_inline void
+scaled_bilinear_scanline_8888_8888_OVER (uint32_t *       dst,
+                                         const uint32_t * mask,
+                                         const uint32_t * src_top,
+                                         const uint32_t * src_bottom,
+                                         int32_t          w,
+                                         int              wt,
+                                         int              wb,
+                                         pixman_fixed_t   vx,
+                                         pixman_fixed_t   unit_x,
+                                         pixman_fixed_t   max_vx,
+                                         pixman_bool_t    zero_src)
+{
+    while ((w -= 1) >= 0)
+    {
+	uint32_t tl = src_top [pixman_fixed_to_int (vx)];
+	uint32_t tr = src_top [pixman_fixed_to_int (vx) + 1];
+	uint32_t bl = src_bottom [pixman_fixed_to_int (vx)];
+	uint32_t br = src_bottom [pixman_fixed_to_int (vx) + 1];
+	uint32_t src;
+	uint32_t d;
+	uint32_t result;
+	d = *dst;
+	src = bilinear_interpolation (tl, tr,
+				      bl, br,
+				      interpolation_coord(vx),
+				      wb >> (8 - INTERPOLATION_PRECISION_BITS));
+	vx += unit_x;
+	*dst++ = over (src, d);
+    }
+}
+
+#if 1
+
+static force_inline void
+scaled_bilinear_scanline_565_565_SRC (uint16_t *       dst,
+				      const uint32_t * mask,
+				      const uint16_t * src_top,
+				      const uint16_t * src_bottom,
+				      int32_t          w,
+				      int              wt,
+				      int              wb,
+				      pixman_fixed_t   vx,
+				      pixman_fixed_t   unit_x,
+				      pixman_fixed_t   max_vx,
+				      pixman_bool_t    zero_src)
+{
+    while ((w -= 1) >= 0)
+    {
+	uint16_t tl = src_top [pixman_fixed_to_int (vx)];
+	uint16_t tr = src_top [pixman_fixed_to_int (vx) + 1];
+	uint16_t bl = src_bottom [pixman_fixed_to_int (vx)];
+	uint16_t br = src_bottom [pixman_fixed_to_int (vx) + 1];
+	uint32_t d;
+	d = bilinear_interpolation(CONVERT_0565_TO_8888(tl),
+				   CONVERT_0565_TO_8888(tr),
+				   CONVERT_0565_TO_8888(bl),
+				   CONVERT_0565_TO_8888(br),
+				   interpolation_coord(vx),
+				   wb >> (8 - INTERPOLATION_PRECISION_BITS));
+	vx += unit_x;
+	*dst++ = CONVERT_8888_TO_0565(d);
+    }
+}
+
+#else
+
+#define SK_G16_MASK_IN_PLACE 0xfc0
+
+static inline uint32_t SkExpand_rgb_16(uint16_t c) {
+
+    return ((c & SK_G16_MASK_IN_PLACE) << 16) | (c & ~SK_G16_MASK_IN_PLACE);
+}
+
+/** Compress an expanded value (from SkExpand_rgb_16) back down to a 16bit
+    color value. The computation yields only 16bits of valid data, but we claim
+    to return 32bits, so that the compiler won't generate extra instructions to
+    "clean" the top 16bits. However, the top 16 can contain garbage, so it is
+    up to the caller to safely ignore them.
+*/
+static inline uint16_t SkCompact_rgb_16(uint32_t c) {
+    return ((c >> 16) & SK_G16_MASK_IN_PLACE) | (c & ~SK_G16_MASK_IN_PLACE);
+}
+// returns expanded * 5bits
+static inline uint32_t Filter_565_Expanded(unsigned x, unsigned y,
+                                           uint32_t a00, uint32_t a01,
+                                           uint32_t a10, uint32_t a11) {
+    a00 = SkExpand_rgb_16(a00);
+    a01 = SkExpand_rgb_16(a01);
+    a10 = SkExpand_rgb_16(a10);
+    a11 = SkExpand_rgb_16(a11);
+    
+    int xy = x * y >> 3;
+    return  a00 * (32 - 2*y - 2*x + xy) +
+            a01 * (2*x - xy) +
+            a10 * (2*y - xy) +
+            a11 * xy;
+}
+
+
+
+static force_inline void
+scaled_bilinear_scanline_565_565_SRC (uint16_t *       dst,
+				      const uint32_t * mask,
+				      const uint16_t * src_top,
+				      const uint16_t * src_bottom,
+				      int32_t          w,
+				      int              wt,
+				      int              wb,
+				      pixman_fixed_t   vx,
+				      pixman_fixed_t   unit_x,
+				      pixman_fixed_t   max_vx,
+				      pixman_bool_t    zero_src)
+{
+    while ((w -= 1) >= 0)
+    {
+	uint16_t tl = src_top [pixman_fixed_to_int (vx)];
+	uint16_t tr = src_top [pixman_fixed_to_int (vx) + 1];
+	uint16_t bl = src_bottom [pixman_fixed_to_int (vx)];
+	uint16_t br = src_bottom [pixman_fixed_to_int (vx) + 1];
+
+        uint32_t tmp = Filter_565_Expanded((vx>>12)&0xf, wb>>4, tl, tr, bl, br);
+        vx += unit_x;
+        *dst++ = SkCompact_rgb_16((tmp) >> 5);
+    }
+}
+
+
+#endif
+FAST_BILINEAR_MAINLOOP_COMMON (565_565_cover_SRC,
+			       scaled_bilinear_scanline_565_565_SRC,
+			       uint16_t, uint32_t, uint16_t,
+			       COVER, FLAG_NONE)
+FAST_BILINEAR_MAINLOOP_COMMON (565_565_pad_SRC,
+			       scaled_bilinear_scanline_565_565_SRC,
+			       uint16_t, uint32_t, uint16_t,
+			       PAD, FLAG_NONE)
+FAST_BILINEAR_MAINLOOP_COMMON (565_565_none_SRC,
+			       scaled_bilinear_scanline_565_565_SRC,
+			       uint16_t, uint32_t, uint16_t,
+			       NONE, FLAG_NONE)
+FAST_BILINEAR_MAINLOOP_COMMON (565_565_normal_SRC,
+			       scaled_bilinear_scanline_565_565_SRC,
+			       uint16_t, uint32_t, uint16_t,
+			       NORMAL, FLAG_NONE)
+
+FAST_BILINEAR_MAINLOOP_COMMON (8888_565_cover_OVER,
+			       scaled_bilinear_scanline_8888_565_OVER,
+			       uint32_t, uint32_t, uint16_t,
+			       COVER, FLAG_NONE)
+FAST_BILINEAR_MAINLOOP_COMMON (8888_565_pad_OVER,
+			       scaled_bilinear_scanline_8888_565_OVER,
+			       uint32_t, uint32_t, uint16_t,
+			       PAD, FLAG_NONE)
+FAST_BILINEAR_MAINLOOP_COMMON (8888_565_none_OVER,
+			       scaled_bilinear_scanline_8888_565_OVER,
+			       uint32_t, uint32_t, uint16_t,
+			       NONE, FLAG_NONE)
+FAST_BILINEAR_MAINLOOP_COMMON (8888_565_normal_OVER,
+			       scaled_bilinear_scanline_8888_565_OVER,
+			       uint32_t, uint32_t, uint16_t,
+			       NORMAL, FLAG_NONE)
+
+FAST_BILINEAR_MAINLOOP_COMMON (8888_8888_cover_OVER,
+			       scaled_bilinear_scanline_8888_8888_OVER,
+			       uint32_t, uint32_t, uint32_t,
+			       COVER, FLAG_NONE)
+FAST_BILINEAR_MAINLOOP_COMMON (8888_8888_pad_OVER,
+			       scaled_bilinear_scanline_8888_8888_OVER,
+			       uint32_t, uint32_t, uint32_t,
+			       PAD, FLAG_NONE)
+FAST_BILINEAR_MAINLOOP_COMMON (8888_8888_none_OVER,
+			       scaled_bilinear_scanline_8888_8888_OVER,
+			       uint32_t, uint32_t, uint32_t,
+			       NONE, FLAG_NONE)
+FAST_BILINEAR_MAINLOOP_COMMON (8888_8888_normal_OVER,
+			       scaled_bilinear_scanline_8888_8888_OVER,
+			       uint32_t, uint32_t, uint32_t,
+			       NORMAL, FLAG_NONE)
+
 #define REPEAT_MIN_WIDTH    32
 
 static void
 fast_composite_tiled_repeat (pixman_implementation_t *imp,
 			     pixman_composite_info_t *info)
 {
     PIXMAN_COMPOSITE_ARGS (info);
     pixman_composite_func_t func;
@@ -1960,16 +2172,20 @@ static const pixman_fast_path_t c_fast_p
 	PIXMAN_any,
 	(FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | FAST_PATH_BITS_IMAGE |
 	 FAST_PATH_NORMAL_REPEAT),
 	PIXMAN_any, 0,
 	PIXMAN_any, FAST_PATH_STD_DEST_FLAGS,
 	fast_composite_tiled_repeat
     },
 
+    SIMPLE_BILINEAR_FAST_PATH (SRC, r5g6b5, r5g6b5, 565_565),
+    SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, r5g6b5, 8888_565),
+    SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, 8888_8888),
+
     {   PIXMAN_OP_NONE	},
 };
 
 #ifdef WORDS_BIGENDIAN
 #define A1_FILL_MASK(n, offs) (((1U << (n)) - 1) << (32 - (offs) - (n)))
 #else
 #define A1_FILL_MASK(n, offs) (((1U << (n)) - 1) << (offs))
 #endif
--- a/gfx/cairo/libpixman/src/pixman-inlines.h
+++ b/gfx/cairo/libpixman/src/pixman-inlines.h
@@ -80,16 +80,21 @@ repeat (pixman_repeat_t repeat, int *c, 
     }
     return TRUE;
 }
 
 #ifdef MOZ_GFX_OPTIMIZE_MOBILE
 #define LOW_QUALITY_INTERPOLATION
 #endif
 
+#ifdef LOW_QUALITY_INTERPOLATION
+#define INTERPOLATION_PRECISION_BITS 4
+#else
+#define INTERPOLATION_PRECISION_BITS 8
+#endif
 static force_inline int32_t
 interpolation_coord(pixman_fixed_t t)
 {
 #ifdef LOW_QUALITY_INTERPOLATION
     return (t >> 12) & 0xf;
 #else
     return (t >> 8) & 0xff;
 #endif
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/pixman-bilinear-fastpath.patch
@@ -0,0 +1,287 @@
+changeset:   94061:73a9b24d863a
+tag:         bilin
+tag:         qbase
+tag:         qtip
+tag:         tip
+user:        Jeff Muizelaar <jmuizelaar@mozilla.com>
+date:        Tue May 15 18:26:16 2012 -0400
+summary:     Bug 754364. Add bilinear non-repeat and repeat fast paths. r=joe
+
+diff --git a/gfx/cairo/libpixman/src/pixman-fast-path.c b/gfx/cairo/libpixman/src/pixman-fast-path.c
+--- a/gfx/cairo/libpixman/src/pixman-fast-path.c
++++ b/gfx/cairo/libpixman/src/pixman-fast-path.c
+@@ -1186,16 +1186,228 @@ FAST_NEAREST (8888_565_none, 8888, 0565,
+ FAST_NEAREST (8888_565_pad, 8888, 0565, uint32_t, uint16_t, SRC, PAD)
+ FAST_NEAREST (8888_565_normal, 8888, 0565, uint32_t, uint16_t, SRC, NORMAL)
+ FAST_NEAREST (565_565_normal, 0565, 0565, uint16_t, uint16_t, SRC, NORMAL)
+ FAST_NEAREST (8888_565_cover, 8888, 0565, uint32_t, uint16_t, OVER, COVER)
+ FAST_NEAREST (8888_565_none, 8888, 0565, uint32_t, uint16_t, OVER, NONE)
+ FAST_NEAREST (8888_565_pad, 8888, 0565, uint32_t, uint16_t, OVER, PAD)
+ FAST_NEAREST (8888_565_normal, 8888, 0565, uint32_t, uint16_t, OVER, NORMAL)
+ 
++static force_inline void
++scaled_bilinear_scanline_8888_565_OVER (uint16_t *       dst,
++                                        const uint32_t * mask,
++                                        const uint32_t * src_top,
++                                        const uint32_t * src_bottom,
++                                        int32_t          w,
++                                        int              wt,
++                                        int              wb,
++                                        pixman_fixed_t   vx,
++                                        pixman_fixed_t   unit_x,
++                                        pixman_fixed_t   max_vx,
++                                        pixman_bool_t    zero_src)
++{
++    while ((w -= 1) >= 0)
++    {
++	uint32_t tl = src_top [pixman_fixed_to_int (vx)];
++	uint32_t tr = src_top [pixman_fixed_to_int (vx) + 1];
++	uint32_t bl = src_bottom [pixman_fixed_to_int (vx)];
++	uint32_t br = src_bottom [pixman_fixed_to_int (vx) + 1];
++	uint32_t src, result;
++	uint16_t d;
++	d = *dst;
++	src = bilinear_interpolation (tl, tr,
++				      bl, br,
++				      interpolation_coord(vx),
++				      wb >> (8 - INTERPOLATION_PRECISION_BITS));
++	vx += unit_x;
++	result = over (src, CONVERT_0565_TO_0888 (d));
++	*dst++ = CONVERT_8888_TO_0565(result);
++    }
++}
++
++static force_inline void
++scaled_bilinear_scanline_8888_8888_OVER (uint32_t *       dst,
++                                         const uint32_t * mask,
++                                         const uint32_t * src_top,
++                                         const uint32_t * src_bottom,
++                                         int32_t          w,
++                                         int              wt,
++                                         int              wb,
++                                         pixman_fixed_t   vx,
++                                         pixman_fixed_t   unit_x,
++                                         pixman_fixed_t   max_vx,
++                                         pixman_bool_t    zero_src)
++{
++    while ((w -= 1) >= 0)
++    {
++	uint32_t tl = src_top [pixman_fixed_to_int (vx)];
++	uint32_t tr = src_top [pixman_fixed_to_int (vx) + 1];
++	uint32_t bl = src_bottom [pixman_fixed_to_int (vx)];
++	uint32_t br = src_bottom [pixman_fixed_to_int (vx) + 1];
++	uint32_t src;
++	uint32_t d;
++	uint32_t result;
++	d = *dst;
++	src = bilinear_interpolation (tl, tr,
++				      bl, br,
++				      interpolation_coord(vx),
++				      wb >> (8 - INTERPOLATION_PRECISION_BITS));
++	vx += unit_x;
++	*dst++ = over (src, d);
++    }
++}
++
++#if 1
++
++static force_inline void
++scaled_bilinear_scanline_565_565_SRC (uint16_t *       dst,
++				      const uint32_t * mask,
++				      const uint16_t * src_top,
++				      const uint16_t * src_bottom,
++				      int32_t          w,
++				      int              wt,
++				      int              wb,
++				      pixman_fixed_t   vx,
++				      pixman_fixed_t   unit_x,
++				      pixman_fixed_t   max_vx,
++				      pixman_bool_t    zero_src)
++{
++    while ((w -= 1) >= 0)
++    {
++	uint16_t tl = src_top [pixman_fixed_to_int (vx)];
++	uint16_t tr = src_top [pixman_fixed_to_int (vx) + 1];
++	uint16_t bl = src_bottom [pixman_fixed_to_int (vx)];
++	uint16_t br = src_bottom [pixman_fixed_to_int (vx) + 1];
++	uint32_t d;
++	d = bilinear_interpolation(CONVERT_0565_TO_8888(tl),
++				   CONVERT_0565_TO_8888(tr),
++				   CONVERT_0565_TO_8888(bl),
++				   CONVERT_0565_TO_8888(br),
++				   interpolation_coord(vx),
++				   wb >> (8 - INTERPOLATION_PRECISION_BITS));
++	vx += unit_x;
++	*dst++ = CONVERT_8888_TO_0565(d);
++    }
++}
++
++#else
++
++#define SK_G16_MASK_IN_PLACE 0xfc0
++
++static inline uint32_t SkExpand_rgb_16(uint16_t c) {
++
++    return ((c & SK_G16_MASK_IN_PLACE) << 16) | (c & ~SK_G16_MASK_IN_PLACE);
++}
++
++/** Compress an expanded value (from SkExpand_rgb_16) back down to a 16bit
++    color value. The computation yields only 16bits of valid data, but we claim
++    to return 32bits, so that the compiler won't generate extra instructions to
++    "clean" the top 16bits. However, the top 16 can contain garbage, so it is
++    up to the caller to safely ignore them.
++*/
++static inline uint16_t SkCompact_rgb_16(uint32_t c) {
++    return ((c >> 16) & SK_G16_MASK_IN_PLACE) | (c & ~SK_G16_MASK_IN_PLACE);
++}
++// returns expanded * 5bits
++static inline uint32_t Filter_565_Expanded(unsigned x, unsigned y,
++                                           uint32_t a00, uint32_t a01,
++                                           uint32_t a10, uint32_t a11) {
++    a00 = SkExpand_rgb_16(a00);
++    a01 = SkExpand_rgb_16(a01);
++    a10 = SkExpand_rgb_16(a10);
++    a11 = SkExpand_rgb_16(a11);
++    
++    int xy = x * y >> 3;
++    return  a00 * (32 - 2*y - 2*x + xy) +
++            a01 * (2*x - xy) +
++            a10 * (2*y - xy) +
++            a11 * xy;
++}
++
++
++
++static force_inline void
++scaled_bilinear_scanline_565_565_SRC (uint16_t *       dst,
++				      const uint32_t * mask,
++				      const uint16_t * src_top,
++				      const uint16_t * src_bottom,
++				      int32_t          w,
++				      int              wt,
++				      int              wb,
++				      pixman_fixed_t   vx,
++				      pixman_fixed_t   unit_x,
++				      pixman_fixed_t   max_vx,
++				      pixman_bool_t    zero_src)
++{
++    while ((w -= 1) >= 0)
++    {
++	uint16_t tl = src_top [pixman_fixed_to_int (vx)];
++	uint16_t tr = src_top [pixman_fixed_to_int (vx) + 1];
++	uint16_t bl = src_bottom [pixman_fixed_to_int (vx)];
++	uint16_t br = src_bottom [pixman_fixed_to_int (vx) + 1];
++
++        uint32_t tmp = Filter_565_Expanded((vx>>12)&0xf, wb>>4, tl, tr, bl, br);
++        vx += unit_x;
++        *dst++ = SkCompact_rgb_16((tmp) >> 5);
++    }
++}
++
++
++#endif
++FAST_BILINEAR_MAINLOOP_COMMON (565_565_cover_SRC,
++			       scaled_bilinear_scanline_565_565_SRC,
++			       uint16_t, uint32_t, uint16_t,
++			       COVER, FLAG_NONE)
++FAST_BILINEAR_MAINLOOP_COMMON (565_565_pad_SRC,
++			       scaled_bilinear_scanline_565_565_SRC,
++			       uint16_t, uint32_t, uint16_t,
++			       PAD, FLAG_NONE)
++FAST_BILINEAR_MAINLOOP_COMMON (565_565_none_SRC,
++			       scaled_bilinear_scanline_565_565_SRC,
++			       uint16_t, uint32_t, uint16_t,
++			       NONE, FLAG_NONE)
++FAST_BILINEAR_MAINLOOP_COMMON (565_565_normal_SRC,
++			       scaled_bilinear_scanline_565_565_SRC,
++			       uint16_t, uint32_t, uint16_t,
++			       NORMAL, FLAG_NONE)
++
++FAST_BILINEAR_MAINLOOP_COMMON (8888_565_cover_OVER,
++			       scaled_bilinear_scanline_8888_565_OVER,
++			       uint32_t, uint32_t, uint16_t,
++			       COVER, FLAG_NONE)
++FAST_BILINEAR_MAINLOOP_COMMON (8888_565_pad_OVER,
++			       scaled_bilinear_scanline_8888_565_OVER,
++			       uint32_t, uint32_t, uint16_t,
++			       PAD, FLAG_NONE)
++FAST_BILINEAR_MAINLOOP_COMMON (8888_565_none_OVER,
++			       scaled_bilinear_scanline_8888_565_OVER,
++			       uint32_t, uint32_t, uint16_t,
++			       NONE, FLAG_NONE)
++FAST_BILINEAR_MAINLOOP_COMMON (8888_565_normal_OVER,
++			       scaled_bilinear_scanline_8888_565_OVER,
++			       uint32_t, uint32_t, uint16_t,
++			       NORMAL, FLAG_NONE)
++
++FAST_BILINEAR_MAINLOOP_COMMON (8888_8888_cover_OVER,
++			       scaled_bilinear_scanline_8888_8888_OVER,
++			       uint32_t, uint32_t, uint32_t,
++			       COVER, FLAG_NONE)
++FAST_BILINEAR_MAINLOOP_COMMON (8888_8888_pad_OVER,
++			       scaled_bilinear_scanline_8888_8888_OVER,
++			       uint32_t, uint32_t, uint32_t,
++			       PAD, FLAG_NONE)
++FAST_BILINEAR_MAINLOOP_COMMON (8888_8888_none_OVER,
++			       scaled_bilinear_scanline_8888_8888_OVER,
++			       uint32_t, uint32_t, uint32_t,
++			       NONE, FLAG_NONE)
++FAST_BILINEAR_MAINLOOP_COMMON (8888_8888_normal_OVER,
++			       scaled_bilinear_scanline_8888_8888_OVER,
++			       uint32_t, uint32_t, uint32_t,
++			       NORMAL, FLAG_NONE)
++
+ #define REPEAT_MIN_WIDTH    32
+ 
+ static void
+ fast_composite_tiled_repeat (pixman_implementation_t *imp,
+ 			     pixman_composite_info_t *info)
+ {
+     PIXMAN_COMPOSITE_ARGS (info);
+     pixman_composite_func_t func;
+@@ -1960,16 +2172,20 @@ static const pixman_fast_path_t c_fast_p
+ 	PIXMAN_any,
+ 	(FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | FAST_PATH_BITS_IMAGE |
+ 	 FAST_PATH_NORMAL_REPEAT),
+ 	PIXMAN_any, 0,
+ 	PIXMAN_any, FAST_PATH_STD_DEST_FLAGS,
+ 	fast_composite_tiled_repeat
+     },
+ 
++    SIMPLE_BILINEAR_FAST_PATH (SRC, r5g6b5, r5g6b5, 565_565),
++    SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, r5g6b5, 8888_565),
++    SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, 8888_8888),
++
+     {   PIXMAN_OP_NONE	},
+ };
+ 
+ #ifdef WORDS_BIGENDIAN
+ #define A1_FILL_MASK(n, offs) (((1U << (n)) - 1) << (32 - (offs) - (n)))
+ #else
+ #define A1_FILL_MASK(n, offs) (((1U << (n)) - 1) << (offs))
+ #endif
+diff --git a/gfx/cairo/libpixman/src/pixman-inlines.h b/gfx/cairo/libpixman/src/pixman-inlines.h
+--- a/gfx/cairo/libpixman/src/pixman-inlines.h
++++ b/gfx/cairo/libpixman/src/pixman-inlines.h
+@@ -80,16 +80,21 @@ repeat (pixman_repeat_t repeat, int *c, 
+     }
+     return TRUE;
+ }
+ 
+ #ifdef MOZ_GFX_OPTIMIZE_MOBILE
+ #define LOW_QUALITY_INTERPOLATION
+ #endif
+ 
++#ifdef LOW_QUALITY_INTERPOLATION
++#define INTERPOLATION_PRECISION_BITS 4
++#else
++#define INTERPOLATION_PRECISION_BITS 8
++#endif
+ static force_inline int32_t
+ interpolation_coord(pixman_fixed_t t)
+ {
+ #ifdef LOW_QUALITY_INTERPOLATION
+     return (t >> 12) & 0xf;
+ #else
+     return (t >> 8) & 0xff;
+ #endif
--- a/gfx/gl/GLLibraryEGL.cpp
+++ b/gfx/gl/GLLibraryEGL.cpp
@@ -1,37 +1,30 @@
 /* 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 "GLLibraryEGL.h"
 
 #include "gfxCrashReporterUtils.h"
 #include "mozilla/Preferences.h"
-
-#define EGL_LIB "libEGL.so"
-#define EGL_LIB1 "libEGL.so.1"
-
-#if defined(XP_WIN)
-
-#define EGL_LIB "libEGL.dll"
-
-#endif
+#include "nsDirectoryServiceDefs.h"
 
 namespace mozilla {
 namespace gl {
 
+#if defined(ANDROID)
+
 static PRLibrary* LoadApitraceLibrary()
 {
     static PRLibrary* sApitraceLibrary = NULL;
 
     if (sApitraceLibrary)
         return sApitraceLibrary;
 
-#if defined(ANDROID)
     nsCString logFile = Preferences::GetCString("gfx.apitrace.logfile");
 
     if (logFile.IsEmpty()) {
         logFile = "firefox.trace";
     }
 
     // The firefox process can't write to /data/local, but it can write
     // to $GRE_HOME/
@@ -41,82 +34,92 @@ static PRLibrary* LoadApitraceLibrary()
     // apitrace uses the TRACE_FILE environment variable to determine where
     // to log trace output to
     printf_stderr("Logging GL tracing output to %s", logPath.get());
     setenv("TRACE_FILE", logPath.get(), false);
 
     printf_stderr("Attempting load of %s\n", APITRACE_LIB);
 
     sApitraceLibrary = PR_LoadLibrary(APITRACE_LIB);
-#endif
 
     return sApitraceLibrary;
 }
 
+#endif // ANDROID
+
 bool
 GLLibraryEGL::EnsureInitialized()
 {
+    nsresult rv;
+
     if (mInitialized) {
         return true;
     }
 
     mozilla::ScopedGfxFeatureReporter reporter("EGL");
 
 #ifdef XP_WIN
-    // Allow for explicitly specifying the location of libEGL.dll and
-    // libGLESv2.dll.
-    do {
-        nsCOMPtr<nsILocalFile> eglFile, glesv2File;
-        nsresult rv = Preferences::GetComplex("gfx.angle.egl.path",
-                                              NS_GET_IID(nsILocalFile),
-                                              getter_AddRefs(eglFile));
-        if (NS_FAILED(rv) || !eglFile)
-            break;
+    if (!mEGLLibrary) {
+        // On Windows, the GLESv2 and EGL libraries are shipped with libxul and
+        // we should look for them there. We have to load the libs in this
+        // order, because libEGL.dll depends on libGLESv2.dll.
+
+        nsCOMPtr<nsIFile> libraryFile;
 
-        nsCAutoString s;
+        nsCOMPtr<nsIProperties> dirService =
+            do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
+        if (!dirService)
+            return false;
+
+        rv = dirService->Get(NS_GRE_DIR, NS_GET_IID(nsIFile),
+                             getter_AddRefs(libraryFile));
+        if (NS_FAILED(rv))
+            return false;
+
+        libraryFile->Append(NS_LITERAL_STRING("libGLESv2.dll"));
+        PRLibrary* glesv2lib = nsnull;
 
-        // note that we have to load the libs in this order, because libEGL.dll
-        // depends on libGLESv2.dll, but is not/may not be in our search path.
-        nsCOMPtr<nsIFile> f;
-        eglFile->Clone(getter_AddRefs(f));
-        glesv2File = do_QueryInterface(f);
-        if (!glesv2File)
-            break;
+        libraryFile->Load(&glesv2lib);
 
-        glesv2File->Append(NS_LITERAL_STRING("libGLESv2.dll"));
+        // Intentionally leak glesv2lib
+    
+        libraryFile->SetLeafName(NS_LITERAL_STRING("libEGL.dll"));
+        rv = libraryFile->Load(&mEGLLibrary);
+        if (NS_FAILED(rv)) {
+            NS_WARNING("Couldn't load libEGL.dll, canvas3d will be disabled.");
+            return false;
+        }
+    }
+#else // !Windows
 
-        PRLibrary *glesv2lib = nsnull; // this will be leaked on purpose
-        glesv2File->Load(&glesv2lib);
-        if (!glesv2lib)
-            break;
+    // On non-Windows (Android) we use system copies of libEGL. We look for
+    // the APITrace lib, libEGL.so, and libEGL.so.1 in that order.
 
-        eglFile->Append(NS_LITERAL_STRING("libEGL.dll"));
-        eglFile->Load(&mEGLLibrary);
-    } while (false);
+#if defined(ANDROID)
+    if (!mEGLLibrary)
+        mEGLLibrary = LoadApitraceLibrary();
 #endif
 
     if (!mEGLLibrary) {
-        mEGLLibrary = LoadApitraceLibrary();
-
-        if (!mEGLLibrary) {
-            printf_stderr("Attempting load of %s\n", EGL_LIB);
-            mEGLLibrary = PR_LoadLibrary(EGL_LIB);
+        printf_stderr("Attempting load of libEGL.so\n");
+        mEGLLibrary = PR_LoadLibrary("libEGL.so");
+    }
 #if defined(XP_UNIX)
-            if (!mEGLLibrary) {
-                mEGLLibrary = PR_LoadLibrary(EGL_LIB1);
-            }
+    if (!mEGLLibrary) {
+        mEGLLibrary = PR_LoadLibrary("libEGL.so.1");
+    }
 #endif
-        }
-    }
 
     if (!mEGLLibrary) {
         NS_WARNING("Couldn't load EGL LIB.");
         return false;
     }
 
+#endif // !Windows
+
 #define SYMBOL(name) \
 { (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, NULL } }
 
     GLLibraryLoader::SymLoadStruct earlySymbols[] = {
         SYMBOL(GetDisplay),
         SYMBOL(GetCurrentSurface),
         SYMBOL(GetCurrentContext),
         SYMBOL(MakeCurrent),
--- a/gfx/layers/basic/BasicTiledThebesLayer.cpp
+++ b/gfx/layers/basic/BasicTiledThebesLayer.cpp
@@ -91,17 +91,17 @@ BasicTiledLayerBuffer::PaintThebes(Basic
 #ifdef GFX_TILEDLAYER_PREF_WARNINGS
     if (PR_IntervalNow() - start > 3) {
       printf_stderr("Slow alloc %i\n", PR_IntervalNow() - start);
     }
     start = PR_IntervalNow();
 #endif
     SAMPLE_LABEL("BasicTiledLayerBuffer", "PaintThebesSingleBufferDraw");
 
-    mCallback(mThebesLayer, ctxt, aPaintRegion, aPaintRegion, mCallbackData);
+    mCallback(mThebesLayer, ctxt, aPaintRegion, nsIntRegion(), mCallbackData);
   }
 
 #ifdef GFX_TILEDLAYER_PREF_WARNINGS
   if (PR_IntervalNow() - start > 30) {
     const nsIntRect bounds = aPaintRegion.GetBounds();
     printf_stderr("Time to draw %i: %i, %i, %i, %i\n", PR_IntervalNow() - start, bounds.x, bounds.y, bounds.width, bounds.height);
     if (aPaintRegion.IsComplex()) {
       printf_stderr("Complex region\n");
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -505,16 +505,20 @@ gfxUtils::DrawPixelSnapped(gfxContext*  
                                             aFill, currentTarget);
     if (!workaround.Succeeded())
         return;
 
     nsRefPtr<gfxDrawable> drawable = aDrawable;
 
     aFilter = ReduceResamplingFilter(aFilter, aImageRect.Width(), aImageRect.Height(), aSourceRect.Width(), aSourceRect.Height());
 
+    // On Mobile, we don't ever want to do this; it has the potential for
+    // allocating very large temporary surfaces, especially since we'll
+    // do full-page snapshots often (see bug 749426).
+#ifndef MOZ_GFX_OPTIMIZE_MOBILE
     // OK now, the hard part left is to account for the subimage sampling
     // restriction. If all the transforms involved are just integer
     // translations, then we assume no resampling will occur so there's
     // nothing to do.
     // XXX if only we had source-clipping in cairo!
     if (aContext->CurrentMatrix().HasNonIntegerTranslation() ||
         aUserSpaceToImageSpace.HasNonIntegerTranslation()) {
         if (doTile || !aSubimage.Contains(aImageRect)) {
@@ -526,16 +530,17 @@ gfxUtils::DrawPixelSnapped(gfxContext*  
                 drawable.swap(restrictedDrawable);
             }
         }
         // We no longer need to tile: Either we never needed to, or we already
         // filled a surface with the tiled pattern; this surface can now be
         // drawn without tiling.
         doTile = false;
     }
+#endif
 
     gfxContext::GraphicsOperator op = aContext->CurrentOperator();
     if ((op == gfxContext::OPERATOR_OVER || workaround.PushedGroup()) &&
         aFormat == gfxASurface::ImageFormatRGB24) {
         aContext->SetOperator(OptimalFillOperator());
     }
 
     drawable->Draw(aContext, aFill, doTile, aFilter, aUserSpaceToImageSpace);
--- a/hal/gonk/GonkSensor.cpp
+++ b/hal/gonk/GonkSensor.cpp
@@ -97,35 +97,35 @@ class SensorRunnable : public nsRunnable
 public:
   SensorRunnable(const sensors_event_t& data)
   {
     mSensorData.sensor() = HardwareSensorToHalSensor(data.type);
     if (mSensorData.sensor() == SENSOR_UNKNOWN) {
       // Emulator is broken and gives us events without types set
       const sensor_t* sensors = NULL;
       SensorDevice& device = SensorDevice::getInstance();
-      size_t size = device.getSensorList(&sensors);
+      ssize_t size = device.getSensorList(&sensors);
       if (data.sensor < size)
         mSensorData.sensor() = HardwareSensorToHalSensor(sensors[data.sensor].type);
     }
     mSensorData.accuracy() = HardwareStatusToHalAccuracy(SensorseventStatus(data));
     mSensorData.timestamp() = data.timestamp;
     if (mSensorData.sensor() == SENSOR_GYROSCOPE) {
       // libhardware returns gyro as rad.  convert.
       mSensorValues.AppendElement(radToDeg(data.data[0]));
       mSensorValues.AppendElement(radToDeg(data.data[1]));
       mSensorValues.AppendElement(radToDeg(data.data[2]));
     } else if (mSensorData.sensor() == SENSOR_PROXIMITY) {
       mSensorValues.AppendElement(data.data[0]);
       mSensorValues.AppendElement(0);     
 
       // Determine the maxRange for this sensor.
       const sensor_t* sensors = NULL;
-      size_t size = SensorDevice::getInstance().getSensorList(&sensors);
-      for (size_t i = 0; i < size; i++) {
+      ssize_t size = SensorDevice::getInstance().getSensorList(&sensors);
+      for (ssize_t i = 0; i < size; i++) {
         if (sensors[i].type == SENSOR_TYPE_PROXIMITY) {
           mSensorValues.AppendElement(sensors[i].maxRange);     
         }
       }
     } else if (mSensorData.sensor() == SENSOR_LIGHT) {
       mSensorValues.AppendElement(data.data[0]);
     } else {
       mSensorValues.AppendElement(data.data[0]);
@@ -236,18 +236,18 @@ class SwitchSensor {
 
 
 static void
 SetSensorState(SensorType aSensor, bool activate)
 {
   int type = HalSensorToHardwareSensor(aSensor);
   const sensor_t* sensors = NULL;
   SensorDevice& device = SensorDevice::getInstance();
-  size_t size = device.getSensorList(&sensors);
-  for (size_t i = 0; i < size; i++) {
+  ssize_t size = device.getSensorList(&sensors);
+  for (ssize_t i = 0; i < size; i++) {
     if (sensors[i].type == type) {
       // Post an event to the sensor thread
       nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(new SwitchSensor(activate, sensors[i], pthread_self()),
                                                          &SwitchSensor::Switch);
 
       sSwitchThread->Dispatch(event, NS_DISPATCH_NORMAL);
       break;
     }
new file mode 100644
--- /dev/null
+++ b/js/src/config/makefiles/debugmake.mk
@@ -0,0 +1,118 @@
+# -*- makefile -*-
+# vim:set ts=8 sw=8 sts=8 noet:
+#
+# 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/.
+#
+
+###########################################################################
+## Intent: Helper targets for displaying variables and state information
+###########################################################################
+
+# Support usage outside of config/rules.mk
+ifndef INCLUDED_DEBUGMAKE_MK #{
+
+echo-variable-%:
+	@echo "$($*)"
+
+echo-tiers:
+	@echo $(TIERS)
+
+echo-tier-dirs:
+	@$(foreach tier,$(TIERS),echo '$(tier):'; echo '  dirs: $(tier_$(tier)_dirs)'; echo '  staticdirs: $(tier_$(tier)_staticdirs)'; )
+
+echo-dirs:
+	@echo $(DIRS)
+
+echo-module:
+	@echo $(MODULE)
+
+echo-depth-path:
+	@$(topsrcdir)/build/unix/print-depth-path.sh
+
+echo-module-name:
+	@$(topsrcdir)/build/package/rpm/print-module-name.sh
+
+echo-module-filelist:
+	@$(topsrcdir)/build/package/rpm/print-module-filelist.sh
+
+showtargs:
+ifneq (,$(filter $(PROGRAM) $(HOST_PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY),$(TARGETS)))
+	@echo --------------------------------------------------------------------------------
+	@echo "PROGRAM             = $(PROGRAM)"
+	@echo "SIMPLE_PROGRAMS     = $(SIMPLE_PROGRAMS)"
+	@echo "LIBRARY             = $(LIBRARY)"
+	@echo "SHARED_LIBRARY      = $(SHARED_LIBRARY)"
+	@echo "SHARED_LIBRARY_LIBS = $(SHARED_LIBRARY_LIBS)"
+	@echo "LIBS                = $(LIBS)"
+	@echo "DEF_FILE            = $(DEF_FILE)"
+	@echo "IMPORT_LIBRARY      = $(IMPORT_LIBRARY)"
+	@echo "STATIC_LIBS         = $(STATIC_LIBS)"
+	@echo "SHARED_LIBS         = $(SHARED_LIBS)"
+	@echo "EXTRA_DSO_LIBS      = $(EXTRA_DSO_LIBS)"
+	@echo "EXTRA_DSO_LDOPTS    = $(EXTRA_DSO_LDOPTS)"
+	@echo "DEPENDENT_LIBS      = $(DEPENDENT_LIBS)"
+	@echo --------------------------------------------------------------------------------
+endif
+	$(LOOP_OVER_PARALLEL_DIRS)
+	$(LOOP_OVER_DIRS)
+
+showbuild:
+	@echo "MOZ_BUILD_ROOT     = $(MOZ_BUILD_ROOT)"
+	@echo "MOZ_WIDGET_TOOLKIT = $(MOZ_WIDGET_TOOLKIT)"
+	@echo "CC                 = $(CC)"
+	@echo "CXX                = $(CXX)"
+	@echo "CCC                = $(CCC)"
+	@echo "CPP                = $(CPP)"
+	@echo "LD                 = $(LD)"
+	@echo "AR                 = $(AR)"
+	@echo "IMPLIB             = $(IMPLIB)"
+	@echo "FILTER             = $(FILTER)"
+	@echo "MKSHLIB            = $(MKSHLIB)"
+	@echo "MKCSHLIB           = $(MKCSHLIB)"
+	@echo "RC                 = $(RC)"
+	@echo "MC                 = $(MC)"
+	@echo "CFLAGS             = $(CFLAGS)"
+	@echo "OS_CFLAGS          = $(OS_CFLAGS)"
+	@echo "COMPILE_CFLAGS     = $(COMPILE_CFLAGS)"
+	@echo "CXXFLAGS           = $(CXXFLAGS)"
+	@echo "OS_CXXFLAGS        = $(OS_CXXFLAGS)"
+	@echo "COMPILE_CXXFLAGS   = $(COMPILE_CXXFLAGS)"
+	@echo "COMPILE_CMFLAGS    = $(COMPILE_CMFLAGS)"
+	@echo "COMPILE_CMMFLAGS   = $(COMPILE_CMMFLAGS)"
+	@echo "LDFLAGS            = $(LDFLAGS)"
+	@echo "OS_LDFLAGS         = $(OS_LDFLAGS)"
+	@echo "DSO_LDOPTS         = $(DSO_LDOPTS)"
+	@echo "OS_INCLUDES        = $(OS_INCLUDES)"
+	@echo "OS_LIBS            = $(OS_LIBS)"
+	@echo "EXTRA_LIBS         = $(EXTRA_LIBS)"
+	@echo "BIN_FLAGS          = $(BIN_FLAGS)"
+	@echo "INCLUDES           = $(INCLUDES)"
+	@echo "DEFINES            = $(DEFINES)"
+	@echo "ACDEFINES          = $(ACDEFINES)"
+	@echo "BIN_SUFFIX         = $(BIN_SUFFIX)"
+	@echo "LIB_SUFFIX         = $(LIB_SUFFIX)"
+	@echo "DLL_SUFFIX         = $(DLL_SUFFIX)"
+	@echo "IMPORT_LIB_SUFFIX  = $(IMPORT_LIB_SUFFIX)"
+	@echo "INSTALL            = $(INSTALL)"
+	@echo "VPATH              = $(VPATH)"
+
+showhost:
+	@echo "HOST_CC            = $(HOST_CC)"
+	@echo "HOST_CXX           = $(HOST_CXX)"
+	@echo "HOST_CFLAGS        = $(HOST_CFLAGS)"
+	@echo "HOST_LDFLAGS       = $(HOST_LDFLAGS)"
+	@echo "HOST_LIBS          = $(HOST_LIBS)"
+	@echo "HOST_EXTRA_LIBS    = $(HOST_EXTRA_LIBS)"
+	@echo "HOST_EXTRA_DEPS    = $(HOST_EXTRA_DEPS)"
+	@echo "HOST_PROGRAM       = $(HOST_PROGRAM)"
+	@echo "HOST_OBJS          = $(HOST_OBJS)"
+	@echo "HOST_PROGOBJS      = $(HOST_PROGOBJS)"
+	@echo "HOST_LIBRARY       = $(HOST_LIBRARY)"
+
+showbuildmods::
+	@echo "Module dirs	= $(BUILD_MODULE_DIRS)"
+
+INCLUDED_DEBUGMAKE_MK = 1
+endif #}
--- a/js/src/config/makefiles/makeutils.mk
+++ b/js/src/config/makefiles/makeutils.mk
@@ -62,18 +62,21 @@ is_XinY =$(filter $(1),$(call subargv,3,
 # Provide an alternate var to support testing
 ifdef MAKEUTILS_UNIT_TEST
   mcg_goals=TEST_MAKECMDGOALS
 else
   mcg_goals=MAKECMDGOALS
 endif
 
 # Intent: Conditionals for detecting common/tier target use
-#   Todo: are check, install, test needed ?
-isTargetStem       = $(sort $(foreach pat, $(1)% %$(1), $(call is_XinY,$(pat),${$(mcg_goals)})))
+isTargetStem       = $(sort \
+  $(foreach var,$(getargv),\
+    $(foreach pat,$(var)% %$(var),\
+      $(call is_XinY,$(pat),${$(mcg_goals)})\
+  )))
 isTargetStemClean  = $(call isTargetStem,clean)
 isTargetStemExport = $(call isTargetStem,export)
 isTargetStemLibs   = $(call isTargetStem,libs)
 isTargetStemTools  = $(call isTargetStem,tools)
 
 ##################################################
 # Intent: Validation functions / unit test helpers
 
new file mode 100644
--- /dev/null
+++ b/js/src/config/makefiles/xpcshell.mk
@@ -0,0 +1,128 @@
+# -*- makefile -*-
+# vim:set ts=8 sw=8 sts=8 noet:
+#
+# 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 INCLUDED_TESTS_XPCSHELL_MK #{
+
+ifdef XPCSHELL_TESTS #{
+
+ifndef relativesrcdir
+$(error Must define relativesrcdir when defining XPCSHELL_TESTS.)
+endif
+
+define _INSTALL_TESTS
+$(DIR_INSTALL) $(wildcard $(srcdir)/$(dir)/*) $(testxpcobjdir)/$(relativesrcdir)/$(dir)
+
+endef # do not remove the blank line!
+
+SOLO_FILE ?= $(error Specify a test filename in SOLO_FILE when using check-interactive or check-one)
+
+testxpcsrcdir = $(topsrcdir)/testing/xpcshell
+
+libs:: libs-xpcshell-tests
+
+###########################################################################
+libs-xpcshell-tests:
+	$(foreach dir,$(XPCSHELL_TESTS),$(_INSTALL_TESTS))
+ifndef NO_XPCSHELL_MANIFEST_CHECK #{
+	$(PYTHON) $(MOZILLA_DIR)/build/xpccheck.py \
+	  $(topsrcdir) \
+	  $(topsrcdir)/testing/xpcshell/xpcshell.ini \
+	  $(addprefix $(MOZILLA_DIR)/$(relativesrcdir)/,$(XPCSHELL_TESTS))
+endif #} NO_XPCSHELL_MANIFEST_CHECK 
+
+###########################################################################
+# Execute all tests in the $(XPCSHELL_TESTS) directories.
+# See also testsuite-targets.mk 'xpcshell-tests' target for global execution.
+xpcshell-tests:
+	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
+	  -I$(topsrcdir)/build \
+      -I$(DEPTH)/_tests/mozbase/mozinfo \
+	  $(testxpcsrcdir)/runxpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  --build-info-json=$(DEPTH)/mozinfo.json \
+	  --tests-root-dir=$(testxpcobjdir) \
+	  --testing-modules-dir=$(DEPTH)/_tests/modules \
+	  --xunit-file=$(testxpcobjdir)/$(relativesrcdir)/results.xml \
+	  --xunit-suite-name=xpcshell \
+	  $(EXTRA_TEST_ARGS) \
+	  $(LIBXUL_DIST)/bin/xpcshell \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+
+xpcshell-tests-remote: DM_TRANS?=adb
+xpcshell-tests-remote:
+	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
+	  -I$(topsrcdir)/build \
+	  -I$(topsrcdir)/build/mobile \
+	  $(topsrcdir)/testing/xpcshell/remotexpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  --build-info-json=$(DEPTH)/mozinfo.json \
+	  $(EXTRA_TEST_ARGS) \
+	  --dm_trans=$(DM_TRANS) \
+	  --deviceIP=${TEST_DEVICE} \
+	  --objdir=$(DEPTH) \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+
+###########################################################################
+# Execute a single test, specified in $(SOLO_FILE), but don't automatically
+# start the test. Instead, present the xpcshell prompt so the user can
+# attach a debugger and then start the test.
+check-interactive:
+	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
+	  -I$(topsrcdir)/build \
+      -I$(DEPTH)/_tests/mozbase/mozinfo \
+	  $(testxpcsrcdir)/runxpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  --build-info-json=$(DEPTH)/mozinfo.json \
+	  --test-path=$(SOLO_FILE) \
+	  --testing-modules-dir=$(DEPTH)/_tests/modules \
+	  --profile-name=$(MOZ_APP_NAME) \
+	  --interactive \
+	  $(LIBXUL_DIST)/bin/xpcshell \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+
+# Execute a single test, specified in $(SOLO_FILE)
+check-one:
+	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
+	  -I$(topsrcdir)/build \
+      -I$(DEPTH)/_tests/mozbase/mozinfo \
+	  $(testxpcsrcdir)/runxpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  --build-info-json=$(DEPTH)/mozinfo.json \
+	  --test-path=$(SOLO_FILE) \
+	  --testing-modules-dir=$(DEPTH)/_tests/modules \
+	  --profile-name=$(MOZ_APP_NAME) \
+	  --verbose \
+	  $(EXTRA_TEST_ARGS) \
+	  $(LIBXUL_DIST)/bin/xpcshell \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+
+check-one-remote: DM_TRANS?=adb
+check-one-remote:
+	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
+	  -I$(topsrcdir)/build \
+	  -I$(topsrcdir)/build/mobile \
+	  $(testxpcsrcdir)/remotexpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  --build-info-json=$(DEPTH)/mozinfo.json \
+	  --test-path=$(SOLO_FILE) \
+	  --profile-name=$(MOZ_APP_NAME) \
+	  --verbose \
+	  $(EXTRA_TEST_ARGS) \
+	  --dm_trans=$(DM_TRANS) \
+	  --deviceIP=${TEST_DEVICE} \
+	  --objdir=$(DEPTH) \
+          --noSetup \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+
+
+.PHONY: xpcshell-tests check-interactive check-one libs-xpcshell-tests
+
+endif #} XPCSHELL_TESTS
+
+INCLUDED_TESTS_XPCSHELL_MK = 1
+endif #} INCLUDED_TESTS_XPCSHELL_MK
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -80,118 +80,19 @@ ifdef ENABLE_TESTS
 # The current developer workflow expects tests to be updated when processing
 # the default target. If we ever change this implementation, the behavior
 # should be preserved or the change should be widely communicated. A
 # consequence of not processing test dir targets during the default target is
 # that changes to tests may not be updated and code could assume to pass
 # locally against non-current test code.
 DIRS += $(TEST_DIRS)
 
-ifdef XPCSHELL_TESTS
-ifndef relativesrcdir
-$(error Must define relativesrcdir when defining XPCSHELL_TESTS.)
-endif
-
-define _INSTALL_TESTS
-$(DIR_INSTALL) $(wildcard $(srcdir)/$(dir)/*) $(testxpcobjdir)/$(relativesrcdir)/$(dir)
-
-endef # do not remove the blank line!
-
-SOLO_FILE ?= $(error Specify a test filename in SOLO_FILE when using check-interactive or check-one)
-
-libs::
-	$(foreach dir,$(XPCSHELL_TESTS),$(_INSTALL_TESTS))
-ifndef NO_XPCSHELL_MANIFEST_CHECK
-	$(PYTHON) $(MOZILLA_DIR)/build/xpccheck.py \
-	  $(topsrcdir) \
-	  $(topsrcdir)/testing/xpcshell/xpcshell.ini \
-	  $(addprefix $(MOZILLA_DIR)/$(relativesrcdir)/,$(XPCSHELL_TESTS))
-endif
-
-testxpcsrcdir = $(topsrcdir)/testing/xpcshell
-
-# Execute all tests in the $(XPCSHELL_TESTS) directories.
-# See also testsuite-targets.mk 'xpcshell-tests' target for global execution.
-xpcshell-tests:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build -I$(DEPTH)/_tests/mozbase/mozinfo \
-	  $(testxpcsrcdir)/runxpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  --tests-root-dir=$(testxpcobjdir) \
-	  --testing-modules-dir=$(DEPTH)/_tests/modules \
-	  --xunit-file=$(testxpcobjdir)/$(relativesrcdir)/results.xml \
-	  --xunit-suite-name=xpcshell \
-	  $(EXTRA_TEST_ARGS) \
-	  $(LIBXUL_DIST)/bin/xpcshell \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-
-xpcshell-tests-remote: DM_TRANS?=adb
-xpcshell-tests-remote:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build \
-	  -I$(topsrcdir)/build/mobile \
-	  $(topsrcdir)/testing/xpcshell/remotexpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  $(EXTRA_TEST_ARGS) \
-	  --dm_trans=$(DM_TRANS) \
-	  --deviceIP=${TEST_DEVICE} \
-	  --objdir=$(DEPTH) \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-
-# Execute a single test, specified in $(SOLO_FILE), but don't automatically
-# start the test. Instead, present the xpcshell prompt so the user can
-# attach a debugger and then start the test.
-check-interactive:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build -I$(DEPTH)/_tests/mozbase/mozinfo \
-	  $(testxpcsrcdir)/runxpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  --test-path=$(SOLO_FILE) \
-	  --testing-modules-dir=$(DEPTH)/_tests/modules \
-	  --profile-name=$(MOZ_APP_NAME) \
-	  --interactive \
-	  $(LIBXUL_DIST)/bin/xpcshell \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-
-# Execute a single test, specified in $(SOLO_FILE)
-check-one:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build -I$(DEPTH)/_tests/mozbase/mozinfo \
-	  $(testxpcsrcdir)/runxpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  --test-path=$(SOLO_FILE) \
-	  --testing-modules-dir=$(DEPTH)/_tests/modules \
-	  --profile-name=$(MOZ_APP_NAME) \
-	  --verbose \
-	  $(EXTRA_TEST_ARGS) \
-	  $(LIBXUL_DIST)/bin/xpcshell \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-
-check-one-remote: DM_TRANS?=adb
-check-one-remote:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build \
-	  -I$(topsrcdir)/build/mobile \
-	  $(testxpcsrcdir)/remotexpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  --test-path=$(SOLO_FILE) \
-	  --profile-name=$(MOZ_APP_NAME) \
-	  --verbose \
-	  $(EXTRA_TEST_ARGS) \
-	  --dm_trans=$(DM_TRANS) \
-	  --deviceIP=${TEST_DEVICE} \
-	  --objdir=$(DEPTH) \
-          --noSetup \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-endif # XPCSHELL_TESTS
+ifndef INCLUDED_TESTS_XPCSHELL_MK #{
+  include $(topsrcdir)/config/makefiles/xpcshell.mk
+endif #}
 
 ifdef CPP_UNIT_TESTS
 
 # Compile the tests to $(DIST)/bin.  Make lots of niceties available by default
 # through TestHarness.h, by modifying the list of includes and the libs against
 # which stuff links.
 CPPSRCS += $(CPP_UNIT_TESTS)
 SIMPLE_PROGRAMS += $(CPP_UNIT_TESTS:.cpp=$(BIN_SUFFIX))
@@ -202,17 +103,17 @@ LIBS += $(XPCOM_GLUE_LDOPTS) $(NSPR_LIBS
 check::
 	@$(EXIT_ON_ERROR) \
 	  for f in $(subst .cpp,$(BIN_SUFFIX),$(CPP_UNIT_TESTS)); do \
 	    XPCOM_DEBUG_BREAK=stack-and-abort $(RUN_TEST_PROGRAM) $(DIST)/bin/$$f; \
 	  done
 
 endif # CPP_UNIT_TESTS
 
-.PHONY: check xpcshell-tests check-interactive check-one
+.PHONY: check
 
 endif # ENABLE_TESTS
 
 
 #
 # Library rules
 #
 # If FORCE_STATIC_LIB is set, build a static library.
@@ -1370,16 +1271,17 @@ ifneq ($(AUTOCFG_JS_EXPORTS),)
 	$(NSINSTALL) -D $@
 
 ifndef NO_DIST_INSTALL
 export:: $(AUTOCFG_JS_EXPORTS) $(FINAL_TARGET)/defaults/autoconfig
 	$(INSTALL) $(IFLAGS1) $^
 endif
 
 endif
+
 ################################################################################
 # Export the elements of $(XPIDLSRCS)
 # generating .h and .xpt files and moving them to the appropriate places.
 
 ifneq ($(XPIDLSRCS),)
 
 export:: $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.h, $(XPIDLSRCS))
 
@@ -1843,116 +1745,22 @@ FORCE:
 
 tags: TAGS
 
 TAGS: $(SUBMAKEFILES) $(CSRCS) $(CPPSRCS) $(wildcard *.h)
 	-etags $(CSRCS) $(CPPSRCS) $(wildcard *.h)
 	$(LOOP_OVER_PARALLEL_DIRS)
 	$(LOOP_OVER_DIRS)
 
-echo-variable-%:
-	@echo "$($*)"
-
-echo-tiers:
-	@echo $(TIERS)
-
-echo-tier-dirs:
-	@$(foreach tier,$(TIERS),echo '$(tier):'; echo '  dirs: $(tier_$(tier)_dirs)'; echo '  staticdirs: $(tier_$(tier)_staticdirs)'; )
-
-echo-dirs:
-	@echo $(DIRS)
-
-echo-module:
-	@echo $(MODULE)
-
-echo-depth-path:
-	@$(topsrcdir)/build/unix/print-depth-path.sh
-
-echo-module-name:
-	@$(topsrcdir)/build/package/rpm/print-module-name.sh
-
-echo-module-filelist:
-	@$(topsrcdir)/build/package/rpm/print-module-filelist.sh
-
-showtargs:
-ifneq (,$(filter $(PROGRAM) $(HOST_PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY),$(TARGETS)))
-	@echo --------------------------------------------------------------------------------
-	@echo "PROGRAM             = $(PROGRAM)"
-	@echo "SIMPLE_PROGRAMS     = $(SIMPLE_PROGRAMS)"
-	@echo "LIBRARY             = $(LIBRARY)"
-	@echo "SHARED_LIBRARY      = $(SHARED_LIBRARY)"
-	@echo "SHARED_LIBRARY_LIBS = $(SHARED_LIBRARY_LIBS)"
-	@echo "LIBS                = $(LIBS)"
-	@echo "DEF_FILE            = $(DEF_FILE)"
-	@echo "IMPORT_LIBRARY      = $(IMPORT_LIBRARY)"
-	@echo "STATIC_LIBS         = $(STATIC_LIBS)"
-	@echo "SHARED_LIBS         = $(SHARED_LIBS)"
-	@echo "EXTRA_DSO_LIBS      = $(EXTRA_DSO_LIBS)"
-	@echo "EXTRA_DSO_LDOPTS    = $(EXTRA_DSO_LDOPTS)"
-	@echo "DEPENDENT_LIBS      = $(DEPENDENT_LIBS)"
-	@echo --------------------------------------------------------------------------------
-endif
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-
-showbuild:
-	@echo "MOZ_BUILD_ROOT     = $(MOZ_BUILD_ROOT)"
-	@echo "MOZ_WIDGET_TOOLKIT = $(MOZ_WIDGET_TOOLKIT)"
-	@echo "CC                 = $(CC)"
-	@echo "CXX                = $(CXX)"
-	@echo "CCC                = $(CCC)"
-	@echo "CPP                = $(CPP)"
-	@echo "LD                 = $(LD)"
-	@echo "AR                 = $(AR)"
-	@echo "IMPLIB             = $(IMPLIB)"
-	@echo "FILTER             = $(FILTER)"
-	@echo "MKSHLIB            = $(MKSHLIB)"
-	@echo "MKCSHLIB           = $(MKCSHLIB)"
-	@echo "RC                 = $(RC)"
-	@echo "MC                 = $(MC)"
-	@echo "CFLAGS             = $(CFLAGS)"
-	@echo "OS_CFLAGS          = $(OS_CFLAGS)"
-	@echo "COMPILE_CFLAGS     = $(COMPILE_CFLAGS)"
-	@echo "CXXFLAGS           = $(CXXFLAGS)"
-	@echo "OS_CXXFLAGS        = $(OS_CXXFLAGS)"
-	@echo "COMPILE_CXXFLAGS   = $(COMPILE_CXXFLAGS)"
-	@echo "COMPILE_CMFLAGS    = $(COMPILE_CMFLAGS)"
-	@echo "COMPILE_CMMFLAGS   = $(COMPILE_CMMFLAGS)"
-	@echo "LDFLAGS            = $(LDFLAGS)"
-	@echo "OS_LDFLAGS         = $(OS_LDFLAGS)"
-	@echo "DSO_LDOPTS         = $(DSO_LDOPTS)"
-	@echo "OS_INCLUDES        = $(OS_INCLUDES)"
-	@echo "OS_LIBS            = $(OS_LIBS)"
-	@echo "EXTRA_LIBS         = $(EXTRA_LIBS)"
-	@echo "BIN_FLAGS          = $(BIN_FLAGS)"
-	@echo "INCLUDES           = $(INCLUDES)"
-	@echo "DEFINES            = $(DEFINES)"
-	@echo "ACDEFINES          = $(ACDEFINES)"
-	@echo "BIN_SUFFIX         = $(BIN_SUFFIX)"
-	@echo "LIB_SUFFIX         = $(LIB_SUFFIX)"
-	@echo "DLL_SUFFIX         = $(DLL_SUFFIX)"
-	@echo "IMPORT_LIB_SUFFIX  = $(IMPORT_LIB_SUFFIX)"
-	@echo "INSTALL            = $(INSTALL)"
-	@echo "VPATH              = $(VPATH)"
-
-showhost:
-	@echo "HOST_CC            = $(HOST_CC)"
-	@echo "HOST_CXX           = $(HOST_CXX)"
-	@echo "HOST_CFLAGS        = $(HOST_CFLAGS)"
-	@echo "HOST_LDFLAGS       = $(HOST_LDFLAGS)"
-	@echo "HOST_LIBS          = $(HOST_LIBS)"
-	@echo "HOST_EXTRA_LIBS    = $(HOST_EXTRA_LIBS)"
-	@echo "HOST_EXTRA_DEPS    = $(HOST_EXTRA_DEPS)"
-	@echo "HOST_PROGRAM       = $(HOST_PROGRAM)"
-	@echo "HOST_OBJS          = $(HOST_OBJS)"
-	@echo "HOST_PROGOBJS      = $(HOST_PROGOBJS)"
-	@echo "HOST_LIBRARY       = $(HOST_LIBRARY)"
-
-showbuildmods::
-	@echo "Module dirs	= $(BUILD_MODULE_DIRS)"
+ifndef INCLUDED_DEBUGMAKE_MK #{
+  ## Only parse when an echo* or show* target is requested
+  ifneq (,$(call isTargetStem,echo,show))
+    include $(topsrcdir)/config/makefiles/debugmake.mk
+  endif #}
+endif #}
 
 documentation:
 	@cd $(DEPTH)
 	$(DOXYGEN) $(DEPTH)/config/doxygen.cfg
 
 ifdef ENABLE_TESTS
 check:: $(SUBMAKEFILES) $(MAKE_DIRS)
 	$(LOOP_OVER_PARALLEL_DIRS)
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -106,16 +106,21 @@ namespace CType {
    * |obj| must be a CType object.
    *
    * This function never returns NULL.
    */
   static JSObject* GetGlobalCTypes(JSContext* cx, JSObject* obj);
 
 }
 
+namespace ABI {
+  bool IsABI(JSObject* obj);
+  static JSBool ToSource(JSContext* cx, unsigned argc, jsval* vp);
+}
+
 namespace PointerType {
   static JSBool Create(JSContext* cx, unsigned argc, jsval* vp);
   static JSBool ConstructData(JSContext* cx, JSObject* obj, unsigned argc, jsval* vp);
 
   static JSBool TargetTypeGetter(JSContext* cx, JSObject* obj, jsid idval,
     jsval* vp);
   static JSBool ContentsGetter(JSContext* cx, JSObject* obj, jsid idval,
     jsval* vp);
@@ -447,16 +452,19 @@ static JSClass sCDataFinalizerClass = {
   (JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)
 
 #define CTYPESCTOR_FLAGS \
   (CTYPESFN_FLAGS | JSFUN_CONSTRUCTOR)
 
 #define CTYPESPROP_FLAGS \
   (JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)
 
+#define CABIFN_FLAGS \
+  (JSPROP_READONLY | JSPROP_PERMANENT)
+
 #define CDATAFN_FLAGS \
   (JSPROP_READONLY | JSPROP_PERMANENT)
 
 #define CDATAFINALIZERFN_FLAGS \
   (JSPROP_READONLY | JSPROP_PERMANENT)
 
 static JSPropertySpec sCTypeProps[] = {
   { "name", 0, CTYPESPROP_FLAGS, CType::NameGetter, NULL },
@@ -468,16 +476,22 @@ static JSPropertySpec sCTypeProps[] = {
 
 static JSFunctionSpec sCTypeFunctions[] = {
   JS_FN("array", CType::CreateArray, 0, CTYPESFN_FLAGS),
   JS_FN("toString", CType::ToString, 0, CTYPESFN_FLAGS),
   JS_FN("toSource", CType::ToSource, 0, CTYPESFN_FLAGS),
   JS_FS_END
 };
 
+static JSFunctionSpec sCABIFunctions[] = {
+  JS_FN("toSource", ABI::ToSource, 0, CABIFN_FLAGS),
+  JS_FN("toString", ABI::ToSource, 0, CABIFN_FLAGS),
+  JS_FS_END
+};
+
 static JSPropertySpec sCDataProps[] = {
   { "value", 0, JSPROP_SHARED | JSPROP_PERMANENT,
     CData::ValueGetter, CData::ValueSetter },
   { 0, 0, 0, NULL, NULL }
 };
 
 static JSFunctionSpec sCDataFunctions[] = {
   JS_FN("address", CData::Address, 0, CDATAFN_FLAGS),
@@ -749,16 +763,31 @@ InitCTypeClass(JSContext* cx, JSObject* 
 
   if (!JS_FreezeObject(cx, ctor) || !JS_FreezeObject(cx, prototype))
     return NULL;
 
   return prototype;
 }
 
 static JSObject*
+InitABIClass(JSContext* cx, JSObject* parent)
+{
+  JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL);
+  
+  if (!obj)
+    return NULL;
+    
+  if (!JS_DefineFunctions(cx, obj, sCABIFunctions))
+    return NULL;
+  
+  return obj;
+}
+
+
+static JSObject*
 InitCDataClass(JSContext* cx, JSObject* parent, JSObject* CTypeProto)
 {
   JSFunction* fun = JS_DefineFunction(cx, parent, "CData", ConstructAbstract, 0,
                       CTYPESCTOR_FLAGS);
   if (!fun)
     return NULL;
 
   JSObject* ctor = JS_GetFunctionObject(fun);
@@ -794,19 +823,20 @@ InitCDataClass(JSContext* cx, JSObject* 
 
   return prototype;
 }
 
 static JSBool
 DefineABIConstant(JSContext* cx,
                   JSObject* parent,
                   const char* name,
-                  ABICode code)
-{
-  JSObject* obj = JS_DefineObject(cx, parent, name, &sCABIClass, NULL,
+                  ABICode code,
+                  JSObject* prototype)
+{
+  JSObject* obj = JS_DefineObject(cx, parent, name, &sCABIClass, prototype,
                     JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
   if (!obj)
     return false;
   JS_SetReservedSlot(obj, SLOT_ABICODE, INT_TO_JSVAL(code));
   return JS_FreezeObject(cx, obj);
 }
 
 // Set up a single type constructor for
@@ -1054,20 +1084,24 @@ InitTypeClasses(JSContext* cx, JSObject*
   // and the special type constructors, so we can access them when constructing
   // instances of those types. 
   AttachProtos(CTypeProto, protos);
   AttachProtos(protos[SLOT_POINTERPROTO], protos);
   AttachProtos(protos[SLOT_ARRAYPROTO], protos);
   AttachProtos(protos[SLOT_STRUCTPROTO], protos);
   AttachProtos(protos[SLOT_FUNCTIONPROTO], protos);
 
+  JSObject* ABIProto = InitABIClass(cx, parent);
+  if (!ABIProto)
+    return false;
+
   // Attach objects representing ABI constants.
-  if (!DefineABIConstant(cx, parent, "default_abi", ABI_DEFAULT) ||
-      !DefineABIConstant(cx, parent, "stdcall_abi", ABI_STDCALL) ||
-      !DefineABIConstant(cx, parent, "winapi_abi", ABI_WINAPI))
+  if (!DefineABIConstant(cx, parent, "default_abi", ABI_DEFAULT, ABIProto) ||
+      !DefineABIConstant(cx, parent, "stdcall_abi", ABI_STDCALL, ABIProto) ||
+      !DefineABIConstant(cx, parent, "winapi_abi", ABI_WINAPI, ABIProto))
     return false;
 
   // Create objects representing the builtin types, and attach them to the
   // ctypes object. Each type object 't' has:
   //   * [[Class]] "CType"
   //   * __proto__ === ctypes.CType.prototype
   //   * A constructor which creates and returns a CData object, containing
   //     binary data of the given type.
@@ -3529,16 +3563,65 @@ CType::GetGlobalCTypes(JSContext* cx, JS
 
   jsval valCTypes = JS_GetReservedSlot(objTypeProto, SLOT_CTYPES);
   JS_ASSERT(!JSVAL_IS_PRIMITIVE(valCTypes));
 
   return JSVAL_TO_OBJECT(valCTypes);
 }
 
 /*******************************************************************************
+** ABI implementation
+*******************************************************************************/
+
+bool
+ABI::IsABI(JSObject* obj)
+{
+  return JS_GetClass(obj) == &sCABIClass;
+}
+
+JSBool
+ABI::ToSource(JSContext* cx, unsigned argc, jsval* vp)
+{
+  if (argc != 0) {
+    JS_ReportError(cx, "toSource takes zero arguments");
+    return JS_FALSE;
+  }
+  
+  JSObject* obj = JS_THIS_OBJECT(cx, vp);
+  if (!obj)
+    return JS_FALSE;
+  if (!ABI::IsABI(obj)) {
+    JS_ReportError(cx, "not an ABI");
+    return JS_FALSE;
+  }
+  
+  JSString* result;
+  switch (GetABICode(obj)) {
+    case ABI_DEFAULT:
+      result = JS_NewStringCopyZ(cx, "ctypes.default_abi");
+      break;
+    case ABI_STDCALL:
+      result = JS_NewStringCopyZ(cx, "ctypes.stdcall_abi");
+      break;
+    case ABI_WINAPI:
+      result = JS_NewStringCopyZ(cx, "ctypes.winapi_abi");
+      break;
+    default:
+      JS_ReportError(cx, "not a valid ABICode");
+      return JS_FALSE;
+  }
+  if (!result)
+    return JS_FALSE;
+  
+  JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(result));
+  return JS_TRUE;
+}
+
+
+/*******************************************************************************
 ** PointerType implementation
 *******************************************************************************/
 
 JSBool
 PointerType::Create(JSContext* cx, unsigned argc, jsval* vp)
 {
   // Construct and return a new PointerType object.
   if (argc != 1) {
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -6027,28 +6027,16 @@ Parser::xmlExpr(JSBool inTag)
 
     MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_IN_XML_EXPR);
     tokenStream.setXMLTagMode(oldflag);
     pn->pn_kid = pn2;
     pn->setOp(inTag ? JSOP_XMLTAGEXPR : JSOP_XMLELTEXPR);
     return pn;
 }
 
-ParseNode *
-Parser::atomNode(ParseNodeKind kind, JSOp op)
-{
-    ParseNode *node = NullaryNode::create(kind, this);
-    if (!node)
-        return NULL;
-    node->setOp(op);
-    const Token &tok = tokenStream.currentToken();
-    node->pn_atom = tok.atom();
-    return node;
-}
-
 /*
  * Parse the productions:
  *
  *      XMLNameExpr:
  *              XMLName XMLNameExpr?
  *              { Expr } XMLNameExpr?
  *
  * Return a PN_LIST, PN_UNARY, or PN_NULLARY according as XMLNameExpr produces
@@ -6547,16 +6535,28 @@ Parser::starOrAtPropertyIdentifier(Token
         reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_SYNTAX_ERROR);
         return NULL;
     }
     return (tt == TOK_AT) ? attributeIdentifier() : qualifiedIdentifier();
 }
 #endif
 
 ParseNode *
+Parser::atomNode(ParseNodeKind kind, JSOp op)
+{
+    ParseNode *node = NullaryNode::create(kind, this);
+    if (!node)
+        return NULL;
+    node->setOp(op);
+    const Token &tok = tokenStream.currentToken();
+    node->pn_atom = tok.atom();
+    return node;
+}
+
+ParseNode *
 Parser::primaryExpr(TokenKind tt, bool afterDoubleDot)
 {
     JS_ASSERT(tokenStream.isCurrentTokenType(tt));
 
     ParseNode *pn, *pn2, *pn3;
     JSOp op;
 
     JS_CHECK_RECURSION(context, return NULL);
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -2,16 +2,17 @@
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsprf.h"
 #include "jsscope.h"
 #include "jsstr.h"
+#include "jsxml.h"
 
 #include "gc/Marking.h"
 #include "methodjit/MethodJIT.h"
 
 #include "jsobjinlines.h"
 #include "jsscopeinlines.h"
 
 #include "vm/String-inl.h"
@@ -44,18 +45,20 @@
  * pointers to be visited. Eventually, this leads to the MarkChildren functions
  * being called. These functions duplicate much of the functionality of
  * scanning functions, but they don't push onto an explicit stack.
  */
 
 namespace js {
 namespace gc {
 
+#if JS_HAS_XML_SUPPORT
 static inline void
 PushMarkStack(GCMarker *gcmarker, JSXML *thing);
+#endif
 
 static inline void
 PushMarkStack(GCMarker *gcmarker, JSObject *thing);
 
 static inline void
 PushMarkStack(GCMarker *gcmarker, JSFunction *thing);
 
 static inline void
@@ -446,24 +449,26 @@ MarkValueUnbarriered(JSTracer *trc, Valu
 
 #define JS_COMPARTMENT_ASSERT(rt, thing)                                \
     JS_ASSERT((thing)->compartment()->isCollecting())
 
 #define JS_COMPARTMENT_ASSERT_STR(rt, thing)                            \
     JS_ASSERT((thing)->compartment()->isCollecting() ||                 \
               (thing)->compartment() == (rt)->atomsCompartment);
 
+#if JS_HAS_XML_SUPPORT
 static void
 PushMarkStack(GCMarker *gcmarker, JSXML *thing)
 {
     JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing);
 
     if (thing->markIfUnmarked(gcmarker->getMarkColor()))
         gcmarker->pushXML(thing);
 }
+#endif
 
 static void
 PushMarkStack(GCMarker *gcmarker, JSObject *thing)
 {
     JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing);
 
     if (thing->markIfUnmarked(gcmarker->getMarkColor()))
         gcmarker->pushObject(thing);
@@ -810,17 +815,17 @@ MarkChildren(JSTracer *trc, types::TypeO
         MarkObject(trc, &type->newScript->fun, "type_new_function");
         MarkShape(trc, &type->newScript->shape, "type_new_shape");
     }
 
     if (type->interpretedFunction)
         MarkObject(trc, &type->interpretedFunction, "type_function");
 }
 
-#ifdef JS_HAS_XML_SUPPORT
+#if JS_HAS_XML_SUPPORT
 static void
 MarkChildren(JSTracer *trc, JSXML *xml)
 {
     js_TraceXML(trc, xml);
 }
 #endif
 
 template<typename T>
@@ -990,20 +995,23 @@ GCMarker::processMarkStackOther(uintptr_
     } else if (tag == SavedValueArrayTag) {
         JS_ASSERT(!(addr & Cell::CellMask));
         JSObject *obj = reinterpret_cast<JSObject *>(addr);
         HeapValue *vp, *end;
         if (restoreValueArray(obj, (void **)&vp, (void **)&end))
             pushValueArray(obj, vp, end);
         else
             pushObject(obj);
-    } else {
+    }
+#if JS_HAS_XML_SUPPORT
+    else {
         JS_ASSERT(tag == XmlTag);
         MarkChildren(this, reinterpret_cast<JSXML *>(addr));
     }
+#endif
 }
 
 inline void
 GCMarker::processMarkStackTop(SliceBudget &budget)
 {
     /*
      * The function uses explicit goto and implements the scanning of the
      * object directly. It allows to eliminate the tail recursion and
--- a/js/src/gc/Marking.h
+++ b/js/src/gc/Marking.h
@@ -211,21 +211,23 @@ Mark(JSTracer *trc, HeapPtr<JSObject> *o
 }
 
 inline void
 Mark(JSTracer *trc, HeapPtr<JSScript> *o, const char *name)
 {
     MarkScript(trc, o, name);
 }
 
+#if JS_HAS_XML_SUPPORT
 inline void
 Mark(JSTracer *trc, HeapPtr<JSXML> *xml, const char *name)
 {
     MarkXML(trc, xml, name);
 }
+#endif
 
 inline bool
 IsMarked(const Value &v)
 {
     if (v.isMarkable())
         return !IsAboutToBeFinalized(v);
     return true;
 }
deleted file mode 100644
--- a/js/src/jit-test/tests/basic/bug529130.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// don't crash
-
-var q = 30;
-
-function var_iter(v) {
-  q--;
-  yield v;
-  if (q > 0) {
-    for each (let ret in var_iter(v)) {
-      var_iter(v);
-      yield ret;
-    }
-  }
-}
-
-for (x in var_iter([1, 2, 3, 4, 5, 6, 7, 8, 9]))
- print(x);
-
-
--- a/js/src/jit-test/tests/debug/Environment-find-01.js
+++ b/js/src/jit-test/tests/debug/Environment-find-01.js
@@ -1,15 +1,15 @@
 // find sees that vars are hoisted out of with statements.
 
 var g = newGlobal('new-compartment');
 var dbg = Debugger(g);
 var hits = 0;
 dbg.onDebuggerStatement = function (frame) {
-    assertEq(frame.environment.find("x").type, "object");
+    assertEq(frame.environment.find("x").type, "with");
     hits++;
 };
 
 assertEq(g.eval("(function () {\n" +
                 "    function g() { x = 1; }\n" +
                 "    with ({x: 2}) {\n" +
                 "        var x;\n" +
                 "        debugger;\n" +
--- a/js/src/jit-test/tests/debug/Environment-type-01.js
+++ b/js/src/jit-test/tests/debug/Environment-type-01.js
@@ -8,18 +8,18 @@ function test(code, expected) {
     g.eval(code);
     assertEq(actual, expected);
 }
 
 test("h();", 'object');
 test("(function (s) { eval(s); })('var v = h();')", 'declarative');
 test("(function (s) { h(); })();", 'declarative');
 test("{let x = 1, y = 2; h();}", 'declarative');
-test("with({x: 1, y: 2}) h();", 'object');
-test("(function (s) { with ({x: 1, y: 2}) h(); })();", 'object');
+test("with({x: 1, y: 2}) h();", 'with');
+test("(function (s) { with ({x: 1, y: 2}) h(); })();", 'with');
 test("let (x = 1) { h(); }", 'declarative');
 test("(let (x = 1) h());", 'declarative');
 test("for (let x = 0; x < 1; x++) h();", 'declarative');
 test("for (let x in h()) ;", 'object');
 test("for (let x in {a:1}) h();", 'declarative');
 test("try { throw new Error; } catch (x) { h(x) }", 'declarative');
 test("'use strict'; eval('var z = 1; h();');", 'declarative');
 test("for (var x in [h(m) for (m in [1])]) ;", 'declarative');
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -1371,17 +1371,17 @@ struct AutoResolving {
     JSContext           *const context;
     JSObject            *const object;
     jsid                const id;
     Kind                const kind;
     AutoResolving       *const link;
     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
-#ifdef JS_HAS_XML_SUPPORT
+#if JS_HAS_XML_SUPPORT
 class AutoXMLRooter : private AutoGCRooter {
   public:
     AutoXMLRooter(JSContext *cx, JSXML *xml
                   JS_GUARD_OBJECT_NOTIFIER_PARAM)
       : AutoGCRooter(cx, XML), xml(xml)
     {
         JS_GUARD_OBJECT_NOTIFIER_INIT;
         JS_ASSERT(xml);
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -197,16 +197,18 @@ GetGlobalForScopeChain(JSContext *cx)
 }
 
 inline GSNCache *
 GetGSNCache(JSContext *cx)
 {
     return &cx->runtime->gsnCache;
 }
 
+#if JS_HAS_XML_SUPPORT
+
 class AutoNamespaceArray : protected AutoGCRooter {
   public:
     AutoNamespaceArray(JSContext *cx)
         : AutoGCRooter(cx, NAMESPACES), context(cx) {
         array.init();
     }
 
     ~AutoNamespaceArray() {
@@ -218,16 +220,18 @@ class AutoNamespaceArray : protected Aut
   private:
     JSContext *context;
     friend void AutoGCRooter::trace(JSTracer *trc);
 
   public:
     JSXMLArray<JSObject> array;
 };
 
+#endif /* JS_HAS_XML_SUPPORT */
+
 template <typename T>
 class AutoPtr
 {
     JSContext *cx;
     T *value;
 
     AutoPtr(const AutoPtr &other) MOZ_DELETE;
 
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2160,26 +2160,28 @@ AutoGCRooter::trace(JSTracer *trc)
         if (desc.attrs & JSPROP_SETTER && desc.setter) {
             JSObject *tmp = JS_FUNC_TO_DATA_PTR(JSObject *, desc.setter);
             MarkObjectRoot(trc, &tmp, "Descriptor::set");
             desc.setter = JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, tmp);
         }
         return;
       }
 
+#if JS_HAS_XML_SUPPORT
       case NAMESPACES: {
         JSXMLArray<JSObject> &array = static_cast<AutoNamespaceArray *>(this)->array;
         MarkObjectRange(trc, array.length, array.vector, "JSXMLArray.vector");
         js_XMLArrayCursorTrace(trc, array.cursors);
         return;
       }
 
       case XML:
         js_TraceXML(trc, static_cast<AutoXMLRooter *>(this)->xml);
         return;
+#endif
 
       case OBJECT:
         if (static_cast<AutoObjectRooter *>(this)->obj)
             MarkObjectRoot(trc, &static_cast<AutoObjectRooter *>(this)->obj,
                            "JS::AutoObjectRooter.obj");
         return;
 
       case ID:
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -59,19 +59,16 @@
 #include "gc/Heap.h"
 #include "gc/Statistics.h"
 #include "js/HashTable.h"
 #include "js/Vector.h"
 #include "js/TemplateLib.h"
 
 struct JSCompartment;
 
-extern void
-js_TraceXML(JSTracer *trc, JSXML* thing);
-
 #if JS_STACK_GROWTH_DIRECTION > 0
 # define JS_CHECK_STACK_SIZE(limit, lval)  ((uintptr_t)(lval) < limit)
 #else
 # define JS_CHECK_STACK_SIZE(limit, lval)  ((uintptr_t)(lval) > limit)
 #endif
 
 namespace js {
 
@@ -919,19 +916,21 @@ struct GCMarker : public JSTracer {
     void pushObject(JSObject *obj) {
         pushTaggedPtr(ObjectTag, obj);
     }
 
     void pushType(types::TypeObject *type) {
         pushTaggedPtr(TypeTag, type);
     }
 
+#if JS_HAS_XML_SUPPORT
     void pushXML(JSXML *xml) {
         pushTaggedPtr(XmlTag, xml);
     }
+#endif
 
     uint32_t getMarkColor() const {
         return color;
     }
 
     /*
      * The only valid color transition during a GC is from black to gray. It is
      * wrong to switch the mark color from gray to black. The reason is that the
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -3630,31 +3630,33 @@ BEGIN_CASE(JSOP_ANYNAME)
     cx->runtime->gcExactScanningEnabled = false;
 
     jsid id;
     if (!js_GetAnyName(cx, &id))
         goto error;
     PUSH_COPY(IdToValue(id));
 }
 END_CASE(JSOP_ANYNAME)
+#endif
 
 BEGIN_CASE(JSOP_QNAMEPART)
 {
     /*
      * We do not JS_ASSERT(!script->strictModeCode) here because JSOP_QNAMEPART
      * is used for __proto__ and (in contexts where we favor JSOP_*ELEM instead
      * of JSOP_*PROP) obj.prop compiled as obj['prop'].
      */
 
     JSAtom *atom;
     LOAD_ATOM(0, atom);
     PUSH_STRING(atom);
 }
 END_CASE(JSOP_QNAMEPART)
 
+#if JS_HAS_XML_SUPPORT
 BEGIN_CASE(JSOP_QNAMECONST)
 {
     JS_ASSERT(!script->strictModeCode);
 
     JSAtom *atom;
     LOAD_ATOM(0, atom);
     Value rval = StringValue(atom);
     Value lval = regs.sp[-1];
@@ -4111,17 +4113,16 @@ END_CASE(JSOP_ARRAYPUSH)
   L_JSOP_SETXMLNAME:
   L_JSOP_BINDXMLNAME:
   L_JSOP_ADDATTRVAL:
   L_JSOP_ADDATTRNAME:
   L_JSOP_TOATTRVAL:
   L_JSOP_TOATTRNAME:
   L_JSOP_QNAME:
   L_JSOP_QNAMECONST:
-  L_JSOP_QNAMEPART:
   L_JSOP_ANYNAME:
   L_JSOP_DEFXMLNS:
 # endif
 
 #endif /* !JS_THREADED_INTERP */
 #if !JS_THREADED_INTERP
           default:
 #endif
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -374,18 +374,23 @@ Snapshot(JSContext *cx, JSObject *obj, u
                     if (state.isNull())
                         break;
                     if (!Enumerate(cx, obj, pobj, id, true, flags, ht, props))
                         return false;
                 }
             }
         }
 
-        if ((flags & JSITER_OWNONLY) || pobj->isXML())
+        if (flags & JSITER_OWNONLY)
             break;
+
+#if JS_HAS_XML_SUPPORT
+        if (pobj->isXML())
+            break;
+#endif
     } while ((pobj = pobj->getProto()) != NULL);
 
 #ifdef JS_MORE_DETERMINISTIC
 
     /*
      * In some cases the enumeration order for an object depends on the
      * execution mode (interpreter vs. JIT), especially for native objects
      * with a class enumerate hook (where resolving a property changes the
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -2396,20 +2396,22 @@ obj_create(JSContext *cx, unsigned argc,
             return false;
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNEXPECTED_TYPE,
                              bytes, "not an object or null");
         JS_free(cx, bytes);
         return false;
     }
 
     JSObject *proto = v.toObjectOrNull();
+#if JS_HAS_XML_SUPPORT
     if (proto && proto->isXML()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_XML_PROTO_FORBIDDEN);
         return false;
     }
+#endif
 
     /*
      * Use the callee's global as the parent of the new object to avoid dynamic
      * scoping (i.e., using the caller's global).
      */
     RootedVarObject obj(cx);
     obj = NewObjectWithGivenProto(cx, &ObjectClass, proto, &args.callee().global());
     if (!obj)
@@ -4126,20 +4128,22 @@ static JSObjectOp lazy_prototype_init[JS
 namespace js {
 
 bool
 SetProto(JSContext *cx, HandleObject obj, HandleObject proto, bool checkForCycles)
 {
     JS_ASSERT_IF(!checkForCycles, obj != proto);
     JS_ASSERT(obj->isExtensible());
 
+#if JS_HAS_XML_SUPPORT
     if (proto && proto->isXML()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_XML_PROTO_FORBIDDEN);
         return false;
     }
+#endif
 
     /*
      * Regenerate shapes for all of the scopes along the old prototype chain,
      * in case any entries were filled by looking up through obj. Stop when a
      * non-native object is found, prototype lookups will not be cached across
      * these.
      *
      * How this shape change is done is very delicate; the change can be made
@@ -5597,17 +5601,19 @@ MaybeCallMethod(JSContext *cx, HandleObj
     }
     return Invoke(cx, ObjectValue(*obj), *vp, 0, NULL, vp);
 }
 
 JSBool
 DefaultValue(JSContext *cx, HandleObject obj, JSType hint, Value *vp)
 {
     JS_ASSERT(hint == JSTYPE_NUMBER || hint == JSTYPE_STRING || hint == JSTYPE_VOID);
+#if JS_HAS_XML_SUPPORT
     JS_ASSERT(!obj->isXML());
+#endif
 
     Class *clasp = obj->getClass();
     if (hint == JSTYPE_STRING) {
         /* Optimize (new String(...)).toString(). */
         if (clasp == &StringClass &&
             ClassMethodIsNative(cx, obj,
                                  &StringClass,
                                  RootedVarId(cx, NameToId(cx->runtime->atomState.toStringAtom)),
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -920,30 +920,32 @@ struct JSObject : public js::ObjectImpl
     inline bool isDataView() const;
     inline bool isDate() const;
     inline bool isElementIterator() const;
     inline bool isError() const;
     inline bool isFunction() const;
     inline bool isGenerator() const;
     inline bool isGlobal() const;
     inline bool isIterator() const;
-    inline bool isNamespace() const;
     inline bool isObject() const;
-    inline bool isQName() const;
     inline bool isPrimitive() const;
     inline bool isProxy() const;
     inline bool isRegExp() const;
     inline bool isRegExpStatics() const;
     inline bool isScope() const;
     inline bool isScript() const;
     inline bool isStopIteration() const;
     inline bool isTypedArray() const;
     inline bool isWeakMap() const;
+#if JS_HAS_XML_SUPPORT
+    inline bool isNamespace() const;
+    inline bool isQName() const;
     inline bool isXML() const;
     inline bool isXMLId() const;
+#endif
 
     /* Subtypes of ScopeObject. */
     inline bool isBlock() const;
     inline bool isCall() const;
     inline bool isDeclEnv() const;
     inline bool isNestedScope() const;
     inline bool isWith() const;
     inline bool isClonedBlock() const;
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -575,16 +575,18 @@ JSObject::getNativeIterator() const
 }
 
 inline void
 JSObject::setNativeIterator(js::NativeIterator *ni)
 {
     setPrivate(ni);
 }
 
+#if JS_HAS_XML_SUPPORT
+
 inline JSLinearString *
 JSObject::getNamePrefix() const
 {
     JS_ASSERT(isNamespace() || isQName());
     const js::Value &v = getSlot(JSSLOT_NAME_PREFIX);
     return !v.isUndefined() ? &v.toString()->asLinear() : NULL;
 }
 
@@ -662,16 +664,18 @@ JSObject::getQNameLocalNameVal() const
 
 inline void
 JSObject::setQNameLocalName(JSAtom *name)
 {
     JS_ASSERT(isQName());
     setSlot(JSSLOT_QNAME_LOCAL_NAME, name ? js::StringValue(name) : js::UndefinedValue());
 }
 
+#endif
+
 inline bool
 JSObject::setSingletonType(JSContext *cx)
 {
     if (!cx->typeInferenceEnabled())
         return true;
 
     JS_ASSERT(!hasLazyType());
     JS_ASSERT_IF(getProto(), type() == getProto()->getNewType(cx, NULL));
@@ -794,32 +798,34 @@ inline bool JSObject::isDataView() const
 inline bool JSObject::isDate() const { return hasClass(&js::DateClass); }
 inline bool JSObject::isDeclEnv() const { return hasClass(&js::DeclEnvClass); }
 inline bool JSObject::isElementIterator() const { return hasClass(&js::ElementIteratorClass); }
 inline bool JSObject::isError() const { return hasClass(&js::ErrorClass); }
 inline bool JSObject::isFunction() const { return hasClass(&js::FunctionClass); }
 inline bool JSObject::isFunctionProxy() const { return hasClass(&js::FunctionProxyClass); }
 inline bool JSObject::isGenerator() const { return hasClass(&js::GeneratorClass); }
 inline bool JSObject::isIterator() const { return hasClass(&js::IteratorClass); }
-inline bool JSObject::isNamespace() const { return hasClass(&js::NamespaceClass); }
 inline bool JSObject::isNestedScope() const { return isBlock() || isWith(); }
 inline bool JSObject::isNormalArguments() const { return hasClass(&js::NormalArgumentsObjectClass); }
 inline bool JSObject::isNumber() const { return hasClass(&js::NumberClass); }
 inline bool JSObject::isObject() const { return hasClass(&js::ObjectClass); }
 inline bool JSObject::isPrimitive() const { return isNumber() || isString() || isBoolean(); }
 inline bool JSObject::isRegExp() const { return hasClass(&js::RegExpClass); }
 inline bool JSObject::isRegExpStatics() const { return hasClass(&js::RegExpStaticsClass); }
 inline bool JSObject::isScope() const { return isCall() || isDeclEnv() || isNestedScope(); }
 inline bool JSObject::isStaticBlock() const { return isBlock() && !getProto(); }
 inline bool JSObject::isStopIteration() const { return hasClass(&js::StopIterationClass); }
 inline bool JSObject::isStrictArguments() const { return hasClass(&js::StrictArgumentsObjectClass); }
 inline bool JSObject::isString() const { return hasClass(&js::StringClass); }
 inline bool JSObject::isTypedArray() const { return IsTypedArrayClass(getClass()); }
 inline bool JSObject::isWeakMap() const { return hasClass(&js::WeakMapClass); }
 inline bool JSObject::isWith() const { return hasClass(&js::WithClass); }
+
+#if JS_HAS_XML_SUPPORT
+inline bool JSObject::isNamespace() const { return hasClass(&js::NamespaceClass); }
 inline bool JSObject::isXML() const { return hasClass(&js::XMLClass); }
 
 inline bool
 JSObject::isXMLId() const
 {
     return hasClass(&js::QNameClass)
         || hasClass(&js::AttributeNameClass)
         || hasClass(&js::AnyNameClass);
@@ -827,16 +833,17 @@ JSObject::isXMLId() const
 
 inline bool
 JSObject::isQName() const
 {
     return hasClass(&js::QNameClass)
         || hasClass(&js::AttributeNameClass)
         || hasClass(&js::AnyNameClass);
 }
+#endif /* JS_HAS_XML_SUPPORT */
 
 /* static */ inline JSObject *
 JSObject::create(JSContext *cx, js::gc::AllocKind kind,
                  js::HandleShape shape, js::HandleTypeObject type, js::HeapSlot *slots)
 {
     /*
      * Callers must use dynamicSlotsCount to size the initial slot array of the
      * object. We can't check the allocated capacity of the dynamic slots, but
@@ -850,20 +857,22 @@ JSObject::create(JSContext *cx, js::gc::
     if (!obj)
         return NULL;
 
     obj->shape_.init(shape);
     obj->type_.init(type);
     obj->slots = slots;
     obj->elements = js::emptyObjectElements;
 
-    if (shape->getObjectClass()->hasPrivate())
+    const js::Class *clasp = shape->getObjectClass();
+    if (clasp->hasPrivate())
         obj->privateRef(shape->numFixedSlots()) = NULL;
 
-    if (size_t span = shape->slotSpan())
+    size_t span = shape->slotSpan();
+    if (span && clasp != &js::ArrayBufferClass)
         obj->initializeSlotRange(0, span);
 
     return obj;
 }
 
 /* static */ inline JSObject *
 JSObject::createDenseArray(JSContext *cx, js::gc::AllocKind kind,
                            js::HandleShape shape, js::HandleTypeObject type,
@@ -1219,28 +1228,35 @@ OBJ_TO_INNER_OBJECT(JSContext *cx, JSObj
 
 inline void
 OBJ_TO_OUTER_OBJECT(JSContext *cx, JSObject *&obj)
 {
     if (JSObjectOp op = obj->getClass()->ext.outerObject)
         obj = op(cx, obj);
 }
 
+#if JS_HAS_XML_SUPPORT
 /*
  * Methods to test whether an object or a value is of type "xml" (per typeof).
  */
 
-#define VALUE_IS_XML(v)      (!JSVAL_IS_PRIMITIVE(v) && JSVAL_TO_OBJECT(v)->isXML())
+#define VALUE_IS_XML(v)     ((v).isObject() && (v).toObject().isXML())
 
 static inline bool
 IsXML(const js::Value &v)
 {
     return v.isObject() && v.toObject().isXML();
 }
 
+#else
+
+#define VALUE_IS_XML(v)     false
+
+#endif /* JS_HAS_XML_SUPPORT */
+
 static inline bool
 IsStopIteration(const js::Value &v)
 {
     return v.isObject() && v.toObject().isStopIteration();
 }
 
 /* ES5 9.1 ToPrimitive(input). */
 static JS_ALWAYS_INLINE bool
@@ -1590,20 +1606,20 @@ IsObjectWithClass(const Value &v, ESClas
     if (!v.isObject())
         return false;
     return ObjectClassIs(v.toObject(), classValue, cx);
 }
 
 static JS_ALWAYS_INLINE bool
 ValueIsSpecial(JSObject *obj, Value *propval, SpecialId *sidp, JSContext *cx)
 {
+#if JS_HAS_XML_SUPPORT
     if (!propval->isObject())
         return false;
 
-#if JS_HAS_XML_SUPPORT
     if (obj->isXML()) {
         *sidp = SpecialId(propval->toObject());
         return true;
     }
 
     JSObject &propobj = propval->toObject();
     JSAtom *name;
     if (propobj.isQName() && GetLocalNameFromFunctionQName(&propobj, &name, cx)) {
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -386,17 +386,17 @@ PreprocessValue(JSContext *cx, JSObject 
  * gauntlet will result in Str returning |undefined|.  This function is used to
  * properly omit properties resulting in such values when stringifying objects,
  * while properly stringifying such properties as null when they're encountered
  * in arrays.
  */
 static inline bool
 IsFilteredValue(const Value &v)
 {
-    return v.isUndefined() || js_IsCallable(v) || (v.isObject() && v.toObject().isXML());
+    return v.isUndefined() || js_IsCallable(v) || VALUE_IS_XML(v);
 }
 
 /* ES5 15.12.3 JO. */
 static JSBool
 JO(JSContext *cx, HandleObject obj, StringifyContext *scx)
 {
     /*
      * This method implements the JO algorithm in ES5 15.12.3, but:
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -1488,17 +1488,21 @@ PopOffPrec(SprintStack *ss, uint8_t prec
     /* ss->top points to the next free slot; be paranoid about underflow. */
     top = ss->top;
     JS_ASSERT(top != 0);
     if (top == 0)
         return 0;
 
     ss->top = --top;
     off = GetOff(ss, top);
-    topcs = &js_CodeSpec[ss->opcodes[top]];
+
+    int op = ss->opcodes[top];
+    if (op >= JSOP_LIMIT)
+        op = JSOP_NOP;
+    topcs = &js_CodeSpec[op];
 
     jsbytecode *pc = ss->bytecodes[top];
     if (ppc)
         *ppc = pc;
 
     if (topcs->prec != 0 && topcs->prec < prec) {
         ss->offsets[top] = off - 2;
         ss->sprinter.setOffset(off - 2);
@@ -2566,18 +2570,19 @@ Decompile(SprintStack *ss, jsbytecode *p
     const char *lval, *rval, *xval, *fmt, *token;
     unsigned nuses;
     int i, argc;
     JSAtom *atom;
     JSObject *obj;
     JSFunction *fun = NULL; /* init to shut GCC up */
     JSString *str;
     JSBool ok;
+    JSBool foreach;
 #if JS_HAS_XML_SUPPORT
-    JSBool foreach, inXML, quoteAttr;
+    JSBool inXML, quoteAttr;
 #else
 #define inXML JS_FALSE
 #endif
     jsval val;
 
     static const char exception_cookie[] = "/*EXCEPTION*/";
     static const char retsub_pc_cookie[] = "/*RETSUB_PC*/";
     static const char forelem_cookie[]   = "/*FORELEM*/";
@@ -2673,18 +2678,19 @@ Decompile(SprintStack *ss, jsbytecode *p
     startpc = pc;
     endpc = (nb < 0) ? jp->script->code + jp->script->length : pc + nb;
     tail = -1;
     todo = -2;                  /* NB: different from Sprint() error return. */
     saveop = JSOP_NOP;
     sn = NULL;
     rval = NULL;
     bool forOf = false;
+    foreach = false;
 #if JS_HAS_XML_SUPPORT
-    foreach = inXML = quoteAttr = JS_FALSE;
+    inXML = quoteAttr = false;
 #endif
 
     while (nb < 0 || pc < endpc) {
         /*
          * Move saveop to lastop so prefixed bytecodes can take special action
          * while sharing maximal code.  Set op and saveop to the new bytecode,
          * use op in POP_STR to trigger automatic parenthesization, but push
          * saveop at the bottom of the loop if this op pushes.  Thus op may be
@@ -3779,22 +3785,22 @@ Decompile(SprintStack *ss, jsbytecode *p
               case JSOP_GOTO:
                 sn = js_GetSrcNote(jp->script, pc);
                 switch (sn ? SN_TYPE(sn) : SRC_NULL) {
                   case SRC_FOR_IN:
                     /*
                      * The bytecode around pc looks like this:
                      *     <<RHS>>
                      *     iter
-                     * pc: goto/gotox C         [src_for_in(B, D)]
+                     * pc: goto C               [src_for_in(B, D)]
                      *  A: <<LHS = iternext>>
                      *  B: pop                  [maybe a src_decl_var/let]
                      *     <<S>>
                      *  C: moreiter
-                     *     ifne/ifnex A
+                     *     ifne A
                      *     enditer
                      *  D: ...
                      *
                      * In an array comprehension or generator expression, we
                      * construct the for-head and store it in the slot pushed
                      * by JSOP_ITER, then recurse to decompile S. The
                      * culminating JSOP_ARRAYPUSH or JSOP_YIELD instruction
                      * (which S must contain, by construction) glues all the
@@ -5193,27 +5199,31 @@ Decompile(SprintStack *ss, jsbytecode *p
               case JSOP_ANYNAME:
                 if (pc[JSOP_ANYNAME_LENGTH] == JSOP_TOATTRNAME) {
                     len += JSOP_TOATTRNAME_LENGTH;
                     todo = ss->sprinter.put("@*", 2);
                 } else {
                     todo = ss->sprinter.put("*", 1);
                 }
                 break;
+#endif
 
               case JSOP_QNAMEPART:
                 LOAD_ATOM(0);
+#if JS_HAS_XML_SUPPORT
                 if (pc[JSOP_QNAMEPART_LENGTH] == JSOP_TOATTRNAME) {
                     saveop = JSOP_TOATTRNAME;
                     len += JSOP_TOATTRNAME_LENGTH;
                     lval = "@";
                     goto do_qname;
                 }
+#endif
                 goto do_name;
 
+#if JS_HAS_XML_SUPPORT
               case JSOP_QNAMECONST:
                 LOAD_ATOM(0);
                 rval = QuoteString(&ss->sprinter, atom, 0);
                 if (!rval)
                     return NULL;
                 ss->sprinter.setOffset(rval);
                 lval = POP_STR();
                 todo = Sprint(&ss->sprinter, "%s::%s", lval, rval);
--- a/js/src/jsprvtd.h
+++ b/js/src/jsprvtd.h
@@ -90,17 +90,20 @@ typedef struct JSTryNote            JSTr
 
 /* Friend "Advanced API" typedefs. */
 typedef struct JSAtomState          JSAtomState;
 typedef struct JSCodeSpec           JSCodeSpec;
 typedef struct JSPrinter            JSPrinter;
 typedef struct JSStackHeader        JSStackHeader;
 typedef struct JSSubString          JSSubString;
 typedef struct JSSpecializedNative  JSSpecializedNative;
+
+#if JS_HAS_XML_SUPPORT
 typedef struct JSXML                JSXML;
+#endif
 
 /*
  * Template declarations.
  *
  * jsprvtd.h can be included in both C and C++ translation units. For C++, it
  * may possibly be wrapped in an extern "C" block which does not agree with
  * templates.
  */
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -2491,17 +2491,17 @@ ASTSerializer::expression(ParseNode *pn,
         Value expr;
         return expression(pn->pn_kid, &expr) &&
                builder.unaryExpression(op, expr, &pn->pn_pos, dst);
       }
 
       case PNK_NEW:
       case PNK_LP:
       {
-#ifdef JS_HAS_GENERATOR_EXPRS
+#if JS_HAS_GENERATOR_EXPRS
         if (pn->isGeneratorExpr())
             return generatorExpression(pn->generatorExpr(), dst);
 #endif
 
         ParseNode *next = pn->pn_head;
 
         Value callee;
         if (!expression(next, &callee))
@@ -2606,17 +2606,17 @@ ASTSerializer::expression(ParseNode *pn,
         LOCAL_ASSERT(pn->pn_count == 1);
         LOCAL_ASSERT(pn->pn_head->isKind(PNK_LEXICALSCOPE));
 
         return comprehension(pn->pn_head->pn_expr, dst);
 
       case PNK_LET:
         return let(pn, true, dst);
 
-#ifdef JS_HAS_XML_SUPPORT
+#if JS_HAS_XML_SUPPORT
       case PNK_XMLUNARY:
         JS_ASSERT(pn->isOp(JSOP_XMLNAME) ||
                   pn->isOp(JSOP_SETXMLNAME) ||
                   pn->isOp(JSOP_BINDXMLNAME));
         return expression(pn->pn_kid, dst);
 
       case PNK_ANYNAME:
         return builder.xmlAnyName(&pn->pn_pos, dst);
@@ -2680,17 +2680,17 @@ ASTSerializer::expression(ParseNode *pn,
     }
 }
 
 bool
 ASTSerializer::xml(ParseNode *pn, Value *dst)
 {
     JS_CHECK_RECURSION(cx, return false);
     switch (pn->getKind()) {
-#ifdef JS_HAS_XML_SUPPORT
+#if JS_HAS_XML_SUPPORT
       case PNK_XMLCURLYEXPR:
       {
         Value expr;
         return expression(pn->pn_kid, &expr) &&
                builder.xmlEscapeExpression(expr, &pn->pn_pos, dst);
       }
 
       case PNK_XMLELEM:
@@ -2944,24 +2944,24 @@ ASTSerializer::identifier(ParseNode *pn,
 }
 
 bool
 ASTSerializer::function(ParseNode *pn, ASTType type, Value *dst)
 {
     JSFunction *func = (JSFunction *)pn->pn_funbox->object;
 
     bool isGenerator =
-#ifdef JS_HAS_GENERATORS
+#if JS_HAS_GENERATORS
         pn->pn_funbox->tcflags & TCF_FUN_IS_GENERATOR;
 #else
         false;
 #endif
 
     bool isExpression =
-#ifdef JS_HAS_EXPR_CLOSURES
+#if JS_HAS_EXPR_CLOSURES
         func->flags & JSFUN_EXPR_CLOSURE;
 #else
         false;
 #endif
 
     Value id;
     if (!optIdentifier(func->atom, NULL, &id))
         return false;
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -408,20 +408,23 @@ AbstractWrapper::leave(JSContext *cx, JS
 }
 
 Wrapper Wrapper::singleton((unsigned)0);
 
 JSObject *
 Wrapper::New(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent, Wrapper *handler)
 {
     JS_ASSERT(parent);
+#if JS_HAS_XML_SUPPORT
     if (obj->isXML()) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_WRAP_XML_OBJECT);
         return NULL;
     }
+#endif
+
     return NewProxyObject(cx, handler, ObjectValue(*obj), proto, parent,
                           obj->isCallable() ? obj : NULL, NULL);
 }
 
 /* Compartments. */
 
 namespace js {
 
--- a/js/src/jsxml.cpp
+++ b/js/src/jsxml.cpp
@@ -32,18 +32,21 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#include <stddef.h>
 #include "jsversion.h"
 
+size_t sE4XObjectsCreated = 0;
+
 #if JS_HAS_XML_SUPPORT
 
 #include <math.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "mozilla/Util.h"
 
@@ -169,18 +172,16 @@ IsDeclared(const JSObject *obj)
 
 static JSBool
 xml_isXMLName(JSContext *cx, unsigned argc, jsval *vp)
 {
     *vp = BOOLEAN_TO_JSVAL(js_IsXMLName(cx, argc ? vp[2] : JSVAL_VOID));
     return JS_TRUE;
 }
 
-size_t sE4XObjectsCreated = 0;
-
 /*
  * This wrapper is needed because NewBuiltinClassInstance doesn't
  * call the constructor, and we need a place to set the
  * HAS_EQUALITY bit.
  */
 static inline JSObject *
 NewBuiltinClassInstanceXML(JSContext *cx, Class *clasp)
 {
--- a/js/src/jsxml.h
+++ b/js/src/jsxml.h
@@ -40,16 +40,18 @@
 #define jsxml_h___
 
 #include "jspubtd.h"
 #include "jsobj.h"
 
 #include "gc/Barrier.h"
 #include "gc/Heap.h"
 
+#if JS_HAS_XML_SUPPORT
+
 extern const char js_AnyName_str[];
 extern const char js_AttributeName_str[];
 extern const char js_isXMLName_str[];
 extern const char js_XMLList_str[];
 
 extern const char js_amp_entity_str[];
 extern const char js_gt_entity_str[];
 extern const char js_lt_entity_str[];
@@ -327,9 +329,11 @@ js_ConcatenateXML(JSContext *cx, JSObjec
 
 namespace js {
 
 extern bool
 GetLocalNameFromFunctionQName(JSObject *qn, JSAtom **namep, JSContext *cx);
 
 } /* namespace js */
 
+#endif /* JS_HAS_XML_SUPPORT */
+
 #endif /* jsxml_h___ */
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -2135,16 +2135,18 @@ DumpStack(JSContext *cx, unsigned argc, 
         Value v;
         if (iter.isNonEvalFunctionFrame() || iter.isNativeCall()) {
             v = iter.calleev();
         } else if (iter.isEvalFrame()) {
             v = StringValue(evalStr);
         } else {
             v = StringValue(globalStr);
         }
+        if (!JS_WrapValue(cx, &v))
+            return false;
         if (!JS_SetElement(cx, arr, index, &v))
             return false;
     }
 
     JS_SET_RVAL(cx, vp, ObjectValue(*arr));
     return true;
 }
 
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -4254,16 +4254,18 @@ static JSBool
 DebuggerEnv_getType(JSContext *cx, unsigned argc, Value *vp)
 {
     THIS_DEBUGENV(cx, argc, vp, "get type", args, envobj, env);
 
     /* Don't bother switching compartments just to check env's class. */
     const char *s;
     if (env->isCall() || env->isBlock() || env->isDeclEnv())
         s = "declarative";
+    else if (env->isWith())
+        s = "with";
     else
         s = "object";
 
     JSAtom *str = js_Atomize(cx, s, strlen(s), InternAtom, NormalEncoding);
     if (!str)
         return false;
     args.rval().setString(str);
     return true;
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -192,20 +192,21 @@ public:
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIPresShell_base, NS_IPRESSHELL_IID)
 
 class nsIPresShell : public nsIPresShell_base
 {
 protected:
   typedef mozilla::layers::LayerManager LayerManager;
 
-  enum {
+  enum eRenderFlag {
     STATE_IGNORING_VIEWPORT_SCROLLING = 0x1,
     STATE_USING_DISPLAYPORT = 0x2
   };
+  typedef PRUint8 RenderFlags; // for storing the above flags
 
 public:
   virtual NS_HIDDEN_(nsresult) Init(nsIDocument* aDocument,
                                    nsPresContext* aPresContext,
                                    nsIViewManager* aViewManager,
                                    nsStyleSet* aStyleSet,
                                    nsCompatibility aCompatMode) = 0;
 
@@ -589,17 +590,17 @@ public:
 
   enum WhenToScroll {
     SCROLL_ALWAYS,
     SCROLL_IF_NOT_VISIBLE,
     SCROLL_IF_NOT_FULLY_VISIBLE
   };
   typedef struct ScrollAxis {
     PRInt16 mWhereToScroll;
-    WhenToScroll mWhenToScroll;
+    WhenToScroll mWhenToScroll : 16;
   /**
    * @param aWhere: Either a percentage or a special value.
    *                nsIPresShell defines:
    *                * (Default) SCROLL_MINIMUM = -1: The visible area is
    *                scrolled to show the entire frame. If the frame is too
    *                large, the top and left edges are given precedence.
    *                * SCROLL_TOP = 0: The frame's upper edge is aligned with the
    *                top edge of the visible area.
@@ -1328,17 +1329,17 @@ public:
 
 protected:
   friend class nsRefreshDriver;
 
   // IMPORTANT: The ownership implicit in the following member variables
   // has been explicitly checked.  If you add any members to this class,
   // please make the ownership explicit (pinkerton, scc).
 
-  // these are the same Document and PresContext owned by the DocViewer.
+  // These are the same Document and PresContext owned by the DocViewer.
   // we must share ownership.
   nsIDocument*              mDocument;      // [STRONG]
   nsPresContext*            mPresContext;   // [STRONG]
   nsStyleSet*               mStyleSet;      // [OWNS]
   nsCSSFrameConstructor*    mFrameConstructor; // [OWNS]
   nsIViewManager*           mViewManager;   // [WEAK] docViewer owns it so I don't have to
   nsPresArena               mFrameArena;
   nsFrameSelection*         mSelection;
@@ -1348,65 +1349,65 @@ protected:
   nsWeakPtr                 mForwardingContainer;
 
 #ifdef NS_DEBUG
   nsIFrame*                 mDrawEventTargetFrame;
   // Ensure that every allocation from the PresArena is eventually freed.
   PRUint32                  mPresArenaAllocCount;
 #endif
 
-  // Count of the number of times this presshell has been painted to
-  // a window
+  // Count of the number of times this presshell has been painted to a window.
   PRUint64                  mPaintCount;
 
-  PRInt16                   mSelectionFlags;
-
-  bool                      mStylesHaveChanged;
-  bool                      mDidInitialReflow;
-  bool                      mIsDestroying;
-  bool                      mIsReflowing;
-  bool                      mPaintingSuppressed;  // For all documents we initially lock down painting.
-  bool                      mIsThemeSupportDisabled;  // Whether or not form controls should use nsITheme in this shell.
-  bool                      mIsActive;
-  bool                      mFrozen;
-
-  bool                      mIsFirstPaint;
-
-  bool                      mObservesMutationsForPrint;
-
-  bool                      mReflowScheduled; // If true, we have a reflow
-                                              // scheduled. Guaranteed to be
-                                              // false if mReflowContinueTimer
-                                              // is non-null.
-
-  bool                      mSuppressInterruptibleReflows;
-
-  bool                      mScrollPositionClampingScrollPortSizeSet;
+  nsSize                    mScrollPositionClampingScrollPortSize;
 
   // A list of weak frames. This is a pointer to the last item in the list.
   nsWeakFrame*              mWeakFrames;
 
   // Most recent canvas background color.
   nscolor                   mCanvasBackgroundColor;
 
+  // Used to force allocation and rendering of proportionally more or
+  // less pixels in the given dimension.
+  float                     mXResolution;
+  float                     mYResolution;
+
+  PRInt16                   mSelectionFlags;
+
   // Flags controlling how our document is rendered.  These persist
   // between paints and so are tied with retained layer pixels.
   // PresShell flushes retained layers when the rendering state
   // changes in a way that prevents us from being able to (usefully)
   // re-use old pixels.
-  PRUint32                  mRenderFlags;
+  RenderFlags               mRenderFlags;
+
+  bool                      mStylesHaveChanged : 1;
+  bool                      mDidInitialReflow : 1;
+  bool                      mIsDestroying : 1;
+  bool                      mIsReflowing : 1;
+
+  // For all documents we initially lock down painting.
+  bool                      mPaintingSuppressed : 1;
+
+  // Whether or not form controls should use nsITheme in this shell.
+  bool                      mIsThemeSupportDisabled : 1;
 
-  // Used to force allocation and rendering of proportionally more or
-  // less pixels in the given dimension.
-  float                     mXResolution;
-  float                     mYResolution;
+  bool                      mIsActive : 1;
+  bool                      mFrozen : 1;
+  bool                      mIsFirstPaint : 1;
+  bool                      mObservesMutationsForPrint : 1;
 
-  nsSize                    mScrollPositionClampingScrollPortSize;
+  // If true, we have a reflow scheduled. Guaranteed to be false if
+  // mReflowContinueTimer is non-null.
+  bool                      mReflowScheduled : 1;
 
-  static nsIContent* gKeyDownTarget;
+  bool                      mSuppressInterruptibleReflows : 1;
+  bool                      mScrollPositionClampingScrollPortSizeSet : 1;
+
+  static nsIContent*        gKeyDownTarget;
 };
 
 /**
  * Create a new empty presentation shell. Upon success, call Init
  * before attempting to use the shell.
  */
 nsresult
 NS_NewPresShell(nsIPresShell** aInstancePtrResult);
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -86,16 +86,17 @@
 #include "nsTArray.h"
 #include "nsCOMArray.h"
 #include "nsHashtable.h"
 #include "nsContainerFrame.h"
 #include "nsDOMEvent.h"
 #include "nsHTMLParts.h"
 #include "nsISelection.h"
 #include "nsISelectionPrivate.h"
+#include "nsTypedSelection.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"
@@ -229,28 +230,16 @@ using namespace mozilla::layers;
 
 CapturingContentInfo nsIPresShell::gCaptureInfo =
   { false /* mAllowed */, false /* mPointerLock */, false /* mRetargetToElement */,
     false /* mPreventDrag */, nsnull /* mContent */ };
 nsIContent* nsIPresShell::gKeyDownTarget;
 nsInterfaceHashtable<nsUint32HashKey, nsIDOMTouch> nsIPresShell::gCaptureTouchList;
 bool nsIPresShell::gPreventMouseEvents = false;
 
-static PRUint32
-ChangeFlag(PRUint32 aFlags, bool aOnOff, PRUint32 aFlag)
-{
-  PRUint32 flags;
-  if (aOnOff) {
-    flags = (aFlags | aFlag);
-  } else {
-    flags = (aFlag & ~aFlag);
-  }
-  return flags;
-}
-
 // convert a color value to a string, in the CSS format #RRGGBB
 // *  - initially created for bugs 31816, 20760, 22963
 static void ColorToString(nscolor aColor, nsAutoString &aString);
 
 // RangePaintInfo is used to paint ranges to offscreen buffers
 struct RangePaintInfo {
   nsRefPtr<nsRange> mRange;
   nsDisplayListBuilder mBuilder;
@@ -860,19 +849,16 @@ PresShell::Init(nsIDocument* aDocument,
       os->AddObserver(this, "agent-sheet-removed", false);
       os->AddObserver(this, "user-sheet-removed", false);
 #ifdef MOZ_XUL
       os->AddObserver(this, "chrome-flush-skin-caches", false);
 #endif
     }
   }
 
-  // cache the drag service so we can check it during reflows
-  mDragService = do_GetService("@mozilla.org/widget/dragservice;1");
-
 #ifdef MOZ_REFLOW_PERF
     if (mReflowCountMgr) {
       bool paintFrameCounts =
         Preferences::GetBool("layout.reflow.showframecounts");
 
       bool dumpFrameCounts =
         Preferences::GetBool("layout.reflow.dumpframecounts");
 
@@ -923,17 +909,20 @@ PresShell::Destroy()
 #endif // ACCESSIBILITY
 
   MaybeReleaseCapturingContent();
 
   if (gKeyDownTarget && gKeyDownTarget->OwnerDoc() == mDocument) {
     NS_RELEASE(gKeyDownTarget);
   }
 
-  mContentToScrollTo = nsnull;
+  if (mContentToScrollTo) {
+    mContentToScrollTo->DeleteProperty(nsGkAtoms::scrolling);
+    mContentToScrollTo = nsnull;
+  }
 
   if (mPresContext) {
     // We need to notify the destroying the nsPresContext to ESM for
     // suppressing to use from ESM.
     mPresContext->EventStateManager()->NotifyDestroyPresContext(mPresContext);
   }
 
   {
@@ -3105,16 +3094,17 @@ static void ScrollToShowRect(nsIScrollab
   // use the in-reflow-safe font-size inflation path). If we did call it,
   // it would assert and possible give the wrong result.
   if (aVertical.mWhenToScroll == nsIPresShell::SCROLL_IF_NOT_VISIBLE ||
       aHorizontal.mWhenToScroll == nsIPresShell::SCROLL_IF_NOT_VISIBLE) {
     lineSize = aScrollFrame->GetLineScrollAmount();
   }
   nsPresContext::ScrollbarStyles ss = aScrollFrame->GetScrollbarStyles();
   nsRect allowedRange(scrollPt, nsSize(0, 0));
+  bool needToScroll = false;
 
   if ((aFlags & nsIPresShell::SCROLL_OVERFLOW_HIDDEN) ||
       ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN) {
 
     if (ComputeNeedToScroll(aVertical.mWhenToScroll,
                             lineSize.height,
                             aRect.y,
                             aRect.YMost(),
@@ -3124,16 +3114,17 @@ static void ScrollToShowRect(nsIScrollab
       scrollPt.y = ComputeWhereToScroll(aVertical.mWhereToScroll,
                                         scrollPt.y,
                                         aRect.y,
                                         aRect.YMost(),
                                         visibleRect.y,
                                         visibleRect.YMost(),
                                         &allowedRange.y, &maxHeight);
       allowedRange.height = maxHeight - allowedRange.y;
+      needToScroll = true;
     }
   }
 
   if ((aFlags & nsIPresShell::SCROLL_OVERFLOW_HIDDEN) ||
       ss.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN) {
 
     if (ComputeNeedToScroll(aHorizontal.mWhenToScroll,
                             lineSize.width,
@@ -3145,68 +3136,87 @@ static void ScrollToShowRect(nsIScrollab
       scrollPt.x = ComputeWhereToScroll(aHorizontal.mWhereToScroll,
                                         scrollPt.x,
                                         aRect.x,
                                         aRect.XMost(),
                                         visibleRect.x,
                                         visibleRect.XMost(),
                                         &allowedRange.x, &maxWidth);
       allowedRange.width = maxWidth - allowedRange.x;
-    }
-  }
-
-  aScrollFrame->ScrollTo(scrollPt, nsIScrollableFrame::INSTANT, &allowedRange);
+      needToScroll = true;
+    }
+  }
+
+  // If we don't need to scroll, then don't try since it might cancel
+  // a current smooth scroll operation.
+  if (needToScroll) {
+    aScrollFrame->ScrollTo(scrollPt, nsIScrollableFrame::INSTANT, &allowedRange);
+  }
+}
+
+static void
+DeleteScrollIntoViewData(void* aObject, nsIAtom* aPropertyName,
+                         void* aPropertyValue, void* aData)
+{
+  PresShell::ScrollIntoViewData* data =
+    static_cast<PresShell::ScrollIntoViewData*>(aPropertyValue);
+  delete data;
 }
 
 nsresult
 PresShell::ScrollContentIntoView(nsIContent*              aContent,
                                  nsIPresShell::ScrollAxis aVertical,
                                  nsIPresShell::ScrollAxis aHorizontal,
                                  PRUint32                 aFlags)
 {
-  nsCOMPtr<nsIContent> content = aContent; // Keep content alive while flushing.
-  NS_ENSURE_TRUE(content, NS_ERROR_NULL_POINTER);
-  nsCOMPtr<nsIDocument> currentDoc = content->GetCurrentDoc();
+  NS_ENSURE_TRUE(aContent, NS_ERROR_NULL_POINTER);
+  nsCOMPtr<nsIDocument> currentDoc = aContent->GetCurrentDoc();
   NS_ENSURE_STATE(currentDoc);
 
   NS_ASSERTION(mDidInitialReflow, "should have done initial reflow by now");
 
+  if (mContentToScrollTo) {
+    mContentToScrollTo->DeleteProperty(nsGkAtoms::scrolling);
+  }
   mContentToScrollTo = aContent;
-  mContentScrollVAxis = aVertical;
-  mContentScrollHAxis = aHorizontal;
-  mContentToScrollToFlags = aFlags;
+  ScrollIntoViewData* data = new ScrollIntoViewData();
+  data->mContentScrollVAxis = aVertical;
+  data->mContentScrollHAxis = aHorizontal;
+  data->mContentToScrollToFlags = aFlags;
+  if (NS_FAILED(mContentToScrollTo->SetProperty(nsGkAtoms::scrolling, data,
+                                                ::DeleteScrollIntoViewData))) {
+    mContentToScrollTo = nsnull;
+  }
 
   // Flush layout and attempt to scroll in the process.
   currentDoc->SetNeedLayoutFlush();
   currentDoc->FlushPendingNotifications(Flush_InterruptibleLayout);
 
   // If mContentToScrollTo is non-null, that means we interrupted the reflow
   // (or suppressed it altogether because we're suppressing interruptible
   // flushes right now) and won't necessarily get the position correct, but do
   // a best-effort scroll here.  The other option would be to do this inside
   // FlushPendingNotifications, but I'm not sure the repeated scrolling that
   // could trigger if reflows keep getting interrupted would be more desirable
   // than a single best-effort scroll followed by one final scroll on the first
   // completed reflow.
   if (mContentToScrollTo) {
-    DoScrollContentIntoView(content, aVertical, aHorizontal, aFlags);
+    DoScrollContentIntoView();
   }
   return NS_OK;
 }
 
 void
-PresShell::DoScrollContentIntoView(nsIContent*              aContent,
-                                   nsIPresShell::ScrollAxis aVertical,
-                                   nsIPresShell::ScrollAxis aHorizontal,
-                                   PRUint32                 aFlags)
+PresShell::DoScrollContentIntoView()
 {
   NS_ASSERTION(mDidInitialReflow, "should have done initial reflow by now");
 
-  nsIFrame* frame = aContent->GetPrimaryFrame();
+  nsIFrame* frame = mContentToScrollTo->GetPrimaryFrame();
   if (!frame) {
+    mContentToScrollTo->DeleteProperty(nsGkAtoms::scrolling);
     mContentToScrollTo = nsnull;
     return;
   }
 
   if (frame->GetStateBits() & NS_FRAME_FIRST_REFLOW) {
     // The reflow flush before this scroll got interrupted, and this frame's
     // coords and size are all zero, and it has no content showing anyway.
     // Don't bother scrolling to it.  We'll try again when we finish up layout.
@@ -3215,43 +3225,52 @@ PresShell::DoScrollContentIntoView(nsICo
 
   nsIFrame* container =
     nsLayoutUtils::GetClosestFrameOfType(frame, nsGkAtoms::scrollFrame);
   if (!container) {
     // nothing can be scrolled
     return;
   }
 
+  ScrollIntoViewData* data = static_cast<ScrollIntoViewData*>(
+    mContentToScrollTo->GetProperty(nsGkAtoms::scrolling));
+  if (NS_UNLIKELY(!data)) {
+    mContentToScrollTo = nsnull;
+    return;
+  }
+
   // This is a two-step process.
   // Step 1: Find the bounds of the rect we want to scroll into view.  For
   //         example, for an inline frame we may want to scroll in the whole
   //         line, or we may want to scroll multiple lines into view.
   // Step 2: Walk container frame and its ancestors and scroll them
   //         appropriately.
   // frameBounds is relative to container. We're assuming
   // that scrollframes don't split so every continuation of frame will
   // be a descendant of container. (Things would still mostly work
   // even if that assumption was false.)
   nsRect frameBounds;
   bool haveRect = false;
-  bool useWholeLineHeightForInlines = aVertical.mWhenToScroll != nsIPresShell::SCROLL_IF_NOT_FULLY_VISIBLE;
+  bool useWholeLineHeightForInlines =
+    data->mContentScrollVAxis.mWhenToScroll != nsIPresShell::SCROLL_IF_NOT_FULLY_VISIBLE;
   // Reuse the same line iterator across calls to AccumulateFrameBounds.  We set
   // it every time we detect a new block (stored in prevBlock).
   nsIFrame* prevBlock = nsnull;
   nsAutoLineIterator lines;
   // The last line we found a continuation on in |lines|.  We assume that later
   // continuations cannot come on earlier lines.
   PRInt32 curLine = 0;
   do {
     AccumulateFrameBounds(container, frame, useWholeLineHeightForInlines,
                           frameBounds, haveRect, prevBlock, lines, curLine);
   } while ((frame = frame->GetNextContinuation()));
 
-  ScrollFrameRectIntoView(container, frameBounds, aVertical, aHorizontal,
-                          aFlags);
+  ScrollFrameRectIntoView(container, frameBounds, data->mContentScrollVAxis,
+                          data->mContentScrollHAxis,
+                          data->mContentToScrollToFlags);
 }
 
 bool
 PresShell::ScrollFrameRectIntoView(nsIFrame*                aFrame,
                                    const nsRect&            aRect,
                                    nsIPresShell::ScrollAxis aVertical,
                                    nsIPresShell::ScrollAxis aHorizontal,
                                    PRUint32                 aFlags)
@@ -3838,21 +3857,21 @@ PresShell::FlushPendingNotifications(moz
     // be good.
 
     if (aType >= (mSuppressInterruptibleReflows ? Flush_Layout : Flush_InterruptibleLayout) &&
         !mIsDestroying) {
       mFrameConstructor->RecalcQuotesAndCounters();
       mViewManager->FlushDelayedResize(true);
       if (ProcessReflowCommands(aType < Flush_Layout) && mContentToScrollTo) {
         // We didn't get interrupted.  Go ahead and scroll to our content
-        DoScrollContentIntoView(mContentToScrollTo,
-                                mContentScrollVAxis,
-                                mContentScrollHAxis,
-                                mContentToScrollToFlags);
-        mContentToScrollTo = nsnull;
+        DoScrollContentIntoView();
+        if (mContentToScrollTo) {
+          mContentToScrollTo->DeleteProperty(nsGkAtoms::scrolling);
+          mContentToScrollTo = nsnull;
+        }
       }
     } else if (!mIsDestroying && mSuppressInterruptibleReflows &&
                aType == Flush_InterruptibleLayout) {
       // We suppressed this flush, but the document thinks it doesn't
       // need to flush anymore.  Let it know what's really going on.
       mDocument->SetNeedLayoutFlush();
     }
 
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -82,16 +82,20 @@ struct RangePaintInfo;
 struct nsCallbackEventRequest;
 #ifdef MOZ_REFLOW_PERF
 class ReflowCountMgr;
 #endif
 
 class nsPresShellEventCB;
 class nsAutoCauseReflowNotifier;
 
+// 250ms.  This is actually pref-controlled, but we use this value if we fail
+// to get the pref for any reason.
+#define PAINTLOCK_EVENT_DELAY 250
+
 class PresShell : public nsIPresShell,
                   public nsStubDocumentObserver,
                   public nsISelectionController, public nsIObserver,
                   public nsSupportsWeakReference
 {
 public:
   PresShell();
 
@@ -346,16 +350,31 @@ public:
   virtual bool GetIsViewportOverridden() { return mViewportOverridden; }
 
   virtual bool IsLayoutFlushObserver()
   {
     return GetPresContext()->RefreshDriver()->
       IsLayoutFlushObserver(this);
   }
 
+  void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
+                           size_t *aArenasSize,
+                           size_t *aStyleSetsSize,
+                           size_t *aTextRunsSize,
+                           size_t *aPresContextSize) const;
+  size_t SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf) const;
+
+  // This data is stored as a content property (nsGkAtoms::scrolling) on
+  // mContentToScrollTo when we have a pending ScrollIntoView.
+  struct ScrollIntoViewData {
+    ScrollAxis mContentScrollVAxis;
+    ScrollAxis mContentScrollHAxis;
+    PRUint32   mContentToScrollToFlags;
+  };
+
 protected:
   virtual ~PresShell();
 
   void HandlePostedReflowCallbacks(bool aInterruptible);
   void CancelPostedReflowCallbacks();
 
   void UnsuppressAndInvalidate();
 
@@ -392,33 +411,30 @@ protected:
   // DoReflow returns whether the reflow finished without interruption
   bool DoReflow(nsIFrame* aFrame, bool aInterruptible);
 #ifdef DEBUG
   void DoVerifyReflow();
   void VerifyHasDirtyRootAncestor(nsIFrame* aFrame);
 #endif
 
   // Helper for ScrollContentIntoView
-  void DoScrollContentIntoView(nsIContent* aContent,
-                               ScrollAxis  aVertical,
-                               ScrollAxis  aHorizontal,
-                               PRUint32    aFlags);
+  void DoScrollContentIntoView();
 
   friend struct AutoRenderingStateSaveRestore;
   friend struct RenderingState;
 
   struct RenderingState {
     RenderingState(PresShell* aPresShell) 
-      : mRenderFlags(aPresShell->mRenderFlags)
-      , mXResolution(aPresShell->mXResolution)
+      : mXResolution(aPresShell->mXResolution)
       , mYResolution(aPresShell->mYResolution)
+      , mRenderFlags(aPresShell->mRenderFlags)
     { }
-    PRUint32 mRenderFlags;
     float mXResolution;
     float mYResolution;
+    RenderFlags mRenderFlags;
   };
 
   struct AutoSaveRestoreRenderingState {
     AutoSaveRestoreRenderingState(PresShell* aPresShell)
       : mPresShell(aPresShell)
       , mOldState(aPresShell)
     {}
 
@@ -427,16 +443,22 @@ protected:
       mPresShell->mRenderFlags = mOldState.mRenderFlags;
       mPresShell->mXResolution = mOldState.mXResolution;
       mPresShell->mYResolution = mOldState.mYResolution;
     }
 
     PresShell* mPresShell;
     RenderingState mOldState;
   };
+  static RenderFlags ChangeFlag(RenderFlags aFlags, bool aOnOff,
+                                eRenderFlag aFlag)
+  {
+    return aOnOff ? (aFlags | aFlag) : (aFlag & ~aFlag);
+  }
+
 
   void SetRenderingState(const RenderingState& aState);
 
   friend class nsPresShellEventCB;
 
   bool mCaretEnabled;
 #ifdef NS_DEBUG
   nsStyleSet* CloneStyleSet(nsStyleSet* aSet);
@@ -521,69 +543,16 @@ protected:
     nsresult rv = NS_OK;
     if (GetCurrentEventFrame()) {
       rv = HandleEventInternal(aEvent, aStatus);
     }
     PopCurrentEventInfo();
     return rv;
   }
 
-  nsRefPtr<nsCSSStyleSheet> mPrefStyleSheet; // mStyleSet owns it but we
-                                             // maintain a ref, may be null
-#ifdef DEBUG
-  PRUint32                  mUpdateCount;
-#endif
-  // reflow roots that need to be reflowed, as both a queue and a hashtable
-  nsTArray<nsIFrame*> mDirtyRoots;
-
-  bool mDocumentLoading;
-
-  bool mIgnoreFrameDestruction;
-  bool mHaveShutDown;
-
-  bool mViewportOverridden;
-
-  bool mLastRootReflowHadUnconstrainedHeight;
-
-  // This is used to protect ourselves from triggering reflow while in the
-  // middle of frame construction and the like... it really shouldn't be
-  // needed, one hopes, but it is for now.
-  PRUint32  mChangeNestCount;
-  
-  nsIFrame*   mCurrentEventFrame;
-  nsCOMPtr<nsIContent> mCurrentEventContent;
-  nsTArray<nsIFrame*> mCurrentEventFrameStack;
-  nsCOMArray<nsIContent> mCurrentEventContentStack;
-
-  nsCOMPtr<nsIContent>          mLastAnchorScrolledTo;
-  nscoord                       mLastAnchorScrollPositionY;
-  nsRefPtr<nsCaret>             mCaret;
-  nsRefPtr<nsCaret>             mOriginalCaret;
-  nsCOMPtr<nsIDragService>      mDragService;
-  
-#ifdef DEBUG
-  // The reflow root under which we're currently reflowing.  Null when
-  // not in reflow.
-  nsIFrame* mCurrentReflowRoot;
-#endif
-
-  // Set of frames that we should mark with NS_FRAME_HAS_DIRTY_CHILDREN after
-  // we finish reflowing mCurrentReflowRoot.
-  nsTHashtable< nsPtrHashKey<nsIFrame> > mFramesToDirty;
-
-  // Information needed to properly handle scrolling content into view if the
-  // pre-scroll reflow flush can be interrupted.  mContentToScrollTo is
-  // non-null between the initial scroll attempt and the first time we finish
-  // processing all our dirty roots.  mContentScrollVPosition and
-  // mContentScrollHPosition are only used when it's non-null.
-  nsCOMPtr<nsIContent> mContentToScrollTo;
-  ScrollAxis mContentScrollVAxis;
-  ScrollAxis mContentScrollHAxis;
-  PRUint32 mContentToScrollToFlags;
-
   class nsDelayedEvent
   {
   public:
     virtual ~nsDelayedEvent() {};
     virtual void Dispatch(PresShell* aShell) {}
   };
 
   class nsDelayedInputEvent : public nsDelayedEvent
@@ -649,68 +618,59 @@ protected:
     }
 
     virtual ~nsDelayedKeyEvent()
     {
       delete static_cast<nsKeyEvent*>(mEvent);
     }
   };
 
-  bool                                 mNoDelayedMouseEvents;
-  bool                                 mNoDelayedKeyEvents;
-  nsTArray<nsAutoPtr<nsDelayedEvent> > mDelayedEvents;
-
-  nsCallbackEventRequest* mFirstCallbackEventRequest;
-  nsCallbackEventRequest* mLastCallbackEventRequest;
+  // Check if aEvent is a mouse event and record the mouse location for later
+  // synth mouse moves.
+  void RecordMouseLocation(nsGUIEvent* aEvent);
+  class nsSynthMouseMoveEvent : public nsARefreshObserver {
+  public:
+    nsSynthMouseMoveEvent(PresShell* aPresShell, bool aFromScroll)
+      : mPresShell(aPresShell), mFromScroll(aFromScroll) {
+      NS_ASSERTION(mPresShell, "null parameter");
+    }
+    ~nsSynthMouseMoveEvent() {
+      Revoke();
+    }
 
-  bool              mIsDocumentGone;      // We've been disconnected from the document.
-                                          // We will refuse to paint the document until either
-                                          // (a) our timer fires or (b) all frames are constructed.
-  bool              mShouldUnsuppressPainting;  // Indicates that it is safe to unlock painting once all pending
-                                                // reflows have been processed.
-  nsCOMPtr<nsITimer> mPaintSuppressionTimer; // This timer controls painting suppression.  Until it fires
-                                             // or all frames are constructed, we won't paint anything but
-                                             // our <body> background and scrollbars.
-#define PAINTLOCK_EVENT_DELAY 250 // 250ms.  This is actually
-                                  // pref-controlled, but we use this
-                                  // value if we fail to get the pref
-                                  // for any reason.
-
-  static void sPaintSuppressionCallback(nsITimer* aTimer, void* aPresShell); // A callback for the timer.
+    NS_INLINE_DECL_REFCOUNTING(nsSynthMouseMoveEvent)
+    
+    void Revoke() {
+      if (mPresShell) {
+        mPresShell->GetPresContext()->RefreshDriver()->
+          RemoveRefreshObserver(this, Flush_Display);
+        mPresShell = nsnull;
+      }
+    }
+    virtual void WillRefresh(mozilla::TimeStamp aTime) {
+      if (mPresShell)
+        mPresShell->ProcessSynthMouseMoveEvent(mFromScroll);
+    }
+  private:
+    PresShell* mPresShell;
+    bool mFromScroll;
+  };
+  void ProcessSynthMouseMoveEvent(bool aFromScroll);
 
-  // At least on Win32 and Mac after interupting a reflow we need to post
-  // the resume reflow event off a timer to avoid event starvation because
-  // posted messages are processed before other messages when the modal
-  // moving/sizing loop is running, see bug 491700 for details.
-  nsCOMPtr<nsITimer> mReflowContinueTimer;
-  static void sReflowContinueCallback(nsITimer* aTimer, void* aPresShell);
-  bool ScheduleReflowOffTimer();
-  
-#ifdef MOZ_REFLOW_PERF
-  ReflowCountMgr * mReflowCountMgr;
-#endif
-
-  static bool sDisableNonTestMouseEvents;
-
-private:
-
+  void QueryIsActive();
+  nsresult UpdateImageLockingState();
 
 #ifdef ANDROID
   nsIDocument* GetTouchEventTargetDocument();
 #endif
   bool InZombieDocument(nsIContent *aContent);
   already_AddRefed<nsIPresShell> GetParentPresShell();
+  nsIFrame* GetCurrentEventFrame();
   nsresult RetargetEventToParent(nsGUIEvent* aEvent,
                                  nsEventStatus*  aEventStatus);
-
-  //helper funcs for event handling
-protected:
-  //protected because nsPresShellEventCB needs this.
-  nsIFrame* GetCurrentEventFrame();
-private:
   void PushCurrentEventInfo(nsIFrame* aFrame, nsIContent* aContent);
   void PopCurrentEventInfo();
   nsresult HandleEventInternal(nsEvent* aEvent, nsEventStatus *aStatus);
   nsresult HandlePositionedEvent(nsIFrame*      aTargetFrame,
                                  nsGUIEvent*    aEvent,
                                  nsEventStatus* aEventStatus);
   // This returns the focused DOM window under our top level window.
   //  I.e., when we are deactive, this returns the *last* focused DOM window.
@@ -741,77 +701,115 @@ private:
   void GetCurrentItemAndPositionForElement(nsIDOMElement *aCurrentEl,
                                            nsIContent **aTargetToUse,
                                            nsIntPoint& aTargetPt,
                                            nsIWidget *aRootWidget);
 
   void FireResizeEvent();
   void FireBeforeResizeEvent();
   static void AsyncResizeEventCallback(nsITimer* aTimer, void* aPresShell);
-  nsRevocableEventPtr<nsRunnableMethod<PresShell> > mResizeEvent;
-  nsCOMPtr<nsITimer> mAsyncResizeEventTimer;
-  bool mAsyncResizeTimerIsActive;
-  bool mInResize;
 
   virtual void SynthesizeMouseMove(bool aFromScroll);
 
-  // Check if aEvent is a mouse event and record the mouse location for later
-  // synth mouse moves.
-  void RecordMouseLocation(nsGUIEvent* aEvent);
+  PresShell* GetRootPresShell();
+
+  nscolor GetDefaultBackgroundColorToDraw();
+
+  // The callback for the mPaintSuppressionTimer timer.
+  static void sPaintSuppressionCallback(nsITimer* aTimer, void* aPresShell);
+
+  // The callback for the mReflowContinueTimer timer.
+  static void sReflowContinueCallback(nsITimer* aTimer, void* aPresShell);
+  bool ScheduleReflowOffTimer();
+  
+#ifdef DEBUG
+  // The reflow root under which we're currently reflowing.  Null when
+  // not in reflow.
+  nsIFrame*                 mCurrentReflowRoot;
+  PRUint32                  mUpdateCount;
+#endif
+
+#ifdef MOZ_REFLOW_PERF
+  ReflowCountMgr*           mReflowCountMgr;
+#endif
+
   // This is used for synthetic mouse events that are sent when what is under
   // the mouse pointer may have changed without the mouse moving (eg scrolling,
   // change to the document contents).
   // It is set only on a presshell for a root document, this value represents
   // the last observed location of the mouse relative to that root document. It
   // is set to (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if the mouse isn't
   // over our window or there is no last observed mouse location for some
   // reason.
-  nsPoint mMouseLocation;
-  class nsSynthMouseMoveEvent : public nsARefreshObserver {
-  public:
-    nsSynthMouseMoveEvent(PresShell* aPresShell, bool aFromScroll)
-      : mPresShell(aPresShell), mFromScroll(aFromScroll) {
-      NS_ASSERTION(mPresShell, "null parameter");
-    }
-    ~nsSynthMouseMoveEvent() {
-      Revoke();
-    }
+  nsPoint                   mMouseLocation;
+
+  // mStyleSet owns it but we maintain a ref, may be null
+  nsRefPtr<nsCSSStyleSheet> mPrefStyleSheet; 
+
+  // Set of frames that we should mark with NS_FRAME_HAS_DIRTY_CHILDREN after
+  // we finish reflowing mCurrentReflowRoot.
+  nsTHashtable<nsPtrHashKey<nsIFrame> > mFramesToDirty;
+
+  // Reflow roots that need to be reflowed.
+  nsTArray<nsIFrame*>       mDirtyRoots;
+
+  nsTArray<nsAutoPtr<nsDelayedEvent> > mDelayedEvents;
+  nsRevocableEventPtr<nsRunnableMethod<PresShell> > mResizeEvent;
+  nsCOMPtr<nsITimer>        mAsyncResizeEventTimer;
+  nsIFrame*                 mCurrentEventFrame;
+  nsCOMPtr<nsIContent>      mCurrentEventContent;
+  nsTArray<nsIFrame*>       mCurrentEventFrameStack;
+  nsCOMArray<nsIContent>    mCurrentEventContentStack;
+  nsRevocableEventPtr<nsSynthMouseMoveEvent> mSynthMouseMoveEvent;
+  nsCOMPtr<nsIContent>      mLastAnchorScrolledTo;
+  nsRefPtr<nsCaret>         mCaret;
+  nsRefPtr<nsCaret>         mOriginalCaret;
+  nsCallbackEventRequest*   mFirstCallbackEventRequest;
+  nsCallbackEventRequest*   mLastCallbackEventRequest;
+
+  // This timer controls painting suppression.  Until it fires
+  // or all frames are constructed, we won't paint anything but
+  // our <body> background and scrollbars.
+  nsCOMPtr<nsITimer>        mPaintSuppressionTimer;
 
-    NS_INLINE_DECL_REFCOUNTING(nsSynthMouseMoveEvent)
-    
-    void Revoke() {
-      if (mPresShell) {
-        mPresShell->GetPresContext()->RefreshDriver()->
-          RemoveRefreshObserver(this, Flush_Display);
-        mPresShell = nsnull;
-      }
-    }
-    virtual void WillRefresh(mozilla::TimeStamp aTime) {
-      if (mPresShell)
-        mPresShell->ProcessSynthMouseMoveEvent(mFromScroll);
-    }
-  private:
-    PresShell* mPresShell;
-    bool mFromScroll;
-  };
-  nsRevocableEventPtr<nsSynthMouseMoveEvent> mSynthMouseMoveEvent;
-  void ProcessSynthMouseMoveEvent(bool aFromScroll);
+  // At least on Win32 and Mac after interupting a reflow we need to post
+  // the resume reflow event off a timer to avoid event starvation because
+  // posted messages are processed before other messages when the modal
+  // moving/sizing loop is running, see bug 491700 for details.
+  nsCOMPtr<nsITimer>        mReflowContinueTimer;
+
+  // Information needed to properly handle scrolling content into view if the
+  // pre-scroll reflow flush can be interrupted.  mContentToScrollTo is
+  // non-null between the initial scroll attempt and the first time we finish
+  // processing all our dirty roots.  mContentToScrollTo has a content property
+  // storing the details for the scroll operation, see ScrollIntoViewData above.
+  nsCOMPtr<nsIContent>      mContentToScrollTo;
+
+  nscoord                   mLastAnchorScrollPositionY;
 
-  PresShell* GetRootPresShell();
-
-public:
+  // This is used to protect ourselves from triggering reflow while in the
+  // middle of frame construction and the like... it really shouldn't be
+  // needed, one hopes, but it is for now.
+  PRUint16                  mChangeNestCount;
+  
+  bool                      mDocumentLoading : 1;
+  bool                      mIgnoreFrameDestruction : 1;
+  bool                      mHaveShutDown : 1;
+  bool                      mViewportOverridden : 1;
+  bool                      mLastRootReflowHadUnconstrainedHeight : 1;
+  bool                      mNoDelayedMouseEvents : 1;
+  bool                      mNoDelayedKeyEvents : 1;
 
-  void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
-                           size_t *aArenasSize,
-                           size_t *aStyleSetsSize,
-                           size_t *aTextRunsSize,
-                           size_t *aPresContextSize) const;
-  size_t SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf) const;
+  // We've been disconnected from the document.  We will refuse to paint the
+  // document until either our timer fires or all frames are constructed.
+  bool                      mIsDocumentGone : 1;
 
-protected:
-  void QueryIsActive();
-  nsresult UpdateImageLockingState();
+  // Indicates that it is safe to unlock painting once all pending reflows
+  // have been processed.
+  bool                      mShouldUnsuppressPainting : 1;
 
-private:
-  nscolor GetDefaultBackgroundColorToDraw();
+  bool                      mAsyncResizeTimerIsActive : 1;
+  bool                      mInResize : 1;
+
+  static bool               sDisableNonTestMouseEvents;
 };
 
 #endif /* !defined(nsPresShell_h_) */
--- a/layout/generic/Makefile.in
+++ b/layout/generic/Makefile.in
@@ -61,16 +61,17 @@ EXPORTS		= \
 		nsIFrameUtil.h \
 		nsILineIterator.h \
 		nsIObjectFrame.h \
 		nsIPageSequenceFrame.h \
 		nsIScrollableFrame.h \
 		nsIStatefulFrame.h \
 		nsFrameSelection.h \
 		nsSubDocumentFrame.h \
+		nsTypedSelection.h \
 		nsObjectFrame.h \
 		$(NULL)
 
 EXPORTS_NAMESPACES = mozilla/layout
 
 EXPORTS_mozilla/layout = \
 		FrameChildList.h \
 		$(NULL)
--- a/layout/generic/nsFrameSelection.h
+++ b/layout/generic/nsFrameSelection.h
@@ -379,17 +379,17 @@ public:
    */
   bool GetTableCellSelection() const { return mSelectingTableCellMode != 0; }
   void ClearTableCellSelection() { mSelectingTableCellMode = 0; }
 
   /** GetSelection
    * no query interface for selection. must use this method now.
    * @param aSelectionType enum value defined in nsISelection for the seleciton you want.
    */
-  nsISelection* GetSelection(SelectionType aType) const;
+  nsTypedSelection* GetSelection(SelectionType aType) const;
 
   /**
    * ScrollSelectionIntoView scrolls a region of the selection,
    * so that it is visible in the scrolled view.
    *
    * @param aType the selection to scroll into view.
    * @param aRegion the region inside the selection to scroll into view.
    * @param aFlags the scroll flags.  Valid bits include:
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -36,26 +36,27 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Implementation of selection: nsISelection,nsISelectionPrivate and nsFrameSelection
  */
 
+#include "nsTypedSelection.h"
+
 #include "mozilla/Attributes.h"
 
 #include "nsCOMPtr.h"
 #include "nsWeakReference.h"
 #include "nsIFactory.h"
 #include "nsIEnumerator.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsFrameSelection.h"
-#include "nsISelectionPrivate.h"
 #include "nsISelectionListener.h"
 #include "nsIComponentManager.h"
 #include "nsContentCID.h"
 #include "nsIContent.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
 #include "nsRange.h"
 #include "nsCOMArray.h"
@@ -155,214 +156,18 @@ struct CachedOffsetForFrame {
   {}
 
   nsPoint      mCachedFrameOffset;      // cached frame offset
   nsIFrame*    mLastCaretFrame;         // store the frame the caret was last drawn in.
   PRInt32      mLastContentOffset;      // store last content offset
   bool mCanCacheFrameOffset;    // cached frame offset is valid?
 };
 
-struct RangeData
-{
-  RangeData(nsRange* aRange)
-    : mRange(aRange)
-  {}
-
-  nsRefPtr<nsRange> mRange;
-  nsTextRangeStyle mTextRangeStyle;
-};
-
 static RangeData sEmptyData(nsnull);
 
-// Note, the ownership of nsTypedSelection depends on which way the object is
-// created. When nsFrameSelection has created nsTypedSelection,
-// addreffing/releasing nsTypedSelection object is aggregated to
-// nsFrameSelection. Otherwise normal addref/release is used.
-// This ensures that nsFrameSelection is never deleted before its
-// nsTypedSelections.
-
-class nsTypedSelection : public nsISelectionPrivate,
-                         public nsSupportsWeakReference
-{
-public:
-  nsTypedSelection();
-  nsTypedSelection(nsFrameSelection *aList);
-  virtual ~nsTypedSelection();
-  
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsTypedSelection, nsISelectionPrivate)
-  NS_DECL_NSISELECTION
-  NS_DECL_NSISELECTIONPRIVATE
-
-  // utility methods for scrolling the selection into view
-  nsresult      GetPresContext(nsPresContext **aPresContext);
-  nsresult      GetPresShell(nsIPresShell **aPresShell);
-  // Returns a rect containing the selection region, and frame that that
-  // position is relative to. For SELECTION_ANCHOR_REGION or
-  // SELECTION_FOCUS_REGION the rect is a zero-width rectangle. For
-  // SELECTION_WHOLE_SELECTION the rect contains both the anchor and focus
-  // region rects.
-  nsIFrame*     GetSelectionAnchorGeometry(SelectionRegion aRegion, nsRect *aRect);
-  // Returns the position of the region (SELECTION_ANCHOR_REGION or
-  // SELECTION_FOCUS_REGION only), and frame that that position is relative to.
-  // The 'position' is a zero-width rectangle.
-  nsIFrame*     GetSelectionEndPointGeometry(SelectionRegion aRegion, nsRect *aRect);
-
-  nsresult      PostScrollSelectionIntoViewEvent(
-                                        SelectionRegion aRegion,
-                                        bool aFirstAncestorOnly,
-                                        nsIPresShell::ScrollAxis aVertical,
-                                        nsIPresShell::ScrollAxis aHorizontal);
-  enum {
-    SCROLL_SYNCHRONOUS = 1<<1,
-    SCROLL_FIRST_ANCESTOR_ONLY = 1<<2,
-    SCROLL_DO_FLUSH = 1<<3
-  };
-  // aDoFlush only matters if aIsSynchronous is true.  If not, we'll just flush
-  // when the scroll event fires so we make sure to scroll to the right place.
-  nsresult      ScrollIntoView(SelectionRegion aRegion,
-                               nsIPresShell::ScrollAxis aVertical =
-                                 nsIPresShell::ScrollAxis(),
-                               nsIPresShell::ScrollAxis aHorizontal =
-                                 nsIPresShell::ScrollAxis(),
-                               PRInt32 aFlags = 0);
-  nsresult      SubtractRange(RangeData* aRange, nsRange* aSubtract,
-                              nsTArray<RangeData>* aOutput);
-  nsresult      AddItem(nsRange *aRange, PRInt32* aOutIndex = nsnull);
-  nsresult      RemoveItem(nsRange *aRange);
-  nsresult      RemoveCollapsedRanges();
-  nsresult      Clear(nsPresContext* aPresContext);
-  nsresult      Collapse(nsINode* aParentNode, PRInt32 aOffset);
-  nsresult      Extend(nsINode* aParentNode, PRInt32 aOffset);
-  nsRange*      GetRangeAt(PRInt32 aIndex);
-
-  // methods for convenience. Note, these don't addref
-  nsINode*     GetAnchorNode();
-  PRInt32      GetAnchorOffset();
-
-  nsINode*     GetFocusNode();
-  PRInt32      GetFocusOffset();
-
-  // Get the anchor-to-focus range if we don't care which end is
-  // anchor and which end is focus.
-  const nsRange* GetAnchorFocusRange() const {
-    return mAnchorFocusRange;
-  }
-
-  nsDirection  GetDirection(){return mDirection;}
-  void         SetDirection(nsDirection aDir){mDirection = aDir;}
-  nsresult     SetAnchorFocusToRange(nsRange *aRange);
-  void         ReplaceAnchorFocusRange(nsRange *aRange);
-
-  //  NS_IMETHOD   GetPrimaryFrameForRangeEndpoint(nsIDOMNode *aNode, PRInt32 aOffset, bool aIsEndNode, nsIFrame **aResultFrame);
-  NS_IMETHOD   GetPrimaryFrameForAnchorNode(nsIFrame **aResultFrame);
-  NS_IMETHOD   GetPrimaryFrameForFocusNode(nsIFrame **aResultFrame, PRInt32 *aOffset, bool aVisual);
-  NS_IMETHOD   LookUpSelection(nsIContent *aContent, PRInt32 aContentOffset, PRInt32 aContentLength,
-                             SelectionDetails **aReturnDetails, SelectionType aType, bool aSlowCheck);
-  NS_IMETHOD   Repaint(nsPresContext* aPresContext);
-
-  // Note: StartAutoScrollTimer might destroy arbitrary frames etc.
-  nsresult     StartAutoScrollTimer(nsIFrame *aFrame,
-                                    nsPoint& aPoint,
-                                    PRUint32 aDelay);
-
-  nsresult     StopAutoScrollTimer();
-
-private:
-  friend class nsAutoScrollTimer;
-
-  // Note: DoAutoScroll might destroy arbitrary frames etc.
-  nsresult DoAutoScroll(nsIFrame *aFrame, nsPoint& aPoint);
-
-public:
-  SelectionType GetType(){return mType;}
-  void          SetType(SelectionType aType){mType = aType;}
-
-  nsresult     NotifySelectionListeners();
-
-private:
-  friend class nsSelectionIterator;
-
-  class ScrollSelectionIntoViewEvent;
-  friend class ScrollSelectionIntoViewEvent;
-
-  class ScrollSelectionIntoViewEvent : public nsRunnable {
-  public:
-    NS_DECL_NSIRUNNABLE
-    ScrollSelectionIntoViewEvent(nsTypedSelection *aTypedSelection,
-                                 SelectionRegion aRegion,
-                                 nsIPresShell::ScrollAxis aVertical,
-                                 nsIPresShell::ScrollAxis aHorizontal,
-                                 bool aFirstAncestorOnly)
-      : mTypedSelection(aTypedSelection),
-        mRegion(aRegion),
-        mVerticalScroll(aVertical),
-        mHorizontalScroll(aHorizontal),
-        mFirstAncestorOnly(aFirstAncestorOnly) {
-      NS_ASSERTION(aTypedSelection, "null parameter");
-    }
-    void Revoke() { mTypedSelection = nsnull; }
-  private:
-    nsTypedSelection *mTypedSelection;
-    SelectionRegion mRegion;
-    nsIPresShell::ScrollAxis mVerticalScroll;
-    nsIPresShell::ScrollAxis mHorizontalScroll;
-    bool mFirstAncestorOnly;
-  };
-
-  void setAnchorFocusRange(PRInt32 aIndex); // pass in index into mRanges;
-                                            // negative value clears
-                                            // mAnchorFocusRange
-  nsresult     SelectAllFramesForContent(nsIContentIterator *aInnerIter,
-                               nsIContent *aContent,
-                               bool aSelected);
-  nsresult     selectFrames(nsPresContext* aPresContext, nsRange *aRange, bool aSelect);
-  nsresult     getTableCellLocationFromRange(nsRange *aRange, PRInt32 *aSelectionType, PRInt32 *aRow, PRInt32 *aCol);
-  nsresult     addTableCellRange(nsRange *aRange, bool *aDidAddRange, PRInt32 *aOutIndex);
-
-  nsresult FindInsertionPoint(
-      nsTArray<RangeData>* aElementArray,
-      nsINode* aPointNode, PRInt32 aPointOffset,
-      nsresult (*aComparator)(nsINode*,PRInt32,nsRange*,PRInt32*),
-      PRInt32* aPoint);
-  bool EqualsRangeAtPoint(nsINode* aBeginNode, PRInt32 aBeginOffset,
-                            nsINode* aEndNode, PRInt32 aEndOffset,
-                            PRInt32 aRangeIndex);
-  void GetIndicesForInterval(nsINode* aBeginNode, PRInt32 aBeginOffset,
-                             nsINode* aEndNode, PRInt32 aEndOffset,
-                             bool aAllowAdjacent,
-                             PRInt32 *aStartIndex, PRInt32 *aEndIndex);
-  RangeData* FindRangeData(nsIDOMRange* aRange);
-
-  // These are the ranges inside this selection. They are kept sorted in order
-  // of DOM start position.
-  //
-  // This data structure is sorted by the range beginnings. As the ranges are
-  // disjoint, it is also implicitly sorted by the range endings. This allows
-  // us to perform binary searches when searching for existence of a range,
-  // giving us O(log n) search time.
-  //
-  // Inserting a new range requires finding the overlapping interval, requiring
-  // two binary searches plus up to an additional 6 DOM comparisons. If this
-  // proves to be a performance concern, then an interval tree may be a
-  // possible solution, allowing the calculation of the overlap interval in
-  // O(log n) time, though this would require rebalancing and other overhead.
-  nsTArray<RangeData> mRanges;
-
-  nsRefPtr<nsRange> mAnchorFocusRange;
-  nsRefPtr<nsFrameSelection> mFrameSelection;
-  nsWeakPtr mPresShellWeak;
-  nsRefPtr<nsAutoScrollTimer> mAutoScrollTimer;
-  nsCOMArray<nsISelectionListener> mSelectionListeners;
-  nsRevocableEventPtr<ScrollSelectionIntoViewEvent> mScrollEvent;
-  CachedOffsetForFrame *mCachedOffsetForFrame;
-  nsDirection mDirection;
-  SelectionType mType;
-};
-
 // Stack-class to turn on/off selection batching for table selection
 class NS_STACK_CLASS nsSelectionBatcher MOZ_FINAL
 {
 private:
   nsCOMPtr<nsISelectionPrivate> mSelection;
 public:
   nsSelectionBatcher(nsISelectionPrivate *aSelection) : mSelection(aSelection)
   {
@@ -1949,24 +1754,24 @@ nsFrameSelection::SetMouseDownState(bool
   if (!mMouseDownState)
   {
     mDragSelectingCells = false;
     PostReason(nsISelectionListener::MOUSEUP_REASON);
     NotifySelectionListeners(nsISelectionController::SELECTION_NORMAL); //notify that reason is mouse up please.
   }
 }
 
-nsISelection*
+nsTypedSelection*
 nsFrameSelection::GetSelection(SelectionType aType) const
 {
   PRInt8 index = GetIndexFromSelectionType(aType);
   if (index < 0)
     return nsnull;
 
-  return static_cast<nsISelection*>(mDomSelections[index]);
+  return mDomSelections[index];
 }
 
 nsresult
 nsFrameSelection::ScrollSelectionIntoView(SelectionType   aType,
                                           SelectionRegion aRegion,
                                           PRInt16         aFlags) const
 {
   PRInt8 index = GetIndexFromSelectionType(aType);
new file mode 100644
--- /dev/null
+++ b/layout/generic/nsTypedSelection.h
@@ -0,0 +1,219 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsTypedSelection_h
+#define nsTypedSelection_h
+
+#include "nsIWeakReference.h"
+
+#include "nsISelection.h"
+#include "nsISelectionController.h"
+#include "nsISelectionPrivate.h"
+
+struct CachedOffsetForFrame;
+class nsAutoScrollTimer;
+class nsIContentIterator;
+class nsIFrame;
+class nsRange;
+struct SelectionDetails;
+
+struct RangeData
+{
+  RangeData(nsRange* aRange)
+    : mRange(aRange)
+  {}
+
+  nsRefPtr<nsRange> mRange;
+  nsTextRangeStyle mTextRangeStyle;
+};
+
+// Note, the ownership of nsTypedSelection depends on which way the object is
+// created. When nsFrameSelection has created nsTypedSelection,
+// addreffing/releasing nsTypedSelection object is aggregated to
+// nsFrameSelection. Otherwise normal addref/release is used.
+// This ensures that nsFrameSelection is never deleted before its
+// nsTypedSelections.
+class nsTypedSelection : public nsISelectionPrivate,
+                         public nsSupportsWeakReference
+{
+public:
+  nsTypedSelection();
+  nsTypedSelection(nsFrameSelection *aList);
+  virtual ~nsTypedSelection();
+  
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsTypedSelection, nsISelectionPrivate)
+  NS_DECL_NSISELECTION
+  NS_DECL_NSISELECTIONPRIVATE
+
+  // utility methods for scrolling the selection into view
+  nsresult      GetPresContext(nsPresContext **aPresContext);
+  nsresult      GetPresShell(nsIPresShell **aPresShell);
+  // Returns a rect containing the selection region, and frame that that
+  // position is relative to. For SELECTION_ANCHOR_REGION or
+  // SELECTION_FOCUS_REGION the rect is a zero-width rectangle. For
+  // SELECTION_WHOLE_SELECTION the rect contains both the anchor and focus
+  // region rects.
+  nsIFrame*     GetSelectionAnchorGeometry(SelectionRegion aRegion, nsRect *aRect);
+  // Returns the position of the region (SELECTION_ANCHOR_REGION or
+  // SELECTION_FOCUS_REGION only), and frame that that position is relative to.
+  // The 'position' is a zero-width rectangle.
+  nsIFrame*     GetSelectionEndPointGeometry(SelectionRegion aRegion, nsRect *aRect);
+
+  nsresult      PostScrollSelectionIntoViewEvent(
+                                        SelectionRegion aRegion,
+                                        bool aFirstAncestorOnly,
+                                        nsIPresShell::ScrollAxis aVertical,
+                                        nsIPresShell::ScrollAxis aHorizontal);
+  enum {
+    SCROLL_SYNCHRONOUS = 1<<1,
+    SCROLL_FIRST_ANCESTOR_ONLY = 1<<2,
+    SCROLL_DO_FLUSH = 1<<3
+  };
+  // aDoFlush only matters if aIsSynchronous is true.  If not, we'll just flush
+  // when the scroll event fires so we make sure to scroll to the right place.
+  nsresult      ScrollIntoView(SelectionRegion aRegion,
+                               nsIPresShell::ScrollAxis aVertical =
+                                 nsIPresShell::ScrollAxis(),
+                               nsIPresShell::ScrollAxis aHorizontal =
+                                 nsIPresShell::ScrollAxis(),
+                               PRInt32 aFlags = 0);
+  nsresult      SubtractRange(RangeData* aRange, nsRange* aSubtract,
+                              nsTArray<RangeData>* aOutput);
+  nsresult      AddItem(nsRange *aRange, PRInt32* aOutIndex = nsnull);
+  nsresult      RemoveItem(nsRange *aRange);
+  nsresult      RemoveCollapsedRanges();
+  nsresult      Clear(nsPresContext* aPresContext);
+  nsresult      Collapse(nsINode* aParentNode, PRInt32 aOffset);
+  nsresult      Extend(nsINode* aParentNode, PRInt32 aOffset);
+  nsRange*      GetRangeAt(PRInt32 aIndex);
+  PRInt32 GetRangeCount() { return mRanges.Length(); }
+
+  // methods for convenience. Note, these don't addref
+  nsINode*     GetAnchorNode();
+  PRInt32      GetAnchorOffset();
+
+  nsINode*     GetFocusNode();
+  PRInt32      GetFocusOffset();
+
+  // Get the anchor-to-focus range if we don't care which end is
+  // anchor and which end is focus.
+  const nsRange* GetAnchorFocusRange() const {
+    return mAnchorFocusRange;
+  }
+
+  nsDirection  GetDirection(){return mDirection;}
+  void         SetDirection(nsDirection aDir){mDirection = aDir;}
+  nsresult     SetAnchorFocusToRange(nsRange *aRange);
+  void         ReplaceAnchorFocusRange(nsRange *aRange);
+
+  //  NS_IMETHOD   GetPrimaryFrameForRangeEndpoint(nsIDOMNode *aNode, PRInt32 aOffset, bool aIsEndNode, nsIFrame **aResultFrame);
+  NS_IMETHOD   GetPrimaryFrameForAnchorNode(nsIFrame **aResultFrame);
+  NS_IMETHOD   GetPrimaryFrameForFocusNode(nsIFrame **aResultFrame, PRInt32 *aOffset, bool aVisual);
+  NS_IMETHOD   LookUpSelection(nsIContent *aContent, PRInt32 aContentOffset, PRInt32 aContentLength,
+                             SelectionDetails **aReturnDetails, SelectionType aType, bool aSlowCheck);
+  NS_IMETHOD   Repaint(nsPresContext* aPresContext);
+
+  // Note: StartAutoScrollTimer might destroy arbitrary frames etc.
+  nsresult     StartAutoScrollTimer(nsIFrame *aFrame,
+                                    nsPoint& aPoint,
+                                    PRUint32 aDelay);
+
+  nsresult     StopAutoScrollTimer();
+
+private:
+  friend class nsAutoScrollTimer;
+
+  // Note: DoAutoScroll might destroy arbitrary frames etc.
+  nsresult DoAutoScroll(nsIFrame *aFrame, nsPoint& aPoint);
+
+public:
+  SelectionType GetType(){return mType;}
+  void          SetType(SelectionType aType){mType = aType;}
+
+  nsresult     NotifySelectionListeners();
+
+private:
+  friend class nsSelectionIterator;
+
+  class ScrollSelectionIntoViewEvent;
+  friend class ScrollSelectionIntoViewEvent;
+
+  class ScrollSelectionIntoViewEvent : public nsRunnable {
+  public:
+    NS_DECL_NSIRUNNABLE
+    ScrollSelectionIntoViewEvent(nsTypedSelection *aTypedSelection,
+                                 SelectionRegion aRegion,
+                                 nsIPresShell::ScrollAxis aVertical,
+                                 nsIPresShell::ScrollAxis aHorizontal,
+                                 bool aFirstAncestorOnly)
+      : mTypedSelection(aTypedSelection),
+        mRegion(aRegion),
+        mVerticalScroll(aVertical),
+        mHorizontalScroll(aHorizontal),
+        mFirstAncestorOnly(aFirstAncestorOnly) {
+      NS_ASSERTION(aTypedSelection, "null parameter");
+    }
+    void Revoke() { mTypedSelection = nsnull; }
+  private:
+    nsTypedSelection *mTypedSelection;
+    SelectionRegion mRegion;
+    nsIPresShell::ScrollAxis mVerticalScroll;
+    nsIPresShell::ScrollAxis mHorizontalScroll;
+    bool mFirstAncestorOnly;
+  };
+
+  void setAnchorFocusRange(PRInt32 aIndex); // pass in index into mRanges;
+                                            // negative value clears
+                                            // mAnchorFocusRange
+  nsresult     SelectAllFramesForContent(nsIContentIterator *aInnerIter,
+                               nsIContent *aContent,
+                               bool aSelected);
+  nsresult     selectFrames(nsPresContext* aPresContext, nsRange *aRange, bool aSelect);
+  nsresult     getTableCellLocationFromRange(nsRange *aRange, PRInt32 *aSelectionType, PRInt32 *aRow, PRInt32 *aCol);
+  nsresult     addTableCellRange(nsRange *aRange, bool *aDidAddRange, PRInt32 *aOutIndex);
+
+  nsresult FindInsertionPoint(
+      nsTArray<RangeData>* aElementArray,
+      nsINode* aPointNode, PRInt32 aPointOffset,
+      nsresult (*aComparator)(nsINode*,PRInt32,nsRange*,PRInt32*),
+      PRInt32* aPoint);
+  bool EqualsRangeAtPoint(nsINode* aBeginNode, PRInt32 aBeginOffset,
+                            nsINode* aEndNode, PRInt32 aEndOffset,
+                            PRInt32 aRangeIndex);
+  void GetIndicesForInterval(nsINode* aBeginNode, PRInt32 aBeginOffset,
+                             nsINode* aEndNode, PRInt32 aEndOffset,
+                             bool aAllowAdjacent,
+                             PRInt32 *aStartIndex, PRInt32 *aEndIndex);
+  RangeData* FindRangeData(nsIDOMRange* aRange);
+
+  // These are the ranges inside this selection. They are kept sorted in order
+  // of DOM start position.
+  //
+  // This data structure is sorted by the range beginnings. As the ranges are
+  // disjoint, it is also implicitly sorted by the range endings. This allows
+  // us to perform binary searches when searching for existence of a range,
+  // giving us O(log n) search time.
+  //
+  // Inserting a new range requires finding the overlapping interval, requiring
+  // two binary searches plus up to an additional 6 DOM comparisons. If this
+  // proves to be a performance concern, then an interval tree may be a
+  // possible solution, allowing the calculation of the overlap interval in
+  // O(log n) time, though this would require rebalancing and other overhead.
+  nsTArray<RangeData> mRanges;
+
+  nsRefPtr<nsRange> mAnchorFocusRange;
+  nsRefPtr<nsFrameSelection> mFrameSelection;
+  nsWeakPtr mPresShellWeak;
+  nsRefPtr<nsAutoScrollTimer> mAutoScrollTimer;
+  nsCOMArray<nsISelectionListener> mSelectionListeners;
+  nsRevocableEventPtr<ScrollSelectionIntoViewEvent> mScrollEvent;
+  CachedOffsetForFrame *mCachedOffsetForFrame;
+  nsDirection mDirection;
+  SelectionType mType;
+};
+
+#endif // nsTypedSelection_h
--- a/layout/generic/test/test_bug632379.xul
+++ b/layout/generic/test/test_bug632379.xul
@@ -175,20 +175,21 @@ function snapshot(elem)
 {
     pos[count] = elem.getBoundingClientRect().top;
     ++count;
     if (count <= 1) {
         // close the submenu and open the bottom submenu
         synthesizeKey("VK_LEFT", {});
         synthesizeKey("9", {});
     } else {
-        // Bug 668716: This test fails on Mac since it was ported to chrome
-        (navigator.platform.indexOf("Mac") == -1 ? is : todo_is)(
-            pos[1], pos[0], "Popup should open in the same place when the menu is scrolled"
-        );
+        if (navigator.platform.indexOf("Mac") == -1) {
+            is(pos[1], pos[0], "Popup should open in the same place when the menu is scrolled");
+        } else {
+            todo(false, "This test fails on Mac since it was ported to chrome: Bug 668716.");
+        }
         SimpleTest.finish();
     }
 }
 
 function doTest() {
     // open the top-level menu
     $("mainMenu").open = true;
 }
--- a/layout/reftests/svg/smil/anim-filter-primitive-size-01.svg
+++ b/layout/reftests/svg/smil/anim-filter-primitive-size-01.svg
@@ -1,14 +1,24 @@
 <svg xmlns="http://www.w3.org/2000/svg"
      xmlns:xlink="http://www.w3.org/1999/xlink"
-     class="reftest-wait"
-     onload="setTimeAndSnapshot(1, true)">
+     class="reftest-wait">
   <title>Test animation of the "width" and "height" attributes of a filter primitive element</title>
   <script xlink:href="smil-util.js" type="text/javascript"/>
+  <script>
+
+window.addEventListener("MozReftestInvalidate", run, false);
+
+setTimeout(run, 3000); // for non-gecko
+
+function run() {
+  setTimeAndSnapshot(1, true)
+}
+
+  </script>
   <filter id="flood_filter" x="0%" y="0%" width="100%" height="100%">
     <feFlood width="0%" height="0%" flood-color="lime">
       <animate attributeName="width"
                calcMode="linear"
                begin="0s" dur="2s"
                from="0%" to="200%"
                fill="freeze"/>
       <animate attributeName="height"
--- a/layout/reftests/svg/smil/anim-filter-size-01.svg
+++ b/layout/reftests/svg/smil/anim-filter-size-01.svg
@@ -1,14 +1,24 @@
 <svg xmlns="http://www.w3.org/2000/svg"
      xmlns:xlink="http://www.w3.org/1999/xlink"
-     class="reftest-wait"
-     onload="setTimeAndSnapshot(1, true)">
+     class="reftest-wait">
   <title>Test animation of the "width" and "height" attributes of the "filter" element</title>
   <script xlink:href="smil-util.js" type="text/javascript"/>
+  <script>
+
+window.addEventListener("MozReftestInvalidate", run, false);
+
+setTimeout(run, 3000); // for non-gecko
+
+function run() {
+  setTimeAndSnapshot(1, true)
+}
+
+  </script>
   <filter id="flood_filter" x="0%" y="0%" width="0%" height="0%">
     <animate attributeName="width"
              calcMode="linear"
              begin="0s" dur="2s"
              from="0%" to="200%"
              fill="freeze"/>
     <animate attributeName="height"
              calcMode="linear"
--- a/layout/reftests/transform-3d/reftest.list
+++ b/layout/reftests/transform-3d/reftest.list
@@ -3,17 +3,17 @@
 # Check that scaleZ(-1) rotateX(180deg) is the same as rotateY(180deg)
 == scalezrotatex-1.html scalezrotatex-1-ref.html
 # Check that the perspectve() transform function results in some visual changes
 != rotatex-perspective-1a.html rotatex-1-ref.html
 # Check that -moz-perspective results in visual changes to child transformed elements
 != rotatex-perspective-1b.html rotatex-1-ref.html
 # -moz-perspective should only apply to child elements
 == rotatex-perspective-1c.html rotatex-1-ref.html
-== rotatex-perspective-3a.html rotatex-perspective-3-ref.html
+fails-if(Android) == rotatex-perspective-3a.html rotatex-perspective-3-ref.html # bug 755543
 == scalez-1a.html scalez-1-ref.html
 fails-if(cocoaWidget) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == preserve3d-1a.html preserve3d-1-ref.html
 == preserve3d-1b.html about:blank
 == preserve3d-clipped.html about:blank 
 == preserve3d-2a.html preserve3d-2-ref.html
 == preserve3d-2b.html preserve3d-2-ref.html
 == preserve3d-2c.html preserve3d-2-ref.html
 == preserve3d-2d.html preserve3d-2-ref.html
--- a/layout/svg/base/src/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/base/src/nsSVGForeignObjectFrame.cpp
@@ -388,20 +388,20 @@ nsSVGForeignObjectFrame::UpdateBounds()
   float x, y, w, h;
   static_cast<nsSVGForeignObjectElement*>(mContent)->
     GetAnimatedLengthValues(&x, &y, &w, &h, nsnull);
 
   // If mRect's width or height are negative, reflow blows up! We must clamp!
   if (w < 0.0f) w = 0.0f;
   if (h < 0.0f) h = 0.0f;
 
+  mRect = nsLayoutUtils::RoundGfxRectToAppRect(
+                           gfxRect(x, y, w, h),
+                           PresContext()->AppUnitsPerCSSPixel());
   // GetCanvasTM includes the x,y translation
-  mRect = nsLayoutUtils::RoundGfxRectToAppRect(
-                           gfxRect(0.0, 0.0, w, h),
-                           PresContext()->AppUnitsPerCSSPixel());
   mCoveredRegion = ToCanvasBounds(gfxRect(0.0, 0.0, w, h), GetCanvasTM(), PresContext());
 
   // Since we'll invalidate our entire area at the end of this method, we
   // empty our cached dirty regions to prevent FlushDirtyRegion under DoReflow
   // from wasting time invalidating:
   mSameDocDirtyRegion.SetEmpty();
   mSubDocDirtyRegion.SetEmpty();
 
@@ -623,17 +623,17 @@ nsSVGForeignObjectFrame::DoReflow()
 void
 nsSVGForeignObjectFrame::InvalidateDirtyRect(nsSVGOuterSVGFrame* aOuter,
     const nsRect& aRect, PRUint32 aFlags)
 {
   if (aRect.IsEmpty())
     return;
 
   // Don't invalidate areas outside our bounds:
-  nsRect rect = aRect.Intersect(mRect);
+  nsRect rect = aRect.Intersect(nsRect(nsPoint(0,0), mRect.Size()));
   if (rect.IsEmpty())
     return;
 
   // The areas dirtied by children are in app units, relative to this frame.
   // We need to convert the rect from app units in our userspace to app units
   // relative to our nsSVGOuterSVGFrame's content rect.
 
   gfxRect r(aRect.x, aRect.y, aRect.width, aRect.height);
--- a/layout/svg/base/src/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/base/src/nsSVGOuterSVGFrame.cpp
@@ -396,21 +396,16 @@ nsSVGOuterSVGFrame::Reflow(nsPresContext
 
   aDesiredSize.width  = aReflowState.ComputedWidth() +
                           aReflowState.mComputedBorderPadding.LeftRight();
   aDesiredSize.height = aReflowState.ComputedHeight() +
                           aReflowState.mComputedBorderPadding.TopBottom();
 
   NS_ASSERTION(!GetPrevInFlow(), "SVG can't currently be broken across pages.");
 
-  // Make sure we scroll if we're too big:
-  // XXX Use the bounding box of our descendants? (See bug 353460 comment 14.)
-  aDesiredSize.SetOverflowAreasToDesiredBounds();
-  FinishAndStoreOverflow(&aDesiredSize);
-
   // If our SVG viewport has changed, update our content and notify.
   // http://www.w3.org/TR/SVG11/coords.html#ViewportSpace
 
   svgFloatSize newViewportSize(
     nsPresContext::AppUnitsToFloatCSSPixels(aReflowState.ComputedWidth()),
     nsPresContext::AppUnitsToFloatCSSPixels(aReflowState.ComputedHeight()));
 
   nsSVGSVGElement *svgElem = static_cast<nsSVGSVGElement*>(mContent);
@@ -424,38 +419,18 @@ nsSVGOuterSVGFrame::Reflow(nsPresContext
     changeBits |= TRANSFORM_CHANGED;
     mFullZoom = PresContext()->GetFullZoom();
   }
   mViewportInitialized = true;
   if (changeBits) {
     NotifyViewportOrTransformChanged(changeBits);
   }
 
-  NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
-                  ("exit nsSVGOuterSVGFrame::Reflow: size=%d,%d",
-                  aDesiredSize.width, aDesiredSize.height));
-  NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsSVGOuterSVGFrame::DidReflow(nsPresContext*   aPresContext,
-                              const nsHTMLReflowState*  aReflowState,
-                              nsDidReflowStatus aStatus)
-{
-  bool firstReflow = (GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
-
-  nsresult rv = nsSVGOuterSVGFrameBase::DidReflow(aPresContext,aReflowState,aStatus);
-
-  if (firstReflow) {
-    // Temporarily add back the NS_FRAME_FIRST_REFLOW bit to indicate
-    // to the children that we are still to receive the invalidation
-    // for our first reflow:
-    AddStateBits(NS_FRAME_FIRST_REFLOW);
-  }
+  // Now that we've marked the necessary children as dirty, call
+  // UpdateBounds() on them:
 
 #ifdef DEBUG
   mCallingUpdateBounds = true;
 #endif
 
   if (!(mState & NS_STATE_SVG_NONDISPLAY_CHILD)) {
     nsIFrame* kid = mFrames.FirstChild();
     while (kid) {
@@ -466,20 +441,34 @@ nsSVGOuterSVGFrame::DidReflow(nsPresCont
       kid = kid->GetNextSibling();
     }
   }
 
 #ifdef DEBUG
   mCallingUpdateBounds = false;
 #endif
 
-  if (firstReflow) {
-    // And now remove it again:
-    RemoveStateBits(NS_FRAME_FIRST_REFLOW);
-  }
+  // Make sure we scroll if we're too big:
+  // XXX Use the bounding box of our descendants? (See bug 353460 comment 14.)
+  aDesiredSize.SetOverflowAreasToDesiredBounds();
+  FinishAndStoreOverflow(&aDesiredSize);
+
+  NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
+                  ("exit nsSVGOuterSVGFrame::Reflow: size=%d,%d",
+                  aDesiredSize.width, aDesiredSize.height));
+  NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSVGOuterSVGFrame::DidReflow(nsPresContext*   aPresContext,
+                              const nsHTMLReflowState*  aReflowState,
+                              nsDidReflowStatus aStatus)
+{
+  nsresult rv = nsSVGOuterSVGFrameBase::DidReflow(aPresContext,aReflowState,aStatus);
 
   // Make sure elements styled by :hover get updated if script/animation moves
   // them under or out from under the pointer:
   PresContext()->PresShell()->SynthesizeMouseMove(false);
 
   return rv;
 }
 
--- a/layout/xul/base/src/nsScrollBoxObject.cpp
+++ b/layout/xul/base/src/nsScrollBoxObject.cpp
@@ -85,23 +85,17 @@ nsScrollBoxObject::~nsScrollBoxObject()
 }
 
 /* void scrollTo (in long x, in long y); */
 NS_IMETHODIMP nsScrollBoxObject::ScrollTo(PRInt32 x, PRInt32 y)
 {
   nsIScrollableFrame* sf = GetScrollFrame();
   if (!sf)
     return NS_ERROR_FAILURE;
-
-  nsPoint pt(nsPresContext::CSSPixelsToAppUnits(x),
-             nsPresContext::CSSPixelsToAppUnits(y));
-  nscoord halfPixel = nsPresContext::CSSPixelsToAppUnits(0.5f);
-  // Don't allow pt.x/y + halfPixel since that would round up to the next CSS pixel.
-  nsRect range(pt.x - halfPixel, pt.y - halfPixel, halfPixel*2 - 1, halfPixel*2 - 1);
-  sf->ScrollTo(pt, nsIScrollableFrame::INSTANT, &range);
+  sf->ScrollToCSSPixels(nsIntPoint(x, y));
   return NS_OK;
 }
 
 /* void scrollBy (in long dx, in long dy); */
 NS_IMETHODIMP nsScrollBoxObject::ScrollBy(PRInt32 dx, PRInt32 dy)
 {
   PRInt32 x, y;
   nsresult rv = GetPosition(&x, &y);
--- a/media/libvpx/vpx_config.h
+++ b/media/libvpx/vpx_config.h
@@ -1,11 +1,15 @@
 #if defined(VPX_X86_ASM)
 
-#if defined(_WIN32) && !defined(__GNUC__) && defined(_M_IX86)
+#if defined(_WIN64)
+/* 64 bit Windows */
+#include "vpx_config_x86_64-win64-vs8.h"
+
+#elif defined(_WIN32)
 /* 32 bit Windows, MSVC. */
 #include "vpx_config_x86-win32-vs8.h"
 
 #elif defined(__APPLE__) && defined(__x86_64__)
 /* 64 bit MacOS. */
 #include "vpx_config_x86_64-darwin9-gcc.h"
 
 #elif defined(__APPLE__) && defined(__i386__)
@@ -23,20 +27,16 @@
 #elif defined(__sun) && defined(__i386)
 /* 32 bit Solaris. */
 #include "vpx_config_x86-linux-gcc.h"
 
 #elif defined(__sun) && defined(__x86_64)
 /* 64 bit Solaris. */
 #include "vpx_config_x86_64-linux-gcc.h"
 
-#elif defined(_MSC_VER) && defined(_M_X64)
-/* 64 bit Windows */
-#include "vpx_config_x86_64-win64-vs8.h"
-
 #else
 #error VPX_X86_ASM is defined, but assembly not supported on this platform!
 #endif
 
 #elif defined(VPX_ARM_ASM)
 
 #if defined(__linux__) && defined(__GNUC__)
 /* ARM Linux */
--- a/media/libvpx/vpx_config_c.c
+++ b/media/libvpx/vpx_config_c.c
@@ -1,11 +1,14 @@
 #if defined(VPX_X86_ASM)
 
-#if defined(WIN32) && !defined(__GNUC__) && !defined(_M_X64)
+#if defined(_WIN64)
+#include "vpx_config_x86_64-win64-vs8.c"
+
+#elif defined(WIN32)
 /* 32 bit Windows, MSVC. */
 #include "vpx_config_x86-win32-vs8.c"
 
 #elif defined(__APPLE__) && defined(__x86_64__)
 /* 64 bit MacOS. */
 #include "vpx_config_x86_64-darwin9-gcc.c"
 
 #elif defined(__APPLE__) && defined(__i386__)
@@ -23,19 +26,16 @@
 #elif defined(__sun) && defined(__i386)
 /* 32 bit Solaris. */
 #include "vpx_config_x86-linux-gcc.h"
 
 #elif defined(__sun) && defined(__x86_64)
 /* 64 bit Solaris. */
 #include "vpx_config_x86_64-linux-gcc.h"
 
-#elif defined(_MSC_VER) && defined(_M_X64)
-#include "vpx_config_x86_64-win64-vs8.c"
-
 #else
 #error VPX_X86_ASM is defined, but assembly not supported on this platform!
 #endif
 
 #elif defined(VPX_ARM_ASM)
 
 #if defined(__linux__) && defined(__GNUC__)
 #include "vpx_config_arm-linux-gcc.c"
--- a/media/libvpx/vpx_config_x86-win32-vs8.h
+++ b/media/libvpx/vpx_config_x86-win32-vs8.h
@@ -22,32 +22,41 @@
 #define HAVE_MMX 1
 #define HAVE_SSE 1
 #define HAVE_SSE2 1
 #define HAVE_SSE3 1
 #define HAVE_SSSE3 1
 #define HAVE_SSE4_1 1
 #define HAVE_ALTIVEC 0
 #define HAVE_VPX_PORTS 1
+#ifndef HAVE_STDINT_H
 #define HAVE_STDINT_H 0
+#endif
 #define HAVE_ALT_TREE_LAYOUT 0
 #define HAVE_PTHREAD_H 0
 #define HAVE_SYS_MMAN_H 0
+#ifndef HAVE_UNISTD_H
 #define HAVE_UNISTD_H 0
+#endif
 #define CONFIG_EXTERNAL_BUILD 1
 #define CONFIG_INSTALL_DOCS 0
 #define CONFIG_INSTALL_BINS 1
 #define CONFIG_INSTALL_LIBS 1
 #define CONFIG_INSTALL_SRCS 0
 #define CONFIG_DEBUG 0
 #define CONFIG_GPROF 0
 #define CONFIG_GCOV 0
 #define CONFIG_RVCT 0
+#ifdef _MSC_VER
 #define CONFIG_GCC 0
 #define CONFIG_MSVS 1
+#else
+#define CONFIG_GCC 1
+#define CONFIG_MSVS 0
+#endif
 #define CONFIG_PIC 0
 #define CONFIG_BIG_ENDIAN 0
 #define CONFIG_CODEC_SRCS 0
 #define CONFIG_DEBUG_LIBS 0
 #define CONFIG_FAST_UNALIGNED 1
 #define CONFIG_MEM_MANAGER 0
 #define CONFIG_MEM_TRACKER 0
 #define CONFIG_MEM_CHECKS 0
--- a/media/libvpx/vpx_config_x86_64-win64-vs8.h
+++ b/media/libvpx/vpx_config_x86_64-win64-vs8.h
@@ -22,32 +22,41 @@
 #define HAVE_MMX 1
 #define HAVE_SSE 1
 #define HAVE_SSE2 1
 #define HAVE_SSE3 1
 #define HAVE_SSSE3 1
 #define HAVE_SSE4_1 1
 #define HAVE_ALTIVEC 0
 #define HAVE_VPX_PORTS 1
+#ifndef HAVE_STDINT_H
 #define HAVE_STDINT_H 0
+#endif
 #define HAVE_ALT_TREE_LAYOUT 0
 #define HAVE_PTHREAD_H 0
 #define HAVE_SYS_MMAN_H 0
+#ifndef HAVE_UNISTD_H
 #define HAVE_UNISTD_H 0
+#endif
 #define CONFIG_EXTERNAL_BUILD 1
 #define CONFIG_INSTALL_DOCS 0
 #define CONFIG_INSTALL_BINS 1
 #define CONFIG_INSTALL_LIBS 1
 #define CONFIG_INSTALL_SRCS 0
 #define CONFIG_DEBUG 0
 #define CONFIG_GPROF 0
 #define CONFIG_GCOV 0
 #define CONFIG_RVCT 0
+#ifdef _MSC_VER
 #define CONFIG_GCC 0
 #define CONFIG_MSVS 1
+#else
+#define CONFIG_GCC 1
+#define CONFIG_MSVS 0
+#endif
 #define CONFIG_PIC 0
 #define CONFIG_BIG_ENDIAN 0
 #define CONFIG_CODEC_SRCS 0
 #define CONFIG_DEBUG_LIBS 0
 #define CONFIG_FAST_UNALIGNED 1
 #define CONFIG_MEM_MANAGER 0
 #define CONFIG_MEM_TRACKER 0
 #define CONFIG_MEM_CHECKS 0
--- a/mobile/android/base/ProfileMigrator.java
+++ b/mobile/android/base/ProfileMigrator.java
@@ -137,16 +137,24 @@ public class ProfileMigrator {
     // Find the Mobile bookmarks root in places (bug 746860).
     // We cannot rely on the name as that is locale-dependent.
     // If it exists, it will have Id=6, fk=null, type=folder.
     private static final String MOBILE_ROOT_QUERY =
         "SELECT id FROM moz_bookmarks " +
         "WHERE id=6 AND type=2 AND fk IS NULL AND parent=1";
     private static final String MOBILE_ROOT_ID = "id";
 
+    // Do not migrate about URLs that we may not support,
+    // and do not migrate links to the XUL addons page.
+    private static final String FILTER_BLACKLISTED_BOOKMARKS =
+        "AND (places.url IS NULL OR (" +
+        "(places.url NOT LIKE 'about:%') AND " +
+        "(places.url NOT LIKE 'https://addons.mozilla.org/%/mobile%')" +
+        "))";
+
     private static final String BOOKMARK_QUERY_SELECT =
         "SELECT places.url             AS p_url,"         +
         "       bookmark.guid          AS b_guid,"        +
         "       bookmark.id            AS b_id,"          +
         "       bookmark.title         AS b_title,"       +
         "       bookmark.type          AS b_type,"        +
         "       bookmark.parent        AS b_parent,"      +
         "       bookmark.dateAdded     AS b_added,"       +
@@ -160,16 +168,17 @@ public class ProfileMigrator {
         "        ON keyword.id = bookmark.keyword_id) "   +
         "       LEFT OUTER JOIN moz_places AS places "    +
         "       ON places.id = bookmark.fk) "             +
         "      LEFT OUTER JOIN moz_favicons AS favicon "  +
         "      ON places.favicon_id = favicon.id) "       +
         // Bookmark folders don't have a places entry.
         "WHERE (places.hidden IS NULL "                   +
         "       OR places.hidden <> 1) "                  +
+        FILTER_BLACKLISTED_BOOKMARKS                      +
         // This gives us a better chance of adding a folder before
         // adding its contents and hence avoiding extra iterations below.
         "ORDER BY bookmark.id";
 
     private static final String BOOKMARK_QUERY_GUID =
         BOOKMARK_QUERY_SELECT                             +
         "       favicon.data           AS f_data,"        +
         "       favicon.mime_type      AS f_mime_type,"   +
--- a/mobile/android/base/locales/en-US/sync_strings.dtd
+++ b/mobile/android/base/locales/en-US/sync_strings.dtd
@@ -41,16 +41,17 @@
 <!-- Setup Success -->
 <!ENTITY sync.title.success.label 'Setup Complete'>
 <!ENTITY sync.subtitle.success.label 'Your data is now being downloaded in the background. You can go to Settings to manage your account.'>
 <!ENTITY sync.settings.label 'Settings'>
 <!ENTITY sync.subtitle.manage.label 'Your &syncBrand.fullName.label; account is already set up. Go to Settings to manage your account.'>
 
 <!-- Pair Device -->
 <!ENTITY sync.pair.tryagain.label 'Please try again.'>
+<!ENTITY sync.pair.connectlocation.label 'To activate your new device, select “Set up &syncBrand.shortName.label;” on the device, and then select “I Have an Account.”'>
 
 <!-- Firefox SyncAdapter Settings Screen -->
 <!ENTITY sync.settings.options.label 'Options'>
 <!ENTITY sync.summary.pair.label 'Link another device to your &syncBrand.shortName.label; account'>
 
 <!-- Common text -->
 <!ENTITY sync.button.cancel.label 'Cancel'>
 <!ENTITY sync.button.connect.label 'Connect'>
--- a/mobile/android/base/resources/layout/sync_setup_pair.xml
+++ b/mobile/android/base/resources/layout/sync_setup_pair.xml
@@ -21,17 +21,17 @@
       android:gravity="center"
       android:padding="10dp" >
 
       <TextView
         android:id="@+id/setup_subtitle"
         style="@style/SyncTextItem"
         android:layout_marginTop="20dp"
         android:layout_marginBottom="10dp"
-        android:text="@string/sync_subtitle_connect" />
+        android:text="@string/sync_subtitle_pair" />
 
       <TextView
         style="@style/SyncLinkItem"
         android:layout_marginBottom="10dp"
         android:onClick="showClickHandler"
         android:text="@string/sync_link_show" />
 
       <LinearLayout
--- a/mobile/android/base/tests/PixelTest.java.in
+++ b/mobile/android/base/tests/PixelTest.java.in
@@ -13,16 +13,32 @@ class PixelTest extends BaseTest {
         PaintedSurface p = mDriver.getPaintedSurface();
         if (p == null) {
             mAsserter.ok(p != null, "checking that painted surface loaded", 
                  "painted surface loaded");
         }
         return p;
     }
 
+    protected final PaintedSurface reloadAndPaint() {
+        Actions.RepeatedEventExpecter paintExpecter = mActions.expectPaint();
+
+        mActions.sendSpecialKey(Actions.SpecialKey.MENU);
+        mSolo.waitForText("Reload");
+        mSolo.clickOnText("Reload");
+
+        paintExpecter.blockUntilClear(PAINT_CLEAR_DELAY);
+        PaintedSurface p = mDriver.getPaintedSurface();
+        if (p == null) {
+            mAsserter.ok(p != null, "checking that painted surface loaded", 
+                 "painted surface loaded");
+        }
+        return p;
+    }
+
     protected final PaintedSurface waitForPaint(Actions.RepeatedEventExpecter expecter) {
         expecter.blockUntilClear(PAINT_CLEAR_DELAY);
         PaintedSurface p = mDriver.getPaintedSurface();
         if (p == null) {
             mAsserter.ok(p != null, "checking that painted surface loaded", 
                  "painted surface loaded");
         }
         return p;
--- a/mobile/android/base/tests/robocop.ini
+++ b/mobile/android/base/tests/robocop.ini
@@ -9,16 +9,17 @@
 [testOverscroll]
 [testAxisLocking]
 [testAboutPage]
 [testWebContentContextMenu]
 [testPasswordProvider]
 [testPasswordEncrypt]
 [testFormHistory]
 [testBrowserProvider]
+[testPermissions]
 # [testJarReader] # see bug 738890
 
 # Used for Talos, please don't use in mochitest
 #[testPan]
 #[testCheck]
 #[testCheck2]
 #[testCheck3]
 #[testBrowserProviderPerf]
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/robocop_geolocation.html
@@ -0,0 +1,17 @@
+<html>
+<title>Geolocation Test Page</title>
+<body>
+<script>
+  function clb(position) {
+    // Show a green background if permission is granted
+    document.body.style.background = "#008000";
+  }
+  function err(error) {
+    // Show a red background if permission is denied
+    if (error.code == error.PERMISSION_DENIED)
+      document.body.style.background = "#FF0000";
+  }
+  navigator.geolocation.getCurrentPosition(clb, err, {timeout: 0});
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/testPermissions.java.in
@@ -0,0 +1,55 @@
+#filter substitution
+package @ANDROID_PACKAGE_NAME@.tests;
+
+import @ANDROID_PACKAGE_NAME@.*;
+
+import android.widget.CheckBox;
+import java.util.ArrayList;
+
+public class testPermissions extends PixelTest {
+    private PaintedSurface mPaintedSurface;
+    private Actions.RepeatedEventExpecter mPaintExpecter;
+
+    public void testPermissions() {
+        setTestType("mochitest");
+        mActions.expectGeckoEvent("Gecko:Ready").blockForEvent();
+
+        geolocationTest();
+    }
+
+    private void geolocationTest() {
+        // Test geolocation notification
+        mPaintedSurface = loadAndPaint(getAbsoluteUrl("/robocop/robocop_geolocation.html"));
+        mSolo.waitForText("wants your location");
+
+        // Uncheck the "Don't ask again for this site" checkbox
+        ArrayList<CheckBox> checkBoxes = mSolo.getCurrentCheckBoxes();
+        mAsserter.ok(checkBoxes.size() == 1, "checkbox count", "only one checkbox visible");
+        mAsserter.ok(mSolo.isCheckBoxChecked(0), "checkbox checked", "checkbox is checked");
+        mSolo.clickOnCheckBox(0);
+        mAsserter.ok(!mSolo.isCheckBoxChecked(0), "checkbox not checked", "checkbox is not checked");
+
+        // Test "Share" button functionality with unchecked checkbox
+        mPaintExpecter = mActions.expectPaint();
+        mSolo.clickOnText("Share");
+        mPaintedSurface = waitForPaint(mPaintExpecter);
+        mAsserter.ispixel(mPaintedSurface.getPixelAt(10, 10), 0, 0x80, 0, "checking page background is green");
+
+        // Re-trigger geolocation notification
+        reloadAndPaint();
+        mSolo.waitForText("wants your location");
+
+        // Make sure the checkbox is checked this time
+        mAsserter.ok(mSolo.isCheckBoxChecked(0), "checkbox checked", "checkbox is checked");
+
+        // Test "Share" button functionality with checked checkbox
+        mPaintExpecter = mActions.expectPaint();
+        mSolo.clickOnText("Share");
+        mPaintedSurface = waitForPaint(mPaintExpecter);
+        mAsserter.ispixel(mPaintedSurface.getPixelAt(10, 10), 0, 0x80, 0, "checking page background is green");
+
+        // When we reload the page, location should be automatically shared
+        mPaintedSurface = reloadAndPaint();
+        mAsserter.ispixel(mPaintedSurface.getPixelAt(10, 10), 0, 0x80, 0, "checking page background is green");
+    }
+}
--- a/mobile/android/components/ContentPermissionPrompt.js
+++ b/mobile/android/components/ContentPermissionPrompt.js
@@ -38,49 +38,18 @@
 const Ci = Components.interfaces;
 const Cr = Components.results;
 const Cu = Components.utils;
 const Cc = Components.classes;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
-const kCountBeforeWeRemember = 5;
-
-function dump(a) {
-    Cc["@mozilla.org/consoleservice;1"]
-        .getService(Ci.nsIConsoleService)
-        .logStringMessage(a);
-}
-
-function setPagePermission(type, uri, allow) {
-  let pm = Services.perms;
-  let contentPrefs = Services.contentPrefs;
-  let contentPrefName = type + ".request.remember";
-
-  if (!contentPrefs.hasPref(uri, contentPrefName))
-      contentPrefs.setPref(uri, contentPrefName, 0);
-
-  let count = contentPrefs.getPref(uri, contentPrefName);
-
-  if (allow == false)
-    count--;
-  else
-    count++;
-    
-  contentPrefs.setPref(uri, contentPrefName, count);
-  if (count == kCountBeforeWeRemember)
-    pm.add(uri, type, Ci.nsIPermissionManager.ALLOW_ACTION);
-  else if (count == -kCountBeforeWeRemember)
-    pm.add(uri, type, Ci.nsIPermissionManager.DENY_ACTION);
-}
-
-const kEntities = { "geolocation": "geolocation", "desktop-notification": "desktopNotification",
-                    "indexedDB": "offlineApps", "indexedDBQuota": "indexedDBQuota",
-                    "openWebappsManage": "openWebappsManage" };
+const kEntities = { "geolocation": "geolocation",
+                    "desktop-notification": "desktopNotification" };
 
 function ContentPermissionPrompt() {}
 
 ContentPermissionPrompt.prototype = {
   classID: Components.ID("{C6E8C44D-9F39-4AF7-BCC0-76E38A8310F5}"),
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]),
 
@@ -111,61 +80,55 @@ ContentPermissionPrompt.prototype = {
   getChromeForRequest: function getChromeForRequest(request) {
     if (request.window) {
       let requestingWindow = request.window.top;
       return this.getChromeWindow(requestingWindow).wrappedJSObject;
     }
     return request.element.ownerDocument.defaultView;
   },
 
-  getTabForRequest: function getTabForRequest(request) {
-    let chromeWin = this.getChromeForRequest(request);
-    if (request.window) {
-      let browser = chromeWin.BrowserApp.getBrowserForWindow(request.window);
-      let tabID = chromeWin.BrowserApp.getTabForBrowser(browser).id;
-      return tabID;
-    }
-    // Fix this if e10s is needed again
-    return null;
-  },
-
   prompt: function(request) {
-    // returns true if the request was handled
+    // Returns true if the request was handled
     if (this.handleExistingPermission(request))
        return;
 
-    let pm = Services.perms;
+    let chromeWin = this.getChromeForRequest(request);
+    let tab = chromeWin.BrowserApp.getTabForWindow(request.window);
+    if (!tab)
+      return;
+
     let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
-
     let entityName = kEntities[request.type];
 
-    let tabID = this.getTabForRequest(request);
-    let chromeWin = this.getChromeForRequest(request);
-
     let buttons = [{
       label: browserBundle.GetStringFromName(entityName + ".allow"),
-      accessKey: null,
-      callback: function(notification) {
-        setPagePermission(request.type, request.uri, true);
+      callback: function(aChecked) {
+        // If the user checked "Don't ask again", make a permanent exception
+        if (aChecked)
+          Services.perms.add(request.uri, request.type, Ci.nsIPermissionManager.ALLOW_ACTION);
+
         request.allow();
       }
     },
     {
       label: browserBundle.GetStringFromName(entityName + ".dontAllow"),
-      accessKey: null,
-      callback: function(notification) {
-        setPagePermission(request.type, request.uri, false);
+      callback: function(aChecked) {
+        // If the user checked "Don't ask again", make a permanent exception
+        if (aChecked)
+          Services.perms.add(request.uri, request.type, Ci.nsIPermissionManager.DENY_ACTION);
+
         request.cancel();
       }
     }];
 
     let message = browserBundle.formatStringFromName(entityName + ".wantsTo",
                                                      [request.uri.host], 1);
+    let options = { checkbox: browserBundle.GetStringFromName(entityName + ".dontAskAgain") };
 
     chromeWin.NativeWindow.doorhanger.show(message,
                                            entityName + request.uri.host,
-                                           buttons, tabID);
+                                           buttons, tab.id, options);
   }
 };
 
 
 //module initialization
 const NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentPermissionPrompt]);
new file mode 100644
--- /dev/null
+++ b/mobile/android/config/tooltool-manifests/android/releng.manifest
@@ -0,0 +1,1 @@
+[]
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -414,16 +414,18 @@
 @BINPATH@/components/Weave.js
 @BINPATH@/components/WeaveCrypto.manifest
 @BINPATH@/components/WeaveCrypto.js
 #endif
 @BINPATH@/components/TelemetryPing.js
 @BINPATH@/components/TelemetryPing.manifest
 @BINPATH@/components/Webapps.js
 @BINPATH@/components/Webapps.manifest
+@BINPATH@/components/AppsService.js
+@BINPATH@/components/AppsService.manifest
 
 ; Modules
 @BINPATH@/modules/*
 
 ; Safe Browsing
 @BINPATH@/components/nsURLClassifier.manifest
 @BINPATH@/components/nsUrlClassifierHashCompleter.js
 @BINPATH@/components/nsUrlClassifierListManager.js
--- a/mobile/android/locales/en-US/chrome/browser.properties
+++ b/mobile/android/locales/en-US/chrome/browser.properties
@@ -81,24 +81,30 @@ identity.ownerUnknown2=(unknown)
 geolocation.allow=Share
 geolocation.dontAllow=Don't share
 geolocation.alwaysAllow=Always Share
 geolocation.neverAllow=Never Share
 geolocation.wantsTo=%S wants your location.
 # LOCALIZATION NOTE (geolocation.shareLocation): Label that will be used in
 # site settings dialog.
 geolocation.shareLocation=Share Location
+# LOCALIZATION NOTE (geolocation.dontAskAgain): This label appears next to a
+# checkbox to indicate whether or not the user wants to make a permanent decision.
+geolocation.dontAskAgain=Don't ask again for this site
 
 # Desktop notification UI
 desktopNotification.allow=Allow
 desktopNotification.dontAllow=Don't allow
 desktopNotification.wantsTo=%S wants to use notifications.
 # LOCALIZATION NOTE (desktopNotification.useNotifications): Label that will be
 # used in site settings dialog.
 desktopNotification.useNotifications=Use Notifications
+# LOCALIZATION NOTE (desktopNotification.dontAskAgain): This label appears next to a
+# checkbox to indicate whether or not the user wants to make a permanent decision.
+desktopNotification.dontAskAgain=Don't ask again for this site
 
 # New Tab Popup
 # LOCALIZATION NOTE (newtabpopup): Semi-colon list of plural forms.
 # See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
 # #1 number of tabs
 newtabpopup.opened=New tab opened;#1 new tabs opened
 
 # Error Console
--- a/mobile/android/sync/strings.xml.in
+++ b/mobile/android/sync/strings.xml.in
@@ -1,16 +1,16 @@
   <string name="sync_app_name">&sync.app.name.label;</string>
   <string name="sync_title_connect">&sync.title.adddevice.label;</string>
   <string name="sync_title_pair">&sync.title.pair.label;</string>
 
   <!-- J-PAKE PIN Screen -->
   <string name="sync_subtitle_header">&sync.subtitle.header.label;</string>
   <string name="sync_subtitle_connect">&sync.subtitle.connectlocation.label;</string>
-  <string name="sync_subtitle_pair">&sync.subtitle.pair.label;</string>
+  <string name="sync_subtitle_pair">&sync.pair.connectlocation.label;</string>
   <string name="sync_pin_default">&sync.pin.oneline.label;</string>
   <string name="sync_link_show"><u>&sync.link.show.label;</u></string>
   <string name="sync_link_advancedsetup"><u>&sync.link.advancedsetup.label;</u></string>
 
   <!-- J-PAKE Waiting Screen -->
   
   <string name="sync_jpake_subtitle_waiting">&sync.jpake.subtitle.waiting.label;</string>
 
new file mode 100644
--- /dev/null
+++ b/mobile/xul/config/tooltool-manifests/android/releng.manifest
@@ -0,0 +1,1 @@
+[]
--- a/netwerk/protocol/http/SpdySession.cpp
+++ b/netwerk/protocol/http/SpdySession.cpp
@@ -402,18 +402,22 @@ SpdySession::ActivateStream(SpdyStream *
   LOG3(("SpdySession::AddStream %p activating stream %p Currently %d "
         "streams in session, high water mark is %d",
         this, stream, mConcurrent, mConcurrentHighWater));
 
   mReadyForWrite.Push(stream);
   SetWriteCallbacks();
 
   // Kick off the SYN transmit without waiting for the poll loop
-  PRUint32 countRead;
-  ReadSegments(nsnull, kDefaultBufferSize, &countRead);
+  // This won't work for stream id=1 because there is no segment reader
+  // yet.
+  if (mSegmentReader) {
+    PRUint32 countRead;
+    ReadSegments(nsnull, kDefaultBufferSize, &countRead);
+  }
 }
 
 void
 SpdySession::ProcessPending()
 {
   NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
 
   while (RoomForMoreConcurrent()) {
@@ -1384,16 +1388,22 @@ SpdySession::OnTransportStatus(nsITransp
 
 nsresult
 SpdySession::ReadSegments(nsAHttpSegmentReader *reader,
                           PRUint32 count,
                           PRUint32 *countRead)
 {
   NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
   
+  NS_ABORT_IF_FALSE(!mSegmentReader || !reader || (mSegmentReader == reader),
+                    "Inconsistent Write Function Callback");
+
+  if (reader)
+    mSegmentReader = reader;
+
   nsresult rv;
   *countRead = 0;
 
   // First priority goes to frames that were writing to the network but were
   // blocked part way through. Then to frames that have no streams (e.g ping
   // reply) and then third to streams marked urgent (generally they have
   // window updates), and finally to streams generally
   // ready to send data frames (http requests).
@@ -1410,21 +1420,16 @@ SpdySession::ReadSegments(nsAHttpSegment
           this));
     FlushOutputQueue();
     SetWriteCallbacks();
     return NS_BASE_STREAM_WOULD_BLOCK;
   }
   
   LOG3(("SpdySession %p will write from SpdyStream %p", this, stream));
 
-  NS_ABORT_IF_FALSE(!mSegmentReader || !reader || (mSegmentReader == reader),
-                    "Inconsistent Write Function Callback");
-
-  if (reader)
-    mSegmentReader = reader;
   rv = stream->ReadSegments(this, count, countRead);
 
   // Not every permutation of stream->ReadSegents produces data (and therefore
   // tries to flush the output queue) - SENDING_FIN_STREAM can be an example
   // of that. But we might still have old data buffered that would be good
   // to flush.
   FlushOutputQueue();
 
@@ -1444,16 +1449,18 @@ SpdySession::ReadSegments(nsAHttpSegment
       rv = NS_BASE_STREAM_WOULD_BLOCK;
     SetWriteCallbacks();
     return rv;
   }
   
   if (NS_FAILED(rv)) {
     LOG3(("SpdySession::ReadSegments %p returning FAIL code %X",
           this, rv));
+    if (rv != NS_BASE_STREAM_WOULD_BLOCK)
+      CleanupStream(stream, rv, RST_CANCEL);
     return rv;
   }
   
   if (*countRead > 0) {
     LOG3(("SpdySession::ReadSegments %p stream=%p generated end of frame %d",
           this, stream, *countRead));
     mReadyForWrite.Push(stream);
     SetWriteCallbacks();
--- a/netwerk/protocol/http/nsHttpPipeline.cpp
+++ b/netwerk/protocol/http/nsHttpPipeline.cpp
@@ -479,16 +479,19 @@ nsHttpPipeline::TakeSubTransactions(
     LOG(("nsHttpPipeline::TakeSubTransactions [this=%p]\n", this));
 
     if (mResponseQ.Length() || mRequestIsPartial)
         return NS_ERROR_ALREADY_OPENED;
 
     PRInt32 i, count = mRequestQ.Length();
     for (i = 0; i < count; ++i) {
         nsAHttpTransaction *trans = Request(i);
+        // set the transaction conneciton object back to the underlying
+        // nsHttpConnectionHandle
+        trans->SetConnection(mConnection);
         outTransactions.AppendElement(trans);
         NS_RELEASE(trans);
     }
     mRequestQ.Clear();
 
     LOG(("   took %d\n", count));
     return NS_OK;
 }
--- a/testing/marionette/client/marionette/emulator.py
+++ b/testing/marionette/client/marionette/emulator.py
@@ -1,13 +1,14 @@
 import datetime
 from mozprocess import ProcessHandlerMixin
 import multiprocessing
 import os
 import re
+import platform
 import shutil
 import socket
 import subprocess
 from telnetlib import Telnet
 import tempfile
 import time
 
 from emulator_battery import EmulatorBattery
@@ -27,27 +28,28 @@ class LogcatProc(ProcessHandlerMixin):
         f.write(line + "\n")
         f.flush()
 
 
 class Emulator(object):
 
     deviceRe = re.compile(r"^emulator-(\d+)(\s*)(.*)$")
 
-    def __init__(self, homedir=None, noWindow=False, logcat_dir=None, arch="x86"):
+    def __init__(self, homedir=None, noWindow=False, logcat_dir=None, arch="x86", emulatorBinary=None):
         self.port = None
         self._emulator_launched = False
         self.proc = None
         self.marionette_port = None
         self.telnet = None
         self._tmp_userdata = None
         self._adb_started = False
         self.logcat_dir = logcat_dir
         self.logcat_proc = None
         self.arch = arch
+        self.binary = emulatorBinary
         self.battery = EmulatorBattery(self)
         self.homedir = homedir
         self.noWindow = noWindow
         if self.homedir is not None:
             self.homedir = os.path.expanduser(homedir)
 
     def _check_for_b2g(self):
         if self.homedir is None:
@@ -59,32 +61,40 @@ class Emulator(object):
         oldstyle_homedir = os.path.join(self.homedir, 'glue/gonk-ics')
         if os.access(oldstyle_homedir, os.F_OK):
             self.homedir = oldstyle_homedir
 
         if self.arch not in ("x86", "arm"):
             raise Exception("Emulator architecture must be one of x86, arm, got: %s" %
                             self.arch)
 
+        host_dir = "linux-x86"
+        if platform.system() == "Darwin":
+            host_dir = "darwin-x86"
+
+        host_bin_dir = os.path.join("out/host", host_dir, "bin")
+
         if self.arch == "x86":
-            binary = "out/host/linux-x86/bin/emulator-x86"
+            binary = os.path.join(host_bin_dir, "emulator-x86")
             kernel = "prebuilts/qemu-kernel/x86/kernel-qemu"
             sysdir = "out/target/product/generic_x86"
             self.tail_args = []
         else:
-            binary = "out/host/linux-x86/bin/emulator"
+            binary = os.path.join(host_bin_dir, "emulator")
             kernel = "prebuilts/qemu-kernel/arm/kernel-qemu-armv7"
             sysdir = "out/target/product/generic"
             self.tail_args = ["-cpu", "cortex-a8"]
 
-        self.adb = os.path.join(self.homedir, 'out/host/linux-x86/bin/adb')
+        self.adb = os.path.join(self.homedir, host_bin_dir, "adb")
         if not os.access(self.adb, os.F_OK):
             self.adb = os.path.join(self.homedir, 'bin/adb')
 
-        self.binary = os.path.join(self.homedir, binary)
+        if not self.binary:
+            self.binary = os.path.join(self.homedir, binary)
+
         self._check_file(self.binary)
 
         self.kernelImg = os.path.join(self.homedir, kernel)
         self._check_file(self.kernelImg)
 
         self.sysDir = os.path.join(self.homedir, sysdir)
         self._check_file(self.sysDir)
 
--- a/testing/marionette/client/marionette/marionette.py
+++ b/testing/marionette/client/marionette/marionette.py
@@ -98,17 +98,17 @@ class HTMLElement(object):
 
 
 class Marionette(object):
 
     CONTEXT_CHROME = 'chrome'
     CONTEXT_CONTENT = 'content'
 
     def __init__(self, host='localhost', port=2828, b2gbin=False,
-                 emulator=None, connectToRunningEmulator=False,
+                 emulator=None, emulatorBinary=None, connectToRunningEmulator=False,
                  homedir=None, baseurl=None, noWindow=False, logcat_dir=None):
         self.host = host
         self.port = self.local_port = port
         self.b2gbin = b2gbin
         self.session = None
         self.window = None
         self.emulator = None
         self.extra_emulators = []
@@ -120,17 +120,18 @@ class Marionette(object):
         if b2gbin:
             self.b2ginstance = B2GInstance(host=self.host, port=self.port, b2gbin=self.b2gbin)
             self.b2ginstance.start()
             assert(self.b2ginstance.wait_for_port())
         if emulator:
             self.emulator = Emulator(homedir=homedir,
                                      noWindow=self.noWindow,
                                      logcat_dir=self.logcat_dir,
-                                     arch=emulator)
+                                     arch=emulator,
+                                     emulatorBinary=emulatorBinary)
             self.emulator.start()
             self.port = self.emulator.setup_port_forwarding(self.port)
             assert(self.emulator.wait_for_port())
 
         if connectToRunningEmulator:
             self.emulator = Emulator(homedir=homedir, logcat_dir=self.logcat_dir)
             self.emulator.connect()
             self.port = self.emulator.setup_port_forwarding(self.port)
--- a/testing/marionette/client/marionette/marionette_test.py
+++ b/testing/marionette/client/marionette/marionette_test.py
@@ -98,16 +98,17 @@ class MarionetteTestCase(CommonTestCase)
         self.marionette = marionette
         self.extra_emulator_index = -1
         CommonTestCase.__init__(self, methodName, **kwargs)
 
     def get_new_emulator(self):
         self.extra_emulator_index += 1
         if len(self.marionette.extra_emulators) == self.extra_emulator_index:
             qemu  = Marionette(emulator=self.marionette.emulator.arch,
+                               emulatorBinary=self.marionette.emulator.binary,
                                homedir=self.marionette.homedir,
                                baseurl=self.marionette.baseurl,
                                noWindow=self.marionette.noWindow)
             qemu.start_session()
             self.marionette.extra_emulators.append(qemu)
         else:
             qemu = self.marionette.extra_emulators[self.extra_emulator_index]
         return qemu
--- a/testing/marionette/client/marionette/runtests.py
+++ b/testing/marionette/client/marionette/runtests.py
@@ -125,22 +125,23 @@ class MarionetteTextTestRunner(unittest.
             self.stream.writeln(" (%s)" % (", ".join(infos),))
         else:
             self.stream.write("\n")
         return result
 
 
 class MarionetteTestRunner(object):
 
-    def __init__(self, address=None, emulator=None, homedir=None,
+    def __init__(self, address=None, emulator=None, emulatorBinary=None, homedir=None,
                  b2gbin=None, autolog=False, revision=None, es_server=None,
                  rest_server=None, logger=None, testgroup="marionette",
                  noWindow=False, logcat_dir=None):
         self.address = address
         self.emulator = emulator
+        self.emulatorBinary = emulatorBinary
         self.homedir = homedir
         self.b2gbin = b2gbin
         self.autolog = autolog
         self.testgroup = testgroup
         self.revision = revision
         self.es_server = es_server
         self.rest_server = rest_server
         self.logger = logger
@@ -196,16 +197,17 @@ class MarionetteTestRunner(object):
                                              b2gbin=self.b2gbin,
                                              baseurl=self.baseurl)
             else:
                 self.marionette = Marionette(host=host,
                                              port=int(port),
                                              baseurl=self.baseurl)
         elif self.emulator:
             self.marionette = Marionette(emulator=self.emulator,
+                                         emulatorBinary=self.emulatorBinary,
                                          homedir=self.homedir,
                                          baseurl=self.baseurl,
                                          noWindow=self.noWindow,
                                          logcat_dir=self.logcat_dir)
         else:
             raise Exception("must specify address or emulator")
 
     def post_to_autolog(self, elapsedtime):
@@ -353,16 +355,21 @@ if __name__ == "__main__":
     parser.add_option("--testgroup",
                       action = "store", dest = "testgroup",
                       help = "testgroup names for autolog submissions")
     parser.add_option("--emulator",
                       action = "store", dest = "emulator",
                       default = None, choices = ["x86", "arm"],
                       help = "Launch a B2G emulator on which to run tests. "
                       "You need to specify which architecture to emulate.")
+    parser.add_option("--emulator-binary",
+                      action = "store", dest = "emulatorBinary",
+                      default = None,
+                      help = "Launch a specific emulator binary rather than "
+                      "launching from the B2G built emulator")
     parser.add_option("--no-window",
                       action = "store_true", dest = "noWindow",
                       default = False,
                       help = "when Marionette launches an emulator, start it "
                       "with the -no-window argument")
     parser.add_option('--logcat-dir', dest='logcat_dir', action='store',
                       help='directory to store logcat dump files')
     parser.add_option('--address', dest='address', action='store',
@@ -394,16 +401,17 @@ if __name__ == "__main__":
         parser.exit()
 
     # default to storing logcat output for emulator runs
     if options.emulator and not options.logcat_dir:
         options.logcat_dir = 'logcat'
 
     runner = MarionetteTestRunner(address=options.address,
                                   emulator=options.emulator,
+                                  emulatorBinary=options.emulatorBinary,
                                   homedir=options.homedir,
                                   logcat_dir=options.logcat_dir,
                                   b2gbin=options.b2gbin,
                                   noWindow=options.noWindow,
                                   revision=options.revision,
                                   testgroup=options.testgroup,
                                   autolog=options.autolog)
     runner.run_tests(tests, testtype=options.type)
--- a/toolkit/components/ctypes/tests/unit/test_jsctypes.js.in
+++ b/toolkit/components/ctypes/tests/unit/test_jsctypes.js.in
@@ -663,16 +663,27 @@ function run_basic_abi_tests(library, t,
                                     ctypes.char.ptr);
   let hello = ctypes.char.array()("hello!");
   do_check_eq(charupper(hello).readString(), "HELLO!");
 #endif
 
   // Check the alignment of the type, and its behavior in a struct,
   // against what C says.
   check_struct_stats(library, t);
+  
+  // Check the ToSource functions defined in the namespace ABI
+  do_check_eq(ctypes.default_abi.toSource(), "ctypes.default_abi");
+
+  let exn;
+  try {
+    ctypes.default_abi.toSource.call(null);
+  } catch(x) {
+    exn = x;
+  }
+  do_check_true(!!exn); // Check that some exception was raised
 }
 
 function run_single_abi_tests(decl, abi, t, toprimitive,
                               get_test, set_tests, sum_tests, sum_many_tests) {
   let getter_t = ctypes.FunctionType(abi, t).ptr;
   let getter = decl(getter_t, "get_");
   do_check_eq(toprimitive(getter()), get_test);
 
--- a/toolkit/components/telemetry/Telemetry.cpp
+++ b/toolkit/components/telemetry/Telemetry.cpp
@@ -64,31 +64,31 @@ namespace {
 
 using namespace base;
 using namespace mozilla;
 
 template<class EntryType>
 class AutoHashtable : public nsTHashtable<EntryType>
 {
 public:
-  AutoHashtable(PRUint32 initSize = PL_DHASH_MIN_SIZE);
+  AutoHashtable(uint32_t initSize = PL_DHASH_MIN_SIZE);
   ~AutoHashtable();
   typedef bool (*ReflectEntryFunc)(EntryType *entry, JSContext *cx, JSObject *obj);
   bool ReflectHashtable(ReflectEntryFunc entryFunc, JSContext *cx, JSObject *obj);
 private:
   struct EnumeratorArgs {
     JSContext *cx;
     JSObject *obj;
     ReflectEntryFunc entryFunc;
   };
   static PLDHashOperator ReflectEntryStub(EntryType *entry, void *arg);
 };
 
 template<class EntryType>
-AutoHashtable<EntryType>::AutoHashtable(PRUint32 initSize)
+AutoHashtable<EntryType>::AutoHashtable(uint32_t initSize)
 {
   this->Init(initSize);
 }
 
 template<class EntryType>
 AutoHashtable<EntryType>::~AutoHashtable()
 {
   this->Clear();
@@ -110,58 +110,58 @@ AutoHashtable<EntryType>::ReflectEntrySt
  * some property and value of obj.  entryFunc is called for each entry.
  */
 template<typename EntryType>
 bool
 AutoHashtable<EntryType>::ReflectHashtable(ReflectEntryFunc entryFunc,
                                            JSContext *cx, JSObject *obj)
 {
   EnumeratorArgs args = { cx, obj, entryFunc };
-  PRUint32 num = this->EnumerateEntries(ReflectEntryStub, static_cast<void*>(&args));
+  uint32_t num = this->EnumerateEntries(ReflectEntryStub, static_cast<void*>(&args));
   return num == this->Count();
 }
 
 class TelemetryImpl : public nsITelemetry
 {
   NS_DECL_ISUPPORTS
   NS_DECL_NSITELEMETRY
 
 public:
   TelemetryImpl();
   ~TelemetryImpl();
   
   static bool CanRecord();
   static already_AddRefed<nsITelemetry> CreateTelemetryInstance();
   static void ShutdownTelemetry();
   static void RecordSlowStatement(const nsACString &sql, const nsACString &dbName,
-                                  PRUint32 delay, bool isDynamicString);
+                                  uint32_t delay, bool isDynamicString);
 #if defined(MOZ_ENABLE_PROFILER_SPS)
-  static void RecordChromeHang(PRUint32 duration,
+  static void RecordChromeHang(uint32_t duration,
                                const Telemetry::HangStack &callStack,
                                SharedLibraryInfo &moduleMap);
 #endif
   static nsresult GetHistogramEnumId(const char *name, Telemetry::ID *id);
   struct StmtStats {
-    PRUint32 hitCount;
-    PRUint32 totalTime;
+    uint32_t hitCount;
+    uint32_t totalTime;
     bool isDynamicSql;
     bool isTrackedDb;
     bool isAggregate;
   };
   typedef nsBaseHashtableET<nsCStringHashKey, StmtStats> SlowSQLEntryType;
   struct HangReport {
-    PRUint32 duration;
+    uint32_t duration;
     Telemetry::HangStack callStack;
 #if defined(MOZ_ENABLE_PROFILER_SPS)
     SharedLibraryInfo moduleMap;
 #endif
   };
 
 private:
-  static void StoreSlowSQL(const nsACString &offender, PRUint32 delay,
+  static void StoreSlowSQL(const nsACString &offender, uint32_t delay,
                            bool isDynamicSql, bool isTrackedDB, bool isAggregate);
 
   static bool ReflectPublicSql(SlowSQLEntryType *entry, JSContext *cx,
                                JSObject *obj);
   static bool ReflectPrivateSql(SlowSQLEntryType *entry, JSContext *cx,
                                 JSObject *obj);
   static bool ReflectSql(SlowSQLEntryType *entry, JSContext *cx, JSObject *obj);
 
@@ -171,20 +171,20 @@ private:
 
   // Like GetHistogramById, but returns the underlying C++ object, not the JS one.
   nsresult GetHistogramByName(const nsACString &name, Histogram **ret);
   bool ShouldReflectHistogram(Histogram *h);
   void IdentifyCorruptHistograms(StatisticsRecorder::Histograms &hs);
   typedef StatisticsRecorder::Histograms::iterator HistogramIterator;
 
   struct AddonHistogramInfo {
-    PRUint32 min;
-    PRUint32 max;
-    PRUint32 bucketCount;
-    PRUint32 histogramType;
+    uint32_t min;
+    uint32_t max;
+    uint32_t bucketCount;
+    uint32_t histogramType;
     Histogram *h;
   };
   typedef nsBaseHashtableET<nsCStringHashKey, AddonHistogramInfo> AddonHistogramEntryType;
   typedef AutoHashtable<AddonHistogramEntryType> AddonHistogramMapType;
   typedef nsBaseHashtableET<nsCStringHashKey, AddonHistogramMapType *> AddonEntryType;
   typedef AutoHashtable<AddonEntryType> AddonMapType;
   static bool AddonHistogramReflector(AddonHistogramEntryType *entry,
                                       JSContext *cx, JSObject *obj);
@@ -212,20 +212,20 @@ private:
 TelemetryImpl*  TelemetryImpl::sTelemetry = NULL;
 
 // A initializer to initialize histogram collection
 StatisticsRecorder gStatisticsRecorder;
 
 // Hardcoded probes
 struct TelemetryHistogram {
   const char *id;
-  PRUint32 min;
-  PRUint32 max;
-  PRUint32 bucketCount;
-  PRUint32 histogramType;
+  uint32_t min;
+  uint32_t max;
+  uint32_t bucketCount;
+  uint32_t histogramType;
   const char *comment;
 };
 
 // Perform the checks at the beginning of HistogramGet at compile time, so
 // that if people add incorrect histogram definitions, they get compiler
 // errors.
 #define HISTOGRAM(id, min, max, bucket_count, histogram_type, b) \
   MOZ_STATIC_ASSERT(nsITelemetry::HISTOGRAM_ ## histogram_type == nsITelemetry::HISTOGRAM_BOOLEAN || \
@@ -244,17 +244,17 @@ const TelemetryHistogram gHistograms[] =
 
 #include "TelemetryHistograms.h"
 
 #undef HISTOGRAM
 };
 bool gCorruptHistograms[Telemetry::HistogramCount];
 
 bool
-TelemetryHistogramType(Histogram *h, PRUint32 *result)
+TelemetryHistogramType(Histogram *h, uint32_t *result)
 {
   switch (h->histogram_type()) {
   case Histogram::HISTOGRAM:
     *result = nsITelemetry::HISTOGRAM_EXPONENTIAL;
     break;
   case Histogram::LINEAR_HISTOGRAM:
     *result = nsITelemetry::HISTOGRAM_LINEAR;
     break;
@@ -266,18 +266,18 @@ TelemetryHistogramType(Histogram *h, PRU
     break;
   default:
     return false;
   }
   return true;
 }
 
 nsresult
-HistogramGet(const char *name, PRUint32 min, PRUint32 max, PRUint32 bucketCount,
-             PRUint32 histogramType, Histogram **result)
+HistogramGet(const char *name, uint32_t min, uint32_t max, uint32_t bucketCount,
+             uint32_t histogramType, Histogram **result)
 {
   if (histogramType != nsITelemetry::HISTOGRAM_BOOLEAN
       && histogramType != nsITelemetry::HISTOGRAM_FLAG) {
     // Sanity checks for histogram parameters.
     if (min >= max)
       return NS_ERROR_ILLEGAL_VALUE;
 
     if (bucketCount <= 2)
@@ -531,17 +531,17 @@ mHangReportsMutex("Telemetry::mHangRepor
   mTrackedDBs.MarkImmutable();
 #endif
 }
 
 TelemetryImpl::~TelemetryImpl() {
 }
 
 NS_IMETHODIMP
-TelemetryImpl::NewHistogram(const nsACString &name, PRUint32 min, PRUint32 max, PRUint32 bucketCount, PRUint32 histogramType, JSContext *cx, jsval *ret)
+TelemetryImpl::NewHistogram(const nsACString &name, uint32_t min, uint32_t max, uint32_t bucketCount, uint32_t histogramType, JSContext *cx, jsval *ret)
 {
   Histogram *h;
   nsresult rv = HistogramGet(PromiseFlatCString(name).get(), min, max, bucketCount, histogramType, &h);
   if (NS_FAILED(rv))
     return rv;
   h->ClearFlags(Histogram::kUmaTargetedHistogramFlag);
   return WrapAndReturnHistogram(h, cx, ret);
 }
@@ -614,17 +614,17 @@ TelemetryImpl::GetHistogramEnumId(const 
   if (!sTelemetry) {
     return NS_ERROR_FAILURE;
   }
 
   // Cache names
   // Note the histogram names are statically allocated
   TelemetryImpl::HistogramMapType *map = &sTelemetry->mHistogramMap;
   if (!map->Count()) {
-    for (PRUint32 i = 0; i < Telemetry::HistogramCount; i++) {
+    for (uint32_t i = 0; i < Telemetry::HistogramCount; i++) {
       CharPtrEntryType *entry = map->PutEntry(gHistograms[i].id);
       if (NS_UNLIKELY(!entry)) {
         map->Clear();
         return NS_ERROR_OUT_OF_MEMORY;
       }
       entry->mData = (Telemetry::ID) i;
     }
   }
@@ -657,17 +657,17 @@ NS_IMETHODIMP
 TelemetryImpl::HistogramFrom(const nsACString &name, const nsACString &existing_name,
                              JSContext *cx, jsval *ret)
 {
   Histogram *existing;
   nsresult rv = GetHistogramByName(existing_name, &existing);
   if (NS_FAILED(rv))
     return rv;
 
-  PRUint32 histogramType;
+  uint32_t histogramType;
   bool success = TelemetryHistogramType(existing, &histogramType);
   if (!success)
     return NS_ERROR_INVALID_ARG;
 
   Histogram *clone;
   rv = HistogramGet(PromiseFlatCString(name).get(), existing->declared_min(),
                     existing->declared_max(), existing->bucket_count(),
                     histogramType, &clone);
@@ -754,19 +754,19 @@ AddonHistogramName(const nsACString &id,
   ret.Append(id);
   ret.Append(NS_LITERAL_CSTRING(":"));
   ret.Append(name);
 }
 
 NS_IMETHODIMP
 TelemetryImpl::RegisterAddonHistogram(const nsACString &id,
                                       const nsACString &name,
-                                      PRUint32 min, PRUint32 max,
-                                      PRUint32 bucketCount,
-                                      PRUint32 histogramType)
+                                      uint32_t min, uint32_t max,
+                                      uint32_t bucketCount,
+                                      uint32_t histogramType)
 {
   AddonEntryType *addonEntry = mAddonMap.GetEntry(id);
   if (!addonEntry) {
     addonEntry = mAddonMap.PutEntry(id);
     if (NS_UNLIKELY(!addonEntry)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
     addonEntry->mData = new AddonHistogramMapType();
@@ -1071,17 +1071,17 @@ TelemetryImpl::GetChromeHangs(JSContext 
       return NS_ERROR_FAILURE;
     }
     ok = JS_DefineProperty(cx, reportObj, "stack", OBJECT_TO_JSVAL(pcArray),
                            NULL, NULL, JSPROP_ENUMERATE);
     if (!ok) {
       return NS_ERROR_FAILURE;
     }
 
-    const PRUint32 pcCount = mHangReports[i].callStack.Length();
+    const uint32_t pcCount = mHangReports[i].callStack.Length();
     for (size_t pcIndex = 0; pcIndex < pcCount; ++pcIndex) {
       nsCAutoString pcString;
       pcString.AppendPrintf("0x%p", mHangReports[i].callStack[pcIndex]);
       JSString *str = JS_NewStringCopyZ(cx, pcString.get());
       if (!str) {
         return NS_ERROR_FAILURE;
       }
       jsval v = STRING_TO_JSVAL(str);
@@ -1098,17 +1098,17 @@ TelemetryImpl::GetChromeHangs(JSContext 
     ok = JS_DefineProperty(cx, reportObj, "memoryMap",
                            OBJECT_TO_JSVAL(moduleArray),
                            NULL, NULL, JSPROP_ENUMERATE);
     if (!ok) {
       return NS_ERROR_FAILURE;
     }
 
 #if defined(MOZ_ENABLE_PROFILER_SPS)
-    const PRUint32 moduleCount = mHangReports[i].moduleMap.GetSize();
+    const uint32_t moduleCount = mHangReports[i].moduleMap.GetSize();
     for (size_t moduleIndex = 0; moduleIndex < moduleCount; ++moduleIndex) {
       // Current module
       const SharedLibrary &module =
         mHangReports[i].moduleMap.GetEntry(moduleIndex);
 
       JSObject *moduleInfoArray = JS_NewArrayObject(cx, 0, nsnull);
       if (!moduleInfoArray) {
         return NS_ERROR_FAILURE;
@@ -1324,17 +1324,17 @@ TelemetrySessionData::GetSnapshots(JSCon
 
   *ret = OBJECT_TO_JSVAL(snapshots);
   return NS_OK;
 }
 
 bool
 TelemetrySessionData::DeserializeHistogramData(Pickle &pickle, void **iter)
 {
-  PRUint32 count = 0;
+  uint32_t count = 0;
   if (!pickle.ReadUInt32(iter, &count)) {
     return false;
   }
 
   for (size_t i = 0; i < count; ++i) {
     int stored_length;
     const char *name;
     if (!pickle.ReadData(iter, &name, &stored_length)) {
@@ -1382,34 +1382,34 @@ TelemetrySessionData::LoadFromDisk(nsIFi
   AutoFDClose fd;
   rv = f->OpenNSPRFileDesc(PR_RDONLY, 0, &fd.rwget());
   if (NS_FAILED(rv)) {
     return NS_ERROR_FAILURE;
   }
 
   // If there's not even enough data to read the header for the pickle,
   // don't bother.  Conveniently, this handles the error case as well.
-  PRInt32 size = PR_Available(fd);
-  if (size < static_cast<PRInt32>(sizeof(Pickle::Header))) {
+  int32_t size = PR_Available(fd);
+  if (size < static_cast<int32_t>(sizeof(Pickle::Header))) {
     return NS_ERROR_FAILURE;
   }
 
   nsAutoArrayPtr<char> data(new char[size]);
-  PRInt32 amount = PR_Read(fd, data, size);
+  int32_t amount = PR_Read(fd, data, size);
   if (amount != size) {
     return NS_ERROR_FAILURE;
   }
 
   Pickle pickle(data, size);
   void *iter = NULL;
 
   // Make sure that how much data the pickle thinks it has corresponds
   // with how much data we actually read.
   const Pickle::Header *header = pickle.headerT<Pickle::Header>();
-  if (header->payload_size != static_cast<PRUint32>(amount) - sizeof(*header)) {
+  if (header->payload_size != static_cast<uint32_t>(amount) - sizeof(*header)) {
     return NS_ERROR_FAILURE;
   }
 
   unsigned int storedVersion;
   if (!(pickle.ReadUInt32(&iter, &storedVersion)
         && storedVersion == sVersion)) {
     return NS_ERROR_FAILURE;
   }
@@ -1485,17 +1485,17 @@ TelemetrySessionData::SaveToDisk(nsIFile
   // Include the trailing NULL for the UUID to make reading easier.
   const char *data;
   size_t length = uuid.GetData(&data);
   if (!(pickle.WriteData(data, length+1)
         && SerializeHistogramData(pickle))) {
     return NS_ERROR_FAILURE;
   }
 
-  PRInt32 amount = PR_Write(fd, static_cast<const char*>(pickle.data()),
+  int32_t amount = PR_Write(fd, static_cast<const char*>(pickle.data()),
                             pickle.size());
   if (amount != pickle.size()) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
@@ -1613,17 +1613,17 @@ TelemetryImpl::CreateTelemetryInstance()
 
 void
 TelemetryImpl::ShutdownTelemetry()
 {
   NS_IF_RELEASE(sTelemetry);
 }
 
 void
-TelemetryImpl::StoreSlowSQL(const nsACString &sql, PRUint32 delay,
+TelemetryImpl::StoreSlowSQL(const nsACString &sql, uint32_t delay,
                             bool isDynamicSql, bool isTrackedDB, bool isAggregate)
 {
   AutoHashtable<SlowSQLEntryType> *slowSQLMap = NULL;
   if (NS_IsMainThread())
     slowSQLMap = &(sTelemetry->mSlowSQLOnMainThread);
   else
     slowSQLMap = &(sTelemetry->mSlowSQLOnOtherThread);
 
@@ -1643,17 +1643,17 @@ TelemetryImpl::StoreSlowSQL(const nsACSt
   }
 
   entry->mData.hitCount++;
   entry->mData.totalTime += delay;
 }
 
 void
 TelemetryImpl::RecordSlowStatement(const nsACString &sql, const nsACString &dbName,
-                                   PRUint32 delay, bool isDynamicString)
+                                   uint32_t delay, bool isDynamicString)
 {
   MOZ_ASSERT(sTelemetry);
   if (!sTelemetry->mCanRecord)
     return;
 
   bool isTrackedDb = sTelemetry->mTrackedDBs.Contains(dbName);
   bool isPrivate = (!isTrackedDb) || isDynamicString;
   if (isPrivate) {
@@ -1668,17 +1668,17 @@ TelemetryImpl::RecordSlowStatement(const
   nsCAutoString fullSql(sql);
   if (!isTrackedDb)
     fullSql.AppendPrintf(" -- Untracked DB %s", dbName.BeginReading());
   StoreSlowSQL(fullSql, delay, isDynamicString, isTrackedDb, false);
 }
 
 #if defined(MOZ_ENABLE_PROFILER_SPS)
 void
-TelemetryImpl::RecordChromeHang(PRUint32 duration,
+TelemetryImpl::RecordChromeHang(uint32_t duration,
                                 const Telemetry::HangStack &callStack,
                                 SharedLibraryInfo &moduleMap)
 {
   MOZ_ASSERT(sTelemetry);
   if (!sTelemetry->mCanRecord) {
     return;
   }
 
@@ -1729,32 +1729,32 @@ const Module kTelemetryModule = {
 };
 
 } // anonymous namespace
 
 namespace mozilla {
 namespace Telemetry {
 
 void
-Accumulate(ID aHistogram, PRUint32 aSample)
+Accumulate(ID aHistogram, uint32_t aSample)
 {
   if (!TelemetryImpl::CanRecord()) {
     return;
   }
   Histogram *h;
   nsresult rv = GetHistogramByEnumId(aHistogram, &h);
   if (NS_SUCCEEDED(rv))
     h->Add(aSample);
 }
 
 void
 AccumulateTimeDelta(ID aHistogram, TimeStamp start, TimeStamp end)
 {
   Accumulate(aHistogram,
-             static_cast<PRUint32>((end - start).ToMilliseconds()));
+             static_cast<uint32_t>((end - start).ToMilliseconds()));
 }
 
 bool
 CanRecord()
 {
   return TelemetryImpl::CanRecord();
 }
 
@@ -1764,32 +1764,32 @@ GetHistogramById(ID id)
   Histogram *h = NULL;
   GetHistogramByEnumId(id, &h);
   return h;
 }
 
 void
 RecordSlowSQLStatement(const nsACString &statement,
                        const nsACString &dbName,
-                       PRUint32 delay,
+                       uint32_t delay,
                        bool isDynamicString)
 {
   TelemetryImpl::RecordSlowStatement(statement, dbName, delay, isDynamicString);
 }
 
 void Init()
 {
   // Make the service manager hold a long-lived reference to the service
   nsCOMPtr<nsITelemetry> telemetryService =
     do_GetService("@mozilla.org/base/telemetry;1");
   MOZ_ASSERT(telemetryService);
 }
 
 #if defined(MOZ_ENABLE_PROFILER_SPS)
-void RecordChromeHang(PRUint32 duration,
+void RecordChromeHang(uint32_t duration,
                       const Telemetry::HangStack &callStack,
                       SharedLibraryInfo &moduleMap)
 {
   TelemetryImpl::RecordChromeHang(duration, callStack, moduleMap);
 }
 #endif
 
 } // namespace Telemetry
@@ -1797,12 +1797,12 @@ void RecordChromeHang(PRUint32 duration,
 
 NSMODULE_DEFN(nsTelemetryModule) = &kTelemetryModule;
 
 /**
  * The XRE_TelemetryAdd function is to be used by embedding applications
  * that can't use mozilla::Telemetry::Accumulate() directly.
  */
 void
-XRE_TelemetryAccumulate(int aID, PRUint32 aSample)
+XRE_TelemetryAccumulate(int aID, uint32_t aSample)
 {
   mozilla::Telemetry::Accumulate((mozilla::Telemetry::ID) aID, aSample);
 }
--- a/toolkit/crashreporter/tools/symbolstore.py
+++ b/toolkit/crashreporter/tools/symbolstore.py
@@ -54,16 +54,17 @@
 #     -s <srcdir>  : Use <srcdir> as the top source directory to
 #                    generate relative filenames.
 
 import sys
 import platform
 import os
 import re
 import shutil
+import textwrap
 from subprocess import call, Popen, PIPE, STDOUT
 from optparse import OptionParser
 
 # Utility classes
 
 class VCSFileInfo:
     """ A base class for version-controlled file information. Ensures that the
         following attributes are generated only once (successfully):
@@ -283,22 +284,28 @@ class HGFileInfo(VCSFileInfo):
             path = read_output('hg', '-R', srcdir,
                                'showconfig', 'paths.default')
             if path == '':
                 hg_root = os.environ.get("SRCSRV_ROOT")
                 if hg_root:
                     path = hg_root
                 else:
                     print >> sys.stderr, "Failed to get HG Repo for %s" % srcdir
+            cleanroot = None
             if path != '': # not there?
                 match = rootRegex.match(path)
                 if match:
                     cleanroot = match.group(1)
                     if cleanroot.endswith('/'):
                         cleanroot = cleanroot[:-1]
+            if cleanroot is None:
+                print >> sys.stderr, textwrap.dedent("""\
+                    Could not determine repo info for %s.  This is either not a clone of the web-based
+                    repository, or you have not specified SRCSRV_ROOT, or the clone is corrupt.""") % srcdir
+                sys.exit(1)
             HGRepoInfo.repos[srcdir] = HGRepoInfo(path, rev, cleanroot)
         self.repo = HGRepoInfo.repos[srcdir]
         self.file = file
         self.srcdir = srcdir
 
     def GetRoot(self):
         return self.repo.path
 
--- a/toolkit/locales/en-US/chrome/mozapps/plugins/plugins.dtd
+++ b/toolkit/locales/en-US/chrome/mozapps/plugins/plugins.dtd
@@ -18,17 +18,17 @@
 <!ENTITY pluginWizard.finalPage.description.label            "&brandShortName; finished installing the missing plugins:">
 
 <!ENTITY pluginWizard.finalPage.moreInfo.label               "Find out more about Plugins or manually find missing plugins.">
 <!ENTITY pluginWizard.finalPage.restart.label                "&brandShortName; needs to be restarted for the plugin(s) to work.">
 
 <!ENTITY missingPlugin                                       "A plugin is needed to display this content.">
 <!-- LOCALIZATION NOTE (tapToPlayPlugin): Mobile (used for touch interfaces) only has one type of plugin possible. -->
 <!ENTITY tapToPlayPlugin                                     "Tap here to activate plugin.">
-<!ENTITY clickToPlayPlugins                                  "Click here to activate plugins.">
+<!ENTITY clickToPlayPlugin                                   "Click here to activate plugin.">
 <!ENTITY disabledPlugin                                      "This plugin is disabled.">
 <!ENTITY blockedPlugin.label                                 "This plugin has been blocked for your protection.">
 
 <!ENTITY installPlugin                                       "Install plugin…">
 <!ENTITY managePlugins                                       "Manage plugins…">
 
 <!-- LOCALIZATION NOTE (reloadPlugin.pre): include a trailing space as needed -->
 <!-- LOCALIZATION NOTE (reloadPlugin.middle): avoid leading/trailing spaces, this text is a link -->
--- a/toolkit/mozapps/extensions/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/XPIProvider.jsm
@@ -270,16 +270,20 @@ SafeInstallOperation.prototype = {
       let entry;
       while (entry = entries.nextFile)
         cacheEntries.push(entry);
     }
     finally {
       entries.close();
     }
 
+    cacheEntries.sort(function(a, b) {
+      return a.path > b.path ? -1 : 1;
+    });
+
     cacheEntries.forEach(function(aEntry) {
       try {
         this._installDirEntry(aEntry, newDir, aCopy);
       }
       catch (e) {
         ERROR("Failed to " + (aCopy ? "copy" : "move") + " entry " +
               aEntry.path, e);
         throw e;
@@ -302,18 +306,35 @@ SafeInstallOperation.prototype = {
     }
 
     // Note we put the directory move in after all the file moves so the
     // directory is recreated before all the files are moved back
     this._installedFiles.push({ oldFile: aDirectory, newFile: newDir });
   },
 
   _installDirEntry: function(aDirEntry, aTargetDirectory, aCopy) {
+    let isDir = null;
+
     try {
-      if (aDirEntry.isDirectory())
+      isDir = aDirEntry.isDirectory();
+    }
+    catch (e) {
+      // If the file has already gone away then don't worry about it, this can
+      // happen on OSX where the resource fork is automatically moved with the
+      // data fork for the file. See bug 733436.
+      if (e.result == Cr.NS_ERROR_FILE_TARGET_DOES_NOT_EXIST)
+        return;
+
+      ERROR("Failure " + (aCopy ? "copying" : "moving") + " " + aDirEntry.path +
+            " to " + aTargetDirectory.path);
+      throw e;
+    }
+
+    try {
+      if (isDir)
         this._installDirectory(aDirEntry, aTargetDirectory, aCopy);
       else
         this._installFile(aDirEntry, aTargetDirectory, aCopy);
     }
     catch (e) {
       ERROR("Failure " + (aCopy ? "copying" : "moving") + " " + aDirEntry.path +
             " to " + aTargetDirectory.path);
       throw e;
@@ -1287,45 +1308,65 @@ function cleanStagingDir(aDir, aLeafName
 
 /**
  * Recursively removes a directory or file fixing permissions when necessary.
  *
  * @param  aFile
  *         The nsIFile to remove
  */
 function recursiveRemove(aFile) {
-  setFilePermissions(aFile, aFile.isDirectory() ? FileUtils.PERMS_DIRECTORY
-                                                : FileUtils.PERMS_FILE);
+  let isDir = null;
+
+  try {
+    isDir = aFile.isDirectory();
+  }
+  catch (e) {
+    // If the file has already gone away then don't worry about it, this can
+    // happen on OSX where the resource fork is automatically moved with the
+    // data fork for the file. See bug 733436.
+    if (e.result == Cr.NS_ERROR_FILE_TARGET_DOES_NOT_EXIST)
+      return;
+
+    throw e;
+  }
+
+  setFilePermissions(aFile, isDir ? FileUtils.PERMS_DIRECTORY
+                                  : FileUtils.PERMS_FILE);
 
   try {
     aFile.remove(true);
     return;
   }
   catch (e) {
     if (!aFile.isDirectory()) {
       ERROR("Failed to remove file " + aFile.path, e);
       throw e;
     }
   }
 
+  let entries = aFile.directoryEntries
+                     .QueryInterface(Ci.nsIDirectoryEnumerator);
+  let cacheEntries = [];
   let entry;
-  let dirEntries = aFile.directoryEntries.QueryInterface(Ci.nsIDirectoryEnumerator);
+  while (entry = entries.nextFile)
+    cacheEntries.push(entry);
+  entries.close();
+
+  cacheEntries.sort(function(a, b) {
+    return a.path > b.path ? -1 : 1;
+  });
+
+  cacheEntries.forEach(recursiveRemove);
+
   try {
-    while (entry = dirEntries.nextFile)
-      recursiveRemove(entry);
-    try {
-      aFile.remove(true);
-    }
-    catch (e) {
-      ERROR("Failed to remove empty directory " + aFile.path, e);
-      throw e;
-    }
+    aFile.remove(true);
   }
-  finally {
-    dirEntries.close();
+  catch (e) {
+    ERROR("Failed to remove empty directory " + aFile.path, e);
+    throw e;
   }
 }
 
 /**
  * Returns the timestamp of the most recently modified file in a directory,
  * or simply the file's own timestamp if it is not a directory.
  *
  * @param  aFile
@@ -2305,16 +2346,22 @@ var XPIProvider = {
       let newAddon = aManifests[aInstallLocation.name][aOldAddon.id];
 
       try {
         // If not load it
         if (!newAddon) {
           let file = aInstallLocation.getLocationForID(aOldAddon.id);
           newAddon = loadManifestFromFile(file);
           applyBlocklistChanges(aOldAddon, newAddon);
+
+          // Carry over any pendingUninstall state to add-ons modified directly
+          // in the profile. This is impoprtant when the attempt to remove the
+          // add-on in processPendingFileChanges failed and caused an mtime
+          // change to the add-ons files.
+          newAddon.pendingUninstall = aOldAddon.pendingUninstall;
         }
 
         // The ID in the manifest that was loaded must match the ID of the old
         // add-on.
         if (newAddon.id != aOldAddon.id)
           throw new Error("Incorrect id in install manifest");
       }
       catch (e) {
@@ -5418,17 +5465,17 @@ var XPIDatabase = {
     // Any errors in here should rollback the transaction
     try {
       this.removeAddonMetadata(aOldAddon);
       aNewAddon.syncGUID = aOldAddon.syncGUID;
       aNewAddon.installDate = aOldAddon.installDate;
       aNewAddon.applyBackgroundUpdates = aOldAddon.applyBackgroundUpdates;
       aNewAddon.foreignInstall = aOldAddon.foreignInstall;
       aNewAddon.active = (aNewAddon.visible && !aNewAddon.userDisabled &&
-                          !aNewAddon.appDisabled)
+                          !aNewAddon.appDisabled && !aNewAddon.pendingUninstall)
 
       this.addAddonMetadata(aNewAddon, aDescriptor);
       this.commitTransaction();
     }
     catch (e) {
       this.rollbackTransaction();
       throw e;
     }
--- a/toolkit/mozapps/plugins/content/pluginProblem.xml
+++ b/toolkit/mozapps/plugins/content/pluginProblem.xml
@@ -54,17 +54,17 @@
     </resources>
 
     <content>
         <xul:vbox class="mainBox" flex="1" chromedir="&locale.dir;">
             <xul:spacer flex="1"/>
             <xul:box class="icon"/>
             <html:div class="msg msgUnsupported">&missingPlugin;</html:div>
             <html:div class="msg msgTapToPlay">&tapToPlayPlugin;</html:div>
-            <html:div class="msg msgClickToPlay">&clickToPlayPlugins;</html:div>
+            <html:div class="msg msgClickToPlay">&clickToPlayPlugin;</html:div>
             <html:div class="msg msgDisabled">&disabledPlugin;</html:div>
             <html:div class="msg msgBlocked">&blockedPlugin.label;</html:div>
             <html:div class="msg msgCrashed"><!-- set at runtime --></html:div>
 
             <html:div class="installStatus">
                 <html:div class="msg msgInstallPlugin"><html:a class="installPluginLink" href="">&installPlugin;</html:a></html:div>
             </html:div>
             <html:div class="msg msgManagePlugins"><html:a class="managePluginsLink" href="">&managePlugins;</html:a></html:div>
--- a/widget/tests/TestAppShellSteadyState.cpp
+++ b/widget/tests/TestAppShellSteadyState.cpp
@@ -20,17 +20,17 @@
 #include "nsIXULWindow.h"
 
 #include "nsAppShellCID.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsNetUtil.h"
 #include "nsThreadUtils.h"
 
 #ifdef XP_WIN
-#include "Windows.h"
+#include <windows.h>
 #endif
 
 using namespace mozilla;
 
 typedef void (*TestFunc)(nsIAppShell*);
 
 bool gStableStateEventHasRun = false;
 
--- a/widget/windows/nsWindowGfx.cpp
+++ b/widget/windows/nsWindowGfx.cpp
@@ -61,16 +61,17 @@ using mozilla::plugins::PluginInstancePa
 #include "gfxImageSurface.h"
 #include "gfxWindowsSurface.h"
 #include "gfxWindowsPlatform.h"
 #include "nsGfxCIID.h"
 #include "gfxContext.h"
 #include "nsRenderingContext.h"
 #include "prmem.h"
 #include "WinUtils.h"
+#include "mozilla/unused.h"
 
 #include "LayerManagerOGL.h"
 #include "BasicLayers.h"
 #ifdef MOZ_ENABLE_D3D9_LAYER
 #include "LayerManagerD3D9.h"
 #endif
 #ifdef MOZ_ENABLE_D3D10_LAYER
 #include "LayerManagerD3D10.h"
@@ -79,16 +80,17 @@ using mozilla::plugins::PluginInstancePa
 #include "nsUXThemeData.h"
 #include "nsUXThemeConstants.h"
 
 extern "C" {
 #define PIXMAN_DONT_DEFINE_STDINT
 #include "pixman.h"
 }
 
+using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::widget;
 
 /**************************************************************
  **************************************************************
  **
  ** BLOCK: Variables
  **
@@ -247,17 +249,17 @@ bool nsWindow::OnPaint(HDC aDC, PRUint32
       BeginPaint(mWnd, &ps);
       EndPaint(mWnd, &ps);
       return true;
     }
 
     PluginInstanceParent* instance = reinterpret_cast<PluginInstanceParent*>(
       ::GetPropW(mWnd, L"PluginInstanceParentProperty"));
     if (instance) {
-      instance->CallUpdateWindow();
+      unused << instance->CallUpdateWindow();
     } else {
       // We should never get here since in-process plugins should have
       // subclassed our HWND and handled WM_PAINT, but in some cases that
       // could fail. Return without asserting since it's not our fault.
       NS_WARNING("Plugin failed to subclass our window");
     }
 
     ValidateRect(mWnd, NULL);