Merged m-c
authorChris Jones <jones.chris.g@gmail.com>
Thu, 13 May 2010 18:04:53 -0500
changeset 46855 3a315d04bc4dd03ec4d472ee3a17d8870f5cf6f2
parent 46854 91789d0400b9376cbf8a9b221575d74f54a21267 (current diff)
parent 42304 7b02623b93fec9169869f6451c7b42e9b2aa437d (diff)
child 46856 2c046167b7281216bbee2d72d7ba50af610f291d
push idunknown
push userunknown
push dateunknown
milestone1.9.3a5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
Merged m-c
browser/app/profile/firefox.js
chrome/src/nsChromeRegistry.cpp
configure.in
content/base/src/nsContentUtils.cpp
content/base/src/nsFrameLoader.cpp
content/base/src/nsObjectLoadingContent.cpp
content/events/src/nsDOMEvent.cpp
content/html/content/src/nsGenericHTMLElement.cpp
content/media/ogg/nsOggReader.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/plugins/PluginInstanceChild.cpp
dom/plugins/PluginModuleChild.cpp
dom/plugins/PluginModuleParent.cpp
dom/plugins/PluginThreadChild.cpp
dom/plugins/PluginThreadChild.h
ipc/chromium/src/base/thread.cc
ipc/chromium/src/chrome/common/ipc_channel_win.cc
ipc/chromium/src/chrome/common/ipc_channel_win.h
ipc/glue/MozillaChildThread.cpp
ipc/glue/MozillaChildThread.h
ipc/glue/RPCChannel.cpp
ipc/ipdl/test/cxx/IPDLUnitTestThreadChild.cpp
ipc/ipdl/test/cxx/IPDLUnitTestThreadChild.h
js/src/xpconnect/shell/xpcshell.cpp
layout/reftests/box-shadow/boxshadow-inner-basic-ref.html
layout/style/nsICSSStyleSheet.h
modules/plugin/base/src/nsPluginHost.cpp
netwerk/base/src/nsStandardURL.cpp
netwerk/protocol/http/src/nsHttpHandler.cpp
storage/test/unit/test_js_helpers_enumerate.js
storage/test/unit/test_js_helpers_prototype_chain_safe.js
toolkit/components/remote/nsPhRemoteService.cpp
toolkit/components/remote/nsPhRemoteService.h
toolkit/content/widgets/browser.xml
toolkit/library/libxul-config.mk
toolkit/toolkit-makefiles.sh
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsEmbedFunctions.cpp
toolkit/xre/nsSigHandlers.cpp
widget/src/photon/Makefile.in
widget/src/photon/PtRawDrawContainer.cpp
widget/src/photon/PtRawDrawContainer.h
widget/src/photon/nsAppShell.cpp
widget/src/photon/nsAppShell.h
widget/src/photon/nsBidiKeyboard.cpp
widget/src/photon/nsBidiKeyboard.h
widget/src/photon/nsClipboard.cpp
widget/src/photon/nsClipboard.h
widget/src/photon/nsDragService.cpp
widget/src/photon/nsDragService.h
widget/src/photon/nsFilePicker.cpp
widget/src/photon/nsFilePicker.h
widget/src/photon/nsLookAndFeel.cpp
widget/src/photon/nsLookAndFeel.h
widget/src/photon/nsScreenManagerPh.cpp
widget/src/photon/nsScreenManagerPh.h
widget/src/photon/nsScreenPh.cpp
widget/src/photon/nsScreenPh.h
widget/src/photon/nsSound.cpp
widget/src/photon/nsSound.h
widget/src/photon/nsToolkit.cpp
widget/src/photon/nsToolkit.h
widget/src/photon/nsWidget.cpp
widget/src/photon/nsWidget.h
widget/src/photon/nsWidgetFactory.cpp
widget/src/photon/nsWindow.cpp
widget/src/photon/nsWindow.h
widget/src/qt/nsWindow.cpp
widget/src/windows/nsWindow.cpp
widget/src/windows/nsWindow.h
widget/src/windows/nsWindowGfx.cpp
widget/src/xremoteclient/PhRemoteClient.cpp
widget/src/xremoteclient/PhRemoteClient.h
--- a/accessible/public/nsIAccessibilityService.h
+++ b/accessible/public/nsIAccessibilityService.h
@@ -134,17 +134,17 @@ public:
     FRAME_SHOW = 0x04,
     FRAME_HIDE = 0x05,
     FRAME_SIGNIFICANT_CHANGE = 0x06
   };
 
   /**
    * Invalidate the accessible tree when DOM tree or frame tree is changed.
    *
-   * @param aPresShell   [in] the presShell where changes occured
+   * @param aPresShell   [in] the presShell where changes occurred
    * @param aContent     [in] the affected DOM content
    * @param aChangeType  [in] the change type (see constants declared above)
    */
   virtual nsresult InvalidateSubtreeFor(nsIPresShell *aPresShell,
                                         nsIContent *aContent,
                                         PRUint32 aChangeType) = 0;
 
   /**
--- a/accessible/public/nsIAccessibleProvider.idl
+++ b/accessible/public/nsIAccessibleProvider.idl
@@ -40,17 +40,17 @@
 
 #include "nsISupports.idl"
 
 /**
  * nsIAccessibleProvider interface is used to link element and accessible
    object. For that XBL binding of element should implement the interface.
  */
 
-[scriptable, uuid(3f7f9194-c625-4a85-8148-6d92d34897fa)]
+[scriptable, uuid(89fb8270-4f25-11df-9879-0800200c9a66)]
 interface nsIAccessibleProvider : nsISupports
 {
   /**
    * Constants set of common use.
    */
 
   /** Do not create an accessible for this object
    * This is useful if an ancestor binding already implements nsIAccessibleProvider,
@@ -121,17 +121,17 @@ interface nsIAccessibleProvider : nsISup
   /** Used for xforms elements that provide accessible object for itself as
    * well for anonymous content. This property are used for upload,
    * input[type="xsd:gDay"] and input[type="xsd:gMonth"] */
   const long XFormsContainer = 0x00002000;
 
   /** Used for label element */
   const long XFormsLabel = 0x00002001;
   /** Used for output element */
-  const long XFormsOuput = 0x00002002;
+  const long XFormsOutput = 0x00002002;
   /** Used for trigger and submit elements */
   const long XFormsTrigger = 0x00002003;
   /** Used for input and textarea elements */
   const long XFormsInput = 0x00002004;
   /** Used for input[xsd:boolean] element */
   const long XFormsInputBoolean = 0x00002005;
   /** Used for input[xsd:date] element */
   const long XFormsInputDate = 0x00002006;
--- a/accessible/src/base/nsAccessibilityAtomList.h
+++ b/accessible/src/base/nsAccessibilityAtomList.h
@@ -190,16 +190,17 @@ ACCESSIBILITY_ATOM(popup, "popup")
 ACCESSIBILITY_ATOM(readonly, "readonly")
 ACCESSIBILITY_ATOM(scope, "scope") // HTML table
 ACCESSIBILITY_ATOM(simple, "simple") // XLink
 ACCESSIBILITY_ATOM(src, "src")
 ACCESSIBILITY_ATOM(selected, "selected")
 ACCESSIBILITY_ATOM(summary, "summary")
 ACCESSIBILITY_ATOM(tabindex, "tabindex")
 ACCESSIBILITY_ATOM(title, "title")
+ACCESSIBILITY_ATOM(toolbarname, "toolbarname")
 ACCESSIBILITY_ATOM(tooltiptext, "tooltiptext")
 ACCESSIBILITY_ATOM(type, "type")
 ACCESSIBILITY_ATOM(usemap, "usemap")
 ACCESSIBILITY_ATOM(value, "value")
 
   // Alphabetical list of object attributes
 ACCESSIBILITY_ATOM(checkable, "checkable")
 ACCESSIBILITY_ATOM(display, "display")
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -1966,17 +1966,17 @@ nsAccessibilityService::CreateAccessible
     // XForms elements
     case nsIAccessibleProvider::XFormsContainer:
       accessible = new nsXFormsContainerAccessible(aNode, aWeakShell);
       break;
 
     case nsIAccessibleProvider::XFormsLabel:
       accessible = new nsXFormsLabelAccessible(aNode, aWeakShell);
       break;
-    case nsIAccessibleProvider::XFormsOuput:
+    case nsIAccessibleProvider::XFormsOutput:
       accessible = new nsXFormsOutputAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsTrigger:
       accessible = new nsXFormsTriggerAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsInput:
       accessible = new nsXFormsInputAccessible(aNode, aWeakShell);
       break;
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -2037,26 +2037,26 @@ nsDocAccessible::InvalidateCacheSubtree(
     // updated to make this accessible content visible. If we don't wait,
     // the assistive technology may receive the event and then retrieve
     // nsIAccessibleStates::STATE_INVISIBLE for the event's accessible object.
 
     FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SHOW, childNode,
                                nsAccEvent::eCoalesceFromSameSubtree,
                                isAsynch);
 
-    // Check to see change occured in an ARIA menu, and fire
+    // Check to see change occurred in an ARIA menu, and fire
     // an EVENT_MENUPOPUP_START if it did.
     nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(childNode);
     if (roleMapEntry && roleMapEntry->role == nsIAccessibleRole::ROLE_MENUPOPUP) {
       FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START,
                                  childNode, nsAccEvent::eRemoveDupes,
                                  isAsynch);
     }
 
-    // Check to see if change occured inside an alert, and fire an EVENT_ALERT if it did
+    // Check to see if change occurred inside an alert, and fire an EVENT_ALERT if it did
     nsIContent *ancestor = aChild;
     while (PR_TRUE) {
       if (roleMapEntry && roleMapEntry->role == nsIAccessibleRole::ROLE_ALERT) {
         nsCOMPtr<nsIDOMNode> alertNode(do_QueryInterface(ancestor));
         FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_ALERT, alertNode,
                                    nsAccEvent::eRemoveDupes, isAsynch);
         break;
       }
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -1002,17 +1002,17 @@ nsresult nsHyperTextAccessible::GetTextH
     NS_ENSURE_TRUE(finalStartOffset >= 0, NS_ERROR_FAILURE);
   }
 
   if (aType == eGetBefore) {
     endOffset = aOffset;
   }
   else {
     // Start moving forward from the start so that we don't get 
-    // 2 words/lines if the offset occured on whitespace boundary
+    // 2 words/lines if the offset occurred on whitespace boundary
     // Careful, startOffset and endOffset are passed by reference to GetPosAndText() and changed
     // For BOUNDARY_LINE_END, make sure we start of this line
     startOffset = endOffset = finalStartOffset + (aBoundaryType == BOUNDARY_LINE_END);
     nsCOMPtr<nsIAccessible> endAcc;
     nsIFrame *endFrame = GetPosAndText(startOffset, endOffset, nsnull, nsnull,
                                        nsnull, getter_AddRefs(endAcc));
     if (nsAccUtils::Role(endAcc) == nsIAccessibleRole::ROLE_STATICTEXT) {
       // Static text like list bullets will ruin our forward calculation,
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -1733,17 +1733,17 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
 }
 
 //------- Helper methods ---------
 
 PRInt32 nsAccessibleWrap::GetChildIDFor(nsIAccessible* aAccessible)
 {
   // A child ID of the window is required, when we use NotifyWinEvent,
   // so that the 3rd party application can call back and get the IAccessible
-  // the event occured on.
+  // the event occurred on.
 
   void *uniqueID = nsnull;
   nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(aAccessible));
   if (!accessNode) {
     return 0;
   }
   accessNode->GetUniqueID(&uniqueID);
 
--- a/accessible/src/xul/nsXULFormControlAccessible.cpp
+++ b/accessible/src/xul/nsXULFormControlAccessible.cpp
@@ -829,16 +829,30 @@ nsAccessibleWrap(aNode, aShell)
 
 nsresult
 nsXULToolbarAccessible::GetRoleInternal(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_TOOLBAR;
   return NS_OK;
 }
 
+nsresult
+nsXULToolbarAccessible::GetNameInternal(nsAString& aName)
+{
+  nsCOMPtr<nsIContent> content = nsCoreUtils::GetRoleContent(mDOMNode);
+  nsAutoString name;
+  if (content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::toolbarname,
+                       name)) {
+    name.CompressWhitespace();
+    aName = name;
+  }
+
+  return NS_OK;
+}
+
 /**
   * XUL Toolbar Separator
   */
 
 nsXULToolbarSeparatorAccessible::nsXULToolbarSeparatorAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
 nsLeafAccessible(aNode, aShell)
 { 
 }
--- a/accessible/src/xul/nsXULFormControlAccessible.h
+++ b/accessible/src/xul/nsXULFormControlAccessible.h
@@ -197,16 +197,17 @@ public:
 
 class nsXULToolbarAccessible : public nsAccessibleWrap
 {
 public:
   nsXULToolbarAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
 
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
+  virtual nsresult GetNameInternal(nsAString& aName);
 };
 
 class nsXULToolbarSeparatorAccessible : public nsLeafAccessible
 {
 public:
   nsXULToolbarSeparatorAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
 
   // nsAccessible
--- a/accessible/tests/mochitest/role.js
+++ b/accessible/tests/mochitest/role.js
@@ -53,16 +53,17 @@ const ROLE_SCROLLBAR = nsIAccessibleRole
 const ROLE_SECTION = nsIAccessibleRole.ROLE_SECTION;
 const ROLE_SEPARATOR = nsIAccessibleRole.ROLE_SEPARATOR;
 const ROLE_SLIDER = nsIAccessibleRole.ROLE_SLIDER;
 const ROLE_STATICTEXT = nsIAccessibleRole.ROLE_STATICTEXT;
 const ROLE_TABLE = nsIAccessibleRole.ROLE_TABLE;
 const ROLE_TEXT_CONTAINER = nsIAccessibleRole.ROLE_TEXT_CONTAINER;
 const ROLE_TEXT_LEAF = nsIAccessibleRole.ROLE_TEXT_LEAF;
 const ROLE_TOGGLE_BUTTON = nsIAccessibleRole.ROLE_TOGGLE_BUTTON;
+const ROLE_TOOLBAR = nsIAccessibleRole.ROLE_TOOLBAR;
 const ROLE_TOOLTIP = nsIAccessibleRole.ROLE_TOOLTIP;
 const ROLE_TREE_TABLE = nsIAccessibleRole.ROLE_TREE_TABLE;
 const ROLE_WHITESPACE = nsIAccessibleRole.ROLE_WHITESPACE;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Public methods
 
 /**
--- a/accessible/tests/mochitest/test_name_button.html
+++ b/accessible/tests/mochitest/test_name_button.html
@@ -123,20 +123,20 @@
          aria-labelledby="aria_labelledby_text_for_input"
          value="1"/>
   <br/>
 
   <!-- label, preferred to @title -->
   <label for="input_labelled">label</label>
   <input type="button" id="input_labelled" value="1" title="title"/>
 
-  <!-- name from @value, prefered to @title -->
+  <!-- name from @value, preferred to @title -->
   <input type="button" id="input_value0" title="title" value="1"/>
 
-  <!-- name from @value, prefered to @alt -->
+  <!-- name from @value, preferred to @alt -->
   <input type="button" id="input_value" value="1" alt="alt"/>
 
   <!-- name from @alt, preferred to @src -->
   <input type="button" id="input_alt" alt="alt" @src="src"/>
 
   <!-- name from @src, preferred to @data -->
   <input type="button" id="input_src" src="src" data="data"/>
 
--- a/accessible/tests/mochitest/tree/test_formctrl.xul
+++ b/accessible/tests/mochitest/tree/test_formctrl.xul
@@ -43,16 +43,46 @@
             role: ROLE_RADIOBUTTON,
             children: [ ]
           }
         ]
       };
 
       testAccessibleTree("radiogroup", accTree);
 
+      // toolbar
+      accTree = {
+        role: ROLE_TOOLBAR,
+        name: "My toolbar",
+        children: [
+          {
+            role: ROLE_PUSHBUTTON,
+            name: "hello",
+            children: [ ]
+          }
+        ]
+      };
+
+      testAccessibleTree("toolbar", accTree);
+
+      // toolbar
+      accTree = {
+        role: ROLE_TOOLBAR,
+        name: "My second toolbar",
+        children: [
+          {
+            role: ROLE_PUSHBUTTON,
+            name: "hello",
+            children: [ ]
+          }
+        ]
+      };
+
+      testAccessibleTree("toolbar2", accTree);
+
       SimpleTest.finish()
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   ]]>
   </script>
 
@@ -71,13 +101,19 @@
     </body>
 
     <vbox flex="1">
       <checkbox id="checkbox" label="checkbox"/>
       <radiogroup id="radiogroup">
         <radio label="radio1"/>
         <radio label="radio2"/>
       </radiogroup>
+      <toolbar id="toolbar" toolbarname="My toolbar">
+        <toolbarbutton id="button1" label="hello"/>
+      </toolbar>
+      <toolbar id="toolbar2" toolbarname="2nd" aria-label="My second toolbar">
+        <toolbarbutton id="button2" label="hello"/>
+      </toolbar>
     </vbox>
   </hbox>
 
 </window>
 
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -16,16 +16,17 @@
 #
 # The Initial Developer of the Original Code is
 # Netscape Communications Corporation.
 # Portions created by the Initial Developer are Copyright (C) 2001
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #   Ehsan Akhgari <ehsan.akhgari@gmail.com>
+#   Rob Campbell <rcampbell@mozilla.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -593,16 +594,22 @@
                         accesskey="&downloads.accesskey;"
                         key="key_openDownloads"
                         command="Tools:Downloads"/>
               <menuitem id="menu_openAddons"
                         label="&addons.label;"
                         accesskey="&addons.accesskey;"
                         command="Tools:Addons"/>
               <menuseparator id="devToolsSeparator"/>
+              <menuitem id="menu_pageinspect"
+                        type="checkbox"
+                        label="&inspectMenu.label;"
+                        accesskey="&inspectMenu.accesskey;"
+                        key="&inspectMenu.commandkey;"
+                        command="Tools:Inspect"/>
               <menuitem id="javascriptConsole"
                         label="&errorConsoleCmd.label;"
                         accesskey="&errorConsoleCmd.accesskey;"
                         key="key_errorConsole"
                         oncommand="toJavaScriptConsole();"/>
               <menuitem id="menu_pageInfo"
                         accesskey="&pageInfoCmd.accesskey;"
                         label="&pageInfoCmd.label;"
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -19,16 +19,17 @@
 # Portions created by the Initial Developer are Copyright (C) 2001
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #   Ben Goodger <ben@bengoodger.com> (v2.0)
 #   Blake Ross <blakeross@telocity.com>
 #   Shawn Wilsher <me@shawnwilsher.com>
 #   Ehsan Akhgari <ehsan.akhgari@gmail.com>
+#   Rob Campbell <rcampbell@mozilla.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -119,16 +120,17 @@
     <command id="cmd_fullZoomReduce"  oncommand="FullZoom.reduce()"/>
     <command id="cmd_fullZoomEnlarge" oncommand="FullZoom.enlarge()"/>
     <command id="cmd_fullZoomReset"   oncommand="FullZoom.reset()"/>
     <command id="cmd_fullZoomToggle"  oncommand="ZoomManager.toggleZoom();"/>
     <command id="Browser:OpenLocation" oncommand="openLocation();"/>
 
     <command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>    
     <command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/>
+    <command id="Tools:Inspect" oncommand="InspectorUI.toggleInspectorUI();"/>
     <command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/>
     <command id="Tools:Sanitize"
      oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/>
     <command id="Tools:PrivateBrowsing" oncommand="gPrivateBrowsingUI.toggleMode();"/>
     <command id="History:UndoCloseTab" oncommand="undoCloseTab();"/>
     <command id="History:UndoCloseWindow" oncommand="undoCloseWindow();"/>
   </commandset>
 
@@ -201,32 +203,31 @@
 #
 # We support Ctrl+K on all platforms now and advertise it in the menu since it is
 # our standard - it is a "safe" choice since it is near no harmful keys like "W" as
 # "E" is. People mourning the loss of Ctrl+K for emacs compat can switch their GTK
 # system setting to use emacs emulation, and we should respect it. Focus-Search-Box
 # is a fundamental keybinding and we are maintaining a XP binding so that it is easy
 # for people to switch to Linux.
 #
-# Do *not* tamper with these values without talking to ben@mozilla.org
-#
     <key id="key_search" key="&searchFocus.commandkey;" command="Tools:Search" modifiers="accel"/>
 #ifdef XP_MACOSX
     <key id="key_search2" key="&findOnCmd.commandkey;" command="Tools:Search" modifiers="accel,alt"/>
 #endif
 #ifdef XP_WIN
     <key id="key_search2" key="&searchFocus.commandkey2;" command="Tools:Search" modifiers="accel"/>
 #endif
 #ifdef XP_GNOME
     <key id="key_search2" key="&searchFocusUnix.commandkey;" command="Tools:Search" modifiers="accel"/>
     <key id="key_openDownloads" key="&downloadsUnix.commandkey;" command="Tools:Downloads" modifiers="accel,shift"/>
 #else
     <key id="key_openDownloads" key="&downloads.commandkey;" command="Tools:Downloads" modifiers="accel"/>
 #endif
     <key id="key_errorConsole" key="&errorConsoleCmd.commandkey;" oncommand="toJavaScriptConsole();" modifiers="accel,shift"/>
+    <key id="key_inspect" key="&inspectMenu.commandkey;" command="Tools:Inspect" modifiers="accel,shift"/>
     <key id="openFileKb" key="&openFileCmd.commandkey;" command="Browser:OpenFile"  modifiers="accel"/>
     <key id="key_savePage" key="&savePageCmd.commandkey;" command="Browser:SavePage" modifiers="accel"/>
     <key id="printKb" key="&printCmd.commandkey;" command="cmd_print"  modifiers="accel"/>
     <key id="key_close" key="&closeCmd.key;" command="cmd_close" modifiers="accel"/>
     <key id="key_closeWindow" key="&closeCmd.key;" command="cmd_closeWindow" modifiers="accel,shift"/>
     <key id="key_undo"
          key="&undoCmd.key;"
          modifiers="accel"/>
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -251,8 +251,15 @@ window[chromehidden~="toolbar"] toolbar:
 .allTabs-preview {
   -moz-binding: url("chrome://browser/content/browser-tabPreviews.xml#allTabs-preview");
 }
 
 #allTabs-tab-close-button {
   -moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-image");
   margin: 0;
 }
+
+/* Inspector / Highlighter */
+
+#highlighter-panel {
+  -moz-appearance: none;
+  -moz-window-shadow: none;
+}
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -46,16 +46,17 @@
 #   Thomas K. Dyas <tdyas@zecador.org>
 #   Edward Lee <edward.lee@engineering.uiuc.edu>
 #   Paul O’Shannessy <paul@oshannessy.com>
 #   Nils Maier <maierman@web.de>
 #   Rob Arnold <robarnold@cmu.edu>
 #   Dietrich Ayala <dietrich@mozilla.com>
 #   Gavin Sharp <gavin@gavinsharp.com>
 #   Justin Dolske <dolske@mozilla.com>
+#   Rob Campbell <rcampbell@mozilla.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -123,16 +124,17 @@ var gEditUIVisible = true;
 
 let gInitialPages = [
   "about:blank",
   "about:privatebrowsing",
   "about:sessionrestore"
 ];
 
 #include browser-fullZoom.js
+#include inspector.js
 #include browser-places.js
 #include browser-tabPreviews.js
 
 XPCOMUtils.defineLazyGetter(this, "Win7Features", function () {
 #ifdef XP_WIN
 #ifndef WINCE
   const WINTASKBAR_CONTRACTID = "@mozilla.org/windows-taskbar;1";
   if (WINTASKBAR_CONTRACTID in Cc &&
@@ -5774,17 +5776,18 @@ function AddKeywordForSearchField() {
       formData.push((isURLEncoded) ? escapeNameValuePair(el.name, "%s", true) :
                                      // Don't escape "%s", just append
                                      escapeNameValuePair(el.name, "", false) + "%s");
       continue;
     }
 
     type = el.type.toLowerCase();
 
-    if ((type == "text" || type == "hidden" || type == "textarea") ||
+    if (((el instanceof HTMLInputElement && el.mozIsTextField(true)) ||
+        type == "hidden" || type == "textarea") ||
         ((type == "checkbox" || type == "radio") && el.checked)) {
       formData.push(escapeNameValuePair(el.name, el.value, isURLEncoded));
     } else if (el instanceof HTMLSelectElement && el.selectedIndex >= 0) {
       for (var j=0; j < el.options.length; j++) {
         if (el.options[j].selected)
           formData.push(escapeNameValuePair(el.name, el.options[j].value,
                                             isURLEncoded));
       }
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -28,16 +28,17 @@
 #   David Hyatt <hyatt@mozilla.org>
 #   Joe Hewitt <hewitt@netscape.com>
 #   Pierre Chanial <chanial@noos.fr>
 #   Dean Tessman <dean_tessman@hotmail.com>
 #   Johnathan Nightingale <johnath@mozilla.com>
 #   Dão Gottwald <dao@mozilla.com>
 #   Ehsan Akhgari <ehsan.akhgari@gmail.com>
 #   Robert Strong <robert.bugzilla@gmail.com>
+#   Rob Campbell <rcampbell@mozilla.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -213,16 +214,45 @@
                 class="editBookmarkPanelBottomButton"
                 label="&editBookmark.done.label;"
                 default="true"
                 oncommand="StarUI.panel.hidePopup();"/>
 #endif
       </hbox>
     </panel>
 
+    <panel id="highlighter-panel"
+           hidden="true"
+           ignorekeys="true"
+           noautofocus="true"
+           noautohide="true"
+           onclick="InspectorUI.stopInspecting();"
+           onmousemove="InspectorUI.highlighter.handleMouseMove(event);"/>
+
+    <panel id="inspector-panel"
+           orient="vertical"
+           hidden="true"
+           ignorekeys="true"
+           noautofocus="true"
+           noautohide="true"
+           level="top"
+           aria-labelledby="inspectPagePanelTitle">
+      <tree id="inspector-tree" class="plain" seltype="single" treelines="true"
+            onselect="InspectorUI.onTreeSelected()" flex="1">
+        <treecols>
+          <treecol id="colNodeName" label="nodeName" primary="true"
+                   persist="width,hidden,ordinal" flex="1"/>
+          <splitter class="tree-splitter"/>
+          <treecol id="colNodeValue" label="nodeValue"
+                   persist="width,hidden,ordinal" flex="1"/>
+        </treecols>
+        <treechildren id="inspector-tree-body"/>
+      </tree>
+    </panel>
+
     <popup id="toolbar-context-menu"
            onpopupshowing="onViewToolbarsPopupShowing(event);">
       <menuseparator/>
       <menuitem command="cmd_ToggleTabsOnTop"
                 type="checkbox"
                 label="&viewTabsOnTop.label;"
                 accesskey="&viewTabsOnTop.accesskey;"/>
       <menuseparator/>
@@ -587,16 +617,17 @@
       </toolbaritem>
     </toolbar>
 
     <toolbar id="TabsToolbar"
              fullscreentoolbar="true"
              customizable="true"
              mode="icons" lockmode="true"
              iconsize="small" defaulticonsize="small" lockiconsize="true"
+             aria-label="&tabsToolbar.label;"
              context="toolbar-context-menu"
              defaultset="tabbrowser-tabs,new-tab-button,alltabs-button,tabs-closebutton"
              collapsed="true">
 
       <tabs id="tabbrowser-tabs"
             class="tabbrowser-tabs"
             context="tabContextMenu"
             tabbrowser="content"
@@ -685,21 +716,23 @@
                      label="&copyCmd.label;"
                      command="cmd_copy"
                      tooltiptext="&copyButton.tooltip;"/>
 
       <toolbarbutton id="paste-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
                      label="&pasteCmd.label;"
                      command="cmd_paste"
                      tooltiptext="&pasteButton.tooltip;"/>
+
       <toolbarbutton id="fullscreen-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
                      observes="View:FullScreen"
                      type="checkbox"
                      label="&fullScreenCmd.label;"
                      tooltiptext="&fullScreenButton.tooltip;"/>
+
     </toolbarpalette>
   </toolbox>
 
   <hbox flex="1" id="browser">
     <vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome">
       <sidebarheader id="sidebar-header" align="center">
         <label id="sidebar-title" persist="value" flex="1" crop="end" control="sidebar"/>
         <image id="sidebar-throbber"/>
new file mode 100644
--- /dev/null
+++ b/browser/base/content/inspector.js
@@ -0,0 +1,758 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+#ifdef 0
+/* ***** 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 the Mozilla Inspector Module.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Rob Campbell <rcampbell@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * 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 ***** */
+#endif
+
+const INSPECTOR_INVISIBLE_ELEMENTS = {
+  "head": true,
+  "base": true,
+  "basefont": true,
+  "isindex": true,
+  "link": true,
+  "meta": true,
+  "script": true,
+  "style": true,
+  "title": true,
+};
+
+///////////////////////////////////////////////////////////////////////////
+//// PanelHighlighter
+
+/**
+ * A highlighter mechanism using xul panels.
+ *
+ * @param aBrowser
+ *        The XUL browser object for the content window being highlighted.
+ * @param aColor
+ *        A string containing an RGB color for the panel background.
+ * @param aBorderSize
+ *        A number representing the border thickness of the panel.
+ * @param anOpacity
+ *        A number representing the alpha value of the panel background.
+ */
+function PanelHighlighter(aBrowser, aColor, aBorderSize, anOpacity)
+{
+  this.panel = document.getElementById("highlighter-panel");
+  this.panel.hidden = false;
+  this.browser = aBrowser;
+  this.win = this.browser.contentWindow;
+  this.backgroundColor = aColor;
+  this.border = aBorderSize;
+  this.opacity = anOpacity;
+  this.updatePanelStyles();
+}
+
+PanelHighlighter.prototype = {
+  
+  /**
+   * Update the panel's style object with current settings.
+   * TODO see bugXXXXXX, https://wiki.mozilla.org/Firefox/Projects/Inspector#0.7
+   * and, https://wiki.mozilla.org/Firefox/Projects/Inspector#1.0.
+   */
+  updatePanelStyles: function PanelHighlighter_updatePanelStyles()
+  {
+    let style = this.panel.style;
+    style.backgroundColor = this.backgroundColor;
+    style.border = "solid blue " + this.border + "px";
+    style.MozBorderRadius = "4px";
+    style.opacity = this.opacity;
+  },
+
+  /**
+   * Highlight this.node, unhilighting first if necessary.
+   *
+   * @param scroll
+   *        Boolean determining whether to scroll or not.
+   */
+  highlight: function PanelHighlighter_highlight(scroll)
+  {
+    // node is not set or node is not highlightable, bail
+    if (!this.isNodeHighlightable()) {
+      return;
+    }
+
+    this.unhighlight();
+
+    let rect = this.node.getBoundingClientRect();
+
+    if (scroll) {
+      this.node.scrollIntoView();
+    }
+
+    if (this.viewContainsRect(rect)) {
+      // TODO check for offscreen boundaries, bug565301
+      this.panel.openPopup(this.node, "overlap", 0, 0, false, false);
+      this.panel.sizeTo(rect.width, rect.height);
+    } else {
+      this.highlightVisibleRegion(rect);
+    }
+  },
+
+  /**
+   * Highlight the given node.
+   *
+   * @param element
+   *        a DOM element to be highlighted
+   * @param params
+   *        extra parameters object
+   */
+  highlightNode: function PanelHighlighter_highlightNode(element, params)
+  {
+    this.node = element;
+    this.highlight(params && params.scroll);
+  },
+
+  /**
+   * Highlight the visible region of the region described by aRect, if any.
+   *
+   * @param aRect
+   * @returns boolean
+   *          was a region highlighted?
+   */
+  highlightVisibleRegion: function PanelHighlighter_highlightVisibleRegion(aRect)
+  {
+    let offsetX = 0;
+    let offsetY = 0;
+    let width = 0;
+    let height = 0;
+    let visibleWidth = this.win.innerWidth;
+    let visibleHeight = this.win.innerHeight;
+
+    // If any of these edges are out-of-bounds, the node's rectangle is
+    // completely out-of-view and we can return.
+    if (aRect.top > visibleHeight || aRect.left > visibleWidth ||
+        aRect.bottom < 0 || aRect.right < 0) {
+      return false;
+    }
+
+    // Calculate node offsets, if values are negative, then start the offsets
+    // at their absolute values from node origin. The delta should be the edge
+    // of view.
+    offsetX = aRect.left < 0 ? Math.abs(aRect.left) : 0;
+    offsetY = aRect.top < 0 ? Math.abs(aRect.top) : 0;
+
+    // Calculate actual node width, taking into account the available visible
+    // width and then subtracting the offset for the final dimension.
+    width = aRect.right > visibleWidth ? visibleWidth - aRect.left :
+      aRect.width;
+    width -= offsetX;
+
+    // Calculate actual node height using the same formula as above for width.
+    height = aRect.bottom > visibleHeight ? visibleHeight - aRect.top :
+      aRect.height;
+    height -= offsetY;
+
+    // If width and height are non-negative, open the highlighter popup over the
+    // node and sizeTo width and height.
+    if (width > 0 && height > 0) {
+      this.panel.openPopup(this.node, "overlap", offsetX, offsetY, false,
+        false);
+      this.panel.sizeTo(width, height);
+      return true;
+    }
+
+    return false;
+  },
+
+  /**
+   * Close the highlighter panel.
+   */
+  unhighlight: function PanelHighlighter_unhighlight()
+  {
+    if (this.isHighlighting) {
+      this.panel.hidePopup();
+    }
+  },
+
+  /**
+   * Is the highlighter panel open?
+   *
+   * @returns boolean
+   */
+  get isHighlighting()
+  {
+    return this.panel.state == "open";
+  },
+
+  /**
+   * Return the midpoint of a line from pointA to pointB.
+   *
+   * @param pointA
+   *        An object with x and y properties.
+   * @param pointB
+   *        An object with x and y properties.
+   * @returns aPoint
+   *          An object with x and y properties.
+   */
+  midPoint: function PanelHighlighter_midPoint(pointA, pointB)
+  {
+    let pointC = { };
+    pointC.x = (pointB.x - pointA.x) / 2 + pointA.x;
+    pointC.y = (pointB.y - pointA.y) / 2 + pointA.y;
+    return pointC;
+  },
+
+  /**
+   * Return the node under the highlighter rectangle. Useful for testing.
+   * Calculation based on midpoint of diagonal from top left to bottom right
+   * of panel.
+   *
+   * @returns a DOM node or null if none
+   */
+  get highlitNode()
+  {
+    // No highlighter panel? Bail.
+    if (!this.isHighlighting) {
+      return null;
+    }
+
+    let browserRect = this.browser.getBoundingClientRect();
+    let clientRect = this.panel.getBoundingClientRect();
+
+    // Calculate top left point offset minus browser chrome.
+    let a = {
+      x: clientRect.left - browserRect.left,
+      y: clientRect.top - browserRect.top
+    };
+
+    // Calculate bottom right point minus browser chrome.
+    let b = {
+      x: clientRect.right - browserRect.left,
+      y: clientRect.bottom - browserRect.top
+    };
+
+    // Get midpoint of diagonal line.
+    let midpoint = this.midPoint(a, b);
+
+    return this.win.document.elementFromPoint(midpoint.x, midpoint.y);
+  },
+
+  /**
+   * Is this.node highlightable?
+   *
+   * @returns boolean
+   */
+  isNodeHighlightable: function PanelHighlighter_isNodeHighlightable()
+  {
+    if (!this.node) {
+      return false;
+    }
+    let nodeName = this.node.nodeName.toLowerCase();
+    if (nodeName[0] == '#') {
+      return false;
+    }
+    return !INSPECTOR_INVISIBLE_ELEMENTS[nodeName];
+  },
+
+  /**
+   * Returns true if the given viewport-relative rect is within the visible area
+   * of the window.
+   *
+   * @param aRect
+   *        a CSS rectangle object
+   * @returns boolean
+   */
+  viewContainsRect: function PanelHighlighter_viewContainsRect(aRect)
+  {
+    let visibleWidth = this.win.innerWidth;
+    let visibleHeight = this.win.innerHeight;
+
+    return ((0 <= aRect.left) && (aRect.right <= visibleWidth) && 
+        (0 <= aRect.top) && (aRect.bottom <= visibleHeight))
+  },
+
+  /////////////////////////////////////////////////////////////////////////
+  //// Event Handling
+
+  /**
+   * Handle mousemoves in panel when InspectorUI.inspecting is true.
+   *
+   * @param event
+   *        The MouseEvent triggering the method.
+   */
+  handleMouseMove: function PanelHighlighter_handleMouseMove(event)
+  {
+    if (!InspectorUI.inspecting) {
+      return;
+    }
+    let browserRect = this.browser.getBoundingClientRect();
+    let element = this.win.document.elementFromPoint(event.clientX -
+      browserRect.left, event.clientY - browserRect.top);
+    if (element && element != this.node) {
+      InspectorUI.inspectNode(element);
+    }
+  },
+};
+
+///////////////////////////////////////////////////////////////////////////
+//// InspectorTreeView
+
+/**
+ * TreeView object to manage the view of the DOM tree. Wraps and provides an
+ * interface to an inIDOMView object
+ *
+ * @param aWindow
+ *        a top-level window object
+ */
+function InspectorTreeView(aWindow)
+{
+  this.tree = document.getElementById("inspector-tree");
+  this.treeBody = document.getElementById("inspector-tree-body");
+  this.view = Cc["@mozilla.org/inspector/dom-view;1"]
+              .createInstance(Ci.inIDOMView);
+  this.view.showSubDocuments = true;
+  this.view.whatToShow = NodeFilter.SHOW_ALL;
+  this.tree.view = this.view;
+  this.contentWindow = aWindow;
+  this.view.rootNode = aWindow.document;
+  this.view.rebuild();
+}
+
+InspectorTreeView.prototype = {
+  get editable() { return false; },
+  get selection() { return this.view.selection; },
+
+  /**
+   * Destroy the view.
+   */
+  destroy: function ITV_destroy()
+  {
+    this.tree.view = null;
+    this.view = null;
+    this.tree = null;
+  },
+
+  /**
+   * Get the cell text at a given row and column.
+   *
+   * @param aRow
+   *        The row index of the desired cell.
+   * @param aCol
+   *        The column index of the desired cell.
+   * @returns string
+   */
+  getCellText: function ITV_getCellText(aRow, aCol)
+  {
+    return this.view.getCellText(aRow, aCol);
+  },
+
+  /**
+   * Get the index of the selected row.
+   *
+   * @returns number
+   */
+  get selectionIndex()
+  {
+    return this.selection.currentIndex;
+  },
+
+  /**
+   * Get the corresponding node for the currently-selected row in the tree.
+   *
+   * @returns DOMNode
+   */
+  get selectedNode()
+  {
+    let rowIndex = this.selectionIndex;
+    return this.view.getNodeFromRowIndex(rowIndex);
+  },
+
+  /**
+   * Set the selected row in the table to the specified index.
+   *
+   * @param anIndex
+   *        The index to set the selection to.
+   */
+  set selectedRow(anIndex)
+  {
+    this.view.selection.select(anIndex);
+    this.tree.treeBoxObject.ensureRowIsVisible(anIndex);
+  },
+
+  /**
+   * Set the selected node to the specified document node.
+   *
+   * @param aNode
+   *        The document node to select in the tree.
+   */
+  set selectedNode(aNode)
+  {
+    let rowIndex = this.view.getRowIndexFromNode(aNode);
+    if (rowIndex > -1) {
+      this.selectedRow = rowIndex;
+    } else {
+      this.selectElementInTree(aNode);
+    }
+  },
+
+  /**
+   * Select the given node in the tree, searching for and expanding rows
+   * as-needed.
+   *
+   * @param aNode
+   *        The document node to select in the three.
+   * @returns boolean
+   *          Whether a node was selected or not if not found.
+   */
+  selectElementInTree: function ITV_selectElementInTree(aNode)
+  {
+    if (!aNode) {
+      this.view.selection.select(null);
+      return false;      
+    }
+
+    // Keep searching until a pre-created ancestor is found, then 
+    // open each ancestor until the found element is created.
+    let domUtils = Cc["@mozilla.org/inspector/dom-utils;1"].
+                    getService(Ci.inIDOMUtils);
+    let line = [];
+    let parent = aNode;
+    let index = null;
+
+    while (parent) {
+      index = this.view.getRowIndexFromNode(parent);
+      line.push(parent);
+      if (index < 0) {
+        // Row for this node hasn't been created yet.
+        parent = domUtils.getParentForNode(parent,
+          this.view.showAnonymousContent);
+      } else {
+        break;
+      }
+    }
+
+    // We have all the ancestors, now open them one-by-one from the top
+    // to bottom.
+    let lastIndex;
+    let view = this.tree.treeBoxObject.view;
+
+    for (let i = line.length - 1; i >= 0; i--) {
+      index = this.view.getRowIndexFromNode(line[i]);
+      if (index < 0) {
+        // Can't find the row, so stop trying to descend.
+        break;
+      }
+      if (i > 0 && !view.isContainerOpen(index)) {
+        view.toggleOpenState(index);
+      }
+      lastIndex = index;
+    }
+
+    if (lastIndex >= 0) {
+      this.selectedRow = lastIndex;
+      return true;
+    }
+    
+    return false;
+  },
+};
+
+///////////////////////////////////////////////////////////////////////////
+//// InspectorUI
+
+/**
+ * Main controller class for the Inspector.
+ */
+var InspectorUI = {
+  browser: null,
+  _showTreePanel: true,
+  _showStylePanel: false,
+  _showDOMPanel: false,
+  highlightColor: "#EEEE66",
+  highlightThickness: 4,
+  highlightOpacity: 0.4,
+  selectEventsSuppressed: false,
+  inspecting: false,
+
+  /**
+   * Toggle the inspector interface elements on or off.
+   *
+   * @param event
+   *        The event that requested the UI change. Toolbar button or menu.
+   */
+  toggleInspectorUI: function InspectorUI_toggleInspectorUI()
+  {
+    let toolsInspectCmd = document.getElementById("Tools:Inspect");
+    if (this.isPanelOpen) {
+      this.closeInspectorUI();
+      toolsInspectCmd.setAttribute("checked", "false");
+    } else {
+      this.openInspectorUI();
+      toolsInspectCmd.setAttribute("checked", "true");
+    }
+  },
+
+  /**
+   * Is the tree panel open?
+   *
+   * @returns boolean
+   */
+  get isPanelOpen()
+  {
+    return this.treePanel && this.treePanel.state == "open";
+  },
+
+  /**
+   * Open the inspector's tree panel and initialize it.
+   */
+  openTreePanel: function InspectorUI_openTreePanel()
+  {
+    if (!this.treePanel) {
+      this.treePanel = document.getElementById("inspector-panel");
+      this.treePanel.hidden = false;
+    }
+    if (!this.isPanelOpen) {
+      const panelWidthRatio = 7 / 8;
+      const panelHeightRatio = 1 / 5;
+      let bar = document.getElementById("status-bar");
+      this.treePanel.openPopup(bar, "overlap", 120, -120, false, false);
+      this.treePanel.sizeTo(this.win.outerWidth * panelWidthRatio, 
+        this.win.outerHeight * panelHeightRatio);
+      this.tree = document.getElementById("inspector-tree");
+      this.createDocumentModel();
+    }
+  },
+
+  openStylePanel: function InspectorUI_openStylePanel()
+  {
+    // # todo
+  },
+
+  openDOMPanel: function InspectorUI_openDOMPanel()
+  {
+    // # todo
+  },
+
+  /**
+   * Open inspector UI. tree, style and DOM panels if enabled. Add listeners for
+   * document scrolling and tabContainer.TabSelect.
+   */
+  openInspectorUI: function InspectorUI_openInspectorUI()
+  {
+    // initialization
+    this.browser = gBrowser.selectedBrowser;
+    this.win = this.browser.contentWindow;
+
+    // open inspector UI
+    if (this._showTreePanel) {
+      this.openTreePanel();
+    }
+    if (this._showStylePanel) {
+      this.openStylePanel();
+    }
+    if (this._showDOMPanel) {
+      this.openDOMPanel();
+    }
+    this.initializeHighlighter();
+    this.startInspecting();
+    this.win.document.addEventListener("scroll", this, false);
+    gBrowser.tabContainer.addEventListener("TabSelect", this, false);
+  },
+
+  /**
+   * Initialize highlighter.
+   */
+  initializeHighlighter: function InspectorUI_initializeHighlighter()
+  {
+    this.highlighter = new PanelHighlighter(this.browser, this.highlightColor,
+      this.highlightThickness, this.highlightOpacity);
+  },
+
+  /**
+   * Close inspector UI and associated panels. Unhighlight and stop inspecting.
+   * Remove event listeners for document scrolling and
+   * tabContainer.TabSelect.
+   */
+  closeInspectorUI: function InspectorUI_closeInspectorUI()
+  {
+    this.win.document.removeEventListener("scroll", this, false);
+    gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
+    this.stopInspecting();
+    if (this.highlighter && this.highlighter.isHighlighting) {
+      this.highlighter.unhighlight();
+    }
+    if (this.isPanelOpen) {
+      this.treePanel.hidePopup();
+      this.treeView.destroy();
+    }
+    this.browser = this.win = null; // null out references to browser and window
+  },
+
+  /**
+   * Begin inspecting webpage, attach page event listeners, activate
+   * highlighter event listeners.
+   */
+  startInspecting: function InspectorUI_startInspecting()
+  {
+    this.attachPageListeners();
+    this.inspecting = true;
+  },
+
+  /**
+   * Stop inspecting webpage, detach page listeners, disable highlighter
+   * event listeners.
+   */
+  stopInspecting: function InspectorUI_stopInspecting()
+  {
+    if (!this.inspecting)
+      return;
+    this.detachPageListeners();
+    this.inspecting = false;
+  },
+
+  /////////////////////////////////////////////////////////////////////////
+  //// Model Creation Methods
+
+  /**
+   * Create treeView object from content window.
+   */
+  createDocumentModel: function InspectorUI_createDocumentModel()
+  {
+    this.treeView = new InspectorTreeView(this.win);
+  },
+
+  /////////////////////////////////////////////////////////////////////////
+  //// Event Handling
+
+  /**
+   * Main callback handler for events.
+   *
+   * @param event
+   *        The event to be handled.
+   */
+  handleEvent: function InspectorUI_handleEvent(event)
+  {
+    switch (event.type) {
+      case "TabSelect":
+        this.closeInspectorUI();
+        break;
+      case "keypress":
+        switch (event.keyCode) {
+          case KeyEvent.DOM_VK_RETURN:
+          case KeyEvent.DOM_VK_ESCAPE:
+            this.stopInspecting();
+            break;
+        }
+        break;
+      case "mousemove":
+        let element = this.win.document.elementFromPoint(event.clientX,
+          event.clientY);
+        if (element && element != this.node) {
+          this.inspectNode(element);
+        }
+        break;
+      case "click":
+        this.stopInspecting();
+        break;
+      case "scroll":
+        this.highlighter.highlight();
+        break;
+    }
+  },
+
+  /**
+   * Event fired when a tree row is selected in the tree panel.
+   */
+  onTreeSelected: function InspectorUI_onTreeSelected()
+  {
+    if (this.selectEventsSuppressed) {
+      return false;
+    }
+
+    let treeView = this.treeView;
+    let node = treeView.selectedNode;
+    this.highlighter.highlightNode(node); // # todo scrolling causes issues
+    this.stopInspecting();
+    return true;
+  },
+
+  /**
+   * Attach event listeners to content window and child windows to enable 
+   * highlighting and click to stop inspection.
+   */
+  attachPageListeners: function InspectorUI_attachPageListeners()
+  {
+    this.win.addEventListener("keypress", this, true);
+    this.browser.addEventListener("mousemove", this, true);
+    this.browser.addEventListener("click", this, true);
+  },
+
+  /**
+   * Detach event listeners from content window and child windows
+   * to disable highlighting.
+   */
+  detachPageListeners: function InspectorUI_detachPageListeners()
+  {
+    this.win.removeEventListener("keypress", this, true);
+    this.browser.removeEventListener("mousemove", this, true);
+    this.browser.removeEventListener("click", this, true);
+  },
+
+  /////////////////////////////////////////////////////////////////////////
+  //// Utility Methods
+
+  /**
+   * inspect the given node, highlighting it on the page and selecting the
+   * correct row in the tree panel
+   *
+   * @param element
+   *        the element in the document to inspect
+   */
+  inspectNode: function InspectorUI_inspectNode(element)
+  {
+    this.highlighter.highlightNode(element);
+    this.selectEventsSuppressed = true;
+    this.treeView.selectedNode = element;
+    this.selectEventsSuppressed = false;
+  },
+
+  ///////////////////////////////////////////////////////////////////////////
+  //// Utility functions
+
+  /**
+   * debug logging facility
+   * @param msg
+   *        text message to send to the log
+   */
+  _log: function LOG(msg)
+  {
+    Services.console.logStringMessage(msg);
+  },
+}
+
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -1326,28 +1326,27 @@ nsContextMenu.prototype = {
            "contextMenu.inFrame    = " + this.inFrame + "\n" +
            "contextMenu.hasBGImage = " + this.hasBGImage + "\n";
   },
 
   // Returns true if aNode is a from control (except text boxes and images).
   // This is used to disable the context menu for form controls.
   isTargetAFormControl: function(aNode) {
     if (aNode instanceof HTMLInputElement)
-      return (aNode.type != "text" && aNode.type != "password" &&
-              aNode.type != "image");
+      return (!aNode.mozIsTextField(false) && aNode.type != "image");
 
     return (aNode instanceof HTMLButtonElement) ||
            (aNode instanceof HTMLSelectElement) ||
            (aNode instanceof HTMLOptionElement) ||
            (aNode instanceof HTMLOptGroupElement);
   },
 
   isTargetATextBox: function(node) {
     if (node instanceof HTMLInputElement)
-      return (node.type == "text" || node.type == "password")
+      return node.mozIsTextField(false);
 
     return (node instanceof HTMLTextAreaElement);
   },
 
   isTargetAKeywordField: function(aNode) {
     if (!(aNode instanceof HTMLInputElement))
       return false;
 
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2165,75 +2165,43 @@
       <method name="_handleKeyEvent">
         <parameter name="aEvent"/>
         <body><![CDATA[
           if (!aEvent.isTrusted) {
             // Don't let untrusted events mess with tabs.
             return;
           }
 
-          if ('altKey' in aEvent && aEvent.altKey)
+          if (aEvent.altKey)
             return;
+
 #ifdef XP_MACOSX
-          if ('metaKey' in aEvent && aEvent.metaKey) {
-            var offset = 1;
-            switch (aEvent.charCode) {
-              case '}'.charCodeAt(0):
+          if (!aEvent.metaKey)
+            return;
+
+          var offset = 1;
+          switch (aEvent.charCode) {
+            case '}'.charCodeAt(0):
+              offset = -1;
+            case '{'.charCodeAt(0):
+              if (window.getComputedStyle(this, null).direction == "ltr")
                 offset *= -1;
-              case '{'.charCodeAt(0):
-                if (window.getComputedStyle(this, null).direction == "ltr")
-                  offset *= -1;
-
-                this.tabContainer.advanceSelectedTab(offset, true);
-                aEvent.stopPropagation();
-                aEvent.preventDefault();
-                return;
-            }
-            if ('shiftKey' in aEvent && aEvent.shiftKey)
-              return;
-#else
-          if (('ctrlKey' in aEvent && aEvent.ctrlKey) &&
-              !('shiftKey' in aEvent && aEvent.shiftKey) &&
-              !('metaKey' in aEvent && aEvent.metaKey)) {
-            if (aEvent.keyCode == KeyEvent.DOM_VK_F4 &&
-                this.mTabBox.handleCtrlPageUpDown) {
-              this.removeCurrentTab();
-
+              this.tabContainer.advanceSelectedTab(offset, true);
               aEvent.stopPropagation();
               aEvent.preventDefault();
-              return;
-            }
+          }
+#else
+          if (aEvent.ctrlKey && !aEvent.shiftKey && !aEvent.metaKey &&
+              aEvent.keyCode == KeyEvent.DOM_VK_F4 &&
+              this.mTabBox.handleCtrlPageUpDown) {
+            this.removeCurrentTab();
+            aEvent.stopPropagation();
+            aEvent.preventDefault();
+          }
 #endif
-            if (aEvent.target.parentNode == this.tabContainer) {
-              switch (aEvent.keyCode) {
-                case KeyEvent.DOM_VK_UP:
-                  this.moveTabBackward();
-                  break;
-                case KeyEvent.DOM_VK_DOWN:
-                  this.moveTabForward();
-                  break;
-                case KeyEvent.DOM_VK_RIGHT:
-                case KeyEvent.DOM_VK_LEFT:
-                  this.moveTabOver(aEvent);
-                  break;
-                case KeyEvent.DOM_VK_HOME:
-                  this.moveTabToStart();
-                  break;
-                case KeyEvent.DOM_VK_END:
-                  this.moveTabToEnd();
-                  break;
-                default:
-                  // Stop the keypress event for the above keyboard
-                  // shortcuts only.
-                  return;
-              }
-              aEvent.stopPropagation();
-              aEvent.preventDefault();
-            }
-          }
         ]]></body>
       </method>
 
       <property name="userTypedClear"
                 onget="return this.mCurrentBrowser.userTypedClear;"
                 onset="return this.mCurrentBrowser.userTypedClear = val;"/>
 
       <property name="userTypedValue"
@@ -2786,16 +2754,51 @@
 
         if (this.childNodes.length > 1 ||
             !this._closeWindowWithLastTab)
           this.tabbrowser.removeTab(event.target);
 
         event.stopPropagation();
       ]]></handler>
 
+      <handler event="keypress"><![CDATA[
+        if (event.altKey || event.shiftKey ||
+#ifdef XP_MACOSX
+            !event.metaKey)
+#else
+            !event.ctrlKey || event.metaKey)
+#endif
+          return;
+
+        switch (event.keyCode) {
+          case KeyEvent.DOM_VK_UP:
+            this.tabbrowser.moveTabBackward();
+            break;
+          case KeyEvent.DOM_VK_DOWN:
+            this.tabbrowser.moveTabForward();
+            break;
+          case KeyEvent.DOM_VK_RIGHT:
+          case KeyEvent.DOM_VK_LEFT:
+            this.tabbrowser.moveTabOver(event);
+            break;
+          case KeyEvent.DOM_VK_HOME:
+            this.tabbrowser.moveTabToStart();
+            break;
+          case KeyEvent.DOM_VK_END:
+            this.tabbrowser.moveTabToEnd();
+            break;
+          default:
+            // Stop the keypress event for the above keyboard
+            // shortcuts only.
+            return;
+        }
+        event.stopPropagation();
+        event.preventDefault();
+      ]]></handler>
+
       <handler event="dragstart"><![CDATA[
         var tab = this._getDragTargetTab(event);
         if (!tab)
           return;
 
         let dt = event.dataTransfer;
         dt.mozSetDataAt(TAB_DROP_TYPE, tab, 0);
         let uri = this.tabbrowser.getBrowserForTab(tab).currentURI;
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -120,16 +120,19 @@ include $(topsrcdir)/config/rules.mk
                  browser_bug550565.js \
                  browser_bug555224.js \
                  browser_contextSearchTabPosition.js \
                  browser_ctrlTab.js \
                  browser_discovery.js \
                  browser_drag.js \
                  browser_gestureSupport.js \
                  browser_getshortcutoruri.js \
+                 browser_inspector_initialization.js \
+                 browser_inspector_treeSelection.js \
+                 browser_inspector_highlighter.js \
                  browser_overflowScroll.js \
                  browser_pageInfo.js \
                  browser_page_style_menu.js \
                  browser_plainTextLinks.js \
                  browser_pluginnotification.js \
                  browser_popupUI.js \
                  browser_relatedTabs.js \
                  browser_sanitize-passwordDisabledHosts.js \
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_inspector_highlighter.js
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * 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 Inspector Highlighter Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Rob Campbell <rcampbell@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * 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 ***** */
+
+let doc;
+let h1;
+
+function createDocument()
+{
+  let div = doc.createElement("div");
+  let h1 = doc.createElement("h1");
+  let p1 = doc.createElement("p");
+  let p2 = doc.createElement("p");
+  let div2 = doc.createElement("div");
+  let p3 = doc.createElement("p");
+  doc.title = "Inspector Tree Selection Test";
+  h1.textContent = "Inspector Tree Selection Test";
+  p1.textContent = "This is some example text";
+  p2.textContent = "Lorem ipsum dolor sit amet, consectetur adipisicing " +
+    "elit, sed do eiusmod tempor incididunt ut labore et dolore magna " +
+    "aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " +
+    "laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
+    "dolor in reprehenderit in voluptate velit esse cillum dolore eu " +
+    "fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " +
+    "proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
+  p3.textContent = "Lorem ipsum dolor sit amet, consectetur adipisicing " +
+    "elit, sed do eiusmod tempor incididunt ut labore et dolore magna " +
+    "aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " +
+    "laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
+    "dolor in reprehenderit in voluptate velit esse cillum dolore eu " +
+    "fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " +
+    "proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
+  div.appendChild(h1);
+  div.appendChild(p1);
+  div.appendChild(p2);
+  div2.appendChild(p3);
+  doc.body.appendChild(div);
+  doc.body.appendChild(div2);
+  setupHighlighterTests();
+}
+
+function setupHighlighterTests()
+{
+  h1 = doc.querySelectorAll("h1")[0];
+  ok(h1, "we have the header node");
+  document.addEventListener("popupshown", runSelectionTests, false);
+  InspectorUI.toggleInspectorUI();
+}
+
+function runSelectionTests(evt)
+{
+  if (evt.target.id != "inspector-panel")
+    return true;
+  document.removeEventListener("popupshown", runSelectionTests, false);
+  document.addEventListener("popupshown", performTestComparisons, false);
+  EventUtils.synthesizeMouse(h1, 2, 2, {type: "mousemove"}, content);
+}
+
+function performTestComparisons(evt)
+{
+  if (evt.target.id != "highlighter-panel")
+    return true;
+  document.removeEventListener("popupshown", performTestComparisons, false);
+  is(h1, InspectorUI.treeView.selectedNode, "selection matches node");
+  ok(InspectorUI.highlighter.isHighlighting, "panel is highlighting");
+  is(InspectorUI.highlighter.highlitNode, h1, "highlighter matches selection");
+  executeSoon(finishUp);
+}
+
+function finishUp() {
+  InspectorUI.closeInspectorUI();
+  gBrowser.removeCurrentTab();
+  finish();
+}
+
+function test()
+{
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function() {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+    doc = content.document;
+    waitForFocus(createDocument, content);
+  }, true);
+  
+  content.location = "data:text/html,basic tests for inspector";
+}
+
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_inspector_initialization.js
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * 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 Inspector Initializationa and Shutdown Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Rob Campbell <rcampbell@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * 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 ***** */
+
+let doc;
+
+function startInspectorTests()
+{
+  ok(InspectorUI, "InspectorUI variable exists");
+  document.addEventListener("popupshown", runInspectorTests, false);
+  InspectorUI.toggleInspectorUI();
+}
+
+function runInspectorTests(evt)
+{
+  if (evt.target.id != "inspector-panel")
+    return true;
+  document.removeEventListener("popupshown", runInspectorTests, false);
+  document.addEventListener("popuphidden", finishInspectorTests, false);
+  ok(InspectorUI.inspecting, "Inspector is highlighting");
+  ok(InspectorUI.isPanelOpen, "Inspector Tree Panel is open");
+  todo(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
+  todo(InspectorUI.isDOMPanelOpen, "Inspector DOM Panel is open");
+  InspectorUI.toggleInspectorUI();
+}
+
+function finishInspectorTests(evt)
+{
+  if (evt.target.id != "inspector-panel")
+    return true;
+  document.removeEventListener("popuphidden", finishInspectorTests, false);
+  ok(!InspectorUI.isDOMPanelOpen, "Inspector DOM Panel is closed");
+  ok(!InspectorUI.isStylePanelOpen, "Inspector Style Panel is closed");
+  ok(!InspectorUI.isPanelOpen, "Inspector Tree Panel is closed");
+  ok(!InspectorUI.inspecting, "Inspector is not highlighting");
+  gBrowser.removeCurrentTab();
+  finish();
+}
+
+function test()
+{
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function() {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+    doc = content.document;
+    waitForFocus(startInspectorTests, content);
+  }, true);
+  
+  content.location = "data:text/html,basic tests for inspector";
+}
+
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_inspector_treeSelection.js
@@ -0,0 +1,114 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * 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 Inspector Tree Selection Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Rob Campbell <rcampbell@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * 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 ***** */
+
+let doc;
+let h1;
+
+function createDocument()
+{
+  let div = doc.createElement("div");
+  let h1 = doc.createElement("h1");
+  let p1 = doc.createElement("p");
+  let p2 = doc.createElement("p");
+  doc.title = "Inspector Tree Selection Test";
+  h1.textContent = "Inspector Tree Selection Test";
+  p1.textContent = "This is some example text";
+  p2.textContent = "Lorem ipsum dolor sit amet, consectetur adipisicing " +
+    "elit, sed do eiusmod tempor incididunt ut labore et dolore magna " +
+    "aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " +
+    "laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
+    "dolor in reprehenderit in voluptate velit esse cillum dolore eu " +
+    "fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " +
+    "proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
+  div.appendChild(h1);
+  div.appendChild(p1);
+  div.appendChild(p2);
+  // doc.body.addEventListener("DOMSubtreeModified", , false);
+  doc.body.appendChild(div);
+  setupSelectionTests();
+}
+
+function setupSelectionTests()
+{
+  h1 = doc.querySelectorAll("h1")[0];
+  ok(h1, "we have the header node");
+  document.addEventListener("popupshown", runSelectionTests, false);
+  InspectorUI.openInspectorUI();
+}
+
+function runSelectionTests(evt)
+{
+  if (evt.target.id != "inspector-panel")
+    return true;
+  document.removeEventListener("popupshown", runSelectionTests, false);
+  InspectorUI.stopInspecting();
+  document.addEventListener("popupshown", performTestComparisons, false);
+  InspectorUI.treeView.selectedNode = h1;
+}
+
+function performTestComparisons(evt)
+{
+  if (evt.target.id != "highlighter-panel")
+    return true;
+  document.removeEventListener("popupshown", performTestComparisons, false);
+  is(h1, InspectorUI.treeView.selectedNode, "selection matches node");
+  ok(InspectorUI.highlighter.isHighlighting, "panel is highlighting");
+  is(h1, InspectorUI.highlighter.highlitNode, "highlighter highlighting correct node");
+  finishUp();
+}
+
+function finishUp() {
+  InspectorUI.closeInspectorUI();
+  gBrowser.removeCurrentTab();
+  finish();
+}
+
+function test()
+{
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function() {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+    doc = content.document;
+    waitForFocus(createDocument, content);
+  }, true);
+  
+  content.location = "data:text/html,basic tests for inspector";
+}
+
--- a/browser/components/feeds/src/FeedConverter.js
+++ b/browser/components/feeds/src/FeedConverter.js
@@ -211,17 +211,17 @@ FeedConverter.prototype = {
     // that all other applications will auto-load with that handler too, 
     // regardless of the content-type. 
     //
     // This means that content-type alone is not enough to determine whether
     // or not a feed should be auto-handled. This means that for feeds we need
     // to always use this stream converter, even when an auto-action is 
     // specified, not the basic one provided by WebContentConverter. This 
     // converter needs to consume all of the data and parse it, and based on
-    // that determination make a judgement about type. 
+    // that determination make a judgment about type. 
     //
     // Since there are no content types for this content, and I'm not going to
     // invent any, the upshot is that while a user can set an auto-handler for
     // generic feed content, the system will prevent them from setting an auto-
     // handler for other stream types. In those cases, the user will always see
     // the preview page and have to select a handler. We can guess and show 
     // a client handler, but will not be able to show web handlers for those
     // types.
--- a/browser/components/places/tests/browser/browser_library_infoBox.js
+++ b/browser/components/places/tests/browser/browser_library_infoBox.js
@@ -147,17 +147,16 @@ gTests.push({
     menuNode.containerOpen = false;
 
     bhist.removeAllPages();
     nextTest();
   }
 });
 
 function checkInfoBoxSelected(PO) {
-  PO._places.focus();
   is(getAndCheckElmtById("detailsDeck").selectedIndex, 1,
      "Selected element in detailsDeck is infoBox.");
 }
 
 function checkAddInfoFieldsCollapsed(PO) {
   PO._additionalInfoFields.forEach(function (id) {
     ok(getAndCheckElmtById(id).collapsed,
        "Additional info field correctly collapsed: #" + id);
@@ -221,17 +220,20 @@ var ww = Cc["@mozilla.org/embedcomp/wind
 
 function windowObserver(aSubject, aTopic, aData) {
   if (aTopic != "domwindowopened")
     return;
   ww.unregisterNotification(windowObserver);
   gLibrary = aSubject.QueryInterface(Ci.nsIDOMWindow);
   gLibrary.addEventListener("load", function onLoad(event) {
     gLibrary.removeEventListener("load", onLoad, false);
-    executeSoon(nextTest);
+    executeSoon(function() {
+      gLibrary.PlacesOrganizer._places.focus();
+      waitForFocus(nextTest, gLibrary);
+    });
   }, false);
 }
 
 function test() {
   dump("Starting test browser_library_infoBox.js\n");
   waitForExplicitFinish();
   // Sanity checks.
   ok(PlacesUtils, "PlacesUtils is running in chrome context");
--- a/browser/components/places/tests/browser/browser_library_panel_leak.js
+++ b/browser/components/places/tests/browser/browser_library_panel_leak.js
@@ -60,16 +60,23 @@ function windowObserver(aSubject, aTopic
   let organizer = aSubject.QueryInterface(Ci.nsIDOMWindow);
   organizer.addEventListener("load", function onLoad(event) {
     organizer.removeEventListener("load", onLoad, false);
     executeSoon(function () {
       let contentTree = organizer.document.getElementById("placeContent");
       isnot(contentTree, null, "Sanity check: placeContent tree should exist");
       isnot(organizer.PlacesOrganizer, null, "Sanity check: PlacesOrganizer should exist");
       isnot(organizer.gEditItemOverlay, null, "Sanity check: gEditItemOverlay should exist");
+
+      if (!organizer.gEditItemOverlay._initialized){
+        // The overlay is initialized on focus, we wait for it to be fully operational.
+        setTimeout(arguments.callee, 10);
+        return;
+      }
+
       isnot(organizer.gEditItemOverlay.itemId, -1, "Editing a bookmark");
       // Select History in the left pane.
       organizer.PlacesOrganizer.selectLeftPaneQuery('History');
       // Select the first history entry.
       let selection = contentTree.view.selection;
       selection.clearSelection();
       selection.rangedSelect(0, 0, true);
       // Check the panel is editing the history entry.
--- a/browser/components/sessionstore/content/aboutSessionRestore.js
+++ b/browser/components/sessionstore/content/aboutSessionRestore.js
@@ -155,19 +155,24 @@ function startNewSession() {
 function onListClick(aEvent) {
   // don't react to right-clicks
   if (aEvent.button == 2)
     return;
   
   var row = {}, col = {};
   treeView.treeBox.getCellAt(aEvent.clientX, aEvent.clientY, row, col, {});
   if (col.value) {
-    // restore this specific tab in the same window for double clicking or middle clicking
-    // or Ctrl+clicking on a tab's title - note: ctrl clicking doesn't work on Mac
-    if ((aEvent.button == 1 || aEvent.button == 0 && aEvent.detail == 2 || aEvent.ctrlKey) &&
+    // Restore this specific tab in the same window for middle/double/accel clicking
+    // on a tab's title.
+#ifdef XP_MACOSX
+    let accelKey = aEvent.metaKey;
+#else
+    let accelKey = aEvent.ctrlKey;
+#endif
+    if ((aEvent.button == 1 || aEvent.button == 0 && aEvent.detail == 2 || accelKey) &&
         col.value.id == "title" &&
         !treeView.isContainer(row.value))
       restoreSingleTab(row.value, aEvent.shiftKey);
     else if (col.value.id == "restore")
       toggleRowChecked(row.value);
   }
 }
 
--- a/browser/components/sessionstore/content/aboutSessionRestore.xhtml
+++ b/browser/components/sessionstore/content/aboutSessionRestore.xhtml
@@ -49,17 +49,17 @@
 
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <title>&restorepage.tabtitle;</title>
     <link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all"/>
     <link rel="stylesheet" href="chrome://browser/skin/aboutSessionRestore.css" type="text/css" media="all"/>
     <link rel="icon" type="image/png" href="chrome://global/skin/icons/warning-16.png"/>
 
-    <script type="application/javascript" src="chrome://browser/content/aboutSessionRestore.js"/>
+    <script type="application/javascript;version=1.8" src="chrome://browser/content/aboutSessionRestore.js"/>
   </head>
 
   <body dir="&locale.dir;">
 
     <!-- PAGE CONTAINER (for styling purposes only) -->
     <div id="errorPageContainer">
     
       <!-- Error Title -->
--- a/browser/components/sessionstore/jar.mn
+++ b/browser/components/sessionstore/jar.mn
@@ -1,3 +1,3 @@
 browser.jar:
 *   content/browser/aboutSessionRestore.xhtml             (content/aboutSessionRestore.xhtml) 
-    content/browser/aboutSessionRestore.js                (content/aboutSessionRestore.js)
+*   content/browser/aboutSessionRestore.js                (content/aboutSessionRestore.js)
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -154,16 +154,20 @@
 <!ENTITY downloadsUnix.commandkey     "y">
 <!ENTITY addons.label                 "Add-ons">
 <!ENTITY addons.accesskey             "A">
 
 <!ENTITY errorConsoleCmd.label        "Error Console">
 <!ENTITY errorConsoleCmd.accesskey    "C">
 <!ENTITY errorConsoleCmd.commandkey   "j">
 
+<!ENTITY inspectMenu.label            "Inspect">
+<!ENTITY inspectMenu.accesskey        "I">
+<!ENTITY inspectMenu.commandkey       "I">
+
 <!ENTITY fileMenu.label         "File"> 
 <!ENTITY fileMenu.accesskey       "F">
 <!ENTITY newNavigatorCmd.label        "New Window">
 <!ENTITY newNavigatorCmd.key        "N">
 <!ENTITY newNavigatorCmd.accesskey      "N">
 
 <!ENTITY editMenu.label         "Edit"> 
 <!ENTITY editMenu.accesskey       "E"> 
@@ -470,8 +474,11 @@ with that structure, consider a translat
 just addresses the organization to follow, e.g. "This site is run by " -->
 <!ENTITY identity.runBy "which is run by">
 
 <!ENTITY identity.moreInfoLinkText "More Information…">
 
 <!ENTITY downloadMonitor2.tooltip "Click to open downloads window">
 
 <!ENTITY allTabs.filter.emptyText "Search Tabs">
+<!-- Name for the tabs toolbar as spoken by screen readers.
+     The word "toolbar" is appended automatically and should not be contained below! -->
+<!ENTITY tabsToolbar.label "Browser tabs">
--- a/browser/locales/en-US/chrome/browser/places/places.dtd
+++ b/browser/locales/en-US/chrome/browser/places/places.dtd
@@ -8,18 +8,16 @@
 <!ENTITY file.accesskey                 "F">
 <!ENTITY file.close.label               "Close">
 <!ENTITY file.close.accesskey           "C">
 <!ENTITY cmd.close.key                  "w">
 <!ENTITY edit.label                     "Edit">
 <!ENTITY edit.accesskey                 "E">
 <!ENTITY views.label                    "Views">
 <!ENTITY views.accesskey                "V">
-<!ENTITY view.toolbar.label             "Toolbar">
-<!ENTITY view.toolbar.accesskey         "o">
 <!ENTITY view.columns.label             "Show Columns">
 <!ENTITY view.columns.accesskey         "C">
 <!ENTITY view.sort.label                "Sort">
 <!ENTITY view.sort.accesskey            "S">
 <!ENTITY view.unsorted.label            "Unsorted">
 <!ENTITY view.unsorted.accesskey        "U">
 <!ENTITY view.sortAscending.label       "A > Z Sort Order">
 <!ENTITY view.sortAscending.accesskey   "A">
@@ -38,38 +36,16 @@
 
 <!ENTITY cmd.backup.label               "Backup…">
 <!ENTITY cmd.backup.accesskey           "B">
 <!ENTITY cmd.restore2.label             "Restore">
 <!ENTITY cmd.restore2.accesskey         "R">
 <!ENTITY cmd.restoreFromFile.label      "Choose File…">
 <!ENTITY cmd.restoreFromFile.accesskey  "C">
 
-<!ENTITY cmd.select_all.label "Select All">
-<!ENTITY cmd.select_all.accesskey "A">
-<!ENTITY cmd.select_all.key "a">
-
-<!ENTITY cmd.edit_cut.label         "Cut">
-<!ENTITY cmd.edit_cut.accesskey     "t">
-<!ENTITY cmd.edit_cut.key           "x">
-<!ENTITY cmd.edit_copy.label        "Copy">
-<!ENTITY cmd.edit_copy.accesskey    "C">
-<!ENTITY cmd.edit_copy.key          "c">
-<!ENTITY cmd.edit_paste.label       "Paste">
-<!ENTITY cmd.edit_paste.accesskey   "P">
-<!ENTITY cmd.edit_paste.key         "v">
-<!ENTITY cmd.edit_delete.label      "Delete">
-<!ENTITY cmd.edit_delete.accesskey  "D">
-<!ENTITY cmd.edit_undo.label        "Undo">
-<!ENTITY cmd.edit_undo.accesskey    "U">
-<!ENTITY cmd.edit_undo.key          "z">
-<!ENTITY cmd.edit_redo.label        "Redo">
-<!ENTITY cmd.edit_redo.accesskey    "R">
-<!ENTITY cmd.edit_redo.key          "y">
-
 <!ENTITY cmd.bookmarkLink.label         "Bookmark This Page…">
 <!ENTITY cmd.bookmarkLink.accesskey     "B">
 <!ENTITY cmd.delete.label               "Delete This Page">
 <!ENTITY cmd.delete.accesskey           "D">
 <!ENTITY cmd.deleteDomainData.label     "Forget About This Site">
 <!ENTITY cmd.deleteDomainData.accesskey "F">
 
 <!ENTITY cmd.open.label                  "Open">
@@ -79,27 +55,22 @@
 <!ENTITY cmd.open_tab.label              "Open in a New Tab">
 <!ENTITY cmd.open_tab.accesskey          "w">
 <!ENTITY cmd.open_all_in_tabs.label      "Open All in Tabs">
 <!ENTITY cmd.open_all_in_tabs.accesskey  "O">
 
 <!ENTITY cmd.properties.label      "Properties">
 <!ENTITY cmd.properties.accesskey  "i">
 
-<!ENTITY cmd.rename.label      "Rename">
-<!ENTITY cmd.rename.accesskey  "R">
-
 <!ENTITY cmd.sortby_name.label              "Sort By Name">
 <!ENTITY cmd.sortby_name.accesskey          "S">
 <!ENTITY cmd.context_sortby_name.accesskey  "r">
 
 <!ENTITY cmd.new_bookmark.label            "New Bookmark…">
 <!ENTITY cmd.new_bookmark.accesskey        "B">
-<!ENTITY cmd.new_livemark.label            "New Live Bookmark…">
-<!ENTITY cmd.new_livemark.accesskey        "L">
 <!ENTITY cmd.new_folder.label              "New Folder…">
 <!ENTITY cmd.new_folder.accesskey          "o">
 <!ENTITY cmd.context_new_folder.accesskey  "F">
 <!ENTITY cmd.new_separator.label           "New Separator">
 <!ENTITY cmd.new_separator.accesskey       "S">
 
 <!ENTITY cmd.reloadLivebookmark.label      "Reload Live Bookmark">
 <!ENTITY cmd.reloadLivebookmark.accesskey  "R">
@@ -129,19 +100,16 @@
 <!ENTITY search.scopeDownloads.accesskey           "D">
 <!ENTITY search.scopeHistory.label                 "History">
 <!ENTITY search.scopeHistory.accesskey             "H">
 <!ENTITY saveSearch.label                          "Save">
 <!ENTITY saveSearch.accesskey                      "S">
 
 <!ENTITY cmd.find.key  "f">
 
-<!ENTITY feed.subscribe.label    "Feed">
-<!ENTITY feed.subscribe.tooltip  "Subscribe">
-
 <!ENTITY maintenance.label      "Import and Backup">
 <!ENTITY maintenance.accesskey  "I">
 
 <!ENTITY backCmd.label       "Back">
 <!ENTITY backButton.tooltip  "Go back">
 
 <!ENTITY forwardCmd.label       "Forward">
 <!ENTITY forwardButton.tooltip  "Go forward">
--- a/browser/locales/en-US/chrome/browser/places/places.properties
+++ b/browser/locales/en-US/chrome/browser/places/places.properties
@@ -1,50 +1,32 @@
 deleteHost=Delete all from %S
 deleteDomain=Delete entire domain %S
-deleteHostNoSelection=Delete host
-deleteDomainNoSelection=Delete domain
 
 load-js-data-url-error=For security reasons, javascript or data urls cannot be loaded from the history window or sidebar.
 noTitle=(no title)
 
 bookmarksMenuEmptyFolder=(Empty)
 
-# LOCALIZATION NOTE (bookmarksBackupFilename) :
-# %S will be replaced by the current date in ISO 8601 format, YYYY-MM-DD.
-# The resulting string will be suggested as a filename, so make sure that you're
-# only using characters legal for file names. Consider falling back to the
-# en-US value if you have to use non-ascii characters.
-bookmarksBackupFilename=Bookmarks %S.html
-bookmarksBackupFilenameJSON=Bookmarks %S.json
 bookmarksBackupTitle=Bookmarks backup filename
 
 bookmarksRestoreAlertTitle=Revert Bookmarks
 bookmarksRestoreAlert=This will replace all of your current bookmarks with the backup. Are you sure?
-bookmarksRestoreAlertTags=This will replace all of your current bookmarks and tags with the backup. Are you sure?
 bookmarksRestoreTitle=Select a bookmarks backup
 bookmarksRestoreFilterName=JSON
 bookmarksRestoreFilterExtension=*.json
 
 bookmarksRestoreFormatError=Unsupported file type.
 bookmarksRestoreParseError=Unable to process the backup file.
 
 bookmarksLivemarkLoading=Live Bookmark loading…
 bookmarksLivemarkFailed=Live Bookmark feed failed to load.
 
-headerTextPrefix1=Showing 
-headerTextPrefix2=Search Results for 
-headerTextPrefix3=Advanced Search
-
 menuOpenLivemarkOrigin.label=Open "%S"
 
-livemarkReload=Reload
-livemarkReloadAll=Reload All Live Bookmarks
-livemarkReloadOne=Reload %S
-
 sortByName=Sort '%S' by Name
 sortByNameGeneric=Sort by Name
 view.sortBy.name.label=Sort by Name
 view.sortBy.name.accesskey=N
 view.sortBy.url.label=Sort by Location
 view.sortBy.url.accesskey=L
 view.sortBy.date.label=Sort by Visit Date
 view.sortBy.date.accesskey=V
@@ -66,30 +48,27 @@ searchHistory=Search History
 searchCurrentDefault=Search in '%S'
 findInPrefix=Find in '%S'…
 
 tabs.openWarningTitle=Confirm open
 tabs.openWarningMultipleBranded=You are about to open %S tabs.  This might slow down %S while the pages are loading.  Are you sure you want to continue?
 tabs.openButtonMultiple=Open tabs
 tabs.openWarningPromptMeBranded=Warn me when opening multiple tabs might slow down %S
 
-status_foldercount = %S object(s)
-
 SelectImport=Import Bookmarks File
 EnterExport=Export Bookmarks File
 
 saveSearch.title=Save Search
 saveSearch.inputLabel=Name:
 saveSearch.inputDefaultText=New Search
 
 detailsPane.noItems=No items
 detailsPane.oneItem=One item
 detailsPane.multipleItems=%S items
 
-smartBookmarksFolderTitle=Smart Bookmarks
 mostVisitedTitle=Most Visited
 recentlyBookmarkedTitle=Recently Bookmarked
 recentTagsTitle=Recent Tags
 
 OrganizerQueryHistory=History
 OrganizerQueryDownloads=Downloads
 OrganizerQueryAllBookmarks=All Bookmarks
 OrganizerQueryTags=Tags
--- a/browser/themes/gnomestripe/browser/aboutSessionRestore.css
+++ b/browser/themes/gnomestripe/browser/aboutSessionRestore.css
@@ -62,16 +62,25 @@ treechildren::-moz-tree-image(container,
 }
 treechildren::-moz-tree-image(checked) {
   list-style-image: url("chrome://global/skin/checkbox/cbox-check.gif");
 }
 treechildren::-moz-tree-image(partial) {
   list-style-image: url("chrome://global/skin/checkbox/cbox-check-dis.gif");
 }
 
+/* undo odd row highlighting from tree.css */
+treechildren::-moz-tree-row(odd) {
+  background-color: transparent;
+}
+treechildren::-moz-tree-row(odd, selected, focus) {
+  background-color: Highlight;
+}
+
+/* highlight "windows" instead */
 treechildren::-moz-tree-row(alternate) {
   background-color: -moz-oddtreerow;
 }
 treechildren::-moz-tree-row(alternate, selected) {
   background-color: Highlight;
 }
 
 #buttons {
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -2039,8 +2039,9 @@ toolbarbutton.chevron > .toolbarbutton-m
 
 .allTabs-preview:not(:hover):not([closebuttonhover]) > html|canvas {
   opacity: .8;
 }
 
 .allTabs-preview:focus > * > .allTabs-preview-inner {
   -moz-box-shadow: @focusRingShadow@;
 }
+
--- a/build/autoconf/glib.m4
+++ b/build/autoconf/glib.m4
@@ -178,17 +178,17 @@ main ()
           echo "*** If you have an old version installed, it is best to remove it, although"
           echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
           echo "***"
           echo "*** If you have a RedHat 5.0 system, you should remove the GTK package that"
           echo "*** came with the system with the command"
           echo "***"
           echo "***    rpm --erase --nodeps gtk gtk-devel" ],
         [ echo "*** The test program failed to compile or link. See the file config.log for the"
-          echo "*** exact error that occured. This usually means GLIB was incorrectly installed"
+          echo "*** exact error that occurred. This usually means GLIB was incorrectly installed"
           echo "*** or that you have moved GLIB since it was installed. In the latter case, you"
           echo "*** may want to edit the glib-config script: $GLIB_CONFIG" ])
           CFLAGS="$ac_save_CFLAGS"
           LIBS="$ac_save_LIBS"
        fi
      fi
      GLIB_CFLAGS=""
      GLIB_LIBS=""
--- a/build/autoconf/libIDL.m4
+++ b/build/autoconf/libIDL.m4
@@ -176,17 +176,17 @@ main ()
           echo "*** version of LIBIDL. If it is not finding libIDL, you'll need to set your"
           echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
           echo "*** to the installed location  Also, make sure you have run ldconfig if that"
           echo "*** is required on your system"
 	  echo "***"
           echo "*** If you have an old version installed, it is best to remove it, although"
           echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ],
         [ echo "*** The test program failed to compile or link. See the file config.log for the"
-          echo "*** exact error that occured. This usually means libIDL was incorrectly installed"
+          echo "*** exact error that occurred. This usually means libIDL was incorrectly installed"
           echo "*** or that you have moved libIDL since it was installed. In the latter case, you"
           echo "*** may want to edit the libIDL-config script: $LIBIDL_CONFIG" ])
           CFLAGS="$ac_save_CFLAGS"
           LIBS="$ac_save_LIBS"
        fi
      fi
      LIBIDL_CFLAGS=""
      LIBIDL_LIBS=""
--- a/build/pgo/js-input/crypto-otp.html
+++ b/build/pgo/js-input/crypto-otp.html
@@ -1284,17 +1284,17 @@ a program different from the purported s
 an interpreted language what you read is what you run.
 </p>
 
 <p>
 Transparency is important even if you don't know enough about
 programming or security to determine whether the program
 contains any flaws.  The very fact that it can be examined
 by anybody allows those with the required expertise to pass
-judgement, and you can form your own conclusions based on
+judgment, and you can form your own conclusions based on
 their analysis.
 </p>
 
 <h2>Credits</h2>
 
 <p>
 
 The pseudorandom sequence generator is based on L'Ecuyer's
--- a/build/unix/run-mozilla.sh
+++ b/build/unix/run-mozilla.sh
@@ -98,17 +98,17 @@ moz_test_binary()
 			return 1
 		fi
 	fi
 	return 0
 }
 ##########################################################################
 moz_get_debugger()
 {
-	debuggers="ddd gdb dbx bdb"
+	debuggers="ddd gdb dbx bdb native-gdb"
 	debugger="notfound"
 	done="no"
 	for d in $debuggers
 	do
 		moz_test_binary /bin/which
 		if [ $? -eq 1 ]
 		then
 			dpath=`which ${d}`	
@@ -164,16 +164,20 @@ moz_debug_program()
 	else
 		debugger=`moz_get_debugger`
 	fi
     if [ -x "$debugger" ] 
     then
 # If you are not using ddd, gdb and know of a way to convey the arguments 
 # over to the prog then add that here- Gagan Saksena 03/15/00
         case `basename $debugger` in
+            native-gdb) echo "$debugger $moz_debugger_args --args $prog" ${1+"$@"}
+                exec "$debugger" $moz_debugger_args --args "$prog" ${1+"$@"}
+                exitcode=$?
+                ;;
             gdb) echo "$debugger $moz_debugger_args --args $prog" ${1+"$@"}
                 exec "$debugger" $moz_debugger_args --args "$prog" ${1+"$@"}
 		exitcode=$?
                 ;;
             ddd) echo "$debugger $moz_debugger_args --gdb -- --args $prog" ${1+"$@"}
 		exec "$debugger" $moz_debugger_args --gdb -- --args "$prog" ${1+"$@"}
 		exitcode=$?
                 ;;
--- a/caps/idl/nsIScriptSecurityManager.idl
+++ b/caps/idl/nsIScriptSecurityManager.idl
@@ -311,17 +311,17 @@ interface nsIScriptSecurityManager : nsI
     [noscript,notxpcom] nsIPrincipal getCxSubjectPrincipal(in JSContextPtr cx);
     [noscript,notxpcom] nsIPrincipal getCxSubjectPrincipalAndFrame(in JSContextPtr cx,
                                                                    out JSStackFramePtr fp);
 
     /**
      * If no scripted code is running "above" (or called from) fp, then
      * instead of looking at cx->globalObject, we will return |principal|.
      * This function only affects |cx|. If someone pushes another context onto
-     * the context stack, then it supercedes this call.
+     * the context stack, then it supersedes this call.
      * NOTE: If |fp| is non-null popContextPrincipal must be called before fp
      * has finished executing.
      *
      * @param cx The context to clamp.
      * @param fp The frame pointer to clamp at. May be 'null'.
      * @param principal The principal to clamp to.
      */
     [noscript] void pushContextPrincipal(in JSContextPtr cx,
--- a/chrome/src/nsChromeRegistry.cpp
+++ b/chrome/src/nsChromeRegistry.cpp
@@ -40,48 +40,97 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsChromeRegistry.h"
 
 #include <string.h>
 
 #include "prio.h"
 #include "prprf.h"
+#if defined(XP_WIN)
+#include <windows.h>
+#elif defined(XP_MACOSX)
+#include <CoreServices/CoreServices.h>
+#elif defined(MOZ_WIDGET_GTK2)
+#include <gtk/gtk.h>
+#endif
 
+#include "nsAppDirectoryServiceDefs.h"
+#include "nsArrayEnumerator.h"
+#include "nsStringEnumerator.h"
+#include "nsEnumeratorUtils.h"
 #include "nsCOMPtr.h"
 #include "nsDOMError.h"
 #include "nsEscape.h"
+#include "nsInt64.h"
 #include "nsLayoutCID.h"
+#include "nsNetCID.h"
 #include "nsNetUtil.h"
+#include "nsReadableUtils.h"
 #include "nsString.h"
 #include "nsUnicharUtils.h"
+#include "nsWidgetsCID.h"
+#include "nsXPCOMCIDInternal.h"
+#include "nsXPIDLString.h"
+#include "nsXULAppAPI.h"
+#include "nsTextFormatter.h"
 
-#include "nsICSSStyleSheet.h"
+#include "nsIAtom.h"
+#include "nsICommandLine.h"
+#include "nsCSSStyleSheet.h"
 #include "nsIConsoleService.h"
+#include "nsIDirectoryService.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDocShell.h"
+#include "nsIDocumentObserver.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMLocation.h"
 #include "nsIDOMWindowCollection.h"
 #include "nsIDOMWindowInternal.h"
+#include "nsIFileChannel.h"
+#include "nsIFileURL.h"
 #include "nsIIOService.h"
 #include "nsIJARProtocolHandler.h"
+#include "nsIJARURI.h"
+#include "nsILocalFile.h"
+#include "nsILocaleService.h"
+#include "nsILookAndFeel.h"
 #include "nsIObserverService.h"
+#include "nsIPrefService.h"
+#include "nsIPrefBranch.h"
+#include "nsIPrefBranch2.h"
 #include "nsIPresShell.h"
 #include "nsIProtocolHandler.h"
+#include "nsIResProtocolHandler.h"
 #include "nsIScriptError.h"
+#include "nsIServiceManager.h"
+#include "nsISimpleEnumerator.h"
+#include "nsIStyleSheet.h"
+#include "nsISupportsArray.h"
+#include "nsIVersionComparator.h"
 #include "nsIWindowMediator.h"
+#include "nsIXPConnect.h"
+#include "nsIXULAppInfo.h"
+#include "nsIXULRuntime.h"
+
+#define UILOCALE_CMD_LINE_ARG "UILocale"
+
+#define MATCH_OS_LOCALE_PREF "intl.locale.matchOS"
+#define SELECTED_LOCALE_PREF "general.useragent.locale"
+#define SELECTED_SKIN_PREF   "general.skins.selectedSkin"
+
+static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
 
 nsChromeRegistry* nsChromeRegistry::gChromeRegistry;
 
 ////////////////////////////////////////////////////////////////////////////////
 
-void
-nsChromeRegistry::LogMessage(const char* aMsg, ...)
+static void
+LogMessage(const char* aMsg, ...)
 {
   nsCOMPtr<nsIConsoleService> console 
     (do_GetService(NS_CONSOLESERVICE_CONTRACTID));
   if (!console)
     return;
 
   va_list args;
   va_start(args, aMsg);
@@ -89,19 +138,19 @@ nsChromeRegistry::LogMessage(const char*
   va_end(args);
   if (!formatted)
     return;
 
   console->LogStringMessage(NS_ConvertUTF8toUTF16(formatted).get());
   PR_smprintf_free(formatted);
 }
 
-void
-nsChromeRegistry::LogMessageWithContext(nsIURI* aURL, PRUint32 aLineNumber, PRUint32 flags,
-                                        const char* aMsg, ...)
+static void
+LogMessageWithContext(nsIURI* aURL, PRUint32 aLineNumber, PRUint32 flags,
+                      const char* aMsg, ...)
 {
   nsresult rv;
 
   nsCOMPtr<nsIConsoleService> console 
     (do_GetService(NS_CONSOLESERVICE_CONTRACTID));
 
   nsCOMPtr<nsIScriptError> error
     (do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
@@ -126,16 +175,248 @@ nsChromeRegistry::LogMessageWithContext(
   PR_smprintf_free(formatted);
 
   if (NS_FAILED(rv))
     return;
 
   console->LogMessage(error);
 }
 
+// We use a "best-fit" algorithm for matching locales and themes. 
+// 1) the exact selected locale/theme
+// 2) (locales only) same language, different country
+//    e.g. en-GB is the selected locale, only en-US is available
+// 3) any available locale/theme
+
+/**
+ * Match the language-part of two lang-COUNTRY codes, hopefully but
+ * not guaranteed to be in the form ab-CD or abz-CD. "ab" should also
+ * work, any other garbage-in will produce undefined results as long
+ * as it does not crash.
+ */
+static PRBool
+LanguagesMatch(const nsACString& a, const nsACString& b)
+{
+  if (a.Length() < 2 || b.Length() < 2)
+    return PR_FALSE;
+
+  nsACString::const_iterator as, ae, bs, be;
+  a.BeginReading(as);
+  a.EndReading(ae);
+  b.BeginReading(bs);
+  b.EndReading(be);
+
+  while (*as == *bs) {
+    if (*as == '-')
+      return PR_TRUE;
+ 
+    ++as; ++bs;
+
+    // reached the end
+    if (as == ae && bs == be)
+      return PR_TRUE;
+
+    // "a" is short
+    if (as == ae)
+      return (*bs == '-');
+
+    // "b" is short
+    if (bs == be)
+      return (*as == '-');
+  }
+
+  return PR_FALSE;
+}
+
+static PRBool
+CanLoadResource(nsIURI* aResourceURI)
+{
+  PRBool isLocalResource = PR_FALSE;
+  (void)NS_URIChainHasFlags(aResourceURI,
+                            nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
+                            &isLocalResource);
+  return isLocalResource;
+}
+
+nsChromeRegistry::ProviderEntry*
+nsChromeRegistry::nsProviderArray::GetProvider(const nsACString& aPreferred, MatchType aType)
+{
+  PRInt32 i = mArray.Count();
+  if (!i)
+    return nsnull;
+
+  ProviderEntry* found = nsnull;  // Only set if we find a partial-match locale
+  ProviderEntry* entry;
+
+  while (i--) {
+    entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
+    if (aPreferred.Equals(entry->provider))
+      return entry;
+
+    if (aType != LOCALE)
+      continue;
+
+    if (LanguagesMatch(aPreferred, entry->provider)) {
+      found = entry;
+      continue;
+    }
+
+    if (!found && entry->provider.EqualsLiteral("en-US"))
+      found = entry;
+  }
+
+  if (!found && aType != EXACT)
+    return entry;
+
+  return found;
+}
+
+nsIURI*
+nsChromeRegistry::nsProviderArray::GetBase(const nsACString& aPreferred, MatchType aType)
+{
+  ProviderEntry* provider = GetProvider(aPreferred, aType);
+
+  if (!provider)
+    return nsnull;
+
+  return provider->baseURI;
+}
+
+const nsACString&
+nsChromeRegistry::nsProviderArray::GetSelected(const nsACString& aPreferred, MatchType aType)
+{
+  ProviderEntry* entry = GetProvider(aPreferred, aType);
+
+  if (entry)
+    return entry->provider;
+
+  return EmptyCString();
+}
+
+void
+nsChromeRegistry::nsProviderArray::SetBase(const nsACString& aProvider, nsIURI* aBaseURL)
+{
+  ProviderEntry* provider = GetProvider(aProvider, EXACT);
+
+  if (provider) {
+    provider->baseURI = aBaseURL;
+    return;
+  }
+
+  // no existing entries, add a new one
+  provider = new ProviderEntry(aProvider, aBaseURL);
+  if (!provider)
+    return; // It's safe to silently fail on OOM
+
+  mArray.AppendElement(provider);
+}
+
+void
+nsChromeRegistry::nsProviderArray::EnumerateToArray(nsTArray<nsCString> *a)
+{
+  PRInt32 i = mArray.Count();
+  while (i--) {
+    ProviderEntry *entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
+    a->AppendElement(entry->provider);
+  }
+}
+
+void
+nsChromeRegistry::nsProviderArray::Clear()
+{
+  PRInt32 i = mArray.Count();
+  while (i--) {
+    ProviderEntry* entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
+    delete entry;
+  }
+
+  mArray.Clear();
+}
+
+nsChromeRegistry::PackageEntry::PackageEntry(const nsACString& aPackage) :
+  package(aPackage), flags(0)
+{
+}
+
+PLHashNumber
+nsChromeRegistry::HashKey(PLDHashTable *table, const void *key)
+{
+  const nsACString& str = *reinterpret_cast<const nsACString*>(key);
+  return HashString(str);
+}
+
+PRBool
+nsChromeRegistry::MatchKey(PLDHashTable *table, const PLDHashEntryHdr *entry,
+                           const void *key)
+{
+  const nsACString& str = *reinterpret_cast<const nsACString*>(key);
+  const PackageEntry* pentry = static_cast<const PackageEntry*>(entry);
+  return str.Equals(pentry->package);
+}
+
+void
+nsChromeRegistry::ClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
+{
+  PackageEntry* pentry = static_cast<PackageEntry*>(entry);
+  pentry->~PackageEntry();
+}
+
+PRBool
+nsChromeRegistry::InitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
+                            const void *key)
+{
+  const nsACString& str = *reinterpret_cast<const nsACString*>(key);
+
+  new (entry) PackageEntry(str);
+  return PR_TRUE;
+}
+
+const PLDHashTableOps
+nsChromeRegistry::kTableOps = {
+  PL_DHashAllocTable,
+  PL_DHashFreeTable,
+  HashKey,
+  MatchKey,
+  PL_DHashMoveEntryStub,
+  ClearEntry,
+  PL_DHashFinalizeStub,
+  InitEntry
+};
+
+void
+nsChromeRegistry::OverlayListEntry::AddURI(nsIURI* aURI)
+{
+  PRInt32 i = mArray.Count();
+  while (i--) {
+    PRBool equals;
+    if (NS_SUCCEEDED(aURI->Equals(mArray[i], &equals)) && equals)
+        return;
+  }
+
+  mArray.AppendObject(aURI);
+}
+
+void
+nsChromeRegistry::OverlayListHash::Add(nsIURI* aBase, nsIURI* aOverlay)
+{
+  OverlayListEntry* entry = mTable.PutEntry(aBase);
+  if (entry)
+    entry->AddURI(aOverlay);
+}
+
+const nsCOMArray<nsIURI>*
+nsChromeRegistry::OverlayListHash::GetArray(nsIURI* aBase)
+{
+  OverlayListEntry* entry = mTable.GetEntry(aBase);
+  if (!entry)
+    return nsnull;
+
+  return &entry->mArray;
+}
+
 nsChromeRegistry::~nsChromeRegistry()
 {
   gChromeRegistry = nsnull;
 }
 
 NS_INTERFACE_MAP_BEGIN(nsChromeRegistry)
   NS_INTERFACE_MAP_ENTRY(nsIChromeRegistry)
   NS_INTERFACE_MAP_ENTRY(nsIXULChromeRegistry)
@@ -479,23 +760,21 @@ nsresult nsChromeRegistry::RefreshWindow
     nsCOMArray<nsIStyleSheet> agentSheets;
     rv = shell->GetAgentStyleSheets(agentSheets);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMArray<nsIStyleSheet> newAgentSheets;
     for (PRInt32 l = 0; l < agentSheets.Count(); ++l) {
       nsIStyleSheet *sheet = agentSheets[l];
 
-      nsCOMPtr<nsIURI> uri;
-      rv = sheet->GetSheetURI(getter_AddRefs(uri));
-      if (NS_FAILED(rv)) return rv;
+      nsCOMPtr<nsIURI> uri = sheet->GetSheetURI();
 
       if (IsChromeURI(uri)) {
         // Reload the sheet.
-        nsCOMPtr<nsICSSStyleSheet> newSheet;
+        nsRefPtr<nsCSSStyleSheet> newSheet;
         rv = document->LoadChromeSheetSync(uri, PR_TRUE,
                                            getter_AddRefs(newSheet));
         if (NS_FAILED(rv)) return rv;
         if (newSheet) {
           rv = newAgentSheets.AppendObject(newSheet) ? NS_OK : NS_ERROR_FAILURE;
           if (NS_FAILED(rv)) return rv;
         }
       }
@@ -524,22 +803,22 @@ nsresult nsChromeRegistry::RefreshWindow
     if (!oldSheets.AppendObject(styleSheet)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   // Iterate over our old sheets and kick off a sync load of the new
   // sheet if and only if it's a chrome URL.
   for (i = 0; i < count; i++) {
-    nsCOMPtr<nsICSSStyleSheet> sheet = do_QueryInterface(oldSheets[i]);
+    nsRefPtr<nsCSSStyleSheet> sheet = do_QueryObject(oldSheets[i]);
     nsIURI* uri = sheet ? sheet->GetOriginalURI() : nsnull;
 
     if (uri && IsChromeURI(uri)) {
       // Reload the sheet.
-      nsCOMPtr<nsICSSStyleSheet> newSheet;
+      nsRefPtr<nsCSSStyleSheet> newSheet;
       // XXX what about chrome sheets that have a title or are disabled?  This
       // only works by sheer dumb luck.
       document->LoadChromeSheetSync(uri, PR_FALSE, getter_AddRefs(newSheet));
       // Even if it's null, we put in in there.
       newSheets.AppendObject(newSheet);
     }
     else {
       // Just use the same sheet.
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -134,22 +134,24 @@ export::
 		-DMOZ_NATIVE_LIBEVENT=$(MOZ_NATIVE_LIBEVENT) \
 		$(srcdir)/system-headers | $(PERL) $(topsrcdir)/nsprpub/config/make-system-wrappers.pl system_wrappers
 	$(INSTALL) system_wrappers $(DIST)
 
 GARBAGE_DIRS += system_wrappers
 endif
 
 ifdef WRAP_STL_INCLUDES
-ifdef GCC_VERSION
+ifdef GNU_CXX
 stl_compiler = gcc
 else
+ifdef _MSC_VER
 stl_compiler = msvc
 endif
 endif
+endif
 
 ifdef stl_compiler
 stl-wrappers-sentinel: $(srcdir)/make-stl-wrappers.py $(srcdir)/$(stl_compiler)-stl-wrapper.template.h $(srcdir)/stl-headers $(GLOBAL_DEPS)
 	$(PYTHON) $(srcdir)/make-stl-wrappers.py stl_wrappers $(stl_compiler) $(srcdir)/$(stl_compiler)-stl-wrapper.template.h $(srcdir)/stl-headers
 	$(PYTHON) $(srcdir)/nsinstall.py stl_wrappers $(DIST)
 	touch stl-wrappers-sentinel
 
 export:: stl-wrappers-sentinel
--- a/config/configobj.py
+++ b/config/configobj.py
@@ -256,17 +256,17 @@ class ParseError(ConfigObjError):
 
 class DuplicateError(ConfigObjError):
     """
     The keyword or section specified already exists.
     """
 
 class ConfigspecError(ConfigObjError):
     """
-    An error occured whilst parsing a configspec.
+    An error occurred whilst parsing a configspec.
     """
 
 class InterpolationError(ConfigObjError):
     """Base class for the two interpolation errors."""
 
 class InterpolationLoopError(InterpolationError):
     """Maximum interpolation depth exceeded in string interpolation."""
 
@@ -1595,17 +1595,17 @@ class ConfigObj(Section):
         # shouldn't get here
         raise SyntaxError
 
     def _handle_error(self, text, ErrorClass, infile, cur_index):
         """
         Handle an error according to the error settings.
         
         Either raise the error or store it.
-        The error will have occured at ``cur_index``
+        The error will have occurred at ``cur_index``
         """
         line = infile[cur_index]
         cur_index += 1
         message = text % cur_index
         error = ErrorClass(message, cur_index, line)
         if self.raise_errors:
             # raise the error - parsing stops here
             raise error
--- a/config/fast-update.pl
+++ b/config/fast-update.pl
@@ -1,15 +1,15 @@
 #!/usr/bin/env perl
 #
 # fast-update.pl [-h hours] [-m module] [-r branch]
 #
 # This command, fast-update.pl, does a (fast) cvs update of the current 
 # directory. It is fast because the cvs up command is only run on those 
-# directories / sub-directories where changes have occured since the 
+# directories / sub-directories where changes have occurred since the 
 # last fast-update.
 #
 # The last update time is stored in a ".fast-update" file in the current
 # directory. Thus one can choose to only fast-update a branch of the tree 
 # and then fast-update the whole tree later.
 #
 # The first time this command is run in a directory the last cvs update
 # time is assumed to be the timestamp of the CVS/Entries file.
--- a/config/outofdate.pl
+++ b/config/outofdate.pl
@@ -36,17 +36,17 @@
 #
 # ***** END LICENSE BLOCK *****
 
 #
 #Input: [-d dir] foo1.java foo2.java
 #Compares with: foo1.class foo2.class (if -d specified, checks in 'dir', 
 #  otherwise assumes .class files in same directory as .java files)
 #Returns: list of input arguments which are newer than corresponding class
-#files (non-existant class files are considered to be real old :-)
+#files (non-existent class files are considered to be real old :-)
 #
 
 $found = 1;
 
 # GLOBALS
 $SEP = 0; # the paltform independent path separator
 $CFG = 0; # the value of the -cfg flag
 
--- a/configure.in
+++ b/configure.in
@@ -2249,16 +2249,17 @@ ia64*-hpux*)
         # mingw doesn't require kernel32, user32, and advapi32 explicitly
         LIBS="$LIBS -luuid -lgdi32 -lwinmm -lwsock32"
         MOZ_JS_LIBS='-L$(LIBXUL_DIST)/lib -lmozjs'
         MOZ_FIX_LINK_PATHS=
         DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/lib -lxpcom -lxpcom_core -lmozalloc'
         XPCOM_FROZEN_LDOPTS='-L$(LIBXUL_DIST)/lib -lxpcom -lmozalloc'
         DLL_PREFIX=
         IMPORT_LIB_SUFFIX=dll.a
+        GCC_VERSION=`$CC -v 2>&1 | awk '/^gcc version/ { print $3 }'`
     else
         TARGET_COMPILER_ABI=msvc
         HOST_CC='$(CC)'
         HOST_CXX='$(CXX)'
         HOST_LD='$(LD)'
         if test "$AS_BIN"; then
             AS="$(basename "$AS_BIN")"
         fi
@@ -2282,16 +2283,17 @@ ia64*-hpux*)
         MKSHLIB_FORCE_ALL=
         MKSHLIB_UNFORCE_ALL=
         DSO_LDOPTS=-SUBSYSTEM:WINDOWS
         _USE_CPP_INCLUDE_FLAG=1
         _DEFINES_CFLAGS='-FI $(DEPTH)/dist/include/mozilla-config.h -DMOZILLA_CLIENT'
         _DEFINES_CXXFLAGS='-FI $(DEPTH)/dist/include/mozilla-config.h -DMOZILLA_CLIENT'
         CFLAGS="$CFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
         CXXFLAGS="$CXXFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
+        CXXFLAGS="$CXXFLAGS -wd4800" # disable warning "forcing value to bool"
         LIBS="$LIBS kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib"
         MOZ_DEBUG_FLAGS='-Zi'
         MOZ_DEBUG_LDFLAGS='-DEBUG -DEBUGTYPE:CV'
         WARNINGS_AS_ERRORS='-WX'
     	MOZ_OPTIMIZE_FLAGS='-O1'
         MOZ_JS_LIBS='$(LIBXUL_DIST)/lib/mozjs.lib'
         MOZ_FIX_LINK_PATHS=
         DYNAMIC_XPCOM_LIBS='$(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/xpcom_core.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
new file mode 100644
--- /dev/null
+++ b/content/base/crashtests/565125-1.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+
+function boom()
+{
+  var a = document.createTextNode(" ");
+  (document.documentElement).appendChild(a);
+  var b = document.createElement("span");
+  (document.documentElement).appendChild(b);
+  var c = document.createTextNode(" ");
+  (document.documentElement).appendChild(c);
+  var r = document.createRange();
+  r.setStart(a, 0); 
+  r.setEnd(c, 0); 
+  try {
+    r.surroundContents(document.documentElement); 
+  } catch(e) {
+  }
+  document.documentElement.appendChild(b);
+}
+
+</script>
+</head>
+<body onload="boom();"></body>
+</html>
--- a/content/base/crashtests/crashtests.list
+++ b/content/base/crashtests/crashtests.list
@@ -60,8 +60,9 @@ load 493281-2.html
 load 490760-1.xhtml
 load 494810-1.html
 load 529670.html
 asserts(1) load 554230-1.xhtml # bug 336104
 load 552651.html
 load 558973.html
 load 564079-1.html 
 load 564114.html
+load 565125-1.html
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -65,17 +65,17 @@
 
 class nsIContent;
 class nsPresContext;
 class nsIPresShell;
 class nsIDocShell;
 class nsStyleSet;
 class nsIStyleSheet;
 class nsIStyleRule;
-class nsICSSStyleSheet;
+class nsCSSStyleSheet;
 class nsIViewManager;
 class nsIScriptGlobalObject;
 class nsIDOMEvent;
 class nsIDOMEventTarget;
 class nsIDeviceContext;
 class nsIParser;
 class nsIDOMNode;
 class nsIDOMElement;
@@ -111,18 +111,18 @@ class Loader;
 
 namespace dom {
 class Link;
 class Element;
 } // namespace dom
 } // namespace mozilla
 
 #define NS_IDOCUMENT_IID      \
-{ 0xa979dabe, 0x75de, 0x4c2d, \
-  { 0x8b, 0x83, 0x17, 0xb2, 0xde, 0x9d, 0x9d, 0x37 } }
+{ 0x625fe492, 0x0344, 0x406c, \
+  { 0xaf, 0x7f, 0x55, 0xfe, 0xa2, 0x6b, 0x3d, 0x20 } }
 
 // Flag for AddStyleSheet().
 #define NS_STYLESHEET_FROM_CATALOG                (1 << 0)
 
 // Document states
 
 // RTL locale: specific to the XUL localedir attribute
 #define NS_DOCUMENT_STATE_RTL_LOCALE              (1 << 0)
@@ -1280,17 +1280,17 @@ public:
    * Called by the chrome registry to load style sheets.  Can be put
    * back there if and when when that module is merged with libgklayout.
    *
    * This always does a synchronous load.  If aIsAgentSheet is true,
    * it also uses the system principal and enables unsafe rules.
    * DO NOT USE FOR UNTRUSTED CONTENT.
    */
   virtual nsresult LoadChromeSheetSync(nsIURI* aURI, PRBool aIsAgentSheet,
-                                       nsICSSStyleSheet** aSheet) = 0;
+                                       nsCSSStyleSheet** aSheet) = 0;
 
   /**
    * Returns true if the locale used for the document specifies a direction of
    * right to left. For chrome documents, this comes from the chrome registry.
    * This is used to determine the current state for the :-moz-locale-dir pseudoclass
    * so once can know whether a document is expected to be rendered left-to-right
    * or right-to-left.
    */
--- a/content/base/public/nsINameSpaceManager.h
+++ b/content/base/public/nsINameSpaceManager.h
@@ -63,17 +63,17 @@ static const PRInt32 kNameSpaceID_None =
 
 #define NS_NAMESPACEMANAGER_CONTRACTID "@mozilla.org/content/namespacemanager;1"
 
 #define NS_INAMESPACEMANAGER_IID \
   { 0xd74e83e6, 0xf932, 0x4289, \
     { 0xac, 0x95, 0x9e, 0x10, 0x24, 0x30, 0x88, 0xd6 } }
 
 /**
- * The Name Space Manager tracks the associtation between a NameSpace
+ * The Name Space Manager tracks the association between a NameSpace
  * URI and the PRInt32 runtime id. Mappings between NameSpaces and 
  * NameSpace prefixes are managed by nsINameSpaces.
  *
  * All NameSpace URIs are stored in a global table so that IDs are
  * consistent accross the app. NameSpace IDs are only consistent at runtime
  * ie: they are not guaranteed to be consistent accross app sessions.
  *
  * The nsINameSpaceManager needs to have a live reference for as long as
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -189,23 +189,23 @@ inline nsINode* NODE_FROM(C& aContent, D
     return static_cast<nsINode*>(aContent);
   return static_cast<nsINode*>(aDocument);
 }
 
 /**
  * Class used to detect unexpected mutations. To use the class create an
  * nsMutationGuard on the stack before unexpected mutations could occur.
  * You can then at any time call Mutated to check if any unexpected mutations
- * have occured.
+ * have occurred.
  *
  * When a guard is instantiated sMutationCount is set to 300. It is then
  * decremented by every mutation (capped at 0). This means that we can only
  * detect 300 mutations during the lifetime of a single guard, however that
  * should be more then we ever care about as we usually only care if more then
- * one mutation has occured.
+ * one mutation has occurred.
  *
  * When the guard goes out of scope it will adjust sMutationCount so that over
  * the lifetime of the guard the guard itself has not affected sMutationCount,
  * while mutations that happened while the guard was alive still will. This
  * allows a guard to be instantiated even if there is another guard higher up
  * on the callstack watching for mutations.
  *
  * The only thing that has to be avoided is for an outer guard to be used
@@ -222,17 +222,17 @@ public:
   }
   ~nsMutationGuard()
   {
     sMutationCount =
       mDelta > sMutationCount ? 0 : sMutationCount - mDelta;
   }
 
   /**
-   * Returns true if any unexpected mutations have occured. You can pass in
+   * Returns true if any unexpected mutations have occurred. You can pass in
    * an 8-bit ignore count to ignore a number of expected mutations.
    */
   PRBool Mutated(PRUint8 aIgnoreCount)
   {
     return sMutationCount < static_cast<PRUint32>(eMaxMutations - aIgnoreCount);
   }
 
   // This function should be called whenever a mutation that we want to keep
@@ -710,45 +710,45 @@ public:
    * remove itself in case it dies before the node.  If an observer is added
    * while observers are being notified, it may also be notified.  In general,
    * adding observers while inside a notification is not a good idea.  An
    * observer that is already observing the node must not be added without
    * being removed first.
    */
   void AddMutationObserver(nsIMutationObserver* aMutationObserver)
   {
-    nsSlots* slots = GetSlots();
-    if (slots) {
-      NS_ASSERTION(slots->mMutationObservers.IndexOf(aMutationObserver) ==
+    nsSlots* s = GetSlots();
+    if (s) {
+      NS_ASSERTION(s->mMutationObservers.IndexOf(aMutationObserver) ==
                    nsTArray_base::NoIndex,
                    "Observer already in the list");
-      slots->mMutationObservers.AppendElement(aMutationObserver);
+      s->mMutationObservers.AppendElement(aMutationObserver);
     }
   }
 
   /**
    * Same as above, but only adds the observer if its not observing
    * the node already.
    */
   void AddMutationObserverUnlessExists(nsIMutationObserver* aMutationObserver)
   {
-    nsSlots* slots = GetSlots();
-    if (slots) {
-      slots->mMutationObservers.AppendElementUnlessExists(aMutationObserver);
+    nsSlots* s = GetSlots();
+    if (s) {
+      s->mMutationObservers.AppendElementUnlessExists(aMutationObserver);
     }
   }
 
   /**
    * Removes a mutation observer.
    */
   void RemoveMutationObserver(nsIMutationObserver* aMutationObserver)
   {
-    nsSlots* slots = GetExistingSlots();
-    if (slots) {
-      slots->mMutationObservers.RemoveElement(aMutationObserver);
+    nsSlots* s = GetExistingSlots();
+    if (s) {
+      s->mMutationObservers.RemoveElement(aMutationObserver);
     }
   }
 
   /**
    * Clones this node. This needs to be overriden by all node classes. aNodeInfo
    * should be identical to this node's nodeInfo, except for the document which
    * may be different. When cloning an element, all attributes of the element
    * will be cloned. The children of the node will not be cloned.
--- a/content/base/src/nsAttrAndChildArray.cpp
+++ b/content/base/src/nsAttrAndChildArray.cpp
@@ -661,16 +661,28 @@ nsAttrAndChildArray::Clear()
 
   nsAutoScriptBlocker scriptBlocker;
   PRUint32 end = slotCount * ATTRSIZE + ChildCount();
   for (i = slotCount * ATTRSIZE; i < end; ++i) {
     nsIContent* child = static_cast<nsIContent*>(mImpl->mBuffer[i]);
     // making this PR_FALSE so tree teardown doesn't end up being
     // O(N*D) (number of nodes times average depth of tree).
     child->UnbindFromTree(PR_FALSE); // XXX is it better to let the owner do this?
+    // Make sure to unlink our kids from each other, since someone
+    // else could stil be holding references to some of them.
+
+    // XXXbz We probably can't push this assignment down into the |aNullParent|
+    // case of UnbindFromTree because we still need the assignment in
+    // RemoveChildAt.  In particular, ContentRemoved fires between
+    // RemoveChildAt and UnbindFromTree, and in ContentRemoved the sibling
+    // chain needs to be correct.  Though maybe we could set the prev and next
+    // to point to each other but keep the kid being removed pointing to them
+    // through ContentRemoved so consumers can find where it used to be in the
+    // list?
+    child->mPreviousSibling = child->mNextSibling = nsnull;
     NS_RELEASE(child);
   }
 
   SetAttrSlotAndChildCount(0, 0);
 }
 
 PRUint32
 nsAttrAndChildArray::NonMappedAttrCount() const
--- a/content/base/src/nsCSPService.cpp
+++ b/content/base/src/nsCSPService.cpp
@@ -263,24 +263,21 @@ CSPService::OnChannelRedirect(nsIChannel
     PR_LOG(gCspPRLog, PR_LOG_DEBUG,
            ("CSPService::OnChannelRedirect ALLOWING request."));
   else
     PR_LOG(gCspPRLog, PR_LOG_DEBUG,
            ("CSPService::OnChannelRedirect CANCELLING request."));
 #endif
 
   // if ShouldLoad doesn't accept the load, cancel the request
-  if (aDecision != 1) {
-    newChannel->Cancel(NS_BINDING_FAILED);
-  }
+  if (aDecision != 1)
+    return NS_BINDING_FAILED;
 
-  else {
-    // the redirect is permitted, so propagate the Content Security Policy
-    // and load type to the redirecting channel
-    nsresult rv;
-    nsCOMPtr<nsIWritablePropertyBag2> props = do_QueryInterface(newChannel, &rv);
-    if (props)
-      props->SetPropertyAsInterface(NS_CHANNEL_PROP_CHANNEL_POLICY,
-                                    channelPolicy);
-  }
+  // the redirect is permitted, so propagate the Content Security Policy
+  // and load type to the redirecting channel
+  nsresult rv;
+  nsCOMPtr<nsIWritablePropertyBag2> props2 = do_QueryInterface(newChannel, &rv);
+  if (props2)
+    props2->SetPropertyAsInterface(NS_CHANNEL_PROP_CHANNEL_POLICY,
+                                   channelPolicy);
 
   return NS_OK;
 }
--- a/content/base/src/nsContentAreaDragDrop.h
+++ b/content/base/src/nsContentAreaDragDrop.h
@@ -76,17 +76,17 @@ public:
    *                    holding down Alt over a link should select the text,
    *                    not drag the link.
    * aDataTransfer - the dataTransfer for the drag event.
    * aCanDrag - [out] set to true if the drag may proceed, false to stop the
    *            drag entirely
    * aDragSelection - [out] set to true to indicate that a selection is being
    *                  dragged, rather than a specific node
    * aDragNode - [out] the link, image or area being dragged, or null if the
-   *             drag occured on another element.
+   *             drag occurred on another element.
    */
   static nsresult GetDragData(nsIDOMWindow* aWindow,
                               nsIContent* aTarget,
                               nsIContent* aSelectionTargetNode,
                               PRBool aIsAltKeyPressed,
                               nsDOMDataTransfer* aDataTransfer,
                               PRBool* aCanDrag,
                               PRBool* aDragSelection,
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -318,17 +318,17 @@ nsContentSink::Init(nsIDocument* aDoc,
 
   mCanInterruptParser = sCanInterruptParser;
 
   return NS_OK;
 
 }
 
 NS_IMETHODIMP
-nsContentSink::StyleSheetLoaded(nsICSSStyleSheet* aSheet,
+nsContentSink::StyleSheetLoaded(nsCSSStyleSheet* aSheet,
                                 PRBool aWasAlternate,
                                 nsresult aStatus)
 {
   if (!aWasAlternate) {
     NS_ASSERTION(mPendingSheetCount > 0, "How'd that happen?");
     --mPendingSheetCount;
 
     if (mPendingSheetCount == 0 &&
--- a/content/base/src/nsContentSink.h
+++ b/content/base/src/nsContentSink.h
@@ -122,17 +122,17 @@ class nsContentSink : public nsICSSLoade
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsContentSink,
                                            nsIScriptLoaderObserver)
   NS_DECL_NSISCRIPTLOADEROBSERVER
 
     // nsITimerCallback
   NS_DECL_NSITIMERCALLBACK
 
   // nsICSSLoaderObserver
-  NS_IMETHOD StyleSheetLoaded(nsICSSStyleSheet* aSheet, PRBool aWasAlternate,
+  NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet, PRBool aWasAlternate,
                               nsresult aStatus);
 
   virtual nsresult ProcessMETATag(nsIContent* aContent);
 
   // nsIContentSink implementation helpers
   NS_HIDDEN_(nsresult) WillParseImpl(void);
   NS_HIDDEN_(nsresult) WillInterruptImpl(void);
   NS_HIDDEN_(nsresult) WillResumeImpl(void);
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -4572,17 +4572,17 @@ nsContentUtils::ProcessViewportInfo(nsID
   viewportInfo.BeginReading(tip);
   tail = tip;
   viewportInfo.EndReading(end);
 
   /* Read the tip to the first non-separator character. */
   while ((tip != end) && IS_SEPARATOR(*tip))
     ++tip;
 
-  /* Read through and find tokens seperated by separators. */
+  /* Read through and find tokens separated by separators. */
   while (tip != end) {
     
     /* Synchronize tip and tail. */
     tail = tip;
 
     /* Advance tip past non-separator characters. */
     while ((tip != end) && !IS_SEPARATOR(*tip))
       ++tip;
@@ -5699,17 +5699,19 @@ nsContentUtils::ReparentClonedObjectToSc
   scope = JS_GetGlobalForObject(cx, scope);
 
   nsAutoTArray<ReparentObjectData, 20> objectData;
   objectData.AppendElement(ReparentObjectData(cx, obj));
 
   while (!objectData.IsEmpty()) {
     ReparentObjectData& data = objectData[objectData.Length() - 1];
 
-    if (!data.ids && !data.index) {
+    if (!data.ids) {
+      NS_ASSERTION(!data.index, "Shouldn't have index here");
+
       // Typed arrays are special and don't need to be enumerated.
       if (js_IsTypedArray(data.obj)) {
         if (!js_ReparentTypedArrayToScope(cx, data.obj, scope)) {
           return NS_ERROR_FAILURE;
         }
 
         // No need to enumerate anything here.
         objectData.RemoveElementAt(objectData.Length() - 1);
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1978,33 +1978,29 @@ nsDocument::ResetStylesheetsToURI(nsIURI
   mozAutoDocUpdate upd(this, UPDATE_STYLE, PR_TRUE);
   
   // The stylesheets should forget us
   PRInt32 indx = mStyleSheets.Count();
   while (--indx >= 0) {
     nsIStyleSheet* sheet = mStyleSheets[indx];
     sheet->SetOwningDocument(nsnull);
 
-    PRBool applicable;
-    sheet->GetApplicable(applicable);
-    if (applicable) {
+    if (sheet->GetApplicable()) {
       RemoveStyleSheetFromStyleSets(sheet);
     }
 
     // XXX Tell observers?
   }
 
   indx = mCatalogSheets.Count();
   while (--indx >= 0) {
     nsIStyleSheet* sheet = mCatalogSheets[indx];
     sheet->SetOwningDocument(nsnull);
 
-    PRBool applicable;
-    sheet->GetApplicable(applicable);
-    if (applicable) {
+    if (sheet->GetApplicable()) {
       nsCOMPtr<nsIPresShell> shell = GetPrimaryShell();
       if (shell) {
         shell->StyleSet()->RemoveStyleSheet(nsStyleSet::eAgentSheet, sheet);
       }
     }
 
     // XXX Tell observers?
   }
@@ -2087,28 +2083,24 @@ nsDocument::FillStyleSet(nsStyleSet* aSt
   aStyleSet->AppendStyleSheet(GetAttrSheetType(), mAttrStyleSheet);
 
   aStyleSet->AppendStyleSheet(nsStyleSet::eStyleAttrSheet,
                               mStyleAttrStyleSheet);
 
   PRInt32 i;
   for (i = mStyleSheets.Count() - 1; i >= 0; --i) {
     nsIStyleSheet* sheet = mStyleSheets[i];
-    PRBool sheetApplicable;
-    sheet->GetApplicable(sheetApplicable);
-    if (sheetApplicable) {
+    if (sheet->GetApplicable()) {
       aStyleSet->AddDocStyleSheet(sheet, this);
     }
   }
 
   for (i = mCatalogSheets.Count() - 1; i >= 0; --i) {
     nsIStyleSheet* sheet = mCatalogSheets[i];
-    PRBool sheetApplicable;
-    sheet->GetApplicable(sheetApplicable);
-    if (sheetApplicable) {
+    if (sheet->GetApplicable()) {
       aStyleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, sheet);
     }
   }
 }
 
 nsresult
 nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
                               nsILoadGroup* aLoadGroup,
@@ -3369,20 +3361,17 @@ nsDocument::AddStyleSheetToStyleSets(nsI
 
 void
 nsDocument::AddStyleSheet(nsIStyleSheet* aSheet)
 {
   NS_PRECONDITION(aSheet, "null arg");
   mStyleSheets.AppendObject(aSheet);
   aSheet->SetOwningDocument(this);
 
-  PRBool applicable;
-  aSheet->GetApplicable(applicable);
-
-  if (applicable) {
+  if (aSheet->GetApplicable()) {
     AddStyleSheetToStyleSets(aSheet);
   }
 
   NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetAdded, (this, aSheet, PR_TRUE));
 }
 
 void
 nsDocument::RemoveStyleSheetFromStyleSets(nsIStyleSheet* aSheet)
@@ -3400,19 +3389,17 @@ nsDocument::RemoveStyleSheet(nsIStyleShe
   nsCOMPtr<nsIStyleSheet> sheet = aSheet; // hold ref so it won't die too soon
 
   if (!mStyleSheets.RemoveObject(aSheet)) {
     NS_NOTREACHED("stylesheet not found");
     return;
   }
 
   if (!mIsGoingAway) {
-    PRBool applicable = PR_TRUE;
-    aSheet->GetApplicable(applicable);
-    if (applicable) {
+    if (aSheet->GetApplicable()) {
       RemoveStyleSheetFromStyleSets(aSheet);
     }
 
     NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetRemoved, (this, aSheet, PR_TRUE));
   }
 
   aSheet->SetOwningDocument(nsnull);
 }
@@ -3438,19 +3425,17 @@ nsDocument::UpdateStyleSheets(nsCOMArray
     PRInt32 oldIndex = mStyleSheets.IndexOf(oldSheet);
     RemoveStyleSheet(oldSheet);  // This does the right notifications
 
     // Now put the new one in its place.  If it's null, just ignore it.
     nsIStyleSheet* newSheet = aNewSheets[i];
     if (newSheet) {
       mStyleSheets.InsertObjectAt(newSheet, oldIndex);
       newSheet->SetOwningDocument(this);
-      PRBool applicable = PR_TRUE;
-      newSheet->GetApplicable(applicable);
-      if (applicable) {
+      if (newSheet->GetApplicable()) {
         AddStyleSheetToStyleSets(newSheet);
       }
 
       NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetAdded, (this, newSheet, PR_TRUE));
     }
   }
 
   EndUpdate(UPDATE_STYLE);
@@ -3459,20 +3444,17 @@ nsDocument::UpdateStyleSheets(nsCOMArray
 void
 nsDocument::InsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex)
 {
   NS_PRECONDITION(aSheet, "null ptr");
   mStyleSheets.InsertObjectAt(aSheet, aIndex);
 
   aSheet->SetOwningDocument(this);
 
-  PRBool applicable;
-  aSheet->GetApplicable(applicable);
-
-  if (applicable) {
+  if (aSheet->GetApplicable()) {
     AddStyleSheetToStyleSets(aSheet);
   }
 
   NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetAdded, (this, aSheet, PR_TRUE));
 }
 
 
 void
@@ -3515,20 +3497,17 @@ nsDocument::GetCatalogStyleSheetAt(PRInt
 }
 
 void
 nsDocument::AddCatalogStyleSheet(nsIStyleSheet* aSheet)
 {
   mCatalogSheets.AppendObject(aSheet);
   aSheet->SetOwningDocument(this);
 
-  PRBool applicable;
-  aSheet->GetApplicable(applicable);
-                                                                                
-  if (applicable) {
+  if (aSheet->GetApplicable()) {
     // This is like |AddStyleSheetToStyleSets|, but for an agent sheet.
     nsCOMPtr<nsIPresShell> shell = GetPrimaryShell();
     if (shell) {
       shell->StyleSet()->AppendStyleSheet(nsStyleSet::eAgentSheet, aSheet);
     }
   }
                                                                                 
   NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetAdded, (this, aSheet, PR_FALSE));
@@ -3539,29 +3518,28 @@ nsDocument::EnsureCatalogStyleSheet(cons
 {
   mozilla::css::Loader* cssLoader = CSSLoader();
   if (cssLoader->GetEnabled()) {
     PRInt32 sheetCount = GetNumberOfCatalogStyleSheets();
     for (PRInt32 i = 0; i < sheetCount; i++) {
       nsIStyleSheet* sheet = GetCatalogStyleSheetAt(i);
       NS_ASSERTION(sheet, "unexpected null stylesheet in the document");
       if (sheet) {
-        nsCOMPtr<nsIURI> uri;
-        sheet->GetSheetURI(getter_AddRefs(uri));
+        nsCOMPtr<nsIURI> uri = sheet->GetSheetURI();
         nsCAutoString uriStr;
         uri->GetSpec(uriStr);
         if (uriStr.Equals(aStyleSheetURI))
           return;
       }
     }
 
     nsCOMPtr<nsIURI> uri;
     NS_NewURI(getter_AddRefs(uri), aStyleSheetURI);
     if (uri) {
-      nsCOMPtr<nsICSSStyleSheet> sheet;
+      nsRefPtr<nsCSSStyleSheet> sheet;
       cssLoader->LoadSheetSync(uri, PR_TRUE, PR_TRUE, getter_AddRefs(sheet));
       if (sheet) {
         BeginUpdate(UPDATE_STYLE);
         AddCatalogStyleSheet(sheet);
         EndUpdate(UPDATE_STYLE);
       }
     }
   }
@@ -6220,26 +6198,31 @@ nsDocument::CreateEventGroup(nsIDOMEvent
   NS_ADDREF(*aInstancePtrResult);
 
   return NS_OK;
 }
 
 void
 nsDocument::FlushPendingNotifications(mozFlushType aType)
 {
-  nsCOMPtr<nsIContentSink> sink;
-  if (mParser) {
-    sink = mParser->GetContentSink();
-  } else {
-    sink = do_QueryReferent(mWeakSink);
-  }
-  // Determine if it is safe to flush the sink notifications
-  // by determining if it safe to flush all the presshells.
-  if (sink && (aType == Flush_Content || IsSafeToFlush())) {
-    sink->FlushPendingNotifications(aType);
+  if (mParser || mWeakSink) {
+    nsCOMPtr<nsIContentSink> sink;
+    if (mParser) {
+      sink = mParser->GetContentSink();
+    } else {
+      sink = do_QueryReferent(mWeakSink);
+      if (!sink) {
+        mWeakSink = nsnull;
+      }
+    }
+    // Determine if it is safe to flush the sink notifications
+    // by determining if it safe to flush all the presshells.
+    if (sink && (aType == Flush_Content || IsSafeToFlush())) {
+      sink->FlushPendingNotifications(aType);
+    }
   }
 
   // Should we be flushing pending binding constructors in here?
 
   if (aType <= Flush_ContentAndNotify) {
     // Nothing to do here
     return;
   }
@@ -7580,17 +7563,17 @@ namespace {
 
 /**
  * Stub for LoadSheet(), since all we want is to get the sheet into
  * the CSSLoader's style cache
  */
 class StubCSSLoaderObserver : public nsICSSLoaderObserver {
 public:
   NS_IMETHOD
-  StyleSheetLoaded(nsICSSStyleSheet*, PRBool, nsresult)
+  StyleSheetLoaded(nsCSSStyleSheet*, PRBool, nsresult)
   {
     return NS_OK;
   }
   NS_DECL_ISUPPORTS
 };
 NS_IMPL_ISUPPORTS1(StubCSSLoaderObserver, nsICSSLoaderObserver)
 
 }
@@ -7604,17 +7587,17 @@ nsDocument::PreloadStyle(nsIURI* uri, co
   // Charset names are always ASCII.
   CSSLoader()->LoadSheet(uri, NodePrincipal(),
                          NS_LossyConvertUTF16toASCII(charset),
                          obs);
 }
 
 nsresult
 nsDocument::LoadChromeSheetSync(nsIURI* uri, PRBool isAgentSheet,
-                                nsICSSStyleSheet** sheet)
+                                nsCSSStyleSheet** sheet)
 {
   return CSSLoader()->LoadSheetSync(uri, isAgentSheet, isAgentSheet, sheet);
 }
 
 class nsDelayedEventDispatcher : public nsRunnable
 {
 public:
   nsDelayedEventDispatcher(nsTArray<nsCOMPtr<nsIDocument> >& aDocuments)
@@ -7740,44 +7723,37 @@ nsIDocument::CreateStaticClone(nsISuppor
   nsCOMPtr<nsIDocument> clonedDoc;
   if (NS_SUCCEEDED(rv)) {
     clonedDoc = do_QueryInterface(clonedNode);
     nsCOMPtr<nsIDOMDocument> clonedDOMDoc = do_QueryInterface(clonedDoc);
     if (clonedDOMDoc) {
       clonedDoc->mOriginalDocument = this;
       PRInt32 sheetsCount = GetNumberOfStyleSheets();
       for (PRInt32 i = 0; i < sheetsCount; ++i) {
-        nsCOMPtr<nsICSSStyleSheet> sheet =
-          do_QueryInterface(GetStyleSheetAt(i));
+        nsRefPtr<nsCSSStyleSheet> sheet = do_QueryObject(GetStyleSheetAt(i));
         if (sheet) {
-          PRBool applicable = PR_TRUE;
-          sheet->GetApplicable(applicable);
-          if (applicable) {
-            nsCOMPtr<nsICSSStyleSheet> clonedSheet;
-            sheet->Clone(nsnull, nsnull, clonedDoc, nsnull,
-                         getter_AddRefs(clonedSheet));
+          if (sheet->GetApplicable()) {
+            nsRefPtr<nsCSSStyleSheet> clonedSheet =
+              sheet->Clone(nsnull, nsnull, clonedDoc, nsnull);
             NS_WARN_IF_FALSE(clonedSheet, "Cloning a stylesheet didn't work!");
             if (clonedSheet) {
               clonedDoc->AddStyleSheet(clonedSheet);
             }
           }
         }
       }
 
       sheetsCount = GetNumberOfCatalogStyleSheets();
       for (PRInt32 i = 0; i < sheetsCount; ++i) {
-        nsCOMPtr<nsICSSStyleSheet> sheet =
-          do_QueryInterface(GetCatalogStyleSheetAt(i));
+        nsRefPtr<nsCSSStyleSheet> sheet =
+          do_QueryObject(GetCatalogStyleSheetAt(i));
         if (sheet) {
-          PRBool applicable = PR_TRUE;
-          sheet->GetApplicable(applicable);
-          if (applicable) {
-            nsCOMPtr<nsICSSStyleSheet> clonedSheet;
-            sheet->Clone(nsnull, nsnull, clonedDoc, nsnull,
-                         getter_AddRefs(clonedSheet));
+          if (sheet->GetApplicable()) {
+            nsRefPtr<nsCSSStyleSheet> clonedSheet =
+              sheet->Clone(nsnull, nsnull, clonedDoc, nsnull);
             NS_WARN_IF_FALSE(clonedSheet, "Cloning a stylesheet didn't work!");
             if (clonedSheet) {
               clonedDoc->AddCatalogStyleSheet(clonedSheet);
             }
           }
         }
       }
     }
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -914,17 +914,17 @@ public:
 
   void MaybeEndOutermostXBLUpdate();
 
   virtual void MaybePreLoadImage(nsIURI* uri);
 
   virtual void PreloadStyle(nsIURI* uri, const nsAString& charset);
 
   virtual nsresult LoadChromeSheetSync(nsIURI* uri, PRBool isAgentSheet,
-                                       nsICSSStyleSheet** sheet);
+                                       nsCSSStyleSheet** sheet);
 
   virtual nsISupports* GetCurrentContentSink();
 
   virtual PRInt32 GetDocumentState();
 
   virtual void RegisterFileDataUri(nsACString& aUri);
 
   // Only BlockOnload should call this!
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -99,17 +99,16 @@
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsNetUtil.h"
 
 #include "nsGkAtoms.h"
 #include "nsINameSpaceManager.h"
 
 #include "nsThreadUtils.h"
-#include "nsICSSStyleSheet.h"
 #include "nsIContentViewer.h"
 #include "nsIView.h"
 
 #include "nsIDOMChromeWindow.h"
 
 #ifdef MOZ_WIDGET_GTK2
 #include "mozcontainer.h"
 
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -5067,17 +5067,17 @@ nsGenericElement::List(FILE* out, PRInt3
   mNodeInfo->GetQualifiedName(buf);
   fputs(NS_LossyConvertUTF16toASCII(buf).get(), out);
 
   fprintf(out, "@%p", (void *)this);
 
   ListAttributes(out);
 
   fprintf(out, " intrinsicstate=[%08x]", IntrinsicState());
-  fprintf(out, " flags=[%08x]", GetFlags());
+  fprintf(out, " flags=[%08x]", static_cast<unsigned int>(GetFlags()));
   fprintf(out, " primaryframe=%p", static_cast<void*>(GetPrimaryFrame()));
   fprintf(out, " refcount=%d<", mRefCnt.get());
 
   PRUint32 i, length = GetChildCount();
   if (length > 0) {
     fputs("\n", out);
 
     for (i = 0; i < length; ++i) {
--- a/content/base/src/nsStyleLinkElement.cpp
+++ b/content/base/src/nsStyleLinkElement.cpp
@@ -42,17 +42,17 @@
  * be subclassed by various content nodes that want to load
  * stylesheets (<style>, <link>, processing instructions, etc).
  */
 
 #include "nsStyleLinkElement.h"
 
 #include "nsIContent.h"
 #include "nsCSSLoader.h"
-#include "nsICSSStyleSheet.h"
+#include "nsCSSStyleSheet.h"
 #include "nsIDocument.h"
 #include "nsIDOMComment.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMStyleSheet.h"
 #include "nsIDOMText.h"
 #include "nsIUnicharInputStream.h"
 #include "nsISimpleUnicharStreamFactory.h"
 #include "nsNetUtil.h"
@@ -72,23 +72,23 @@ nsStyleLinkElement::nsStyleLinkElement()
 nsStyleLinkElement::~nsStyleLinkElement()
 {
   nsStyleLinkElement::SetStyleSheet(nsnull);
 }
 
 NS_IMETHODIMP 
 nsStyleLinkElement::SetStyleSheet(nsIStyleSheet* aStyleSheet)
 {
-  nsCOMPtr<nsICSSStyleSheet> cssSheet = do_QueryInterface(mStyleSheet);
+  nsRefPtr<nsCSSStyleSheet> cssSheet = do_QueryObject(mStyleSheet);
   if (cssSheet) {
     cssSheet->SetOwningNode(nsnull);
   }
 
   mStyleSheet = aStyleSheet;
-  cssSheet = do_QueryInterface(mStyleSheet);
+  cssSheet = do_QueryObject(mStyleSheet);
   if (cssSheet) {
     nsCOMPtr<nsIDOMNode> node;
     CallQueryInterface(this,
                        static_cast<nsIDOMNode**>(getter_AddRefs(node)));
     if (node) {
       cssSheet->SetOwningNode(node);
     }
   }
@@ -243,19 +243,17 @@ nsStyleLinkElement::DoUpdateStyleSheet(n
   if (!doc || !doc->CSSLoader()->GetEnabled()) {
     return NS_OK;
   }
 
   PRBool isInline;
   nsCOMPtr<nsIURI> uri = GetStyleSheetURL(&isInline);
 
   if (!aForceUpdate && mStyleSheet && !isInline && uri) {
-    nsCOMPtr<nsIURI> oldURI;
-
-    mStyleSheet->GetSheetURI(getter_AddRefs(oldURI));
+    nsCOMPtr<nsIURI> oldURI = mStyleSheet->GetSheetURI();
     if (oldURI) {
       PRBool equal;
       nsresult rv = oldURI->Equals(uri, &equal);
       if (NS_SUCCEEDED(rv) && equal) {
         return NS_OK; // We already loaded this stylesheet
       }
     }
   }
--- a/content/base/src/nsTextNode.cpp
+++ b/content/base/src/nsTextNode.cpp
@@ -231,17 +231,17 @@ nsTextNode::UnbindFromAttribute()
 void
 nsTextNode::List(FILE* out, PRInt32 aIndent) const
 {
   PRInt32 index;
   for (index = aIndent; --index >= 0; ) fputs("  ", out);
 
   fprintf(out, "Text@%p", static_cast<const void*>(this));
   fprintf(out, " intrinsicstate=[%08x]", IntrinsicState());
-  fprintf(out, " flags=[%08x]", GetFlags());
+  fprintf(out, " flags=[%08x]", static_cast<unsigned int>(GetFlags()));
   fprintf(out, " primaryframe=%p", static_cast<void*>(GetPrimaryFrame()));
   fprintf(out, " refcount=%d<", mRefCnt.get());
 
   nsAutoString tmp;
   ToCString(tmp, 0, mText.GetLength());
   fputs(NS_LossyConvertUTF16toASCII(tmp).get(), out);
 
   fputs(">\n", out);
--- a/content/base/test/file_bug416317.xhtml
+++ b/content/base/test/file_bug416317.xhtml
@@ -660,17 +660,17 @@
       t( "Broken Selector", "()" );
       t( "Broken Selector", "<>" );
       t( "Broken Selector", "{}" );
 
       t( "ID Selector", "#body", ["body"], false );
       t( "ID Selector w/ Element", "body#body", ["body"], false );
       t( "ID Selector w/ Element", "ul#first", [] );
       t( "ID selector with existing ID descendant", "#firstp #simon1", ["simon1"] );
-      t( "ID selector with non-existant descendant", "#firstp #foobar", [] );
+      t( "ID selector with non-existent descendant", "#firstp #foobar", [] );
 
       t( "ID selector using UTF8", "#台北Táiběi", ["台北Táiběi"] );
       t( "Multiple ID selectors using UTF8", "#台北Táiběi, #台北", ["台北Táiběi","台北"] );
       t( "Descendant ID selector using UTF8", "div #台北", ["台北"] );
       t( "Child ID selector using UTF8", "form > #台北", ["台北"] );
   
       t( "Escaped ID", "#foo\\:bar", ["foo:bar"] );
       t( "Escaped ID", "#test\\.foo\\[5\\]bar", ["test.foo[5]bar"] );
@@ -681,17 +681,17 @@
   
       t( "ID Selector, child ID present", "#form > #radio1", ["radio1"] ); // bug #267
       t( "ID Selector, not an ancestor ID", "#form #first", [] );
       t( "ID Selector, not a child ID", "#form > #option1a", [] );
       
       t( "All Children of ID", "#foo > *", ["sndp", "en", "sap"] );
       t( "All Children of ID with no children", "#firstUL > *", [] );
 
-      t( "ID selector with non-existant ancestor", "#asdfasdf #foobar", [] ); // bug #986
+      t( "ID selector with non-existent ancestor", "#asdfasdf #foobar", [] ); // bug #986
 
       //t( "body div#form", [], "ID selector within the context of another element" );
 
       t( "Class Selector", ".blog", ["mark","simon"] );
       t( "Class Selector", ".blog.link", ["simon"] );
       t( "Class Selector w/ Element", "a.blog", ["mark","simon"] );
       t( "Parent Class Selector", "p .blog", ["mark","simon"] );
   
--- a/content/base/test/test_csp_redirects.html
+++ b/content/base/test/test_csp_redirects.html
@@ -95,17 +95,17 @@ var testExpectedResults = { "font-src": 
                             "style-src-redir": false,
                             "worker": true,
                             "worker-redir": false,
                             "xhr-src": true,
                             "xhr-src-redir": false,
                           };
 
 // takes the name of the test, the URL that was tested, and whether the
-// load occured
+// load occurred
 var testResult = function(testName, url, result) {
   netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
   log("  testName: "+testName+", result: "+result+", expected: "+testExpectedResults[testName]+"\n");
   is(result, testExpectedResults[testName], testName+" test: "+url);
 
  // mark test as completed
   testExpectedResults[testName] = "completed";
 
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -869,24 +869,16 @@ NS_METHOD nsDOMEvent::DuplicatePrivateDa
       dragEvent->acceptActivation = oldDragEvent->acceptActivation;
       dragEvent->relatedTarget = oldDragEvent->relatedTarget;
       dragEvent->button = oldDragEvent->button;
       static_cast<nsMouseEvent*>(dragEvent)->inputSource =
         static_cast<nsMouseEvent*>(oldDragEvent)->inputSource;
       newEvent = dragEvent;
       break;
     }
-    case NS_MENU_EVENT:
-    {
-      newEvent = new nsMenuEvent(PR_FALSE, msg, nsnull);
-      NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
-      static_cast<nsMenuEvent*>(newEvent)->mCommand =
-        static_cast<nsMenuEvent*>(mEvent)->mCommand;
-      break;
-    }
     case NS_SCRIPT_ERROR_EVENT:
     {
       newEvent = new nsScriptErrorEvent(PR_FALSE, msg);
       NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
       static_cast<nsScriptErrorEvent*>(newEvent)->lineNr =
         static_cast<nsScriptErrorEvent*>(mEvent)->lineNr;
       break;
     }
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -183,18 +183,17 @@ static nscoord gPixelScrollDeltaY = 0;
 static PRUint32 gPixelScrollDeltaTimeout = 0;
 
 static nscoord
 GetScrollableLineHeight(nsIFrame* aTargetFrame);
 
 static inline PRBool
 IsMouseEventReal(nsEvent* aEvent)
 {
-  NS_ABORT_IF_FALSE(aEvent->eventStructType == NS_MOUSE_EVENT,
-                    "Not a mouse event");
+  NS_ABORT_IF_FALSE(NS_IS_MOUSE_EVENT_STRUCT(aEvent), "Not a mouse event");
   // Return true if not synthesized.
   return static_cast<nsMouseEvent*>(aEvent)->reason == nsMouseEvent::eReal;
 }
 
 #ifdef DEBUG_DOCSHELL_FOCUS
 static void
 PrintDocTree(nsIDocShellTreeItem* aParentItem, int aLevel)
 {
@@ -1733,16 +1732,17 @@ nsEventStateManager::FireContextClick()
       nsCOMPtr<nsIFormControl> formCtrl(do_QueryInterface(mGestureDownContent));
 
       if (formCtrl) {
         // of all form controls, only ones dealing with text are
         // allowed to have context menus
         PRInt32 type = formCtrl->GetType();
 
         allowedToDispatch = (type == NS_FORM_INPUT_TEXT ||
+                             type == NS_FORM_INPUT_TEL ||
                              type == NS_FORM_INPUT_PASSWORD ||
                              type == NS_FORM_INPUT_FILE ||
                              type == NS_FORM_TEXTAREA);
       }
       else if (tag == nsGkAtoms::applet ||
                tag == nsGkAtoms::embed  ||
                tag == nsGkAtoms::object) {
         allowedToDispatch = PR_FALSE;
@@ -2042,17 +2042,17 @@ nsEventStateManager::DetermineDragTarget
   PRBool canDrag;
   nsCOMPtr<nsIContent> dragDataNode;
   nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(container);
   if (dsti) {
     PRInt32 type = -1;
     if (NS_SUCCEEDED(dsti->GetItemType(&type)) &&
         type != nsIDocShellTreeItem::typeChrome) {
       // mGestureDownContent is the node where the mousedown event for the drag
-      // occured, and aSelectionTarget is the node to use when a selection is used
+      // occurred, and aSelectionTarget is the node to use when a selection is used
       nsresult rv =
         nsContentAreaDragDrop::GetDragData(window, mGestureDownContent,
                                            aSelectionTarget, mGestureDownAlt,
                                            aDataTransfer, &canDrag, aIsSelection,
                                            getter_AddRefs(dragDataNode));
       if (NS_FAILED(rv) || !canDrag)
         return;
     }
--- a/content/events/test/test_dragstart.html
+++ b/content/events/test/test_dragstart.html
@@ -27,17 +27,17 @@ function runTests()
   synthesizeMouse(draggable, 14, 14, { type: "mousemove" });
   // drags are asynchronous on Linux, so this extra event is needed to make
   // sure the drag gets processed
   synthesizeMouse(draggable, 15, 15, { type: "mousemove" });
 }
 
 function afterDragTests()
 {
-  // the dragstart should have occured due to moving the mouse. gDataTransfer
+  // the dragstart should have occurred due to moving the mouse. gDataTransfer
   // caches the dataTransfer that was used, however it should now be empty and
   // be read only.
   ok(gDataTransfer instanceof DataTransfer, "DataTransfer after dragstart event");
   checkTypes(gDataTransfer, [], 0, "after dragstart event");
 
   expectError(function() gDataTransfer.setData("text/plain", "Some Text"),
               "NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR", "setData when read only");
   expectError(function() gDataTransfer.clearData("text/plain"),
@@ -152,17 +152,17 @@ function test_DataTransfer(dt)
   is(dt.getData("text/plain"), "", "empty data is empty");
 
   // calling setDataAt requires an index that is 0 <= index <= dt.itemCount
   expectError(function() dt.mozSetDataAt("text/plain", "Some Text", 1),
               "NS_ERROR_DOM_INDEX_SIZE_ERR", "setDataAt index too high");
 
   is(dt.mozUserCancelled, false, "userCancelled");
 
-  // because an exception occured, the data should not have been added
+  // because an exception occurred, the data should not have been added
   is(dt.mozItemCount, 0, "empty setDataAt index too high itemCount");
   dt.getData("text/plain", "", "empty setDataAt index too high getData");
 
   // if the type is '', do nothing, or return ''
   dt.setData("", "Invalid Type");
   is(dt.types.length, 0, "invalid type setData");
   is(dt.getData(""), "", "invalid type getData"),
   dt.mozSetDataAt("", "Invalid Type", 0);
--- a/content/html/content/public/nsIFormControl.h
+++ b/content/html/content/public/nsIFormControl.h
@@ -53,25 +53,26 @@ class nsFormSubmission;
 #define NS_FORM_INPUT_CHECKBOX  6
 #define NS_FORM_INPUT_FILE      7
 #define NS_FORM_INPUT_HIDDEN    8
 #define NS_FORM_INPUT_RESET     9
 #define NS_FORM_INPUT_IMAGE    10
 #define NS_FORM_INPUT_PASSWORD 11
 #define NS_FORM_INPUT_RADIO    12
 #define NS_FORM_INPUT_SUBMIT   13
-#define NS_FORM_INPUT_TEXT     14
-#define NS_FORM_LABEL          15
-#define NS_FORM_OPTION         16
-#define NS_FORM_OPTGROUP       17
-#define NS_FORM_OUTPUT         18
-#define NS_FORM_LEGEND         19
-#define NS_FORM_SELECT         20
-#define NS_FORM_TEXTAREA       21
-#define NS_FORM_OBJECT         22
+#define NS_FORM_INPUT_TEL      14
+#define NS_FORM_INPUT_TEXT     15
+#define NS_FORM_LABEL          16
+#define NS_FORM_OPTION         17
+#define NS_FORM_OPTGROUP       18
+#define NS_FORM_OUTPUT         19
+#define NS_FORM_LEGEND         20
+#define NS_FORM_SELECT         21
+#define NS_FORM_TEXTAREA       22
+#define NS_FORM_OBJECT         23
 
 #define NS_IFORMCONTROL_IID   \
 { 0x52dc1f0d, 0x1683, 0x4dd7, \
  { 0xae, 0x0a, 0xc4, 0x76, 0x10, 0x64, 0x2f, 0xa8 } }
 
 /**
  * Interface which all form controls (e.g. buttons, checkboxes, text,
  * radio buttons, select, etc) implement in addition to their dom specific
@@ -153,13 +154,27 @@ public:
   virtual PRBool AllowDrop() = 0;
 
   /**
    * Returns true if this is a control which submits the form when
    * activated by the user.
    * @return Whether this is a submit control.
    */
   virtual PRBool IsSubmitControl() const = 0;
+
+  /**
+   * Returns true if this is a control which has a text field.
+   * @param  aExcludePassword  to have NS_FORM_INPUT_PASSWORD returning false.
+   * @return Whether this is a text control.
+   */
+  virtual PRBool IsTextControl(PRBool aExcludePassword) const = 0;
+
+  /**
+   * Returns true if this is a control which has a single line text field.
+   * @param  aExcludePassword  to have NS_FORM_INPUT_PASSWORD returning false.
+   * @return Whether this is a single line text control.
+   */
+  virtual PRBool IsSingleLineTextControl(PRBool aExcludePassword) const = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIFormControl, NS_IFORMCONTROL_IID)
 
 #endif /* nsIFormControl_h___ */
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -803,22 +803,23 @@ nsGenericHTMLElement::GetSpellcheck(PRBo
 
   // Is this a multiline plaintext input?
   PRInt32 controlType = formControl->GetType();
   if (controlType == NS_FORM_TEXTAREA) {
     *aSpellcheck = PR_TRUE;             // Spellchecked by default
     return NS_OK;
   }
 
-  // Is this anything other than a single-line plaintext input?
+  // Is this anything other than an input text?
+  // Other inputs are not spellchecked.
   if (controlType != NS_FORM_INPUT_TEXT) {
     return NS_OK;                       // Not spellchecked by default
   }
 
-  // Does the user want single-line inputs spellchecked by default?
+  // Does the user want input text spellchecked by default?
   // NOTE: Do not reflect a pref value of 0 back to the DOM getter.
   // The web page should not know if the user has disabled spellchecking.
   // We'll catch this in the editor itself.
   PRInt32 spellcheckLevel =
     nsContentUtils::GetIntPref("layout.spellcheckDefault", 1);
   if (spellcheckLevel == 2) {           // "Spellcheck multi- and single-line"
     *aSpellcheck = PR_TRUE;             // Spellchecked by default
   }
@@ -1609,18 +1610,17 @@ nsGenericHTMLFormElement::UpdateEditable
   nsIContent *parent = GetParent();
 
   if (parent && parent->HasFlag(NODE_IS_EDITABLE)) {
     SetEditableFlag(PR_TRUE);
     return;
   }
 
   PRInt32 formType = GetType();
-  if (formType != NS_FORM_INPUT_PASSWORD && formType != NS_FORM_INPUT_TEXT &&
-      formType != NS_FORM_TEXTAREA) {
+  if (!IsTextControl(PR_FALSE)) {
     SetEditableFlag(PR_FALSE);
     return;
   }
 
   // If not contentEditable we still need to check the readonly attribute.
   PRBool roState;
   GetBoolAttr(nsGkAtoms::readonly, &roState);
 
@@ -2606,16 +2606,33 @@ PRBool
 nsGenericHTMLFormElement::IsSubmitControl() const
 {
   PRInt32 type = GetType();
   return type == NS_FORM_INPUT_SUBMIT ||
          type == NS_FORM_BUTTON_SUBMIT ||
          type == NS_FORM_INPUT_IMAGE;
 }
 
+PRBool
+nsGenericHTMLFormElement::IsTextControl(PRBool aExcludePassword) const
+{
+  PRInt32 type = GetType();
+  return nsGenericHTMLFormElement::IsSingleLineTextControl(aExcludePassword) ||
+         type == NS_FORM_TEXTAREA;
+}
+
+PRBool
+nsGenericHTMLFormElement::IsSingleLineTextControl(PRBool aExcludePassword) const
+{
+  PRInt32 type = GetType();
+  return type == NS_FORM_INPUT_TEXT ||
+         type == NS_FORM_INPUT_TEL ||
+         (!aExcludePassword && type == NS_FORM_INPUT_PASSWORD);
+}
+
 PRInt32
 nsGenericHTMLFormElement::IntrinsicState() const
 {
   // If you add attribute-dependent states here, you need to add them them to
   // AfterSetAttr too.  And add them to AfterSetAttr for all subclasses that
   // implement IntrinsicState() and are affected by that attribute.
   PRInt32 state = nsGenericHTMLElement::IntrinsicState();
 
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -784,16 +784,20 @@ public:
   }
   virtual PRBool AllowDrop()
   {
     return PR_TRUE;
   }
   
   virtual PRBool IsSubmitControl() const;
 
+          PRBool IsTextControl(PRBool aExcludePassword) const;
+
+          PRBool IsSingleLineTextControl(PRBool aExcludePassword) const;
+
   // nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               PRBool aCompileEventHandlers);
   virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
                               PRBool aNullParent = PR_TRUE);
   virtual PRUint32 GetDesiredIMEState();
   virtual PRInt32 IntrinsicState() const;
--- a/content/html/content/src/nsHTMLFormElement.cpp
+++ b/content/html/content/src/nsHTMLFormElement.cpp
@@ -182,16 +182,17 @@ ShouldBeInElements(nsIFormControl* aForm
   case NS_FORM_INPUT_CHECKBOX :
   case NS_FORM_INPUT_FILE :
   case NS_FORM_INPUT_HIDDEN :
   case NS_FORM_INPUT_RESET :
   case NS_FORM_INPUT_PASSWORD :
   case NS_FORM_INPUT_RADIO :
   case NS_FORM_INPUT_SUBMIT :
   case NS_FORM_INPUT_TEXT :
+  case NS_FORM_INPUT_TEL :
   case NS_FORM_SELECT :
   case NS_FORM_TEXTAREA :
   case NS_FORM_FIELDSET :
   case NS_FORM_OBJECT :
   case NS_FORM_OUTPUT :
     return PR_TRUE;
   }
 
@@ -1465,19 +1466,18 @@ nsHTMLFormElement::IsDefaultSubmitElemen
 
 PRBool
 nsHTMLFormElement::HasSingleTextControl() const
 {
   // Input text controls are always in the elements list.
   PRUint32 numTextControlsFound = 0;
   PRUint32 length = mControls->mElements.Length();
   for (PRUint32 i = 0; i < length && numTextControlsFound < 2; ++i) {
-    PRInt32 type = mControls->mElements[i]->GetType();
-    if (type == NS_FORM_INPUT_TEXT || type == NS_FORM_INPUT_PASSWORD) {
-        numTextControlsFound++;
+    if (mControls->mElements[i]->IsSingleLineTextControl(PR_FALSE)) {
+      numTextControlsFound++;
     }
   }
   return numTextControlsFound == 1;
 }
 
 NS_IMETHODIMP
 nsHTMLFormElement::GetEncoding(nsAString& aEncoding)
 {
--- a/content/html/content/src/nsHTMLFormElement.h
+++ b/content/html/content/src/nsHTMLFormElement.h
@@ -183,17 +183,17 @@ public:
    *
    * @param aElement the element to remove
    * @param aNotify If true, send nsIDocumentObserver notifications as needed.
    * @return NS_OK if the element was successfully removed.
    */
   nsresult RemoveElement(nsGenericHTMLFormElement* aElement, PRBool aNotify);
 
   /**
-   * Remove an element from the lookup table mainted by the form.
+   * Remove an element from the lookup table maintained by the form.
    * We can't fold this method into RemoveElement() because when
    * RemoveElement() is called it doesn't know if the element is
    * removed because the id attribute has changed, or bacause the
    * name attribute has changed.
    *
    * @param aElement the element to remove
    * @param aName the name or id of the element to remove
    * @return NS_OK if the element was successfully removed.
@@ -205,17 +205,17 @@ public:
    *
    * @param aElement the element to add
    * @param aNotify If true, send nsIDocumentObserver notifications as needed.
    * @return NS_OK if the element was successfully added
    */
   nsresult AddElement(nsGenericHTMLFormElement* aElement, PRBool aNotify);
 
   /**    
-   * Add an element to the lookup table mainted by the form.
+   * Add an element to the lookup table maintained by the form.
    *
    * We can't fold this method into AddElement() because when
    * AddElement() is called, the form control has no
    * attributes.  The name or id attributes of the form control
    * are used as a key into the table.
    */
   nsresult AddElementToTable(nsGenericHTMLFormElement* aChild,
                              const nsAString& aName);
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -158,22 +158,23 @@ static const nsAttrValue::EnumTable kInp
   { "checkbox", NS_FORM_INPUT_CHECKBOX },
   { "file", NS_FORM_INPUT_FILE },
   { "hidden", NS_FORM_INPUT_HIDDEN },
   { "reset", NS_FORM_INPUT_RESET },
   { "image", NS_FORM_INPUT_IMAGE },
   { "password", NS_FORM_INPUT_PASSWORD },
   { "radio", NS_FORM_INPUT_RADIO },
   { "submit", NS_FORM_INPUT_SUBMIT },
+  { "tel", NS_FORM_INPUT_TEL },
   { "text", NS_FORM_INPUT_TEXT },
   { 0 }
 };
 
 // Default type is 'text'.
-static const nsAttrValue::EnumTable* kInputDefaultType = &kInputTypeTable[9];
+static const nsAttrValue::EnumTable* kInputDefaultType = &kInputTypeTable[10];
 
 #define NS_INPUT_ELEMENT_STATE_IID                 \
 { /* dc3b3d14-23e2-4479-b513-7b369343e3a0 */       \
   0xdc3b3d14,                                      \
   0x23e2,                                          \
   0x4479,                                          \
   {0xb5, 0x13, 0x7b, 0x36, 0x93, 0x43, 0xe3, 0xa0} \
 }
@@ -557,16 +558,17 @@ nsHTMLInputElement::Clone(nsINodeInfo *a
 
   nsCOMPtr<nsINode> kungFuDeathGrip = it;
   nsresult rv = CopyInnerTo(it);
   NS_ENSURE_SUCCESS(rv, rv);
 
   switch (mType) {
     case NS_FORM_INPUT_TEXT:
     case NS_FORM_INPUT_PASSWORD:
+    case NS_FORM_INPUT_TEL:
       if (GET_BOOLBIT(mBitField, BF_VALUE_CHANGED)) {
         // We don't have our default value anymore.  Set our value on
         // the clone.
         // XXX GetValue should be const
         nsAutoString value;
         const_cast<nsHTMLInputElement*>(this)->GetValue(value);
         // SetValueInternal handles setting the VALUE_CHANGED bit for us
         it->SetValueInternal(value, nsnull, PR_FALSE);
@@ -656,16 +658,17 @@ nsHTMLInputElement::AfterSetAttr(PRInt32
     //
     // We only really need to call reset for the value so that the text control
     // knows the new value.  No other reason.
     //
     if (aName == nsGkAtoms::value &&
         !GET_BOOLBIT(mBitField, BF_VALUE_CHANGED) &&
         (mType == NS_FORM_INPUT_TEXT ||
          mType == NS_FORM_INPUT_PASSWORD ||
+         mType == NS_FORM_INPUT_TEL ||
          mType == NS_FORM_INPUT_FILE)) {
       Reset();
     }
     //
     // Checked must be set no matter what type of control it is, since
     // GetChecked() must reflect the new value
     if (aName == nsGkAtoms::checked &&
         !GET_BOOLBIT(mBitField, BF_CHECKED_CHANGED)) {
@@ -691,21 +694,22 @@ nsHTMLInputElement::AfterSetAttr(PRInt32
 
       if (!aValue) {
         // We're now a text input.  Note that we have to handle this manually,
         // since removing an attribute (which is what happened, since aValue is
         // null) doesn't call ParseAttribute.
         mType = kInputDefaultType->value;
       }
     
-      // If we are changing type from File/Text/Passwd to other input types
-      // we need save the mValue into value attribute
+      // If we are changing type from File/Text/Tel/Passwd
+      // to other input types we need save the mValue into value attribute
       if (mValue &&
           mType != NS_FORM_INPUT_TEXT &&
           mType != NS_FORM_INPUT_PASSWORD &&
+          mType != NS_FORM_INPUT_TEL &&
           mType != NS_FORM_INPUT_FILE) {
         SetAttr(kNameSpaceID_None, nsGkAtoms::value,
                 NS_ConvertUTF8toUTF16(mValue), PR_FALSE);
         if (mValue) {
           nsMemory::Free(mValue);
           mValue = nsnull;
         }
       }
@@ -740,20 +744,20 @@ nsHTMLInputElement::AfterSetAttr(PRInt32
                                        NS_EVENT_STATE_SUPPRESSED |
                                        NS_EVENT_STATE_LOADING |
                                        NS_EVENT_STATE_INDETERMINATE |
                                        NS_EVENT_STATE_MOZ_READONLY |
                                        NS_EVENT_STATE_MOZ_READWRITE);
       }
     }
 
-    // If readonly is changed for text and password we need to handle
+    // If readonly is changed for single line text controls, we need to handle
     // :read-only / :read-write
     if (aNotify && aName == nsGkAtoms::readonly &&
-        (mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_PASSWORD)) {
+        IsSingleLineTextControl(PR_FALSE)) {
       UpdateEditableState();
 
       nsIDocument* document = GetCurrentDoc();
       if (document) {
         mozAutoDocUpdate upd(document, UPDATE_CONTENT_STATE, PR_TRUE);
         document->ContentStatesChanged(this, nsnull,
                                        NS_EVENT_STATE_MOZ_READONLY |
                                        NS_EVENT_STATE_MOZ_READWRITE);
@@ -870,17 +874,17 @@ nsHTMLInputElement::SetSize(PRUint32 aVa
   val.AppendInt(aValue);
 
   return SetAttr(kNameSpaceID_None, nsGkAtoms::size, val, PR_TRUE);
 }
 
 NS_IMETHODIMP 
 nsHTMLInputElement::GetValue(nsAString& aValue)
 {
-  if (mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_PASSWORD) {
+  if (IsSingleLineTextControl(PR_FALSE)) {
     // No need to flush here, if there's no frame created for this
     // input yet, there won't be a value in it (that we don't already
     // have) even if we force it to be created
     nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
 
     PRBool frameOwnsValue = PR_FALSE;
     if (formControlFrame) {
       nsITextControlFrame* textControlFrame = do_QueryFrame(formControlFrame);
@@ -1007,16 +1011,24 @@ nsHTMLInputElement::MozSetFileNameArray(
     fileNames.AppendElement(aFileNames[i]);
   }
 
   SetFileNames(fileNames);
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsHTMLInputElement::MozIsTextField(PRBool aExcludePassword, PRBool* aResult)
+{
+  *aResult = IsSingleLineTextControl(aExcludePassword);
+
+  return NS_OK;
+}
+
 NS_IMETHODIMP 
 nsHTMLInputElement::SetUserInput(const nsAString& aValue)
 {
   if (!nsContentUtils::IsCallerTrustedForWrite()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   if (mType == NS_FORM_INPUT_FILE)
@@ -1137,18 +1149,17 @@ nsHTMLInputElement::UpdateFileList()
 nsresult
 nsHTMLInputElement::SetValueInternal(const nsAString& aValue,
                                      nsITextControlFrame* aFrame,
                                      PRBool aUserInput)
 {
   NS_PRECONDITION(mType != NS_FORM_INPUT_FILE,
                   "Don't call SetValueInternal for file inputs");
 
-  if (mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_PASSWORD) {
-
+  if (IsSingleLineTextControl(PR_FALSE)) {
     nsIFormControlFrame* formControlFrame = aFrame;
     if (!formControlFrame) {
       // No need to flush here, if there's no frame at this point we
       // don't need to force creation of one just to tell it about this
       // new value.
       formControlFrame = GetFormControlFrame(PR_FALSE);
     }
 
@@ -1472,17 +1483,17 @@ nsHTMLInputElement::Focus()
   }
 
   return nsGenericHTMLElement::Focus();
 }
 
 NS_IMETHODIMP
 nsHTMLInputElement::Select()
 {
-  if (mType != NS_FORM_INPUT_PASSWORD && mType != NS_FORM_INPUT_TEXT) {
+  if (!IsSingleLineTextControl(PR_FALSE)) {
     return NS_OK;
   }
 
   // XXX Bug?  We have to give the input focus before contents can be
   // selected
 
   FocusTristate state = FocusState();
   if (state == eUnfocusable) {
@@ -1761,17 +1772,17 @@ nsHTMLInputElement::PreHandleEvent(nsEve
   }
 
   // If NS_EVENT_FLAG_NO_CONTENT_DISPATCH is set we will not allow content to handle
   // this event.  But to allow middle mouse button paste to work we must allow 
   // middle clicks to go to text fields anyway.
   if (aVisitor.mEvent->flags & NS_EVENT_FLAG_NO_CONTENT_DISPATCH) {
     aVisitor.mItemFlags |= NS_NO_CONTENT_DISPATCH;
   }
-  if ((mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_PASSWORD) &&
+  if (IsSingleLineTextControl(PR_FALSE) &&
       aVisitor.mEvent->message == NS_MOUSE_CLICK &&
       aVisitor.mEvent->eventStructType == NS_MOUSE_EVENT &&
       static_cast<nsMouseEvent*>(aVisitor.mEvent)->button ==
         nsMouseEvent::eMiddleButton) {
     aVisitor.mEvent->flags &= ~NS_EVENT_FLAG_NO_CONTENT_DISPATCH;
   }
 
   // We must cache type because mType may change during JS event (bug 2369)
@@ -1841,17 +1852,17 @@ nsHTMLInputElement::PostHandleEvent(nsEv
   // Ideally we would make the default action for click and space just dispatch
   // DOMActivate, and the default action for DOMActivate flip the checkbox/
   // radio state and fire onchange.  However, for backwards compatibility, we
   // need to flip the state before firing click, and we need to fire click
   // when space is pressed.  So, we just nest the firing of DOMActivate inside
   // the click event handling, and allow cancellation of DOMActivate to cancel
   // the click.
   if (aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault &&
-      mType != NS_FORM_INPUT_TEXT &&
+      !IsSingleLineTextControl(PR_TRUE) &&
       NS_IS_MOUSE_LEFT_CLICK(aVisitor.mEvent)) {
     nsUIEvent actEvent(NS_IS_TRUSTED_EVENT(aVisitor.mEvent), NS_UI_ACTIVATE, 1);
 
     nsCOMPtr<nsIPresShell> shell = aVisitor.mPresContext->GetPresShell();
     if (shell) {
       nsEventStatus status = nsEventStatus_eIgnore;
       SET_BOOLBIT(mBitField, BF_IN_INTERNAL_ACTIVATE, PR_TRUE);
       rv = shell->HandleDOMEventWithTarget(this, &actEvent, &status);
@@ -1932,17 +1943,17 @@ nsHTMLInputElement::PostHandleEvent(nsEv
 
         case NS_FOCUS_CONTENT:
         {
           // see if we should select the contents of the textbox. This happens
           // for text and password fields when the field was focused by the
           // keyboard or a navigation, the platform allows it, and it wasn't
           // just because we raised a window.
           nsIFocusManager* fm = nsFocusManager::GetFocusManager();
-          if (fm && (mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_PASSWORD) &&
+          if (fm && IsSingleLineTextControl(PR_FALSE) &&
               !(static_cast<nsFocusEvent *>(aVisitor.mEvent))->fromRaise &&
               SelectTextFieldOnFocus()) {
             nsIDocument* document = GetCurrentDoc();
             if (document) {
               PRUint32 lastFocusMethod;
               fm->GetLastFocusMethod(document->GetWindow(), &lastFocusMethod);
               if (lastFocusMethod &
                   (nsIFocusManager::FLAG_BYKEY | nsIFocusManager::FLAG_BYMOVEFOCUS)) {
@@ -2049,16 +2060,17 @@ nsHTMLInputElement::PostHandleEvent(nsEv
            *     not submit, period.
            */
 
           if (aVisitor.mEvent->message == NS_KEY_PRESS &&
               (keyEvent->keyCode == NS_VK_RETURN ||
                keyEvent->keyCode == NS_VK_ENTER) &&
               (mType == NS_FORM_INPUT_TEXT ||
                mType == NS_FORM_INPUT_PASSWORD ||
+               mType == NS_FORM_INPUT_TEL ||
                mType == NS_FORM_INPUT_FILE)) {
 
             PRBool isButton = PR_FALSE;
             // If this is an enter on the button of a file input, don't submit
             // -- that's supposed to put up the filepicker
             if (mType == NS_FORM_INPUT_FILE) {
               nsCOMPtr<nsIContent> maybeButton =
                 do_QueryInterface(aVisitor.mEvent->originalTarget);
@@ -2324,18 +2336,17 @@ nsHTMLInputElement::GetAttributeChangeHi
              (aAttribute == nsGkAtoms::alt ||
               aAttribute == nsGkAtoms::value)) {
     // We might need to rebuild our alt text.  Just go ahead and
     // reconstruct our frame.  This should be quite rare..
     NS_UpdateHint(retval, NS_STYLE_HINT_FRAMECHANGE);
   } else if (aAttribute == nsGkAtoms::value) {
     NS_UpdateHint(retval, NS_STYLE_HINT_REFLOW);
   } else if (aAttribute == nsGkAtoms::size &&
-             (mType == NS_FORM_INPUT_TEXT ||
-              mType == NS_FORM_INPUT_PASSWORD)) {
+             IsSingleLineTextControl(PR_FALSE)) {
     NS_UpdateHint(retval, NS_STYLE_HINT_REFLOW);
   }
   return retval;
 }
 
 NS_IMETHODIMP_(PRBool)
 nsHTMLInputElement::IsAttributeMapped(const nsIAtom* aAttribute) const
 {
@@ -2365,17 +2376,17 @@ nsHTMLInputElement::GetAttributeMappingF
 // Controllers Methods
 
 NS_IMETHODIMP
 nsHTMLInputElement::GetControllers(nsIControllers** aResult)
 {
   NS_ENSURE_ARG_POINTER(aResult);
 
   //XXX: what about type "file"?
-  if (mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_PASSWORD)
+  if (IsSingleLineTextControl(PR_FALSE))
   {
     if (!mControllers)
     {
       nsresult rv;
       mControllers = do_CreateInstance(kXULControllersCID, &rv);
       NS_ENSURE_SUCCESS(rv, rv);
 
       nsCOMPtr<nsIController>
@@ -2560,16 +2571,17 @@ nsHTMLInputElement::Reset()
       PRBool resetVal;
       GetDefaultChecked(&resetVal);
       rv = DoSetChecked(resetVal);
       SetCheckedChanged(PR_FALSE);
       break;
     }
     case NS_FORM_INPUT_PASSWORD:
     case NS_FORM_INPUT_TEXT:
+    case NS_FORM_INPUT_TEL:
     {
       // If the frame is there, we have to set the value so that it will show
       // up.
       if (formControlFrame) {
         nsAutoString resetVal;
         GetDefaultValue(resetVal);
         rv = SetValue(resetVal);
       }
@@ -2697,17 +2709,17 @@ nsHTMLInputElement::SubmitNamesValues(ns
   }
 
   if (mType == NS_FORM_INPUT_HIDDEN && name.EqualsLiteral("_charset_")) {
     nsCString charset;
     aFormSubmission->GetCharset(charset);
     rv = aFormSubmission->AddNameValuePair(name,
                                            NS_ConvertASCIItoUTF16(charset));
   }
-  else if (mType == NS_FORM_INPUT_TEXT &&
+  else if (IsSingleLineTextControl(PR_TRUE) &&
            name.EqualsLiteral("isindex") &&
            aFormSubmission->SupportsIsindexSubmission()) {
     rv = aFormSubmission->AddIsindex(value);
   }
   else {
     rv = aFormSubmission->AddNameValuePair(name, value);
   }
 
@@ -2742,16 +2754,17 @@ nsHTMLInputElement::SaveState()
         }
         break;
       }
 
     // Never save passwords in session history
     case NS_FORM_INPUT_PASSWORD:
       break;
     case NS_FORM_INPUT_TEXT:
+    case NS_FORM_INPUT_TEL:
     case NS_FORM_INPUT_HIDDEN:
       {
         if (GET_BOOLBIT(mBitField, BF_VALUE_CHANGED)) {
           inputState = new nsHTMLInputElementState();
           if (!inputState) {
             return NS_ERROR_OUT_OF_MEMORY;
           }
 
@@ -2875,16 +2888,17 @@ nsHTMLInputElement::RestoreState(nsPresS
           if (inputState->IsCheckedSet()) {
             restoredCheckedState = PR_TRUE;
             DoSetChecked(inputState->GetChecked());
           }
           break;
         }
 
       case NS_FORM_INPUT_TEXT:
+      case NS_FORM_INPUT_TEL:
       case NS_FORM_INPUT_HIDDEN:
         {
           SetValueInternal(inputState->GetValue(), nsnull, PR_FALSE);
           break;
         }
       case NS_FORM_INPUT_FILE:
         {
           SetFileNames(inputState->GetFilenames());
@@ -3026,17 +3040,17 @@ nsHTMLInputElement::IsHTMLFocusable(PRBo
     return PR_TRUE;
   }
 
   if (HasAttr(kNameSpaceID_None, nsGkAtoms::disabled)) {
     *aIsFocusable = PR_FALSE;
     return PR_TRUE;
   }
 
-  if (mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_PASSWORD) {
+  if (IsSingleLineTextControl(PR_FALSE)) {
     *aIsFocusable = PR_TRUE;
     return PR_FALSE;
   }
 
   if (mType == NS_FORM_INPUT_FILE) {
     if (aTabIndex) {
       *aTabIndex = -1;
     }
@@ -3054,17 +3068,17 @@ nsHTMLInputElement::IsHTMLFocusable(PRBo
 
   if (!aTabIndex) {
     // The other controls are all focusable
     *aIsFocusable = PR_TRUE;
     return PR_FALSE;
   }
 
   // We need to set tabindex to -1 if we're not tabbable
-  if (mType != NS_FORM_INPUT_TEXT && mType != NS_FORM_INPUT_PASSWORD &&
+  if (!IsSingleLineTextControl(PR_FALSE) &&
       !(sTabFocusModel & eTabFocus_formElementsMask)) {
     *aTabIndex = -1;
   }
 
   if (mType != NS_FORM_INPUT_RADIO) {
     *aIsFocusable = PR_TRUE;
     return PR_FALSE;
   }
--- a/content/html/content/src/nsHTMLLegendElement.cpp
+++ b/content/html/content/src/nsHTMLLegendElement.cpp
@@ -101,16 +101,23 @@ public:
   }
   virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
                            nsIAtom* aPrefix, const nsAString& aValue,
                            PRBool aNotify);
   virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
                              PRBool aNotify);
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+
+protected:
+  /**
+   * Get the fieldset content element that contains this legend.
+   * Returns null if there is no fieldset containing this legend.
+   */
+  nsIContent* GetFieldSet();
 };
 
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Legend)
 
 
 nsHTMLLegendElement::nsHTMLLegendElement(nsINodeInfo *aNodeInfo)
   : nsGenericHTMLFormElement(aNodeInfo)
@@ -140,33 +147,49 @@ NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLA
 
 
 NS_IMPL_ELEMENT_CLONE(nsHTMLLegendElement)
 
 
 NS_IMETHODIMP
 nsHTMLLegendElement::GetForm(nsIDOMHTMLFormElement** aForm)
 {
-  return nsGenericHTMLFormElement::GetForm(aForm);
+  *aForm = nsnull;
+
+  nsCOMPtr<nsIFormControl> fieldsetControl = do_QueryInterface(GetFieldSet());
+
+  return fieldsetControl ? fieldsetControl->GetForm(aForm) : NS_OK;
 }
 
 
 NS_IMPL_STRING_ATTR(nsHTMLLegendElement, AccessKey, accesskey)
 NS_IMPL_STRING_ATTR(nsHTMLLegendElement, Align, align)
 
 // this contains center, because IE4 does
 static const nsAttrValue::EnumTable kAlignTable[] = {
   { "left", NS_STYLE_TEXT_ALIGN_LEFT },
   { "right", NS_STYLE_TEXT_ALIGN_RIGHT },
   { "center", NS_STYLE_TEXT_ALIGN_CENTER },
   { "bottom", NS_STYLE_VERTICAL_ALIGN_BOTTOM },
   { "top", NS_STYLE_VERTICAL_ALIGN_TOP },
   { 0 }
 };
 
+nsIContent*
+nsHTMLLegendElement::GetFieldSet()
+{
+  nsIContent* parent = GetParent();
+
+  if (parent && parent->IsHTML() && parent->Tag() == nsGkAtoms::fieldset) {
+    return parent;
+  }
+
+  return nsnull;
+}
+
 PRBool
 nsHTMLLegendElement::ParseAttribute(PRInt32 aNamespaceID,
                                     nsIAtom* aAttribute,
                                     const nsAString& aValue,
                                     nsAttrValue& aResult)
 {
   if (aAttribute == nsGkAtoms::align && aNamespaceID == kNameSpaceID_None) {
     return aResult.ParseEnumValue(aValue, kAlignTable, PR_FALSE);
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -734,17 +734,17 @@ nsresult nsHTMLMediaElement::LoadResourc
     // cycle here.  The channel holds the only reference to the listener,
     // and is useless now anyway, so drop our reference to it to allow it to
     // be destroyed.
     mChannel = nsnull;
     return rv;
   }
 
   // Else the channel must be open and starting to download. If it encounters
-  // a non-catestrophic failure, it will set a new task to continue loading
+  // a non-catastrophic failure, it will set a new task to continue loading
   // another candidate.
   return NS_OK;
 }
 
 nsresult nsHTMLMediaElement::LoadWithChannel(nsIChannel *aChannel,
                                              nsIStreamListener **aListener)
 {
   NS_ENSURE_ARG_POINTER(aChannel);
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -55,16 +55,19 @@ include $(topsrcdir)/config/rules.mk
 		test_bug2082.html \
 		test_bug3348.html \
 		test_bug6296.html \
 		test_bug24958.html \
 		test_bug41464.html \
 		bug100533_load.html \
 		bug100533_iframe.html \
 		test_bug100533.html \
+		image.png \
+		test_bug109445.html \
+		test_bug109445.xhtml \
 		test_bug143220.html \
 		test_bug237071.html \
 		bug242709_iframe.html \
 		bug242709_load.html \
 		test_bug242709.html \
 		bug277724_iframe1.html \
 		bug277724_iframe2.xhtml \
 		test_bug277724.html \
@@ -155,14 +158,16 @@ include $(topsrcdir)/config/rules.mk
 		test_bug535043.html \
 		test_bug547850.html \
 		test_bug457800.html \
 		test_bug536891.html \
 		test_bug536895.html \
 		test_bug458037.xhtml \
 		test_bug556645.html \
 		test_bug559284.html \
-        test_bug551670.html \
-        test_bug346485.html \
+		test_bug551670.html \
+		test_bug346485.html \
+		test_bug555567.html \
+		test_bug557620.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d26878c9f22d53bb44be515fa9f0ffbb90a71cbd
GIT binary patch
literal 268
zc%17D@N?(olHy`uVBq!ia0vp^DIm<j1SJ1AFfjuu#^NA%Cx&(BWL^R}oCO|{#S9GG
z!XV7ZFl&wkP>{XE)7O>#7PFLqm5kQ!$`+u|JWm(LkcwMxFBmd1FmNz0$ozjU>fm{H
zrGS|QSGZD6PEz%rro*}k!eEMoFdB8hjHM3Kz>FXTZ!kl1f-0CHassR?l5*|8wspoc
V9#?7J!~=9GgQu&X%Q~loCIIdPS=0ak
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_bug109445.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=109445
+-->
+<head>
+  <title>Test for Bug 109445</title>
+  <script src="/MochiKit/packed.js"></script>
+  <script src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=109445">Mozilla Bug 109445</a>
+<p id="display">
+<map name=a>
+<area shape=rect coords=25,25,75,75 href=#x>
+</map>
+<map id=b>
+<area shape=rect coords=25,25,75,75 href=#y>
+</map>
+<map name=a>
+<area shape=rect coords=25,25,75,75 href=#FAIL>
+</map>
+<map id=b>
+<area shape=rect coords=25,25,75,75 href=#FAIL>
+</map>
+
+<img usemap=#a src=image.png>
+<img usemap=#b src=image.png>
+</p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 109445 **/
+SimpleTest.waitForExplicitFinish();
+var images = document.getElementsByTagName("img");
+var second = false;
+onhashchange = function() {
+  if (!second) {
+    second = true;
+    is(location.hash, "#x", "First map");
+    SimpleTest.waitForFocus(function() synthesizeMouse(images[1], 50, 50, {}));
+  } else {
+    is(location.hash, "#y", "Second map");
+    SimpleTest.finish();
+  }
+};
+SimpleTest.waitForFocus(function() synthesizeMouse(images[0], 50, 50, {}));
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_bug109445.xhtml
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=109445
+-->
+<head>
+  <title>Test for Bug 109445</title>
+  <script src="/MochiKit/packed.js"></script>
+  <script src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=109445">Mozilla Bug 109445</a>
+<p id="display">
+<map name="a">
+<area shape="rect" coords="25,25,75,75" href="#x"/>
+</map>
+<map id="b">
+<area shape="rect" coords="25,25,75,75" href="#y"/>
+</map>
+<map name="a">
+<area shape="rect" coords="25,25,75,75" href="#FAIL"/>
+</map>
+<map id="b">
+<area shape="rect" coords="25,25,75,75" href="#FAIL"/>
+</map>
+
+<img usemap="#a" src="image.png"/>
+<img usemap="#b" src="image.png"/>
+</p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 109445 **/
+SimpleTest.waitForExplicitFinish();
+var images = document.getElementsByTagName("img");
+var second = false;
+onhashchange = function() {
+  if (!second) {
+    second = true;
+    is(location.hash, "#x", "First map");
+    SimpleTest.waitForFocus(function() synthesizeMouse(images[1], 50, 50, {}));
+  } else {
+    is(location.hash, "#y", "Second map");
+    SimpleTest.finish();
+  }
+};
+SimpleTest.waitForFocus(function() synthesizeMouse(images[0], 50, 50, {}));
+</script>
+</pre>
+</body>
+</html>
--- a/content/html/content/test/test_bug551670.html
+++ b/content/html/content/test/test_bug551670.html
@@ -86,13 +86,14 @@ checkType(document.getElementById('i1'),
 checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'checkbox', wrongType);
 checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'file', wrongType);
 checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'hidden', wrongType);
 checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'reset', wrongType);
 checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'image', wrongType);
 checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'password', wrongType);
 checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'radio', wrongType);
 checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'submit', wrongType);
+checkType(document.getElementById('i1'), document.getElementById('i2'), 'text', 'tel', wrongType);
 
 </script>
 </pre>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_bug555567.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=555567
+-->
+<head>
+  <title>Test for Bug 555567</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=555567">Mozilla Bug 555567</a>
+<div id='content' style="display: none">
+  <form>
+    <fieldset>
+      <legend id="a"></legend>
+    </fieldset>
+    <legend id="b"></legend>
+  </form>
+  <legend id="c"></legend>
+</div>
+<pre id="test">
+<p id="display"></p>
+<script type="application/javascript">
+
+/** Test for Bug 555567 **/
+
+// This test works only with html5 parser.
+netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+var prefs = Components.classes["@mozilla.org/preferences-service;1"]
+            .getService(Components.interfaces.nsIPrefBranch);
+
+if (prefs.getBoolPref("html5.enable")) {
+  var a = document.getElementById('a');
+  var b = document.getElementById('b');
+  var c = document.getElementById('c');
+
+  isnot(a.form, null,
+    "First legend element should have a not null form IDL attribute");
+  is(b.form, null,
+    "Second legend element should have a null form IDL attribute");
+  is(c.form, null,
+    "Third legend element should have a null form IDL attribute");
+}
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_bug557620.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=557620
+-->
+<head>
+  <title>Test for Bug 557620</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=557620">Mozilla Bug 557620</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  <input type="tel" id='i'>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 557620 **/
+
+// More checks are done in test_bug551670.html.
+
+var tel = document.getElementById('i');
+is(tel.type, 'tel', "input with type='tel' should return 'tel'");
+
+ok(tel.mozIsTextField, "tel input type is a text field");
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -1199,27 +1199,28 @@ nsHTMLDocument::GetImageMap(const nsAStr
 
   for (i = 0; i < n; ++i) {
     nsIDOMHTMLMapElement *map = mImageMaps[i];
     NS_ASSERTION(map, "Null map in map list!");
 
     PRBool match;
     nsresult rv;
 
-    if (!IsHTML()) {
-      rv = map->GetId(name);
-
-      match = name.Equals(aMapName);
-    } else {
+    rv = map->GetId(name);
+    NS_ENSURE_SUCCESS(rv, nsnull);
+
+    match = name.Equals(aMapName);
+    if (!match) {
       rv = map->GetName(name);
+      NS_ENSURE_SUCCESS(rv, nsnull);
 
       match = name.Equals(aMapName, nsCaseInsensitiveStringComparator());
     }
 
-    if (match && NS_SUCCEEDED(rv)) {
+    if (match) {
       // Quirk: if the first matching map is empty, remember it, but keep
       // searching for a non-empty one, only use it if none was found (bug 264624).
       if (mCompatMode == eCompatibility_NavQuirks) {
         nsCOMPtr<nsIDOMHTMLCollection> mapAreas;
         rv = map->GetAreas(getter_AddRefs(mapAreas));
         if (NS_SUCCEEDED(rv) && mapAreas) {
           PRUint32 length = 0;
           mapAreas->GetLength(&length);
--- a/content/mathml/content/src/nsMathMLElement.cpp
+++ b/content/mathml/content/src/nsMathMLElement.cpp
@@ -17,16 +17,17 @@
  * The Initial Developer of the Original Code is
  * mozilla.org.
  * Portions created by the Initial Developer are Copyright (C) 2007
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *    Vlad Sukhoy <vladimir.sukhoy@gmail.com> (original developer)
  *    Daniel Kraft <d@domob.eu> (nsMathMLElement patch, attachment 262925)
+ *    Frederic Wang <fred.wang@free.fr>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -117,52 +118,90 @@ nsMathMLElement::ParseAttribute(PRInt32 
 
   return nsMathMLElementBase::ParseAttribute(aNamespaceID, aAttribute,
                                              aValue, aResult);
 }
 
 static nsGenericElement::MappedAttributeEntry sTokenStyles[] = {
   { &nsGkAtoms::mathsize_ },
   { &nsGkAtoms::fontsize_ },
-  { &nsGkAtoms::mathcolor_ },
   { &nsGkAtoms::color },
-  { &nsGkAtoms::mathbackground_ },
   { &nsGkAtoms::fontfamily_ },
   { nsnull }
 };
 
 static nsGenericElement::MappedAttributeEntry sEnvironmentStyles[] = {
   { &nsGkAtoms::scriptlevel_ },
   { &nsGkAtoms::scriptminsize_ },
   { &nsGkAtoms::scriptsizemultiplier_ },
   { &nsGkAtoms::background },
   { nsnull }
 };
 
+static nsGenericElement::MappedAttributeEntry sCommonPresStyles[] = {
+  { &nsGkAtoms::mathcolor_ },
+  { &nsGkAtoms::mathbackground_ },
+  { nsnull }
+};
+
 PRBool
 nsMathMLElement::IsAttributeMapped(const nsIAtom* aAttribute) const
 {
   static const MappedAttributeEntry* const tokenMap[] = {
-    sTokenStyles
+    sTokenStyles,
+    sCommonPresStyles
   };
   static const MappedAttributeEntry* const mstyleMap[] = {
     sTokenStyles,
-    sEnvironmentStyles
+    sEnvironmentStyles,
+    sCommonPresStyles
+  };
+  static const MappedAttributeEntry* const commonPresMap[] = {
+    sCommonPresStyles
   };
   
   // We don't support mglyph (yet).
   nsIAtom* tag = Tag();
   if (tag == nsGkAtoms::ms_ || tag == nsGkAtoms::mi_ ||
       tag == nsGkAtoms::mn_ || tag == nsGkAtoms::mo_ ||
-      tag == nsGkAtoms::mtext_)
+      tag == nsGkAtoms::mtext_ || tag == nsGkAtoms::mspace_)
     return FindAttributeDependence(aAttribute, tokenMap,
                                    NS_ARRAY_LENGTH(tokenMap));
   if (tag == nsGkAtoms::mstyle_)
     return FindAttributeDependence(aAttribute, mstyleMap,
                                    NS_ARRAY_LENGTH(mstyleMap));
+
+  if (tag == nsGkAtoms::maction_ ||
+      tag == nsGkAtoms::maligngroup_ ||
+      tag == nsGkAtoms::malignmark_ ||
+      tag == nsGkAtoms::math ||
+      tag == nsGkAtoms::menclose_ ||
+      tag == nsGkAtoms::merror_ ||
+      tag == nsGkAtoms::mfenced_ ||
+      tag == nsGkAtoms::mfrac_ ||
+      tag == nsGkAtoms::mover_ ||
+      tag == nsGkAtoms::mpadded_ ||
+      tag == nsGkAtoms::mphantom_ ||
+      tag == nsGkAtoms::mprescripts_ ||
+      tag == nsGkAtoms::mroot_ ||
+      tag == nsGkAtoms::mrow_ ||
+      tag == nsGkAtoms::msqrt_ ||
+      tag == nsGkAtoms::msub_ ||
+      tag == nsGkAtoms::msubsup_ ||
+      tag == nsGkAtoms::msup_ ||
+      tag == nsGkAtoms::mtable_ ||
+      tag == nsGkAtoms::mtd_ ||
+      tag == nsGkAtoms::mtr_ ||
+      tag == nsGkAtoms::munder_ ||
+      tag == nsGkAtoms::munderover_ ||
+      tag == nsGkAtoms::none) {
+    return FindAttributeDependence(aAttribute, commonPresMap,
+                                   NS_ARRAY_LENGTH(commonPresMap));
+  }
+
   return PR_FALSE;
 }
 
 nsMapRuleToAttributesFunc
 nsMathMLElement::GetAttributeMappingFunction() const
 {
   // It doesn't really matter what our tag is here, because only attributes
   // that satisfy IsAttributeMapped will be stored in the mapped attributes
--- a/content/media/nsBuiltinDecoderStateMachine.cpp
+++ b/content/media/nsBuiltinDecoderStateMachine.cpp
@@ -77,16 +77,20 @@ extern PRLogModuleInfo* gBuiltinDecoderL
 // keyframe.
 //
 // Also if the decode catches up with the end of the downloaded data,
 // we'll only go into BUFFERING state if we've got audio and have queued
 // less than LOW_AUDIO_MS of audio, or if we've got video and have queued
 // less than LOW_VIDEO_FRAMES frames.
 static const PRUint32 LOW_AUDIO_MS = 100;
 
+// If more than this many ms of decoded audio is queued, we'll hold off
+// decoding more audio.
+const unsigned AMPLE_AUDIO_MS = 2000;
+
 // If we have fewer than LOW_VIDEO_FRAMES decoded frames, and
 // we're not "pumping video", we'll skip the video up to the next keyframe
 // which is at or after the current playback position.
 //
 // Also if the decode catches up with the end of the downloaded data,
 // we'll only go into BUFFERING state if we've got audio and have queued
 // less than LOW_AUDIO_MS of audio, or if we've got video and have queued
 // less than LOW_VIDEO_FRAMES frames.
@@ -123,16 +127,30 @@ nsBuiltinDecoderStateMachine::nsBuiltinD
   MOZ_COUNT_CTOR(nsBuiltinDecoderStateMachine);
 }
 
 nsBuiltinDecoderStateMachine::~nsBuiltinDecoderStateMachine()
 {
   MOZ_COUNT_DTOR(nsBuiltinDecoderStateMachine);
 }
 
+PRBool nsBuiltinDecoderStateMachine::HasFutureAudio() const {
+  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  return HasAudio() &&
+         !mAudioCompleted &&
+         (mReader->mAudioQueue.GetSize() > 0 ||
+         mAudioEndTime - mCurrentFrameTime + mStartTime > LOW_AUDIO_MS);
+}
+
+PRBool nsBuiltinDecoderStateMachine::HaveNextFrameData() const {
+    return ((!HasAudio() || mReader->mAudioQueue.AtEndOfStream()) && 
+             mReader->mVideoQueue.GetSize() > 0) ||
+            HasFutureAudio();
+}
+
 void nsBuiltinDecoderStateMachine::DecodeLoop()
 {
   NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
   PRBool videoPlaying = PR_FALSE;
   PRBool audioPlaying = PR_FALSE;
   {
     MonitorAutoEnter mon(mDecoder->GetMonitor());
     videoPlaying = HasVideo();
@@ -159,20 +177,16 @@ void nsBuiltinDecoderStateMachine::Decod
   // been consumed by the play state machine thread.
   const unsigned videoWaitThreshold = 10;
 
   // After the audio decode fills with more than audioPumpThresholdMs ms
   // of decoded audio, we'll start to check whether the audio or video decode
   // is falling behind.
   const unsigned audioPumpThresholdMs = 250;
 
-  // If more than this many ms of decoded audio is queued, we'll hold off
-  // decoding more audio.
-  const unsigned audioWaitThresholdMs = 2000;
-
   // Main decode loop.
   while (videoPlaying || audioPlaying) {
     PRBool audioWait = !audioPlaying;
     PRBool videoWait = !videoPlaying;
     {
       // Wait for more data to download if we've exhausted all our
       // buffered data.
       MonitorAutoEnter mon(mDecoder->GetMonitor());
@@ -201,33 +215,34 @@ void nsBuiltinDecoderStateMachine::Decod
     }
     if (!videoPump &&
         videoPlaying &&
         videoQueueSize < LOW_VIDEO_FRAMES)
     {
       skipToNextKeyframe = PR_TRUE;
     }
 
-    PRInt64 initialDownloadPosition = 0;
-    PRInt64 currentTime = 0;
-    {
-      MonitorAutoEnter mon(mDecoder->GetMonitor());
-      initialDownloadPosition =
-        mDecoder->GetCurrentStream()->GetCachedDataEnd(mDecoder->mDecoderPosition);
-      currentTime = mCurrentFrameTime + mStartTime;
-    }
-
     // Determine how much audio data is decoded ahead of the current playback
     // position.
     int audioQueueSize = mReader->mAudioQueue.GetSize();
-    PRInt64 audioDecoded = mReader->mAudioQueue.Duration();
+    PRInt64 initialDownloadPosition = 0;
+    PRInt64 currentTime = 0;
+    PRInt64 audioDecoded = 0;
+    {
+      MonitorAutoEnter mon(mDecoder->GetMonitor());
+      currentTime = mCurrentFrameTime + mStartTime;
+      audioDecoded = mReader->mAudioQueue.Duration() +
+                     mAudioEndTime - currentTime;
+      initialDownloadPosition =
+        mDecoder->GetCurrentStream()->GetCachedDataEnd(mDecoder->mDecoderPosition);
+    }
 
     // Don't decode any audio if the audio decode is way ahead, or if we're
     // skipping to the next video keyframe and the audio is marginally ahead.
-    if (audioDecoded > audioWaitThresholdMs ||
+    if (audioDecoded > AMPLE_AUDIO_MS ||
         (skipToNextKeyframe && audioDecoded > audioPumpThresholdMs)) {
       audioWait = PR_TRUE;
     }
     if (audioPump && audioDecoded > audioPumpThresholdMs) {
       audioPump = PR_FALSE;
     }
     if (!audioPump && audioPlaying && audioDecoded < LOW_AUDIO_MS) {
       skipToNextKeyframe = PR_TRUE;
@@ -360,53 +375,82 @@ void nsBuiltinDecoderStateMachine::Audio
       // Remember the presentation time of the first audio sample we play.
       // We add this to the position/played duration of the audio stream to
       // determine the audio clock time. Used for A/V sync.
       MonitorAutoEnter mon(mDecoder->GetMonitor());
       mAudioStartTime = audioStartTime = sound->mTime;
       LOG(PR_LOG_DEBUG, ("First audio sample has timestamp %lldms", mAudioStartTime));
     }
 
+    PRInt64 audioEndTime = -1;
     {
       MonitorAutoEnter audioMon(mAudioMonitor);
       if (mAudioStream) {
         // The state machine could have paused since we've released the decoder
         // monitor and acquired the audio monitor. Rather than acquire both
         // monitors, the audio stream also maintains whether its paused or not.
         // This prevents us from doing a blocking write while holding the audio
         // monitor while paused; we would block, and the state machine won't be 
         // able to acquire the audio monitor in order to resume or destroy the
         // audio stream.
         if (!mAudioStream->IsPaused()) {
           mAudioStream->Write(sound->mAudioData,
                               sound->AudioDataLength(),
                               PR_TRUE);
-          mAudioEndTime = sound->mTime + sound->mDuration;
+          audioEndTime = sound->mTime + sound->mDuration;
           mDecoder->UpdatePlaybackOffset(sound->mOffset);
         } else {
           mReader->mAudioQueue.PushFront(sound);
           sound.forget();
         }
       }
     }
     sound = nsnull;
 
-    if (mReader->mAudioQueue.AtEndOfStream()) {
-      // Last sample pushed to audio hardware, wait for the audio to finish,
-      // before the audio thread terminates.
-      MonitorAutoEnter audioMon(mAudioMonitor);
-      if (mAudioStream) {
-        mAudioStream->Drain();
+    {
+      MonitorAutoEnter mon(mDecoder->GetMonitor());
+      if (audioEndTime != -1) {
+        mAudioEndTime = audioEndTime;
       }
-      LOG(PR_LOG_DEBUG, ("%p Reached audio stream end.", mDecoder));
+      PRInt64 audioAhead = mAudioEndTime - mCurrentFrameTime - mStartTime;
+      if (audioAhead > AMPLE_AUDIO_MS) {
+        // We've pushed enough audio onto the hardware that we've queued up a
+        // significant amount ahead of the playback position. The decode
+        // thread will be going to sleep, so we won't get any new samples
+        // anyway, so sleep until we need to push to the hardware again.
+        Wait(AMPLE_AUDIO_MS / 2);
+        // Kick the decode thread; since above we only do a NotifyAll when
+        // we pop an audio chunk of the queue, the decoder won't wake up if
+        // we've got no more decoded chunks to push to the hardware. We can
+        // hit this condition if the last sample in the stream doesn't have
+        // it's EOS flag set, and the decode thread sleeps just after decoding
+        // that packet, but before realising there's no more packets.
+        mon.NotifyAll();
+      }
     }
   }
+  if (mReader->mAudioQueue.AtEndOfStream() &&
+      mState != DECODER_STATE_SHUTDOWN &&
+      !mStopDecodeThreads)
+  {
+    // Last sample pushed to audio hardware, wait for the audio to finish,
+    // before the audio thread terminates.
+    MonitorAutoEnter audioMon(mAudioMonitor);
+    if (mAudioStream) {
+      mAudioStream->Drain();
+    }
+    LOG(PR_LOG_DEBUG, ("%p Reached audio stream end.", mDecoder));
+  }
   {
     MonitorAutoEnter mon(mDecoder->GetMonitor());
     mAudioCompleted = PR_TRUE;
+    UpdateReadyState();
+    // Kick the decode and state machine threads; they may be sleeping waiting
+    // for this to finish.
+    mDecoder->GetMonitor().NotifyAll();
   }
   LOG(PR_LOG_DEBUG, ("Audio stream finished playing, audio thread exit"));
 }
 
 nsresult nsBuiltinDecoderStateMachine::Init()
 {
   return mReader->Init();
 }
@@ -934,23 +978,24 @@ nsresult nsBuiltinDecoderStateMachine::R
       }
 
     case DECODER_STATE_COMPLETED:
       {
         if (NS_FAILED(StartDecodeThreads())) {
           continue;
         }
 
-        // Play the remaining media.
-        while (mState == DECODER_STATE_COMPLETED &&
-               (mReader->mVideoQueue.GetSize() > 0 ||
-                (HasAudio() && !mAudioCompleted)))
-        {
+        // Play the remaining media. We want to run AdvanceFrame() at least
+        // once to ensure the current playback position is advanced to the
+        // end of the media, and so that we update the readyState.
+        do {
           AdvanceFrame();
-        }
+        } while (mState == DECODER_STATE_COMPLETED &&
+                 (mReader->mVideoQueue.GetSize() > 0 ||
+                 (HasAudio() && !mAudioCompleted)));
 
         if (mAudioStream) {
           // Close the audop stream so that next time audio is used a new stream
           // is created. The StopPlayback call also resets the IsPlaying() state
           // so audio is restarted correctly.
           StopPlayback(AUDIO_SHUTDOWN);
         }
 
--- a/content/media/nsBuiltinDecoderStateMachine.h
+++ b/content/media/nsBuiltinDecoderStateMachine.h
@@ -188,22 +188,17 @@ public:
   // This is called on the state machine thread and audio thread.
   // The decoder monitor must be obtained before calling this.
   PRBool HasVideo() const {
     mDecoder->GetMonitor().AssertCurrentThreadIn();
     return mInfo.mHasVideo;
   }
 
   // Should be called by main thread.
-  PRBool HaveNextFrameData() const {
-    PRUint32 audioQueueSize = mReader->mAudioQueue.GetSize();
-    return (mReader->mVideoQueue.GetSize() > 0 &&
-            (!HasAudio() || audioQueueSize > 0)) ||
-           audioQueueSize > 0;
-  }
+  PRBool HaveNextFrameData() const;
 
   // Must be called with the decode monitor held.
   PRBool IsBuffering() const {
     mDecoder->GetMonitor().AssertCurrentThreadIn();
 
     return mState == nsBuiltinDecoderStateMachine::DECODER_STATE_BUFFERING;
   }
 
@@ -235,16 +230,20 @@ public:
   // The decoder monitor must be obtained before modifying this state.
   // NotifyAll on the monitor must be called when the state is changed by
   // the main thread so the decoder thread can wake up.
   // Accessed on state machine, audio, main, and AV thread. 
   State mState;
 
 protected:
 
+  // Returns PR_TRUE when there's decoded audio waiting to play.
+  // The decoder monitor must be held.
+  PRBool HasFutureAudio() const;
+
   // Waits on the decoder Monitor for aMs. If the decoder monitor is awoken
   // by a Notify() call, we'll continue waiting, unless we've moved into
   // shutdown state. This enables us to ensure that we wait for a specified
   // time, and that the myriad of Notify()s we do an the decoder monitor
   // don't cause the audio thread to be starved. The decoder monitor must
   // be locked.
   void Wait(PRUint32 aMs);
 
--- a/content/media/ogg/nsOggReader.cpp
+++ b/content/media/ogg/nsOggReader.cpp
@@ -998,17 +998,17 @@ nsresult nsOggReader::Seek(PRInt64 aTarg
       // time in ms which a keyframe could be before a given interframe. We
       // subtract this from our seek target, seek to the new target, and then
       // decode forwards to the original seek target. We should encounter a
       // keyframe in that interval. This prevents us from needing to run two
       // bisections; one for the seek target frame, and another to find its
       // keyframe. It's usually faster to just download this extra data, rather
       // tham perform two bisections to find the seek target's keyframe. We
       // don't do this offsetting when seeking in a buffered ranges (above),
-      // as the extra decoding causes a noticable speed hit when all the data
+      // as the extra decoding causes a noticeable speed hit when all the data
       // is buffered.
       PRInt64 keyframeOffsetMs = 0;
       if (HasVideo() && mTheoraState) {
         keyframeOffsetMs = mTheoraState->MaxKeyframeOffset();
       }
       PRInt64 seekTarget = NS_MAX(aStartTime, aTarget - keyframeOffsetMs);
 
       ByteRange k = GetSeekRange(ranges, seekTarget, aStartTime, aEndTime, PR_FALSE);
--- a/content/media/test/file_access_controls.html
+++ b/content/media/test/file_access_controls.html
@@ -36,17 +36,17 @@ var gTests = [
     // Test 5
     url: "http://example.org/tests/content/media/test/320x240.ogv",
     result: "loadeddata",
     description: "Can load from same domain"
   },{
     // Test 6
     url: "http://example.org:8000/tests/content/media/test/320x240.ogv",
     result: "error",
-    description: "Won't load from differnet port on same domain"
+    description: "Won't load from different port on same domain"
   },{
     // Test 7
     url: "http://example.org:8000/tests/content/media/test/320x240.allow-origin.ogv",
     result: "loadeddata",
     description: "Can load from different port on same domain with allow-origin",
   },{
     // Test 8
     url: "http://example.com/tests/content/media/test/320x240.ogv",
--- a/content/media/test/manifest.js
+++ b/content/media/test/manifest.js
@@ -32,18 +32,19 @@ var gPlayTests = [
   { name:"r11025_u8_c1.wav", type:"audio/x-wav", duration:1.0 },
   // 8-bit samples, file is truncated
   { name:"r11025_u8_c1_trunc.wav", type:"audio/x-wav", duration:1.8 },
   // file has trailing non-PCM data
   { name:"r11025_s16_c1_trailing.wav", type:"audio/x-wav", duration:1.0 },
   // file with list chunk
   { name:"r16000_u8_c1_list.wav", type:"audio/x-wav", duration:4.2 },
 
-  // Ogg stream with eof marker
+  // Ogg stream without eof marker
   { name:"bug461281.ogg", type:"application/ogg" },
+
   // oggz-chop stream
   { name:"bug482461.ogv", type:"video/ogg", duration:4.34 },
   // With first frame a "duplicate" (empty) frame.
   { name:"bug500311.ogv", type:"video/ogg", duration:1.96 },
   // Small audio file
   { name:"small-shot.ogg", type:"video/ogg" },
   // More audio in file than video.
   { name:"short-video.ogv", type:"video/ogg", duration:1.081 },
--- a/content/xbl/src/nsXBLContentSink.cpp
+++ b/content/xbl/src/nsXBLContentSink.cpp
@@ -311,17 +311,17 @@ nsXBLContentSink::HandleEndElement(const
     PRInt32 nameSpaceID;
     nsCOMPtr<nsIAtom> prefix, localName;
     nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
 
     if (nameSpaceID == kNameSpaceID_XBL) {
       if (mState == eXBL_Error) {
         // Check whether we've opened this tag before; we may not have if
-        // it was a real XBL tag before the error occured.
+        // it was a real XBL tag before the error occurred.
         if (!GetCurrentContent()->NodeInfo()->Equals(localName,
                                                      nameSpaceID)) {
           // OK, this tag was never opened as far as the XML sink is
           // concerned.  Just drop the HandleEndElement
           return NS_OK;
         }
       }
       else if (mState == eXBL_InHandlers) {
--- a/content/xbl/src/nsXBLContentSink.h
+++ b/content/xbl/src/nsXBLContentSink.h
@@ -50,17 +50,17 @@
  */
 typedef enum {
   eXBL_InDocument,       /* outside any bindings */
   eXBL_InBindings,       /* Inside a <bindings> element */
   eXBL_InBinding,        /* Inside a <binding> */
   eXBL_InResources,      /* Inside a <resources> */
   eXBL_InImplementation, /* Inside a <implementation> */
   eXBL_InHandlers,       /* Inside a <handlers> */
-  eXBL_Error             /* An error has occured.  Suspend binding construction */
+  eXBL_Error             /* An error has occurred.  Suspend binding construction */
 } XBLPrimaryState;
 
 /*
  * Enum that describes our substate (typically when parsing something
  * like <handlers> or <implementation>).
  */
 typedef enum {
   eXBL_None,
--- a/content/xbl/src/nsXBLPrototypeBinding.cpp
+++ b/content/xbl/src/nsXBLPrototypeBinding.cpp
@@ -1041,17 +1041,17 @@ nsXBLPrototypeBinding::GetRuleProcessor(
 {
   if (mResources) {
     return mResources->mRuleProcessor;
   }
   
   return nsnull;
 }
 
-nsCOMArray<nsICSSStyleSheet>*
+nsXBLPrototypeResources::sheet_array_type*
 nsXBLPrototypeBinding::GetStyleSheets()
 {
   if (mResources) {
     return &mResources->mStyleSheetList;
   }
 
   return nsnull;
 }
--- a/content/xbl/src/nsXBLPrototypeBinding.h
+++ b/content/xbl/src/nsXBLPrototypeBinding.h
@@ -38,33 +38,33 @@
 
 #ifndef nsXBLPrototypeBinding_h__
 #define nsXBLPrototypeBinding_h__
 
 #include "nsCOMPtr.h"
 #include "nsXBLPrototypeResources.h"
 #include "nsXBLPrototypeHandler.h"
 #include "nsXBLProtoImplMethod.h"
-#include "nsICSSStyleSheet.h"
 #include "nsICSSLoaderObserver.h"
 #include "nsWeakReference.h"
 #include "nsIContent.h"
 #include "nsHashtable.h"
 #include "nsIXBLDocumentInfo.h"
 #include "nsCOMArray.h"
 #include "nsXBLProtoImpl.h"
 
 class nsIAtom;
 class nsIDocument;
 class nsIScriptContext;
 class nsSupportsHashtable;
 class nsIXBLService;
 class nsFixedSizeAllocator;
 class nsXBLProtoImplField;
 class nsXBLBinding;
+class nsCSSStyleSheet;
 
 // *********************************************************************/
 // The XBLPrototypeBinding class
 
 // Instances of this class are owned by the nsXBLDocumentInfo object returned
 // by XBLDocumentInfo().  Consumers who want to refcount things should refcount
 // that.
 class nsXBLPrototypeBinding
@@ -144,22 +144,22 @@ public:
   PRBool IsChrome() { return mXBLDocInfoWeak->IsChrome(); }
   
   PRBool HasBasePrototype() { return mHasBaseProto; }
   void SetHasBasePrototype(PRBool aHasBase) { mHasBaseProto = aHasBase; }
 
   void SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent);
 
   nsIStyleRuleProcessor* GetRuleProcessor();
-  nsCOMArray<nsICSSStyleSheet>* GetStyleSheets();
+  nsXBLPrototypeResources::sheet_array_type* GetStyleSheets();
 
   PRBool HasInsertionPoints() { return mInsertionPointTable != nsnull; }
   
   PRBool HasStyleSheets() {
-    return mResources && mResources->mStyleSheetList.Count() > 0;
+    return mResources && mResources->mStyleSheetList.Length() > 0;
   }
 
   nsresult FlushSkinSheets();
 
   void InstantiateInsertionPoints(nsXBLBinding* aBinding);
 
   // XXXbz this aIndex has nothing to do with an index into the child
   // list of the insertion parent or anything.
--- a/content/xbl/src/nsXBLPrototypeResources.cpp
+++ b/content/xbl/src/nsXBLPrototypeResources.cpp
@@ -31,17 +31,16 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "nsICSSStyleSheet.h"
 #include "nsIStyleRuleProcessor.h"
 #include "nsIDocument.h"
 #include "nsIContent.h"
 #include "nsIXBLService.h"
 #include "nsIServiceManager.h"
 #include "nsXBLResourceLoader.h"
 #include "nsXBLPrototypeResources.h"
 #include "nsXBLPrototypeBinding.h"
@@ -98,47 +97,45 @@ static PRBool IsChromeURI(nsIURI* aURI)
   if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome)
     return PR_TRUE;
   return PR_FALSE;
 }
 
 nsresult
 nsXBLPrototypeResources::FlushSkinSheets()
 {
-  if (mStyleSheetList.Count() == 0)
+  if (mStyleSheetList.Length() == 0)
     return NS_OK;
 
   nsCOMPtr<nsIDocument> doc;
   mLoader->mBinding->XBLDocumentInfo()->GetDocument(getter_AddRefs(doc));
   mozilla::css::Loader* cssLoader = doc->CSSLoader();
 
   // We have scoped stylesheets.  Reload any chrome stylesheets we
   // encounter.  (If they aren't skin sheets, it doesn't matter, since
   // they'll still be in the chrome cache.
   mRuleProcessor = nsnull;
 
-  nsCOMArray<nsICSSStyleSheet> oldSheets(mStyleSheetList);
+  sheet_array_type oldSheets(mStyleSheetList);
   mStyleSheetList.Clear();
 
-  PRInt32 i;
-  PRInt32 count = oldSheets.Count();
-  for (i = 0; i < count; i++) {
-    nsICSSStyleSheet* oldSheet = oldSheets[i];
+  for (sheet_array_type::size_type i = 0, count = oldSheets.Length();
+       i < count; ++i) {
+    nsCSSStyleSheet* oldSheet = oldSheets[i];
 
-    nsCOMPtr<nsIURI> uri;
-    oldSheet->GetSheetURI(getter_AddRefs(uri));
+    nsCOMPtr<nsIURI> uri = oldSheet->GetSheetURI();
 
-    nsCOMPtr<nsICSSStyleSheet> newSheet;
+    nsRefPtr<nsCSSStyleSheet> newSheet;
     if (IsChromeURI(uri)) {
       if (NS_FAILED(cssLoader->LoadSheetSync(uri, getter_AddRefs(newSheet))))
         continue;
     }
     else {
       newSheet = oldSheet;
     }
 
-    mStyleSheetList.AppendObject(newSheet);
+    mStyleSheetList.AppendElement(newSheet);
   }
   mRuleProcessor = new nsCSSRuleProcessor(mStyleSheetList, 
                                           nsStyleSet::eDocSheet);
 
   return NS_OK;
 }
--- a/content/xbl/src/nsXBLPrototypeResources.h
+++ b/content/xbl/src/nsXBLPrototypeResources.h
@@ -37,26 +37,25 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsXBLPrototypeResources_h__
 #define nsXBLPrototypeResources_h__
 
 #include "nsCOMPtr.h"
 #include "nsICSSLoaderObserver.h"
 #include "nsIStyleRuleProcessor.h"
-#include "nsCOMArray.h"
 
 class nsIContent;
 class nsIAtom;
 class nsIDocument;
 class nsIScriptContext;
 class nsSupportsHashtable;
 class nsXBLResourceLoader;
 class nsXBLPrototypeBinding;
-class nsICSSStyleSheet;
+class nsCSSStyleSheet;
 
 // *********************************************************************/
 // The XBLPrototypeResources class
 
 class nsXBLPrototypeResources
 {
 public:
   void LoadResources(PRBool* aResult);
@@ -64,16 +63,17 @@ public:
   void AddResourceListener(nsIContent* aElement);
   nsresult FlushSkinSheets();
 
   nsXBLPrototypeResources(nsXBLPrototypeBinding* aBinding);
   ~nsXBLPrototypeResources();
 
 // MEMBER VARIABLES
   nsXBLResourceLoader* mLoader; // A loader object. Exists only long enough to load resources, and then it dies.
-  nsCOMArray<nsICSSStyleSheet> mStyleSheetList; // A list of loaded stylesheets for this binding.
+  typedef nsTArray<nsRefPtr<nsCSSStyleSheet> > sheet_array_type;
+  sheet_array_type mStyleSheetList; // A list of loaded stylesheets for this binding.
 
   // The list of stylesheets converted to a rule processor.
   nsCOMPtr<nsIStyleRuleProcessor> mRuleProcessor;
 };
 
 #endif
 
--- a/content/xbl/src/nsXBLResourceLoader.cpp
+++ b/content/xbl/src/nsXBLResourceLoader.cpp
@@ -31,17 +31,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "nsICSSStyleSheet.h"
+#include "nsCSSStyleSheet.h"
 #include "nsIStyleRuleProcessor.h"
 #include "nsIDocument.h"
 #include "nsIContent.h"
 #include "nsIPresShell.h"
 #include "nsIXBLService.h"
 #include "nsIServiceManager.h"
 #include "nsXBLResourceLoader.h"
 #include "nsXBLPrototypeResources.h"
@@ -148,17 +148,17 @@ nsXBLResourceLoader::LoadResources(PRBoo
       PRBool chrome;
       nsresult rv;
       if (NS_SUCCEEDED(url->SchemeIs("chrome", &chrome)) && chrome)
       {
         rv = nsContentUtils::GetSecurityManager()->
           CheckLoadURIWithPrincipal(docPrincipal, url,
                                     nsIScriptSecurityManager::ALLOW_CHROME);
         if (NS_SUCCEEDED(rv)) {
-          nsCOMPtr<nsICSSStyleSheet> sheet;
+          nsRefPtr<nsCSSStyleSheet> sheet;
           rv = cssLoader->LoadSheetSync(url, getter_AddRefs(sheet));
           NS_ASSERTION(NS_SUCCEEDED(rv), "Load failed!!!");
           if (NS_SUCCEEDED(rv))
           {
             rv = StyleSheetLoaded(sheet, PR_FALSE, NS_OK);
             NS_ASSERTION(NS_SUCCEEDED(rv), "Processing the style sheet failed!!!");
           }
         }
@@ -177,26 +177,26 @@ nsXBLResourceLoader::LoadResources(PRBoo
   
   // Destroy our resource list.
   delete mResourceList;
   mResourceList = nsnull;
 }
 
 // nsICSSLoaderObserver
 NS_IMETHODIMP
-nsXBLResourceLoader::StyleSheetLoaded(nsICSSStyleSheet* aSheet,
+nsXBLResourceLoader::StyleSheetLoaded(nsCSSStyleSheet* aSheet,
                                       PRBool aWasAlternate,
                                       nsresult aStatus)
 {
   if (!mResources) {
     // Our resources got destroyed -- just bail out
     return NS_OK;
   }
    
-  mResources->mStyleSheetList.AppendObject(aSheet);
+  mResources->mStyleSheetList.AppendElement(aSheet);
 
   if (!mInLoadResourcesFunc)
     mPendingSheets--;
   
   if (mPendingSheets == 0) {
     // All stylesheets are loaded.  
     mResources->mRuleProcessor =
       new nsCSSRuleProcessor(mResources->mStyleSheetList, 
--- a/content/xbl/src/nsXBLResourceLoader.h
+++ b/content/xbl/src/nsXBLResourceLoader.h
@@ -73,17 +73,17 @@ struct nsXBLResource {
 
 class nsXBLResourceLoader : public nsICSSLoaderObserver
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(nsXBLResourceLoader)
 
   // nsICSSLoaderObserver
-  NS_IMETHOD StyleSheetLoaded(nsICSSStyleSheet* aSheet, PRBool aWasAlternate,
+  NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet, PRBool aWasAlternate,
                               nsresult aStatus);
 
   void LoadResources(PRBool* aResult);
   void AddResource(nsIAtom* aResourceType, const nsAString& aSrc);
   void AddResourceListener(nsIContent* aElement);
 
   nsXBLResourceLoader(nsXBLPrototypeBinding* aBinding,
                       nsXBLPrototypeResources* aResources);
--- a/content/xml/document/src/nsXMLContentSink.cpp
+++ b/content/xml/document/src/nsXMLContentSink.cpp
@@ -54,17 +54,17 @@
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsIDOMComment.h"
 #include "nsIDOMCDATASection.h"
 #include "nsDOMDocumentType.h"
 #include "nsHTMLParts.h"
 #include "nsCRT.h"
-#include "nsICSSStyleSheet.h"
+#include "nsCSSStyleSheet.h"
 #include "nsCSSLoader.h"
 #include "nsGkAtoms.h"
 #include "nsContentUtils.h"
 #include "nsIScriptContext.h"
 #include "nsINameSpaceManager.h"
 #include "nsIServiceManager.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIContentViewer.h"
@@ -457,17 +457,17 @@ nsXMLContentSink::OnTransformDone(nsresu
   ScrollToRef();
 
   originalDocument->EndLoad();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXMLContentSink::StyleSheetLoaded(nsICSSStyleSheet* aSheet,
+nsXMLContentSink::StyleSheetLoaded(nsCSSStyleSheet* aSheet,
                                    PRBool aWasAlternate,
                                    nsresult aStatus)
 {
   if (!mPrettyPrinting) {
     return nsContentSink::StyleSheetLoaded(aSheet, aWasAlternate, aStatus);
   }
 
   if (!mDocument->CSSLoader()->HasPendingLoads()) {
@@ -1252,19 +1252,19 @@ nsXMLContentSink::HandleDoctypeDecl(cons
     return rv;
   }
 
   if (aCatalogData && mCSSLoader && mDocument) {
     // bug 124570 - we only expect additional agent sheets for now -- ignore
     // exit codes, error are not fatal here, just that the stylesheet won't apply
     nsCOMPtr<nsIURI> uri(do_QueryInterface(aCatalogData));
     if (uri) {
-      nsCOMPtr<nsICSSStyleSheet> sheet;
+      nsRefPtr<nsCSSStyleSheet> sheet;
       mCSSLoader->LoadSheetSync(uri, PR_TRUE, PR_TRUE, getter_AddRefs(sheet));
-      
+
 #ifdef NS_DEBUG
       nsCAutoString uriStr;
       uri->GetSpec(uriStr);
       printf("Loading catalog stylesheet: %s ... %s\n", uriStr.get(), sheet.get() ? "Done" : "Failed");
 #endif
       if (sheet) {
         mDocument->BeginUpdate(UPDATE_STYLE);
         mDocument->AddCatalogStyleSheet(sheet);
--- a/content/xml/document/src/nsXMLContentSink.h
+++ b/content/xml/document/src/nsXMLContentSink.h
@@ -102,17 +102,17 @@ public:
   virtual nsISupports *GetTarget();
   virtual PRBool IsScriptExecuting();
 
   // nsITransformObserver
   NS_IMETHOD OnDocumentCreated(nsIDocument *aResultDocument);
   NS_IMETHOD OnTransformDone(nsresult aResult, nsIDocument *aResultDocument);
 
   // nsICSSLoaderObserver
-  NS_IMETHOD StyleSheetLoaded(nsICSSStyleSheet* aSheet, PRBool aWasAlternate,
+  NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet, PRBool aWasAlternate,
                               nsresult aStatus);
   static PRBool ParsePIData(const nsString &aData, nsString &aHref,
                           nsString &aTitle, nsString &aMedia,
                           PRBool &aIsAlternate);
 
 protected:
   // Start layout.  If aIgnorePendingSheets is true, this will happen even if
   // we still have stylesheet loads pending.  Otherwise, we'll wait until the
--- a/content/xslt/src/base/txErrorObserver.h
+++ b/content/xslt/src/base/txErrorObserver.h
@@ -94,17 +94,17 @@ public:
     **/
     SimpleErrorObserver(ostream& errStream);
 
     /**
      *  Notifies this Error observer of a new error aRes
     **/
     void receiveError(const nsAString& errorMessage, nsresult aRes);
 
-    virtual void supressWarnings(MBool supress);
+    virtual void suppressWarnings(MBool suppress);
 
 private:
 
     ostream* errStream;
     MBool hideWarnings;
 }; //-- SimpleErrorObserver
 #endif
 
--- a/content/xslt/src/base/txSimpleErrorObserver.cpp
+++ b/content/xslt/src/base/txSimpleErrorObserver.cpp
@@ -70,11 +70,11 @@ void SimpleErrorObserver::receiveError(c
         *errStream << "error: ";
     }
 
     *errStream << NS_LossyConvertUTF16toASCII(errorMessage).get() << endl;
     errStream->flush();
 #endif
 }
 
-void SimpleErrorObserver::supressWarnings(MBool supress) {
-    this->hideWarnings = supress;
-} //-- supressWarnings
+void SimpleErrorObserver::suppressWarnings(MBool suppress) {
+    this->hideWarnings = suppress;
+} //-- suppressWarnings
--- a/content/xslt/src/xslt/txKey.h
+++ b/content/xslt/src/xslt/txKey.h
@@ -127,17 +127,17 @@ public:
     txXSLKey(const txExpandedName& aName) : mName(aName)
     {
     }
     
     /**
      * Adds a match/use pair.
      * @param aMatch  match-pattern
      * @param aUse    use-expression
-     * @return PR_FALSE if an error occured, PR_TRUE otherwise
+     * @return PR_FALSE if an error occurred, PR_TRUE otherwise
      */
     PRBool addKey(nsAutoPtr<txPattern> aMatch, nsAutoPtr<Expr> aUse);
 
     /**
      * Indexes a subtree and adds it to the hash of key values
      * @param aRoot         Subtree root to index and add
      * @param aKeyValueHash Hash to add values to
      * @param aEs           txExecutionState to use for XPath evaluation
--- a/content/xslt/src/xslt/txKeyFunctionCall.cpp
+++ b/content/xslt/src/xslt/txKeyFunctionCall.cpp
@@ -294,17 +294,17 @@ txKeyHash::init()
     return NS_OK;
 }
 
 
 /**
  * Adds a match/use pair.
  * @param aMatch  match-pattern
  * @param aUse    use-expression
- * @return PR_FALSE if an error occured, PR_TRUE otherwise
+ * @return PR_FALSE if an error occurred, PR_TRUE otherwise
  */
 PRBool txXSLKey::addKey(nsAutoPtr<txPattern> aMatch, nsAutoPtr<Expr> aUse)
 {
     if (!aMatch || !aUse)
         return PR_FALSE;
 
     Key* key = mKeys.AppendElement();
     if (!key)
--- a/content/xslt/src/xslt/txMozillaXMLOutput.cpp
+++ b/content/xslt/src/xslt/txMozillaXMLOutput.cpp
@@ -52,17 +52,17 @@
 #include "nsContentCID.h"
 #include "nsNetUtil.h"
 #include "nsUnicharUtils.h"
 #include "txAtoms.h"
 #include "txLog.h"
 #include "nsIConsoleService.h"
 #include "nsIDOMDocumentFragment.h"
 #include "nsINameSpaceManager.h"
-#include "nsICSSStyleSheet.h"
+#include "nsCSSStyleSheet.h"
 #include "txStringUtils.h"
 #include "txURIUtils.h"
 #include "nsIHTMLDocument.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsIDocumentTransformer.h"
 #include "nsCSSLoader.h"
 #include "nsICharsetAlias.h"
 #include "nsIHTMLContentSink.h"
@@ -980,17 +980,17 @@ txTransformNotifier::ScriptEvaluated(nsr
     if (mScriptElements.RemoveObject(aElement)) {
         SignalTransformEnd();
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP 
-txTransformNotifier::StyleSheetLoaded(nsICSSStyleSheet* aSheet,
+txTransformNotifier::StyleSheetLoaded(nsCSSStyleSheet* aSheet,
                                       PRBool aWasAlternate,
                                       nsresult aStatus)
 {
     if (mPendingStylesheetCount == 0) {
         // We weren't waiting on this stylesheet anyway.  This can happen if
         // SignalTransformEnd got called with an error aResult.  See
         // http://bugzilla.mozilla.org/show_bug.cgi?id=215465.
         return NS_OK;
--- a/content/xslt/src/xslt/txMozillaXMLOutput.h
+++ b/content/xslt/src/xslt/txMozillaXMLOutput.h
@@ -64,17 +64,17 @@ class txTransformNotifier : public nsISc
 {
 public:
     txTransformNotifier();
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSISCRIPTLOADEROBSERVER
     
     // nsICSSLoaderObserver
-    NS_IMETHOD StyleSheetLoaded(nsICSSStyleSheet* aSheet,
+    NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet,
                                 PRBool aWasAlternate,
                                 nsresult aStatus);
 
     void Init(nsITransformObserver* aObserver);
     nsresult AddScriptElement(nsIScriptElement* aElement);
     void AddPendingStylesheet();
     void OnTransformEnd(nsresult aResult = NS_OK);
     void OnTransformStart();
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -108,17 +108,17 @@
 #include "nsIScriptGlobalObjectOwner.h"
 #include "nsIScriptRuntime.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsNodeInfoManager.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentUtils.h"
 #include "nsIParser.h"
 #include "nsIParserService.h"
-#include "nsICSSStyleSheet.h"
+#include "nsCSSStyleSheet.h"
 #include "nsCSSLoader.h"
 #include "nsIScriptError.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsEventDispatcher.h"
 #include "nsContentErrors.h"
 #include "nsIObserverService.h"
 #include "nsNodeUtils.h"
 #include "nsIDocShellTreeItem.h"
@@ -3148,17 +3148,17 @@ nsresult
 nsXULDocument::DoneWalking()
 {
     NS_PRECONDITION(mPendingSheets == 0, "there are sheets to be loaded");
     NS_PRECONDITION(!mStillWalking, "walk not done");
 
     // XXXldb This is where we should really be setting the chromehidden
     // attribute.
 
-    PRUint32 count = mOverlaySheets.Count();
+    PRUint32 count = mOverlaySheets.Length();
     for (PRUint32 i = 0; i < count; ++i) {
         AddStyleSheet(mOverlaySheets[i]);
     }
     mOverlaySheets.Clear();
 
     if (!mDocumentLoaded) {
         // Make sure we don't reenter here from StartLayout().  Note that
         // setting mDocumentLoaded to true here means that if StartLayout()
@@ -3258,17 +3258,17 @@ nsXULDocument::DoneWalking()
             }
         }
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULDocument::StyleSheetLoaded(nsICSSStyleSheet* aSheet,
+nsXULDocument::StyleSheetLoaded(nsCSSStyleSheet* aSheet,
                                 PRBool aWasAlternate,
                                 nsresult aStatus)
 {
     if (!aWasAlternate) {
         // Don't care about when alternate sheets finish loading
 
         NS_ASSERTION(mPendingSheets > 0,
             "Unexpected StyleSheetLoaded notification");
@@ -3888,28 +3888,28 @@ nsXULDocument::AddPrototypeSheets()
 {
     nsresult rv;
 
     const nsCOMArray<nsIURI>& sheets = mCurrentPrototype->GetStyleSheetReferences();
 
     for (PRInt32 i = 0; i < sheets.Count(); i++) {
         nsCOMPtr<nsIURI> uri = sheets[i];
 
-        nsCOMPtr<nsICSSStyleSheet> incompleteSheet;
+        nsRefPtr<nsCSSStyleSheet> incompleteSheet;
         rv = CSSLoader()->LoadSheet(uri,
                                     mCurrentPrototype->DocumentPrincipal(),
                                     EmptyCString(), this,
                                     getter_AddRefs(incompleteSheet));
 
         // XXXldb We need to prevent bogus sheets from being held in the
         // prototype's list, but until then, don't propagate the failure
         // from LoadSheet (and thus exit the loop).
         if (NS_SUCCEEDED(rv)) {
             ++mPendingSheets;
-            if (!mOverlaySheets.AppendObject(incompleteSheet)) {
+            if (!mOverlaySheets.AppendElement(incompleteSheet)) {
                 return NS_ERROR_OUT_OF_MEMORY;
             }
         }
     }
 
     return NS_OK;
 }
 
--- a/content/xul/document/src/nsXULDocument.h
+++ b/content/xul/document/src/nsXULDocument.h
@@ -171,17 +171,17 @@ public:
 
     // nsIDOMXULDocument interface
     NS_DECL_NSIDOMXULDOCUMENT
 
     // nsIDOMNSDocument
     NS_IMETHOD GetContentType(nsAString& aContentType);
 
     // nsICSSLoaderObserver
-    NS_IMETHOD StyleSheetLoaded(nsICSSStyleSheet* aSheet,
+    NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet,
                                 PRBool aWasAlternate,
                                 nsresult aStatus);
 
     virtual void EndUpdate(nsUpdateType aUpdateType);
 
     virtual PRBool IsDocumentRightToLeft();
 
     virtual void ResetDocumentDirection();
@@ -299,17 +299,17 @@ protected:
      * called in this situation.
      */
     PRPackedBool               mStillWalking;
 
     /**
      * An array of style sheets, that will be added (preserving order) to the
      * document after all of them are loaded (in DoneWalking).
      */
-    nsCOMArray<nsICSSStyleSheet> mOverlaySheets;
+    nsTArray<nsRefPtr<nsCSSStyleSheet> > mOverlaySheets;
 
     nsCOMPtr<nsIDOMXULCommandDispatcher>     mCommandDispatcher; // [OWNER] of the focus tracker
 
     // Maintains the template builders that have been attached to
     // content elements
     typedef nsInterfaceHashtable<nsISupportsHashKey, nsIXULTemplateBuilder>
         BuilderTable;
     BuilderTable* mTemplateBuilderTable;
--- a/content/xul/document/src/nsXULPrototypeCache.cpp
+++ b/content/xul/document/src/nsXULPrototypeCache.cpp
@@ -40,17 +40,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsXULPrototypeCache.h"
 
 #include "nsContentUtils.h"
 #include "plstr.h"
 #include "nsXULPrototypeDocument.h"
-#include "nsICSSStyleSheet.h"
+#include "nsCSSStyleSheet.h"
 #include "nsIScriptRuntime.h"
 #include "nsIServiceManager.h"
 #include "nsIURI.h"
 #include "nsIXBLDocumentInfo.h"
 
 #include "nsIChromeRegistry.h"
 #include "nsIFastLoadService.h"
 #include "nsIFastLoadFileControl.h"
@@ -238,22 +238,19 @@ nsXULPrototypeCache::PutPrototype(nsXULP
     nsCOMPtr<nsIURI> uri = aDocument->GetURI();
     // Put() releases any old value and addrefs the new one
     NS_ENSURE_TRUE(mPrototypeTable.Put(uri, aDocument), NS_ERROR_OUT_OF_MEMORY);
 
     return NS_OK;
 }
 
 nsresult
-nsXULPrototypeCache::PutStyleSheet(nsICSSStyleSheet* aStyleSheet)
+nsXULPrototypeCache::PutStyleSheet(nsCSSStyleSheet* aStyleSheet)
 {
-    nsCOMPtr<nsIURI> uri;
-    nsresult rv = aStyleSheet->GetSheetURI(getter_AddRefs(uri));
-    if (NS_FAILED(rv))
-        return rv;
+    nsCOMPtr<nsIURI> uri = aStyleSheet->GetSheetURI();
 
    NS_ENSURE_TRUE(mStyleSheetTable.Put(uri, aStyleSheet),
                   NS_ERROR_OUT_OF_MEMORY);
 
     return NS_OK;
 }
 
 
@@ -340,20 +337,19 @@ FlushSkinXBL(nsIURI* aKey, nsCOMPtr<nsIX
   if (!strncmp(str.get(), "/skin", 5)) {
     ret = PL_DHASH_REMOVE;
   }
 
   return ret;
 }
 
 static PLDHashOperator
-FlushSkinSheets(nsIURI* aKey, nsCOMPtr<nsICSSStyleSheet>& aSheet, void* aClosure)
+FlushSkinSheets(nsIURI* aKey, nsRefPtr<nsCSSStyleSheet>& aSheet, void* aClosure)
 {
-  nsCOMPtr<nsIURI> uri;
-  aSheet->GetSheetURI(getter_AddRefs(uri));
+  nsCOMPtr<nsIURI> uri = aSheet->GetSheetURI();
   nsCAutoString str;
   uri->GetPath(str);
 
   PLDHashOperator ret = PL_DHASH_NEXT;
 
   if (!strncmp(str.get(), "/skin", 5)) {
     // This is a skin binding. Add the key to the list.
     ret = PL_DHASH_REMOVE;
--- a/content/xul/document/src/nsXULPrototypeCache.h
+++ b/content/xul/document/src/nsXULPrototypeCache.h
@@ -39,27 +39,27 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsXULPrototypeCache_h__
 #define nsXULPrototypeCache_h__
 
 #include "nsCOMPtr.h"
-#include "nsICSSStyleSheet.h"
 #include "nsIObserver.h"
 #include "nsIXBLDocumentInfo.h"
 #include "nsIXULPrototypeCache.h"
 #include "nsDataHashtable.h"
 #include "nsInterfaceHashtable.h"
 #include "nsRefPtrHashtable.h"
 #include "nsURIHashKey.h"
 #include "nsXULPrototypeDocument.h"
 
 class nsIFastLoadService;
+class nsCSSStyleSheet;
 
 struct CacheScriptEntry
 {
     PRUint32    mScriptTypeID; // the script language ID.
     void*       mScriptObject; // the script object.
 };
 
 /**
@@ -120,25 +120,25 @@ public:
         return mXBLDocTable.GetWeak(aURL);
     }
     nsresult PutXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo);
 
     /**
      * Get a style sheet by URI. If the style sheet is not in the cache,
      * returns nsnull.
      */
-    nsICSSStyleSheet* GetStyleSheet(nsIURI* aURI) {
+    nsCSSStyleSheet* GetStyleSheet(nsIURI* aURI) {
         return mStyleSheetTable.GetWeak(aURI);
     }
 
     /**
      * Store a style sheet in the cache. The key, style sheet's URI is obtained
      * from the style sheet itself.
      */
-    nsresult PutStyleSheet(nsICSSStyleSheet* aStyleSheet);
+    nsresult PutStyleSheet(nsCSSStyleSheet* aStyleSheet);
 
 
     static nsXULPrototypeCache* GetInstance();
     static nsIFastLoadService* GetFastLoadService();
 
     static void ReleaseGlobals()
     {
         NS_IF_RELEASE(sInstance);
@@ -152,17 +152,17 @@ protected:
     virtual ~nsXULPrototypeCache();
 
     static nsXULPrototypeCache* sInstance;
 
     void FlushScripts();
     void FlushSkinFiles();
 
     nsRefPtrHashtable<nsURIHashKey,nsXULPrototypeDocument>  mPrototypeTable; // owns the prototypes
-    nsInterfaceHashtable<nsURIHashKey,nsICSSStyleSheet>    mStyleSheetTable;
+    nsRefPtrHashtable<nsURIHashKey,nsCSSStyleSheet>        mStyleSheetTable;
     nsDataHashtable<nsURIHashKey,CacheScriptEntry>         mScriptTable;
     nsInterfaceHashtable<nsURIHashKey,nsIXBLDocumentInfo>  mXBLDocTable;
 
     ///////////////////////////////////////////////////////////////////////////
     // FastLoad
     // this is really a hash set, with a dummy data parameter
     nsDataHashtable<nsURIHashKey,PRUint32> mFastLoadURITable;
 
--- a/docshell/base/crashtests/crashtests.list
+++ b/docshell/base/crashtests/crashtests.list
@@ -1,9 +1,9 @@
 load 40929-1.html
 load 369126-1.html
 load 403574-1.xhtml
 load 430124-1.html
 load 430628-1.html
 asserts(1-4) load 432114-1.html # bug 336104 and others
-asserts(0-1) load 432114-2.html # bug 336104
+asserts(0-2) load 432114-2.html # bug 336104, bug 492165
 load 436900-1.html
 load 500328-1.html
new file mode 100644
--- /dev/null
+++ b/dom/base/crashtests/499006-1.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+<script type="text/javascript">
+
+function select(start, startOffset, end, endOffset) {
+  var sel = getSelection();
+  sel.removeAllRanges();
+  var range = document.createRange();
+  range.setStart(start, startOffset);
+  range.setEnd(end, endOffset);
+  sel.addRange(range);
+}
+
+function boom() {
+  var p = document.body;
+  select(p.childNodes[0],0,p.childNodes[0],1);
+  sel = getSelection();
+  range = sel.getRangeAt(0);
+  range.detach();
+  range.insertNode(p);
+}
+
+</script>
+</head>
+<body onload="boom()"><span>Hello Kitty</span></body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/base/crashtests/499006-2.html
@@ -0,0 +1,35 @@
+<html>
+<head>
+<script>
+function extractc(j) {
+var sel = window.getSelection();
+
+
+var b=document.getElementById('b');
+
+var range =document.createRange();
+range.setStart(document.documentElement, 0);
+range.setEnd(document.documentElement, 0);
+sel.addRange(range);
+range.extractContents();
+
+range.setStart(b, 0);
+range.setEnd(b, 0);
+sel.addRange(range);
+range.extractContents();
+
+
+range.setStart(b, 0);
+range.setEnd(b, 0);
+sel.addRange(range);
+range.extractContents();
+
+
+}
+setTimeout(extractc,200,0);
+</script>
+<title id="b"></title>
+</head>
+<body>
+</body>
+</html>
\ No newline at end of file
--- a/dom/base/crashtests/crashtests.list
+++ b/dom/base/crashtests/crashtests.list
@@ -13,10 +13,12 @@ load 371124-1.html
 load 371124-2.html
 load 372554-1.html
 load 375399-1.html
 load 404869-1.xul
 load 417852-1.html
 load 462947.html
 load 439206-1.html
 load 473284.xul
+load 499006-1.html
+load 499006-2.html
 load 502617.html
 asserts(1) load 504224.html # bug 564098
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1769,17 +1769,17 @@ nsDOMClassInfo::ThrowJSException(JSConte
 
   if (NS_SUCCEEDED(CreateExceptionFromResult(cx, aResult))) {
     return NS_OK;
   }
 
   // XXX This probably wants to be localized, but that can fail in ways that
   // are hard to report correctly.
   JSString *str =
-    JS_NewStringCopyZ(cx, "An error occured throwing an exception");
+    JS_NewStringCopyZ(cx, "An error occurred throwing an exception");
   if (!str) {
     // JS_NewStringCopyZ reported the error for us.
     return NS_OK; 
   }
   JS_SetPendingException(cx, STRING_TO_JSVAL(str));
   return NS_OK;
 }
 
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -1517,17 +1517,17 @@ nsFocusManager::Blur(nsPIDOMWindow* aWin
     if (mFocusedWindow == nsnull)
       SendFocusOrBlurEvent(NS_BLUR_CONTENT, presShell, doc, window, 1, PR_FALSE);
 
     // check if a different window was focused
     result = (mFocusedWindow == nsnull && mActiveWindow);
   }
   else if (mActiveWindow) {
     // Otherwise, the blur of the element without blurring the document
-    // occured normally. Call UpdateCaret to redisplay the caret at the right
+    // occurred normally. Call UpdateCaret to redisplay the caret at the right
     // location within the document. This is needed to ensure that the caret
     // used for caret browsing is made visible again when an input field is
     // blurred.
     UpdateCaret(PR_FALSE, PR_TRUE, nsnull);
   }
 
   if (clearFirstBlurEvent)
     mFirstBlurEvent = nsnull;
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -127,26 +127,26 @@
 #include "nsIHttpProtocolHandler.h"
 #include "nsIJSContextStack.h"
 #include "nsIJSRuntimeService.h"
 #include "nsIMarkupDocumentViewer.h"
 #include "nsIPrefBranch.h"
 #include "nsIPresShell.h"
 #include "nsIPrivateDOMEvent.h"
 #include "nsIProgrammingLanguage.h"
-#include "nsIAuthPrompt.h"
 #include "nsIServiceManager.h"
 #include "nsIScriptGlobalObjectOwner.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIScrollableFrame.h"
 #include "nsIView.h"
 #include "nsIViewManager.h"
 #include "nsISelectionController.h"
 #include "nsISelection.h"
 #include "nsIPrompt.h"
+#include "nsIPromptService.h"
 #include "nsIWebNavigation.h"
 #include "nsIWebBrowser.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsIWebBrowserFind.h"  // For window.find()
 #include "nsIWebContentHandlerRegistrar.h"
 #include "nsIWindowMediator.h"  // For window.find()
 #include "nsComputedDOMStyle.h"
 #include "nsIEntropyCollector.h"
@@ -663,17 +663,17 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalW
 #if defined(XP_MAC) || defined(XP_MACOSX)
     mShowAccelerators(PR_FALSE),
     mShowFocusRings(PR_FALSE),
 #else
     mShowAccelerators(PR_TRUE),
     mShowFocusRings(PR_TRUE),
 #endif
     mShowFocusRingForContent(PR_FALSE),
-    mFocusByKeyOccured(PR_FALSE),
+    mFocusByKeyOccurred(PR_FALSE),
     mHasAcceleration(PR_FALSE),
     mTimeoutInsertionPoint(nsnull),
     mTimeoutPublicIdCounter(1),
     mTimeoutFiringDepth(0),
     mJSObject(nsnull),
     mPendingStorageEventsObsolete(nsnull),
     mTimeoutsSuspendDepth(0),
     mFocusMethod(0)
@@ -3576,16 +3576,35 @@ nsGlobalWindow::GetMozInnerScreenY(float
   FORWARD_TO_OUTER(GetMozInnerScreenY, (aScreenY), NS_ERROR_NOT_INITIALIZED);
 
   nsRect r = GetInnerScreenRect();
   *aScreenY = nsPresContext::AppUnitsToFloatCSSPixels(r.y);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsGlobalWindow::GetMozPaintCount(PRUint64* aResult)
+{
+  FORWARD_TO_OUTER(GetMozPaintCount, (aResult), NS_ERROR_NOT_INITIALIZED);
+
+  *aResult = 0;
+
+  if (!mDocShell)
+    return NS_OK;
+
+  nsCOMPtr<nsIPresShell> presShell;
+  mDocShell->GetPresShell(getter_AddRefs(presShell));
+  if (!presShell)
+    return NS_OK;
+
+  *aResult = presShell->GetPaintCount();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsGlobalWindow::SetScreenX(PRInt32 aScreenX)
 {
   FORWARD_TO_OUTER(SetScreenX, (aScreenX), NS_ERROR_NOT_INITIALIZED);
 
   /*
    * If caller is not chrome and the user has not explicitly exempted the site,
    * prevent setting window.screenX by exiting early
    */
@@ -4236,19 +4255,16 @@ nsGlobalWindow::CanMoveResizeWindows()
   return PR_TRUE;
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::Alert(const nsAString& aString)
 {
   FORWARD_TO_OUTER(Alert, (aString), NS_ERROR_NOT_INITIALIZED);
 
-  nsCOMPtr<nsIPrompt> prompter(do_GetInterface(mDocShell));
-  NS_ENSURE_TRUE(prompter, NS_ERROR_FAILURE);
-
   // Reset popup state while opening a modal dialog, and firing events
   // about the dialog, to prevent the current state from being active
   // the whole time a modal dialog is open.
   nsAutoPopupStatePusher popupStatePusher(openAbused, PR_TRUE);
 
   // Special handling for alert(null) in JS for backwards
   // compatibility.
 
@@ -4263,27 +4279,28 @@ nsGlobalWindow::Alert(const nsAString& a
   nsAutoString title;
   MakeScriptDialogTitle(title);
 
   // Remove non-terminating null characters from the 
   // string. See bug #310037. 
   nsAutoString final;
   nsContentUtils::StripNullChars(*str, final);
 
-  return prompter->Alert(title.get(), final.get());
+  nsresult rv;
+  nsCOMPtr<nsIPromptService> promptSvc = do_GetService("@mozilla.org/embedcomp/prompt-service;1", &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return promptSvc->Alert(this, title.get(), final.get());
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::Confirm(const nsAString& aString, PRBool* aReturn)
 {
   FORWARD_TO_OUTER(Confirm, (aString, aReturn), NS_ERROR_NOT_INITIALIZED);
 
-  nsCOMPtr<nsIPrompt> prompter(do_GetInterface(mDocShell));
-  NS_ENSURE_TRUE(prompter, NS_ERROR_FAILURE);
-
   // Reset popup state while opening a modal dialog, and firing events
   // about the dialog, to prevent the current state from being active
   // the whole time a modal dialog is open.
   nsAutoPopupStatePusher popupStatePusher(openAbused, PR_TRUE);
 
   *aReturn = PR_FALSE;
 
   // Before bringing up the window, unsuppress painting and flush
@@ -4293,72 +4310,63 @@ nsGlobalWindow::Confirm(const nsAString&
   nsAutoString title;
   MakeScriptDialogTitle(title);
 
   // Remove non-terminating null characters from the 
   // string. See bug #310037. 
   nsAutoString final;
   nsContentUtils::StripNullChars(aString, final);
 
-  return prompter->Confirm(title.get(), final.get(),
-                           aReturn);
+  nsresult rv;
+  nsCOMPtr<nsIPromptService> promptSvc = do_GetService("@mozilla.org/embedcomp/prompt-service;1", &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return promptSvc->Confirm(this, title.get(), final.get(), aReturn);
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::Prompt(const nsAString& aMessage, const nsAString& aInitial,
-                       const nsAString& aTitle, PRUint32 aSavePassword,
                        nsAString& aReturn)
 {
-  // We don't use "aTitle" because we ignore the 3rd (title) argument to
-  // prompt(). IE and Opera ignore it too. See Mozilla bug 334893.
   SetDOMStringToNull(aReturn);
 
-  // This code depends on aSavePassword being defaulted to
-  // nsIAuthPrompt::SAVE_PASSWORD_NEVER, which happens to have the
-  // value 0. If that ever changes, this code needs to deal!
-
-  PR_STATIC_ASSERT(nsIAuthPrompt::SAVE_PASSWORD_NEVER == 0);
-
-  nsresult rv;
-  nsCOMPtr<nsIWindowWatcher> wwatch =
-    do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIAuthPrompt> prompter;
-  wwatch->GetNewAuthPrompter(this, getter_AddRefs(prompter));
-  NS_ENSURE_TRUE(prompter, NS_ERROR_FAILURE);
-
   // Reset popup state while opening a modal dialog, and firing events
   // about the dialog, to prevent the current state from being active
   // the whole time a modal dialog is open.
   nsAutoPopupStatePusher popupStatePusher(openAbused, PR_TRUE);
 
-  PRBool b;
-  nsXPIDLString uniResult;
-
   // Before bringing up the window, unsuppress painting and flush
   // pending reflows.
   EnsureReflowFlushAndPaint();
 
   nsAutoString title;
   MakeScriptDialogTitle(title);
   
   // Remove non-terminating null characters from the 
   // string. See bug #310037. 
   nsAutoString fixedMessage, fixedInitial;
   nsContentUtils::StripNullChars(aMessage, fixedMessage);
   nsContentUtils::StripNullChars(aInitial, fixedInitial);
 
-  rv = prompter->Prompt(title.get(), fixedMessage.get(), nsnull,
-                        aSavePassword, fixedInitial.get(),
-                        getter_Copies(uniResult), &b);
+  nsresult rv;
+  nsCOMPtr<nsIPromptService> promptSvc = do_GetService("@mozilla.org/embedcomp/prompt-service;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (uniResult && b) {
-    aReturn.Assign(uniResult);
+  // Pass in the default value, if any.
+  PRUnichar *inoutValue = ToNewUnicode(fixedInitial);
+
+  PRBool ok, dummy;
+  rv = promptSvc->Prompt(this, title.get(), fixedMessage.get(),
+                         &inoutValue, nsnull, &dummy, &ok);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsAdoptingString outValue(inoutValue);
+
+  if (ok && outValue) {
+    aReturn.Assign(outValue);
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::Focus()
 {
@@ -6960,17 +6968,17 @@ nsGlobalWindow::SetFocusedNode(nsIConten
 
   if (mFocusedNode) {
     // if a node was focused by a keypress, turn on focus rings for the
     // window. Focus rings are always shown when the FLAG_SHOWRING flag is
     // used, or for XUL elements on GTK, but in this case we set
     // mShowFocusRingForContent, as we don't want this to be permanent for
     // the window.
     if (mFocusMethod == nsIFocusManager::FLAG_BYKEY) {
-      mFocusByKeyOccured = PR_TRUE;
+      mFocusByKeyOccurred = PR_TRUE;
     } else if (aFocusMethod & nsIFocusManager::FLAG_SHOWRING
 #ifdef MOZ_WIDGET_GTK2
              || mFocusedNode->IsXUL()
 #endif
             ) {
       mShowFocusRingForContent = PR_TRUE;
     }
   }
@@ -6987,17 +6995,17 @@ nsGlobalWindow::GetFocusMethod()
   return mFocusMethod;
 }
 
 PRBool
 nsGlobalWindow::ShouldShowFocusRing()
 {
   FORWARD_TO_INNER(ShouldShowFocusRing, (), PR_FALSE);
 
-  return mShowFocusRings || mShowFocusRingForContent || mFocusByKeyOccured;
+  return mShowFocusRings || mShowFocusRingForContent || mFocusByKeyOccurred;
 }
 
 void
 nsGlobalWindow::SetKeyboardIndicators(UIStateChangeType aShowAccelerators,
                                       UIStateChangeType aShowFocusRings)
 {
   FORWARD_TO_INNER_VOID(SetKeyboardIndicators, (aShowAccelerators, aShowFocusRings));
 
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -734,19 +734,19 @@ protected:
 
   // whether to show focus rings
   PRPackedBool           mShowFocusRings : 1;
 
   // when true, show focus rings for the current focused content only.
   // This will be reset when another element is focused
   PRPackedBool           mShowFocusRingForContent : 1;
 
-  // true if tab navigation has occured for this window. Focus rings
+  // true if tab navigation has occurred for this window. Focus rings
   // should be displayed.
-  PRPackedBool           mFocusByKeyOccured : 1;
+  PRPackedBool           mFocusByKeyOccurred : 1;
 
   // Indicates whether this window is getting acceleration change events
   PRPackedBool           mHasAcceleration  : 1;
 
   nsCOMPtr<nsIScriptContext>    mContext;
   nsWeakPtr                     mOpener;
   nsCOMPtr<nsIControllers>      mControllers;
   nsCOMPtr<nsIArray>            mArguments;
--- a/dom/interfaces/base/nsIDOMWindowInternal.idl
+++ b/dom/interfaces/base/nsIDOMWindowInternal.idl
@@ -39,17 +39,17 @@
 
 #include "nsIDOMWindow2.idl"
 
 interface nsIPrompt;
 interface nsIControllers;
 interface nsIDOMLocation;
 interface nsIVariant;
 
-[scriptable, uuid(c2f4433a-8b4c-4676-ab30-3bffd26fb29e)]
+[scriptable, uuid(52d034f1-f1a6-4be7-adc9-b39fa7df51de)]
 interface nsIDOMWindowInternal : nsIDOMWindow2
 {
   readonly attribute nsIDOMWindowInternal        window;
 
   /* [replaceable] self */
   readonly attribute nsIDOMWindowInternal        self;
 
   readonly attribute nsIDOMNavigator             navigator;
@@ -121,19 +121,17 @@ interface nsIDOMWindowInternal : nsIDOMW
 
            attribute boolean                     fullScreen;
 
   void                      alert(in DOMString text);
   boolean                   confirm(in DOMString text);
 
   // prompt() should return a null string if cancel is pressed
   DOMString                 prompt([optional] in DOMString aMessage,
-                                   [optional] in DOMString aInitial,
-                                   [optional] in DOMString aTitle,
-                                   [optional] in unsigned long aSavePassword);
+                                   [optional] in DOMString aInitial);
 
   void                      focus();
   void                      blur();
 
   void                      back();
   void                      forward();
   void                      home();
   void                      stop();
@@ -213,9 +211,15 @@ interface nsIDOMWindowInternal : nsIDOMW
    * only when the target window has the same origin as targetOrigin (since,
    * when the sender and the target have different origins, neither can read the
    * location of the other).
    * 
    * See the WHATWG HTML5 specification, section 6.4, for more details.
    */
   [binaryname(PostMessageMoz)] void postMessage(in DOMString message,
                                                 in DOMString targetOrigin);
+
+  /**
+   * Returns the number of times this document for this window has
+   * been painted to the screen.
+   */
+  readonly attribute unsigned long long mozPaintCount;
 };
--- a/dom/interfaces/html/nsIDOMNSHTMLInputElement.idl
+++ b/dom/interfaces/html/nsIDOMNSHTMLInputElement.idl
@@ -37,17 +37,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "domstubs.idl"
 
 interface nsIControllers;
 interface nsIDOMFileList;
 
-[scriptable, uuid(e79806b8-7788-4229-ac69-debe395cb0e1)]
+[scriptable, uuid(bc4acab7-1ad4-40ce-8b5f-c95bdd7bf8ff)]
 interface nsIDOMNSHTMLInputElement : nsISupports
 {
 	readonly attribute nsIControllers   controllers;
 	
 	readonly attribute long             textLength;
 	
            attribute long             selectionStart;
            attribute long             selectionEnd;
@@ -63,9 +63,15 @@ interface nsIDOMNSHTMLInputElement : nsI
   void mozGetFileNameArray([optional] out unsigned long aLength,
                            [array,size_is(aLength), retval] out wstring aFileNames);
   void mozSetFileNameArray([array,size_is(aLength)] in wstring aFileNames,
                            in unsigned long aLength);
 
 	/* convenience */
   void                      setSelectionRange(in long selectionStart,
                                               in long selectionEnd);
+
+  /**
+   * This non-standard method prevents to check types manually to know if the
+   * element is a text field.
+   */
+  boolean mozIsTextField(in boolean aExcludePassword);
 };
--- a/dom/locales/en-US/chrome/xslt/xslt.properties
+++ b/dom/locales/en-US/chrome/xslt/xslt.properties
@@ -39,17 +39,17 @@ 1  = Parsing an XSLT stylesheet failed.
 2  = Parsing an XPath expression failed.
 3  = 
 4  = XSLT transformation failed.
 5  = Invalid XSLT/XPath function.
 6  = XSLT Stylesheet (possibly) contains a recursion.
 7  = Attribute value illegal in XSLT 1.0.
 8  = An XPath expression was expected to return a NodeSet.
 9  = XSLT transformation was terminated by <xsl:message>.
-10 = A network error occured loading an XSLT stylesheet:
+10 = A network error occurred loading an XSLT stylesheet:
 11 = An XSLT stylesheet does not have an XML mimetype:
 12 = An XSLT stylesheet directly or indirectly imports or includes itself:
 13 = An XPath function was called with the wrong number of arguments.
 14 = An unknown XPath extension function was called.
 15 = XPath parse failure: ')' expected:
 16 = XPath parse failure: invalid axis:
 17 = XPath parse failure: Name or Nodetype test expected:
 18 = XPath parse failure: ']' expected:
--- a/dom/plugins/BrowserStreamChild.cpp
+++ b/dom/plugins/BrowserStreamChild.cpp
@@ -268,17 +268,17 @@ BrowserStreamChild::Deliver()
 bool
 BrowserStreamChild::DeliverPendingData()
 {
   if (mState != ALIVE && mState != DYING)
     NS_RUNTIMEABORT("Unexpected state");
 
   NS_ASSERTION(mPendingData.Length(), "Called from Deliver with empty pending");
 
-  while (mPendingData[0].curpos < mPendingData[0].data.Length()) {
+  while (mPendingData[0].curpos < static_cast<int32_t>(mPendingData[0].data.Length())) {
     int32_t r = mInstance->mPluginIface->writeready(&mInstance->mData, &mStream);
     if (kStreamOpen != mStreamStatus)
       return false;
     if (0 == r) // plugin wants to suspend delivery
       return true;
 
     r = mInstance->mPluginIface->write(
       &mInstance->mData, &mStream,
--- a/dom/plugins/Makefile.in
+++ b/dom/plugins/Makefile.in
@@ -78,17 +78,17 @@ EXPORTS_mozilla/plugins = \
   PluginInstanceParent.h \
   AStream.h \
   BrowserStreamChild.h \
   BrowserStreamParent.h \
   PluginStreamChild.h \
   PluginStreamParent.h \
   PluginMessageUtils.h \
   PluginProcessParent.h \
-  PluginThreadChild.h \
+  PluginProcessChild.h \
   StreamNotifyChild.h \
   StreamNotifyParent.h \
   $(NULL)
 
 MODULE           = dom
 LIBRARY_NAME     = domplugins_s
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
@@ -98,24 +98,24 @@ ENABLE_CXX_EXCEPTIONS = 1
 CPPSRCS = \
   ChildAsyncCall.cpp \
   ChildTimer.cpp \
   PluginMessageUtils.cpp \
   PluginInstanceChild.cpp \
   PluginInstanceParent.cpp \
   PluginModuleChild.cpp \
   PluginModuleParent.cpp \
+  PluginProcessChild.cpp \
   PluginProcessParent.cpp \
   PluginScriptableObjectChild.cpp \
   PluginScriptableObjectParent.cpp \
   BrowserStreamChild.cpp \
   BrowserStreamParent.cpp \
   PluginStreamChild.cpp \
   PluginStreamParent.cpp \
-  PluginThreadChild.cpp \
   $(NULL)
 
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/modules/plugin/base/public/ \
   -I$(topsrcdir)/modules/plugin/base/src/ \
   $(NULL)
 
 include $(topsrcdir)/config/config.mk
--- a/dom/plugins/PluginInstanceChild.cpp
+++ b/dom/plugins/PluginInstanceChild.cpp
@@ -37,20 +37,21 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "PluginInstanceChild.h"
 #include "PluginModuleChild.h"
 #include "BrowserStreamChild.h"
 #include "PluginStreamChild.h"
 #include "StreamNotifyChild.h"
-#include "PluginThreadChild.h"
+#include "PluginProcessChild.h"
 
 #include "mozilla/ipc/SyncChannel.h"
 
+using mozilla::ipc::ProcessChild;
 using namespace mozilla::plugins;
 
 #ifdef MOZ_WIDGET_GTK2
 
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
 #include <gdk/gdk.h>
 #include "gtk2xtbin.h"
@@ -1925,17 +1926,17 @@ void
 PluginInstanceChild::AsyncCall(PluginThreadCallback aFunc, void* aUserData)
 {
     ChildAsyncCall* task = new ChildAsyncCall(this, aFunc, aUserData);
 
     {
         MutexAutoLock lock(mAsyncCallMutex);
         mPendingAsyncCalls.AppendElement(task);
     }
-    PluginThreadChild::current()->message_loop()->PostTask(FROM_HERE, task);
+    ProcessChild::message_loop()->PostTask(FROM_HERE, task);
 }
 
 static PLDHashOperator
 InvalidateObject(DeletingObjectEntry* e, void* userArg)
 {
     NPObject* o = e->GetKey();
     if (!e->mDeleted && o->_class && o->_class->invalidate)
         o->_class->invalidate(o);
--- a/dom/plugins/PluginModuleChild.cpp
+++ b/dom/plugins/PluginModuleChild.cpp
@@ -54,17 +54,16 @@
 #include "nsCOMPtr.h"
 #include "nsPluginsDir.h"
 #include "nsXULAppAPI.h"
 
 #include "mozilla/plugins/PluginInstanceChild.h"
 #include "mozilla/plugins/StreamNotifyChild.h"
 #include "mozilla/plugins/BrowserStreamChild.h"
 #include "mozilla/plugins/PluginStreamChild.h"
-#include "mozilla/plugins/PluginThreadChild.h"
 #include "PluginIdentifierChild.h"
 
 #include "nsNPAPIPlugin.h"
 
 using namespace mozilla::plugins;
 
 #if defined(XP_WIN)
 #ifndef WM_MOUSEHWHEEL
--- a/dom/plugins/PluginModuleParent.cpp
+++ b/dom/plugins/PluginModuleParent.cpp
@@ -732,17 +732,17 @@ PluginModuleParent::NPP_New(NPMIMEType p
         // condition is signaled to nsNPAPIPluginInstance
         if (NPERR_NO_ERROR == *error)
             *error = NPERR_GENERIC_ERROR;
         return NS_ERROR_FAILURE;
     }
 
     if (*error != NPERR_NO_ERROR) {
         NPP_Destroy(instance, 0);
-        return *error;
+        return NS_ERROR_FAILURE;
     }
 
     return NS_OK;
 }
 
 bool
 PluginModuleParent::AnswerNPN_GetValue_WithBoolReturn(const NPNVariable& aVariable,
                                                       NPError* aError,
rename from dom/plugins/PluginThreadChild.cpp
rename to dom/plugins/PluginProcessChild.cpp
--- a/dom/plugins/PluginThreadChild.cpp
+++ b/dom/plugins/PluginProcessChild.cpp
@@ -32,48 +32,45 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "mozilla/plugins/PluginThreadChild.h"
+#include "mozilla/ipc/IOThreadChild.h"
+#include "mozilla/plugins/PluginProcessChild.h"
 
 #include "prlink.h"
 
 #include "base/command_line.h"
 #include "base/string_util.h"
-#include "chrome/common/child_process.h"
 #include "chrome/common/chrome_switches.h"
 
-using mozilla::ipc::MozillaChildThread;
+#ifdef XP_WIN
+#include <objbase.h>
+#endif
+
+using mozilla::ipc::IOThreadChild;
 
 namespace mozilla {
 namespace plugins {
 
-PluginThreadChild::PluginThreadChild(ProcessHandle aParentHandle) :
-    MozillaChildThread(aParentHandle, MessageLoop::TYPE_UI)
-{
-    NS_ASSERTION(!gInstance, "Two PluginThreadChild?");
-    gInstance = this;
-}
-
-PluginThreadChild::~PluginThreadChild()
+bool
+PluginProcessChild::Init()
 {
-    gInstance = NULL;
-}
-
-PluginThreadChild* PluginThreadChild::gInstance;
+#ifdef XP_WIN
+    // Silverlight depends on the host calling CoInitialize.
+    ::CoInitialize(NULL);
+#endif
 
-void
-PluginThreadChild::Init()
-{
-    MozillaChildThread::Init();
+    // Certain plugins, such as flash, steal the unhandled exception filter
+    // thus we never get crash reports when they fault. This call fixes it.
+    message_loop()->set_exception_restoration(true);
 
     std::string pluginFilename;
 
 #if defined(OS_POSIX)
     // NB: need to be very careful in ensuring that the first arg
     // (after the binary name) here is indeed the plugin module path.
     // Keep in sync with dom/plugins/PluginModuleParent.
     std::vector<std::string> values = CommandLine::ForCurrentProcess()->argv();
@@ -87,33 +84,37 @@ PluginThreadChild::Init()
     NS_ABORT_IF_FALSE(values.size() >= 1, "not enough loose args");
 
     pluginFilename = WideToUTF8(values[0]);
 
 #else
 #  error Sorry
 #endif
 
-    // FIXME owner_loop() is bad here
-    mPlugin.Init(pluginFilename,
-                 GetParentProcessHandle(), owner_loop(), channel());
+    mPlugin.Init(pluginFilename, ParentHandle(),
+                 IOThreadChild::message_loop(),
+                 IOThreadChild::channel());
+
+    return true;
 }
 
 void
-PluginThreadChild::CleanUp()
+PluginProcessChild::CleanUp()
 {
-    mPlugin.CleanUp();
-    MozillaChildThread::CleanUp();
+#ifdef XP_WIN
+    ::CoUninitialize();
+#endif
 }
 
 /* static */
 void
-PluginThreadChild::AppendNotesToCrashReport(const nsCString& aNotes)
+PluginProcessChild::AppendNotesToCrashReport(const nsCString& aNotes)
 {
     AssertPluginThread();
 
-    if (gInstance) {
-        gInstance->mPlugin.SendAppendNotesToCrashReport(aNotes);
+    PluginProcessChild* p = PluginProcessChild::current();
+    if (p) {
+        p->mPlugin.SendAppendNotesToCrashReport(aNotes);
     }
 }
 
 } // namespace plugins
 } // namespace mozilla
rename from dom/plugins/PluginThreadChild.h
rename to dom/plugins/PluginProcessChild.h
--- a/dom/plugins/PluginThreadChild.h
+++ b/dom/plugins/PluginProcessChild.h
@@ -32,54 +32,50 @@
  * 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 dom_plugins_PluginThreadChild_h
-#define dom_plugins_PluginThreadChild_h 1
-
-#include "base/basictypes.h"
+#ifndef dom_plugins_PluginProcessChild_h
+#define dom_plugins_PluginProcessChild_h 1
 
-#include "mozilla/ipc/MozillaChildThread.h"
-#include "base/file_path.h"
-#include "base/process.h"
-
+#include "mozilla/ipc/ProcessChild.h"
 #include "mozilla/plugins/PluginModuleChild.h"
 
 namespace mozilla {
 namespace plugins {
 //-----------------------------------------------------------------------------
 
-// The PluginThreadChild class represents a background thread where plugin instances
-// live.
-class PluginThreadChild : public mozilla::ipc::MozillaChildThread {
+class PluginProcessChild : public mozilla::ipc::ProcessChild {
+protected:
+    typedef mozilla::ipc::ProcessChild ProcessChild;
+
 public:
-    PluginThreadChild(ProcessHandle aParentHandle);
-    ~PluginThreadChild();
+    PluginProcessChild(ProcessHandle parentHandle) : ProcessChild(parentHandle)
+    { }
 
-    static PluginThreadChild* current() {
-        return gInstance;
-    }
+    virtual ~PluginProcessChild()
+    { }
+
+    NS_OVERRIDE virtual bool Init();
+    NS_OVERRIDE virtual void CleanUp();
 
     // For use on the plugin thread.
     static void AppendNotesToCrashReport(const nsCString& aNotes);
 
-private:
-    static PluginThreadChild* gInstance;
+protected:
+    static PluginProcessChild* current() {
+        return static_cast<PluginProcessChild*>(ProcessChild::current());
+    }
 
-    // Thread implementation:
-    virtual void Init();
-    virtual void CleanUp();
+private:
+    PluginModuleChild mPlugin;
 
-    PluginModuleChild mPlugin;
-    IPC::Channel* mChannel;
-
-    DISALLOW_EVIL_CONSTRUCTORS(PluginThreadChild);
+    DISALLOW_EVIL_CONSTRUCTORS(PluginProcessChild);
 };
 
 }  // namespace plugins
 }  // namespace mozilla
 
-#endif  // ifndef dom_plugins_PluginThreadChild_h
+#endif  // ifndef dom_plugins_PluginProcessChild_h
--- a/dom/tests/mochitest/general/489127.html
+++ b/dom/tests/mochitest/general/489127.html
@@ -13,22 +13,22 @@
   let e = {};
 
   // Enable privileges so we can use nsIDOMWindowUtils interface
   netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   let dwu = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                   .getInterface(Components.interfaces.nsIDOMWindowUtils);
 
   /*
-    nsIDOMNodeList nodesFromRect(in long aX,
-                                 in long aY,
-                                 in long aTopSize, 
-                                 in long aRightSize,
-                                 in long aBottomSize,
-                                 in long aLeftSize,
+    nsIDOMNodeList nodesFromRect(in float aX,
+                                 in float aY,
+                                 in float aTopSize, 
+                                 in float aRightSize,
+                                 in float aBottomSize,
+                                 in float aLeftSize,
                                  in boolean aIgnoreRootScrollFrame,
                                  in boolean aFlushLayout);
 
   */
 
   function check(x, y, top, right, bottom, left, list) {
     let nodes = dwu.nodesFromRect(x, y, top, right, bottom, left, true, false);
     
@@ -59,27 +59,26 @@
 
     // Set up shortcut access to elements
     e['html'] = document.getElementsByTagName("html")[0];
     ['h1', 'd1', 'd2', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'span',
      'a1', 'a2', 'a3', 'transf', 'iframe1', 'decimal', 'body'].forEach(function(a) {
       e[a] = document.getElementById(a);
     });
 
+    window.scrollTo(0, 0);
+
     // Top, Right, Bottom, Left directions:
     check(53, 71, 0,  0,  0,  0, []);
     check(53, 71, 10, 0,  0,  0, [e.h1]);
     check(53, 71, 0,  10, 0,  0, [e.p3]);
     check(53, 71, 0,  0,  10, 0, [e.d1]);
     check(152, 105, 0, 0, 0, 10, [e.d1]);
     check(152, 105, 10, 10, 10, 10, [e.p4, e.p3, e.d1]);
 
-    // Including text nodes:
-    check(53,71,30,30,30,30, [e.p3.firstChild, e.p3, e.d1.firstChild, e.h1.firstChild, e.d1, e.h1]);
-
     // e.p1 is invisible and shouldn't appear:
     check(153,193,0,0,0,0,[e.p5]);
     check(153,193,0,20,0,20, [e.p5, e.d2]);
 
     // Precise pixel checks:
     check(144, 183, 0, 0, 0, 0, []);
     check(144, 183, 0, 0, 1, 0, [e.p5]);
     check(144, 183, 0, 0, 0, 1, [e.d2]);
@@ -92,43 +91,53 @@
     // Expanding area checks:
     check(39, 212, 0,  0,  0,  0, []);
     check(39, 212, 10, 0,  0,  0, [e.d2]);
     check(39, 212, 0,  0,  10, 0, [e.p2]);
     check(39, 212, 10, 1,  30, 0, [e.d2, e.p2]);
     check(39, 212, 10, 5,  30, 0, [e.span, e.d2, e.p2]);
     check(39, 212, 10, 15, 30, 0, [e.p5, e.span, e.d2, e.p2]);
 
-    // Area with links and text nodes:
-    check(45, 343, 0,0,  17, 0, [e.a3.firstChild, e.a3, e.a1.firstChild, e.a1, e.p6]);
-    check(45, 343, 0,0,  0,  0, [e.a1.firstChild, e.a1, e.p6]);
-    check(45, 343, 0,25, 0,  0, [e.p6.childNodes[1], e.a1.firstChild, e.a1, e.p6]);
-    check(45, 343, 0,35, 0,  0, [e.a2.firstChild, e.a2, e.p6.childNodes[1], e.a1.firstChild, e.a1, e.p6]);
-    check(45, 343, 0,35, 17, 0, [e.a3.firstChild, e.a3, e.a2.firstChild, e.a2, e.p6.childNodes[1], e.a1.firstChild, e.a1, e.p6]);
-    check(45, 343, 0,65, 17, 0, [e.a3.firstChild, e.a3, e.p6.childNodes[3], e.a2.firstChild, e.a2, e.p6.childNodes[1], e.a1.firstChild, e.a1, e.p6]);
-
-    // 2d transform:
-    check(61, 426, 0, 0,  0,  0,  []);
-    check(61, 426, 0, 30, 0,  10, [e.transf]);
-    check(61, 426, 0, 30, 80, 10, [e.transf.firstChild, e.transf]);
+    // Decimal CSS pixels
+    check(18,    330,   0, 0,    0,   0,   []);
+    check(18,    330,   0, 0.5,  0,   0,   []);
+    check(18,    330,   0, 0,    0.5, 0,   []);
+    check(18,    330,   0, 0.25, 0.5, 0,   []);
+    check(18,    330,   0, 0.5,  0.5, 0,   [e.decimal]);
+    check(144,   330.5, 0, 0,    0,   0,   [e.decimal]);
+    check(144.5, 330.5, 0, 0,    0,   0,   []);
+    check(144.5, 330.5, 0, 0,    0,   0.1, [e.decimal]);
 
     // Elements inside iframe shouldn't be returned:
-    check(25, 536, 0, 30, 100, 0, [e.iframe1]);
+    check(15, 410, 0, 30, 50, 0, [e.iframe1]);
+
+    // Area with links and text nodes:
+    let [x1, y1] = getCenterFor(e.a1);
+    let [x2, y2] = getCenterFor(e.a2);
+    let [x3, y3] = getCenterFor(e.a3);
+    let [xt, yt] = [(x2 + x1) / 2, y1]; //text node between a1 and a2
 
-    // Decimal CSS pixels
-    check(18,    726,   0, 0,    0,   0,   []);
-    check(18,    726,   0, 0.5,  0,   0,   []);
-    check(18,    726,   0, 0,    0.5, 0,   []);
-    check(18,    726,   0, 0.25, 0.5, 0,   []);
-    check(18,    726,   0, 0.5,  0.5, 0,   [e.decimal]);
-    check(144,   726.5, 0, 0,    0,   0,   [e.decimal]);
-    check(144.5, 726.5, 0, 0,    0,   0,   []);
-    check(144.5, 726.5, 0, 0,    0,   0.1, [e.decimal]);
+    check(x1, y1, 0, 0,       0,       0, [e.a1.firstChild, e.a1, e.p6]);
+    check(x1, y1, 0, 0,       y3 - y1, 0, [e.a3.firstChild, e.a3, e.a1.firstChild, e.a1, e.p6]);
+    check(x1, y1, 0, xt - x1, 0,       0, [e.p6.childNodes[1], e.a1.firstChild, e.a1, e.p6]);
+    check(x1, y1, 0, x2 - x1, 0,       0, [e.a2.firstChild, e.a2, e.p6.childNodes[1], e.a1.firstChild, e.a1, e.p6]);
+    check(x1, y1, 0, x2 - x1, y3 - y1, 0, [e.a3.firstChild, e.a3, e.a2.firstChild, e.a2, e.p6.childNodes[1], e.a1.firstChild, e.a1, e.p6]);
+
+    // 2d transform:
+    check(61, 671, 0, 0,  0,  0,  []);
+    check(61, 671, 0, 30, 0,  10, [e.transf]);
+    check(61, 671, 0, 30, 90, 10, [e.transf.firstChild, e.transf]);
 
     done();
+
+  }
+
+  function getCenterFor(element) {
+    let rect = element.getBoundingClientRect();
+    return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];
   }
 
   addLoadEvent(doTest);
 </script>
 <style type="text/css">
 
 body {
   margin: 8px;
@@ -144,59 +153,61 @@ h1, div, p, span, iframe {
   margin: 10px;
 }
 
 
 span {
   display: inline-block;
 }
 
-h1:hover, div:hover, p:hover, span:hover {
-  background-color: yellow;
+#iframe1 {
+  height: 100px;
+  margin-top: 60px;
 }
 
-#p6, #iframe1 {
-  height: auto;
-  margin-top: 50px;
-  font-weight: bold;
+#p6 {
+  height: 50px;
+  margin-top: 30px;
 }
 
 #transf {
-  margin-top: 3em;
+  margin-top: 60px;
   -moz-transform: rotate(-45deg);
 }
 
 #decimal {
   position: relative;
   left: 0.5px;
-  top: 0.5px;
+  top: 50.5px;
 }
 </style>
 </head>
 <body id="body">
-  <h1 id="h1">h1</h1>
-  <div id="d1">div</div>
+  <h1 id="h1"></h1>
+  <div id="d1"></div>
   
   <!-- floated element -->
   <div id="d2" style="float: left"></div>
+
   <!-- hidden element -->
   <p id="p1" style="float: left; visibility: hidden"></p>
+
   <p id="p2" style="clear: left"><span id="span"></span></p>
   
   <!-- absolute position -->
-  <p id="p3" style="position:absolute; top: 10px; left:50px; height:50px;">p</p>
+  <p id="p3" style="position:absolute; top: 10px; left:50px; height:50px;"></p>
   
   <!-- fixed position -->
   <p id="p4" style="position: fixed; top: 30px; left: 150px; height: 50px; background-color: blue;"></p>
 
   <!-- relative position -->
   <p id="p5" style="position:relative; top: -100px; left: 30px; margin-bottom: -70px; background-color: green"></p>
-  <p id="p6"><a href="#" id="a1">Link</a> / <a href="#" id="a2">Link</a> / <a href="#" id="a3">Link</a></p>
 
-  <div id="transf">text</div>
+  <!-- decimal CSS pixels -->
+  <div id="decimal"></div>
 
   <iframe id="iframe1" src="data:text/html,<div>div</div><p>p</p>"></iframe>
 
-  <!-- decimal CSS pixels -->
-  <div id="decimal"></div>
+  <p id="p6"><a href="#" id="a1">A</a> / <a href="#" id="a2">A</a><br/><a href="#" id="a3">A</a></p>
+
+  <div id="transf">text</div>
 </body>
 </html>
-
--- a/dom/tests/mochitest/general/Makefile.in
+++ b/dom/tests/mochitest/general/Makefile.in
@@ -53,13 +53,13 @@ include $(topsrcdir)/config/rules.mk
 		test_domWindowUtils_scrollXY.html \
 		test_innerScreen.xul \
 		test_offsets.html \
 		test_offsets.js \
 		test_offsets.xul \
 		test_windowProperties.html \
 		test_clipboard_events.html \
 		test_focusrings.xul \
-		$(warning test_nodesFromRect.html temporarily disabled) \
+		test_nodesFromRect.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
--- a/editor/idl/nsIEditorStyleSheets.idl
+++ b/editor/idl/nsIEditorStyleSheets.idl
@@ -34,20 +34,20 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
 
 %{C++
-class nsICSSStyleSheet;
+class nsCSSStyleSheet;
 %}
 
-[ptr] native nsICSSStyleSheet(nsICSSStyleSheet);
+[ptr] native nsCSSStyleSheet(nsCSSStyleSheet);
 
 [scriptable, uuid(4805e682-49b9-11d3-9ce4-ed60bd6cb5bc)]
 
 interface nsIEditorStyleSheets : nsISupports
 {
   /** Load and apply the style sheet, specified by aURL, to the
     * editor's document, replacing the last style sheet added (if any).
     * This is always asynchronous, and may cause network I/O.
@@ -103,22 +103,22 @@ interface nsIEditorStyleSheets : nsISupp
   /** Enable or disable the given style sheet from the editor's document
     * This is always synchronous
     *
     * @param aURL  The style sheet to be enabled or disabled
     * @param aEnable true to enable, or false to disable the style sheet
     */
   void enableStyleSheet(in AString aURL, in PRBool aEnable);
 
-  /** Get the nsICSSStyleSheet associated with the given URL.
+  /** Get the nsCSSStyleSheet associated with the given URL.
     *
     * @param aURL         The style sheet's URL
     * @return             the style sheet
     */
-  [noscript] nsICSSStyleSheet getStyleSheetForURL(in AString aURL);
+  [noscript] nsCSSStyleSheet getStyleSheetForURL(in AString aURL);
 
-  /** Get the URL associated with the given nsICSSStyleSheet.
+  /** Get the URL associated with the given nsCSSStyleSheet.
     *
     * @param aStyleSheet  The style sheet
     * @return             the style sheet's URL
     */
-  [noscript] AString getURLForStyleSheet(in nsICSSStyleSheet aStyleSheet);
+  [noscript] AString getURLForStyleSheet(in nsCSSStyleSheet aStyleSheet);
 };
--- a/editor/libeditor/base/nsEditor.cpp
+++ b/editor/libeditor/base/nsEditor.cpp
@@ -74,17 +74,17 @@
 #include "nsIAtom.h"
 #include "nsCaret.h"
 #include "nsIWidget.h"
 #include "nsIPlaintextEditor.h"
 #include "nsGUIEvent.h"  // nsTextEventReply
 
 #include "nsIFrame.h"  // Needed by IME code
 
-#include "nsICSSStyleSheet.h"
+#include "nsCSSStyleSheet.h"
 
 #include "nsIContent.h"
 #include "nsServiceManagerUtils.h"
 
 // transactions the editor knows how to build
 #include "EditAggregateTxn.h"
 #include "PlaceholderTxn.h"
 #include "ChangeAttributeTxn.h"
@@ -4596,30 +4596,30 @@ nsEditor::CreateTxnForIMEText(const nsAS
   NS_ADDREF(*aTxn);
 
   return (*aTxn)->Init(mIMETextNode, mIMETextOffset, mIMEBufferLength,
                        mIMETextRangeList, aStringToInsert, mSelConWeak);
 }
 
 
 NS_IMETHODIMP 
-nsEditor::CreateTxnForAddStyleSheet(nsICSSStyleSheet* aSheet, AddStyleSheetTxn* *aTxn)
+nsEditor::CreateTxnForAddStyleSheet(nsCSSStyleSheet* aSheet, AddStyleSheetTxn* *aTxn)
 {
   *aTxn = new AddStyleSheetTxn();
   if (! *aTxn)
     return NS_ERROR_OUT_OF_MEMORY;
   NS_ADDREF(*aTxn);
 
   return (*aTxn)->Init(this, aSheet);
 }
 
 
 
 NS_IMETHODIMP 
-nsEditor::CreateTxnForRemoveStyleSheet(nsICSSStyleSheet* aSheet, RemoveStyleSheetTxn* *aTxn)
+nsEditor::CreateTxnForRemoveStyleSheet(nsCSSStyleSheet* aSheet, RemoveStyleSheetTxn* *aTxn)
 {
   *aTxn = new RemoveStyleSheetTxn();
   if (! *aTxn)
     return NS_ERROR_OUT_OF_MEMORY;
   NS_ADDREF(*aTxn);
 
   return (*aTxn)->Init(this, aSheet);
 }
--- a/editor/libeditor/base/nsEditor.h
+++ b/editor/libeditor/base/nsEditor.h
@@ -53,17 +53,16 @@
 #include "nsIDOMCharacterData.h"
 #include "nsIPrivateTextRange.h"
 #include "nsITransactionManager.h"
 #include "nsIComponentManager.h"
 #include "nsCOMArray.h"
 #include "nsIEditActionListener.h"
 #include "nsIEditorObserver.h"
 #include "nsIDocumentStateListener.h"
-#include "nsICSSStyleSheet.h"
 #include "nsIDOMElement.h"
 #include "nsSelectionState.h"
 #include "nsIEditorSpellCheck.h"
 #include "nsIInlineSpellChecker.h"
 #include "nsPIDOMEventTarget.h"
 #include "nsStubMutationObserver.h"
 #include "nsIViewManager.h"
 #include "nsCycleCollectionParticipant.h"
@@ -81,16 +80,17 @@ class SplitElementTxn;
 class JoinElementTxn;
 class EditAggregateTxn;
 class IMETextTxn;
 class AddStyleSheetTxn;
 class RemoveStyleSheetTxn;
 class nsIFile;
 class nsISelectionController;
 class nsIDOMEventTarget;
+class nsCSSStyleSheet;
 
 #define kMOZEditorBogusNodeAttrAtom nsEditProperty::mozEditorBogusNode
 #define kMOZEditorBogusNodeValue NS_LITERAL_STRING("TRUE")
 
 /** implementation of an editor object.  it will be the controller/focal point 
  *  for the main editor services. i.e. the GUIManager, publishing, transaction 
  *  manager, event interfaces. the idea for the event interfaces is to have them 
  *  delegate the actual commands to the editor independent of the XPFE implementation.
@@ -255,21 +255,21 @@ protected:
                                     PRInt32 aOffset,
                                     InsertTextTxn ** aTxn);
 
   NS_IMETHOD CreateTxnForIMEText(const nsAString & aStringToInsert,
                                  IMETextTxn ** aTxn);
 
   /** create a transaction for adding a style sheet
     */
-  NS_IMETHOD CreateTxnForAddStyleSheet(nsICSSStyleSheet* aSheet, AddStyleSheetTxn* *aTxn);
+  NS_IMETHOD CreateTxnForAddStyleSheet(nsCSSStyleSheet* aSheet, AddStyleSheetTxn* *aTxn);
 
   /** create a transaction for removing a style sheet
     */
-  NS_IMETHOD CreateTxnForRemoveStyleSheet(nsICSSStyleSheet* aSheet, RemoveStyleSheetTxn* *aTxn);
+  NS_IMETHOD CreateTxnForRemoveStyleSheet(nsCSSStyleSheet* aSheet, RemoveStyleSheetTxn* *aTxn);
   
   NS_IMETHOD DeleteText(nsIDOMCharacterData *aElement,
                         PRUint32             aOffset,
                         PRUint32             aLength);
 
 //  NS_IMETHOD DeleteRange(nsIDOMRange *aRange);
 
   NS_IMETHOD CreateTxnForDeleteText(nsIDOMCharacterData *aElement,
--- a/editor/libeditor/base/nsStyleSheetTxns.cpp
+++ b/editor/libeditor/base/nsStyleSheetTxns.cpp
@@ -33,17 +33,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 
 #include "nsEditor.h"
 
-#include "nsICSSStyleSheet.h"
+#include "nsCSSStyleSheet.h"
 #include "nsIDocument.h"
 #include "nsIDocumentObserver.h"
 #include "nsISelectionController.h"
 
 
 #include "nsStyleSheetTxns.h"
 
 static void
@@ -80,33 +80,30 @@ AddStyleSheetTxn::AddStyleSheetTxn()
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(AddStyleSheetTxn)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(AddStyleSheetTxn, EditTxn)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSheet)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(AddStyleSheetTxn, EditTxn)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSheet)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mSheet, nsIStyleSheet)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AddStyleSheetTxn)
 NS_INTERFACE_MAP_END_INHERITING(EditTxn)
 
 NS_IMETHODIMP
-AddStyleSheetTxn::Init(nsIEditor *aEditor, nsICSSStyleSheet *aSheet)
+AddStyleSheetTxn::Init(nsIEditor *aEditor, nsCSSStyleSheet *aSheet)
 {
-  if (!aEditor)
-    return NS_ERROR_INVALID_ARG;
-
-  if (!aSheet)
+  if (!aEditor || !aSheet)
     return NS_ERROR_INVALID_ARG;
 
   mEditor = aEditor;
-  mSheet = do_QueryInterface(aSheet);
+  mSheet = aSheet;
   
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 AddStyleSheetTxn::DoTransaction()
 {
@@ -147,34 +144,31 @@ RemoveStyleSheetTxn::RemoveStyleSheetTxn
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(RemoveStyleSheetTxn)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(RemoveStyleSheetTxn, EditTxn)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSheet)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(RemoveStyleSheetTxn, EditTxn)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSheet)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mSheet, nsIStyleSheet)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RemoveStyleSheetTxn)
 NS_INTERFACE_MAP_END_INHERITING(EditTxn)
 
 NS_IMETHODIMP
-RemoveStyleSheetTxn::Init(nsIEditor *aEditor, nsICSSStyleSheet *aSheet)
+RemoveStyleSheetTxn::Init(nsIEditor *aEditor, nsCSSStyleSheet *aSheet)
 {
-  if (!aEditor)
-    return NS_ERROR_INVALID_ARG;
-
-  if (!aSheet)
+  if (!aEditor || !aSheet)
     return NS_ERROR_INVALID_ARG;
 
   mEditor = aEditor;
-  mSheet = do_QueryInterface(aSheet);
-  
+  mSheet = aSheet;
+
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 RemoveStyleSheetTxn::DoTransaction()
 {
   if (!mEditor || !mSheet)
--- a/editor/libeditor/base/nsStyleSheetTxns.h
+++ b/editor/libeditor/base/nsStyleSheetTxns.h
@@ -36,61 +36,60 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsStylesheetTxns_h__
 #define nsStylesheetTxns_h__
 
 #include "EditTxn.h"
 #include "nsCOMPtr.h"
 #include "nsIEditor.h"
-#include "nsICSSStyleSheet.h"
 
 class AddStyleSheetTxn : public EditTxn
 {
 public:
   /** Initialize the transaction.
     * @param aEditor the object providing core editing operations
     * @param aSheet   the stylesheet to add
     */
   NS_IMETHOD Init(nsIEditor         *aEditor,
-                  nsICSSStyleSheet  *aSheet);
+                  nsCSSStyleSheet   *aSheet);
 
   AddStyleSheetTxn();
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AddStyleSheetTxn, EditTxn)
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
 
   NS_DECL_EDITTXN
 
 protected:
 
-  nsIEditor*  mEditor;									// the editor that created this transaction
-  nsCOMPtr<nsICSSStyleSheet>	mSheet;		// the style sheet to add
-  
+  nsIEditor*  mEditor;                  // the editor that created this transaction
+  nsRefPtr<nsCSSStyleSheet>  mSheet;    // the style sheet to add
+
 };
 
 
 class RemoveStyleSheetTxn : public EditTxn
 {
 public:
   /** Initialize the transaction.
     * @param aEditor the object providing core editing operations
     * @param aSheet   the stylesheet to remove
     */
   NS_IMETHOD Init(nsIEditor         *aEditor,
-                  nsICSSStyleSheet  *aSheet);
-	
+                  nsCSSStyleSheet   *aSheet);
+
   RemoveStyleSheetTxn();
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(RemoveStyleSheetTxn, EditTxn)
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
 
   NS_DECL_EDITTXN
 
 protected:
 
-  nsIEditor*  mEditor;									// the editor that created this transaction
-  nsCOMPtr<nsICSSStyleSheet>	mSheet;		// the style sheet to remove
-  
+  nsIEditor*  mEditor;                  // the editor that created this transaction
+  nsRefPtr<nsCSSStyleSheet>  mSheet;    // the style sheet to remove
+
 };
 
 
 #endif /* nsStylesheetTxns_h__ */
--- a/editor/libeditor/html/TypeInState.cpp
+++ b/editor/libeditor/html/TypeInState.cpp
@@ -314,17 +314,16 @@ nsresult TypeInState::GetTypingState(PRB
 /********************************************************************
  *                   protected methods
  *******************************************************************/
  
 nsresult TypeInState::RemovePropFromSetList(nsIAtom *aProp, 
                                             const nsString &aAttr)
 {
   PRInt32 index;
-  PropItem *item;
   if (!aProp)
   {
     // clear _all_ props
     for(PRUint32 i = 0, n = mSetArray.Length(); i < n; i++) {
       delete mSetArray[i];
     }
     mSetArray.Clear();
     mRelativeFontSize=0;
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp
@@ -57,17 +57,16 @@
 #include "nsIDOMComment.h"
 #include "nsISelection.h"
 #include "nsISelectionPrivate.h"
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsISelectionController.h"
 #include "nsIFileChannel.h"
 
-#include "nsICSSStyleSheet.h"
 #include "nsIDocumentObserver.h"
 #include "nsIDocumentStateListener.h"
 
 #include "nsIEnumerator.h"
 #include "nsIContent.h"
 #include "nsIContentIterator.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMNSRange.h"
--- a/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/editor/libeditor/html/nsHTMLEditor.cpp
@@ -67,17 +67,17 @@
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsISelectionController.h"
 #include "nsIDOMHTMLHtmlElement.h"
 #include "nsGUIEvent.h"
 #include "nsIDOMEventGroup.h"
 #include "nsILinkHandler.h"
 
 #include "nsCSSLoader.h"
-#include "nsICSSStyleSheet.h"
+#include "nsCSSStyleSheet.h"
 #include "nsIDOMStyleSheet.h"
 #include "nsIDocumentObserver.h"
 #include "nsIDocumentStateListener.h"
 
 #include "nsIEnumerator.h"
 #include "nsIContent.h"
 #include "nsIContentIterator.h"
 #include "nsIDOMRange.h"
@@ -3381,17 +3381,17 @@ nsHTMLEditor::ReplaceStyleSheet(const ns
 
   return ps->GetDocument()->CSSLoader()->
     LoadSheet(uaURI, nsnull, EmptyCString(), this);
 }
 
 NS_IMETHODIMP
 nsHTMLEditor::RemoveStyleSheet(const nsAString &aURL)
 {
-  nsCOMPtr<nsICSSStyleSheet> sheet;
+  nsRefPtr<nsCSSStyleSheet> sheet;
   nsresult rv = GetStyleSheetForURL(aURL, getter_AddRefs(sheet));
   NS_ENSURE_SUCCESS(rv, rv);
   if (!sheet)
     return NS_ERROR_UNEXPECTED;
 
   nsRefPtr<RemoveStyleSheetTxn> txn;
   rv = CreateTxnForRemoveStyleSheet(sheet, getter_AddRefs(txn));
   if (!txn) rv = NS_ERROR_NULL_POINTER;
@@ -3423,17 +3423,17 @@ nsHTMLEditor::AddOverrideStyleSheet(cons
 
   nsCOMPtr<nsIURI> uaURI;
   nsresult rv = NS_NewURI(getter_AddRefs(uaURI), aURL);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // We MUST ONLY load synchronous local files (no @import)
   // XXXbz Except this will actually try to load remote files
   // synchronously, of course..
-  nsCOMPtr<nsICSSStyleSheet> sheet;
+  nsRefPtr<nsCSSStyleSheet> sheet;
   // Editor override style sheets may want to style Gecko anonymous boxes
   rv = ps->GetDocument()->CSSLoader()->
     LoadSheetSync(uaURI, PR_TRUE, PR_TRUE, getter_AddRefs(sheet));
 
   // Synchronous loads should ALWAYS return completed
   if (!sheet)
     return NS_ERROR_NULL_POINTER;
 
@@ -3468,17 +3468,17 @@ nsHTMLEditor::ReplaceOverrideStyleSheet(
 
   return AddOverrideStyleSheet(aURL);
 }
 
 // Do NOT use transaction system for override style sheets
 NS_IMETHODIMP
 nsHTMLEditor::RemoveOverrideStyleSheet(const nsAString &aURL)
 {
-  nsCOMPtr<nsICSSStyleSheet> sheet;
+  nsRefPtr<nsCSSStyleSheet> sheet;
   GetStyleSheetForURL(aURL, getter_AddRefs(sheet));
 
   // Make sure we remove the stylesheet from our internal list in all
   // cases.
   nsresult rv = RemoveStyleSheetFromList(aURL);
 
   if (!sheet)
     return NS_OK; /// Don't fail if sheet not found
@@ -3492,96 +3492,85 @@ nsHTMLEditor::RemoveOverrideStyleSheet(c
 
   // Remove it from our internal list
   return rv;
 }
 
 NS_IMETHODIMP
 nsHTMLEditor::EnableStyleSheet(const nsAString &aURL, PRBool aEnable)
 {
-  nsCOMPtr<nsICSSStyleSheet> sheet;
+  nsRefPtr<nsCSSStyleSheet> sheet;
   nsresult rv = GetStyleSheetForURL(aURL, getter_AddRefs(sheet));
   NS_ENSURE_SUCCESS(rv, rv);
   if (!sheet)
     return NS_OK; // Don't fail if sheet not found
 
-  nsCOMPtr<nsIDOMStyleSheet> domSheet(do_QueryInterface(sheet));
-  NS_ASSERTION(domSheet, "Sheet not implementing nsIDOMStyleSheet!");
-
   // Ensure the style sheet is owned by our document.
   nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocWeak);
-  rv = sheet->SetOwningDocument(doc);
-  NS_ENSURE_SUCCESS(rv, rv);
-  
-  return domSheet->SetDisabled(!aEnable);
+  sheet->SetOwningDocument(doc);
+
+  return sheet->SetDisabled(!aEnable);
 }
 
 PRBool
 nsHTMLEditor::EnableExistingStyleSheet(const nsAString &aURL)
 {
-  nsCOMPtr<nsICSSStyleSheet> sheet;
+  nsRefPtr<nsCSSStyleSheet> sheet;
   nsresult rv = GetStyleSheetForURL(aURL, getter_AddRefs(sheet));
   if (NS_FAILED(rv))
     return PR_FALSE;
 
   // Enable sheet if already loaded.
   if (sheet)
   {
     // Ensure the style sheet is owned by our document.
     nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocWeak);
-    rv = sheet->SetOwningDocument(doc);
-    if (NS_FAILED(rv))
-      return PR_FALSE;
-
-    nsCOMPtr<nsIDOMStyleSheet> domSheet(do_QueryInterface(sheet));
-    NS_ASSERTION(domSheet, "Sheet not implementing nsIDOMStyleSheet!");
-    
-    domSheet->SetDisabled(PR_FALSE);
+    sheet->SetOwningDocument(doc);
+
+    sheet->SetDisabled(PR_FALSE);
     return PR_TRUE;
   }
   return PR_FALSE;
 }
 
 nsresult
 nsHTMLEditor::AddNewStyleSheetToList(const nsAString &aURL,
-                                     nsICSSStyleSheet *aStyleSheet)
+                                     nsCSSStyleSheet *aStyleSheet)
 {
-  PRInt32 countSS = mStyleSheets.Count();
+  PRUint32 countSS = mStyleSheets.Length();
   PRUint32 countU = mStyleSheetURLs.Length();
 
   if (countU < 0 || countSS != countU)
     return NS_ERROR_UNEXPECTED;
 
   if (!mStyleSheetURLs.AppendElement(aURL))
     return NS_ERROR_UNEXPECTED;
 
-  return mStyleSheets.AppendObject(aStyleSheet) ? NS_OK : NS_ERROR_UNEXPECTED;
+  return mStyleSheets.AppendElement(aStyleSheet) ? NS_OK : NS_ERROR_UNEXPECTED;
 }
 
 nsresult
 nsHTMLEditor::RemoveStyleSheetFromList(const nsAString &aURL)
 {
   // is it already in the list?
   PRUint32 foundIndex;
   foundIndex = mStyleSheetURLs.IndexOf(aURL);
   if (foundIndex == mStyleSheetURLs.NoIndex)
     return NS_ERROR_FAILURE;
 
   // Attempt both removals; if one fails there's not much we can do.
-  nsresult rv = NS_OK;
-  if (!mStyleSheets.RemoveObjectAt(foundIndex))
-    rv = NS_ERROR_FAILURE;
+  mStyleSheets.RemoveElementAt(foundIndex);
   mStyleSheetURLs.RemoveElementAt(foundIndex);
 
-  return rv;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLEditor::GetStyleSheetForURL(const nsAString &aURL,
-                                  nsICSSStyleSheet **aStyleSheet)
+                                  nsCSSStyleSheet **aStyleSheet)
 {
   NS_ENSURE_ARG_POINTER(aStyleSheet);
   *aStyleSheet = 0;
 
   // is it already in the list?
   PRUint32 foundIndex;
   foundIndex = mStyleSheetURLs.IndexOf(aURL);
   if (foundIndex == mStyleSheetURLs.NoIndex)
@@ -3592,17 +3581,17 @@ nsHTMLEditor::GetStyleSheetForURL(const 
     return NS_ERROR_FAILURE;
 
   NS_ADDREF(*aStyleSheet);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLEditor::GetURLForStyleSheet(nsICSSStyleSheet *aStyleSheet,
+nsHTMLEditor::GetURLForStyleSheet(nsCSSStyleSheet *aStyleSheet,
                                   nsAString &aURL)
 {
   // is it already in the list?
   PRInt32 foundIndex = mStyleSheets.IndexOf(aStyleSheet);
 
   // Don't fail if we don't find it in our list
   // Note: mStyleSheets is nsCOMArray, so its IndexOf() method
   // returns -1 on failure.
@@ -3887,17 +3876,17 @@ nsHTMLEditor::DebugUnitTests(PRInt32 *ou
 #ifdef XP_MAC
 #pragma mark -
 #pragma mark  StyleSheet utils 
 #pragma mark -
 #endif
 
 
 NS_IMETHODIMP 
-nsHTMLEditor::StyleSheetLoaded(nsICSSStyleSheet* aSheet, PRBool aWasAlternate,
+nsHTMLEditor::StyleSheetLoaded(nsCSSStyleSheet* aSheet, PRBool aWasAlternate,
                                nsresult aStatus)
 {
   nsresult rv = NS_OK;
   nsAutoEditBatch batchIt(this);
 
   if (!mLastStyleSheetURL.IsEmpty())
     RemoveStyleSheet(mLastStyleSheetURL);
 
@@ -3905,33 +3894,28 @@ nsHTMLEditor::StyleSheetLoaded(nsICSSSty
   rv = CreateTxnForAddStyleSheet(aSheet, getter_AddRefs(txn));
   if (!txn) rv = NS_ERROR_NULL_POINTER;
   if (NS_SUCCEEDED(rv))
   {
     rv = DoTransaction(txn);
     if (NS_SUCCEEDED(rv))
     {
       // Get the URI, then url spec from the sheet
-      nsCOMPtr<nsIStyleSheet> sheet = do_QueryInterface(aSheet);
-      nsCOMPtr<nsIURI> uri;
-      rv = sheet->GetSheetURI(getter_AddRefs(uri));
+      nsCOMPtr<nsIURI> uri = aSheet->GetSheetURI();
+
+      nsCAutoString spec;
+      rv = uri->GetSpec(spec);
 
       if (NS_SUCCEEDED(rv))
       {
-        nsCAutoString spec;
-        rv = uri->GetSpec(spec);
-
-        if (NS_SUCCEEDED(rv))
-        {
-          // Save it so we can remove before applying the next one
-          mLastStyleSheetURL.AssignWithConversion(spec.get());
-
-          // Also save in our arrays of urls and sheets
-          AddNewStyleSheetToList(mLastStyleSheetURL, aSheet);
-        }
+        // Save it so we can remove before applying the next one
+        mLastStyleSheetURL.AssignWithConversion(spec.get());
+
+        // Also save in our arrays of urls and sheets
+        AddNewStyleSheetToList(mLastStyleSheetURL, aSheet);
       }
     }
   }
 
   return NS_OK;
 }
 
 #ifdef XP_MAC
--- a/editor/libeditor/html/nsHTMLEditor.h
+++ b/editor/libeditor/html/nsHTMLEditor.h
@@ -65,16 +65,17 @@
 #include "nsIHTMLAbsPosEditor.h"
 #include "nsIHTMLInlineTableEditor.h"
 #include "nsIHTMLObjectResizeListener.h"
 
 #include "nsIDocumentObserver.h"
 
 #include "nsPoint.h"
 #include "nsTArray.h"
+#include "nsAutoPtr.h"
 
 class nsIDOMKeyEvent;
 class nsITransferable;
 class nsIDOMNSRange;
 class nsIDocumentEncoder;
 class nsIClipboard;
 class TypeInState;
 class nsIContentFilter;
@@ -364,17 +365,17 @@ public:
                             nsCOMPtr<nsIDOMNode> *aInOutNode, 
                             PRInt32 *aInOutOffset,
                             nsIDOMDocument *aDoc);
   NS_IMETHOD_(PRBool) IsModifiableNode(nsIDOMNode *aNode);
 
   NS_IMETHOD SelectAll();
 
   /* ------------ nsICSSLoaderObserver -------------- */
-  NS_IMETHOD StyleSheetLoaded(nsICSSStyleSheet*aSheet, PRBool aWasAlternate,
+  NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet*aSheet, PRBool aWasAlternate,
                               nsresult aStatus);
 
   /* ------------ Utility Routines, not part of public API -------------- */
   NS_IMETHOD TypedText(const nsAString& aString, PRInt32 aAction);
   nsresult InsertNodeAtPoint( nsIDOMNode *aNode, 
                               nsCOMPtr<nsIDOMNode> *ioParent, 
                               PRInt32 *ioOffset, 
                               PRBool aNoEmptyNodes);
@@ -412,22 +413,22 @@ public:
                            PRBool aSafeToAskFrames,
                            PRBool *aSeenBR);
 
   // Returns TRUE if sheet was loaded, false if it wasn't
   PRBool   EnableExistingStyleSheet(const nsAString& aURL);
 
   // Dealing with the internal style sheet lists:
   NS_IMETHOD GetStyleSheetForURL(const nsAString &aURL,
-                               nsICSSStyleSheet **_retval);
-  NS_IMETHOD GetURLForStyleSheet(nsICSSStyleSheet *aStyleSheet, nsAString &aURL);
+                                 nsCSSStyleSheet **_retval);
+  NS_IMETHOD GetURLForStyleSheet(nsCSSStyleSheet *aStyleSheet, nsAString &aURL);
 
   // Add a url + known style sheet to the internal lists:
   nsresult AddNewStyleSheetToList(const nsAString &aURL,
-                                  nsICSSStyleSheet *aStyleSheet);
+                                  nsCSSStyleSheet *aStyleSheet);
 
   nsresult RemoveStyleSheetFromList(const nsAString &aURL);
                        
 protected:
 
   NS_IMETHOD  InitRules();
 
   // Create the event listeners for the editor to install
@@ -747,17 +748,17 @@ protected:
   // Used by GetFirstSelectedCell and GetNextSelectedCell
   PRInt32  mSelectedCellIndex;
 
   nsString mLastStyleSheetURL;
   nsString mLastOverrideStyleSheetURL;
 
   // Maintain a list of associated style sheets and their urls.
   nsTArray<nsString> mStyleSheetURLs;
-  nsCOMArray<nsICSSStyleSheet> mStyleSheets;
+  nsTArray<nsRefPtr<nsCSSStyleSheet> > mStyleSheets;
   
   // an array for holding default style settings
   nsTArray<PropItem*> mDefaultStyles;
 
    // for real-time spelling
    nsCOMPtr<nsITextServicesDocument> mTextServices;
 
   // And a static range utils service
--- a/editor/libeditor/html/nsHTMLEditorStyle.cpp
+++ b/editor/libeditor/html/nsHTMLEditorStyle.cpp
@@ -46,17 +46,16 @@
 #include "nsIDOMAttr.h"
 #include "nsIDOMKeyListener.h" 
 #include "nsIDOMMouseListener.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsISelection.h"
 #include "nsISelectionPrivate.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsISelectionController.h"
-#include "nsICSSStyleSheet.h"
 #include "nsIDocumentObserver.h"
 #include "TypeInState.h"
 
 #include "nsIEnumerator.h"
 #include "nsIContent.h"
 #include "nsIContentIterator.h"
 #include "nsAttrName.h"
 
--- a/editor/libeditor/html/tests/Makefile.in
+++ b/editor/libeditor/html/tests/Makefile.in
@@ -56,10 +56,10 @@ include $(topsrcdir)/config/rules.mk
 		test_bug537046.html \
 		test_contenteditable_focus.html \
 		test_select_all_without_body.html \
 		file_select_all_without_body.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
-	(cd $(srcdir) && tar $(TAR_CREATE_FLAGS) - browserscope) | (cd $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir) && tar -xf -)
+	(cd $(srcdir) && tar $(TAR_CREATE_FLAGS) - browserscope 2> /dev/null) | (cd $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir) && tar -xf -)
 
--- a/embedding/browser/activex/src/common/StdAfx.h
+++ b/embedding/browser/activex/src/common/StdAfx.h
@@ -73,17 +73,17 @@
 
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentType.h"
 #include "nsIDOMElement.h"
 
 #undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0400
+#define _WIN32_WINNT 0x0403
 #define _ATL_APARTMENT_THREADED
 #define _ATL_STATIC_REGISTRY
 // #define _ATL_DEBUG_INTERFACES
 
 // ATL headers
 // The ATL headers that come with the platform SDK have bad for scoping
 #if _MSC_VER >= 1400
 #pragma conform(forScope, push, atlhack, off)
--- a/embedding/browser/activex/src/control/StdAfx.h
+++ b/embedding/browser/activex/src/control/StdAfx.h
@@ -108,17 +108,17 @@
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentType.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIDOMEventTarget.h"
 
 #undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0400
+#define _WIN32_WINNT 0x0403
 #define _ATL_APARTMENT_THREADED
 #define _ATL_STATIC_REGISTRY
 // #define _ATL_DEBUG_INTERFACES
 
 // ATL headers
 #include <atlbase.h>
 //You may derive a class from CComModule and use it if you want to override
 //something, but do not change the name of _Module
--- a/embedding/browser/activex/src/plugin/StdAfx.h
+++ b/embedding/browser/activex/src/plugin/StdAfx.h
@@ -45,17 +45,17 @@
 
 #if _MSC_VER >= 1000
 #pragma once
 #endif // _MSC_VER >= 1000
 
 #define STRICT
 
 #undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0400
+#define _WIN32_WINNT 0x0403
 #define _ATL_APARTMENT_THREADED
 #define _ATL_STATIC_REGISTRY
 
 #define USE_PLUGIN
 
 // Uncomment if you want to say what is QI'ing for what
 //#define _ATL_DEBUG_QI
 
--- a/embedding/browser/activex/src/pluginhostctrl/StdAfx.h
+++ b/embedding/browser/activex/src/pluginhostctrl/StdAfx.h
@@ -43,17 +43,17 @@
 #define AFX_STDAFX_H__113F2370_7A1B_4C16_BDFB_37785C884DA6__INCLUDED_
 
 #if _MSC_VER > 1000
 #pragma once
 #endif // _MSC_VER > 1000
 
 #define STRICT
 #ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0400
+#define _WIN32_WINNT 0x0403
 #endif
 #define _ATL_APARTMENT_THREADED
 
 #include <atlbase.h>
 //You may derive a class from CComModule and use it if you want to override
 //something, but do not change the name of _Module
 extern CComModule _Module;
 #include <atlcom.h>
--- a/embedding/browser/activex/src/xml/StdAfx.h
+++ b/embedding/browser/activex/src/xml/StdAfx.h
@@ -6,17 +6,17 @@
 #define AFX_STDAFX_H__45E5B413_2805_11D3_9425_000000000000__INCLUDED_
 
 #if _MSC_VER > 1000
 #pragma once
 #endif // _MSC_VER > 1000
 
 #define STRICT
 #ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0400
+#define _WIN32_WINNT 0x0403
 #endif
 #define _ATL_APARTMENT_THREADED
 
 #include <atlbase.h>
 //You may derive a class from CComModule and use it if you want to override
 //something, but do not change the name of _Module
 extern CComModule _Module;
 #include <atlcom.h>
--- a/embedding/browser/gtk/src/EmbedContextMenuInfo.cpp
+++ b/embedding/browser/gtk/src/EmbedContextMenuInfo.cpp
@@ -213,16 +213,17 @@ EmbedContextMenuInfo::SetFormControlType
         mEmbedCtxType |= GTK_MOZ_EMBED_CTX_INPUT;
         mEmbedCtxType |= GTK_MOZ_EMBED_CTX_IPASSWORD;
         break;
       case NS_FORM_INPUT_RADIO:
         break;
       case NS_FORM_INPUT_SUBMIT:
         break;
       case NS_FORM_INPUT_TEXT:
+      case NS_FORM_INPUT_TEL:
         mEmbedCtxType |= GTK_MOZ_EMBED_CTX_INPUT;
         break;
       case NS_FORM_LABEL:
         break;
       case NS_FORM_OPTION:
         break;
       case NS_FORM_OPTGROUP:
         break;
--- a/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
+++ b/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
@@ -75,16 +75,17 @@
 #include "nsIDOMSVGTitleElement.h"
 #include "nsIDOMSVGForeignObjectElem.h"
 #endif
 #include "nsIDOMEvent.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIDOMNSUIEvent.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMNamedNodeMap.h"
+#include "nsIFormControl.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsIDOMHTMLHtmlElement.h"
 #include "nsIDOMHTMLAppletElement.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMHTMLEmbedElement.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIImageLoadingContent.h"
@@ -1809,37 +1810,37 @@ ChromeContextMenuListener::ContextMenu(n
       content->GetCurrentURI(getter_AddRefs(imgUri));
       if (imgUri) {
         flags |= nsIContextMenuListener::CONTEXT_IMAGE;
         flags2 |= nsIContextMenuListener2::CONTEXT_IMAGE;
         targetDOMnode = node;
       }
     }
 
-    nsCOMPtr<nsIDOMHTMLInputElement> inputElement(do_QueryInterface(node));
-    if (inputElement) {
-      flags |= nsIContextMenuListener::CONTEXT_INPUT;
-      flags2 |= nsIContextMenuListener2::CONTEXT_INPUT;
+    nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(node));
+    if (formControl) {
+      if (formControl->GetType() == NS_FORM_TEXTAREA) {
+        flags |= nsIContextMenuListener::CONTEXT_TEXT;
+        flags2 |= nsIContextMenuListener2::CONTEXT_TEXT;
+        targetDOMnode = node;
+      } else {
+        nsCOMPtr<nsIDOMHTMLInputElement> inputElement(do_QueryInterface(formControl));
+        if (inputElement) {
+          flags |= nsIContextMenuListener::CONTEXT_INPUT;
+          flags2 |= nsIContextMenuListener2::CONTEXT_INPUT;
 
-      if (menuListener2) {
-        nsAutoString inputElemType;
-        inputElement->GetType(inputElemType);
-        if (inputElemType.LowerCaseEqualsLiteral("text") ||
-            inputElemType.LowerCaseEqualsLiteral("password"))
-          flags2 |= nsIContextMenuListener2::CONTEXT_TEXT;
-      }
+          if (menuListener2) {
+            if (formControl->IsSingleLineTextControl(PR_FALSE)) {
+              flags2 |= nsIContextMenuListener2::CONTEXT_TEXT;
+            }
+          }
 
-      targetDOMnode = node;
-    }
-
-    nsCOMPtr<nsIDOMHTMLTextAreaElement> textElement(do_QueryInterface(node));
-    if (textElement) {
-      flags |= nsIContextMenuListener::CONTEXT_TEXT;
-      flags2 |= nsIContextMenuListener2::CONTEXT_TEXT;
-      targetDOMnode = node;
+          targetDOMnode = node;
+        }
+      }
     }
 
     // always consume events for plugins and Java who may throw their
     // own context menus but not for image objects.  Document objects
     // will never be targets or ancestors of targets, so that's OK.
     nsCOMPtr<nsIDOMHTMLObjectElement> objectElement;
     if (!(flags & nsIContextMenuListener::CONTEXT_IMAGE))
       objectElement = do_QueryInterface(node);
--- a/embedding/components/find/src/nsFind.cpp
+++ b/embedding/components/find/src/nsFind.cpp
@@ -338,20 +338,19 @@ nsFindContentIterator::MaybeSetupInnerIt
   mInnerIterator = nsnull;
 
   nsCOMPtr<nsIContent> content =
     do_QueryInterface(mOuterIterator->GetCurrentNode());
   if (!content || !content->IsNodeOfType(nsINode::eHTML_FORM_CONTROL))
     return;
 
   nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(content));
-  PRInt32 controlType = formControl->GetType();
-  if (controlType != NS_FORM_TEXTAREA && 
-      controlType != NS_FORM_INPUT_TEXT)
+  if (!formControl->IsTextControl(PR_TRUE)) {
     return;
+  }
 
   SetupInnerIterator(content);
   if (mInnerIterator) {
     if (!mFindBackward) {
       mInnerIterator->First();
       // finish setup: position mOuterIterator on the actual "next"
       // node (this completes its re-init, @see SetupInnerIterator)
       if (!mOuterIterator->IsDone())
--- a/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
+++ b/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
@@ -3300,16 +3300,17 @@ nsWebBrowserPersist::CloneNodeWithFixedU
 
             nsAutoString valueStr;
             NS_NAMED_LITERAL_STRING(valueAttr, "value");
             // Update element node attributes with user-entered form state
             nsCOMPtr<nsIDOMHTMLInputElement> outElt = do_QueryInterface(*aNodeOut);
             nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(*aNodeOut);
             switch (formControl->GetType()) {
                 case NS_FORM_INPUT_TEXT:
+                case NS_FORM_INPUT_TEL:
                     nodeAsInput->GetValue(valueStr);
                     // Avoid superfluous value="" serialization
                     if (valueStr.IsEmpty())
                       outElt->RemoveAttribute(valueAttr);
                     else
                       outElt->SetAttribute(valueAttr, valueStr);
                     break;
                 case NS_FORM_INPUT_CHECKBOX:
--- a/extensions/metrics/src/nsProfileCollector.cpp
+++ b/extensions/metrics/src/nsProfileCollector.cpp
@@ -215,17 +215,17 @@ nsProfileCollector::LogCPU(nsIMetricsEve
 
 nsresult
 nsProfileCollector::LogMemory(nsIMetricsEventItem *profile)
 {
   nsCOMPtr<nsIWritablePropertyBag2> properties;
   nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
   NS_ENSURE_STATE(properties);
 
-  PRUint64 size = PR_GetPhysicalMemorySize();
+  static PRUint64 size = PR_GetPhysicalMemorySize();
   if (size == 0) {
     MS_LOG(("Failed to get physical memory size"));
     return NS_ERROR_FAILURE;
   }
 
   PRUint64 sizeMB = size >> 20;
   properties->SetPropertyAsUint64(NS_LITERAL_STRING("mb"), sizeMB);
   MS_LOG(("Logged memory mb=%ull", sizeMB));
--- a/gfx/cairo/libpixman/src/Makefile.in
+++ b/gfx/cairo/libpixman/src/Makefile.in
@@ -63,20 +63,20 @@ endif
 
 DEFINES += -DPIXMAN_NO_TLS
 
 # Build MMX code either with VC or with gcc-on-x86
 ifdef _MSC_VER
 ifeq (86,$(findstring 86,$(OS_TEST)))
 ifneq (64,$(findstring 64,$(OS_TEST)))
 USE_MMX=1
+endif
 USE_SSE2=1
 MMX_CFLAGS=
 endif
-endif
 ifeq (arm,$(findstring arm,$(OS_TEST)))
 USE_ARM_SIMD_MSVC=1
 endif
 endif
 
 ifdef GNU_CC
 ifeq (86,$(findstring 86,$(OS_TEST)))
 USE_MMX=1
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -40,27 +40,29 @@
 
 #include "gfxTypes.h"
 #include "nsRegion.h"
 #include "nsPoint.h"
 #include "nsRect.h"
 #include "nsISupportsImpl.h"
 #include "nsAutoPtr.h"
 #include "gfx3DMatrix.h"
+#include "gfxColor.h"
 
 class gfxContext;
 class nsPaintEvent;
 
 namespace mozilla {
 namespace layers {
 
 class Layer;
 class ThebesLayer;
 class ContainerLayer;
 class ImageLayer;
+class ColorLayer;
 class ImageContainer;
 
 /*
  * Motivation: For truly smooth animation and video playback, we need to
  * be able to compose frames and render them on a dedicated thread (i.e.
  * off the main thread where DOM manipulation, script execution and layout
  * induce difficult-to-bound latency). This requires Gecko to construct
  * some kind of persistent scene structure (graph or tree) that can be
@@ -159,16 +161,21 @@ public:
    * Create a ContainerLayer for this manager's layer tree.
    */
   virtual already_AddRefed<ContainerLayer> CreateContainerLayer() = 0;
   /**
    * CONSTRUCTION PHASE ONLY
    * Create an ImageLayer for this manager's layer tree.
    */
   virtual already_AddRefed<ImageLayer> CreateImageLayer() = 0;
+  /**
+   * CONSTRUCTION PHASE ONLY
+   * Create a ColorLayer for this manager's layer tree.
+   */
+  virtual already_AddRefed<ColorLayer> CreateColorLayer() = 0;
 
   /**
    * Can be called anytime
    */
   virtual already_AddRefed<ImageContainer> CreateImageContainer() = 0;
 
   /**
    * Type of layer manager his is. This is to be used sparsely in order to
@@ -359,30 +366,16 @@ public:
    * DRAWING PHASE ONLY
    * We've finished drawing into this layer. At this point the caller
    * must have drawn all of aRegionToDraw that was returned by
    * BeginDrawing, and we guarantee that buffered contents in the visible
    * region are now valid.
    */
   virtual void EndDrawing() = 0;
 
-  /**
-   * DRAWING PHASE ONLY
-   * Copy the aRegion contents from aSource into this layer, offsetting
-   * them by aDelta. The validity is also copied, so invalid areas in
-   * aSource will make corresponding areas of this layer invalid. You
-   * must not call this after BeginDrawing/EndDrawing on this layer.
-   * 
-   * aSource must be this layer or a layer after this layer in a
-   * preorder traversal of the layer tree.
-   */
-  virtual void CopyFrom(ThebesLayer* aSource,
-                        const nsIntRegion& aRegion,
-                        const nsIntPoint& aDelta) = 0;
-
 protected:
   ThebesLayer(LayerManager* aManager, void* aImplData)
     : Layer(aManager, aImplData) {}
 };
 
 /**
  * A Layer which other layers render into. It holds references to its
  * children.
@@ -411,12 +404,38 @@ protected:
   ContainerLayer(LayerManager* aManager, void* aImplData)
     : Layer(aManager, aImplData),
       mFirstChild(nsnull)
   {}
 
   Layer* mFirstChild;
 };
 
+/**
+ * A Layer which just renders a solid color in its visible region.
+ */
+class THEBES_API ColorLayer : public Layer {
+public:
+  /**
+   * CONSTRUCTION PHASE ONLY
+   * Set the color of the layer.
+   */
+  virtual void SetColor(const gfxRGBA& aColor)
+  {
+    mColor = aColor;
+  }
+
+  // This getter can be used anytime.
+  virtual const gfxRGBA& GetColor() { return mColor; }
+
+protected:
+  ColorLayer(LayerManager* aManager, void* aImplData)
+    : Layer(aManager, aImplData),
+      mColor(0.0, 0.0, 0.0, 0.0)
+  {}
+
+  gfxRGBA mColor;
+};
+
 }
 }
 
 #endif /* GFX_LAYERS_H */
--- a/gfx/layers/Makefile.in
+++ b/gfx/layers/Makefile.in
@@ -59,16 +59,17 @@ EXPORTS = \
         Layers.h \
         LayerManagerOGL.h \
         $(NULL)
 
 CPPSRCS = \
         BasicImages.cpp \
         BasicLayers.cpp \
         LayerManagerOGL.cpp \
+        ColorLayerOGL.cpp \
         ThebesLayerOGL.cpp \
         ContainerLayerOGL.cpp \
         ImageLayerOGL.cpp \
         $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 CXXFLAGS += $(MOZ_CAIRO_CFLAGS)
--- a/gfx/layers/basic/BasicLayers.cpp
+++ b/gfx/layers/basic/BasicLayers.cpp
@@ -234,19 +234,16 @@ public:
   virtual void InvalidateRegion(const nsIntRegion& aRegion)
   {
     NS_ASSERTION(BasicManager()->InConstruction(),
                  "Can only set properties in construction phase");
   }
 
   virtual gfxContext* BeginDrawing(nsIntRegion* aRegionToDraw);
   virtual void EndDrawing();
-  virtual void CopyFrom(ThebesLayer* aSource,
-                        const nsIntRegion& aRegion,
-                        const nsIntPoint& aDelta);
 
 protected:
   BasicLayerManager* BasicManager()
   {
     return static_cast<BasicLayerManager*>(mManager);
   }
 };
 
@@ -271,32 +268,16 @@ void
 BasicThebesLayer::EndDrawing()
 {
   NS_ASSERTION(BasicManager()->InDrawing(),
                "Can only draw in drawing phase");
   NS_ASSERTION(BasicManager()->GetLastPainted() == this,
                "Not currently drawing this layer");
 }
 
-void
-BasicThebesLayer::CopyFrom(ThebesLayer* aSource,
-                           const nsIntRegion& aRegion,
-                           const nsIntPoint& aDelta)
-{
-  NS_ASSERTION(!BasicManager()->IsBeforeInTree(aSource, this),
-               "aSource must not be before this layer in tree");
-  NS_ASSERTION(BasicManager()->IsBeforeInTree(BasicManager()->GetLastPainted(), this),
-               "Cannot copy into a layer already painted");
-  NS_ASSERTION(BasicManager()->InDrawing(),
-               "Can only draw in drawing phase");
-  // Nothing to do here since we have no retained buffers. Our
-  // valid region is empty (since we haven't painted this layer yet),
-  // so no need to mark anything invalid.
-}
-
 class BasicImageLayer : public ImageLayer, BasicImplData {
 public:
   BasicImageLayer(BasicLayerManager* aLayerManager) :
     ImageLayer(aLayerManager, static_cast<BasicImplData*>(this))
   {
     MOZ_COUNT_CTOR(BasicImageLayer);
   }
   virtual ~BasicImageLayer()
@@ -357,16 +338,51 @@ BasicImageLayer::Paint(gfxContext* aCont
 
   /* Draw RGB surface onto frame */
   aContext->NewPath();
   aContext->PixelSnappedRectangleAndSetPattern(
       gfxRect(0, 0, size.width, size.height), pat);
   aContext->Fill();
 }
 
+class BasicColorLayer : public ColorLayer, BasicImplData {
+public:
+  BasicColorLayer(BasicLayerManager* aLayerManager) :
+    ColorLayer(aLayerManager, static_cast<BasicImplData*>(this))
+  {
+    MOZ_COUNT_CTOR(BasicColorLayer);
+  }
+  virtual ~BasicColorLayer()
+  {
+    MOZ_COUNT_DTOR(BasicColorLayer);
+  }
+
+  virtual void SetVisibleRegion(const nsIntRegion& aRegion)
+  {
+    NS_ASSERTION(BasicManager()->InConstruction(),
+                 "Can only set properties in construction phase");
+    mVisibleRegion = aRegion;
+  }
+
+  virtual void Paint(gfxContext* aContext);
+
+protected:
+  BasicLayerManager* BasicManager()
+  {
+    return static_cast<BasicLayerManager*>(mManager);
+  }
+};
+
+void
+BasicColorLayer::Paint(gfxContext* aContext)
+{
+  aContext->SetColor(mColor);
+  aContext->Paint();
+}
+
 BasicLayerManager::BasicLayerManager(gfxContext* aContext) :
   mDefaultTarget(aContext), mLastPainted(nsnull)
 #ifdef DEBUG
   , mPhase(PHASE_NONE)
 #endif
 {
   MOZ_COUNT_CTOR(BasicLayerManager);
 }
@@ -598,16 +614,24 @@ BasicLayerManager::CreateContainerLayer(
 already_AddRefed<ImageLayer>
 BasicLayerManager::CreateImageLayer()
 {
   NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
   nsRefPtr<ImageLayer> layer = new BasicImageLayer(this);
   return layer.forget();
 }
 
+already_AddRefed<ColorLayer>
+BasicLayerManager::CreateColorLayer()
+{
+  NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
+  nsRefPtr<ColorLayer> layer = new BasicColorLayer(this);
+  return layer.forget();
+}
+
 #ifdef DEBUG
 static void
 AppendAncestors(Layer* aLayer, nsTArray<Layer*>* aAncestors)
 {
   while (aLayer) {
     aAncestors->AppendElement(aLayer);
     aLayer = aLayer->GetParent();
   }
--- a/gfx/layers/basic/BasicLayers.h
+++ b/gfx/layers/basic/BasicLayers.h
@@ -82,16 +82,17 @@ public:
   virtual void EndTransaction();
 
   virtual void SetRoot(Layer* aLayer);
 
   virtual already_AddRefed<ThebesLayer> CreateThebesLayer();
   virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
   virtual already_AddRefed<ImageLayer> CreateImageLayer();
   virtual already_AddRefed<ImageContainer> CreateImageContainer();
+  virtual already_AddRefed<ColorLayer> CreateColorLayer();
   virtual LayersBackend GetBackendType() { return LAYERS_BASIC; }
 
 #ifdef DEBUG
   PRBool InConstruction() { return mPhase == PHASE_CONSTRUCTION; }
   PRBool InDrawing() { return mPhase == PHASE_DRAWING; }
   PRBool IsBeforeInTree(Layer* aBefore, Layer* aLayer);
 #endif
   // Prepares mTarget for painting into aLayer. Layers are painted
new file mode 100644
--- /dev/null
+++ b/gfx/layers/opengl/ColorLayerOGL.cpp
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * ***** 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 Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Robert O'Callahan <robert@ocallahan.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "ColorLayerOGL.h"
+
+namespace mozilla {
+namespace layers {
+
+LayerOGL::LayerType
+ColorLayerOGL::GetType()
+{
+  return TYPE_COLOR;
+}
+
+Layer*
+ColorLayerOGL::GetLayer()
+{
+  return this;
+}
+
+void
+ColorLayerOGL::RenderLayer(int)
+{
+  static_cast<LayerManagerOGL*>(mManager)->MakeCurrent();
+
+  // XXX we might be able to improve performance by using glClear
+
+  float quadTransform[4][4];
+  nsIntRect visibleRect = mVisibleRegion.GetBounds();
+  // Transform the quad to the size of the visible area.
+  memset(&quadTransform, 0, sizeof(quadTransform));
+  quadTransform[0][0] = (float)visibleRect.width;
+  quadTransform[1][1] = (float)visibleRect.height;
+  quadTransform[2][2] = 1.0f;
+  quadTransform[3][0] = (float)visibleRect.x;
+  quadTransform[3][1] = (float)visibleRect.y;
+  quadTransform[3][3] = 1.0f;
+  
+  ColorLayerProgram *program =
+    static_cast<LayerManagerOGL*>(mManager)->GetColorLayerProgram();
+
+  program->Activate();
+
+  program->SetLayerQuadTransform(&quadTransform[0][0]);
+
+  gfxRGBA color = mColor;
+  // color is premultiplied, so we need to adjust all channels
+  color.r *= GetOpacity();
+  color.g *= GetOpacity();
+  color.b *= GetOpacity();
+  color.a *= GetOpacity();
+  program->SetLayerColor(color);
+  program->SetLayerTransform(&mTransform._11);
+  program->Apply();
+
+  gl()->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
+}
+
+} /* layers */
+} /* mozilla */
new file mode 100644
--- /dev/null
+++ b/gfx/layers/opengl/ColorLayerOGL.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * ***** 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 Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Robert O'Callahan <robert@ocallahan.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * 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 GFX_COLORLAYEROGL_H
+#define GFX_COLORLAYEROGL_H
+
+#include "LayerManagerOGL.h"
+
+namespace mozilla {
+namespace layers {
+
+class THEBES_API ColorLayerOGL : public ColorLayer,
+                                 public LayerOGL
+{
+public:
+  ColorLayerOGL(LayerManagerOGL *aManager)
+    : ColorLayer(aManager, NULL)
+    , LayerOGL(aManager)
+  { 
+    mImplData = static_cast<LayerOGL*>(this);
+  }
+
+  virtual void SetVisibleRegion(const nsIntRegion& aRegion) { mVisibleRegion = aRegion; }
+
+  // LayerOGL Implementation
+  virtual LayerType GetType();
+
+  virtual Layer* GetLayer();
+
+  virtual void RenderLayer(int aPreviousDestination);
+
+protected:
+  nsIntRegion mVisibleRegion;
+};
+
+} /* layers */
+} /* mozilla */
+#endif /* GFX_COLORLAYEROGL_H */
--- a/gfx/layers/opengl/ContainerLayerOGL.cpp
+++ b/gfx/layers/opengl/ContainerLayerOGL.cpp
@@ -129,16 +129,18 @@ ContainerLayerOGL::RenderLayer(int aPrev
 {
   /**
    * Setup our temporary texture for rendering the contents of this container.
    */
   GLuint containerSurface;
   GLuint frameBuffer;
   RGBLayerProgram *rgbProgram =
     static_cast<LayerManagerOGL*>(mManager)->GetRGBLayerProgram();
+  ColorLayerProgram *colorProgram =
+    static_cast<LayerManagerOGL*>(mManager)->GetColorLayerProgram();
   YCbCrLayerProgram *yCbCrProgram =
     static_cast<LayerManagerOGL*>(mManager)->GetYCbCrLayerProgram();
 
   if (GetOpacity() != 1.0) {
     gl()->fGenTextures(1, &containerSurface);
     gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, containerSurface);
     gl()->fTexImage2D(LOCAL_GL_TEXTURE_2D,
 			    0,
@@ -169,21 +171,23 @@ ContainerLayerOGL::RenderLayer(int aPrev
 	    LOCAL_GL_FRAMEBUFFER_COMPLETE, "Error setting up framebuffer.");
 
     /**
      * Store old shader program variables and set the ones used for rendering
      * this container's content.
      */
     
     rgbProgram->Activate();
-    rgbProgram->PushRenderTargetOffset((GLfloat)GetVisibleRect().x,
-					 (GLfloat)GetVisibleRect().y);
+    rgbProgram->PushRenderTargetOffset((GLfloat)GetVisibleRect().x, (GLfloat)GetVisibleRect().y);
+
+    colorProgram->Activate();
+    colorProgram->PushRenderTargetOffset((GLfloat)GetVisibleRect().x, (GLfloat)GetVisibleRect().y);
+
     yCbCrProgram->Activate();
-    yCbCrProgram->PushRenderTargetOffset((GLfloat)GetVisibleRect().x,
-					   (GLfloat)GetVisibleRect().y);
+    yCbCrProgram->PushRenderTargetOffset((GLfloat)GetVisibleRect().x, (GLfloat)GetVisibleRect().y);
   } else {
     frameBuffer = aPreviousFrameBuffer;
   }
   
   /**
    * Render this container's contents.
    */
   LayerOGL *layerToRender = GetFirstChildOGL();
@@ -206,16 +210,19 @@ ContainerLayerOGL::RenderLayer(int aPrev
     // Unbind the current framebuffer and rebind the previous one.
     gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer);
     gl()->fDeleteFramebuffers(1, &frameBuffer);
 
     // Restore old shader program variables.
     yCbCrProgram->Activate();
     yCbCrProgram->PopRenderTargetOffset();
 
+    colorProgram->Activate();
+    colorProgram->PopRenderTargetOffset();
+
     rgbProgram->Activate();
     rgbProgram->PopRenderTargetOffset();
 
     /**
      * Render the contents of this container to our destination.
      */
     float quadTransform[4][4];
     /*
--- a/gfx/layers/opengl/LayerManagerOGL.cpp
+++ b/gfx/layers/opengl/LayerManagerOGL.cpp
@@ -34,16 +34,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "LayerManagerOGL.h"
 #include "ThebesLayerOGL.h"
 #include "ContainerLayerOGL.h"
 #include "ImageLayerOGL.h"
+#include "ColorLayerOGL.h"
 #include "LayerManagerOGLShaders.h"
 
 #include "gfxContext.h"
 #include "nsIWidget.h"
 
 #include "GLContext.h"
 #include "GLContextProvider.h"
 
@@ -71,16 +72,17 @@ LayerManagerOGL::LayerManagerOGL(nsIWidg
   , mYUVShader(0)
 {
 }
 
 LayerManagerOGL::~LayerManagerOGL()
 {
   mGLContext->MakeCurrent();
   delete mRGBLayerProgram;
+  delete mColorLayerProgram;
   delete mYCbCrLayerProgram;
 }
 
 PRBool
 LayerManagerOGL::Initialize()
 {
   mGLContext = sGLContextProvider.CreateForWindow(mWidget);
 
@@ -92,53 +94,120 @@ LayerManagerOGL::Initialize()
 
   mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA, LOCAL_GL_ONE, LOCAL_GL_ONE);
   mGLContext->fEnable(LOCAL_GL_BLEND);
   mGLContext->fEnable(LOCAL_GL_TEXTURE_2D);
   mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST);
 
   mVertexShader = mGLContext->fCreateShader(LOCAL_GL_VERTEX_SHADER);
   mRGBShader = mGLContext->fCreateShader(LOCAL_GL_FRAGMENT_SHADER);
+  mColorShader = mGLContext->fCreateShader(LOCAL_GL_FRAGMENT_SHADER);
   mYUVShader = mGLContext->fCreateShader(LOCAL_GL_FRAGMENT_SHADER);
 
   mGLContext->fShaderSource(mVertexShader, 1, (const GLchar**)&sVertexShader, NULL);
   mGLContext->fShaderSource(mRGBShader, 1, (const GLchar**)&sRGBLayerPS, NULL);
+  mGLContext->fShaderSource(mColorShader, 1, (const GLchar**)&sColorLayerPS, NULL);
   mGLContext->fShaderSource(mYUVShader, 1, (const GLchar**)&sYUVLayerPS, NULL);
 
   mGLContext->fCompileShader(mVertexShader);
   mGLContext->fCompileShader(mRGBShader);
+  mGLContext->fCompileShader(mColorShader);
   mGLContext->fCompileShader(mYUVShader);
 
   GLint status;
   mGLContext->fGetShaderiv(mVertexShader, LOCAL_GL_COMPILE_STATUS, &status);
   if (!status) {
     return false;
   }
 
   mGLContext->fGetShaderiv(mRGBShader, LOCAL_GL_COMPILE_STATUS, &status);
   if (!status) {
     return false;
   }
 
+  mGLContext->fGetShaderiv(mColorShader, LOCAL_GL_COMPILE_STATUS, &status);
+  if (!status) {
+    return false;
+  }
+
   mGLContext->fGetShaderiv(mYUVShader, LOCAL_GL_COMPILE_STATUS, &status);
+  if (!status) {
+    return false;
+  }
+
+  /**
+   * We'll test the ability here to bind NPOT textures to a framebuffer, if
+   * this fails we'll try EXT_texture_rectangle.
+   */
+  mGLContext->fGenFramebuffers(1, &mFrameBuffer);
+
+  GLenum textureTargets[] = { LOCAL_GL_TEXTURE_2D,
+                              LOCAL_GL_TEXTURE_RECTANGLE_EXT };
+  mFBOTextureTarget = 0;
 
-  if (!status) {
+  for (int i = 0; i < NS_ARRAY_LENGTH(textureTargets); i++) {
+    mGLContext->fGenTextures(1, &mBackBuffer);
+    mGLContext->fBindTexture(textureTargets[i], mBackBuffer);
+    mGLContext->fTexParameteri(textureTargets[i],
+                               LOCAL_GL_TEXTURE_MIN_FILTER,
+                               LOCAL_GL_NEAREST);
+    mGLContext->fTexParameteri(textureTargets[i],
+                               LOCAL_GL_TEXTURE_MAG_FILTER,
+                               LOCAL_GL_NEAREST);
+    mGLContext->fTexImage2D(textureTargets[i],
+                            0,
+                            LOCAL_GL_RGBA,
+                            200,
+                            100,
+                            0,
+                            LOCAL_GL_RGBA,
+                            LOCAL_GL_UNSIGNED_BYTE,
+                            NULL);
+
+    mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mFrameBuffer);
+    mGLContext->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
+                                      LOCAL_GL_COLOR_ATTACHMENT0,
+                                      textureTargets[i],
+                                      mBackBuffer,
+                                      0);
+
+    if (mGLContext->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER) ==
+        LOCAL_GL_FRAMEBUFFER_COMPLETE) {
+          mFBOTextureTarget = textureTargets[i];
+          break;
+    }
+
+    mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
+    mGLContext->fBindTexture(textureTargets[i], 0);
+    /**
+     * We need to delete this texture since we can't bind a texture multiple
+     * time to different textures.
+     */
+    mGLContext->fDeleteTextures(1, &mBackBuffer);
+  }
+  if (mFBOTextureTarget == 0) {
+    /* Unable to find a texture target that works with FBOs and NPOT textures */
     return false;
   }
 
   mRGBLayerProgram = new RGBLayerProgram();
   if (!mRGBLayerProgram->Initialize(mVertexShader, mRGBShader, mGLContext)) {
     return false;
   }
+  mColorLayerProgram = new ColorLayerProgram();
+  if (!mColorLayerProgram->Initialize(mVertexShader, mColorShader, mGLContext)) {
+    return false;
+  }
   mYCbCrLayerProgram = new YCbCrLayerProgram();
   if (!mYCbCrLayerProgram->Initialize(mVertexShader, mYUVShader, mGLContext)) {
     return false;
   }
 
   mRGBLayerProgram->UpdateLocations();
+  mColorLayerProgram->UpdateLocations();
   mYCbCrLayerProgram->UpdateLocations();
 
   mGLContext->fGenBuffers(1, &mVBO);
   mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mVBO);
   mGLContext->fEnableClientState(LOCAL_GL_VERTEX_ARRAY);
   mGLContext->fEnableVertexAttribArray(VERTEX_ATTRIB_LOCATION);
 
   GLfloat vertices[] = { 0, 0, 1.0f, 0, 0, 1.0f, 1.0f, 1.0f };
@@ -146,16 +215,23 @@ LayerManagerOGL::Initialize()
 
   mRGBLayerProgram->Activate();
   mGLContext->fVertexAttribPointer(VERTEX_ATTRIB_LOCATION,
                         2,
                         LOCAL_GL_FLOAT,
                         LOCAL_GL_FALSE,
                         0,
                         0);
+  mColorLayerProgram->Activate();
+  mGLContext->fVertexAttribPointer(VERTEX_ATTRIB_LOCATION,
+                        2,
+                        LOCAL_GL_FLOAT,
+                        LOCAL_GL_FALSE,
+                        0,
+                        0);
   mYCbCrLayerProgram->Activate();
   mGLContext->fVertexAttribPointer(VERTEX_ATTRIB_LOCATION,
                         2,
                         LOCAL_GL_FLOAT,
                         LOCAL_GL_FALSE,
                         0,
                         0);
 
@@ -244,16 +320,23 @@ LayerManagerOGL::CreateImageContainer()
 
 already_AddRefed<ImageLayer>
 LayerManagerOGL::CreateImageLayer()
 {
   nsRefPtr<ImageLayer> layer = new ImageLayerOGL(this);
   return layer.forget();
 }
 
+already_AddRefed<ColorLayer>
+LayerManagerOGL::CreateColorLayer()
+{
+  nsRefPtr<ColorLayer> layer = new ColorLayerOGL(this);
+  return layer.forget();
+}
+
 void
 LayerManagerOGL::SetClippingEnabled(PRBool aEnabled)
 {
   if (aEnabled) {
     mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST);
   } else {
     mGLContext->fDisable(LOCAL_GL_SCISSOR_TEST);
   }
@@ -300,21 +383,24 @@ LayerManagerOGL::Render()
   } else {
     /**
      * Draw our backbuffer to the screen without using vertex or fragment
      * shaders. We're fine with just calculating the viewport coordinates
      * in software. And nothing special is required for the texture sampling.
      */
     mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
     mGLContext->fUseProgram(0);
+    if (mFBOTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE_EXT) {
+      mGLContext->fEnable(LOCAL_GL_TEXTURE_RECTANGLE_EXT);
+    }
     mGLContext->fDisableVertexAttribArray(VERTEX_ATTRIB_LOCATION);
     mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
     mGLContext->fEnableClientState(LOCAL_GL_VERTEX_ARRAY);
     mGLContext->fEnableClientState(LOCAL_GL_TEXTURE_COORD_ARRAY);
-    mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mBackBuffer);
+    mGLContext->fBindTexture(mFBOTextureTarget, mBackBuffer);
 
     const nsIntRect *r;
     for (nsIntRegionRectIterator iter(mClippingRegion);
          (r = iter.Next()) != nsnull;) {
       mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ZERO, LOCAL_GL_ONE, LOCAL_GL_ZERO);
       float left = (GLfloat)r->x / width;
       float right = (GLfloat)r->XMost() / width;
       float top = (GLfloat)r->y / height;
@@ -323,25 +409,41 @@ LayerManagerOGL::Render()
       float vertices[] = { left * 2.0f - 1.0f,
                            -(top * 2.0f - 1.0f),
                            right * 2.0f - 1.0f,
                            -(top * 2.0f - 1.0f),
                            left * 2.0f - 1.0f,
                            -(bottom * 2.0f - 1.0f),
                            right * 2.0f - 1.0f,
                            -(bottom * 2.0f - 1.0f) };
-      float coords[] = { left, top, right, top, left, bottom, right, bottom };
+
+      float coords[8];
+      if (mFBOTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE_EXT) {
+        /* These are in non-normalized texture coords */
+        coords[0] = (GLfloat)r->x; coords[1] = (GLfloat)r->y;
+        coords[2] = (GLfloat)r->XMost(); coords[3] = (GLfloat)r->y;
+        coords[4] = (GLfloat)r->x; coords[5] = (GLfloat)r->YMost();
+        coords[6] = (GLfloat)r->XMost(); coords[7] = (GLfloat)r->YMost();
+      } else {
+        coords[0] = left; coords[1] = top;
+        coords[2] = right; coords[3] = top;
+        coords[4] = left; coords[5] = bottom;
+        coords[6] = right; coords[7] = bottom;
+      }
 
       mGLContext->fVertexPointer(2, LOCAL_GL_FLOAT, 0, vertices);
       mGLContext->fTexCoordPointer(2, LOCAL_GL_FLOAT, 0, coords);
       mGLContext->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
     }
     mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mVBO);
     mGLContext->fEnableVertexAttribArray(VERTEX_ATTRIB_LOCATION);
     mGLContext->fDisableClientState(LOCAL_GL_TEXTURE_COORD_ARRAY);
+    if (mFBOTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE_EXT) {
+      mGLContext->fDisable(LOCAL_GL_TEXTURE_RECTANGLE_EXT);
+    }
   }
 
   mGLContext->fFinish();
 }
 
 void
 LayerManagerOGL::SetupPipeline()
 {
@@ -361,65 +463,59 @@ LayerManagerOGL::SetupPipeline()
   viewMatrix[2][2] = 1.0f;
   viewMatrix[3][0] = -1.0f;
   viewMatrix[3][1] = -1.0f;
   viewMatrix[3][3] = 1.0f;
   
   mRGBLayerProgram->Activate();
   mRGBLayerProgram->SetMatrixProj(&viewMatrix[0][0]);
 
+  mColorLayerProgram->Activate();
+  mColorLayerProgram->SetMatrixProj(&viewMatrix[0][0]);
+
   mYCbCrLayerProgram->Activate();
   mYCbCrLayerProgram->SetMatrixProj(&viewMatrix[0][0]);
 }
 
 PRBool
 LayerManagerOGL::SetupBackBuffer()
 {
   nsIntRect rect;
   mWidget->GetBounds(rect);
   GLint width = rect.width;
   GLint height = rect.height;
 
   if (width == mBackBufferSize.width && height == mBackBufferSize.height) {
     return PR_TRUE;
   }
 
-  if (!mBackBuffer) {
-    mGLContext->fGenTextures(1, &mBackBuffer);
-  }
-
   /**
-   * Setup the texture used as the backbuffer.
+   * Setup the texture used as the backbuffer. We use a texture as our
+   * backbuffer since we can rely on both GLES and OGL 2.1 to support this
+   * method.
    */
-  mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mBackBuffer);
+  mGLContext->fBindTexture(mFBOTextureTarget, mBackBuffer);
   mGLContext->fTexEnvf(LOCAL_GL_TEXTURE_ENV, LOCAL_GL_TEXTURE_ENV_MODE, LOCAL_GL_MODULATE);
-  mGLContext->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
-  mGLContext->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
-  mGLContext->fTexImage2D(LOCAL_GL_TEXTURE_2D,
+  mGLContext->fTexParameteri(mFBOTextureTarget, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
+  mGLContext->fTexParameteri(mFBOTextureTarget, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
+  mGLContext->fTexImage2D(mFBOTextureTarget,
                         0,
                         LOCAL_GL_RGBA,
                         width,
                         height,
                         0,
                         LOCAL_GL_RGBA,
                         LOCAL_GL_UNSIGNED_BYTE,
                         NULL);
 
-  /**
-   * Create the framebuffer and bind it to make our content render into our
-   * framebuffer.
-   */
-  if (!mFrameBuffer) {
-    mGLContext->fGenFramebuffers(1, &mFrameBuffer);
-  }
-
+  /* Bind our framebuffer to make our content render into our backbuffer. */
   mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mFrameBuffer);
   mGLContext->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
                                    LOCAL_GL_COLOR_ATTACHMENT0,
-                                   LOCAL_GL_TEXTURE_2D,
+                                   mFBOTextureTarget,
                                    mBackBuffer,
                                    0);
 
   return PR_TRUE;
 }
 
 void
 LayerManagerOGL::CopyToTarget()
@@ -556,16 +652,22 @@ LayerProgram::SetMatrixUniform(GLint aLo
 
 void
 LayerProgram::SetInt(GLint aLocation, GLint aValue)
 {
   mGLContext->fUniform1i(aLocation, aValue);
 }
 
 void
+LayerProgram::SetColor(GLint aLocation, const gfxRGBA& aColor)
+{
+  mGLContext->fUniform4f(aLocation, aColor.r, aColor.g, aColor.b, aColor.a);
+}
+
+void
 LayerProgram::SetLayerOpacity(GLfloat aValue)
 {
   mGLContext->fUniform1f(mLayerOpacityLocation, aValue);
 }
 
 void
 LayerProgram::PushRenderTargetOffset(GLfloat aValueX, GLfloat aValueY)
 {
@@ -598,16 +700,24 @@ void
 RGBLayerProgram::UpdateLocations()
 {
   LayerProgram::UpdateLocations();
 
   mLayerTextureLocation = mGLContext->fGetUniformLocation(mProgram, "uLayerTexture");
 }
 
 void
+ColorLayerProgram::UpdateLocations()
+{
+  LayerProgram::UpdateLocations();
+
+  mRenderColorLocation = mGLContext->fGetUniformLocation(mProgram, "uRenderColor");
+}
+
+void
 YCbCrLayerProgram::UpdateLocations()
 {
   LayerProgram::UpdateLocations();
 
   mYTextureLocation = mGLContext->fGetUniformLocation(mProgram, "uYTexture");
   mCbTextureLocation = mGLContext->fGetUniformLocation(mProgram, "uCbTexture");
   mCrTextureLocation = mGLContext->fGetUniformLocation(mProgram, "uCrTexture");
 }
--- a/gfx/layers/opengl/LayerManagerOGL.h
+++ b/gfx/layers/opengl/LayerManagerOGL.h
@@ -85,16 +85,17 @@ public:
                     mozilla::gl::GLContext *aContext);
 
   virtual void UpdateLocations();
 
   void Activate();
 
   void SetMatrixUniform(GLint aLocation, const GLfloat *aValue);
   void SetInt(GLint aLocation, GLint aValue);
+  void SetColor(GLint aLocation, const gfxRGBA& aColor);
 
   void SetMatrixProj(GLfloat *aValue)
   {
     SetMatrixUniform(mMatrixProjLocation, aValue);
   }
 
   void SetLayerQuadTransform(GLfloat *aValue)
   {
@@ -134,16 +135,30 @@ public:
   void SetLayerTexture(GLint aValue)
   {
     SetInt(mLayerTextureLocation, aValue);
   }
 protected:
   GLint mLayerTextureLocation;
 };
 
+class ColorLayerProgram : public LayerProgram
+{
+public:
+  void UpdateLocations();
+
+  void SetLayerColor(const gfxRGBA& aColor)
+  {
+    SetColor(mRenderColorLocation, aColor);
+  }
+
+protected:
+  GLint mRenderColorLocation;
+};
+
 class YCbCrLayerProgram : public LayerProgram
 {
 public:
   void UpdateLocations();
 
   void SetYTexture(GLint aValue)
   {
     SetInt(mYTextureLocation, aValue);
@@ -206,28 +221,31 @@ public:
   void SetRoot(Layer* aLayer);
   
   virtual already_AddRefed<ThebesLayer> CreateThebesLayer();
 
   virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
 
   virtual already_AddRefed<ImageLayer> CreateImageLayer();
 
+  virtual already_AddRefed<ColorLayer> CreateColorLayer();
+
   virtual already_AddRefed<ImageContainer> CreateImageContainer();
 
   virtual LayersBackend GetBackendType() { return LAYERS_OPENGL; }
 
   /**
    * Helper methods.
    */
   void SetClippingEnabled(PRBool aEnabled);
 
   void MakeCurrent();
 
   RGBLayerProgram *GetRGBLayerProgram() { return mRGBLayerProgram; }
+  ColorLayerProgram *GetColorLayerProgram() { return mColorLayerProgram; }
   YCbCrLayerProgram *GetYCbCrLayerProgram() { return mYCbCrLayerProgram; }
 
   typedef mozilla::gl::GLContext GLContext;
 
   GLContext *gl() const { return mGLContext; }
 
 private:
   /** Widget associated with this layer manager */
@@ -242,28 +260,34 @@ private:
   /** Backbuffer */
   GLuint mBackBuffer;
   /** Backbuffer size */
   nsIntSize mBackBufferSize;
   /** Framebuffer */
   GLuint mFrameBuffer;
   /** RGB Layer Program */
   RGBLayerProgram *mRGBLayerProgram;
+  /** Color Layer Program */
+  ColorLayerProgram *mColorLayerProgram;
   /** YUV Layer Program */
   YCbCrLayerProgram *mYCbCrLayerProgram;
   /** Vertex Shader */
   GLuint mVertexShader;
   /** RGB fragment shader */
   GLuint mRGBShader;
+  /** Solid color shader */
+  GLuint mColorShader;
   /** YUV fragment shader */
   GLuint mYUVShader;
   /** Current root layer. */
   LayerOGL *mRootLayer;
   /** Vertex buffer */
   GLuint mVBO;
+  /** Texture target to use for FBOs */
+  GLenum mFBOTextureTarget;
 
   /**
    * Region we're clipping our current drawing to.
    */
   nsIntRegion mClippingRegion;
   /**
    * Render the current layer tree to the active target.
    */
@@ -287,17 +311,17 @@ private:
 /**
  * General information and tree management for OGL layers.
  */
 class LayerOGL
 {
 public:
   LayerOGL(LayerManagerOGL *aManager);
 
-  enum LayerType { TYPE_THEBES, TYPE_CONTAINER, TYPE_IMAGE };
+  enum LayerType { TYPE_THEBES, TYPE_CONTAINER, TYPE_IMAGE, TYPE_COLOR };
   
   virtual LayerType GetType() = 0;
 
   LayerOGL *GetNextSibling();
   virtual LayerOGL *GetFirstChildOGL() { return nsnull; }
 
   void SetNextSibling(LayerOGL *aParent);
   void SetFirstChild(LayerOGL *aParent);
--- a/gfx/layers/opengl/LayerManagerOGLShaders.h
+++ b/gfx/layers/opengl/LayerManagerOGLShaders.h
@@ -1,12 +1,13 @@
 #define SHADER_GLOBAL_VARS "uniform mat4 uMatrixProj; \
 uniform mat4 uLayerQuadTransform; \
 uniform mat4 uLayerTransform; \
 uniform vec4 uRenderTargetOffset; \
+uniform vec4 uRenderColor; \
 uniform float uLayerOpacity; \
 \
 uniform sampler2D uLayerTexture; \
 uniform sampler2D uYTexture; \
 uniform sampler2D uCbTexture; \
 uniform sampler2D uCrTexture; \
 varying vec2 vTextureCoordinate;"
 
@@ -22,16 +23,21 @@ void main() \
     vTextureCoordinate = vec2(aVertex); \
     }";
 
 static const GLchar *sRGBLayerPS = SHADER_GLOBAL_VARS "void main() \
 { \
 gl_FragColor = texture2D(uLayerTexture, vTextureCoordinate) * uLayerOpacity; \
 }";
 
+static const GLchar *sColorLayerPS = SHADER_GLOBAL_VARS "void main() \
+{ \
+gl_FragColor = uRenderColor; \
+}";
+
 static const GLchar *sYUVLayerPS = SHADER_GLOBAL_VARS "void main() \
 { \
     vec4 yuv; \
     vec4 color; \
     yuv.r = texture2D(uCrTexture, vTextureCoordinate).r - 0.5; \
     yuv.g = texture2D(uYTexture, vTextureCoordinate).r - 0.0625; \
     yuv.b = texture2D(uCbTexture, vTextureCoordinate).r - 0.5; \
     color.r = yuv.g * 1.164 + yuv.r * 1.596; \
--- a/gfx/layers/opengl/ThebesLayerOGL.cpp
+++ b/gfx/layers/opengl/ThebesLayerOGL.cpp
@@ -213,24 +213,16 @@ ThebesLayerOGL::EndDrawing()
                        LOCAL_GL_BGRA,
                        LOCAL_GL_UNSIGNED_BYTE,
                        imageSurface->Data());
 
   mDestinationSurface = NULL;
   mContext = NULL;
 }
 
-void
-ThebesLayerOGL::CopyFrom(ThebesLayer* aSource,
-                           const nsIntRegion& aRegion,
-                           const nsIntPoint& aDelta)
-{
-  // XXX - Roc says this is going away in the API. Ignore it for now.
-}
-
 LayerOGL::LayerType
 ThebesLayerOGL::GetType()
 {
   return TYPE_THEBES;
 }
 
 const nsIntRect&
 ThebesLayerOGL::GetVisibleRect()
--- a/gfx/layers/opengl/ThebesLayerOGL.h
+++ b/gfx/layers/opengl/ThebesLayerOGL.h
@@ -58,20 +58,16 @@ public:
 
   /** ThebesLayer implementation */
   void InvalidateRegion(const nsIntRegion& aRegion);
 
   gfxContext *BeginDrawing(nsIntRegion* aRegionToDraw);
 
   void EndDrawing();
 
-  void CopyFrom(ThebesLayer* aSource,
-                const nsIntRegion& aRegion,
-                const nsIntPoint& aDelta);
-
   /** LayerOGL implementation */
   LayerType GetType();
   Layer* GetLayer();
   virtual PRBool IsEmpty();
   virtual void RenderLayer(int aPreviousFrameBuffer);
 
   /** ThebesLayerOGL */
   const nsIntRect &GetVisibleRect();
--- a/gfx/thebes/public/gfxFont.h
+++ b/gfx/thebes/public/gfxFont.h
@@ -943,16 +943,20 @@ protected:
     nsAutoTArray<gfxGlyphExtents*,1> mGlyphExtentsArray;
 
     // synthetic bolding for environments where this is not supported by the platform
     PRUint32                   mSyntheticBoldOffset;  // number of devunit pixels to offset double-strike, 0 ==> no bolding
 
     // the AA setting requested for this font - may affect glyph bounds
     AntialiasOption            mAntialiasOption;
 
+    // a copy of the font without antialiasing, if needed for separate
+    // measurement by mathml code
+    nsAutoPtr<gfxFont>         mNonAAFont;
+
     nsAutoPtr<gfxFontShaper>   mShaper;
 
     // some fonts have bad metrics, this method sanitize them.
     // if this font has bad underline offset, aIsBadUnderlineFont should be true.
     void SanitizeMetrics(gfxFont::Metrics *aMetrics, PRBool aIsBadUnderlineFont);
 };
 
 class THEBES_API gfxTextRunFactory {
--- a/gfx/thebes/public/gfxImageSurface.h
+++ b/gfx/thebes/public/gfxImageSurface.h
@@ -94,17 +94,19 @@ public:
     /**
      * Returns the total size of the image data.
      */
     PRInt32 GetDataSize() const { return mStride*mSize.height; }
 
     /* Fast copy from another image surface; returns TRUE if successful, FALSE otherwise */
     PRBool CopyFrom (gfxImageSurface *other);
 
-private:
+protected:
+    gfxImageSurface();
+    void InitFromSurface(cairo_surface_t *csurf);
     long ComputeStride() const;
 
     gfxIntSize mSize;
     PRBool mOwnsData;
     unsigned char *mData;
     gfxImageFormat mFormat;
     long mStride;
 };
--- a/gfx/thebes/public/gfxQtPlatform.h
+++ b/gfx/thebes/public/gfxQtPlatform.h
@@ -53,18 +53,18 @@ class FontEntry;
 #endif
 
 class THEBES_API gfxQtPlatform : public gfxPlatform {
 public:
 
     enum RenderMode {
         /* Use QPainter surfaces */
         RENDER_QPAINTER = 0,
-        /* Use image surfaces and XShmPutImage to QPixmap */
-        RENDER_SHARED_IMAGE,
+        /* Use offscreen buffer for rendering with image or xlib gfx backend */
+        RENDER_BUFFERED,
         /* max */
         RENDER_MODE_MAX
     };
 
     gfxQtPlatform();
     virtual ~gfxQtPlatform();
 
     static gfxQtPlatform *GetPlatform() {
--- a/gfx/thebes/public/gfxSharedImageSurface.h
+++ b/gfx/thebes/public/gfxSharedImageSurface.h
@@ -1,8 +1,9 @@
+// vim:set ts=4 sts=4 sw=4 et cin:
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * ***** 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/
@@ -33,121 +34,66 @@
  * 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 GFX_SHARED_IMAGESURFACE_H
 #define GFX_SHARED_IMAGESURFACE_H
 
-#ifdef MOZ_X11
-#ifdef HAVE_XSHM
-
 #include "gfxASurface.h"
 #include "gfxImageSurface.h"
-#include "gfxPoint.h"
 
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef MOZ_WIDGET_QT
-#include <QX11Info>
-#endif
-
-#ifdef MOZ_WIDGET_GTK2
-#include <gtk/gtk.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkx.h>
-#endif
-
-#ifdef MOZ_X11
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/XShm.h>
-#endif
+#include "mozilla/ipc/SharedMemory.h"
+#include "mozilla/ipc/Shmem.h"
 
-#include <sys/ipc.h>
-#include <sys/shm.h>
-
-class THEBES_API gfxSharedImageSurface : public gfxASurface {
+class THEBES_API gfxSharedImageSurface : public gfxImageSurface {
 public:
-  gfxSharedImageSurface();
-  ~gfxSharedImageSurface();
+    /**
+     * Init must be called after ctor
+     */
+    gfxSharedImageSurface();
 
-  // ImageSurface methods
-  gfxImageFormat Format() const { return mFormat; }
+    /**
+     * Create shared image from external Shmem
+     * Shmem must be initialized by this class
+     */
+    gfxSharedImageSurface(const mozilla::ipc::Shmem &aShmem);
 
-  const gfxIntSize& GetSize() const { return mSize; }
-  int Width() const { return mSize.width; }
-  int Height() const { return mSize.height; }
-
-  /**
-   * Distance in bytes between the start of a line and the start of the
-   * next line.
-   */
-  int Stride() const { return mStride; }
+    ~gfxSharedImageSurface();
 
-  /**
-   * Returns a pointer for the image data. Users of this function can
-   * write to it, but must not attempt to free the buffer.
-   */
-  unsigned char* Data() const { return mData; } // delete this data under us and die.
-
-  /**
-   * Returns the total size of the image data.
-   */
-  int GetDataSize() const { return mStride*mSize.height; }
-
-  /**
-   * Returns a pointer for the X-image structure.
-   */
-  XImage *image() const { return mXShmImage; }
-
-  /**
-   * Returns a gfxImageSurface as gfxASurface.
-   */
-  already_AddRefed<gfxASurface> getASurface(void);
+    /**
+     * Initialize shared image surface
+     * @param aAllocator The pointer to protocol class which has AllocShmem method
+     * @param aSize The size of the buffer
+     * @param aFormat Format of the data
+     * @see gfxImageFormat
+     */
+    template<class ShmemAllocator>
+    bool Init(ShmemAllocator *aAllocator,
+              const gfxIntSize& aSize,
+              gfxImageFormat aFormat,
+              mozilla::ipc::SharedMemory::SharedMemoryType aShmType = mozilla::ipc::SharedMemory::TYPE_BASIC)
+    {
+        mSize = aSize;
+        mFormat = aFormat;
+        mStride = ComputeStride();
+        if (!aAllocator->AllocShmem(GetAlignedSize(),
+                                    aShmType, &mShmem))
+            return false;
 
-  /**
-   * Construct an shared image surface and XImage
-   * @param aSize The size of the buffer
-   * @param aFormat Format of the data
-   * @see gfxImageFormat
-   * @param aShmId Shared Memory ID of data created outside,
-   *                if not specified, then class will allocate own shared memory
-   * @display aDisplay display used for X-Image creation
-   *                if not specified, then used system default
-   *
-   */
-  bool Init(const gfxIntSize& aSize,
-            gfxImageFormat aFormat = ImageFormatUnknown,
-            int aDepth = 0,
-            int aShmId = -1);
+        return InitSurface(PR_TRUE);
+    }
 
-  /**
-   * Returns the depth of image surface 
-  */
-  int Depth() const { return mDepth; }
+    /* Gives Shmem data, which can be passed to IPDL interfaces */
+    mozilla::ipc::Shmem& GetShmem() { return mShmem; }
+
+    // This can be used for recognizing normal gfxImageSurface as SharedImage
+    static cairo_user_data_key_t SHM_KEY;
 
 private:
-  bool CreateInternal(int aShmid);
-  long ComputeStride() const;
-  inline bool ComputeDepth();
-  inline bool ComputeFormat();
-
-  unsigned int     mDepth;
-  int              mShmId;
+    size_t GetAlignedSize();
+    bool InitSurface(PRBool aUpdateShmemInfo);
 
-  gfxIntSize mSize;
-  bool mOwnsData;
-
-  unsigned char   *mData;
-  gfxImageFormat   mFormat;
-  long mStride;
-
-  Display *mDisp;
-  XShmSegmentInfo  mShmInfo;
-  XImage          *mXShmImage;
+    mozilla::ipc::Shmem mShmem;
 };
 
-#endif /* HAVE_XSHM */
-#endif /* MOZ_X11 */
 #endif /* GFX_SHARED_IMAGESURFACE_H */
--- a/gfx/thebes/src/GLContextProviderCGL.mm
+++ b/gfx/thebes/src/GLContextProviderCGL.mm
@@ -44,17 +44,17 @@
 namespace mozilla {
 namespace gl {
 
 GLContextProvider sGLContextProvider;
 
 class CGLLibrary
 {
 public:
-    CGLLibrary() : mInitialized(PR_FALSE) {}
+    CGLLibrary() : mInitialized(PR_FALSE), mOGLLibrary(nsnull) {}
 
     PRBool EnsureInitialized()
     {
         if (mInitialized) {
             return PR_TRUE;
         }
         if (!mOGLLibrary) {
             mOGLLibrary = PR_LoadLibrary("/System/Library/Frameworks/OpenGL.framework/OpenGL");
--- a/gfx/thebes/src/Makefile.in
+++ b/gfx/thebes/src/Makefile.in
@@ -220,16 +220,19 @@ CMMSRCS += GLContextProviderCGL.mm
 else
 CPPSRCS += GLContextProviderNull.cpp
 endif
 endif
 
 DEFINES += -DIMPL_THEBES -DWOFF_MOZILLA_CLIENT
 
 include $(topsrcdir)/config/rules.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
+
+DEFINES := $(filter-out -DUNICODE,$(DEFINES))
 
 CXXFLAGS += $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
 CFLAGS += $(MOZ_CAIRO_CFLAGS) $(TK_CFLAGS)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
 ifdef WINCE
 CXXFLAGS += $(CAIRO_FT_CFLAGS)
 endif
--- a/gfx/thebes/src/gfxFont.cpp
+++ b/gfx/thebes/src/gfxFont.cpp
@@ -1069,26 +1069,28 @@ gfxFont::Measure(gfxTextRun *aTextRun,
                  PRUint32 aStart, PRUint32 aEnd,
                  BoundingBoxType aBoundingBoxType,
                  gfxContext *aRefContext,
                  Spacing *aSpacing)
 {
     // If aBoundingBoxType is TIGHT_HINTED_OUTLINE_EXTENTS
     // and the underlying cairo font may be antialiased,
     // we need to create a copy in order to avoid getting cached extents.
-    // This is inefficient, but only used by MathML layout at present.
+    // This is only used by MathML layout at present.
     if (aBoundingBoxType == TIGHT_HINTED_OUTLINE_EXTENTS &&
         mAntialiasOption != kAntialiasNone) {
-        nsAutoPtr<gfxFont> tempFont(CopyWithAntialiasOption(kAntialiasNone));
+        if (!mNonAAFont) {
+            mNonAAFont = CopyWithAntialiasOption(kAntialiasNone);
+        }
         // if font subclass doesn't implement CopyWithAntialiasOption(),
         // it will return null and we'll proceed to use the existing font
-        if (tempFont) {
-            return tempFont->Measure(aTextRun, aStart, aEnd,
-                                     TIGHT_HINTED_OUTLINE_EXTENTS,
-                                     aRefContext, aSpacing);
+        if (mNonAAFont) {
+            return mNonAAFont->Measure(aTextRun, aStart, aEnd,
+                                       TIGHT_HINTED_OUTLINE_EXTENTS,
+                                       aRefContext, aSpacing);
         }
     }
 
     const PRUint32 appUnitsPerDevUnit = aTextRun->GetAppUnitsPerDevUnit();
     // Current position in appunits
     const gfxFont::Metrics& fontMetrics = GetMetrics();
 
     RunMetrics metrics;
--- a/gfx/thebes/src/gfxImageSurface.cpp
+++ b/gfx/thebes/src/gfxImageSurface.cpp
@@ -36,16 +36,37 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "prmem.h"
 
 #include "gfxImageSurface.h"
 
 #include "cairo.h"
 
+gfxImageSurface::gfxImageSurface()
+  : mSize(0, 0),
+    mOwnsData(PR_FALSE),
+    mFormat(ImageFormatUnknown),
+    mStride(0)
+{
+}
+
+void
+gfxImageSurface::InitFromSurface(cairo_surface_t *csurf)
+{
+    mSize.width = cairo_image_surface_get_width(csurf);
+    mSize.height = cairo_image_surface_get_height(csurf);
+    mData = cairo_image_surface_get_data(csurf);
+    mFormat = (gfxImageFormat) cairo_image_surface_get_format(csurf);
+    mOwnsData = PR_FALSE;
+    mStride = cairo_image_surface_get_stride(csurf);
+
+    Init(csurf, PR_TRUE);
+}
+
 gfxImageSurface::gfxImageSurface(unsigned char *aData, const gfxIntSize& aSize,
                                  long aStride, gfxImageFormat aFormat)
   : mSize(aSize)
   , mOwnsData(PR_FALSE)
   , mData(aData)
   , mFormat(aFormat)
   , mStride(aStride)
 {
--- a/gfx/thebes/src/gfxQtPlatform.cpp
+++ b/gfx/thebes/src/gfxQtPlatform.cpp
@@ -35,16 +35,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include <QPixmap>
 #include <QX11Info>
 #include <QApplication>
 #include <QDesktopWidget>
+#include <QPaintEngine>
 
 #include "gfxQtPlatform.h"
 
 #include "gfxFontconfigUtils.h"
 
 #include "cairo.h"
 
 #include "gfxImageSurface.h"
@@ -73,18 +74,21 @@
 #ifndef MOZ_PANGO
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #endif
 
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
 
-#define DEFAULT_RENDER_MODE RENDER_SHARED_IMAGE
+// Because the QPainter backend has some problems with glyphs rendering
+// it is better to use image or xlib cairo backends by default
+#define DEFAULT_RENDER_MODE RENDER_BUFFERED
 
+static QPaintEngine::Type sDefaultQtPaintEngineType = QPaintEngine::X11;
 gfxFontconfigUtils *gfxQtPlatform::sFontconfigUtils = nsnull;
 static cairo_user_data_key_t cairo_qt_pixmap_key;
 static void do_qt_pixmap_unref (void *data)
 {
     QPixmap *pmap = (QPixmap*)data;
     delete pmap;
 }
 
@@ -135,21 +139,26 @@ gfxQtPlatform::gfxQtPlatform()
     if (envTypeOverride)
         ival = atoi(envTypeOverride);
 
     switch (ival) {
         case 0:
             mRenderMode = RENDER_QPAINTER;
             break;
         case 1:
-            mRenderMode = RENDER_SHARED_IMAGE;
+            mRenderMode = RENDER_BUFFERED;
             break;
         default:
             mRenderMode = RENDER_QPAINTER;
     }
+
+    // Qt doesn't provide a public API to detect the graphicssystem type. We hack