Merge s-c and m-c.
authorRichard Newman <rnewman@mozilla.com>
Fri, 21 Oct 2011 11:39:55 -0700
changeset 79724 e79245e249c486bf7ebb3748846b4e2872a56b16
parent 79723 01942de9ff57fa60755eb1271afa7252ecb247b1 (current diff)
parent 79704 75eaad17724f031b2fd2dc61ec999222a02363ef (diff)
child 79725 475896b92d6c189a53fbf680995b32dac8cc9513
child 79822 0e9e8433d5f033b259d6555de1c372190f6e970b
push id506
push userclegnitto@mozilla.com
push dateWed, 09 Nov 2011 02:03:18 +0000
treeherdermozilla-aurora@63587fc7bb93 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone10.0a1
Merge s-c and m-c.
browser/base/content/tabview/content.js
browser/base/content/tabview/drag.js
browser/base/content/tabview/groupitems.js
browser/base/content/tabview/iq.js
browser/base/content/tabview/items.js
browser/base/content/tabview/modules/utils.jsm
browser/base/content/tabview/search.js
browser/base/content/tabview/storage.js
browser/base/content/tabview/storagePolicy.js
browser/base/content/tabview/tabitems.js
browser/base/content/tabview/tabview.css
browser/base/content/tabview/tabview.html
browser/base/content/tabview/tabview.js
browser/base/content/tabview/thumbnailStorage.js
browser/base/content/tabview/trench.js
browser/base/content/tabview/ui.js
browser/base/content/test/tabview/Makefile.in
browser/base/content/test/tabview/browser_tabview_alltabs.js
browser/base/content/test/tabview/browser_tabview_apptabs.js
browser/base/content/test/tabview/browser_tabview_bug580412.js
browser/base/content/test/tabview/browser_tabview_bug586553.js
browser/base/content/test/tabview/browser_tabview_bug587043.js
browser/base/content/test/tabview/browser_tabview_bug587231.js
browser/base/content/test/tabview/browser_tabview_bug587276.js
browser/base/content/test/tabview/browser_tabview_bug587351.js
browser/base/content/test/tabview/browser_tabview_bug587503.js
browser/base/content/test/tabview/browser_tabview_bug587990.js
browser/base/content/test/tabview/browser_tabview_bug588265.js
browser/base/content/test/tabview/browser_tabview_bug589324.js
browser/base/content/test/tabview/browser_tabview_bug590606.js
browser/base/content/test/tabview/browser_tabview_bug591706.js
browser/base/content/test/tabview/browser_tabview_bug593283.js
browser/base/content/test/tabview/browser_tabview_bug594958.js
browser/base/content/test/tabview/browser_tabview_bug595191.js
browser/base/content/test/tabview/browser_tabview_bug595436.js
browser/base/content/test/tabview/browser_tabview_bug595518.js
browser/base/content/test/tabview/browser_tabview_bug595521.js
browser/base/content/test/tabview/browser_tabview_bug595560.js
browser/base/content/test/tabview/browser_tabview_bug595601.js
browser/base/content/test/tabview/browser_tabview_bug595804.js
browser/base/content/test/tabview/browser_tabview_bug595930.js
browser/base/content/test/tabview/browser_tabview_bug595943.js
browser/base/content/test/tabview/browser_tabview_bug595965.js
browser/base/content/test/tabview/browser_tabview_bug596781.js
browser/base/content/test/tabview/browser_tabview_bug597248.js
browser/base/content/test/tabview/browser_tabview_bug597360.js
browser/base/content/test/tabview/browser_tabview_bug597399.js
browser/base/content/test/tabview/browser_tabview_bug597980.js
browser/base/content/test/tabview/browser_tabview_bug598375.js
browser/base/content/test/tabview/browser_tabview_bug598600.js
browser/base/content/test/tabview/browser_tabview_bug599048.js
browser/base/content/test/tabview/browser_tabview_bug599626.js
browser/base/content/test/tabview/browser_tabview_bug600645.js
browser/base/content/test/tabview/browser_tabview_bug600812.js
browser/base/content/test/tabview/browser_tabview_bug602432.js
browser/base/content/test/tabview/browser_tabview_bug604098.js
browser/base/content/test/tabview/browser_tabview_bug606657.js
browser/base/content/test/tabview/browser_tabview_bug606905.js
browser/base/content/test/tabview/browser_tabview_bug607108.js
browser/base/content/test/tabview/browser_tabview_bug608037.js
browser/base/content/test/tabview/browser_tabview_bug608158.js
browser/base/content/test/tabview/browser_tabview_bug608184.js
browser/base/content/test/tabview/browser_tabview_bug608405.js
browser/base/content/test/tabview/browser_tabview_bug610208.js
browser/base/content/test/tabview/browser_tabview_bug610242.js
browser/base/content/test/tabview/browser_tabview_bug612470.js
browser/base/content/test/tabview/browser_tabview_bug613541.js
browser/base/content/test/tabview/browser_tabview_bug616729.js
browser/base/content/test/tabview/browser_tabview_bug616967.js
browser/base/content/test/tabview/browser_tabview_bug618816.js
browser/base/content/test/tabview/browser_tabview_bug618828.js
browser/base/content/test/tabview/browser_tabview_bug619937.js
browser/base/content/test/tabview/browser_tabview_bug622835.js
browser/base/content/test/tabview/browser_tabview_bug623768.js
browser/base/content/test/tabview/browser_tabview_bug624265.js
browser/base/content/test/tabview/browser_tabview_bug624692.js
browser/base/content/test/tabview/browser_tabview_bug624727.js
browser/base/content/test/tabview/browser_tabview_bug624847.js
browser/base/content/test/tabview/browser_tabview_bug624931.js
browser/base/content/test/tabview/browser_tabview_bug624953.js
browser/base/content/test/tabview/browser_tabview_bug625195.js
browser/base/content/test/tabview/browser_tabview_bug625269.js
browser/base/content/test/tabview/browser_tabview_bug625424.js
browser/base/content/test/tabview/browser_tabview_bug625955.js
browser/base/content/test/tabview/browser_tabview_bug626368.js
browser/base/content/test/tabview/browser_tabview_bug626455.js
browser/base/content/test/tabview/browser_tabview_bug626525.js
browser/base/content/test/tabview/browser_tabview_bug626791.js
browser/base/content/test/tabview/browser_tabview_bug627288.js
browser/base/content/test/tabview/browser_tabview_bug627736.js
browser/base/content/test/tabview/browser_tabview_bug628061.js
browser/base/content/test/tabview/browser_tabview_bug628165.js
browser/base/content/test/tabview/browser_tabview_bug628270.js
browser/base/content/test/tabview/browser_tabview_bug628887.js
browser/base/content/test/tabview/browser_tabview_bug629189.js
browser/base/content/test/tabview/browser_tabview_bug629195.js
browser/base/content/test/tabview/browser_tabview_bug630102.js
browser/base/content/test/tabview/browser_tabview_bug630157.js
browser/base/content/test/tabview/browser_tabview_bug631662.js
browser/base/content/test/tabview/browser_tabview_bug631752.js
browser/base/content/test/tabview/browser_tabview_bug633190.js
browser/base/content/test/tabview/browser_tabview_bug633788.js
browser/base/content/test/tabview/browser_tabview_bug634077.js
browser/base/content/test/tabview/browser_tabview_bug634085.js
browser/base/content/test/tabview/browser_tabview_bug634672.js
browser/base/content/test/tabview/browser_tabview_bug635696.js
browser/base/content/test/tabview/browser_tabview_bug637840.js
browser/base/content/test/tabview/browser_tabview_bug640765.js
browser/base/content/test/tabview/browser_tabview_bug641802.js
browser/base/content/test/tabview/browser_tabview_bug642793.js
browser/base/content/test/tabview/browser_tabview_bug643392.js
browser/base/content/test/tabview/browser_tabview_bug644097.js
browser/base/content/test/tabview/browser_tabview_bug648882.js
browser/base/content/test/tabview/browser_tabview_bug649006.js
browser/base/content/test/tabview/browser_tabview_bug649307.js
browser/base/content/test/tabview/browser_tabview_bug649319.js
browser/base/content/test/tabview/browser_tabview_bug650280.js
browser/base/content/test/tabview/browser_tabview_bug650573.js
browser/base/content/test/tabview/browser_tabview_bug651311.js
browser/base/content/test/tabview/browser_tabview_bug654295.js
browser/base/content/test/tabview/browser_tabview_bug654721.js
browser/base/content/test/tabview/browser_tabview_bug654941.js
browser/base/content/test/tabview/browser_tabview_bug655269.js
browser/base/content/test/tabview/browser_tabview_bug656778.js
browser/base/content/test/tabview/browser_tabview_bug656913.js
browser/base/content/test/tabview/browser_tabview_bug662266.js
browser/base/content/test/tabview/browser_tabview_bug663421.js
browser/base/content/test/tabview/browser_tabview_bug665502.js
browser/base/content/test/tabview/browser_tabview_bug669694.js
browser/base/content/test/tabview/browser_tabview_bug673196.js
browser/base/content/test/tabview/browser_tabview_bug673729.js
browser/base/content/test/tabview/browser_tabview_bug677310.js
browser/base/content/test/tabview/browser_tabview_bug679853.js
browser/base/content/test/tabview/browser_tabview_bug681599.js
browser/base/content/test/tabview/browser_tabview_bug685476.js
browser/base/content/test/tabview/browser_tabview_bug685692.js
browser/base/content/test/tabview/browser_tabview_bug686654.js
browser/base/content/test/tabview/browser_tabview_click_group.js
browser/base/content/test/tabview/browser_tabview_dragdrop.js
browser/base/content/test/tabview/browser_tabview_exit_button.js
browser/base/content/test/tabview/browser_tabview_expander.js
browser/base/content/test/tabview/browser_tabview_firstrun_pref.js
browser/base/content/test/tabview/browser_tabview_group.js
browser/base/content/test/tabview/browser_tabview_launch.js
browser/base/content/test/tabview/browser_tabview_layout.js
browser/base/content/test/tabview/browser_tabview_multiwindow_search.js
browser/base/content/test/tabview/browser_tabview_privatebrowsing.js
browser/base/content/test/tabview/browser_tabview_rtl.js
browser/base/content/test/tabview/browser_tabview_search.js
browser/base/content/test/tabview/browser_tabview_snapping.js
browser/base/content/test/tabview/browser_tabview_startup_transitions.js
browser/base/content/test/tabview/browser_tabview_storage_policy.js
browser/base/content/test/tabview/browser_tabview_thumbnail_storage.js
browser/base/content/test/tabview/browser_tabview_undo_group.js
browser/base/content/test/tabview/dummy_page.html
browser/base/content/test/tabview/head.js
browser/base/content/test/tabview/search1.html
browser/base/content/test/tabview/search2.html
browser/base/content/test/tabview/test_bug600645.html
browser/base/content/test/tabview/test_bug644097.html
--- a/browser/base/Makefile.in
+++ b/browser/base/Makefile.in
@@ -78,11 +78,8 @@ endif
 
 ifneq (,$(filter windows, $(MOZ_WIDGET_TOOLKIT)))
 DEFINES += -DCAN_DRAW_IN_TITLEBAR=1
 endif
 
 ifneq (,$(filter windows gtk2, $(MOZ_WIDGET_TOOLKIT)))
 DEFINES += -DMENUBAR_CAN_AUTOHIDE=1
 endif
-
-libs::
-	$(NSINSTALL) $(srcdir)/content/tabview/modules/* $(FINAL_TARGET)/modules/tabview
--- a/browser/base/content/aboutDialog.xul
+++ b/browser/base/content/aboutDialog.xul
@@ -62,30 +62,31 @@
 #ifdef MOZ_UPDATER
         onunload="onUnload(event);"
 #endif
 #ifdef XP_MACOSX
         inwindowmenu="false"
 #else
         title="&aboutDialog.title;"
 #endif
-        aria-describedby="version distribution distributionId"
+        role="dialog"
+        aria-describedby="version distribution distributionId communityDesc contributeDesc trademark"
         >
 
   <script type="application/javascript" src="chrome://browser/content/aboutDialog.js"/>
 
   <vbox id="aboutDialogContainer">
     <hbox id="clientBox">
       <vbox id="leftBox" flex="1"/>
       <vbox id="rightBox" flex="1">
 #expand <label id="version">__MOZ_APP_VERSION__</label>
         <label id="distribution" class="text-blurb"/>
         <label id="distributionId" class="text-blurb"/>
 
-        <vbox id="detailsBox" aria-describedby="communityDesc contributeDesc">
+        <vbox id="detailsBox">
           <vbox id="updateBox">
 #ifdef MOZ_UPDATER
             <deck id="updateDeck" orient="vertical">
               <hbox id="updateButtonBox" align="center">
                 <button id="updateButton" align="start"
                         oncommand="gAppUpdater.buttonOnCommand();"/>
                 <spacer flex="1"/>
               </hbox>
--- a/browser/base/content/browser-tabview.js
+++ b/browser/base/content/browser-tabview.js
@@ -88,20 +88,19 @@ let TabView = {
   // ----------
   set sessionRestoreEnabledOnce(val) {
     Services.prefs.setBoolPref(this.PREF_RESTORE_ENABLED_ONCE, val);
   },
 
   // ----------
   init: function TabView_init() {
     // disable the ToggleTabView command for popup windows
-    if (!window.toolbar.visible) {
-      goSetCommandEnabled("Browser:ToggleTabView", false);
+    goSetCommandEnabled("Browser:ToggleTabView", window.toolbar.visible);
+    if (!window.toolbar.visible)
       return;
-    }
 
     if (this._initialized)
       return;
 
     if (this.firstUseExperienced) {
       if ((gBrowser.tabs.length - gBrowser.visibleTabs.length) > 0)
         this._setBrowserKeyHandlers();
 
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -35,20 +35,16 @@
 # ***** END LICENSE BLOCK *****
 
 DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = browser/base/content/test
 
-DIRS += \
-		tabview \
-		$(NULL)
-
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES = \
 		test_feed_discovery.html \
 		feed_discovery.html \
 		test_bug395533.html \
 		bug395533-data.txt \
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -44,20 +44,16 @@ browser.jar:
 *       content/browser/safeMode.js                   (content/safeMode.js)
 *       content/browser/safeMode.xul                  (content/safeMode.xul)
 *       content/browser/sanitize.js                   (content/sanitize.js)
 *       content/browser/sanitize.xul                  (content/sanitize.xul)
 *       content/browser/sanitizeDialog.js             (content/sanitizeDialog.js)
         content/browser/sanitizeDialog.css            (content/sanitizeDialog.css)
 *       content/browser/tabbrowser.css                (content/tabbrowser.css)
 *       content/browser/tabbrowser.xml                (content/tabbrowser.xml)
-        content/browser/tabview.css                   (content/tabview/tabview.css)
-*       content/browser/tabview.js                    (content/tabview/tabview.js)
-        content/browser/tabview.html                  (content/tabview/tabview.html)
-        content/browser/tabview-content.js            (content/tabview/content.js)
 *       content/browser/urlbarBindings.xml            (content/urlbarBindings.xml)
 *       content/browser/utilityOverlay.js             (content/utilityOverlay.js)
 *       content/browser/web-panels.js                 (content/web-panels.js)
 *       content/browser/web-panels.xul                (content/web-panels.xul)
 *       content/browser/baseMenuOverlay.xul           (content/baseMenuOverlay.xul)
 *       content/browser/nsContextMenu.js              (content/nsContextMenu.js)
 #ifdef MOZ_SERVICES_SYNC
 *       content/browser/aboutSyncTabs.xul             (content/aboutSyncTabs.xul)
--- a/browser/components/Makefile.in
+++ b/browser/components/Makefile.in
@@ -65,16 +65,17 @@ PARALLEL_DIRS = \
   feeds \
   places \
   preferences \
   privatebrowsing \
   search \
   sessionstore \
   shell \
   sidebar/src \
+  tabview \
   migration \
   $(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows) 
 PARALLEL_DIRS += wintaskbar
 endif
 
 ifdef MOZ_SAFE_BROWSING
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_searchbar.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_searchbar.js
@@ -36,25 +36,33 @@
  * ***** END LICENSE BLOCK ***** */
 
 // This test makes sure that the search bar is cleared when leaving the
 // private browsing mode.
 
 function test() {
   // initialization
   waitForExplicitFinish();
-  gPrefService.setBoolPref("browser.privatebrowsing.keep_current_session", true);
   let pb = Cc["@mozilla.org/privatebrowsing;1"].
            getService(Ci.nsIPrivateBrowsingService);
 
-  // fill in the search bar with something
+  // fill in the search bar with something, twice to populate undo history
   const kTestSearchString = "privatebrowsing";
   let searchBar = BrowserSearch.searchBar;
+  searchBar.value = kTestSearchString + "foo";
   searchBar.value = kTestSearchString;
 
+  gPrefService.setBoolPref("browser.privatebrowsing.keep_current_session", true);
+
+  registerCleanupFunction(function () {
+    searchBar.textbox.reset();
+
+    gPrefService.clearUserPref("browser.privatebrowsing.keep_current_session");
+  });
+
   // enter private browsing mode
   pb.privateBrowsingEnabled = true;
 
   is(searchBar.value, kTestSearchString,
     "entering the private browsing mode should not clear the search bar");
   ok(searchBar.textbox.editor.transactionManager.numberOfUndoItems > 0,
     "entering the private browsing mode should not reset the undo list of the searchbar control");
 
@@ -80,13 +88,11 @@ function test() {
 
     var browser = gBrowser.selectedBrowser;
     is(typeof browser.engines, "undefined",
        "An engine should not be discovered in private browsing mode");
 
     gBrowser.removeTab(gBrowser.selectedTab);
     pb.privateBrowsingEnabled = false;
 
-    // cleanup
-    gPrefService.clearUserPref("browser.privatebrowsing.keep_current_session");
     finish();
   }, true);
 }
copy from browser/components/places/Makefile.in
copy to browser/components/tabview/Makefile.in
--- a/browser/components/places/Makefile.in
+++ b/browser/components/tabview/Makefile.in
@@ -38,17 +38,16 @@
 
 DEPTH		= ../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-DIRS = src
-
 ifdef ENABLE_TESTS
-	DIRS += tests
+	DIRS += test
 endif
 
 include $(topsrcdir)/config/rules.mk
 
