Merge m-c --> cedar
authorChris Jones <jones.chris.g@gmail.com>
Wed, 15 Sep 2010 16:44:30 -0500
changeset 54114 5bcf939df740000a8550715111b5faf2e066f194
parent 54113 0de4051026629e9b63732400a29fd0f4ec9e8f96 (current diff)
parent 53973 b9ff2a9339e2ea624d80483320fba9c36a8ff0b0 (diff)
child 54115 af33e0ee0168e0441c6bc4de575408e770f462fc
push idunknown
push userunknown
push dateunknown
milestone2.0b7pre
Merge m-c --> cedar
browser/base/content/browser.xul
browser/themes/gnomestripe/browser/browser.css
content/base/public/nsIFrameLoader.idl
content/base/src/nsFrameLoader.cpp
content/base/test/chrome/bug514705.html
content/base/test/chrome/bug514705_helper.xul
content/base/test/chrome/test_bug514705.xul
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/PBrowser.ipdl
dom/ipc/PContent.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
ipc/glue/IPCMessageUtils.h
layout/base/FrameLayerBuilder.cpp
layout/base/FrameLayerBuilder.h
toolkit/mozapps/extensions/test/browser/browser_backgroundupdate_menuitem.js
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -508,39 +508,23 @@
                         accesskey="&addons.accesskey;"
                         key="key_openAddons"
                         command="Tools:Addons"/>
 #ifdef MOZ_SERVICES_SYNC
               <!-- only one of sync-setup or sync-menu will be showing at once -->
               <menuitem id="sync-setup"
                         label="&syncSetup.label;"
                         accesskey="&syncSetup.accesskey;"
+                        observes="sync-setup-state"
                         oncommand="gSyncUI.openSetup()"/>
-              <menu id="sync-menu"
-                    label="&syncMenu.label;"
-                    accesskey="&syncMenu.accesskey;">
-                <menupopup id="sync-menu-popup"
-                           onpopupshowing="if (event.target == this) gSyncUI.doUpdateMenu(event);">
-                  <menuitem id="sync-loginitem"
-                            label="&syncLogInItem.label;"
-                            accesskey="&syncLogInItem.accesskey;"
-                            oncommand="gSyncUI.doLogin();"/>
-                  <menuitem id="sync-logoutitem"
-                            label="&syncLogOutItem.label;"
-                            accesskey="&syncLogOutItem.accesskey;"
-                            oncommand="gSyncUI.doLogout();"/>
-                  <menuitem id="sync-syncnowitem"
-                            label="&syncSyncNowItem.label;"
-                            accesskey="&syncSyncNowItem.accesskey;"
-                            oncommand="gSyncUI.doSync(event);"/>
-                  <menuseparator id="sync-lastsyncsep" hidden="true"/>
-                  <menuitem id="sync-lastsyncitem"
-                            disabled="true" hidden="true"/>
-                </menupopup>
-              </menu>
+              <menuitem id="sync-syncnowitem"
+                        label="&syncSyncNowItem.label;"
+                        accesskey="&syncSyncNowItem.accesskey;"
+                        observes="sync-syncnow-state"
+                        oncommand="gSyncUI.doSync(event);"/>
 #endif
               <menuseparator id="devToolsSeparator"/>
               <menuitem id="menu_pageinspect"
                         type="checkbox"
                         hidden="true"
                         label="&inspectMenu.label;"
                         accesskey="&inspectMenu.accesskey;"
                         key="key_inspect"
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -187,16 +187,20 @@
                  type="checkbox"
                  oncommand="gPopupBlockerObserver.dontShowMessage();"/>
     <broadcaster id="blockedPopupsSeparator"/>
     <broadcaster id="isImage"/>
     <broadcaster id="isFrameImage"/>
     <broadcaster id="singleFeedMenuitemState" disabled="true"/>
     <broadcaster id="multipleFeedsMenuState" hidden="true"/>
     <broadcaster id="tabviewGroupsNumber" groups="0"/>
+#ifdef MOZ_SERVICES_SYNC
+    <broadcaster id="sync-setup-state"/>
+    <broadcaster id="sync-syncnow-state"/>
+#endif
   </broadcasterset>
 
   <keyset id="mainKeyset">
     <key id="key_newNavigator"
          key="&newNavigatorCmd.key;"
          command="cmd_newNavigator"
          modifiers="accel"/>
     <key id="key_newNavigatorTab" key="&tabCmd.commandkey;" modifiers="accel" command="cmd_newNavigatorTab"/>
--- a/browser/base/content/browser-syncui.js
+++ b/browser/base/content/browser-syncui.js
@@ -100,31 +100,25 @@ let gSyncUI = {
   _isLoggedIn: function() {
     if (this._needsSetup())
       return false;
     return Weave.Service.isLoggedIn;
   },
 
   updateUI: function SUI_updateUI() {
     let needsSetup = this._needsSetup();
-    document.getElementById("sync-setup").hidden = !needsSetup;
-    document.getElementById("sync-menu").hidden = needsSetup;
+    document.getElementById("sync-setup-state").hidden = !needsSetup;
+    document.getElementById("sync-syncnow-state").hidden = needsSetup;
 
     if (gBrowser) {
-      let showLabel = !this._isLoggedIn() && !needsSetup;
-      let button = document.getElementById("sync-status-button");
-      button.setAttribute("class", showLabel ? "statusbarpanel-iconic-text"
-                                             : "statusbarpanel-iconic");
-      button.image = "chrome://browser/skin/sync-16.png";
-
-      if (!this._isLoggedIn()) {
-        //XXXzpao When we move the string bundle, we can add more and make this
-        //        say "needs setup" or something similar. (bug 583381)
-        button.removeAttribute("tooltiptext");
-      }
+      document.getElementById("sync-button").removeAttribute("status");
+      this._updateLastSyncTime();
+    }
+    if (needsSetup) {
+      document.getElementById("sync-button").removeAttribute("tooltiptext");
     }
   },
 
   alltabsPopupShowing: function(event) {
     // Should we show the menu item?
     if (!Weave.Service.isLoggedIn || !Weave.Engines.get("tabs").enabled)
       return;
 
@@ -150,18 +144,17 @@ let gSyncUI = {
     popup.insertBefore(menuitem, sep);
   },
 
 
   // Functions called by observers
   onActivityStart: function SUI_onActivityStart() {
     //XXXzpao Followup: Do this with a class. (bug 583384)
     if (gBrowser)
-      document.getElementById("sync-status-button").image =
-        "chrome://browser/skin/sync-16-throbber.png";
+      document.getElementById("sync-button").setAttribute("status", "active");
   },
 
   onSyncFinish: function SUI_onSyncFinish() {
     this._onSyncEnd(true);
   },
 
   onSyncError: function SUI_onSyncError() {
     this._onSyncEnd(false);
@@ -177,17 +170,17 @@ let gSyncUI = {
   },
 
   onLoginFinish: function SUI_onLoginFinish() {
     // Clear out any login failure notifications
     let title = this._stringBundle.GetStringFromName("error.login.title");
     Weave.Notifications.removeAll(title);
 
     this.updateUI();
-    this._updateLastSyncItem();
+    this._updateLastSyncTime();
   },
 
   onLoginError: function SUI_onLoginError() {
     // if login fails, any other notifications are essentially moot
     Weave.Notifications.removeAll();
 
     // if we haven't set up the client, don't show errors
     if (this._needsSetup()) {
@@ -261,61 +254,34 @@ let gSyncUI = {
     }
     else {
       // Display remaining notifications
       this.onNotificationAdded();
     }
   },
 
   // Commands
-  doUpdateMenu: function SUI_doUpdateMenu(event) {
-    this._updateLastSyncItem();
-
-    let loginItem = document.getElementById("sync-loginitem");
-    let logoutItem = document.getElementById("sync-logoutitem");
-    let syncItem = document.getElementById("sync-syncnowitem");
-
-    // Don't allow "login" to be selected in some cases
-    let offline = Services.io.offline;
-    let locked = Weave.Service.locked;
-    let noUser = Weave.Service.username == "";
-    let notReady = offline || locked || noUser;
-    loginItem.setAttribute("disabled", notReady);
-    logoutItem.setAttribute("disabled", notReady);
-
-    // Don't allow "sync now" to be selected in some cases
-    let loggedIn = Weave.Service.isLoggedIn;
-    let noNode = Weave.Status.sync == Weave.NO_SYNC_NODE_FOUND;
-    let disableSync = notReady || !loggedIn || noNode;
-    syncItem.setAttribute("disabled", disableSync);
-
-    // Only show one of login/logout
-    loginItem.setAttribute("hidden", loggedIn);
-    logoutItem.setAttribute("hidden", !loggedIn);
-  },
-
   doLogin: function SUI_doLogin() {
     Weave.Service.login();
   },
 
   doLogout: function SUI_doLogout() {
     Weave.Service.logout();
   },
 
   doSync: function SUI_doSync() {
-    Weave.Service.sync();
+    if (Weave.Service.isLoggedIn || Weave.Service.login())
+      Weave.Service.sync();
   },
 
-  handleStatusbarButton: function SUI_handleStatusbarButton() {
-    if (Weave.Service.isLoggedIn)
-      Weave.Service.sync();
-    else if (this._needsSetup())
+  handleToolbarButton: function SUI_handleStatusbarButton() {
+    if (this._needsSetup())
       this.openSetup();
     else
-      Weave.Service.login();
+      this.doSync();
   },
 
   //XXXzpao should be part of syncCommon.js - which we might want to make a module...
   //        To be fixed in a followup (bug 583366)
   openSetup: function SUI_openSetup() {
     let win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
     if (win)
       win.focus();
@@ -336,38 +302,37 @@ let gSyncUI = {
   },
 
   openPrefs: function SUI_openPrefs() {
     openPreferences("paneSync");
   },
 
 
   // Helpers
-  _updateLastSyncItem: function SUI__updateLastSyncItem() {
+  _updateLastSyncTime: function SUI__updateLastSyncTime() {
+    if (!gBrowser)
+      return;
+
+    let syncButton = document.getElementById("sync-button");
     let lastSync;
     try {
       lastSync = Services.prefs.getCharPref("services.sync.lastSync");
     }
     catch (e) { };
-    if (!lastSync)
+    if (!lastSync || this._needsSetup()) {
+      syncButton.removeAttribute("tooltiptext");
       return;
-
-    let lastSyncItem = document.getElementById("sync-lastsyncitem");
+    }
 
     // Show the day-of-week and time (HH:MM) of last sync
     let lastSyncDate = new Date(lastSync).toLocaleFormat("%a %H:%M");
     let lastSyncLabel =
       this._stringBundle.formatStringFromName("lastSync.label", [lastSyncDate], 1);
-    lastSyncItem.setAttribute("label", lastSyncLabel);
-    lastSyncItem.setAttribute("hidden", "false");
-    document.getElementById("sync-lastsyncsep").hidden = false;
 
-    if (gBrowser)
-      document.getElementById("sync-status-button").
-               setAttribute("tooltiptext", lastSyncLabel);
+    syncButton.setAttribute("tooltiptext", lastSyncLabel);
   },
 
   _onSyncEnd: function SUI__onSyncEnd(success) {
     let title = this._stringBundle.GetStringFromName("error.sync.title");
     if (!success) {
       if (Weave.Status.login != Weave.LOGIN_SUCCEEDED) {
         this.onLoginError();
         return;
@@ -410,17 +375,17 @@ let gSyncUI = {
 
     if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) {
       title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
       Weave.Notifications.removeAll(title);
       this._wasDelayed = false;
     }
 
     this.updateUI();
-    this._updateLastSyncItem();
+    this._updateLastSyncTime();
   },
   
   observe: function SUI_observe(subject, topic, data) {
     switch (topic) {
       case "weave:service:sync:start":
         this.onActivityStart();
         break;
       case "weave:service:sync:finish":
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -443,17 +443,21 @@
           type="menu"
 #ifdef XP_WIN
           label="&brandShortName;"
 #else
           label="&appMenuButton.label;"
 #endif
           style="-moz-user-focus: ignore;">
     <menupopup id="appmenu-popup"
+#ifdef MOZ_SERVICES_SYNC
+               onpopupshowing="updateEditUIVisibility();gSyncUI.updateUI();">
+#else
                onpopupshowing="updateEditUIVisibility();">
+#endif
       <hbox>
         <vbox id="appmenuPrimaryPane">
           <hbox flex="1"
                 class="split-menuitem">
             <menuitem id="appmenu_newTab"
                       class="menuitem-tooltip split-menuitem-item"
                       flex="1"
                       label="&tabCmd.label;"
@@ -759,16 +763,28 @@
                             onclick="checkForMiddleClick(this, event);"/>
                   <menuseparator/>
                   <menuitem id="appmenu_about"
                             label="&aboutProduct.label;"
                             oncommand="openAboutDialog();"/>
                 </menupopup>
               </menu>
             </hbox>
+#ifdef MOZ_SERVICES_SYNC
+            <spacer flex="1"/>
+            <!-- only one of sync-setup or sync-syncnow will be showing at once -->
+            <menuitem id="sync-setup-appmenu"
+                      label="&syncSetup.label;"
+                      observes="sync-setup-state"
+                      oncommand="gSyncUI.openSetup()"/>
+            <menuitem id="sync-syncnowitem-appmenu"
+                      label="&syncSyncNowItem.label;"
+                      observes="sync-syncnow-state"
+                      oncommand="gSyncUI.doSync(event);"/>
+#endif
         </vbox>
       </hbox>
     </menupopup>
   </button>
   </hbox>
   <spacer id="titlebar-spacer" flex="1"/>
   <hbox id="titlebar-buttonbox">
     <toolbarbutton id="titlebar-min" oncommand="window.minimize();"/>
@@ -1228,17 +1244,22 @@
                        label="&fullZoomReduceCmd.label;"
                        command="cmd_fullZoomReduce"
                        tooltiptext="&zoomOutButton.tooltip;"/>
         <toolbarbutton id="zoom-in-button" class="toolbarbutton-1"
                        label="&fullZoomEnlargeCmd.label;"
                        command="cmd_fullZoomEnlarge"
                        tooltiptext="&zoomInButton.tooltip;"/>
       </toolbaritem>
-
+#ifdef MOZ_SERVICES_SYNC
+      <toolbarbutton id="sync-button"
+                     class="toolbarbutton-1 chromeclass-toolbar-additional"
+                     label="&syncToolbarButton.label;"
+                     oncommand="gSyncUI.handleToolbarButton()"/>
+#endif
     </toolbarpalette>
   </toolbox>
 
   <hbox flex="1" id="browser">
     <vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome">
       <sidebarheader id="sidebar-header" align="center">
         <label id="sidebar-title" persist="value" flex="1" crop="end" control="sidebar"/>
         <image id="sidebar-throbber"/>
@@ -1271,24 +1292,16 @@
       </statusbarpanel>
       <statusbarpanel id="download-monitor" class="statusbarpanel-iconic-text"
                       tooltiptext="&downloadMonitor2.tooltip;" hidden="true"
                       command="Tools:Downloads"/>
       <statusbarpanel id="security-button" class="statusbarpanel-iconic"
                       hidden="true"
                       onclick="if (event.button == 0 &amp;&amp; event.detail == 1) displaySecurityInfo();"/>
 #ifdef MOZ_SERVICES_SYNC
-      <statusbarpanel id="sync-status-button"
-                      class="statusbarpanel-iconic"
-                      image="chrome://browser/skin/sync-16.png"
-                      label="&syncLogInItem.label;"
-                      oncommand="gSyncUI.handleStatusbarButton();"
-                      onmousedown="event.preventDefault();">
-      </statusbarpanel>
-      <separator class="thin"/>
       <statusbarpanel id="sync-notifications-button"
                       class="statusbarpanel-iconic-text"
                       hidden="true"
                       popup="sync-notifications-panel">
       </statusbarpanel>
       <panel id="sync-notifications-panel" position="before_end">
           <notificationbox id="sync-notifications-box"/>
       </panel>
--- a/browser/components/preferences/advanced.js
+++ b/browser/components/preferences/advanced.js
@@ -65,16 +65,17 @@ var gAdvancedPane = {
     this.updateAppUpdateItems();
     this.updateAutoItems();
     this.updateModeItems();
 #endif
     this.updateOfflineApps();
 #ifdef MOZ_CRASHREPORTER
     this.initSubmitCrashes();
 #endif
+    this.updateActualCacheSize();
   },
 
   /**
    * Stores the identity of the current tab in preferences so that the selected
    * tab can be persisted between openings of the preferences window.
    */
   tabSelectionChanged: function ()
   {
@@ -185,27 +186,72 @@ var gAdvancedPane = {
 
   // NETWORK TAB
 
   /*
    * Preferences:
    *
    * browser.cache.disk.capacity
    * - the size of the browser cache in KB
+   * browser.cache.disk.smart_size.enabled
+   * - If disabled, disk.capacity is used
    */
 
   /**
    * Displays a dialog in which proxy settings may be changed.
    */
   showConnections: function ()
   {
     document.documentElement.openSubDialog("chrome://browser/content/preferences/connection.xul",
                                            "", null);
   },
+ 
+  // Retrieves the amount of space currently used by disk cache
+  updateActualCacheSize: function ()
+  {
+    var visitor = {
+      visitDevice: function (deviceID, deviceInfo)
+      {
+        if (deviceID == "disk") {
+          var actualSizeLabel = document.getElementById("actualCacheSize");
+          var sizeStrings = DownloadUtils.convertByteUnits(deviceInfo.totalSize);
+          var prefStrBundle = document.getElementById("bundlePreferences");
+          var sizeStr = prefStrBundle.getFormattedString("actualCacheSize",
+                                                          sizeStrings);
+          actualSizeLabel.value = sizeStr;
+        }
+        // Do not enumerate entries
+        return false;
+      },
 
+      visitEntry: function (deviceID, entryInfo)
+      {
+        // Do not enumerate entries.
+        return false;
+      }
+    };
+    var cacheService =
+      Components.classes["@mozilla.org/network/cache-service;1"]
+                .getService(Components.interfaces.nsICacheService);
+    cacheService.visitEntries(visitor);
+  },
+
+  updateCacheSizeUI: function (smartSizeEnabled)
+  {
+    document.getElementById("useCacheBefore").disabled = smartSizeEnabled;
+    document.getElementById("cacheSize").disabled = smartSizeEnabled;
+    document.getElementById("useCacheAfter").disabled = smartSizeEnabled;
+  },
+
+  readSmartSizeEnabled: function ()
+  {
+    var enabled = document.getElementById("browser.cache.disk.smart_size.enabled").value;
+    this.updateCacheSizeUI(enabled);
+  },
+  
   /**
    * Converts the cache size from units of KB to units of MB and returns that
    * value.
    */
   readCacheSize: function ()
   {
     var preference = document.getElementById("browser.cache.disk.capacity");
     return preference.value / 1024;
@@ -227,16 +273,17 @@ var gAdvancedPane = {
    */
   clearCache: function ()
   {
     var cacheService = Components.classes["@mozilla.org/network/cache-service;1"]
                          	       .getService(Components.interfaces.nsICacheService);
     try {
       cacheService.evictEntries(Components.interfaces.nsICache.STORE_ANYWHERE);
     } catch(ex) {}
+    this.updateActualCacheSize();
   },
 
   readOfflineNotify: function()
   {
     var pref = document.getElementById("browser.offline-apps.notify");
     var button = document.getElementById("offlineNotifyExceptions");
     button.disabled = !pref.value;
     return pref.value;
--- a/browser/components/preferences/advanced.xul
+++ b/browser/components/preferences/advanced.xul
@@ -80,18 +80,22 @@
       <preference id="pref.general.disable_button.default_browser"
                   name="pref.general.disable_button.default_browser"
                   type="bool"/>
 #endif
 
       <!-- Network tab -->
       <preference id="browser.cache.disk.capacity"     name="browser.cache.disk.capacity"     type="int"/>
       <preference id="browser.offline-apps.notify"     name="browser.offline-apps.notify"     type="bool"/>
-
-      <!-- Update tab -->
+ 
+      <preference id="browser.cache.disk.smart_size.enabled"
+                  name="browser.cache.disk.smart_size.enabled"
+                  type="bool"/>
+ 
+     <!-- Update tab -->
 #ifdef MOZ_UPDATER
       <preference id="app.update.enabled"              name="app.update.enabled"              type="bool"
                   onchange="gAdvancedPane.updateAppUpdateItems();
                             gAdvancedPane.updateAutoItems();
                             gAdvancedPane.updateModeItems();"/>
       <preference id="app.update.auto"                 name="app.update.auto"                 type="bool"
                   onchange="gAdvancedPane.updateAutoItems();
                             gAdvancedPane.updateModeItems();"/>
@@ -209,75 +213,81 @@
 #endif
           </groupbox>
 #endif
         </tabpanel>
 
         <!-- Network -->
         <tabpanel id="networkPanel" orient="vertical">
 
-           <!-- Connection -->
-           <groupbox id="connectionGroup">
-             <caption label="&connection.label;"/>
+          <!-- Connection -->
+          <groupbox id="connectionGroup">
+            <caption label="&connection.label;"/>
 
-             <hbox align="center">
-               <description flex="1" control="connectionSettings">&connectionDesc.label;</description>
-               <button id="connectionSettings" icon="network" label="&connectionSettings.label;"
-                       accesskey="&connectionSettings.accesskey;"
-                       oncommand="gAdvancedPane.showConnections();"/>
-             </hbox>
-           </groupbox>
-
-           <!-- Cache/Offline apps -->
-           <groupbox id="offlineGroup">
-             <caption label="&offlineStorage.label;"/>
+            <hbox align="center">
+              <description flex="1" control="connectionSettings">&connectionDesc.label;</description>
+              <button id="connectionSettings" icon="network" label="&connectionSettings.label;"
+                      accesskey="&connectionSettings.accesskey;"
+                      oncommand="gAdvancedPane.showConnections();"/>
+            </hbox>
+          </groupbox>
 
-             <hbox align="center">
-               <label id="useCacheBefore" control="cacheSize"
-                      accesskey="&useCacheBefore.accesskey;" value="&useCacheBefore.label;"/>
-               <textbox id="cacheSize" type="number" size="2"
-                        preference="browser.cache.disk.capacity"
-                        onsyncfrompreference="return gAdvancedPane.readCacheSize();"
-                        onsynctopreference="return gAdvancedPane.writeCacheSize();"
-                        aria-labelledby="useCacheBefore cacheSize useCacheAfter"/>
-               <label id="useCacheAfter" flex="1">&useCacheAfter.label;</label>
-               <button id="clearCacheButton" icon="clear"
-                       label="&clearCacheNow.label;" accesskey="&clearCacheNow.accesskey;"
-                       oncommand="gAdvancedPane.clearCache();"/>
-             </hbox>
-	     <hbox align="center">
-	       <checkbox id="offlineNotify" flex="1"
-			 label="&offlineNotify.label;" accesskey="&offlineNotify.accesskey;"
-			 preference="browser.offline-apps.notify"
-			 onsyncfrompreference="return gAdvancedPane.readOfflineNotify();"/>
-	       <button id="offlineNotifyExceptions"
-		       label="&offlineNotifyExceptions.label;"
-		       accesskey="&offlineNotifyExceptions.accesskey;"
-		       oncommand="gAdvancedPane.showOfflineExceptions();"/>
-	     </hbox>
-	     <hbox>
-	       <vbox flex="1">
-
-		 <label id="offlineAppsListLabel">&offlineAppsList.label;</label>
-		 <listbox id="offlineAppsList"
-			  style="height: &offlineAppsList.height;;"
-			  flex="1"
-			  aria-labelledby="offlineAppsListLabel"
-			  onselect="gAdvancedPane.offlineAppSelected(event);">
-		 </listbox>
-	       </vbox>
-	       <vbox pack="end">
-		 <button id="offlineAppsListRemove"
-			 disabled="true"
-			 label="&offlineAppsListRemove.label;"
-			 accesskey="&offlineAppsListRemove.accesskey;" 
-			 oncommand="gAdvancedPane.removeOfflineApp();"/>
-	       </vbox>
-	     </hbox>
-	   </groupbox>
+          <!-- Cache/Offline apps -->
+          <groupbox id="offlineGroup">
+            <caption label="&offlineStorage.label;"/>
+ 
+            <hbox align="center">
+              <label id="actualCacheSize" flex="1"/>
+              <button id="clearCacheButton" icon="clear"
+                      label="&clearCacheNow.label;" accesskey="&clearCacheNow.accesskey;"
+                      oncommand="gAdvancedPane.clearCache();"/>
+            </hbox>
+            <checkbox preference="browser.cache.disk.smart_size.enabled"
+                      id="allowSmartSize" flex="1"
+                      onsyncfrompreference="return gAdvancedPane.readSmartSizeEnabled();"
+                      label="&smartSizeCache.label;"/>
+            <hbox align="center" class="indent">
+              <label id="useCacheBefore" control="cacheSize"
+                     accesskey="&useCacheBefore.accesskey;" value="&useCacheBefore.label;"/>
+              <textbox id="cacheSize" type="number" size="2"
+                       preference="browser.cache.disk.capacity"
+                       onsyncfrompreference="return gAdvancedPane.readCacheSize();"
+                       onsynctopreference="return gAdvancedPane.writeCacheSize();"
+                       aria-labelledby="useCacheBefore cacheSize useCacheAfter"/>
+              <label id="useCacheAfter" flex="1">&useCacheAfter.label;</label>
+            </hbox>
+            <hbox align="center">
+              <checkbox id="offlineNotify" flex="1"
+                        label="&offlineNotify.label;" accesskey="&offlineNotify.accesskey;"
+                        preference="browser.offline-apps.notify"
+                        onsyncfrompreference="return gAdvancedPane.readOfflineNotify();"/>
+              <button id="offlineNotifyExceptions"
+                      label="&offlineNotifyExceptions.label;"
+                      accesskey="&offlineNotifyExceptions.accesskey;"
+                      oncommand="gAdvancedPane.showOfflineExceptions();"/>
+            </hbox>
+            <hbox>
+              <vbox flex="1">
+                <label id="offlineAppsListLabel">&offlineAppsList.label;</label>
+                <listbox id="offlineAppsList"
+                         style="height: &offlineAppsList.height;;"
+                         flex="1"
+                         aria-labelledby="offlineAppsListLabel"
+                         onselect="gAdvancedPane.offlineAppSelected(event);">
+                </listbox>
+              </vbox>
+              <vbox pack="end">
+                <button id="offlineAppsListRemove"
+                        disabled="true"
+                        label="&offlineAppsListRemove.label;"
+                        accesskey="&offlineAppsListRemove.accesskey;" 
+                        oncommand="gAdvancedPane.removeOfflineApp();"/>
+              </vbox>
+            </hbox>
+          </groupbox>
         </tabpanel>
 
         <!-- Update -->
         <tabpanel id="updatePanel" orient="vertical" align="start">
           <label control="autoUpdateGroup">&autoCheck.label;</label>
           <vbox class="indent" id="autoUpdateGroup" role="group">
 #ifdef MOZ_UPDATER
             <checkbox id="enableAppUpdate"
--- a/browser/components/preferences/main.js
+++ b/browser/components/preferences/main.js
@@ -46,16 +46,23 @@ var gMainPane = {
    */
   init: function ()
   {
     this._pane = document.getElementById("paneMain");
 
     // set up the "use current page" label-changing listener
     this._updateUseCurrentButton();
     window.addEventListener("focus", this._updateUseCurrentButton, false);
+
+    this.updateBrowserStartupLastSession();
+
+    // Notify observers that the UI is now ready
+    Components.classes["@mozilla.org/observer-service;1"]
+              .getService(Components.interfaces.nsIObserverService)
+              .notifyObservers(window, "main-pane-loaded", null);
   },
 
   // HOME PAGE
 
   /*
    * Preferences:
    *
    * browser.startup.homepage
@@ -486,10 +493,31 @@ var gMainPane = {
   },
 
   /**
    * Displays the Add-ons Manager.
    */
   showAddonsMgr: function ()
   {
     openUILinkIn("about:addons", "window");
+  },
+
+  /**
+   * Hide/show the "Show my windows and tabs from last time" option based
+   * on the value of the browser.privatebrowsing.autostart pref.
+   */
+  updateBrowserStartupLastSession: function()
+  {
+    let pbAutoStartPref = document.getElementById("browser.privatebrowsing.autostart");
+    let startupPref = document.getElementById("browser.startup.page");
+    let menu = document.getElementById("browserStartupPage");
+    let option = document.getElementById("browserStartupLastSession");
+    if (pbAutoStartPref.value) {
+      option.setAttribute("disabled", "true");
+      if (option.selected) {
+        menu.selectedItem = document.getElementById("browserStartupHomePage");
+      }
+    } else {
+      option.removeAttribute("disabled");
+      startupPref.updateElements(); // select the correct index in the startup menulist
+    }
   }
 };
--- a/browser/components/preferences/main.xul
+++ b/browser/components/preferences/main.xul
@@ -74,16 +74,21 @@
                   type="bool"/>
       <preference id="pref.browser.homepage.disable_button.bookmark_page"
                   name="pref.browser.homepage.disable_button.bookmark_page"
                   type="bool"/>
       <preference id="pref.browser.homepage.disable_button.restore_default"
                   name="pref.browser.homepage.disable_button.restore_default"
                   type="bool"/>
 
+      <preference id="browser.privatebrowsing.autostart"
+                  name="browser.privatebrowsing.autostart"
+                  type="bool"
+                  onchange="gMainPane.updateBrowserStartupLastSession();"/>
+
       <!-- Downloads -->
       <preference id="browser.download.manager.showWhenStarting"
                   name="browser.download.manager.showWhenStarting"
                   type="bool"
                   onchange="gMainPane.showDownloadsWhenStartingPrefChanged();"/>
       <preference id="browser.download.manager.closeWhenDone"
                   name="browser.download.manager.closeWhenDone"
                   type="bool"/>
@@ -104,19 +109,19 @@
     <groupbox id="startupGroup">
       <caption label="&startup.label;"/>
 
       <hbox align="center">
         <label value="&startupPage.label;" accesskey="&startupPage.accesskey;"
                control="browserStartupPage"/>
         <menulist id="browserStartupPage" preference="browser.startup.page">
           <menupopup>
-            <menuitem label="&startupHomePage.label;"     value="1"/>
-            <menuitem label="&startupBlankPage.label;"    value="0"/>
-            <menuitem label="&startupLastSession.label;"  value="3"/>
+            <menuitem label="&startupHomePage.label;"     value="1" id="browserStartupHomePage"/>
+            <menuitem label="&startupBlankPage.label;"    value="0" id="browserStartupBlank"/>
+            <menuitem label="&startupLastSession.label;"  value="3" id="browserStartupLastSession"/>
           </menupopup>
         </menulist>
       </hbox>
       <separator class="thin"/>
       <hbox align="center">
         <label value="&location.label;" accesskey="&location.accesskey;" control="browserHomePage"/>
         <textbox id="browserHomePage" class="padded uri-element" flex="1"
                  type="autocomplete" autocompletesearch="history"
--- a/browser/components/preferences/tests/Makefile.in
+++ b/browser/components/preferences/tests/Makefile.in
@@ -40,16 +40,17 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = browser/components/preferences/tests
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_FILES = \
     browser_bug410900.js \
+    browser_bug567487.js \
     privacypane_tests.js \
     browser_privacypane_1.js \
     browser_privacypane_2.js \
     browser_privacypane_3.js \
     browser_privacypane_4.js \
     browser_privacypane_5.js \
     browser_privacypane_6.js \
     browser_privacypane_7.js \
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/tests/browser_bug567487.js
@@ -0,0 +1,67 @@
+function test() {
+  waitForExplicitFinish();
+
+  function observer(win, topic, data) {
+    if (topic != "main-pane-loaded")
+      return;
+
+    Services.obs.removeObserver(observer, "main-pane-loaded");
+    runTest(win);
+  }
+  Services.obs.addObserver(observer, "main-pane-loaded", false);
+
+  openDialog("chrome://browser/content/preferences/preferences.xul", "Preferences",
+             "chrome,titlebar,toolbar,centerscreen,dialog=no", "paneMain");
+}
+
+function runTest(win) {
+  let doc = win.document;
+  let pbAutoStartPref = doc.getElementById("browser.privatebrowsing.autostart");
+  let startupPref = doc.getElementById("browser.startup.page");
+  let menu = doc.getElementById("browserStartupPage");
+  let option = doc.getElementById("browserStartupLastSession");
+  let defOption = doc.getElementById("browserStartupHomePage");
+  let otherOption = doc.getElementById("browserStartupBlank");
+
+  ok(!pbAutoStartPref.value, "Sanity check");
+  is(startupPref.value, startupPref.defaultValue, "Sanity check");
+
+  // First, check to make sure that setting pbAutoStartPref disables the menu item
+  pbAutoStartPref.value = true;
+  is(option.getAttribute("disabled"), "true", "Setting private browsing to autostart " +
+     "should disable the 'Show my tabs and windows from last time' option");
+  pbAutoStartPref.value = false;
+
+  // Now ensure the correct behavior when pbAutoStartPref is set with option enabled
+  startupPref.value = option.getAttribute("value");
+  is(menu.selectedItem, option, "Sanity check");
+  pbAutoStartPref.value = true;
+  is(option.getAttribute("disabled"), "true", "Setting private browsing to autostart " +
+     "should disable the 'Show my tabs and windows from last time' option");
+  is(menu.selectedItem, defOption, "The 'Show home page' option should be selected");
+  is(startupPref.value, option.getAttribute("value"), "But the value of the startup " +
+     "pref itself shouldn't change");
+  menu.selectedItem = otherOption;
+  menu.doCommand();
+  is(startupPref.value, otherOption.getAttribute("value"), "And we should be able to " +
+     "chnage it!");
+  pbAutoStartPref.value = false;
+
+  // Now, ensure that with 'Show my windows and tabs from last time' enabled, toggling
+  // pbAutoStartPref would restore that value in the menulist.
+  startupPref.value = option.getAttribute("value");
+  is(menu.selectedItem, option, "Sanity check");
+  pbAutoStartPref.value = true;
+  is(menu.selectedItem, defOption, "The 'Show home page' option should be selected");
+  pbAutoStartPref.value = false;
+  is(menu.selectedItem, option, "The correct value should be restored");
+
+  // cleanup
+  [pbAutoStartPref, startupPref].forEach(function (pref) {
+    if (pref.hasUserValue)
+      pref.reset();
+  });
+
+  win.close();
+  finish();
+}
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -536,22 +536,15 @@ just addresses the organization to follo
 <!ENTITY allTabs.filter.emptyText "Search Tabs">
 <!-- Name for the tabs toolbar as spoken by screen readers.
      The word "toolbar" is appended automatically and should not be contained below! -->
 <!ENTITY tabsToolbar.label "Browser tabs">
 
 <!-- LOCALIZATION NOTE (syncTabsMenu.label): This appears in the history menu -->
 <!ENTITY syncTabsMenu.label     "Tabs From Other Computers">
 
-<!ENTITY syncBrand.shortName.label  "Sync">
+<!ENTITY syncBrand.shortName.label    "Sync">
 
-<!ENTITY syncMenu.label               "&syncBrand.shortName.label;">
-<!-- LOCALIZATION NOTE (sync.menu.accesskey): This is part of the tools menu, so
-                                              don't use a conflicting access key -->
-<!ENTITY syncMenu.accesskey           "Y">
 <!ENTITY syncSetup.label              "Set Up &syncBrand.shortName.label;…">
 <!ENTITY syncSetup.accesskey          "Y">
-<!ENTITY syncLogInItem.label          "Connect">
-<!ENTITY syncLogInItem.accesskey      "C">
-<!ENTITY syncLogOutItem.label         "Disconnect">
-<!ENTITY syncLogOutItem.accesskey     "D">
 <!ENTITY syncSyncNowItem.label        "Sync Now">
 <!ENTITY syncSyncNowItem.accesskey    "S">
+<!ENTITY syncToolbarButton.label      "Sync">
--- a/browser/locales/en-US/chrome/browser/preferences/advanced.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/advanced.dtd
@@ -46,16 +46,17 @@
 
   &useCacheBefore.label  [ textbox for cache size in MB ]   &useCacheAfter.label;
 -->
 <!ENTITY useCacheBefore.label            "Use up to">
 <!ENTITY useCacheBefore.accesskey        "U">
 <!ENTITY useCacheAfter.label             "MB of space for the cache">
 <!ENTITY clearCacheNow.label             "Clear Now">
 <!ENTITY clearCacheNow.accesskey         "C">
+<!ENTITY smartSizeCache.label            "Let &brandShortName; manage the size of my cache">
 
 <!ENTITY updateTab.label                 "Update">
 
 <!ENTITY autoCheck.label                 "Automatically check for updates to:">
 <!ENTITY enableAppUpdate.label           "&brandShortName;">
 <!ENTITY enableAppUpdate.accesskey       "F">
 <!ENTITY enableAddonsUpdate2.label       "Add-ons">
 <!ENTITY enableAddonsUpdate2.accesskey   "n">
--- a/browser/locales/en-US/chrome/browser/preferences/preferences.properties
+++ b/browser/locales/en-US/chrome/browser/preferences/preferences.properties
@@ -99,16 +99,22 @@ offlineAppRemoveConfirm=Remove offline d
 #   e.g. offlineAppUsage : "50.23 MB"
 #   %1$S = size (in bytes or megabytes, ...)
 #   %2$S = unit of measure (bytes, KB, MB, ...)
 offlineAppUsage=%1$S %2$S
 
 offlinepermissionstext=The following websites are not allowed to store data for offline use:
 offlinepermissionstitle=Offline Data
 
+####Preferences::Advanced::Network
+#LOCALIZATION NOTE: The next string is for the disk usage of the http cache.
+#   e.g., "Your cache is currently using 200 MB"
+#   %1$S = size
+#   %2$S = unit (MB, KB, etc.)
+actualCacheSize=Your cache is currently using %1$S %2$S of disk space
 
 #### Syncing
 connect.label=Connect
 disconnect.label=Disconnect
 
 stopUsingAccount.title=Do you want to stop using this account?
 differentAccount.label=This will reset all of your Sync account information and preferences.
 differentAccountConfirm.label=Reset All Information
--- a/browser/themes/browserShared.inc
+++ b/browser/themes/browserShared.inc
@@ -1,3 +1,3 @@
 %filter substitution
 
-%define primaryToolbarButtons #back-button, #forward-button, #reload-button, #stop-button, #home-button, #print-button, #downloads-button, #history-button, #bookmarks-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #cut-button, #copy-button, #paste-button, #fullscreen-button, #zoom-out-button, #zoom-in-button
+%define primaryToolbarButtons #back-button, #forward-button, #reload-button, #stop-button, #home-button, #print-button, #downloads-button, #history-button, #bookmarks-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #cut-button, #copy-button, #paste-button, #fullscreen-button, #zoom-out-button, #zoom-in-button, #sync-buttons
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -677,22 +677,36 @@ toolbar[mode="full"] .toolbarbutton-1 > 
 }
 
 #fullscreen-button {
   list-style-image: url("moz-icon://stock/gtk-fullscreen?size=toolbar");
 }
 
 #zoom-out-button {
   list-style-image: url("moz-icon://stock/gtk-zoom-out?size=toolbar");
-}
 
 #zoom-in-button {
   list-style-image: url("moz-icon://stock/gtk-zoom-in?size=toolbar");
 }
 
+/* sync button */
+#sync-button {
+  list-style-image: url("chrome://browser/skin/sync-16.png");
+}
+
+#sync-button[status="active"] {
+  list-style-image: url("chrome://browser/skin/sync-16-throbber.png");
+}
+
+toolbar:not([iconsize="small"]) #sync-button > .toolbarbutton-icon {
+  margin: 1px;
+  width: 16px;
+  height: 16px;
+}
+
 /* 16px primary toolbar buttons */
 toolbar[iconsize="small"] .toolbarbutton-1:not([type="menu-button"]) {
   -moz-box-orient: vertical;
   min-width: 0;
   list-style-image: url("chrome://browser/skin/Toolbar-small.png");
 }
 
 toolbar[iconsize="small"] .toolbarbutton-1[type="menu-button"] {
--- a/browser/themes/gnomestripe/browser/tabview/tabview.css
+++ b/browser/themes/gnomestripe/browser/tabview/tabview.css
@@ -388,17 +388,17 @@ input.defaultName {
 /* Exit button
 +----------------------------------*/
 #exit-button {
   cursor: default;
   top: 0;
   right: 0;
   width: 28px;
   height: 27px;
-  background: url(chrome://browser/skin/tabview/tabview.png) no-repeat scroll 7px 7px #b7b7b7;
+  background: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 16, 16, 0) no-repeat scroll 7px 7px #b7b7b7;
   border-bottom: 1px solid #909090;
   border-left: 1px solid #B7B7B7;
   border-top: 1px solid #CFCFCF;
   border-radius: 3px 0 0 3px;
 }
 
 /* Search
 ----------------------------------*/
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -679,30 +679,47 @@ toolbar[iconsize="small"][mode="icons"] 
 
 toolbar[mode="icons"] #zoom-out-button {
   -moz-margin-end: 0;
 }
 
 toolbar[mode="icons"] #zoom-in-button {
   -moz-border-start: none;
   -moz-margin-start: 0;
+  height: 16px;
 }
 
 #zoom-out-button:-moz-locale-dir(ltr),
 #zoom-in-button:-moz-locale-dir(rtl) {
   border-top-right-radius: 0;
   border-bottom-right-radius: 0;
 }
 
 #zoom-out-button:-moz-locale-dir(rtl),
 #zoom-in-button:-moz-locale-dir(ltr) {
   border-top-left-radius: 0;
   border-bottom-left-radius: 0;
 }
 
+/* sync button */
+
+#sync-button {
+  list-style-image: url("chrome://browser/skin/sync-16.png");
+}
+
+#sync-button[status="active"] {
+  list-style-image: url("chrome://browser/skin/sync-16-throbber.png");
+}
+
+toolbar:not([iconsize="small"]) #sync-button > .toolbarbutton-icon {
+  margin: 1px;
+  width: 16px;
+  height: 16px;
+}
+
 /* ----- FULLSCREEN WINDOW CONTROLS ----- */
 
 #minimize-button,
 #close-button,
 #fullscreen-button ~ #window-controls > #restore-button {
   display: none;
 }
 
@@ -2251,14 +2268,8 @@ listitem.style-section {
   background-color: LightGray;
   color: black;
   font-weight: bold;
 }
 
 panel[dimmed="true"] {
   opacity: 0.5;
 }
-
-/* Sync */
-
-#sync-status-button.statusbarpanel-iconic {
-  padding: 0 5px;
-}
--- a/browser/themes/pinstripe/browser/tabview/tabview.css
+++ b/browser/themes/pinstripe/browser/tabview/tabview.css
@@ -394,17 +394,17 @@ input.defaultName {
 /* Exit button
 +----------------------------------*/
 #exit-button {
   cursor: default;
   top: 0;
   right: 0;
   width: 28px;
   height: 27px;
-  background: url(chrome://browser/skin/tabview/tabview.png) no-repeat scroll 4px 4px #b7b7b7;
+  background: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 20, 20, 0) no-repeat scroll 4px 4px #b7b7b7;
   border-bottom: 1px solid #909090;
   border-left: 1px solid #B7B7B7;
   border-top: 1px solid #CFCFCF;
   border-radius: 3px 0 0 3px;
 }
 
 /* Search
 ----------------------------------*/
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -907,16 +907,32 @@ toolbar:not([iconsize="small"])[mode="ic
 }
 
 #zoom-out-button:-moz-locale-dir(rtl),
 #zoom-in-button:-moz-locale-dir(ltr) {
   border-top-left-radius: 0;
   border-bottom-left-radius: 0;
 }
 