-XPIDL_FLAGS += -I$(topsrcdir)/browser/components/
+libs::
+	$(NSINSTALL) $(srcdir)/modules/* $(FINAL_TARGET)/modules/tabview
rename from browser/base/content/tabview/content.js
rename to browser/components/tabview/content.js
rename from browser/base/content/tabview/drag.js
rename to browser/components/tabview/drag.js
rename from browser/base/content/tabview/groupitems.js
rename to browser/components/tabview/groupitems.js
rename from browser/base/content/tabview/iq.js
rename to browser/components/tabview/iq.js
rename from browser/base/content/tabview/items.js
rename to browser/components/tabview/items.js
new file mode 100644
--- /dev/null
+++ b/browser/components/tabview/jar.mn
@@ -0,0 +1,5 @@
+browser.jar:
+        content/browser/tabview.css                   (tabview.css)
+*       content/browser/tabview.js                    (tabview.js)
+        content/browser/tabview.html                  (tabview.html)
+        content/browser/tabview-content.js            (content.js)
rename from browser/base/content/tabview/modules/utils.jsm
rename to browser/components/tabview/modules/utils.jsm
rename from browser/base/content/tabview/search.js
rename to browser/components/tabview/search.js
rename from browser/base/content/tabview/storage.js
rename to browser/components/tabview/storage.js
rename from browser/base/content/tabview/storagePolicy.js
rename to browser/components/tabview/storagePolicy.js
rename from browser/base/content/tabview/tabitems.js
rename to browser/components/tabview/tabitems.js
rename from browser/base/content/tabview/tabview.css
rename to browser/components/tabview/tabview.css
rename from browser/base/content/tabview/tabview.html
rename to browser/components/tabview/tabview.html
rename from browser/base/content/tabview/tabview.js
rename to browser/components/tabview/tabview.js
rename from browser/base/content/test/tabview/Makefile.in
rename to browser/components/tabview/test/Makefile.in
--- a/browser/base/content/test/tabview/Makefile.in
+++ b/browser/components/tabview/test/Makefile.in
@@ -29,21 +29,21 @@
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
-DEPTH		= ../../../../..
+DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
-relativesrcdir  = browser/base/content/test/tabview
+relativesrcdir  = browser/components/tabview/test
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_FILES = \
                  browser_tabview_alltabs.js \
                  browser_tabview_apptabs.js \
                  browser_tabview_bug580412.js \
rename from browser/base/content/test/tabview/browser_tabview_alltabs.js
rename to browser/components/tabview/test/browser_tabview_alltabs.js
rename from browser/base/content/test/tabview/browser_tabview_apptabs.js
rename to browser/components/tabview/test/browser_tabview_apptabs.js
rename from browser/base/content/test/tabview/browser_tabview_bug580412.js
rename to browser/components/tabview/test/browser_tabview_bug580412.js
rename from browser/base/content/test/tabview/browser_tabview_bug586553.js
rename to browser/components/tabview/test/browser_tabview_bug586553.js
rename from browser/base/content/test/tabview/browser_tabview_bug587043.js
rename to browser/components/tabview/test/browser_tabview_bug587043.js
rename from browser/base/content/test/tabview/browser_tabview_bug587231.js
rename to browser/components/tabview/test/browser_tabview_bug587231.js
rename from browser/base/content/test/tabview/browser_tabview_bug587276.js
rename to browser/components/tabview/test/browser_tabview_bug587276.js
rename from browser/base/content/test/tabview/browser_tabview_bug587351.js
rename to browser/components/tabview/test/browser_tabview_bug587351.js
rename from browser/base/content/test/tabview/browser_tabview_bug587503.js
rename to browser/components/tabview/test/browser_tabview_bug587503.js
rename from browser/base/content/test/tabview/browser_tabview_bug587990.js
rename to browser/components/tabview/test/browser_tabview_bug587990.js
rename from browser/base/content/test/tabview/browser_tabview_bug588265.js
rename to browser/components/tabview/test/browser_tabview_bug588265.js
rename from browser/base/content/test/tabview/browser_tabview_bug589324.js
rename to browser/components/tabview/test/browser_tabview_bug589324.js
--- a/browser/base/content/test/tabview/browser_tabview_bug589324.js
+++ b/browser/components/tabview/test/browser_tabview_bug589324.js
@@ -1,12 +1,12 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const DUMMY_PAGE_URL = "http://mochi.test:8888/browser/browser/base/content/test/tabview/dummy_page.html";
+const DUMMY_PAGE_URL = "http://mochi.test:8888/browser/browser/components/tabview/test/dummy_page.html";
 const DUMMY_PAGE_URL_2 = "http://mochi.test:8888/";
 
 let state = {
   windows: [{
     tabs: [{
       entries: [{ url: DUMMY_PAGE_URL }],
       hidden: true,
       attributes: {},
rename from browser/base/content/test/tabview/browser_tabview_bug590606.js
rename to browser/components/tabview/test/browser_tabview_bug590606.js
rename from browser/base/content/test/tabview/browser_tabview_bug591706.js
rename to browser/components/tabview/test/browser_tabview_bug591706.js
rename from browser/base/content/test/tabview/browser_tabview_bug593283.js
rename to browser/components/tabview/test/browser_tabview_bug593283.js
rename from browser/base/content/test/tabview/browser_tabview_bug594958.js
rename to browser/components/tabview/test/browser_tabview_bug594958.js
new file mode 100644
--- /dev/null
+++ b/browser/components/tabview/test/browser_tabview_bug595020.js
@@ -0,0 +1,39 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
+
+let stateStartup = {windows:[
+  {tabs:[{entries:[{url:"about:home"}]}], extData:{"tabview-last-session-group-name":"title"}}
+]};
+
+function test() {
+  let assertWindowTitle = function (win, title) {
+    let browser = win.gBrowser.tabs[0].linkedBrowser;
+    let winTitle = win.gBrowser.getWindowTitleForBrowser(browser);
+
+    info('window title is: "' + winTitle + '"');
+    is(winTitle.indexOf(title), 0, "title starts with '" + title + "'");
+  };
+
+  let testGroupNameChange = function (win) {
+    showTabView(function () {
+      let cw = win.TabView.getContentWindow();
+      let groupItem = cw.GroupItems.groupItems[0];
+      groupItem.setTitle("new-title");
+
+      hideTabView(function () {
+        assertWindowTitle(win, "new-title");
+        finish();
+      }, win);
+    }, win);
+  };
+
+  waitForExplicitFinish();
+
+  newWindowWithState(stateStartup, function (win) {
+    registerCleanupFunction(function () win.close());
+    assertWindowTitle(win, "title");
+    testGroupNameChange(win);
+  });
+}
rename from browser/base/content/test/tabview/browser_tabview_bug595191.js
rename to browser/components/tabview/test/browser_tabview_bug595191.js
rename from browser/base/content/test/tabview/browser_tabview_bug595436.js
rename to browser/components/tabview/test/browser_tabview_bug595436.js
rename from browser/base/content/test/tabview/browser_tabview_bug595518.js
rename to browser/components/tabview/test/browser_tabview_bug595518.js
rename from browser/base/content/test/tabview/browser_tabview_bug595521.js
rename to browser/components/tabview/test/browser_tabview_bug595521.js
rename from browser/base/content/test/tabview/browser_tabview_bug595560.js
rename to browser/components/tabview/test/browser_tabview_bug595560.js
rename from browser/base/content/test/tabview/browser_tabview_bug595601.js
rename to browser/components/tabview/test/browser_tabview_bug595601.js
rename from browser/base/content/test/tabview/browser_tabview_bug595804.js
rename to browser/components/tabview/test/browser_tabview_bug595804.js
rename from browser/base/content/test/tabview/browser_tabview_bug595930.js
rename to browser/components/tabview/test/browser_tabview_bug595930.js
rename from browser/base/content/test/tabview/browser_tabview_bug595943.js
rename to browser/components/tabview/test/browser_tabview_bug595943.js
rename from browser/base/content/test/tabview/browser_tabview_bug595965.js
rename to browser/components/tabview/test/browser_tabview_bug595965.js
rename from browser/base/content/test/tabview/browser_tabview_bug596781.js
rename to browser/components/tabview/test/browser_tabview_bug596781.js
rename from browser/base/content/test/tabview/browser_tabview_bug597248.js
rename to browser/components/tabview/test/browser_tabview_bug597248.js
--- a/browser/base/content/test/tabview/browser_tabview_bug597248.js
+++ b/browser/components/tabview/test/browser_tabview_bug597248.js
@@ -11,18 +11,18 @@ let frameInitialized = false;
 function test() {
   waitForExplicitFinish();
   newWindowWithTabView(setupOne);
 }
 
 function setupOne(win) {
   win.TabView.firstUseExperienced = true;
 
-  win.gBrowser.addTab("http://mochi.test:8888/browser/browser/base/content/test/tabview/search1.html");
-  win.gBrowser.addTab("http://mochi.test:8888/browser/browser/base/content/test/tabview/dummy_page.html");
+  win.gBrowser.addTab("http://mochi.test:8888/browser/browser/components/tabview/test/search1.html");
+  win.gBrowser.addTab("http://mochi.test:8888/browser/browser/components/tabview/test/dummy_page.html");
 
   afterAllTabsLoaded(function () setupTwo(win), win);
 }
 
 let restoredWin;
 
 function setupTwo(win) {
   let contentWindow = win.TabView.getContentWindow();
rename from browser/base/content/test/tabview/browser_tabview_bug597360.js
rename to browser/components/tabview/test/browser_tabview_bug597360.js
rename from browser/base/content/test/tabview/browser_tabview_bug597399.js
rename to browser/components/tabview/test/browser_tabview_bug597399.js
rename from browser/base/content/test/tabview/browser_tabview_bug597980.js
rename to browser/components/tabview/test/browser_tabview_bug597980.js
rename from browser/base/content/test/tabview/browser_tabview_bug598375.js
rename to browser/components/tabview/test/browser_tabview_bug598375.js
rename from browser/base/content/test/tabview/browser_tabview_bug598600.js
rename to browser/components/tabview/test/browser_tabview_bug598600.js
rename from browser/base/content/test/tabview/browser_tabview_bug599048.js
rename to browser/components/tabview/test/browser_tabview_bug599048.js
rename from browser/base/content/test/tabview/browser_tabview_bug599626.js
rename to browser/components/tabview/test/browser_tabview_bug599626.js
rename from browser/base/content/test/tabview/browser_tabview_bug600645.js
rename to browser/components/tabview/test/browser_tabview_bug600645.js
--- a/browser/base/content/test/tabview/browser_tabview_bug600645.js
+++ b/browser/components/tabview/test/browser_tabview_bug600645.js
@@ -63,10 +63,10 @@ function onTabViewWindowLoaded() {
       }
       window.addEventListener("tabviewhidden", endGame, false);
       TabView.toggle();
     });
   };
   newTab.addEventListener("error", errorHandler, false);
 
   newTab.linkedBrowser.loadURI(
-    "http://mochi.test:8888/browser/browser/base/content/test/tabview/test_bug600645.html");
+    "http://mochi.test:8888/browser/browser/components/tabview/test/test_bug600645.html");
 }
rename from browser/base/content/test/tabview/browser_tabview_bug600812.js
rename to browser/components/tabview/test/browser_tabview_bug600812.js
rename from browser/base/content/test/tabview/browser_tabview_bug602432.js
rename to browser/components/tabview/test/browser_tabview_bug602432.js
rename from browser/base/content/test/tabview/browser_tabview_bug604098.js
rename to browser/components/tabview/test/browser_tabview_bug604098.js
rename from browser/base/content/test/tabview/browser_tabview_bug606657.js
rename to browser/components/tabview/test/browser_tabview_bug606657.js
rename from browser/base/content/test/tabview/browser_tabview_bug606905.js
rename to browser/components/tabview/test/browser_tabview_bug606905.js
rename from browser/base/content/test/tabview/browser_tabview_bug607108.js
rename to browser/components/tabview/test/browser_tabview_bug607108.js
rename from browser/base/content/test/tabview/browser_tabview_bug608037.js
rename to browser/components/tabview/test/browser_tabview_bug608037.js
--- a/browser/base/content/test/tabview/browser_tabview_bug608037.js
+++ b/browser/components/tabview/test/browser_tabview_bug608037.js
@@ -3,17 +3,17 @@
 
 let tabOne;
 let tabTwo;
 
 function test() {
   waitForExplicitFinish();
 
   tabOne = gBrowser.addTab("http://mochi.test:8888/");
-  tabTwo = gBrowser.addTab("http://mochi.test:8888/browser/browser/base/content/test/tabview/dummy_page.html");
+  tabTwo = gBrowser.addTab("http://mochi.test:8888/browser/browser/components/tabview/test/dummy_page.html");
 
   afterAllTabsLoaded(function () {
     // make sure the tab one is selected because undoCloseTab() would remove
     // the selected tab if it's a blank tab.
     gBrowser.selectedTab = tabOne;
     showTabView(onTabViewWindowLoaded);
   });
 }
rename from browser/base/content/test/tabview/browser_tabview_bug608158.js
rename to browser/components/tabview/test/browser_tabview_bug608158.js
rename from browser/base/content/test/tabview/browser_tabview_bug608184.js
rename to browser/components/tabview/test/browser_tabview_bug608184.js
rename from browser/base/content/test/tabview/browser_tabview_bug608405.js
rename to browser/components/tabview/test/browser_tabview_bug608405.js
rename from browser/base/content/test/tabview/browser_tabview_bug610208.js
rename to browser/components/tabview/test/browser_tabview_bug610208.js
rename from browser/base/content/test/tabview/browser_tabview_bug610242.js
rename to browser/components/tabview/test/browser_tabview_bug610242.js
rename from browser/base/content/test/tabview/browser_tabview_bug612470.js
rename to browser/components/tabview/test/browser_tabview_bug612470.js
rename from browser/base/content/test/tabview/browser_tabview_bug613541.js
rename to browser/components/tabview/test/browser_tabview_bug613541.js
rename from browser/base/content/test/tabview/browser_tabview_bug616729.js
rename to browser/components/tabview/test/browser_tabview_bug616729.js
rename from browser/base/content/test/tabview/browser_tabview_bug616967.js
rename to browser/components/tabview/test/browser_tabview_bug616967.js
rename from browser/base/content/test/tabview/browser_tabview_bug618816.js
rename to browser/components/tabview/test/browser_tabview_bug618816.js
rename from browser/base/content/test/tabview/browser_tabview_bug618828.js
rename to browser/components/tabview/test/browser_tabview_bug618828.js
rename from browser/base/content/test/tabview/browser_tabview_bug619937.js
rename to browser/components/tabview/test/browser_tabview_bug619937.js
rename from browser/base/content/test/tabview/browser_tabview_bug622835.js
rename to browser/components/tabview/test/browser_tabview_bug622835.js
rename from browser/base/content/test/tabview/browser_tabview_bug623768.js
rename to browser/components/tabview/test/browser_tabview_bug623768.js
rename from browser/base/content/test/tabview/browser_tabview_bug624265.js
rename to browser/components/tabview/test/browser_tabview_bug624265.js
rename from browser/base/content/test/tabview/browser_tabview_bug624692.js
rename to browser/components/tabview/test/browser_tabview_bug624692.js
rename from browser/base/content/test/tabview/browser_tabview_bug624727.js
rename to browser/components/tabview/test/browser_tabview_bug624727.js
rename from browser/base/content/test/tabview/browser_tabview_bug624847.js
rename to browser/components/tabview/test/browser_tabview_bug624847.js
rename from browser/base/content/test/tabview/browser_tabview_bug624931.js
rename to browser/components/tabview/test/browser_tabview_bug624931.js
rename from browser/base/content/test/tabview/browser_tabview_bug624953.js
rename to browser/components/tabview/test/browser_tabview_bug624953.js
rename from browser/base/content/test/tabview/browser_tabview_bug625195.js
rename to browser/components/tabview/test/browser_tabview_bug625195.js
rename from browser/base/content/test/tabview/browser_tabview_bug625269.js
rename to browser/components/tabview/test/browser_tabview_bug625269.js
rename from browser/base/content/test/tabview/browser_tabview_bug625424.js
rename to browser/components/tabview/test/browser_tabview_bug625424.js
rename from browser/base/content/test/tabview/browser_tabview_bug625955.js
rename to browser/components/tabview/test/browser_tabview_bug625955.js
rename from browser/base/content/test/tabview/browser_tabview_bug626368.js
rename to browser/components/tabview/test/browser_tabview_bug626368.js
rename from browser/base/content/test/tabview/browser_tabview_bug626455.js
rename to browser/components/tabview/test/browser_tabview_bug626455.js
rename from browser/base/content/test/tabview/browser_tabview_bug626525.js
rename to browser/components/tabview/test/browser_tabview_bug626525.js
rename from browser/base/content/test/tabview/browser_tabview_bug626791.js
rename to browser/components/tabview/test/browser_tabview_bug626791.js
rename from browser/base/content/test/tabview/browser_tabview_bug627288.js
rename to browser/components/tabview/test/browser_tabview_bug627288.js
rename from browser/base/content/test/tabview/browser_tabview_bug627736.js
rename to browser/components/tabview/test/browser_tabview_bug627736.js
rename from browser/base/content/test/tabview/browser_tabview_bug628061.js
rename to browser/components/tabview/test/browser_tabview_bug628061.js
rename from browser/base/content/test/tabview/browser_tabview_bug628165.js
rename to browser/components/tabview/test/browser_tabview_bug628165.js
rename from browser/base/content/test/tabview/browser_tabview_bug628270.js
rename to browser/components/tabview/test/browser_tabview_bug628270.js
rename from browser/base/content/test/tabview/browser_tabview_bug628887.js
rename to browser/components/tabview/test/browser_tabview_bug628887.js
rename from browser/base/content/test/tabview/browser_tabview_bug629189.js
rename to browser/components/tabview/test/browser_tabview_bug629189.js
rename from browser/base/content/test/tabview/browser_tabview_bug629195.js
rename to browser/components/tabview/test/browser_tabview_bug629195.js
rename from browser/base/content/test/tabview/browser_tabview_bug630102.js
rename to browser/components/tabview/test/browser_tabview_bug630102.js
rename from browser/base/content/test/tabview/browser_tabview_bug630157.js
rename to browser/components/tabview/test/browser_tabview_bug630157.js
rename from browser/base/content/test/tabview/browser_tabview_bug631662.js
rename to browser/components/tabview/test/browser_tabview_bug631662.js
rename from browser/base/content/test/tabview/browser_tabview_bug631752.js
rename to browser/components/tabview/test/browser_tabview_bug631752.js
rename from browser/base/content/test/tabview/browser_tabview_bug633190.js
rename to browser/components/tabview/test/browser_tabview_bug633190.js
rename from browser/base/content/test/tabview/browser_tabview_bug633788.js
rename to browser/components/tabview/test/browser_tabview_bug633788.js
rename from browser/base/content/test/tabview/browser_tabview_bug634077.js
rename to browser/components/tabview/test/browser_tabview_bug634077.js
rename from browser/base/content/test/tabview/browser_tabview_bug634085.js
rename to browser/components/tabview/test/browser_tabview_bug634085.js
rename from browser/base/content/test/tabview/browser_tabview_bug634672.js
rename to browser/components/tabview/test/browser_tabview_bug634672.js
rename from browser/base/content/test/tabview/browser_tabview_bug635696.js
rename to browser/components/tabview/test/browser_tabview_bug635696.js
rename from browser/base/content/test/tabview/browser_tabview_bug637840.js
rename to browser/components/tabview/test/browser_tabview_bug637840.js
rename from browser/base/content/test/tabview/browser_tabview_bug640765.js
rename to browser/components/tabview/test/browser_tabview_bug640765.js
rename from browser/base/content/test/tabview/browser_tabview_bug641802.js
rename to browser/components/tabview/test/browser_tabview_bug641802.js
rename from browser/base/content/test/tabview/browser_tabview_bug642793.js
rename to browser/components/tabview/test/browser_tabview_bug642793.js
rename from browser/base/content/test/tabview/browser_tabview_bug643392.js
rename to browser/components/tabview/test/browser_tabview_bug643392.js
rename from browser/base/content/test/tabview/browser_tabview_bug644097.js
rename to browser/components/tabview/test/browser_tabview_bug644097.js
--- a/browser/base/content/test/tabview/browser_tabview_bug644097.js
+++ b/browser/components/tabview/test/browser_tabview_bug644097.js
@@ -7,17 +7,17 @@ function test() {
   newWindowWithTabView(function (win) {
     registerCleanupFunction(function () win.close());
 
     let cw = win.TabView.getContentWindow();
     let groupItem = cw.GroupItems.groupItems[0];
 
     // create some tabs with favIcons
     for (let i = 0; i < 3; i++)
-      win.gBrowser.loadOneTab("http://mochi.test:8888/browser/browser/base/content/test/tabview/test_bug644097.html", {inBackground: true});
+      win.gBrowser.loadOneTab("http://mochi.test:8888/browser/browser/components/tabview/test/test_bug644097.html", {inBackground: true});
 
     win.gBrowser.removeTab(win.gBrowser.tabs[0]);
 
     // shrink the group until it stacks
     let size = 400;
     while (!groupItem.isStacked() && --size)
       groupItem.setSize(size, size, true);
 
rename from browser/base/content/test/tabview/browser_tabview_bug648882.js
rename to browser/components/tabview/test/browser_tabview_bug648882.js
rename from browser/base/content/test/tabview/browser_tabview_bug649006.js
rename to browser/components/tabview/test/browser_tabview_bug649006.js
rename from browser/base/content/test/tabview/browser_tabview_bug649307.js
rename to browser/components/tabview/test/browser_tabview_bug649307.js
rename from browser/base/content/test/tabview/browser_tabview_bug649319.js
rename to browser/components/tabview/test/browser_tabview_bug649319.js
rename from browser/base/content/test/tabview/browser_tabview_bug650280.js
rename to browser/components/tabview/test/browser_tabview_bug650280.js
rename from browser/base/content/test/tabview/browser_tabview_bug650573.js
rename to browser/components/tabview/test/browser_tabview_bug650573.js
rename from browser/base/content/test/tabview/browser_tabview_bug651311.js
rename to browser/components/tabview/test/browser_tabview_bug651311.js
rename from browser/base/content/test/tabview/browser_tabview_bug654295.js
rename to browser/components/tabview/test/browser_tabview_bug654295.js
rename from browser/base/content/test/tabview/browser_tabview_bug654721.js
rename to browser/components/tabview/test/browser_tabview_bug654721.js
rename from browser/base/content/test/tabview/browser_tabview_bug654941.js
rename to browser/components/tabview/test/browser_tabview_bug654941.js
rename from browser/base/content/test/tabview/browser_tabview_bug655269.js
rename to browser/components/tabview/test/browser_tabview_bug655269.js
rename from browser/base/content/test/tabview/browser_tabview_bug656778.js
rename to browser/components/tabview/test/browser_tabview_bug656778.js
rename from browser/base/content/test/tabview/browser_tabview_bug656913.js
rename to browser/components/tabview/test/browser_tabview_bug656913.js
--- a/browser/base/content/test/tabview/browser_tabview_bug656913.js
+++ b/browser/components/tabview/test/browser_tabview_bug656913.js
@@ -1,16 +1,16 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // ----------
 function test() {
   waitForExplicitFinish();
 
-  let urlBase = "http://mochi.test:8888/browser/browser/base/content/test/tabview/";
+  let urlBase = "http://mochi.test:8888/browser/browser/components/tabview/test/";
   let newTab = gBrowser.addTab(urlBase + "search1.html");
 
   registerCleanupFunction(function() {
     if (gBrowser.tabs[1])
       gBrowser.removeTab(gBrowser.tabs[1]);
     TabView.hide();
   });
 
rename from browser/base/content/test/tabview/browser_tabview_bug662266.js
rename to browser/components/tabview/test/browser_tabview_bug662266.js
rename from browser/base/content/test/tabview/browser_tabview_bug663421.js
rename to browser/components/tabview/test/browser_tabview_bug663421.js
rename from browser/base/content/test/tabview/browser_tabview_bug665502.js
rename to browser/components/tabview/test/browser_tabview_bug665502.js
rename from browser/base/content/test/tabview/browser_tabview_bug669694.js
rename to browser/components/tabview/test/browser_tabview_bug669694.js
rename from browser/base/content/test/tabview/browser_tabview_bug673196.js
rename to browser/components/tabview/test/browser_tabview_bug673196.js
rename from browser/base/content/test/tabview/browser_tabview_bug673729.js
rename to browser/components/tabview/test/browser_tabview_bug673729.js
rename from browser/base/content/test/tabview/browser_tabview_bug677310.js
rename to browser/components/tabview/test/browser_tabview_bug677310.js
rename from browser/base/content/test/tabview/browser_tabview_bug679853.js
rename to browser/components/tabview/test/browser_tabview_bug679853.js
rename from browser/base/content/test/tabview/browser_tabview_bug681599.js
rename to browser/components/tabview/test/browser_tabview_bug681599.js
rename from browser/base/content/test/tabview/browser_tabview_bug685476.js
rename to browser/components/tabview/test/browser_tabview_bug685476.js
rename from browser/base/content/test/tabview/browser_tabview_bug685692.js
rename to browser/components/tabview/test/browser_tabview_bug685692.js
rename from browser/base/content/test/tabview/browser_tabview_bug686654.js
rename to browser/components/tabview/test/browser_tabview_bug686654.js
rename from browser/base/content/test/tabview/browser_tabview_click_group.js
rename to browser/components/tabview/test/browser_tabview_click_group.js
rename from browser/base/content/test/tabview/browser_tabview_dragdrop.js
rename to browser/components/tabview/test/browser_tabview_dragdrop.js
rename from browser/base/content/test/tabview/browser_tabview_exit_button.js
rename to browser/components/tabview/test/browser_tabview_exit_button.js
rename from browser/base/content/test/tabview/browser_tabview_expander.js
rename to browser/components/tabview/test/browser_tabview_expander.js
rename from browser/base/content/test/tabview/browser_tabview_firstrun_pref.js
rename to browser/components/tabview/test/browser_tabview_firstrun_pref.js
rename from browser/base/content/test/tabview/browser_tabview_group.js
rename to browser/components/tabview/test/browser_tabview_group.js
rename from browser/base/content/test/tabview/browser_tabview_launch.js
rename to browser/components/tabview/test/browser_tabview_launch.js
rename from browser/base/content/test/tabview/browser_tabview_layout.js
rename to browser/components/tabview/test/browser_tabview_layout.js
rename from browser/base/content/test/tabview/browser_tabview_multiwindow_search.js
rename to browser/components/tabview/test/browser_tabview_multiwindow_search.js
rename from browser/base/content/test/tabview/browser_tabview_privatebrowsing.js
rename to browser/components/tabview/test/browser_tabview_privatebrowsing.js
rename from browser/base/content/test/tabview/browser_tabview_rtl.js
rename to browser/components/tabview/test/browser_tabview_rtl.js
rename from browser/base/content/test/tabview/browser_tabview_search.js
rename to browser/components/tabview/test/browser_tabview_search.js
--- a/browser/base/content/test/tabview/browser_tabview_search.js
+++ b/browser/components/tabview/test/browser_tabview_search.js
@@ -3,17 +3,17 @@
 
 let newTabs = [];
 
 // ----------
 function test() {
   waitForExplicitFinish();
 
   // set up our tabs
-  let urlBase = "http://mochi.test:8888/browser/browser/base/content/test/tabview/";
+  let urlBase = "http://mochi.test:8888/browser/browser/components/tabview/test/";
   let tabOne = gBrowser.addTab(urlBase + "search1.html");
   let tabTwo = gBrowser.addTab(urlBase + "search2.html");
   newTabs = [ tabOne, tabTwo ];
 
   // make sure our tabs are loaded so their titles are right
   let stillToLoad = 0; 
   let onLoad = function() {
     this.removeEventListener("load", onLoad, true);
rename from browser/base/content/test/tabview/browser_tabview_snapping.js
rename to browser/components/tabview/test/browser_tabview_snapping.js
rename from browser/base/content/test/tabview/browser_tabview_startup_transitions.js
rename to browser/components/tabview/test/browser_tabview_startup_transitions.js
rename from browser/base/content/test/tabview/browser_tabview_storage_policy.js
rename to browser/components/tabview/test/browser_tabview_storage_policy.js
--- a/browser/base/content/test/tabview/browser_tabview_storage_policy.js
+++ b/browser/components/tabview/test/browser_tabview_storage_policy.js
@@ -43,17 +43,17 @@ function test1() {
     ok(!contentWindow.StoragePolicy.canStoreThumbnailForTab(newTab), 
        "Should not save the thumbnail for tab");
 
     whenDeniedToSaveImageData(tabItem, test2);
     tabItem.saveThumbnail({synchronously: true});
     HttpRequestObserver.cacheControlValue = null;
   });
 
-  newTab.linkedBrowser.loadURI("http://www.example.com/browser/browser/base/content/test/tabview/dummy_page.html");
+  newTab.linkedBrowser.loadURI("http://www.example.com/browser/browser/components/tabview/test/dummy_page.html");
 }
 
 function test2() {
   // page with cache-control: private, should save thumbnail
   HttpRequestObserver.cacheControlValue = "private";
 
   newTab.linkedBrowser.loadURI("http://www.example.com/");
   afterAllTabsLoaded(function() {
@@ -68,17 +68,17 @@ function test2() {
 }
 
 function test3() {
   // page with cache-control: private with https caching enabled, should save thumbnail
   HttpRequestObserver.cacheControlValue = "private";
 
   Services.prefs.setBoolPref(PREF_DISK_CACHE_SSL, true);
 
-  newTab.linkedBrowser.loadURI("https://example.com/browser/browser/base/content/test/tabview/dummy_page.html");
+  newTab.linkedBrowser.loadURI("https://example.com/browser/browser/components/tabview/test/dummy_page.html");
   afterAllTabsLoaded(function() {
     let tabItem = newTab._tabViewTabItem;
 
     ok(contentWindow.StoragePolicy.canStoreThumbnailForTab(newTab),
        "Should save the thumbnail for tab");
 
     whenSavedCachedImageData(tabItem, test4);
     tabItem.saveThumbnail({synchronously: true});
@@ -86,17 +86,17 @@ function test3() {
 }
 
 function test4() {
   // page with cache-control: public with https caching disabled, should save thumbnail
   HttpRequestObserver.cacheControlValue = "public";
 
   Services.prefs.setBoolPref(PREF_DISK_CACHE_SSL, false);
 
-  newTab.linkedBrowser.loadURI("https://example.com/browser/browser/base/content/test/tabview/");
+  newTab.linkedBrowser.loadURI("https://example.com/browser/browser/components/tabview/test/");
   afterAllTabsLoaded(function() {
     let tabItem = newTab._tabViewTabItem;
 
     ok(contentWindow.StoragePolicy.canStoreThumbnailForTab(newTab),
        "Should save the thumbnail for tab");
 
     whenSavedCachedImageData(tabItem, test5);
     tabItem.saveThumbnail({synchronously: true});
rename from browser/base/content/test/tabview/browser_tabview_thumbnail_storage.js
rename to browser/components/tabview/test/browser_tabview_thumbnail_storage.js
rename from browser/base/content/test/tabview/browser_tabview_undo_group.js
rename to browser/components/tabview/test/browser_tabview_undo_group.js
rename from browser/base/content/test/tabview/dummy_page.html
rename to browser/components/tabview/test/dummy_page.html
rename from browser/base/content/test/tabview/head.js
rename to browser/components/tabview/test/head.js
rename from browser/base/content/test/tabview/search1.html
rename to browser/components/tabview/test/search1.html
rename from browser/base/content/test/tabview/search2.html
rename to browser/components/tabview/test/search2.html
rename from browser/base/content/test/tabview/test_bug600645.html
rename to browser/components/tabview/test/test_bug600645.html
rename from browser/base/content/test/tabview/test_bug644097.html
rename to browser/components/tabview/test/test_bug644097.html
rename from browser/base/content/tabview/thumbnailStorage.js
rename to browser/components/tabview/thumbnailStorage.js
rename from browser/base/content/tabview/trench.js
rename to browser/components/tabview/trench.js
rename from browser/base/content/tabview/ui.js
rename to browser/components/tabview/ui.js
--- a/browser/installer/windows/nsis/shared.nsh
+++ b/browser/installer/windows/nsis/shared.nsh
@@ -284,17 +284,17 @@
   ${If} $7 == "false"
     WriteRegStr SHCTX "$0\.webm"  "" "FirefoxHTML"
   ${EndIf}
 
   StrCpy $3 "$\"%1$\",,0,0,,,,"
 
   ; An empty string is used for the 5th param because FirefoxHTML is not a
   ; protocol handler
-  ${AddDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" "${AppRegName} Document" "" \
+  ${AddDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" "${AppRegName} HTML Document" "" \
                          "${DDEApplication}" "$3" "WWW_OpenURL"
 
   ${AddDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" "true" \
                          "${DDEApplication}" "$3" "WWW_OpenURL"
 
   ; An empty string is used for the 4th & 5th params because the following
   ; protocol handlers already have a display name and the additional keys
   ; required for a protocol handler.
@@ -504,17 +504,17 @@
 
   ; Only set the file and protocol handlers if the existing one under HKCR is
   ; for this install location.
 
   ${IsHandlerForInstallDir} "FirefoxHTML" $R9
   ${If} "$R9" == "true"
     ; An empty string is used for the 5th param because FirefoxHTML is not a
     ; protocol handler.
-    ${AddDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" "${AppRegName} Document" "" \
+    ${AddDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" "${AppRegName} HTML Document" "" \
                            "${DDEApplication}" "$3" "WWW_OpenURL"
   ${EndIf}
 
   ${IsHandlerForInstallDir} "FirefoxURL" $R9
   ${If} "$R9" == "true"
     ${AddDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" "true" \
                            "${DDEApplication}" "$3" "WWW_OpenURL"
   ${EndIf}
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -1343,17 +1343,22 @@ nsIContent::GetFlattenedTreeParent() con
   }
   return parent;
 }
 
 PRUint32
 nsIContent::GetDesiredIMEState()
 {
   if (!IsEditableInternal()) {
-    return IME_STATUS_DISABLE;
+    // Check for the special case where we're dealing with elements which don't
+    // have the editable flag set, but are readwrite (such as text controls).
+    if (!IsElement() ||
+        !AsElement()->State().HasState(NS_EVENT_STATE_MOZ_READWRITE)) {
+      return IME_STATUS_DISABLE;
+    }
   }
   // NOTE: The content for independent editors (e.g., input[type=text],
   // textarea) must override this method, so, we don't need to worry about
   // that here.
   nsIContent *editableAncestor = GetEditingHost();
 
   // This is in another editable content, use the result of it.
   if (editableAncestor && editableAncestor != this) {
--- a/content/base/src/nsTextFragment.h
+++ b/content/base/src/nsTextFragment.h
@@ -224,17 +224,17 @@ public:
 
   /**
    * Returns the size taken in memory by this text fragment.
    * @return the size taken in memory by this text fragment.
    */
   PRInt64 SizeOf() const
   {
     PRInt64 size = sizeof(*this);
-    size += GetLength() * Is2b() ? sizeof(*m2b) : sizeof(*m1b);
+    size += GetLength() * (Is2b() ? sizeof(*m2b) : sizeof(*m1b));
     return size;
   }
 
 private:
   void ReleaseText();
 
   /**
    * Scan the contents of the fragment and turn on mState.mIsBidi if it
--- a/content/base/src/nsWebSocket.cpp
+++ b/content/base/src/nsWebSocket.cpp
@@ -50,17 +50,16 @@
 #include "nsContentUtils.h"
 #include "nsEventDispatcher.h"
 #include "nsDOMError.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsDOMClassInfoID.h"
 #include "jsapi.h"
 #include "nsIURL.h"
 #include "nsIPrivateDOMEvent.h"
-#include "nsIInterfaceRequestor.h"
 #include "nsICharsetConverterManager.h"
 #include "nsIUnicodeEncoder.h"
 #include "nsThreadUtils.h"
 #include "nsIDOMMessageEvent.h"
 #include "nsIPromptFactory.h"
 #include "nsIWindowWatcher.h"
 #include "nsIPrompt.h"
 #include "nsIStringBundle.h"
@@ -68,30 +67,23 @@
 #include "nsLayoutStatics.h"
 #include "nsIDOMCloseEvent.h"
 #include "nsICryptoHash.h"
 #include "jsdbgapi.h"
 #include "nsIJSContextStack.h"
 #include "nsJSUtils.h"
 #include "nsIScriptError.h"
 #include "nsNetUtil.h"
-#include "nsIWebSocketChannel.h"
-#include "nsIWebSocketListener.h"
 #include "nsILoadGroup.h"
-#include "nsIRequest.h"
 #include "mozilla/Preferences.h"
 #include "nsDOMLists.h"
 #include "xpcpublic.h"
 
 using namespace mozilla;
 
-////////////////////////////////////////////////////////////////////////////////
-// nsWebSocketEstablishedConnection
-////////////////////////////////////////////////////////////////////////////////
-
 #define UTF_8_REPLACEMENT_CHAR    static_cast<PRUnichar>(0xFFFD)
 
 #define ENSURE_TRUE_AND_FAIL_IF_FAILED(x, ret)                            \
   PR_BEGIN_MACRO                                                          \
     if (NS_UNLIKELY(!(x))) {                                              \
        NS_WARNING("ENSURE_TRUE_AND_FAIL_IF_FAILED(" #x ") failed");       \
        FailConnection();                                                  \
        return ret;                                                        \
@@ -103,233 +95,23 @@ using namespace mozilla;
     nsresult __rv = res;                                                  \
     if (NS_FAILED(__rv)) {                                                \
       NS_ENSURE_SUCCESS_BODY(res, ret)                                    \
       FailConnection();                                                   \
       return ret;                                                         \
     }                                                                     \
   PR_END_MACRO
 
-// nsIInterfaceRequestor will be the unambiguous class for this class
-class nsWebSocketEstablishedConnection: public nsIInterfaceRequestor,
-                                        public nsIWebSocketListener,
-                                        public nsIRequest
-{
-public:
-  nsWebSocketEstablishedConnection();
-  virtual ~nsWebSocketEstablishedConnection();
-
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIINTERFACEREQUESTOR
-  NS_DECL_NSIWEBSOCKETLISTENER
-  NS_DECL_NSIREQUEST
-
-  nsresult Init(nsWebSocket *aOwner);
-  nsresult Disconnect();
-
-  // these method when called can release both the WebSocket object
-  // (i.e. mOwner) and its connection (i.e. *this*).
-  nsresult Close();
-  nsresult FailConnection();
-  nsresult ConsoleError();
-
-  bool HasOutgoingMessages()
-  { return mOutgoingBufferedAmount != 0; }
-
-  bool ClosedCleanly() { return mClosedCleanly; }
-
-  nsresult PostMessage(const nsString& aMessage);
-  PRUint32 GetOutgoingBufferedAmount() { return mOutgoingBufferedAmount; }
-
-private:
-
-  nsresult PrintErrorOnConsole(const char       *aBundleURI,
-                               const PRUnichar  *aError,
-                               const PRUnichar **aFormatStrings,
-                               PRUint32          aFormatStringsLen);
-  nsresult UpdateMustKeepAlive();
-  
-  // Frames that have been sent to websockethandler but not placed on wire
-  PRUint32 mOutgoingBufferedAmount;
-
-  nsWebSocket* mOwner; // weak reference
-  nsCOMPtr<nsIWebSocketChannel> mWebSocketChannel;
-
-  bool mClosedCleanly;
-
-  enum ConnectionStatus {
-    CONN_NOT_CONNECTED,
-    CONN_CONNECTED_AND_READY,
-    CONN_CLOSED
-  };
-
-  ConnectionStatus mStatus;
-};
-
-//-----------------------------------------------------------------------------
-// nsWebSocketEstablishedConnection::nsISupports
-//-----------------------------------------------------------------------------
-
-NS_IMPL_THREADSAFE_ISUPPORTS3(nsWebSocketEstablishedConnection,
-                              nsIInterfaceRequestor,
-                              nsIWebSocketListener,
-                              nsIRequest)
-
-//-----------------------------------------------------------------------------
-// nsWebSocketEstablishedConnection methods:
-//-----------------------------------------------------------------------------
-
-nsWebSocketEstablishedConnection::nsWebSocketEstablishedConnection() :
-  mOutgoingBufferedAmount(0),
-  mOwner(nsnull),
-  mClosedCleanly(false),
-  mStatus(CONN_NOT_CONNECTED)
-{
-  NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
-  nsLayoutStatics::AddRef();
-}
-
-nsWebSocketEstablishedConnection::~nsWebSocketEstablishedConnection()
-{
-  NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
-  NS_ABORT_IF_FALSE(!mOwner, "Disconnect wasn't called!");
-  NS_ABORT_IF_FALSE(!mWebSocketChannel, "Disconnect wasn't called!");
-}
-
 nsresult
-nsWebSocketEstablishedConnection::PostMessage(const nsString& aMessage)
+nsWebSocket::PrintErrorOnConsole(const char *aBundleURI,
+                                 const PRUnichar *aError,
+                                 const PRUnichar **aFormatStrings,
+                                 PRUint32 aFormatStringsLen)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
-
-  if (!mOwner) {
-    return NS_OK;
-  }
-
-  // only send messages when connected
-  NS_ENSURE_STATE(mStatus >= CONN_CONNECTED_AND_READY);
-
-  nsresult rv;
-
-  nsCOMPtr<nsICharsetConverterManager> ccm =
-    do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
-  ENSURE_SUCCESS_AND_FAIL_IF_FAILED(rv, rv);
-
-  nsCOMPtr<nsIUnicodeEncoder> converter;
-  rv = ccm->GetUnicodeEncoder("UTF-8", getter_AddRefs(converter));
-  ENSURE_SUCCESS_AND_FAIL_IF_FAILED(rv, rv);
-
-  rv = converter->SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace,
-                                         nsnull, UTF_8_REPLACEMENT_CHAR);
-  ENSURE_SUCCESS_AND_FAIL_IF_FAILED(rv, rv);
-
-  PRInt32 inLen = aMessage.Length();
-  PRInt32 maxLen;
-  rv = converter->GetMaxLength(aMessage.BeginReading(), inLen, &maxLen);
-  ENSURE_SUCCESS_AND_FAIL_IF_FAILED(rv, rv);
-
-  nsCString buf;
-  buf.SetLength(maxLen);
-  ENSURE_TRUE_AND_FAIL_IF_FAILED(buf.Length() == static_cast<PRUint32>(maxLen),
-                                 NS_ERROR_OUT_OF_MEMORY);
-
-  char* start = buf.BeginWriting();
-
-  PRInt32 outLen = maxLen;
-  rv = converter->Convert(aMessage.BeginReading(), &inLen, start, &outLen);
-  if (NS_SUCCEEDED(rv)) {
-    PRInt32 outLen2 = maxLen - outLen;
-    rv = converter->Finish(start + outLen, &outLen2);
-    outLen += outLen2;
-  }
-  if (NS_FAILED(rv) || rv == NS_ERROR_UENC_NOMAPPING) {
-    // Yes, NS_ERROR_UENC_NOMAPPING is a success code
-    return NS_ERROR_DOM_SYNTAX_ERR;
-  }
-
-  buf.SetLength(outLen);
-  ENSURE_TRUE_AND_FAIL_IF_FAILED(buf.Length() == static_cast<PRUint32>(outLen),
-                                 NS_ERROR_UNEXPECTED);
-
-  if (mStatus == CONN_CLOSED) {
-    NS_ABORT_IF_FALSE(mOwner, "Posting data after disconnecting the websocket");
-    // the tcp connection has been closed, but the main thread hasn't received
-    // the event for disconnecting the object yet.
-    rv = NS_BASE_STREAM_CLOSED;
-  } else {
-    mOutgoingBufferedAmount += buf.Length();
-    mWebSocketChannel->SendMsg(buf);
-    rv = NS_OK;
-  }
-
-  UpdateMustKeepAlive();
-  ENSURE_SUCCESS_AND_FAIL_IF_FAILED(rv, rv);
-
-  return NS_OK;
-}
-
-nsresult
-nsWebSocketEstablishedConnection::Init(nsWebSocket *aOwner)
-{
-  NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
-  NS_ABORT_IF_FALSE(!mOwner, "WebSocket's connection is already initialized");
-
-  nsresult rv;
-  mOwner = aOwner;
-
-  if (mOwner->mSecure) {
-    mWebSocketChannel =
-      do_CreateInstance("@mozilla.org/network/protocol;1?name=wss", &rv);
-  }
-  else {
-    mWebSocketChannel =
-      do_CreateInstance("@mozilla.org/network/protocol;1?name=ws", &rv);
-  }
-  NS_ENSURE_SUCCESS(rv, rv);
-  
-  rv = mWebSocketChannel->SetNotificationCallbacks(this);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // add ourselves to the document's load group and
-  // provide the http stack the loadgroup info too
-  nsCOMPtr<nsILoadGroup> loadGroup;
-  rv = GetLoadGroup(getter_AddRefs(loadGroup));
-  if (loadGroup) {
-    rv = mWebSocketChannel->SetLoadGroup(loadGroup);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = loadGroup->AddRequest(this, nsnull);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  if (!mOwner->mRequestedProtocolList.IsEmpty()) {
-    rv = mWebSocketChannel->SetProtocol(mOwner->mRequestedProtocolList);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  nsCString asciiOrigin;
-  rv = nsContentUtils::GetASCIIOrigin(mOwner->mPrincipal, asciiOrigin);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  ToLowerCase(asciiOrigin);
-
-  rv = mWebSocketChannel->AsyncOpen(mOwner->mURI,
-                                    asciiOrigin, this, nsnull);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return NS_OK;
-}
-
-nsresult
-nsWebSocketEstablishedConnection::PrintErrorOnConsole(const char *aBundleURI,
-                                                      const PRUnichar *aError,
-                                                      const PRUnichar **aFormatStrings,
-                                                      PRUint32 aFormatStringsLen)
-{
-  NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
-  NS_ABORT_IF_FALSE(mOwner, "No owner");
-
   nsresult rv;
 
   nsCOMPtr<nsIStringBundleService> bundleService =
     do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIStringBundle> strBundle;
   rv = bundleService->CreateBundle(aBundleURI, getter_AddRefs(strBundle));
@@ -349,271 +131,244 @@ nsWebSocketEstablishedConnection::PrintE
     rv = strBundle->FormatStringFromName(aError, aFormatStrings,
                                          aFormatStringsLen,
                                          getter_Copies(message));
   } else {
     rv = strBundle->GetStringFromName(aError, getter_Copies(message));
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
-  errorObject->InitWithWindowID
-    (message.get(),
-     NS_ConvertUTF8toUTF16(mOwner->GetScriptFile()).get(),
-     nsnull,
-     mOwner->GetScriptLine(), 0, nsIScriptError::errorFlag,
-     "Web Socket", mOwner->InnerWindowID()
-     );
-  
+  errorObject->InitWithWindowID(message.get(),
+                                NS_ConvertUTF8toUTF16(mScriptFile).get(),
+                                nsnull, mScriptLine, 0,
+                                nsIScriptError::errorFlag, "Web Socket",
+                                mInnerWindowID);
+
   // print the error message directly to the JS console
   nsCOMPtr<nsIScriptError> logError(do_QueryInterface(errorObject));
   rv = console->LogMessage(logError);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 // when this is called the browser side wants no more part of it
 nsresult
-nsWebSocketEstablishedConnection::Close()
+nsWebSocket::CloseConnection()
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
-  if (!mOwner)
+  if (mDisconnected)
     return NS_OK;
 
   // Disconnect() can release this object, so we keep a
   // reference until the end of the method
-  nsRefPtr<nsWebSocketEstablishedConnection> kungfuDeathGrip = this;
+  nsRefPtr<nsWebSocket> kungfuDeathGrip = this;
 
-  if (mOwner->mReadyState == nsIMozWebSocket::CONNECTING) {
-    mOwner->SetReadyState(nsIMozWebSocket::CLOSED);
-    mWebSocketChannel->Close(mOwner->mClientReasonCode,
-                             mOwner->mClientReason);
+  if (mReadyState == nsIMozWebSocket::CONNECTING) {
+    SetReadyState(nsIMozWebSocket::CLOSED);
+    mWebSocketChannel->Close(mClientReasonCode, mClientReason);
     Disconnect();
     return NS_OK;
   }
 
-  mOwner->SetReadyState(nsIMozWebSocket::CLOSING);
+  SetReadyState(nsIMozWebSocket::CLOSING);
 
-  if (mStatus == CONN_CLOSED) {
-    mOwner->SetReadyState(nsIMozWebSocket::CLOSED);
+  if (mDisconnected) {
+    SetReadyState(nsIMozWebSocket::CLOSED);
     Disconnect();
     return NS_OK;
   }
 
-  return mWebSocketChannel->Close(mOwner->mClientReasonCode,
-                                  mOwner->mClientReason);
+  return mWebSocketChannel->Close(mClientReasonCode, mClientReason);
 }
 
 nsresult
-nsWebSocketEstablishedConnection::ConsoleError()
+nsWebSocket::ConsoleError()
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
   nsresult rv;
-  if (!mOwner) return NS_OK;
-  
+
   nsCAutoString targetSpec;
-  rv = mOwner->mURI->GetSpec(targetSpec);
+  rv = mURI->GetSpec(targetSpec);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to get targetSpec");
   } else {
     NS_ConvertUTF8toUTF16 specUTF16(targetSpec);
     const PRUnichar *formatStrings[] = { specUTF16.get() };
-    
-    if (mStatus < CONN_CONNECTED_AND_READY) {
+
+    if (mReadyState < nsIMozWebSocket::OPEN) {
       PrintErrorOnConsole("chrome://global/locale/appstrings.properties",
                           NS_LITERAL_STRING("connectionFailure").get(),
                           formatStrings, ArrayLength(formatStrings));
     } else {
       PrintErrorOnConsole("chrome://global/locale/appstrings.properties",
                           NS_LITERAL_STRING("netInterrupt").get(),
                           formatStrings, ArrayLength(formatStrings));
     }
   }
   /// todo some specific errors - like for message too large
   return rv;
 }
 
 
 nsresult
-nsWebSocketEstablishedConnection::FailConnection()
+nsWebSocket::FailConnection()
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
-  nsresult rv = ConsoleError();
-  Close();
-  return rv;
+  ConsoleError();
+
+  nsresult rv = CloseConnection();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("error"));
+  if (NS_FAILED(rv))
+    NS_WARNING("Failed to dispatch the error event");
+
+  return NS_OK;
 }
 
 nsresult
-nsWebSocketEstablishedConnection::Disconnect()
+nsWebSocket::Disconnect()
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
 
-  if (!mOwner) {
+  if (mDisconnected)
     return NS_OK;
-  }
-  
+
   nsCOMPtr<nsILoadGroup> loadGroup;
   GetLoadGroup(getter_AddRefs(loadGroup));
   if (loadGroup)
     loadGroup->RemoveRequest(this, nsnull, NS_OK);
 
-  // If mOwner is deleted when calling mOwner->DontKeepAliveAnyMore()
-  // then this method can be called again, and we will get a deadlock.
-  nsRefPtr<nsWebSocket> kungfuDeathGrip = mOwner;
-  
-  mOwner->DontKeepAliveAnyMore();
-  mStatus = CONN_CLOSED;
-  mOwner = nsnull;
-  mWebSocketChannel = nsnull;
+  // DontKeepAliveAnyMore() can release the object. So hold a reference to this
+  // until the end of the method.
+  nsRefPtr<nsWebSocket> kungfuDeathGrip = this;
 
-  nsLayoutStatics::Release();
-  return NS_OK;
-}
+  DontKeepAliveAnyMore();
+  mWebSocketChannel = nsnull;
+  mDisconnected = true;
 
-nsresult
-nsWebSocketEstablishedConnection::UpdateMustKeepAlive()
-{
-  NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
-  NS_ABORT_IF_FALSE(mOwner, "No owner");
-
-  mOwner->UpdateMustKeepAlive();
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
-// nsWebSocketEstablishedConnection::nsIWebSocketListener methods:
+// nsWebSocket::nsIWebSocketListener methods:
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::OnMessageAvailable(nsISupports *aContext,
-                                                     const nsACString & aMsg)
+nsWebSocket::OnMessageAvailable(nsISupports *aContext, const nsACString & aMsg)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
-  if (!mOwner)
-    return NS_ERROR_NOT_AVAILABLE;
-  
+
+  NS_ABORT_IF_FALSE(!mDisconnected, "Received message after disconnecting");
+
   // Dispatch New Message
-  nsresult rv = mOwner->CreateAndDispatchMessageEvent(aMsg);
+  nsresult rv = CreateAndDispatchMessageEvent(aMsg);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to dispatch the message event");
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::OnBinaryMessageAvailable(
-  nsISupports *aContext,
-  const nsACString & aMsg)
+nsWebSocket::OnBinaryMessageAvailable(nsISupports *aContext,
+                                      const nsACString & aMsg)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::OnStart(nsISupports *aContext)
+nsWebSocket::OnStart(nsISupports *aContext)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
-  if (!mOwner)
+  if (mDisconnected)
     return NS_OK;
 
-  if (!mOwner->mRequestedProtocolList.IsEmpty())
-    mWebSocketChannel->GetProtocol(mOwner->mEstablishedProtocol);
+  if (!mRequestedProtocolList.IsEmpty())
+    mWebSocketChannel->GetProtocol(mEstablishedProtocol);
 
-  mWebSocketChannel->GetExtensions(mOwner->mEstablishedExtensions);
+  mWebSocketChannel->GetExtensions(mEstablishedExtensions);
 
-  mStatus = CONN_CONNECTED_AND_READY;
-  mOwner->SetReadyState(nsIMozWebSocket::OPEN);
+  SetReadyState(nsIMozWebSocket::OPEN);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::OnStop(nsISupports *aContext,
-                                         nsresult aStatusCode)
+nsWebSocket::OnStop(nsISupports *aContext, nsresult aStatusCode)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
-  if (!mOwner)
+  if (mDisconnected)
     return NS_OK;
 
   mClosedCleanly = NS_SUCCEEDED(aStatusCode);
 
-  if (aStatusCode == NS_BASE_STREAM_CLOSED && 
-      mOwner->mReadyState >= nsIMozWebSocket::CLOSING) {
+  if (aStatusCode == NS_BASE_STREAM_CLOSED &&
+      mReadyState >= nsIMozWebSocket::CLOSING) {
     // don't generate an error event just because of an unclean close
     aStatusCode = NS_OK;
   }
 
   if (NS_FAILED(aStatusCode)) {
     ConsoleError();
-    if (mOwner) {
-      nsresult rv =
-        mOwner->CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("error"));
-      if (NS_FAILED(rv))
-        NS_WARNING("Failed to dispatch the error event");
-    }
+    nsresult rv = CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("error"));
+    if (NS_FAILED(rv))
+      NS_WARNING("Failed to dispatch the error event");
   }
 
-  mStatus = CONN_CLOSED;
-  if (mOwner) {
-    mOwner->SetReadyState(nsIMozWebSocket::CLOSED);
-    Disconnect();
-  }
+  SetReadyState(nsIMozWebSocket::CLOSED);
+  Disconnect();
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::OnAcknowledge(nsISupports *aContext,
-                                                PRUint32 aSize)
+nsWebSocket::OnAcknowledge(nsISupports *aContext, PRUint32 aSize)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
 
   if (aSize > mOutgoingBufferedAmount)
     return NS_ERROR_UNEXPECTED;
-  
+
   mOutgoingBufferedAmount -= aSize;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::OnServerClose(nsISupports *aContext,
-                                                PRUint16 aCode,
-                                                const nsACString &aReason)
+nsWebSocket::OnServerClose(nsISupports *aContext, PRUint16 aCode,
+                           const nsACString &aReason)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
-  if (mOwner) {
-    mOwner->mServerReasonCode = aCode;
-    CopyUTF8toUTF16(aReason, mOwner->mServerReason);
-  }
+  mServerReasonCode = aCode;
+  CopyUTF8toUTF16(aReason, mServerReason);
 
-  Close();                                        /* reciprocate! */
+  CloseConnection();                              /* reciprocate! */
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
-// nsWebSocketEstablishedConnection::nsIInterfaceRequestor
+// nsWebSocket::nsIInterfaceRequestor
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::GetInterface(const nsIID &aIID,
-                                               void **aResult)
+nsWebSocket::GetInterface(const nsIID &aIID, void **aResult)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
 
-  if (!mOwner)
+  if (mDisconnected)
     return NS_ERROR_FAILURE;
 
   if (aIID.Equals(NS_GET_IID(nsIAuthPrompt)) ||
       aIID.Equals(NS_GET_IID(nsIAuthPrompt2))) {
     nsresult rv;
 
     nsCOMPtr<nsIDocument> doc =
-      nsContentUtils::GetDocumentFromScriptContext(mOwner->mScriptContext);
-
-    if (!doc) {
+      nsContentUtils::GetDocumentFromScriptContext(mScriptContext);
+    if (!doc)
       return NS_ERROR_NOT_AVAILABLE;
-    }
 
     nsCOMPtr<nsIPromptFactory> wwatch =
       do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsPIDOMWindow> outerWindow = doc->GetWindow();
     return wwatch->GetPrompt(outerWindow, aIID, aResult);
   }
@@ -623,72 +378,73 @@ nsWebSocketEstablishedConnection::GetInt
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsWebSocket
 ////////////////////////////////////////////////////////////////////////////////
 
 nsWebSocket::nsWebSocket() : mKeepingAlive(false),
                              mCheckMustKeepAlive(true),
                              mTriggeredCloseEvent(false),
+                             mClosedCleanly(false),
+                             mDisconnected(false),
                              mClientReasonCode(0),
                              mServerReasonCode(nsIWebSocketChannel::CLOSE_ABNORMAL),
                              mReadyState(nsIMozWebSocket::CONNECTING),
                              mOutgoingBufferedAmount(0),
                              mScriptLine(0),
                              mInnerWindowID(0)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
+  nsLayoutStatics::AddRef();
 }
 
 nsWebSocket::~nsWebSocket()
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
-  if (mConnection) {
-    mConnection->Disconnect();
-    mConnection = nsnull;
-  }
   if (mListenerManager) {
     mListenerManager->Disconnect();
     mListenerManager = nsnull;
   }
+  Disconnect();
+  nsLayoutStatics::Release();
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsWebSocket)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsWebSocket,
                                                   nsDOMEventTargetWrapperCache)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnOpenListener)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnMessageListener)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnCloseListener)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPrincipal)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mURI)
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mConnection");
-  cb.NoteXPCOMChild(static_cast<nsIInterfaceRequestor*>(tmp->mConnection));
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mWebSocketChannel)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsWebSocket,
                                                 nsDOMEventTargetWrapperCache)
-  if (tmp->mConnection) {
-    tmp->mConnection->Disconnect();
-    tmp->mConnection = nsnull;
-  }
+  tmp->Disconnect();
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnOpenListener)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnMessageListener)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnCloseListener)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPrincipal)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mURI)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mWebSocketChannel)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 DOMCI_DATA(MozWebSocket, nsWebSocket)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsWebSocket)
   NS_INTERFACE_MAP_ENTRY(nsIMozWebSocket)
   NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