+/* sync button */
+
+#sync-button {
+  list-style-image: url("chrome://browser/skin/sync-16.png");
+}
+
+#sync-button[status="active"] {
+  list-style-image: url("chrome://browser/skin/sync-16-throbber.png");
+}
+
+toolbar:not([iconsize="small"]) #sync-button > .toolbarbutton-icon {
+  margin: 1px;
+  width: 16px;
+  height: 16px;
+}
+
 /* ::::: fullscreen window controls ::::: */
 
 #minimize-button,
 #restore-button,
 #close-button {
   list-style-image: url("chrome://global/skin/icons/windowControls.png");
   padding: 0;
 }
--- a/browser/themes/winstripe/browser/tabview/tabview.css
+++ b/browser/themes/winstripe/browser/tabview/tabview.css
@@ -400,17 +400,17 @@ input.defaultName {
 /* Exit button
 +----------------------------------*/
 #exit-button {
   cursor: default;
   top: 0;
   right: 0;
   width: 28px;
   height: 27px;
-  background: url(chrome://browser/skin/tabview/tabview.png) no-repeat scroll 4px 4px #b7b7b7;
+  background: -moz-image-rect(url(chrome://browser/skin/tabview/tabview.png), 0, 18, 18, 0) no-repeat scroll 4px 4px #b7b7b7;
   border-bottom: 1px solid #909090;
   border-left: 1px solid #B7B7B7;
   border-top: 1px solid #CFCFCF;
   border-radius: 3px 0 0 3px;
 }
 
 /* Search
 ----------------------------------*/
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -370,16 +370,19 @@ user_pref("geo.ignore.location_filter", 
 user_pref("camino.warn_when_closing", false); // Camino-only, harmless to others
 
 // Make url-classifier updates so rare that they won't affect tests
 user_pref("urlclassifier.updateinterval", 172800);
 // Point the url-classifier to the local testing server for fast failures
 user_pref("browser.safebrowsing.provider.0.gethashURL", "http://%(server)s/safebrowsing-dummy/gethash");
 user_pref("browser.safebrowsing.provider.0.keyURL", "http://%(server)s/safebrowsing-dummy/newkey");
 user_pref("browser.safebrowsing.provider.0.updateURL", "http://%(server)s/safebrowsing-dummy/update");
+// Point update checks to the local testing server for fast failures
+user_pref("extensions.update.url", "http://%(server)s/extensions-dummy/updateURL");
+user_pref("extensions.blocklist.url", "http://%(server)s/extensions-dummy/blocklistURL");
 """ % { "server" : self.webServer + ":" + str(self.httpPort) }
     prefs.append(part)
 
     if useServerLocations == False:
       part = """
 user_pref("capability.principal.codebase.p1.granted",
           "UniversalXPConnect UniversalBrowserRead UniversalBrowserWrite \
            UniversalPreferencesRead UniversalPreferencesWrite \
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -2352,10 +2352,10 @@ FREEZE_VARIABLES = \
 $(foreach var,$(FREEZE_VARIABLES),$(eval $(var)_FROZEN := '$($(var))'))
 
 CHECK_FROZEN_VARIABLES = $(foreach var,$(FREEZE_VARIABLES), \
   $(if $(subst $($(var)_FROZEN),,'$($(var))'),$(error Makefile variable '$(var)' changed value after including rules.mk. Was $($(var)_FROZEN), now $($(var)).)))
 
 libs export libs::
 	$(CHECK_FROZEN_VARIABLES)
 
-default::
+default all::
 	if test -d $(DIST)/bin ; then touch $(DIST)/bin/.purgecaches ; fi
--- a/content/base/public/nsIFrameLoader.idl
+++ b/content/base/public/nsIFrameLoader.idl
@@ -36,35 +36,29 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
 
 interface nsIDocShell;
 interface nsIURI;
-interface nsIWebProgress;
 interface nsIFrame;
 interface nsIChromeFrameMessageManager;
 interface nsIVariant;
 
 [scriptable, uuid(afb86369-d183-4bc4-9fce-26cd314a4ac0)]
 interface nsIFrameLoader : nsISupports
 {
   /**
    * Get the docshell from the frame loader.
    */
   readonly attribute nsIDocShell docShell;
 
   /**
-   * Get the nsIWebProgress from the frame loader, allowing listener registration.
-   */
-  readonly attribute nsIWebProgress webProgress;
-
-  /**
    * Start loading the frame. This method figures out what to load
    * from the owner content in the frame loader.
    */
   void loadFrame();
 
   /**
    * Loads the specified URI in this frame. Behaves identically to loadFrame,
    * except that this method allows specifying the URI to load.
--- a/content/base/src/nsContentList.cpp
+++ b/content/base/src/nsContentList.cpp
@@ -205,21 +205,27 @@ ContentListHashtableMatchEntry(PLDHashTa
     static_cast<const ContentListHashEntry *>(entry);
   const nsContentListKey* list1 = e->mContentList->GetKey();
   const nsContentListKey* list2 = static_cast<const nsContentListKey *>(key);
 
   return list1->Equals(*list2);
 }
 
 already_AddRefed<nsContentList>
-NS_GetContentList(nsINode* aRootNode, nsIAtom* aMatchAtom,
-                  PRInt32 aMatchNameSpaceId)
+NS_GetContentList(nsINode* aRootNode, 
+                  PRInt32  aMatchNameSpaceId,
+                  nsIAtom* aHTMLMatchAtom,
+                  nsIAtom* aXMLMatchAtom)
+                  
 {
   NS_ASSERTION(aRootNode, "content list has to have a root");
 
+  if(!aXMLMatchAtom)
+    aXMLMatchAtom = aHTMLMatchAtom;
+
   nsContentList* list = nsnull;
 
   static PLDHashTableOps hash_table_ops =
   {
     PL_DHashAllocTable,
     PL_DHashFreeTable,
     ContentListHashtableHashKey,
     ContentListHashtableMatchEntry,
@@ -238,42 +244,37 @@ NS_GetContentList(nsINode* aRootNode, ns
     if (!success) {
       gContentListHashTable.ops = nsnull;
     }
   }
   
   ContentListHashEntry *entry = nsnull;
   // First we look in our hashtable.  Then we create a content list if needed
   if (gContentListHashTable.ops) {
-    nsContentListKey hashKey(aRootNode, aMatchAtom,
-                             aMatchNameSpaceId);
+    nsContentListKey hashKey(aRootNode, aHTMLMatchAtom,
+                             aXMLMatchAtom, aMatchNameSpaceId);
     
     // A PL_DHASH_ADD is equivalent to a PL_DHASH_LOOKUP for cases
     // when the entry is already in the hashtable.
     entry = static_cast<ContentListHashEntry *>
                        (PL_DHashTableOperate(&gContentListHashTable,
                                                 &hashKey,
                                                 PL_DHASH_ADD));
     if (entry)
       list = entry->mContentList;
   }
 
   if (!list) {
     // We need to create a ContentList and add it to our new entry, if
     // we have an entry
-    list = new nsContentList(aRootNode, aMatchAtom,
-                             aMatchNameSpaceId);
+    list = new nsContentList(aRootNode, aMatchNameSpaceId,
+                             aHTMLMatchAtom, aXMLMatchAtom);
     if (entry) {
-      if (list)
-        entry->mContentList = list;
-      else
-        PL_DHashTableRawRemove(&gContentListHashTable, entry);
+      entry->mContentList = list;
     }
-
-    NS_ENSURE_TRUE(list, nsnull);
   }
 
   NS_ADDREF(list);
 
   return list;
 }
 
 // Hashtable for storing nsCacheableFuncStringContentList
@@ -380,30 +381,32 @@ NS_GetFuncStringContentList(nsINode* aRo
   // Don't cache these lists globally
 
   return list;
 }
 
 // nsContentList implementation
 
 nsContentList::nsContentList(nsINode* aRootNode,
-                             nsIAtom* aMatchAtom,
                              PRInt32 aMatchNameSpaceId,
+                             nsIAtom* aHTMLMatchAtom,
+                             nsIAtom* aXMLMatchAtom,
                              PRBool aDeep)
   : nsBaseContentList(),
-    nsContentListKey(aRootNode, aMatchAtom, aMatchNameSpaceId),
+    nsContentListKey(aRootNode, aHTMLMatchAtom, aXMLMatchAtom, aMatchNameSpaceId),
     mFunc(nsnull),
     mDestroyFunc(nsnull),
     mData(nsnull),
     mState(LIST_DIRTY),
     mDeep(aDeep),
     mFuncMayDependOnAttr(PR_FALSE)
 {
   NS_ASSERTION(mRootNode, "Must have root");
-  if (nsGkAtoms::_asterix == mMatchAtom) {
+  if (nsGkAtoms::_asterix == mHTMLMatchAtom) {
+    NS_ASSERTION(mXMLMatchAtom == nsGkAtoms::_asterix, "HTML atom and XML atom are not both asterix?");
     mMatchAll = PR_TRUE;
   }
   else {
     mMatchAll = PR_FALSE;
   }
   mRootNode->AddMutationObserver(this);
 }
 
@@ -411,17 +414,17 @@ nsContentList::nsContentList(nsINode* aR
                              nsContentListMatchFunc aFunc,
                              nsContentListDestroyFunc aDestroyFunc,
                              void* aData,
                              PRBool aDeep,
                              nsIAtom* aMatchAtom,
                              PRInt32 aMatchNameSpaceId,
                              PRBool aFuncMayDependOnAttr)
   : nsBaseContentList(),
-    nsContentListKey(aRootNode, aMatchAtom, aMatchNameSpaceId),
+    nsContentListKey(aRootNode, aMatchAtom, aMatchAtom, aMatchNameSpaceId),
     mFunc(aFunc),
     mDestroyFunc(aDestroyFunc),
     mData(aData),
     mMatchAll(PR_FALSE),
     mState(LIST_DIRTY),
     mDeep(aDeep),
     mFuncMayDependOnAttr(aFuncMayDependOnAttr)
 {
@@ -768,35 +771,49 @@ nsContentList::ContentRemoved(nsIDocumen
 
   ASSERT_IN_SYNC;
 }
 
 PRBool
 nsContentList::Match(Element *aElement)
 {
   if (mFunc) {
-    return (*mFunc)(aElement, mMatchNameSpaceId, mMatchAtom, mData);
+    return (*mFunc)(aElement, mMatchNameSpaceId, mXMLMatchAtom, mData);
   }
 
-  if (mMatchAtom) {
-    nsINodeInfo *ni = aElement->NodeInfo();
+  if (!mXMLMatchAtom)
+    return PR_FALSE;
 
-    if (mMatchNameSpaceId == kNameSpaceID_Unknown) {
-      return (mMatchAll || ni->QualifiedNameEquals(mMatchAtom));
-    }
+  nsINodeInfo *ni = aElement->NodeInfo();
+ 
+  PRBool unknown = mMatchNameSpaceId == kNameSpaceID_Unknown;
+  PRBool wildcard = mMatchNameSpaceId == kNameSpaceID_Wildcard;
+  PRBool toReturn = mMatchAll;
+  if (!unknown && !wildcard)
+    toReturn &= ni->NamespaceEquals(mMatchNameSpaceId);
+
+  if (toReturn)
+    return toReturn;
 
-    if (mMatchNameSpaceId == kNameSpaceID_Wildcard) {
-      return (mMatchAll || ni->Equals(mMatchAtom));
-    }
-
-    return ((mMatchAll && ni->NamespaceEquals(mMatchNameSpaceId)) ||
-            ni->Equals(mMatchAtom, mMatchNameSpaceId));
+  nsIDocument* doc = aElement->GetOwnerDoc();
+  PRBool matchHTML = aElement->GetNameSpaceID() == kNameSpaceID_XHTML &&
+    doc && doc->IsHTML();
+ 
+  if (unknown) {
+    return matchHTML ? ni->QualifiedNameEquals(mHTMLMatchAtom) :
+                       ni->QualifiedNameEquals(mXMLMatchAtom);
   }
-
-  return PR_FALSE;
+  
+  if (wildcard) {
+    return matchHTML ? ni->Equals(mHTMLMatchAtom) :
+                       ni->Equals(mXMLMatchAtom);
+  }
+  
+  return matchHTML ? ni->Equals(mHTMLMatchAtom, mMatchNameSpaceId) :
+                     ni->Equals(mXMLMatchAtom, mMatchNameSpaceId);
 }
 
 PRBool 
 nsContentList::MatchSelf(nsIContent *aContent)
 {
   NS_PRECONDITION(aContent, "Can't match null stuff, you know");
   NS_PRECONDITION(mDeep || aContent->GetNodeParent() == mRootNode,
                   "MatchSelf called on a node that we can't possibly match");
--- a/content/base/src/nsContentList.h
+++ b/content/base/src/nsContentList.h
@@ -139,48 +139,57 @@ public:
 /**
  * Class that's used as the key to hash nsContentList implementations
  * for fast retrieval
  */
 class nsContentListKey
 {
 public:
   nsContentListKey(nsINode* aRootNode,
-                   nsIAtom* aMatchAtom, 
+                   nsIAtom* aHTMLMatchAtom,
+                   nsIAtom* aXMLMatchAtom,
                    PRInt32 aMatchNameSpaceId)
-    : mMatchAtom(aMatchAtom),
+    : mHTMLMatchAtom(aHTMLMatchAtom),
+      mXMLMatchAtom(aXMLMatchAtom),
       mMatchNameSpaceId(aMatchNameSpaceId),
       mRootNode(aRootNode)
   {
+    NS_ASSERTION(!aXMLMatchAtom == !aHTMLMatchAtom, "Either neither or both atoms should be null");
   }
   
   nsContentListKey(const nsContentListKey& aContentListKey)
-    : mMatchAtom(aContentListKey.mMatchAtom),
+    : mHTMLMatchAtom(aContentListKey.mHTMLMatchAtom),
+      mXMLMatchAtom(aContentListKey.mXMLMatchAtom),
       mMatchNameSpaceId(aContentListKey.mMatchNameSpaceId),
       mRootNode(aContentListKey.mRootNode)
   {
   }
 
   PRBool Equals(const nsContentListKey& aContentListKey) const
   {
+    NS_ASSERTION(mHTMLMatchAtom == aContentListKey.mHTMLMatchAtom 
+                 || mXMLMatchAtom != aContentListKey.mXMLMatchAtom, "HTML atoms should match if XML atoms match");
+
     return
-      mMatchAtom == aContentListKey.mMatchAtom &&
+      mXMLMatchAtom == aContentListKey.mXMLMatchAtom &&
       mMatchNameSpaceId == aContentListKey.mMatchNameSpaceId &&
       mRootNode == aContentListKey.mRootNode;
   }
+
   inline PRUint32 GetHash(void) const
   {
     return
-      NS_PTR_TO_INT32(mMatchAtom.get()) ^
+      NS_PTR_TO_INT32(mXMLMatchAtom.get()) ^
       (NS_PTR_TO_INT32(mRootNode) << 12) ^
       (mMatchNameSpaceId << 24);
   }
   
 protected:
-  nsCOMPtr<nsIAtom> mMatchAtom;
+  nsCOMPtr<nsIAtom> mHTMLMatchAtom;
+  nsCOMPtr<nsIAtom> mXMLMatchAtom;
   PRInt32 mMatchNameSpaceId;
   nsINode* mRootNode; // Weak ref
 };
 
 /**
  * LIST_UP_TO_DATE means that the list is up to date and need not do
  * any walking to be able to answer any questions anyone may have.
  */
@@ -225,18 +234,19 @@ public:
    *                          Otherwise we match nodes whose namespace is
    *                          aMatchNameSpaceId and localName matches
    *                          aMatchAtom.
    * @param aDeep If false, then look only at children of the root, nothing
    *              deeper.  If true, then look at the whole subtree rooted at
    *              our root.
    */  
   nsContentList(nsINode* aRootNode,
-                nsIAtom* aMatchAtom, 
                 PRInt32 aMatchNameSpaceId,
+                nsIAtom* aHTMLMatchAtom,
+                nsIAtom* aXMLMatchAtom,
                 PRBool aDeep = PR_TRUE);
 
   /**
    * @param aRootNode The node under which to limit our search.
    * @param aFunc the function to be called to determine whether we match.
    *              This function MUST NOT ever cause mutation of the DOM.
    *              The nsContentList implementation guarantees that everything
    *              passed to the function will be IsElement().
@@ -480,18 +490,20 @@ protected:
     RemoveFromFuncStringHashtable();
   }
   void RemoveFromFuncStringHashtable();
 
   nsString mString;
 };
 
 already_AddRefed<nsContentList>
-NS_GetContentList(nsINode* aRootNode, nsIAtom* aMatchAtom,
-                  PRInt32 aMatchNameSpaceId);
+NS_GetContentList(nsINode* aRootNode,
+                  PRInt32 aMatchNameSpaceId,
+                  nsIAtom* aHTMLMatchAtom,
+                  nsIAtom* aXMLMatchAtom = nsnull);
 
 already_AddRefed<nsContentList>
 NS_GetFuncStringContentList(nsINode* aRootNode,
                             nsContentListMatchFunc aFunc,
                             nsContentListDestroyFunc aDestroyFunc,
                             nsFuncStringContentListDataAllocator aDataAllocator,
                             const nsAString& aString);
 #endif // nsContentList_h___
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -4402,17 +4402,19 @@ nsDocument::CreateElement(const nsAStrin
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRBool needsLowercase = IsHTML() && !IsLowercaseASCII(aTagName);
   nsAutoString lcTagName;
   if (needsLowercase) {
     ToLowerCase(aTagName, lcTagName);
   }
 
-  rv = CreateElem(needsLowercase ? lcTagName : aTagName, nsnull,
+  rv = CreateElem(needsLowercase ? static_cast<const nsAString&>(lcTagName)
+                                 : aTagName,
+                  nsnull,
                   IsHTML() ? kNameSpaceID_XHTML : GetDefaultNamespaceID(),
                   PR_TRUE, aReturn);
   return rv;
 }
 
 NS_IMETHODIMP
 nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
                             const nsAString& aQualifiedName,
@@ -4589,28 +4591,22 @@ nsDocument::CreateEntityReference(const 
 
   *aReturn = nsnull;
   return NS_OK;
 }
 
 already_AddRefed<nsContentList>
 nsDocument::GetElementsByTagName(const nsAString& aTagname)
 {
-  nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aTagname);
-  if (IsHTML()) {
-    nsAutoString tmp(aTagname);
-    ToLowerCase(tmp); // HTML elements are lower case internally.
-    nameAtom = do_GetAtom(tmp);
-  }
-  else {
-    nameAtom = do_GetAtom(aTagname);
-  }
-  NS_ENSURE_TRUE(nameAtom, nsnull);
-
-  return NS_GetContentList(this, nameAtom, kNameSpaceID_Unknown);
+  nsAutoString lowercaseName;
+  nsContentUtils::ASCIIToLower(aTagname, lowercaseName);
+  nsCOMPtr<nsIAtom> xmlAtom = do_GetAtom(aTagname);
+  nsCOMPtr<nsIAtom> htmlAtom = do_GetAtom(lowercaseName);
+
+  return NS_GetContentList(this, kNameSpaceID_Unknown, htmlAtom, xmlAtom);
 }
 
 NS_IMETHODIMP
 nsDocument::GetElementsByTagName(const nsAString& aTagname,
                                  nsIDOMNodeList** aReturn)
 {
   nsRefPtr<nsContentList> list = GetElementsByTagName(aTagname);
   NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
@@ -4629,19 +4625,18 @@ nsDocument::GetElementsByTagNameNS(const
   if (!aNamespaceURI.EqualsLiteral("*")) {
     nsresult rv =
       nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
                                                             nameSpaceId);
     NS_ENSURE_SUCCESS(rv, nsnull);
   }
 
   nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aLocalName);
-  NS_ENSURE_TRUE(nameAtom, nsnull);
-
-  return NS_GetContentList(this, nameAtom, nameSpaceId);
+
+  return NS_GetContentList(this, nameSpaceId, nameAtom);
 }
 
 NS_IMETHODIMP
 nsDocument::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
                                    const nsAString& aLocalName,
                                    nsIDOMNodeList** aReturn)
 {
   nsRefPtr<nsContentList> list = GetElementsByTagNameNS(aNamespaceURI,
@@ -5198,19 +5193,17 @@ nsDocument::GetTitleContent(PRUint32 aNa
   // <title> element has been bound to this document. So if it's false,
   // we know there is nothing to do here. This avoids us having to search
   // the whole DOM if someone calls document.title on a large document
   // without a title.
   if (!mMayHaveTitleElement)
     return nsnull;
 
   nsRefPtr<nsContentList> list =
-    NS_GetContentList(this, nsGkAtoms::title, aNamespace);
-  if (!list)
-    return nsnull;
+    NS_GetContentList(this, aNamespace, nsGkAtoms::title);
 
   return list->Item(0, PR_FALSE);
 }
 
 void
 nsDocument::GetTitleFromElement(PRUint32 aNamespace, nsAString& aTitle)
 {
   nsIContent* title = GetTitleContent(aNamespace);
@@ -5841,17 +5834,17 @@ NS_IMETHODIMP
 nsDocument::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
 {
   return nsNodeUtils::CloneNodeImpl(this, aDeep, aReturn);
 }
 
 NS_IMETHODIMP
 nsDocument::Normalize()
 {
-  for (PRInt32 i = 0; i < mChildren.ChildCount(); ++i) {
+  for (PRUint32 i = 0; i < mChildren.ChildCount(); ++i) {
     nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mChildren.ChildAt(i)));
     node->Normalize();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -7401,26 +7394,24 @@ nsDocument::OnPageShow(PRBool aPersisted
 
   EnumerateFreezableElements(NotifyActivityChanged, nsnull);
   EnumerateExternalResources(NotifyPageShow, &aPersisted);
 
   Element* root = GetRootElement();
   if (aPersisted && root) {
     // Send out notifications that our <link> elements are attached.
     nsRefPtr<nsContentList> links = NS_GetContentList(root,
-                                                      nsGkAtoms::link,
-                                                      kNameSpaceID_Unknown);
-
-    if (links) {
-      PRUint32 linkCount = links->Length(PR_TRUE);
-      for (PRUint32 i = 0; i < linkCount; ++i) {
-        nsCOMPtr<nsILink> link = do_QueryInterface(links->Item(i, PR_FALSE));
-        if (link) {
-          link->LinkAdded();
-        }
+                                                      kNameSpaceID_Unknown,
+                                                      nsGkAtoms::link);
+
+    PRUint32 linkCount = links->Length(PR_TRUE);
+    for (PRUint32 i = 0; i < linkCount; ++i) {
+      nsCOMPtr<nsILink> link = do_QueryInterface(links->Item(i, PR_FALSE));
+      if (link) {
+        link->LinkAdded();
       }
     }
   }
 
   // See nsIDocument
   if (!aDispatchStartTarget) {
     // Set mIsShowing before firing events, in case those event handlers
     // move us around.
@@ -7455,26 +7446,24 @@ void
 nsDocument::OnPageHide(PRBool aPersisted,
                        nsIDOMEventTarget* aDispatchStartTarget)
 {
   // Send out notifications that our <link> elements are detached,
   // but only if this is not a full unload.
   Element* root = GetRootElement();
   if (aPersisted && root) {
     nsRefPtr<nsContentList> links = NS_GetContentList(root,
-                                                      nsGkAtoms::link,
-                                                      kNameSpaceID_Unknown);
-
-    if (links) {
-      PRUint32 linkCount = links->Length(PR_TRUE);
-      for (PRUint32 i = 0; i < linkCount; ++i) {
-        nsCOMPtr<nsILink> link = do_QueryInterface(links->Item(i, PR_FALSE));
-        if (link) {
-          link->LinkRemoved();
-        }
+                                                      kNameSpaceID_Unknown,
+                                                      nsGkAtoms::link);
+
+    PRUint32 linkCount = links->Length(PR_TRUE);
+    for (PRUint32 i = 0; i < linkCount; ++i) {
+      nsCOMPtr<nsILink> link = do_QueryInterface(links->Item(i, PR_FALSE));
+      if (link) {
+        link->LinkRemoved();
       }
     }
   }
 
   // See nsIDocument
   if (!aDispatchStartTarget) {
     // Set mIsShowing before firing events, in case those event handlers
     // move us around.
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -407,44 +407,16 @@ nsFrameLoader::GetDocShell(nsIDocShell *
   }
 
   *aDocShell = mDocShell;
   NS_IF_ADDREF(*aDocShell);
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsFrameLoader::GetWebProgress(nsIWebProgress **aWebProgress)
-{
-  nsresult rv;
-  *aWebProgress = nsnull;
-#ifdef MOZ_IPC
-  if (mRemoteFrame) {
-    if (!mRemoteBrowser) {
-      TryRemoteBrowser();
-    }
-    if (!mRemoteBrowser) {
-      return NS_ERROR_UNEXPECTED;
-    }
-    *aWebProgress = mRemoteBrowser;
-    NS_ADDREF(*aWebProgress);
-    return NS_OK;
-  }
-#endif
-
-  nsCOMPtr<nsIDocShell> shell;
-  rv = GetDocShell(getter_AddRefs(shell));
-  if (NS_SUCCEEDED(rv)) {
-    nsCOMPtr<nsIWebProgress> progress(do_QueryInterface(shell));
-    progress.swap(*aWebProgress);
-  }
-  return rv;
-}
-
 void
 nsFrameLoader::Finalize()
 {
   nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
   if (base_win) {
     base_win->Destroy();
   }
   mDocShell = nsnull;
@@ -1398,16 +1370,24 @@ nsFrameLoader::CheckForRecursiveLoad(nsI
                "Shouldn't call CheckForRecursiveLoad on remote frames.");
 #endif
   if (!mDocShell) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
   NS_ASSERTION(treeItem, "docshell must be a treeitem!");
+
+  // Check that we're still in the docshell tree.
+  nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
+  treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
+  NS_WARN_IF_FALSE(treeOwner,
+                   "Trying to load a new url to a docshell without owner!");
+  NS_ENSURE_STATE(treeOwner);
+  
   
   PRInt32 ourType;
   rv = treeItem->GetItemType(&ourType);
   if (NS_SUCCEEDED(rv) && ourType != nsIDocShellTreeItem::typeContent) {
     // No need to do recursion-protection here XXXbz why not??  Do we really
     // trust people not to screw up with non-content docshells?
     return NS_OK;
   }
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -1360,18 +1360,19 @@ nsNSElementTearoff::GetNextElementSiblin
 
 nsContentList*
 nsGenericElement::GetChildrenList()
 {
   nsGenericElement::nsDOMSlots *slots = GetDOMSlots();
   NS_ENSURE_TRUE(slots, nsnull);
 
   if (!slots->mChildrenList) {
-    slots->mChildrenList = new nsContentList(this, nsGkAtoms::_asterix,
-                                             kNameSpaceID_Wildcard, PR_FALSE);
+    slots->mChildrenList = new nsContentList(this, kNameSpaceID_Wildcard, 
+                                             nsGkAtoms::_asterix, nsGkAtoms::_asterix,
+                                             PR_FALSE);
   }
 
   return slots->mChildrenList;
 }
 
 NS_IMETHODIMP
 nsNSElementTearoff::GetChildElementCount(PRUint32* aResult)
 {
@@ -2490,22 +2491,23 @@ nsGenericElement::RemoveAttributeNode(ns
 
   return rv;
 }
 
 nsresult
 nsGenericElement::GetElementsByTagName(const nsAString& aTagname,
                                        nsIDOMNodeList** aReturn)
 {
-  nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aTagname);
-  NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
-
-  nsContentList *list = NS_GetContentList(this, nameAtom,
-                                          kNameSpaceID_Unknown).get();
-  NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
+  nsAutoString lowercaseName;
+  nsContentUtils::ASCIIToLower(aTagname, lowercaseName);
+  nsCOMPtr<nsIAtom> XMLAtom = do_GetAtom(aTagname);
+  nsCOMPtr<nsIAtom> HTMLAtom = do_GetAtom(lowercaseName);
+
+  nsContentList *list = NS_GetContentList(this, kNameSpaceID_Unknown, 
+                                          HTMLAtom, XMLAtom).get();
 
   // transfer ref to aReturn
   *aReturn = list;
   return NS_OK;
 }
 
 nsresult
 nsGenericElement::GetAttributeNS(const nsAString& aNamespaceURI,
@@ -2622,20 +2624,18 @@ nsGenericElement::GetElementsByTagNameNS
   if (!aNamespaceURI.EqualsLiteral("*")) {
     nsresult rv =
       nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
                                                             nameSpaceId);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aLocalName);
-  NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
-
-  nsContentList *list = NS_GetContentList(this, nameAtom, nameSpaceId).get();
-  NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
+
+  nsContentList *list = NS_GetContentList(this, nameSpaceId, nameAtom).get();
 
   // transfer ref to aReturn
   *aReturn = list;
   return NS_OK;
 }
 
 nsresult
 nsGenericElement::HasAttribute(const nsAString& aName, PRBool* aReturn)
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -170,16 +170,18 @@ include $(topsrcdir)/config/rules.mk
 		test_bug417384.html \
 		test_bug418214.html \
 		test_bug419527.xhtml \
 		test_bug420609.xhtml \
 		test_bug420700.html \
 		test_bug421602.html \
 		test_bug422537.html \
 		test_bug424359-1.html \
+		test_bug499656.html \
+		test_bug499656.xhtml \
 		file_htmlserializer_1.html \
 		file_htmlserializer_1_bodyonly.html \
 		file_htmlserializer_1_format.html \
 		file_htmlserializer_1_linebreak.html \
 		file_htmlserializer_1_links.html \
 		file_htmlserializer_1_noflag.html \
 		file_htmlserializer_1_noformatpre.html \
 		file_htmlserializer_1_raw.html \
--- a/content/base/test/chrome/Makefile.in
+++ b/content/base/test/chrome/Makefile.in
@@ -40,27 +40,24 @@ srcdir    = @srcdir@
 VPATH     = @srcdir@
 relativesrcdir  = content/base/test/chrome
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES = \
     bug421622-referer.sjs \
-    bug514705.html \
     $(NULL)
 
 _CHROME_FILES = \
     test_bug206691.xul \
     test_bug421622.xul \
     test_bug429785.xul \
     test_bug430050.xul \
     test_bug467123.xul \
-    test_bug514705.xul \
-    bug514705_helper.xul \
     test_title.xul \
     title_window.xul \
     test_bug549682.xul \
     file_bug549682.xul \
     $(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
deleted file mode 100644
--- a/content/base/test/chrome/bug514705.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<html>
-<head>
-  <title>bug514705.html</title>
-</head>
-
-<body>
-bug514705.html
-</body>
-</html>
deleted file mode 100644
--- a/content/base/test/chrome/bug514705_helper.xul
+++ /dev/null
@@ -1,90 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-
-<window title="Bug514705 helper"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        onload="RunTest();">
-
-  <script type="application/javascript">
-  <![CDATA[
-    var Ci = Components.interfaces;
-    var imports = [ "SimpleTest", "is", "isnot", "ok" ];
-    for each (var import in imports) {
-      window[import] = window.opener.wrappedJSObject[import];
-    }
-    var locationChanged = false;
-    var progressChanged = false;
-    var refreshAttempted = false;
-
-    var listener = {
-      onLocationChange: function(webProgress, request, location) {
-        locationChanged = true;
-      },
-      onProgressChange: function(webProgress, request, curSelfProgress, 
-                                 maxSelfProgress, curTotalProgress,
-                                 maxTotalProgress) {
-      },
-      onSecurityChange: function(webProgress, request, state) { 
-      },
-      onStateChange: function(webProgress, request, stateFlags, status) { 
- 
-        if ((stateFlags & Ci.nsIWebProgressListener.STATE_STOP) &&
-            (stateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW)) {
-          var test = SimpleTest;
-          ok (locationChanged, "onLocationChanged was called.");
-          ok (progressChanged, "onProgressChanged64 was called.");
-          ok (refreshAttempted, "onRefreshAttempted was called.");
-          ok (true, "onStateChange was called.");
-          window.close();
-          test.finish();
-        }
-      },
-      onStatusChange: function(webProgress, request, status, message) { 
-      },
-      onProgressChange64 : function(webProgress, request, curSelfProgress,
-                                    maxSelfProgress, curTotalProgress,
-                                    maxTotalProgress) {
-        
-        progressChanged = true;
-      },
-      onRefreshAttempted : function(webProgress, uri, millis, sameURI)
-      {
-        refreshAttempted = true;
-        return true;
-      },
-      QueryInterface: function(iid) {
-        if (iid.equals(Components.interfaces.nsIWebProgressListener) ||
-            iid.equals(Components.interfaces.nsIWebProgressListener2) ||
-            iid.equals(Components.interfaces.nsISupportsWeakReference)) {
-          return this;
-        }
-        throw Components.results.NS_NOINTERFACE;
-      }
-    }
-    function EndTest() {
-      var test = SimpleTest;
-      window.close();
-      test.finish();
-    }
-    function RunTest()
-    {
-      var browser = document.getElementById('page');
-      var flags = Ci.nsIWebProgress.NOTIFY_ALL;
-
-      browser.webProgress.addProgressListener(listener, flags);
-            
-      var script = "refreshURI = docShell.QueryInterface(Components.interfaces.nsIRefreshURI);"
-        + "var ioServ = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService);"
-        + "var uri = ioServ.newURI('http://localhost:8888/tests/content/base/test/chrome/bug514705.html', null, null);"
-        + "refreshURI.refreshURI(uri, 100, false, false);";
-      messageManager.loadFrameScript("data:," + script, true);
-     }
-
-  ]]>
-  </script>
-
-
-  <browser type="content" flex="1" id="page" remote="true"/>
-
-</window>
deleted file mode 100644
--- a/content/base/test/chrome/test_bug514705.xul
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-
-<window title="Bug 514705"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        onload="RunTest();">
-  <script type="application/javascript" 
-          src="chrome://mochikit/content/MochiKit/packed.js"/>
-  <script type="application/javascript"
-          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
-  <!-- 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=421622"
-     target="_blank">Mozilla Bug 421622</a>
-  </body>
-
-  <script type="application/javascript">
-  <![CDATA[
-    //SimpleTest.waitForExplicitFinish();
-    todo(false, "Enable this test");
-    
-    function RunTest()
-    {
-      //window.open("bug514705_helper.xul", "bug514705",
-      //            "chrome,width=100,height=100");
-    }
-  ]]>
-  </script>
-</window>
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug499656.html
@@ -0,0 +1,58 @@
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=499656
+-->
+<head>
+  <title>Test for Bug 499656</title>
+  <script type="text/javascript" src="/MochiKit/packed.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=499656">Mozilla Bug 499655</a>
+<p id="display"></p>
+<div id="content">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 499655 **/
+
+div1 = document.createElementNS("http://www.w3.org/1999/xhtml","test");
+div2 = document.createElementNS("http://www.w3.org/1999/xhtml","TEst");
+div3 = document.createElementNS("test","test");
+div4 = document.createElementNS("test","TEst");
+div5 = document.createElement("test");
+div6 = document.createElement("TEst");
+
+content = document.getElementById("content");
+
+content.appendChild(div1);
+content.appendChild(div2);
+content.appendChild(div3);
+content.appendChild(div4);
+content.appendChild(div5);
+content.appendChild(div6);
+
+list = document.getElementsByTagName('test');
+is(list.length, 4, "Number of elements found");
+ok(list[0] == div1, "First element didn't match");
+ok(list[1] == div3, "Third element didn't match");
+ok(list[2] == div5, "Fifth element didn't match");
+ok(list[3] == div6, "Sixth element didn't match");
+
+list = document.getElementsByTagName('TEst');
+is(list.length, 4, "Wrong number of elements found");
+ok(list[0] == div1, "First element didn't match");
+ok(list[1] == div4, "Fourth element didn't match");
+ok(list[2] == div5, "Fifth element didn't match");
+ok(list[3] == div6, "Sixth element didn't match");
+
+list = document.getElementsByTagNameNS('test', 'test');
+is(list.length, 1, "Wrong number of elements found");
+ok(list[0] == div3, "Third element didn't match");
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug499656.xhtml
@@ -0,0 +1,58 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=499655
+-->
+<head>
+  <title>Test for Bug 499655</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <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=499655">Mozilla Bug 499655</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+<![CDATA[
+
+div1 = document.createElementNS("http://www.w3.org/1999/xhtml","test");
+div2 = document.createElementNS("http://www.w3.org/1999/xhtml","TEst");
+div3 = document.createElementNS("test","test");
+div4 = document.createElementNS("test","TEst");
+div5 = document.createElement("test");
+div6 = document.createElement("TEst");
+
+content = document.getElementById("content");
+
+content.appendChild(div1);
+content.appendChild(div2);
+content.appendChild(div3);
+content.appendChild(div4);
+content.appendChild(div5);
+content.appendChild(div6);
+
+
+list = document.getElementsByTagName('test');
+is(list.length, 3, "Number of elements found");
+ok(list[0] == div1, "First element didn't match");
+ok(list[1] == div3, "Third element didn't match");
+ok(list[2] == div5, "Fifth element didn't match");
+
+list = document.getElementsByTagName('TEst');
+is(list.length, 3, "Number of elements found");
+ok(list[0] == div2, "Second element didn't match");
+ok(list[1] == div4, "Fourth element didn't match");
+ok(list[2] == div6, "Sixth element didn't match");
+
+list = document.getElementsByTagNameNS('test', 'test');
+is(list.length, 1, "Wrong number of elements found");
+ok(list[0] == div3, "Third element didn't match");
+
+]]>
+</script>
+</pre>
+</body>
+</html>
--- a/content/html/content/src/nsHTMLMapElement.cpp
+++ b/content/html/content/src/nsHTMLMapElement.cpp
@@ -111,23 +111,20 @@ NS_IMPL_ELEMENT_CLONE(nsHTMLMapElement)
 NS_IMETHODIMP
 nsHTMLMapElement::GetAreas(nsIDOMHTMLCollection** aAreas)
 {
   NS_ENSURE_ARG_POINTER(aAreas);
 
   if (!mAreas) {
     // Not using NS_GetContentList because this should not be cached
     mAreas = new nsContentList(this,
+                               mNodeInfo->NamespaceID(),
                                nsGkAtoms::area,
-                               mNodeInfo->NamespaceID(),
+                               nsGkAtoms::area,
                                PR_FALSE);
-
-    if (!mAreas) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
   }
 
   NS_ADDREF(*aAreas = mAreas);
   return NS_OK;
 }
 
 
 NS_IMPL_STRING_ATTR(nsHTMLMapElement, Name, name)
--- a/content/html/content/src/nsHTMLTableElement.cpp
+++ b/content/html/content/src/nsHTMLTableElement.cpp
@@ -164,20 +164,21 @@ NS_INTERFACE_TABLE_HEAD(TableRowsCollect
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(TableRowsCollection)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(HTMLCollection)
 NS_INTERFACE_MAP_END
 
 nsresult
 TableRowsCollection::Init()
 {
   mOrphanRows = new nsContentList(mParent,
+                                  mParent->NodeInfo()->NamespaceID(),
                                   nsGkAtoms::tr,
-                                  mParent->NodeInfo()->NamespaceID(),
+                                  nsGkAtoms::tr,
                                   PR_FALSE);
-  return mOrphanRows ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+  return NS_OK;
 }
 
 // Macro that can be used to avoid copy/pasting code to iterate over the
 // rowgroups.  _code should be the code to execute for each rowgroup.  The
 // rowgroup's rows will be in the nsIDOMHTMLCollection* named "rows".  Note
 // that this may be null at any time.  This macro assumes an nsresult named
 // |rv| is in scope.
 #define DO_FOR_EACH_ROWGROUP(_code)                                  \
@@ -594,21 +595,20 @@ nsHTMLTableElement::GetRows(nsIDOMHTMLCo
 }
 
 NS_IMETHODIMP
 nsHTMLTableElement::GetTBodies(nsIDOMHTMLCollection** aValue)
 {
   if (!mTBodies) {
     // Not using NS_GetContentList because this should not be cached
     mTBodies = new nsContentList(this,
+                                 mNodeInfo->NamespaceID(),
                                  nsGkAtoms::tbody,
-                                 mNodeInfo->NamespaceID(),
+                                 nsGkAtoms::tbody,
                                  PR_FALSE);
-
-    NS_ENSURE_TRUE(mTBodies, NS_ERROR_OUT_OF_MEMORY);
   }
 
   NS_ADDREF(*aValue = mTBodies);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLTableElement::CreateTHead(nsIDOMHTMLElement** aValue)
--- a/content/html/content/src/nsHTMLTableSectionElement.cpp
+++ b/content/html/content/src/nsHTMLTableSectionElement.cpp
@@ -128,18 +128,19 @@ NS_IMPL_STRING_ATTR(nsHTMLTableSectionEl
 
 NS_IMETHODIMP
 nsHTMLTableSectionElement::GetRows(nsIDOMHTMLCollection** aValue)
 {
   *aValue = nsnull;
 
   if (!mRows) {
     mRows = new nsContentList(this,
+                              mNodeInfo->NamespaceID(),
                               nsGkAtoms::tr,
-                              mNodeInfo->NamespaceID(),
+                              nsGkAtoms::tr,
                               PR_FALSE);
 
     NS_ENSURE_TRUE(mRows, NS_ERROR_OUT_OF_MEMORY);
   }
 
   NS_ADDREF(*aValue = mRows);
   return NS_OK;
 }
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -1169,19 +1169,18 @@ nsHTMLDocument::SetTitle(const nsAString
 {
   return nsDocument::SetTitle(aTitle);
 }
 
 nsIDOMHTMLMapElement *
 nsHTMLDocument::GetImageMap(const nsAString& aMapName)
 {
   if (!mImageMaps) {
-    mImageMaps = new nsContentList(this, nsGkAtoms::map, kNameSpaceID_XHTML);
+    mImageMaps = new nsContentList(this, kNameSpaceID_XHTML, nsGkAtoms::map, nsGkAtoms::map);
   }
-  NS_ASSERTION(mImageMaps, "Infallible malloc failed.");
 
   nsIDOMHTMLMapElement* firstMatch = nsnull;
   nsAutoString name;
   PRUint32 i, n = mImageMaps->Length(PR_TRUE);
   for (i = 0; i < n; ++i) {
     nsCOMPtr<nsIDOMHTMLMapElement> map(
       do_QueryInterface(mImageMaps->GetNodeAt(i)));
 
@@ -1545,22 +1544,17 @@ nsHTMLDocument::GetBody(nsresult *aResul
   if (body) {
     // There is a body element, return that as the body.
     return body;
   }
 
   // The document is most likely a frameset document so look for the
   // outer most frameset element
   nsRefPtr<nsContentList> nodeList =
-    NS_GetContentList(this, nsGkAtoms::frameset, kNameSpaceID_XHTML);
-  if (!nodeList) {
-    *aResult = NS_ERROR_OUT_OF_MEMORY;
-
-    return nsnull;
-  }
+    NS_GetContentList(this, kNameSpaceID_XHTML, nsGkAtoms::frameset);
 
   return nodeList->GetNodeAt(0);
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::GetBody(nsIDOMHTMLElement** aBody)
 {
   *aBody = nsnull;
@@ -1608,36 +1602,30 @@ nsHTMLDocument::GetHead(nsIDOMHTMLHeadEl
 
   return head ? CallQueryInterface(head, aHead) : NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::GetImages(nsIDOMHTMLCollection** aImages)
 {
   if (!mImages) {
-    mImages = new nsContentList(this, nsGkAtoms::img, kNameSpaceID_XHTML);
-    if (!mImages) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
+    mImages = new nsContentList(this, kNameSpaceID_XHTML, nsGkAtoms::img, nsGkAtoms::img);
   }
 
   *aImages = mImages;
   NS_ADDREF(*aImages);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::GetApplets(nsIDOMHTMLCollection** aApplets)
 {
   if (!mApplets) {
-    mApplets = new nsContentList(this, nsGkAtoms::applet, kNameSpaceID_XHTML);
-    if (!mApplets) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
+    mApplets = new nsContentList(this, kNameSpaceID_XHTML, nsGkAtoms::applet, nsGkAtoms::applet);
   }
 
   *aApplets = mApplets;
   NS_ADDREF(*aApplets);
 
   return NS_OK;
 }
 
@@ -1673,19 +1661,16 @@ nsHTMLDocument::MatchLinks(nsIContent *a
   return PR_FALSE;
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::GetLinks(nsIDOMHTMLCollection** aLinks)
 {
   if (!mLinks) {
     mLinks = new nsContentList(this, MatchLinks, nsnull, nsnull);
-    if (!mLinks) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
   }
 
   *aLinks = mLinks;
   NS_ADDREF(*aLinks);
 
   return NS_OK;
 }
 
@@ -1713,19 +1698,16 @@ nsHTMLDocument::MatchAnchors(nsIContent 
   return PR_FALSE;
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::GetAnchors(nsIDOMHTMLCollection** aAnchors)
 {
   if (!mAnchors) {
     mAnchors = new nsContentList(this, MatchAnchors, nsnull, nsnull);
-    if (!mAnchors) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
   }
 
   *aAnchors = mAnchors;
   NS_ADDREF(*aAnchors);
 
   return NS_OK;
 }
 
@@ -2511,20 +2493,17 @@ nsHTMLDocument::SetFgColor(const nsAStri
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsHTMLDocument::GetEmbeds(nsIDOMHTMLCollection** aEmbeds)
 {
   if (!mEmbeds) {
-    mEmbeds = new nsContentList(this, nsGkAtoms::embed, kNameSpaceID_XHTML);
-    if (!mEmbeds) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
+    mEmbeds = new nsContentList(this, kNameSpaceID_XHTML, nsGkAtoms::embed, nsGkAtoms::embed);
   }
 
   *aEmbeds = mEmbeds;
   NS_ADDREF(*aEmbeds);
 
   return NS_OK;
 }
 
@@ -2804,18 +2783,19 @@ nsHTMLDocument::GetForms(nsIDOMHTMLColle
 
   NS_ADDREF(*aForms = forms);
   return NS_OK;
 }
 
 nsContentList*
 nsHTMLDocument::GetForms()
 {
-  if (!mForms)
-    mForms = new nsContentList(this, nsGkAtoms::form, kNameSpaceID_XHTML);
+  if (!mForms) {
+    mForms = new nsContentList(this, kNameSpaceID_XHTML, nsGkAtoms::form, nsGkAtoms::form);
+  }
 
   return mForms;
 }
 
 static PRBool MatchFormControls(nsIContent* aContent, PRInt32 aNamespaceID,
                                 nsIAtom* aAtom, void* aData)
 {
   return aContent->IsNodeOfType(nsIContent::eHTML_FORM_CONTROL);
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -1119,17 +1119,19 @@ nsXBLBinding::ChangeDocument(nsIDocument
               if (!proto) {
                 break;
               }
 
               JSClass* clazz = ::JS_GET_CLASS(cx, proto);
               if (!clazz ||
                   (~clazz->flags &
                    (JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS)) ||
-                  JSCLASS_RESERVED_SLOTS(clazz) != 1) {
+                  JSCLASS_RESERVED_SLOTS(clazz) != 1 ||
+                  clazz->resolve != (JSResolveOp)XBLResolve ||
+                  clazz->finalize != XBLFinalize) {
                 // Clearly not the right class
                 continue;
               }
 
               nsRefPtr<nsXBLDocumentInfo> docInfo =
                 static_cast<nsXBLDocumentInfo*>(::JS_GetPrivate(cx, proto));
               if (!docInfo) {
                 // Not the proto we seek
@@ -1337,16 +1339,20 @@ nsXBLBinding::DoInitJSClass(JSContext *c
 
       c->Drop();
 
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
     // Keep this proto binding alive while we're alive.  Do this first so that
     // we can guarantee that in XBLFinalize this will be non-null.
+    // Note that we can't just store aProtoBinding in the private and
+    // addref/release the nsXBLDocumentInfo through it, because cycle
+    // collection doesn't seem to work right if the private is not an
+    // nsISupports.
     nsXBLDocumentInfo* docInfo = aProtoBinding->XBLDocumentInfo();
     ::JS_SetPrivate(cx, proto, docInfo);
     NS_ADDREF(docInfo);
 
     if (!::JS_SetReservedSlot(cx, proto, 0, PRIVATE_TO_JSVAL(aProtoBinding))) {
       (nsXBLService::gClassTable)->Remove(&key);
 
       // |c| will get dropped when |proto| is finalized
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1628,16 +1628,17 @@ jsid nsDOMClassInfo::sOncanplay_id      
 jsid nsDOMClassInfo::sOncanplaythrough_id= JSID_VOID;
 jsid nsDOMClassInfo::sOnseeking_id       = JSID_VOID;
 jsid nsDOMClassInfo::sOnseeked_id        = JSID_VOID;
 jsid nsDOMClassInfo::sOntimeupdate_id    = JSID_VOID;
 jsid nsDOMClassInfo::sOnended_id         = JSID_VOID;
 jsid nsDOMClassInfo::sOnratechange_id    = JSID_VOID;
 jsid nsDOMClassInfo::sOndurationchange_id= JSID_VOID;
 jsid nsDOMClassInfo::sOnvolumechange_id  = JSID_VOID;
+jsid nsDOMClassInfo::sOnmessage_id       = JSID_VOID;
 
 static const JSClass *sObjectClass = nsnull;
 JSPropertyOp nsDOMClassInfo::sXPCNativeWrapperGetPropertyOp = nsnull;
 JSPropertyOp nsDOMClassInfo::sXrayWrapperPropertyHolderGetPropertyOp = nsnull;
 
 /**
  * Set our JSClass pointer for the Object class
  */
@@ -1851,16 +1852,17 @@ nsDOMClassInfo::DefineStaticJSVals(JSCon
   SET_JSID_TO_STRING(sOncanplaythrough_id,cx, "oncanplaythrough");
   SET_JSID_TO_STRING(sOnseeking_id,       cx, "onseeking");
   SET_JSID_TO_STRING(sOnseeked_id,        cx, "onseeked");
   SET_JSID_TO_STRING(sOntimeupdate_id,    cx, "ontimeupdate");
   SET_JSID_TO_STRING(sOnended_id,         cx, "onended");
   SET_JSID_TO_STRING(sOnratechange_id,    cx, "onratechange");
   SET_JSID_TO_STRING(sOndurationchange_id,cx, "ondurationchange");
   SET_JSID_TO_STRING(sOnvolumechange_id,  cx, "onvolumechange");
+  SET_JSID_TO_STRING(sOnmessage_id,       cx, "onmessage");
 #endif // MOZ_MEDIA
 
   return NS_OK;
 }
 
 static nsresult
 CreateExceptionFromResult(JSContext *cx, nsresult aResult)
 {
@@ -4923,16 +4925,17 @@ nsDOMClassInfo::ShutDown()
   sOncanplaythrough_id= JSID_VOID;
   sOnseeking_id       = JSID_VOID;
   sOnseeked_id        = JSID_VOID;
   sOntimeupdate_id    = JSID_VOID;
   sOnended_id         = JSID_VOID;
   sOnratechange_id    = JSID_VOID;
   sOndurationchange_id= JSID_VOID;
   sOnvolumechange_id  = JSID_VOID;
+  sOnmessage_id       = JSID_VOID;
 
   NS_IF_RELEASE(sXPConnect);
   NS_IF_RELEASE(sSecMan);
   sIsInitialized = PR_FALSE;
 }
 
 // Window helper
 
@@ -7772,17 +7775,18 @@ nsEventReceiverSH::ReallyIsEventName(jsi
             id == sOnloadeddata_id     ||
             id == sOnloadedmetadata_id ||
             id == sOnloadstart_id);
   case 'm' :
     return (id == sOnmousemove_id    ||
             id == sOnmouseout_id     ||
             id == sOnmouseover_id    ||
             id == sOnmouseup_id      ||
-            id == sOnmousedown_id);
+            id == sOnmousedown_id    ||
+            id == sOnmessage_id);
   case 'p' :
     return (id == sOnpaint_id        ||
             id == sOnpageshow_id     ||
             id == sOnpagehide_id     ||
             id == sOnpaste_id        ||
             id == sOnpopstate_id     ||
             id == sOnpause_id        ||
             id == sOnplay_id         ||
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -375,16 +375,17 @@ protected:
   static jsid sOncanplaythrough_id;
   static jsid sOnseeking_id;
   static jsid sOnseeked_id;
   static jsid sOntimeupdate_id;
   static jsid sOnended_id;
   static jsid sOnratechange_id;
   static jsid sOndurationchange_id;
   static jsid sOnvolumechange_id;
+  static jsid sOnmessage_id;
 
   static JSPropertyOp sXPCNativeWrapperGetPropertyOp;
   static JSPropertyOp sXrayWrapperPropertyHolderGetPropertyOp;
 };
 
 
 inline
 const nsQueryInterface
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -175,16 +175,51 @@ private:
     nsCString mPrefRoot;
     nsCString mDomain;
 
     // disable these
     PrefObserver(const PrefObserver&);
     PrefObserver& operator=(const PrefObserver&);
 };
 
+class AlertObserver
+{
+public:
+
+    AlertObserver(nsIObserver *aObserver, const nsString& aData)
+        : mData(aData)
+        , mObserver(aObserver)
+    {
+    }
+
+    ~AlertObserver() {}
+
+    bool ShouldRemoveFrom(nsIObserver* aObserver,
+                          const nsString& aData) const
+    {
+        return (mObserver == aObserver &&
+                mData == aData);
+    }
+
+    bool Observes(const nsString& aData) const
+    {
+        return mData.Equals(aData);
+    }
+
+    bool Notify(const nsCString& aType) const
+    {
+        mObserver->Observe(nsnull, aType.get(), mData.get());
+        return true;
+    }
+
+private:
+    nsCOMPtr<nsIObserver> mObserver;
+    nsString mData;
+};
+
 
 ContentChild* ContentChild::sSingleton;
 
 ContentChild::ContentChild()
     : mDead(false)
 {
 }
 
@@ -304,17 +339,17 @@ ContentChild::ActorDestroy(ActorDestroyR
     // We might be holding the last ref to some of the observers in
     // mPrefObserverArray.  Some of them try to unregister themselves
     // in their dtors (sketchy).  To side-step uaf problems and so
     // forth, we set this mDead flag.  Then, if during a Clear() a
     // being-deleted observer tries to unregister itself, it hits the
     // |if (mDead)| special case below and we're safe.
     mDead = true;
     mPrefObservers.Clear();
-
+    mAlertObservers.Clear();
     XRE_ShutdownChildProcess();
 }
 
 void
 ContentChild::ProcessingError(Result what)
 {
     switch (what) {
     case MsgDropped:
@@ -376,16 +411,25 @@ ContentChild::RemoveRemotePrefObserver(c
         }
         ++i;
     }
 
     NS_WARNING("RemoveRemotePrefObserver(): no observer was matched!");
     return NS_ERROR_UNEXPECTED;
 }
 
+nsresult
+ContentChild::AddRemoteAlertObserver(const nsString& aData,
+                                     nsIObserver* aObserver)
+{
+    NS_ASSERTION(aObserver, "Adding a null observer?");
+    mAlertObservers.AppendElement(new AlertObserver(aObserver, aData));
+    return NS_OK;
+}
+
 bool
 ContentChild::RecvNotifyRemotePrefObserver(const nsCString& aPref)
 {
     for (PRUint32 i = 0; i < mPrefObservers.Length();
          /*we mutate the array during the loop; ++i iff no mutation*/) {
         PrefObserver* observer = mPrefObservers[i];
         if (observer->Observes(aPref) &&
             !observer->Notify()) {
@@ -395,16 +439,37 @@ ContentChild::RecvNotifyRemotePrefObserv
             continue;
         }
         ++i;
     }
     return true;
 }
 
 bool
+ContentChild::RecvNotifyAlertsObserver(const nsCString& aType, const nsString& aData)
+{
+    printf("ContentChild::RecvNotifyAlertsObserver %s\n", aType.get() );
+
+    for (PRUint32 i = 0; i < mAlertObservers.Length();
+         /*we mutate the array during the loop; ++i iff no mutation*/) {
+        AlertObserver* observer = mAlertObservers[i];
+        if (observer->Observes(aData) && observer->Notify(aType)) {
+            // if aType == alertfinished, this alert is done.  we can
+            // remove the observer.
+            if (aType.Equals(nsDependentCString("alertfinished"))) {
+                mAlertObservers.RemoveElementAt(i);
+                continue;
+            }
+        }
+        ++i;
+    }
+    return true;
+}
+
+bool
 ContentChild::RecvNotifyVisited(const IPC::URI& aURI)
 {
     nsCOMPtr<nsIURI> newURI(aURI);
     History::GetService()->NotifyVisited(newURI);
     return true;
 }
 
 
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -47,16 +47,17 @@
 struct ChromePackage;
 class nsIObserver;
 struct ResourceMapping;
 struct OverrideMapping;
 
 namespace mozilla {
 namespace dom {
 
+class AlertObserver;
 class PrefObserver;
 
 class ContentChild : public PContentChild
 {
 public:
     ContentChild();
     virtual ~ContentChild();
 
@@ -96,33 +97,39 @@ public:
      */
     nsresult AddRemotePrefObserver(const nsCString& aDomain, 
                                    const nsCString& aPrefRoot, 
                                    nsIObserver* aObserver, PRBool aHoldWeak);
     nsresult RemoveRemotePrefObserver(const nsCString& aDomain, 
                                       const nsCString& aPrefRoot, 
                                       nsIObserver* aObserver);
 
+    // auto remove when alertfinished is received.
+    nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver);
+
     virtual bool RecvNotifyRemotePrefObserver(const nsCString& aDomain);
     
+    virtual bool RecvNotifyAlertsObserver(const nsCString& aType, const nsString& aData);
+
     virtual bool RecvAsyncMessage(const nsString& aMsg, const nsString& aJSON);
 
 private:
     NS_OVERRIDE
     virtual void ActorDestroy(ActorDestroyReason why);
 
     NS_OVERRIDE
     virtual void ProcessingError(Result what);
 
     /**
      * Exit *now*.  Do not shut down XPCOM, do not pass Go, do not run
      * static destructors, do not collect $200.
      */
     NS_NORETURN void QuickExit();
 
+    nsTArray<nsAutoPtr<AlertObserver> > mAlertObservers;
     nsTArray<nsAutoPtr<PrefObserver> > mPrefObservers;
     bool mDead;
 
     static ContentChild* sSingleton;
 
     DISALLOW_EVIL_CONSTRUCTORS(ContentChild);
 };
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -51,16 +51,18 @@
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "nsChromeRegistryChrome.h"
 #include "nsExternalHelperAppService.h"
 #include "nsCExternalHandlerService.h"
 #include "nsFrameMessageManager.h"
+#include "nsIAlertsService.h"
+#include "nsToolkitCompsCID.h"
 
 #ifdef ANDROID
 #include "AndroidBridge.h"
 using namespace mozilla;
 #endif
 
 using namespace mozilla::ipc;
 using namespace mozilla::net;
@@ -362,16 +364,23 @@ ContentParent::Observe(nsISupports* aSub
             return NS_ERROR_NOT_AVAILABLE;
     }
     else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC)) {
       NS_ConvertUTF16toUTF8 dataStr(aData);
       const char *offline = dataStr.get();
       if (!SendSetOffline(!strcmp(offline, "true") ? true : false))
           return NS_ERROR_NOT_AVAILABLE;
     }
+    // listening for alert notifications
+    else if (!strcmp(aTopic, "alertfinished") ||
+             !strcmp(aTopic, "alertclickcallback") ) {
+        if (!SendNotifyAlertsObserver(nsDependentCString(aTopic),
+                                      nsDependentString(aData)))
+            return NS_ERROR_NOT_AVAILABLE;
+    }
     return NS_OK;
 }
 
 PBrowserParent*
 ContentParent::AllocPBrowser(const PRUint32& aChromeFlags)
 {
   TabParent* parent = new TabParent();
   if (parent){
@@ -553,16 +562,29 @@ ContentParent::RecvNotifyIME(const int& 
 #ifdef ANDROID
     AndroidBridge::Bridge()->NotifyIME(aType, aStatus);
     return true;
 #else
     return false;
 #endif
 }
 
+bool
+ContentParent::RecvShowAlertNotification(const nsString& aImageUrl, const nsString& aTitle,
+                                         const nsString& aText, const PRBool& aTextClickable,
+                                         const nsString& aCookie, const nsString& aName)
+{
+    nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_ALERTSERVICE_CONTRACTID));
+    if (sysAlerts) {
+        sysAlerts->ShowAlertNotification(aImageUrl, aTitle, aText, aTextClickable,
+                                         aCookie, this, aName);
+    }
+
+    return true;
+}
 
 bool
 ContentParent::RecvSyncMessage(const nsString& aMsg, const nsString& aJSON,
                                nsTArray<nsString>* aRetvals)
 {
   nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sParentProcessManager;
   if (ppm) {
     ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -153,19 +153,21 @@ private:
                               const PRUint32& flags);
 
     virtual bool RecvSetURITitle(const IPC::URI& uri,
                                  const nsString& title);
     
     virtual bool RecvNotifyIME(const int&, const int&);
 
     virtual bool RecvNotifyIMEChange(const nsString&, const PRUint32&, const int&, 
-                               const int&, const int&)
-;
+                                     const int&, const int&);
 
+    virtual bool RecvShowAlertNotification(const nsString& aImageUrl, const nsString& aTitle,
+                                           const nsString& aText, const PRBool& aTextClickable,
+                                           const nsString& aCookie, const nsString& aName);
 
     virtual bool RecvLoadURIExternal(const IPC::URI& uri);
 
     virtual bool RecvSyncMessage(const nsString& aMsg, const nsString& aJSON,
                                  nsTArray<nsString>* aRetvals);
     virtual bool RecvAsyncMessage(const nsString& aMsg, const nsString& aJSON);
 
     mozilla::Monitor mMonitor;
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -82,37 +82,16 @@ parent:
     /**
      * When child sends this message, parent should move focus to
      * the next or previous focusable element.
      */
     MoveFocus(bool forward);
 
     Event(RemoteDOMEvent aEvent);
 
-    NotifyStateChange(PRUint32 stateFlags, nsresult status);
-
-    NotifyProgressChange(PRInt64 curSelfProgress,
-                         PRInt64 maxSelfProgress,
-                         PRInt64 curTotalProgress,
-                         PRInt64 maxTotalProgress);
-
-    NotifyLocationChange(nsCString uri);
-
-    NotifyStatusChange(nsresult status,
-                       nsString message);
-
-    NotifySecurityChange(PRUint32 aState,
-                         PRBool aUseSSLStatusObject,
-                         nsString aTooltip,
-                         nsCString aSecInfoAsString);
-
-    sync RefreshAttempted(nsCString uri, PRInt32 millis,
-                          bool sameURI) returns (bool retval);
-
-
     rpc CreateWindow() returns (PBrowser window);
 
     sync SyncMessage(nsString aMessage, nsString aJSON)
       returns (nsString[] retval);
 
     QueryContentResult(nsQueryContentEvent event);
 
     PContentPermissionRequest(nsCString aType, URI uri);
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -66,16 +66,18 @@ child:
                    OverrideMapping[] overrides);
 
     async SetOffline(PRBool offline);
 
     async NotifyVisited(URI uri);
 
     NotifyRemotePrefObserver(nsCString aDomain);
 
+    NotifyAlertsObserver(nsCString topic, nsString data);
+
 parent:
     PNecko();
 
     // Services remoting
 
     async StartVisitedQuery(URI uri);
     async VisitURI(URI uri, URI referrer, PRUint32 flags);
     async SetURITitle(URI uri, nsString title);
@@ -96,15 +98,22 @@ parent:
     sync TestPermission(URI uri, nsCString type, PRBool exact) returns (PRUint32 retValue);
     NotifyIME(int aType, int aState);
     NotifyIMEChange(nsString aText, PRUint32 aTextLen,
                     int aStart, int aEnd, int aNewEnd);
 
     sync SyncMessage(nsString aMessage, nsString aJSON)
       returns (nsString[] retval);
 
+    ShowAlertNotification(nsString imageUrl, 
+                          nsString title, 
+                          nsString text, 
+                          PRBool textClickable,
+                          nsString cookie,
+                          nsString name);
+
 both:
      AsyncMessage(nsString aMessage, nsString aJSON);
 
 };
 
 }
 }
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -129,42 +129,35 @@ TabChild::Init()
 {
   nsCOMPtr<nsIWebBrowser> webBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID);
   if (!webBrowser) {
     NS_ERROR("Couldn't create a nsWebBrowser?");
     return NS_ERROR_FAILURE;
   }
 
   webBrowser->SetContainerWindow(this);
-  nsCOMPtr<nsIWeakReference> weak =
-    do_GetWeakReference(static_cast<nsSupportsWeakReference*>(this));
-  webBrowser->AddWebBrowserListener(weak, NS_GET_IID(nsIWebProgressListener));
-
   mWebNav = do_QueryInterface(webBrowser);
   NS_ASSERTION(mWebNav, "nsWebBrowser doesn't implement nsIWebNavigation?");
 
   nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(mWebNav));
   docShellItem->SetItemType(nsIDocShellTreeItem::typeContentWrapper);
   return NS_OK;
 }
 
 NS_INTERFACE_MAP_BEGIN(TabChild)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebProgressListener2)
   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome2)
   NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow)
   NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow2)
   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChromeFocus)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
   NS_INTERFACE_MAP_ENTRY(nsIWindowProvider)
-  NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
-  NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener2)
-  NS_INTERFACE_MAP_ENTRY(nsSupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY(nsITabChild)
   NS_INTERFACE_MAP_ENTRY(nsIDialogCreator)
+  NS_INTERFACE_MAP_ENTRY(nsSupportsWeakReference)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(TabChild)
 NS_IMPL_RELEASE(TabChild)
 
 NS_IMETHODIMP
 TabChild::SetStatus(PRUint32 aStatusType, const PRUnichar* aStatus)
 {
@@ -439,169 +432,30 @@ TabChild::ActorDestroy(ActorDestroyReaso
   static_cast<nsFrameMessageManager*>
     (mTabChildGlobal->mMessageManager.get())->Disconnect();
   mTabChildGlobal->mMessageManager = nsnull;
 }
 
 TabChild::~TabChild()
 {
     nsCOMPtr<nsIWebBrowser> webBrowser = do_QueryInterface(mWebNav);
-    nsCOMPtr<nsIWeakReference> weak =
-      do_GetWeakReference(static_cast<nsSupportsWeakReference*>(this));
-    webBrowser->RemoveWebBrowserListener(weak, NS_GET_IID(nsIWebProgressListener));
-
     if (webBrowser) {
       webBrowser->SetContainerWindow(nsnull);
     }
     if (mCx) {
       DestroyCx();
     }
     
     nsIEventListenerManager* elm = mTabChildGlobal->GetListenerManager(PR_FALSE);
     if (elm) {
       elm->Disconnect();
     }
     mTabChildGlobal->mTabChild = nsnull;
 }
 
-NS_IMETHODIMP
-TabChild::OnStateChange(nsIWebProgress *aWebProgress,
-                        nsIRequest *aRequest,
-                        PRUint32 aStateFlags,
-                        nsresult aStatus)
-{
-  SendNotifyStateChange(aStateFlags, aStatus);
-  return NS_OK;
-}
-
-// Only one of OnProgressChange / OnProgressChange64 will be called.
-// According to interface, it should be OnProgressChange64, but looks
-// like docLoader only sends the former.
-NS_IMETHODIMP
-TabChild::OnProgressChange(nsIWebProgress *aWebProgress,
-                           nsIRequest *aRequest,
-                           PRInt32 aCurSelfProgress,
-                           PRInt32 aMaxSelfProgress,
-                           PRInt32 aCurTotalProgress,
-                           PRInt32 aMaxTotalProgress)
-{
-  SendNotifyProgressChange(aCurSelfProgress, aMaxSelfProgress,
-                           aCurTotalProgress, aMaxTotalProgress);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-TabChild::OnStatusChange(nsIWebProgress *aWebProgress,
-                         nsIRequest *aRequest,
-                         nsresult aStatus,
-                         const PRUnichar* aMessage)
-{
-  nsDependentString message(aMessage);
-  SendNotifyStatusChange(aStatus, message);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-TabChild::OnSecurityChange(nsIWebProgress *aWebProgress,
-                           nsIRequest *aRequest,
-                           PRUint32 aState)
-{
-  nsCString secInfoAsString;
-  if (aState & nsIWebProgressListener::STATE_IS_SECURE) {
-    nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
-    if (channel) {
-      nsCOMPtr<nsISupports> secInfoSupports;
-      channel->GetSecurityInfo(getter_AddRefs(secInfoSupports));
-
-      nsCOMPtr<nsISerializable> secInfoSerializable =
-          do_QueryInterface(secInfoSupports);
-      NS_SerializeToString(secInfoSerializable, secInfoAsString);
-    }
-  }
-
-  PRBool useSSLStatusObject = PR_FALSE;
-  nsAutoString securityTooltip;
-  nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aWebProgress);
-  if (docShell) {
-    nsCOMPtr<nsISecureBrowserUI> secureUI;
-    docShell->GetSecurityUI(getter_AddRefs(secureUI));
-    if (secureUI) {
-      secureUI->GetTooltipText(securityTooltip);
-      nsCOMPtr<nsISupports> supports;
-      nsCOMPtr<nsISSLStatusProvider> provider = do_QueryInterface(secureUI);
-      nsresult rv = provider->GetSSLStatus(getter_AddRefs(supports));
-      if (NS_SUCCEEDED(rv) && supports) {
-        /*
-         * useSSLStatusObject: Security UI internally holds 4 states: secure, mixed,
-         * broken, no security.  In cases of secure, mixed and broken it holds reference
-         * to a valid SSL status object.  But, in case of the 'broken' state it doesn't
-         * return the SSL status object (returns null), in contrary to the 'mixed' state
-         * for which it returns.
-         * 
-         * However, mixed and broken states are both reported to the upper level
-         * as nsIWebProgressListener::STATE_IS_BROKEN, i.e. states are merged,
-         * so we cannot determine, if to return the status object or not.
-         *
-         * TabParent is extracting the SSL status object from the security info
-         * serialization (string). SSL status object is always present there
-         * even security UI implementation doesn't present it.  This argument 
-         * tells the parent if the SSL status object is being presented by 
-         * the security UI here, on the child process, and so if it has to be
-         * presented also on the parent process.
-         */
-        useSSLStatusObject = PR_TRUE;
-      }
-    }
-  }
-
-  SendNotifySecurityChange(aState, useSSLStatusObject, securityTooltip,
-                           secInfoAsString);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-TabChild::OnLocationChange(nsIWebProgress *aWebProgress,
-                           nsIRequest *aRequest,
-                           nsIURI *aLocation)
-{
-  NS_ENSURE_ARG_POINTER(aLocation);
-  nsCString uri;
-  aLocation->GetSpec(uri);
-  SendNotifyLocationChange(uri);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-TabChild::OnProgressChange64(nsIWebProgress *aWebProgress,
-                             nsIRequest *aRequest,
-                             PRInt64 aCurSelfProgress,
-                             PRInt64 aMaxSelfProgress,
-                             PRInt64 aCurTotalProgress,
-                             PRInt64 aMaxTotalProgress)
-{
-  SendNotifyProgressChange(aCurSelfProgress, aMaxSelfProgress,
-                           aCurTotalProgress, aMaxTotalProgress);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-TabChild::OnRefreshAttempted(nsIWebProgress *aWebProgress,
-                             nsIURI *aURI, PRInt32 aMillis,
-                             PRBool aSameURL, PRBool *aRefreshAllowed)
-{
-  NS_ENSURE_ARG_POINTER(aURI);
-  nsCString uri;
-  aURI->GetSpec(uri);
-  bool sameURL = aSameURL;
-  bool refreshAllowed;
-  SendRefreshAttempted(uri, aMillis, sameURL, &refreshAllowed);
-  *aRefreshAllowed = refreshAllowed;
-  return NS_OK;
-}
-
 bool
 TabChild::RecvLoadURL(const nsCString& uri)
 {
     printf("loading %s, %d\n", uri.get(), NS_IsMainThread());
 
     nsresult rv = mWebNav->LoadURI(NS_ConvertUTF8toUTF16(uri).get(),
                                    nsIWebNavigation::LOAD_FLAGS_NONE,
                                    NULL, NULL, NULL);
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -43,18 +43,16 @@
 #include "mozilla/dom/PBrowserChild.h"
 #endif
 #include "nsIWebNavigation.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsIWebBrowserChrome2.h"
 #include "nsIEmbeddingSiteWindow2.h"
 #include "nsIWebBrowserChromeFocus.h"
-#include "nsIWebProgressListener.h"
-#include "nsIWebProgressListener2.h"
 #include "nsIWidget.h"
 #include "nsIDOMEventListener.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIWindowProvider.h"
 #include "nsIXPCScriptable.h"
 #include "nsIClassInfo.h"
 #include "jsapi.h"
@@ -145,17 +143,16 @@ public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMEVENTLISTENER
 protected:
   TabChild* mTabChild;
 };
 
 class TabChild : public PBrowserChild,
                  public nsFrameScriptExecutor,
-                 public nsIWebProgressListener2,
                  public nsIWebBrowserChrome2,
                  public nsIEmbeddingSiteWindow2,
                  public nsIWebBrowserChromeFocus,
                  public nsIInterfaceRequestor,
                  public nsIWindowProvider,
                  public nsSupportsWeakReference,
                  public nsIDialogCreator,
                  public nsITabChild
@@ -163,18 +160,16 @@ class TabChild : public PBrowserChild,
     typedef mozilla::layout::RenderFrameChild RenderFrameChild;
 
 public:
     TabChild(PRUint32 aChromeFlags);
     virtual ~TabChild();
     nsresult Init();
 
     NS_DECL_ISUPPORTS
-    NS_DECL_NSIWEBPROGRESSLISTENER
-    NS_DECL_NSIWEBPROGRESSLISTENER2
     NS_DECL_NSIWEBBROWSERCHROME
     NS_DECL_NSIWEBBROWSERCHROME2
     NS_DECL_NSIEMBEDDINGSITEWINDOW
     NS_DECL_NSIEMBEDDINGSITEWINDOW2
     NS_DECL_NSIWEBBROWSERCHROMEFOCUS
     NS_DECL_NSIINTERFACEREQUESTOR
     NS_DECL_NSIWINDOWPROVIDER
     NS_DECL_NSIDIALOGCREATOR
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -54,17 +54,16 @@
 #include "nsIDOMEventTarget.h"
 #include "nsIWindowWatcher.h"
 #include "nsIDOMWindow.h"
 #include "nsIIdentityInfo.h"
 #include "nsPIDOMWindow.h"
 #include "TabChild.h"
 #include "nsIDOMEvent.h"
 #include "nsIPrivateDOMEvent.h"
-#include "nsIWebProgressListener2.h"
 #include "nsFrameLoader.h"
 #include "nsNetUtil.h"
 #include "jsarray.h"
 #include "nsContentUtils.h"
 #include "nsContentPermissionHelper.h"
 #include "nsIDOMNSHTMLFrameElement.h"
 #include "nsIDialogCreator.h"
 #include "nsThreadUtils.h"
@@ -84,20 +83,20 @@ using namespace mozilla::layout;
 
 // The flags passed by the webProgress notifications are 16 bits shifted
 // from the ones registered by webProgressListeners.
 #define NOTIFY_FLAG_SHIFT 16
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_ISUPPORTS5(TabParent, nsITabParent, nsIWebProgress, nsIAuthPromptProvider, nsISSLStatusProvider, nsISecureBrowserUI)
+NS_IMPL_ISUPPORTS4(TabParent, nsITabParent, nsIAuthPromptProvider, nsISSLStatusProvider, nsISecureBrowserUI)
 
 TabParent::TabParent()
-  : mSecurityState(nsIWebProgressListener::STATE_IS_INSECURE)
+  : mSecurityState(0)
 {
 }
 
 TabParent::~TabParent()
 {
 }
 
 void
@@ -133,279 +132,16 @@ TabParent::RecvEvent(const RemoteDOMEven
   NS_ENSURE_TRUE(target, true);
 
   PRBool dummy;
   target->DispatchEvent(event, &dummy);
   return true;
 }
 
 bool
-TabParent::RecvNotifyProgressChange(const PRInt64& aProgress,
-                                    const PRInt64& aProgressMax,
-                                    const PRInt64& aTotalProgress,
-                                    const PRInt64& aMaxTotalProgress)
-{
-  /*
-   * First notify any listeners of the new progress info...
-   *
-   * Operate the elements from back to front so that if items get
-   * get removed from the list it won't affect our iteration
-   */
-  nsCOMPtr<nsIWebProgressListener> listener;
-  PRUint32 count = mListenerInfoList.Length();
-
-  while (count-- > 0) {
-    TabParentListenerInfo *info = &mListenerInfoList[count];
-    if (!(info->mNotifyMask & nsIWebProgress::NOTIFY_PROGRESS)) {
-      continue;
-    }
-
-    listener = do_QueryReferent(info->mWeakListener);
-    if (!listener) {
-      // the listener went away. gracefully pull it out of the list.
-      mListenerInfoList.RemoveElementAt(count);
-      continue;
-    }
-
-    nsCOMPtr<nsIWebProgressListener2> listener2 =
-      do_QueryReferent(info->mWeakListener);
-    if (listener2) {
-      listener2->OnProgressChange64(this, nsnull, aProgress, aProgressMax,
-                                    aTotalProgress, aMaxTotalProgress);
-    } else {
-      listener->OnProgressChange(this, nsnull, PRInt32(aProgress),
-                                 PRInt32(aProgressMax),
-                                 PRInt32(aTotalProgress), 
-                                 PRInt32(aMaxTotalProgress));
-    }
-  }
-
-  return true;
-}
-
-bool
-TabParent::RecvNotifyStateChange(const PRUint32& aStateFlags,
-                                 const nsresult& aStatus)
-{
-  /*                                                                           
-   * First notify any listeners of the new state info...
-   *
-   * Operate the elements from back to front so that if items get
-   * get removed from the list it won't affect our iteration
-   */
-  nsCOMPtr<nsIWebProgressListener> listener;
-  PRUint32 count = mListenerInfoList.Length();
-  
-  while (count-- > 0) {
-    TabParentListenerInfo *info = &mListenerInfoList[count];
-
-    // The flags used in listener registration are shifted over
-    // 16 bits from the ones sent in the notification, so we shift
-    // to see if the listener is interested in this change.
-    // Note that the flags are not changed in the notification we
-    // send along. Flags are defined in  nsIWebProgressListener and 
-    // nsIWebProgress.
-    // See nsDocLoader for another example of this.
-    if (!(info->mNotifyMask & (aStateFlags >> NOTIFY_FLAG_SHIFT))) {
-        continue;
-    }
-    
-    listener = do_QueryReferent(info->mWeakListener);
-    if (!listener) {
-      // the listener went away. gracefully pull it out of the list.
-      mListenerInfoList.RemoveElementAt(count);
-      continue;
-    }
-    
-    listener->OnStateChange(this, nsnull, aStateFlags, aStatus); 
-  }   
-
-  return true;
- }
-
-bool
-TabParent::RecvNotifyLocationChange(const nsCString& aUri)
-{
-  nsCOMPtr<nsIURI> uri;
-  nsresult rv = NS_NewURI(getter_AddRefs(uri), aUri);
-  if (NS_FAILED(rv)) {
-    return false;
-  }
-
-  /*                                                                           
-   * First notify any listeners of the new state info...
-   *
-   * Operate the elements from back to front so that if items get
-   * get removed from the list it won't affect our iteration
-   */
-  nsCOMPtr<nsIWebProgressListener> listener;
-  PRUint32 count = mListenerInfoList.Length();
-
-  while (count-- > 0) {
-    TabParentListenerInfo *info = &mListenerInfoList[count];
-    if (!(info->mNotifyMask & nsIWebProgress::NOTIFY_LOCATION)) {
-      continue;
-    }
-    
-    listener = do_QueryReferent(info->mWeakListener);
-    if (!listener) {
-      // the listener went away. gracefully pull it out of the list.
-      mListenerInfoList.RemoveElementAt(count);
-      continue;
-    }
-    
-    listener->OnLocationChange(this, nsnull, uri);
-  }
-
-  return true;
-}
-
-bool
-TabParent::RecvNotifyStatusChange(const nsresult& status,
-                                  const nsString& message)
-{
-  /*                                                                           
-   * First notify any listeners of the new state info...
-   *
-   * Operate the elements from back to front so that if items get
-   * get removed from the list it won't affect our iteration
-   */
-  nsCOMPtr<nsIWebProgressListener> listener;
-  PRUint32 count = mListenerInfoList.Length();
-
-  while (count-- > 0) {
-    TabParentListenerInfo *info = &mListenerInfoList[count];
-    if (!(info->mNotifyMask & nsIWebProgress::NOTIFY_STATUS)) {
-      continue;
-    }
-
-    listener = do_QueryReferent(info->mWeakListener);
-    if (!listener) {
-      // the listener went away. gracefully pull it out of the list.
-      mListenerInfoList.RemoveElementAt(count);
-      continue;
-    }
-
-    listener->OnStatusChange(this, nsnull, status, message.BeginReading());
-  }
-
-  return true;
-}
-
-bool
-TabParent::RecvNotifySecurityChange(const PRUint32& aState,
-                                    const PRBool& aUseSSLStatusObject,
-                                    const nsString& aTooltip,
-                                    const nsCString& aSecInfoAsString)
-{
-  /*                                                                           
-   * First notify any listeners of the new state info...
-   *
-   * Operate the elements from back to front so that if items get
-   * get removed from the list it won't affect our iteration
-   */
-
-  mSecurityState = aState;
-  mSecurityTooltipText = aTooltip;
-
-  if (!aSecInfoAsString.IsEmpty()) {
-    nsCOMPtr<nsISupports> secInfoSupports;
-    nsresult rv = NS_DeserializeObject(aSecInfoAsString, getter_AddRefs(secInfoSupports));
-
-    if (NS_SUCCEEDED(rv)) {
-      nsCOMPtr<nsIIdentityInfo> idInfo = do_QueryInterface(secInfoSupports);
-      if (idInfo) {
-        PRBool isEV;
-        if (NS_SUCCEEDED(idInfo->GetIsExtendedValidation(&isEV)) && isEV)
-          mSecurityState |= nsIWebProgressListener::STATE_IDENTITY_EV_TOPLEVEL;
-      }
-    }
-
-    mSecurityStatusObject = nsnull;
-    if (aUseSSLStatusObject)
-    {
-      nsCOMPtr<nsISSLStatusProvider> sslStatusProvider =
-        do_QueryInterface(secInfoSupports);
-      if (sslStatusProvider)
-        sslStatusProvider->GetSSLStatus(getter_AddRefs(mSecurityStatusObject));
-    }
-  }
-
-  nsCOMPtr<nsIWebProgressListener> listener;
-  PRUint32 count = mListenerInfoList.Length();
-
-  while (count-- > 0) {
-    TabParentListenerInfo *info = &mListenerInfoList[count];
-    if (!(info->mNotifyMask & nsIWebProgress::NOTIFY_SECURITY)) {
-      continue;
-    }
-
-    listener = do_QueryReferent(info->mWeakListener);
-    if (!listener) {
-      // the listener went away. gracefully pull it out of the list.
-      mListenerInfoList.RemoveElementAt(count);
-      continue;
-    }
-
-    listener->OnSecurityChange(this, nsnull, mSecurityState);
-  }
-
-  return true;
-}
-
-bool
-TabParent::RecvRefreshAttempted(const nsCString& aURI, const PRInt32& aMillis, 
-                                const bool& aSameURI, bool* refreshAllowed)
-{
-  nsCOMPtr<nsIURI> uri;
-  nsresult rv = NS_NewURI(getter_AddRefs(uri), aURI);
-  if (NS_FAILED(rv)) {
-    return false;
-  }
-  /*                                                                           
-   * First notify any listeners of the new state info...
-   *
-   * Operate the elements from back to front so that if items get
-   * get removed from the list it won't affect our iteration
-   */
-
-  nsCOMPtr<nsIWebProgressListener> listener;
-  PRUint32 count = mListenerInfoList.Length();
-
-  *refreshAllowed = true;
-  while (count-- > 0) {
-    TabParentListenerInfo *info = &mListenerInfoList[count];
-    if (!(info->mNotifyMask & nsIWebProgress::NOTIFY_REFRESH)) {
-      continue;
-    }
-
-    listener = do_QueryReferent(info->mWeakListener);
-    if (!listener) {
-      // the listener went away. gracefully pull it out of the list.
-      mListenerInfoList.RemoveElementAt(count);
-      continue;
-    }
-
-    nsCOMPtr<nsIWebProgressListener2> listener2 =
-      do_QueryReferent(info->mWeakListener);
-    if (!listener2) {
-      continue;
-    }
-
-    // some listeners don't seem to set this at all...
-    PRBool allowed = true;
-    listener2->OnRefreshAttempted(this, uri, 
-                                  aMillis, aSameURI, &allowed);
-    *refreshAllowed = allowed && *refreshAllowed;
-  }
-
-  return true;
-}
-
-bool
 TabParent::AnswerCreateWindow(PBrowserParent** retval)
 {
     if (!mBrowserDOMWindow) {
         return false;
     }
 
     // Get a new rendering area from the browserDOMWin.  We don't want
     // to be starting any loads here, so get it with a null URI.
@@ -460,16 +196,17 @@ TabParent::Init(nsIDOMWindow *window)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TabParent::GetState(PRUint32 *aState)
 {
   NS_ENSURE_ARG(aState);
+  NS_WARNING("SecurityState not valid here");
   *aState = mSecurityState;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TabParent::GetTooltipText(nsAString & aTooltipText)
 {
   aTooltipText = mSecurityTooltipText;
@@ -630,81 +367,16 @@ TabParent::ReceiveMessage(const nsString
                             aSync,
                             aJSON,
                             objectsArray,
                             aJSONRetVal);
   }
   return true;
 }
 
-// nsIWebProgress
-nsresult
-TabParent::AddProgressListener(nsIWebProgressListener* aListener,
-                               PRUint32 aNotifyMask)
-{
-  if (GetListenerInfo(aListener)) {
-    // The listener is already registered!
-    return NS_ERROR_FAILURE;
-  }
-
-  nsWeakPtr listener = do_GetWeakReference(aListener);
-  if (!listener) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  TabParentListenerInfo info(listener, aNotifyMask);
-
-  if (!mListenerInfoList.AppendElement(info))
-    return NS_ERROR_FAILURE;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-TabParent::RemoveProgressListener(nsIWebProgressListener *aListener)
-{
-  nsAutoPtr<TabParentListenerInfo> info(GetListenerInfo(aListener));
-  
-  return info && mListenerInfoList.RemoveElement(*info) ?
-    NS_OK : NS_ERROR_FAILURE;
-}
-
-TabParentListenerInfo * 
-TabParent::GetListenerInfo(nsIWebProgressListener *aListener)
-{
-  PRUint32 i, count;
-  TabParentListenerInfo *info;
-
-  nsCOMPtr<nsISupports> listener1 = do_QueryInterface(aListener);
-  count = mListenerInfoList.Length();
-  for (i = 0; i < count; ++i) {
-    info = &mListenerInfoList[i];
-
-    if (info) {
-      nsCOMPtr<nsISupports> listener2 = do_QueryReferent(info->mWeakListener);
-      if (listener1 == listener2) {
-        return info;
-      }
-    }
-  }
-  return nsnull;
-}
-
-NS_IMETHODIMP
-TabParent::GetDOMWindow(nsIDOMWindow **aResult)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-TabParent::GetIsLoadingDocument(PRBool *aIsLoadingDocument)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
 // nsIAuthPromptProvider
 
 // This method is largely copied from nsDocShell::GetAuthPrompt
 NS_IMETHODIMP
 TabParent::GetAuthPrompt(PRUint32 aPromptReason, const nsIID& iid,
                           void** aResult)
 {
   // we're either allowing auth, or it's a proxy request
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -43,96 +43,53 @@
 #include "mozilla/dom/PContentDialogParent.h"
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 #include "mozilla/dom/PExternalHelperApp.h"
 
 #include "jsapi.h"
 #include "nsCOMPtr.h"
 #include "nsITabParent.h"
 #include "nsIBrowserDOMWindow.h"
-#include "nsIWebProgress.h"
-#include "nsIWebProgressListener.h"
 #include "nsWeakReference.h"
 #include "nsIDialogParamBlock.h"
 #include "nsIAuthPromptProvider.h"
 #include "nsISSLStatusProvider.h"
 #include "nsISecureBrowserUI.h"
 
 class nsFrameLoader;
 class nsIURI;
 class nsIDOMElement;
 struct gfxMatrix;
 
 struct JSContext;
 struct JSObject;
 
 namespace mozilla {
 namespace dom {
-struct TabParentListenerInfo 
-{
-  TabParentListenerInfo(nsIWeakReference *aListener, unsigned long aNotifyMask)
-    : mWeakListener(aListener), mNotifyMask(aNotifyMask)
-  {
-  }
-
-  TabParentListenerInfo(const TabParentListenerInfo& obj)
-    : mWeakListener(obj.mWeakListener), mNotifyMask(obj.mNotifyMask) 
-  {
-  }
-
-  nsWeakPtr mWeakListener;
-
-  PRUint32 mNotifyMask;
-};
-
-inline    
-bool operator==(const TabParentListenerInfo& lhs, const TabParentListenerInfo& rhs)
-{
-  return &lhs == &rhs;
-}
 
 class ContentDialogParent : public PContentDialogParent {};
 
 class TabParent : public PBrowserParent 
                 , public nsITabParent 
-                , public nsIWebProgress
                 , public nsIAuthPromptProvider
                 , public nsISecureBrowserUI
                 , public nsISSLStatusProvider
 {
 public:
     TabParent();
     virtual ~TabParent();
     nsIDOMElement* GetOwnerElement() { return mFrameElement; }
     void SetOwnerElement(nsIDOMElement* aElement) { mFrameElement = aElement; }
     nsIBrowserDOMWindow *GetBrowserDOMWindow() { return mBrowserDOMWindow; }
     void SetBrowserDOMWindow(nsIBrowserDOMWindow* aBrowserDOMWindow) {
         mBrowserDOMWindow = aBrowserDOMWindow;
     }
  
     virtual bool RecvMoveFocus(const bool& aForward);
     virtual bool RecvEvent(const RemoteDOMEvent& aEvent);
-    virtual bool RecvNotifyProgressChange(const PRInt64& aProgress,
-                                          const PRInt64& aProgressMax,
-                                          const PRInt64& aTotalProgress,
-                                          const PRInt64& aMaxTotalProgress);
-    virtual bool RecvNotifyStateChange(const PRUint32& aStateFlags,
-                                       const nsresult& aStatus);
-    virtual bool RecvNotifyLocationChange(const nsCString& aUri);
-    virtual bool RecvNotifyStatusChange(const nsresult& status,
-                                        const nsString& message);
-    virtual bool RecvNotifySecurityChange(const PRUint32& aState,
-                                          const PRBool& aUseSSLStatusObject,
-                                          const nsString& aTooltip,
-                                          const nsCString& aSecInfoAsString);
-
-    virtual bool RecvRefreshAttempted(const nsCString& aURI,
-                                      const PRInt32& aMillis,
-                                      const bool& aSameURI,
-                                      bool* aAllowRefresh);
 
     virtual bool AnswerCreateWindow(PBrowserParent** retval);
     virtual bool RecvSyncMessage(const nsString& aMessage,
                                  const nsString& aJSON,
                                  nsTArray<nsString>* aJSONRetVal);
     virtual bool RecvAsyncMessage(const nsString& aMessage,
                                   const nsString& aJSON);
     virtual bool RecvQueryContentResult(const nsQueryContentEvent& event);
@@ -205,37 +162,32 @@ public:
 
 
     virtual PContentPermissionRequestParent* AllocPContentPermissionRequest(const nsCString& aType, const IPC::URI& uri);
     virtual bool DeallocPContentPermissionRequest(PContentPermissionRequestParent* actor);
 
     JSBool GetGlobalJSObject(JSContext* cx, JSObject** globalp);
 
     NS_DECL_ISUPPORTS
-    NS_DECL_NSIWEBPROGRESS
     NS_DECL_NSIAUTHPROMPTPROVIDER
     NS_DECL_NSISECUREBROWSERUI
     NS_DECL_NSISSLSTATUSPROVIDER
 
     void HandleDelayedDialogs();
 protected:
     bool ReceiveMessage(const nsString& aMessage,
                         PRBool aSync,
                         const nsString& aJSON,
                         nsTArray<nsString>* aJSONRetVal = nsnull);
 
-    TabParentListenerInfo* GetListenerInfo(nsIWebProgressListener *aListener);
-
     void ActorDestroy(ActorDestroyReason why);
 
     nsIDOMElement* mFrameElement;
     nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
 
-    nsTArray<TabParentListenerInfo> mListenerInfoList;
-
     struct DelayedDialogData
     {
       DelayedDialogData(PContentDialogParent* aDialog, PRUint32 aType,
                         const nsCString& aName,
                         const nsCString& aFeatures,
                         nsIDialogParamBlock* aParams)
       : mDialog(aDialog), mType(aType), mName(aName), mFeatures(aFeatures),
         mParams(aParams) {}
--- a/dom/plugins/PPluginInstance.ipdl
+++ b/dom/plugins/PPluginInstance.ipdl
@@ -47,20 +47,40 @@ include "mozilla/plugins/PluginMessageUt
 
 using NPError;
 using NPRemoteWindow;
 using NPRemoteEvent;
 using NPRect;
 using NPNURLVariable;
 using NPCoordinateSpace;
 using mozilla::plugins::NativeWindowHandle;
+using mozilla::gfxSurfaceType;
+using gfxIntSize;
+using mozilla::null_t;
 
 namespace mozilla {
 namespace plugins {
 
+struct SurfaceDescriptorX11 {
+  int XID;
+  int xrenderPictID;
+  gfxIntSize size;
+};
+
+union SurfaceDescriptor {
+  Shmem;
+  SurfaceDescriptorX11;
+  // Descriptor can be null here in case
+  // 1) of first Show call (prevSurface is null)
+  // 2) when child is going to destroy
+  //    and it just want to grab prevSurface
+  //     back without giving new surface
+  null_t;
+};
+
 rpc protocol PPluginInstance
 {
   manager PPluginModule;
 
   manages PPluginScriptableObject;
   manages PBrowserStream;
   manages PPluginStream;
   manages PStreamNotify;
@@ -87,16 +107,30 @@ child:
   rpc NPP_HandleEvent_IOSurface(NPRemoteEvent event, uint32_t surfaceid)
     returns (int16_t handled);
   // special cases of HandleEvent to make mediating races simpler
   rpc Paint(NPRemoteEvent event)
     returns (int16_t handled);
   // this is only used on windows to forward WM_WINDOWPOSCHANGE
   async WindowPosChanged(NPRemoteEvent event);
 
+  // ********************** Async plugins rendering
+  // see https://wiki.mozilla.org/Gecko:AsyncPluginPainting
+  // **********************
+
+  // Plugin parent notify child that plugin frame
+  // has been painted to the screen
+  async PaintFinished();
+
+  // Async version of SetWindow call
+  // @param surfaceType - gfxASurface::gfxSurfaceType
+  //        plugin child must create offscreen buffer
+  //        with type equals to surfaceType
+  async AsyncSetWindow(gfxSurfaceType surfaceType, NPRemoteWindow window);
+
   rpc NPP_Destroy()
     returns (NPError rv);
 
 parent:
   rpc NPN_GetValue_NPNVjavascriptEnabledBool()
     returns (bool value, NPError result);
   rpc NPN_GetValue_NPNVisOfflineBool()
     returns (bool value, NPError result);
@@ -129,16 +163,26 @@ parent:
    *       but IPDL doesn't allow that for constructors.
    */
   rpc PStreamNotify(nsCString url, nsCString target, bool post,
                     nsCString buffer, bool file)
     returns (NPError result);
 
   async NPN_InvalidateRect(NPRect rect);
 
+  // Give |newSurface|, containing this instance's updated pixels, to
+  // the browser for compositing.  Get back |prevSurface|, containing
+  // old pixels, to be recycled
+  // @param rect - actually updated rectangle, comparing to prevSurface content
+  //               could be used for partial render of layer to topLevel context
+  // @param newSurface - remotable surface
+  // @param prevSurface - return surface for recycling
+  sync Show(NPRect updatedRect, SurfaceDescriptor newSurface)
+    returns (SurfaceDescriptor prevSurface);
+
   rpc NPN_PushPopupsEnabledState(bool aState);
 
   rpc NPN_PopPopupsEnabledState();
 
   rpc NPN_GetValueForURL(NPNURLVariable variable, nsCString url)
     returns (nsCString value, NPError result);
 
   rpc NPN_SetValueForURL(NPNURLVariable variable, nsCString url,
--- a/dom/plugins/PluginInstanceChild.cpp
+++ b/dom/plugins/PluginInstanceChild.cpp
@@ -38,16 +38,24 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "PluginInstanceChild.h"
 #include "PluginModuleChild.h"
 #include "BrowserStreamChild.h"
 #include "PluginStreamChild.h"
 #include "StreamNotifyChild.h"
 #include "PluginProcessChild.h"
+#include "gfxASurface.h"
+#include "gfxContext.h"
+#ifdef MOZ_X11
+#include "gfxXlibSurface.h"
+#endif
+#include "gfxSharedImageSurface.h"
+#include "gfxUtils.h"
+#include "gfxAlphaRecovery.h"
 
 #include "mozilla/ipc/SyncChannel.h"
 
 using mozilla::ipc::ProcessChild;
 using namespace mozilla::plugins;
 
 #ifdef MOZ_WIDGET_GTK2
 
@@ -85,16 +93,23 @@ using mozilla::gfx::SharedDIB;
 // from Chromium's web plugin delegate src. See 'flash msg throttling
 // helpers' section for details.
 const int kFlashWMUSERMessageThrottleDelayMs = 5;
 
 #elif defined(XP_MACOSX)
 #include <ApplicationServices/ApplicationServices.h>
 #endif // defined(XP_MACOSX)
 
+template<>
+struct RunnableMethodTraits<PluginInstanceChild>
+{
+    static void RetainCallee(PluginInstanceChild* obj) { }
+    static void ReleaseCallee(PluginInstanceChild* obj) { }
+};
+
 PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
                                          const nsCString& aMimeType)
     : mPluginIface(aPluginIface)
     , mQuirks(0)
     , mCachedWindowActor(nsnull)
     , mCachedElementActor(nsnull)
 #if defined(OS_WIN)
     , mPluginWindowHWND(0)
@@ -107,32 +122,53 @@ PluginInstanceChild::PluginInstanceChild
 #endif // OS_WIN
     , mAsyncCallMutex("PluginInstanceChild::mAsyncCallMutex")
 #if defined(OS_MACOSX)  
     , mShColorSpace(nsnull)
     , mShContext(nsnull)
     , mDrawingModel(NPDrawingModelCoreGraphics)
     , mCurrentEvent(nsnull)
 #endif
+    , mLayersRendering(PR_FALSE)
+    , mAccumulatedInvalidRect(0,0,0,0)
+    , mIsTransparent(PR_FALSE)
+    , mSurfaceType(gfxASurface::SurfaceTypeMax)
+    , mPendingForcePaint(PR_FALSE)
+    , mCurrentInvalidateTask(nsnull)
+    , mPendingPluginCall(PR_FALSE)
+    , mDoAlphaExtraction(PR_FALSE)
+    , mSurfaceDifferenceRect(0,0,0,0)
+#ifdef MOZ_X11
+    , mFlash10Quirks(PR_FALSE)
+#endif
 {
     memset(&mWindow, 0, sizeof(mWindow));
     mData.ndata = (void*) this;
     mData.pdata = nsnull;
 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
     mWindow.ws_info = &mWsInfo;
     memset(&mWsInfo, 0, sizeof(mWsInfo));
     mWsInfo.display = DefaultXDisplay();
 #endif // MOZ_X11 && XP_UNIX && !XP_MACOSX
 #if defined(OS_WIN)
     memset(&mAlphaExtract, 0, sizeof(mAlphaExtract));
 #endif // OS_WIN
     InitQuirksModes(aMimeType);
 #if defined(OS_WIN)
     InitPopupMenuHook();
 #endif // OS_WIN
+#ifdef MOZ_X11
+    const char *description = NULL;
+    mPluginIface->getvalue(GetNPP(), NPPVpluginDescriptionString,
+                           &description);
+    if (description) {
+        NS_NAMED_LITERAL_CSTRING(flash10Head, "Shockwave Flash 10.");
+        mFlash10Quirks = StringBeginsWith(nsDependentCString(description), flash10Head);
+    }
+#endif
 }
 
 PluginInstanceChild::~PluginInstanceChild()
 {
 #if defined(OS_WIN)
   DestroyPluginWindow();
 #endif
 #if defined(OS_MACOSX)
@@ -396,19 +432,19 @@ PluginInstanceChild::NPN_SetValue(NPPVar
         if (!CallNPN_SetValue_NPPVpluginWindow(windowed, &rv))
             return NPERR_GENERIC_ERROR;
 
         return rv;
     }
 
     case NPPVpluginTransparentBool: {
         NPError rv;
-        bool transparent = (NPBool) (intptr_t) aValue;
+        mIsTransparent = (NPBool) (intptr_t) aValue;
 
-        if (!CallNPN_SetValue_NPPVpluginTransparent(transparent, &rv))
+        if (!CallNPN_SetValue_NPPVpluginTransparent(mIsTransparent, &rv))
             return NPERR_GENERIC_ERROR;
 
         return rv;
     }
 
 #ifdef XP_MACOSX
     case NPPVpluginDrawingModel: {
         NPError rv;
@@ -809,16 +845,18 @@ PluginInstanceChild::AnswerNPP_SetWindow
     mWindow.clipRect = aWindow.clipRect;
     mWindow.type = aWindow.type;
 
     mWsInfo.colormap = aWindow.colormap;
     if (!XVisualIDToInfo(mWsInfo.display, aWindow.visualID,
                          &mWsInfo.visual, &mWsInfo.depth))
         return false;
 
+    mLayersRendering = PR_FALSE;
+
 #ifdef MOZ_WIDGET_GTK2
     if (gtk_check_version(2,18,7) != NULL) { // older
         if (aWindow.type == NPWindowTypeWindow) {
             GdkWindow* socket_window = gdk_window_lookup(aWindow.window);
             if (socket_window) {
                 // A GdkWindow for the socket already exists.  Need to
                 // workaround https://bugzilla.gnome.org/show_bug.cgi?id=607061
                 // See wrap_gtk_plug_embedded in PluginModuleChild.cpp.
@@ -1933,32 +1971,497 @@ PluginInstanceChild::NPN_NewStream(NPMIM
         PPluginStreamChild::Call__delete__(ps, NPERR_GENERIC_ERROR, true);
         return result;
     }
 
     *aStream = &ps->mStream;
     return NPERR_NO_ERROR;
 }
 
+bool
+PluginInstanceChild::RecvPaintFinished(void)
+{
+    if (mPendingForcePaint) {
+        nsIntRect r(0, 0, mWindow.width, mWindow.height);
+        mAccumulatedInvalidRect.UnionRect(r, mAccumulatedInvalidRect);
+        mPendingForcePaint = PR_FALSE;
+    }
+    if (!mAccumulatedInvalidRect.IsEmpty()) {
+        AsyncShowPluginFrame();
+    }
+
+    return true;
+}
+
+bool
+PluginInstanceChild::RecvAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
+                                        const NPRemoteWindow& aWindow)
+{
+    AssertPluginThread();
+
+    mWindow.window = reinterpret_cast<void*>(aWindow.window);
+    if (mWindow.width != aWindow.width || mWindow.height != aWindow.height) {
+        mCurrentSurface = nsnull;
+        mHelperSurface = nsnull;
+        mPendingForcePaint = PR_TRUE;
+    }
+    mWindow.x = aWindow.x;
+    mWindow.y = aWindow.y;
+    mWindow.width = aWindow.width;
+    mWindow.height = aWindow.height;
+    mWindow.clipRect = aWindow.clipRect;
+    mWindow.type = aWindow.type;
+
+    mLayersRendering = PR_TRUE;
+    mSurfaceType = aSurfaceType;
+    UpdateWindowAttributes(PR_TRUE);
+
+    return true;
+}
+
+static inline gfxRect
+GfxFromNsRect(const nsIntRect& aRect)
+{
+    return gfxRect(aRect.x, aRect.y, aRect.width, aRect.height);
+}
+
+PRBool
+PluginInstanceChild::CreateOptSurface(void)
+{
+    nsRefPtr<gfxASurface> retsurf;
+    gfxASurface::gfxImageFormat format =
+        mIsTransparent ? gfxASurface::ImageFormatARGB32 :
+                         gfxASurface::ImageFormatRGB24;
+
+#ifdef MOZ_X11
+    Display* dpy = mWsInfo.display;
+    Screen* screen = DefaultScreenOfDisplay(dpy);
+    if (format == gfxASurface::ImageFormatRGB24 &&
+        DefaultDepth(dpy, DefaultScreen(dpy)) == 16) {
+        format = gfxASurface::ImageFormatRGB16_565;
+    }
+
+    if (mSurfaceType == gfxASurface::SurfaceTypeXlib) {
+        XRenderPictFormat* xfmt = gfxXlibSurface::FindRenderFormat(dpy, format);
+        if (!xfmt) {
+            NS_ERROR("Need X falback surface, but FindRenderFormat failed");
+            return PR_FALSE;
+        }
+        mCurrentSurface =
+            gfxXlibSurface::Create(screen, xfmt,
+                                   gfxIntSize(mWindow.width,
+                                              mWindow.height));
+        return mCurrentSurface != nsnull;
+    }
+#endif
+
+    // Make common shmem implementation working for any platform
+    mCurrentSurface = new gfxSharedImageSurface();
+    if (NS_FAILED(static_cast<gfxSharedImageSurface*>(mCurrentSurface.get())->
+        Init(this, gfxIntSize(mWindow.width, mWindow.height), format))) {
+        return PR_FALSE;
+    }
+
+    return PR_TRUE;
+}
+
+PRBool
+PluginInstanceChild::MaybeCreatePlatformHelperSurface(void)
+{
+    if (!mCurrentSurface) {
+        NS_ERROR("Cannot create helper surface without mCurrentSurface");
+        return PR_FALSE;
+    }
+
+#ifdef MOZ_PLATFORM_MAEMO
+    // On maemo plugins support non-default visual rendering
+    PRBool supportNonDefaultVisual = PR_TRUE;
+#else
+    PRBool supportNonDefaultVisual = PR_FALSE;
+#endif
+#ifdef MOZ_X11
+    Screen* screen = DefaultScreenOfDisplay(mWsInfo.display);
+    Visual* defaultVisual = DefaultVisualOfScreen(screen);
+    Visual* visual = nsnull;
+    Colormap colormap = 0;
+    mDoAlphaExtraction = PR_FALSE;
+    PRBool createHelperSurface = PR_FALSE;
+
+    if (mCurrentSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
+        static_cast<gfxXlibSurface*>(mCurrentSurface.get())->
+            GetColormapAndVisual(&colormap, &visual);
+        // Create helper surface if layer surface visual not same as default
+        // and we don't support non-default visual rendering
+        if (!visual || (defaultVisual != visual && !supportNonDefaultVisual)) {
+            createHelperSurface = PR_TRUE;
+            visual = defaultVisual;
+            mDoAlphaExtraction = mIsTransparent;
+        }
+    } else if (mCurrentSurface->GetType() == gfxASurface::SurfaceTypeImage) {
+        // For image layer surface we should always create helper surface
+        createHelperSurface = PR_TRUE;
+        // Check if we can create helper surface with non-default visual
+        visual = gfxXlibSurface::FindVisual(screen,
+            static_cast<gfxImageSurface*>(mCurrentSurface.get())->Format());
+        if (visual && defaultVisual != visual && !supportNonDefaultVisual) {
+            visual = defaultVisual;
+            mDoAlphaExtraction = mIsTransparent;
+        }
+    }
+
+    if (createHelperSurface) {
+        if (!visual) {
+            NS_ERROR("Need X falback surface, but visual failed");
+            return PR_FALSE;
+        }
+        mHelperSurface =
+            gfxXlibSurface::Create(screen, visual,
+                                   mCurrentSurface->GetSize());
+        if (!mHelperSurface) {
+            NS_WARNING("Fail to create create helper surface");
+            return PR_FALSE;
+        }
+    }
+#endif
+
+    return PR_TRUE;
+}
+
+PRBool
+PluginInstanceChild::EnsureCurrentBuffer(void)
+{
+    if (mCurrentSurface) {
+       return PR_TRUE;
+    }
+
+    if (!mWindow.width || !mWindow.height) {
+        return PR_FALSE;
+    }
+
+    if (!CreateOptSurface()) {
+        NS_ERROR("Cannot create optimized surface");
+        return PR_FALSE;
+    }
+
+    if (!MaybeCreatePlatformHelperSurface()) {
+        NS_ERROR("Cannot create helper surface");
+        return PR_FALSE;
+    }
+
+    return PR_TRUE;
+}
+
+void
+PluginInstanceChild::UpdateWindowAttributes(PRBool aForceSetWindow)
+{
+    nsRefPtr<gfxASurface> curSurface = mHelperSurface ? mHelperSurface : mCurrentSurface;
+    PRBool needWindowUpdate = aForceSetWindow;
+#ifdef MOZ_X11
+    Visual* visual = nsnull;
+    Colormap colormap = 0;
+    if (curSurface && curSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
+        static_cast<gfxXlibSurface*>(curSurface.get())->
+            GetColormapAndVisual(&colormap, &visual);
+        if (visual != mWsInfo.visual || colormap != mWsInfo.colormap) {
+            mWsInfo.visual = visual;
+            mWsInfo.colormap = colormap;
+            needWindowUpdate = PR_TRUE;
+        }
+    }
+#endif
+    if (!needWindowUpdate) {
+        return;
+    }
+
+    // The clip rect is relative to drawable top-left.
+    nsIntRect clipRect;
+    mWindow.x = mWindow.y = 0;
+    clipRect.SetRect(mWindow.x, mWindow.y, mWindow.width, mWindow.height);
+    // Don't ask the plugin to draw outside the drawable.
+    // This also ensures that the unsigned clip rectangle offsets won't be -ve.
+
+    NPRect newClipRect;
+    newClipRect.left = clipRect.x;
+    newClipRect.top = clipRect.y;
+    newClipRect.right = clipRect.XMost();
+    newClipRect.bottom = clipRect.YMost();
+    mWindow.clipRect = newClipRect;
+
+    if (mPluginIface->setwindow) {
+        mPluginIface->setwindow(&mData, &mWindow);
+    }
+
+    return;
+}
+
+void
+PluginInstanceChild::PaintRectToPlatformSurface(const nsIntRect& aRect,
+                                                gfxASurface* aSurface)
+{
+    UpdateWindowAttributes();
+#ifdef MOZ_X11
+    NS_ASSERTION(aSurface->GetType() == gfxASurface::SurfaceTypeXlib,
+                 "Non supported platform surface type");
+
+    mPendingPluginCall = PR_TRUE;
+    NPEvent pluginEvent;
+    XGraphicsExposeEvent& exposeEvent = pluginEvent.xgraphicsexpose;
+    exposeEvent.type = GraphicsExpose;
+    exposeEvent.display = mWsInfo.display;
+    exposeEvent.drawable = static_cast<gfxXlibSurface*>(aSurface)->XDrawable();
+    exposeEvent.x = aRect.x;
+    exposeEvent.y = aRect.y;
+    exposeEvent.width = aRect.width;
+    exposeEvent.height = aRect.height;
+    exposeEvent.count = 0;
+    // information not set:
+    exposeEvent.serial = 0;
+    exposeEvent.send_event = False;
+    exposeEvent.major_code = 0;
+    exposeEvent.minor_code = 0;
+    mPluginIface->event(&mData, reinterpret_cast<void*>(&exposeEvent));
+    mPendingPluginCall = PR_FALSE;
+#endif
+}
+
+void
+PluginInstanceChild::PaintRectToSurface(const nsIntRect& aRect,
+                                        gfxASurface* aSurface,
+                                        const gfxRGBA& aColor)
+{
+    // Render using temporary X surface, with copy to image surface
+    nsIntRect plPaintRect(aRect);
+    nsRefPtr<gfxASurface> renderSurface = aSurface;
+#ifdef MOZ_X11
+    if (mIsTransparent && mFlash10Quirks) {
+        // Work around a bug in Flash up to 10.1 d51 at least, where expose event
+        // top left coordinates within the plugin-rect and not at the drawable
+        // origin are misinterpreted.  (We can move the top left coordinate
+        // provided it is within the clipRect.), see bug 574583
+        plPaintRect.SetRect(0, 0, aRect.XMost(), aRect.YMost());
+    }
+    if (renderSurface->GetType() != gfxASurface::SurfaceTypeXlib) {
+        // On X11 we can paint to non Xlib surface only with HelperSurface
+        renderSurface = mHelperSurface;
+    }
+#endif
+
+    if (mIsTransparent) {
+       // Clear surface content for transparent rendering
+       nsRefPtr<gfxContext> ctx = new gfxContext(renderSurface);
+       ctx->SetColor(aColor);
+       ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
+       ctx->Rectangle(GfxFromNsRect(plPaintRect));
+       ctx->Fill();
+    }
+
+    PaintRectToPlatformSurface(plPaintRect, renderSurface);
+
+    if (renderSurface != aSurface) {
+        // Copy helper surface content to target
+        nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
+        ctx->SetSource(renderSurface);
+        ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
+        ctx->Rectangle(GfxFromNsRect(aRect));
+        ctx->Fill();
+    }
+}
+
+void
+PluginInstanceChild::PaintRectWithAlphaExtraction(const nsIntRect& aRect,
+                                                  gfxASurface* aSurface)
+{
+    // Paint onto black image
+    PRBool needImageSurface = PR_TRUE;
+    nsRefPtr<gfxImageSurface> blackImage;
+    gfxIntSize clipSize(aRect.width, aRect.height);
+    gfxPoint deviceOffset(-aRect.x, -aRect.y);
+    // Try to re-use existing image surface, and avoid one copy
+    if (aSurface->GetType() == gfxASurface::SurfaceTypeImage) {
+        gfxImageSurface *surface = static_cast<gfxImageSurface*>(aSurface);
+        if (surface->Format() == gfxASurface::ImageFormatARGB32) {
+            needImageSurface = PR_FALSE;
+            blackImage = surface->GetSubimage(GfxFromNsRect(aRect));
+        }
+    }
+    // otherwise create new helper surface
+    if (needImageSurface) {
+        blackImage = new gfxImageSurface(clipSize, gfxASurface::ImageFormatARGB32);
+    }
+
+    // Paint to black image
+    blackImage->SetDeviceOffset(deviceOffset);
+    PaintRectToSurface(aRect, blackImage, gfxRGBA(0.0, 0.0, 0.0));
+
+    // Paint onto white image
+    nsRefPtr<gfxImageSurface> whiteImage =
+        new gfxImageSurface(clipSize, gfxASurface::ImageFormatRGB24);
+
+    whiteImage->SetDeviceOffset(deviceOffset);
+    PaintRectToSurface(aRect, whiteImage, gfxRGBA(1.0, 1.0, 1.0));
+
+    // Extract Alpha from black and white image and store to black Image
+    gfxRect rect(aRect.x, aRect.y, aRect.width, aRect.height);
+    if (!gfxAlphaRecovery::RecoverAlpha(blackImage, whiteImage, nsnull)) {
+        return;
+    }
+
+    if (needImageSurface) {
+        nsRefPtr<gfxContext> ctx = new gfxContext(aSurface);
+        ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
+        ctx->SetSource(blackImage);
+        ctx->Rectangle(GfxFromNsRect(aRect));
+        ctx->Fill();
+    }
+}
+
+PRBool
+PluginInstanceChild::ShowPluginFrame()
+{
+    if (mPendingPluginCall) {
+        return PR_FALSE;
+    }
+
+    if (!EnsureCurrentBuffer()) {
+        return PR_FALSE;
+    }
+
+    // Make expose rect not bigger than clip rect
+    mAccumulatedInvalidRect.IntersectRect(mAccumulatedInvalidRect,
+        nsIntRect(mWindow.clipRect.left, mWindow.clipRect.top,
+                  mWindow.clipRect.right - mWindow.clipRect.left,
+                  mWindow.clipRect.bottom - mWindow.clipRect.top));
+
+    // Cleare accRect here to be able to pass test_invalidate_during_plugin_paint  test
+    nsIntRect rect = mAccumulatedInvalidRect;
+    mAccumulatedInvalidRect.Empty();
+
+#ifdef MOZ_X11
+    // We can read safetly from XSurface, because PluginHost is not able to modify that surface
+    if (mBackSurface && mBackSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
+        if (!mSurfaceDifferenceRect.IsEmpty()) {
+            // Read back previous content
+            nsRefPtr<gfxContext> ctx = new gfxContext(mCurrentSurface);
+            ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
+            ctx->SetSource(mBackSurface);
+            // Subtract from mSurfaceDifferenceRect area which is overlapping with rect
+            nsIntRegion result;
+            result.Sub(mSurfaceDifferenceRect, nsIntRegion(rect));
+            nsIntRegionRectIterator iter(result);
+            const nsIntRect* r;
+            while ((r = iter.Next()) != nsnull) {
+                ctx->Rectangle(GfxFromNsRect(*r));
+            }
+            ctx->Fill();
+        }
+    } else
+#endif
+    {
+        // Just repaint whole plugin, because we cannot read back from Shmem which is owned by another process
+        rect.SetRect(0, 0, mWindow.width, mWindow.height);
+    }
+
+    if (mDoAlphaExtraction) {
+        PaintRectWithAlphaExtraction(rect, mCurrentSurface);
+    } else {
+        PaintRectToSurface(rect, mCurrentSurface, gfxRGBA(0.0, 0.0, 0.0, 0.0));
+    }
+
+    NPRect r = { rect.y, rect.x, rect.YMost(), rect.XMost() };
+    SurfaceDescriptor currSurf;
+    SurfaceDescriptor outSurf = null_t();
+#ifdef MOZ_X11
+    if (mCurrentSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
+        gfxXlibSurface *xsurf = static_cast<gfxXlibSurface*>(mCurrentSurface.get());
+        currSurf = SurfaceDescriptorX11(xsurf->XDrawable(), xsurf->XRenderFormat()->id,
+                                        mCurrentSurface->GetSize());
+        // Need to sync all pending x-paint requests
+        // before giving drawable to another process
+        XSync(mWsInfo.display, False);
+    } else
+#endif
+    if (gfxSharedImageSurface::IsSharedImage(mCurrentSurface)) {
+        currSurf = static_cast<gfxSharedImageSurface*>(mCurrentSurface.get())->GetShmem();
+    } else {
+        NS_RUNTIMEABORT("Surface type is not remotable");
+        return PR_FALSE;
+    }
+    if (!SendShow(r, currSurf, &outSurf)) {
+        return PR_FALSE;
+    }
+
+    nsRefPtr<gfxASurface> tmp = mCurrentSurface;
+    mCurrentSurface = mBackSurface;
+    mBackSurface = tmp;
+    // Outdated back surface... not usable anymore due to changed plugin size.
+    // Dropping obsolete surface
+    if (mCurrentSurface && mBackSurface &&
+        mCurrentSurface->GetSize() != mBackSurface->GetSize()) {
+        mCurrentSurface = nsnull;
+    }
+    mSurfaceDifferenceRect = rect;
+    return PR_TRUE;
+}
+
+void
+PluginInstanceChild::InvalidateRectDelayed(void)
+{
+    if (!mCurrentInvalidateTask) {
+        return;
+    }
+
+    mCurrentInvalidateTask = nsnull;
+    if (mAccumulatedInvalidRect.IsEmpty()) {
+        return;
+    }
+
+    if (!ShowPluginFrame()) {
+        AsyncShowPluginFrame();
+    }
+}
+
+void
+PluginInstanceChild::AsyncShowPluginFrame(void)
+{
+    if (mCurrentInvalidateTask) {
+        return;
+    }
+
+    mCurrentInvalidateTask =
+        NewRunnableMethod(this, &PluginInstanceChild::InvalidateRectDelayed);
+    MessageLoop::current()->PostTask(FROM_HERE, mCurrentInvalidateTask);
+}
+
 void
 PluginInstanceChild::InvalidateRect(NPRect* aInvalidRect)
 {
     NS_ASSERTION(aInvalidRect, "Null pointer!");
 
 #ifdef OS_WIN
     // Invalidate and draw locally for windowed plugins.
     if (mWindow.type == NPWindowTypeWindow) {
       NS_ASSERTION(IsWindow(mPluginWindowHWND), "Bad window?!");
       RECT rect = { aInvalidRect->left, aInvalidRect->top,
                     aInvalidRect->right, aInvalidRect->bottom };
       ::InvalidateRect(mPluginWindowHWND, &rect, FALSE);
       return;
     }
 #endif
 
+    if (mLayersRendering) {
+        nsIntRect r(aInvalidRect->left, aInvalidRect->top,
+                    aInvalidRect->right - aInvalidRect->left,
+                    aInvalidRect->bottom - aInvalidRect->top);
+
+        mAccumulatedInvalidRect.UnionRect(r, mAccumulatedInvalidRect);
+        // If we are able to paint and invalidate sent, then reset
+        // accumulated rectangle
+        AsyncShowPluginFrame();
+        return;
+    }
     SendNPN_InvalidateRect(*aInvalidRect);
 }
 
 uint32_t
 PluginInstanceChild::ScheduleTimer(uint32_t interval, bool repeat,
                                    TimerFunc func)
 {
     ChildTimer* t = new ChildTimer(this, interval, repeat, func);
@@ -2026,16 +2529,29 @@ DeleteObject(DeletingObjectEntry* e, voi
 }
 
 bool
 PluginInstanceChild::AnswerNPP_Destroy(NPError* aResult)
 {
     PLUGIN_LOG_DEBUG_METHOD;
     AssertPluginThread();
 
+    if (mBackSurface) {
+        // Get last surface back, and drop it
+        SurfaceDescriptor temp = null_t();
+        NPRect r = { 0, 0, 1, 1 };
+        SendShow(r, temp, &temp);
+    }
+    if (gfxSharedImageSurface::IsSharedImage(mCurrentSurface))
+        DeallocShmem(static_cast<gfxSharedImageSurface*>(mCurrentSurface.get())->GetShmem());
+    if (gfxSharedImageSurface::IsSharedImage(mBackSurface))
+        DeallocShmem(static_cast<gfxSharedImageSurface*>(mBackSurface.get())->GetShmem());
+    mCurrentSurface = nsnull;
+    mBackSurface = nsnull;
+
     nsTArray<PBrowserStreamChild*> streams;
     ManagedPBrowserStreamChild(streams);
 
     // First make sure none of these streams become deleted
     for (PRUint32 i = 0; i < streams.Length(); ) {
         if (static_cast<BrowserStreamChild*>(streams[i])->InstanceDying())
             ++i;
         else
@@ -2047,16 +2563,20 @@ PluginInstanceChild::AnswerNPP_Destroy(N
     {
         MutexAutoLock lock(mAsyncCallMutex);
         for (PRUint32 i = 0; i < mPendingAsyncCalls.Length(); ++i)
             mPendingAsyncCalls[i]->Cancel();
         mPendingAsyncCalls.TruncateLength(0);
     }
 
     mTimers.Clear();
+    if (mCurrentInvalidateTask) {
+        mCurrentInvalidateTask->Cancel();
+        mCurrentInvalidateTask = nsnull;
+    }
 
     PluginModuleChild::current()->NPP_Destroy(this);
     mData.ndata = 0;
 
     mDeletingHash = new nsTHashtable<DeletingObjectEntry>;
     mDeletingHash->Init();
     PluginModuleChild::current()->FindNPObjectsForInstance(this);
 
--- a/dom/plugins/PluginInstanceChild.h
+++ b/dom/plugins/PluginInstanceChild.h
@@ -52,16 +52,17 @@
 #include "npfunctions.h"
 #include "nsAutoPtr.h"
 #include "nsTArray.h"
 #include "ChildAsyncCall.h"
 #include "ChildTimer.h"
 #include "nsRect.h"
 #include "nsTHashtable.h"
 #include "mozilla/PaintTracker.h"
+#include "gfxASurface.h"
 
 namespace mozilla {
 namespace plugins {
 
 class PBrowserStreamChild;
 class BrowserStreamChild;
 class StreamNotifyChild;
 
@@ -92,16 +93,22 @@ protected:
 
     virtual bool
     AnswerNPP_HandleEvent(const NPRemoteEvent& event, int16_t* handled);
     virtual bool
     AnswerNPP_HandleEvent_Shmem(const NPRemoteEvent& event, Shmem& mem, int16_t* handled, Shmem* rtnmem);
     virtual bool
     AnswerNPP_HandleEvent_IOSurface(const NPRemoteEvent& event, const uint32_t& surface, int16_t* handled);
 
+    // Async rendering
+    virtual bool
+    RecvAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
+                       const NPRemoteWindow& aWindow);
+    virtual bool RecvPaintFinished(void);
+
     NS_OVERRIDE
     virtual bool
     AnswerPaint(const NPRemoteEvent& event, int16_t* handled)
     {
         PaintTracker pt;
         return AnswerNPP_HandleEvent(event, handled);
     }
 
@@ -367,14 +374,110 @@ private:
 public:
     const NPCocoaEvent* getCurrentEvent() {
         return mCurrentEvent;
     }
 
 private:
     const NPCocoaEvent   *mCurrentEvent;
 #endif
+
+    // ShowPluginFrame - in general does four things:
+    // 1) Create mCurrentSurface optimized for rendering to parent process
+    // 2) Updated mCurrentSurface to be a complete copy of mBackSurface
+    // 3) Draw the invalidated plugin area into mCurrentSurface
+    // 4) Send it to parent process.
+    PRBool ShowPluginFrame(void);
+
+    // Post ShowPluginFrame task
+    void AsyncShowPluginFrame(void);
+
+    // In the PaintRect functions, aSurface is the size of the full plugin window. Each PaintRect function
+    // renders into the subrectangle aRect of aSurface (possibly more if we're working around a Flash bug).
+
+    // Paint plugin content rectangle to surface with bg color filling
+    void PaintRectToSurface(const nsIntRect& aRect,
+                            gfxASurface* aSurface,
+                            const gfxRGBA& aColor);
+
+    // Render plugin content to surface using
+    // white/black image alpha extraction algorithm
+    void PaintRectWithAlphaExtraction(const nsIntRect& aRect,
+                                      gfxASurface* aSurface);
+
+    // Call plugin NPAPI function to render plugin content to surface
+    // @param - aSurface - should be compatible with current platform plugin rendering
+    // @return - FALSE if plugin not painted to surface
+    void PaintRectToPlatformSurface(const nsIntRect& aRect,
+                                    gfxASurface* aSurface);
+
+    // Update NPWindow platform attributes and call plugin "setwindow"
+    // @param - aForceSetWindow - call setwindow even if platform attributes are the same
+    void UpdateWindowAttributes(PRBool aForceSetWindow = PR_FALSE);
+
+    // Create optimized mCurrentSurface for parent process rendering
+    // @return FALSE if optimized surface not created
+    PRBool CreateOptSurface(void);
+
+    // Create mHelperSurface if mCurrentSurface non compatible with plugins
+    // @return TRUE if helper surface created successfully, or not needed
+    PRBool MaybeCreatePlatformHelperSurface(void);
+
+    // Make sure that we have surface for rendering
+    PRBool EnsureCurrentBuffer(void);
+
+    // Helper function for delayed InvalidateRect call
+    // non null mCurrentInvalidateTask will call this function
+    void InvalidateRectDelayed(void);
+
+    // Set as true when SetupLayer called
+    // and go with different path in InvalidateRect function
+    PRPackedBool          mLayersRendering;
+    // Current surface available for rendering
+    nsRefPtr<gfxASurface> mCurrentSurface;
+    // Back surface, just keeping reference to
+    // surface which is on ParentProcess side
+    nsRefPtr<gfxASurface> mBackSurface;
+    // Accumulated invalidate rect, while back buffer is not accessible
+    nsIntRect             mAccumulatedInvalidRect;
+    // Plugin only call SetTransparent
+    // and does not remember their transparent state
+    // and p->getvalue return always false
+    PRPackedBool          mIsTransparent;
+    // Surface type optimized of parent process
+    gfxSurfaceType        mSurfaceType;
+
+    // set TRUE if plugin surface dropped in asyncSetWindow
+    // if TRUE then initiate full repaint in RecvPaintFinished
+    PRPackedBool          mPendingForcePaint;
+
+    // Keep InvalidateRect task pointer to be able Cancel it on Destroy
+    CancelableTask       *mCurrentInvalidateTask;
+
+    // True while plugin-child in plugin call
+    // Use to prevent plugin paint re-enter
+    PRPackedBool          mPendingPluginCall;
+
+    // On some platforms, plugins may not support rendering to a surface with
+    // alpha, or not support rendering to an image surface.
+    // In those cases we need to draw to a temporary platform surface; we cache
+    // that surface here.
+    nsRefPtr<gfxASurface> mHelperSurface;
+
+    // true when plugin does not support painting to ARGB32 surface
+    // this is false for maemo platform, and false if plugin
+    // supports NPPVpluginTransparentAlphaBool (which is not part of NPAPI yet)
+    PRPackedBool          mDoAlphaExtraction;
+
+    // Cached rectangle rendered to previous surface(mBackSurface)
+    // Used for reading back to current surface and syncing data
+    nsIntRect             mSurfaceDifferenceRect;
+
+#ifdef MOZ_X11
+    // Used with windowless flash plugin only, see bug 574583
+    PRPackedBool          mFlash10Quirks;
+#endif
 };
 
 } // namespace plugins
 } // namespace mozilla
 
 #endif // ifndef dom_plugins_PluginInstanceChild_h
--- a/dom/plugins/PluginInstanceParent.cpp
+++ b/dom/plugins/PluginInstanceParent.cpp
@@ -41,16 +41,26 @@
 
 #include "BrowserStreamParent.h"
 #include "PluginModuleParent.h"
 #include "PluginStreamParent.h"
 #include "StreamNotifyParent.h"
 #include "npfunctions.h"
 #include "nsAutoPtr.h"
 #include "mozilla/unused.h"
+#include "gfxASurface.h"
+#include "gfxContext.h"
+#include "gfxPlatform.h"
+#include "gfxSharedImageSurface.h"
+#ifdef MOZ_X11
+#include "gfxXlibSurface.h"
+#endif
+#include "gfxContext.h"
+#include "gfxColor.h"
+#include "gfxUtils.h"
 
 #if defined(OS_WIN)
 #include <windowsx.h>
 
 // Plugin focus event for widget.
 extern const PRUnichar* kOOPPPluginFocusEventId;
 UINT gOOPPPluginFocusEvent =
     RegisterWindowMessage(kOOPPPluginFocusEventId);
@@ -83,16 +93,17 @@ PluginInstanceParent::PluginInstancePare
     , mQuirks(0)
 #if defined(XP_MACOSX)
     , mShWidth(0)
     , mShHeight(0)
     , mShColorSpace(nsnull)
     , mDrawingModel(NPDrawingModelCoreGraphics)
     , mIOSurface(nsnull)
 #endif
+    , mSentPaintNotification(PR_FALSE)
 {
     InitQuirksModes(aMimeType);
 }
 
 void
 PluginInstanceParent::InitQuirksModes(const nsCString& aMimeType)
 {
 #ifdef OS_MACOSX
@@ -455,32 +466,119 @@ PluginInstanceParent::DeallocPStreamNoti
 
 bool
 PluginInstanceParent::RecvNPN_InvalidateRect(const NPRect& rect)
 {
     mNPNIface->invalidaterect(mNPP, const_cast<NPRect*>(&rect));
     return true;
 }
 
+bool
+PluginInstanceParent::RecvShow(const NPRect& updatedRect,
+                               const SurfaceDescriptor& newSurface,
+                               SurfaceDescriptor* prevSurface)
+{
+    nsRefPtr<gfxASurface> surface;
+    if (newSurface.type() == SurfaceDescriptor::TShmem) {
+        if (!newSurface.get_Shmem().IsReadable()) {
+            NS_WARNING("back surface not readable");
+            return false;
+        }
+        surface = new gfxSharedImageSurface(newSurface.get_Shmem());
+    }
+#ifdef MOZ_X11
+    else if (newSurface.type() == SurfaceDescriptor::TSurfaceDescriptorX11) {
+        SurfaceDescriptorX11 xdesc = newSurface.get_SurfaceDescriptorX11();
+        XRenderPictFormat pf;
+        pf.id = xdesc.xrenderPictID();
+        XRenderPictFormat *incFormat =
+            XRenderFindFormat(DefaultXDisplay(), PictFormatID, &pf, 0);
+        surface =
+            new gfxXlibSurface(DefaultScreenOfDisplay(DefaultXDisplay()),
+                               xdesc.XID(), incFormat, xdesc.size());
+    }
+#endif
+
+    mSentPaintNotification = PR_FALSE;
+    if (mFrontSurface) {
+#ifdef MOZ_X11
+        if (mFrontSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
+            gfxXlibSurface *xsurf = static_cast<gfxXlibSurface*>(mFrontSurface.get());
+            *prevSurface =
+                SurfaceDescriptorX11(xsurf->XDrawable(), xsurf->XRenderFormat()->id,
+                                    mFrontSurface->GetSize());
+        } else
+#endif
+        if (gfxSharedImageSurface::IsSharedImage(mFrontSurface)) {
+            *prevSurface = static_cast<gfxSharedImageSurface*>(mFrontSurface.get())->GetShmem();
+        } else {
+            *prevSurface = null_t();
+        }
+    } else {
+        *prevSurface = null_t();
+    }
+    mFrontSurface = surface;
+    RecvNPN_InvalidateRect(updatedRect);
+#ifdef MOZ_X11
+    // Sync prevSurface before sending to child
+    if (prevSurface->type() == SurfaceDescriptor::TSurfaceDescriptorX11) {
+        XSync(DefaultXDisplay(), False);
+    }
+#endif
+
+    return true;
+}
+
 nsresult
 PluginInstanceParent::AsyncSetWindow(NPWindow* aWindow)
 {
-    return NS_ERROR_NOT_IMPLEMENTED;
+    NPRemoteWindow window;
+    mWindowType = aWindow->type;
+    window.window = reinterpret_cast<unsigned long>(aWindow->window);
+    window.x = aWindow->x;
+    window.y = aWindow->y;
+    window.width = aWindow->width;
+    window.height = aWindow->height;
+    window.clipRect = aWindow->clipRect;
+    window.type = aWindow->type;
+    mSentPaintNotification = PR_FALSE;
+    if (!SendAsyncSetWindow(gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType(),
+                            window))
+        return NS_ERROR_FAILURE;
+
+    return NS_OK;
 }
 
 nsresult
 PluginInstanceParent::NotifyPainted(void)
 {
-    return NS_ERROR_NOT_IMPLEMENTED;
+    bool rv = true;
+    if (!mSentPaintNotification) {
+        rv = SendPaintFinished();
+        mSentPaintNotification = rv;
+    }
+    return rv ? NS_OK : NS_ERROR_FAILURE;
 }
 
 nsresult
 PluginInstanceParent::GetSurface(gfxASurface** aSurface)
 {
-    return NS_ERROR_NOT_IMPLEMENTED;
+    if (mFrontSurface) {
+      NS_ADDREF(*aSurface = mFrontSurface);
+      return NS_OK;
+    }
+    return NS_ERROR_NOT_AVAILABLE;
+}
+
+nsresult
+PluginInstanceParent::UseAsyncPainting(PRBool* aIsAsync)
+{
+    NS_ENSURE_ARG_POINTER(aIsAsync);
+    *aIsAsync = PR_TRUE;
+    return NS_OK;
 }
 
 NPError
 PluginInstanceParent::NPP_SetWindow(const NPWindow* aWindow)
 {
     PLUGIN_LOG_DEBUG(("%s (aWindow=%p)", FULLFUNCTION, (void*) aWindow));
 
     NS_ENSURE_TRUE(aWindow, NPERR_GENERIC_ERROR);
--- a/dom/plugins/PluginInstanceParent.h
+++ b/dom/plugins/PluginInstanceParent.h
@@ -47,16 +47,20 @@
 #include "nsCoreAnimationSupport.h"
 #endif
 
 #include "npfunctions.h"
 #include "nsAutoPtr.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsRect.h"
+#include "gfxASurface.h"
+#ifdef MOZ_X11
+class gfxXlibSurface;
+#endif
 
 namespace mozilla {
 namespace plugins {
 
 class PBrowserStreamParent;
 class PluginModuleParent;
 
 class PluginInstanceParent : public PPluginInstanceParent
@@ -160,16 +164,22 @@ public:
                                    NPError* result);
 
     virtual bool
     DeallocPStreamNotify(PStreamNotifyParent* notifyData);
 
     virtual bool
     RecvNPN_InvalidateRect(const NPRect& rect);
 
+    // Async rendering
+    virtual bool
+    RecvShow(const NPRect& updatedRect,
+             const SurfaceDescriptor& newSurface,
+             SurfaceDescriptor* prevSurface);
+
     virtual bool
     AnswerNPN_PushPopupsEnabledState(const bool& aState);
 
     virtual bool
     AnswerNPN_PopPopupsEnabledState();
 
     NS_OVERRIDE virtual bool
     AnswerNPN_GetValueForURL(const NPNURLVariable& variable,
@@ -248,16 +258,17 @@ public:
 
 #if defined(OS_MACOSX)
     void Invalidate();
 #endif // definied(OS_MACOSX)
 
     nsresult AsyncSetWindow(NPWindow* window);
     nsresult NotifyPainted(void);
     nsresult GetSurface(gfxASurface** aSurface);
+    nsresult UseAsyncPainting(PRBool* aIsAsync);
 
 private:
     // Quirks mode support for various plugin mime types
     enum PluginQuirks {
         // OSX: Don't use the refresh timer for plug-ins
         // using this quirk. These plug-in most have another
         // way to refresh the window.
         COREANIMATION_REFRESH_TIMER = 1,
@@ -303,15 +314,21 @@ private:
 private:
     Shmem              mShSurface; 
     size_t             mShWidth;
     size_t             mShHeight;
     CGColorSpaceRef    mShColorSpace;
     int16_t            mDrawingModel;
     nsIOSurface       *mIOSurface;
 #endif // definied(OS_MACOSX)
+
+    // ObjectFrame layer wrapper
+    nsRefPtr<gfxASurface>    mFrontSurface;
+
+    // Don't spam plugin process with extra paint notifications
+    PRPackedBool             mSentPaintNotification;
 };
 
 
 } // namespace plugins
 } // namespace mozilla
 
 #endif // ifndef dom_plugins_PluginInstanceParent_h
--- a/dom/plugins/PluginLibrary.h
+++ b/dom/plugins/PluginLibrary.h
@@ -77,14 +77,15 @@ public:
   virtual nsresult NPP_New(NPMIMEType pluginType, NPP instance,
                            uint16_t mode, int16_t argc, char* argn[],
                            char* argv[], NPSavedData* saved,
                            NPError* error) = 0;
 
   virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window) = 0;
   virtual nsresult NotifyPainted(NPP instance) = 0;
   virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface) = 0;
+  virtual nsresult UseAsyncPainting(NPP instance, PRBool* aIsAsync) = 0;
 };
 
 
 } // namespace mozilla
 
 #endif  // ifndef mozilla_PluginLibrary_h
--- a/dom/plugins/PluginModuleParent.cpp
+++ b/dom/plugins/PluginModuleParent.cpp
@@ -638,16 +638,26 @@ PluginModuleParent::GetSurface(NPP insta
 {
     PluginInstanceParent* i = InstCast(instance);
     if (!i)
         return NS_ERROR_FAILURE;
 
     return i->GetSurface(aSurface);
 }
 
+nsresult
+PluginModuleParent::UseAsyncPainting(NPP instance, PRBool* aIsAsync)
+{
+    PluginInstanceParent* i = InstCast(instance);
+    if (!i)
+        return NS_ERROR_FAILURE;
+
+    return i->UseAsyncPainting(aIsAsync);
+}
+
 
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
 nsresult
 PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error)
 {
     PLUGIN_LOG_DEBUG_METHOD;
 
     mNPNIface = bFuncs;
--- a/dom/plugins/PluginModuleParent.h
+++ b/dom/plugins/PluginModuleParent.h
@@ -219,16 +219,17 @@ private:
                                 NPPVariable variable, void *ret_value);
     static NPError NPP_SetValue(NPP instance, NPNVariable variable,
                                 void *value);
 
     virtual bool HasRequiredFunctions();
     virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window);
     virtual nsresult NotifyPainted(NPP instance);
     virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface);
+    virtual nsresult UseAsyncPainting(NPP instance, PRBool* aIsAsync);
 
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
     virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error);
 #else
     virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error);
 #endif
     virtual nsresult NP_Shutdown(NPError* error);
     virtual nsresult NP_GetMIMEDescription(const char** mimeDesc);
--- a/dom/plugins/PluginProcessChild.cpp
+++ b/dom/plugins/PluginProcessChild.cpp
@@ -85,29 +85,35 @@ PluginProcessChild::Init()
     NS_ABORT_IF_FALSE(values.size() >= 1, "not enough loose args");
 
     pluginFilename = WideToUTF8(values[0]);
 
 #else
 #  error Sorry
 #endif
 
+    if (NS_FAILED(nsRegion::InitStatic())) {
+      NS_ERROR("Could not initialize nsRegion");
+      return false;
+    }
+
     mPlugin.Init(pluginFilename, ParentHandle(),
                  IOThreadChild::message_loop(),
                  IOThreadChild::channel());
 
     return true;
 }
 
 void
 PluginProcessChild::CleanUp()
 {
 #ifdef XP_WIN
     ::OleUninitialize();
 #endif
+    nsRegion::ShutdownStatic();
 }
 
 /* static */
 void
 PluginProcessChild::AppendNotesToCrashReport(const nsCString& aNotes)
 {
     AssertPluginThread();
 
--- a/dom/tests/mochitest/bugs/Makefile.in
+++ b/dom/tests/mochitest/bugs/Makefile.in
@@ -115,14 +115,15 @@ include $(topsrcdir)/config/rules.mk
 		test_bug558973.html \
 		test_bug563487.html \
 		test_bug545314.html \
 		test_bug548828.html \
 		test_bug562433.html \
 		test_DOMWindowCreated_chromeonly.html \
 		test_bug581072.html \
 		test_bug583225.html \
+		test_bug585240.html \
 		test_bug585819.html \
 		test_bug369306.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_bug585240.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=585240
+-->
+<head>
+  <title>Test for Bug 585240</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <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=585240">Mozilla Bug 585240</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 585240 **/
+
+  SimpleTest.waitForExplicitFinish();
+
+  window.onmessage = function(event) {
+    ok(true, "message event should fire!");
+    SimpleTest.finish();
+  }
+  window.postMessage("hello", "*");  
+
+</script>
+</pre>
+</body>
+</html>
--- a/gfx/layers/d3d9/ContainerLayerD3D9.cpp
+++ b/gfx/layers/d3d9/ContainerLayerD3D9.cpp
@@ -153,16 +153,17 @@ ContainerLayerD3D9::RenderLayer()
     device()->GetScissorRect(&oldClipRect);
     device()->CreateTexture(visibleRect.width, visibleRect.height, 1,
                             D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
                             D3DPOOL_DEFAULT, getter_AddRefs(renderTexture),
                             NULL);
     nsRefPtr<IDirect3DSurface9> renderSurface;
     renderTexture->GetSurfaceLevel(0, getter_AddRefs(renderSurface));
     device()->SetRenderTarget(0, renderSurface);
+    device()->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 0), 0, 0);
     device()->GetVertexShaderConstantF(12, previousRenderTargetOffset, 1);
     renderTargetOffset[0] = (float)visibleRect.x;
     renderTargetOffset[1] = (float)visibleRect.y;
     device()->SetVertexShaderConstantF(12, renderTargetOffset, 1);
 
     float viewMatrix[4][4];
     /*
      * Matrix to transform to viewport space ( <-1.0, 1.0> topleft,
--- a/gfx/thebes/gfxImageSurface.cpp
+++ b/gfx/thebes/gfxImageSurface.cpp
@@ -187,8 +187,32 @@ gfxImageSurface::CopyFrom(gfxImageSurfac
             unsigned char *dst = mData + mStride * i;
 
             memcpy (dst, src, lineSize);
         }
     }
 
     return PR_TRUE;
 }
+
+already_AddRefed<gfxSubimageSurface>
+gfxImageSurface::GetSubimage(const gfxRect& aRect)
+{
+    gfxRect r(aRect);
+    r.Round();
+    unsigned char* subData = Data() +
+        (Stride() * (int)r.Y()) +
+        (int)r.X() * gfxASurface::BytePerPixelFromFormat(Format());
+
+    nsRefPtr<gfxSubimageSurface> image =
+        new gfxSubimageSurface(this, subData,
+                               gfxIntSize((int)r.Width(), (int)r.Height()));
+
+    return image.forget().get();
+}
+
+gfxSubimageSurface::gfxSubimageSurface(gfxImageSurface* aParent,
+                                       unsigned char* aData,
+                                       const gfxIntSize& aSize)
+  : gfxImageSurface(aData, aSize, aParent->Stride(), aParent->Format())
+  , mParent(aParent)
+{
+}
--- a/gfx/thebes/gfxImageSurface.h
+++ b/gfx/thebes/gfxImageSurface.h
@@ -38,16 +38,18 @@
 #ifndef GFX_IMAGESURFACE_H
 #define GFX_IMAGESURFACE_H
 
 #include "gfxASurface.h"
 #include "gfxPoint.h"
 
 // ARGB -- raw buffer.. wont be changed.. good for storing data.
 
+class gfxSubimageSurface;
+
 /**
  * A raw image buffer. The format can be set in the constructor. Its main
  * purpose is for storing read-only images and using it as a source surface,
  * but it can also be drawn to.
  */
 class THEBES_API gfxImageSurface : public gfxASurface {
 public:
     /**
@@ -94,21 +96,36 @@ public:
     /**
      * Returns the total size of the image data.
      */
     PRInt32 GetDataSize() const { return mStride*mSize.height; }
 
     /* Fast copy from another image surface; returns TRUE if successful, FALSE otherwise */
     PRBool CopyFrom (gfxImageSurface *other);
 
+    /* return new Subimage with pointing to original image starting from aRect.pos
+     * and size of aRect.size. New subimage keeping current image reference
+     */
+    already_AddRefed<gfxSubimageSurface> GetSubimage(const gfxRect& aRect);
+
 protected:
     gfxImageSurface();
     void InitFromSurface(cairo_surface_t *csurf);
     long ComputeStride() const;
 
     gfxIntSize mSize;
     PRBool mOwnsData;
     unsigned char *mData;
     gfxImageFormat mFormat;
     long mStride;
 };
 
+class THEBES_API gfxSubimageSurface : public gfxImageSurface {
+protected:
+    friend class gfxImageSurface;
+    gfxSubimageSurface(gfxImageSurface* aParent,
+                       unsigned char* aData,
+                       const gfxIntSize& aSize);
+private:
+    nsRefPtr<gfxImageSurface> mParent;
+};
+
 #endif /* GFX_IMAGESURFACE_H */
--- a/ipc/glue/IPCMessageUtils.h
+++ b/ipc/glue/IPCMessageUtils.h
@@ -45,25 +45,27 @@
 #include "nsStringGlue.h"
 #include "nsTArray.h"
 #include "gfx3DMatrix.h"
 #include "gfxColor.h"
 #include "gfxMatrix.h"
 #include "gfxPattern.h"
 #include "nsRect.h"
 #include "nsRegion.h"
+#include "gfxASurface.h"
 
 #ifdef _MSC_VER
 #pragma warning( disable : 4800 )
 #endif
 
 
 namespace mozilla {
 
 typedef gfxPattern::GraphicsFilter GraphicsFilterType;
+typedef gfxASurface::gfxSurfaceType gfxSurfaceType;
 
 // XXX there are out of place and might be generally useful.  Could
 // move to nscore.h or something.
 struct void_t {
   bool operator==(const void_t&) const { return true; }
 };
 struct null_t {
   bool operator==(const null_t&) const { return true; }
@@ -310,34 +312,16 @@ struct ParamTraits<float>
 
   static void Log(const paramType& aParam, std::wstring* aLog)
   {
     aLog->append(StringPrintf(L"%g", aParam));
   }
 };
 
 template<>
-struct ParamTraits<gfxIntSize>
-{
-  typedef gfxIntSize paramType;
-  
-  static void Write(Message* msg, const paramType& param)
-  {
-    WriteParam(msg, param.width);
-    WriteParam(msg, param.height);
-  }
-
-  static bool Read(const Message* msg, void** iter, paramType* result)
-  {
-    return (ReadParam(msg, iter, &result->width) &&
-            ReadParam(msg, iter, &result->height));
-  }
-};
-
-template<>
 struct ParamTraits<gfxMatrix>
 {
   typedef gfxMatrix paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.xx);
     WriteParam(aMsg, aParam.xy);
@@ -432,16 +416,48 @@ struct ParamTraits<mozilla::GraphicsFilt
       *result = paramType(filter);
       return true;
 
     default:
       return false;
     }
   }
 };
+
+ template<>
+struct ParamTraits<mozilla::gfxSurfaceType>
+{
+  typedef mozilla::gfxSurfaceType paramType;
+
+  static void Write(Message* msg, const paramType& param)
+  {
+    if (gfxASurface::SurfaceTypeImage <= param &&
+        param < gfxASurface::SurfaceTypeMax) {
+      WriteParam(msg, int32(param));
+      return;
+    }
+    NS_RUNTIMEABORT("surface type not reached");
+  }
+
+  static bool Read(const Message* msg, void** iter, paramType* result)
+  {
+    int32 filter;
+    if (!ReadParam(msg, iter, &filter))
+      return false;
+
+    if (gfxASurface::SurfaceTypeImage <= filter &&
+        filter < gfxASurface::SurfaceTypeMax) {
+      *result = paramType(filter);
+      return true;
+    }
+    return false;
+  }
+};
+
+
 template<>
 struct ParamTraits<gfxRGBA>
 {
   typedef gfxRGBA paramType;
 
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.r);
@@ -565,11 +581,29 @@ struct ParamTraits<nsIntSize>
 
   static bool Read(const Message* msg, void** iter, paramType* result)
   {
     return (ReadParam(msg, iter, &result->width) &&
             ReadParam(msg, iter, &result->height));
   }
 };
 
+template<>
+struct ParamTraits<gfxIntSize>
+{
+  typedef gfxIntSize paramType;
+  
+  static void Write(Message* msg, const paramType& param)
+  {
+    WriteParam(msg, param.width);
+    WriteParam(msg, param.height); 
+  }
+
+  static bool Read(const Message* msg, void** iter, paramType* result)
+  {
+    return (ReadParam(msg, iter, &result->width) &&
+            ReadParam(msg, iter, &result->height));
+  }
+};
+
 } /* namespace IPC */
 
 #endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */
--- a/js/src/assembler/wtf/Platform.h
+++ b/js/src/assembler/wtf/Platform.h
@@ -895,19 +895,16 @@ on MinGW. See https://bugs.webkit.org/sh
 #endif
 
 /* Yet Another Regex Runtime. */
 #if !defined(ENABLE_YARR_JIT)
 
 /* YARR supports x86 & x86-64, and has been tested on Mac and Windows. */
 #if (WTF_CPU_X86 \
  || WTF_CPU_X86_64 \
- || WTF_CPU_ARM_THUMB2 \
- || WTF_CPU_ARM_TRADITIONAL \
- || WTF_CPU_ARM_TRADITIONAL \
  || WTF_CPU_X86)
 #define ENABLE_YARR_JIT 1
 #else
 #define ENABLE_YARR_JIT 0
 #endif
 
 #endif /* !defined(ENABLE_YARR_JIT) */
 
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -2352,10 +2352,10 @@ FREEZE_VARIABLES = \
 $(foreach var,$(FREEZE_VARIABLES),$(eval $(var)_FROZEN := '$($(var))'))
 
 CHECK_FROZEN_VARIABLES = $(foreach var,$(FREEZE_VARIABLES), \
   $(if $(subst $($(var)_FROZEN),,'$($(var))'),$(error Makefile variable '$(var)' changed value after including rules.mk. Was $($(var)_FROZEN), now $($(var)).)))
 
 libs export libs::
 	$(CHECK_FROZEN_VARIABLES)
 
-default::
+default all::
 	if test -d $(DIST)/bin ; then touch $(DIST)/bin/.purgecaches ; fi
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/594737-1-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<body>
+  <select disabled size="4">
+    <option>One</option>
+    <option>Two</option>
+    <option>Three</option>
+    <option>Four</option>
+  </select>
+</body>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/594737-1.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<body>
+  <select disabled multiple size="4">
+    <option>One</option>
+    <option>Two</option>
+    <option>Three</option>
+    <option>Four</option>
+  </select>
+</body>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1498,9 +1498,10 @@ random-if(layersGPUAccelerated) == 58131
 == 582037-2a.html 582037-2-ref.html
 == 582037-2b.html 582037-2-ref.html
 == 584400-dash-length.svg 584400-dash-length-ref.svg
 == 584699-1.html 584699-1-ref.html
 == 585598-2.xhtml 585598-2-ref.xhtml
 == 589672-1.html 589672-1-ref.html
 == 586400-1.html 586400-1-ref.html
 == 593544-1.html 593544-1-ref.html
+== 594737-1.html 594737-1-ref.html
 == 594624-1.html 594624-1-ref.html
new file mode 100755
--- /dev/null
+++ b/layout/style/crashtests/592698-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <iframe id="x"
+          src="data:text/html;charset=utf-8,%3Cdiv%20id%3D%22a%22%3Eaaa"></iframe>
+
+  <script>
+    window.onload = function() {
+      window.frames[0].document.getElementById("a").setAttribute("style",
+        '-moz-transition-property: color;' +
+        '-moz-transition-duration: 10s;' +
+        'transition-property: color;' +
+        'transition-duration: 10s; ' +
+        'color: red;');
+
+      // And start the transition
+      window.frames[0].document.documentElement.getBoundingClientRect();
+
+      // Now kill off the presshell
+      var frame = document.getElementById("x");
+      frame.style.display = "none";
+      document.documentElement.getBoundingClientRect();
+
+      // And wait for the refresh driver to fire
+      setTimeout(function() {
+          document.documentElement.className = "";
+      }, 100);
+    }
+  </script>
+</html>
--- a/layout/style/crashtests/crashtests.list
+++ b/layout/style/crashtests/crashtests.list
@@ -55,8 +55,9 @@ load 509569-1.html
 load 524252-1.html
 load font-face-truncated-src.html 
 load 536789-1.html
 load 565248-1.html
 load 558943-1.xhtml
 load 571105-1.xhtml
 load 573127-1.html
 load 580685.html
+load 592698-1.html
--- a/layout/style/forms.css
+++ b/layout/style/forms.css
@@ -355,17 +355,19 @@ optgroup:before {
   border: 1px outset black !important;
   border-left-width: 2px ! important;
 } 
 
 input[disabled],
 textarea[disabled],
 option[disabled],
 optgroup[disabled],
-select[disabled] {
+select[disabled][disabled] /* Need the attr twice to have the specificity be at
+                              least the same as select[size][multiple] above */
+{
   -moz-user-input: disabled;
   -moz-user-focus: ignore;
   color: GrayText;
   background-color: ThreeDFace;
   cursor: inherit;
 }
 
 option[disabled],
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -274,23 +274,29 @@ nsTransitionManager::~nsTransitionManage
 {
   NS_ABORT_IF_FALSE(!mPresContext, "Disconnect should have been called");
 }
 
 void
 nsTransitionManager::Disconnect()
 {
   // Content nodes might outlive the transition manager.
+  RemoveAllTransitions();
+
+  mPresContext = nsnull;
+}
+
+void
+nsTransitionManager::RemoveAllTransitions()
+{
   while (!PR_CLIST_IS_EMPTY(&mElementTransitions)) {
     ElementTransitions *head = static_cast<ElementTransitions*>(
                                  PR_LIST_HEAD(&mElementTransitions));
     head->Destroy();
   }
-
-  mPresContext = nsnull;
 }
 
 static PRBool
 TransExtractComputedValue(nsCSSProperty aProperty,
                           nsStyleContext* aStyleContext,
                           nsStyleAnimation::Value& aComputedValue)
 {
   PRBool result =
@@ -863,16 +869,24 @@ struct TransitionEventInfo {
 };
 
 /* virtual */ void
 nsTransitionManager::WillRefresh(mozilla::TimeStamp aTime)
 {
   NS_ABORT_IF_FALSE(mPresContext,
                     "refresh driver should not notify additional observers "
                     "after pres context has been destroyed");
+  if (!mPresContext->GetPresShell()) {
+    // Someone might be keeping mPresContext alive past the point
+    // where it has been torn down; don't bother doing anything in
+    // this case.  But do get rid of all our transitions so we stop
+    // triggering refreshes.
+    RemoveAllTransitions();
+    return;
+  }
 
   nsTArray<TransitionEventInfo> events;
 
   // Trim transitions that have completed, and post restyle events for
   // frames that are still transitioning.
   {
     PRCList *next = PR_LIST_HEAD(&mElementTransitions);
     while (next != &mElementTransitions) {
--- a/layout/style/nsTransitionManager.h
+++ b/layout/style/nsTransitionManager.h
@@ -117,13 +117,15 @@ private:
   ElementTransitions* GetElementTransitions(mozilla::dom::Element *aElement,
                                             nsCSSPseudoElements::Type aPseudoType,
                                             PRBool aCreateIfNeeded);
   void AddElementTransitions(ElementTransitions* aElementTransitions);
   void TransitionsRemoved();
   void WalkTransitionRule(RuleProcessorData* aData,
                           nsCSSPseudoElements::Type aPseudoType);
 
+  void RemoveAllTransitions();
+
   PRCList mElementTransitions;
   nsPresContext *mPresContext; // weak (non-null from ctor to Disconnect)
 };
 
 #endif /* !defined(nsTransitionManager_h_) */
--- a/layout/xul/base/src/nsMenuFrame.cpp
+++ b/layout/xul/base/src/nsMenuFrame.cpp
@@ -1363,16 +1363,23 @@ nsMenuFrame::SizeToPopup(nsBoxLayoutStat
     PRBool widthSet, heightSet;
     nsSize tmpSize(-1, 0);
     nsIBox::AddCSSPrefSize(this, tmpSize, widthSet, heightSet);
     if (!widthSet && GetFlex(aState) == 0) {
       if (!mPopupFrame)
         return PR_FALSE;
       tmpSize = mPopupFrame->GetPrefSize(aState);
       aSize.width = tmpSize.width;
+
+      // if there is a scroll frame, add the desired width of the scrollbar as well
+      nsIScrollableFrame* scrollFrame = do_QueryFrame(mPopupFrame->GetFirstChild(nsnull));
+      if (scrollFrame) {
+        aSize.width += scrollFrame->GetDesiredScrollbarSizes(&aState).LeftRight();
+      }
+
       return PR_TRUE;
     }
   }
 
   return PR_FALSE;
 }
 
 nsSize
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -55,16 +55,21 @@ pref("general.useragent.compatMode.firef
 pref("general.config.obscure_value", 13); // for MCD .cfg files
 
 pref("general.warnOnAboutConfig", true);
 
 // maximum number of dated backups to keep at any time
 pref("browser.bookmarks.max_backups",       5);
 
 pref("browser.cache.disk.enable",           true);
+// Is this the first-time smartsizing has been introduced?
+pref("browser.cache.disk.smart_size.first_run", true);
+// Does the user want smart-sizing?
+pref("browser.cache.disk.smart_size.enabled", true);
+// Size explicitly set by the user. Used when smart_size.enabled == false
 #ifndef WINCE
 pref("browser.cache.disk.capacity",         256000);
 #else
 pref("browser.cache.disk.capacity",         20000);
 #endif
 pref("browser.cache.memory.enable",         true);
 //pref("browser.cache.memory.capacity",     -1);
 // -1 = determine dynamically, 0 = none, n = memory capacity in kilobytes
@@ -793,22 +798,33 @@ pref("network.IDN.whitelist.sh", true);
 pref("network.IDN.whitelist.th", true);
 pref("network.IDN.whitelist.tm", true);
 pref("network.IDN.whitelist.tw", true);
 pref("network.IDN.whitelist.vn", true);
 
 // IDN ccTLDs
 // ae, UAE, .<Emarat>
 pref("network.IDN.whitelist.xn--mgbaam7a8h", true); 
-// sa, Saudi Arabia, .<al-Saudiah>
-pref("network.IDN.whitelist.xn--mgberp4a5d4ar", true); 
+// cn, China, .<China> with variants
+pref("network.IDN.whitelist.xn--fiqz9s", true); // Traditional
+pref("network.IDN.whitelist.xn--fiqs8s", true); // Simplified
+// hk, Hong Kong, .<Hong Kong>
+pref("network.IDN.whitelist.xn--j6w193g", true);
+// jo, Jordan, .<Al-Ordon>
+pref("network.IDN.whitelist.xn--mgbayh7gpa", true);
 // ru, Russian Federation, .<RF>
 pref("network.IDN.whitelist.xn--p1ai", true);
-// jo, Jordan, .<Al-Ordon>
-pref("network.IDN.whitelist.xn--mgbayh7gpa", true);
+// sa, Saudi Arabia, .<al-Saudiah> with variants
+pref("network.IDN.whitelist.xn--mgberp4a5d4ar", true); 
+pref("network.IDN.whitelist.xn--mgberp4a5d4a87g", true);
+pref("network.IDN.whitelist.xn--mgbqly7c0a67fbc", true);
+pref("network.IDN.whitelist.xn--mgbqly7cvafr", true);
+// tw, Taiwan, <.Taiwan> with variants
+pref("network.IDN.whitelist.xn--kpry57d", true);  // Traditional
+pref("network.IDN.whitelist.xn--kprw13d", true);  // Simplified
 
 // gTLDs
 pref("network.IDN.whitelist.biz", true);
 pref("network.IDN.whitelist.cat", true);
 pref("network.IDN.whitelist.info", true);
 pref("network.IDN.whitelist.museum", true);
 pref("network.IDN.whitelist.org", true);
 pref("network.IDN.whitelist.tel", true);
--- a/modules/plugin/base/public/nsIPluginInstance.idl
+++ b/modules/plugin/base/public/nsIPluginInstance.idl
@@ -236,9 +236,14 @@ interface nsIPluginInstance : nsISupport
      * Call this each time after the plugin has been painted to the screen
      */
     void notifyPainted();
 
     /**
      * This should return a valid gfxASurface pointer, or null if there is nothing to render yet.
      */
     void getSurface(out gfxASurfacePtr aSurface);
+
+    /**
+     * @return true if plugin module supports async rendering
+     */
+    PRBool useAsyncPainting();
 };
--- a/modules/plugin/base/src/PluginPRLibrary.cpp
+++ b/modules/plugin/base/src/PluginPRLibrary.cpp
@@ -186,30 +186,38 @@ PluginPRLibrary::NPP_New(NPMIMEType plug
   return NS_OK;
 }
 
 nsresult
 PluginPRLibrary::AsyncSetWindow(NPP instance, NPWindow* window)
 {
   nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
   NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
-  return inst->AsyncSetWindow(window);
+  return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 nsresult
 PluginPRLibrary::NotifyPainted(NPP instance)
 {
   nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
   NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
-  return inst->NotifyPainted();
+  return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 nsresult
 PluginPRLibrary::GetSurface(NPP instance, gfxASurface** aSurface)
 {
   nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
   NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
   *aSurface = nsnull;
   return NS_OK;
 }
 
+nsresult
+PluginPRLibrary::UseAsyncPainting(NPP instance, PRBool* aIsAsync)
+{
+  nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
+  NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
+  aIsAsync = PR_FALSE;
+  return NS_OK;
+}
 
 } // namespace mozilla
--- a/modules/plugin/base/src/PluginPRLibrary.h
+++ b/modules/plugin/base/src/PluginPRLibrary.h
@@ -131,16 +131,17 @@ public:
     virtual nsresult NPP_New(NPMIMEType pluginType, NPP instance,
                              uint16_t mode, int16_t argc, char* argn[],
                              char* argv[], NPSavedData* saved,
                              NPError* error);
 
     virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window);
     virtual nsresult NotifyPainted(NPP instance);
     virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface);
+    virtual nsresult UseAsyncPainting(NPP instance, PRBool* aIsAsync);
 
 private:
     NP_InitializeFunc mNP_Initialize;
     NP_ShutdownFunc mNP_Shutdown;
     NP_GetMIMEDescriptionFunc mNP_GetMIMEDescription;
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
     NP_GetValueFunc mNP_GetValue;
 #endif
--- a/modules/plugin/base/src/nsNPAPIPluginInstance.cpp
+++ b/modules/plugin/base/src/nsNPAPIPluginInstance.cpp
@@ -870,16 +870,33 @@ nsNPAPIPluginInstance::NotifyPainted(voi
 
   PluginLibrary* library = mPlugin->GetLibrary();
   if (!library)
     return NS_ERROR_FAILURE;
 
   return library->NotifyPainted(&mNPP);
 }
 
+NS_IMETHODIMP
+nsNPAPIPluginInstance::UseAsyncPainting(PRBool* aIsAsync)
+{
+  if (RUNNING != mRunning)
+    return NS_OK;
+
+  PluginDestructionGuard guard(this);
+
+  if (!mPlugin)
+    return NS_ERROR_FAILURE;
+
+  PluginLibrary* library = mPlugin->GetLibrary();
+  if (!library)
+    return NS_ERROR_FAILURE;
+
+  return library->UseAsyncPainting(&mNPP, aIsAsync);
+}
 
 NS_IMETHODIMP
 nsNPAPIPluginInstance::IsTransparent(PRBool* isTransparent)
 {
   *isTransparent = mTransparent;
   return NS_OK;
 }
 
--- a/netwerk/cache/nsCacheService.cpp
+++ b/netwerk/cache/nsCacheService.cpp
@@ -1,10 +1,11 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 ts=8 et tw=80 : */
+/*
  * ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
  *
@@ -79,16 +80,21 @@
  * nsCacheProfilePrefObserver
  *****************************************************************************/
 #ifdef XP_MAC
 #pragma mark nsCacheProfilePrefObserver
 #endif
 
 #define DISK_CACHE_ENABLE_PREF      "browser.cache.disk.enable"
 #define DISK_CACHE_DIR_PREF         "browser.cache.disk.parent_directory"
+#define DISK_CACHE_SMART_SIZE_FIRST_RUN_PREF\
+    "browser.cache.disk.smart_size.first_run"
+#define DISK_CACHE_SMART_SIZE_ENABLED_PREF \
+    "browser.cache.disk.smart_size.enabled"
+#define DISK_CACHE_SMART_SIZE_PREF "browser.cache.disk.smart_size_cached_value"
 #define DISK_CACHE_CAPACITY_PREF    "browser.cache.disk.capacity"
 #define DISK_CACHE_MAX_ENTRY_SIZE_PREF "browser.cache.disk.max_entry_size"
 #define DISK_CACHE_CAPACITY         256000
 
 #define OFFLINE_CACHE_ENABLE_PREF   "browser.cache.offline.enable"
 #define OFFLINE_CACHE_DIR_PREF      "browser.cache.offline.parent_directory"
 #define OFFLINE_CACHE_CAPACITY_PREF "browser.cache.offline.capacity"
 #define OFFLINE_CACHE_CAPACITY      512000
@@ -101,28 +107,35 @@ static const char * observerList[] = {
     "profile-before-change",
     "profile-after-change",
     NS_XPCOM_SHUTDOWN_OBSERVER_ID,
     NS_PRIVATE_BROWSING_SWITCH_TOPIC
 };
 static const char * prefList[] = { 
 #ifdef NECKO_DISK_CACHE
     DISK_CACHE_ENABLE_PREF,
+    DISK_CACHE_SMART_SIZE_ENABLED_PREF,
     DISK_CACHE_CAPACITY_PREF,
     DISK_CACHE_DIR_PREF,
 #endif
 #ifdef NECKO_OFFLINE_CACHE
     OFFLINE_CACHE_ENABLE_PREF,
     OFFLINE_CACHE_CAPACITY_PREF,
     OFFLINE_CACHE_DIR_PREF,
 #endif
     MEMORY_CACHE_ENABLE_PREF,
     MEMORY_CACHE_CAPACITY_PREF
 };
 
+// Let our base line be 250MB. 
+const PRInt32 BASE_LINE = 250 * 1024 * 1024;
+const PRInt32 MIN_SIZE = 50 * 1024 * 1024;
+const PRInt32 MAX_SIZE = 1024 * 1024 * 1024;
+
+
 class nsCacheProfilePrefObserver : public nsIObserver
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOBSERVER
 
     nsCacheProfilePrefObserver()
         : mHaveProfile(PR_FALSE)
@@ -139,43 +152,115 @@ public:
     virtual ~nsCacheProfilePrefObserver() {}
     
     nsresult        Install();
     void            Remove();
     nsresult        ReadPrefs(nsIPrefBranch* branch);
     
     PRBool          DiskCacheEnabled();
     PRInt32         DiskCacheCapacity()         { return mDiskCacheCapacity; }
+    void            SetDiskCacheCapacity(PRInt32);
     nsILocalFile *  DiskCacheParentDirectory()  { return mDiskCacheParentDirectory; }
 
     PRBool          OfflineCacheEnabled();
     PRInt32         OfflineCacheCapacity()         { return mOfflineCacheCapacity; }
     nsILocalFile *  OfflineCacheParentDirectory()  { return mOfflineCacheParentDirectory; }
     
     PRBool          MemoryCacheEnabled();
     PRInt32         MemoryCacheCapacity();
 
+    static PRUint32 GetSmartCacheSize(void);
+
 private:
+    bool                    PermittedToSmartSize(nsIPrefBranch*, PRBool firstRun);
     PRBool                  mHaveProfile;
     
     PRBool                  mDiskCacheEnabled;
     PRInt32                 mDiskCacheCapacity; // in kilobytes
     nsCOMPtr<nsILocalFile>  mDiskCacheParentDirectory;
 
     PRBool                  mOfflineCacheEnabled;
     PRInt32                 mOfflineCacheCapacity; // in kilobytes
     nsCOMPtr<nsILocalFile>  mOfflineCacheParentDirectory;
     
     PRBool                  mMemoryCacheEnabled;
     PRInt32                 mMemoryCacheCapacity; // in kilobytes
 
     PRBool                  mInPrivateBrowsing;
 };
 
-NS_IMPL_ISUPPORTS1(nsCacheProfilePrefObserver, nsIObserver)
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheProfilePrefObserver, nsIObserver)
+
+// Runnable sent to main thread after the cache IO thread calculates available
+// disk space, so that there is no race in setting mDiskCacheCapacity.
+class nsSetSmartSizeEvent: public nsRunnable 
+{
+public:
+    nsSetSmartSizeEvent(bool firstRun, PRInt32 smartSize) 
+        : mFirstRun(firstRun) , mSmartSize(smartSize) {}
+
+    NS_IMETHOD Run() 
+    {
+        nsresult rv;
+        NS_ASSERTION(NS_IsMainThread(), 
+                     "Setting smart size data off the main thread");
+
+        // Main thread may have already called nsCacheService::Shutdown
+        if (!nsCacheService::gService || !nsCacheService::gService->mObserver)
+            return NS_ERROR_NOT_AVAILABLE;
+    
+        PRBool smartSizeEnabled;
+        nsCOMPtr<nsIPrefBranch2> branch = do_GetService(NS_PREFSERVICE_CONTRACTID);
+        if (!branch) {
+            NS_WARNING("Failed to get pref service!");
+            return NS_ERROR_NOT_AVAILABLE;
+        }
+        // ensure smart sizing wasn't switched off while event was pending
+        rv = branch->GetBoolPref(DISK_CACHE_SMART_SIZE_ENABLED_PREF,
+                                 &smartSizeEnabled);
+        if (NS_FAILED(rv)) 
+            smartSizeEnabled = PR_FALSE;
+        if (smartSizeEnabled) {
+            nsCacheService::SetDiskCacheCapacity(mSmartSize);
+            // also set on observer, in case mDiskDevice not init'd yet.
+            nsCacheService::gService->mObserver->SetDiskCacheCapacity(mSmartSize);
+            rv = branch->SetIntPref(DISK_CACHE_SMART_SIZE_PREF, mSmartSize);
+            if (NS_FAILED(rv)) 
+                NS_WARNING("Failed to set smart size pref");
+        }
+        return rv;
+    }
+
+private: 
+    bool mFirstRun;
+    PRInt32 mSmartSize;
+};
+
+
+// Runnable sent from main thread to cacheIO thread
+class nsGetSmartSizeEvent: public nsRunnable
+{
+public:
+    nsGetSmartSizeEvent(bool firstRun) : mFirstRun(firstRun) , mSmartSize(0) {}
+   
+    // Calculates user's disk space available on a background thread and
+    // dispatches this value back to the main thread.
+    NS_IMETHOD Run()
+    {
+        mSmartSize = nsCacheProfilePrefObserver::GetSmartCacheSize() / 1024;
+        nsCOMPtr<nsIRunnable> event = new nsSetSmartSizeEvent(mFirstRun,
+                                                              mSmartSize);
+        NS_DispatchToMainThread(event);
+        return NS_OK;
+    }
+
+private: 
+    bool mFirstRun;
+    PRInt32 mSmartSize;
+};
 
 
 nsresult
 nsCacheProfilePrefObserver::Install()
 {
     // install profile-change observer
     nsCOMPtr<nsIObserverService> observerService =
         mozilla::services::GetObserverService();
@@ -241,16 +326,22 @@ nsCacheProfilePrefObserver::Remove()
     nsCOMPtr<nsIPrefBranch2> prefs =
         do_GetService(NS_PREFSERVICE_CONTRACTID);
     if (!prefs)
         return;
     for (unsigned int i=0; i<NS_ARRAY_LENGTH(prefList); i++)
         prefs->RemoveObserver(prefList[i], this); // remove cache pref observers
 }
 
+void
+nsCacheProfilePrefObserver::SetDiskCacheCapacity(PRInt32 capacity)
+{
+    mDiskCacheCapacity = PR_MAX(0, capacity);
+}
+
 
 NS_IMETHODIMP
 nsCacheProfilePrefObserver::Observe(nsISupports *     subject,
                                     const char *      topic,
                                     const PRUnichar * data_unicode)
 {
     nsresult rv;
     NS_ConvertUTF16toUTF8 data(data_unicode);
@@ -297,16 +388,40 @@ nsCacheProfilePrefObserver::Observe(nsIS
 
         } else if (!strcmp(DISK_CACHE_CAPACITY_PREF, data.get())) {
 
             PRInt32 capacity = 0;
             rv = branch->GetIntPref(DISK_CACHE_CAPACITY_PREF, &capacity);
             if (NS_FAILED(rv))  return rv;
             mDiskCacheCapacity = PR_MAX(0, capacity);
             nsCacheService::SetDiskCacheCapacity(mDiskCacheCapacity);
+       
+        // Update the cache capacity when smart sizing is turned on/off 
+        } else if (!strcmp(DISK_CACHE_SMART_SIZE_ENABLED_PREF, data.get())) {
+            // Is the update because smartsizing was turned on, or off?
+            PRBool smartSizeEnabled;
+            rv = branch->GetBoolPref(DISK_CACHE_SMART_SIZE_ENABLED_PREF,
+                                     &smartSizeEnabled);
+            if (NS_FAILED(rv)) return rv;
+            PRInt32 newCapacity = 0;
+            if (smartSizeEnabled) {
+                // Smart sizing switched on: recalculate the capacity.
+                nsCOMPtr<nsIRunnable> event = new nsGetSmartSizeEvent(false);
+                rv = nsCacheService::DispatchToCacheIOThread(event);
+                // If the dispatch failed, just use our base line for the size
+                if (NS_FAILED(rv)) mDiskCacheCapacity = BASE_LINE;
+            } else {
+                // Smart sizing switched off: use user specified size
+                rv = branch->GetIntPref(DISK_CACHE_CAPACITY_PREF, &newCapacity);
+                if (NS_FAILED(rv)) return rv;
+                mDiskCacheCapacity = PR_MAX(0, newCapacity);
+                nsCacheService::SetDiskCacheCapacity(mDiskCacheCapacity);
+            } 
+            
+               
 #if 0            
         } else if (!strcmp(DISK_CACHE_DIR_PREF, data.get())) {
             // XXX We probaby don't want to respond to this pref except after
             // XXX profile changes.  Ideally, there should be somekind of user
             // XXX notification that the pref change won't take effect until
             // XXX the next time the profile changes (browser launch)
 #endif            
         } else 
@@ -392,16 +507,118 @@ nsCacheProfilePrefObserver::Observe(nsIS
                                        &mOfflineCacheEnabled);
             nsCacheService::SetOfflineCacheEnabled(OfflineCacheEnabled());
 #endif // !NECKO_OFFLINE_CACHE
         }
     }
     
     return NS_OK;
 }
+ 
+ 
+
+ /* Computes our best guess for the default size of the user's disk cache, 
+  * based on the amount of space they have free on their hard drive. 
+  * We use a tiered scheme: the more space available, 
+  * the larger the disk cache will be. However, we do not want
+  * to enable the disk cache to grow to an unbounded size, so the larger the
+  * user's available space is, the smaller of a percentage we take. We set a
+  * lower bound of 50MB and an upper bound of 1GB.  
+  *
+  *@param:  None.
+  *@return: The size that the user's disk cache should default to, in bytes.
+  */
+PRUint32
+nsCacheProfilePrefObserver::GetSmartCacheSize(void) {
+  // Get a handle to disk where cache lives, so we can check for free space
+  nsresult rv;
+  nsCOMPtr<nsIFile> profileDirectory;
+  rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
+                              getter_AddRefs(profileDirectory));
+  if (NS_FAILED(rv)) { 
+    return BASE_LINE;
+  }
+  nsCOMPtr<nsILocalFile> diskHandle = do_QueryInterface(profileDirectory);
+  PRInt64 bytesAvailable;
+  diskHandle->GetDiskSpaceAvailable(&bytesAvailable);
+  
+  /* 0MB <= Available < 500MB
+   * Use between 50MB  and 200MB
+   */ 
+  if (bytesAvailable < BASE_LINE * 2) {
+    return PR_MAX(MIN_SIZE, bytesAvailable * 4 / 10);
+  }
+  
+  /* 500MB <= Available < 2500MB
+   * Use 250MB 
+   */
+  if (bytesAvailable < static_cast<PRInt64>(BASE_LINE) * 10) {
+    return BASE_LINE;
+  }
+
+  /* 2500MB <= Available < 5000MB 
+   * Use between 250MB and 500MB
+   */
+  if (bytesAvailable < static_cast<PRInt64>(BASE_LINE) * 20) {
+    return bytesAvailable / 10;
+  }
+
+  /* 5000MB <= Available < 50000MB 
+   * Use 625MB
+   */
+  if (bytesAvailable < static_cast<PRInt64>(BASE_LINE) * 200 ) {
+    return BASE_LINE * 5 / 2;
+  }
+
+  /* 50000MB <= Available < 75000MB
+   * Use 800MB
+   */
+  if (bytesAvailable < static_cast<PRInt64>(BASE_LINE) * 300) {
+    return BASE_LINE / 5 * 16;  
+  }
+  
+  /* We have come within range of the ceiling
+   * Use 1GB
+   */
+  return MAX_SIZE;
+}
+
+/* Determine if we are permitted to dynamically size the user's disk cache based
+ * on their disk space available. We may do this so long as the pref 
+ * smart_size.enabled is true.
+ */
+bool
+nsCacheProfilePrefObserver::PermittedToSmartSize(nsIPrefBranch* branch, PRBool
+                                                 firstRun)
+{
+    nsresult rv;
+    // If user has explicitly set cache size to be smaller than previous default
+    // of 250MB, then smart sizing is off by default. Otherwise, smart sizing is
+    // on by default.
+    if (firstRun) {
+        // check if user has set cache size in the past
+        PRBool userSet;
+        rv = branch->PrefHasUserValue(DISK_CACHE_CAPACITY_PREF, &userSet);
+        if (NS_FAILED(rv)) userSet = PR_TRUE;
+        if (userSet) {
+            PRInt32 oldCapacity;
+            rv = branch->GetIntPref(DISK_CACHE_CAPACITY_PREF, &oldCapacity);
+            if (oldCapacity < BASE_LINE / 1024) {
+                branch->SetBoolPref(DISK_CACHE_SMART_SIZE_ENABLED_PREF, 
+                                    PR_FALSE);
+                return false;
+            }
+        }
+    }
+    PRBool smartSizeEnabled; 
+    rv = branch->GetBoolPref(DISK_CACHE_SMART_SIZE_ENABLED_PREF,
+                             &smartSizeEnabled);
+    if (NS_FAILED(rv)) return false;
+    return !!smartSizeEnabled;
+}
 
 
 nsresult
 nsCacheProfilePrefObserver::ReadPrefs(nsIPrefBranch* branch)
 {
     nsresult rv = NS_OK;
 
 #ifdef NECKO_DISK_CACHE
@@ -451,16 +668,47 @@ nsCacheProfilePrefObserver::ReadPrefs(ns
         // use file cache in build tree only if asked, to avoid cache dir litter
         if (!directory && PR_GetEnv("NECKO_DEV_ENABLE_DISK_CACHE")) {
             rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
                                         getter_AddRefs(directory));
         }
         if (directory)
             mDiskCacheParentDirectory = do_QueryInterface(directory, &rv);
     }
+    if (mDiskCacheParentDirectory) {
+        PRBool firstSmartSizeRun;
+        rv = branch->GetBoolPref(DISK_CACHE_SMART_SIZE_FIRST_RUN_PREF, 
+                                 &firstSmartSizeRun); 
+        if (NS_FAILED(rv)) firstSmartSizeRun = PR_FALSE;
+        if (PermittedToSmartSize(branch, firstSmartSizeRun)) {
+            // Prevent unnecessary eviction before smart size event returns 
+            if (!firstSmartSizeRun) {
+                PRInt32 oldSmartSize;
+                rv = branch->GetIntPref(DISK_CACHE_SMART_SIZE_PREF,
+                                        &oldSmartSize);
+                mDiskCacheCapacity = oldSmartSize;
+            } else {
+                rv = branch->SetIntPref(DISK_CACHE_CAPACITY_PREF, 
+                                        MAX_SIZE / 1024);
+                if (NS_FAILED(rv)) NS_WARNING("Failed setting capacity pref");
+            }
+            nsCOMPtr<nsIRunnable> event = 
+                new nsGetSmartSizeEvent(!!firstSmartSizeRun);
+            rv = nsCacheService::DispatchToCacheIOThread(event);
+            if (NS_FAILED(rv)) mDiskCacheCapacity = BASE_LINE;
+        }
+
+        if (firstSmartSizeRun) {
+            // It is no longer our first run
+            rv = branch->SetBoolPref(DISK_CACHE_SMART_SIZE_FIRST_RUN_PREF, 
+                                     PR_FALSE);
+            if (NS_FAILED(rv)) 
+                NS_WARNING("Failed setting first_run pref in ReadPrefs.");
+        }
+    }
 #endif // !NECKO_DISK_CACHE
 
 #ifdef NECKO_OFFLINE_CACHE
     // read offline cache device prefs
     if (!mInPrivateBrowsing) {
         mOfflineCacheEnabled = PR_TRUE;  // presume offline cache is enabled
         (void) branch->GetBoolPref(OFFLINE_CACHE_ENABLE_PREF,
                                    &mOfflineCacheEnabled);
@@ -508,16 +756,23 @@ nsCacheProfilePrefObserver::ReadPrefs(ns
 
     mMemoryCacheCapacity = -1;
     (void) branch->GetIntPref(MEMORY_CACHE_CAPACITY_PREF,
                               &mMemoryCacheCapacity);
         
     return rv;
 }
 
+nsresult
+nsCacheService::DispatchToCacheIOThread(nsIRunnable* event)
+{
+    if (!gService->mCacheIOThread) return NS_ERROR_NOT_AVAILABLE;
+    return gService->mCacheIOThread->Dispatch(event, NS_DISPATCH_NORMAL);
+}
+
 
 PRBool
 nsCacheProfilePrefObserver::DiskCacheEnabled()
 {
     if ((mDiskCacheCapacity == 0) || (!mDiskCacheParentDirectory))  return PR_FALSE;
     return mDiskCacheEnabled;
 }
 
@@ -1713,17 +1968,18 @@ nsCacheService::SetDiskCacheCapacity(PRI
     nsCacheServiceAutoLock lock;
 
 #ifdef NECKO_DISK_CACHE
     if (gService->mDiskDevice) {
         gService->mDiskDevice->SetCapacity(capacity);
     }
 #endif // !NECKO_DISK_CACHE
     
-    gService->mEnableDiskDevice = gService->mObserver->DiskCacheEnabled();
+    if (gService->mObserver)
+        gService->mEnableDiskDevice = gService->mObserver->DiskCacheEnabled();
 }
 
 void
 nsCacheService::SetOfflineCacheEnabled(PRBool  enabled)
 {
     if (!gService)  return;
     nsCacheServiceAutoLock lock;
     gService->mEnableOfflineDevice = enabled;
--- a/netwerk/cache/nsCacheService.h
+++ b/netwerk/cache/nsCacheService.h
@@ -138,16 +138,19 @@ public:
     // This method may be called to release an object while the cache service
     // lock is being held.  If a non-null target is specified and the target
     // does not correspond to the current thread, then the release will be
     // proxied to the specified target.  Otherwise, the object will be added to
     // the list of objects to be released when the cache service is unlocked.
     static void      ReleaseObject_Locked(nsISupports *    object,
                                           nsIEventTarget * target = nsnull);
 
+    static nsresult DispatchToCacheIOThread(nsIRunnable* event);
+
+
     /**
      * Methods called by nsCacheProfilePrefObserver
      */
     static void      OnProfileShutdown(PRBool cleanse);
     static void      OnProfileChanged();
 
     static void      SetDiskCacheEnabled(PRBool  enabled);
     // Sets the disk cache capacity (in kilobytes)
@@ -162,16 +165,17 @@ public:
     static void      OnEnterExitPrivateBrowsing();
 
     nsresult         Init();
     void             Shutdown();
 private:
     friend class nsCacheServiceAutoLock;
     friend class nsOfflineCacheDevice;
     friend class nsProcessRequestEvent;
+    friend class nsSetSmartSizeEvent;
 
     /**
      * Internal Methods
      */
 
     static void      Lock();
     static void      Unlock();
 
--- a/netwerk/wifi/nsWifiScannerMac.cpp
+++ b/netwerk/wifi/nsWifiScannerMac.cpp
@@ -172,21 +172,21 @@ nsWifiMonitor::DoScanOld()
 
     CFArrayRef managed_access_points = NULL;
     CFArrayRef adhoc_access_points = NULL;
 
     if ((*WirelessScanSplit_function_)(wifi_context_,
                                       &managed_access_points,
                                       &adhoc_access_points,
                                       0) != noErr) {
-      continue;
+      return NS_ERROR_FAILURE;
     }
 
     if (managed_access_points == NULL) {
-      continue;
+      return NS_ERROR_FAILURE;
     }
 
     int accessPointsCount = CFArrayGetCount(managed_access_points);
 
     for (int i = 0; i < accessPointsCount; ++i) {
 
       nsWifiAccessPoint* ap = new nsWifiAccessPoint();
       if (!ap)
--- a/toolkit/components/alerts/src/Makefile.in
+++ b/toolkit/components/alerts/src/Makefile.in
@@ -50,11 +50,13 @@ LIBXUL_LIBRARY = 1
 
 
 CPPSRCS   = \
     nsAlertsService.cpp \
     $(NULL)
 
 LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/components/build/
 
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
 EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS)
--- a/toolkit/components/alerts/src/nsAlertsService.cpp
+++ b/toolkit/components/alerts/src/nsAlertsService.cpp
@@ -33,16 +33,22 @@
  * 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 ***** */
 
+#ifdef MOZ_IPC
+#include "mozilla/dom/ContentChild.h"
+#include "nsXULAppAPI.h"
+using mozilla::dom::ContentChild;
+#endif
+
 #include "nsAlertsService.h"
 
 #ifdef ANDROID
 #include "AndroidBridge.h"
 #else
 
 #include "nsISupportsArray.h"
 #include "nsXPCOM.h"
@@ -77,16 +83,33 @@ nsAlertsService::~nsAlertsService()
 {}
 
 NS_IMETHODIMP nsAlertsService::ShowAlertNotification(const nsAString & aImageUrl, const nsAString & aAlertTitle, 
                                                      const nsAString & aAlertText, PRBool aAlertTextClickable,
                                                      const nsAString & aAlertCookie,
                                                      nsIObserver * aAlertListener,
                                                      const nsAString & aAlertName)
 {
+#ifdef MOZ_IPC
+  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    ContentChild* cpc = ContentChild::GetSingleton();
+
+    if (aAlertListener)
+      cpc->AddRemoteAlertObserver(nsDependentString(aAlertCookie), aAlertListener);
+
+    cpc->SendShowAlertNotification(nsAutoString(aImageUrl),
+                                   nsAutoString(aAlertTitle),
+                                   nsAutoString(aAlertText),
+                                   aAlertTextClickable,
+                                   nsAutoString(aAlertCookie),
+                                   nsAutoString(aAlertName));
+    return NS_OK;
+  }
+#endif
+
 #ifdef ANDROID
   mozilla::AndroidBridge::Bridge()->ShowAlertNotification(aImageUrl, aAlertTitle, aAlertText, aAlertCookie,
                                                           aAlertListener, aAlertName);
   return NS_OK;
 #else
   // Check if there is an optional service that handles system-level notifications
   nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_SYSTEMALERTSERVICE_CONTRACTID));
   nsresult rv;
--- a/toolkit/components/console/hudservice/HUDService.jsm
+++ b/toolkit/components/console/hudservice/HUDService.jsm
@@ -2282,17 +2282,17 @@ HUD_SERVICE.prototype =
                 textNode.parentNode.removeChild(textNode);
 
                 data = [ httpActivity.url,
                          httpActivity.response.status ];
 
                 msgObject.messageNode.appendChild(
                   msgObject.textFactory(
                     msgObject.prefix +
-                    self.getFormatStr("networkUrlWithStatus", data)));
+                    self.getFormatStr("networkUrlWithStatus", data) + "\n"));
 
                 break;
 
               case activityDistributor.ACTIVITY_SUBTYPE_TRANSACTION_CLOSE:
                 msgObject = httpActivity.messageObject;
 
 
                 let timing = httpActivity.timing;
@@ -2307,17 +2307,18 @@ HUD_SERVICE.prototype =
 
                 data = [ httpActivity.url,
                          httpActivity.response.status,
                          requestDuration ];
 
                 msgObject.messageNode.appendChild(
                   msgObject.textFactory(
                     msgObject.prefix +
-                    self.getFormatStr("networkUrlWithStatusAndDuration", data)));
+                    self.getFormatStr("networkUrlWithStatusAndDuration",
+                                      data) + "\n"));
 
                 delete self.openRequests[item.id];
                 updatePanel = true;
                 break;
             }
 
             if (updatePanel) {
               httpActivity.panels.forEach(function(weakRef) {
@@ -3319,17 +3320,17 @@ function HUDConsole(aHeadsUpDisplay)
 
     let argumentArray = [];
     for (var i = 0; i < aArguments.length; i++) {
       argumentArray.push(aArguments[i]);
     }
 
     let message = argumentArray.join(' ');
     let timestampedMessage = ConsoleUtils.timestampString(ts) + ": " +
-      message;
+      message + "\n";
 
     messageNode.appendChild(chromeDocument.createTextNode(timestampedMessage));
 
     // need a constructor here to properly set all attrs
     let messageObject = {
       logLevel: aLevel,
       hudId: hud.hudId,
       message: message,
@@ -4017,17 +4018,17 @@ JSTerm.prototype = {
     node.setAttribute("crop", "end");
     node.onclick = function() {
       self.openPropertyPanel(aEvalString, aOutputObject, node);
     }
 
     // TODO: format the aOutputObject and don't just use the
     // aOuputObject.toString() function: [object object] -> Object {prop, ...}
     // See bug 586249.
-    let textNode = this.textFactory(aOutputObject);
+    let textNode = this.textFactory(aOutputObject + "\n");
     node.appendChild(textNode);
 
     lastGroupNode.appendChild(node);
     ConsoleUtils.scrollToVisible(node);
     pruneConsoleOutputIfNecessary(this.outputNode);
   },
 
   /**
@@ -4057,17 +4058,17 @@ JSTerm.prototype = {
 
     if (this.cssClassOverride) {
       let classes = this.cssClassOverride.split(" ");
       for (let i = 0; i < classes.length; i++) {
         node.classList.add(classes[i]);
       }
     }
 
-    var textNode = this.textFactory(aOutputMessage);
+    var textNode = this.textFactory(aOutputMessage + "\n");
     node.appendChild(textNode);
 
     lastGroupNode.appendChild(node);
     ConsoleUtils.scrollToVisible(node);
     pruneConsoleOutputIfNecessary(this.outputNode);
   },
 
   clearOutput: function JST_clearOutput()
@@ -4547,17 +4548,17 @@ LogMessage.prototype = {
    */
   createLogNode: function LM_createLogNode()
   {
     this.messageNode = this.xulElementFactory("label");
 
     var ts = ConsoleUtils.timestamp();
     this.timestampedMessage = ConsoleUtils.timestampString(ts) + ": " +
       this.message.message;
-    var messageTxtNode = this.textFactory(this.timestampedMessage);
+    var messageTxtNode = this.textFactory(this.timestampedMessage + "\n");
 
     this.messageNode.appendChild(messageTxtNode);
 
     var klass = "hud-msg-node hud-" + this.level;
     this.messageNode.setAttribute("class", klass);
 
     var self = this;
 
--- a/toolkit/components/console/hudservice/tests/browser/Makefile.in
+++ b/toolkit/components/console/hudservice/tests/browser/Makefile.in
@@ -44,23 +44,25 @@ relativesrcdir  = toolkit/components/con
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 
 _BROWSER_TEST_FILES = \
 	browser_HUDServiceTestsAll.js \
 	browser_warn_user_about_replaced_api.js \
 	browser_webconsole_bug_585237_line_limit.js \
+	browser_webconsole_bug_586142_insert_newlines.js \
 	browser_webconsole_bug_586388_select_all.js  \
 	browser_webconsole_bug_588967_input_expansion.js \
 	browser_webconsole_bug_580454_timestamp_l10n.js \
 	browser_webconsole_netlogging.js \
 	browser_webconsole_bug_593003_iframe_wrong_hud.js \
 	browser_webconsole_bug_581231_close_button.js \
 	browser_webconsole_consoleonpage.js \
+	browser_webconsole_bug_587617_output_copy.js \
 	$(NULL)
 
 _BROWSER_TEST_PAGES = \
 	test-console.html \
 	test-network.html \
 	test-network-request.html \
 	test-mutation.html \
 	testscript.js \
--- a/toolkit/components/console/hudservice/tests/browser/browser_HUDServiceTestsAll.js
+++ b/toolkit/components/console/hudservice/tests/browser/browser_HUDServiceTestsAll.js
@@ -440,27 +440,27 @@ function testNullUndefinedOutput()
 
   jsterm.clearOutput();
   jsterm.execute("null;");
 
   let group = outputNode.querySelector(".hud-group");
   is(group.childNodes.length, 2, "Three children in output");
   let outputChildren = group.childNodes;
 
-  is (outputChildren[1].childNodes[0].nodeValue, "null",
+  is (outputChildren[1].childNodes[0].nodeValue, "null\n",
       "'null' printed to output");
 
   jsterm.clearOutput();
   jsterm.execute("undefined;");
 
   group = outputNode.querySelector(".hud-group");
   is(group.childNodes.length, 2, "Three children in output");
   outputChildren = group.childNodes;
 
-  is (outputChildren[1].childNodes[0].nodeValue, "undefined",
+  is (outputChildren[1].childNodes[0].nodeValue, "undefined\n",
       "'undefined' printed to output");
 }
 
 function testJSInputAndOutputStyling() {
   let jsterm = HUDService.hudWeakReferences[hudId].get().jsterm;
 
   jsterm.clearOutput();
   jsterm.execute("2 + 2");
@@ -1031,49 +1031,50 @@ function testJSTermHelper()
   content.location.href = TEST_URI;
 
   let HUD = HUDService.hudWeakReferences[hudId].get();
   let jsterm = HUD.jsterm;
 
   jsterm.clearOutput();
   jsterm.execute("'id=' + $('header').getAttribute('id')");
   let group = jsterm.outputNode.querySelector(".hud-group");
-  is(group.childNodes[1].textContent, "id=header", "$() worked");
+  is(group.childNodes[1].textContent, "id=header\n", "$() worked");
 
   jsterm.clearOutput();
   jsterm.execute("headerQuery = $$('h1')");
   jsterm.execute("'length=' + headerQuery.length");
   let group = jsterm.outputNode.querySelector(".hud-group");
-  is(group.childNodes[3].textContent, "length=1", "$$() worked");
+  is(group.childNodes[3].textContent, "length=1\n", "$$() worked");
 
   jsterm.clearOutput();
   jsterm.execute("xpathQuery = $x('.//*', document.body);");
   jsterm.execute("'headerFound='  + (xpathQuery[0] == headerQuery[0])");
   let group = jsterm.outputNode.querySelector(".hud-group");
-  is(group.childNodes[3].textContent, "headerFound=true", "$x() worked");
+  is(group.childNodes[3].textContent, "headerFound=true\n", "$x() worked");
 
   // no jsterm.clearOutput() here as we clear the output using the clear() fn.
   jsterm.execute("clear()");
   let group = jsterm.outputNode.querySelector(".hud-group");
-  is(group.childNodes[0].textContent, "undefined", "clear() worked");
+  is(group.childNodes[0].textContent, "undefined\n", "clear() worked");
 
   jsterm.clearOutput();
   jsterm.execute("'keysResult=' + (keys({b:1})[0] == 'b')");
   let group = jsterm.outputNode.querySelector(".hud-group");
-  is(group.childNodes[1].textContent, "keysResult=true", "keys() worked");
+  is(group.childNodes[1].textContent, "keysResult=true\n", "keys() worked");
 
   jsterm.clearOutput();
   jsterm.execute("'valuesResult=' + (values({b:1})[0] == 1)");
   let group = jsterm.outputNode.querySelector(".hud-group");
-  is(group.childNodes[1].textContent, "valuesResult=true", "values() worked");
+  is(group.childNodes[1].textContent, "valuesResult=true\n",
+     "values() worked");
 
   jsterm.clearOutput();
   jsterm.execute("pprint({b:2, a:1})");
   let group = jsterm.outputNode.querySelector(".hud-group");
-  is(group.childNodes[1].textContent, "  a: 1\n  b: 2", "pprint() worked");
+  is(group.childNodes[1].textContent, "  a: 1\n  b: 2\n", "pprint() worked");
 }
 
 function testPropertyPanel()
 {
   var HUD = HUDService.hudWeakReferences[hudId].get();
   var jsterm = HUD.jsterm;
 
   let propPanel = jsterm.openPropertyPanel("Test", [
new file mode 100644
--- /dev/null
+++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_586142_insert_newlines.js
@@ -0,0 +1,72 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ *
+ * Contributor(s):
+ *  Patrick Walton <pcwalton@mozilla.com>
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Tests that newlines are present in the output of the console, so that
+// copying works properly.
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const TEST_URI = "http://example.com/";
+
+XPCOMUtils.defineLazyGetter(this, "HUDService", function () {
+  Cu.import("resource://gre/modules/HUDService.jsm");
+  return HUDService;
+});
+
+function test()
+{
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab(TEST_URI);
+  gBrowser.selectedBrowser.addEventListener("DOMContentLoaded", onLoad, false);
+}
+
+function onLoad() {
+  gBrowser.selectedBrowser.removeEventListener("DOMContentLoaded", onLoad,
+                                               false);
+  executeSoon(testNewlines);
+}
+
+function testNewlines() {
+  HUDService.activateHUDForContext(gBrowser.selectedTab);
+  let hudId = HUDService.displaysIndex()[0];
+  ok(hudId != null, "we have the HUD ID");
+
+  HUDService.clearDisplay(hudId);
+
+  let contentWindow = gBrowser.selectedTab.linkedBrowser.contentWindow;
+  let console = contentWindow.wrappedJSObject.console;
+  ok(console != null, "we have the console object");
+
+  for (let i = 0; i < 20; i++) {
+    console.log("Hello world!");
+  }
+
+  let hudNode = HUDService.getOutputNodeById(hudId);
+  let outputNode = hudNode.querySelector(".hud-output-node");
+  ok(outputNode != null, "we have the output node");
+
+  let labels = outputNode.querySelectorAll("label");
+  is(labels.length, 20, "we found 20 labels in the output node");
+
+  for (let i = 0; i < labels.length; i++) {
+    let value = labels[i].textContent;
+    is(value[value.length - 1], "\n", "the value of label " + i + " ends " +
+       "with a newline");
+  }
+
+  HUDService.deactivateHUDForContext(gBrowser.selectedTab);
+  gBrowser.removeCurrentTab();
+  finish();
+}
+
new file mode 100644
--- /dev/null
+++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_587617_output_copy.js
@@ -0,0 +1,101 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ *
+ * Contributor(s):
+ *  Mihai Șucan <mihai.sucan@gmail.com>
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/HUDService.jsm");
+
+const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
+
+function tabLoaded() {
+  gBrowser.selectedBrowser.removeEventListener("load", tabLoaded, true);
+
+  waitForFocus(function () {
+    HUDService.activateHUDForContext(gBrowser.selectedTab);
+
+    // See bugs 574036, 586386 and 587617.
+
+    let HUD = HUDService.getDisplayByURISpec(content.location.href);
+    let filterBox = HUD.querySelector(".hud-filter-box");
+    let outputNode = HUD.querySelector(".hud-output-node");
+    let selection = getSelection();
+    let jstermInput = HUD.querySelector(".jsterm-input-node");
+    let console = content.wrappedJSObject.console;
+    let contentSelection = content.getSelection();
+
+    let make_selection = function () {
+      let controller = top.document.commandDispatcher.
+        getControllerForCommand("cmd_copy");
+      is(controller.isCommandEnabled("cmd_copy"), false, "cmd_copy is disabled");
+
+      console.log("Hello world!");
+
+      let range = document.createRange();
+      let selectedNode = outputNode.querySelector(".hud-group > label:last-child");
+      range.selectNode(selectedNode);
+      selection.addRange(range);
+
+      selectedNode.focus();
+
+      goUpdateCommand("cmd_copy");
+
+      controller = top.document.commandDispatcher.
+        getControllerForCommand("cmd_copy");
+      is(controller.isCommandEnabled("cmd_copy"), true, "cmd_copy is enabled");
+
+      waitForClipboard(selectedNode.textContent, clipboard_setup,
+        clipboard_copy_done, clipboard_copy_done);
+    };
+
+    let clipboard_setup = function () {
+      goDoCommand("cmd_copy");
+    };
+
+    let clipboard_copy_done = function () {
+      selection.removeAllRanges();
+      testEnd();
+    };
+
+    // Check if we first need to clear any existing selections.
+    if (selection.rangeCount > 0 || contentSelection.rangeCount > 0 ||
+        jstermInput.selectionStart != jstermInput.selectionEnd) {
+      if (jstermInput.selectionStart != jstermInput.selectionEnd) {
+        jstermInput.selectionStart = jstermInput.selectionEnd = 0;
+      }
+
+      if (selection.rangeCount > 0) {
+        selection.removeAllRanges();
+      }
+
+      if (contentSelection.rangeCount > 0) {
+        contentSelection.removeAllRanges();
+      }
+
+      goUpdateCommand("cmd_copy");
+      make_selection();
+    }
+    else {
+      make_selection();
+    }
+  });
+}
+
+function testEnd() {
+  HUDService.deactivateHUDForContext(gBrowser.selectedTab);
+  finish();
+}
+
+function test() {
+  waitForExplicitFinish();
+
+  gBrowser.selectedBrowser.addEventListener("load", tabLoaded, true);
+
+  content.location = TEST_URI;
+}
+
--- a/toolkit/content/tests/widgets/Makefile.in
+++ b/toolkit/content/tests/widgets/Makefile.in
@@ -52,16 +52,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug460942.xul \
 		test_bug509732.xul \
 		test_bug557987.xul\
 		test_bug562554.xul \
 		test_button.xul \
 		test_closemenu_attribute.xul \
 		test_colorpicker_popup.xul \
 		test_deck.xul \
+		test_menulist.xul \
 		test_menuitem_blink.xul \
 		test_menulist_keynav.xul \
 		test_menulist_null_value.xul \
 		test_popup_coords.xul \
 		test_popup_recreate.xul \
 		test_popup_button.xul \
 		test_menuchecks.xul \
 		test_popup_attribute.xul \
new file mode 100644
--- /dev/null
+++ b/toolkit/content/tests/widgets/test_menulist.xul
@@ -0,0 +1,241 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
+
+<window title="Menulist Tests"
+        onload="setTimeout(testtag_menulists, 0);"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>      
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>      
+  <script type="application/javascript" src="xul_selectcontrol.js"></script>      
+
+<vbox id="scroller" style="overflow: auto" height="60">
+  <menulist id="menulist" onpopupshown="test_menulist_open(this, this.parentNode)"
+            onpopuphidden="$('menulist-in-listbox').open = true;">
+    <menupopup id="menulist-popup"/>
+  </menulist>
+  <button label="Two"/>
+  <button label="Three"/>
+</vbox>
+<listbox id="scroller-in-listbox" style="overflow: auto" height="60">
+  <listitem allowevents="true">
+    <menulist id="menulist-in-listbox" onpopupshown="test_menulist_open(this, this.parentNode.parentNode)"
+              onpopuphidden="SimpleTest.executeSoon(checkScrollAndFinish)">
+      <menupopup id="menulist-in-listbox-popup">
+        <menuitem label="One" value="one"/>
+        <menuitem label="Two" value="two"/>
+      </menupopup>
+    </menulist>
+  </listitem>
+  <listitem label="Two"/>
+  <listitem label="Three"/>
+  <listitem label="Four"/>
+  <listitem label="Five"/>
+  <listitem label="Six"/>
+</listbox>
+
+<hbox>
+  <menulist id="menulist-size">
+    <menupopup>
+      <menuitem label="Menuitem Label" width="200"/>
+    </menupopup>
+  </menulist>
+</hbox>
+
+<menulist id="menulist-editable" editable="true">
+  <menupopup id="menulist-popup-editable"/>
+</menulist>
+
+<menulist id="menulist-initwithvalue" value="two">
+  <menupopup>
+    <menuitem label="One" value="one"/>
+    <menuitem label="Two" value="two"/>
+    <menuitem label="Three" value="three"/>
+  </menupopup>
+</menulist>
+<menulist id="menulist-initwithselected" value="two">
+  <menupopup>
+    <menuitem label="One" value="one"/>
+    <menuitem label="Two" value="two"/>
+    <menuitem label="Three" value="three" selected="true"/>
+  </menupopup>
+</menulist>
+<menulist id="menulist-editable-initwithvalue" editable="true" value="Two">
+  <menupopup>
+    <menuitem label="One" value="one"/>
+    <menuitem label="Two" value="two"/>
+    <menuitem label="Three" value="three"/>
+  </menupopup>
+</menulist>
+<menulist id="menulist-editable-initwithselected" editable="true" value="two">
+  <menupopup>
+    <menuitem label="One" value="one"/>
+    <menuitem label="Two" value="two"/>
+    <menuitem label="Three" value="three" selected="true"/>
+  </menupopup>
+</menulist>
+
+<script class="testbody" type="application/javascript">
+<![CDATA[
+
+SimpleTest.waitForExplicitFinish();
+
+function testtag_menulists()
+{
+  testtag_menulist_UI_start($("menulist"), false);
+  testtag_menulist_UI_start($("menulist-editable"), true);
+
+  // bug 566154, the menulist width should account for vertical scrollbar
+  ok(document.getElementById("menulist-size").getBoundingClientRect().width >= 210,
+     "menulist popup width includes scrollbar width");
+
+  $("menulist").open = true;
+}
+
+function testtag_menulist_UI_start(element, editable)
+{
+  var testprefix = editable ? "editable" : "";
+
+  // check the menupopup property
+  var popup = element.menupopup;
+  ok(popup && popup.localName == "menupopup" &&
+              popup.parentNode == element, testprefix + " menupopup");
+
+  // test the interfaces that menulist implements
+  test_nsIDOMXULMenuListElement(element, testprefix, editable);
+
+  element.value = "";
+
+  test_nsIDOMXULSelectControlElement(element, "menuitem",
+                                     editable ? "editable" : null);
+}
+
+function test_nsIDOMXULMenuListElement(element, testprefix, editable)
+{
+  is(element.open, false, testprefix + " open");
+  is(element.editable, editable, testprefix + " editable");
+
+  if (editable) {
+    var inputField = element.inputField;
+    is(inputField &&
+                  inputField instanceof Components.interfaces.nsIDOMHTMLInputElement,
+                  true, testprefix + " inputField");
+
+    // check if the select method works
+    inputField.select();
+    is(inputField.selectionStart, 0, testprefix + " empty select selectionStart");
+    is(inputField.selectionEnd, 0, testprefix + " empty select selectionEnd");
+
+    element.value = "Some Text";
+    inputField.select();
+    is(inputField.selectionStart, 0, testprefix + " empty select selectionStart");
+    is(inputField.selectionEnd, 9, testprefix + " empty select selectionEnd");
+  }
+  else {
+    is(element.inputField, null , testprefix + " inputField");
+  }
+
+  element.appendItem("Item One", "one");
+  var seconditem = element.appendItem("Item Two", "two");
+  var thirditem = element.appendItem("Item Three", "three");
+  element.appendItem("Item Four", "four");
+
+  seconditem.image = "happy.png";
+  seconditem.setAttribute("description", "This is the second description");
+  thirditem.image = "happy.png";
+  thirditem.setAttribute("description", "This is the third description");
+
+  // check the image and description properties
+  // editable menulists don't use the image or description properties currently
+  if (editable) {
+    element.selectedIndex = 1;
+    is(element.image, "", testprefix + " image set to selected");
+    is(element.description, "", testprefix + " description set to selected");
+  }
+  else {
+    element.selectedIndex = 1;
+    is(element.image, "happy.png", testprefix + " image set to selected");
+    is(element.description, "This is the second description", testprefix + " description set to selected");
+    element.selectedIndex = -1;
+    is(element.image, "", testprefix + " image set when none selected");
+    is(element.description, "", testprefix + " description set when none selected");
+    element.selectedIndex = 2;
+    is(element.image, "happy.png", testprefix + " image set to selected again");
+    is(element.description, "This is the third description", testprefix + " description set to selected again");
+
+    // check that changing the properties of the selected item changes the menulist's properties
+    thirditem.label = "Item Number Three";
+    is(element.label, "Item Number Three", testprefix + " label modified");
+    thirditem.value = "item-three";
+    is(element.value, "item-three", testprefix + " value modified");
+    thirditem.image = "smile.png";
+    is(element.image, "smile.png", testprefix + " image modified");
+    thirditem.setAttribute("description", "Changed description");
+    is(element.description, "Changed description", testprefix + " description modified");
+    seconditem.label = "Changed Label 2";
+    is(element.label, "Item Number Three", testprefix + " label of another item modified");
+
+    element.selectedIndex = 0;
+    is(element.image, "", testprefix + " image set to selected with no image");
+    is(element.description, "", testprefix + " description set to selected with no description");
+  }
+
+  // check the removeAllItems method
+  element.appendItem("An Item", "anitem");
+  element.appendItem("Another Item", "anotheritem");
+  element.removeAllItems();
+  is(element.itemCount, 0, testprefix + " removeAllItems");
+}
+
+function test_menulist_open(element, scroller)
+{
+  element.appendItem("Scroll Item 1", "scrollitem1");
+  element.appendItem("Scroll Item 2", "scrollitem2");
+  element.focus();
+
+/*
+  // bug 530504, mousewheel while menulist is open should not scroll menulist
+  // items or parent
+  var scrolled = false;
+  var mouseScrolled = function (event) { scrolled = true; }
+  window.addEventListener("DOMMouseScroll", mouseScrolled, false);
+  synthesizeMouseScroll(element, 2, 2, { delta: 10 });
+  is(scrolled, true, "mousescroll " + element.id);
+  is(scroller.scrollTop, 0, "scroll position on mousescroll " + element.id);
+  window.removeEventListener("DOMMouseScroll", mouseScrolled, false);
+*/
+
+  // bug 543065, hovering the mouse over an item should highlight it and not
+  // scroll the parent
+  var item = element.menupopup.childNodes[1];
+
+  synthesizeMouse(element.menupopup.childNodes[1], 2, 2, { type: "mousemove" });
+  synthesizeMouse(element.menupopup.childNodes[1], 6, 6, { type: "mousemove" });
+  is(element.menuBoxObject.activeChild, item, "activeChild after menu highlight " + element.id);
+  is(scroller.scrollTop, 0, "scroll position after menu highlight " + element.id);
+
+  element.open = false;
+}
+
+function checkScrollAndFinish()
+{
+  is($("scroller").scrollTop, 0, "mousewheel on menulist does not scroll vbox parent");
+  is($("scroller-in-listbox").scrollTop, 0, "mousewheel on menulist does not scroll listbox parent");
+  SimpleTest.finish();
+}
+
+]]>
+</script>
+
+<body xmlns="http://www.w3.org/1999/xhtml">
+<p id="display">
+</p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+</pre>
+</body>
+
+</window>
--- a/toolkit/content/tests/widgets/xul_selectcontrol.js
+++ b/toolkit/content/tests/widgets/xul_selectcontrol.js
@@ -1,26 +1,28 @@
 // This script is used to test elements that implement
 // nsIDOMXULSelectControlElement. This currently is the following elements:
 //   listbox, menulist, radiogroup, richlistbox, tabs
 //
 // flag behaviours that differ for certain elements
 //   allow-other-value - alternate values for the value property may be used
 //                       besides those in the list
+//   other-value-clears-selection - alternative values for the value property
+//                                  clears the selected item
 //   selection-required - an item must be selected in the list, unless there
 //                        aren't any to select
 //   activate-disabled-menuitem - disabled menuitems can be highlighted
 //   select-keynav-wraps - key navigation over a selectable list wraps
 //   select-extended-keynav - home, end, page up and page down keys work to
 //                            navigate over a selectable list
 //   keynav-leftright - key navigation is left/right rather than up/down
 // The win:, mac: and gtk: or other prefixes may be used for platform specific behaviour
 var behaviours = {
   menu: "win:activate-disabled-menuitem activate-disabled-menuitem-mousemove select-keynav-wraps select-extended-keynav",
-  menulist: "allow-other-value",
+  menulist: "allow-other-value other-value-clears-selection",
   listbox: "select-extended-keynav",
   richlistbox: "select-extended-keynav",
   radiogroup: "select-keynav-wraps dont-select-disabled allow-other-value",
   tabs: "select-extended-keynav mac:select-keynav-wraps allow-other-value selection-required keynav-leftright"
 };
 
 function behaviourContains(tag, behaviour)
 {
@@ -97,27 +99,32 @@ function test_nsIDOMXULSelectControlElem
 
   // 'getItemAtIndex' - check if getItemAtIndex returns the right item
   is(element.getItemAtIndex(0), firstitem, testid + "getItemAtIndex - index 0 is first item");
   is(element.getItemAtIndex(1), seconditem, testid + "getItemAtIndex - index 0 is second item");
   is(element.getItemAtIndex(-1), null, testid + "getItemAtIndex - index -1 is null");
   is(element.getItemAtIndex(2), null, testid + "getItemAtIndex - index 2 is null");
 
   // check if setting the value changes the selection
-  element.value = "first";
-  test_nsIDOMXULSelectControlElement_States(element, testid + "set value 1", 2, firstitem, 0, "first");
-  element.value = "second";
-  test_nsIDOMXULSelectControlElement_States(element, testid + "set value 2", 2, seconditem, 1, "second");
+  element.value = firstvalue;
+  test_nsIDOMXULSelectControlElement_States(element, testid + "set value 1", 2, firstitem, 0, firstvalue);
+  element.value = secondvalue;
+  test_nsIDOMXULSelectControlElement_States(element, testid + "set value 2", 2, seconditem, 1, secondvalue);
   // setting the value attribute to one not in the list doesn't change the selection.
   // The value is only changed for elements which support having a value other than the
   // selection.
   element.value = "other";
   var allowOtherValue = behaviourContains(element.localName, "allow-other-value");
-  test_nsIDOMXULSelectControlElement_States(element, testid + "set value other", 2, seconditem, 1,
-                                            allowOtherValue ? "other" : "second");
+  var otherValueClearsSelection = behaviourContains(element.localName, "other-value-clears-selection");
+  test_nsIDOMXULSelectControlElement_States(element, testid + "set value other", 2,
+                                            otherValueClearsSelection ? null : seconditem,
+                                            otherValueClearsSelection ? -1 : 1,
+                                            allowOtherValue ? "other" : secondvalue);
+  if (allowOtherValue)
+    element.value = "";
 
   // 'removeItemAt' - check if removeItemAt removes the right item
   if (selectionRequired)
     element.value = secondvalue;
   else
     element.selectedIndex = -1;
 
   var removeditem = element.removeItemAt(0);
@@ -165,17 +172,18 @@ function test_nsIDOMXULSelectControlElem
 
   // 'removeItemAt 6' - check that removeItemAt doesn't fail when removing invalid items
   is(element.removeItemAt(1), null, testid + "removeItemAt 6 return value");
   is("item removed", "item removed", testid + "removeItemAt 6");
   if (isnotradio)
     test_nsIDOMXULSelectControlElement_States(element, testid + "removeItemAt 6", 1, fourthitem, 0, fourthvalue);
 
   // 'insertItemAt' - check if insertItemAt inserts items at the right locations
-  var fifthitem = test_nsIDOMXULSelectControlElement_insertItemAt(element, 0, 0, testid, 5);
+  element.selectedIndex = 0;
+  test_nsIDOMXULSelectControlElement_insertItemAt(element, 0, 0, testid, 5);
   test_nsIDOMXULSelectControlElement_insertItemAt(element, 2, 2, testid, 6);
   test_nsIDOMXULSelectControlElement_insertItemAt(element, -1, 3, testid, 7);
   test_nsIDOMXULSelectControlElement_insertItemAt(element, 6, 4, testid, 8);
 
   element.selectedIndex = 0;
   fourthitem.disabled = true;
   element.selectedIndex = 1;
   test_nsIDOMXULSelectControlElement_States(element, testid + "selectedIndex disabled", 5, fourthitem, 1, fourthvalue);
@@ -189,29 +197,34 @@ function test_nsIDOMXULSelectControlElem
     element.removeItemAt(0);
   if (isnotradio)
     test_nsIDOMXULSelectControlElement_States(element, testid + "remove all", 0, null, -1,
                                               allowOtherValue ? "number8" : "");
 }
 
 function test_nsIDOMXULSelectControlElement_init(element, testprefix)
 {
+  // editable menulists use the label as the value
+  var isEditable = (element.localName == "menulist" && element.editable);
+
   var id = element.id;
   element = document.getElementById(id + "-initwithvalue");
   if (element) {
     var seconditem = element.getItemAtIndex(1);
     test_nsIDOMXULSelectControlElement_States(element, testprefix + " value initialization",
-                                              3, seconditem, 1, seconditem.value);
+                                              3, seconditem, 1,
+                                              isEditable ? seconditem.label : seconditem.value);
   }
 
   element = document.getElementById(id + "-initwithselected");
   if (element) {
     var thirditem = element.getItemAtIndex(2);
     test_nsIDOMXULSelectControlElement_States(element, testprefix + " selected initialization",
-                                              3, thirditem, 2, thirditem.value);
+                                              3, thirditem, 2,
+                                              isEditable ? thirditem.label : thirditem.value);
   }
 }
 
 function test_nsIDOMXULSelectControlElement_States(element, testid,
                                                    expectedcount, expecteditem,
                                                    expectedindex, expectedvalue)
 {
   // need an itemCount property here
@@ -235,17 +248,17 @@ function test_nsIDOMXULSelectControlElem
 
   var newitem = element.insertItemAt(index, "Item " + number, "number" + number);
   is(element.getIndexOfItem(newitem), expectedindex,
                 testid + "insertItemAt " + expectedindex + " - get inserted item");
   expectedCount++;
   if (expectedSelIndex >= expectedindex)
     expectedSelIndex++;
 
-  test_nsIDOMXULSelectControlElement_States(element, testid + "insertItemAt " + expectedindex,
+  test_nsIDOMXULSelectControlElement_States(element, testid + "insertItemAt " + index,
                                            expectedCount, expectedSelItem,
                                            expectedSelIndex, expectedSelValue);
   return newitem;
 }
 
 /** test_nsIDOMXULSelectControlElement_UI
   *
   * Test the UI aspects of an element which implements nsIDOMXULSelectControlElement
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -313,17 +313,17 @@
           }
           return this._fastFind;
         ]]>
         </getter>
       </property>
       
       <property name="webProgress"
                 readonly="true"
-                onget="return this.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.webProgress;"/>
+                onget="return this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);"/>
 
       <field name="_contentWindow">null</field>
 
       <property name="contentWindow"
                 readonly="true"
                 onget="return this._contentWindow || (this._contentWindow = this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindow));"/>
 
       <property name="sessionHistory"
--- a/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.dtd
+++ b/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.dtd
@@ -2,18 +2,18 @@
 <!ENTITY search.placeholder                   "Search all add-ons">
 <!ENTITY loading.label                        "Loading…">
 <!ENTITY listEmpty.installed.label            "You don't have any add-ons of this type installed">
 <!ENTITY listEmpty.availableUpdates.label     "No updates found">
 <!ENTITY listEmpty.recentUpdates.label        "You haven't recently updated any add-ons">
 <!ENTITY listEmpty.findUpdates.label          "Check For Updates">
 <!ENTITY listEmpty.search.label               "Could not find any matching add-ons">
 <!ENTITY listEmpty.button.label               "Learn more about add-ons">
-<!ENTITY installFromFile.label                "Install From File…">
-<!ENTITY installFromFile.accesskey            "I">
+<!ENTITY installAddonFromFile.label           "Install Add-on From File…">
+<!ENTITY installAddonFromFile.accesskey       "I">
 
 <!ENTITY cmd.back.tooltip                     "Go back one page">
 <!ENTITY cmd.forward.tooltip                  "Go forward one page">
 
 <!-- global warnings -->
 <!ENTITY warning.safemode.label                    "All add-ons have been disabled by safe mode.">
 <!ENTITY warning.checkcompatibility.label          "Add-on compatibility checking is disabled. You may have incompatible add-ons.">
 <!ENTITY warning.checkcompatibility.enable.label   "Enable">
@@ -35,18 +35,16 @@
 <!ENTITY view.utilites.preferences.tooltip    "Options for all add-ons">
 <!ENTITY view.utilites.preferencesUnix.tooltip "Preferences for all add-ons">
 
 <!-- addon updates -->
 <!ENTITY updates.updateAddonsNow.label        "Update Add-ons Now">
 <!ENTITY updates.updateAddonsNow.accesskey    "U">
 <!ENTITY updates.viewUpdates.label            "View Recent Updates">
 <!ENTITY updates.viewUpdates.accesskey        "V">
-<!ENTITY updates.backgroudUpdateCheck.label   "Check for Updates Automatically">
-<!ENTITY updates.backgroudUpdateCheck.accesskey "C">
 <!ENTITY updates.updateAddonsAutomatically.label     "Update Add-ons Automatically">
 <!ENTITY updates.updateAddonsAutomatically.accesskey "A">
 <!ENTITY updates.resetUpdatesToAutomatic.label       "Reset All Add-ons to Update Automatically">
 <!ENTITY updates.resetUpdatesToAutomatic.accesskey   "R">
 <!ENTITY updates.resetUpdatesToManual.label          "Reset All Add-ons to Update Manually">
 <!ENTITY updates.resetUpdatesToManual.accesskey      "R">
 <!ENTITY updates.updating.label               "Updating add-ons">
 <!ENTITY updates.installed.label              "Your add-ons have been updated.">
--- a/toolkit/mozapps/extensions/AddonRepository.jsm
+++ b/toolkit/mozapps/extensions/AddonRepository.jsm
@@ -86,34 +86,58 @@ const PROP_SINGLE = ["id", "type", "name
                      "updateDate"];
 const PROP_MULTI = ["developers", "screenshots"]
 
 // A map between XML keys to AddonSearchResult keys for string values
 // that require no extra parsing from XML
 const STRING_KEY_MAP = {
   name:               "name",
   version:            "version",
+  icon:               "iconURL",
+  homepage:           "homepageURL",
+  support:            "supportURL"
+};
+
+// A map between XML keys to AddonSearchResult keys for string values
+// that require parsing from HTML
+const HTML_KEY_MAP = {
   summary:            "description",
   description:        "fullDescription",
   developer_comments: "developerComments",
-  eula:               "eula",
-  icon:               "iconURL",
-  homepage:           "homepageURL",
-  support:            "supportURL"
+  eula:               "eula"
 };
 
 // A map between XML keys to AddonSearchResult keys for integer values
 // that require no extra parsing from XML
 const INTEGER_KEY_MAP = {
   total_downloads:  "totalDownloads",
   weekly_downloads: "weeklyDownloads",
   daily_users:      "dailyUsers"
 };
 
 
+function convertHTMLToPlainText(html) {
+  if (!html)
+    return html;
+  var converter = Cc["@mozilla.org/widget/htmlformatconverter;1"].
+                  createInstance(Ci.nsIFormatConverter);
+
+  var input = Cc["@mozilla.org/supports-string;1"].
+              createInstance(Ci.nsISupportsString);
+  input.data = html.replace("\n", "<br>", "g");
+
+  var output = {};
+  converter.convert("text/html", input, input.data.length, "text/unicode",
+                    output, {});
+
+  if (output.value instanceof Ci.nsISupportsString)
+    return output.value.data.replace("\r\n", "\n", "g");
+  return html;
+}
+
 function AddonSearchResult(aId) {
   this.id = aId;
 }
 
 AddonSearchResult.prototype = {
   /**
    * The ID of the add-on
    */
@@ -782,16 +806,22 @@ var AddonRepository = {
       let localName = node.localName;
 
       // Handle case where the wanted string value is located in text content
       if (localName in STRING_KEY_MAP) {
         addon[STRING_KEY_MAP[localName]] = this._getTextContent(node);
         continue;
       }
 
+      // Handle case where the wanted string value is html located in text content
+      if (localName in HTML_KEY_MAP) {
+        addon[HTML_KEY_MAP[localName]] = convertHTMLToPlainText(this._getTextContent(node));
+        continue;
+      }
+
       // Handle case where the wanted integer value is located in text content
       if (localName in INTEGER_KEY_MAP) {
         let value = parseInt(this._getTextContent(node));
         if (value >= 0)
           addon[INTEGER_KEY_MAP[localName]] = value;
         continue;
       }
 
--- a/toolkit/mozapps/extensions/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/XPIProvider.jsm
@@ -4080,16 +4080,21 @@ function AddonInstall(aCallback, aInstal
   this.installLocation = aInstallLocation;
   this.sourceURI = aUrl;
   this.releaseNotesURI = aReleaseNotesURI;
   this.hash = aHash;
   this.loadGroup = aLoadGroup;
   this.listeners = [];
   this.existingAddon = aExistingAddon;
   this.error = 0;
+  if (aLoadGroup)
+    this.window = aLoadGroup.notificationCallbacks
+                            .getInterface(Ci.nsIDOMWindow);
+  else
+    this.window = null;
 
   if (aUrl instanceof Ci.nsIFileURL) {
     this.file = aUrl.file.QueryInterface(Ci.nsILocalFile);
 
     if (!this.file.exists()) {
       WARN("XPI file " + this.file.path + " does not exist");
       this.state = AddonManager.STATE_DOWNLOAD_FAILED;
       this.error = AddonManager.ERROR_NETWORK_FAILURE;
@@ -4963,17 +4968,17 @@ AddonInstall.prototype = {
       this.removeTemporaryFile();
     }
   },
 
   getInterface: function(iid) {
     if (iid.equals(Ci.nsIAuthPrompt2)) {
       var factory = Cc["@mozilla.org/prompter;1"].
                     getService(Ci.nsIPromptFactory);
-      return factory.getPrompt(null, Ci.nsIAuthPrompt);
+      return factory.getPrompt(this.window, Ci.nsIAuthPrompt);
     }
     else if (iid.equals(Ci.nsIChannelEventSink)) {
       return this;
     }
 
     return this.badCertHandler.getInterface(iid);
   }
 }
--- a/toolkit/mozapps/extensions/addonManager.js
+++ b/toolkit/mozapps/extensions/addonManager.js
@@ -216,25 +216,23 @@ amManager.prototype = {
               var returnMessageManager = flo.frameLoader.messageManager;
               returnMessageManager.sendAsyncMessage(MSG_INSTALL_CALLBACK,
                 { installerId: payload.installerId,
                   callbackId: payload.callbackId, url: url, status: status }
               );
             },
           };
         }
-        var window;
+        var window = null;
         try {
           // Normal approach for single-process mode
-          window = aMessage.target.docShell
-                           .QueryInterface(Ci.nsIInterfaceRequestor)
-                           .getInterface(Ci.nsIDOMWindow).content;
+          window = aMessage.target.contentWindow;
         } catch (e) {
-          // Fallback for multiprocess (e10s) mode. Appears to work but has
-          // not had a full suite of automated tests run on it.
+          // Fallback for multiprocess (e10s) mode. Should reimplement this
+          // properly with Window IDs when possible, see bug 596109.
           window = aMessage.target.ownerDocument.defaultView;
         }
         return this.installAddonsFromWebpage(payload.mimetype,
           window, referer, payload.uris, payload.hashes, payload.names,
           payload.icons, callback, payload.uris.length);
     }
   },
 
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -587,24 +587,16 @@ var gViewController = {
 
     cmd_goToAvailableUpdates: {
       isEnabled: function() true,
       doCommand: function() {
         gViewController.loadView("addons://updates/available");
       }
     },
 
-    cmd_toggleBackgroundUpdateCheck: {
-      isEnabled: function() true,
-      doCommand: function() {
-        var enabled = !Services.prefs.getBoolPref(PREF_BACKGROUND_UPDATE);
-        Services.prefs.setBoolPref(PREF_BACKGROUND_UPDATE, enabled);
-      }
-    },
-
     cmd_showItemDetails: {
       isEnabled: function(aAddon) {
         return !!aAddon;
       },
       doCommand: function(aAddon) {
         gViewController.loadView("addons://detail/" +
                                  encodeURIComponent(aAddon.id));
       }
@@ -2115,39 +2107,36 @@ var gDetailView = {
 
 var gUpdatesView = {
   node: null,
   _listBox: null,
   _emptyNotice: null,
   _sorters: null,
   _updateSelected: null,
   _updatePrefs: null,
-  _backgroundUpdateCheck: null,
   _categoryItem: null,
   _numManualUpdaters: 0,
 
   initialize: function() {
     this.node = document.getElementById("updates-view");
     this._listBox = document.getElementById("updates-list");
     this._emptyNotice = document.getElementById("updates-list-empty");
     this._sorters = document.getElementById("updates-sorters");
     this._sorters.handler = this;
 
-    this._backgroundUpdateCheck = document.getElementById("utils-backgroudUpdateCheck");
     this._categoryItem = gCategories.get("addons://updates/available");
 
     this._updateSelected = document.getElementById("update-selected");
     this._updateSelected.addEventListener("command", function() {
       gUpdatesView.installSelected();
     }, false);
 
     this._updatePrefs = Services.prefs.getBranch("extensions.update.");
     this._updatePrefs.QueryInterface(Ci.nsIPrefBranch2);
     this._updatePrefs.addObserver("", this, false);
-    this.updateBackgroundCheck();
     this.updateManualUpdatersCount(true);
     this.updateAvailableCount(true);
 
     AddonManager.addAddonListener(this);
     AddonManager.addInstallListener(this);
   },
 
   shutdown: function() {
@@ -2255,27 +2244,20 @@ var gUpdatesView = {
     if (isManual && aOnlyAvailable)
       return isInState(aInstall, "available");
     return isManual;
   },
 
   observe: function(aSubject, aTopic, aData) {
     if (aTopic != "nsPref:changed")
       return;
-    if (aData == "enabled")
-      this.updateBackgroundCheck();
-    else if (aData == "autoUpdateDefault")
+    if (aData == "autoUpdateDefault")
       this.updateManualUpdatersCount();
   },
 
-  updateBackgroundCheck: function() {
-    let isEnabled = this._updatePrefs.getBoolPref("enabled");
-    this._backgroundUpdateCheck.setAttribute("checked", isEnabled);
-  },
-
   maybeRefresh: function() {
     if (gViewController.currentViewId == "addons://updates/available") {
       this._showAvailableUpdates(true);
     } else {
       this.updateManualUpdatersCount();
       this.updateAvailableCount();
     }
   },
--- a/toolkit/mozapps/extensions/content/extensions.xul
+++ b/toolkit/mozapps/extensions/content/extensions.xul
@@ -107,17 +107,16 @@
        in some other way -->
   <commandset id="globalCommandSet"
               oncommand="gViewController.doCommand(event.target.id);">
     <command id="cmd_findAllUpdates"/>
     <command id="cmd_restartApp"/>
     <command id="cmd_goToDiscoverPane"/>
     <command id="cmd_goToRecentUpdates"/>
     <command id="cmd_goToAvailableUpdates"/>
-    <command id="cmd_toggleBackgroundUpdateCheck"/>
     <command id="cmd_installFromFile"/>
     <command id="cmd_back"/>
     <command id="cmd_forward"/>
     <command id="cmd_enableCheckCompatibility"/>
     <command id="cmd_enableUpdateSecurity"/>
     <command id="cmd_toggleAutoUpdateDefault"/>
     <command id="cmd_resetAddonAutoUpdate"/>
   </commandset>
@@ -176,25 +175,20 @@
                   accesskey="&updates.updateAddonsNow.accesskey;"
                   command="cmd_findAllUpdates"/>
         <menuitem id="utils-viewUpdates"
                   label="&updates.viewUpdates.label;"
                   accesskey="&updates.viewUpdates.accesskey;"
                   command="cmd_goToRecentUpdates"/>
         <menuseparator id="utils-installFromFile-separator"/>
         <menuitem id="utils-installFromFile"
-                  label="&installFromFile.label;"
-                  accesskey="&installFromFile.accesskey;"
+                  label="&installAddonFromFile.label;"
+                  accesskey="&installAddonFromFile.accesskey;"
                   command="cmd_installFromFile"/>
         <menuseparator/>
-        <menuitem id="utils-backgroudUpdateCheck"
-                  label="&updates.backgroudUpdateCheck.label;"
-                  accesskey="&updates.backgroudUpdateCheck.accesskey;"
-                  type="checkbox" autocheck="false"
-                  command="cmd_toggleBackgroundUpdateCheck"/>
         <menuitem id="utils-autoUpdateDefault"
                   label="&updates.updateAddonsAutomatically.label;"
                   accesskey="&updates.updateAddonsAutomatically.accesskey;"
                   type="checkbox" autocheck="false"
                   command="cmd_toggleAutoUpdateDefault"/>
         <menuitem id="utils-resetAddonUpdatesToAutomatic"
                   label="&updates.resetUpdatesToAutomatic.label;"
                   accesskey="&updates.resetUpdatesToAutomatic.accesskey;"
--- a/toolkit/mozapps/extensions/test/browser/Makefile.in
+++ b/toolkit/mozapps/extensions/test/browser/Makefile.in
@@ -71,17 +71,16 @@ include $(DEPTH)/config/autoconf.mk
   browser_searching.js \
   browser_searching.xml \
   browser_searching_empty.xml \
   browser_sorting.js \
   browser_uninstalling.js \
   browser_updatessl.js \
   browser_updatessl.rdf \
   browser_installssl.js \
-  browser_backgroundupdate_menuitem.js \
   browser_recentupdates.js \
   browser_manualupdates.js \
   browser_globalwarnings.js \
   redirect.sjs \
   releaseNotes.xhtml \
   $(NULL)
 
 # Disabled browser_bug586574.js due to bug 596174
deleted file mode 100644
--- a/toolkit/mozapps/extensions/test/browser/browser_backgroundupdate_menuitem.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-// Tests the menuitem for the background update check
-
-var gManagerWindow;
-
-function test() {
-  waitForExplicitFinish();
-
-  open_manager("addons://list/extension", function(aWindow) {
-    gManagerWindow = aWindow;
-    run_next_test();
-  });
-}
-
-function end_test() {
-  close_manager(gManagerWindow, function() {
-    finish();
-  });
-}
-
-add_test(function() {
-  var menuitem = gManagerWindow.document.getElementById("utils-backgroudUpdateCheck");
-
-  function is_backgroundcheck_insync(aExpected) {
-    var enabled = Services.prefs.getBoolPref("extensions.update.enabled");
-    var checked = menuitem.getAttribute("checked") == "true";
-    is(enabled, aExpected, "Background check should be " + (aExpected ? "enabled" : "disabled"));
-    is(checked, enabled, "Background check menuitem should be in sync with preference");
-  }
-
-  is_backgroundcheck_insync(true);
-  info("Setting background check pref to true");
-  Services.prefs.setBoolPref("extensions.update.enabled", false);
-  is_backgroundcheck_insync(false);
-  info("Setting background check pref to false");
-  Services.prefs.setBoolPref("extensions.update.enabled", true);
-  is_backgroundcheck_insync(true);
-  run_next_test();
-/* XXX This is failing on OSX - need to investigate why
-  
-  info("Clicking on background check menuitem - setting to unchecked");
-  var utilsBtn = gManagerWindow.document.getElementById("header-utils-btn");
-  utilsBtn.addEventListener("popupshown", function() {
-    EventUtils.synthesizeMouse(menuitem, 2, 2, { }, gManagerWindow);
-    executeSoon(function() {
-      is_backgroundcheck_insync(false);
-      info("Manually invoking command to toggle background update check on");
-      gManagerWindow.gViewController.doCommand("cmd_toggleBackgroundUpdateCheck");
-      is_backgroundcheck_insync(true);
-      run_next_test();
-    });
-  }, false);
-  EventUtils.synthesizeMouse(utilsBtn, 2, 2, { }, gManagerWindow);
-*/
-});
--- a/toolkit/mozapps/extensions/test/browser/browser_details.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_details.js
@@ -34,16 +34,17 @@ function open_details(aId, aType, aCallb
   });
 }
 
 function get(aId) {
   return gManagerWindow.document.getElementById(aId);
 }
 
 function test() {
+  requestLongerTimeout(2);
   // Turn on searching for this test
   Services.prefs.setIntPref(PREF_SEARCH_MAXRESULTS, 15);
   Services.prefs.setCharPref(PREF_GETADDONS_GETSEARCHRESULTS, SEARCH_URL);
 
   waitForExplicitFinish();
 
   gProvider = new MockProvider();
 
--- a/toolkit/mozapps/extensions/test/browser/browser_searching.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_searching.js
@@ -15,16 +15,17 @@ const REMOTE_INSTALL_URL = TESTROOT + "a
 
 var gManagerWindow;
 var gCategoryUtilities;
 var gProvider;
 var gServer;
 var gAddonInstalled = false;
 
 function test() {
+  requestLongerTimeout(2);
   // Turn on searching for this test
   Services.prefs.setIntPref(PREF_SEARCH_MAXRESULTS, 15);
 
   waitForExplicitFinish();
 
   gProvider = new MockProvider();
 
   gProvider.createAddons([{
--- a/toolkit/mozapps/extensions/test/browser/head.js
+++ b/toolkit/mozapps/extensions/test/browser/head.js
@@ -21,16 +21,17 @@ function getChromeRoot(path) {
   if (path === undefined) {
     return "chrome://" + CHROME_NAME + "/content/" + RELATIVE_DIR;
   }
   return getRootDirectory(path);
 }
 
 var gPendingTests = [];
 var gTestsRun = 0;
+var gTestStart = null;
 
 var gUseInContentUI = ("switchToTabHavingURI" in window);
 
 // Turn logging on for all tests
 Services.prefs.setBoolPref(PREF_LOGGING_ENABLED, true);
 // Turn off remote results in searches
 Services.prefs.setIntPref(PREF_SEARCH_MAXRESULTS, 0);
 registerCleanupFunction(function() {
@@ -42,25 +43,33 @@ registerCleanupFunction(function() {
   }
 });
 
 function add_test(test) {
   gPendingTests.push(test);
 }
 
 function run_next_test() {
+  if (gTestsRun > 0)
+    info("Test " + gTestsRun + " took " + (Date.now() - gTestStart) + "ms");
+
   if (gPendingTests.length == 0) {
     end_test();
     return;
   }
 
   gTestsRun++;
-  info("Running test " + gTestsRun);
+  var test = gPendingTests.shift();
+  if (test.name)
+    info("Running test " + gTestsRun + " (" + test.name + ")");
+  else
+    info("Running test " + gTestsRun);
 
-  gPendingTests.shift()();
+  gTestStart = Date.now();
+  test();
 }
 
 function get_addon_file_url(aFilename) {
   var chromeroot = getChromeRoot(gTestPath);
   try {
     var cr = Cc["@mozilla.org/chrome/chrome-registry;1"].
              getService(Ci.nsIChromeRegistry);
     var fileurl = cr.convertChromeURL(makeURI(chromeroot + "addons/" + aFilename));
--- a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository.xml
+++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository.xml
@@ -44,19 +44,20 @@
         <name>Test Creator 2</name>
         <link>http://localhost:4444/creator2.html</link>
       </author>
       <author>
         <name>Test Developer 2</name>
         <link>http://localhost:4444/developer2.html</link>
       </author>
     </authors>
-    <summary>Test Summary 2</summary>
-    <description>Test Description 2</description>
-    <developer_comments>Test Developer Comments 2</developer_comments>
+    <summary>&lt;h1&gt;Test Summary 2&lt;/h1&gt;&lt;p&gt;paragraph&lt;/p&gt;</summary>
+    <description>Test Description 2&lt;br&gt;newline</description>
+    <developer_comments>Test Developer
+                        Comments 2</developer_comments>
     <eula>Test EULA 2</eula>
     <icon>http://localhost:4444/icon2.png</icon>
     <status id="4">Public</status>
     <compatible_applications>
       <application>
         <appID>xpcshell@tests.mozilla.org</appID>
         <min_version>1</min_version>
         <max_version>1</max_version>
@@ -123,17 +124,17 @@
         <link>    </link>
       </author>
       <author>
         <name>   Second Test Developer 3   </name>
         <link>   http://localhost:4444/developer2-3.html   </link>
       </author>
     </authors>
     <summary>   Test Summary 3   </summary>
-    <description>   Test Description 3   </description>
+    <description>   Test Description 3&lt;br&gt;&lt;ul&gt;&lt;li&gt;List item 1&lt;li&gt;List item 2&lt;/ul&gt;   </description>
     <developer_comments>   Test Developer Comments 3   </developer_comments>
     <eula>   Test EULA 3   </eula>
     <icon>   http://localhost:4444/icon3.png   </icon>
     <status id="   4   ">Public</status>
     <!-- Test that an incompatible + compatible application list passes -->
     <compatible_applications>
       <application>
         <appID>   unknown@tests.mozilla.org   </appID>
--- a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_cache.xml
+++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_cache.xml
@@ -14,20 +14,21 @@
         <name>Repo Add-on 1 - First Developer</name>
         <link>http://localhost:4444/repo/1/firstDeveloper.html</link>
       </author>
       <author>
         <name>Repo Add-on 1 - Second Developer</name>
         <link>http://localhost:4444/repo/1/secondDeveloper.html</link>
       </author>
     </authors>
-    <summary>Repo Add-on 1 - Description</summary>
-    <description>Repo Add-on 1 - Full Description</description>
+    <summary>Repo Add-on 1 - Description&lt;br&gt;Second line</summary>
+    <description>&lt;p&gt;Repo Add-on 1 - Full Description &amp;amp; some extra&lt;/p&gt;</description>
     <eula>Repo Add-on 1 - EULA</eula>
-    <developer_comments>Repo Add-on 1 - Developer Comments</developer_comments>
+    <developer_comments>Repo Add-on 1
+                        Developer Comments</developer_comments>
     <icon>http://localhost:4444/repo/1/icon.png</icon>
     <status id="4">Public</status>
     <rating>1</rating>
     <learnmore>http://localhost:4444/repo/1/learnmore.html</learnmore>
     <homepage>http://localhost:4444/repo/1/homepage.html</homepage>
     <support>http://localhost:4444/repo/1/support.html</support>
     <contribution_data>
       <link>http://localhost:4444/repo/1/contribution.html</link>
--- a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository.js
@@ -102,19 +102,19 @@ var SEARCH_RESULTS = [{
   creator:                {
                             name: "Test Creator 2",
                             url:  BASE_URL + "/creator2.html"
                           },
   developers:             [{
                             name: "Test Developer 2",
                             url:  BASE_URL + "/developer2.html"
                           }],
-  description:            "Test Summary 2",
-  fullDescription:        "Test Description 2",
-  developerComments:      "Test Developer Comments 2",
+  description:            "Test Summary 2\n\nparagraph",
+  fullDescription:        "Test Description 2\nnewline",
+  developerComments:      "Test Developer\nComments 2",
   eula:                   "Test EULA 2",
   iconURL:                BASE_URL + "/icon2.png",
   screenshots:            [{
                             url:          BASE_URL + "/full1-2.png",
                             thumbnailURL: BASE_URL + "/thumbnail1-2.png"
                           }, {
                             url:          BASE_URL + "/full2-2.png",
                             thumbnailURL: BASE_URL + "/thumbnail2-2.png",
@@ -137,17 +137,17 @@ var SEARCH_RESULTS = [{
   developers:             [{
                             name: "First Test Developer 3",
                             url:  BASE_URL + "/developer1-3.html"
                           }, {
                             name: "Second Test Developer 3",
                             url:  BASE_URL + "/developer2-3.html"
                           }],
   description:            "Test Summary 3",
-  fullDescription:        "Test Description 3",
+  fullDescription:        "Test Description 3\n\n    List item 1\n    List item 2",
   developerComments:      "Test Developer Comments 3",
   eula:                   "Test EULA 3",
   iconURL:                BASE_URL + "/icon3.png",
   screenshots:            [{
                             url:          BASE_URL + "/full1-3.png",
                             thumbnailURL: BASE_URL + "/thumbnail1-3.png",
                             caption:      "Caption 1 - 3"
                           }, {
--- a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_cache.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_cache.js
@@ -66,19 +66,19 @@ const REPOSITORY_ADDONS = [{
                           },
   developers:             [{
                             name: "Repo Add-on 1 - First Developer",
                             url:  BASE_URL + "/repo/1/firstDeveloper.html"
                           }, {
                             name: "Repo Add-on 1 - Second Developer",
                             url:  BASE_URL + "/repo/1/secondDeveloper.html"
                           }],
-  description:            "Repo Add-on 1 - Description",
-  fullDescription:        "Repo Add-on 1 - Full Description",
-  developerComments:      "Repo Add-on 1 - Developer Comments",
+  description:            "Repo Add-on 1 - Description\nSecond line",
+  fullDescription:        "Repo Add-on 1 - Full Description & some extra",
+  developerComments:      "Repo Add-on 1\nDeveloper Comments",
   eula:                   "Repo Add-on 1 - EULA",
   iconURL:                BASE_URL + "/repo/1/icon.png",
   homepageURL:            BASE_URL + "/repo/1/homepage.html",
   supportURL:             BASE_URL + "/repo/1/support.html",
   contributionURL:        BASE_URL + "/repo/1/meetDevelopers.html",
   contributionAmount:     "$11.11",
   averageRating:          1,
   reviewCount:            1111,
@@ -197,18 +197,18 @@ const WITH_CACHE = [{
                           },
   developers:             [{ name: "XPI Add-on 1 - First Developer" },
                            { name: "XPI Add-on 1 - Second Developer" }],
   translators:            [{ name: "XPI Add-on 1 - First Translator" },
                            { name: "XPI Add-on 1 - Second Translator" }],
   contributors:           [{ name: "XPI Add-on 1 - First Contributor" },
                            { name: "XPI Add-on 1 - Second Contributor" }],
   description:            "XPI Add-on 1 - Description",
-  fullDescription:        "Repo Add-on 1 - Full Description",
-  developerComments:      "Repo Add-on 1 - Developer Comments",
+  fullDescription:        "Repo Add-on 1 - Full Description & some extra",
+  developerComments:      "Repo Add-on 1\nDeveloper Comments",
   eula:                   "Repo Add-on 1 - EULA",
   iconURL:                BASE_URL + "/xpi/1/icon.png",
   homepageURL:            BASE_URL + "/xpi/1/homepage.html",
   supportURL:             BASE_URL + "/repo/1/support.html",
   optionsURL:             BASE_URL + "/xpi/1/options.html",
   aboutURL:               BASE_URL + "/xpi/1/about.html",
   contributionURL:        BASE_URL + "/repo/1/meetDevelopers.html",
   contributionAmount:     "$11.11",
--- a/toolkit/mozapps/extensions/test/xpinstall/Makefile.in
+++ b/toolkit/mozapps/extensions/test/xpinstall/Makefile.in
@@ -73,16 +73,17 @@ include $(topsrcdir)/config/rules.mk
                  browser_enabled3.js \
                  browser_softwareupdate.js \
                  browser_installchrome.js \
                  browser_localfile.js \
                  browser_localfile2.js \
                  browser_auth.js \
                  browser_auth2.js \
                  browser_auth3.js \
+                 browser_auth4.js \
                  browser_offline.js \
                  browser_navigateaway.js \
                  browser_navigateaway2.js \
                  browser_bug540558.js \
                  browser_relative.js \
                  browser_cancel.js \
                  browser_multipackage.js \
                  browser_trigger_redirect.js \
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpinstall/browser_auth4.js
@@ -0,0 +1,43 @@
+// ----------------------------------------------------------------------------
+// Test whether a request for auth for an XPI switches to the appropriate tab
+function test() {
+  Harness.authenticationCallback = get_auth_info;
+  Harness.downloadFailedCallback = download_failed;
+  Harness.installEndedCallback = install_ended;
+  Harness.installsCompletedCallback = finish_test;
+  Harness.setup();
+
+  var pm = Services.perms;
+  pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
+
+  var triggers = encodeURIComponent(JSON.stringify({
+    "Unsigned XPI": TESTROOT + "authRedirect.sjs?" + TESTROOT + "unsigned.xpi"
+  }));
+  gNewTab = gBrowser.addTab();
+  gBrowser.getBrowserForTab(gNewTab).loadURI(TESTROOT + "installtrigger.html?" + triggers);
+}
+
+function get_auth_info() {
+  is(gBrowser.selectedTab, gNewTab, "Should have focused the tab loading the XPI");
+  return [ "testuser", "testpass" ];
+}
+
+function download_failed(install) {
+  ok(false, "Install should not have failed");
+}
+
+function install_ended(install, addon) {
+  install.cancel();
+}
+
+function finish_test(count) {
+  is(count, 1, "1 Add-on should have been successfully installed");
+  var authMgr = Components.classes['@mozilla.org/network/http-auth-manager;1']
+                          .getService(Components.interfaces.nsIHttpAuthManager);
+  authMgr.clearAll();
+
+  Services.perms.remove("example.com", "install");
+
+  gBrowser.removeTab(gNewTab);
+  Harness.finish();
+}
--- a/toolkit/themes/faststripe/global/menu.css
+++ b/toolkit/themes/faststripe/global/menu.css
@@ -179,20 +179,17 @@ popup > menuitem[_moz-menuactive="true"]
 /* ::::: menu/menuitems in menulist popups ::::: */
 
 .menulist-menupopup > menuitem,
 menulist > menupopup > menuitem,
 .menulist-menupopup > menu,
 menulist > menupopup > menu {
   -moz-appearance: none;
   border: 1px solid transparent;
-  padding-top: 1px;
-  -moz-padding-end: 30px;
-  padding-bottom: 1px;
-  -moz-padding-start: 5px;
+  padding: 1px 5px;
   max-width: none;
   font: message-box;
   color: -moz-FieldText;
 }
 
 .menulist-menupopup > menuitem > .menu-iconic-left,
 menulist > menupopup > menuitem > .menu-iconic-left,
 .menulist-menupopup > menu > .menu-iconic-left,
--- a/toolkit/themes/gnomestripe/global/menu.css
+++ b/toolkit/themes/gnomestripe/global/menu.css
@@ -99,20 +99,17 @@ menuitem.spell-suggestion {
 }
 
 /* ::::: menu/menuitems in menulist popups ::::: */
 
 .menulist-menupopup > menuitem,
 menulist > menupopup > menuitem,
 .menulist-menupopup > menu,
 menulist > menupopup > menu {
-  padding-top: 1px;
-  padding-bottom: 1px;
-  -moz-padding-start: 1px;
-  -moz-padding-end: 30px;
+  padding: 1px 5px;
   max-width: none;
   font: message-box;
 }
 
 /* ..... internal content .... */
 
 .menu-text,
 .menu-iconic-left,
--- a/toolkit/themes/gnomestripe/global/webConsole.css
+++ b/toolkit/themes/gnomestripe/global/webConsole.css
@@ -16,17 +16,18 @@
  * The Initial Developer of the Original Code is
  *   Mozilla Corporation
  * Portions created by the Initial Developer are Copyright (C) 2010
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   David Dahl <ddahl@mozilla.com>
  *   Patrick Walton <pcwalton@mozilla.com>
-
+ *   Mihai Șucan <mihai.sucan@gmail.com>
+ *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * 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
@@ -55,17 +56,17 @@
 }
 
 .hud-main-label {
     font-size: 1em;
     padding-top: 0.33em;
     font-weight: bold;
 }
 
-.hud-output-node div {
+.hud-output-node * {
     -moz-user-select: text;
     white-space: pre-wrap;
     -moz-user-focus: normal;
 }
 
 .hud-clickable {
     cursor: pointer !important;
     text-decoration: underline;
--- a/toolkit/themes/gnomestripe/mozapps/extensions/extensions.css
+++ b/toolkit/themes/gnomestripe/mozapps/extensions/extensions.css
@@ -577,16 +577,17 @@
   margin-bottom: 2em;
   /* This is necessary to fix layout issues with multi-line descriptions, see
      bug 592712*/
   outline: solid transparent;
 }
 
 #detail-desc {
   -moz-margin-start: 6px;
+  white-space: pre-wrap;
 }
 
 #detail-contributions {
   border-radius: 5px;
   border: 1px solid #B0C8D1;
   margin-bottom: 2em;
   padding: 1em;
   background: #D8DDE4;
--- a/toolkit/themes/pinstripe/mozapps/extensions/extensions.css
+++ b/toolkit/themes/pinstripe/mozapps/extensions/extensions.css
@@ -613,16 +613,17 @@
   margin-bottom: 2em;
 }
 
 #detail-desc {
   -moz-margin-start: 6px;
   /* This is necessary to fix layout issues with multi-line descriptions, see
      bug 592712*/
   outline: solid transparent;
+  white-space: pre-wrap;
 }
 
 #detail-contributions {
   border-radius: 5px;
   border: 1px solid #B0C8D1;
   margin-bottom: 2em;
   padding: 1em;
   background: #D8DDE4;
--- a/toolkit/themes/pmstripe/global/menu.css
+++ b/toolkit/themes/pmstripe/global/menu.css
@@ -192,20 +192,17 @@ popup > menuitem[_moz-menuactive="true"]
 
 /* ::::: menu/menuitems in menulist popups ::::: */
 
 .menulist-menupopup > menuitem,
 menulist > menupopup > menuitem,
 .menulist-menupopup > menu,
 menulist > menupopup > menu {
   border: 1px solid transparent;
-  -moz-padding-end: 30px;
-  -moz-padding-start: 5px;
-  padding-top: 0;
-  padding-bottom: 0;
+  padding: 1px 5px;
   max-width: none;
   font: message-box;
   color: -moz-FieldText;
   background-color: -moz-Field;
 }
 
 .menulist-menupopup > menuitem > .menu-iconic-left,
 menulist > menupopup > menuitem > .menu-iconic-left,
--- a/toolkit/themes/winstripe/global/menu.css
+++ b/toolkit/themes/winstripe/global/menu.css
@@ -202,20 +202,17 @@ menupopup > menuitem[_moz-menuactive="tr
 /* ::::: menu/menuitems in menulist popups ::::: */
 
 .menulist-menupopup > menuitem,
 menulist > menupopup > menuitem,
 .menulist-menupopup > menu,
 menulist > menupopup > menu {
   -moz-appearance: none;
   border: 1px solid transparent;
-  padding-top: 1px;
-  -moz-padding-end: 30px;
-  padding-bottom: 1px;
-  -moz-padding-start: 5px;
+  padding: 1px 5px;
   max-width: none;
   font: message-box;
   color: -moz-FieldText;
 }
 
 .menulist-menupopup > menuitem > .menu-iconic-left,
 menulist > menupopup > menuitem > .menu-iconic-left,
 .menulist-menupopup > menu > .menu-iconic-left,
--- a/toolkit/themes/winstripe/mozapps/extensions/extensions.css
+++ b/toolkit/themes/winstripe/mozapps/extensions/extensions.css
@@ -594,16 +594,17 @@
   margin-bottom: 2em;
   /* This is necessary to fix layout issues with multi-line descriptions, see
      bug 592712*/
   outline: solid transparent;
 }
 
 #detail-desc {
   -moz-margin-start: 6px;
+  white-space: pre-wrap;
 }
 
 #detail-contributions {
   border-radius: 5px;
   border: 1px solid #B0C8D1;
   margin-bottom: 2em;
   padding: 1em;
   background: #D8DDE4;
--- a/widget/src/qt/mozqwidget.h
+++ b/widget/src/qt/mozqwidget.h
@@ -234,17 +234,17 @@ public:
     MozMSceneWindow(MozQWidget* aTopLevel)
      : MSceneWindow(aTopLevel->parentItem())
      , mTopLevelWidget(aTopLevel)
      , mStatusBar(nsnull)
     {
         mTopLevelWidget->setParentItem(this);
         mTopLevelWidget->installEventFilter(this);
         mStatusBar = new MStatusBar();
-        mStatusBar->appear();
+        mStatusBar->appear(scene());
         connect(mStatusBar, SIGNAL(appeared()), this, SLOT(CheckTopLevelSize()));
         connect(mStatusBar, SIGNAL(disappeared()), this, SLOT(CheckTopLevelSize()));
         MInputMethodState *inputMethodState = MInputMethodState::instance();
         if (inputMethodState) 
             connect(inputMethodState, SIGNAL(inputMethodAreaChanged(const QRect &)),
                     this, SLOT(VisibleScreenAreaChanged(const QRect &)));
     }
 
--- a/widget/src/qt/nsWindow.cpp
+++ b/widget/src/qt/nsWindow.cpp
@@ -2385,16 +2385,19 @@ nsWindow::createQWidget(MozQWidget *pare
         } else
 #else
         newView = new MozQGraphicsView(widget);
 #endif
         if (!newView) {
             delete widget;
             return nsnull;
         }
+        if (!IsAcceleratedQView(newView) && GetShouldAccelerate()) {
+            newView->setViewport(new QGLWidget());
+        }
 
         // Enable gestures:
 #if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
         newView->grabGesture(Qt::PinchGesture);
         newView->viewport()->grabGesture(Qt::PinchGesture);
 #endif
         newView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
         newView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
@@ -2425,38 +2428,16 @@ nsWindow::IsAcceleratedQView(QGraphicsVi
 {
     if (view && view->viewport()) {
         QPaintEngine::Type type = view->viewport()->paintEngine()->type();
         return (type == QPaintEngine::OpenGL || type == QPaintEngine::OpenGL2);
     }
     return PR_FALSE;
 }
 
-NS_IMETHODIMP
-nsWindow::SetAcceleratedRendering(PRBool aEnabled)
-{
-    if (mUseAcceleratedRendering == aEnabled)
-        return NS_OK;
-
-    mUseAcceleratedRendering = aEnabled;
-    mLayerManager = NULL;
-
-    QGraphicsView* view = static_cast<QGraphicsView*>(GetViewWidget());
-    if (view) {
-        if (aEnabled && !IsAcceleratedQView(view))
-            view->setViewport(new QGLWidget());
-        if (!aEnabled && IsAcceleratedQView(view))
-            view->setViewport(new QWidget());
-        view->viewport()->setAttribute(Qt::WA_PaintOnScreen, aEnabled);
-        view->viewport()->setAttribute(Qt::WA_NoSystemBackground, aEnabled);
-    }
-
-    return NS_OK;
-}
-
 // return the gfxASurface for rendering to this widget
 gfxASurface*
 nsWindow::GetThebesSurface()
 {
     /* This is really a dummy surface; this is only used when doing reflow, because
      * we need a RenderingContext to measure text against.
      */
     if (mThebesSurface)
--- a/widget/src/qt/nsWindow.h
+++ b/widget/src/qt/nsWindow.h
@@ -195,17 +195,16 @@ public:
 
     NS_IMETHOD         SetWindowClass(const nsAString& xulWinType);
 
     NS_IMETHOD         GetAttention(PRInt32 aCycleCount);
     NS_IMETHOD         BeginResizeDrag   (nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical);
 
     NS_IMETHODIMP      SetIMEEnabled(PRUint32 aState);
     NS_IMETHODIMP      GetIMEEnabled(PRUint32* aState);
-    NS_IMETHOD         SetAcceleratedRendering(PRBool aEnabled);
 
     //
     // utility methods
     //
     void               QWidgetDestroyed();
 
     /***** from CommonWidget *****/