+  NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
+  NS_INTERFACE_MAP_ENTRY(nsIWebSocketListener)
+  NS_INTERFACE_MAP_ENTRY(nsIRequest)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozWebSocket)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache)
 
 NS_IMPL_ADDREF_INHERITED(nsWebSocket, nsDOMEventTargetWrapperCache)
 NS_IMPL_RELEASE_INHERITED(nsWebSocket, nsDOMEventTargetWrapperCache)
 
 //-----------------------------------------------------------------------------
 // nsWebSocket::nsIJSNativeInitializer methods:
@@ -806,35 +562,83 @@ nsWebSocket::Initialize(nsISupports* aOw
 
   return Init(principal, scriptContext, ownerWindow, urlParam, protocolArray);
 }
 
 //-----------------------------------------------------------------------------
 // nsWebSocket methods:
 //-----------------------------------------------------------------------------
 
+class nsAutoCloseWS
+{
+public:
+  nsAutoCloseWS(nsWebSocket *aWebSocket)
+    : mWebSocket(aWebSocket)
+  {}
+
+  ~nsAutoCloseWS()
+  {
+    if (!mWebSocket->mWebSocketChannel) {
+      mWebSocket->CloseConnection();
+    }
+  }
+private:
+  nsRefPtr<nsWebSocket> mWebSocket;
+};
+
 nsresult
 nsWebSocket::EstablishConnection()
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
-  NS_ABORT_IF_FALSE(!mConnection, "mConnection should be null");
+  NS_ABORT_IF_FALSE(!mWebSocketChannel, "mWebSocketChannel should be null");
 
   nsresult rv;
 
-  nsRefPtr<nsWebSocketEstablishedConnection> conn =
-    new nsWebSocketEstablishedConnection();
+  nsCOMPtr<nsIWebSocketChannel> wsChannel;
+  nsAutoCloseWS autoClose(this);
+
+  if (mSecure) {
+    wsChannel =
+      do_CreateInstance("@mozilla.org/network/protocol;1?name=wss", &rv);
+  } else {
+    wsChannel =
+      do_CreateInstance("@mozilla.org/network/protocol;1?name=ws", &rv);
+  }
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = wsChannel->SetNotificationCallbacks(this);
+  NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = conn->Init(this);
-  mConnection = conn;
-  if (NS_FAILED(rv)) {
-    Close(0, EmptyString(), 0);
-    mConnection = nsnull;
-    return rv;
+  // add ourselves to the document's load group and
+  // provide the http stack the loadgroup info too
+  nsCOMPtr<nsILoadGroup> loadGroup;
+  rv = GetLoadGroup(getter_AddRefs(loadGroup));
+  if (loadGroup) {
+    rv = wsChannel->SetLoadGroup(loadGroup);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = loadGroup->AddRequest(this, nsnull);
+    NS_ENSURE_SUCCESS(rv, rv);
   }
 
+  if (!mRequestedProtocolList.IsEmpty()) {
+    rv = wsChannel->SetProtocol(mRequestedProtocolList);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  nsCString asciiOrigin;
+  rv = nsContentUtils::GetASCIIOrigin(mPrincipal, asciiOrigin);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  ToLowerCase(asciiOrigin);
+
+  rv = wsChannel->AsyncOpen(mURI, asciiOrigin, this, nsnull);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  mWebSocketChannel = wsChannel;
+
   return NS_OK;
 }
 
 class nsWSCloseEvent : public nsRunnable
 {
 public:
 nsWSCloseEvent(nsWebSocket *aWebSocket, bool aWasClean, 
                PRUint16 aCode, const nsString &aReason)
@@ -885,17 +689,17 @@ nsWebSocket::CreateAndDispatchSimpleEven
   return DispatchDOMEvent(nsnull, event, nsnull, nsnull);
 }
 
 nsresult
 nsWebSocket::CreateAndDispatchMessageEvent(const nsACString& aData)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
   nsresult rv;
-  
+
   rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv)) {
     return NS_OK;
   }
 
   // Let's play get the JSContext
   nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(mOwner);
   NS_ENSURE_TRUE(sgo, NS_ERROR_FAILURE);
@@ -1018,32 +822,25 @@ nsWebSocket::SetReadyState(PRUint16 aNew
                       "unexpected readyState transition");
     mReadyState = aNewReadyState;
     return;
   }
 
   if (aNewReadyState == nsIMozWebSocket::CLOSED) {
     mReadyState = aNewReadyState;
 
-    if (mConnection) {
-      // The close event must be dispatched asynchronously.
-      nsCOMPtr<nsIRunnable> event =
-        new nsWSCloseEvent(this,
-                           mConnection->ClosedCleanly(),
-                           mServerReasonCode,
-                           mServerReason);
-      mOutgoingBufferedAmount += mConnection->GetOutgoingBufferedAmount();
-      mConnection = nsnull; // this is no longer necessary
-
-      rv = NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
-      if (NS_FAILED(rv)) {
-        NS_WARNING("Failed to dispatch the close event");
-        mTriggeredCloseEvent = true;
-        UpdateMustKeepAlive();
-      }
+    // The close event must be dispatched asynchronously.
+    rv = NS_DispatchToMainThread(new nsWSCloseEvent(this, mClosedCleanly,
+                                                    mServerReasonCode,
+                                                    mServerReason),
+                                 NS_DISPATCH_NORMAL);
+    if (NS_FAILED(rv)) {
+      NS_WARNING("Failed to dispatch the close event");
+      mTriggeredCloseEvent = true;
+      UpdateMustKeepAlive();
     }
   }
 }
 
 nsresult
 nsWebSocket::ParseURL(const nsString& aURL)
 {
   nsresult rv;
@@ -1143,28 +940,30 @@ nsWebSocket::UpdateMustKeepAlive()
 
   if (mListenerManager) {
     switch (mReadyState)
     {
       case nsIMozWebSocket::CONNECTING:
       {
         if (mListenerManager->HasListenersFor(NS_LITERAL_STRING("open")) ||
             mListenerManager->HasListenersFor(NS_LITERAL_STRING("message")) ||
+            mListenerManager->HasListenersFor(NS_LITERAL_STRING("error")) ||
             mListenerManager->HasListenersFor(NS_LITERAL_STRING("close"))) {
           shouldKeepAlive = true;
         }
       }
       break;
 
       case nsIMozWebSocket::OPEN:
       case nsIMozWebSocket::CLOSING:
       {
         if (mListenerManager->HasListenersFor(NS_LITERAL_STRING("message")) ||
+            mListenerManager->HasListenersFor(NS_LITERAL_STRING("error")) ||
             mListenerManager->HasListenersFor(NS_LITERAL_STRING("close")) ||
-            mConnection->HasOutgoingMessages()) {
+            mOutgoingBufferedAmount != 0) {
           shouldKeepAlive = true;
         }
       }
       break;
 
       case nsIMozWebSocket::CLOSED:
       {
         shouldKeepAlive =
@@ -1258,21 +1057,17 @@ nsWebSocket::GetReadyState(PRUint16 *aRe
 {
   *aReadyState = mReadyState;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWebSocket::GetBufferedAmount(PRUint32 *aBufferedAmount)
 {
-  if (!mConnection) {
-    *aBufferedAmount = mOutgoingBufferedAmount;
-  } else {
-    *aBufferedAmount = mConnection->GetOutgoingBufferedAmount();
-  }
+  *aBufferedAmount = mOutgoingBufferedAmount;
   return NS_OK;
 }
 
 #define NS_WEBSOCKET_IMPL_DOMEVENTLISTENER(_eventlistenername, _eventlistener) \
   NS_IMETHODIMP                                                                \
   nsWebSocket::GetOn##_eventlistenername(nsIDOMEventListener * *aEventListener)\
   {                                                                            \
     return GetInnerEventListener(_eventlistener, aEventListener);              \
@@ -1323,17 +1118,63 @@ nsWebSocket::Send(const nsAString& aData
     return NS_ERROR_DOM_SYNTAX_ERR;
 
   if (mReadyState == nsIMozWebSocket::CLOSING ||
       mReadyState == nsIMozWebSocket::CLOSED) {
     mOutgoingBufferedAmount += NS_ConvertUTF16toUTF8(aData).Length();
     return NS_OK;
   }
 
-  mConnection->PostMessage(PromiseFlatString(aData));
+  nsString message = PromiseFlatString(aData);
+  nsresult rv;
+
+  nsCOMPtr<nsICharsetConverterManager> ccm =
+    do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
+  ENSURE_SUCCESS_AND_FAIL_IF_FAILED(rv, rv);
+
+  nsCOMPtr<nsIUnicodeEncoder> converter;
+  rv = ccm->GetUnicodeEncoder("UTF-8", getter_AddRefs(converter));
+  ENSURE_SUCCESS_AND_FAIL_IF_FAILED(rv, rv);
+
+  rv = converter->SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace,
+                                         nsnull, UTF_8_REPLACEMENT_CHAR);
+  ENSURE_SUCCESS_AND_FAIL_IF_FAILED(rv, rv);
+
+  PRInt32 inLen = message.Length();
+  PRInt32 maxLen;
+  rv = converter->GetMaxLength(message.BeginReading(), inLen, &maxLen);
+  ENSURE_SUCCESS_AND_FAIL_IF_FAILED(rv, rv);
+
+  nsCString buf;
+  buf.SetLength(maxLen);
+  ENSURE_TRUE_AND_FAIL_IF_FAILED(buf.Length() == static_cast<PRUint32>(maxLen),
+                                 NS_ERROR_OUT_OF_MEMORY);
+
+  char* start = buf.BeginWriting();
+
+  PRInt32 outLen = maxLen;
+  rv = converter->Convert(message.BeginReading(), &inLen, start, &outLen);
+  if (NS_SUCCEEDED(rv)) {
+    PRInt32 outLen2 = maxLen - outLen;
+    rv = converter->Finish(start + outLen, &outLen2);
+    outLen += outLen2;
+  }
+  if (NS_FAILED(rv) || rv == NS_ERROR_UENC_NOMAPPING) {
+    // Yes, NS_ERROR_UENC_NOMAPPING is a success code
+    return NS_ERROR_DOM_SYNTAX_ERR;
+  }
+
+  buf.SetLength(outLen);
+  ENSURE_TRUE_AND_FAIL_IF_FAILED(buf.Length() == static_cast<PRUint32>(outLen),
+                                 NS_ERROR_UNEXPECTED);
+
+  mOutgoingBufferedAmount += buf.Length();
+  mWebSocketChannel->SendMsg(buf);
+
+  UpdateMustKeepAlive();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWebSocket::Close(PRUint16 code, const nsAString & reason, PRUint8 argc)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
@@ -1367,24 +1208,22 @@ nsWebSocket::Close(PRUint16 code, const 
     return NS_OK;
   }
 
   if (mReadyState == nsIMozWebSocket::CONNECTING) {
     // FailConnection() can release the object, so we keep a reference
     // before calling it
     nsRefPtr<nsWebSocket> kungfuDeathGrip = this;
 
-    if (mConnection) {
-      mConnection->FailConnection();
-    }
+    FailConnection();
     return NS_OK;
   }
 
   // mReadyState == nsIMozWebSocket::OPEN
-  mConnection->Close();
+  CloseConnection();
 
   return NS_OK;
 }
 
 /**
  * This Init method should only be called by C++ consumers.
  */
 NS_IMETHODIMP
@@ -1403,18 +1242,17 @@ nsWebSocket::Init(nsIPrincipal* aPrincip
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   mPrincipal = aPrincipal;
   mScriptContext = aScriptContext;
   if (aOwnerWindow) {
     mOwner = aOwnerWindow->IsOuterWindow() ?
       aOwnerWindow->GetCurrentInnerWindow() : aOwnerWindow;
-  }
-  else {
+  } else {
     mOwner = nsnull;
   }
 
   nsCOMPtr<nsIJSContextStack> stack =
     do_GetService("@mozilla.org/js/xpc/ContextStack;1");
   JSContext* cx = nsnull;
   if (stack && NS_SUCCEEDED(stack->Peek(&cx)) && cx) {
     JSStackFrame *fp = JS_GetScriptedCaller(cx, NULL);
@@ -1433,17 +1271,17 @@ nsWebSocket::Init(nsIPrincipal* aPrincip
     mInnerWindowID = nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(cx);
   }
 
   // parses the url
   rv = ParseURL(PromiseFlatString(aURL));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Don't allow https:// to open ws://
-  if (!mSecure && 
+  if (!mSecure &&
       !Preferences::GetBool("network.websocket.allowInsecureFromHTTPS",
                             false)) {
     // Confirmed we are opening plain ws:// and want to prevent this from a
     // secure context (e.g. https). Check the security context of the document
     // associated with this script, which is the same as associated with mOwner.
     nsCOMPtr<nsIDocument> originDoc =
       nsContentUtils::GetDocumentFromScriptContext(mScriptContext);
     if (originDoc && originDoc->GetSecurityInfo())
@@ -1466,97 +1304,91 @@ nsWebSocket::Init(nsIPrincipal* aPrincip
   // the constructor should throw a SYNTAX_ERROR only if it fails to parse the
   // url parameter, so we don't care about the EstablishConnection result.
   EstablishConnection();
 
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
-// nsWebSocketEstablishedConnection::nsIRequest
+// nsWebSocket::nsIRequest
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::GetName(nsACString &aName)
+nsWebSocket::GetName(nsACString &aName)
 {
-  if (!mOwner)
-    return NS_ERROR_UNEXPECTED;
-  
-  CopyUTF16toUTF8(mOwner->mOriginalURL, aName);
+  CopyUTF16toUTF8(mOriginalURL, aName);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::IsPending(bool *aValue)
+nsWebSocket::IsPending(bool *aValue)
 {
-  *aValue = !!(mOwner);
+  *aValue = !mDisconnected;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::GetStatus(nsresult *aStatus)
+nsWebSocket::GetStatus(nsresult *aStatus)
 {
   *aStatus = NS_OK;
   return NS_OK;
 }
 
 // Window closed, stop/reload button pressed, user navigated away from page, etc.
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::Cancel(nsresult aStatus)
+nsWebSocket::Cancel(nsresult aStatus)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
 
-  if (!mOwner) {
+  if (mDisconnected)
     return NS_OK;
-  }
 
   ConsoleError();
-  return Close();
+  return CloseConnection();
 }
 
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::Suspend()
+nsWebSocket::Suspend()
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::Resume()
+nsWebSocket::Resume()
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::GetLoadGroup(nsILoadGroup **aLoadGroup)
+nsWebSocket::GetLoadGroup(nsILoadGroup **aLoadGroup)
 {
   *aLoadGroup = nsnull;
-  if (!mOwner)
-    return NS_OK;
 
   nsCOMPtr<nsIDocument> doc =
-    nsContentUtils::GetDocumentFromScriptContext(mOwner->mScriptContext);
+    nsContentUtils::GetDocumentFromScriptContext(mScriptContext);
 
   if (doc) {
     *aLoadGroup = doc->GetDocumentLoadGroup().get();  // already_AddRefed
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::SetLoadGroup(nsILoadGroup *aLoadGroup)
+nsWebSocket::SetLoadGroup(nsILoadGroup *aLoadGroup)
 {
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::GetLoadFlags(nsLoadFlags *aLoadFlags)
+nsWebSocket::GetLoadFlags(nsLoadFlags *aLoadFlags)
 {
   *aLoadFlags = nsIRequest::LOAD_BACKGROUND;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsWebSocketEstablishedConnection::SetLoadFlags(nsLoadFlags aLoadFlags)
+nsWebSocket::SetLoadFlags(nsLoadFlags aLoadFlags)
 {
   // we won't change the load flags at all.
   return NS_OK;
 }
--- a/content/base/src/nsWebSocket.h
+++ b/content/base/src/nsWebSocket.h
@@ -46,46 +46,54 @@
 #include "nsString.h"
 #include "nsIJSNativeInitializer.h"
 #include "nsIPrincipal.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDOMEventListener.h"
 #include "nsDOMEventTargetWrapperCache.h"
 #include "nsAutoPtr.h"
 #include "nsIDOMDOMStringList.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsIWebSocketChannel.h"
+#include "nsIWebSocketListener.h"
+#include "nsIRequest.h"
 
 #define DEFAULT_WS_SCHEME_PORT  80
 #define DEFAULT_WSS_SCHEME_PORT 443
 
 #define NS_WEBSOCKET_CID                            \
  { /* 7ca25214-98dc-40a6-bc1f-41ddbe41f46c */       \
   0x7ca25214, 0x98dc, 0x40a6,                       \
  {0xbc, 0x1f, 0x41, 0xdd, 0xbe, 0x41, 0xf4, 0x6c} }
 
 #define NS_WEBSOCKET_CONTRACTID "@mozilla.org/websocket;1"
 
-class nsWSNetAddressComparator;
-class nsWebSocketEstablishedConnection;
 class nsWSCloseEvent;
+class nsAutoCloseWS;
 
 class nsWebSocket: public nsDOMEventTargetWrapperCache,
                    public nsIMozWebSocket,
-                   public nsIJSNativeInitializer
+                   public nsIJSNativeInitializer,
+                   public nsIInterfaceRequestor,
+                   public nsIWebSocketListener,
+                   public nsIRequest
 {
-friend class nsWSNetAddressComparator;
-friend class nsWebSocketEstablishedConnection;
 friend class nsWSCloseEvent;
+friend class nsAutoCloseWS;
 
 public:
   nsWebSocket();
   virtual ~nsWebSocket();
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsWebSocket,
                                            nsDOMEventTargetWrapperCache)
   NS_DECL_NSIMOZWEBSOCKET
+  NS_DECL_NSIINTERFACEREQUESTOR
+  NS_DECL_NSIWEBSOCKETLISTENER
+  NS_DECL_NSIREQUEST
 
   // nsIJSNativeInitializer
   NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext,
                         JSObject* aObject, PRUint32 aArgc, jsval* aArgv);
 
   // nsIDOMEventTarget
   NS_IMETHOD AddEventListener(const nsAString& aType,
                               nsIDOMEventListener *aListener,
@@ -94,77 +102,84 @@ public:
                               PRUint8 optional_argc);
   NS_IMETHOD RemoveEventListener(const nsAString& aType,
                                  nsIDOMEventListener* aListener,
                                  bool aUseCapture);
 
   // Determine if preferences allow WebSocket
   static bool PrefEnabled();
 
-  const PRUint64 InnerWindowID() const { return mInnerWindowID; }
-  const nsCString& GetScriptFile() const { return mScriptFile; }
-  const PRUint32 GetScriptLine() const { return mScriptLine; }
-
 protected:
   nsresult ParseURL(const nsString& aURL);
   nsresult EstablishConnection();
 
+  // these three methods when called can release the WebSocket object
+  nsresult FailConnection();
+  nsresult CloseConnection();
+  nsresult Disconnect();
+
+  nsresult ConsoleError();
+  nsresult PrintErrorOnConsole(const char       *aBundleURI,
+                               const PRUnichar  *aError,
+                               const PRUnichar **aFormatStrings,
+                               PRUint32          aFormatStringsLen);
+
   nsresult CreateAndDispatchSimpleEvent(const nsString& aName);
   nsresult CreateAndDispatchMessageEvent(const nsACString& aData);
   nsresult CreateAndDispatchCloseEvent(bool aWasClean, PRUint16 aCode,
                                        const nsString &aReason);
 
-  // called from mConnection accordingly to the situation
   void SetReadyState(PRUint16 aNewReadyState);
 
   // if there are "strong event listeners" (see comment in nsWebSocket.cpp) or
   // outgoing not sent messages then this method keeps the object alive
   // when js doesn't have strong references to it.
   void UpdateMustKeepAlive();
   // ATTENTION, when calling this method the object can be released
   // (and possibly collected).
   void DontKeepAliveAnyMore();
 
+  nsCOMPtr<nsIWebSocketChannel> mWebSocketChannel;
+
   nsRefPtr<nsDOMEventListenerWrapper> mOnOpenListener;
   nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
   nsRefPtr<nsDOMEventListenerWrapper> mOnMessageListener;
   nsRefPtr<nsDOMEventListenerWrapper> mOnCloseListener;
 
   // related to the WebSocket constructor steps
   nsString mOriginalURL;
   bool mSecure; // if true it is using SSL and the wss scheme,
                         // otherwise it is using the ws scheme with no SSL
 
   bool mKeepingAlive;
   bool mCheckMustKeepAlive;
   bool mTriggeredCloseEvent;
+  bool mClosedCleanly;
+  bool mDisconnected;
 
   nsCString mClientReason;
   PRUint16  mClientReasonCode;
   nsString  mServerReason;
   PRUint16  mServerReasonCode;
 
   nsCString mAsciiHost;  // hostname
   PRUint32  mPort;
   nsCString mResource; // [filepath[?query]]
   nsString  mUTF16Origin;
-  
+
   nsCOMPtr<nsIURI> mURI;
   nsCString mRequestedProtocolList;
   nsCString mEstablishedProtocol;
   nsCString mEstablishedExtensions;
 
   PRUint16 mReadyState;
 
   nsCOMPtr<nsIPrincipal> mPrincipal;
 
-  nsRefPtr<nsWebSocketEstablishedConnection> mConnection;
-  PRUint32 mOutgoingBufferedAmount; // actually, we get this value from
-                                    // mConnection when we are connected,
-                                    // but we need this one after disconnecting.
+  PRUint32 mOutgoingBufferedAmount;
 
   // Web Socket owner information:
   // - the script file name, UTF8 encoded.
   // - source code line number where the Web Socket object was constructed.
   // - the ID of the inner window where the script lives. Note that this may not
   //   be the same as the Web Socket owner window.
   // These attributes are used for error reporting.
   nsCString mScriptFile;
--- a/content/base/test/test_websocket.html
+++ b/content/base/test/test_websocket.html
@@ -365,19 +365,25 @@ function test8()
 
 var waitTest9 = false;
 
 function test9()
 {
   waitTest9 = true;
 
   var ws = CreateTestWS("ws://test2.example.org/tests/content/base/test/file_websocket", "test-9");
+  ws._receivedErrorEvent = false;
   ws.onopen = shouldNotOpen;
+  ws.onerror = function(e)
+  {
+    ws._receivedErrorEvent = true;
+  };
   ws.onclose = function(e)
   {
+    ok(ws._receivedErrorEvent, "Didn't received the error event in test 9.");
     shouldCloseNotCleanly(e);
     waitTest9 = false;
     maybeFinished();
   };
 
   ws.close();
   
   // the server injects a delay, so proceed with this in the background
--- a/content/events/src/nsIMEStateManager.cpp
+++ b/content/events/src/nsIMEStateManager.cpp
@@ -641,23 +641,34 @@ nsTextStateManager::ContentRemoved(nsIDo
     return;
 
   // fire notification
   if (childOffset)
     nsContentUtils::AddScriptRunner(
         new TextChangeEvent(mWidget, offset, offset + childOffset, offset));
 }
 
+static bool IsEditable(nsINode* node) {
+  if (node->IsEditable()) {
+    return true;
+  }
+  // |node| might be readwrite (for example, a text control)
+  if (node->IsElement() && node->AsElement()->State().HasState(NS_EVENT_STATE_MOZ_READWRITE)) {
+    return true;
+  }
+  return false;
+}
+
 static nsINode* GetRootEditableNode(nsPresContext* aPresContext,
                                     nsIContent* aContent)
 {
   if (aContent) {
     nsINode* root = nsnull;
     nsINode* node = aContent;
-    while (node && node->IsEditable()) {
+    while (node && IsEditable(node)) {
       root = node;
       node = node->GetNodeParent();
     }
     return root;
   }
   if (aPresContext) {
     nsIDocument* document = aPresContext->Document();
     if (document && document->IsEditable())
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -1788,47 +1788,16 @@ nsGenericHTMLElement::MapCommonAttribute
     if (display->GetUnit() == eCSSUnit_Null) {
       if (aAttributes->IndexOfAttr(nsGkAtoms::hidden, kNameSpaceID_None) >= 0) {
         display->SetIntValue(NS_STYLE_DISPLAY_NONE, eCSSUnit_Enumerated);
       }
     }
   }
 }
 
-void
-nsGenericHTMLFormElement::UpdateEditableFormControlState(bool aNotify)
-{
-  // nsCSSFrameConstructor::MaybeConstructLazily is based on the logic of this
-  // function, so should be kept in sync with that.
-
-  ContentEditableTristate value = GetContentEditableValue();
-  if (value != eInherit) {
-    DoSetEditableFlag(!!value, aNotify);
-    return;
-  }
-
-  nsIContent *parent = GetParent();
-
-  if (parent && parent->HasFlag(NODE_IS_EDITABLE)) {
-    DoSetEditableFlag(true, aNotify);
-    return;
-  }
-
-  if (!IsTextControl(false)) {
-    DoSetEditableFlag(false, aNotify);
-    return;
-  }
-
-  // If not contentEditable we still need to check the readonly attribute.
-  bool roState;
-  GetBoolAttr(nsGkAtoms::readonly, &roState);
-
-  DoSetEditableFlag(!roState, aNotify);
-}
-
 
 /* static */ const nsGenericHTMLElement::MappedAttributeEntry
 nsGenericHTMLElement::sCommonAttributeMap[] = {
   { &nsGkAtoms::contenteditable },
   { &nsGkAtoms::lang },
   { &nsGkAtoms::hidden },
   { nsnull }
 };
@@ -2911,16 +2880,28 @@ nsGenericHTMLFormElement::IntrinsicState
   
   if (mForm && mForm->IsDefaultSubmitElement(this)) {
       NS_ASSERTION(IsSubmitControl(),
                    "Default submit element that isn't a submit control.");
       // We are the default submit element (:default)
       state |= NS_EVENT_STATE_DEFAULT;
   }
 
+  // Make the text controls read-write
+  if (!state.HasState(NS_EVENT_STATE_MOZ_READWRITE) &&
+      IsTextControl(false)) {
+    bool roState;
+    GetBoolAttr(nsGkAtoms::readonly, &roState);
+
+    if (!roState) {
+      state |= NS_EVENT_STATE_MOZ_READWRITE;
+      state &= ~NS_EVENT_STATE_MOZ_READONLY;
+    }
+  }
+
   return state;
 }
 
 nsGenericHTMLFormElement::FocusTristate
 nsGenericHTMLFormElement::FocusState()
 {
   // We can't be focused if we aren't in a document
   nsIDocument* doc = GetCurrentDoc();
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -923,18 +923,16 @@ public:
 
 protected:
   virtual nsresult BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
                                  const nsAString* aValue, bool aNotify);
 
   virtual nsresult AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
                                 const nsAString* aValue, bool aNotify);
 
-  void UpdateEditableFormControlState(bool aNotify);
-
   /**
    * This method will update the form owner, using @form or looking to a parent.
    *
    * @param aBindToTree Whether the element is being attached to the tree.
    * @param aFormIdElement The element associated with the id in @form. If
    * aBindToTree is false, aFormIdElement *must* contain the element associated
    * with the id in @form. Otherwise, it *must* be null.
    *
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -841,17 +841,16 @@ nsHTMLInputElement::AfterSetAttr(PRInt32
     } else if (MaxLengthApplies() && aName == nsGkAtoms::maxlength) {
       UpdateTooLongValidityState();
     } else if (aName == nsGkAtoms::pattern) {
       UpdatePatternMismatchValidityState();
     } else if (aName == nsGkAtoms::multiple) {
       UpdateTypeMismatchValidityState();
     }
 
-    UpdateEditableState(aNotify);
     UpdateState(aNotify);
   }
 
   return nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName,
                                                 aValue, aNotify);
 }
 
 // nsIDOMHTMLInputElement
--- a/content/html/content/src/nsHTMLInputElement.h
+++ b/content/html/content/src/nsHTMLInputElement.h
@@ -230,21 +230,16 @@ public:
    * @return the selected button (or null).
    */
   already_AddRefed<nsIDOMHTMLInputElement> GetSelectedRadioButton();
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   NS_IMETHOD FireAsyncClickHandler();
 
-  virtual void UpdateEditableState(bool aNotify)
-  {
-    return UpdateEditableFormControlState(aNotify);
-  }
-
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLInputElement,
                                            nsGenericHTMLFormElement)
 
   static UploadLastDir* gUploadLastDir;
   // create and destroy the static UploadLastDir object for remembering
   // which directory was last used on a site-by-site basis
   static void InitUploadLastDir();
   static void DestroyUploadLastDir();
--- a/content/html/content/src/nsHTMLTextAreaElement.cpp
+++ b/content/html/content/src/nsHTMLTextAreaElement.cpp
@@ -198,21 +198,16 @@ public:
                                  const nsAString* aValue, bool aNotify);
 
   // nsIMutationObserver
   NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
 
-  virtual void UpdateEditableState(bool aNotify)
-  {
-    return UpdateEditableFormControlState(aNotify);
-  }
-
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLTextAreaElement,
                                            nsGenericHTMLFormElement)
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   // nsIConstraintValidation
   bool     IsTooLong();
   bool     IsValueMissing() const;
@@ -1269,19 +1264,16 @@ nsHTMLTextAreaElement::AfterSetAttr(PRIn
       // This *has* to be called *after* validity has changed.
       if (aName == nsGkAtoms::readonly || aName == nsGkAtoms::disabled) {
         UpdateBarredFromConstraintValidation();
       }
     } else if (aName == nsGkAtoms::maxlength) {
       UpdateTooLongValidityState();
     }
 
-    if (aName == nsGkAtoms::readonly) {
-      UpdateEditableState(aNotify);
-    }
     UpdateState(aNotify);
   }
 
   return nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName, aValue,
                                                 aNotify);
 }
 
 nsresult
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -1558,16 +1558,19 @@ nsTextEditorState::CreateRootNode()
   }
 
   return rv;
 }
 
 nsresult
 nsTextEditorState::InitializeRootNode()
 {
+  // Make our root node editable
+  mRootNode->SetFlags(NODE_IS_EDITABLE);
+
   // Set the necessary classes on the text control. We use class values
   // instead of a 'style' attribute so that the style comes from a user-agent
   // style sheet and is still applied even if author styles are disabled.
   nsAutoString classValue;
   classValue.AppendLiteral("anonymous-div");
   PRInt32 wrapCols = GetWrapCols();
   if (wrapCols >= 0) {
     classValue.AppendLiteral(" wrap");
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -2694,27 +2694,25 @@ nsHTMLDocument::GetDocumentAllResult(con
 
   // There's only 0 or 1 items. Return the first one or null.
   *aCache = cont = docAllList->Item(0, true);
 
   return cont;
 }
 
 static void
-NotifyEditableStateChange(nsINode *aNode, nsIDocument *aDocument,
-                          bool aEditable)
+NotifyEditableStateChange(nsINode *aNode, nsIDocument *aDocument)
 {
   for (nsIContent* child = aNode->GetFirstChild();
        child;
        child = child->GetNextSibling()) {
-    if (child->HasFlag(NODE_IS_EDITABLE) != aEditable &&
-        child->IsElement()) {
+    if (child->IsElement()) {
       child->AsElement()->UpdateState(true);
     }
-    NotifyEditableStateChange(child, aDocument, aEditable);
+    NotifyEditableStateChange(child, aDocument);
   }
 }
 
 void
 nsHTMLDocument::TearingDownEditor(nsIEditor *aEditor)
 {
   if (IsEditingOn()) {
     EditingState oldState = mEditingState;
@@ -2797,16 +2795,18 @@ nsHTMLDocument::EditingStateChanged()
                           (mContentEditableCount > 0 ? eContentEditable : eOff);
   if (mEditingState == newState) {
     // No changes in editing mode.
     return NS_OK;
   }
 
   if (newState == eOff) {
     // Editing is being turned off.
+    nsAutoScriptBlocker scriptBlocker;
+    NotifyEditableStateChange(this, this);
     return TurnEditingOff();
   }
 
   // Flush out style changes on our _parent_ document, if any, so that
   // our check for a presshell won't get stale information.
   if (mParentDocument) {
     mParentDocument->FlushPendingNotifications(Flush_Style);
   }
@@ -2953,17 +2953,17 @@ nsHTMLDocument::EditingStateChanged()
       mEditingState = eOff;
 
       return rv;
     }
   }
 
   if (updateState) {
     nsAutoScriptBlocker scriptBlocker;
-    NotifyEditableStateChange(this, this, designMode);
+    NotifyEditableStateChange(this, this);
   }
 
   // Resync the editor's spellcheck state.
   if (spellRecheckAll) {
     nsCOMPtr<nsISelectionController> selcon;
     nsresult rv = editor->GetSelectionController(getter_AddRefs(selcon));
     NS_ENSURE_SUCCESS(rv, rv); 
 
--- a/content/media/nsBuiltinDecoderReader.h
+++ b/content/media/nsBuiltinDecoderReader.h
@@ -380,17 +380,17 @@ private:
   mutable ReentrantMonitor mReentrantMonitor;
 
   // True when we've decoded the last frame of data in the
   // bitstream for which we're queueing frame data.
   bool mEndOfStream;
 };
 
 // Encapsulates the decoding and reading of media data. Reading can only be
-// done on the decode thread thread. Never hold the decoder monitor when
+// done on the decode thread. Never hold the decoder monitor when
 // calling into this class. Unless otherwise specified, methods and fields of
 // this class can only be accessed on the decode thread.
 class nsBuiltinDecoderReader : public nsRunnable {
 public:
   typedef mozilla::ReentrantMonitor ReentrantMonitor;
   typedef mozilla::ReentrantMonitorAutoEnter ReentrantMonitorAutoEnter;
 
   nsBuiltinDecoderReader(nsBuiltinDecoder* aDecoder);
--- a/content/svg/content/src/nsSVGMpathElement.cpp
+++ b/content/svg/content/src/nsSVGMpathElement.cpp
@@ -224,16 +224,17 @@ nsSVGMpathElement::GetReferencedPath()
     NS_ABORT_IF_FALSE(!mHrefTarget.get(),
                       "We shouldn't have an xlink:href target "
                       "if we don't have an xlink:href attribute");
     return nsnull;
   }
 
   nsIContent* genericTarget = mHrefTarget.get();
   if (genericTarget &&
+      genericTarget->GetNameSpaceID() == kNameSpaceID_SVG &&
       genericTarget->Tag() == nsGkAtoms::path) {
     return static_cast<nsSVGPathElement*>(genericTarget);
   }
   return nsnull;
 }
 
 //----------------------------------------------------------------------
 // Protected helper methods
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -7976,16 +7976,41 @@ nsNamedNodeMapSH::GetNamedItem(nsISuppor
   *aCache = attr = map->GetNamedItem(aName, aResult);
   return attr;
 }
 
 
 // HTMLCollection helper
 
 nsresult
+nsHTMLCollectionSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
+                              JSObject *globalObj, JSObject **parentObj)
+{
+  nsIHTMLCollection* list = static_cast<nsIHTMLCollection*>(nativeObj);
+#ifdef DEBUG
+  {
+    nsCOMPtr<nsIHTMLCollection> list_qi = do_QueryInterface(nativeObj);
+
+    // If this assertion fires the QI implementation for the object in
+    // question doesn't use the nsIHTMLCollection pointer as the nsISupports
+    // pointer. That must be fixed, or we'll crash...
+    NS_ASSERTION(list_qi == list, "Uh, fix QI!");
+  }
+#endif
+
+  nsINode* native_parent = list->GetParentObject();
+
+  nsresult rv =
+    WrapNativeParent(cx, globalObj, native_parent, native_parent, parentObj);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_SUCCESS_ALLOW_SLIM_WRAPPERS;
+}
+
+nsresult
 nsHTMLCollectionSH::GetLength(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                               JSObject *obj, PRUint32 *length)
 {
   nsIHTMLCollection* collection =
     static_cast<nsIHTMLCollection*>(GetNative(wrapper, obj));
 #ifdef DEBUG
   {
     nsCOMPtr<nsIHTMLCollection> collection_qi =
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -727,16 +727,19 @@ protected:
 
   // Override nsNamedArraySH::GetNamedItem()
   virtual nsISupports* GetNamedItem(nsISupports *aNative,
                                     const nsAString& aName,
                                     nsWrapperCache **cache,
                                     nsresult *aResult);
 
 public:
+  NS_IMETHOD PreCreate(nsISupports *nativeObj, JSContext *cx,
+                       JSObject *globalObj, JSObject **parentObj);
+
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   {
     return new nsHTMLCollectionSH(aData);
   }
 };
 
 
 // ContentList helper
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1812,16 +1812,44 @@ WindowStateHolder::~WindowStateHolder()
     // true for aClearScope won't do anything; this is OK since
     // SetDocShell(null) already did it.
     mInnerWindow->FreeInnerObjects(true);
   }
 }
 
 NS_IMPL_ISUPPORTS1(WindowStateHolder, WindowStateHolder)
 
+
+struct ReparentWaiverClosure
+{
+  JSContext *mCx;
+  JSObject *mNewInner;
+};
+
+static JSDHashOperator
+ReparentWaiverWrappers(JSDHashTable *table, JSDHashEntryHdr *hdr,
+                       uint32 number, void *arg)
+{
+    ReparentWaiverClosure *closure = static_cast<ReparentWaiverClosure*>(arg);
+    JSObject *value = static_cast<JSObject2JSObjectMap::Entry *>(hdr)->value;
+
+    // We reparent wrappers that have as their parent an inner window whose
+    // outer has the new inner window as its current inner.
+    JSObject *parent = JS_GetParent(closure->mCx, value);
+    JSObject *outer = JS_ObjectToOuterObject(closure->mCx, parent);
+    if (outer) {
+      JSObject *inner = JS_ObjectToInnerObject(closure->mCx, outer);
+      if (inner == closure->mNewInner && inner != parent)
+        JS_SetParent(closure->mCx, value, closure->mNewInner);
+    } else {
+      JS_ClearPendingException(closure->mCx);
+    }
+    return JS_DHASH_NEXT;
+}
+
 nsresult
 nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
                                nsISupports* aState,
                                bool aForceReuseInnerWindow)
 {
   NS_TIME_FUNCTION;
 
   NS_PRECONDITION(mDocumentPrincipal == nsnull,
@@ -2158,16 +2186,29 @@ nsGlobalWindow::SetNewDocument(nsIDocume
         if (!ac.enter(cx, mJSObject)) {
           NS_ERROR("unable to enter a compartment");
           return NS_ERROR_FAILURE;
         }
 
         JS_SetParent(cx, mJSObject, newInnerWindow->mJSObject);
 
         mContext->SetOuterObject(mJSObject);
+
+        JSCompartment *compartment = js::GetObjectCompartment(mJSObject);
+        xpc::CompartmentPrivate *priv =
+          static_cast<xpc::CompartmentPrivate*>(JS_GetCompartmentPrivate(cx, compartment));
+        if (priv && priv->waiverWrapperMap) {
+          NS_ASSERTION(!JS_IsExceptionPending(cx),
+                       "We might overwrite a pending exception!");
+          ReparentWaiverClosure closure = {
+            cx,
+            newInnerWindow->mJSObject
+          };
+          priv->waiverWrapperMap->Enumerate(ReparentWaiverWrappers, &closure);
+        }
       }
     }
 
     JSAutoEnterCompartment ac;
     if (!ac.enter(cx, mJSObject)) {
       NS_ERROR("unable to enter a compartment");
       return NS_ERROR_FAILURE;
     }
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -153,17 +153,25 @@ public:
 
   bool PreservingWrapper()
   {
     return (mWrapperPtrBits & WRAPPER_BIT_PRESERVED) != 0;
   }
 
   void SetIsProxy()
   {
-    mWrapperPtrBits |= WRAPPER_IS_PROXY;
+    NS_ASSERTION(!mWrapperPtrBits,
+                 "This flag should be set before creating any wrappers.");
+    mWrapperPtrBits = WRAPPER_IS_PROXY;
+  }
+  void ClearIsProxy()
+  {
+    NS_ASSERTION(!mWrapperPtrBits || mWrapperPtrBits == WRAPPER_IS_PROXY,
+                 "This flag should be cleared before creating any wrappers.");
+    mWrapperPtrBits = 0;
   }
 
   bool IsProxy() const
   {
     return (mWrapperPtrBits & WRAPPER_IS_PROXY) != 0;
   }
 
 
--- a/dom/tests/mochitest/bugs/test_bug633133.html
+++ b/dom/tests/mochitest/bugs/test_bug633133.html
@@ -23,17 +23,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script type="application/javascript">
 
 /** Test for Bug 633133 **/
 
 var divCollection = document.getElementsByTagName('div');
 
 ok("foo" in divCollection, "'foo' should be in the div collection");
 ok("bar" in divCollection, "'bar' should be in the div collection");
-ok("" in divCollection, "empty string should be in the div collection");
+ok(!("" in divCollection), "empty string shouldn't be in the div collection");
 ok(!("foobar" in divCollection), "'foobar' shouldn't be in the div collection");
 
 var select = $('select');
 is(select[0].text, "option1", "select elements work");
 Math.sin();
 ok(1 in select, "in works");
 is(select[1].text, "option2", "can get it too");
 ok(!(2 in select), "in works for elements out of range");
--- a/editor/libeditor/base/crashtests/382527-1.html
+++ b/editor/libeditor/base/crashtests/382527-1.html
@@ -31,17 +31,19 @@ function init2()
 
 function init3()
 {
   var rng = targetDocument.createRange(); 
   rng.setStart(textNode, 1);
   rng.setEnd(textNode, 1);
   targetWindow.getSelection().addRange(rng);
 
-  targetDocument.execCommand("inserthtml", false, "<p>");
+  try {
+    targetDocument.execCommand("inserthtml", false, "<p>");
+  } catch(e) {}
   
   document.documentElement.removeAttribute("class");
 }
 
 
 </script>
 
 </head>
--- a/editor/libeditor/base/crashtests/crashtests.list
+++ b/editor/libeditor/base/crashtests/crashtests.list
@@ -1,10 +1,10 @@
 load 336104.html
 load 382527-1.html
 load 402172-1.html
 load 407079-1.html
 load 407256-1.html
 load 430624-1.html
 load 459613.html
 load 475132-1.xhtml
-asserts-if(!Android,1) load 633709.xhtml # Bug 695364
+load 633709.xhtml
 asserts-if(!Android,6) load 636074-1.html # Bug 439258, charged to the wrong test due to bug 635550
--- a/editor/libeditor/base/nsEditor.h
+++ b/editor/libeditor/base/nsEditor.h
@@ -543,17 +543,17 @@ public:
 
   /** returns true if aNode is a descendant of our root node */
   bool IsDescendantOfBody(nsIDOMNode *inNode);
 
   /** returns true if aNode is a container */
   virtual bool IsContainer(nsIDOMNode *aNode);
 
   /** returns true if aNode is an editable node */
-  bool IsEditable(nsIDOMNode *aNode);
+  virtual bool IsEditable(nsIDOMNode *aNode);
 
   virtual bool IsTextInDirtyFrameVisible(nsIDOMNode *aNode);
 
   /** returns true if aNode is a MozEditorBogus node */
   bool IsMozEditorBogusNode(nsIDOMNode *aNode);
 
   /** counts number of editable child nodes */
   nsresult CountEditableChildren(nsIDOMNode *aNode, PRUint32 &outCount);
--- a/editor/libeditor/base/nsEditorCommands.cpp
+++ b/editor/libeditor/base/nsEditorCommands.cpp
@@ -657,31 +657,33 @@ nsDeleteCommand::GetCommandStateParams(c
 NS_IMETHODIMP
 nsSelectAllCommand::IsCommandEnabled(const char * aCommandName,
                                      nsISupports *aCommandRefCon,
                                      bool *outCmdEnabled)
 {
   NS_ENSURE_ARG_POINTER(outCmdEnabled);
 
   nsresult rv = NS_OK;
-  *outCmdEnabled = false;
+  // You can always select all, unless the selection is editable,
+  // and the editable region is empty!
+  *outCmdEnabled = true;
   bool docIsEmpty, selectionIsEditable;
- 
+
   // you can select all if there is an editor which is non-empty
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
   if (editor) {
     rv = editor->GetIsSelectionEditable(&selectionIsEditable);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (selectionIsEditable) {
       rv = editor->GetDocumentIsEmpty(&docIsEmpty);
       NS_ENSURE_SUCCESS(rv, rv);
       *outCmdEnabled = !docIsEmpty;
     }
-  } 
+  }
 
   return rv;
 }
 
 
 NS_IMETHODIMP
 nsSelectAllCommand::DoCommand(const char *aCommandName,
                               nsISupports *aCommandRefCon)
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp
@@ -308,17 +308,19 @@ nsHTMLEditor::DoInsertHTMLWithContext(co
   nsCOMPtr<nsIDOMNode> targetNode, tempNode;
   PRInt32 targetOffset=0;
 
   if (!aDestNode)
   {
     // if caller didn't provide the destination/target node,
     // fetch the paste insertion point from our selection
     res = GetStartNodeAndOffset(selection, getter_AddRefs(targetNode), &targetOffset);
-    if (!targetNode) res = NS_ERROR_FAILURE;
+    if (!targetNode || !IsEditable(targetNode)) {
+      res = NS_ERROR_FAILURE;
+    }
     NS_ENSURE_SUCCESS(res, res);
   }
   else
   {
     targetNode = aDestNode;
     targetOffset = aDestOffset;
   }
 
--- a/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/editor/libeditor/html/nsHTMLEditor.cpp
@@ -426,16 +426,22 @@ nsHTMLEditor::FindSelectionRoot(nsINode 
   // permission script.
   if (IsReadonly()) {
     // We still want to allow selection in a readonly editor.
     content = do_QueryInterface(GetRoot());
     return content.forget();
   }
 
   if (!content->HasFlag(NODE_IS_EDITABLE)) {
+    // If the content is in read-write state but is not editable itself,
+    // return it as the selection root.
+    if (content->IsElement() &&
+        content->AsElement()->State().HasState(NS_EVENT_STATE_MOZ_READWRITE)) {
+      return content.forget();
+    }
     return nsnull;
   }
 
   // For non-readonly editors we want to find the root of the editable subtree
   // containing aContent.
   content = content->GetEditingHost();
   return content.forget();
 }
@@ -6023,8 +6029,27 @@ nsHTMLEditor::GetPreferredIMEState(PRUin
     *aState = nsIContent::IME_STATUS_DISABLE;
     return NS_OK;
   }
 
   // HTML editor don't prefer the CSS ime-mode because IE didn't do so too.
   *aState = nsIContent::IME_STATUS_ENABLE;
   return NS_OK;
 }
+
+bool
+nsHTMLEditor::IsEditable(nsIDOMNode* aNode) {
+  if (!nsPlaintextEditor::IsEditable(aNode)) {
+    return false;
+  }
+  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+  if (!node) {
+    // If what we're dealing with is not a node, then it's not editable!
+    return false;
+  }
+  if (node->IsElement()) {
+    // If we're dealing with an element, then ask it whether it's editable.
+    return node->IsEditable();
+  }
+  // We might be dealing with a text node for example, which we always consider
+  // to be editable.
+  return true;
+}
--- a/editor/libeditor/html/nsHTMLEditor.h
+++ b/editor/libeditor/html/nsHTMLEditor.h
@@ -149,16 +149,17 @@ public:
   NS_IMETHOD GetIsDocumentEditable(bool *aIsDocumentEditable);
   NS_IMETHOD BeginningOfDocument();
   virtual nsresult HandleKeyPressEvent(nsIDOMKeyEvent* aKeyEvent);
   virtual already_AddRefed<nsIContent> GetFocusedContent();
   virtual bool IsActiveInDOMWindow();
   virtual already_AddRefed<nsIDOMEventTarget> GetDOMEventTarget();
   virtual already_AddRefed<nsIContent> FindSelectionRoot(nsINode *aNode);
   virtual bool IsAcceptableInputEvent(nsIDOMEvent* aEvent);
+  virtual bool IsEditable(nsIDOMNode *aNode);
 
   /* ------------ nsStubMutationObserver overrides --------- */
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
 
   /* ------------ nsIEditorIMESupport overrides ------------ */
   NS_IMETHOD GetPreferredIMEState(PRUint32 *aState);
--- a/editor/libeditor/html/tests/Makefile.in
+++ b/editor/libeditor/html/tests/Makefile.in
@@ -74,16 +74,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug551704.html \
 		test_bug552782.html \
 		test_bug570144.html \
 		test_bug592592.html \
 		test_bug597784.html \
 		test_bug599322.html \
 		test_bug607584.html \
 		test_bug611182.html \
+		test_bug612128.html \
 		test_bug612447.html \
 		test_bug620906.html \
 		test_bug622371.html \
 		test_bug629845.html \
 		test_bug640321.html \
 		test_bug668599.html \
 		test_bug674861.html \
 		test_bug676401.html \
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/html/tests/test_bug612128.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=612128
+-->
+<head>
+  <title>Test for Bug 612128</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.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=612128">Mozilla Bug 612128</a>
+<p id="display"></p>
+<div id="content">
+<input>
+<div contenteditable></div>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 612128 **/
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(function() {
+  document.querySelector("input").focus();
+  var threw = false;
+  try {
+    document.execCommand("inserthtml", null, "<span>f" + "oo</span>");
+  } catch (e) {
+    threw = true;
+  }
+  ok(threw, "The inserthtml command should fail");
+  is(document.querySelectorAll("span").length, 0, "No span element should be injected inside the page");
+  is(document.body.innerHTML.indexOf("f" + "oo"), -1, "No text should be injected inside the page");
+  SimpleTest.finish();
+});
+
+</script>
+</pre>
+</body>
+</html>
--- a/editor/libeditor/html/tests/test_bug676401.html
+++ b/editor/libeditor/html/tests/test_bug676401.html
@@ -30,20 +30,27 @@ https://bugzilla.mozilla.org/show_bug.cg
 SimpleTest.waitForExplicitFinish();
 SimpleTest.waitForFocus(runTests);
 
 var gBlock1, gBlock2;
 
 function IsCommandEnabled(command) {
   var enabled;
 
+  var resultInNonEditableRegion = false;
+  if (command == "selectAll") {
+    // The select all command is sort of exceptional, as it needs to be enabled
+    // everywhere.
+    resultInNonEditableRegion = true;
+  }
+
   // non-editable div: should return false
   window.getSelection().selectAllChildren(gBlock1);
   enabled = document.queryCommandEnabled(command);
-  is(enabled, false, "'" + command + "' should not be enabled on a non-editable block.");
+  is(enabled, resultInNonEditableRegion, "'" + command + "' should not be enabled on a non-editable block.");
 
   // editable div: should return true
   window.getSelection().selectAllChildren(gBlock2);
   enabled = document.queryCommandEnabled(command);
   is(enabled, true, "'" + command + "' should be enabled on an editable block.");
 }
 
 function runTests() {
--- a/gfx/layers/basic/BasicLayers.cpp
+++ b/gfx/layers/basic/BasicLayers.cpp
@@ -2384,17 +2384,18 @@ BasicShadowableThebesLayer::CreateBuffer
 }
 
 
 class BasicShadowableImageLayer : public BasicImageLayer,
                                   public BasicShadowableLayer
 {
 public:
   BasicShadowableImageLayer(BasicShadowLayerManager* aManager) :
-    BasicImageLayer(aManager)
+    BasicImageLayer(aManager),
+    mBufferIsOpaque(false)
   {
     MOZ_COUNT_CTOR(BasicShadowableImageLayer);
   }
   virtual ~BasicShadowableImageLayer()
   {
     DestroyBackBuffer();
     MOZ_COUNT_DTOR(BasicShadowableImageLayer);
   }
@@ -2446,16 +2447,17 @@ private:
   BasicShadowLayerManager* BasicManager()
   {
     return static_cast<BasicShadowLayerManager*>(mManager);
   }
 
   // For YUV Images these are the 3 planes (Y, Cb and Cr),
   // for RGB images only mBackSurface is used.
   SurfaceDescriptor mBackBuffer;
+  bool mBufferIsOpaque;
   nsRefPtr<gfxSharedImageSurface> mBackBufferY;
   nsRefPtr<gfxSharedImageSurface> mBackBufferU;
   nsRefPtr<gfxSharedImageSurface> mBackBufferV;
   gfxIntSize mCbCrSize;
 };
  
 void
 BasicShadowableImageLayer::Paint(gfxContext* aContext)
@@ -2513,22 +2515,26 @@ BasicShadowableImageLayer::Paint(gfxCont
     return;
   }
 
   gfxIntSize oldSize = mSize;
   nsRefPtr<gfxPattern> pat = GetAndPaintCurrentImage(aContext, GetEffectiveOpacity());
   if (!pat || !HasShadow())
     return;
 
-  if (oldSize != mSize || !IsSurfaceDescriptorValid(mBackBuffer)) {
+  bool isOpaque = (GetContentFlags() & CONTENT_OPAQUE);
+  if (oldSize != mSize || 
+      !IsSurfaceDescriptorValid(mBackBuffer) ||
+      isOpaque != mBufferIsOpaque) {
     DestroyBackBuffer();
+    mBufferIsOpaque = isOpaque;
 
     if (!BasicManager()->AllocBuffer(
           mSize,
-          (GetContentFlags() & CONTENT_OPAQUE) ?
+          isOpaque ?
             gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA,
           &mBackBuffer))
       NS_RUNTIMEABORT("creating ImageLayer 'front buffer' failed!");
   }
 
   nsRefPtr<gfxASurface> backSurface =
     BasicManager()->OpenDescriptor(mBackBuffer);
   nsRefPtr<gfxContext> tmpCtx = new gfxContext(backSurface);
@@ -2570,17 +2576,18 @@ public:
   }
 };
 
 class BasicShadowableCanvasLayer : public BasicCanvasLayer,
                                    public BasicShadowableLayer
 {
 public:
   BasicShadowableCanvasLayer(BasicShadowLayerManager* aManager) :
-    BasicCanvasLayer(aManager)
+    BasicCanvasLayer(aManager),
+    mBufferIsOpaque(false)
   {
     MOZ_COUNT_CTOR(BasicShadowableCanvasLayer);
   }
   virtual ~BasicShadowableCanvasLayer()
   {
     DestroyBackBuffer();
     MOZ_COUNT_DTOR(BasicShadowableCanvasLayer);
   }
@@ -2617,16 +2624,17 @@ public:
 
 private:
   BasicShadowLayerManager* BasicManager()
   {
     return static_cast<BasicShadowLayerManager*>(mManager);
   }
 
   SurfaceDescriptor mBackBuffer;
+  bool mBufferIsOpaque;
 };
 
 void
 BasicShadowableCanvasLayer::Initialize(const Data& aData)
 {
   BasicCanvasLayer::Initialize(aData);
   if (!HasShadow())
       return;
@@ -2646,20 +2654,24 @@ BasicShadowableCanvasLayer::Initialize(c
 void
 BasicShadowableCanvasLayer::Paint(gfxContext* aContext)
 {
   if (!HasShadow()) {
     BasicCanvasLayer::Paint(aContext);
     return;
   }
 
-  if (!IsSurfaceDescriptorValid(mBackBuffer)) {
+  bool isOpaque = (GetContentFlags() & CONTENT_OPAQUE);
+  if (!IsSurfaceDescriptorValid(mBackBuffer) ||
+      isOpaque != mBufferIsOpaque) {
+    DestroyBackBuffer();
+    mBufferIsOpaque = isOpaque;
     if (!BasicManager()->AllocBuffer(
         gfxIntSize(mBounds.width, mBounds.height),
-        (GetContentFlags() & CONTENT_OPAQUE) ?
+        isOpaque ?
           gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA,
         &mBackBuffer))
     NS_RUNTIMEABORT("creating CanvasLayer back buffer failed!");
   }
 
   nsRefPtr<gfxASurface> backSurface =
     BasicManager()->OpenDescriptor(mBackBuffer);
 
@@ -2938,17 +2950,23 @@ protected:
 
 void
 BasicShadowImageLayer::Swap(const SharedImage& aNewFront,
                             SharedImage* aNewBack)
 {
   nsRefPtr<gfxASurface> surface =
     BasicManager()->OpenDescriptor(aNewFront);
   // Destroy mFrontBuffer if size different
-  if (surface->GetSize() != mSize) {
+  bool needDrop = false;
+  if (IsSurfaceDescriptorValid(mFrontBuffer)) {
+    nsRefPtr<gfxASurface> front = BasicManager()->OpenDescriptor(mFrontBuffer);
+    needDrop = surface->GetSize() != mSize ||
+               surface->GetContentType() != front->GetContentType();
+  }
+  if (needDrop) {
     DestroyFrontBuffer();
     mSize = surface->GetSize();
   }
 
   // If mFrontBuffer
   if (IsSurfaceDescriptorValid(mFrontBuffer)) {
     *aNewBack = mFrontBuffer;
   } else {
@@ -3054,17 +3072,23 @@ BasicShadowCanvasLayer::Initialize(const
 void
 BasicShadowCanvasLayer::Swap(const CanvasSurface& aNewFront, bool needYFlip,
                              CanvasSurface* aNewBack)
 {
   nsRefPtr<gfxASurface> surface =
     BasicManager()->OpenDescriptor(aNewFront);
   // Destroy mFrontBuffer if size different
   gfxIntSize sz = surface->GetSize();
-  if (sz != gfxIntSize(mBounds.width, mBounds.height)) {
+  bool needDrop = false;
+  if (IsSurfaceDescriptorValid(mFrontSurface)) {
+    nsRefPtr<gfxASurface> front = BasicManager()->OpenDescriptor(mFrontSurface);
+    needDrop = sz != gfxIntSize(mBounds.width, mBounds.height) ||
+               surface->GetContentType() != front->GetContentType();
+  }
+  if (needDrop) {
     DestroyFrontBuffer();
     mBounds.SetRect(0, 0, sz.width, sz.height);
   }
 
   mNeedsYFlip = needYFlip;
   // If mFrontBuffer
   if (IsSurfaceDescriptorValid(mFrontSurface)) {
     *aNewBack = mFrontSurface;
--- a/gfx/layers/opengl/CanvasLayerOGL.cpp
+++ b/gfx/layers/opengl/CanvasLayerOGL.cpp
@@ -319,17 +319,18 @@ ShadowCanvasLayerOGL::Init(const CanvasS
 void
 ShadowCanvasLayerOGL::Swap(const CanvasSurface& aNewFront,
                            bool needYFlip,
                            CanvasSurface* aNewBack)
 {
   if (!mDestroyed) {
     nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront);
     gfxIntSize sz = surf->GetSize();
-    if (!mTexImage || mTexImage->GetSize() != sz) {
+    if (!mTexImage || mTexImage->GetSize() != sz ||
+        mTexImage->GetContentType() != surf->GetContentType()) {
       Init(aNewFront, needYFlip);
     }
     nsIntRegion updateRegion(nsIntRect(0, 0, sz.width, sz.height));
     mTexImage->DirectUpdate(surf, updateRegion);
   }
 
   *aNewBack = aNewFront;
 }
--- a/gfx/layers/opengl/ImageLayerOGL.cpp
+++ b/gfx/layers/opengl/ImageLayerOGL.cpp
@@ -880,17 +880,18 @@ void
 ShadowImageLayerOGL::Swap(const SharedImage& aNewFront,
                           SharedImage* aNewBack)
 {
   if (!mDestroyed) {
     if (aNewFront.type() == SharedImage::TSurfaceDescriptor) {
       nsRefPtr<gfxASurface> surf =
         ShadowLayerForwarder::OpenDescriptor(aNewFront.get_SurfaceDescriptor());
       gfxIntSize size = surf->GetSize();
-      if (mSize != size || !mTexImage) {
+      if (mSize != size || !mTexImage ||
+          mTexImage->GetContentType() != surf->GetContentType()) {
         Init(aNewFront);
       }
       // XXX this is always just ridiculously slow
       nsIntRegion updateRegion(nsIntRect(0, 0, size.width, size.height));
       mTexImage->DirectUpdate(surf, updateRegion);
     } else {
       const YUVImage& yuv = aNewFront.get_YUVImage();
 
--- a/gfx/thebes/GLContext.cpp
+++ b/gfx/thebes/GLContext.cpp
@@ -1025,24 +1025,24 @@ GLContext::ResizeOffscreenFBO(const gfxI
 
     MakeCurrent();
 
     const bool alpha = mCreationFormat.alpha > 0;
     const int depth = mCreationFormat.depth;
     const int stencil = mCreationFormat.stencil;
     int samples = mCreationFormat.samples;
 
-    const bool useDrawMSFBO = (samples > 0) && SupportsFramebufferMultisample();
+    if (!SupportsFramebufferMultisample() || aDisableAA)
+        samples = 0;
+
+    const bool useDrawMSFBO = (samples > 0);
 
     if (!useDrawMSFBO && !aUseReadFBO)
         return true;
 
-    if (!useDrawMSFBO || aDisableAA)
-        samples = 0;
-
     const bool firstTime = (mOffscreenDrawFBO == 0 && mOffscreenReadFBO == 0);
 
     GLuint curBoundFramebufferDraw = 0;
     GLuint curBoundFramebufferRead = 0;
     GLuint curBoundRenderbuffer = 0;
     GLuint curBoundTexture = 0;
 
     GLint viewport[4];
--- a/gfx/thebes/GLContext.h
+++ b/gfx/thebes/GLContext.h
@@ -1323,17 +1323,21 @@ protected:
     // for offscreen implementations that use FBOs.
     bool ResizeOffscreenFBO(const gfxIntSize& aSize, const bool aUseReadFBO, const bool aDisableAA);
     bool ResizeOffscreenFBO(const gfxIntSize& aSize, const bool aUseReadFBO) {
         if (ResizeOffscreenFBO(aSize, aUseReadFBO, false))
             return true;
 
         if (!mCreationFormat.samples)
             return false;
-        printf("ResizeOffscreenFBO failed with AA, retrying without...\n");
+
+        if (mDebugMode) {
+            printf_stderr("Requested level of multisampling is unavailable, continuing without multisampling\n");
+        }
+
         return ResizeOffscreenFBO(aSize, aUseReadFBO, true);
     }
     void DeleteOffscreenFBO();
     GLuint mOffscreenDrawFBO;
     GLuint mOffscreenReadFBO;
     GLuint mOffscreenColorRB;
     GLuint mOffscreenDepthRB;
     GLuint mOffscreenStencilRB;
--- a/gfx/thebes/gfxMatrix.h
+++ b/gfx/thebes/gfxMatrix.h
@@ -246,18 +246,17 @@ public:
      * to be assumed to be in the X direction or not.
      */
     gfxSize ScaleFactors(bool xMajor) const {
         double det = Determinant();
 
         if (det == 0.0)
             return gfxSize(0.0, 0.0);
 
-        gfxSize sz((xMajor != 0 ? 1.0 : 0.0),
-                        (xMajor != 0 ? 0.0 : 1.0));
+        gfxSize sz = xMajor ? gfxSize(1.0, 0.0) : gfxSize(0.0, 1.0);
         sz = Transform(sz);
 
         double major = sqrt(sz.width * sz.width + sz.height * sz.height);
         double minor = 0.0;
 
         // ignore mirroring
         if (det < 0.0)
             det = - det;
--- a/gfx/thebes/nsCoreAnimationSupport.h
+++ b/gfx/thebes/nsCoreAnimationSupport.h
@@ -55,49 +55,49 @@ struct _CGLPBufferObject;
 struct _CGLContextObject;
 class nsIOSurface;
 
 typedef uint32_t IOSurfaceID;
 
 class THEBES_API nsCARenderer {
   NS_INLINE_DECL_REFCOUNTING(nsCARenderer)
 public:
-  nsCARenderer() : mCARenderer(nsnull), mPixelBuffer(nsnull), mOpenGLContext(nsnull),
+  nsCARenderer() : mCARenderer(nsnull), mFBOTexture(nsnull), mOpenGLContext(nsnull),
                    mCGImage(nsnull), mCGData(nsnull), mIOSurface(nsnull), mFBO(nsnull),
-                   mIOTexture(nsnull), 
+                   mIOTexture(nsnull),
                    mUnsupportedWidth(UINT32_MAX), mUnsupportedHeight(UINT32_MAX) {}
   ~nsCARenderer();
   nsresult SetupRenderer(void* aCALayer, int aWidth, int aHeight);
   nsresult Render(int aWidth, int aHeight, CGImageRef *aOutCAImage);
   bool isInit() { return mCARenderer != nsnull; }
   /*
    * Render the CALayer to an IOSurface. If no IOSurface
    * is attached then an internal pixel buffer will be
    * used.
-   */ 
+   */
   void AttachIOSurface(nsRefPtr<nsIOSurface> aSurface);
   IOSurfaceID GetIOSurfaceID();
-  static nsresult DrawSurfaceToCGContext(CGContextRef aContext, 
-                                         nsIOSurface *surf, 
-                                         CGColorSpaceRef aColorSpace, 
+  static nsresult DrawSurfaceToCGContext(CGContextRef aContext,
+                                         nsIOSurface *surf,
+                                         CGColorSpaceRef aColorSpace,
                                          int aX, int aY,
                                          size_t aWidth, size_t aHeight);
-  
+
   // Remove & Add the layer without destroying
   // the renderer for fast back buffer swapping.
   void DettachCALayer();
   void AttachCALayer(void *aCALayer);
 #ifdef DEBUG
   static void SaveToDisk(nsIOSurface *surf);
 #endif
 private:
   void Destroy();
 
   void *mCARenderer;
-  _CGLPBufferObject     *mPixelBuffer;
+  GLuint                 mFBOTexture;
   _CGLContextObject     *mOpenGLContext;
   CGImageRef             mCGImage;
   void                  *mCGData;
   nsRefPtr<nsIOSurface>  mIOSurface;
   uint32_t               mFBO;
   uint32_t               mIOTexture;
   uint32_t               mUnsupportedWidth;
   uint32_t               mUnsupportedHeight;
--- a/gfx/thebes/nsCoreAnimationSupport.mm
+++ b/gfx/thebes/nsCoreAnimationSupport.mm
@@ -397,25 +397,25 @@ void nsCARenderer::Destroy() {
   if (mCARenderer) {
     CARenderer* caRenderer = (CARenderer*)mCARenderer;
     // Bug 556453:
     // Explicitly remove the layer from the renderer
     // otherwise it does not always happen right away.
     caRenderer.layer = nsnull;
     [caRenderer release];
   }
-  if (mPixelBuffer) {
-    ::CGLDestroyPBuffer((CGLPBufferObj)mPixelBuffer);
-  }
   if (mOpenGLContext) {
-    if (mFBO || mIOTexture) {
+    if (mFBO || mIOTexture || mFBOTexture) {
       // Release these resources with the context that allocated them
       CGLContextObj oldContext = ::CGLGetCurrentContext();
       ::CGLSetCurrentContext(mOpenGLContext);
 
+      if (mFBOTexture) {
+        ::glDeleteTextures(1, &mFBOTexture);
+      }
       if (mIOTexture) {
         ::glDeleteTextures(1, &mIOTexture);
       }
       if (mFBO) {
         ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
         ::glDeleteFramebuffersEXT(1, &mFBO);
       }
 
@@ -425,54 +425,43 @@ void nsCARenderer::Destroy() {
     ::CGLDestroyContext((CGLContextObj)mOpenGLContext);
   }
   if (mCGImage) {
     ::CGImageRelease(mCGImage);
   }
   // mCGData is deallocated by cgdata_release_callback
 
   mCARenderer = nil;
-  mPixelBuffer = nsnull;
+  mFBOTexture = 0;
   mOpenGLContext = nsnull;
   mCGImage = nsnull;
   mIOSurface = nsnull;
   mFBO = nsnull;
   mIOTexture = nsnull;
 }
 
 nsresult nsCARenderer::SetupRenderer(void *aCALayer, int aWidth, int aHeight) {
   if (aWidth == 0 || aHeight == 0)
     return NS_ERROR_FAILURE;
 
-  if (aWidth == mUnsupportedWidth && 
+  if (aWidth == mUnsupportedWidth &&
       aHeight == mUnsupportedHeight) {
     return NS_ERROR_FAILURE;
   }
 
   CALayer* layer = (CALayer*)aCALayer;
   CARenderer* caRenderer = nsnull;
 
   CGLPixelFormatAttribute attributes[] = {
     kCGLPFAAccelerated,
     kCGLPFAAllowOfflineRenderers,
     kCGLPFADepthSize, (CGLPixelFormatAttribute)24,
     (CGLPixelFormatAttribute)0
   };
 
-  if (!mIOSurface) {
-    CGLError result = ::CGLCreatePBuffer(aWidth, aHeight,
-                         GL_TEXTURE_2D, GL_RGBA, 0, &mPixelBuffer);
-    if (result != kCGLNoError) {
-      mUnsupportedWidth = aWidth;
-      mUnsupportedHeight = aHeight;
-      Destroy();
-      return NS_ERROR_FAILURE;
-    }
-  }
-
   GLint screen;
   CGLPixelFormatObj format;
   if (::CGLChoosePixelFormat(attributes, &format, &screen) != kCGLNoError) {
     mUnsupportedWidth = aWidth;
     mUnsupportedHeight = aHeight;
     Destroy();
     return NS_ERROR_FAILURE;
   }
@@ -511,95 +500,103 @@ nsresult nsCARenderer::SetupRenderer(voi
   [CATransaction setValue: [NSNumber numberWithFloat:0.0f] forKey: kCATransactionAnimationDuration];
   [CATransaction setValue: (id) kCFBooleanTrue forKey: kCATransactionDisableActions];
   [layer setBounds:CGRectMake(0, 0, aWidth, aHeight)];
   [layer setPosition:CGPointMake(aWidth/2.0, aHeight/2.0)];
   caRenderer.layer = layer;
   caRenderer.bounds = CGRectMake(0, 0, aWidth, aHeight);
   [CATransaction commit];
 
-  // We either target rendering to a CGImage or IOSurface.
+  // We target rendering to a CGImage if no shared IOSurface are given.
   if (!mIOSurface) {
     mCGData = malloc(aWidth*aHeight*4);
     if (!mCGData) {
       mUnsupportedWidth = aWidth;
       mUnsupportedHeight = aHeight;
       Destroy();
     }
     memset(mCGData, 0, aWidth*aHeight*4);
 
     CGDataProviderRef dataProvider = nsnull;
     dataProvider = ::CGDataProviderCreateWithData(mCGData,
-                                        mCGData, aHeight*aWidth*4, 
+                                        mCGData, aHeight*aWidth*4,
                                         cgdata_release_callback);
     if (!dataProvider) {
       cgdata_release_callback(mCGData, mCGData, aHeight*aWidth*4);
       mUnsupportedWidth = aWidth;
       mUnsupportedHeight = aHeight;
       Destroy();
       return NS_ERROR_FAILURE;
     }
 
     CGColorSpaceRef colorSpace = CreateSystemColorSpace();
 
-    mCGImage = ::CGImageCreate(aWidth, aHeight, 8, 32, aWidth * 4, colorSpace, 
+    mCGImage = ::CGImageCreate(aWidth, aHeight, 8, 32, aWidth * 4, colorSpace,
                 kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
                 dataProvider, NULL, true, kCGRenderingIntentDefault);
 
     ::CGDataProviderRelease(dataProvider);
     if (colorSpace) {
       ::CGColorSpaceRelease(colorSpace);
     }
     if (!mCGImage) {
       mUnsupportedWidth = aWidth;
       mUnsupportedHeight = aHeight;
       Destroy();
       return NS_ERROR_FAILURE;
     }
-  } else {
-    CGLContextObj oldContext = ::CGLGetCurrentContext();
-    ::CGLSetCurrentContext(mOpenGLContext);
+  }
 
+  CGLContextObj oldContext = ::CGLGetCurrentContext();
+  ::CGLSetCurrentContext(mOpenGLContext);
+
+  if (mIOSurface) {
     // Create the IOSurface mapped texture.
     ::glGenTextures(1, &mIOTexture);
     ::glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mIOTexture);
     ::glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     ::glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     nsIOSurfaceLib::CGLTexImageIOSurface2D(mOpenGLContext, GL_TEXTURE_RECTANGLE_ARB,
                                            GL_RGBA, aWidth, aHeight,
-                                           GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 
+                                           GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
                                            mIOSurface->mIOSurfacePtr, 0);
     ::glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
-
-    // Create the fbo
-    ::glGenFramebuffersEXT(1, &mFBO);
-    ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
-    ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 
-                                GL_TEXTURE_RECTANGLE_ARB, mIOTexture, 0);
+  } else {
+    ::glGenTextures(1, &mFBOTexture);
+    ::glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mFBOTexture);
+    ::glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    ::glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    ::glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
+  }
 
-    // Make sure that the Framebuffer configuration is supported on the client machine
-    GLenum fboStatus;
-    fboStatus = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
-    if (fboStatus != GL_FRAMEBUFFER_COMPLETE_EXT) {
-      NS_ERROR("FBO not supported");
-      if (oldContext)
-        ::CGLSetCurrentContext(oldContext);
-      mUnsupportedWidth = aWidth;
-      mUnsupportedHeight = aHeight;
-      Destroy();
-      return NS_ERROR_FAILURE; 
-    }
+  // Create the fbo
+  ::glGenFramebuffersEXT(1, &mFBO);
+  ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
+  if (mIOSurface) {
+   ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+                                GL_TEXTURE_RECTANGLE_ARB, mIOTexture, 0);
+  } else {
+    ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+                                GL_TEXTURE_RECTANGLE_ARB, mFBOTexture, 0);
+  }
 
+
+  // Make sure that the Framebuffer configuration is supported on the client machine
+  GLenum fboStatus;
+  fboStatus = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+  if (fboStatus != GL_FRAMEBUFFER_COMPLETE_EXT) {
+    NS_ERROR("FBO not supported");
     if (oldContext)
       ::CGLSetCurrentContext(oldContext);
+    mUnsupportedWidth = aWidth;
+    mUnsupportedHeight = aHeight;
+    Destroy();
+    return NS_ERROR_FAILURE;
   }
 
-  CGLContextObj oldContext = ::CGLGetCurrentContext();
-  ::CGLSetCurrentContext(mOpenGLContext);
-
   ::glViewport(0.0, 0.0, aWidth, aHeight);
   ::glMatrixMode(GL_PROJECTION);
   ::glLoadIdentity();
   ::glOrtho (0.0, aWidth, 0.0, aHeight, -1, 1);
 
   // Render upside down to speed up CGContextDrawImage
   ::glTranslatef(0.0f, aHeight, 0.0);
   ::glScalef(1.0, -1.0, 1.0);
@@ -677,17 +674,19 @@ nsresult nsCARenderer::Render(int aWidth
     }
 
     caRenderer = (CARenderer*)mCARenderer;
   }
 
   CGLContextObj oldContext = ::CGLGetCurrentContext();
   ::CGLSetCurrentContext(mOpenGLContext);
   if (!mIOSurface) {
-    ::CGLSetPBuffer(mOpenGLContext, mPixelBuffer, 0, 0, 0);
+    // If no shared IOSurface is given render to our own
+    // texture for readback.
+    ::glGenTextures(1, &mFBOTexture);
   }
 
   GLenum result = ::glGetError();
   if (result != GL_NO_ERROR) {
     NS_ERROR("Unexpected OpenGL Error");
     Destroy();
     if (oldContext)
       ::CGLSetCurrentContext(oldContext);
--- a/hal/HalImpl.h
+++ b/hal/HalImpl.h
@@ -1,10 +1,10 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: sw=2 ts=8 et ft=cpp : */
+/* vim: set sw=2 ts=8 et ft=cpp : */
 /* ***** 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/
  *
--- a/hal/HalSandbox.h
+++ b/hal/HalSandbox.h
@@ -1,10 +1,10 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: sw=2 ts=8 et ft=cpp : */
+/* vim: set sw=2 ts=8 et ft=cpp : */
 /* ***** 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/
  *
--- a/hal/fallback/FallbackHal.cpp
+++ b/hal/fallback/FallbackHal.cpp
@@ -1,10 +1,10 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: sw=2 ts=8 et ft=cpp : */
+/* vim: set sw=2 ts=8 et ft=cpp : */
 /* ***** 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/
  *
--- a/hal/sandbox/PHal.ipdl
+++ b/hal/sandbox/PHal.ipdl
@@ -1,10 +1,10 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: sw=2 ts=8 et ft=cpp : */
+/* vim: set sw=2 ts=8 et ft=cpp : */
 /* ***** 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/
  *
--- a/hal/sandbox/SandboxHal.cpp
+++ b/hal/sandbox/SandboxHal.cpp
@@ -1,10 +1,10 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: sw=2 ts=8 et ft=cpp : */
+/* vim: set sw=2 ts=8 et ft=cpp : */
 /* ***** 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/
  *
--- a/hal/sandbox/SandboxHal.h
+++ b/hal/sandbox/SandboxHal.h
@@ -1,10 +1,10 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: sw=2 ts=8 et ft=cpp : */
+/* vim: set sw=2 ts=8 et ft=cpp : */
 /* ***** 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/
  *
--- a/image/decoders/nsBMPDecoder.cpp
+++ b/image/decoders/nsBMPDecoder.cpp
@@ -58,17 +58,17 @@ namespace imagelib {
 #ifdef PR_LOGGING
 PRLogModuleInfo *gBMPLog = PR_NewLogModule("BMPDecoder");
 #endif
 
 // Convert from row (1..height) to absolute line (0..height-1)
 #define LINE(row) ((mBIH.height < 0) ? (-mBIH.height - (row)) : ((row) - 1))
 #define PIXEL_OFFSET(row, col) (LINE(row) * mBIH.width + col)
 
-nsBMPDecoder::nsBMPDecoder(RasterImage *aImage, imgIDecoderObserver* aObserver)
+nsBMPDecoder::nsBMPDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver)
  : Decoder(aImage, aObserver)
 {
   mColors = nsnull;
   mRow = nsnull;
   mImageData = nsnull;
   mCurPos = mPos = mNumColors = mRowBytes = 0;
   mOldLine = mCurLine = 1; // Otherwise decoder will never start
   mState = eRLEStateInitial;
@@ -336,38 +336,38 @@ nsBMPDecoder::WriteInternal(const char* 
                  ("BMP ALPHABITFIELDS only supports 16 or 32 bits per pixel\n"));
           PostDataError();
           return;
         }
 
         PRUint32 imageLength;
         if (mBIH.compression == BI_RLE8 || mBIH.compression == BI_RLE4 || 
             mBIH.compression == BI_ALPHABITFIELDS) {
-            rv = mImage->EnsureFrame(0, 0, 0, mBIH.width, real_height, 
-                                     gfxASurface::ImageFormatARGB32,
-                                     (PRUint8**)&mImageData, &imageLength);
+            rv = mImage.EnsureFrame(0, 0, 0, mBIH.width, real_height, 
+                                    gfxASurface::ImageFormatARGB32,
+                                    (PRUint8**)&mImageData, &imageLength);
         } else {
             // mRow is not used for RLE encoded images
             mRow = (PRUint8*)moz_malloc((mBIH.width * mBIH.bpp) / 8 + 4);
             // + 4 because the line is padded to a 4 bit boundary, but I don't want
             // to make exact calculations here, that's unnecessary.
             // Also, it compensates rounding error.
             if (!mRow) {
                 PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
                 return;
             }
 
             if (mUseAlphaData) {
-              rv = mImage->EnsureFrame(0, 0, 0, mBIH.width, real_height, 
-                                       gfxASurface::ImageFormatARGB32,
-                                       (PRUint8**)&mImageData, &imageLength);
+              rv = mImage.EnsureFrame(0, 0, 0, mBIH.width, real_height, 
+                                      gfxASurface::ImageFormatARGB32,
+                                      (PRUint8**)&mImageData, &imageLength);
             } else {
-              rv = mImage->EnsureFrame(0, 0, 0, mBIH.width, real_height, 
-                                       gfxASurface::ImageFormatRGB24,
-                                       (PRUint8**)&mImageData, &imageLength);
+              rv = mImage.EnsureFrame(0, 0, 0, mBIH.width, real_height, 
+                                      gfxASurface::ImageFormatRGB24,
+                                      (PRUint8**)&mImageData, &imageLength);
             }
         }
         if (NS_FAILED(rv) || !mImageData) {
             PostDecoderError(NS_ERROR_FAILURE);
             return;
         }
 
         // Prepare for transparency
--- a/image/decoders/nsBMPDecoder.h
+++ b/image/decoders/nsBMPDecoder.h
@@ -54,17 +54,17 @@ class RasterImage;
 
 /**
  * Decoder for BMP-Files, as used by Windows and OS/2
  */
 class nsBMPDecoder : public Decoder
 {
 public:
 
-    nsBMPDecoder(RasterImage *aImage, imgIDecoderObserver* aObserver);
+    nsBMPDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver);
     ~nsBMPDecoder();
 
     // Specifies whether or not the BMP file will contain alpha data
     // If set to true and the BMP is 32BPP, the alpha data will be
     // retrieved from the 4th byte of image data per pixel 
     void SetUseAlphaData(bool useAlphaData);
     // Obtains the bits per pixel from the internal BIH header
     PRInt32 GetBitsPerPixel() const;
--- a/image/decoders/nsGIFDecoder2.cpp
+++ b/image/decoders/nsGIFDecoder2.cpp
@@ -102,17 +102,17 @@ namespace imagelib {
     mGIFStruct.state = (s);            \
   PR_END_MACRO
 
 /* Get a 16-bit value stored in little-endian format */
 #define GETINT16(p)   ((p)[1]<<8|(p)[0])
 //////////////////////////////////////////////////////////////////////
 // GIF Decoder Implementation
 
-nsGIFDecoder2::nsGIFDecoder2(RasterImage *aImage, imgIDecoderObserver* aObserver)
+nsGIFDecoder2::nsGIFDecoder2(RasterImage &aImage, imgIDecoderObserver* aObserver)
   : Decoder(aImage, aObserver)
   , mCurrentRow(-1)
   , mLastFlushedRow(-1)
   , mImageData(nsnull)
   , mOldColor(0)
   , mCurrentFrame(-1)
   , mCurrentPass(0)
   , mLastFlushedPass(0)
@@ -145,17 +145,17 @@ nsGIFDecoder2::FinishInternal()
   // If the GIF got cut off, handle it anyway
   if (!IsSizeDecode() && mGIFOpen) {
     if (mCurrentFrame == mGIFStruct.images_decoded)
       EndImageFrame();
     PostDecodeDone();
     mGIFOpen = false;
   }
 
-  mImage->SetLoopCount(mGIFStruct.loop_count - 1);
+  mImage.SetLoopCount(mGIFStruct.loop_count - 1);
 }
 
 // Push any new rows according to mCurrentPass/mLastFlushedPass and
 // mCurrentRow/mLastFlushedRow.  Note: caller is responsible for
 // updating mlastFlushed{Row,Pass}.
 void
 nsGIFDecoder2::FlushImageData(PRUint32 fromRow, PRUint32 rows)
 {
@@ -211,45 +211,45 @@ nsresult nsGIFDecoder2::BeginImageFrame(
     format = gfxASurface::ImageFormatARGB32;
   else
     format = gfxASurface::ImageFormatRGB24;
 
   // Use correct format, RGB for first frame, PAL for following frames
   // and include transparency to allow for optimization of opaque images
   if (mGIFStruct.images_decoded) {
     // Image data is stored with original depth and palette
-    rv = mImage->EnsureFrame(mGIFStruct.images_decoded,
-                             mGIFStruct.x_offset, mGIFStruct.y_offset,
-                             mGIFStruct.width, mGIFStruct.height,
-                             format, aDepth, &mImageData, &imageDataLength,
-                             &mColormap, &mColormapSize);
+    rv = mImage.EnsureFrame(mGIFStruct.images_decoded,
+                            mGIFStruct.x_offset, mGIFStruct.y_offset,
+                            mGIFStruct.width, mGIFStruct.height,
+                            format, aDepth, &mImageData, &imageDataLength,
+                            &mColormap, &mColormapSize);
   } else {
     // Regardless of depth of input, image is decoded into 24bit RGB
-    rv = mImage->EnsureFrame(mGIFStruct.images_decoded,
-                             mGIFStruct.x_offset, mGIFStruct.y_offset,
-                             mGIFStruct.width, mGIFStruct.height,
-                             format, &mImageData, &imageDataLength);
+    rv = mImage.EnsureFrame(mGIFStruct.images_decoded,
+                            mGIFStruct.x_offset, mGIFStruct.y_offset,
+                            mGIFStruct.width, mGIFStruct.height,
+                            format, &mImageData, &imageDataLength);
   }
 
   if (NS_FAILED(rv))
     return rv;
 
-  mImage->SetFrameDisposalMethod(mGIFStruct.images_decoded,
-                                 mGIFStruct.disposal_method);
+  mImage.SetFrameDisposalMethod(mGIFStruct.images_decoded,
+                                mGIFStruct.disposal_method);
 
   // Tell the superclass we're starting a frame
   PostFrameStart();
 
   if (!mGIFStruct.images_decoded) {
     // Send a onetime invalidation for the first frame if it has a y-axis offset. 
     // Otherwise, the area may never be refreshed and the placeholder will remain
     // on the screen. (Bug 37589)
     if (mGIFStruct.y_offset > 0) {
       PRInt32 imgWidth;
-      mImage->GetWidth(&imgWidth);
+      mImage.GetWidth(&imgWidth);
       nsIntRect r(0, 0, imgWidth, mGIFStruct.y_offset);
       PostInvalidation(r);
     }
   }
 
   mCurrentFrame = mGIFStruct.images_decoded;
   return NS_OK;
 }
@@ -270,17 +270,17 @@ void nsGIFDecoder2::EndImageFrame()
     if (realFrameHeight < mGIFStruct.screen_height) {
       nsIntRect r(0, realFrameHeight,
                   mGIFStruct.screen_width,
                   mGIFStruct.screen_height - realFrameHeight);
       PostInvalidation(r);
     }
     // This transparency check is only valid for first frame
     if (mGIFStruct.is_transparent && !mSawTransparency) {
-      mImage->SetFrameHasNoAlpha(mGIFStruct.images_decoded);
+      mImage.SetFrameHasNoAlpha(mGIFStruct.images_decoded);
     }
   }
   mCurrentRow = mLastFlushedRow = -1;
   mCurrentPass = mLastFlushedPass = 0;
 
   // Only add frame if we have any rows at all
   if (mGIFStruct.rows_remaining != mGIFStruct.height) {
     if (mGIFStruct.rows_remaining && mGIFStruct.images_decoded) {
@@ -288,17 +288,17 @@ void nsGIFDecoder2::EndImageFrame()
       PRUint8 *rowp = mImageData + ((mGIFStruct.height - mGIFStruct.rows_remaining) * mGIFStruct.width);
       memset(rowp, 0, mGIFStruct.rows_remaining * mGIFStruct.width);
     }
 
     // We actually have the timeout information before we get the lzw encoded 
     // image data, at least according to the spec, but we delay in setting the 
     // timeout for the image until here to help ensure that we have the whole 
     // image frame decoded before we go off and try to display another frame.
-    mImage->SetFrameTimeout(mGIFStruct.images_decoded, mGIFStruct.delay_time);
+    mImage.SetFrameTimeout(mGIFStruct.images_decoded, mGIFStruct.delay_time);
   }
 
   // Unconditionally increment images_decoded, because we unconditionally
   // append frames in BeginImageFrame(). This ensures that images_decoded
   // always refers to the frame in mImage we're currently decoding,
   // even if some of them weren't decoded properly and thus are blank.
   mGIFStruct.images_decoded++;
 
--- a/image/decoders/nsGIFDecoder2.h
+++ b/image/decoders/nsGIFDecoder2.h
@@ -53,17 +53,17 @@ class RasterImage;
 
 //////////////////////////////////////////////////////////////////////
 // nsGIFDecoder2 Definition
 
 class nsGIFDecoder2 : public Decoder
 {
 public:
 
-  nsGIFDecoder2(RasterImage *aImage, imgIDecoderObserver* aObserver);
+  nsGIFDecoder2(RasterImage &aImage, imgIDecoderObserver* aObserver);
   ~nsGIFDecoder2();
 
   virtual void WriteInternal(const char* aBuffer, PRUint32 aCount);
   virtual void FinishInternal();
   virtual Telemetry::ID SpeedHistogram();
 
 private:
   /* These functions will be called when the decoder has a decoded row,
--- a/image/decoders/nsICODecoder.cpp
+++ b/image/decoders/nsICODecoder.cpp
@@ -94,17 +94,17 @@ nsICODecoder::GetNumColors()
     default:
       numColors = (PRUint16)-1;
     }
   }
   return numColors;
 }
 
 
-nsICODecoder::nsICODecoder(RasterImage *aImage, imgIDecoderObserver* aObserver)
+nsICODecoder::nsICODecoder(RasterImage &aImage, imgIDecoderObserver* aObserver)
  : Decoder(aImage, aObserver)
 {
   mPos = mImageOffset = mCurrIcon = mNumIcons = mBPP = mRowBytes = 0;
   mIsPNG = false;
   mRow = nsnull;
   mOldLine = mCurLine = 1; // Otherwise decoder will never start
 }
 
@@ -204,18 +204,18 @@ nsICODecoder::SetHotSpotIfCursor() {
     do_CreateInstance("@mozilla.org/supports-PRUint32;1");
   nsCOMPtr<nsISupportsPRUint32> intwrapy = 
     do_CreateInstance("@mozilla.org/supports-PRUint32;1");
 
   if (intwrapx && intwrapy) {
     intwrapx->SetData(mDirEntry.mXHotspot);
     intwrapy->SetData(mDirEntry.mYHotspot);
 
-    mImage->Set("hotspotX", intwrapx);
-    mImage->Set("hotspotY", intwrapy);
+    mImage.Set("hotspotX", intwrapx);
+    mImage.Set("hotspotY", intwrapy);
   }
 }
 
 void
 nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
 {
   NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!");
 
@@ -490,18 +490,17 @@ nsICODecoder::WriteInternal(const char* 
           if (!mRow) {
             PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
             return;
           }
         }
 
         // Ensure memory has been allocated before decoding.
         NS_ABORT_IF_FALSE(mRow, "mRow is null");
-        NS_ABORT_IF_FALSE(mImage, "mImage is null");
-        if (!mRow || !mImage) {
+        if (!mRow) {
           PostDataError();
           return;
         }
 
         while (mCurLine > 0 && aCount > 0) {
           PRUint32 toCopy = NS_MIN(rowSize - mRowBytes, aCount);
           if (toCopy) {
             memcpy(mRow + mRowBytes, aBuffer, toCopy);
--- a/image/decoders/nsICODecoder.h
+++ b/image/decoders/nsICODecoder.h
@@ -53,17 +53,17 @@ namespace mozilla {
 namespace imagelib {
 
 class RasterImage;
 
 class nsICODecoder : public Decoder
 {
 public:
 
-  nsICODecoder(RasterImage *aImage, imgIDecoderObserver* aObserver);
+  nsICODecoder(RasterImage &aImage, imgIDecoderObserver* aObserver);
   virtual ~nsICODecoder();
 
   // Obtains the width of the icon directory entry
   PRUint32 GetRealWidth() const
   {
     return mDirEntry.mWidth == 0 ? 256 : mDirEntry.mWidth; 
   }
 
--- a/image/decoders/nsIconDecoder.cpp
+++ b/image/decoders/nsIconDecoder.cpp
@@ -45,17 +45,17 @@
 #include "nspr.h"
 #include "nsRect.h"
 
 #include "ImageErrors.h"
 
 namespace mozilla {
 namespace imagelib {
 
-nsIconDecoder::nsIconDecoder(RasterImage *aImage, imgIDecoderObserver* aObserver)
+nsIconDecoder::nsIconDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver)
  : Decoder(aImage, aObserver),
    mWidth(-1),
    mHeight(-1),
    mPixBytesRead(0),
    mPixBytesTotal(0),
    mImageData(nsnull),
    mState(iconStateStart)
 {
@@ -109,19 +109,19 @@ nsIconDecoder::WriteInternal(const char 
 
         // If We're doing a size decode, we're done
         if (IsSizeDecode()) {
           mState = iconStateFinished;
           break;
         }
 
         // Add the frame and signal
-        rv = mImage->EnsureFrame(0, 0, 0, mWidth, mHeight,
-                                 gfxASurface::ImageFormatARGB32,
-                                 &mImageData, &mPixBytesTotal);
+        rv = mImage.EnsureFrame(0, 0, 0, mWidth, mHeight,
+                                gfxASurface::ImageFormatARGB32,
+                                &mImageData, &mPixBytesTotal);
         if (NS_FAILED(rv)) {
           PostDecoderError(rv);
           return;
         }
 
         // Tell the superclass we're starting a frame
         PostFrameStart();
 
--- a/image/decoders/nsIconDecoder.h
+++ b/image/decoders/nsIconDecoder.h
@@ -69,17 +69,17 @@ class RasterImage;
 //
 //
 //////////////////////////////////////////////////////////////////////////////////////////////
 
 class nsIconDecoder : public Decoder
 {
 public:
 
-  nsIconDecoder(RasterImage *aImage, imgIDecoderObserver* aObserver);
+  nsIconDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver);
   virtual ~nsIconDecoder();
 
   virtual void WriteInternal(const char* aBuffer, PRUint32 aCount);
 
   PRUint8 mWidth;
   PRUint8 mHeight;
   PRUint32 mPixBytesRead;
   PRUint32 mPixBytesTotal;
--- a/image/decoders/nsJPEGDecoder.cpp
+++ b/image/decoders/nsJPEGDecoder.cpp
@@ -104,17 +104,17 @@ METHODDEF(boolean) fill_input_buffer (j_
 METHODDEF(void) skip_input_data (j_decompress_ptr jd, long num_bytes);
 METHODDEF(void) term_source (j_decompress_ptr jd);
 METHODDEF(void) my_error_exit (j_common_ptr cinfo);
 
 /* Normal JFIF markers can't have more bytes than this. */
 #define MAX_JPEG_MARKER_LENGTH  (((PRUint32)1 << 16) - 1)
 
 
-nsJPEGDecoder::nsJPEGDecoder(RasterImage *aImage, imgIDecoderObserver* aObserver)
+nsJPEGDecoder::nsJPEGDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver)
  : Decoder(aImage, aObserver)
 {
   mState = JPEG_HEADER;
   mReading = true;
   mImageData = nsnull;
 
   mBytesToSkip = 0;
   memset(&mInfo, 0, sizeof(jpeg_decompress_struct));
@@ -387,19 +387,19 @@ nsJPEGDecoder::WriteInternal(const char 
      * when the image is a sequential JPEG.
      */
     mInfo.buffered_image = jpeg_has_multiple_scans(&mInfo);
 
     /* Used to set up image size so arrays can be allocated */
     jpeg_calc_output_dimensions(&mInfo);
 
     PRUint32 imagelength;
-    if (NS_FAILED(mImage->EnsureFrame(0, 0, 0, mInfo.image_width, mInfo.image_height,
-                                      gfxASurface::ImageFormatRGB24,
-                                      &mImageData, &imagelength))) {
+    if (NS_FAILED(mImage.EnsureFrame(0, 0, 0, mInfo.image_width, mInfo.image_height,
+                                     gfxASurface::ImageFormatRGB24,
+                                     &mImageData, &imagelength))) {
       mState = JPEG_ERROR;
       PostDecoderError(NS_ERROR_OUT_OF_MEMORY);
       PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
              ("} (could not initialize image frame)"));
       return;
     }
 
     PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
--- a/image/decoders/nsJPEGDecoder.h
+++ b/image/decoders/nsJPEGDecoder.h
@@ -81,17 +81,17 @@ typedef enum {
     JPEG_ERROR    
 } jstate;
 
 class RasterImage;
 
 class nsJPEGDecoder : public Decoder
 {
 public:
-  nsJPEGDecoder(RasterImage *aImage, imgIDecoderObserver* aObserver);
+  nsJPEGDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver);
   virtual ~nsJPEGDecoder();
 
   virtual void InitInternal();
   virtual void WriteInternal(const char* aBuffer, PRUint32 aCount);
   virtual void FinishInternal();
 
   virtual Telemetry::ID SpeedHistogram();
   void NotifyDone();
--- a/image/decoders/nsPNGDecoder.cpp
+++ b/image/decoders/nsPNGDecoder.cpp
@@ -76,17 +76,17 @@ static PRLogModuleInfo *gPNGDecoderAccou
 #define WIDTH_OFFSET 16
 #define HEIGHT_OFFSET (WIDTH_OFFSET + 4)
 #define BYTES_NEEDED_FOR_DIMENSIONS (HEIGHT_OFFSET + 4)
 
 // First 8 bytes of a PNG file
 const PRUint8 
 nsPNGDecoder::pngSignatureBytes[] = { 137, 80, 78, 71, 13, 10, 26, 10 };
 
-nsPNGDecoder::nsPNGDecoder(RasterImage *aImage, imgIDecoderObserver* aObserver)
+nsPNGDecoder::nsPNGDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver)
  : Decoder(aImage, aObserver),
    mPNG(nsnull), mInfo(nsnull),
    mCMSLine(nsnull), interlacebuf(nsnull),
    mInProfile(nsnull), mTransform(nsnull),
    mHeaderBuf(nsnull), mHeaderBytesRead(0),
    mChannels(0), mFrameIsHidden(false),
    mCMSMode(0), mDisablePremultipliedAlpha(false)
 {
@@ -112,19 +112,19 @@ nsPNGDecoder::~nsPNGDecoder()
 }
 
 // CreateFrame() is used for both simple and animated images
 void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
                                PRInt32 width, PRInt32 height,
                                gfxASurface::gfxImageFormat format)
 {
   PRUint32 imageDataLength;
-  nsresult rv = mImage->EnsureFrame(GetFrameCount(), x_offset, y_offset,
-                                    width, height, format,
-                                    &mImageData, &imageDataLength);
+  nsresult rv = mImage.EnsureFrame(GetFrameCount(), x_offset, y_offset,
+                                   width, height, format,
+                                   &mImageData, &imageDataLength);
   if (NS_FAILED(rv))
     longjmp(png_jmpbuf(mPNG), 5); // NS_ERROR_OUT_OF_MEMORY
 
   mFrameRect.x = x_offset;
   mFrameRect.y = y_offset;
   mFrameRect.width = width;
   mFrameRect.height = height;
 
@@ -135,17 +135,17 @@ void nsPNGDecoder::CreateFrame(png_uint_
 
   // Tell the superclass we're starting a frame
   PostFrameStart();
 
   PR_LOG(gPNGDecoderAccountingLog, PR_LOG_DEBUG,
          ("PNGDecoderAccounting: nsPNGDecoder::CreateFrame -- created "
           "image frame with %dx%d pixels in container %p",
           width, height,
-          mImage.get ()));
+          &mImage));
 
   mFrameHasNoAlpha = true;
 }
 
 #ifdef PNG_APNG_SUPPORTED
 // set timeout and frame disposal method for the current frame
 void nsPNGDecoder::SetAnimFrameInfo()
 {
@@ -167,52 +167,52 @@ void nsPNGDecoder::SetAnimFrameInfo()
       delay_den = 100; // so says the APNG spec
 
     // Need to cast delay_num to float to have a proper division and
     // the result to int to avoid compiler warning
     timeout = static_cast<PRInt32>
               (static_cast<PRFloat64>(delay_num) * 1000 / delay_den);
   }
 
-  PRUint32 numFrames = mImage->GetNumFrames();
+  PRUint32 numFrames = mImage.GetNumFrames();
 
-  mImage->SetFrameTimeout(numFrames - 1, timeout);
+  mImage.SetFrameTimeout(numFrames - 1, timeout);
 
   if (dispose_op == PNG_DISPOSE_OP_PREVIOUS)
-      mImage->SetFrameDisposalMethod(numFrames - 1,
-                                     RasterImage::kDisposeRestorePrevious);
+      mImage.SetFrameDisposalMethod(numFrames - 1,
+                                    RasterImage::kDisposeRestorePrevious);
   else if (dispose_op == PNG_DISPOSE_OP_BACKGROUND)
-      mImage->SetFrameDisposalMethod(numFrames - 1,
-                                     RasterImage::kDisposeClear);
+      mImage.SetFrameDisposalMethod(numFrames - 1,
+                                    RasterImage::kDisposeClear);
   else
-      mImage->SetFrameDisposalMethod(numFrames - 1,
-                                     RasterImage::kDisposeKeep);
+      mImage.SetFrameDisposalMethod(numFrames - 1,
+                                    RasterImage::kDisposeKeep);
 
   if (blend_op == PNG_BLEND_OP_SOURCE)
-      mImage->SetFrameBlendMethod(numFrames - 1, RasterImage::kBlendSource);
+      mImage.SetFrameBlendMethod(numFrames - 1, RasterImage::kBlendSource);
   /*else // 'over' is the default
-      mImage->SetFrameBlendMethod(numFrames - 1, RasterImage::kBlendOver); */
+      mImage.SetFrameBlendMethod(numFrames - 1, RasterImage::kBlendOver); */
 }
 #endif
 
 // set timeout and frame disposal method for the current frame
 void nsPNGDecoder::EndImageFrame()
 {
   if (mFrameIsHidden)
     return;
 
   PRUint32 numFrames = 1;
 #ifdef PNG_APNG_SUPPORTED
-  numFrames = mImage->GetNumFrames();
+  numFrames = mImage.GetNumFrames();
 
   // We can't use mPNG->num_frames_read as it may be one ahead.
   if (numFrames > 1) {
     // Tell the image renderer that the frame is complete
     if (mFrameHasNoAlpha)
-      mImage->SetFrameHasNoAlpha(numFrames - 1);
+      mImage.SetFrameHasNoAlpha(numFrames - 1);
 
     PostInvalidation(mFrameRect);
   }
 #endif
 
   PostFrameStop();
 }
 
@@ -791,17 +791,17 @@ nsPNGDecoder::row_callback(png_structp p
       break;
       default:
         longjmp(png_jmpbuf(decoder->mPNG), 1);
     }
 
     if (!rowHasNoAlpha)
       decoder->mFrameHasNoAlpha = false;
 
-    PRUint32 numFrames = decoder->mImage->GetNumFrames();
+    PRUint32 numFrames = decoder->mImage.GetNumFrames();
     if (numFrames <= 1) {
       // Only do incremental image display for the first frame
       // XXXbholley - this check should be handled in the superclass
       nsIntRect r(0, row_num, width, 1);
       decoder->PostInvalidation(r);
     }
   }
 }
@@ -851,17 +851,17 @@ nsPNGDecoder::end_callback(png_structp p
                static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
 
   // We shouldn't get here if we've hit an error
   NS_ABORT_IF_FALSE(!decoder->HasError(), "Finishing up PNG but hit error!");
 
 #ifdef PNG_APNG_SUPPORTED
   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL)) {
     PRInt32 num_plays = png_get_num_plays(png_ptr, info_ptr);
-    decoder->mImage->SetLoopCount(num_plays - 1);
+    decoder->mImage.SetLoopCount(num_plays - 1);
   }
 #endif
 
   // Send final notifications
   decoder->EndImageFrame();
   decoder->PostDecodeDone();
 }
 
--- a/image/decoders/nsPNGDecoder.h
+++ b/image/decoders/nsPNGDecoder.h
@@ -54,17 +54,17 @@
 
 namespace mozilla {
 namespace imagelib {
 class RasterImage;
 
 class nsPNGDecoder : public Decoder
 {
 public:
-  nsPNGDecoder(RasterImage *aImage, imgIDecoderObserver* aObserver);
+  nsPNGDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver);
   virtual ~nsPNGDecoder();
 
   virtual void InitInternal();
   virtual void WriteInternal(const char* aBuffer, PRUint32 aCount);
   virtual Telemetry::ID SpeedHistogram();
 
   void CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
                    PRInt32 width, PRInt32 height,
--- a/image/src/Decoder.cpp
+++ b/image/src/Decoder.cpp
@@ -39,32 +39,28 @@
 #include "Decoder.h"
 #include "nsIServiceManager.h"
 #include "nsIConsoleService.h"
 #include "nsIScriptError.h"
 
 namespace mozilla {
 namespace imagelib {
 
-Decoder::Decoder(RasterImage *aImage, imgIDecoderObserver* aObserver)
-  : mDecodeFlags(0)
+Decoder::Decoder(RasterImage &aImage, imgIDecoderObserver* aObserver)
+  : mImage(aImage)
+  , mObserver(aObserver)
+  , mDecodeFlags(0)
   , mFrameCount(0)
   , mFailCode(NS_OK)
   , mInitialized(false)
   , mSizeDecode(false)
   , mInFrame(false)
   , mDecodeDone(false)
   , mDataError(false)
 {
-  // We should always have an image
-  NS_ABORT_IF_FALSE(aImage, "Can't initialize decoder without an image!");
-
-  // Save our paremeters
-  mImage = aImage;
-  mObserver = aObserver;
 }
 
 Decoder::~Decoder()
 {
   NS_WARN_IF_FALSE(!mInFrame, "Shutting down decoder mid-frame!");
   mInitialized = false;
 }
 
@@ -133,40 +129,40 @@ Decoder::Finish()
     // Log data errors to the error console
     nsCOMPtr<nsIConsoleService> consoleService =
       do_GetService(NS_CONSOLESERVICE_CONTRACTID);
     nsCOMPtr<nsIScriptError2> errorObject =
       do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
 
     if (consoleService && errorObject && !HasDecoderError()) {
       nsAutoString msg(NS_LITERAL_STRING("Image corrupt or truncated: ") +
-                       NS_ConvertASCIItoUTF16(mImage->GetURIString()));
+                       NS_ConvertASCIItoUTF16(mImage.GetURIString()));
 
       errorObject->InitWithWindowID
         (msg.get(),
-         NS_ConvertUTF8toUTF16(mImage->GetURIString()).get(),
+         NS_ConvertUTF8toUTF16(mImage.GetURIString()).get(),
          nsnull,
          0, 0, nsIScriptError::errorFlag,
-         "Image", mImage->InnerWindowID()
+         "Image", mImage.InnerWindowID()
          );
   
       nsCOMPtr<nsIScriptError> error = do_QueryInterface(errorObject);
       consoleService->LogMessage(error);
     }
 
     // If we only have a data error, see if things are worth salvaging
-    bool salvage = !HasDecoderError() && mImage->GetNumFrames();
+    bool salvage = !HasDecoderError() && mImage.GetNumFrames();
 
     // If we're salvaging, say we finished decoding
     if (salvage)
-      mImage->DecodingComplete();
+      mImage.DecodingComplete();
 
     // Fire teardown notifications
     if (mObserver) {
-      mObserver->OnStopContainer(nsnull, mImage);
+      mObserver->OnStopContainer(nsnull, &mImage);
       mObserver->OnStopDecode(nsnull, salvage ? NS_OK : NS_ERROR_FAILURE, nsnull);
     }
   }
 }
 
 void
 Decoder::FinishSharedDecoder()
 {
@@ -181,21 +177,21 @@ Decoder::FlushInvalidations()
   NS_ABORT_IF_FALSE(!HasDecoderError(),
                     "Not allowed to make more decoder calls after error!");
 
   // If we've got an empty invalidation rect, we have nothing to do
   if (mInvalidRect.IsEmpty())
     return;
 
   // Tell the image that it's been updated
-  mImage->FrameUpdated(mFrameCount - 1, mInvalidRect);
+  mImage.FrameUpdated(mFrameCount - 1, mInvalidRect);
 
   // Fire OnDataAvailable
   if (mObserver) {
-    bool isCurrentFrame = mImage->GetCurrentFrameIndex() == (mFrameCount - 1);
+    bool isCurrentFrame = mImage.GetCurrentFrameIndex() == (mFrameCount - 1);
     mObserver->OnDataAvailable(nsnull, isCurrentFrame, &mInvalidRect);
   }
 
   // Clear the invalidation rectangle
   mInvalidRect.SetEmpty();
 }
 
 /*
@@ -213,21 +209,21 @@ void Decoder::FinishInternal() { }
 void
 Decoder::PostSize(PRInt32 aWidth, PRInt32 aHeight)
 {
   // Validate
   NS_ABORT_IF_FALSE(aWidth >= 0, "Width can't be negative!");
   NS_ABORT_IF_FALSE(aHeight >= 0, "Height can't be negative!");
 
   // Tell the image
-  mImage->SetSize(aWidth, aHeight);
+  mImage.SetSize(aWidth, aHeight);
 
   // Notify the observer
   if (mObserver)
-    mObserver->OnStartContainer(nsnull, mImage);
+    mObserver->OnStartContainer(nsnull, &mImage);
 }
 
 void
 Decoder::PostFrameStart()
 {
   // We shouldn't already be mid-frame
   NS_ABORT_IF_FALSE(!mInFrame, "Starting new frame but not done with old one!");
 
@@ -238,17 +234,17 @@ Decoder::PostFrameStart()
 
   // Update our state to reflect the new frame
   mFrameCount++;
   mInFrame = true;
 
   // Decoder implementations should only call this method if they successfully
   // appended the frame to the image. So mFrameCount should always match that
   // reported by the Image.
-  NS_ABORT_IF_FALSE(mFrameCount == mImage->GetNumFrames(),
+  NS_ABORT_IF_FALSE(mFrameCount == mImage.GetNumFrames(),
                     "Decoder frame count doesn't match image's!");
 
   // Fire notification
   if (mObserver)
     mObserver->OnStartFrame(nsnull, mFrameCount - 1); // frame # is zero-indexed
 }
 
 void
@@ -282,19 +278,19 @@ void
 Decoder::PostDecodeDone()
 {
   NS_ABORT_IF_FALSE(!IsSizeDecode(), "Can't be done with decoding with size decode!");
   NS_ABORT_IF_FALSE(!mInFrame, "Can't be done decoding if we're mid-frame!");
   NS_ABORT_IF_FALSE(!mDecodeDone, "Decode already done!");
   mDecodeDone = true;
 
   // Notify
-  mImage->DecodingComplete();
+  mImage.DecodingComplete();
   if (mObserver) {
-    mObserver->OnStopContainer(nsnull, mImage);
+    mObserver->OnStopContainer(nsnull, &mImage);
     mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
   }
 }
 
 void
 Decoder::PostDataError()
 {
   mDataError = true;
--- a/image/src/Decoder.h
+++ b/image/src/Decoder.h
@@ -45,17 +45,17 @@
 
 namespace mozilla {
 namespace imagelib {
 
 class Decoder
 {
 public:
 
-  Decoder(RasterImage* aImage, imgIDecoderObserver* aObserver);
+  Decoder(RasterImage& aImage, imgIDecoderObserver* aObserver);
   virtual ~Decoder();
 
   /**
    * Initialize an image decoder. Decoders may not be re-initialized.
    *
    * @param aContainer The image container to decode to.
    * @param aObserver The observer for decode notification events.
    *
@@ -196,17 +196,17 @@ protected:
   // Data errors are the fault of the source data, decoder errors are our fault
   void PostDataError();
   void PostDecoderError(nsresult aFailCode);
 
   /*
    * Member variables.
    *
    */
-  nsRefPtr<RasterImage> mImage;
+  RasterImage &mImage;
   nsCOMPtr<imgIDecoderObserver> mObserver;
 
   PRUint32 mDecodeFlags;
   bool mDecodeDone;
   bool mDataError;
 
 private:
   PRUint32 mFrameCount; // Number of frames, including anything in-progress
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -2157,32 +2157,32 @@ RasterImage::InitDecoder(bool aDoSizeDec
   // Figure out which decoder we want
   eDecoderType type = GetDecoderType(mSourceDataMimeType.get());
   CONTAINER_ENSURE_TRUE(type != eDecoderType_unknown, NS_IMAGELIB_ERROR_NO_DECODER);
 
   nsCOMPtr<imgIDecoderObserver> observer(do_QueryReferent(mObserver));
   // Instantiate the appropriate decoder
   switch (type) {
     case eDecoderType_png:
-      mDecoder = new nsPNGDecoder(this, observer);
+      mDecoder = new nsPNGDecoder(*this, observer);
       break;
     case eDecoderType_gif:
-      mDecoder = new nsGIFDecoder2(this, observer);
+      mDecoder = new nsGIFDecoder2(*this, observer);
       break;
     case eDecoderType_jpeg:
-      mDecoder = new nsJPEGDecoder(this, observer);
+      mDecoder = new nsJPEGDecoder(*this, observer);
       break;
     case eDecoderType_bmp:
-      mDecoder = new nsBMPDecoder(this, observer);
+      mDecoder = new nsBMPDecoder(*this, observer);
       break;
     case eDecoderType_ico:
-      mDecoder = new nsICODecoder(this, observer);
+      mDecoder = new nsICODecoder(*this, observer);
       break;
     case eDecoderType_icon:
-      mDecoder = new nsIconDecoder(this, observer);
+      mDecoder = new nsIconDecoder(*this, observer);
       break;
     default:
       NS_ABORT_IF_FALSE(0, "Shouldn't get here!");
   }
 
   // Initialize the decoder
   mDecoder->SetSizeDecode(aDoSizeDecode);
   mDecoder->SetDecodeFlags(mFrameDecodeFlags);
--- a/js/public/Vector.h
+++ b/js/public/Vector.h
@@ -555,36 +555,29 @@ Vector<T,N,AP>::~Vector()
  */
 template <class T, size_t N, class AP>
 STATIC_POSTCONDITION(!return || newCap >= curLength + lengthInc)
 inline bool
 Vector<T,N,AP>::calculateNewCapacity(size_t curLength, size_t lengthInc,
                                      size_t &newCap)
 {
     size_t newMinCap = curLength + lengthInc;
-    size_t newMinSize = newMinCap * sizeof(T);
 
     /*
      * Check for overflow in the above addition, below CEILING_LOG2, and later
      * multiplication by sizeof(T).
      */
     if (newMinCap < curLength ||
         newMinCap & tl::MulOverflowMask<2 * sizeof(T)>::result) {
         this->reportAllocOverflow();
         return false;
     }
 
-    /*
-     * It's best to request 2^N sized chunks because they are unlikely to be
-     * rounded up by the allocator.  (Asking for a 2^N number of elements isn't
-     * as good, because if sizeof(T) is not a power-of-two that would result in
-     * a non-2^N request size, which can cause waste.)
-     */
-    size_t newSize = RoundUpPow2(newMinSize);
-    newCap = newSize / sizeof(T);
+    /* Round up to next power of 2. */
+    newCap = RoundUpPow2(newMinCap);
 
     /*
      * Do not allow a buffer large enough that the expression ((char *)end() -
      * (char *)begin()) overflows ptrdiff_t. See Bug 510319.
      */
     if (newCap & tl::UnsafeRangeSizeMask<T>::result) {
         this->reportAllocOverflow();
         return false;
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -815,19 +815,16 @@ endif
 endif # WINNT
 
 ifeq ($(OS_ARCH),FreeBSD)
 EXTRA_LIBS	+= -pthread
 endif
 ifeq ($(OS_ARCH),Linux)
 EXTRA_LIBS	+= -ldl
 endif
-ifeq ($(OS_ARCH),OSF1)
-EXTRA_LIBS	+= -lc_r
-endif
 # Silence warnings on AIX/HP-UX from non-GNU compilers
 ifndef GNU_CC
 ifeq ($(OS_ARCH),AIX)
 # Suppress warnings from xlC
 # 1540-1281: offsetof() on null non-POD types
 # 1540-1608: anonymous unions using static data members
 CFLAGS		+= -qsuppress=1540-1281 -qsuppress=1540-1608
 CXXFLAGS	+= -qsuppress=1540-1281 -qsuppress=1540-1608
@@ -903,29 +900,18 @@ HOST_CXX := $(HOST_CXX) -DMDCPUCFG=$(TAR
 HOST_CXXFLAGS := $(patsubst -DXP_%,,$(HOST_CXXFLAGS))
 endif
 
 ifdef CROSS_COMPILE
 # jscpucfg needs to know when it's supposed to produce a config for the target
 JSCPUCFG_DEFINES = $(ACDEFINES)
 endif
 
-ifeq ($(OS_ARCH),QNX)
-ifneq ($(OS_TARGET),NTO)
-# QNX's compiler apparently can't build a binary directly from a source file.
-jscpucfg.o: jscpucfg.cpp Makefile.in
-	$(HOST_CXX) $(HOST_CXXFLAGS) -c $(JSCPUCFG_DEFINES) $(DEFINES) $(NSPR_CFLAGS) -o $@ $<
-
-jscpucfg: jscpucfg.o
-	$(HOST_CXX) $(HOST_CXXFLAGS) $(JSCPUCFG_DEFINES) $(DEFINES) -o $@ $<
-endif
-else
 jscpucfg$(HOST_BIN_SUFFIX): jscpucfg.cpp Makefile.in
 	$(HOST_CXX) $(HOST_CXXFLAGS) $(JSCPUCFG_DEFINES) $(DEFINES) $(NSPR_CFLAGS) $(HOST_OUTOPTION)$@ $<
-endif
 
 # Compute the linker flags that programs linking against SpiderMonkey should
 # pass to get SpiderMonkey and its dependencies, beyond just the -L and -l
 # for the SpiderMonkey library itself.
 # - EXTRA_DSO_LDOPTS includes the NSPR -L and -l flags.
 # - OS_LIBS includes libraries selected by the configure script.
 # - EXTRA_LIBS includes libraries selected by this Makefile.
 JS_CONFIG_LIBS=$(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) 
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -2428,16 +2428,32 @@ JS_PrintTraceThingInfo(char *buf, size_t
             break;
           }
 #endif
         }
     }
     buf[bufsize - 1] = '\0';
 }
 
+extern JS_PUBLIC_API(const char *)
+JS_GetTraceEdgeName(JSTracer *trc, char *buffer, int bufferSize)
+{
+    if (trc->debugPrinter) {
+        trc->debugPrinter(trc, buffer, bufferSize);
+        return buffer;
+    }
+    if (trc->debugPrintIndex != (size_t) - 1) {
+        JS_snprintf(buffer, bufferSize, "%s[%lu]",
+                    (const char *)trc->debugPrintArg,
+                    trc->debugPrintIndex);
+        return buffer;
+    }
+    return (const char*)trc->debugPrintArg;
+}
+
 typedef struct JSHeapDumpNode JSHeapDumpNode;
 
 struct JSHeapDumpNode {
     void            *thing;
     JSGCTraceKind   kind;
     JSHeapDumpNode  *next;          /* next sibling */
     JSHeapDumpNode  *parent;        /* node with the thing that refer to thing
                                        from this node */
@@ -2499,28 +2515,17 @@ DumpNotify(JSTracer *trc, void *thing, J
             dtrc->ok = JS_FALSE;
             return;
         }
         if (entry->key)
             return;
         entry->key = thing;
     }
 
-    if (dtrc->base.debugPrinter) {
-        dtrc->base.debugPrinter(trc, dtrc->buffer, sizeof(dtrc->buffer));
-        edgeName = dtrc->buffer;
-    } else if (dtrc->base.debugPrintIndex != (size_t)-1) {
-        JS_snprintf(dtrc->buffer, sizeof(dtrc->buffer), "%s[%lu]",
-                    (const char *)dtrc->base.debugPrintArg,
-                    dtrc->base.debugPrintIndex);
-        edgeName = dtrc->buffer;
-    } else {
-        edgeName = (const char*)dtrc->base.debugPrintArg;
-    }
-
+    edgeName = JS_GetTraceEdgeName(&dtrc->base, dtrc->buffer, sizeof(dtrc->buffer));
     edgeNameSize = strlen(edgeName) + 1;
     size_t bytes = offsetof(JSHeapDumpNode, edgeName) + edgeNameSize;
     node = (JSHeapDumpNode *) OffTheBooks::malloc_(bytes);
     if (!node) {
         dtrc->ok = JS_FALSE;
         return;
     }
 
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2802,16 +2802,19 @@ extern JS_PUBLIC_API(void)
 JS_TraceRuntime(JSTracer *trc);
 
 #ifdef DEBUG
 
 extern JS_PUBLIC_API(void)
 JS_PrintTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc,
                        void *thing, JSGCTraceKind kind, JSBool includeDetails);
 
+extern JS_PUBLIC_API(const char *)
+JS_GetTraceEdgeName(JSTracer *trc, char *buffer, int bufferSize);
+
 /*
  * DEBUG-only method to dump the object graph of heap-allocated things.
  *
  * fp:              file for the dump output.
  * start:           when non-null, dump only things reachable from start
  *                  thing. Otherwise dump all things reachable from the
  *                  runtime roots.
  * startKind:       trace kind of start if start is not null. Must be
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -192,17 +192,17 @@ namespace js {
  * 
  * In our implementation, it would be sufficient to check for JSVAL_IS_INT(id)
  * except that by using signed 31-bit integers we miss the top half of the
  * valid range. This function checks the string representation itself; note
  * that calling a standard conversion routine might allow strings such as
  * "08" or "4.0" as array indices, which they are not.
  *
  */
-bool
+JS_FRIEND_API(bool)
 StringIsArrayIndex(JSLinearString *str, jsuint *indexp)
 {
     const jschar *s = str->chars();
     uint32 length = str->length();
     const jschar *end = s + length;
 
     if (length == 0 || length > (sizeof("4294967294") - 1) || !JS7_ISDEC(*s))
         return false;
--- a/js/src/jsarray.h
+++ b/js/src/jsarray.h
@@ -63,20 +63,16 @@ JSObject::isPackedDenseArray()
 {
     JS_ASSERT(isDenseArray());
     return flags & PACKED_ARRAY;
 }
 
 namespace js {
 /* 2^32-2, inclusive */
 const uint32 MAX_ARRAY_INDEX = 4294967294u;
-    
-extern bool
-StringIsArrayIndex(JSLinearString *str, jsuint *indexp);
-    
 }
 
 inline JSBool
 js_IdIsIndex(jsid id, jsuint *indexp)
 {
     if (JSID_IS_INT(id)) {
         jsint i;
         i = JSID_TO_INT(id);
--- a/js/src/jsbool.cpp
+++ b/js/src/jsbool.cpp
@@ -49,16 +49,17 @@
 #include "jscntxt.h"
 #include "jsinfer.h"
 #include "jsversion.h"
 #include "jslock.h"
 #include "jsnum.h"
 #include "jsobj.h"
 #include "jsstr.h"
 
+#include "vm/BooleanObject-inl.h"
 #include "vm/GlobalObject.h"
 
 #include "jsinferinlines.h"
 #include "jsobjinlines.h"
 #include "jsstrinlines.h"
 
 using namespace js;
 using namespace js::types;
@@ -129,27 +130,25 @@ static JSFunctionSpec boolean_methods[] 
     JS_FN(js_toString_str,  bool_toString,  0, 0),
     JS_FN(js_valueOf_str,   bool_valueOf,   0, 0),
     JS_FS_END
 };
 
 static JSBool
 Boolean(JSContext *cx, uintN argc, Value *vp)
 {
-    Value *argv = vp + 2;
-    bool b = argc != 0 ? js_ValueToBoolean(argv[0]) : false;
+    CallArgs args = CallArgsFromVp(argc, vp);
+
+    bool b = args.length() != 0 ? js_ValueToBoolean(args[0]) : false;
 
     if (IsConstructing(vp)) {
-        JSObject *obj = NewBuiltinClassInstance(cx, &BooleanClass);
-        if (!obj)
-            return false;
-        obj->setPrimitiveThis(BooleanValue(b));
-        vp->setObject(*obj);
+        JSObject *obj = BooleanObject::create(cx, b);
+        args.rval().setObject(*obj);
     } else {
-        vp->setBoolean(b);
+        args.rval().setBoolean(b);
     }
     return true;
 }
 
 JSObject *
 js_InitBooleanClass(JSContext *cx, JSObject *obj)
 {
     JS_ASSERT(obj->isNative());
@@ -200,24 +199,24 @@ BooleanGetPrimitiveValueSlow(JSContext *
     JS_ASSERT(obj.isProxy());
 
     /*
      * To respect the proxy abstraction, we can't simply unwrap and call
      * getPrimitiveThis on the wrapped object. All we know is that obj says
      * its [[Class]] is "Boolean". Boolean.prototype.valueOf is specified to
      * return the [[PrimitiveValue]] internal property, so call that instead.
      */
-    InvokeArgsGuard args;
-    if (!cx->stack.pushInvokeArgs(cx, 0, &args))
+    InvokeArgsGuard ag;
+    if (!cx->stack.pushInvokeArgs(cx, 0, &ag))
         return false;
-    args.calleev().setUndefined();
-    args.thisv().setObject(obj);
-    if (!GetProxyHandler(&obj)->nativeCall(cx, &obj, &BooleanClass, bool_valueOf, args))
+    ag.calleev().setUndefined();
+    ag.thisv().setObject(obj);
+    if (!GetProxyHandler(&obj)->nativeCall(cx, &obj, &BooleanClass, bool_valueOf, ag))
         return false;
-    *vp = args.rval();
+    *vp = ag.rval();
     return true;
 }
 
 }  /* namespace js */
 
 JSBool
 js_ValueToBoolean(const Value &v)
 {
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -223,8 +223,99 @@ JS_GetCustomIteratorCount(JSContext *cx)
     return sCustomIteratorCount;
 }
 
 JS_FRIEND_API(void)
 JS_SetAccumulateTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback)
 {
     rt->telemetryCallback = callback;
 }
+
+#ifdef DEBUG
+
+struct DumpingChildInfo {
+    void *node;
+    JSGCTraceKind kind;
+
+    DumpingChildInfo (void *n, JSGCTraceKind k)
+        : node(n), kind(k)
+    {}
+};
+
+typedef HashSet<void *, DefaultHasher<void *>, ContextAllocPolicy> PtrSet;
+
+struct JSDumpHeapTracer : public JSTracer {
+    PtrSet visited;
+    FILE   *output;
+    Vector<DumpingChildInfo, 0, ContextAllocPolicy> nodes;
+    char   buffer[200];
+    bool   rootTracing;
+
+    JSDumpHeapTracer(JSContext *cx, FILE *fp)
+        : visited(cx), output(fp), nodes(cx)
+    {}
+};
+
+static void
+DumpHeapVisitChild(JSTracer *trc, void *thing, JSGCTraceKind kind);
+
+static void
+DumpHeapPushIfNew(JSTracer *trc, void *thing, JSGCTraceKind kind)
+{
+    JS_ASSERT(trc->callback == DumpHeapPushIfNew ||
+              trc->callback == DumpHeapVisitChild);
+    JSDumpHeapTracer *dtrc = static_cast<JSDumpHeapTracer *>(trc);
+
+    /*
+     * If we're tracing roots, print root information.  Do this even if we've
+     * already seen thing, for complete root information.
+     */
+    if (dtrc->rootTracing) {
+        fprintf(dtrc->output, "%p %s\n", thing,
+                JS_GetTraceEdgeName(dtrc, dtrc->buffer, sizeof(dtrc->buffer)));
+    }
+
+    PtrSet::AddPtr ptrEntry = dtrc->visited.lookupForAdd(thing);
+    if (ptrEntry || !dtrc->visited.add(ptrEntry, thing))
+        return;
+
+    dtrc->nodes.append(DumpingChildInfo(thing, kind));
+}
+
+static void
+DumpHeapVisitChild(JSTracer *trc, void *thing, JSGCTraceKind kind)
+{
+    JS_ASSERT(trc->callback == DumpHeapVisitChild);
+    JSDumpHeapTracer *dtrc = static_cast<JSDumpHeapTracer *>(trc);
+    const char *edgeName = JS_GetTraceEdgeName(dtrc, dtrc->buffer, sizeof(dtrc->buffer));
+    fprintf(dtrc->output, "> %p %s\n", (void *)thing, edgeName);
+    DumpHeapPushIfNew(dtrc, thing, kind);
+}
+
+void
+js::DumpHeapComplete(JSContext *cx, FILE *fp)
+{
+    JSDumpHeapTracer dtrc(cx, fp);
+    JS_TRACER_INIT(&dtrc, cx, DumpHeapPushIfNew);
+    if (!dtrc.visited.init(10000))
+        return;
+
+    /* Store and log the root information. */
+    dtrc.rootTracing = true;
+    TraceRuntime(&dtrc);
+    fprintf(dtrc.output, "==========\n");
+
+    /* Log the graph. */
+    dtrc.rootTracing = false;
+    dtrc.callback = DumpHeapVisitChild;
+
+    while (!dtrc.nodes.empty()) {
+        DumpingChildInfo dci = dtrc.nodes.popCopy();
+        JS_PrintTraceThingInfo(dtrc.buffer, sizeof(dtrc.buffer),
+                               &dtrc, dci.node, dci.kind, JS_TRUE);
+        fprintf(fp, "%p %s\n", dci.node, dtrc.buffer);
+        JS_TraceChildren(&dtrc, dci.node, dci.kind);
+    }
+
+    dtrc.visited.finish();
+}
+
+#endif
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -146,16 +146,26 @@ JS_EnumerateState(JSContext *cx, JSObjec
 #endif
 
 JS_END_EXTERN_C
 
 #ifdef __cplusplus
 
 namespace js {
 
+#ifdef DEBUG
+ /*
+  * DEBUG-only method to dump the complete object graph of heap-allocated things.
+  * fp is the file for the dump output.
+  */
+extern JS_FRIEND_API(void)
+DumpHeapComplete(JSContext *cx, FILE *fp);
+
+#endif
+
 class JS_FRIEND_API(AutoPreserveCompartment) {
   private:
     JSContext *cx;
     JSCompartment *oldCompartment;
   public:
     AutoPreserveCompartment(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM);
     ~AutoPreserveCompartment();
     JS_DECL_USE_GUARD_OBJECT_NOTIFIER
@@ -329,16 +339,19 @@ static inline js::StrictPropertyOp
 CastAsJSStrictPropertyOp(JSObject *object)
 {
     return JS_DATA_TO_FUNC_PTR(js::StrictPropertyOp, object);
 }
 
 JS_FRIEND_API(bool)
 GetPropertyNames(JSContext *cx, JSObject *obj, uintN flags, js::AutoIdVector *props);
 
+JS_FRIEND_API(bool)
+StringIsArrayIndex(JSLinearString *str, jsuint *indexp);
+
 /*
  * NB: these flag bits are encoded into the bytecode stream in the immediate
  * operand of JSOP_ITER, so don't change them without advancing jsxdrapi.h's
  * JSXDR_BYTECODE_VERSION.
  */
 #define JSITER_ENUMERATE  0x1   /* for-in compatible hidden default iterator */
 #define JSITER_FOREACH    0x2   /* return [key, value] pair rather than key */
 #define JSITER_KEYVALUE   0x4   /* destructuring for-in wants [key, value] */
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -610,22 +610,32 @@ struct ChunkBitmap {
         }
         return true;
     }
 #endif
 };
 
 JS_STATIC_ASSERT(ArenaBitmapBytes * ArenasPerChunk == sizeof(ChunkBitmap));
 
+const size_t ChunkPadSize = GC_CHUNK_SIZE
+                            - (sizeof(Arena) * ArenasPerChunk)
+                            - sizeof(ChunkBitmap)
+                            - sizeof(ChunkInfo);
+JS_STATIC_ASSERT(ChunkPadSize < BytesPerArena);
+
 /*
  * Chunks contain arenas and associated data structures (mark bitmap, delayed
  * marking state).
  */
 struct Chunk {
     Arena           arenas[ArenasPerChunk];
+
+    /* Pad to full size to ensure cache alignment of ChunkInfo. */
+    uint8           padding[ChunkPadSize];
+
     ChunkBitmap     bitmap;
     ChunkInfo       info;
 
     static Chunk *fromAddress(uintptr_t addr) {
         addr &= ~GC_CHUNK_MASK;
         return reinterpret_cast<Chunk *>(addr);
     }
 
@@ -662,18 +672,17 @@ struct Chunk {
 
     static Chunk *allocate(JSRuntime *rt);
     static inline void release(JSRuntime *rt, Chunk *chunk);
 
   private:
     inline void init();
 };
 
-JS_STATIC_ASSERT(sizeof(Chunk) <= GC_CHUNK_SIZE);
-JS_STATIC_ASSERT(sizeof(Chunk) + BytesPerArena > GC_CHUNK_SIZE);
+JS_STATIC_ASSERT(sizeof(Chunk) == GC_CHUNK_SIZE);
 
 class ChunkPool {
     Chunk   *emptyChunkListHead;
     size_t  emptyCount;
 
   public:
     ChunkPool()
       : emptyChunkListHead(NULL),
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -86,16 +86,17 @@
 #include "frontend/Parser.h"
 
 #include "jsarrayinlines.h"
 #include "jsinterpinlines.h"
 #include "jsscopeinlines.h"
 #include "jsscriptinlines.h"
 #include "jsobjinlines.h"
 
+#include "vm/BooleanObject-inl.h"
 #include "vm/NumberObject-inl.h"
 #include "vm/StringObject-inl.h"
 
 #if JS_HAS_GENERATORS
 #include "jsiter.h"
 #endif
 
 #if JS_HAS_XML_SUPPORT
@@ -6778,22 +6779,17 @@ JSObject *
 PrimitiveToObject(JSContext *cx, const Value &v)
 {
     if (v.isString())
         return StringObject::create(cx, v.toString());
     if (v.isNumber())
         return NumberObject::create(cx, v.toNumber());
 
     JS_ASSERT(v.isBoolean());
-    JSObject *obj = NewBuiltinClassInstance(cx, &BooleanClass);
-    if (!obj)
-        return NULL;
-
-    obj->setPrimitiveThis(v);
-    return obj;
+    return BooleanObject::create(cx, v.toBoolean());
 }
 
 JSBool
 js_PrimitiveToObject(JSContext *cx, Value *vp)
 {
     JSObject *obj = PrimitiveToObject(cx, *vp);
     if (!obj)
         return false;
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -343,16 +343,17 @@ extern Class SlowArrayClass;
 extern Class StopIterationClass;
 extern Class StringClass;
 extern Class StrictArgumentsObjectClass;
 extern Class WeakMapClass;
 extern Class WithClass;
 extern Class XMLFilterClass;
 
 class ArgumentsObject;
+class BooleanObject;
 class GlobalObject;
 class NormalArgumentsObject;
 class NumberObject;
 class StrictArgumentsObject;
 class StringObject;
 class RegExpObject;
 
 }  /* namespace js */
@@ -1019,16 +1020,17 @@ struct JSObject : js::gc::Cell {
     inline void setPrimitiveThis(const js::Value &pthis);
 
     static size_t getPrimitiveThisOffset() {
         /* All primitive objects have their value in a fixed slot. */
         return getFixedSlotOffset(JSSLOT_PRIMITIVE_THIS);
     }
 
   public:
+    inline js::BooleanObject *asBoolean();
     inline js::NumberObject *asNumber();
     inline js::StringObject *asString();
     inline js::RegExpObject *asRegExp();
 
     /*
      * Array-specific getters and setters (for both dense and slow arrays).
      */
 
--- a/js/src/jsxml.cpp
+++ b/js/src/jsxml.cpp
@@ -1761,17 +1761,17 @@ ParseXMLSource(JSContext *cx, JSString *
     }
 
     {
         Parser parser(cx);
         if (parser.init(chars, length, filename, lineno, cx->findVersion())) {
             JSObject *scopeChain = GetCurrentScopeChain(cx);
             if (!scopeChain) {
                 cx->free_(chars);
-                return false;
+                return NULL;
             }
 
             ParseNode *pn = parser.parseXMLText(scopeChain, false);
             uintN flags;
             if (pn && GetXMLSettingFlags(cx, &flags)) {
                 AutoNamespaceArray namespaces(cx);
                 if (namespaces.array.setCapacity(cx, 1))
                     xml = ParseNodeToXML(&parser, pn, &namespaces.array, flags);
new file mode 100644
--- /dev/null
+++ b/js/src/vm/BooleanObject-inl.h
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=78:
+ *
+ * ***** 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/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is SpiderMonkey string object code.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Terrence Cole <tcole+code@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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
+ * 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 ***** */
+
+#ifndef BooleanObject_inl_h___
+#define BooleanObject_inl_h___
+
+#include "jsobjinlines.h"
+
+#include "vm/BooleanObject.h"
+
+inline js::BooleanObject *
+JSObject::asBoolean()
+{
+    JS_ASSERT(isBoolean());
+    return static_cast<js::BooleanObject *>(const_cast<JSObject *>(this));
+}
+
+namespace js {
+
+inline BooleanObject *
+BooleanObject::create(JSContext *cx, bool b)
+{
+    JSObject *obj = NewBuiltinClassInstance(cx, &BooleanClass);
+    if (!obj)
+        return NULL;
+    BooleanObject *boolobj = obj->asBoolean();
+    boolobj->setPrimitiveValue(b);
+    return boolobj;
+}
+
+inline BooleanObject *
+BooleanObject::createWithProto(JSContext *cx, bool b, JSObject &proto)
+{
+    JSObject *obj = NewObjectWithClassProto(cx, &BooleanClass, &proto,
+                                            gc::GetGCObjectKind(RESERVED_SLOTS));
+    if (!obj)
+        return NULL;
+    BooleanObject *boolobj = obj->asBoolean();
+    boolobj->setPrimitiveValue(b);
+    return boolobj;
+}
+
+} // namespace js
+
+#endif /* BooleanObject_inl_h__ */
new file mode 100644
--- /dev/null
+++ b/js/src/vm/BooleanObject.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=78:
+ *
+ * ***** 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/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is SpiderMonkey boolean object code.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Terrence Cole <tcole+code@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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
+ * 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 ***** */
+
+#ifndef BooleanObject_h___
+#define BooleanObject_h___
+
+#include "jsbool.h"
+
+namespace js {
+
+class BooleanObject : public ::JSObject
+{
+    /* Stores this Boolean object's [[PrimitiveValue]]. */
+    static const uintN PRIMITIVE_VALUE_SLOT = 0;
+
+  public:
+    static const uintN RESERVED_SLOTS = 1;
+
+    /*
+     * Creates a new Boolean object boxing the given primitive bool.  The
+     * object's [[Prototype]] is determined from context.
+     */
+    static inline BooleanObject *create(JSContext *cx, bool b);
+
+    /*
+     * Identical to create(), but uses |proto| as [[Prototype]].  This method
+     * must not be used to create |Boolean.prototype|.
+     */
+    static inline BooleanObject *createWithProto(JSContext *cx, bool b, JSObject &proto);
+
+    Value unbox() const {
+        JS_ASSERT(getSlot(PRIMITIVE_VALUE_SLOT).isBoolean());
+        return getSlot(PRIMITIVE_VALUE_SLOT);
+    }
+
+  private:
+    inline void setPrimitiveValue(bool b) {
+        setSlot(PRIMITIVE_VALUE_SLOT, BooleanValue(b));
+    }
+
+    /* For access to init, as Boolean.prototype is special. */
+    friend JSObject *
+    ::js_InitBooleanClass(JSContext *cx, JSObject *global);
+
+  private:
+    BooleanObject();
+    BooleanObject &operator=(const BooleanObject &bo);
+};
+
+} // namespace js
+
+#endif /* BooleanObject_h__ */
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -1824,17 +1824,17 @@ JSObject *
 Debugger::newDebuggerScript(JSContext *cx, JSScript *script, JSObject *holder)
 {
     assertSameCompartment(cx, object);
 
     JSObject *proto = &object->getReservedSlot(JSSLOT_DEBUG_SCRIPT_PROTO).toObject();
     JS_ASSERT(proto);
     JSObject *scriptobj = NewNonFunction<WithProto::Given>(cx, &DebuggerScript_class, proto, NULL);
     if (!scriptobj || !scriptobj->ensureClassReservedSlots(cx))
-        return false;
+        return NULL;
     scriptobj->setPrivate(script);
     scriptobj->setReservedSlot(JSSLOT_DEBUGSCRIPT_OWNER, ObjectValue(*object));
     scriptobj->setReservedSlot(JSSLOT_DEBUGSCRIPT_HOLDER, PrivateValue(holder));
 
     return scriptobj;
 }
 
 JSObject *
--- a/js/xpconnect/shell/Makefile.in
+++ b/js/xpconnect/shell/Makefile.in
@@ -69,16 +69,19 @@ NSDISTMODE = copy
 
 ifdef _MSC_VER
 ifeq ($(OS_TEST),x86_64)
 # set stack to 2MB on x64 build.  See bug 582910
 WIN32_EXE_LDFLAGS += -STACK:2097152
 endif
 endif
 
+ifeq ($(OS_TEST),ia64)
+LIBS += $(JEMALLOC_LIBS)
+endif
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
 DEFINES		+= -DJS_THREADSAFE
 
 ifdef MOZ_SHARK
 DEFINES += -DMOZ_SHARK
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -431,17 +431,17 @@ TraceCompartment(xpc::PtrAndPrincipalHas
 }
 
 void XPCJSRuntime::TraceXPConnectRoots(JSTracer *trc)
 {
     JSContext *iter = nsnull, *acx;
     while ((acx = JS_ContextIterator(GetJSRuntime(), &iter))) {
         JS_ASSERT(acx->hasRunOption(JSOPTION_UNROOTED_GLOBAL));
         if (acx->globalObject)
-            JS_CALL_OBJECT_TRACER(trc, acx->globalObject, "global object");
+            JS_CALL_OBJECT_TRACER(trc, acx->globalObject, "XPC global object");
     }
 
     XPCAutoLock lock(mMapLock);
 
     XPCWrappedNativeScope::TraceJS(trc, this);
 
     for (XPCRootSetElem *e = mVariantRoots; e ; e = e->GetNextRoot())
         static_cast<XPCTraceableVariant*>(e)->TraceJS(trc);
--- a/js/xpconnect/src/dombindings.cpp
+++ b/js/xpconnect/src/dombindings.cpp
@@ -482,16 +482,18 @@ ListBase<LC>::create(JSContext *cx, XPCW
     if (js::GetObjectGlobal(parent) != scope->GetGlobalJSObject()) {
         if (!ac.enter(cx, parent))
             return NULL;
 
         scope = XPCWrappedNativeScope::FindInJSObjectScope(cx, parent);
     }
 
     JSObject *proto = getPrototype(cx, scope, triedToWrap);
+    if (!proto && !*triedToWrap)
+        aWrapperCache->ClearIsProxy();
     if (!proto)
         return NULL;
     JSObject *obj = NewProxyObject(cx, &ListBase<LC>::instance,
                                    PrivateValue(aList), proto, parent);
     if (!obj)
         return NULL;
 
     NS_ADDREF(aList);
@@ -534,16 +536,19 @@ GetArrayIndexFromId(JSContext *cx, jsid 
         return JSID_TO_INT(id);
     if (NS_LIKELY(id == s_length_id))
         return -1;
     if (NS_LIKELY(JSID_IS_ATOM(id))) {
         JSAtom *atom = JSID_TO_ATOM(id);
         jschar s = *atom->chars();
         if (NS_LIKELY((unsigned)s >= 'a' && (unsigned)s <= 'z'))
             return -1;
+
+        jsuint i;
+        return js::StringIsArrayIndex(JSID_TO_ATOM(id), &i) ? i : -1;
     }
     return IdToInt32(cx, id);
 }
 
 static void
 FillPropertyDescriptor(PropertyDescriptor *desc, JSObject *obj, jsval v, bool readonly)
 {
     desc->obj = obj;
--- a/js/xpconnect/tests/chrome/test_nodelists.xul
+++ b/js/xpconnect/tests/chrome/test_nodelists.xul
@@ -25,17 +25,20 @@
         is(list[0], list.item(0), "list.item works");
         is(list.item, list.item, "don't recreate functions for each get");
 
         var list2 = list[2];
         ok(list[2].toString().indexOf("[object HTMLParagraphElement"), "list[2] exists");
         ok("2" in list, "in operator works");
 
         is(win.document.body.removeChild(win.document.body.lastChild), list2, "remove last paragraph element");
-        ok(!("2" in list), "in operator doesn't see phantom element");
+        if (SpecialPowers.getBoolPref("dom.new_bindings"))
+            ok(!("2" in list), "in operator doesn't see phantom element");
+        else
+            todo(!("2" in list), "in operator doesn't see phantom element");
         is(list[2], undefined, "no node there!");
         SimpleTest.finish();
       }
   ]]></script>
 
   <iframe id="ifr"
           src="http://mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_nodelists.html"
           onload="go()" />
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3877,16 +3877,41 @@ nsCSSFrameConstructor::CreateAnonymousFr
       // create the frame and attach it to our frame
       ConstructFrame(aState, content, aParentFrame, aChildItems);
     }
   }
 
   return NS_OK;
 }
 
+static void
+SetFlagsOnSubtree(nsIContent *aNode, PtrBits aFlagsToSet)
+{
+#ifdef DEBUG
+  // Make sure that the node passed to us doesn't have any XBL children
+  {
+    nsIDocument *doc = aNode->OwnerDoc();
+    NS_ASSERTION(doc, "The node must be in a document");
+    NS_ASSERTION(!doc->BindingManager()->GetXBLChildNodesFor(aNode),
+                 "The node should not have any XBL children");
+  }
+#endif
+
+  // Set the flag on the node itself
+  aNode->SetFlags(aFlagsToSet);
+
+  // Set the flag on all of its children recursively
+  PRUint32 count;
+  nsIContent * const *children = aNode->GetChildArray(&count);
+
+  for (PRUint32 index = 0; index < count; ++index) {
+    SetFlagsOnSubtree(children[index], aFlagsToSet);
+  }
+}
+
 nsresult
 nsCSSFrameConstructor::GetAnonymousContent(nsIContent* aParent,
                                            nsIFrame* aParentFrame,
                                            nsTArray<nsIAnonymousContentCreator::ContentInfo>& aContent)
 {
   nsIAnonymousContentCreator* creator = do_QueryFrame(aParentFrame);
   if (!creator)
     return NS_OK;
@@ -3904,17 +3929,27 @@ nsCSSFrameConstructor::GetAnonymousConte
     // cascading rules for <svg:use> - bug 265894
     if (aParent &&
         aParent->NodeInfo()->Equals(nsGkAtoms::use, kNameSpaceID_SVG)) {
       content->SetFlags(NODE_IS_ANONYMOUS);
     } else {
       content->SetNativeAnonymous();
     }
 
+    bool anonContentIsEditable = content->HasFlag(NODE_IS_EDITABLE);
     rv = content->BindToTree(mDocument, aParent, aParent, true);
+    // If the anonymous content creator requested that the content should be
+    // editable, honor its request.
+    // We need to set the flag on the whole subtree, because existing
+    // children's flags have already been set as part of the BindToTree operation.
+    if (anonContentIsEditable) {
+      NS_ASSERTION(aParentFrame->GetType() == nsGkAtoms::textInputFrame,
+                   "We only expect this for anonymous content under a text control frame");
+      SetFlagsOnSubtree(content, NODE_IS_EDITABLE);
+    }
     if (NS_FAILED(rv)) {
       content->UnbindFromTree();
       return rv;
     }
   }
 
   return NS_OK;
 }
@@ -6127,59 +6162,40 @@ nsCSSFrameConstructor::ReframeTextIfNeed
     // NS_CREATE_FRAME_IF_NON_WHITESPACE flag)
     return;
   }
   NS_ASSERTION(!aContent->GetPrimaryFrame(),
                "Text node has a frame and NS_CREATE_FRAME_IF_NON_WHITESPACE");
   ContentInserted(aParentContent, aContent, nsnull, false);
 }
 
-// We want to disable lazy frame construction for nodes that are under an
-// editor. We use nsINode::IsEditable, but that includes inputs with type text
-// and password and textareas, which are common and aren't really editable (the
-// native anonymous content under them is what is actually editable) so we want
-// to construct frames for those lazily.
-// The logic for this check is based on
-// nsGenericHTMLFormElement::UpdateEditableFormControlState and so must be kept
-// in sync with that.  MayHaveContentEditableAttr() being true only indicates
-// a contenteditable attribute, it doesn't indicate whether it is true or false,
-// so we force eager construction in some cases when the node is not editable,
-// but that should be rare.
-static inline bool
-IsActuallyEditable(nsIContent* aContainer, nsIContent* aChild)
-{
-  return (aChild->IsEditable() &&
-          (aContainer->IsEditable() ||
-           aChild->MayHaveContentEditableAttr()));
-}
-
 // For inserts aChild should be valid, for appends it should be null.
 // Returns true if this operation can be lazy, false if not.
 bool
 nsCSSFrameConstructor::MaybeConstructLazily(Operation aOperation,
                                             nsIContent* aContainer,
                                             nsIContent* aChild)
 {
   if (mPresShell->GetPresContext()->IsChrome() || !aContainer ||
       aContainer->IsInNativeAnonymousSubtree() || aContainer->IsXUL()) {
     return false;
   }
 
   if (aOperation == CONTENTINSERT) {
     if (aChild->IsRootOfAnonymousSubtree() ||
-        aChild->IsXUL() || IsActuallyEditable(aContainer, aChild)) {
+        aChild->IsEditable() || aChild->IsXUL()) {
       return false;
     }
   } else { // CONTENTAPPEND
     NS_ASSERTION(aOperation == CONTENTAPPEND,
                  "operation should be either insert or append");
     for (nsIContent* child = aChild; child; child = child->GetNextSibling()) {
       NS_ASSERTION(!child->IsRootOfAnonymousSubtree(),
                    "Should be coming through the CONTENTAPPEND case");
-      if (child->IsXUL() || IsActuallyEditable(aContainer, child)) {
+      if (child->IsXUL() || child->IsEditable()) {
         return false;
       }
     }
   }
 
   // We can construct lazily; just need to set suitable bits in the content
   // tree.
 
@@ -9283,19 +9299,25 @@ nsCSSFrameConstructor::CreateNeededTable
       do {
         /* Walk an iterator past any whitespace that we might be able to drop from the list */
         FCItemIterator spaceEndIter(endIter);
         if (prevParentType != eTypeBlock &&
             !aParentFrame->IsGeneratedContentFrame() &&
             spaceEndIter.item().IsWhitespace(aState)) {
           bool trailingSpaces = spaceEndIter.SkipWhitespace(aState);
 
-          // See whether we can drop the whitespace
-          if (trailingSpaces ||
-              spaceEndIter.item().DesiredParentType() != eTypeBlock) {
+          // We drop the whitespace if these are not trailing spaces and the next item
+          // does not want a block parent (see case 2 above)
+          // if these are trailing spaces and aParentFrame is a tabular container
+          // according to rule 1.3 of CSS 2.1 Sec 17.2.1. (Being a tabular container
+          // pretty much means ourParentType != eTypeBlock besides the eTypeColGroup case,
+          // which won't reach here.)
+          if ((trailingSpaces && ourParentType != eTypeBlock) ||
+              (!trailingSpaces && spaceEndIter.item().DesiredParentType() != 
+               eTypeBlock)) {
             bool updateStart = (iter == endIter);
             endIter.DeleteItemsTo(spaceEndIter);
             NS_ASSERTION(trailingSpaces == endIter.IsDone(), "These should match");
 
             if (updateStart) {
               iter = endIter;
             }
 
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -2972,25 +2972,8 @@ bool nsDisplaySVGEffects::TryMerge(nsDis
   if (aItem->GetUnderlyingFrame()->GetContent() != mFrame->GetContent())
     return false;
   nsDisplaySVGEffects* other = static_cast<nsDisplaySVGEffects*>(aItem);
   mList.AppendToBottom(&other->mList);
   mBounds.UnionRect(mBounds,
     other->mBounds + other->mEffectsFrame->GetOffsetTo(mEffectsFrame));
   return true;
 }
-
-nsDisplayForcePaintOnScroll::nsDisplayForcePaintOnScroll(
-    nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
-  : nsDisplayItem(aBuilder, aFrame) {
-  MOZ_COUNT_CTOR(nsDisplayForcePaintOnScroll);
-}
-
-#ifdef NS_BUILD_REFCNT_LOGGING
-nsDisplayForcePaintOnScroll::~nsDisplayForcePaintOnScroll() {
-  MOZ_COUNT_DTOR(nsDisplayForcePaintOnScroll);
-}
-#endif
-
-bool nsDisplayForcePaintOnScroll::IsVaryingRelativeToMovingFrame(
-         nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) {
-  return true;
-}
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -2256,27 +2256,9 @@ public:
             t == nsDisplayItem::TYPE_TEXT_SHADOW)
       ? static_cast<nsCharClipDisplayItem*>(aItem) : nsnull;
   }
 
   nscoord mLeftEdge;  // length from the left side
   nscoord mRightEdge; // length from the right side
 };
 
-
-/**
- * This is a dummy item that reports true for IsVaryingRelativeToMovingFrame.
- * It forces the bounds of its frame to be repainted every time it is scrolled.
- * It is transparent to events and does not paint anything.
- */
-class nsDisplayForcePaintOnScroll : public nsDisplayItem
-{
-public:
-  nsDisplayForcePaintOnScroll(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
-#ifdef NS_BUILD_REFCNT_LOGGING
-  virtual ~nsDisplayForcePaintOnScroll();
-#endif
-  NS_DISPLAY_DECL_NAME("ForcePaintOnScroll", TYPE_FORCEPAINTONSCROLL)
-  virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
-                                                nsIFrame* aFrame);
-};
-
 #endif /*NSDISPLAYLIST_H_*/
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -4256,33 +4256,32 @@ nsLayoutUtils::GetFontFacesForText(nsIFr
   NS_PRECONDITION(aFrame, "NULL frame pointer");
 
   if (aFrame->GetType() != nsGkAtoms::textFrame) {
     return NS_OK;
   }
 
   nsTextFrame* curr = static_cast<nsTextFrame*>(aFrame);
   do {
-    PRInt32 offset = curr->GetContentOffset();
-    PRInt32 fstart = NS_MAX(offset, aStartOffset);
+    PRInt32 fstart = NS_MAX(curr->GetContentOffset(), aStartOffset);
     PRInt32 fend = NS_MIN(curr->GetContentEnd(), aEndOffset);
     if (fstart >= fend) {
       continue;
     }
 
     // overlapping with the offset we want
-    curr->EnsureTextRun();
+    gfxSkipCharsIterator iter = curr->EnsureTextRun();
     gfxTextRun* textRun = curr->GetTextRun();
     NS_ENSURE_TRUE(textRun, NS_ERROR_OUT_OF_MEMORY);
 
-    gfxSkipCharsIterator iter(textRun->GetSkipChars());
-    PRUint32 skipStart = iter.ConvertOriginalToSkipped(fstart - offset);
-    PRUint32 skipEnd = iter.ConvertOriginalToSkipped(fend - offset);
+    PRUint32 skipStart = iter.ConvertOriginalToSkipped(fstart);
+    PRUint32 skipEnd = iter.ConvertOriginalToSkipped(fend);
     aFontFaceList->AddFontsFromTextRun(textRun,
-                                       skipStart, skipEnd - skipStart,
+                                       skipStart,
+                                       skipEnd - skipStart,
                                        curr);
   } while (aFollowContinuations &&
            (curr = static_cast<nsTextFrame*>(curr->GetNextContinuation())));
 
   return NS_OK;
 }
 
 /* static */
--- a/layout/generic/TextOverflow.cpp
+++ b/layout/generic/TextOverflow.cpp
@@ -46,16 +46,17 @@
 #include "nsCaret.h"
 #include "nsContentUtils.h"
 #include "nsIScrollableFrame.h"
 #include "nsLayoutUtils.h"
 #include "nsPresContext.h"
 #include "nsRect.h"
 #include "nsRenderingContext.h"
 #include "nsTextFrame.h"
+#include "nsGfxScrollFrame.h"
 
 namespace mozilla {
 namespace css {
 
 static const PRUnichar kEllipsisChar[] = { 0x2026, 0x0 };
 static const PRUnichar kASCIIPeriodsChar[] = { '.', '.', '.', 0x0 };
 
 // Return an ellipsis if the font supports it,
@@ -273,46 +274,31 @@ TextOverflow::WillProcessLines(nsDisplay
   textOverflow->mContentArea = aBlockFrame->GetContentRectRelativeToSelf();
   nsIScrollableFrame* scroll =
     nsLayoutUtils::GetScrollableFrameFor(aBlockFrame);
   textOverflow->mCanHaveHorizontalScrollbar = false;
   if (scroll) {
     textOverflow->mCanHaveHorizontalScrollbar =
       scroll->GetScrollbarStyles().mHorizontal != NS_STYLE_OVERFLOW_HIDDEN;
     textOverflow->mContentArea.MoveBy(scroll->GetScrollPosition());
+    nsIFrame* scrollFrame = do_QueryFrame(scroll);
+    scrollFrame->AddStateBits(NS_SCROLLFRAME_INVALIDATE_CONTENTS_ON_SCROLL);
   }
   PRUint8 direction = aBlockFrame->GetStyleVisibility()->mDirection;
   textOverflow->mBlockIsRTL = direction == NS_STYLE_DIRECTION_RTL;
   const nsStyleTextReset* style = aBlockFrame->GetStyleTextReset();
   textOverflow->mLeft.Init(style->mTextOverflow.GetLeft(direction));
   textOverflow->mRight.Init(style->mTextOverflow.GetRight(direction));
   // The left/right marker string is setup in ExamineLineFrames when a line
   // has overflow on that side.
 
   return textOverflow.forget();
 }
 
 void
-TextOverflow::DidProcessLines()
-{
-  nsIScrollableFrame* scroll = nsLayoutUtils::GetScrollableFrameFor(mBlock);
-  if (scroll) {
-    // Create a dummy item covering the entire area, it doesn't paint
-    // but reports true for IsVaryingRelativeToMovingFrame().
-    nsIFrame* scrollFrame = do_QueryFrame(scroll);
-    nsDisplayItem* marker = new (mBuilder)
-      nsDisplayForcePaintOnScroll(mBuilder, scrollFrame);
-    if (marker) {
-      mMarkerList->AppendNewToBottom(marker);
-      mBlock->PresContext()->SetHasFixedBackgroundFrame();
-    }
-  }
-}
-
-void
 TextOverflow::ExamineFrameSubtree(nsIFrame*       aFrame,
                                   const nsRect&   aContentArea,
                                   const nsRect&   aInsideMarkersArea,
                                   FrameHashtable* aFramesToHide,
                                   AlignmentEdges* aAlignmentEdges)
 {
   const nsIAtom* frameType = aFrame->GetType();
   if (frameType == nsGkAtoms::brFrame ||
--- a/layout/generic/TextOverflow.h
+++ b/layout/generic/TextOverflow.h
@@ -47,17 +47,16 @@
 namespace mozilla {
 namespace css {
 
 /**
  * A class for rendering CSS3 text-overflow.
  * Usage:
  *  1. allocate an object using WillProcessLines
  *  2. then call ProcessLine for each line you are building display lists for
- *  3. finally call DidProcessLines
  */
 class TextOverflow {
  public:
   /**
    * Allocate an object for text-overflow processing.
    * @return nsnull if no processing is necessary.  The caller owns the object.
    */
   static TextOverflow* WillProcessLines(nsDisplayListBuilder*   aBuilder,
@@ -66,22 +65,16 @@ class TextOverflow {
   /**
    * Analyze the display lists for text overflow and what kind of item is at
    * the content edges.  Add display items for text-overflow markers as needed
    * and remove or clip items that would overlap a marker.
    */
   void ProcessLine(const nsDisplayListSet& aLists, nsLineBox* aLine);
 
   /**
-   * Do final processing, currently just adds a dummy item for scroll frames
-   * to make IsVaryingRelativeToMovingFrame() true for the entire area.
-   */
-  void DidProcessLines();
-
-  /**
    * @return true if aBlockFrame needs analysis for text overflow.
    */
   static bool CanHaveTextOverflow(nsDisplayListBuilder* aBuilder,
                                   nsIFrame*             aBlockFrame);
 
   typedef nsTHashtable<nsPtrHashKey<nsIFrame> > FrameHashtable;
 
  protected:
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -6242,21 +6242,16 @@ nsBlockFrame::BuildDisplayList(nsDisplay
       lineCount++;
     }
 
     if (NS_SUCCEEDED(rv) && nonDecreasingYs && lineCount >= MIN_LINES_NEEDING_CURSOR) {
       SetupLineCursor();
     }
   }
 
-  // Finalize text-overflow processing.
-  if (textOverflow) {
-    textOverflow->DidProcessLines();
-  }
-
   if (NS_SUCCEEDED(rv) && (nsnull != mBullet) && HaveOutsideBullet()) {
     // Display outside bullets manually
     rv = BuildDisplayListForChild(aBuilder, mBullet, aDirtyRect, aLists);
   }
 
 #ifdef DEBUG
   if (gLamePaintMetrics) {
     PRTime end = PR_Now();
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -1614,16 +1614,19 @@ static void AdjustViews(nsIFrame* aFrame
       AdjustViews(childFrames.get());
     }
   }
 }
 
 static bool
 CanScrollWithBlitting(nsIFrame* aFrame)
 {
+  if (aFrame->GetStateBits() & NS_SCROLLFRAME_INVALIDATE_CONTENTS_ON_SCROLL)
+    return false;
+
   for (nsIFrame* f = aFrame; f;
        f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
     if (nsSVGIntegrationUtils::UsingEffectsForFrame(f) ||
         f->IsFrameOfType(nsIFrame::eSVG)) {
       return false;
     }
     nsIScrollableFrame* sf = do_QueryFrame(f);
     if (sf && nsLayoutUtils::HasNonZeroCorner(f->GetStyleBorder()->mBorderRadius))
@@ -1727,16 +1730,17 @@ void nsGfxScrollFrameInner::ScrollVisual
 
   rootPresContext->RequestUpdatePluginGeometry(mOuter);
 
   AdjustViews(mScrolledFrame);
   // We need to call this after fixing up the view positions
   // to be consistent with the frame hierarchy.
   PRUint32 flags = nsIFrame::INVALIDATE_REASON_SCROLL_REPAINT;
   bool canScrollWithBlitting = CanScrollWithBlitting(mOuter);
+  mOuter->RemoveStateBits(NS_SCROLLFRAME_INVALIDATE_CONTENTS_ON_SCROLL);
   if (IsScrollingActive()) {
     if (!canScrollWithBlitting) {
       MarkInactive();
     } else {
       flags |= nsIFrame::INVALIDATE_NO_THEBES_LAYERS;
     }
   }
   if (canScrollWithBlitting) {
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -59,16 +59,22 @@ class nsPresContext;
 class nsIPresShell;
 class nsIContent;
 class nsIAtom;
 class nsIDocument;
 class nsIScrollFrameInternal;
 class nsPresState;
 struct ScrollReflowState;
 
+// When set, the next scroll operation on the scrollframe will invalidate its
+// entire contents. Useful for text-overflow.
+// This bit is cleared after each time the scrollframe is scrolled. Whoever
+// needs to set it should set it again on each paint.
+#define NS_SCROLLFRAME_INVALIDATE_CONTENTS_ON_SCROLL NS_FRAME_STATE_BIT(20)
+
 class nsGfxScrollFrameInner : public nsIReflowCallback {
 public:
   class AsyncScroll;
 
   nsGfxScrollFrameInner(nsContainerFrame* aOuter, bool aIsRoot);
   ~nsGfxScrollFrameInner();
 
   typedef nsIScrollableFrame::ScrollbarStyles ScrollbarStyles;
--- a/layout/generic/nsIAnonymousContentCreator.h
+++ b/layout/generic/nsIAnonymousContentCreator.h
@@ -74,16 +74,20 @@ public:
     nsIContent* mContent;
     nsRefPtr<nsStyleContext> mStyleContext;
   };
 
   /**
    * Creates "native" anonymous content and adds the created content to
    * the aElements array. None of the returned elements can be nsnull.
    *
+   * If the anonymous content creator sets the editable flag on some
+   * of the elements that it creates, the flag will be applied to the node
+   * upon being bound to the document.
+   *
    * @note The returned elements are owned by this object. This object is
    *       responsible for calling UnbindFromTree on the elements it returned
    *       from CreateAnonymousContent when appropriate (i.e. before releasing
    *       them).
    */
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements)=0;
 
   /**
--- a/layout/inspector/tests/chrome/Makefile.in
+++ b/layout/inspector/tests/chrome/Makefile.in
@@ -42,13 +42,15 @@ VPATH		= @srcdir@
 relativesrcdir	= layout/inspector/tests/chrome
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _CHROME_FILES =\
 		test_bug467669.xul \
 		test_bug467669.css \
+		test_bug695639.xul \
+		test_bug695639.css \
 		GentiumPlus-R.woff \
 		$(NULL)
 
 libs:: $(_CHROME_FILES)
 	$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/layout/inspector/tests/chrome/test_bug695639.css
@@ -0,0 +1,8 @@
+@font-face {
+  font-family: gent;
+  src: url(GentiumPlus-R.woff) format("woff");
+}
+
+.test {
+  font-family: gent, sans-serif;
+}
new file mode 100644
--- /dev/null
+++ b/layout/inspector/tests/chrome/test_bug695639.xul
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+<?xml-stylesheet type="text/css" href="test_bug695639.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=695639
+-->
+<window title="Mozilla Bug 695639"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        onload="RunTest();">
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+  <script type="application/javascript">
+  <![CDATA[
+  /** Test for Bug 695639 - check that GetFontFacesForText handles wrapped lines properly **/
+
+SimpleTest.waitForExplicitFinish();
+
+function RunTest() {
+  const CI = Components.interfaces;
+  const CC = Components.classes;
+
+  var domUtils =
+    CC["@mozilla.org/inspector/dom-utils;1"].getService(CI.inIDOMUtils);
+
+  var rng = document.createRange();
+  var elem, fonts, f;
+
+  elem = document.getElementById("test").childNodes[0];
+  rng.setStart(elem, 0);
+  rng.setEnd(elem, 14);
+  fonts = domUtils.getUsedFontFaces(rng);
+  is(fonts.length, 2, "number of fonts used for entire text");
+
+  // initial latin substring...
+  rng.setStart(elem, 0);
+  rng.setEnd(elem, 5); // "Hello"
+  fonts = domUtils.getUsedFontFaces(rng);
+  is(fonts.length, 1, "number of fonts (1)");
+  f = fonts.item(0);
+  is(f.name, "Gentium Plus", "font name (1)");
+
+  // the space (where the line wraps) should also be Gentium
+  rng.setStart(elem, 5);
+  rng.setEnd(elem, 6); // space
+  fonts = domUtils.getUsedFontFaces(rng);
+  is(fonts.length, 1, "number of fonts (2)");
+  f = fonts.item(0);
+  is(f.name, "Gentium Plus", "font name (2)");
+
+  // the Chinese text "ni hao" should NOT be in Gentium
+  rng.setStart(elem, 6);
+  rng.setEnd(elem, 8); // two Chinese characters on second line
+  fonts = domUtils.getUsedFontFaces(rng);
+  is(fonts.length, 1, "number of fonts (3)");
+  f = fonts.item(0);
+  isnot(f.name, "Gentium Plus", "font name (3)");
+
+  // space and "world" should be Gentium again
+  rng.setStart(elem, 8);
+  rng.setEnd(elem, 14);
+  fonts = domUtils.getUsedFontFaces(rng);
+  is(fonts.length, 1, "number of fonts (4)");
+  f = fonts.item(0);
+  is(f.name, "Gentium Plus", "font name (4)");
+
+  SimpleTest.finish();
+}
+  ]]>
+  </script>
+
+  <style type="text/css">
+  </style>
+
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=695639"
+     target="_blank">Mozilla Bug 695639</a>
+  <div style="width: 2em;" class="test" id="test">Hello &#x4F60;&#x597D; world</div>
+  </body>
+
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/editor/694880-1.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <style>
+    :-moz-read-only { color: green; }
+    :-moz-read-write { color: red; }
+  </style>
+  <body onload="document.designMode='on';document.designMode='off'">
+    <div>test</div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/editor/694880-2.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <style>
+    :-moz-read-only { color: green; }
+    :-moz-read-write { color: red; }
+  </style>
+  <body onload="document.designMode='on';document.designMode='off'">
+    <div>test</div>
+    <div contenteditable></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/editor/694880-3.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <style>
+    :-moz-read-only { color: red; }
+    :-moz-read-write { color: green; }
+  </style>
+  <body onload="document.designMode='on';document.designMode='off'">
+    <div contenteditable>test</div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/editor/694880-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+  <style>
+    div { color: green; }
+  </style>
+  <body>
+    <div>test</div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/editor/readonly-editable-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <input>
+    <input readonly>
+    <input type=password>
+    <input type=password readonly>
+    <input type=email>
+    <input type=email readonly>
+    <textarea></textarea>
+    <textarea readonly></textarea>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/editor/readonly-editable.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      :-moz-read-write + span {
+        display: none;
+      }
+      span {
+        color: transparent; /* workaround for bug 617524 */
+        outline: 1px solid green;
+      }
+    </style>
+  </head>
+  <body contenteditable>
+    <input><span>hide me</span>
+    <input readonly><span>hide me</span>
+    <input type=password><span>hide me</span>
+    <input type=password readonly><span>hide me</span>
+    <input type=email><span>hide me</span>
+    <input type=email readonly><span>hide me</span>
+    <textarea></textarea><span>hide me</span>
+    <textarea readonly></textarea><span>hide me</span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/editor/readonly-non-editable-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      span {
+        color: transparent; /* workaround for bug 617524 */
+        outline: 1px solid green;
+      }
+    </style>
+  </head>
+  <body>
+    <input><span>hide me</span>
+    <input readonly>
+    <input type=password><span>hide me</span>
+    <input type=password readonly>
+    <input type=email><span>hide me</span>
+    <input type=email readonly>
+    <textarea></textarea><span>hide me</span>
+    <textarea readonly></textarea>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/editor/readonly-non-editable.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      :-moz-read-only + span {
+        display: none;
+      }
+      span {
+        color: transparent; /* workaround for bug 617524 */
+        outline: 1px solid green;
+      }
+    </style>
+  </head>
+  <body>
+    <input><span>hide me</span>
+    <input readonly><span>hide me</span>
+    <input type=password><span>hide me</span>
+    <input type=password readonly><span>hide me</span>
+    <input type=email><span>hide me</span>
+    <input type=email readonly><span>hide me</span>
+    <textarea></textarea><span>hide me</span>
+    <textarea readonly></textarea><span>hide me</span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/editor/readwrite-editable-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <input>
+    <input readonly>
+    <input type=password>
+    <input type=password readonly>
+    <input type=email>
+    <input type=email readonly>
+    <textarea></textarea>
+    <textarea readonly></textarea>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/editor/readwrite-editable.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      :-moz-read-write + span {
+        display: none;
+      }
+      span {
+        color: transparent; /* workaround for bug 617524 */
+        outline: 1px solid green;
+      }
+    </style>
+  </head>
+  <body contenteditable>
+    <input><span>hide me</span>
+    <input readonly><span>hide me</span>
+    <input type=password><span>hide me</span>
+    <input type=password readonly><span>hide me</span>
+    <input type=email><span>hide me</span>
+    <input type=email readonly><span>hide me</span>
+    <textarea></textarea><span>hide me</span>
+    <textarea readonly></textarea><span>hide me</span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/editor/readwrite-non-editable-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      span {
+        color: transparent; /* workaround for bug 617524 */
+        outline: 1px solid green;
+      }
+    </style>
+  </head>
+  <body>
+    <input>
+    <input readonly><span>hide me</span>
+    <input type=password>
+    <input type=password readonly><span>hide me</span>
+    <input type=email>
+    <input type=email readonly><span>hide me</span>
+    <textarea></textarea>
+    <textarea readonly></textarea><span>hide me</span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/editor/readwrite-non-editable.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      :-moz-read-write + span {
+        display: none;
+      }
+      span {
+        color: transparent; /* workaround for bug 617524 */
+        outline: 1px solid green;
+      }
+    </style>
+  </head>
+  <body>
+    <input><span>hide me</span>
+    <input readonly><span>hide me</span>
+    <input type=password><span>hide me</span>
+    <input type=password readonly><span>hide me</span>
+    <input type=email><span>hide me</span>
+    <input type=email readonly><span>hide me</span>
+    <textarea></textarea><span>hide me</span>
+    <textarea readonly></textarea><span>hide me</span>
+  </body>
+</html>
--- a/layout/reftests/editor/reftest.list
+++ b/layout/reftests/editor/reftest.list
@@ -78,9 +78,16 @@ fails-if(Android) != spellcheck-hyphen-m
 != selection_visibility_after_reframe-2.html selection_visibility_after_reframe-ref.html
 != selection_visibility_after_reframe-3.html selection_visibility_after_reframe-ref.html
 == 672709.html 672709-ref.html
 == 338427-1.html 338427-1-ref.html
 skip-if(Android) == 674212-spellcheck.html 674212-spellcheck-ref.html
 skip-if(Android) == 338427-2.html 338427-2-ref.html
 skip-if(Android) needs-focus == 338427-3.html 338427-3-ref.html
 skip-if(Android) == 462758-grabbers-resizers.html 462758-grabbers-resizers-ref.html
+== readwrite-non-editable.html readwrite-non-editable-ref.html
+== readwrite-editable.html readwrite-editable-ref.html
+== readonly-non-editable.html readonly-non-editable-ref.html
+== readonly-editable.html readonly-editable-ref.html
 == dynamic-overflow-change.html dynamic-overflow-change-ref.html
+== 694880-1.html 694880-ref.html
+== 694880-2.html 694880-ref.html
+== 694880-3.html 694880-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/695538-1-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<style>
+:root {
+     border-collapse: collapse;
+     border-spacing: 1px;
+}
+.cell {
+     display: table-cell;
+     border: solid black;
+}
+.pre {
+     white-space: pre;
+     border: solid blue;
+}
+.table {
+     display: inline-table;
+}
+</style>
+<span class="pre"> <span class="table"><span class="cell">A</span>
+<span class="cell">B</span></span> </span>
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-anonymous-boxes/695538-1.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<style>
+:root {
+     border-collapse: collapse;
+     border-spacing: 1px;
+}
+.cell {
+     display: table-cell;
+     border: solid black;
+}
+.pre {
+     white-space: pre;
+     border: solid blue;
+}
+</style>
+<span class="pre"> <span class="cell">A</span>
+<span class="cell">B</span> </span>
+
--- a/layout/reftests/table-anonymous-boxes/reftest.list
+++ b/layout/reftests/table-anonymous-boxes/reftest.list
@@ -30,16 +30,17 @@
 random-if(d2d) == 394402-1a.html 394402-1-ref.html # bug 586833
 == 394402-1b.html 394402-1-ref.html # bug 586833
 == 398095-1.html 398095-1-ref.html
 == 407115-1.html 407115-1-ref.html
 == 443616-1a.xhtml 443616-1-ref.html
 == 443616-1b.html 443616-1-ref.html
 == 448111-1.html 448111-1-ref.html
 == 490174-1.html 490174-1-ref.html
+== 695538-1.html 695538-1-ref.html
 == infer-first-row.html 3x3-ref.html
 == infer-first-row-and-table.html 3x3-ref.html
 == infer-second-row.html 3x3-ref.html
 == infer-second-row-and-table.html 3x3-ref.html
 == infer-table-around-headers-footers-1.html 3x3-ref.html
 == infer-table-around-headers-footers-2.html 3x3-ref.html
 == infer-table-around-headers-footers-3.html 3x3-ref.html
 == infer-rows-inside-rowgroups.html 3x3-ref.html
--- a/memory/mozalloc/mozalloc.h
+++ b/memory/mozalloc/mozalloc.h
@@ -209,25 +209,23 @@ MOZALLOC_EXPORT void* moz_valloc(size_t 
 
 #if defined(ANDROID) || defined(_MSC_VER)
 /*
  * Android doesn't fully support exceptions, so its <new> header
  * has operators that don't specify throw() at all. Also include MSVC
  * to suppress build warning spam (bug 578546).
  */
 #define MOZALLOC_THROW_IF_HAS_EXCEPTIONS /**/
+#define MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS
 #else
 #define MOZALLOC_THROW_IF_HAS_EXCEPTIONS throw()
+#define MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS throw(std::bad_alloc)
 #endif
 
-#ifdef MOZ_CPP_EXCEPTIONS
-#define MOZALLOC_THROW_BAD_ALLOC throw(std::bad_alloc)
-#else
-#define MOZALLOC_THROW_BAD_ALLOC MOZALLOC_THROW_IF_HAS_EXCEPTIONS
-#endif
+#define MOZALLOC_THROW_BAD_ALLOC MOZALLOC_THROW_BAD_ALLOC_IF_HAS_EXCEPTIONS
 
 MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
 void* operator new(size_t size) MOZALLOC_THROW_BAD_ALLOC
 {
     return moz_xmalloc(size);
 }
 
 MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -113,138 +113,126 @@ NS_IMPL_THREADSAFE_ISUPPORTS11(WebSocket
 
 // some helper classes
 
 class CallOnMessageAvailable : public nsIRunnable
 {
 public:
   NS_DECL_ISUPPORTS
 
-  CallOnMessageAvailable(nsIWebSocketListener *aListener,
-                         nsISupports          *aContext,
-                         nsCString            &aData,
-                         PRInt32               aLen)
-    : mListener(aListener),
-      mContext(aContext),
+  CallOnMessageAvailable(WebSocketChannel *aChannel,
+                         nsCString        &aData,
+                         PRInt32           aLen)
+    : mChannel(aChannel),
       mData(aData),
       mLen(aLen) {}
 
   NS_SCRIPTABLE NS_IMETHOD Run()
   {
     if (mLen < 0)
-      mListener->OnMessageAvailable(mContext, mData);
+      mChannel->mListener->OnMessageAvailable(mChannel->mContext, mData);
     else
-      mListener->OnBinaryMessageAvailable(mContext, mData);
+      mChannel->mListener->OnBinaryMessageAvailable(mChannel->mContext, mData);
     return NS_OK;
   }
 
 private:
   ~CallOnMessageAvailable() {}
 
-  nsCOMPtr<nsIWebSocketListener>    mListener;
-  nsCOMPtr<nsISupports>             mContext;
+  nsRefPtr<WebSocketChannel>        mChannel;
   nsCString                         mData;
   PRInt32                           mLen;
 };
 NS_IMPL_THREADSAFE_ISUPPORTS1(CallOnMessageAvailable, nsIRunnable)
 
 class CallOnStop : public nsIRunnable
 {
 public:
   NS_DECL_ISUPPORTS
 
-  CallOnStop(nsIWebSocketListener *aListener,
-             nsISupports          *aContext,
-             nsresult              aData)
-    : mListener(aListener),
-      mContext(aContext),
+  CallOnStop(WebSocketChannel *aChannel,
+             nsresult          aData)
+    : mChannel(aChannel),
       mData(aData) {}
 
   NS_SCRIPTABLE NS_IMETHOD Run()
   {
-    mListener->OnStop(mContext, mData);
+    mChannel->mListener->OnStop(mChannel->mContext, mData);
     return NS_OK;
   }
 
 private:
   ~CallOnStop() {}
 
-  nsCOMPtr<nsIWebSocketListener>    mListener;
-  nsCOMPtr<nsISupports>             mContext;
+  nsRefPtr<WebSocketChannel>        mChannel;
   nsresult                          mData;
 };
 NS_IMPL_THREADSAFE_ISUPPORTS1(CallOnStop, nsIRunnable)
 
 class CallOnServerClose : public nsIRunnable
 {
 public:
   NS_DECL_ISUPPORTS
 
-  CallOnServerClose(nsIWebSocketListener *aListener,
-                    nsISupports          *aContext,
-                    PRUint16              aCode,
-                    nsCString            &aReason)
-    : mListener(aListener),
-      mContext(aContext),
+  CallOnServerClose(WebSocketChannel *aChannel,
+                    PRUint16          aCode,
+                    nsCString        &aReason)
+    : mChannel(aChannel),
       mCode(aCode),
       mReason(aReason) {}
 
   NS_SCRIPTABLE NS_IMETHOD Run()
   {
-    mListener->OnServerClose(mContext, mCode, mReason);
+    mChannel->mListener->OnServerClose(mChannel->mContext, mCode, mReason);
     return NS_OK;
   }
 
 private:
   ~CallOnServerClose() {}
 
-  nsCOMPtr<nsIWebSocketListener>    mListener;
-  nsCOMPtr<nsISupports>             mContext;
+  nsRefPtr<WebSocketChannel>        mChannel;
   PRUint16                          mCode;
   nsCString                         mReason;
 };
 NS_IMPL_THREADSAFE_ISUPPORTS1(CallOnServerClose, nsIRunnable)
 
 class CallAcknowledge : public nsIRunnable
 {
 public:
   NS_DECL_ISUPPORTS
 
-  CallAcknowledge(nsIWebSocketListener *aListener,
-                  nsISupports          *aContext,
-                  PRUint32              aSize)
-    : mListener(aListener),
-      mContext(aContext),
+  CallAcknowledge(WebSocketChannel *aChannel,
+                  PRUint32          aSize)
+    : mChannel(aChannel),
       mSize(aSize) {}
 
   NS_SCRIPTABLE NS_IMETHOD Run()
   {
     LOG(("WebSocketChannel::CallAcknowledge: Size %u\n", mSize));
-    mListener->OnAcknowledge(mContext, mSize);
+    mChannel->mListener->OnAcknowledge(mChannel->mContext, mSize);
     return NS_OK;
   }
 
 private:
   ~CallAcknowledge() {}
 
-  nsCOMPtr<nsIWebSocketListener>    mListener;
-  nsCOMPtr<nsISupports>             mContext;
+  nsRefPtr<WebSocketChannel>        mChannel;
   PRUint32                          mSize;
 };
 NS_IMPL_THREADSAFE_ISUPPORTS1(CallAcknowledge, nsIRunnable)
 
 class nsPostMessage : public nsIRunnable
 {
 public:
   NS_DECL_ISUPPORTS
 
-  nsPostMessage(WebSocketChannel *channel,
+  nsPostMessage(WebSocketChannel *aChannel,
                 nsCString        *aData,
                 PRInt32           aDataLen)
-    : mChannel(channel),
+    : mChannel(aChannel),
       mData(aData),
       mDataLen(aDataLen) {}
 
   NS_SCRIPTABLE NS_IMETHOD Run()
   {
     if (mData)
       mChannel->SendMsgInternal(mData, mDataLen);
     return NS_OK;
@@ -930,18 +918,17 @@ WebSocketChannel::ProcessInput(PRUint8 *
         // but secteam feels that silently rewriting messages is
         // inappropriate - so we will fail the connection instead.
         if (!IsUTF8(utf8Data, false)) {
           LOG(("WebSocketChannel:: text frame invalid utf-8\n"));
           AbortSession(NS_ERROR_ILLEGAL_VALUE);
           return NS_ERROR_ILLEGAL_VALUE;
         }
 
-        NS_DispatchToMainThread(new CallOnMessageAvailable(mListener, mContext,
-                                                           utf8Data, -1));
+        NS_DispatchToMainThread(new CallOnMessageAvailable(this, utf8Data, -1));
       }
     } else if (opcode & kControlFrameMask) {
       // control frames
       if (payloadLength > 125) {
         LOG(("WebSocketChannel:: bad control frame code %d length %d\n",
              opcode, payloadLength));
         AbortSession(NS_ERROR_ILLEGAL_VALUE);
         return NS_ERROR_ILLEGAL_VALUE;
@@ -976,20 +963,20 @@ WebSocketChannel::ProcessInput(PRUint8 *
                  mServerCloseReason.get()));
           }
         }
 
         if (mCloseTimer) {
           mCloseTimer->Cancel();
           mCloseTimer = nsnull;
         }
-        if (mListener)
-          NS_DispatchToMainThread(
-            new CallOnServerClose(mListener, mContext,
-                                  mServerCloseCode, mServerCloseReason));
+        if (mListener) {
+          NS_DispatchToMainThread(new CallOnServerClose(this, mServerCloseCode,
+                                                        mServerCloseReason));
+        }
 
         if (mClientClosed)
           ReleaseSession();
       } else if (opcode == kPing) {
         LOG(("WebSocketChannel:: ping received\n"));
         GeneratePong(payload, payloadLength);
       } else if (opcode == kPong) {
         // opcode kPong: the mere act of receiving the packet is all we need
@@ -1014,18 +1001,17 @@ WebSocketChannel::ProcessInput(PRUint8 *
         if (mBuffered)
           mBuffered -= framingLength + payloadLength;
         payloadLength = 0;
       }
     } else if (opcode == kBinary) {
       LOG(("WebSocketChannel:: binary frame received\n"));
       if (mListener) {
         nsCString binaryData((const char *)payload, payloadLength);
-        NS_DispatchToMainThread(new CallOnMessageAvailable(mListener, mContext,
-                                                           binaryData,
+        NS_DispatchToMainThread(new CallOnMessageAvailable(this, binaryData,
                                                            payloadLength));
       }
     } else if (opcode != kContinuation) {
       /* unknown opcode */
       LOG(("WebSocketChannel:: unknown op code %d\n", opcode));
       AbortSession(NS_ERROR_ILLEGAL_VALUE);
       return NS_ERROR_ILLEGAL_VALUE;
     }
@@ -1484,17 +1470,17 @@ WebSocketChannel::StopSession(nsresult r
   mInflateStream = nsnull;
 
   delete mCompressor;
   mCompressor = nsnull;
 
   if (!mCalledOnStop) {
     mCalledOnStop = 1;
     if (mListener)
-      NS_DispatchToMainThread(new CallOnStop(mListener, mContext, reason));
+      NS_DispatchToMainThread(new CallOnStop(this, reason));
   }
 
   return;
 }
 
 void
 WebSocketChannel::AbortSession(nsresult reason)
 {
@@ -2197,17 +2183,17 @@ WebSocketChannel::OnTransportAvailable(n
   mSocketIn = aSocketIn;
   mSocketOut = aSocketOut;
   if (sWebSocketAdmissions)
     sWebSocketAdmissions->IncrementConnectedCount();
 
   nsresult rv;
   rv = mTransport->SetEventSink(nsnull, nsnull);
   if (NS_FAILED(rv)) return rv;
-  rv = mTransport->SetSecurityCallbacks(mCallbacks);
+  rv = mTransport->SetSecurityCallbacks(this);
   if (NS_FAILED(rv)) return rv;
 
   mRecvdHttpUpgradeTransport = 1;
   if (mRecvdHttpOnStartRequest)
     return StartWebsocketData();
   return NS_OK;
 }
 
@@ -2515,17 +2501,17 @@ WebSocketChannel::OnOutputStreamReady(ns
         mHdrOutToSend = 0;
       } else {
         mHdrOut += amtSent;
         mHdrOutToSend -= amtSent;
       }
     } else {
       if (amtSent == toSend) {
         if (!mStopped) {
-          NS_DispatchToMainThread(new CallAcknowledge(mListener, mContext,
+          NS_DispatchToMainThread(new CallAcknowledge(this,
                                                       mCurrentOut->Length()));
         }
         delete mCurrentOut;
         mCurrentOut = nsnull;
         mCurrentOutSent = 0;
         PrimeNewOutgoingMessage();
       } else {
         mCurrentOutSent += amtSent;
--- a/netwerk/protocol/websocket/WebSocketChannel.h
+++ b/netwerk/protocol/websocket/WebSocketChannel.h
@@ -65,16 +65,20 @@
 #include "nsString.h"
 #include "nsDeque.h"
 
 namespace mozilla { namespace net {
 
 class nsPostMessage;
 class nsWSAdmissionManager;
 class nsWSCompression;
+class CallOnMessageAvailable;
+class CallOnStop;
+class CallOnServerClose;
+class CallAcknowledge;
 
 class WebSocketChannel : public BaseWebSocketChannel,
                          public nsIHttpUpgradeListener,
                          public nsIStreamListener,
                          public nsIInputStreamCallback,
                          public nsIOutputStreamCallback,
                          public nsITimerCallback,
                          public nsIDNSListener,
@@ -124,16 +128,20 @@ public:
   const static PRUint8 kFinalFragBit        = 0x80;
 
 protected:
   virtual ~WebSocketChannel();
 
 private:
   friend class nsPostMessage;
   friend class nsWSAdmissionManager;
+  friend class CallOnMessageAvailable;
+  friend class CallOnStop;
+  friend class CallOnServerClose;
+  friend class CallAcknowledge;
 
   void SendMsgInternal(nsCString *aMsg, PRInt32 datalen);
   void PrimeNewOutgoingMessage();
   void GeneratePong(PRUint8 *payload, PRUint32 len);
   void GeneratePing();
 
   nsresult BeginOpen();
   nsresult HandleExtensions();
--- a/toolkit/components/places/nsPlacesExpiration.js
+++ b/toolkit/components/places/nsPlacesExpiration.js
@@ -150,16 +150,20 @@ const IDLE_TIMEOUT_SECONDS = 5 * 60;
 // expiration at shutdown.  This is maximum number of seconds from last
 // clearHistory to decide to skip expiration at shutdown.
 const SHUTDOWN_WITH_RECENT_CLEARHISTORY_TIMEOUT_SECONDS = 10;
 
 // If the pages delta from the last ANALYZE is over this threashold, the tables
 // should be analyzed again.
 const ANALYZE_PAGES_THRESHOLD = 100;
 
+// If the number of pages over history limit is greater than this threshold,
+// expiration will be more aggressive, to bring back history to a saner size.
+const OVERLIMIT_PAGES_THRESHOLD = 1000;
+
 const USECS_PER_DAY = 86400000000;
 const ANNOS_EXPIRE_POLICIES = [
   { bind: "expire_days",
     type: Ci.nsIAnnotationService.EXPIRE_DAYS,
     time: 7 * USECS_PER_DAY },
   { bind: "expire_weeks",
     type: Ci.nsIAnnotationService.EXPIRE_WEEKS,
     time: 30 * USECS_PER_DAY },
@@ -626,26 +630,31 @@ nsPlacesExpiration.prototype = {
 
   //////////////////////////////////////////////////////////////////////////////
   //// nsITimerCallback
 
   notify: function PEX_timerCallback()
   {
     // Check if we are over history capacity, if so visits must be expired.
     this._getPagesStats((function onPagesCount(aPagesCount, aStatsCount) {
-      this._overLimit = aPagesCount > this._urisLimit;
+      let overLimitPages = aPagesCount - this._urisLimit;
+      this._overLimit = overLimitPages > 0;
+
       let action = this._overLimit ? ACTION.TIMED_OVERLIMIT : ACTION.TIMED;
-
       // If the number of pages changed significantly from the last ANALYZE
       // update SQLite statistics.
       if (Math.abs(aPagesCount - aStatsCount) >= ANALYZE_PAGES_THRESHOLD) {
         action = action | ACTION.TIMED_ANALYZE;
       }
 
-      this._expireWithActionAndLimit(action, LIMIT.SMALL);
+      // Adapt expiration aggressivity to the number of pages over the limit.
+      let limit = overLimitPages > OVERLIMIT_PAGES_THRESHOLD ? LIMIT.LARGE
+                                                             : LIMIT.SMALL;
+
+      this._expireWithActionAndLimit(action, limit);
     }).bind(this));
   },
 
   //////////////////////////////////////////////////////////////////////////////
   //// mozIStorageStatementCallback
 
   handleResult: function PEX_handleResult(aResultSet)
   {
--- a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
@@ -1425,17 +1425,17 @@ nsUrlClassifierDBService::CheckClean(con
     }
 
     PRUint32 hostprefix = hostkey.ToUint32();
     PRUint32 fragkey = fragmentKeyHash.ToUint32();
     PRUint32 codedkey;
     rv = KeyedHash(fragkey, hostprefix, prefixkey, &codedkey);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    bool found;
+    bool found = false;
     bool ready = false;  /* opportunistic probe */
     rv = mPrefixSet->Probe(codedkey, prefixkey, &ready, &found);
     NS_ENSURE_SUCCESS(rv, rv);
     LOG(("CheckClean Probed %X ready: %d found: %d ",
          codedkey, ready, found));
     if (found || !ready) {
       *clean = false;
     }
--- a/toolkit/components/url-classifier/nsUrlClassifierPrefixSet.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierPrefixSet.cpp
@@ -273,16 +273,18 @@ nsUrlClassifierPrefixSet::GetKey(PRUint3
 }
 
 NS_IMETHODIMP
 nsUrlClassifierPrefixSet::Probe(PRUint32 aPrefix, PRUint32 aKey,
                                 bool* aReady, bool* aFound)
 {
   MutexAutoLock lock(mPrefixSetLock);
 
+  *aFound = false;
+
   // We might have raced here with a LoadPrefixSet call,
   // loading a saved PrefixSet with another key than the one used to probe us.
   // This must occur exactly between the GetKey call and the Probe call.
   // This could cause a false negative immediately after browser start.
   // Claim we are still busy loading instead.
   if (aKey != mRandomKey) {
     LOG(("Potential race condition detected, avoiding"));
     *aReady = false;
--- a/toolkit/content/widgets/browser.xml
+++ b/toolkit/content/widgets/browser.xml
@@ -916,21 +916,22 @@
 
             // this is a list of overflow property values that allow scrolling
             const scrollingAllowed = ['scroll', 'auto'];
 
             // go upward in the DOM and find any parent element that has a overflow
             // area and can therefore be scrolled
             for (this._scrollable = event.originalTarget; this._scrollable;
                  this._scrollable = this._scrollable.parentNode) {
-              // do not use overflow based autoscroll for <html> Elements
-              // or non-html elements such as svg or Document nodes
+              // do not use overflow based autoscroll for <html> and <body>
+              // Elements or non-html elements such as svg or Document nodes
               // also make sure to skip select elements that are not multiline
               if (!(this._scrollable instanceof HTMLElement) ||
                   (this._scrollable instanceof HTMLHtmlElement) ||
+                  (this._scrollable instanceof HTMLBodyElement) ||
                   ((this._scrollable instanceof HTMLSelectElement) && !this._scrollable.multiple)) {
                 continue;
               }
 
               var overflowx = this._scrollable.ownerDocument.defaultView
                                   .getComputedStyle(this._scrollable, '')
                                   .getPropertyValue('overflow-x');
               var overflowy = this._scrollable.ownerDocument.defaultView
--- a/toolkit/mozapps/extensions/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/XPIProvider.jsm
@@ -2594,24 +2594,30 @@ var XPIProvider = {
         // A theme's disabled state is determined by the selected theme
         // preference which is read in loadManifestFromRDF
         if (newAddon.type != "theme")
           newAddon.userDisabled = aMigrateData.userDisabled;
         if ("installDate" in aMigrateData)
           newAddon.installDate = aMigrateData.installDate;
         if ("softDisabled" in aMigrateData)
           newAddon.softDisabled = aMigrateData.softDisabled;
+        if ("applyBackgroundUpdates" in aMigrateData)
+          newAddon.applyBackgroundUpdates = aMigrateData.applyBackgroundUpdates;
+        if ("sourceURI" in aMigrateData)
+          newAddon.sourceURI = aMigrateData.sourceURI;
+        if ("releaseNotesURI" in aMigrateData)
+          newAddon.releaseNotesURI = aMigrateData.releaseNotesURI;
 
         // Some properties should only be migrated if the add-on hasn't changed.
         // The version property isn't a perfect check for this but covers the
         // vast majority of cases.
-        if (aMigrateData.version == newAddon.version) {
+        if (aMigrateData.version == newAddon.version &&
+            "targetApplications" in aMigrateData) {
           LOG("Migrating compatibility info");
-          if ("targetApplications" in aMigrateData)
-            newAddon.applyCompatibilityUpdate(aMigrateData, true);
+          newAddon.applyCompatibilityUpdate(aMigrateData, true);
         }
 
         // Since the DB schema has changed make sure softDisabled is correct
         applyBlocklistChanges(newAddon, newAddon, aOldAppVersion,
                               aOldPlatformVersion);
       }
 
       if (aActiveBundles) {
@@ -3547,40 +3553,49 @@ var XPIProvider = {
    *         The reason flag to pass to the bootstrap's startup method
    */
   callBootstrapMethod: function XPI_callBootstrapMethod(aId, aVersion, aType, aFile,
                                                         aMethod, aReason) {
     // Never call any bootstrap methods in safe mode
     if (Services.appinfo.inSafeMode)
       return;
 
-    // Load the scope if it hasn't already been loaded
-    if (!(aId in this.bootstrapScopes))
-      this.loadBootstrapScope(aId, aFile, aVersion, aType);
-
-    if (!(aMethod in this.bootstrapScopes[aId])) {
-      WARN("Add-on " + aId + " is missing bootstrap method " + aMethod);
-      return;
-    }
-
-    let params = {
-      id: aId,
-      version: aVersion,
-      installPath: aFile.clone(),
-      resourceURI: getURIForResourceInFile(aFile, "")
-    };
-
-    LOG("Calling bootstrap method " + aMethod + " on " + aId + " version " +
-        aVersion);
+    if (aMethod == "startup")
+      Components.manager.addBootstrappedManifestLocation(aFile);
+
     try {
-      this.bootstrapScopes[aId][aMethod](params, aReason);
-    }
-    catch (e) {
-      WARN("Exception running bootstrap method " + aMethod + " on " +
-           aId, e);
+      // Load the scope if it hasn't already been loaded
+      if (!(aId in this.bootstrapScopes))
+        this.loadBootstrapScope(aId, aFile, aVersion, aType);
+
+      if (!(aMethod in this.bootstrapScopes[aId])) {
+        WARN("Add-on " + aId + " is missing bootstrap method " + aMethod);
+        return;
+      }
+
+      let params = {
+        id: aId,
+        version: aVersion,
+        installPath: aFile.clone(),
+        resourceURI: getURIForResourceInFile(aFile, "")
+      };
+
+      LOG("Calling bootstrap method " + aMethod + " on " + aId + " version " +
+          aVersion);
+      try {
+        this.bootstrapScopes[aId][aMethod](params, aReason);
+      }
+      catch (e) {
+        WARN("Exception running bootstrap method " + aMethod + " on " +
+             aId, e);
+      }
+    }
+    finally {
+      if (aMethod == "shutdown")
+        Components.manager.removeBootstrappedManifestLocation(aFile);
     }
   },
 
   /**
    * Updates the appDisabled property for all add-ons.
    */
   updateAllAddonDisabledStates: function XPI_updateAllAddonDisabledStates() {
     let addons = XPIDatabase.getAddons();
@@ -4352,17 +4367,21 @@ var XPIDatabase = {
 
     // Attempt to migrate data from a different (even future!) version of the
     // database
     try {
       // Build a list of sql statements that might recover useful data from this
       // and future versions of the schema
       var sql = [];
       sql.push("SELECT internal_id, id, location, userDisabled, " +
-               "softDisabled, installDate, version FROM addon");
+               "softDisabled, installDate, version, applyBackgroundUpdates, " +
+               "sourceURI, releaseNotesURI FROM addon");
+      sql.push("SELECT internal_id, id, location, userDisabled, " +
+               "installDate, version, applyBackgroundUpdates, " +
+               "sourceURI, releaseNotesURI FROM addon");
       sql.push("SELECT internal_id, id, location, userDisabled, installDate, " +
                "version FROM addon");
 
       var stmt = null;
       if (!sql.some(function(aSql) {
         try {
           stmt = this.connection.createStatement(aSql);
           return true;
@@ -4383,16 +4402,22 @@ var XPIDatabase = {
           version: row.version,
           installDate: row.installDate,
           userDisabled: row.userDisabled == 1,
           targetApplications: []
         };
 
         if ("softDisabled" in row)
           migrateData[row.location][row.id].softDisabled = row.softDisabled == 1;
+        if ("applyBackgroundUpdates" in row)
+          migrateData[row.location][row.id].applyBackgroundUpdates = row.applyBackgroundUpdates == 1;
+        if ("sourceURI" in row)
+          migrateData[row.location][row.id].sourceURI = row.sourceURI;
+        if ("releaseNotesURI" in row)
+          migrateData[row.location][row.id].releaseNotesURI = row.releaseNotesURI;
       }
 
       var taStmt = this.connection.createStatement("SELECT id, minVersion, " +
                                                    "maxVersion FROM " +
                                                    "targetApplication WHERE " +
                                                    "addon_internal_id=:internal_id");
 
       for (let location in migrateData) {
--- a/toolkit/mozapps/extensions/content/selectAddons.js
+++ b/toolkit/mozapps/extensions/content/selectAddons.js
@@ -75,23 +75,17 @@ function isAddonDistroInstalled(aID) {
   let branch = Services.prefs.getBranch("extensions.installedDistroAddon.");
   if (!branch.prefHasUserValue(aID))
     return false;
 
   return branch.getBoolPref(aID);
 }
 
 function orderForScope(aScope) {
-  switch (aScope) {
-  case AddonManager.SCOPE_PROFILE:
-  case AddonManager.SCOPE_APPLICATION:
-    return 1;
-  default:
-    return 0;
-  }
+  return aScope == AddonManager.SCOPE_PROFILE ? 1 : 0;
 }
 
 var gAddons = {};
 
 var gChecking = {
   nodeID: "checking",
 
   _progress: null,
--- a/toolkit/mozapps/extensions/content/selectAddons.xml
+++ b/toolkit/mozapps/extensions/content/selectAddons.xml
@@ -114,30 +114,25 @@
         <body><![CDATA[
           this._addon = aAddon;
           this._install = aInstall;
           this._wasActive = aWasActive;
 
           this.setAttribute("name", aAddon.name);
           this.setAttribute("type", aAddon.type);
 
-          // User and application installed add-ons default to staying enabled,
+          // User and bundled add-ons default to staying enabled,
           // others default to disabled.
-          let scope = aAddon.scope;
-          if (aDistroInstalled)
-            scope = AddonManager.SCOPE_APPLICATION;
-
-          switch (scope) {
+          switch (aAddon.scope) {
             case AddonManager.SCOPE_PROFILE:
               this._keep.checked = !aAddon.userDisabled;
-              this.setAttribute("source", this._strings.getString("source.profile"));
-              break;
-            case AddonManager.SCOPE_APPLICATION:
-              this._keep.checked = !aAddon.userDisabled;
-              this.setAttribute("source", this._strings.getString("source.bundled"));
+              if (aDistroInstalled)
+                this.setAttribute("source", this._strings.getString("source.bundled"));
+              else
+                this.setAttribute("source", this._strings.getString("source.profile"));
               break;
             default:
               this._keep.checked = false;
               this.setAttribute("source", this._strings.getString("source.other"));
           }
 
           this.updateAction();
         ]]></body>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/addons/test_bug675371/chrome.manifest
@@ -0,0 +1,1 @@
+content bug675371 .
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/addons/test_bug675371/install.rdf
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>bug675371@tests.mozilla.org</em:id>
+    <em:version>1.0</em:version>
+    <em:bootstrap>true</em:bootstrap>
+
+    <!-- Front End MetaData -->
+    <em:name>Bug 675371 Test</em:name>
+    <em:description>Test Description</em:description>
+
+    <em:targetApplication>
+      <Description>
+        <em:id>xpcshell@tests.mozilla.org</em:id>
+        <em:minVersion>1</em:minVersion>
+        <em:maxVersion>1</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+
+  </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/addons/test_bug675371/test.js
@@ -0,0 +1,1 @@
+active = true;
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/addons/test_migrate4_6/install.rdf
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>addon6@tests.mozilla.org</em:id>
+    <em:version>2.0</em:version>
+
+    <!-- Front End MetaData -->
+    <em:name>Test 6</em:name>
+    <em:description>Test Description</em:description>
+
+    <em:targetApplication>
+      <Description>
+        <em:id>xpcshell@tests.mozilla.org</em:id>
+        <em:minVersion>1</em:minVersion>
+        <em:maxVersion>2</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+
+  </Description>
+</RDF>
--- a/toolkit/mozapps/extensions/test/browser/browser_select_selection.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_select_selection.js
@@ -6,59 +6,60 @@
 
 var gProvider;
 var gWin;
 
 const PROFILE = AddonManager.SCOPE_PROFILE;
 const USER = AddonManager.SCOPE_USER;
 const APP = AddonManager.SCOPE_APPLICATION;
 const SYSTEM = AddonManager.SCOPE_SYSTEM;
+const DIST = -1;
 
 // The matrix of testcases for the selection part of the UI
 // Note that the isActive flag has the value it had when the previous version
 // of the application ran with this add-on.
 var ADDONS = [
   //userDisabled   wasAppDisabled isAppDisabled  isActive  hasUpdate  autoUpdate  scope    defaultKeep  position  keepString           disableString
-  [false,          true,          false,         false,    false,     true,       PROFILE, true,        38,      "enabled",           ""],               // 0
-  [false,          true,          false,         false,    true,      true,       PROFILE, true,        39,       "enabled",           ""],               // 1
-  [false,          true,          false,         false,    true,      false,      PROFILE, true,        48,       "unneededupdate",    ""],               // 2
+  [false,          true,          false,         false,    false,     true,       PROFILE, true,        42,       "enabled",           ""],               // 0
+  [false,          true,          false,         false,    true,      true,       PROFILE, true,        43,       "enabled",           ""],               // 1
+  [false,          true,          false,         false,    true,      false,      PROFILE, true,        52,       "unneededupdate",    ""],               // 2
   [false,          false,         false,         true,     false,     true,       PROFILE, true,        53,       "",                  "disabled"],       // 3
   [false,          false,         false,         true,     true,      true,       PROFILE, true,        54,       "",                  "disabled"],       // 4
   [false,          false,         false,         true,     true,      false,      PROFILE, true,        55,       "unneededupdate",    "disabled"],       // 5
   [false,          true,          true,          false,    false,     true,       PROFILE, true,        56,       "incompatible",      ""],               // 6
   [false,          true,          true,          false,    true,      true,       PROFILE, true,        57,       "autoupdate",        ""],               // 7
   [false,          true,          true,          false,    true,      false,      PROFILE, true,        58,       "neededupdate",      ""],               // 8
   [false,          false,         true,          true,     false,     true,       PROFILE, true,        59,       "incompatible",      "disabled"],       // 9
-  [false,          true,          true,          true,     true,      true,       PROFILE, true,        40,       "autoupdate",        "disabled"],       // 10
-  [false,          true,          true,          true,     true,      false,      PROFILE, true,        41,       "neededupdate",      "disabled"],       // 11
-  [true,           false,         false,         false,    false,     true,       PROFILE, false,       42,       "enabled",           ""],               // 12
-  [true,           false,         false,         false,    true,      true,       PROFILE, false,       43,       "enabled",           ""],               // 13
-  [true,           false,         false,         false,    true,      false,      PROFILE, false,       44,       "unneededupdate",    ""],               // 14
+  [false,          true,          true,          true,     true,      true,       PROFILE, true,        44,       "autoupdate",        "disabled"],       // 10
+  [false,          true,          true,          true,     true,      false,      PROFILE, true,        45,       "neededupdate",      "disabled"],       // 11
+  [true,           false,         false,         false,    false,     true,       PROFILE, false,       46,       "enabled",           ""],               // 12
+  [true,           false,         false,         false,    true,      true,       PROFILE, false,       47,       "enabled",           ""],               // 13
+  [true,           false,         false,         false,    true,      false,      PROFILE, false,       48,       "unneededupdate",    ""],               // 14
 
   // userDisabled and isActive cannot be true on startup
 
-  [true,           true,          true,          false,    false,     true,       PROFILE, false,       45,       "incompatible",      ""],               // 15
-  [true,           true,          true,          false,    true,      true,       PROFILE, false,       46,       "autoupdate",        ""],               // 16
-  [true,           true,          true,          false,    true,      false,      PROFILE, false,       47,       "neededupdate",      ""],               // 17
+  [true,           true,          true,          false,    false,     true,       PROFILE, false,       49,       "incompatible",      ""],               // 15
+  [true,           true,          true,          false,    true,      true,       PROFILE, false,       50,       "autoupdate",        ""],               // 16
+  [true,           true,          true,          false,    true,      false,      PROFILE, false,       51,       "neededupdate",      ""],               // 17
 
   // userDisabled and isActive cannot be true on startup
 
   // Being in a different scope should make little difference except no updates are possible so don't exhaustively test each
   [false,          false,         false,         true,     true,      false,      USER,    false,       0,        "",                  "disabled"],       // 18
   [true,           true,          false,         false,    true,      false,      USER,    false,       1,        "enabled",           ""],               // 19
   [false,          true,          true,          true,     true,      false,      USER,    false,       2,        "incompatible",      "disabled"],       // 20
   [true,           true,          true,          false,    true,      false,      USER,    false,       3,        "incompatible",      ""],               // 21
   [false,          false,         false,         true,     true,      false,      SYSTEM,  false,       4,        "",                  "disabled"],       // 22
   [true,           true,          false,         false,    true,      false,      SYSTEM,  false,       5,        "enabled",           ""],               // 23
   [false,          true,          true,          true,     true,      false,      SYSTEM,  false,       6,        "incompatible",      "disabled"],       // 24
   [true,           true,          true,          false,    true,      false,      SYSTEM,  false,       7,        "incompatible",      ""],               // 25
-  [false,          false,         false,         true,     true,      false,      APP,     true,        49,       "",                  "disabled"],       // 26
-  [true,           true,          false,         false,    true,      false,      APP,     false,       50,       "enabled",           ""],               // 27
-  [false,          true,          true,          true,     true,      false,      APP,     true,        51,       "incompatible",      "disabled"],       // 28
-  [true,           true,          true,          false,    true,      false,      APP,     false,       52,       "incompatible",      ""],               // 29
+  [false,          false,         false,         true,     true,      false,      APP,     false,       8,        "",                  "disabled"],       // 26
+  [true,           true,          false,         false,    true,      false,      APP,     false,       9,        "enabled",           ""],               // 27
+  [false,          true,          true,          true,     true,      false,      APP,     false,       10,       "incompatible",      "disabled"],       // 28
+  [true,           true,          true,          false,    true,      false,      APP,     false,       11,       "incompatible",      ""],               // 29
 ];
 
 function waitForView(aView, aCallback) {
   var view = gWin.document.getElementById(aView);
   view.addEventListener("ViewChanged", function() {
     view.removeEventListener("ViewChanged", arguments.callee, false);
     aCallback();
   }, false);
@@ -73,20 +74,20 @@ function getString(aName) {
 }
 
 function getSourceString(aSource) {
   if (!aSource)
     return "";
 
   var strings = Services.strings.createBundle("chrome://mozapps/locale/extensions/selectAddons.properties");
   switch (aSource) {
-    case APP:
-      return strings.GetStringFromName("source.bundled");
     case PROFILE:
       return strings.GetStringFromName("source.profile");
+    case DIST:
+      return strings.GetStringFromName("source.bundled");
     default:
       return strings.GetStringFromName("source.other");
   }
 }
 
 function test() {
   waitForExplicitFinish();
 
@@ -227,17 +228,17 @@ add_test(function selection_test() {
     scrollBoxObject.ensureElementIsVisible(row);
     var keep = gWin.document.getAnonymousElementByAttribute(row, "anonid", "keep");
     var action = gWin.document.getAnonymousElementByAttribute(row, "class", "addon-action-message");
     var update = gWin.document.getAnonymousElementByAttribute(row, "anonid", "update");
     var source = gWin.document.getAnonymousElementByAttribute(row, "class", "addon-source");
 
     if (id == 3 || id == 12 || id == 15) {
       // Distro Installed To Profile
-      is(source.textContent, getSourceString(APP), "Source message should have the right text for Distributed Addons");
+      is(source.textContent, getSourceString(DIST), "Source message should have the right text for Distributed Addons");
     } else {
       is(source.textContent, getSourceString(addon[6]), "Source message should have the right text");
     }
 
     // Non-profile add-ons don't appear to have updates since we won't install
     // them
     var hasUpdate = addon[4] && addon[6] == PROFILE;
 
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_migrate4.rdf
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+  <Description about="urn:mozilla:extension:addon5@tests.mozilla.org">
+    <em:updates>
+      <Seq>
+        <li>
+          <Description>
+            <em:version>2.0</em:version>
+            <em:targetApplication>
+              <Description>
+                <em:id>xpcshell@tests.mozilla.org</em:id>
+                <em:minVersion>0</em:minVersion>
+                <em:maxVersion>2</em:maxVersion>
+              </Description>
+            </em:targetApplication>
+          </Description>
+        </li>
+      </Seq>
+    </em:updates>
+  </Description>
+
+  <Description about="urn:mozilla:extension:addon6@tests.mozilla.org">
+    <em:updates>
+      <Seq>
+        <li>
+          <Description>
+            <em:version>2.0</em:version>
+            <em:targetApplication>
+              <Description>
+                <em:id>xpcshell@tests.mozilla.org</em:id>
+                <em:minVersion>0</em:minVersion>
+                <em:maxVersion>2</em:maxVersion>
+                <em:updateLink>http://localhost:4444/addons/test_migrate4_6.xpi</em:updateLink>
+                <em:updateInfoURL>http://example.com/updateInfo.xhtml</em:updateInfoURL>
+              </Description>
+            </em:targetApplication>
+          </Description>
+        </li>
+      </Seq>
+    </em:updates>
+  </Description>
+
+</RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_bug675371.js
@@ -0,0 +1,91 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+function run_test() {
+  do_test_pending();
+  createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
+  startupManager();
+
+  prepare_test({ }, [
+    "onNewInstall"
+  ]);
+
+  AddonManager.getInstallForFile(do_get_addon("test_bug675371"), function(install) {
+    ensure_test_completed();
+
+    do_check_neq(install, null);
+
+    prepare_test({
+      "bug675371@tests.mozilla.org": [
+        ["onInstalling", false],
+        "onInstalled"
+      ]
+    }, [
+      "onInstallStarted",
+      "onInstallEnded",
+    ], check_test);
+    install.install();
+  });
+}
+
+function check_test() {
+  AddonManager.getAddonByID("bug675371@tests.mozilla.org", function(addon) {
+    do_check_neq(addon, null);
+    do_check_true(addon.isActive);
+
+    // Tests that chrome.manifest is registered when the addon is installed.
+    var target = { active: false };
+    Services.scriptloader.loadSubScript("chrome://bug675371/content/test.js", target);
+    do_check_true(target.active);
+
+    prepare_test({
+      "bug675371@tests.mozilla.org": [
+        ["onDisabling", false],
+        "onDisabled"
+      ]
+    });
+
+    // Tests that chrome.manifest is unregistered when the addon is disabled.
+    addon.userDisabled = true;
+    target.active = false;
+    try {
+      Services.scriptloader.loadSubScript("chrome://bug675371/content/test.js", target);
+      do_throw("Chrome file should not have been found");
+    } catch (e) {
+      do_check_false(target.active);
+    }
+
+    prepare_test({
+      "bug675371@tests.mozilla.org": [
+        ["onEnabling", false],
+        "onEnabled"
+      ]
+    });
+
+    // Tests that chrome.manifest is registered when the addon is enabled.
+    addon.userDisabled = false;
+    target.active = false;
+    Services.scriptloader.loadSubScript("chrome://bug675371/content/test.js", target);
+    do_check_true(target.active);
+
+    prepare_test({
+      "bug675371@tests.mozilla.org": [
+        ["onUninstalling", false],
+        "onUninstalled"
+      ]
+    });
+
+    // Tests that chrome.manifest is unregistered when the addon is uninstalled.
+    addon.uninstall();
+    target.active = false;
+    try {
+      Services.scriptloader.loadSubScript("chrome://bug675371/content/test.js", target);
+      do_throw("Chrome file should not have been found");
+    } catch (e) {
+      do_check_false(target.active);
+    }
+
+    do_test_finished();
+  });
+}
--- a/toolkit/mozapps/extensions/test/xpcshell/test_migrate1.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_migrate1.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-// Checks that we migrate data from previous versions of the database
+// Checks that we migrate data from the old rdf style database
 
 var addon1 = {
   id: "addon1@tests.mozilla.org",
   version: "1.0",
   name: "Test 1",
   targetApplications: [{
     id: "xpcshell@tests.mozilla.org",
     minVersion: "1",
--- a/toolkit/mozapps/extensions/test/xpcshell/test_migrate2.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_migrate2.js
@@ -172,17 +172,16 @@ function run_test() {
     do_check_false(a4.userDisabled);
     do_check_false(a4.appDisabled);
     do_check_true(a4.isActive);
     // addon5 was enabled in the database but needed a compatibiltiy update
     do_check_neq(a5, null);
     do_check_false(a5.userDisabled);
     do_check_false(a5.appDisabled);
     do_check_true(a5.isActive);
-    do_test_finished();
     // addon6 was disabled and compatible but a new version has been installed
     // since, it should still be disabled but should be incompatible
     do_check_neq(a6, null);
     do_check_true(a6.userDisabled);
     do_check_true(a6.appDisabled);
     do_check_false(a6.isActive);
     do_test_finished();
   });
--- a/toolkit/mozapps/extensions/test/xpcshell/test_migrate3.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_migrate3.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-// Checks that we migrate data from previous versions of the database. This
+// Checks that we migrate data from the old extensions.rdf database. This
 // matches test_migrate1.js however it runs with a lightweight theme selected
 // so the themes should appear disabled.
 
 Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm");
 
 var addon1 = {
   id: "addon1@tests.mozilla.org",
   version: "1.0",
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_migrate4.js
@@ -0,0 +1,223 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// Checks that we migrate data from a previous version of the sqlite database
+
+// The test extension uses an insecure update url.
+Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false);
+
+var addon1 = {
+  id: "addon1@tests.mozilla.org",
+  version: "1.0",
+  name: "Test 1",
+  targetApplications: [{
+    id: "xpcshell@tests.mozilla.org",
+    minVersion: "1",
+    maxVersion: "2"
+  }]
+};
+
+var addon2 = {
+  id: "addon2@tests.mozilla.org",
+  version: "2.0",
+  name: "Test 2",
+  targetApplications: [{
+    id: "xpcshell@tests.mozilla.org",
+    minVersion: "1",
+    maxVersion: "2"
+  }]
+};
+
+var addon3 = {
+  id: "addon3@tests.mozilla.org",
+  version: "2.0",
+  name: "Test 3",
+  targetApplications: [{
+    id: "xpcshell@tests.mozilla.org",
+    minVersion: "1",
+    maxVersion: "2"
+  }]
+};
+
+var addon4 = {
+  id: "addon4@tests.mozilla.org",
+  version: "2.0",
+  name: "Test 4",
+  targetApplications: [{
+    id: "xpcshell@tests.mozilla.org",
+    minVersion: "1",
+    maxVersion: "2"
+  }]
+};
+
+var addon5 = {
+  id: "addon5@tests.mozilla.org",
+  version: "2.0",
+  name: "Test 5",
+  updateURL: "http://localhost:4444/data/test_migrate4.rdf",
+  targetApplications: [{
+    id: "xpcshell@tests.mozilla.org",
+    minVersion: "0",
+    maxVersion: "1"
+  }]
+};
+
+var addon6 = {
+  id: "addon6@tests.mozilla.org",
+  version: "1.0",
+  name: "Test 6",
+  updateURL: "http://localhost:4444/data/test_migrate4.rdf",
+  targetApplications: [{
+    id: "xpcshell@tests.mozilla.org",
+    minVersion: "0",
+    maxVersion: "1"
+  }]
+};
+
+const profileDir = gProfD.clone();
+profileDir.append("extensions");
+
+do_load_httpd_js();
+var testserver;
+
+function prepare_profile() {
+  createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
+
+  // Create and configure the HTTP server.
+  testserver = new nsHttpServer();
+  testserver.registerDirectory("/data/", do_get_file("data"));
+  testserver.registerDirectory("/addons/", do_get_file("addons"));
+  testserver.start(4444);
+
+  writeInstallRDFForExtension(addon1, profileDir);
+  writeInstallRDFForExtension(addon2, profileDir);
+  writeInstallRDFForExtension(addon3, profileDir);
+  writeInstallRDFForExtension(addon4, profileDir);
+  writeInstallRDFForExtension(addon5, profileDir);
+  writeInstallRDFForExtension(addon6, profileDir);
+
+  startupManager();
+  AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
+                               "addon2@tests.mozilla.org",
+                               "addon3@tests.mozilla.org",
+                               "addon4@tests.mozilla.org",
+                               "addon5@tests.mozilla.org",
+                               "addon6@tests.mozilla.org"],
+                               function([a1, a2, a3, a4, a5, a6]) {
+    a2.userDisabled = true;
+    a2.applyBackgroundUpdates = false;
+    a4.userDisabled = true;
+    a6.userDisabled = true;
+
+    a6.findUpdates({
+      onUpdateAvailable: function(aAddon, aInstall) {
+        completeAllInstalls([aInstall], function() {
+          restartManager();
+
+          AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
+                                       "addon2@tests.mozilla.org",
+                                       "addon3@tests.mozilla.org",
+                                       "addon4@tests.mozilla.org",
+                                       "addon5@tests.mozilla.org",
+                                       "addon6@tests.mozilla.org"],
+                                       function([a1, a2, a3, a4, a5, a6]) {
+            a3.userDisabled = true;
+            a4.userDisabled = false;
+
+            a5.findUpdates({
+              onUpdateFinished: function() {
+                shutdownManager();
+
+                perform_migration();
+              }
+            }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
+          });
+        });
+      }
+    }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
+  });
+}
+
+function perform_migration() {
+  let dbfile = gProfD.clone();
+  dbfile.append("extensions.sqlite");
+  let db = AM_Cc["@mozilla.org/storage/service;1"].
+           getService(AM_Ci.mozIStorageService).
+           openDatabase(dbfile);
+  db.schemaVersion = 1;
+  Services.prefs.setIntPref("extensions.databaseSchema", 1);
+  db.close();
+
+  gAppInfo.version = "2"
+  startupManager(true);
+  test_results();
+}
+
+function test_results() {
+  check_startup_changes("installed", []);
+  check_startup_changes("updated", []);
+  check_startup_changes("uninstalled", []);
+  check_startup_changes("disabled", []);
+  check_startup_changes("enabled", []);
+
+  AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
+                               "addon2@tests.mozilla.org",
+                               "addon3@tests.mozilla.org",
+                               "addon4@tests.mozilla.org",
+                               "addon5@tests.mozilla.org",
+                               "addon6@tests.mozilla.org"],
+                               function([a1, a2, a3, a4, a5, a6]) {
+    // addon1 was enabled
+    do_check_neq(a1, null);
+    do_check_false(a1.userDisabled);
+    do_check_false(a1.appDisabled);
+    do_check_true(a1.isActive);
+    do_check_true(a1.applyBackgroundUpdates);
+
+    // addon2 was disabled
+    do_check_neq(a2, null);
+    do_check_true(a2.userDisabled);
+    do_check_false(a2.appDisabled);
+    do_check_false(a2.isActive);
+    do_check_false(a2.applyBackgroundUpdates);
+
+    // addon3 was pending-disable in the database
+    do_check_neq(a3, null);
+    do_check_true(a3.userDisabled);
+    do_check_false(a3.appDisabled);
+    do_check_false(a3.isActive);
+    do_check_true(a3.applyBackgroundUpdates);
+
+    // addon4 was pending-enable in the database
+    do_check_neq(a4, null);
+    do_check_false(a4.userDisabled);
+    do_check_false(a4.appDisabled);
+    do_check_true(a4.isActive);
+    do_check_true(a4.applyBackgroundUpdates);
+
+    // addon5 was enabled in the database but needed a compatibiltiy update
+    do_check_neq(a5, null);
+    do_check_false(a5.userDisabled);
+    do_check_false(a5.appDisabled);
+    do_check_true(a5.isActive);
+    do_check_true(a5.applyBackgroundUpdates);
+
+    // addon6 was disabled and compatible but a new version has been installed
+    do_check_neq(a6, null);
+    do_check_eq(a6.version, "2.0");
+    do_check_true(a6.userDisabled);
+    do_check_false(a6.appDisabled);
+    do_check_false(a6.isActive);
+    do_check_true(a6.applyBackgroundUpdates);
+    do_check_eq(a6.sourceURI.spec, "http://localhost:4444/addons/test_migrate4_6.xpi");
+    do_check_eq(a6.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml");
+    testserver.stop(do_test_finished);
+  });
+}
+
+function run_test() {
+  do_test_pending();
+
+  prepare_profile();
+}
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
@@ -112,16 +112,17 @@ fail-if = os == "android"
 [test_bug596607.js]
 [test_bug616841.js]
 # Bug 676992: test consistently fails on Android
 fail-if = os == "android"
 [test_bug619730.js]
 [test_bug620837.js]
 [test_bug655254.js]
 [test_bug659772.js]
+[test_bug675371.js]
 [test_cacheflush.js]
 [test_checkcompatibility.js]
 [test_corrupt.js]
 [test_dictionary.js]
 [test_disable.js]
 [test_distribution.js]
 [test_dss.js]
 # Bug 676992: test consistently fails on Android
@@ -153,16 +154,17 @@ skip-if = os == "android"
 # Bug 676992: test consistently hangs on Android
 skip-if = os == "android"
 [test_locale.js]
 [test_locked.js]
 [test_manifest.js]
 [test_migrate1.js]
 [test_migrate2.js]
 [test_migrate3.js]
+[test_migrate4.js]
 [test_migrateAddonRepository.js]
 [test_permissions.js]
 [test_plugins.js]
 # Bug 676992: test consistently fails on Android
 fail-if = os == "android"
 [test_registry.js]
 [test_safemode.js]
 [test_startup.js]
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -66,16 +66,19 @@
 #ifdef MOZ_INSTRUMENT_EVENT_LOOP
 #include "EventTracer.h"
 #endif
 
 #ifdef XP_MACOSX
 #include "MacLaunchHelper.h"
 #include "MacApplicationDelegate.h"
 #include "MacAutoreleasePool.h"
+// these are needed for sysctl
+#include <sys/types.h>
+#include <sys/sysctl.h>
 #endif
 
 #ifdef XP_OS2
 #include "private/pprthred.h"
 #endif
 #include "prmem.h"
 #include "prnetdb.h"
 #include "prprf.h"
@@ -2650,16 +2653,18 @@ XRE_main(int argc, char* argv[], const n
   nsresult rv;
   ArgResult ar;
 
 #ifdef DEBUG
   if (PR_GetEnv("XRE_MAIN_BREAK"))
     NS_BREAK();
 #endif
 
+  TriggerQuirks();
+
   // see bug 639842
   // it's very important to fire this process BEFORE we set up error handling.
   // indeed, this process is expected to be crashy, and we don't want the user to see its crashes.
   // That's the whole reason for doing this in a separate process.
 #ifdef MOZ_X11
 #ifndef MOZ_PLATFORM_MAEMO
   if (fire_glxtest_process())
     return 0;
@@ -3782,8 +3787,53 @@ SetupErrorHandling(const char* progname)
 
 #if defined(FREEBSD)
   // Disable all SIGFPE's on FreeBSD, as it has non-IEEE-conformant fp
   // trap behavior that trips up on floating-point tests performed by
   // the JS engine.  See bugzilla bug 9967 details.
   fpsetmask(0);
 #endif
 }
+
+void
+TriggerQuirks()
+{
+#if defined(XP_MACOSX)
+  int mib[2];
+
+  mib[0] = CTL_KERN;
+  mib[1] = KERN_OSRELEASE;
+  // we won't support versions greater than 10.7.99
+  char release[sizeof("10.7.99")];
+  size_t len = sizeof(release);
+  // sysctl will return ENOMEM if the release string is longer than sizeof(release)
+  int ret = sysctl(mib, 2, release, &len, NULL, 0);
+  // we only want to trigger this on OS X 10.6, on versions 10.6.8 or newer
+  // Darwin version 10 corresponds to OS X version 10.6, version 11 is 10.7
+  // http://en.wikipedia.org/wiki/Darwin_(operating_system)#Release_history
+  if (ret == 0 && NS_CompareVersions(release, "10.8.0") >= 0 && NS_CompareVersions(release, "11") < 0) {
+    CFBundleRef mainBundle = CFBundleGetMainBundle();
+    if (mainBundle) {
+      CFRetain(mainBundle);
+
+      CFStringRef bundleID = CFBundleGetIdentifier(mainBundle);
+      if (bundleID) {
+        CFRetain(bundleID);
+
+        CFMutableDictionaryRef dict = (CFMutableDictionaryRef)CFBundleGetInfoDictionary(mainBundle);
+        CFDictionarySetValue(dict, CFSTR("CFBundleIdentifier"), CFSTR("org.mozilla.firefox"));
+
+        // Calling Gestalt will trigger a load of the quirks table for org.mozilla.firefox
+        SInt32 major;
+        ::Gestalt(gestaltSystemVersionMajor, &major);
+
+        // restore the original id
+        dict = (CFMutableDictionaryRef)CFBundleGetInfoDictionary(mainBundle);
+        CFDictionarySetValue(dict, CFSTR("CFBundleIdentifier"), bundleID);
+
+        CFRelease(bundleID);
+      }
+      CFRelease(mainBundle);
+    }
+  }
+#endif
+}
+
--- a/toolkit/xre/nsAppRunner.h
+++ b/toolkit/xre/nsAppRunner.h
@@ -189,9 +189,10 @@ extern GeckoProcessType sChildProcessTyp
 }
 
 /**
  * Set up platform specific error handling such as suppressing DLL load dialog
  * and the JIT debugger on Windows, and install unix signal handlers.
  */
 void SetupErrorHandling(const char* progname);
 
+void TriggerQuirks();
 #endif // nsAppRunner_h__
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -309,16 +309,18 @@ nsresult
 XRE_InitChildProcess(int aArgc,
                      char* aArgv[],
                      GeckoProcessType aProcess)
 {
   NS_ENSURE_ARG_MIN(aArgc, 2);
   NS_ENSURE_ARG_POINTER(aArgv);
   NS_ENSURE_ARG_POINTER(aArgv[0]);
 
+  TriggerQuirks();
+
   sChildProcessType = aProcess;
 
   // Complete 'task_t' exchange for Mac OS X. This structure has the same size
   // regardless of architecture so we don't have any cross-arch issues here.
 #ifdef XP_MACOSX
   if (aArgc < 1)
     return 1;
   const char* const mach_port_name = aArgv[--aArgc];
--- a/widget/public/LookAndFeel.h
+++ b/widget/public/LookAndFeel.h
@@ -452,17 +452,17 @@ public:
    * use a value for the default value, you should use the other method which
    * returns int or float directly.
    */
   static nsresult GetInt(IntID aID, PRInt32* aResult);
   static nsresult GetFloat(FloatID aID, float* aResult);
 
   static nscolor GetColor(ColorID aID, nscolor aDefault = NS_RGB(0, 0, 0))
   {
-    nscolor result;
+    nscolor result = NS_RGB(0, 0, 0);
     if (NS_FAILED(GetColor(aID, &result))) {
       return aDefault;
     }
     return result;
   }
 
   static PRInt32 GetInt(IntID aID, PRInt32 aDefault = 0)
   {
--- a/xpcom/base/nsMemoryReporterManager.cpp
+++ b/xpcom/base/nsMemoryReporterManager.cpp
@@ -79,17 +79,17 @@ static PRInt64 GetProcSelfStatmField(int
 {
     // There are more than two fields, but we're only interested in the first
     // two.
     static const int MAX_FIELD = 2;
     size_t fields[MAX_FIELD];
     NS_ASSERTION(n < MAX_FIELD, "bad field number");
     FILE *f = fopen("/proc/self/statm", "r");
     if (f) {
-        int nread = fscanf(f, "%lu %lu", &fields[0], &fields[1]);
+        int nread = fscanf(f, "%zu %zu", &fields[0], &fields[1]);
         fclose(f);
         return (PRInt64) ((nread == MAX_FIELD) ? fields[n]*getpagesize() : -1);
     }
     return (PRInt64) -1;
 }
 
 static PRInt64 GetVsize()
 {