Merge with mozilla-central 95bca70369ef
authorDoug Turner <dougt@dougt.org>
Tue, 29 Nov 2011 20:58:39 -0800
changeset 83631 79608738a7e808a564f26fcedf4e31e54529a1fc
parent 83630 23a4ea178f9a610d7939226a8b001a906ea28e81 (current diff)
parent 82572 95bca70369ef6cbcbb642143ae8dc488b3cbf109 (diff)
child 83632 9a578e5405f552aa545eb4c13681aa1ef62d6f70
push idunknown
push userunknown
push dateunknown
milestone11.0a1
Merge with mozilla-central 95bca70369ef
browser/themes/gnomestripe/feeds/audioFeedIcon.png
browser/themes/gnomestripe/feeds/audioFeedIcon16.png
browser/themes/gnomestripe/feeds/videoFeedIcon.png
browser/themes/gnomestripe/feeds/videoFeedIcon16.png
browser/themes/pinstripe/feeds/audioFeedIcon.png
browser/themes/pinstripe/feeds/audioFeedIcon16.png
browser/themes/pinstripe/feeds/videoFeedIcon.png
browser/themes/pinstripe/feeds/videoFeedIcon16.png
browser/themes/winstripe/aboutSessionRestore-window-icon.png
browser/themes/winstripe/feeds/audioFeedIcon-aero.png
browser/themes/winstripe/feeds/audioFeedIcon.png
browser/themes/winstripe/feeds/audioFeedIcon16-aero.png
browser/themes/winstripe/feeds/audioFeedIcon16.png
browser/themes/winstripe/feeds/videoFeedIcon-aero.png
browser/themes/winstripe/feeds/videoFeedIcon.png
browser/themes/winstripe/feeds/videoFeedIcon16-aero.png
browser/themes/winstripe/feeds/videoFeedIcon16.png
browser/themes/winstripe/places/searching_16-aero.png
browser/themes/winstripe/preferences/plugin-aero.png
config/autoconf.mk.in
configure.in
content/base/test/file_html_in_xhr_slow.sjs
dom/base/nsGlobalWindow.cpp
dom/interfaces/base/nsIAnimationFrameListener.idl
editor/libeditor/base/nsEditor.cpp
extensions/pref/system-pref/src/Makefile.in
extensions/pref/system-pref/src/gconf/Makefile.in
extensions/pref/system-pref/src/gconf/gconf_pref_list.inc
extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp
extensions/pref/system-pref/src/gconf/nsSystemPrefService.h
extensions/pref/system-pref/src/nsSystemPref.cpp
extensions/pref/system-pref/src/nsSystemPref.h
extensions/pref/system-pref/src/nsSystemPrefFactory.cpp
extensions/pref/system-pref/src/nsSystemPrefLog.h
layout/base/nsPresShell.cpp
layout/xul/base/src/tree/src/nsITreeImageListener.h
mobile/android/base/AndroidManifest.xml.in
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/GeckoEvent.java
mobile/android/base/GeckoSmsManager.java
mobile/android/base/Makefile.in
mobile/xul/installer/package-manifest.in
other-licenses/android/APKOpen.cpp
toolkit/Makefile.in
toolkit/components/places/History.cpp
toolkit/components/places/Makefile.in
toolkit/components/places/nsIDynamicContainer.idl
toolkit/components/places/tests/unit/nsDynamicContainerServiceSample.js
toolkit/components/places/tests/unit/nsDynamicContainerServiceSample.manifest
toolkit/components/places/tests/unit/test_457698_crash.js
toolkit/components/places/tests/unit/test_dynamic_containers.js
toolkit/content/tests/chrome/test_autocomplete.xul
toolkit/library/Makefile.in
toolkit/themes/gnomestripe/mozapps/extensions/category-extensions.png
toolkit/themes/gnomestripe/mozapps/extensions/category-languages.png
toolkit/themes/gnomestripe/mozapps/extensions/category-themes.png
toolkit/themes/gnomestripe/mozapps/passwordmgr/key.png
toolkit/themes/gnomestripe/mozapps/places/tagContainerIcon.png
toolkit/themes/gnomestripe/mozapps/plugins/pluginOutdated-16.png
toolkit/themes/pinstripe/global/dirListing/local.png
toolkit/themes/pinstripe/global/notification/question-icon.png
toolkit/themes/pinstripe/mozapps/extensions/category-extensions.png
toolkit/themes/pinstripe/mozapps/extensions/category-languages.png
toolkit/themes/pinstripe/mozapps/extensions/category-themes.png
toolkit/themes/pinstripe/mozapps/places/tagContainerIcon.png
toolkit/themes/winstripe/global/arrow/arrow-lft-hov.gif
toolkit/themes/winstripe/global/arrow/arrow-rit-hov.gif
toolkit/themes/winstripe/global/console/bullet-error-aero.png
toolkit/themes/winstripe/global/console/bullet-error.png
toolkit/themes/winstripe/global/console/bullet-question-aero.png
toolkit/themes/winstripe/global/console/bullet-question.png
toolkit/themes/winstripe/global/console/bullet-warning-aero.png
toolkit/themes/winstripe/global/console/bullet-warning.png
toolkit/themes/winstripe/global/icons/informationBar-30-aero.png
toolkit/themes/winstripe/global/icons/informationBar-30.png
toolkit/themes/winstripe/global/icons/informationBar-60-aero.png
toolkit/themes/winstripe/global/icons/informationBar-60.png
toolkit/themes/winstripe/global/icons/loading_16-aero.png
toolkit/themes/winstripe/global/icons/notfound-aero.png
toolkit/themes/winstripe/global/icons/notfound.png
toolkit/themes/winstripe/global/icons/notloading_16-aero.png
toolkit/themes/winstripe/global/icons/questionBar-30-aero.png
toolkit/themes/winstripe/global/icons/questionBar-30.png
toolkit/themes/winstripe/global/icons/questionBar-60-aero.png
toolkit/themes/winstripe/global/icons/questionBar-60.png
toolkit/themes/winstripe/mozapps/extensions/category-extensions-aero.png
toolkit/themes/winstripe/mozapps/extensions/category-extensions.png
toolkit/themes/winstripe/mozapps/extensions/category-languages-aero.png
toolkit/themes/winstripe/mozapps/extensions/category-languages.png
toolkit/themes/winstripe/mozapps/extensions/category-themes-aero.png
toolkit/themes/winstripe/mozapps/extensions/category-themes.png
toolkit/themes/winstripe/mozapps/places/tagContainerIcon-aero.png
toolkit/themes/winstripe/mozapps/places/tagContainerIcon.png
toolkit/themes/winstripe/mozapps/plugins/pluginFinderWizard.css
toolkit/themes/winstripe/mozapps/plugins/pluginHelp-16-aero.png
toolkit/themes/winstripe/mozapps/plugins/pluginOutdated-16-aero.png
toolkit/themes/winstripe/mozapps/plugins/pluginOutdated-16.png
widget/src/android/AndroidBridge.cpp
widget/src/android/AndroidBridge.h
widget/src/android/AndroidJNI.cpp
widget/src/android/nsWindow.cpp
widget/src/android/nsWindow.h
--- a/accessible/src/atk/nsApplicationAccessibleWrap.cpp
+++ b/accessible/src/atk/nsApplicationAccessibleWrap.cpp
@@ -39,37 +39,42 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsApplicationAccessibleWrap.h"
 
 #include "nsCOMPtr.h"
 #include "nsMai.h"
 #include "prlink.h"
 #include "prenv.h"
-#include "nsIPrefBranch.h"
+#include "mozilla/Preferences.h"
+#include "nsIGConfService.h"
 #include "nsIServiceManager.h"
 #include "nsAutoPtr.h"
 #include "nsAccessibilityService.h"
 #include "AtkSocketAccessible.h"
 
 #include <gtk/gtk.h>
 #include <atk/atk.h>
 
+using namespace mozilla;
+
 typedef GType (* AtkGetTypeType) (void);
 GType g_atk_hyperlink_impl_type = G_TYPE_INVALID;
 static bool sATKChecked = false;
 static PRLibrary *sATKLib = nsnull;
 static const char sATKLibName[] = "libatk-1.0.so.0";
 static const char sATKHyperlinkImplGetTypeSymbol[] =
     "atk_hyperlink_impl_get_type";
 static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
-static const char sSysPrefService [] =
-    "@mozilla.org/system-preference-service;1";
+static const char sUseSystemPrefsKey[] =
+    "config.use_system_prefs";
 static const char sAccessibilityKey [] =
     "config.use_system_prefs.accessibility";
+static const char sGconfAccessibilityKey[] =
+    "/desktop/gnome/interface/accessibility";
 
 /* gail function pointer */
 static guint (* gail_add_global_event_listener) (GSignalEmissionHook listener,
                                                  const gchar *event_type);
 static void (* gail_remove_global_event_listener) (guint remove_listener);
 static void (* gail_remove_key_event_listener) (guint remove_listener);
 static AtkObject * (*gail_get_root) (void);
 
@@ -620,21 +625,27 @@ nsApplicationAccessibleWrap::Init()
 
     // check if accessibility enabled/disabled by environment variable
     bool isGnomeATEnabled = false;
     const char *envValue = PR_GetEnv(sAccEnv);
     if (envValue) {
         isGnomeATEnabled = !!atoi(envValue);
     } else {
         //check gconf-2 setting
-        nsresult rv;
-        nsCOMPtr<nsIPrefBranch> sysPrefService =
-            do_GetService(sSysPrefService, &rv);
-        if (NS_SUCCEEDED(rv) && sysPrefService) {
-            sysPrefService->GetBoolPref(sAccessibilityKey, &isGnomeATEnabled);
+        if (Preferences::GetBool(sUseSystemPrefsKey, false)) {
+            nsresult rv;
+            nsCOMPtr<nsIGConfService> gconf =
+                do_GetService(NS_GCONFSERVICE_CONTRACTID, &rv);
+            if (NS_SUCCEEDED(rv) && gconf) {
+                gconf->GetBool(NS_LITERAL_CSTRING(sGconfAccessibilityKey),
+                               &isGnomeATEnabled);
+            }
+        } else {
+            isGnomeATEnabled =
+                Preferences::GetBool(sAccessibilityKey, false);
         }
     }
 
     if (isGnomeATEnabled) {
         // load and initialize gail library
         nsresult rv = LoadGtkModule(sGail);
         if (NS_SUCCEEDED(rv)) {
             (*sGail.init)();
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -45,16 +45,17 @@
 #include "nsApplicationAccessibleWrap.h"
 #include "nsARIAGridAccessibleWrap.h"
 #include "nsARIAMap.h"
 #include "FocusManager.h"
 
 #include "nsIContentViewer.h"
 #include "nsCURILoader.h"
 #include "nsDocAccessible.h"
+#include "nsHTMLCanvasAccessible.h"
 #include "nsHTMLImageMapAccessible.h"
 #include "nsHTMLLinkAccessible.h"
 #include "nsHTMLSelectAccessible.h"
 #include "nsHTMLTableAccessibleWrap.h"
 #include "nsHTMLTextAccessible.h"
 #include "nsHyperTextAccessibleWrap.h"
 #include "nsIAccessibilityService.h"
 #include "nsIAccessibleProvider.h"
@@ -271,16 +272,26 @@ nsAccessibilityService::CreateHTMLCombob
 {
   nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
   nsAccessible* accessible = new nsHTMLComboboxAccessible(aContent, weakShell);
   NS_IF_ADDREF(accessible);
   return accessible;
 }
 
 already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLCanvasAccessible(nsIContent* aContent,
+                                                   nsIPresShell* aPresShell)
+{
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLCanvasAccessible(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
+}
+
+already_AddRefed<nsAccessible>
 nsAccessibilityService::CreateHTMLImageAccessible(nsIContent* aContent,
                                                   nsIPresShell* aPresShell)
 {
   nsAutoString mapElmName;
   aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usemap, mapElmName);
   nsCOMPtr<nsIDOMHTMLMapElement> mapElm;
   if (nsIDocument* document = aContent->GetCurrentDoc()) {
     mapElm = do_QueryInterface(document->FindImageMap(mapElmName));
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -78,16 +78,18 @@ public:
                                                   bool aCanCreate);
 
   virtual already_AddRefed<nsAccessible>
     CreateHTMLBRAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   virtual already_AddRefed<nsAccessible>
     CreateHTML4ButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   virtual already_AddRefed<nsAccessible>
     CreateHTMLButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
+  already_AddRefed<nsAccessible>
+    CreateHTMLCanvasAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   virtual already_AddRefed<nsAccessible>
     CreateHTMLCaptionAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   virtual already_AddRefed<nsAccessible>
     CreateHTMLCheckboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   virtual already_AddRefed<nsAccessible>
     CreateHTMLComboboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   virtual already_AddRefed<nsAccessible>
     CreateHTMLGroupboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -386,39 +386,35 @@ nsRootAccessible::ProcessDOMEvent(nsIDOM
     return;
 
   nsDocAccessible* targetDocument = accessible->GetDocAccessible();
   NS_ASSERTION(targetDocument, "No document while accessible is in document?!");
 
   nsINode* targetNode = accessible->GetNode();
 
 #ifdef MOZ_XUL
-  bool isTree = targetNode->IsElement() &&
-    targetNode->AsElement()->NodeInfo()->Equals(nsGkAtoms::tree, kNameSpaceID_XUL);
-
-  if (isTree) {
-    nsRefPtr<nsXULTreeAccessible> treeAcc = do_QueryObject(accessible);
-    NS_ASSERTION(treeAcc,
-                 "Accessible for xul:tree isn't nsXULTreeAccessible.");
+  nsRefPtr<nsXULTreeAccessible> treeAcc;
+  if (targetNode->IsElement() &&
+      targetNode->AsElement()->NodeInfo()->Equals(nsGkAtoms::tree,
+                                                  kNameSpaceID_XUL)) {
+    treeAcc = do_QueryObject(accessible);
 
-    if (treeAcc) {
-      if (eventType.EqualsLiteral("TreeViewChanged")) {
-        treeAcc->TreeViewChanged();
-        return;
-      }
+    if (eventType.EqualsLiteral("TreeViewChanged")) {
+      treeAcc->TreeViewChanged();
+      return;
+    }
 
-      if (eventType.EqualsLiteral("TreeRowCountChanged")) {
-        HandleTreeRowCountChangedEvent(aDOMEvent, treeAcc);
-        return;
-      }
-      
-      if (eventType.EqualsLiteral("TreeInvalidated")) {
-        HandleTreeInvalidatedEvent(aDOMEvent, treeAcc);
-        return;
-      }
+    if (eventType.EqualsLiteral("TreeRowCountChanged")) {
+      HandleTreeRowCountChangedEvent(aDOMEvent, treeAcc);
+      return;
+    }
+
+    if (eventType.EqualsLiteral("TreeInvalidated")) {
+      HandleTreeInvalidatedEvent(aDOMEvent, treeAcc);
+      return;
     }
   }
 #endif
 
   if (eventType.EqualsLiteral("RadioStateChange")) {
     PRUint64 state = accessible->State();
 
     // radiogroup in prefWindow is exposed as a list,
@@ -446,38 +442,36 @@ nsRootAccessible::ProcessDOMEvent(nsIDOM
 
     nsRefPtr<AccEvent> accEvent =
       new AccStateChangeEvent(accessible, states::CHECKED, isEnabled);
 
     nsEventShell::FireEvent(accEvent);
     return;
   }
 
-  nsAccessible *treeItemAccessible = nsnull;
+  nsAccessible* treeItemAcc = nsnull;
 #ifdef MOZ_XUL
-  // If it's a tree element, need the currently selected item
-  if (isTree) {
-    treeItemAccessible = accessible->CurrentItem();
-    if (treeItemAccessible)
-      accessible = treeItemAccessible;
+  // If it's a tree element, need the currently selected item.
+  if (treeAcc) {
+    treeItemAcc = accessible->CurrentItem();
+    if (treeItemAcc)
+      accessible = treeItemAcc;
   }
-#endif
 
-#ifdef MOZ_XUL
-  if (treeItemAccessible && eventType.EqualsLiteral("OpenStateChange")) {
+  if (treeItemAcc && eventType.EqualsLiteral("OpenStateChange")) {
     PRUint64 state = accessible->State();
     bool isEnabled = (state & states::EXPANDED) != 0;
 
     nsRefPtr<AccEvent> accEvent =
       new AccStateChangeEvent(accessible, states::EXPANDED, isEnabled);
     nsEventShell::FireEvent(accEvent);
     return;
   }
 
-  if (treeItemAccessible && eventType.EqualsLiteral("select")) {
+  if (treeItemAcc && eventType.EqualsLiteral("select")) {
     // XXX: We shouldn't be based on DOM select event which doesn't provide us
     // any context info. We should integrate into nsTreeSelection instead.
     // If multiselect tree, we should fire selectionadd or selection removed
     if (FocusMgr()->HasDOMFocus(targetNode)) {
       nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSel =
         do_QueryInterface(targetNode);
       nsAutoString selType;
       multiSel->GetSelType(selType);
@@ -486,18 +480,20 @@ nsRootAccessible::ProcessDOMEvent(nsIDOM
         // for each tree item. Perhaps each tree item will need to cache its
         // selection state and fire an event after a DOM "select" event when
         // that state changes. nsXULTreeAccessible::UpdateTreeSelection();
         nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN,
                                 accessible);
         return;
       }
 
-      nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SELECTION,
-                              treeItemAccessible);
+      nsRefPtr<AccSelChangeEvent> selChangeEvent =
+        new AccSelChangeEvent(treeAcc, treeItemAcc,
+                              AccSelChangeEvent::eSelectionAdd);
+      nsEventShell::FireEvent(selChangeEvent);
       return;
     }
   }
   else
 #endif
   if (eventType.EqualsLiteral("AlertActive")) {
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_ALERT, accessible);
   }
--- a/accessible/src/html/Makefile.in
+++ b/accessible/src/html/Makefile.in
@@ -45,16 +45,17 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE = accessibility
 LIBRARY_NAME = accessibility_html_s
 LIBXUL_LIBRARY = 1
 
 
 
 CPPSRCS = \
+  nsHTMLCanvasAccessible.cpp \
   nsHTMLFormControlAccessible.cpp \
   nsHTMLImageAccessible.cpp \
   nsHTMLImageMapAccessible.cpp \
   nsHTMLLinkAccessible.cpp \
   nsHTMLSelectAccessible.cpp \
   nsHTMLTableAccessible.cpp \
   nsHTMLTextAccessible.cpp \
   nsHyperTextAccessible.cpp \
new file mode 100644
--- /dev/null
+++ b/accessible/src/html/nsHTMLCanvasAccessible.cpp
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 "nsHTMLCanvasAccessible.h"
+
+using namespace mozilla::a11y;
+
+nsHTMLCanvasAccessible::
+  nsHTMLCanvasAccessible(nsIContent* aContent, nsIWeakReference* aShell) :
+  nsHyperTextAccessible(aContent, aShell)
+{
+}
+
+PRUint32
+nsHTMLCanvasAccessible::NativeRole()
+{
+  return nsIAccessibleRole::ROLE_CANVAS;
+}
new file mode 100644
--- /dev/null
+++ b/accessible/src/html/nsHTMLCanvasAccessible.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 "nsHyperTextAccessible.h"
+
+#ifndef _nsHTMLCanvasAccessible_H_
+#define _nsHTMLCanvasAccessible_H_
+
+/**
+ * HTML canvas accessible (html:canvas).
+ */
+class nsHTMLCanvasAccessible : public nsHyperTextAccessible
+{
+public:
+  nsHTMLCanvasAccessible(nsIContent* aContent, nsIWeakReference* aShell);
+  virtual ~nsHTMLCanvasAccessible() { }
+
+  // nsAccessible
+  virtual PRUint32 NativeRole();
+};
+
+#endif
--- a/accessible/tests/mochitest/role.js
+++ b/accessible/tests/mochitest/role.js
@@ -2,16 +2,17 @@
 // Role constants
 
 const ROLE_ALERT = nsIAccessibleRole.ROLE_ALERT;
 const ROLE_ANIMATION = nsIAccessibleRole.ROLE_ANIMATION;
 const ROLE_APPLICATION = nsIAccessibleRole.ROLE_APPLICATION;
 const ROLE_APP_ROOT = nsIAccessibleRole.ROLE_APP_ROOT;
 const ROLE_AUTOCOMPLETE = nsIAccessibleRole.ROLE_AUTOCOMPLETE;
 const ROLE_BUTTONDROPDOWNGRID = nsIAccessibleRole.ROLE_BUTTONDROPDOWNGRID;
+const ROLE_CANVAS = nsIAccessibleRole.ROLE_CANVAS;
 const ROLE_CAPTION = nsIAccessibleRole.ROLE_CAPTION;
 const ROLE_CELL = nsIAccessibleRole.ROLE_CELL;
 const ROLE_CHECKBUTTON = nsIAccessibleRole.ROLE_CHECKBUTTON;
 const ROLE_CHROME_WINDOW = nsIAccessibleRole.ROLE_CHROME_WINDOW;
 const ROLE_COMBOBOX = nsIAccessibleRole.ROLE_COMBOBOX;
 const ROLE_COMBOBOX_LIST = nsIAccessibleRole.ROLE_COMBOBOX_LIST;
 const ROLE_COMBOBOX_OPTION = nsIAccessibleRole.ROLE_COMBOBOX_OPTION;
 const ROLE_COLUMNHEADER = nsIAccessibleRole.ROLE_COLUMNHEADER;
--- a/accessible/tests/mochitest/tree/Makefile.in
+++ b/accessible/tests/mochitest/tree/Makefile.in
@@ -47,16 +47,17 @@ include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES =\
 		dockids.html \
 	$(warning test_applicationacc.xul temporarily disabled, see bug 561508) \
 		test_aria_globals.html \
 		test_aria_imgmap.html \
 		test_aria_presentation.html \
 		test_button.xul \
+		test_canvas.html \
 		test_combobox.xul \
 		test_cssoverflow.html \
 		test_dochierarchy.html \
 		test_dockids.html \
 		test_filectrl.html \
 		test_formctrl.html \
 		test_formctrl.xul \
 		test_gencontent.html \
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/tree/test_canvas.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=495912
+-->
+<head>
+  <title>File Input Control tests</title>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../role.js"></script>
+
+  <script type="application/javascript">
+    function doTest()
+    {
+      var accTree = {
+        role: ROLE_CANVAS,
+        children: [
+        ]
+      };
+      testAccessibleTree("canvas", accTree);
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+</head>
+<body>
+
+  <a target="_blank"
+     title="Expose alternative content in Canvas element to ATs"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=495912">Mozilla Bug 495912</a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <canvas id="canvas" tabindex="0">
+    fallback content.
+  </canvas>
+
+  <script type="text/javascript">
+    var c=document.getElementById("canvas");
+    var cxt=c.getContext("2d");
+    cxt.fillStyle="#005500";
+    cxt.fillRect(0,0,150,75);
+  </script>  
+
+</body>
+</html>
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -7,16 +7,17 @@ builtin(include, build/autoconf/glib.m4)
 builtin(include, build/autoconf/nspr.m4)dnl
 builtin(include, build/autoconf/nss.m4)dnl
 builtin(include, build/autoconf/pkg.m4)dnl
 builtin(include, build/autoconf/freetype2.m4)dnl
 builtin(include, build/autoconf/codeset.m4)dnl
 builtin(include, build/autoconf/altoptions.m4)dnl
 builtin(include, build/autoconf/mozprog.m4)dnl
 builtin(include, build/autoconf/mozheader.m4)dnl
+builtin(include, build/autoconf/mozcommonheader.m4)dnl
 builtin(include, build/autoconf/acwinpaths.m4)dnl
 builtin(include, build/autoconf/lto.m4)dnl
 builtin(include, build/autoconf/gcc-pr49911.m4)dnl
 builtin(include, build/autoconf/frameptr.m4)dnl
 
 MOZ_PROG_CHECKMSYS()
 
 # Read the user's .mozconfig script.  We can't do this in
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1318359094000">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1321712096000">
   <emItems>
       <emItem  blockID="i41" id="{99079a25-328f-4bd4-be04-00955acaa0a7}">
                         <versionRange  minVersion="0.1" maxVersion="4.3.1.00" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i8" id="{B13721C7-F507-4982-B2E5-502A71474FED}">
                         <versionRange  minVersion=" " severity="1">
                     </versionRange>
@@ -112,16 +112,23 @@
                               <versionRange  minVersion="3.5.7" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
                   </emItem>
       <emItem  blockID="i17" id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}">
                         <versionRange  minVersion="2.2" maxVersion="2.2">
                     </versionRange>
                   </emItem>
+      <emItem  blockID="i45" id="{22119944-ED35-4ab1-910B-E619EA06A115}">
+                        <versionRange  minVersion="0.1" maxVersion="7.6.1">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="8.0a1" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                  </emItem>
       <emItem  blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
                         <versionRange  minVersion="2.0" maxVersion="2.0">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
                         </emItem>
       <emItem  blockID="i24" id="{6E19037A-12E3-4295-8915-ED48BC341614}">
                         <versionRange  minVersion="0.1" maxVersion="1.3.328.4" severity="1">
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3476,17 +3476,16 @@ const BrowserSearch = {
     // SearchService._addEngineToStore() should fail for such an engine),
     // but let's be on the safe side.
     if (!submission)
       return;
 
     openLinkIn(submission.uri.spec,
                useNewTab ? "tab" : "current",
                { postData: submission.postData,
-                 inBackground: false,
                  relatedToCurrent: true });
   },
 
   /**
    * Returns the search bar element if it is present in the toolbar, null otherwise.
    */
   get searchBar() {
     return document.getElementById("searchbar");
@@ -3946,16 +3945,19 @@ var FullScreen = {
     let focusManger = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
     if (focusManger.activeWindow != window) {
       // The top-level window has lost focus since the request to enter
       // full-screen was made. Cancel full-screen.
       document.mozCancelFullScreen();
       return;
     }
 
+    if (gFindBarInitialized)
+      gFindBar.close();
+
     this.showWarning(true);
 
     // Exit DOM full-screen mode upon open, close, or change tab.
     gBrowser.tabContainer.addEventListener("TabOpen", this.exitDomFullScreen);
     gBrowser.tabContainer.addEventListener("TabClose", this.exitDomFullScreen);
     gBrowser.tabContainer.addEventListener("TabSelect", this.exitDomFullScreen);
 
     // Exit DOM full-screen mode when the browser window loses focus (ALT+TAB, etc).
--- a/browser/components/migration/content/migration.js
+++ b/browser/components/migration/content/migration.js
@@ -335,16 +335,19 @@ var MigrationWizard = {
         source = "sourceNameIE";
         break;
       case "opera":
         source = "sourceNameOpera";
         break;
       case "safari":
         source = "sourceNameSafari";
         break;
+      case "chrome":
+        source = "sourceNameChrome";
+        break;
     }
 
     // semi-wallpaper for crash when multiple profiles exist, since we haven't initialized mSourceProfile in places
     this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate);
 
     var oldHomePageURL = this._migrator.sourceHomePageURL;
 
     if (oldHomePageURL && source) {
--- a/browser/components/migration/content/migration.xul
+++ b/browser/components/migration/content/migration.xul
@@ -74,16 +74,17 @@
 #elifdef XP_UNIX
       <radio id="opera"     label="&importFromOpera.label;"     accesskey="&importFromOpera.accesskey;"/>
 #elifdef XP_WIN
 #ifndef NO_IE_MIGRATOR
       <radio id="ie"        label="&importFromIE.label;"        accesskey="&importFromIE.accesskey;"/>
 #endif
       <radio id="opera"     label="&importFromOpera.label;"     accesskey="&importFromOpera.accesskey;"/>
 #endif
+      <radio id="chrome"    label="&importFromChrome.label;"    accesskey="&importFromChrome.accesskey;"/>
       <radio id="fromfile"  label="&importFromHTMLFile.label;"  accesskey="&importFromHTMLFile.accesskey;" hidden="true"/>
       <radio id="nothing"   label="&importFromNothing.label;"   accesskey="&importFromNothing.accesskey;" hidden="true"/>
     </radiogroup>
     <label id="noSources" hidden="true">&noMigrationSources.label;</label>
   </wizardpage>
 
   <wizardpage id="selectProfile" pageid="selectProfile" label="&selectProfile.title;"
               next="importItems"
new file mode 100644
--- /dev/null
+++ b/browser/components/migration/src/BrowserProfileMigrators.manifest
@@ -0,0 +1,2 @@
+component {4cec1de4-1671-4fc3-a53e-6c539dc77a26} ChromeProfileMigrator.js
+contract @mozilla.org/profile/migrator;1?app=browser&type=chrome {4cec1de4-1671-4fc3-a53e-6c539dc77a26}
new file mode 100644
--- /dev/null
+++ b/browser/components/migration/src/ChromeProfileMigrator.js
@@ -0,0 +1,532 @@
+/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=2 sts=2 et
+ * ***** 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 Browser Profile Migrator.
+ *
+ * The Initial Developer of the Original Code is the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Makoto Kato <m_kato@ga2.so-net.ne.jp> (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 ***** */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+const LOCAL_FILE_CID = "@mozilla.org/file/local;1";
+const FILE_INPUT_STREAM_CID = "@mozilla.org/network/file-input-stream;1";
+
+const BUNDLE_MIGRATION = "chrome://browser/locale/migration/migration.properties";
+
+const MIGRATE_ALL = 0x0000;
+const MIGRATE_SETTINGS = 0x0001;
+const MIGRATE_COOKIES = 0x0002;
+const MIGRATE_HISTORY = 0x0004;
+const MIGRATE_FORMDATA = 0x0008;
+const MIGRATE_PASSWORDS = 0x0010;
+const MIGRATE_BOOKMARKS = 0x0020;
+const MIGRATE_OTHERDATA = 0x0040;
+
+const S100NS_FROM1601TO1970 = 0x19DB1DED53E8000;
+const S100NS_PER_MS = 10;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
+Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
+Components.utils.import("resource://gre/modules/NetUtil.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "bookmarksSubfolderTitle", function () {
+  // get "import from google chrome" string for folder
+  let strbundle =
+    Services.strings.createBundle(BUNDLE_MIGRATION);
+  let sourceNameChrome = strbundle.GetStringFromName("sourceNameChrome");
+  return strbundle.formatStringFromName("importedBookmarksFolder",
+                                        [sourceNameChrome],
+                                        1);
+});
+
+/*
+ * Convert Chrome time format to Date object
+ *
+ * @param   aTime
+ *          Chrome time 
+ * @return  converted Date object
+ * @note    Google Chrome uses FILETIME / 10 as time.
+ *          FILETIME is based on same structure of Windows.
+ */
+function chromeTimeToDate(aTime)
+{
+  return new Date((aTime * S100NS_PER_MS - S100NS_FROM1601TO1970 ) / 10000);
+}
+
+/*
+ * Insert bookmark items into specific folder.
+ *
+ * @param   aFolderId
+ *          id of folder where items will be inserted
+ * @param   aItems
+ *          bookmark items to be inserted
+ */
+function insertBookmarkItems(aFolderId, aItems)
+{
+  for (let i = 0; i < aItems.length; i++) {
+    let item = aItems[i];
+
+    try {
+      if (item.type == "url") {
+        PlacesUtils.bookmarks.insertBookmark(aFolderId,
+                                             NetUtil.newURI(item.url),
+                                             PlacesUtils.bookmarks.DEFAULT_INDEX,
+                                             item.name);
+      } else if (item.type == "folder") {
+        let newFolderId =
+          PlacesUtils.bookmarks.createFolder(aFolderId,
+                                             item.name,
+                                             PlacesUtils.bookmarks.DEFAULT_INDEX);
+
+        insertBookmarkItems(newFolderId, item.children);
+      }
+    } catch (e) {
+      Cu.reportError(e);
+    }
+  }
+}
+
+function ChromeProfileMigrator()
+{
+}
+
+ChromeProfileMigrator.prototype = {
+  _paths: {
+    bookmarks : null,
+    cookies : null,
+    history : null,
+    prefs : null,
+  },
+
+  _homepageURL : null,
+  _replaceBookmarks : false,
+
+  /*
+   * Notify to observers to start migration
+   *
+   * @param   aType
+   *          notification type such as MIGRATE_BOOKMARKS
+   */
+
+  _notifyStart : function Chrome_notifyStart(aType)
+  {
+    Services.obs.notifyObservers(null, "Migration:ItemBeforeMigrate", aType);
+    this._pendingCount++;
+  },
+
+  /*
+   * Notify to observers to finish migration for item
+   * If all items are finished, it sends migration end notification.
+   *
+   * @param   aType
+   *          notification type such as MIGRATE_BOOKMARKS
+   */
+  _notifyCompleted : function Chrome_notifyIfCompleted(aType)
+  {
+    Services.obs.notifyObservers(null, "Migration:ItemAfterMigrate", aType);
+    if (--this._pendingCount == 0) {
+      // All items are migrated, so we have to send end notification.
+      Services.obs.notifyObservers(null, "Migration:Ended", null);
+    }
+  },
+
+  /*
+   * Migrating bookmark items
+   */
+  _migrateBookmarks : function Chrome_migrateBookmarks()
+  {
+    this._notifyStart(MIGRATE_BOOKMARKS);
+
+    try {
+      PlacesUtils.bookmarks.runInBatchMode({
+        _self : this,
+        runBatched : function (aUserData) {
+          let migrator = this._self;
+          let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+          file.initWithPath(migrator._paths.bookmarks);
+
+          NetUtil.asyncFetch(file, function(aInputStream, aResultCode) {
+            if (!Components.isSuccessCode(aResultCode)) {
+              migrator._notifyCompleted(MIGRATE_BOOKMARKS);
+              return;
+            }
+
+            // Parse Chrome bookmark file that is JSON format
+            let bookmarkJSON = NetUtil.readInputStreamToString(aInputStream,
+                                                               aInputStream.available(),
+                                                               { charset : "UTF-8" });
+            let roots = JSON.parse(bookmarkJSON).roots;
+
+            // Importing bookmark bar items
+            if (roots.bookmark_bar.children &&
+                roots.bookmark_bar.children.length > 0) {
+              // Toolbar
+              let parentId = PlacesUtils.toolbarFolderId;
+              if (!migrator._replaceBookmarks) { 
+                parentId =
+                  PlacesUtils.bookmarks.createFolder(parentId,
+                                                     bookmarksSubfolderTitle,
+                                                     PlacesUtils.bookmarks.DEFAULT_INDEX);
+              }
+              insertBookmarkItems(parentId, roots.bookmark_bar.children);
+            }
+
+            // Importing bookmark menu items
+            if (roots.other.children &&
+                roots.other.children.length > 0) {
+              // Bookmark menu
+              let parentId = PlacesUtils.bookmarksMenuFolderId;
+              if (!migrator._replaceBookmarks) { 
+                parentId =
+                  PlacesUtils.bookmarks.createFolder(parentId,
+                                                     bookmarksSubfolderTitle,
+                                                     PlacesUtils.bookmarks.DEFAULT_INDEX);
+              }
+              insertBookmarkItems(parentId, roots.other.children);
+            }
+
+            migrator._notifyCompleted(MIGRATE_BOOKMARKS);
+          });
+        }
+      }, null);
+    } catch (e) {
+      Cu.reportError(e);
+      this._notifyCompleted(MIGRATE_BOOKMARKS);
+    }
+  },
+
+  /*
+   * Migrating history
+   */
+  _migrateHistory : function Chrome_migrateHistory()
+  {
+    this._notifyStart(MIGRATE_HISTORY);
+
+    try {
+      PlacesUtils.history.runInBatchMode({
+        _self : this,
+        runBatched : function (aUserData) {
+          // access sqlite3 database of Chrome's history
+          let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+          file.initWithPath(this._self._paths.history);
+
+          let dbConn = Services.storage.openUnsharedDatabase(file);
+          let stmt = dbConn.createAsyncStatement(
+              "SELECT url, title, last_visit_time, typed_count FROM urls WHERE hidden = 0");
+
+          stmt.executeAsync({
+            _asyncHistory : Cc["@mozilla.org/browser/history;1"]
+                            .getService(Ci.mozIAsyncHistory),
+            _db : dbConn,
+            _self : this._self,
+            handleResult : function(aResults) {
+              let places = [];
+              for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) {
+                try {
+                  // if having typed_count, we changes transition type to typed.
+                  let transType = PlacesUtils.history.TRANSITION_LINK;
+                  if (row.getResultByName("typed_count") > 0)
+                    transType = PlacesUtils.history.TRANSITION_TYPED;
+
+                  places.push({
+                    uri: NetUtil.newURI(row.getResultByName("url")),
+                    title: row.getResultByName("title"),
+                    visits: [{
+                      transitionType: transType,
+                      visitDate: chromeTimeToDate(
+                                   row.getResultByName(
+                                     "last_visit_time")) * 1000,
+                    }],
+                  });
+                } catch (e) {
+                  Cu.reportError(e);
+                }
+              }
+
+              try {
+                this._asyncHistory.updatePlaces(places);
+              } catch (e) {
+                Cu.reportError(e);
+              }
+            },
+
+            handleError : function(aError) {
+              Cu.reportError("Async statement execution returned with '" +
+                             aError.result + "', '" + aError.message + "'");
+            },
+
+            handleCompletion : function(aReason) {
+              this._db.asyncClose();
+              this._self._notifyCompleted(MIGRATE_HISTORY);
+            }
+          });
+          stmt.finalize();
+        }
+      }, null);
+    } catch (e) {
+      Cu.reportError(e);
+      this._notifyCompleted(MIGRATE_HISTORY);
+    }
+  },
+
+  /*
+   * Migrating cookies
+   */
+  _migrateCookies : function Chrome_migrateCookies()
+  {
+    this._notifyStart(MIGRATE_COOKIES);
+
+    try {
+      // Access sqlite3 database of Chrome's cookie
+      let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+      file.initWithPath(this._paths.cookies);
+
+      let dbConn = Services.storage.openUnsharedDatabase(file);
+      let stmt = dbConn.createAsyncStatement(
+          "SELECT host_key, path, name, value, secure, httponly, expires_utc FROM cookies");
+
+      stmt.executeAsync({
+        _db : dbConn,
+        _self : this,
+        handleResult : function(aResults) {
+          for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) {
+            let host_key = row.getResultByName("host_key");
+            if (host_key.match(/^\./)) {
+              // 1st character of host_key may be ".", so we have to remove it
+              host_key = host_key.substr(1);
+            }
+
+            try {
+              let expiresUtc =
+                chromeTimeToDate(row.getResultByName("expires_utc")) / 1000;
+              Services.cookies.add(host_key,
+                                   row.getResultByName("path"),
+                                   row.getResultByName("name"),
+                                   row.getResultByName("value"),
+                                   row.getResultByName("secure"),
+                                   row.getResultByName("httponly"),
+                                   false,
+                                   parseInt(expiresUtc));
+            } catch (e) {
+              Cu.reportError(e);
+            }
+          }
+        },
+
+        handleError : function(aError) {
+          Cu.reportError("Async statement execution returned with '" +
+                         aError.result + "', '" + aError.message + "'");
+        },
+
+        handleCompletion : function(aReason) {
+          this._db.asyncClose();
+          this._self._notifyCompleted(MIGRATE_COOKIES);
+        },
+      });
+      stmt.finalize();
+    } catch (e) {
+      Cu.reportError(e);
+      this._notifyCompleted(MIGRATE_COOKIES);
+    }
+  },
+
+  /*
+   * nsIBrowserProfileMigrator interface implementation
+   */
+
+  /*
+   * Let's migrate all items
+   *
+   * @param   aItems
+   *          list of data items to migrate.  but this is unused.
+   * @param   aStartup
+   *          non-null if called during startup.
+   * @param   aProfile
+   *          this is unused due to single profile support only
+   */
+  migrate : function Chrome_migrate(aItems, aStartup, aProfile)
+  {
+    if (aStartup) {
+      aStartup.doStartup();
+      this._replaceBookmarks = true;
+    }
+
+    Services.obs.notifyObservers(null, "Migration:Started", null);
+
+    // Reset panding count.  If this count becomes 0, "Migration:Ended"
+    // notification is sent
+    this._pendingCount = 1;
+
+    if (aItems & MIGRATE_HISTORY)
+      this._migrateHistory();
+
+    if (aItems & MIGRATE_COOKIES)
+      this._migrateCookies();
+
+    if (aItems & MIGRATE_BOOKMARKS)
+      this._migrateBookmarks();
+
+    if (--this._pendingCount == 0) {
+      // When async imports are immeditelly completed unfortunately,
+      // this will be called.
+      // Usually, this notification is sent by _notifyCompleted()
+      Services.obs.notifyObservers(null, "Migration:Ended", null);
+    }
+  },
+
+  /*
+   * return supported migration types
+   *
+   * @param   aProfile
+   *          this is unused due to single profile support only
+   * @param   aDoingStartup
+   *          non-null if called during startup.
+   * @return  supported migration types
+   */
+  getMigrateData: function Chrome_getMigrateData(aProfile, aDoingStartup)
+  {
+#ifdef XP_WIN
+    let chromepath = Services.dirsvc.get("LocalAppData", Ci.nsIFile).path +
+                     "\\Google\\Chrome\\User Data\\Default\\";
+#elifdef XP_MACOSX
+    let chromepath = Services.dirsvc.get("Home", Ci.nsIFile).path +
+                     "/Library/Application Support/Google/Chrome/Default/";
+#else
+    let chromepath = Services.dirsvc.get("Home", Ci.nsIFile).path +
+                     "/.config/google-chrome/Default/";
+#endif
+
+    let result = 0;
+
+    // bookmark and preference are JSON format
+
+    try {
+      let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+      file.initWithPath(chromepath + "Bookmarks");
+      if (file.exists()) {
+        this._paths.bookmarks = file.path
+        result += MIGRATE_BOOKMARKS;
+      }
+    } catch (e) {
+      Cu.reportError(e);
+    }
+
+    if (!this._paths.prefs)
+      this._paths.prefs = chromepath + "Preferences";
+
+    // history and cookies are SQLite database
+
+    try {
+      let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+      file.initWithPath(chromepath + "History");
+      if (file.exists()) {
+        this._paths.history = file.path
+        result += MIGRATE_HISTORY;
+      }
+    } catch (e) {
+      Cu.reportError(e);
+    }
+
+    try {
+      let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+      file.initWithPath(chromepath + "Cookies");
+      if (file.exists()) {
+        this._paths.cookies = file.path
+        result += MIGRATE_COOKIES;
+      }
+    } catch (e) {
+      Cu.reportError(e);
+    }
+
+    return result;
+  },
+
+  /*
+   * Whether we support migration of Chrome
+   *
+   * @return true if supported
+   */
+  sourceExists: function Chrome_sourceExists()
+  {
+    let result = this.getMigrateData(null, false);
+    return result != 0;
+  },
+
+  // Although Chrome supports multi-profiles, there is no way
+  // to get profile lists.
+  sourceHasMultipleProfiles: false,
+  sourceProfiles: null,
+
+  /*
+   * Return home page URL
+   *
+   * @return  home page URL
+   */
+  sourceHomePageURL: function Chrome_sourceHomePageURL()
+  {
+    try  {
+      if (this._homepageURL)
+        return this._homepageURL;
+
+      if (!this._paths.prefs)
+        this.getMigrateData(null, false);
+
+      // XXX reading and parsing JSON is synchronous.
+      let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+      file.initWithPath(this._paths.prefs);
+      let fstream = Cc[FILE_INPUT_STREAM_CID].
+                    createInstance(Ci.nsIFileInputStream);
+      fstream.init(file, -1, 0, 0); 
+      this._homepageURL = JSON.parse(
+        NetUtil.readInputStreamToString(fstream, fstream.available(),
+                                        { charset: "UTF-8" })).homepage;
+      return this._homepageURL;
+    } catch (e) {
+      Cu.reportError(e);
+    }
+    return "";
+  },
+
+  QueryInterface: XPCOMUtils.generateQI([
+    Ci.nsIBrowserProfileMigrator
+  ]),
+
+  classDescription: "Chrome Profile Migrator",
+  contractID: "@mozilla.org/profile/migrator;1?app=browser&type=chrome",
+  classID: Components.ID("{4cec1de4-1671-4fc3-a53e-6c539dc77a26}")
+};
+
+const NSGetFactory = XPCOMUtils.generateNSGetFactory([ChromeProfileMigrator]);
--- a/browser/components/migration/src/Makefile.in
+++ b/browser/components/migration/src/Makefile.in
@@ -62,10 +62,18 @@ CPPSRCS += nsIEProfileMigrator.cpp \
            $(NULL)
 endif
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS += nsSafariProfileMigrator.cpp \
            $(NULL)
 endif            
 
+EXTRA_PP_COMPONENTS = \
+  ChromeProfileMigrator.js \
+  $(NULL)
+
+EXTRA_COMPONENTS = \
+	BrowserProfileMigrators.manifest \
+	$(NULL)
+
 include $(topsrcdir)/config/rules.mk
 
--- a/browser/components/migration/src/nsProfileMigrator.cpp
+++ b/browser/components/migration/src/nsProfileMigrator.cpp
@@ -158,16 +158,17 @@ nsProfileMigrator::Import()
 
 NS_IMPL_ISUPPORTS1(nsProfileMigrator, nsIProfileMigrator)
 
 #ifdef XP_WIN
 
 #define INTERNAL_NAME_IEXPLORE        "iexplore"
 #define INTERNAL_NAME_MOZILLA_SUITE   "apprunner"
 #define INTERNAL_NAME_OPERA           "opera"
+#define INTERNAL_NAME_CHROME          "chrome"
 #endif
 
 nsresult
 nsProfileMigrator::GetDefaultBrowserMigratorKey(nsACString& aKey,
                                                 nsCOMPtr<nsIBrowserProfileMigrator>& bpm)
 {
 #if XP_WIN
 
@@ -241,32 +242,37 @@ nsProfileMigrator::GetDefaultBrowserMigr
   if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_IEXPLORE)) {
     aKey = "ie";
     return NS_OK;
   }
   else if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_OPERA)) {
     aKey = "opera";
     return NS_OK;
   }
+  else if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_CHROME)) {
+    aKey = "chrome";
+    return NS_OK;
+  }
 
 #else
   bool exists = false;
 #define CHECK_MIGRATOR(browser) do {\
   bpm = do_CreateInstance(NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX browser);\
   if (bpm)\
     bpm->GetSourceExists(&exists);\
   if (exists) {\
     aKey = browser;\
     return NS_OK;\
   }} while(0)
 
 #if defined(XP_MACOSX)
   CHECK_MIGRATOR("safari");
 #endif
   CHECK_MIGRATOR("opera");
+  CHECK_MIGRATOR("chrome");
 
 #undef CHECK_MIGRATOR
 #endif
   return NS_ERROR_FAILURE;
 }
 
 bool
 nsProfileMigrator::ImportRegistryProfiles(const nsACString& aAppName)
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -442,17 +442,16 @@ PlacesController.prototype = {
    * Gathers information about the selected nodes according to the following
    * rules:
    *    "link"              node is a URI
    *    "bookmark"          node is a bookamrk
    *    "livemarkChild"     node is a child of a livemark
    *    "tagChild"          node is a child of a tag
    *    "folder"            node is a folder
    *    "query"             node is a query
-   *    "dynamiccontainer"  node is a dynamic container
    *    "separator"         node is a separator line
    *    "host"              node is a host
    *
    * @returns an array of objects corresponding the selected nodes. Each
    *          object has each of the properties above set if its corresponding
    *          node matches the rule. In addition, the annotations names for each
    *          node are set on its corresponding object as properties.
    * Notes:
@@ -485,19 +484,16 @@ PlacesController.prototype = {
                 break;
               case Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_SITE_QUERY:
               case Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_QUERY:
                 nodeData["day"] = true;
                 break;
             }
           }
           break;
-        case Ci.nsINavHistoryResultNode.RESULT_TYPE_DYNAMIC_CONTAINER:
-          nodeData["dynamiccontainer"] = true;
-          break;
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER:
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT:
           nodeData["folder"] = true;
           break;
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR:
           nodeData["separator"] = true;
           break;
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_URI:
--- a/browser/config/mozconfigs/linux32/debug
+++ b/browser/config/mozconfigs/linux32/debug
@@ -1,13 +1,13 @@
 ac_add_options --enable-debug
 ac_add_options --enable-trace-malloc
 
-CC=/tools/gcc-4.5-0moz2/bin/gcc
-CXX=/tools/gcc-4.5-0moz2/bin/g++
+. $topsrcdir/build/unix/mozconfig.linux
+
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
--- a/browser/config/mozconfigs/linux32/l10n-mozconfig
+++ b/browser/config/mozconfigs/linux32/l10n-mozconfig
@@ -1,7 +1,7 @@
 ac_add_options --with-l10n-base=../../l10n-central
 ac_add_options --enable-official-branding
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 
-CC=/tools/gcc-4.5-0moz2/bin/gcc
-CXX=/tools/gcc-4.5-0moz2/bin/g++
+. $topsrcdir/build/unix/mozconfig.linux
+
--- a/browser/config/mozconfigs/linux32/nightly
+++ b/browser/config/mozconfigs/linux32/nightly
@@ -1,17 +1,17 @@
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-codesighs
 
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
 
-CC=/tools/gcc-4.5-0moz2/bin/gcc
-CXX=/tools/gcc-4.5-0moz2/bin/g++
+. $topsrcdir/build/unix/mozconfig.linux
+
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 
--- a/browser/config/mozconfigs/linux32/qt
+++ b/browser/config/mozconfigs/linux32/qt
@@ -1,13 +1,13 @@
 ac_add_options --enable-update-packaging
 ac_add_options --enable-codesighs
 
-CC=/tools/gcc-4.5-0moz2/bin/gcc
-CXX=/tools/gcc-4.5-0moz2/bin/g++
+. $topsrcdir/build/unix/mozconfig.linux
+
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 # PGO
 mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'
--- a/browser/config/mozconfigs/linux32/release
+++ b/browser/config/mozconfigs/linux32/release
@@ -1,14 +1,14 @@
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-official-branding
 
-CC=/tools/gcc-4.5-0moz2/bin/gcc
-CXX=/tools/gcc-4.5-0moz2/bin/g++
+. $topsrcdir/build/unix/mozconfig.linux
+
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # PGO
 mk_add_options MOZ_PGO=1
 mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'
 
 # Needed to enable breakpad in application.ini
--- a/browser/config/mozconfigs/linux32/rpm
+++ b/browser/config/mozconfigs/linux32/rpm
@@ -4,18 +4,18 @@ ac_add_options --enable-codesighs
 # Options for rpm versions of mozconfigs
 PREFIX=/usr
 LIBDIR=${PREFIX}/lib
 ac_add_options --with-app-name=mozilla-nightly
 ac_add_options --disable-updater
 ac_add_options --prefix=$PREFIX
 ac_add_options --libdir=$LIBDIR
 
-CC=/tools/gcc-4.5-0moz2/bin/gcc
-CXX=/tools/gcc-4.5-0moz2/bin/g++
+. $topsrcdir/build/unix/mozconfig.linux
+
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 
--- a/browser/config/mozconfigs/linux64/debug
+++ b/browser/config/mozconfigs/linux64/debug
@@ -1,13 +1,13 @@
 ac_add_options --enable-debug
 ac_add_options --enable-trace-malloc
 
-CC=/tools/gcc-4.5-0moz2/bin/gcc
-CXX=/tools/gcc-4.5-0moz2/bin/g++
+. $topsrcdir/build/unix/mozconfig.linux
+
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 # Enable parallel compiling
 mk_add_options MOZ_MAKE_FLAGS="-j4"
--- a/browser/config/mozconfigs/linux64/l10n-mozconfig
+++ b/browser/config/mozconfigs/linux64/l10n-mozconfig
@@ -1,7 +1,7 @@
 ac_add_options --with-l10n-base=../../l10n-central
 ac_add_options --enable-official-branding
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 
-CC=/tools/gcc-4.5-0moz2/bin/gcc
-CXX=/tools/gcc-4.5-0moz2/bin/g++
+. $topsrcdir/build/unix/mozconfig.linux
+
--- a/browser/config/mozconfigs/linux64/nightly
+++ b/browser/config/mozconfigs/linux64/nightly
@@ -1,17 +1,17 @@
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-codesighs
 
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
 
-CC=/tools/gcc-4.5-0moz2/bin/gcc
-CXX=/tools/gcc-4.5-0moz2/bin/g++
+. $topsrcdir/build/unix/mozconfig.linux
+
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 
--- a/browser/config/mozconfigs/linux64/release
+++ b/browser/config/mozconfigs/linux64/release
@@ -1,14 +1,14 @@
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-official-branding
 
-CC=/tools/gcc-4.5-0moz2/bin/gcc
-CXX=/tools/gcc-4.5-0moz2/bin/g++
+. $topsrcdir/build/unix/mozconfig.linux
+
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # PGO
 mk_add_options MOZ_PGO=1
 mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'
 
 # Needed to enable breakpad in application.ini
--- a/browser/config/mozconfigs/linux64/rpm
+++ b/browser/config/mozconfigs/linux64/rpm
@@ -4,18 +4,18 @@ ac_add_options --enable-codesighs
 # Options for rpm versions of mozconfigs
 PREFIX=/usr
 LIBDIR=${PREFIX}/lib64
 ac_add_options --with-app-name=mozilla-nightly
 ac_add_options --disable-updater
 ac_add_options --prefix=$PREFIX
 ac_add_options --libdir=$LIBDIR
 
-CC=/tools/gcc-4.5-0moz2/bin/gcc
-CXX=/tools/gcc-4.5-0moz2/bin/g++
+. $topsrcdir/build/unix/mozconfig.linux
+
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -143,16 +143,17 @@
 @BINPATH@/components/dom_geolocation.xpt
 @BINPATH@/components/dom_notification.xpt
 @BINPATH@/components/dom_html.xpt
 @BINPATH@/components/dom_indexeddb.xpt
 @BINPATH@/components/dom_offline.xpt
 @BINPATH@/components/dom_json.xpt
 @BINPATH@/components/dom_range.xpt
 @BINPATH@/components/dom_sidebar.xpt
+@BINPATH@/components/dom_sms.xpt
 @BINPATH@/components/dom_storage.xpt
 @BINPATH@/components/dom_stylesheets.xpt
 @BINPATH@/components/dom_threads.xpt
 @BINPATH@/components/dom_traversal.xpt
 @BINPATH@/components/dom_xbl.xpt
 @BINPATH@/components/dom_xpath.xpt
 @BINPATH@/components/dom_xul.xpt
 @BINPATH@/components/dom_loadsave.xpt
@@ -351,16 +352,18 @@
 @BINPATH@/components/satchel.manifest
 @BINPATH@/components/nsFormAutoComplete.js
 @BINPATH@/components/nsFormHistory.js
 @BINPATH@/components/nsInputListAutoComplete.js
 @BINPATH@/components/contentSecurityPolicy.manifest
 @BINPATH@/components/contentSecurityPolicy.js
 @BINPATH@/components/contentAreaDropListener.manifest
 @BINPATH@/components/contentAreaDropListener.js
+@BINPATH@/components/BrowserProfileMigrators.manifest
+@BINPATH@/components/ChromeProfileMigrator.js
 #ifdef XP_MACOSX
 @BINPATH@/components/libalerts_s.dylib
 #endif
 #ifdef MOZ_ENABLE_DBUS
 @BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
 #endif
 @BINPATH@/components/nsINIProcessor.manifest
 @BINPATH@/components/nsINIProcessor.js
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -309,16 +309,17 @@ searchplugins/answers.png
 searchplugins/answers.src
 searchplugins/answers.src
 searchplugins/atlas-sk.gif
 searchplugins/atlas-sk.png
 searchplugins/atlas-sk.src
 searchplugins/baidu.gif
 searchplugins/baidu.png
 searchplugins/baidu.src
+searchplugins/bluu.xml
 searchplugins/bok-NO.gif
 searchplugins/bok-NO.png
 searchplugins/bok-NO.src
 searchplugins/bolcom-nl.gif
 searchplugins/bolcom-nl.png
 searchplugins/bolcom-nl.src
 searchplugins/bookplus-fi.gif
 searchplugins/bookplus-fi.png
--- a/browser/locales/en-US/chrome/browser/migration/migration.dtd
+++ b/browser/locales/en-US/chrome/browser/migration/migration.dtd
@@ -10,16 +10,18 @@
 <!ENTITY importFromNothing.label        "Don't import anything">
 <!ENTITY importFromNothing.accesskey    "D">
 <!ENTITY importFromSeamonkey.label      "Netscape 6, 7 or Mozilla 1.x">
 <!ENTITY importFromSeamonkey.accesskey  "N">
 <!ENTITY importFromOpera.label          "Opera">
 <!ENTITY importFromOpera.accesskey      "O">
 <!ENTITY importFromSafari.label         "Safari">
 <!ENTITY importFromSafari.accesskey     "S">
+<!ENTITY importFromChrome.label         "Chrome">
+<!ENTITY importFromChrome.accesskey     "C">
 <!ENTITY importFromHTMLFile.label       "From an HTML File">
 <!ENTITY importFromHTMLFile.accesskey   "F">
 
 <!ENTITY noMigrationSources.label       "No programs that contain bookmarks, history or password data could be found.">
 
 <!ENTITY importSource.title             "Import Settings and Data">
 <!ENTITY importItems.title              "Items to Import">
 <!ENTITY importItems.label              "Select which items to import:">
--- a/browser/locales/en-US/chrome/browser/migration/migration.properties
+++ b/browser/locales/en-US/chrome/browser/migration/migration.properties
@@ -1,54 +1,62 @@
 profileName_format=%S %S
 
 # Browser Specific
 sourceNameIE=Internet Explorer
 sourceNameSeamonkey=Netscape 6/7/Mozilla
 sourceNameOpera=Opera
 sourceNameSafari=Safari
+sourceNameChrome=Google Chrome
 
 importedBookmarksFolder=From %S
 importedSearchURLsFolder=Keyword Searches (From %S)
 importedSearchURLsTitle=Search on %S
 importedSearchUrlDesc=Type "%S <search query>" in the Location Bar to perform a search on %S.
 
 importedSeamonkeyBookmarksTitle=From Netscape 6/7/Mozilla
 importedSafariBookmarks=From Safari
 importedOperaHotlistTitle=From Opera
 importedOperaSearchUrls=Keyword Searches (From Opera)
 
 # Import Sources
 1_ie=Internet Options
 1_opera=Preferences
 1_seamonkey=Preferences
 1_safari=Preferences
+1_chrome=Preferences
 
 2_ie=Cookies
 2_opera=Cookies
 2_seamonkey=Cookies
 2_safari=Cookies
+2_chrome=Cookies
 
 4_ie=Browsing History
 4_opera=Browsing History
 4_seamonkey=Browsing History
 4_safari=Browsing History
+4_chrome=Browsing History
 
 8_ie=Saved Form History
 8_opera=Saved Form History
 8_seamonkey=Saved Form History
 8_safari=Saved Form History
+8_chrome=Saved Form History
 
 16_ie=Saved Passwords
 16_opera=Saved Passwords
 16_seamonkey=Saved Passwords
 16_safari=Saved Passwords
+16_chrome=Saved Passwords
 
 32_ie=Favorites
 32_opera=Bookmarks
 32_seamonkey=Bookmarks
 32_safari=Bookmarks
+32_chrome=Bookmarks
 
 64_ie=Other Data
 64_opera=Other Data
 64_seamonkey=Other Data
 64_safari=Other Data
+64_chrome=Other Data
 
--- a/browser/themes/gnomestripe/browser.css
+++ b/browser/themes/gnomestripe/browser.css
@@ -217,17 +217,17 @@ menuitem.bookmark-item {
   list-style-image: url("chrome://browser/skin/places/livemark-item.png");
 }
 
 .bookmark-item[container][query] {
   list-style-image: url("chrome://browser/skin/places/query.png");
 }
 
 .bookmark-item[query][tagContainer] {
-  list-style-image: url("chrome://mozapps/skin/places/tagContainerIcon.png");
+  list-style-image: url("chrome://browser/skin/places/tag.png");
 }
 
 .bookmark-item[query][dayContainer] {
   list-style-image: url("chrome://browser/skin/places/calendar.png");
 }
 
 .bookmark-item[query][hostContainer] {
   list-style-image: url("moz-icon://stock/gtk-directory?size=menu");
deleted file mode 100644
index a788fffb00e59e3fff6931ad34cbc12a59f34254..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index f8536a4e1f9301b9d1304e575d17214325f9652f..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index a788fffb00e59e3fff6931ad34cbc12a59f34254..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index f8536a4e1f9301b9d1304e575d17214325f9652f..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/gnomestripe/jar.mn
+++ b/browser/themes/gnomestripe/jar.mn
@@ -34,20 +34,20 @@ browser.jar:
   skin/classic/browser/Secure.png
   skin/classic/browser/Security-broken.png
   skin/classic/browser/setDesktopBackground.css
   skin/classic/browser/Toolbar.png
   skin/classic/browser/Toolbar-small.png
   skin/classic/browser/urlbar-arrow.png
   skin/classic/browser/feeds/feedIcon.png             (feeds/feedIcon.png)
   skin/classic/browser/feeds/feedIcon16.png           (feeds/feedIcon16.png)
-  skin/classic/browser/feeds/videoFeedIcon.png        (feeds/videoFeedIcon.png)
-  skin/classic/browser/feeds/videoFeedIcon16.png      (feeds/videoFeedIcon16.png)
-  skin/classic/browser/feeds/audioFeedIcon.png        (feeds/audioFeedIcon.png)
-  skin/classic/browser/feeds/audioFeedIcon16.png      (feeds/audioFeedIcon16.png)
+  skin/classic/browser/feeds/videoFeedIcon.png        (feeds/feedIcon.png)
+  skin/classic/browser/feeds/videoFeedIcon16.png      (feeds/feedIcon16.png)
+  skin/classic/browser/feeds/audioFeedIcon.png        (feeds/feedIcon.png)
+  skin/classic/browser/feeds/audioFeedIcon16.png      (feeds/feedIcon16.png)
   skin/classic/browser/feeds/subscribe.css            (feeds/subscribe.css)
   skin/classic/browser/feeds/subscribe-ui.css         (feeds/subscribe-ui.css)
   skin/classic/browser/places/bookmarksMenu.png       (places/bookmarksMenu.png)
   skin/classic/browser/places/bookmarksToolbar.png    (places/bookmarksToolbar.png)
   skin/classic/browser/places/calendar.png            (places/calendar.png)
 * skin/classic/browser/places/editBookmarkOverlay.css (places/editBookmarkOverlay.css)
   skin/classic/browser/places/livemark-item.png       (places/livemark-item.png)
   skin/classic/browser/places/pageStarred.png         (places/pageStarred.png)
--- a/browser/themes/gnomestripe/places/places.css
+++ b/browser/themes/gnomestripe/places/places.css
@@ -72,17 +72,17 @@ treechildren::-moz-tree-image(title, que
 
 treechildren::-moz-tree-image(query, OrganizerQuery_Downloads) {
   list-style-image: url("chrome://browser/skin/places/downloads.png");
   -moz-image-region: auto;
 }
 
 treechildren::-moz-tree-image(title, query, tagContainer),
 treechildren::-moz-tree-image(query, OrganizerQuery_Tags) {
-  list-style-image: url("chrome://mozapps/skin/places/tagContainerIcon.png");
+  list-style-image: url("chrome://browser/skin/places/tag.png");
 }
 
 /* calendar icon for folders grouping items by date */
 treechildren::-moz-tree-image(title, query, dayContainer) {
   list-style-image: url("chrome://browser/skin/places/calendar.png");
 }
 
 treechildren::-moz-tree-image(title, query, hostContainer) {
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -83,16 +83,27 @@
   border-top: 1px solid rgba(0,0,0,0.65);
 }
 
 #navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
   -moz-box-align: center;
   padding: 2px 4px;
 }
 
+/* Because of -moz-box-align: center above, separators will be invisible unless
+   we set their min-height. See bug 583510 for more information. */
+toolbarseparator {
+  min-height: 22px;
+}
+
+/* We need more height when toolbar buttons show both icon and text. */
+toolbar[mode="full"] toolbarseparator {
+  min-height: 36px;
+}
+
 #nav-bar {
   padding-bottom: 4px !important;
 }
 
 #PersonalToolbar {
   -moz-appearance: none;
   margin-top: -2px; /* overlay the bottom border of the toolbar above us */
   padding-top: 1px !important;
@@ -226,17 +237,17 @@ toolbarbutton.bookmark-item > menupopup 
   list-style-image: url("chrome://browser/skin/page-livemarks.png");
 }
 
 .bookmark-item[query] {
   list-style-image: url("chrome://browser/skin/places/query.png");
 }
 
 .bookmark-item[query][tagContainer] {
-  list-style-image: url("chrome://mozapps/skin/places/tagContainerIcon.png");
+  list-style-image: url("chrome://browser/skin/places/tag.png");
 }
 
 .bookmark-item[query][dayContainer] {
   list-style-image: url("chrome://browser/skin/places/history.png");
 }
 
 .bookmark-item[query][hostContainer] {
   list-style-image: url("chrome://global/skin/tree/folder.png");
@@ -1897,16 +1908,17 @@ toolbarbutton.chevron > .toolbarbutton-m
   box-shadow: @focusRingShadow@;
 }
 
 .tabbrowser-tab:not([selected="true"]):not(:hover):not(:-moz-lwtheme) {
   color: #222;
 }
 
 .tabbrowser-tab[selected="true"] {
+  color: #000;
   z-index: 1;
   position: relative;
 }
 
 .tabbrowser-tab:-moz-lwtheme {
   color: inherit;
   text-shadow: inherit;
 }
deleted file mode 100644
index 236b5f82106ed4e9f74eff40a29ee36701a894c2..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index a489de3bf858b6ea84d1470c17ab157f50adc01d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 236b5f82106ed4e9f74eff40a29ee36701a894c2..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index a489de3bf858b6ea84d1470c17ab157f50adc01d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/pinstripe/jar.mn
+++ b/browser/themes/pinstripe/jar.mn
@@ -46,20 +46,20 @@ browser.jar:
   skin/classic/browser/toolbarbutton-dropmarker.png
   skin/classic/browser/urlbar-history-dropmarker.png
   skin/classic/browser/urlbar-arrow.png
   skin/classic/browser/urlbar-popup-blocked.png
   skin/classic/browser/feeds/subscribe.css                  (feeds/subscribe.css)
   skin/classic/browser/feeds/subscribe-ui.css               (feeds/subscribe-ui.css)
   skin/classic/browser/feeds/feedIcon.png                   (feeds/feedIcon.png)
   skin/classic/browser/feeds/feedIcon16.png                 (feeds/feedIcon16.png)
-  skin/classic/browser/feeds/videoFeedIcon.png              (feeds/videoFeedIcon.png)
-  skin/classic/browser/feeds/videoFeedIcon16.png            (feeds/videoFeedIcon16.png)
-  skin/classic/browser/feeds/audioFeedIcon.png              (feeds/audioFeedIcon.png)
-  skin/classic/browser/feeds/audioFeedIcon16.png            (feeds/audioFeedIcon16.png)
+  skin/classic/browser/feeds/videoFeedIcon.png              (feeds/feedIcon.png)
+  skin/classic/browser/feeds/videoFeedIcon16.png            (feeds/feedIcon16.png)
+  skin/classic/browser/feeds/audioFeedIcon.png              (feeds/feedIcon.png)
+  skin/classic/browser/feeds/audioFeedIcon16.png            (feeds/feedIcon16.png)
   skin/classic/browser/setDesktopBackground.css
   skin/classic/browser/inspector.css
   skin/classic/browser/monitor.png
   skin/classic/browser/monitor_16-10.png
   skin/classic/browser/places/allBookmarks.png              (places/allBookmarks.png)
 * skin/classic/browser/places/places.css                    (places/places.css)
 * skin/classic/browser/places/organizer.css                 (places/organizer.css)
   skin/classic/browser/places/query.png                     (places/query.png)
--- a/browser/themes/pinstripe/places/places.css
+++ b/browser/themes/pinstripe/places/places.css
@@ -1,18 +1,12 @@
 %include ../shared.inc
 
 /* Sidebars */
 
-.sidebar-placesTree {
-  background-color: transparent !important;
-  -moz-appearance: none !important;
-  border: none !important;
-}
-
 #bookmarksPanel, 
 #history-panel,
 #sidebar-search-container {
   -moz-appearance: none !important;
   background-color: transparent !important;
   border-top: none !important;
 }
 
@@ -145,17 +139,17 @@ treechildren::-moz-tree-image(query) {
 }
 
 treechildren::-moz-tree-image(query, OrganizerQuery_Downloads) {
   list-style-image: url("chrome://browser/skin/places/downloads.png");
 }
 
 treechildren::-moz-tree-image(title, query, tagContainer),
 treechildren::-moz-tree-image(query, OrganizerQuery_Tags) {
-  list-style-image: url("chrome://mozapps/skin/places/tagContainerIcon.png");
+  list-style-image: url("chrome://browser/skin/places/tag.png");
 }
 
 /* calendar icon for folders grouping items by date */
 treechildren::-moz-tree-image(title, query, dayContainer) {
   list-style-image: url("chrome://browser/skin/places/history.png");
 }
 
 treechildren::-moz-tree-image(title, query, hostContainer) {
deleted file mode 100644
index ff2ecc2f351ef37d250264aa2bb273de08518165..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -616,17 +616,17 @@ menuitem.bookmark-item {
 }
 
 .bookmark-item[container][query] {
   list-style-image: url("chrome://browser/skin/places/query.png");
   -moz-image-region: auto;
 }
 
 .bookmark-item[query][tagContainer] {
-  list-style-image: url("chrome://mozapps/skin/places/tagContainerIcon.png");
+  list-style-image: url("chrome://browser/skin/places/tag.png");
   -moz-image-region: auto;
 }
 
 .bookmark-item[query][dayContainer] {
   list-style-image: url("chrome://browser/skin/places/calendar.png");
   -moz-image-region: auto;
 }
 
deleted file mode 100644
index b4d5994995f24adf40fe10f407c9644e802b140d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index e69bc4496139006ad20e34db308bfcc0cbc396c2..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 7c3aceb66f351208cf25ff02abe617cbb5e56456..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index d778807532bc0a1d47ac82370255600d503d66eb..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index b4d5994995f24adf40fe10f407c9644e802b140d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index e69bc4496139006ad20e34db308bfcc0cbc396c2..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 7c3aceb66f351208cf25ff02abe617cbb5e56456..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index d778807532bc0a1d47ac82370255600d503d66eb..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/winstripe/jar.mn
+++ b/browser/themes/winstripe/jar.mn
@@ -1,17 +1,17 @@
 browser.jar:
 % skin browser classic/1.0 %skin/classic/browser/ os=WINNT osversion<6
 % skin browser classic/1.0 %skin/classic/browser/ os!=WINNT
 # NOTE: If you add a new file here, you'll need to add it to the aero
 # section at the bottom of this file
         skin/classic/browser/sanitizeDialog.css                      (sanitizeDialog.css)
 *       skin/classic/browser/aboutPrivateBrowsing.css                (aboutPrivateBrowsing.css)
 *       skin/classic/browser/aboutSessionRestore.css                 (aboutSessionRestore.css)
-        skin/classic/browser/aboutSessionRestore-window-icon.png     (aboutSessionRestore-window-icon.png)
+        skin/classic/browser/aboutSessionRestore-window-icon.png     (preferences/application.png)
         skin/classic/browser/aboutCertError.css                      (aboutCertError.css)
 #ifdef MOZ_SERVICES_SYNC
         skin/classic/browser/aboutSyncTabs.css
 #endif
         skin/classic/browser/actionicon-tab.png
         skin/classic/browser/appmenu-icons.png
         skin/classic/browser/appmenu-dropmarker.png
 *       skin/classic/browser/browser.css                             (browser.css)
@@ -46,20 +46,20 @@ browser.jar:
         skin/classic/browser/menu-forward.png                        (menu-forward.png)
         skin/classic/browser/monitor.png
         skin/classic/browser/monitor_16-10.png
         skin/classic/browser/urlbar-arrow.png
         skin/classic/browser/urlbar-popup-blocked.png
         skin/classic/browser/urlbar-history-dropmarker.png
         skin/classic/browser/feeds/feedIcon.png                      (feeds/feedIcon.png)
         skin/classic/browser/feeds/feedIcon16.png                    (feeds/feedIcon16.png)
-        skin/classic/browser/feeds/audioFeedIcon.png                 (feeds/audioFeedIcon.png)
-        skin/classic/browser/feeds/audioFeedIcon16.png               (feeds/audioFeedIcon16.png)
-        skin/classic/browser/feeds/videoFeedIcon.png                 (feeds/videoFeedIcon.png)
-        skin/classic/browser/feeds/videoFeedIcon16.png               (feeds/videoFeedIcon16.png)
+        skin/classic/browser/feeds/audioFeedIcon.png                 (feeds/feedIcon.png)
+        skin/classic/browser/feeds/audioFeedIcon16.png               (feeds/feedIcon16.png)
+        skin/classic/browser/feeds/videoFeedIcon.png                 (feeds/feedIcon.png)
+        skin/classic/browser/feeds/videoFeedIcon16.png               (feeds/feedIcon16.png)
         skin/classic/browser/feeds/subscribe.css                     (feeds/subscribe.css)
         skin/classic/browser/feeds/subscribe-ui.css                  (feeds/subscribe-ui.css)
         skin/classic/browser/inspector.css
         skin/classic/browser/places/places.css                       (places/places.css)
 *       skin/classic/browser/places/organizer.css                    (places/organizer.css)
         skin/classic/browser/places/bookmark.png                     (places/bookmark.png)
         skin/classic/browser/places/editBookmark.png                 (places/editBookmark.png)
         skin/classic/browser/places/query.png                        (places/query.png)
@@ -199,20 +199,20 @@ browser.jar:
         skin/classic/aero/browser/menu-forward.png                   (menu-forward-aero.png)
         skin/classic/aero/browser/monitor.png
         skin/classic/aero/browser/monitor_16-10.png
         skin/classic/aero/browser/urlbar-arrow.png
         skin/classic/aero/browser/urlbar-popup-blocked.png
         skin/classic/aero/browser/urlbar-history-dropmarker.png
         skin/classic/aero/browser/feeds/feedIcon.png                 (feeds/feedIcon-aero.png)
         skin/classic/aero/browser/feeds/feedIcon16.png               (feeds/feedIcon16-aero.png)
-        skin/classic/aero/browser/feeds/audioFeedIcon.png            (feeds/audioFeedIcon-aero.png)
-        skin/classic/aero/browser/feeds/audioFeedIcon16.png          (feeds/audioFeedIcon16-aero.png)
-        skin/classic/aero/browser/feeds/videoFeedIcon.png            (feeds/videoFeedIcon-aero.png)
-        skin/classic/aero/browser/feeds/videoFeedIcon16.png          (feeds/videoFeedIcon16-aero.png)
+        skin/classic/aero/browser/feeds/audioFeedIcon.png            (feeds/feedIcon-aero.png)
+        skin/classic/aero/browser/feeds/audioFeedIcon16.png          (feeds/feedIcon16-aero.png)
+        skin/classic/aero/browser/feeds/videoFeedIcon.png            (feeds/feedIcon-aero.png)
+        skin/classic/aero/browser/feeds/videoFeedIcon16.png          (feeds/feedIcon16-aero.png)
         skin/classic/aero/browser/feeds/subscribe.css                (feeds/subscribe.css)
         skin/classic/aero/browser/feeds/subscribe-ui.css             (feeds/subscribe-ui.css)
         skin/classic/aero/browser/inspector.css
 *       skin/classic/aero/browser/places/places.css                  (places/places-aero.css)
 *       skin/classic/aero/browser/places/organizer.css               (places/organizer-aero.css)
         skin/classic/aero/browser/places/bookmark.png                (places/bookmark.png)
         skin/classic/aero/browser/places/editBookmark.png            (places/editBookmark.png)
         skin/classic/aero/browser/places/query.png                   (places/query-aero.png)
@@ -223,26 +223,25 @@ browser.jar:
         skin/classic/aero/browser/places/editBookmarkOverlay.css     (places/editBookmarkOverlay.css)
         skin/classic/aero/browser/places/libraryToolbar.png          (places/libraryToolbar-aero.png)
         skin/classic/aero/browser/places/starred48.png               (places/starred48-aero.png)
         skin/classic/aero/browser/places/unstarred48.png             (places/unstarred48.png)
         skin/classic/aero/browser/places/tag.png                     (places/tag-aero.png)
         skin/classic/aero/browser/places/history.png                 (places/history-aero.png)
         skin/classic/aero/browser/places/allBookmarks.png            (places/allBookmarks-aero.png)
         skin/classic/aero/browser/places/unsortedBookmarks.png       (places/unsortedBookmarks-aero.png)
-        skin/classic/aero/browser/places/searching_16.png            (places/searching_16-aero.png)
+        skin/classic/aero/browser/places/searching_16.png            (places/searching_16.png)
         skin/classic/aero/browser/places/downloads.png               (places/downloads.png)
         skin/classic/aero/browser/preferences/alwaysAsk.png          (preferences/alwaysAsk-aero.png)
         skin/classic/aero/browser/preferences/application.png        (preferences/application-aero.png)
         skin/classic/aero/browser/preferences/mail.png               (preferences/mail-aero.png)
         skin/classic/aero/browser/preferences/Options.png            (preferences/Options-aero.png)
 #ifdef MOZ_SERVICES_SYNC
         skin/classic/aero/browser/preferences/Options-sync.png       (preferences/Options-sync.png)
 #endif
-        skin/classic/aero/browser/preferences/plugin.png             (preferences/plugin-aero.png)
         skin/classic/aero/browser/preferences/saveFile.png           (preferences/saveFile-aero.png)
 *       skin/classic/aero/browser/preferences/preferences.css        (preferences/preferences.css)
         skin/classic/aero/browser/preferences/applications.css       (preferences/applications.css)
         skin/classic/aero/browser/preferences/aboutPermissions.css   (preferences/aboutPermissions.css)
         skin/classic/aero/browser/tabbrowser/alltabs.png             (tabbrowser/alltabs.png)
         skin/classic/aero/browser/tabbrowser/newtab.png              (tabbrowser/newtab.png)
         skin/classic/aero/browser/tabbrowser/newtab-inverted.png     (tabbrowser/newtab-inverted.png)
         skin/classic/aero/browser/tabbrowser/connecting.png          (tabbrowser/connecting.png)
--- a/browser/themes/winstripe/places/places.css
+++ b/browser/themes/winstripe/places/places.css
@@ -76,17 +76,17 @@ treechildren::-moz-tree-image(container,
 /* query-nodes should be styled even if they're not expandable */
 treechildren::-moz-tree-image(title, query) {
   list-style-image: url("chrome://browser/skin/places/query.png");
   -moz-image-region: auto;
 }
 
 treechildren::-moz-tree-image(title, query, tagContainer),
 treechildren::-moz-tree-image(query, OrganizerQuery_Tags) {
-  list-style-image: url("chrome://mozapps/skin/places/tagContainerIcon.png");
+  list-style-image: url("chrome://browser/skin/places/tag.png");
   -moz-image-region: auto;
 }
 
 treechildren::-moz-tree-image(query, OrganizerQuery_Downloads) {
   list-style-image: url("chrome://browser/skin/places/downloads.png");
   -moz-image-region: auto;
 }
 
deleted file mode 100644
index 2f97e742a3f0855c97a356c9f699b3bda3ac7c7b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 5d796cc4c57dd3da1669fd4e51ba8d954ed4c866..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
new file mode 100644
--- /dev/null
+++ b/build/autoconf/mozcommonheader.m4
@@ -0,0 +1,41 @@
+dnl ***** BEGIN LICENSE BLOCK *****
+dnl Version: MPL 1.1/GPL 2.0/LGPL 2.1
+dnl
+dnl The contents of this file are subject to the Mozilla Public License Version
+dnl 1.1 (the "License"); you may not use this file except in compliance with
+dnl the License. You may obtain a copy of the License at
+dnl http://www.mozilla.org/MPL/
+dnl
+dnl Software distributed under the License is distributed on an "AS IS" basis,
+dnl WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+dnl for the specific language governing rights and limitations under the
+dnl License.
+dnl
+dnl The Original Code is mozilla.org code.
+dnl
+dnl The Initial Developer of the Original Code is the
+dnl Mozilla Foundation <http://www.mozilla.org>
+dnl
+dnl Portions created by the Initial Developer are Copyright (C) 2009
+dnl the Initial Developer. All Rights Reserved.
+dnl
+dnl
+dnl Alternatively, the contents of this file may be used under the terms of
+dnl either of the GNU General Public License Version 2 or later (the "GPL"),
+dnl or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+dnl in which case the provisions of the GPL or the LGPL are applicable instead
+dnl of those above. If you wish to allow use of your version of this file only
+dnl under the terms of either the GPL or the LGPL, and not to allow others to
+dnl use your version of this file under the terms of the MPL, indicate your
+dnl decision by deleting the provisions above and replace them with the notice
+dnl and other provisions required by the GPL or the LGPL. If you do not delete
+dnl the provisions above, a recipient may use your version of this file under
+dnl the terms of any one of the MPL, the GPL or the LGPL.
+dnl
+dnl ***** END LICENSE BLOCK *****
+
+AC_DEFUN(MOZ_CHECK_COMMON_HEADERS,
+	MOZ_CHECK_HEADERS(sys/byteorder.h compat.h getopt.h sys/bitypes.h \
+        memory.h unistd.h gnu/libc-version.h nl_types.h malloc.h \
+        X11/XKBlib.h io.h cpuid.h)
+)
--- a/build/autoconf/mozheader.m4
+++ b/build/autoconf/mozheader.m4
@@ -31,35 +31,36 @@ dnl under the terms of either the GPL or
 dnl use your version of this file under the terms of the MPL, indicate your
 dnl decision by deleting the provisions above and replace them with the notice
 dnl and other provisions required by the GPL or the LGPL. If you do not delete
 dnl the provisions above, a recipient may use your version of this file under
 dnl the terms of any one of the MPL, the GPL or the LGPL.
 dnl
 dnl ***** END LICENSE BLOCK *****
 
-dnl MOZ_CHECK_HEADER(HEADER-FILE, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+dnl MOZ_CHECK_HEADER(HEADER-FILE, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, INCLUDES]]])
 AC_DEFUN([MOZ_CHECK_HEADER],
 [ dnl Do the transliteration at runtime so arg 1 can be a shell variable.
   ac_safe=`echo "$1" | sed 'y%./+-%__p_%'`
   AC_MSG_CHECKING([for $1])
   AC_CACHE_VAL(ac_cv_header_$ac_safe,
- [ AC_TRY_COMPILE([#include <$1>], ,
+ [ AC_TRY_COMPILE([$4
+#include <$1>], ,
                   eval "ac_cv_header_$ac_safe=yes",
                   eval "ac_cv_header_$ac_safe=no") ])
   if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
     AC_MSG_RESULT(yes)
     ifelse([$2], , :, [$2])
   else
     AC_MSG_RESULT(no)
     ifelse([$3], , , [$3])
   fi
 ])
 
-dnl MOZ_CHECK_HEADERS(HEADER-FILE... [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+dnl MOZ_CHECK_HEADERS(HEADER-FILE... [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, INCLUDES]]])
 AC_DEFUN([MOZ_CHECK_HEADERS],
 [ for ac_hdr in $1
   do
     MOZ_CHECK_HEADER($ac_hdr,
                      [ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
-                       AC_DEFINE_UNQUOTED($ac_tr_hdr) $2], $3)
+                       AC_DEFINE_UNQUOTED($ac_tr_hdr) $2], $3, [$4])
   done
 ])
new file mode 100644
--- /dev/null
+++ b/build/unix/mozconfig.linux
@@ -0,0 +1,2 @@
+CC=/tools/gcc-4.5-0moz2/bin/gcc
+CXX=/tools/gcc-4.5-0moz2/bin/g++
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -114,17 +114,16 @@ MOZ_MEMORY      = @MOZ_MEMORY@
 MOZ_PROFILING   = @MOZ_PROFILING@
 MOZ_ENABLE_PROFILER_SPS = @MOZ_ENABLE_PROFILER_SPS@
 MOZ_JPROF       = @MOZ_JPROF@
 MOZ_SHARK       = @MOZ_SHARK@
 MOZ_CALLGRIND   = @MOZ_CALLGRIND@
 MOZ_VTUNE       = @MOZ_VTUNE@
 MOZ_ETW         = @MOZ_ETW@
 MOZ_TRACE_JSCALLS = @MOZ_TRACE_JSCALLS@
-MOZ_TRACEVIS    = @MOZ_TRACEVIS@
 DEHYDRA_PATH    = @DEHYDRA_PATH@
 
 NS_TRACE_MALLOC = @NS_TRACE_MALLOC@
 USE_ELF_DYNSTR_GC = @USE_ELF_DYNSTR_GC@
 USE_ELF_HACK = @USE_ELF_HACK@
 STDCXX_COMPAT = @STDCXX_COMPAT@
 MOZ_LIBSTDCXX_TARGET_VERSION=@MOZ_LIBSTDCXX_TARGET_VERSION@
 MOZ_LIBSTDCXX_HOST_VERSION=@MOZ_LIBSTDCXX_HOST_VERSION@
--- a/configure.in
+++ b/configure.in
@@ -3404,22 +3404,17 @@ dnl Checks for header files.
 dnl ========================================================
 AC_HEADER_DIRENT
 case "$target_os" in
 freebsd*|openbsd*)
 # for stuff like -lXshm
     CPPFLAGS="${CPPFLAGS} ${X_CFLAGS}"
     ;;
 esac
-MOZ_CHECK_HEADERS(sys/byteorder.h compat.h getopt.h)
-MOZ_CHECK_HEADERS(sys/bitypes.h memory.h unistd.h)
-MOZ_CHECK_HEADERS(gnu/libc-version.h nl_types.h)
-MOZ_CHECK_HEADERS(malloc.h)
-MOZ_CHECK_HEADERS(X11/XKBlib.h)
-MOZ_CHECK_HEADERS(io.h)
+MOZ_CHECK_COMMON_HEADERS
 
 dnl These are all the places some variant of statfs can be hiding.
 MOZ_CHECK_HEADERS(sys/statvfs.h sys/statfs.h sys/vfs.h sys/mount.h)
 
 dnl Quota support
 MOZ_CHECK_HEADERS(sys/quota.h sys/sysmacros.h)
 MOZ_CHECK_HEADERS(linux/quota.h)
 
@@ -5931,22 +5926,21 @@ MOZ_ARG_DISABLE_BOOL(xtf,
 [  --disable-xtf           Disable XTF (pluggable xml tags) support],
     MOZ_XTF=,
     MOZ_XTF=1 )
 if test "$MOZ_XTF"; then
   AC_DEFINE(MOZ_XTF)
 fi
 
 dnl ========================================================
-dnl Pref extensions (autoconfig and system-pref)
+dnl Pref extensions (autoconfig)
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(pref-extensions,
 [  --disable-pref-extensions
-                          Disable pref extensions such as autoconfig and
-                          system-pref],
+                          Disable pref extensions such as autoconfig],
   MOZ_PREF_EXTENSIONS=,
   MOZ_PREF_EXTENSIONS=1 )
 
 dnl ========================================================
 dnl Searching of system directories for extensions.
 dnl Note: this switch is meant to be used for test builds
 dnl whose behavior should not depend on what happens to be
 dnl installed on the local machine.
@@ -7323,27 +7317,16 @@ MOZ_ARG_ENABLE_BOOL(trace-jscalls,
 [  --enable-trace-jscalls  Enable JS call enter/exit callback (default=no)],
     MOZ_TRACE_JSCALLS=1,
     MOZ_TRACE_JSCALLS= )
 if test -n "$MOZ_TRACE_JSCALLS"; then
     AC_DEFINE(MOZ_TRACE_JSCALLS)
 fi
 
 dnl ========================================================
-dnl = Use TraceVis
-dnl ========================================================
-MOZ_ARG_ENABLE_BOOL(tracevis,
-[  --enable-tracevis       Enable TraceVis tracing tool (default=no)],
-    MOZ_TRACEVIS=1,
-    MOZ_TRACEVIS= )
-if test -n "$MOZ_TRACEVIS"; then
-    AC_DEFINE(MOZ_TRACEVIS)
-fi
-
-dnl ========================================================
 dnl = Use incremental GC
 dnl ========================================================
 JSGC_INCREMENTAL=1
 MOZ_ARG_DISABLE_BOOL(gcincremental,
 [  --disable-gcincremental Disable incremental GC],
     JSGC_INCREMENTAL= )
 if test -n "$JSGC_INCREMENTAL"; then
     AC_DEFINE(JSGC_INCREMENTAL)
@@ -8757,18 +8740,18 @@ if test -n "$MOZ_WEBGL_GLX"; then
     fi
 fi # MOZ_WEBGL_GLX
 fi # COMPILE_ENVIRONMENT
 
 if test "$USE_FC_FREETYPE"; then
     if test "$COMPILE_ENVIRONMENT"; then
     	_SAVE_CPPFLAGS="$CPPFLAGS"
     	CPPFLAGS="$CPPFLAGS $FT2_CFLAGS $XCFLAGS"
-        AC_CHECK_HEADERS(fontconfig/fcfreetype.h, ,
-            [AC_MSG_ERROR(Can't find header fontconfig/fcfreetype.h.)])
+        MOZ_CHECK_HEADERS([fontconfig/fcfreetype.h], ,
+            [AC_MSG_ERROR(Can't find header fontconfig/fcfreetype.h.)], [#include <fontconfig/fontconfig.h>])
     	CPPFLAGS="$_SAVE_CPPFLAGS"
     else
         AC_DEFINE(HAVE_FONTCONFIG_FCFREETYPE_H)
     fi
 fi
 
 dnl Set various defines and substitutions
 dnl ========================================================
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1285,21 +1285,16 @@ public:
 #endif
     }
   }
   static void ReleaseWrapper(nsISupports* aScriptObjectHolder,
                              nsWrapperCache* aCache);
   static void TraceWrapper(nsWrapperCache* aCache, TraceCallback aCallback,
                            void *aClosure);
 
-  /**
-   * Convert nsIContent::IME_STATUS_* to nsIWidget::IME_STATUS_*
-   */
-  static PRUint32 GetWidgetStatusFromIMEStatus(PRUint32 aState);
-
   /*
    * Notify when the first XUL menu is opened and when the all XUL menus are
    * closed. At opening, aInstalling should be TRUE, otherwise, it should be
    * FALSE.
    */
   static void NotifyInstalledMenuKeyboardListener(bool aInstalling);
 
   /**
--- a/content/base/public/nsIAttribute.h
+++ b/content/base/public/nsIAttribute.h
@@ -41,18 +41,18 @@
 #define nsIAttribute_h___
 
 #include "nsINode.h"
 
 class nsDOMAttributeMap;
 class nsIContent;
 
 #define NS_IATTRIBUTE_IID  \
-{ 0xf809b623, 0x5b1e, 0x4121, \
-  { 0xb8, 0x9d, 0x19, 0x24, 0x7b, 0x70, 0x77, 0x08 } }
+{ 0x536167ae, 0x8a9c, 0x4712, \
+  { 0x8b, 0x61, 0x3, 0x43, 0xf6, 0xbc, 0x64, 0x75 } }
 
 class nsIAttribute : public nsINode
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IATTRIBUTE_IID)
 
   virtual void SetMap(nsDOMAttributeMap *aMap) = 0;
   
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -58,37 +58,42 @@ class nsTextFragment;
 class nsIDocShell;
 class nsIFrame;
 class nsISMILAttr;
 class nsIDOMCSSStyleDeclaration;
 
 namespace mozilla {
 namespace css {
 class StyleRule;
-}
-}
+} // namespace css
+namespace widget {
+struct IMEState;
+} // namespace widget
+} // namespace mozilla
 
 enum nsLinkState {
   eLinkState_Unknown    = 0,
   eLinkState_Unvisited  = 1,
   eLinkState_Visited    = 2,
   eLinkState_NotLink    = 3
 };
 
 // IID for the nsIContent interface
 #define NS_ICONTENT_IID \
-{ 0xb651e0a7, 0x1471, 0x49cc, \
-  { 0xb4, 0xe1, 0xc2, 0xca, 0x01, 0xfe, 0xb7, 0x80 } }
+{ 0xed40a3e5, 0xd7ed, 0x473e, \
+ { 0x85, 0xe3, 0x82, 0xc3, 0xf0, 0x41, 0xdb, 0x52 } }
 
 /**
  * A node of content in a document's content model. This interface
  * is supported by all content objects.
  */
 class nsIContent : public nsINode {
 public:
+  typedef mozilla::widget::IMEState IMEState;
+
 #ifdef MOZILLA_INTERNAL_API
   // If you're using the external API, the only thing you can know about
   // nsIContent is that it exists with an IID
 
   nsIContent(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsINode(aNodeInfo),
       mPrimaryFrame(nsnull)
   {
@@ -599,50 +604,28 @@ public:
                                 bool aIsTrustedEvent)
   {
   }
 
   /*
    * Get desired IME state for the content.
    *
    * @return The desired IME status for the content.
-   *         This is a combination of IME_STATUS_* flags,
-   *         controlling what happens to IME when the content takes focus.
-   *         If this is IME_STATUS_NONE, IME remains in its current state.
-   *         IME_STATUS_ENABLE and IME_STATUS_DISABLE must not be set
-   *         together; likewise IME_STATUS_OPEN and IME_STATUS_CLOSE must
-   *         not be set together.
-   *         If you return IME_STATUS_DISABLE, you should not set the
-   *         OPEN or CLOSE flag; that way, when IME is next enabled,
-   *         the previous OPEN/CLOSE state will be restored (unless the newly
-   *         focused content specifies the OPEN/CLOSE state by setting the OPEN
-   *         or CLOSE flag with the ENABLE flag).
-   *         IME_STATUS_PASSWORD should be returned only from password editor,
-   *         this value has a special meaning. It is used as alternative of
-   *         IME_STATUS_DISABLED.
-   *         IME_STATUS_PLUGIN should be returned only when plug-in has focus.
-   *         When a plug-in is focused content, we should send native events
-   *         directly. Because we don't process some native events, but they may
-   *         be needed by the plug-in.
+   *         This is a combination of an IME enabled value and
+   *         an IME open value of widget::IMEState.
+   *         If you return DISABLED, you should not set the OPEN and CLOSE
+   *         value.
+   *         PASSWORD should be returned only from password editor, this value
+   *         has a special meaning. It is used as alternative of DISABLED.
+   *         PLUGIN should be returned only when plug-in has focus.  When a
+   *         plug-in is focused content, we should send native events directly.
+   *         Because we don't process some native events, but they may be needed
+   *         by the plug-in.
    */
-  enum {
-    IME_STATUS_NONE     = 0x0000,
-    IME_STATUS_ENABLE   = 0x0001,
-    IME_STATUS_DISABLE  = 0x0002,
-    IME_STATUS_PASSWORD = 0x0004,
-    IME_STATUS_PLUGIN   = 0x0008,
-    IME_STATUS_OPEN     = 0x0010,
-    IME_STATUS_CLOSE    = 0x0020
-  };
-  enum {
-    IME_STATUS_MASK_ENABLED = IME_STATUS_ENABLE | IME_STATUS_DISABLE |
-                              IME_STATUS_PASSWORD | IME_STATUS_PLUGIN,
-    IME_STATUS_MASK_OPENED  = IME_STATUS_OPEN | IME_STATUS_CLOSE
-  };
-  virtual PRUint32 GetDesiredIMEState();
+  virtual IMEState GetDesiredIMEState();
 
   /**
    * Gets content node with the binding (or native code, possibly on the
    * frame) responsible for our construction (and existence).  Used by
    * anonymous content (both XBL-generated and native-anonymous).
    *
    * null for all explicit content (i.e., content reachable from the top
    * of its GetParent() chain via child lists).
--- a/content/base/public/nsIDOMFileReader.idl
+++ b/content/base/public/nsIDOMFileReader.idl
@@ -36,17 +36,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMEventListener;
 interface nsIDOMBlob;
 interface nsIDOMFileError;
 
-[scriptable, builtinclass, uuid(fc316500-87c4-411e-ab75-dd62468f4174)]
+[scriptable, builtinclass, uuid(d158de26-904e-4731-b42c-8b3a4d172703)]
 interface nsIDOMFileReader : nsIDOMEventTarget
 {
   [implicit_jscontext]
   void readAsArrayBuffer(in nsIDOMBlob filedata);
   void readAsBinaryString(in nsIDOMBlob filedata);
   void readAsText(in nsIDOMBlob filedata, [optional] in DOMString encoding);
   void readAsDataURL(in nsIDOMBlob file);
 
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -59,17 +59,17 @@
 #include "nsIVariant.h"
 #include "nsIObserver.h"
 #include "nsGkAtoms.h"
 #include "nsAutoPtr.h"
 #include "nsPIDOMWindow.h"
 #include "nsSMILAnimationController.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIDocumentEncoder.h"
-#include "nsIAnimationFrameListener.h"
+#include "nsIFrameRequestCallback.h"
 #include "nsEventStates.h"
 #include "nsIStructuredCloneContainer.h"
 #include "nsIBFCacheEntry.h"
 #include "nsDOMMemoryReporter.h"
 
 class nsIContent;
 class nsPresContext;
 class nsIPresShell;
@@ -119,18 +119,18 @@ class Loader;
 
 namespace dom {
 class Link;
 class Element;
 } // namespace dom
 } // namespace mozilla
 
 #define NS_IDOCUMENT_IID \
-{ 0x184e0a3c, 0x1899, 0x417d, \
-  { 0xbf, 0xf4, 0x5a, 0x15, 0xe6, 0xe8, 0xaa, 0x94 } }
+{ 0x3b78f6, 0x6dc5, 0x44c6, \
+  { 0xbc, 0x28, 0x60, 0x2a, 0xb2, 0x4f, 0xfb, 0x7b } }
 
 // Flag for AddStyleSheet().
 #define NS_STYLESHEET_FROM_CATALOG                (1 << 0)
 
 // Enum for requesting a particular type of document when creating a doc
 enum DocumentFlavor {
   DocumentFlavorLegacyGuess, // compat with old code until made HTML5-compliant
   DocumentFlavorHTML, // HTMLDocument with HTMLness bit set to true
@@ -1513,28 +1513,24 @@ public:
    * Lookup an image element using its associated ID, which is usually provided
    * by |-moz-element()|. Similar to GetElementById, with the difference that
    * elements set using mozSetImageElement have higher priority.
    * @param aId the ID associated the element we want to lookup
    * @return the element associated with |aId|
    */
   virtual Element* LookupImageElement(const nsAString& aElementId) = 0;
 
-  void ScheduleBeforePaintEvent(nsIAnimationFrameListener* aListener);
-  void BeforePaintEventFiring()
-  {
-    mHavePendingPaint = false;
-  }
+  void ScheduleFrameRequestCallback(nsIFrameRequestCallback* aCallback);
 
-  typedef nsTArray< nsCOMPtr<nsIAnimationFrameListener> > AnimationListenerList;
+  typedef nsTArray< nsCOMPtr<nsIFrameRequestCallback> > FrameRequestCallbackList;
   /**
-   * Put this documents animation frame listeners into the provided
+   * Put this document's frame request callbacks into the provided
    * list, and forget about them.
    */
-  void TakeAnimationFrameListeners(AnimationListenerList& aListeners);
+  void TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks);
 
   // This returns true when the document tree is being teared down.
   bool InUnlinkOrDeletion() { return mInUnlinkOrDeletion; }
 
   /*
    * Image Tracking
    *
    * Style and content images register their imgIRequests with their document
@@ -1741,19 +1737,16 @@ protected:
   bool mCreatingStaticClone;
 
   // True iff the document is being unlinked or deleted.
   bool mInUnlinkOrDeletion;
 
   // True if document has ever had script handling object.
   bool mHasHadScriptHandlingObject;
 
-  // True if we're waiting for a before-paint event.
-  bool mHavePendingPaint;
-
   // True if we're an SVG document being used as an image.
   bool mIsBeingUsedAsImage;
 
   // True is this document is synthetic : stand alone image, video, audio
   // file, etc.
   bool mIsSyntheticDocument;
 
   // True if this document has links whose state needs updating
@@ -1807,17 +1800,17 @@ protected:
   PRUint32 mExternalScriptsBeingEvaluated;
 
   // Weak reference to mScriptGlobalObject QI:d to nsPIDOMWindow,
   // updated on every set of mSecriptGlobalObject.
   nsPIDOMWindow *mWindow;
 
   nsCOMPtr<nsIDocumentEncoder> mCachedEncoder;
 
-  AnimationListenerList mAnimationFrameListeners;
+  FrameRequestCallbackList mFrameRequestCallbacks;
 
   // This object allows us to evict ourself from the back/forward cache.  The
   // pointer is non-null iff we're currently in the bfcache.
   nsIBFCacheEntry *mBFCacheEntry;
 
   // Our base target.
   nsString mBaseTarget;
 
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -283,18 +283,18 @@ private:
 // Categories of node properties
 // 0 is global.
 #define DOM_USER_DATA         1
 #define DOM_USER_DATA_HANDLER 2
 #define SMIL_MAPPED_ATTR_ANIMVAL 3
 
 // IID for the nsINode interface
 #define NS_INODE_IID \
-{ 0x20d16be2, 0x3c58, 0x4099, \
-  { 0xbf, 0xa6, 0xd0, 0xe7, 0x6b, 0xb1, 0x3d, 0xc5 } }
+{ 0xd026d280, 0x5b25, 0x41c0, \
+  { 0x92, 0xcf, 0x6, 0xf6, 0xf, 0xb, 0x9a, 0xfe } }
 
 /**
  * An internal interface that abstracts some DOMNode-related parts that both
  * nsIContent and nsIDocument share.  An instance of this interface has a list
  * of nsIContent children and provides access to them.
  */
 class nsINode : public nsIDOMEventTarget,
                 public nsWrapperCache
@@ -723,16 +723,17 @@ public:
     return mParent && mParent->IsElement() ? mParent : nsnull;
   }
 
   /**
    * See nsIDOMEventTarget
    */
   NS_DECL_NSIDOMEVENTTARGET
   using nsIDOMEventTarget::AddEventListener;
+  using nsIDOMEventTarget::AddSystemEventListener;
 
   /**
    * Adds a mutation observer to be notified when this node, or any of its
    * descendants, are modified. The node will hold a weak reference to the
    * observer, which means that it is the responsibility of the observer to
    * 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
--- a/content/base/public/nsIXMLHttpRequest.idl
+++ b/content/base/public/nsIXMLHttpRequest.idl
@@ -48,28 +48,28 @@ interface nsPIDOMWindow;
 interface nsIInputStream;
 interface nsIDOMBlob;
 
 %{C++
 // for jsval
 #include "jsapi.h"
 %}
 
-[scriptable, builtinclass, uuid(dea238a1-240f-45f4-9f07-7769bc69eb76)]
+[scriptable, builtinclass, uuid(e2b59e48-3655-4429-a94c-b4332c346ba2)]
 interface nsIXMLHttpRequestEventTarget : nsIDOMEventTarget {
   // event handler attributes
   attribute nsIDOMEventListener onabort;
   attribute nsIDOMEventListener onerror;
   attribute nsIDOMEventListener onload;
   attribute nsIDOMEventListener onloadstart;
   attribute nsIDOMEventListener onprogress;
   attribute nsIDOMEventListener onloadend;
 };
 
-[scriptable, builtinclass, uuid(09ff3682-7759-4441-a765-f70e1a1fabcf)]
+[scriptable, builtinclass, uuid(db9357fc-edf7-42b2-aab2-c24ab19ece20)]
 interface nsIXMLHttpRequestUpload : nsIXMLHttpRequestEventTarget {
   // for future use
 };
 
 /**
  * Mozilla's XMLHttpRequest is modelled after Microsoft's IXMLHttpRequest
  * object. The goal has been to make Mozilla's version match Microsoft's
  * version as closely as possible, but there are bound to be some differences.
--- a/content/base/src/nsCCUncollectableMarker.cpp
+++ b/content/base/src/nsCCUncollectableMarker.cpp
@@ -46,16 +46,19 @@
 #include "nsIWindowMediator.h"
 #include "nsPIDOMWindow.h"
 #include "nsIWebNavigation.h"
 #include "nsISHistory.h"
 #include "nsISHEntry.h"
 #include "nsISHContainer.h"
 #include "nsIWindowWatcher.h"
 #include "mozilla/Services.h"
+#include "nsIXULWindow.h"
+#include "nsIAppShellService.h"
+#include "nsAppShellCID.h"
 
 static bool sInited = 0;
 PRUint32 nsCCUncollectableMarker::sGeneration = 0;
 
 NS_IMPL_ISUPPORTS1(nsCCUncollectableMarker, nsIObserver)
 
 /* static */
 nsresult
@@ -226,11 +229,24 @@ nsCCUncollectableMarker::Observe(nsISupp
     do_GetService(NS_WINDOWWATCHER_CONTRACTID);
   if (ww) {
     rv = ww->GetWindowEnumerator(getter_AddRefs(windowList));
     NS_ENSURE_SUCCESS(rv, rv);
 
     MarkWindowList(windowList);
   }
 
+  nsCOMPtr<nsIAppShellService> appShell = 
+    do_GetService(NS_APPSHELLSERVICE_CONTRACTID);
+  if (appShell) {
+    nsCOMPtr<nsIXULWindow> hw;
+    appShell->GetHiddenWindow(getter_AddRefs(hw));
+    if (hw) {
+      nsCOMPtr<nsIDocShell> shell;
+      hw->GetDocShell(getter_AddRefs(shell));
+      nsCOMPtr<nsIDocShellTreeNode> shellTreeNode = do_QueryInterface(shell);
+      MarkDocShell(shellTreeNode);
+    }
+  }
+
   return NS_OK;
 }
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -207,16 +207,17 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_
 #include "nsIObjectLoadingContent.h"
 
 #include "mozilla/Preferences.h"
 
 #include "nsWrapperCacheInlines.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::layers;
+using namespace mozilla::widget;
 using namespace mozilla;
 
 const char kLoadAsData[] = "loadAsData";
 
 static const char kJSStackContractID[] = "@mozilla.org/js/xpc/ContextStack;1";
 static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
 static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
 
@@ -4022,35 +4023,16 @@ nsContentUtils::DropJSObjects(void* aScr
   nsresult rv = sXPConnect->RemoveJSHolder(aScriptObjectHolder);
   if (--sJSGCThingRootCount == 0) {
     nsLayoutStatics::Release();
   }
   return rv;
 }
 
 /* static */
-PRUint32
-nsContentUtils::GetWidgetStatusFromIMEStatus(PRUint32 aState)
-{
-  switch (aState & nsIContent::IME_STATUS_MASK_ENABLED) {
-    case nsIContent::IME_STATUS_DISABLE:
-      return nsIWidget::IME_STATUS_DISABLED;
-    case nsIContent::IME_STATUS_ENABLE:
-      return nsIWidget::IME_STATUS_ENABLED;
-    case nsIContent::IME_STATUS_PASSWORD:
-      return nsIWidget::IME_STATUS_PASSWORD;
-    case nsIContent::IME_STATUS_PLUGIN:
-      return nsIWidget::IME_STATUS_PLUGIN;
-    default:
-      NS_ERROR("The given state doesn't have valid enable state");
-      return nsIWidget::IME_STATUS_ENABLED;
-  }
-}
-
-/* static */
 void
 nsContentUtils::NotifyInstalledMenuKeyboardListener(bool aInstalling)
 {
   nsIMEStateManager::OnInstalledMenuKeyboardListener(aInstalling);
 }
 
 static bool SchemeIs(nsIURI* aURI, const char* aScheme)
 {
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1876,19 +1876,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFullScreenElement)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mStateObjectCached)
 
   // Traverse all our nsCOMArrays.
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mStyleSheets)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mCatalogSheets)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mPreloadingImages)
 
-  for (PRUint32 i = 0; i < tmp->mAnimationFrameListeners.Length(); ++i) {
-    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mAnimationFrameListeners[i]");
-    cb.NoteXPCOMChild(tmp->mAnimationFrameListeners[i]);
+  for (PRUint32 i = 0; i < tmp->mFrameRequestCallbacks.Length(); ++i) {
+    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mFrameRequestCallbacks[i]");
+    cb.NoteXPCOMChild(tmp->mFrameRequestCallbacks[i]);
   }
 
   // Traverse animation components
   if (tmp->mAnimationController) {
     tmp->mAnimationController->Traverse(&cb);
   }
 
   if (tmp->mSubDocuments && tmp->mSubDocuments->ops) {
@@ -1946,17 +1946,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
     tmp->mListenerManager = nsnull;
   }
 
   if (tmp->mSubDocuments) {
     PL_DHashTableDestroy(tmp->mSubDocuments);
     tmp->mSubDocuments = nsnull;
   }
 
-  tmp->mAnimationFrameListeners.Clear();
+  tmp->mFrameRequestCallbacks.Clear();
 
   tmp->mRadioGroups.Clear();
   
   // nsDocument has a pretty complex destructor, so we're going to
   // assume that *most* cycles you actually want to break somewhere
   // else, and not unlink an awful lot here.
 
   tmp->mIdentifierMap.Clear();
@@ -3209,51 +3209,45 @@ void
 nsDocument::MaybeRescheduleAnimationFrameNotifications()
 {
   if (!mPresShell || !IsEventHandlingEnabled()) {
     // bail out for now, until one of those conditions changes
     return;
   }
 
   nsRefreshDriver* rd = mPresShell->GetPresContext()->RefreshDriver();
-  if (mHavePendingPaint) {
-    rd->ScheduleBeforePaintEvent(this);
-  }
-  if (!mAnimationFrameListeners.IsEmpty()) {
-    rd->ScheduleAnimationFrameListeners(this);
-  }
-}
-
-void
-nsIDocument::TakeAnimationFrameListeners(AnimationListenerList& aListeners)
-{
-  aListeners.AppendElements(mAnimationFrameListeners);
-  mAnimationFrameListeners.Clear();
+  if (!mFrameRequestCallbacks.IsEmpty()) {
+    rd->ScheduleFrameRequestCallbacks(this);
+  }
+}
+
+void
+nsIDocument::TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks)
+{
+  aCallbacks.AppendElements(mFrameRequestCallbacks);
+  mFrameRequestCallbacks.Clear();
 }
 
 void
 nsDocument::DeleteShell()
 {
   mExternalResourceMap.HideViewers();
   if (IsEventHandlingEnabled()) {
     RevokeAnimationFrameNotifications();
   }
 
   mPresShell = nsnull;
 }
 
 void
 nsDocument::RevokeAnimationFrameNotifications()
 {
-  if (mHavePendingPaint) {
-    mPresShell->GetPresContext()->RefreshDriver()->RevokeBeforePaintEvent(this);
-  }
-  if (!mAnimationFrameListeners.IsEmpty()) {
+  if (!mFrameRequestCallbacks.IsEmpty()) {
     mPresShell->GetPresContext()->RefreshDriver()->
-      RevokeAnimationFrameListeners(this);
+      RevokeFrameRequestCallbacks(this);
   }
 }
 
 static void
 SubDocClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
 {
   SubDocMapEntry *e = static_cast<SubDocMapEntry *>(entry);
 
@@ -8069,40 +8063,24 @@ nsIDocument::CreateStaticClone(nsISuppor
       }
     }
   }
   mCreatingStaticClone = false;
   return clonedDoc.forget();
 }
 
 void
-nsIDocument::ScheduleBeforePaintEvent(nsIAnimationFrameListener* aListener)
-{
-  if (aListener) {
-    bool alreadyRegistered = !mAnimationFrameListeners.IsEmpty();
-    if (mAnimationFrameListeners.AppendElement(aListener) &&
-        !alreadyRegistered && mPresShell && IsEventHandlingEnabled()) {
-      mPresShell->GetPresContext()->RefreshDriver()->
-        ScheduleAnimationFrameListeners(this);
-    }
-
-    return;
-  }
-
-  if (!mHavePendingPaint) {
-    // We don't want to use GetShell() here, because we want to schedule the
-    // paint even if we're frozen.  Either we'll get unfrozen and then the
-    // event will fire, or we'll quietly go away at some point.
-    mHavePendingPaint =
-      !mPresShell ||
-      !IsEventHandlingEnabled() ||
-      mPresShell->GetPresContext()->RefreshDriver()->
-        ScheduleBeforePaintEvent(this);
-  }
-
+nsIDocument::ScheduleFrameRequestCallback(nsIFrameRequestCallback* aCallback)
+{
+  bool alreadyRegistered = !mFrameRequestCallbacks.IsEmpty();
+  if (mFrameRequestCallbacks.AppendElement(aCallback) &&
+      !alreadyRegistered && mPresShell && IsEventHandlingEnabled()) {
+    mPresShell->GetPresContext()->RefreshDriver()->
+      ScheduleFrameRequestCallbacks(this);
+  }
 }
 
 nsresult
 nsDocument::GetStateObject(nsIVariant** aState)
 {
   // Get the document's current state object. This is the object backing both
   // history.state and popStateEvent.state.
   //
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -104,16 +104,17 @@
 #include "nsGkAtoms.h"
 #include "nsContentUtils.h"
 #include "nsIJSContextStack.h"
 
 #include "nsIServiceManager.h"
 #include "nsIDOMEventListener.h"
 #include "nsIWebNavigation.h"
 #include "nsIBaseWindow.h"
+#include "nsIWidget.h"
 
 #include "jsapi.h"
 
 #include "nsNodeInfoManager.h"
 #include "nsICategoryManager.h"
 #include "nsIDOMDocumentType.h"
 #include "nsIDOMUserDataHandler.h"
 #include "nsGenericHTMLElement.h"
@@ -1092,27 +1093,51 @@ nsINode::AddEventListener(const nsAStrin
   nsEventListenerManager* listener_manager = GetListenerManager(true);
   NS_ENSURE_STATE(listener_manager);
   listener_manager->AddEventListener(aType, aListener, aUseCapture,
                                      aWantsUntrusted);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsINode::AddSystemEventListener(const nsAString& aType,
+                                nsIDOMEventListener *aListener,
+                                bool aUseCapture,
+                                bool aWantsUntrusted,
+                                PRUint8 aOptionalArgc)
+{
+  NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
+               "Won't check if this is chrome, you want to set "
+               "aWantsUntrusted to false or make the aWantsUntrusted "
+               "explicit by making aOptionalArgc non-zero.");
+
+  if (!aWantsUntrusted &&
+      (aOptionalArgc < 2 &&
+       !nsContentUtils::IsChromeDoc(OwnerDoc()))) {
+    aWantsUntrusted = true;
+  }
+
+  return NS_AddSystemEventListener(this, aType, aListener, aUseCapture,
+                                   aWantsUntrusted);
+}
+
+NS_IMETHODIMP
 nsINode::RemoveEventListener(const nsAString& aType,
                              nsIDOMEventListener* aListener,
                              bool aUseCapture)
 {
   nsEventListenerManager* elm = GetListenerManager(false);
   if (elm) {
     elm->RemoveEventListener(aType, aListener, aUseCapture);
   }
   return NS_OK;
 }
 
+NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsINode)
+
 nsresult
 nsINode::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   // This is only here so that we can use the NS_DECL_NSIDOMTARGET macro
   NS_ABORT();
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
@@ -1334,53 +1359,50 @@ nsIContent::GetFlattenedTreeParent() con
       doc->BindingManager()->GetNestedInsertionPoint(parent, this);
     if (insertionElement) {
       parent = insertionElement;
     }
   }
   return parent;
 }
 
-PRUint32
+nsIContent::IMEState
 nsIContent::GetDesiredIMEState()
 {
   if (!IsEditableInternal()) {
-    return IME_STATUS_DISABLE;
+    return IMEState(IMEState::DISABLED);
   }
   // NOTE: The content for independent editors (e.g., input[type=text],
   // textarea) must override this method, so, we don't need to worry about
   // that here.
   nsIContent *editableAncestor = GetEditingHost();
 
   // This is in another editable content, use the result of it.
   if (editableAncestor && editableAncestor != this) {
     return editableAncestor->GetDesiredIMEState();
   }
   nsIDocument* doc = GetCurrentDoc();
   if (!doc) {
-    return IME_STATUS_DISABLE;
+    return IMEState(IMEState::DISABLED);
   }
   nsIPresShell* ps = doc->GetShell();
   if (!ps) {
-    return IME_STATUS_DISABLE;
+    return IMEState(IMEState::DISABLED);
   }
   nsPresContext* pc = ps->GetPresContext();
   if (!pc) {
-    return IME_STATUS_DISABLE;
+    return IMEState(IMEState::DISABLED);
   }
   nsIEditor* editor = GetHTMLEditor(pc);
   nsCOMPtr<nsIEditorIMESupport> imeEditor = do_QueryInterface(editor);
   if (!imeEditor) {
-    return IME_STATUS_DISABLE;
-  }
-  // Use "enable" for the default value because IME is disabled unexpectedly,
-  // it makes serious a11y problem.
-  PRUint32 state = IME_STATUS_ENABLE;
-  nsresult rv = imeEditor->GetPreferredIMEState(&state);
-  NS_ENSURE_SUCCESS(rv, IME_STATUS_ENABLE);
+    return IMEState(IMEState::DISABLED);
+  }
+  IMEState state;
+  imeEditor->GetPreferredIMEState(&state);
   return state;
 }
 
 bool
 nsIContent::HasIndependentSelection()
 {
   nsIFrame* frame = GetPrimaryFrame();
   return (frame && frame->GetStateBits() & NS_FRAME_INDEPENDENT_SELECTION);
--- a/content/base/src/nsInProcessTabChildGlobal.cpp
+++ b/content/base/src/nsInProcessTabChildGlobal.cpp
@@ -306,17 +306,17 @@ nsInProcessTabChildGlobal::InitTabChildG
 
   mCx = cx;
 
   nsContentUtils::XPConnect()->SetSecurityManagerForJSContext(cx, nsContentUtils::GetSecurityManager(), 0);
   nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(mPrincipal));
 
   JS_SetNativeStackQuota(cx, 128 * sizeof(size_t) * 1024);
 
-  JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_JIT | JSOPTION_PRIVATE_IS_NSISUPPORTS);
+  JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_PRIVATE_IS_NSISUPPORTS);
   JS_SetVersion(cx, JSVERSION_LATEST);
   JS_SetErrorReporter(cx, ContentScriptErrorReporter);
 
   xpc_LocalizeContext(cx);
 
   JSAutoRequest ar(cx);
   nsIXPConnect* xpc = nsContentUtils::XPConnect();
   const PRUint32 flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES |
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -879,17 +879,17 @@ NS_IMETHODIMP nsXMLHttpRequest::GetRespo
 
   if (!(mState & (XML_HTTP_REQUEST_DONE | XML_HTTP_REQUEST_LOADING))) {
     return NS_OK;
   }
 
   // We only decode text lazily if we're also parsing to a doc.
   // Also, if we've decoded all current data already, then no need to decode
   // more.
-  if (IsWaitingForHTMLCharset() || !mResponseXML ||
+  if (!mResponseXML ||
       mResponseBodyDecodedPos == mResponseBody.Length()) {
     aResponseText = mResponseText;
     return NS_OK;
   }
 
   nsresult rv;
 
   nsCOMPtr<nsIDocument> document = do_QueryInterface(mResponseXML);
@@ -1468,26 +1468,16 @@ nsXMLHttpRequest::GetCurrentHttpChannel(
 }
 
 bool
 nsXMLHttpRequest::IsSystemXHR()
 {
   return !!nsContentUtils::IsSystemPrincipal(mPrincipal);
 }
 
-bool
-nsXMLHttpRequest::IsWaitingForHTMLCharset()
-{
-  if (!mIsHtml || !mResponseXML) {
-    return false;
-  }
-  nsCOMPtr<nsIDocument> doc = do_QueryInterface(mResponseXML);
-  return doc->GetDocumentCharacterSetSource() < kCharsetFromDocTypeDefault;
-}
-
 nsresult
 nsXMLHttpRequest::CheckChannelForCrossSiteRequest(nsIChannel* aChannel)
 {
   // First check if cross-site requests are enabled...
   if (IsSystemXHR()) {
     return NS_OK;
   }
 
@@ -1923,17 +1913,23 @@ nsXMLHttpRequest::OnStartRequest(nsIRequ
   if (parseBody && NS_SUCCEEDED(status)) {
     // We can gain a huge performance win by not even trying to
     // parse non-XML data. This also protects us from the situation
     // where we have an XML document and sink, but HTML (or other)
     // parser, which can produce unreliable results.
     nsCAutoString type;
     channel->GetContentType(type);
 
-    if (type.EqualsLiteral("text/html")) {
+    if ((mResponseType == XML_HTTP_RESPONSE_TYPE_DOCUMENT) &&
+        type.EqualsLiteral("text/html")) {
+      // HTML parsing is only supported for responseType == "document" to
+      // avoid running the parser and, worse, populating responseXML for
+      // legacy users of XHR who use responseType == "" for retrieving the
+      // responseText of text/html resources. This legacy case is so common
+      // that it's not useful to emit a warning about it.
       if (!(mState & XML_HTTP_REQUEST_ASYNC)) {
         // We don't make cool new features available in the bad synchronous
         // mode. The synchronous mode is for legacy only.
         mWarnAboutSyncHtml = true;
         mState &= ~XML_HTTP_REQUEST_PARSEBODY;
       } else if (mState & XML_HTTP_REQUEST_MULTIPART) {
         // HTML parsing is supported only for non-multipart responses. The
         // multipart implementation assumes that it's OK to start the next part
@@ -3133,23 +3129,21 @@ nsXMLHttpRequest::MaybeDispatchProgressE
                             mUploadTotal, mUploadProgress,
                             mUploadProgressMax);
     }
   } else {
     if (aFinalProgress) {
       mLoadTotal = mLoadTransferred;
       mLoadLengthComputable = true;
     }
-    if (aFinalProgress || !IsWaitingForHTMLCharset()) {
-      mInLoadProgressEvent = true;
-      DispatchProgressEvent(this, NS_LITERAL_STRING(PROGRESS_STR),
-                            true, mLoadLengthComputable, mLoadTransferred,
-                            mLoadTotal, mLoadTransferred, mLoadTotal);
-      mInLoadProgressEvent = false;
-    }
+    mInLoadProgressEvent = true;
+    DispatchProgressEvent(this, NS_LITERAL_STRING(PROGRESS_STR),
+                          true, mLoadLengthComputable, mLoadTransferred,
+                          mLoadTotal, mLoadTransferred, mLoadTotal);
+    mInLoadProgressEvent = false;
     if (mResponseType == XML_HTTP_RESPONSE_TYPE_CHUNKED_TEXT ||
         mResponseType == XML_HTTP_RESPONSE_TYPE_CHUNKED_ARRAYBUFFER) {
       mResponseBody.Truncate();
       mResponseText.Truncate();
       mResultArrayBuffer = nsnull;
     }
   }
 
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -231,18 +231,16 @@ protected:
 
   nsresult GetInnerEventListener(nsRefPtr<nsDOMEventListenerWrapper>& aWrapper,
                                  nsIDOMEventListener** aListener);
 
   already_AddRefed<nsIHttpChannel> GetCurrentHttpChannel();
 
   bool IsSystemXHR();
 
-  bool IsWaitingForHTMLCharset();
-
   void ChangeStateToDone();
 
   /**
    * Check if aChannel is ok for a cross-site request by making sure no
    * inappropriate headers are set, and no username/password is set.
    *
    * Also updates the XML_HTTP_REQUEST_USE_XSITE_AC bit.
    */
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -505,17 +505,16 @@ include $(topsrcdir)/config/rules.mk
 		somedatas.resource \
 		somedatas.resource^headers^ \
 		delayedServerEvents.sjs \
 		test_html_in_xhr.html \
 		file_html_in_xhr.html \
 		file_html_in_xhr2.html \
 		file_html_in_xhr3.html \
 		file_html_in_xhr.sjs \
-		file_html_in_xhr_slow.sjs \
 		test_bug664916.html \
 		test_bug666604.html \
 		test_bug675121.html \
 		file_bug675121.sjs \
 		test_bug675166.html \
 		test_bug682554.html \
 		test_bug682592.html \
 		bug682592-subframe.html \
deleted file mode 100644
--- a/content/base/test/file_html_in_xhr_slow.sjs
+++ /dev/null
@@ -1,24 +0,0 @@
-var timer;
-
-function handleRequest(request, response)
-{
-  var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
-    .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
-  converter.charset = "windows-1251";
-  var stream = converter.convertToInputStream("\u042E");
-  var out = response.bodyOutputStream;
-  response.setHeader("Cache-Control", "no-cache", false);
-  response.setHeader("Content-Type", "text/html", false);
-  out.writeFrom(stream, 1);
-  var firstPart = "<meta charset='windows";
-  out.write(firstPart, firstPart.length);
-  out.flush();
-  response.processAsync();
-  timer = Components.classes["@mozilla.org/timer;1"]
-    .createInstance(Components.interfaces.nsITimer);
-  timer.initWithCallback(function() {
-      response.write("-1251'>");      
-      response.finish();
-    }, 500, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
-}
-
--- a/content/base/test/test_html_in_xhr.html
+++ b/content/base/test/test_html_in_xhr.html
@@ -24,52 +24,51 @@ SimpleTest.waitForExplicitFinish();
 var xhr = new XMLHttpRequest();
 
 function runTest() {
   xhr.onreadystatechange = function() {
     if (this.readyState == 4) {
       ok(this.responseXML, "Should have gotten responseXML");
       is(this.responseXML.characterSet, "windows-1251", "Wrong character encoding");
       is(this.responseXML.documentElement.firstChild.data, " \u042E ", "Decoded using the wrong encoding.");
-      is(this.responseText.indexOf("\u042E"), 27, "Bad responseText");
+      try {
+        this.responseText;
+        ok(false, "responseText access should have thrown.");
+      } catch (e) {
+        is(e.code, 11, "Should have thrown INVALID_STATE_ERR.");
+      }
       is(this.responseXML.getElementsByTagName("div").length, 1, "There should be one div.");
       ok(!this.responseXML.documentElement.hasAttribute("data-fail"), "Should not have a data-fail attribute.");
       var scripts = this.responseXML.getElementsByTagName("script");
       is(scripts.length, 4, "Unexpected number of scripts.");
       while (scripts.length) {
         // These should not run when moved to another doc
         document.body.appendChild(scripts[0]);
       }
       var s = document.createElement("script");
       s.src = "file_html_in_xhr.sjs?report=1";
       document.body.appendChild(s);
     }
   }
   xhr.open("GET", "file_html_in_xhr.html", true);
+  xhr.responseType = "document";
   xhr.send();
 }
 
 function continueAfterReport() {
-  ok(!document.documentElement.hasAttribute("data-fail"), "Should not have a data-fail attribute on mochitest doc.");  
   xhr = new XMLHttpRequest();
-  xhr.onprogress = function() {
-    ok(this.responseText, "Got falsy responseText");
-    if (this.responseText) {
-      ok(this.responseText.length, "Got zero-length responseText");
-      if (this.responseText.length) {
-        is(this.responseText.charCodeAt(0), 0x042E, "Wrong character encoding for slow text");
-      }
-    }
-  }
   xhr.onreadystatechange = function() {
     if (this.readyState == 4) {
+      is(this.responseText.indexOf("\u042E"), -1, "Honored meta in default mode.");
+      is(this.responseText.indexOf("\uFFFD"), 29, "Honored meta in default mode 2.");
+      is(this.responseXML, null, "responseXML should be null for HTML in the default mode");
       testNonParsingText();
     }
   }
-  xhr.open("GET", "file_html_in_xhr_slow.sjs");
+  xhr.open("GET", "file_html_in_xhr2.html");
   xhr.send();   
 }
 
 function testNonParsingText() {
   xhr = new XMLHttpRequest();
   xhr.onreadystatechange = function() {
     if (this.readyState == 4) {
       is(this.responseText.indexOf("\u042E"), -1, "Honored meta in text mode.");
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -1082,19 +1082,20 @@ public:
         return mImageInfos.ElementAt(level * mFacesCount + face);
     }
 
     const ImageInfo& ImageInfoAt(size_t level, size_t face) const {
         return const_cast<WebGLTexture*>(this)->ImageInfoAt(level, face);
     }
 
     bool HasImageInfoAt(size_t level, size_t face) const {
-        return level <= mMaxLevelWithCustomImages &&
-               face < mFacesCount &&
-               ImageInfoAt(level, 0).mIsDefined;
+        CheckedUint32 checked_index = CheckedUint32(level) * mFacesCount + face;
+        return checked_index.valid() &&
+               checked_index.value() < mImageInfos.Length() &&
+               ImageInfoAt(level, face).mIsDefined;
     }
 
     static size_t FaceForTarget(WebGLenum target) {
         return target == LOCAL_GL_TEXTURE_2D ? 0 : target - LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
     }
 
     PRInt64 MemoryUsage() const {
         PRInt64 result = 0;
--- a/content/events/public/nsIPrivateDOMEvent.h
+++ b/content/events/public/nsIPrivateDOMEvent.h
@@ -139,9 +139,11 @@ NS_NewDOMAnimationEvent(nsIDOMEvent** aI
 nsresult
 NS_NewDOMCloseEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
 nsresult
 NS_NewDOMMozTouchEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsMozTouchEvent* aEvent);
 nsresult
 NS_NewDOMTouchEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsInputEvent *aEvent);
 nsresult
 NS_NewDOMCustomEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent* aEvent);
+nsresult
+NS_NewDOMSmsEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent* aEvent);
 #endif // nsIPrivateDOMEvent_h__
--- a/content/events/src/nsDOMEventTargetHelper.cpp
+++ b/content/events/src/nsDOMEventTargetHelper.cpp
@@ -98,16 +98,18 @@ nsDOMEventTargetHelper::RemoveEventListe
   nsEventListenerManager* elm = GetListenerManager(false);
   if (elm) {
     elm->RemoveEventListener(aType, aListener, aUseCapture);
   }
 
   return NS_OK;
 }
 
+NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsDOMEventTargetHelper)
+
 NS_IMETHODIMP
 nsDOMEventTargetHelper::AddEventListener(const nsAString& aType,
                                          nsIDOMEventListener *aListener,
                                          bool aUseCapture,
                                          bool aWantsUntrusted,
                                          PRUint8 aOptionalArgc)
 {
   NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
@@ -126,16 +128,41 @@ nsDOMEventTargetHelper::AddEventListener
 
   nsEventListenerManager* elm = GetListenerManager(true);
   NS_ENSURE_STATE(elm);
   elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsDOMEventTargetHelper::AddSystemEventListener(const nsAString& aType,
+                                               nsIDOMEventListener *aListener,
+                                               bool aUseCapture,
+                                               bool aWantsUntrusted,
+                                               PRUint8 aOptionalArgc)
+{
+  NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
+               "Won't check if this is chrome, you want to set "
+               "aWantsUntrusted to false or make the aWantsUntrusted "
+               "explicit by making aOptionalArgc non-zero.");
+
+  if (aOptionalArgc < 2) {
+    nsresult rv;
+    nsIScriptContext* context = GetContextForEventHandlers(&rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+    nsCOMPtr<nsIDocument> doc =
+      nsContentUtils::GetDocumentFromScriptContext(context);
+    aWantsUntrusted = doc && !nsContentUtils::IsChromeDoc(doc);
+  }
+
+  return NS_AddSystemEventListener(this, aType, aListener, aUseCapture,
+                                   aWantsUntrusted);
+}
+
+NS_IMETHODIMP
 nsDOMEventTargetHelper::DispatchEvent(nsIDOMEvent* aEvent, bool* aRetVal)
 {
   nsEventStatus status = nsEventStatus_eIgnore;
   nsresult rv =
     nsEventDispatcher::DispatchDOMEvent(this, nsnull, aEvent, nsnull, &status);
 
   *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
   return rv;
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -899,11 +899,13 @@ nsEventDispatcher::CreateEvent(nsPresCon
     return NS_NewDOMCloseEvent(aDOMEvent, aPresContext, nsnull);
   if (aEventType.LowerCaseEqualsLiteral("touchevent") &&
       nsDOMTouchEvent::PrefEnabled())
     return NS_NewDOMTouchEvent(aDOMEvent, aPresContext, nsnull);
   if (aEventType.LowerCaseEqualsLiteral("hashchangeevent"))
     return NS_NewDOMHashChangeEvent(aDOMEvent, aPresContext, nsnull);
   if (aEventType.LowerCaseEqualsLiteral("customevent"))
     return NS_NewDOMCustomEvent(aDOMEvent, aPresContext, nsnull);
+  if (aEventType.LowerCaseEqualsLiteral("mozsmsevent"))
+    return NS_NewDOMSmsEvent(aDOMEvent, aPresContext, nsnull);
 
   return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
 }
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -400,17 +400,17 @@ nsEventListenerManager::SetJSEventListen
 {
   nsresult rv = NS_OK;
   PRUint32 eventType = nsContentUtils::GetEventId(aName);
   nsListenerStruct* ls = FindJSEventListener(eventType, aName);
 
   if (!ls) {
     // If we didn't find a script listener or no listeners existed
     // create and add a new one.
-    nsCOMPtr<nsIDOMEventListener> scriptListener;
+    nsCOMPtr<nsIJSEventListener> scriptListener;
     rv = NS_NewJSEventListener(aContext, aScopeObject, mTarget, aName,
                                aHandler, getter_AddRefs(scriptListener));
     if (NS_SUCCEEDED(rv)) {
       AddEventListener(scriptListener, eventType, aName,
                        NS_EVENT_FLAG_BUBBLE | NS_PRIV_EVENT_FLAG_SCRIPT);
 
       ls = FindJSEventListener(eventType, aName);
     }
@@ -696,20 +696,18 @@ nsEventListenerManager::CompileEventHand
       NS_ENSURE_SUCCESS(result, result);
     }
   }
 
   if (handler) {
     // Bind it
     nsScriptObjectHolder boundHandler(context);
     context->BindCompiledEventHandler(mTarget, listener->GetEventScope(),
-                                      handler, boundHandler);
-    listener->SetHandler(
-      static_cast<JSObject*>(
-        static_cast<void*>(boundHandler)));
+                                      handler.getObject(), boundHandler);
+    listener->SetHandler(boundHandler.getObject());
   }
 
   return result;
 }
 
 nsresult
 nsEventListenerManager::HandleEventSubType(nsListenerStruct* aListenerStruct,
                                            nsIDOMEventListener* aListener,
--- a/content/events/src/nsEventListenerManager.h
+++ b/content/events/src/nsEventListenerManager.h
@@ -58,28 +58,36 @@ class nsIWidget;
 struct nsPoint;
 struct EventTypeData;
 class nsEventTargetChainItem;
 class nsPIDOMWindow;
 class nsCxPusher;
 class nsIEventListenerInfo;
 class nsIDocument;
 
-typedef struct {
+struct nsListenerStruct
+{
   nsRefPtr<nsIDOMEventListener> mListener;
   PRUint32                      mEventType;
   nsCOMPtr<nsIAtom>             mTypeAtom;
   PRUint16                      mFlags;
   bool                          mHandlerIsString;
 
   nsIJSEventListener* GetJSListener() const {
     return (mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) ?
       static_cast<nsIJSEventListener *>(mListener.get()) : nsnull;
   }
-} nsListenerStruct;
+
+  ~nsListenerStruct()
+  {
+    if ((mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) && mListener) {
+      static_cast<nsIJSEventListener*>(mListener.get())->Disconnect();
+    }
+  }
+};
 
 /*
  * Event listener manager
  */
 
 class nsEventListenerManager
 {
 
@@ -313,9 +321,31 @@ protected:
 
   static PRUint32                           mInstanceCount;
   static jsid                               sAddListenerID;
 
   friend class nsEventTargetChainItem;
   static PRUint32                           sCreatedCount;
 };
 
+/**
+ * NS_AddSystemEventListener() is a helper function for implementing
+ * nsIDOMEventTarget::AddSystemEventListener().
+ */
+inline nsresult
+NS_AddSystemEventListener(nsIDOMEventTarget* aTarget,
+                          const nsAString& aType,
+                          nsIDOMEventListener *aListener,
+                          bool aUseCapture,
+                          bool aWantsUntrusted)
+{
+  nsEventListenerManager* listenerManager = aTarget->GetListenerManager(true);
+  NS_ENSURE_STATE(listenerManager);
+  PRUint32 flags = NS_EVENT_FLAG_SYSTEM_EVENT;
+  flags |= aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
+  if (aWantsUntrusted) {
+    flags |= NS_PRIV_EVENT_UNTRUSTED_PERMITTED;
+  }
+  listenerManager->AddEventListenerByType(aListener, aType, flags);
+  return NS_OK;
+}
+
 #endif // nsEventListenerManager_h__
--- a/content/events/src/nsIMEStateManager.cpp
+++ b/content/events/src/nsIMEStateManager.cpp
@@ -35,27 +35,28 @@
  * 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 "nsIMEStateManager.h"
 #include "nsCOMPtr.h"
-#include "nsIWidget.h"
 #include "nsIViewManager.h"
 #include "nsIPresShell.h"
 #include "nsISupports.h"
 #include "nsPIDOMWindow.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIEditorDocShell.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsPresContext.h"
 #include "nsIDOMWindow.h"
+#include "nsIDOMMouseEvent.h"
+#include "nsIDOMNSEvent.h"
 #include "nsContentUtils.h"
 #include "nsINode.h"
 #include "nsIFrame.h"
 #include "nsRange.h"
 #include "nsIDOMRange.h"
 #include "nsISelection.h"
 #include "nsISelectionPrivate.h"
 #include "nsISelectionListener.h"
@@ -63,16 +64,18 @@
 #include "nsIMutationObserver.h"
 #include "nsContentEventHandler.h"
 #include "nsIObserverService.h"
 #include "mozilla/Services.h"
 #include "nsIFormControl.h"
 #include "nsIForm.h"
 #include "nsHTMLFormElement.h"
 
+using namespace mozilla::widget;
+
 /******************************************************************/
 /* nsIMEStateManager                                              */
 /******************************************************************/
 
 nsIContent*    nsIMEStateManager::sContent      = nsnull;
 nsPresContext* nsIMEStateManager::sPresContext  = nsnull;
 bool           nsIMEStateManager::sInstalledMenuKeyboardListener = false;
 bool           nsIMEStateManager::sInSecureInputMode = false;
@@ -82,18 +85,20 @@ nsTextStateManager* nsIMEStateManager::s
 nsresult
 nsIMEStateManager::OnDestroyPresContext(nsPresContext* aPresContext)
 {
   NS_ENSURE_ARG_POINTER(aPresContext);
   if (aPresContext != sPresContext)
     return NS_OK;
   nsCOMPtr<nsIWidget> widget = GetWidget(sPresContext);
   if (widget) {
-    PRUint32 newState = GetNewIMEState(sPresContext, nsnull);
-    SetIMEState(newState, nsnull, widget, IMEContext::FOCUS_REMOVED);
+    IMEState newState = GetNewIMEState(sPresContext, nsnull);
+    InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
+                              InputContextAction::LOST_FOCUS);
+    SetIMEState(newState, nsnull, widget, action);
   }
   sContent = nsnull;
   sPresContext = nsnull;
   OnTextStateBlur(nsnull, nsnull);
   return NS_OK;
 }
 
 nsresult
@@ -107,30 +112,41 @@ nsIMEStateManager::OnRemoveContent(nsPre
     return NS_OK;
 
   // Current IME transaction should commit
   nsCOMPtr<nsIWidget> widget = GetWidget(sPresContext);
   if (widget) {
     nsresult rv = widget->CancelIMEComposition();
     if (NS_FAILED(rv))
       widget->ResetInputState();
-    PRUint32 newState = GetNewIMEState(sPresContext, nsnull);
-    SetIMEState(newState, nsnull, widget, IMEContext::FOCUS_REMOVED);
+    IMEState newState = GetNewIMEState(sPresContext, nsnull);
+    InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
+                              InputContextAction::LOST_FOCUS);
+    SetIMEState(newState, nsnull, widget, action);
   }
 
   sContent = nsnull;
   sPresContext = nsnull;
 
   return NS_OK;
 }
 
 nsresult
 nsIMEStateManager::OnChangeFocus(nsPresContext* aPresContext,
                                  nsIContent* aContent,
-                                 PRUint32 aReason)
+                                 InputContextAction::Cause aCause)
+{
+  InputContextAction action(aCause);
+  return OnChangeFocusInternal(aPresContext, aContent, action);
+}
+
+nsresult
+nsIMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
+                                         nsIContent* aContent,
+                                         InputContextAction aAction)
 {
   NS_ENSURE_ARG_POINTER(aPresContext);
 
   nsCOMPtr<nsIWidget> widget = GetWidget(aPresContext);
   if (!widget) {
     return NS_OK;
   }
 
@@ -152,121 +168,155 @@ nsIMEStateManager::OnChangeFocus(nsPresC
   } else {
     if (contentIsPassword) {
       if (NS_SUCCEEDED(widget->BeginSecureKeyboardInput())) {
         sInSecureInputMode = true;
       }
     }
   }
 
-  PRUint32 newState = GetNewIMEState(aPresContext, aContent);
+  IMEState newState = GetNewIMEState(aPresContext, aContent);
   if (aPresContext == sPresContext && aContent == sContent) {
     // actual focus isn't changing, but if IME enabled state is changing,
     // we should do it.
-    PRUint32 newEnabledState = newState & nsIContent::IME_STATUS_MASK_ENABLED;
-    if (newEnabledState == 0) {
-      // the enabled state isn't changing, we should do nothing.
-      return NS_OK;
-    }
-    IMEContext context;
-    if (!widget || NS_FAILED(widget->GetInputMode(context))) {
-      // this platform doesn't support IME controlling
-      return NS_OK;
-    }
-    if (context.mStatus ==
-        nsContentUtils::GetWidgetStatusFromIMEStatus(newEnabledState)) {
+    InputContext context = widget->GetInputContext();
+    if (context.mIMEState.mEnabled == newState.mEnabled) {
       // the enabled state isn't changing.
       return NS_OK;
     }
+    aAction.mFocusChange = InputContextAction::FOCUS_NOT_CHANGED;
+  } else if (aAction.mFocusChange == InputContextAction::FOCUS_NOT_CHANGED) {
+    // If aContent isn't null or aContent is null but editable, somebody gets
+    // focus.
+    bool gotFocus = aContent || (newState.mEnabled == IMEState::ENABLED);
+    aAction.mFocusChange =
+      gotFocus ? InputContextAction::GOT_FOCUS : InputContextAction::LOST_FOCUS;
   }
 
   // Current IME transaction should commit
   if (sPresContext) {
     nsCOMPtr<nsIWidget> oldWidget;
     if (sPresContext == aPresContext)
       oldWidget = widget;
     else
       oldWidget = GetWidget(sPresContext);
     if (oldWidget)
       oldWidget->ResetInputState();
   }
 
-  if (newState != nsIContent::IME_STATUS_NONE) {
-    // Update IME state for new focus widget
-    SetIMEState(newState, aContent, widget, aReason);
-  }
+  // Update IME state for new focus widget
+  SetIMEState(newState, aContent, widget, aAction);
 
   sPresContext = aPresContext;
   sContent = aContent;
 
   return NS_OK;
 }
 
 void
 nsIMEStateManager::OnInstalledMenuKeyboardListener(bool aInstalling)
 {
   sInstalledMenuKeyboardListener = aInstalling;
 
-  PRUint32 reason = aInstalling ? IMEContext::FOCUS_MOVED_TO_MENU
-                                : IMEContext::FOCUS_MOVED_FROM_MENU;
-  OnChangeFocus(sPresContext, sContent, reason);
+  InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
+    aInstalling ? InputContextAction::MENU_GOT_PSEUDO_FOCUS :
+                  InputContextAction::MENU_LOST_PSEUDO_FOCUS);
+  OnChangeFocusInternal(sPresContext, sContent, action);
 }
 
 void
-nsIMEStateManager::UpdateIMEState(PRUint32 aNewIMEState, nsIContent* aContent)
+nsIMEStateManager::OnClickInEditor(nsPresContext* aPresContext,
+                                   nsIContent* aContent,
+                                   nsIDOMMouseEvent* aMouseEvent)
+{
+  if (sPresContext != aPresContext || sContent != aContent) {
+    return;
+  }
+
+  nsCOMPtr<nsIWidget> widget = GetWidget(aPresContext);
+  NS_ENSURE_TRUE(widget, );
+
+  bool isTrusted;
+  nsCOMPtr<nsIDOMNSEvent> NSEvent = do_QueryInterface(aMouseEvent);
+  nsresult rv = NSEvent->GetIsTrusted(&isTrusted);
+  NS_ENSURE_SUCCESS(rv, );
+  if (!isTrusted) {
+    return; // ignore untrusted event.
+  }
+
+  PRUint16 button;
+  rv = aMouseEvent->GetButton(&button);
+  NS_ENSURE_SUCCESS(rv, );
+  if (button != 0) {
+    return; // not a left click event.
+  }
+
+  PRInt32 clickCount;
+  rv = aMouseEvent->GetDetail(&clickCount);
+  NS_ENSURE_SUCCESS(rv, );
+  if (clickCount != 1) {
+    return; // should notify only first click event.
+  }
+
+  InputContextAction action(InputContextAction::CAUSE_MOUSE,
+                            InputContextAction::FOCUS_NOT_CHANGED);
+  IMEState newState = GetNewIMEState(aPresContext, aContent);
+  SetIMEState(newState, aContent, widget, action);
+}
+
+void
+nsIMEStateManager::UpdateIMEState(const IMEState &aNewIMEState,
+                                  nsIContent* aContent)
 {
   if (!sPresContext) {
     NS_WARNING("ISM doesn't know which editor has focus");
     return;
   }
-  NS_PRECONDITION(aNewIMEState != 0, "aNewIMEState doesn't specify new state.");
   nsCOMPtr<nsIWidget> widget = GetWidget(sPresContext);
   if (!widget) {
     NS_WARNING("focused widget is not found");
     return;
   }
 
   // Don't update IME state when enabled state isn't actually changed.
-  IMEContext context;
-  nsresult rv = widget->GetInputMode(context);
-  if (NS_FAILED(rv)) {
-    return; // This platform doesn't support controling the IME state.
-  }
-  PRUint32 newEnabledState = aNewIMEState & nsIContent::IME_STATUS_MASK_ENABLED;
-  if (context.mStatus ==
-        nsContentUtils::GetWidgetStatusFromIMEStatus(newEnabledState)) {
+  InputContext context = widget->GetInputContext();
+  if (context.mIMEState.mEnabled == aNewIMEState.mEnabled) {
     return;
   }
 
   // commit current composition
   widget->ResetInputState();
 
-  SetIMEState(aNewIMEState, aContent, widget, IMEContext::EDITOR_STATE_MODIFIED);
+  InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
+                            InputContextAction::FOCUS_NOT_CHANGED);
+  SetIMEState(aNewIMEState, aContent, widget, action);
 }
 
-PRUint32
+IMEState
 nsIMEStateManager::GetNewIMEState(nsPresContext* aPresContext,
                                   nsIContent*    aContent)
 {
   // On Printing or Print Preview, we don't need IME.
   if (aPresContext->Type() == nsPresContext::eContext_PrintPreview ||
       aPresContext->Type() == nsPresContext::eContext_Print) {
-    return nsIContent::IME_STATUS_DISABLE;
+    return IMEState(IMEState::DISABLED);
   }
 
-  if (sInstalledMenuKeyboardListener)
-    return nsIContent::IME_STATUS_DISABLE;
+  if (sInstalledMenuKeyboardListener) {
+    return IMEState(IMEState::DISABLED);
+  }
 
   if (!aContent) {
     // Even if there are no focused content, the focused document might be
     // editable, such case is design mode.
     nsIDocument* doc = aPresContext->Document();
-    if (doc && doc->HasFlag(NODE_IS_EDITABLE))
-      return nsIContent::IME_STATUS_ENABLE;
-    return nsIContent::IME_STATUS_DISABLE;
+    if (doc && doc->HasFlag(NODE_IS_EDITABLE)) {
+      return IMEState(IMEState::ENABLED);
+    }
+    return IMEState(IMEState::DISABLED);
   }
 
   return aContent->GetDesiredIMEState();
 }
 
 // Helper class, used for IME enabled state change notification
 class IMEEnabledStateChangedEvent : public nsRunnable {
 public:
@@ -285,75 +335,72 @@ public:
     return NS_OK;
   }
 
 private:
   PRUint32 mState;
 };
 
 void
-nsIMEStateManager::SetIMEState(PRUint32 aState,
+nsIMEStateManager::SetIMEState(const IMEState &aState,
                                nsIContent* aContent,
                                nsIWidget* aWidget,
-                               PRUint32 aReason)
+                               InputContextAction aAction)
 {
-  if (aState & nsIContent::IME_STATUS_MASK_ENABLED) {
-    if (!aWidget)
-      return;
+  NS_ENSURE_TRUE(aWidget, );
+
+  InputContext oldContext = aWidget->GetInputContext();
 
-    PRUint32 state = nsContentUtils::GetWidgetStatusFromIMEStatus(aState);
-    IMEContext context;
-    context.mStatus = state;
-    
-    if (aContent && aContent->GetNameSpaceID() == kNameSpaceID_XHTML &&
-        (aContent->Tag() == nsGkAtoms::input ||
-         aContent->Tag() == nsGkAtoms::textarea)) {
-      aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type,
-                        context.mHTMLInputType);
-      aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::moz_action_hint,
-                        context.mActionHint);
+  InputContext context;
+  context.mIMEState = aState;
+
+  if (aContent && aContent->GetNameSpaceID() == kNameSpaceID_XHTML &&
+      (aContent->Tag() == nsGkAtoms::input ||
+       aContent->Tag() == nsGkAtoms::textarea)) {
+    aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type,
+                      context.mHTMLInputType);
+    aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::moz_action_hint,
+                      context.mActionHint);
 
-      // if we don't have an action hint and  return won't submit the form use "next"
-      if (context.mActionHint.IsEmpty() && aContent->Tag() == nsGkAtoms::input) {
-        bool willSubmit = false;
-        nsCOMPtr<nsIFormControl> control(do_QueryInterface(aContent));
-        mozilla::dom::Element* formElement = control->GetFormElement();
-        nsCOMPtr<nsIForm> form;
-        if (control) {
-          // is this a form and does it have a default submit element?
-          if ((form = do_QueryInterface(formElement)) && form->GetDefaultSubmitElement()) {
-            willSubmit = true;
-          // is this an html form and does it only have a single text input element?
-          } else if (formElement && formElement->Tag() == nsGkAtoms::form && formElement->IsHTML() &&
-                     static_cast<nsHTMLFormElement*>(formElement)->HasSingleTextControl()) {
-            willSubmit = true;
-          }
+    // if we don't have an action hint and  return won't submit the form use "next"
+    if (context.mActionHint.IsEmpty() && aContent->Tag() == nsGkAtoms::input) {
+      bool willSubmit = false;
+      nsCOMPtr<nsIFormControl> control(do_QueryInterface(aContent));
+      mozilla::dom::Element* formElement = control->GetFormElement();
+      nsCOMPtr<nsIForm> form;
+      if (control) {
+        // is this a form and does it have a default submit element?
+        if ((form = do_QueryInterface(formElement)) && form->GetDefaultSubmitElement()) {
+          willSubmit = true;
+        // is this an html form and does it only have a single text input element?
+        } else if (formElement && formElement->Tag() == nsGkAtoms::form && formElement->IsHTML() &&
+                   static_cast<nsHTMLFormElement*>(formElement)->HasSingleTextControl()) {
+          willSubmit = true;
         }
-        context.mActionHint.Assign(willSubmit ? control->GetType() == NS_FORM_INPUT_SEARCH
-                                                  ? NS_LITERAL_STRING("search")
-                                                  : NS_LITERAL_STRING("go")
-                                              : formElement
-                                                  ? NS_LITERAL_STRING("next")
-                                                  : EmptyString());
       }
+      context.mActionHint.Assign(willSubmit ? control->GetType() == NS_FORM_INPUT_SEARCH
+                                                ? NS_LITERAL_STRING("search")
+                                                : NS_LITERAL_STRING("go")
+                                            : formElement
+                                                ? NS_LITERAL_STRING("next")
+                                                : EmptyString());
     }
+  }
 
-    if (XRE_GetProcessType() == GeckoProcessType_Content) {
-      context.mReason = aReason | IMEContext::FOCUS_FROM_CONTENT_PROCESS;
-    } else {
-      context.mReason = aReason;
-    }
+  // XXX I think that we should use nsContentUtils::IsCallerChrome() instead
+  //     of the process type.
+  if (aAction.mCause == InputContextAction::CAUSE_UNKNOWN &&
+      XRE_GetProcessType() != GeckoProcessType_Content) {
+    aAction.mCause = InputContextAction::CAUSE_UNKNOWN_CHROME;
+  }
 
-    aWidget->SetInputMode(context);
-
-    nsContentUtils::AddScriptRunner(new IMEEnabledStateChangedEvent(state));
-  }
-  if (aState & nsIContent::IME_STATUS_MASK_OPENED) {
-    bool open = !!(aState & nsIContent::IME_STATUS_OPEN);
-    aWidget->SetIMEOpenState(open);
+  aWidget->SetInputContext(context, aAction);
+  if (oldContext.mIMEState.mEnabled != context.mIMEState.mEnabled) {
+    nsContentUtils::AddScriptRunner(
+      new IMEEnabledStateChangedEvent(context.mIMEState.mEnabled));
   }
 }
 
 nsIWidget*
 nsIMEStateManager::GetWidget(nsPresContext* aPresContext)
 {
   nsIPresShell* shell = aPresContext->GetPresShell();
   NS_ENSURE_TRUE(shell, nsnull);
--- a/content/events/src/nsIMEStateManager.h
+++ b/content/events/src/nsIMEStateManager.h
@@ -35,37 +35,48 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsIMEStateManager_h__
 #define nsIMEStateManager_h__
 
 #include "nscore.h"
+#include "nsIWidget.h"
 
 class nsIContent;
+class nsIDOMMouseEvent;
 class nsPIDOMWindow;
 class nsPresContext;
-class nsIWidget;
 class nsTextStateManager;
 class nsISelection;
 
 /*
  * IME state manager
  */
 
 class nsIMEStateManager
 {
+protected:
+  typedef mozilla::widget::IMEState IMEState;
+  typedef mozilla::widget::InputContext InputContext;
+  typedef mozilla::widget::InputContextAction InputContextAction;
+
 public:
   static nsresult OnDestroyPresContext(nsPresContext* aPresContext);
   static nsresult OnRemoveContent(nsPresContext* aPresContext,
                                   nsIContent* aContent);
+  /**
+   * OnChangeFocus() should be called when focused content is changed or
+   * IME enabled state is changed.  If focus isn't actually changed and IME
+   * enabled state isn't changed, this will do nothing.
+   */
   static nsresult OnChangeFocus(nsPresContext* aPresContext,
                                 nsIContent* aContent,
-                                PRUint32 aReason);
+                                InputContextAction::Cause aCause);
   static void OnInstalledMenuKeyboardListener(bool aInstalling);
 
   // These two methods manage focus and selection/text observers.
   // They are separate from OnChangeFocus above because this offers finer
   // control compared to having the two methods incorporated into OnChangeFocus
 
   // OnTextStateBlur should be called *before* NS_BLUR_CONTENT fires
   // aPresContext is the nsPresContext receiving focus (not lost focus)
@@ -80,24 +91,37 @@ public:
                                    nsIContent* aContent);
   // Get the focused editor's selection and root
   static nsresult GetFocusSelectionAndRoot(nsISelection** aSel,
                                            nsIContent** aRoot);
   // This method updates the current IME state.  However, if the enabled state
   // isn't changed by the new state, this method does nothing.
   // Note that this method changes the IME state of the active element in the
   // widget.  So, the caller must have focus.
-  // aNewIMEState must have an enabled state of nsIContent::IME_STATUS_*.
-  // And optionally, it can have an open state of nsIContent::IME_STATUS_*.
-  static void UpdateIMEState(PRUint32 aNewIMEState, nsIContent* aContent);
+  static void UpdateIMEState(const IMEState &aNewIMEState,
+                             nsIContent* aContent);
+
+  // This method is called when user clicked in an editor.
+  // aContent must be:
+  //   If the editor is for <input> or <textarea>, the element.
+  //   If the editor is for contenteditable, the active editinghost.
+  //   If the editor is for designMode, NULL.
+  static void OnClickInEditor(nsPresContext* aPresContext,
+                              nsIContent* aContent,
+                              nsIDOMMouseEvent* aMouseEvent);
 
 protected:
-  static void SetIMEState(PRUint32 aState, nsIContent* aContent,
-                          nsIWidget* aWidget, PRUint32 aReason);
-  static PRUint32 GetNewIMEState(nsPresContext* aPresContext,
+  static nsresult OnChangeFocusInternal(nsPresContext* aPresContext,
+                                        nsIContent* aContent,
+                                        InputContextAction aAction);
+  static void SetIMEState(const IMEState &aState,
+                          nsIContent* aContent,
+                          nsIWidget* aWidget,
+                          InputContextAction aAction);
+  static IMEState GetNewIMEState(nsPresContext* aPresContext,
                                  nsIContent* aContent);
 
   static nsIWidget* GetWidget(nsPresContext* aPresContext);
 
   static nsIContent*    sContent;
   static nsPresContext* sPresContext;
   static bool           sInstalledMenuKeyboardListener;
   static bool           sInSecureInputMode;
--- a/content/html/content/public/nsHTMLMediaElement.h
+++ b/content/html/content/public/nsHTMLMediaElement.h
@@ -365,32 +365,49 @@ protected:
    * Create a decoder for the given aMIMEType. Returns null if we
    * were unable to create the decoder.
    */
   already_AddRefed<nsMediaDecoder> CreateDecoder(const nsACString& aMIMEType);
 
   /**
    * Initialize a decoder as a clone of an existing decoder in another
    * element.
+   * mLoadingSrc must already be set.
    */
   nsresult InitializeDecoderAsClone(nsMediaDecoder* aOriginal);
 
   /**
    * Initialize a decoder to load the given channel. The decoder's stream
    * listener is returned via aListener.
+   * mLoadingSrc must already be set.
    */
   nsresult InitializeDecoderForChannel(nsIChannel *aChannel,
                                        nsIStreamListener **aListener);
 
   /**
    * Finish setting up the decoder after Load() has been called on it.
+   * Called by InitializeDecoderForChannel/InitializeDecoderAsClone.
    */
   nsresult FinishDecoderSetup(nsMediaDecoder* aDecoder);
 
   /**
+   * Call this after setting up mLoadingSrc and mDecoder.
+   */
+  void AddMediaElementToURITable();
+  /**
+   * Call this before clearing mLoadingSrc.
+   */
+  void RemoveMediaElementFromURITable();
+  /**
+   * Call this to find a media element with the same NodePrincipal and mLoadingSrc
+   * set to aURI, and with a decoder on which Load() has been called.
+   */
+  nsHTMLMediaElement* LookupMediaElementURITable(nsIURI* aURI);
+
+  /**
    * Execute the initial steps of the load algorithm that ensure existing
    * loads are aborted, the element is emptied, and a new load ID is
    * created.
    */
   void AbortExistingLoads();
 
   /**
    * Create a URI for the given aURISpec string.
@@ -426,17 +443,17 @@ protected:
    * Asynchronously awaits a stable state, and then causes SelectResource()
    * to be run on the main thread's event loop.
    */
   void QueueSelectResourceTask();
 
   /**
    * The resource-fetch algorithm step of the load algorithm.
    */
-  nsresult LoadResource(nsIURI* aURI);
+  nsresult LoadResource();
 
   /**
    * Selects the next <source> child from which to load a resource. Called
    * during the resource selection algorithm. Stores the return value in
    * mSourceLoadCandidate before returning.
    */
   nsIContent* GetNextSource();
 
@@ -487,21 +504,21 @@ protected:
     PRELOAD_UNDEFINED = 0, // not determined - used only for initialization
     PRELOAD_NONE = 1,      // do not preload
     PRELOAD_METADATA = 2,  // preload only the metadata (and first frame)
     PRELOAD_ENOUGH = 3     // preload enough data to allow uninterrupted
                            // playback
   };
 
   /**
-   * Suspends the load of resource at aURI, so that it can be resumed later
+   * Suspends the load of mLoadingSrc, so that it can be resumed later
    * by ResumeLoad(). This is called when we have a media with a 'preload'
    * attribute value of 'none', during the resource selection algorithm.
    */
-  void SuspendLoad(nsIURI* aURI);
+  void SuspendLoad();
 
   /**
    * Resumes a previously suspended load (suspended by SuspendLoad(uri)).
    * Will continue running the resource selection algorithm.
    * Sets mPreloadAction to aAction.
    */
   void ResumeLoad(PreloadAction aAction);
 
@@ -530,16 +547,17 @@ protected:
    **/
   void GetCurrentSpec(nsCString& aString);
 
   /**
    * Process any media fragment entries in the URI
    */
   void ProcessMediaFragmentURI();
 
+  // The current decoder. Load() has been called on this decoder.
   nsRefPtr<nsMediaDecoder> mDecoder;
 
   // A reference to the ImageContainer which contains the current frame
   // of video to display.
   nsRefPtr<ImageContainer> mImageContainer;
 
   // Holds a reference to the first channel we open to the media resource.
   // Once the decoder is created, control over the channel passes to the
@@ -592,21 +610,21 @@ protected:
   double mVolume;
 
   // Current number of audio channels.
   PRUint32 mChannels;
 
   // Current audio sample rate.
   PRUint32 mRate;
 
-  // URI of the resource we're attempting to load. When the decoder is
-  // successfully initialized, we rely on it to record the URI we're playing,
-  // and clear mLoadingSrc. This stores the value we return in the currentSrc
-  // attribute until the decoder is initialized. Use GetCurrentSrc() to access
-  // the currentSrc attribute.
+  // URI of the resource we're attempting to load. This stores the value we
+  // return in the currentSrc attribute. Use GetCurrentSrc() to access the
+  // currentSrc attribute.
+  // This is always the original URL we're trying to load --- before
+  // redirects etc.
   nsCOMPtr<nsIURI> mLoadingSrc;
   
   // Stores the current preload action for this element. Initially set to
   // PRELOAD_UNDEFINED, its value is changed by calling
   // UpdatePreloadAction().
   PreloadAction mPreloadAction;
 
   // Size of the media. Updated by the decoder on the main thread if
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -66,16 +66,17 @@
 #include "nsIStyleRule.h"
 #include "nsIURL.h"
 #include "nsNetUtil.h"
 #include "nsEscape.h"
 #include "nsIFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsIView.h"
 #include "nsIViewManager.h"
+#include "nsIWidget.h"
 #include "nsRange.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsINameSpaceManager.h"
 #include "nsDOMError.h"
 #include "nsScriptLoader.h"
@@ -2647,27 +2648,27 @@ nsGenericHTMLFormElement::GetFormElement
 nsresult
 nsGenericHTMLFormElement::GetForm(nsIDOMHTMLFormElement** aForm)
 {
   NS_ENSURE_ARG_POINTER(aForm);
   NS_IF_ADDREF(*aForm = mForm);
   return NS_OK;
 }
 
-PRUint32
+nsIContent::IMEState
 nsGenericHTMLFormElement::GetDesiredIMEState()
 {
   nsCOMPtr<nsIEditor> editor = nsnull;
   nsresult rv = GetEditorInternal(getter_AddRefs(editor));
   if (NS_FAILED(rv) || !editor)
     return nsGenericHTMLElement::GetDesiredIMEState();
   nsCOMPtr<nsIEditorIMESupport> imeEditor = do_QueryInterface(editor);
   if (!imeEditor)
     return nsGenericHTMLElement::GetDesiredIMEState();
-  PRUint32 state;
+  IMEState state;
   rv = imeEditor->GetPreferredIMEState(&state);
   if (NS_FAILED(rv))
     return nsGenericHTMLElement::GetDesiredIMEState();
   return state;
 }
 
 bool
 nsGenericHTMLFrameElement::IsHTMLFocusable(bool aWithMouse,
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -879,17 +879,17 @@ public:
   }
 
   // nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers);
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true);
-  virtual PRUint32 GetDesiredIMEState();
+  virtual IMEState GetDesiredIMEState();
   virtual nsEventStates IntrinsicState() const;
 
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
 
   virtual bool IsDisabled() const;
 
   /**
    * This callback is called by a fieldest on all its elements whenever its
--- a/content/html/content/src/nsHTMLCanvasElement.cpp
+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
@@ -501,45 +501,47 @@ nsHTMLCanvasElement::GetContext(const ns
         contextProps = do_CreateInstance("@mozilla.org/hash-property-bag;1");
 
         JSObject *opts = JSVAL_TO_OBJECT(aContextOptions);
         JSIdArray *props = JS_Enumerate(cx, opts);
         for (int i = 0; props && i < JS_IdArrayLength(cx, props); ++i) {
           jsid propid = JS_IdArrayGet(cx, props, i);
           jsval propname, propval;
           if (!JS_IdToValue(cx, propid, &propname) ||
-              !JS_GetPropertyById(cx, opts, propid, &propval))
-          {
+              !JS_GetPropertyById(cx, opts, propid, &propval)) {
             continue;
           }
 
           JSString *propnameString = JS_ValueToString(cx, propname);
           nsDependentJSString pstr;
           if (!propnameString || !pstr.init(cx, propnameString)) {
+            JS_DestroyIdArray(cx, props);
             mCurrentContext = nsnull;
             return NS_ERROR_FAILURE;
           }
 
           if (JSVAL_IS_BOOLEAN(propval)) {
             contextProps->SetPropertyAsBool(pstr, propval == JSVAL_TRUE ? true : false);
           } else if (JSVAL_IS_INT(propval)) {
             contextProps->SetPropertyAsInt32(pstr, JSVAL_TO_INT(propval));
           } else if (JSVAL_IS_DOUBLE(propval)) {
             contextProps->SetPropertyAsDouble(pstr, JSVAL_TO_DOUBLE(propval));
           } else if (JSVAL_IS_STRING(propval)) {
             JSString *propvalString = JS_ValueToString(cx, propval);
             nsDependentJSString vstr;
             if (!propvalString || !vstr.init(cx, propvalString)) {
+              JS_DestroyIdArray(cx, props);
               mCurrentContext = nsnull;
               return NS_ERROR_FAILURE;
             }
 
             contextProps->SetPropertyAsAString(pstr, vstr);
           }
         }
+        JS_DestroyIdArray(cx, props);
       }
     }
 
     rv = UpdateContext(contextProps);
     if (NS_FAILED(rv)) {
       if (!forceThebes) {
         // Try again with a Thebes context
         forceThebes = true;
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -84,16 +84,17 @@
 #include "nsIDocShellTreeItem.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsIAppShell.h"
 #include "nsWidgetsCID.h"
 
 #include "nsIPrivateDOMEvent.h"
 #include "nsIDOMNotifyAudioAvailableEvent.h"
 #include "nsMediaFragmentURIParser.h"
+#include "nsURIHashKey.h"
 
 #ifdef MOZ_OGG
 #include "nsOggDecoder.h"
 #endif
 #ifdef MOZ_WAVE
 #include "nsWaveDecoder.h"
 #endif
 #ifdef MOZ_WEBM
@@ -474,34 +475,38 @@ void nsHTMLMediaElement::AbortExistingLo
   // Abort any already-running instance of the resource selection algorithm.
   mLoadWaitStatus = NOT_WAITING;
 
   // Set a new load ID. This will cause events which were enqueued
   // with a different load ID to silently be cancelled.
   mCurrentLoadID++;
 
   bool fireTimeUpdate = false;
+
   if (mDecoder) {
+    RemoveMediaElementFromURITable();
     fireTimeUpdate = mDecoder->GetCurrentTime() != 0.0;
     mDecoder->Shutdown();
     mDecoder = nsnull;
   }
+  mLoadingSrc = nsnull;
 
   if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_LOADING ||
       mNetworkState == nsIDOMHTMLMediaElement::NETWORK_IDLE)
   {
     DispatchEvent(NS_LITERAL_STRING("abort"));
   }
 
   mError = nsnull;
   mLoadedFirstFrame = false;
   mAutoplaying = true;
   mIsLoadingFromSourceChildren = false;
   mSuspendedAfterFirstFrame = false;
   mAllowSuspendAfterFirstFrame = true;
+  mLoadIsSuspended = false;
   mSourcePointer = nsnull;
 
   // TODO: The playback rate must be set to the default playback rate.
 
   if (mNetworkState != nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
     mNetworkState = nsIDOMHTMLMediaElement::NETWORK_EMPTY;
     ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING);
     mPaused = true;
@@ -643,22 +648,22 @@ void nsHTMLMediaElement::SelectResource(
     if (NS_SUCCEEDED(rv)) {
       LOG(PR_LOG_DEBUG, ("%p Trying load from src=%s", this, NS_ConvertUTF16toUTF8(src).get()));
       NS_ASSERTION(!mIsLoadingFromSourceChildren,
         "Should think we're not loading from source children by default");
       mLoadingSrc = uri;
       if (mPreloadAction == nsHTMLMediaElement::PRELOAD_NONE) {
         // preload:none media, suspend the load here before we make any
         // network requests.
-        SuspendLoad(uri);
+        SuspendLoad();
         mIsRunningSelectResource = false;
         return;
       }
 
-      rv = LoadResource(uri);
+      rv = LoadResource();
       if (NS_SUCCEEDED(rv)) {
         mIsRunningSelectResource = false;
         return;
       }
     }
     NoSupportedMediaSourceError();
   } else {
     // Otherwise, the source elements will be used.
@@ -745,55 +750,54 @@ void nsHTMLMediaElement::LoadFromSourceC
 
     mLoadingSrc = uri;
     NS_ASSERTION(mNetworkState == nsIDOMHTMLMediaElement::NETWORK_LOADING,
                  "Network state should be loading");
 
     if (mPreloadAction == nsHTMLMediaElement::PRELOAD_NONE) {
       // preload:none media, suspend the load here before we make any
       // network requests.
-      SuspendLoad(uri);
+      SuspendLoad();
       return;
     }
 
-    if (NS_SUCCEEDED(LoadResource(uri))) {
+    if (NS_SUCCEEDED(LoadResource())) {
       return;
     }
 
     // If we fail to load, loop back and try loading the next resource.
     DispatchAsyncSourceError(child);
   }
   NS_NOTREACHED("Execution should not reach here!");
 }
 
-void nsHTMLMediaElement::SuspendLoad(nsIURI* aURI)
+void nsHTMLMediaElement::SuspendLoad()
 {
   mLoadIsSuspended = true;
   mNetworkState = nsIDOMHTMLMediaElement::NETWORK_IDLE;
   DispatchAsyncEvent(NS_LITERAL_STRING("suspend"));
   ChangeDelayLoadStatus(false);
 }
 
 void nsHTMLMediaElement::ResumeLoad(PreloadAction aAction)
 {
   NS_ASSERTION(mLoadIsSuspended, "Can only resume preload if halted for one");
-  nsCOMPtr<nsIURI> uri = mLoadingSrc;
   mLoadIsSuspended = false;
   mPreloadAction = aAction;
   ChangeDelayLoadStatus(true);
   mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
   if (!mIsLoadingFromSourceChildren) {
     // We were loading from the element's src attribute.
-    if (NS_FAILED(LoadResource(uri))) {
+    if (NS_FAILED(LoadResource())) {
       NoSupportedMediaSourceError();
     }
   } else {
     // We were loading from a child <source> element. Try to resume the
     // load of that child, and if that fails, try the next child.
-    if (NS_FAILED(LoadResource(uri))) {
+    if (NS_FAILED(LoadResource())) {
       LoadFromSourceChildren();
     }
   }
 }
 
 static bool IsAutoplayEnabled()
 {
   return Preferences::GetBool("media.autoplay.enabled");
@@ -868,36 +872,44 @@ void nsHTMLMediaElement::UpdatePreloadAc
       // value "none". The preload value has changed to preload:metadata, so
       // resume the load. We'll pause the load again after we've read the
       // metadata.
       ResumeLoad(PRELOAD_METADATA);
     }
   }
 }
 
-nsresult nsHTMLMediaElement::LoadResource(nsIURI* aURI)
+nsresult nsHTMLMediaElement::LoadResource()
 {
   NS_ASSERTION(mDelayingLoadEvent,
                "Should delay load event (if in document) during load");
 
   // If a previous call to mozSetup() was made, kill that media stream
   // in order to use this new src instead.
   if (mAudioStream) {
     mAudioStream->Shutdown();
     mAudioStream = nsnull;
   }
 
   if (mChannel) {
     mChannel->Cancel(NS_BINDING_ABORTED);
     mChannel = nsnull;
   }
 
+  nsHTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc);
+  if (other) {
+    // Clone it.
+    nsresult rv = InitializeDecoderAsClone(other->mDecoder);
+    if (NS_SUCCEEDED(rv))
+      return rv;
+  }
+
   PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
   nsresult rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_MEDIA,
-                                          aURI,
+                                          mLoadingSrc,
                                           NodePrincipal(),
                                           static_cast<nsGenericElement*>(this),
                                           EmptyCString(), // mime type
                                           nsnull, // extra
                                           &shouldLoad,
                                           nsContentUtils::GetContentPolicy(),
                                           nsContentUtils::GetSecurityManager());
   NS_ENSURE_SUCCESS(rv, rv);
@@ -915,17 +927,17 @@ nsresult nsHTMLMediaElement::LoadResourc
   NS_ENSURE_SUCCESS(rv,rv);
   if (csp) {
     channelPolicy = do_CreateInstance("@mozilla.org/nschannelpolicy;1");
     channelPolicy->SetContentSecurityPolicy(csp);
     channelPolicy->SetLoadType(nsIContentPolicy::TYPE_MEDIA);
   }
   nsCOMPtr<nsIChannel> channel;
   rv = NS_NewChannel(getter_AddRefs(channel),
-                     aURI,
+                     mLoadingSrc,
                      nsnull,
                      loadGroup,
                      nsnull,
                      nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY,
                      channelPolicy);
   NS_ENSURE_SUCCESS(rv,rv);
 
   // The listener holds a strong reference to us.  This creates a
@@ -944,17 +956,17 @@ nsresult nsHTMLMediaElement::LoadResourc
       new nsCORSListenerProxy(loadListener,
                               NodePrincipal(),
                               channel,
                               false,
                               &rv);
   } else {
     rv = nsContentUtils::GetSecurityManager()->
            CheckLoadURIWithPrincipal(NodePrincipal(),
-                                     aURI,
+                                     mLoadingSrc,
                                      nsIScriptSecurityManager::STANDARD);
     listener = loadListener;
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(channel);
   if (hc) {
     // Use a byte range request from the start of the resource.
@@ -986,19 +998,21 @@ nsresult nsHTMLMediaElement::LoadWithCha
 {
   NS_ENSURE_ARG_POINTER(aChannel);
   NS_ENSURE_ARG_POINTER(aListener);
 
   *aListener = nsnull;
 
   AbortExistingLoads();
 
+  nsresult rv = aChannel->GetOriginalURI(getter_AddRefs(mLoadingSrc));
+  NS_ENSURE_SUCCESS(rv, rv);
+
   ChangeDelayLoadStatus(true);
-
-  nsresult rv = InitializeDecoderForChannel(aChannel, aListener);
+  rv = InitializeDecoderForChannel(aChannel, aListener);
   if (NS_FAILED(rv)) {
     ChangeDelayLoadStatus(false);
     return rv;
   }
 
   DispatchAsyncEvent(NS_LITERAL_STRING("loadstart"));
 
   return NS_OK;
@@ -1012,16 +1026,17 @@ NS_IMETHODIMP nsHTMLMediaElement::MozLoa
 
   nsCOMPtr<nsIContent> content = do_QueryInterface(aOther);
   nsHTMLMediaElement* other = static_cast<nsHTMLMediaElement*>(content.get());
   if (!other || !other->mDecoder)
     return NS_OK;
 
   ChangeDelayLoadStatus(true);
 
+  mLoadingSrc = other->mLoadingSrc;
   nsresult rv = InitializeDecoderAsClone(other->mDecoder);
   if (NS_FAILED(rv)) {
     ChangeDelayLoadStatus(false);
     return rv;
   }
 
   DispatchAsyncEvent(NS_LITERAL_STRING("loadstart"));
 
@@ -1236,16 +1251,86 @@ NS_IMETHODIMP nsHTMLMediaElement::SetMut
     mAudioStream->SetVolume(mMuted ? 0.0 : mVolume);
   }
 
   DispatchAsyncEvent(NS_LITERAL_STRING("volumechange"));
 
   return NS_OK;
 }
 
+class MediaElementSetForURI : public nsURIHashKey {
+public:
+  MediaElementSetForURI(const nsIURI* aKey) : nsURIHashKey(aKey) {}
+  MediaElementSetForURI(const MediaElementSetForURI& toCopy)
+    : nsURIHashKey(toCopy), mElements(toCopy.mElements) {}
+  nsTArray<nsHTMLMediaElement*> mElements;
+};
+
+typedef nsTHashtable<MediaElementSetForURI> MediaElementURITable;
+// Elements in this table must have non-null mDecoder and mLoadingSrc, and those
+// can't change while the element is in the table. The table is keyed by
+// the element's mLoadingSrc. Each entry has a list of all elements with the
+// same mLoadingSrc.
+static MediaElementURITable* gElementTable;
+
+void
+nsHTMLMediaElement::AddMediaElementToURITable()
+{
+  NS_ASSERTION(mDecoder && mDecoder->GetStream(), "Call this only with decoder Load called");
+  if (!gElementTable) {
+    gElementTable = new MediaElementURITable();
+    gElementTable->Init();
+  }
+  MediaElementSetForURI* entry = gElementTable->PutEntry(mLoadingSrc);
+  entry->mElements.AppendElement(this);
+}
+
+void
+nsHTMLMediaElement::RemoveMediaElementFromURITable()
+{
+  NS_ASSERTION(mDecoder, "Don't call this without decoder!");
+  NS_ASSERTION(mLoadingSrc, "Can't have decoder without source!");
+  if (!gElementTable)
+    return;
+  MediaElementSetForURI* entry = gElementTable->GetEntry(mLoadingSrc);
+  if (!entry)
+    return;
+  entry->mElements.RemoveElement(this);
+  if (entry->mElements.IsEmpty()) {
+    gElementTable->RemoveEntry(mLoadingSrc);
+    if (gElementTable->Count() == 0) {
+      delete gElementTable;
+      gElementTable = nsnull;
+    }
+  }
+}
+
+nsHTMLMediaElement*
+nsHTMLMediaElement::LookupMediaElementURITable(nsIURI* aURI)
+{
+  if (!gElementTable)
+    return nsnull;
+  MediaElementSetForURI* entry = gElementTable->GetEntry(aURI);
+  if (!entry)
+    return nsnull;
+  for (PRUint32 i = 0; i < entry->mElements.Length(); ++i) {
+    nsHTMLMediaElement* elem = entry->mElements[i];
+    bool equal;
+    // Look for elements that have the same principal.
+    // XXX when we implement crossorigin for video, we'll also need to check
+    // for the same crossorigin mode here. Ditto for anything else that could
+    // cause us to send different headers.
+    if (NS_SUCCEEDED(elem->NodePrincipal()->Equals(NodePrincipal(), &equal)) && equal) {
+      NS_ASSERTION(elem->mDecoder && elem->mDecoder->GetStream(), "Decoder gone");
+      return elem;
+    }
+  }
+  return nsnull;
+}
+
 nsHTMLMediaElement::nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo),
     mCurrentLoadID(0),
     mNetworkState(nsIDOMHTMLMediaElement::NETWORK_EMPTY),
     mReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING),
     mLoadWaitStatus(NOT_WAITING),
     mVolume(1.0),
     mChannels(0),
@@ -1292,26 +1377,24 @@ nsHTMLMediaElement::nsHTMLMediaElement(a
 
 nsHTMLMediaElement::~nsHTMLMediaElement()
 {
   NS_ASSERTION(!mHasSelfReference,
                "How can we be destroyed if we're still holding a self reference?");
 
   UnregisterFreezableElement();
   if (mDecoder) {
+    RemoveMediaElementFromURITable();
     mDecoder->Shutdown();
-    mDecoder = nsnull;
   }
   if (mChannel) {
     mChannel->Cancel(NS_BINDING_ABORTED);
-    mChannel = nsnull;
   }
   if (mAudioStream) {
     mAudioStream->Shutdown();
-    mAudioStream = nsnull;
   }
 }
 
 void nsHTMLMediaElement::StopSuspendingAfterFirstFrame()
 {
   mAllowSuspendAfterFirstFrame = false;
   if (!mSuspendedAfterFirstFrame)
     return;
@@ -1342,19 +1425,23 @@ void nsHTMLMediaElement::SetPlayedOrSeek
 NS_IMETHODIMP nsHTMLMediaElement::Play()
 {
   StopSuspendingAfterFirstFrame();
   SetPlayedOrSeeked(true);
 
   if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
     nsresult rv = Load();
     NS_ENSURE_SUCCESS(rv, rv);
-  } else if (mLoadIsSuspended) {
+  }
+  if (mLoadIsSuspended) {
     ResumeLoad(PRELOAD_ENOUGH);
-  } else if (mDecoder) {
+  }
+  // Even if we just did Load() or ResumeLoad(), we could already have a decoder
+  // here if we managed to clone an existing decoder.
+  if (mDecoder) {
     if (mDecoder->IsEnded()) {
       SetCurrentTime(0);
     }
     if (!mPausedForInactiveDocument) {
       nsresult rv = mDecoder->Play();
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
@@ -1806,17 +1893,19 @@ nsHTMLMediaElement::CreateDecoder(const 
     }
   }
 #endif
   return nsnull;
 }
 
 nsresult nsHTMLMediaElement::InitializeDecoderAsClone(nsMediaDecoder* aOriginal)
 {
-  nsMediaStream* originalStream = aOriginal->GetCurrentStream();
+  NS_ASSERTION(mLoadingSrc, "mLoadingSrc must already be set");
+
+  nsMediaStream* originalStream = aOriginal->GetStream();
   if (!originalStream)
     return NS_ERROR_FAILURE;
   nsRefPtr<nsMediaDecoder> decoder = aOriginal->Clone();
   if (!decoder)
     return NS_ERROR_FAILURE;
 
   LOG(PR_LOG_DEBUG, ("%p Cloned decoder %p from %p", this, decoder.get(), aOriginal));
 
@@ -1843,16 +1932,18 @@ nsresult nsHTMLMediaElement::InitializeD
   }
 
   return FinishDecoderSetup(decoder);
 }
 
 nsresult nsHTMLMediaElement::InitializeDecoderForChannel(nsIChannel *aChannel,
                                                          nsIStreamListener **aListener)
 {
+  NS_ASSERTION(mLoadingSrc, "mLoadingSrc must already be set");
+
   nsCAutoString mimeType;
   aChannel->GetContentType(mimeType);
 
   nsRefPtr<nsMediaDecoder> decoder = CreateDecoder(mimeType);
   if (!decoder) {
     return NS_ERROR_FAILURE;
   }
 
@@ -1873,20 +1964,20 @@ nsresult nsHTMLMediaElement::InitializeD
   // which owns the channel.
   mChannel = nsnull;
 
   return FinishDecoderSetup(decoder);
 }
 
 nsresult nsHTMLMediaElement::FinishDecoderSetup(nsMediaDecoder* aDecoder)
 {
+  NS_ASSERTION(mLoadingSrc, "mLoadingSrc set up");
+
   mDecoder = aDecoder;
-
-  // Decoder has assumed ownership responsibility for remembering the URI.
-  mLoadingSrc = nsnull;
+  AddMediaElementToURITable();
 
   // Force a same-origin check before allowing events for this media resource.
   mMediaSecurityVerified = false;
 
   // The new stream has not been suspended by us.
   mPausedForInactiveDocument = false;
   // But we may want to suspend it now.
   // This will also do an AddRemoveSelfReference.
@@ -2014,19 +2105,21 @@ void nsHTMLMediaElement::ResourceLoaded(
 void nsHTMLMediaElement::NetworkError()
 {
   Error(nsIDOMMediaError::MEDIA_ERR_NETWORK);
 }
 
 void nsHTMLMediaElement::DecodeError()
 {
   if (mDecoder) {
+    RemoveMediaElementFromURITable();
     mDecoder->Shutdown();
     mDecoder = nsnull;
   }
+  mLoadingSrc = nsnull;
   if (mIsLoadingFromSourceChildren) {
     mError = nsnull;
     if (mSourceLoadCandidate) {
       DispatchAsyncSourceError(mSourceLoadCandidate);
       QueueLoadFromSourceTask();
     } else {
       NS_WARNING("Should know the source we were loading from!");
     }
@@ -2664,23 +2757,20 @@ void nsHTMLMediaElement::FireTimeUpdate(
     mFragmentEnd = -1.0;
     mFragmentStart = -1.0;
     mDecoder->SetEndTime(mFragmentEnd);
   }
 }
 
 void nsHTMLMediaElement::GetCurrentSpec(nsCString& aString)
 {
-  if (mDecoder) {
-    nsMediaStream* stream = mDecoder->GetCurrentStream();
-    if (stream) {
-      stream->URI()->GetSpec(aString);
-    }
-  } else if (mLoadingSrc) {
+  if (mLoadingSrc) {
     mLoadingSrc->GetSpec(aString);
+  } else {
+    aString.Truncate();
   }
 }
 
 /* attribute double initialTime; */
 NS_IMETHODIMP nsHTMLMediaElement::GetInitialTime(double *aTime)
 {
   // If there is no start fragment then the initalTime is zero.
   // Clamp to duration if it is greater than duration.
--- a/content/html/content/src/nsHTMLObjectElement.cpp
+++ b/content/html/content/src/nsHTMLObjectElement.cpp
@@ -47,16 +47,17 @@
 #include "nsIDOMDocument.h"
 #include "nsIDOMSVGDocument.h"
 #include "nsIDOMGetSVGDocument.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsFormSubmission.h"
 #include "nsIObjectFrame.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsIConstraintValidation.h"
+#include "nsIWidget.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 class nsHTMLObjectElement : public nsGenericHTMLFormElement
                           , public nsObjectLoadingContent
                           , public nsIDOMHTMLObjectElement
                           , public nsIConstraintValidation
@@ -111,17 +112,17 @@ public:
                               bool aNullParent = true);
   virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom *aName,
                            nsIAtom *aPrefix, const nsAString &aValue,
                            bool aNotify);
   virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
                              bool aNotify);
 
   virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, PRInt32 *aTabIndex);
-  virtual PRUint32 GetDesiredIMEState();
+  virtual IMEState GetDesiredIMEState();
 
   // Overriden nsIFormControl methods
   NS_IMETHOD_(PRUint32) GetType() const
   {
     return NS_FORM_OBJECT;
   }
 
   NS_IMETHOD Reset();
@@ -371,21 +372,21 @@ nsHTMLObjectElement::IsHTMLFocusable(boo
 
   if (aTabIndex && *aIsFocusable) {
     *aTabIndex = attrVal->GetIntegerValue();
   }
 
   return false;
 }
 
-PRUint32
+nsIContent::IMEState
 nsHTMLObjectElement::GetDesiredIMEState()
 {
   if (Type() == eType_Plugin) {
-    return nsIContent::IME_STATUS_PLUGIN;
+    return IMEState(IMEState::PLUGIN);
   }
    
   return nsGenericHTMLFormElement::GetDesiredIMEState();
 }
 
 NS_IMETHODIMP
 nsHTMLObjectElement::Reset()
 {
--- a/content/html/content/src/nsHTMLSharedObjectElement.cpp
+++ b/content/html/content/src/nsHTMLSharedObjectElement.cpp
@@ -45,16 +45,17 @@
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLAppletElement.h"
 #include "nsIDOMHTMLEmbedElement.h"
 #include "nsThreadUtils.h"
 #include "nsIDOMGetSVGDocument.h"
 #include "nsIDOMSVGDocument.h"
 #include "nsIScriptError.h"
+#include "nsIWidget.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 class nsHTMLSharedObjectElement : public nsGenericHTMLElement
                                 , public nsObjectLoadingContent
                                 , public nsIDOMHTMLAppletElement
                                 , public nsIDOMHTMLEmbedElement
@@ -114,17 +115,17 @@ public:
                               bool aCompileEventHandlers);
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true);
   virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom *aName,
                            nsIAtom *aPrefix, const nsAString &aValue,
                            bool aNotify);
 
   virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, PRInt32 *aTabIndex);
-  virtual PRUint32 GetDesiredIMEState();
+  virtual IMEState GetDesiredIMEState();
 
   virtual void DoneAddingChildren(bool aHaveNotified);
   virtual bool IsDoneAddingChildren();
 
   virtual bool ParseAttribute(PRInt32 aNamespaceID,
                                 nsIAtom *aAttribute,
                                 const nsAString &aValue,
                                 nsAttrValue &aResult);
@@ -360,21 +361,21 @@ nsHTMLSharedObjectElement::IsHTMLFocusab
 
     // Let the plugin decide, so override.
     return true;
   }
 
   return nsGenericHTMLElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex);
 }
 
-PRUint32
+nsIContent::IMEState
 nsHTMLSharedObjectElement::GetDesiredIMEState()
 {
   if (Type() == eType_Plugin) {
-    return nsIContent::IME_STATUS_PLUGIN;
+    return IMEState(IMEState::PLUGIN);
   }
    
   return nsGenericHTMLElement::GetDesiredIMEState();
 }
 
 NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Align, align)
 NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Alt, alt)
 NS_IMPL_STRING_ATTR(nsHTMLSharedObjectElement, Archive, archive)
--- a/content/media/nsBuiltinDecoder.cpp
+++ b/content/media/nsBuiltinDecoder.cpp
@@ -372,17 +372,17 @@ nsresult nsBuiltinDecoder::PlaybackRateC
 }
 
 double nsBuiltinDecoder::GetCurrentTime()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   return mCurrentTime;
 }
 
-nsMediaStream* nsBuiltinDecoder::GetCurrentStream()
+nsMediaStream* nsBuiltinDecoder::GetStream()
 {
   return mStream;
 }
 
 already_AddRefed<nsIPrincipal> nsBuiltinDecoder::GetCurrentPrincipal()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   return mStream ? mStream->GetCurrentPrincipal() : nsnull;
--- a/content/media/nsBuiltinDecoder.h
+++ b/content/media/nsBuiltinDecoder.h
@@ -400,17 +400,17 @@ class nsBuiltinDecoder : public nsMediaD
 
   virtual void Pause();
   virtual void SetVolume(double aVolume);
   virtual double GetDuration();
 
   virtual void SetInfinite(bool aInfinite);
   virtual bool IsInfinite();
 
-  virtual nsMediaStream* GetCurrentStream();
+  virtual nsMediaStream* GetStream();
   virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal();
 
   virtual void NotifySuspendedStatusChanged();
   virtual void NotifyBytesDownloaded();
   virtual void NotifyDownloadEnded(nsresult aStatus);
   // Called by the decode thread to keep track of the number of bytes read
   // from the resource.
   void NotifyBytesConsumed(PRInt64 aBytes);
--- a/content/media/nsBuiltinDecoderStateMachine.cpp
+++ b/content/media/nsBuiltinDecoderStateMachine.cpp
@@ -1566,17 +1566,17 @@ private:
   nsRefPtr<nsBuiltinDecoder> mDecoder;
   nsCOMPtr<nsBuiltinDecoderStateMachine> mStateMachine;
 };
 
 nsresult nsBuiltinDecoderStateMachine::RunStateMachine()
 {
   mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
-  nsMediaStream* stream = mDecoder->GetCurrentStream();
+  nsMediaStream* stream = mDecoder->GetStream();
   NS_ENSURE_TRUE(stream, NS_ERROR_NULL_POINTER);
 
   switch (mState) {
     case DECODER_STATE_SHUTDOWN: {
       if (IsPlaying()) {
         StopPlayback();
       }
       StopAudioThread();
@@ -1647,17 +1647,17 @@ nsresult nsBuiltinDecoderStateMachine::R
 
       TimeStamp now = TimeStamp::Now();
       NS_ASSERTION(!mBufferingStart.IsNull(), "Must know buffering start time.");
 
       // We will remain in the buffering state if we've not decoded enough
       // data to begin playback, or if we've not downloaded a reasonable
       // amount of data inside our buffering time.
       TimeDuration elapsed = now - mBufferingStart;
-      bool isLiveStream = mDecoder->GetCurrentStream()->GetLength() == -1;
+      bool isLiveStream = mDecoder->GetStream()->GetLength() == -1;
       if ((isLiveStream || !mDecoder->CanPlayThrough()) &&
             elapsed < TimeDuration::FromSeconds(mBufferingWait) &&
             (mQuickBuffering ? HasLowDecodedData(QUICK_BUFFERING_LOW_DATA_USECS)
                             : (GetUndecodedData() < mBufferingWait * USECS_PER_S / 1000)) &&
             !stream->IsDataCachedToEndOfStream(mDecoder->mDecoderPosition) &&
             !stream->IsSuspended())
       {
         LOG(PR_LOG_DEBUG,
@@ -1845,17 +1845,17 @@ void nsBuiltinDecoderStateMachine::Advan
         ? (DurationToUsecs(TimeStamp::Now() - mPlayStartTime) + mPlayDuration)
         : mPlayDuration;
       remainingTime = frame->mTime - mStartTime - now;
     }
   }
 
   // Check to see if we don't have enough data to play up to the next frame.
   // If we don't, switch to buffering mode.
-  nsMediaStream* stream = mDecoder->GetCurrentStream();
+  nsMediaStream* stream = mDecoder->GetStream();
   if (mState == DECODER_STATE_DECODING &&
       mDecoder->GetState() == nsBuiltinDecoder::PLAY_STATE_PLAYING &&
       HasLowDecodedData(remainingTime + EXHAUSTED_DATA_MARGIN_USECS) &&
       !stream->IsDataCachedToEndOfStream(mDecoder->mDecoderPosition) &&
       !stream->IsSuspended() &&
       (JustExitedQuickBuffering() || HasLowUndecodedData()))
   {
     if (currentFrame) {
@@ -2023,17 +2023,17 @@ void nsBuiltinDecoderStateMachine::Start
   nsMediaDecoder::Statistics stats = mDecoder->GetStatistics();
   LOG(PR_LOG_DEBUG, ("%p Playback rate: %.1lfKB/s%s download rate: %.1lfKB/s%s",
     mDecoder.get(),
     stats.mPlaybackRate/1024, stats.mPlaybackRateReliable ? "" : " (unreliable)",
     stats.mDownloadRate/1024, stats.mDownloadRateReliable ? "" : " (unreliable)"));
 }
 
 nsresult nsBuiltinDecoderStateMachine::GetBuffered(nsTimeRanges* aBuffered) {
-  nsMediaStream* stream = mDecoder->GetCurrentStream();
+  nsMediaStream* stream = mDecoder->GetStream();
   NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE);
   stream->Pin();
   nsresult res = mReader->GetBuffered(aBuffered, mStartTime);
   stream->Unpin();
   return res;
 }
 
 bool nsBuiltinDecoderStateMachine::IsPausedAndDecoderWaiting() {
--- a/content/media/nsMediaDecoder.cpp
+++ b/content/media/nsMediaDecoder.cpp
@@ -256,27 +256,27 @@ void nsMediaDecoder::SetVideoData(const 
 double nsMediaDecoder::GetFrameDelay()
 {
   MutexAutoLock lock(mVideoUpdateLock);
   return mPaintDelay.ToSeconds();
 }
 
 void nsMediaDecoder::PinForSeek()
 {
-  nsMediaStream* stream = GetCurrentStream();
+  nsMediaStream* stream = GetStream();
   if (!stream || mPinnedForSeek) {
     return;
   }
   mPinnedForSeek = true;
   stream->Pin();
 }
 
 void nsMediaDecoder::UnpinForSeek()
 {
-  nsMediaStream* stream = GetCurrentStream();
+  nsMediaStream* stream = GetStream();
   if (!stream || !mPinnedForSeek) {
     return;
   }
   mPinnedForSeek = false;
   stream->Unpin();
 }
 
 bool nsMediaDecoder::CanPlayThrough()
--- a/content/media/nsMediaDecoder.h
+++ b/content/media/nsMediaDecoder.h
@@ -86,18 +86,18 @@ public:
   virtual nsMediaDecoder* Clone() = 0;
 
   // Perform any initialization required for the decoder.
   // Return true on successful initialisation, false
   // on failure.
   virtual bool Init(nsHTMLMediaElement* aElement);
 
   // Get the current nsMediaStream being used. Its URI will be returned
-  // by currentSrc.
-  virtual nsMediaStream* GetCurrentStream() = 0;
+  // by currentSrc. Returns what was passed to Load(), if Load() has been called.
+  virtual nsMediaStream* GetStream() = 0;
 
   // Return the principal of the current URI being played or downloaded.
   virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal() = 0;
 
   // Return the time position in the video stream being
   // played measured in seconds.
   virtual double GetCurrentTime() = 0;
 
--- a/content/media/nsMediaStream.h
+++ b/content/media/nsMediaStream.h
@@ -164,17 +164,17 @@ class nsMediaStream
 public:
   virtual ~nsMediaStream()
   {
     MOZ_COUNT_DTOR(nsMediaStream);
   }
 
   // The following can be called on the main thread only:
   // Get the URI
-  nsIURI* URI() { return mURI; }
+  nsIURI* URI() const { return mURI; }
   // Close the stream, stop any listeners, channels, etc.
   // Cancels any currently blocking Read request and forces that request to
   // return an error.
   virtual nsresult Close() = 0;
   // Suspend any downloads that are in progress.
   // If aCloseImmediately is set, resources should be released immediately
   // since we don't expect to resume again any time soon. Otherwise we
   // may resume again soon so resources should be held for a little
--- a/content/media/ogg/nsOggReader.cpp
+++ b/content/media/ogg/nsOggReader.cpp
@@ -310,17 +310,17 @@ nsresult nsOggReader::ReadMetadata(nsVid
         LOG(PR_LOG_DEBUG, ("Got duration from Skeleton index %lld", duration));
       }
     }
   }
 
   {
     ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
 
-    nsMediaStream* stream = mDecoder->GetCurrentStream();
+    nsMediaStream* stream = mDecoder->GetStream();
     if (mDecoder->GetStateMachine()->GetDuration() == -1 &&
         mDecoder->GetStateMachine()->GetState() != nsDecoderStateMachine::DECODER_STATE_SHUTDOWN &&
         stream->GetLength() >= 0 &&
         mDecoder->GetStateMachine()->IsSeekable())
     {
       // We didn't get a duration from the index or a Content-Duration header.
       // Seek to the end of file to find the end time.
       PRInt64 length = stream->GetLength();
@@ -547,17 +547,17 @@ PRInt64 nsOggReader::ReadOggPage(ogg_pag
     // with the given size. This buffer is stored
     // in the ogg synchronisation structure.
     char* buffer = ogg_sync_buffer(&mOggState, 4096);
     NS_ASSERTION(buffer, "ogg_sync_buffer failed");
 
     // Read from the stream into the buffer
     PRUint32 bytesRead = 0;
 
-    nsresult rv = mDecoder->GetCurrentStream()->Read(buffer, 4096, &bytesRead);
+    nsresult rv = mDecoder->GetStream()->Read(buffer, 4096, &bytesRead);
     if (NS_FAILED(rv) || (bytesRead == 0 && ret == 0)) {
       // End of file.
       return -1;
     }
 
     mDecoder->NotifyBytesConsumed(bytesRead);
     // Update the synchronisation layer with the number
     // of bytes written to the buffer
@@ -611,17 +611,17 @@ GetChecksum(ogg_page* page)
                (p[2] << 16) +
                (p[3] << 24);
   return c;
 }
 
 PRInt64 nsOggReader::RangeStartTime(PRInt64 aOffset)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-  nsMediaStream* stream = mDecoder->GetCurrentStream();
+  nsMediaStream* stream = mDecoder->GetStream();
   NS_ENSURE_TRUE(stream != nsnull, nsnull);
   nsresult res = stream->Seek(nsISeekableStream::NS_SEEK_SET, aOffset);
   NS_ENSURE_SUCCESS(res, nsnull);
   PRInt64 startTime = 0;
   nsBuiltinDecoderReader::FindStartTime(startTime);
   return startTime;
 }
 
@@ -635,30 +635,30 @@ struct nsAutoOggSyncState {
   ogg_sync_state mState;
 };
 
 PRInt64 nsOggReader::RangeEndTime(PRInt64 aEndOffset)
 {
   NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
                "Should be on state machine or decode thread.");
 
-  nsMediaStream* stream = mDecoder->GetCurrentStream();
+  nsMediaStream* stream = mDecoder->GetStream();
   NS_ENSURE_TRUE(stream != nsnull, -1);
   PRInt64 position = stream->Tell();
   PRInt64 endTime = RangeEndTime(0, aEndOffset, false);
   nsresult res = stream->Seek(nsISeekableStream::NS_SEEK_SET, position);
   NS_ENSURE_SUCCESS(res, -1);
   return endTime;
 }
 
 PRInt64 nsOggReader::RangeEndTime(PRInt64 aStartOffset,
                                   PRInt64 aEndOffset,
                                   bool aCachedDataOnly)
 {
-  nsMediaStream* stream = mDecoder->GetCurrentStream();
+  nsMediaStream* stream = mDecoder->GetStream();
   nsAutoOggSyncState sync;
 
   // We need to find the last page which ends before aEndOffset that
   // has a granulepos that we can convert to a timestamp. We do this by
   // backing off from aEndOffset until we encounter a page on which we can
   // interpret the granulepos. If while backing off we encounter a page which
   // we've previously encountered before, we'll either backoff again if we
   // haven't found an end time yet, or return the last end time found.
@@ -765,17 +765,17 @@ PRInt64 nsOggReader::RangeEndTime(PRInt6
 
   return endTime;
 }
 
 nsresult nsOggReader::GetSeekRanges(nsTArray<SeekRange>& aRanges)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
   nsTArray<nsByteRange> cached;
-  nsresult res = mDecoder->GetCurrentStream()->GetCachedRanges(cached);
+  nsresult res = mDecoder->GetStream()->GetCachedRanges(cached);
   NS_ENSURE_SUCCESS(res, res);
 
   for (PRUint32 index = 0; index < cached.Length(); index++) {
     nsByteRange& range = cached[index];
     PRInt64 startTime = -1;
     PRInt64 endTime = -1;
     if (NS_FAILED(ResetDecode())) {
       return NS_ERROR_FAILURE;
@@ -804,17 +804,17 @@ nsOggReader::SeekRange
 nsOggReader::SelectSeekRange(const nsTArray<SeekRange>& ranges,
                              PRInt64 aTarget,
                              PRInt64 aStartTime,
                              PRInt64 aEndTime,
                              bool aExact)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
   PRInt64 so = 0;
-  PRInt64 eo = mDecoder->GetCurrentStream()->GetLength();
+  PRInt64 eo = mDecoder->GetStream()->GetLength();
   PRInt64 st = aStartTime;
   PRInt64 et = aEndTime;
   for (PRUint32 i = 0; i < ranges.Length(); i++) {
     const SeekRange &r = ranges[i];
     if (r.mTimeStart < aTarget) {
       so = r.mOffsetStart;
       st = r.mTimeStart;
     }
@@ -832,26 +832,26 @@ nsOggReader::SelectSeekRange(const nsTAr
     return SeekRange();
   }
   return SeekRange(so, eo, st, et);
 }
 
 nsOggReader::IndexedSeekResult nsOggReader::RollbackIndexedSeek(PRInt64 aOffset)
 {
   mSkeletonState->Deactivate();
-  nsMediaStream* stream = mDecoder->GetCurrentStream();
+  nsMediaStream* stream = mDecoder->GetStream();
   NS_ENSURE_TRUE(stream != nsnull, SEEK_FATAL_ERROR);
   nsresult res = stream->Seek(nsISeekableStream::NS_SEEK_SET, aOffset);
   NS_ENSURE_SUCCESS(res, SEEK_FATAL_ERROR);
   return SEEK_INDEX_FAIL;
 }
  
 nsOggReader::IndexedSeekResult nsOggReader::SeekToKeyframeUsingIndex(PRInt64 aTarget)
 {
-  nsMediaStream* stream = mDecoder->GetCurrentStream();
+  nsMediaStream* stream = mDecoder->GetStream();
   NS_ENSURE_TRUE(stream != nsnull, SEEK_FATAL_ERROR);
   if (!HasSkeleton() || !mSkeletonState->HasIndex()) {
     return SEEK_INDEX_FAIL;
   }
   // We have an index from the Skeleton track, try to use it to seek.
   nsAutoTArray<PRUint32, 2> tracks;
   if (HasVideo()) {
     tracks.AppendElement(mTheoraState->mSerial);
@@ -1009,17 +1009,17 @@ nsresult nsOggReader::SeekInUnbuffered(P
 nsresult nsOggReader::Seek(PRInt64 aTarget,
                            PRInt64 aStartTime,
                            PRInt64 aEndTime,
                            PRInt64 aCurrentTime)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
   LOG(PR_LOG_DEBUG, ("%p About to seek to %lld", mDecoder, aTarget));
   nsresult res;
-  nsMediaStream* stream = mDecoder->GetCurrentStream();
+  nsMediaStream* stream = mDecoder->GetStream();
   NS_ENSURE_TRUE(stream != nsnull, NS_ERROR_FAILURE);
 
   if (aTarget == aStartTime) {
     // We've seeked to the media start. Just seek to the offset of the first
     // content page.
     res = stream->Seek(nsISeekableStream::NS_SEEK_SET, 0);
     NS_ENSURE_SUCCESS(res,res);
 
@@ -1134,17 +1134,17 @@ PageSync(nsMediaStream* aStream,
 }
 
 nsresult nsOggReader::SeekBisection(PRInt64 aTarget,
                                     const SeekRange& aRange,
                                     PRUint32 aFuzz)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
   nsresult res;
-  nsMediaStream* stream = mDecoder->GetCurrentStream();
+  nsMediaStream* stream = mDecoder->GetStream();
 
   if (aTarget == aRange.mTimeStart) {
     if (NS_FAILED(ResetDecode())) {
       return NS_ERROR_FAILURE;
     }
     res = stream->Seek(nsISeekableStream::NS_SEEK_SET, 0);
     NS_ENSURE_SUCCESS(res,res);
     mPageOffset = 0;
@@ -1402,17 +1402,17 @@ nsresult nsOggReader::GetBuffered(nsTime
   // a deadlock. Accessing mInfo doesn't require a lock - it doesn't change
   // after metadata is read and GetBuffered isn't called before metadata is
   // read.
   if (!mInfo.mHasVideo && !mInfo.mHasAudio) {
     // No need to search through the file if there are no audio or video tracks
     return NS_OK;
   }
 
-  nsMediaStream* stream = mDecoder->GetCurrentStream();
+  nsMediaStream* stream = mDecoder->GetStream();
   nsTArray<nsByteRange> ranges;
   nsresult res = stream->GetCachedRanges(ranges);
   NS_ENSURE_SUCCESS(res, res);
 
   // Traverse across the buffered byte ranges, determining the time ranges
   // they contain. nsMediaStream::GetNextCachedData(offset) returns -1 when
   // offset is after the end of the media stream, or there's no more cached
   // data after the offset. This loop will run until we've checked every
--- a/content/media/raw/nsRawReader.cpp
+++ b/content/media/raw/nsRawReader.cpp
@@ -66,17 +66,17 @@ nsresult nsRawReader::ResetDecode()
   return nsBuiltinDecoderReader::ResetDecode();
 }
 
 nsresult nsRawReader::ReadMetadata(nsVideoInfo* aInfo)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(),
                "Should be on decode thread.");
 
-  nsMediaStream* stream = mDecoder->GetCurrentStream();
+  nsMediaStream* stream = mDecoder->GetStream();
   NS_ASSERTION(stream, "Decoder has no media stream");
 
   if (!ReadFromStream(stream, reinterpret_cast<PRUint8*>(&mMetadata),
                       sizeof(mMetadata)))
     return NS_ERROR_FAILURE;
 
   // Validate the header
   if (!(mMetadata.headerPacketID == 0 /* Packet ID of 0 for the header*/ &&
@@ -184,17 +184,17 @@ bool nsRawReader::DecodeVideoFrame(bool 
 
   if (!mFrameSize)
     return false; // Metadata read failed.  We should refuse to play.
 
   PRInt64 currentFrameTime = USECS_PER_S * mCurrentFrame / mFrameRate;
   PRUint32 length = mFrameSize - sizeof(nsRawPacketHeader);
 
   nsAutoArrayPtr<PRUint8> buffer(new PRUint8[length]);
-  nsMediaStream* stream = mDecoder->GetCurrentStream();
+  nsMediaStream* stream = mDecoder->GetStream();
   NS_ASSERTION(stream, "Decoder has no media stream");
 
   // We're always decoding one frame when called
   while(true) {
     nsRawPacketHeader header;
 
     // Read in a packet header and validate
     if (!(ReadFromStream(stream, reinterpret_cast<PRUint8*>(&header),
@@ -254,17 +254,17 @@ bool nsRawReader::DecodeVideoFrame(bool 
   return true;
 }
 
 nsresult nsRawReader::Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(),
                "Should be on decode thread.");
 
-  nsMediaStream *stream = mDecoder->GetCurrentStream();
+  nsMediaStream *stream = mDecoder->GetStream();
   NS_ASSERTION(stream, "Decoder has no media stream");
 
   PRUint32 frame = mCurrentFrame;
   if (aTime >= UINT_MAX)
     return NS_ERROR_FAILURE;
   mCurrentFrame = aTime * mFrameRate / USECS_PER_S;
 
   PRUint32 offset;
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -68,16 +68,17 @@ include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES = \
 		allowed.sjs \
 		can_play_type_ogg.js \
 		can_play_type_wave.js \
 		can_play_type_webm.js \
 		cancellable_request.sjs \
 		dynamic_redirect.sjs \
+		dynamic_resource.sjs \
 		file_access_controls.html \
 		fragment_play.js \
 		fragment_noplay.js \
 		manifest.js \
 		reactivate_helper.html \
 		redirect.sjs \
 		referer.sjs \
 		seek1.js \
@@ -115,16 +116,17 @@ include $(topsrcdir)/config/rules.mk
 		test_decode_error.html \
 		test_decoder_disable.html \
 		test_delay_load.html \
 		test_error_on_404.html \
 		test_error_in_video_document.html \
 		test_info_leak.html \
 		test_load.html \
 		test_load_candidates.html \
+		test_load_same_resource.html \
 		test_load_source.html \
 		test_loop.html \
 		test_media_selection.html \
 		test_mozLoadFrom.html \
 		test_networkState.html \
 		test_new_audio.html \
 		test_paused.html \
 		test_paused_after_ended.html \
--- a/content/media/test/allowed.sjs
+++ b/content/media/test/allowed.sjs
@@ -1,21 +1,36 @@
+function parseQuery(request, key) {
+  var params = request.queryString.split('&');
+  for (var j = 0; j < params.length; ++j) {
+    var p = params[j];
+	if (p == key)
+	  return true;
+    if (p.indexOf(key + "=") == 0)
+	  return p.substring(key.length + 1);
+	if (p.indexOf("=") < 0 && key == "")
+	  return p;
+  }
+  return false;
+}
+
 var types = {
   ogg: "video/ogg",
   ogv: "video/ogg",
   oga: "audio/ogg",
   webm: "video/webm",
   wav: "audio/x-wav"
 };
 
 // Return file with name as per the query string with access control
 // allow headers.
 function handleRequest(request, response)
 {
-  var resource = request.queryString;
+  var resource = parseQuery(request, "");
+
   var file = Components.classes["@mozilla.org/file/directory_service;1"].
                         getService(Components.interfaces.nsIProperties).
                         get("CurWorkD", Components.interfaces.nsILocalFile);
   var fis  = Components.classes['@mozilla.org/network/file-input-stream;1'].
                         createInstance(Components.interfaces.nsIFileInputStream);
   var bis  = Components.classes["@mozilla.org/binaryinputstream;1"].
                         createInstance(Components.interfaces.nsIBinaryInputStream);
   var paths = "tests/content/media/test/" + resource;
--- a/content/media/test/cancellable_request.sjs
+++ b/content/media/test/cancellable_request.sjs
@@ -1,8 +1,22 @@
+function parseQuery(request, key) {
+  var params = request.queryString.split('&');
+  for (var j = 0; j < params.length; ++j) {
+    var p = params[j];
+	if (p == key)
+	  return true;
+    if (p.indexOf(key + "=") == 0)
+	  return p.substring(key.length + 1);
+	if (p.indexOf("=") < 0 && key == "")
+	  return p;
+  }
+  return false;
+}
+
 function push32BE(array, input) {
   array.push(String.fromCharCode((input >> 24) & 0xff));
   array.push(String.fromCharCode((input >> 16) & 0xff));
   array.push(String.fromCharCode((input >> 8) & 0xff));
   array.push(String.fromCharCode((input) & 0xff));
 }
 
 function push32LE(array, input) {
@@ -55,31 +69,31 @@ function poll(f) {
   if (f()) {
     return;
   }
   new Timer(function() { poll(f); }, 100, Ci.nsITimer.TYPE_ONE_SHOT);
 }
 
 function handleRequest(request, response)
 {
-  var cancel = request.queryString.match(/^cancelkey=(.*)$/);
+  var cancel = parseQuery(request, "cancelkey");
   if (cancel) {
     setState(cancel[1], "cancelled");
     response.setStatusLine(request.httpVersion, 200, "OK");
     response.write("Cancel approved!");
     return;
   }
 
   var samples = [];
   for (var i = 0; i < 100000; ++i) {
     samples.push(0);
   }
   var bytes = buildWave(samples, 44100).join("");
 
-  var key = request.queryString.match(/^key=(.*)$/);
+  var key = parseQuery(request, "key");
   response.setHeader("Content-Type", "audio/x-wav");
   response.setHeader("Content-Length", ""+bytes.length, false);
 
   var out = new BinaryOutputStream(response.bodyOutputStream);
 
   var start = 0, end = bytes.length - 1;
   if (request.hasHeader("Range"))
   {
--- a/content/media/test/dynamic_redirect.sjs
+++ b/content/media/test/dynamic_redirect.sjs
@@ -1,14 +1,28 @@
+function parseQuery(request, key) {
+  var params = request.queryString.split('&');
+  for (var j = 0; j < params.length; ++j) {
+    var p = params[j];
+	if (p == key)
+	  return true;
+    if (p.indexOf(key + "=") == 0)
+	  return p.substring(key.length + 1);
+	if (p.indexOf("=") < 0 && key == "")
+	  return p;
+  }
+  return false;
+}
+
 // Return seek.ogv file content for the first request with a given key.
 // All subsequent requests return a redirect to a different-origin resource.
 function handleRequest(request, response)
 {
-  var key = (request.queryString.match(/^key=(.*)&/))[1];
-  var resource = (request.queryString.match(/res=(.*)$/))[1];
+  var key = parseQuery(request, "key");
+  var resource = parseQuery(request, "res");
 
   if (getState(key) == "redirect") {
     var origin = request.host == "mochi.test" ? "example.org" : "mochi.test:8888";
     response.setStatusLine(request.httpVersion, 303, "See Other");
     response.setHeader("Location", "http://" + origin + "/tests/content/media/test/" + resource);
     response.setHeader("Content-Type", "text/html");
     return;
   }
new file mode 100644
--- /dev/null
+++ b/content/media/test/dynamic_resource.sjs
@@ -0,0 +1,48 @@
+function parseQuery(request, key) {
+  var params = request.queryString.split('&');
+  for (var j = 0; j < params.length; ++j) {
+    var p = params[j];
+	if (p == key)
+	  return true;
+    if (p.indexOf(key + "=") == 0)
+	  return p.substring(key.length + 1);
+	if (p.indexOf("=") < 0 && key == "")
+	  return p;
+  }
+  return false;
+}
+
+// Return resource1 file content for the first request with a given key.
+// All subsequent requests return resource2. Both must be video/ogg.
+function handleRequest(request, response)
+{
+  var key = parseQuery(request, "key");
+  var resource1 = parseQuery(request, "res1");
+  var resource2 = parseQuery(request, "res2");
+
+  var resource = getState(key) == "2" ? resource2 : resource1;
+  setState(key, "2");
+
+  var file = Components.classes["@mozilla.org/file/directory_service;1"].
+                        getService(Components.interfaces.nsIProperties).
+                        get("CurWorkD", Components.interfaces.nsILocalFile);
+  var fis  = Components.classes['@mozilla.org/network/file-input-stream;1'].
+                        createInstance(Components.interfaces.nsIFileInputStream);
+  var bis  = Components.classes["@mozilla.org/binaryinputstream;1"].
+                        createInstance(Components.interfaces.nsIBinaryInputStream);
+  var paths = "tests/content/media/test/" + resource;
+  var split = paths.split("/");
+  for(var i = 0; i < split.length; ++i) {
+    file.append(split[i]);
+  }
+  fis.init(file, -1, -1, false);
+  dump("file=" + file + "\n");
+  bis.setInputStream(fis);
+  var bytes = bis.readBytes(bis.available());
+  response.setStatusLine(request.httpVersion, 206, "Partial Content");
+  response.setHeader("Content-Range", "bytes 0-" + (bytes.length - 1) + "/" + bytes.length);
+  response.setHeader("Content-Length", ""+bytes.length, false);
+  response.setHeader("Content-Type", "video/ogg", false);
+  response.write(bytes, bytes.length);
+  bis.close();
+}
--- a/content/media/test/file_access_controls.html
+++ b/content/media/test/file_access_controls.html
@@ -135,17 +135,23 @@ function nextTest() {
 
   gVideo = null;
   netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
   Components.utils.forceGC();  
   
   gVideo = createVideo();
   gVideo.expectedResult = gTests[gTestNum].result;
   gVideo.testDescription = gTests[gTestNum].description;
-  gVideo.src = gTests[gTestNum].url;
+  // Uniquify the resource URL to ensure that the resources loaded by earlier or subsequent tests
+  // don't overlap with the resources we load here, which are loaded with non-default preferences set.
+  // We also want to make sure that an HTTP fetch actually happens for each testcase.
+  var url = gTests[gTestNum].url;
+  var random = Math.floor(Math.random()*1000000000);
+  url += (url.search(/\?/) < 0 ? "?" : "&") + "rand=" + random;
+  gVideo.src = url;
   //dump("Starting test " + gTestNum + " at " + gVideo.src + " expecting:" + gVideo.expectedResult + "\n");
   if (!gTestedRemoved) {
     document.body.appendChild(gVideo); 
     // Will cause load() to be invoked.
   } else {
     gVideo.load();
   }
   gTestNum++;
--- a/content/media/test/manifest.js
+++ b/content/media/test/manifest.js
@@ -20,19 +20,23 @@ var gProgressTests = [
   { name:"seek.ogv", type:"video/ogg", duration:3.966, size:285310 },
   { name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.233, size:28942 },
   { name:"seek.webm", type:"video/webm", duration:3.966, size:215529 },
   { name:"bogus.duh", type:"bogus/duh" }
 ];
 
 // Used by test_mozLoadFrom.  Need one test file per decoder backend, plus
 // anything for testing clone-specific bugs.
+var cloneKey = Math.floor(Math.random()*100000000);
 var gCloneTests = gSmallTests.concat([
   // Actual duration is ~200ms, we have Content-Duration lie about it.
   { name:"bug520908.ogv", type:"video/ogg", duration:9000 },
+  // short-video is more like 1s, so if you load this twice you'll get an unexpected duration
+  { name:"dynamic_resource.sjs?key=" + cloneKey + "&res1=320x240.ogv&res2=short-video.ogv",
+    type:"video/ogg", duration:0.233 },
 ]);
 
 // Used by test_play_twice.  Need one test file per decoder backend, plus
 // anything for testing bugs that occur when replying a played file.
 var gReplayTests = gSmallTests.concat([
   { name:"bug533822.ogg", type:"audio/ogg" },
 ]);
 
@@ -332,42 +336,47 @@ function MediaTestManager() {
   this.runTests = function(tests, startTest) {
     this.startTime = new Date();
     SimpleTest.info("Started " + this.startTime + " (" + this.startTime.getTime()/1000 + "s)");
     this.testNum = 0;
     this.tests = tests;
     this.startTest = startTest;
     this.tokens = [];
     this.isShutdown = false;
+    this.numTestsRunning = 0;
     // Always wait for explicit finish.
     SimpleTest.waitForExplicitFinish();
     this.nextTest();
   }
   
   // Registers that the test corresponding to 'token' has been started.
   // Don't call more than once per token.
   this.started = function(token) {
     this.tokens.push(token);
+    this.numTestsRunning++;
+    is(this.numTestsRunning, this.tokens.length, "[started] Length of array should match number of running tests");
   }
   
   // Registers that the test corresponding to 'token' has finished. Call when
   // you've finished your test. If all tests are complete this will finish the
   // run, otherwise it may start up the next run. It's ok to call multiple times
   // per token.
   this.finished = function(token) {
     var i = this.tokens.indexOf(token);
     if (i != -1) {
       // Remove the element from the list of running tests.
       this.tokens.splice(i, 1);
     }
+    this.numTestsRunning--;
+    is(this.numTestsRunning, this.tokens.length, "[finished] Length of array should match number of running tests");
     if (this.tokens.length < PARALLEL_TESTS) {
       this.nextTest();
     }
   }
-  
+
   // Starts the next batch of tests, or finishes if they're all done.
   // Don't call this directly, call finished(token) when you're done.
   this.nextTest = function() {
     // Force a GC after every completed testcase. This ensures that any decoders
     // with live threads waiting for the GC are killed promptly, to free up the
     // thread stacks' address space.
     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
     Components.utils.forceGC();
--- a/content/media/test/redirect.sjs
+++ b/content/media/test/redirect.sjs
@@ -1,25 +1,26 @@
+function parseQuery(request, key) {
+  var params = request.queryString.split('&');
+  for (var j = 0; j < params.length; ++j) {
+    var p = params[j];
+	if (p == key)
+	  return true;
+    if (p.indexOf(key + "=") == 0)
+	  return p.substring(key.length + 1);
+	if (p.indexOf("=") < 0 && key == "")
+	  return p;
+  }
+  return false;
+}
+
 // Return file content for the first request with a given key.
 // All subsequent requests return a redirect to a different-origin resource.
 function handleRequest(request, response)
 {
-  var params = request.queryString.split('&');
-  var domain = null;
-  var file = null;
-  var allowed = false;
-
-  for (var i=0; i<params.length; i++) {
-    var kv = params[i].split('=');
-    if (kv.length == 1 && kv[0] == 'allowed') {
-      allowed = true;
-    } else if (kv.length == 2 && kv[0] == 'file') {
-      file = kv[1];
-    } else if (kv.length == 2 && kv[0] == 'domain') {
-      domain = kv[1];
-    }
-  }
+  var domain = parseQuery(request, "domain");
+  var file = parseQuery(request, "file");
+  var allowed = parseQuery(request, "allowed");
 
   response.setStatusLine(request.httpVersion, 303, "See Other");
   response.setHeader("Location", "http://" + domain + "/tests/content/media/test/" + (allowed ? "allowed.sjs?" : "") + file);
   response.setHeader("Content-Type", "text/html");
-
 }
--- a/content/media/test/referer.sjs
+++ b/content/media/test/referer.sjs
@@ -1,14 +1,29 @@
+function parseQuery(request, key) {
+  var params = request.queryString.split('&');
+  for (var j = 0; j < params.length; ++j) {
+    var p = params[j];
+	if (p == key)
+	  return true;
+    if (p.indexOf(key + "=") == 0)
+	  return p.substring(key.length + 1);
+	if (p.indexOf("=") < 0 && key == "")
+	  return p;
+  }
+  return false;
+}
+
 function handleRequest(request, response)
 {
   var referer = request.hasHeader("Referer") ? request.getHeader("Referer")
                                              : undefined; 
   if (referer == "http://mochi.test:8888/tests/content/media/test/test_referer.html") {
-    var [ignore, name, type] = request.queryString.match(/name=(.*)&type=(.*)$/);
+    var name = parseQuery(request, "name");
+	var type = parseQuery(request, "type");
     var file = Components.classes["@mozilla.org/file/directory_service;1"].
                           getService(Components.interfaces.nsIProperties).
                           get("CurWorkD", Components.interfaces.nsILocalFile);
     var fis  = Components.classes['@mozilla.org/network/file-input-stream;1'].
                           createInstance(Components.interfaces.nsIFileInputStream);
     var bis  = Components.classes["@mozilla.org/binaryinputstream;1"].
                           createInstance(Components.interfaces.nsIBinaryInputStream);
     var paths = "tests/content/media/test/" + name;
--- a/content/media/test/test_decoder_disable.html
+++ b/content/media/test/test_decoder_disable.html
@@ -72,21 +72,21 @@ function videoError(event, id) {
   gLoadError[id]++;
   gErrorCount++;
   if (gErrorCount >= 4) {
     finishTest();
   }
 }
 
 </script>
-
+<!-- We make the resource URIs unique to ensure that they are (re)loaded with the new disable-decoder prefs. -->
 <video id="video1">
-  <source type="video/ogg" src="320x240.ogv" onerror="videoError(event, 'video1');"/>
-  <source type="audio/wave" src="r11025_u8_c1.wav" id='s2' onerror="videoError(event, 'video1');"/>
+  <source type="video/ogg" src="320x240.ogv?decoder_disabled=1" onerror="videoError(event, 'video1');"/>
+  <source type="audio/wave" src="r11025_u8_c1.wav?decoder_disabled=1" id='s2' onerror="videoError(event, 'video1');"/>
 </video>
 
-<video id="video2" src="320x240.ogv" onerror="videoError(event, 'video2');"></video>
-<video id="video3" src="r11025_u8_c1.wav" onerror="videoError(event, 'video3');"></video>
+<video id="video2" src="320x240.ogv?decoder_disabled=2" onerror="videoError(event, 'video2');"></video>
+<video id="video3" src="r11025_u8_c1.wav?decoder_disabled=2" onerror="videoError(event, 'video3');"></video>
 
 </pre>
 
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_load_same_resource.html
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test loading of the same resource in multiple elements</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+</head>
+<body>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+var manager = new MediaTestManager;
+
+function cloneLoaded(event) {
+  ok(true, "Clone loaded OK");
+  var e = event.target;
+
+  if (e._expectedDuration) {
+    ok(Math.abs(e.duration - e._expectedDuration) < 0.1,
+       "Clone " + e.currentSrc + " duration: " + e.duration + " expected: " + e._expectedDuration);
+  }
+
+  manager.finished(e.token);
+}
+
+function tryClone(event) {
+  var e = event.target;
+  var clone = e.cloneNode(false);
+  clone.token = e.token;
+  
+  if (e._expectedDuration) {
+    ok(Math.abs(e.duration - e._expectedDuration) < 0.1,
+       e.currentSrc + " duration: " + e.duration + " expected: " + e._expectedDuration);
+    clone._expectedDuration = e._expectedDuration;
+  }
+
+  clone.addEventListener("loadeddata", cloneLoaded, false);
+}
+
+// This test checks that loading the same URI twice in different elements at the same time
+// uses the same resource without doing another network fetch. One of the gCloneTests
+// uses dynamic_resource.sjs to return one resource on the first fetch and a different resource
+// on the second fetch. These resources have different lengths, so if the cloned element
+// does a network fetch it will get a resource with the wrong length and we get a test
+// failure.
+
+function initTest(test, token) {
+  var elemType = /^audio/.test(test.type) ? "audio" : "video";
+  var e = document.createElement(elemType);
+  if (e.canPlayType(test.type)) {
+    e.src = test.name;
+    if (test.duration) {
+      e._expectedDuration = test.duration;
+    }
+    ok(true, "Trying to load " + test.name);
+    e.addEventListener("loadeddata", tryClone, false);
+    e.load();
+    e.token = token;
+    manager.started(token);
+  }
+}
+
+manager.runTests(gCloneTests, initTest);
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/media/test/test_playback.html
+++ b/content/media/test/test_playback.html
@@ -30,32 +30,32 @@ function startTest(test, token) {
     if (test.duration) {
       ok(Math.abs(v.currentTime - test.duration) < 0.1,
          test.name + " current time at end: " + v.currentTime + " should be: " + test.duration);
     }
     is(test.name, v.name, "Name should match test.name #2");
     is(v.readyState, v.HAVE_CURRENT_DATA, test.name + " checking readyState");
     ok(v.readyState != v.NETWORK_LOADED, test.name + " shouldn't report NETWORK_LOADED");
     ok(v.ended, test.name + " checking playback has ended");
-    if (v.ended && v.seenSuspend) {
-      if (v.parentNode)
-        v.parentNode.removeChild(v);
+    if (v.ended && v.seenSuspend && !v.finished) {
+      v.finished = true;
+      v.parentNode.removeChild(v);
       manager.finished(v.token);
     }
   }}(test, v);
   var checkSuspended = function(test, v) { return function() {
     is(test.name, v.name, "Name should match test.name #3");
     if (v.seenSuspend)
       return;
 
     v.seenSuspend = true;
     ok(true, test.name + " got suspend");
-    if (v.ended && v.seenSuspend) {
-      if (v.parentNode)
-        v.parentNode.removeChild(v);
+    if (v.ended && !v.finished) {
+      v.finished = true;
+      v.parentNode.removeChild(v);
       manager.finished(v.token);
     }
   }}(test, v);
   v.prevTime = 0;
   var timeUpdate = function(test, v) { return function() {
     is(test.name, v.name, "Name should match test.name #4");
     checkMetadata(test.name, v, test);
     ok(v.prevTime <= v.currentTime,
--- a/content/media/test/test_preload_actions.html
+++ b/content/media/test/test_preload_actions.html
@@ -25,16 +25,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 var manager = new MediaTestManager;
 
 manager.onFinished = function() {
   is(gotLoadEvent, true, "Should not have delayed the load event indefinitely");
 };
 
 var test = getPlayableVideo(gSeekTests);
+var baseName = test.name;
 var gTest = test;
 var bogusSrc = "bogus.duh";
 var bogusType = "video/bogus";
 var gotLoadEvent = false;
 var finished = false;
 
 addLoadEvent(function() {gotLoadEvent=true;});
 
@@ -139,18 +140,19 @@ var tests = [
       document.body.appendChild(v);
     },
   },
   {
     // 4. Add preload:none video to document. Call play(), should load then play through.
     suspend:
     function(e) {
       var v = e.target;
-      if (v._gotSuspend) 
+      if (v._gotSuspend) {
         return; // We can receive multiple suspend events, like the one after download completes.
+      }
       v._gotSuspend = true;
       is(v._gotLoadStart, true, "(4) Must get loadstart.");
       is(v._gotLoadedMetaData, false, "(4) Must not get loadedmetadata.");
       is(v.readyState, v.HAVE_NOTHING, "(4) ReadyState must be HAVE_NOTHING");
       is(v.networkState, v.NETWORK_IDLE, "(4) NetworkState must be NETWORK_IDLE");
       v.play(); // Should load and play through.
     },
     
@@ -552,21 +554,30 @@ var tests = [
       v.preload = "none";
       v.src = test.name; // Schedules async section to continue load algorithm.
       document.body.appendChild(v);
       v.play(); // Should cause preload:none to be overridden.
     },  
     }
 ];
 
+var iterationCount = 0;
 function startTest(test, token) {
+  if (test == tests[0]) {
+    ++iterationCount;
+  }
+  if (iterationCount == 2) {
+    // Do this series of tests on logically different resources
+    test.name = baseName + "?" + Math.floor(Math.random()*100000);
+  }
   var v = document.createElement("video");
   v.token = token;
   test.setup(v);
   manager.started(token);
 }
 
-manager.runTests(tests, startTest);
+var twiceTests = tests.concat(tests);
+manager.runTests(twiceTests, startTest);
 
 </script>
 </pre>
 </body>
 </html>
--- a/content/media/test/test_timeupdate_small_files.html
+++ b/content/media/test/test_timeupdate_small_files.html
@@ -41,29 +41,39 @@ function ended(e) {
       v.removeEventListener("ended", ended, false);
       v.removeEventListener("timeupdate", timeupdate, false);
       v.parentNode.removeChild(v);
       manager.finished(v.token);
     },
     500);
 }
 
+var eventsToLog = ["play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
+  "loadeddata", "playing", "progress", "timeupdate", "ended", "suspend", "error", "stalled", "emptied", "abort",
+  "waiting", "pause"];
+function logEvent(event) {
+  ok(true, event.target.currentSrc + " got " + event.type);
+}
+
 function startTest(test, token) {
   var type = /^video/.test(test.type) ? "video" : "audio";
   var v = document.createElement(type);
   v.token = token;
   manager.started(token);
   v.src = test.name;
   v._name = test.name;
   v._timeupdateCount = 0;
   v._finished = false;
   v.gotEnded = false;
   v.autoplay = true;
   v.addEventListener("ended", ended, false);
   v.addEventListener("timeupdate", timeupdate, false);
+  for (var i = 0; i < eventsToLog.length; ++i) {
+    v.addEventListener(eventsToLog[i], logEvent, false);
+  }
   document.body.appendChild(v);
 }
 
 manager.runTests(gSmallTests, startTest);
 
 </script>
 </pre>
 </body>
--- a/content/media/wave/nsWaveReader.cpp
+++ b/content/media/wave/nsWaveReader.cpp
@@ -256,52 +256,52 @@ nsresult nsWaveReader::Seek(PRInt64 aTar
   }
   double d = BytesToTime(GetDataLength());
   NS_ASSERTION(d < PR_INT64_MAX / USECS_PER_S, "Duration overflow"); 
   PRInt64 duration = static_cast<PRInt64>(d * USECS_PER_S);
   double seekTime = NS_MIN(aTarget, duration) / static_cast<double>(USECS_PER_S);
   PRInt64 position = RoundDownToFrame(static_cast<PRInt64>(TimeToBytes(seekTime)));
   NS_ASSERTION(PR_INT64_MAX - mWavePCMOffset > position, "Integer overflow during wave seek");
   position += mWavePCMOffset;
-  return mDecoder->GetCurrentStream()->Seek(nsISeekableStream::NS_SEEK_SET, position);
+  return mDecoder->GetStream()->Seek(nsISeekableStream::NS_SEEK_SET, position);
 }
 
 static double RoundToUsecs(double aSeconds) {
   return floor(aSeconds * USECS_PER_S) / USECS_PER_S;
 }
 
 nsresult nsWaveReader::GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime)
 {
-  PRInt64 startOffset = mDecoder->GetCurrentStream()->GetNextCachedData(mWavePCMOffset);
+  PRInt64 startOffset = mDecoder->GetStream()->GetNextCachedData(mWavePCMOffset);
   while (startOffset >= 0) {
-    PRInt64 endOffset = mDecoder->GetCurrentStream()->GetCachedDataEnd(startOffset);
+    PRInt64 endOffset = mDecoder->GetStream()->GetCachedDataEnd(startOffset);
     // Bytes [startOffset..endOffset] are cached.
     NS_ASSERTION(startOffset >= mWavePCMOffset, "Integer underflow in GetBuffered");
     NS_ASSERTION(endOffset >= mWavePCMOffset, "Integer underflow in GetBuffered");
 
     // We need to round the buffered ranges' times to microseconds so that they
     // have the same precision as the currentTime and duration attribute on 
     // the media element.
     aBuffered->Add(RoundToUsecs(BytesToTime(startOffset - mWavePCMOffset)),
                    RoundToUsecs(BytesToTime(endOffset - mWavePCMOffset)));
-    startOffset = mDecoder->GetCurrentStream()->GetNextCachedData(endOffset);
+    startOffset = mDecoder->GetStream()->GetNextCachedData(endOffset);
   }
   return NS_OK;
 }
 
 bool
 nsWaveReader::ReadAll(char* aBuf, PRInt64 aSize, PRInt64* aBytesRead)
 {
   PRUint32 got = 0;
   if (aBytesRead) {
     *aBytesRead = 0;
   }
   do {
     PRUint32 read = 0;
-    if (NS_FAILED(mDecoder->GetCurrentStream()->Read(aBuf + got, PRUint32(aSize - got), &read))) {
+    if (NS_FAILED(mDecoder->GetStream()->Read(aBuf + got, PRUint32(aSize - got), &read))) {
       NS_WARNING("Stream read failed");
       return false;
     }
     if (read == 0) {
       return false;
     }
     mDecoder->NotifyBytesConsumed(read);
     got += read;
@@ -313,17 +313,17 @@ nsWaveReader::ReadAll(char* aBuf, PRInt6
 }
 
 bool
 nsWaveReader::LoadRIFFChunk()
 {
   char riffHeader[RIFF_INITIAL_SIZE];
   const char* p = riffHeader;
 
-  NS_ABORT_IF_FALSE(mDecoder->GetCurrentStream()->Tell() == 0,
+  NS_ABORT_IF_FALSE(mDecoder->GetStream()->Tell() == 0,
                     "LoadRIFFChunk called when stream in invalid state");
 
   if (!ReadAll(riffHeader, sizeof(riffHeader))) {
     return false;
   }
 
   PR_STATIC_ASSERT(sizeof(PRUint32) * 2 <= RIFF_INITIAL_SIZE);
   if (ReadUint32BE(&p) != RIFF_CHUNK_MAGIC) {
@@ -385,17 +385,17 @@ nsWaveReader::ScanForwardUntil(PRUint32 
 bool
 nsWaveReader::LoadFormatChunk()
 {
   PRUint32 fmtSize, rate, channels, frameSize, sampleFormat;
   char waveFormat[WAVE_FORMAT_CHUNK_SIZE];
   const char* p = waveFormat;
 
   // RIFF chunks are always word (two byte) aligned.
-  NS_ABORT_IF_FALSE(mDecoder->GetCurrentStream()->Tell() % 2 == 0,
+  NS_ABORT_IF_FALSE(mDecoder->GetStream()->Tell() % 2 == 0,
                     "LoadFormatChunk called with unaligned stream");
 
   // The "format" chunk may not directly follow the "riff" chunk, so skip
   // over any intermediate chunks.
   if (!ScanForwardUntil(FRMT_CHUNK_MAGIC, &fmtSize)) {
     return false;
   }
 
@@ -450,17 +450,17 @@ nsWaveReader::LoadFormatChunk()
       nsAutoArrayPtr<char> chunkExtension(new char[extra]);
       if (!ReadAll(chunkExtension.get(), extra)) {
         return false;
       }
     }
   }
 
   // RIFF chunks are always word (two byte) aligned.
-  NS_ABORT_IF_FALSE(mDecoder->GetCurrentStream()->Tell() % 2 == 0,
+  NS_ABORT_IF_FALSE(mDecoder->GetStream()->Tell() % 2 == 0,
                     "LoadFormatChunk left stream unaligned");
 
   // Make sure metadata is fairly sane.  The rate check is fairly arbitrary,
   // but the channels check is intentionally limited to mono or stereo
   // because that's what the audio backend currently supports.
   if (rate < 100 || rate > 96000 ||
       channels < 1 || channels > MAX_CHANNELS ||
       (frameSize != 1 && frameSize != 2 && frameSize != 4) ||
@@ -480,27 +480,27 @@ nsWaveReader::LoadFormatChunk()
   }
   return true;
 }
 
 bool
 nsWaveReader::FindDataOffset()
 {
   // RIFF chunks are always word (two byte) aligned.
-  NS_ABORT_IF_FALSE(mDecoder->GetCurrentStream()->Tell() % 2 == 0,
+  NS_ABORT_IF_FALSE(mDecoder->GetStream()->Tell() % 2 == 0,
                     "FindDataOffset called with unaligned stream");
 
   // The "data" chunk may not directly follow the "format" chunk, so skip
   // over any intermediate chunks.
   PRUint32 length;
   if (!ScanForwardUntil(DATA_CHUNK_MAGIC, &length)) {
     return false;
   }
 
-  PRInt64 offset = mDecoder->GetCurrentStream()->Tell();
+  PRInt64 offset = mDecoder->GetStream()->Tell();
   if (offset <= 0 || offset > PR_UINT32_MAX) {
     NS_WARNING("PCM data offset out of range");
     return false;
   }
 
   ReentrantMonitorAutoEnter monitor(mDecoder->GetReentrantMonitor());
   mWaveLength = length;
   mWavePCMOffset = PRUint32(offset);
@@ -530,21 +530,21 @@ nsWaveReader::RoundDownToFrame(PRInt64 a
 
 PRInt64
 nsWaveReader::GetDataLength()
 {
   PRInt64 length = mWaveLength;
   // If the decoder has a valid content length, and it's shorter than the
   // expected length of the PCM data, calculate the playback duration from
   // the content length rather than the expected PCM data length.
-  PRInt64 streamLength = mDecoder->GetCurrentStream()->GetLength();
+  PRInt64 streamLength = mDecoder->GetStream()->GetLength();
   if (streamLength >= 0) {
     PRInt64 dataLength = NS_MAX<PRInt64>(0, streamLength - mWavePCMOffset);
     length = NS_MIN(dataLength, length);
   }
   return length;
 }
 
 PRInt64
 nsWaveReader::GetPosition()
 {
-  return mDecoder->GetCurrentStream()->Tell();
+  return mDecoder->GetStream()->Tell();
 }
--- a/content/media/webm/nsWebMReader.cpp
+++ b/content/media/webm/nsWebMReader.cpp
@@ -81,17 +81,17 @@ public:
 
 // Functions for reading and seeking using nsMediaStream required for
 // nestegg_io. The 'user data' passed to these functions is the
 // decoder from which the media stream is obtained.
 static int webm_read(void *aBuffer, size_t aLength, void *aUserData)
 {
   NS_ASSERTION(aUserData, "aUserData must point to a valid nsBuiltinDecoder");
   nsBuiltinDecoder* decoder = reinterpret_cast<nsBuiltinDecoder*>(aUserData);
-  nsMediaStream* stream = decoder->GetCurrentStream();
+  nsMediaStream* stream = decoder->GetStream();
   NS_ASSERTION(stream, "Decoder has no media stream");
 
   nsresult rv = NS_OK;
   bool eof = false;
 
   char *p = static_cast<char *>(aBuffer);
   while (NS_SUCCEEDED(rv) && aLength > 0) {
     PRUint32 bytes = 0;
@@ -107,27 +107,27 @@ static int webm_read(void *aBuffer, size
 
   return NS_FAILED(rv) ? -1 : eof ? 0 : 1;
 }
 
 static int webm_seek(int64_t aOffset, int aWhence, void *aUserData)
 {
   NS_ASSERTION(aUserData, "aUserData must point to a valid nsBuiltinDecoder");
   nsBuiltinDecoder* decoder = reinterpret_cast<nsBuiltinDecoder*>(aUserData);
-  nsMediaStream* stream = decoder->GetCurrentStream();
+  nsMediaStream* stream = decoder->GetStream();
   NS_ASSERTION(stream, "Decoder has no media stream");
   nsresult rv = stream->Seek(aWhence, aOffset);
   return NS_SUCCEEDED(rv) ? 0 : -1;
 }
 
 static int64_t webm_tell(void *aUserData)
 {
   NS_ASSERTION(aUserData, "aUserData must point to a valid nsBuiltinDecoder");
   nsBuiltinDecoder* decoder = reinterpret_cast<nsBuiltinDecoder*>(aUserData);
-  nsMediaStream* stream = decoder->GetCurrentStream();
+  nsMediaStream* stream = decoder->GetStream();
   NS_ASSERTION(stream, "Decoder has no media stream");
   return stream->Tell();
 }
 
 nsWebMReader::nsWebMReader(nsBuiltinDecoder* aDecoder)
   : nsBuiltinDecoderReader(aDecoder),
   mContext(nsnull),
   mPacketCount(0),
@@ -554,17 +554,17 @@ nsReturnRef<NesteggPacketHolder> nsWebMR
     // Keep reading packets until we find a packet
     // for the track we want.
     do {
       nestegg_packet* packet;
       int r = nestegg_read_packet(mContext, &packet);
       if (r <= 0) {
         return nsReturnRef<NesteggPacketHolder>();
       }
-      PRInt64 offset = mDecoder->GetCurrentStream()->Tell();
+      PRInt64 offset = mDecoder->GetStream()->Tell();
       holder.own(new NesteggPacketHolder(packet, offset));
 
       unsigned int track = 0;
       r = nestegg_packet_track(packet, &track);
       if (r == -1) {
         return nsReturnRef<NesteggPacketHolder>();
       }
 
@@ -764,31 +764,31 @@ nsresult nsWebMReader::Seek(PRInt64 aTar
   if (r != 0) {
     return NS_ERROR_FAILURE;
   }
   return DecodeToTarget(aTarget);
 }
 
 nsresult nsWebMReader::GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime)
 {
-  nsMediaStream* stream = mDecoder->GetCurrentStream();
+  nsMediaStream* stream = mDecoder->GetStream();
 
   uint64_t timecodeScale;
   if (!mContext || nestegg_tstamp_scale(mContext, &timecodeScale) == -1) {
     return NS_OK;
   }
 
   // Special case completely cached files.  This also handles local files.
   if (stream->IsDataCachedToEndOfStream(0)) {
     uint64_t duration = 0;
     if (nestegg_duration(mContext, &duration) == 0) {
       aBuffered->Add(0, duration / NS_PER_S);
     }
   } else {
-    nsMediaStream* stream = mDecoder->GetCurrentStream();
+    nsMediaStream* stream = mDecoder->GetStream();
     nsTArray<nsByteRange> ranges;
     nsresult res = stream->GetCachedRanges(ranges);
     NS_ENSURE_SUCCESS(res, res);
 
     PRInt64 startTimeOffsetNS = aStartTime * NS_PER_USEC;
     for (PRUint32 index = 0; index < ranges.Length(); index++) {
       mBufferedState->CalculateBufferedForRange(aBuffered,
                                                 ranges[index].mStart,
--- a/content/smil/nsSMILTimeValueSpec.cpp
+++ b/content/smil/nsSMILTimeValueSpec.cpp
@@ -329,16 +329,21 @@ nsSMILTimeValueSpec::RegisterEventListen
     "Attempting to register event-listener for unexpected nsSMILTimeValueSpec"
     " type");
   NS_ABORT_IF_FALSE(mParams.mEventSymbol,
     "Attempting to register event-listener but there is no event name");
 
   if (!aTarget)
     return;
 
+  // Don't listen for accessKey events if script is disabled. (see bug 704482)
+  if (mParams.mType == nsSMILTimeValueSpecParams::ACCESSKEY &&
+      !aTarget->GetOwnerDocument()->IsScriptEnabled())
+    return;
+
   if (!mEventListener) {
     mEventListener = new EventListener(this);
   }
 
   nsEventListenerManager* elm = GetEventListenerManager(aTarget);
   if (!elm)
     return;
 
--- a/content/svg/content/src/DOMSVGLengthList.cpp
+++ b/content/svg/content/src/DOMSVGLengthList.cpp
@@ -139,17 +139,17 @@ DOMSVGLengthList::InternalListLengthWill
 
   // If our length has increased, null out the new pointers:
   for (PRUint32 i = oldLength; i < aNewLength; ++i) {
     mItems[i] = nsnull;
   }
 }
 
 SVGLengthList&
-DOMSVGLengthList::InternalList()
+DOMSVGLengthList::InternalList() const
 {
   SVGAnimatedLengthList *alist = Element()->GetAnimatedLengthList(AttrEnum());
   return IsAnimValList() && alist->mAnimVal ? *alist->mAnimVal : alist->mBaseVal;
 }
 
 // ----------------------------------------------------------------------------
 // nsIDOMSVGLengthList implementation:
 
--- a/content/svg/content/src/DOMSVGLengthList.h
+++ b/content/svg/content/src/DOMSVGLengthList.h
@@ -98,30 +98,29 @@ public:
   };
 
   /**
    * This will normally be the same as InternalList().Length(), except if we've
    * hit OOM in which case our length will be zero.
    */
   PRUint32 Length() const {
     NS_ABORT_IF_FALSE(mItems.Length() == 0 ||
-                      mItems.Length() ==
-                        const_cast<DOMSVGLengthList*>(this)->InternalList().Length(),
+                      mItems.Length() == InternalList().Length(),
                       "DOM wrapper's list length is out of sync");
     return mItems.Length();
   }
 
   nsIDOMSVGLength* GetItemWithoutAddRef(PRUint32 aIndex);
 
   /// Called to notify us to syncronize our length and detach excess items.
   void InternalListLengthWillChange(PRUint32 aNewLength);
 
 private:
 
-  nsSVGElement* Element() {
+  nsSVGElement* Element() const {
     return mAList->mElement;
   }
 
   PRUint8 AttrEnum() const {
     return mAList->mAttrEnum;
   }
 
   PRUint8 Axis() const {
@@ -138,17 +137,17 @@ private:
   /**
    * Get a reference to this object's corresponding internal SVGLengthList.
    *
    * To simplify the code we just have this one method for obtaining both
    * baseVal and animVal internal lists. This means that animVal lists don't
    * get const protection, but our setter methods guard against changing
    * animVal lists.
    */
-  SVGLengthList& InternalList();
+  SVGLengthList& InternalList() const;
 
   /// Creates a DOMSVGLength for aIndex, if it doesn't already exist.
   void EnsureItemAt(PRUint32 aIndex);
 
   void MaybeInsertNullInAnimValListAt(PRUint32 aIndex);
   void MaybeRemoveItemFromAnimValListAt(PRUint32 aIndex);
 
   // Weak refs to our DOMSVGLength items. The items are friends and take care
--- a/content/svg/content/src/DOMSVGNumberList.cpp
+++ b/content/svg/content/src/DOMSVGNumberList.cpp
@@ -139,17 +139,17 @@ DOMSVGNumberList::InternalListLengthWill
 
   // If our length has increased, null out the new pointers:
   for (PRUint32 i = oldLength; i < aNewLength; ++i) {
     mItems[i] = nsnull;
   }
 }
 
 SVGNumberList&
-DOMSVGNumberList::InternalList()
+DOMSVGNumberList::InternalList() const
 {
   SVGAnimatedNumberList *alist = Element()->GetAnimatedNumberList(AttrEnum());
   return IsAnimValList() && alist->mAnimVal ? *alist->mAnimVal : alist->mBaseVal;
 }
 
 // ----------------------------------------------------------------------------
 // nsIDOMSVGNumberList implementation:
 
--- a/content/svg/content/src/DOMSVGNumberList.h
+++ b/content/svg/content/src/DOMSVGNumberList.h
@@ -97,30 +97,29 @@ public:
   }
 
   /**
    * This will normally be the same as InternalList().Length(), except if we've
    * hit OOM in which case our length will be zero.
    */
   PRUint32 Length() const {
     NS_ABORT_IF_FALSE(mItems.Length() == 0 ||
-                      mItems.Length() ==
-                        const_cast<DOMSVGNumberList*>(this)->InternalList().Length(),
+                      mItems.Length() == InternalList().Length(),
                       "DOM wrapper's list length is out of sync");
     return mItems.Length();
   }
 
   nsIDOMSVGNumber* GetItemWithoutAddRef(PRUint32 aIndex);
 
   /// Called to notify us to syncronize our length and detach excess items.
   void InternalListLengthWillChange(PRUint32 aNewLength);
 
 private:
 
-  nsSVGElement* Element() {
+  nsSVGElement* Element() const {
     return mAList->mElement;
   }
 
   PRUint8 AttrEnum() const {
     return mAList->mAttrEnum;
   }
 
   /// Used to determine if this list is the baseVal or animVal list.
@@ -133,17 +132,17 @@ private:
   /**
    * Get a reference to this object's corresponding internal SVGNumberList.
    *
    * To simplify the code we just have this one method for obtaining both
    * baseVal and animVal internal lists. This means that animVal lists don't
    * get const protection, but our setter methods guard against changing
    * animVal lists.
    */
-  SVGNumberList& InternalList();
+  SVGNumberList& InternalList() const;
 
   /// Creates a DOMSVGNumber for aIndex, if it doesn't already exist.
   void EnsureItemAt(PRUint32 aIndex);
 
   void MaybeInsertNullInAnimValListAt(PRUint32 aIndex);
   void MaybeRemoveItemFromAnimValListAt(PRUint32 aIndex);
 
   // Weak refs to our DOMSVGNumber items. The items are friends and take care
--- a/content/svg/content/src/DOMSVGPathSegList.cpp
+++ b/content/svg/content/src/DOMSVGPathSegList.cpp
@@ -225,28 +225,28 @@ DOMSVGPathSegList::InternalListWillChang
 
   NS_ABORT_IF_FALSE(dataIndex == dataLength, "Serious processing error");
   NS_ABORT_IF_FALSE(index == length, "Serious counting error");
 }
 
 bool
 DOMSVGPathSegList::AttrIsAnimating() const
 {
-  return const_cast<DOMSVGPathSegList*>(this)->InternalAList().IsAnimating();
+  return InternalAList().IsAnimating();
 }
 
 SVGPathData&
-DOMSVGPathSegList::InternalList()
+DOMSVGPathSegList::InternalList() const
 {
   SVGAnimatedPathSegList *alist = mElement->GetAnimPathSegList();
   return mIsAnimValList && alist->IsAnimating() ? *alist->mAnimVal : alist->mBaseVal;
 }
 
 SVGAnimatedPathSegList&
-DOMSVGPathSegList::InternalAList()
+DOMSVGPathSegList::InternalAList() const
 {
   NS_ABORT_IF_FALSE(mElement->GetAnimPathSegList(), "Internal error");
   return *mElement->GetAnimPathSegList();
 }
 
 // ----------------------------------------------------------------------------
 // nsIDOMSVGPathSegList implementation:
 
--- a/content/svg/content/src/DOMSVGPathSegList.h
+++ b/content/svg/content/src/DOMSVGPathSegList.h
@@ -115,18 +115,17 @@ public:
   GetDOMWrapperIfExists(void *aList);
 
   /**
    * This will normally be the same as InternalList().CountItems(), except if
    * we've hit OOM, in which case our length will be zero.
    */
   PRUint32 Length() const {
     NS_ABORT_IF_FALSE(mItems.Length() == 0 ||
-                      mItems.Length() ==
-                        const_cast<DOMSVGPathSegList*>(this)->InternalList().CountItems(),
+                      mItems.Length() == InternalList().CountItems(),
                       "DOM wrapper's list length is out of sync");
     return mItems.Length();
   }
 
   nsIDOMSVGPathSeg* GetItemWithoutAddRef(PRUint32 aIndex);
 
   /**
    * WATCH OUT! If you add code to call this on a baseVal wrapper, then you
@@ -179,19 +178,19 @@ private:
   /**
    * Get a reference to this object's corresponding internal SVGPathData.
    *
    * To simplify the code we just have this one method for obtaining both
    * base val and anim val internal lists. This means that anim val lists don't
    * get const protection, but our setter methods guard against changing
    * anim val lists.
    */
-  SVGPathData& InternalList();
+  SVGPathData& InternalList() const;
 
-  SVGAnimatedPathSegList& InternalAList();
+  SVGAnimatedPathSegList& InternalAList() const;
 
   /// Creates an instance of the appropriate DOMSVGPathSeg sub-class for
   // aIndex, if it doesn't already exist.
   void EnsureItemAt(PRUint32 aIndex);
 
   void MaybeInsertNullInAnimValListAt(PRUint32 aIndex,
                                       PRUint32 aInternalIndex,
                                       PRUint32 aArgCountForItem);
--- a/content/svg/content/src/DOMSVGPointList.cpp
+++ b/content/svg/content/src/DOMSVGPointList.cpp
@@ -170,28 +170,28 @@ DOMSVGPointList::InternalListWillChangeT
   for (PRUint32 i = oldLength; i < newLength; ++i) {
     mItems[i] = nsnull;
   }
 }
 
 bool
 DOMSVGPointList::AttrIsAnimating() const
 {
-  return const_cast<DOMSVGPointList*>(this)->InternalAList().IsAnimating();
+  return InternalAList().IsAnimating();
 }
 
 SVGPointList&
-DOMSVGPointList::InternalList()
+DOMSVGPointList::InternalList() const
 {
   SVGAnimatedPointList *alist = mElement->GetAnimatedPointList();
   return mIsAnimValList && alist->IsAnimating() ? *alist->mAnimVal : alist->mBaseVal;
 }
 
 SVGAnimatedPointList&
-DOMSVGPointList::InternalAList()
+DOMSVGPointList::InternalAList() const
 {
   NS_ABORT_IF_FALSE(mElement->GetAnimatedPointList(), "Internal error");
   return *mElement->GetAnimatedPointList();
 }
 
 // ----------------------------------------------------------------------------
 // nsIDOMSVGPointList implementation:
 
--- a/content/svg/content/src/DOMSVGPointList.h
+++ b/content/svg/content/src/DOMSVGPointList.h
@@ -115,18 +115,17 @@ public:
   GetDOMWrapperIfExists(void *aList);
 
   /**
    * This will normally be the same as InternalList().Length(), except if
    * we've hit OOM, in which case our length will be zero.
    */
   PRUint32 Length() const {
     NS_ABORT_IF_FALSE(mItems.Length() == 0 ||
-                      mItems.Length() ==
-                        const_cast<DOMSVGPointList*>(this)->InternalList().Length(),
+                      mItems.Length() == InternalList().Length(),
                       "DOM wrapper's list length is out of sync");
     return mItems.Length();
   }
 
   nsIDOMSVGPoint* GetItemWithoutAddRef(PRUint32 aIndex);
 
   /**
    * WATCH OUT! If you add code to call this on a baseVal wrapper, then you
@@ -179,19 +178,19 @@ private:
   /**
    * Get a reference to this object's corresponding internal SVGPointList.
    *
    * To simplify the code we just have this one method for obtaining both
    * base val and anim val internal lists. This means that anim val lists don't
    * get const protection, but our setter methods guard against changing
    * anim val lists.
    */
-  SVGPointList& InternalList();
+  SVGPointList& InternalList() const;
 
-  SVGAnimatedPointList& InternalAList();
+  SVGAnimatedPointList& InternalAList() const;
 
   /// Creates a DOMSVGPoint for aIndex, if it doesn't already exist.
   void EnsureItemAt(PRUint32 aIndex);
 
   void MaybeInsertNullInAnimValListAt(PRUint32 aIndex);
   void MaybeRemoveItemFromAnimValListAt(PRUint32 aIndex);
 
   // Weak refs to our DOMSVGPoint items. The items are friends and take care
--- a/content/svg/content/src/DOMSVGTransformList.cpp
+++ b/content/svg/content/src/DOMSVGTransformList.cpp
@@ -141,17 +141,17 @@ DOMSVGTransformList::InternalListLengthW
 
   // If our length has increased, null out the new pointers:
   for (PRUint32 i = oldLength; i < aNewLength; ++i) {
     mItems[i] = nsnull;
   }
 }
 
 SVGTransformList&
-DOMSVGTransformList::InternalList()
+DOMSVGTransformList::InternalList() const
 {
   SVGAnimatedTransformList *alist = Element()->GetAnimatedTransformList();
   return IsAnimValList() && alist->mAnimVal ?
     *alist->mAnimVal :
     alist->mBaseVal;
 }
 
 //----------------------------------------------------------------------
--- a/content/svg/content/src/DOMSVGTransformList.h
+++ b/content/svg/content/src/DOMSVGTransformList.h
@@ -92,30 +92,29 @@ public:
   }
 
   /**
    * This will normally be the same as InternalList().Length(), except if we've
    * hit OOM in which case our length will be zero.
    */
   PRUint32 Length() const {
     NS_ABORT_IF_FALSE(mItems.IsEmpty() ||
-      mItems.Length() ==
-        const_cast<DOMSVGTransformList*>(this)->InternalList().Length(),
+      mItems.Length() == InternalList().Length(),
       "DOM wrapper's list length is out of sync");
     return mItems.Length();
   }
 
   nsIDOMSVGTransform* GetItemWithoutAddRef(PRUint32 aIndex);
 
   /// Called to notify us to synchronize our length and detach excess items.
   void InternalListLengthWillChange(PRUint32 aNewLength);
 
 private:
 
-  nsSVGElement* Element() {
+  nsSVGElement* Element() const {
     return mAList->mElement;
   }
 
   /// Used to determine if this list is the baseVal or animVal list.
   bool IsAnimValList() const {
     NS_ABORT_IF_FALSE(this == mAList->mBaseVal || this == mAList->mAnimVal,
                       "Calling IsAnimValList() too early?!");
     return this == mAList->mAnimVal;
@@ -124,17 +123,17 @@ private:
   /**
    * Get a reference to this object's corresponding internal SVGTransformList.
    *
    * To simplify the code we just have this one method for obtaining both
    * baseVal and animVal internal lists. This means that animVal lists don't
    * get const protection, but our setter methods guard against changing
    * animVal lists.
    */
-  SVGTransformList& InternalList();
+  SVGTransformList& InternalList() const;
 
   /// Creates a DOMSVGTransform for aIndex, if it doesn't already exist.
   void EnsureItemAt(PRUint32 aIndex);
 
   void MaybeInsertNullInAnimValListAt(PRUint32 aIndex);
   void MaybeRemoveItemFromAnimValListAt(PRUint32 aIndex);
 
   // Weak refs to our DOMSVGTransform items. The items are friends and take care
--- a/content/xbl/src/nsXBLProtoImplMember.h
+++ b/content/xbl/src/nsXBLProtoImplMember.h
@@ -110,17 +110,17 @@ public:
 
   virtual nsresult InstallMember(nsIScriptContext* aContext,
                                  nsIContent* aBoundElement, 
                                  void* aScriptObject,
                                  void* aTargetClassObject,
                                  const nsCString& aClassStr) = 0;
   virtual nsresult CompileMember(nsIScriptContext* aContext,
                                  const nsCString& aClassStr,
-                                 void* aClassObject)=0;
+                                 JSObject* aClassObject) = 0;
 
   virtual void Trace(TraceCallback aCallback, void *aClosure) const = 0;
 
   virtual nsresult Write(nsIScriptContext* aContext,
                          nsIObjectOutputStream* aStream)
   {
     return NS_OK;
   }
--- a/content/xbl/src/nsXBLProtoImplMethod.cpp
+++ b/content/xbl/src/nsXBLProtoImplMethod.cpp
@@ -168,17 +168,17 @@ nsXBLProtoImplMethod::InstallMember(nsIS
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
   return NS_OK;
 }
 
 nsresult 
 nsXBLProtoImplMethod::CompileMember(nsIScriptContext* aContext, const nsCString& aClassStr,
-                                    void* aClassObject)
+                                    JSObject* aClassObject)
 {
   NS_TIME_FUNCTION_MIN(5);
   NS_PRECONDITION(!IsCompiled(),
                   "Trying to compile an already-compiled method");
   NS_PRECONDITION(aClassObject,
                   "Must have class object to compile");
 
   nsXBLUncompiledMethod* uncompiledMethod = GetUncompiledMethod();
@@ -234,23 +234,23 @@ nsXBLProtoImplMethod::CompileMember(nsIS
   if (hash != kNotFound) {
     functionUri.Truncate(hash);
   }
 
   JSObject* methodObject = nsnull;
   nsresult rv = aContext->CompileFunction(aClassObject,
                                           cname,
                                           paramCount,
-                                          (const char**)args,
+                                          const_cast<const char**>(args),
                                           body, 
                                           functionUri.get(),
                                           uncompiledMethod->mBodyText.GetLineNumber(),
                                           JSVERSION_LATEST,
                                           true,
-                                          (void **) &methodObject);
+                                          &methodObject);
 
   // Destroy our uncompiled method and delete our arg list.
   delete uncompiledMethod;
   delete [] args;
   if (NS_FAILED(rv)) {
     SetUncompiledMethod(nsnull);
     return rv;
   }
--- a/content/xbl/src/nsXBLProtoImplMethod.h
+++ b/content/xbl/src/nsXBLProtoImplMethod.h
@@ -122,17 +122,17 @@ public:
   
   virtual nsresult InstallMember(nsIScriptContext* aContext,
                                  nsIContent* aBoundElement, 
                                  void* aScriptObject,
                                  void* aTargetClassObject,
                                  const nsCString& aClassStr);
   virtual nsresult CompileMember(nsIScriptContext* aContext,
                                  const nsCString& aClassStr,
-                                 void* aClassObject);
+                                 JSObject* aClassObject);
 
   virtual void Trace(TraceCallback aCallback, void *aClosure) const;
 
   nsresult Read(nsIScriptContext* aContext, nsIObjectInputStream* aStream);
   virtual nsresult Write(nsIScriptContext* aContext, nsIObjectOutputStream* aStream);
 
   bool IsCompiled() const
   {
--- a/content/xbl/src/nsXBLProtoImplProperty.cpp
+++ b/content/xbl/src/nsXBLProtoImplProperty.cpp
@@ -217,17 +217,17 @@ nsXBLProtoImplProperty::InstallMember(ns
                                mJSAttributes))
       return NS_ERROR_OUT_OF_MEMORY;
   }
   return NS_OK;
 }
 
 nsresult 
 nsXBLProtoImplProperty::CompileMember(nsIScriptContext* aContext, const nsCString& aClassStr,
-                                      void* aClassObject)
+                                      JSObject* aClassObject)
 {
   NS_PRECONDITION(!mIsCompiled,
                   "Trying to compile an already-compiled property");
   NS_PRECONDITION(aClassObject,
                   "Must have class object to compile");
 
   if (!mName)
     return NS_ERROR_FAILURE; // Without a valid name, we can't install the member.
@@ -255,17 +255,17 @@ nsXBLProtoImplProperty::CompileMember(ns
                                      NS_ConvertUTF16toUTF8(mName),
                                      0,
                                      nsnull,
                                      getter, 
                                      functionUri.get(),
                                      mGetterText->GetLineNumber(),
                                      JSVERSION_LATEST,
                                      true,
-                                     (void **) &getterObject);
+                                     &getterObject);
 
       // Make sure we free mGetterText here before setting mJSGetterObject, since
       // that'll overwrite mGetterText
       delete mGetterText;
       deletedGetter = true;
       mJSGetterObject = getterObject;
     
       if (mJSGetterObject && NS_SUCCEEDED(rv)) {
@@ -305,17 +305,17 @@ nsXBLProtoImplProperty::CompileMember(ns
                                      NS_ConvertUTF16toUTF8(mName),
                                      1,
                                      gPropertyArgs,
                                      setter, 
                                      functionUri.get(),
                                      mSetterText->GetLineNumber(),
                                      JSVERSION_LATEST,
                                      true,
-                                     (void **) &setterObject);
+                                     &setterObject);
 
       // Make sure we free mSetterText here before setting mJSGetterObject, since
       // that'll overwrite mSetterText
       delete mSetterText;
       deletedSetter = true;
       mJSSetterObject = setterObject;
 
       if (mJSSetterObject && NS_SUCCEEDED(rv)) {
--- a/content/xbl/src/nsXBLProtoImplProperty.h
+++ b/content/xbl/src/nsXBLProtoImplProperty.h
@@ -67,17 +67,17 @@ public:
 
   virtual nsresult InstallMember(nsIScriptContext* aContext,
                                  nsIContent* aBoundElement, 
                                  void* aScriptObject,
                                  void* aTargetClassObject,
                                  const nsCString& aClassStr);
   virtual nsresult CompileMember(nsIScriptContext* aContext,
                                  const nsCString& aClassStr,
-                                 void* aClassObject);
+                                 JSObject* aClassObject);
 
   virtual void Trace(TraceCallback aCallback, void *aClosure) const;
 
   nsresult Read(nsIScriptContext* aContext,
                 nsIObjectInputStream* aStream,
                 XBLBindingSerializeDetails aType);
   virtual nsresult Write(nsIScriptContext* aContext,
                          nsIObjectOutputStream* aStream);
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -318,45 +318,45 @@ nsXBLPrototypeHandler::ExecuteHandler(ns
 
   rv = EnsureEventHandler(boundGlobal, boundContext, onEventAtom, handler);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Bind it to the bound element
   JSObject* scope = boundGlobal->GetGlobalJSObject();
   nsScriptObjectHolder boundHandler(boundContext);
   rv = boundContext->BindCompiledEventHandler(scriptTarget, scope,
-                                              handler, boundHandler);
+                                              handler.getObject(), boundHandler);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Execute it.
-  nsCOMPtr<nsIDOMEventListener> eventListener;
+  nsCOMPtr<nsIJSEventListener> eventListener;
   rv = NS_NewJSEventListener(boundContext, scope,
                              scriptTarget, onEventAtom,
-                             static_cast<JSObject*>(
-                               static_cast<void*>(boundHandler)),
+                             boundHandler.getObject(),
                              getter_AddRefs(eventListener));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Handle the event.
   eventListener->HandleEvent(aEvent);
+  eventListener->Disconnect();
   return NS_OK;
 }
 
 nsresult
 nsXBLPrototypeHandler::EnsureEventHandler(nsIScriptGlobalObject* aGlobal,
                                           nsIScriptContext *aBoundContext,
                                           nsIAtom *aName,
                                           nsScriptObjectHolder &aHandler)
 {
   // Check to see if we've already compiled this
   nsCOMPtr<nsPIDOMWindow> pWindow = do_QueryInterface(aGlobal);
   if (pWindow) {
-    void* cachedHandler = pWindow->GetCachedXBLPrototypeHandler(this);
+    JSObject* cachedHandler = pWindow->GetCachedXBLPrototypeHandler(this);
     if (cachedHandler) {
-      aHandler.set(cachedHandler);
+      aHandler.setObject(cachedHandler);
       return aHandler ? NS_OK : NS_ERROR_FAILURE;
     }
   }
 
   // Ensure that we have something to compile
   nsDependentString handlerText(mHandlerText);
   if (handlerText.IsEmpty())
     return NS_ERROR_FAILURE;
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -722,17 +722,17 @@ nsScriptEventHandlerOwnerTearoff::GetCom
 {
     XUL_PROTOTYPE_ATTRIBUTE_METER(gNumCacheTests);
     aHandler.drop();
 
     nsXULPrototypeAttribute *attr =
         mElement->FindPrototypeAttribute(kNameSpaceID_None, aName);
     if (attr) {
         XUL_PROTOTYPE_ATTRIBUTE_METER(gNumCacheHits);
-        aHandler.set(attr->mEventHandler);
+        aHandler.setObject(attr->mEventHandler);
     }
 
     return NS_OK;
 }
 
 nsresult
 nsScriptEventHandlerOwnerTearoff::CompileEventHandler(
                                                 nsIScriptContext* aContext,
@@ -810,17 +810,17 @@ nsScriptEventHandlerOwnerTearoff::Compil
                                                   elem,
                                                   &NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode),
                                                   aHandler,
                                                   elem->mHoldsScriptObject);
             if (NS_FAILED(rv)) return rv;
 
             elem->mHoldsScriptObject = true;
         }
-        attr->mEventHandler = (void *)aHandler;
+        attr->mEventHandler = aHandler.getObject();
     }
 
     return NS_OK;
 }
 
 void
 nsXULElement::AddListenerFor(const nsAttrName& aName,
                              bool aCompileEventHandlers)
@@ -2562,17 +2562,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_TRACE_NATIVE_BEGIN(nsXULPrototypeNode)
     if (tmp->mType == nsXULPrototypeNode::eType_Element) {
         nsXULPrototypeElement *elem =
             static_cast<nsXULPrototypeElement*>(tmp);
         if (elem->mHoldsScriptObject) {
             PRUint32 i;
             for (i = 0; i < elem->mNumAttributes; ++i) {
-                void *handler = elem->mAttributes[i].mEventHandler;
+                JSObject* handler = elem->mAttributes[i].mEventHandler;
                 NS_IMPL_CYCLE_COLLECTION_TRACE_CALLBACK(elem->mScriptTypeID,
                                                         handler,
                                                         "mAttributes[i].mEventHandler")
             }
         }
     }
     else if (tmp->mType == nsXULPrototypeNode::eType_Script) {
         nsXULPrototypeScript *script =
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -121,17 +121,17 @@ public:
 
     ~nsXULPrototypeAttribute();
 
     nsAttrName mName;
     nsAttrValue mValue;
     // mEventHandler is only valid for the language ID specified in the
     // containing nsXULPrototypeElement.  We would ideally use
     // nsScriptObjectHolder, but want to avoid the extra lang ID.
-    void* mEventHandler;
+    JSObject* mEventHandler;
 
 #ifdef XUL_PROTOTYPE_ATTRIBUTE_METERING
     /**
       If enough attributes, on average, are event handlers, it pays to keep
       mEventHandler here, instead of maintaining a separate mapping in each
       nsXULElement associating those mName values with their mEventHandlers.
       Assume we don't need to keep mNameSpaceID along with mName in such an
       event-handler-only name-to-function-pointer mapping.
--- a/dom/Makefile.in
+++ b/dom/Makefile.in
@@ -66,16 +66,17 @@ DIRS = \
   interfaces/notification \
   interfaces/svg \
   interfaces/smil \
   $(NULL)
 
 DIRS += \
   base \
   battery \
+  sms \
   src \
   locales \
   plugins/base \
   plugins/ipc \
   indexedDB \
   system \
   ipc \
   workers \
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -64,16 +64,18 @@
 #include "nsIScriptSecurityManager.h"
 #include "nsIJSContextStack.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsContentUtils.h"
 #include "nsUnicharUtils.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 #include "BatteryManager.h"
+#include "SmsManager.h"
+#include "nsISmsService.h"
 
 // This should not be in the namespace.
 DOMCI_DATA(Navigator, mozilla::dom::Navigator)
 
 namespace mozilla {
 namespace dom {
 
 static const char sJSStackContractID[] = "@mozilla.org/js/xpc/ContextStack;1";
@@ -101,25 +103,30 @@ Navigator::~Navigator()
 
   if (mPlugins) {
     mPlugins->Invalidate();
   }
 
   if (mBatteryManager) {
     mBatteryManager->Shutdown();
   }
+
+  if (mSmsManager) {
+    mSmsManager->Shutdown();
+  }
 }
 
 NS_INTERFACE_MAP_BEGIN(Navigator)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMNavigator)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigator)
   NS_INTERFACE_MAP_ENTRY(nsIDOMClientInformation)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorGeolocation)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozNavigatorBattery)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorDesktopNotification)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMMozNavigatorSms)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Navigator)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(Navigator)
 NS_IMPL_RELEASE(Navigator)
 
 void
 Navigator::SetDocShell(nsIDocShell* aDocShell)
@@ -140,16 +147,21 @@ Navigator::SetDocShell(nsIDocShell* aDoc
     mNotification->Shutdown();
     mNotification = nsnull;
   }
 
   if (mBatteryManager) {
     mBatteryManager->Shutdown();
     mBatteryManager = nsnull;
   }
+
+  if (mSmsManager) {
+    mSmsManager->Shutdown();
+    mSmsManager = nsnull;
+  }
 }
 
 //*****************************************************************************
 //    Navigator::nsIDOMNavigator
 //*****************************************************************************
 
 NS_IMETHODIMP
 Navigator::GetUserAgent(nsAString& aUserAgent)
@@ -520,16 +532,21 @@ Navigator::LoadingNewDocument()
     mNotification->Shutdown();
     mNotification = nsnull;
   }
 
   if (mBatteryManager) {
     mBatteryManager->Shutdown();
     mBatteryManager = nsnull;
   }
+
+  if (mSmsManager) {
+    mSmsManager->Shutdown();
+    mSmsManager = nsnull;
+  }
 }
 
 nsresult
 Navigator::RefreshMIMEArray()
 {
   if (mMimeTypes) {
     return mMimeTypes->Refresh();
   }
@@ -767,16 +784,112 @@ Navigator::GetMozBattery(nsIDOMMozBatter
     mBatteryManager->Init(window->GetCurrentInnerWindow(), scx);
   }
 
   NS_ADDREF(*aBattery = mBatteryManager);
 
   return NS_OK;
 }
 
+//*****************************************************************************
+//    Navigator::nsIDOMNavigatorSms
+//*****************************************************************************
+
+bool
+Navigator::IsSmsAllowed() const
+{
+  static const bool defaultSmsPermission = false;
+
+  // First of all, the general pref has to be turned on.
+  if (!Preferences::GetBool("dom.sms.enabled", defaultSmsPermission)) {
+    return false;
+  }
+
+  // In addition of having 'dom.sms.enabled' set to true, we require the
+  // website to be whitelisted. This is a temporary 'security model'.
+  // 'dom.sms.whitelist' has to contain comma-separated values of URI prepath.
+  // For local files, "file://" must be listed.
+  // For data-urls: "moz-nullprincipal:".
+  // Chrome files also have to be whitelisted for the moment.
+  nsCOMPtr<nsIDocument> doc = do_GetInterface(mDocShell);
+  if (!doc) {
+    return defaultSmsPermission;
+  }
+
+  nsCOMPtr<nsIURI> uri;
+  doc->NodePrincipal()->GetURI(getter_AddRefs(uri));
+
+  if (!uri) {
+    return defaultSmsPermission;
+  }
+
+  nsCAutoString uriPrePath;
+  uri->GetPrePath(uriPrePath);
+
+  const nsAdoptingString& whitelist =
+    Preferences::GetString("dom.sms.whitelist");
+
+  nsCharSeparatedTokenizer tokenizer(whitelist, ',',
+                                     nsCharSeparatedTokenizerTemplate<>::SEPARATOR_OPTIONAL);
+
+  while (tokenizer.hasMoreTokens()) {
+    const nsSubstring& whitelistItem = tokenizer.nextToken();
+
+    if (NS_ConvertUTF16toUTF8(whitelistItem).Equals(uriPrePath)) {
+      return true;
+    }
+  }
+
+  // The current page hasn't been whitelisted.
+  return false;
+}
+
+bool
+Navigator::IsSmsSupported() const
+{
+  nsCOMPtr<nsISmsService> smsService = do_GetService(SMSSERVICE_CONTRACTID);
+  NS_ENSURE_TRUE(smsService, false);
+
+  bool result = false;
+  smsService->HasSupport(&result);
+
+  return result;
+}
+
+NS_IMETHODIMP
+Navigator::GetMozSms(nsIDOMMozSmsManager** aSmsManager)
+{
+  *aSmsManager = nsnull;
+
+  if (!mSmsManager) {
+    if (!IsSmsSupported() || !IsSmsAllowed()) {
+      return NS_OK;
+    }
+
+    nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mDocShell);
+    NS_ENSURE_TRUE(window, NS_OK);
+
+    nsCOMPtr<nsIDocument> document = do_GetInterface(mDocShell);
+    NS_ENSURE_TRUE(document, NS_OK);
+
+    nsIScriptGlobalObject* sgo = document->GetScopeObject();
+    NS_ENSURE_TRUE(sgo, NS_OK);
+
+    nsIScriptContext* scx = sgo->GetContext();
+    NS_ENSURE_TRUE(scx, NS_OK);
+
+    mSmsManager = new sms::SmsManager();
+    mSmsManager->Init(window->GetCurrentInnerWindow(), scx);
+  }
+
+  NS_ADDREF(*aSmsManager = mSmsManager);
+
+  return NS_OK;
+}
+
 PRInt64
 Navigator::SizeOf() const
 {
   PRInt64 size = sizeof(*this);
 
   // TODO: add SizeOf() to nsMimeTypeArray, bug 674113.
   size += mMimeTypes ? sizeof(*mMimeTypes.get()) : 0;
   // TODO: add SizeOf() to nsPluginArray, bug 674114.
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -43,16 +43,17 @@
 #ifndef mozilla_dom_Navigator_h
 #define mozilla_dom_Navigator_h
 
 #include "nsIDOMNavigator.h"
 #include "nsIDOMNavigatorGeolocation.h"
 #include "nsIDOMNavigatorDesktopNotification.h"
 #include "nsIDOMClientInformation.h"
 #include "nsIDOMNavigatorBattery.h"
+#include "nsIDOMNavigatorSms.h"
 #include "nsAutoPtr.h"
 
 class nsPluginArray;
 class nsMimeTypeArray;
 class nsGeolocation;
 class nsDesktopNotificationCenter;
 class nsIDocShell;
 
@@ -62,32 +63,38 @@ class nsIDocShell;
 
 namespace mozilla {
 namespace dom {
 
 namespace battery {
 class BatteryManager;
 } // namespace battery
 
+namespace sms {
+class SmsManager;
+} // namespace sms
+
 class Navigator : public nsIDOMNavigator,
                   public nsIDOMClientInformation,
                   public nsIDOMNavigatorGeolocation,
                   public nsIDOMNavigatorDesktopNotification,
-                  public nsIDOMMozNavigatorBattery
+                  public nsIDOMMozNavigatorBattery,
+                  public nsIDOMMozNavigatorSms
 {
 public:
   Navigator(nsIDocShell *aDocShell);
   virtual ~Navigator();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMNAVIGATOR
   NS_DECL_NSIDOMCLIENTINFORMATION
   NS_DECL_NSIDOMNAVIGATORGEOLOCATION
   NS_DECL_NSIDOMNAVIGATORDESKTOPNOTIFICATION
   NS_DECL_NSIDOMMOZNAVIGATORBATTERY
+  NS_DECL_NSIDOMMOZNAVIGATORSMS
 
   static void Init();
 
   void SetDocShell(nsIDocShell *aDocShell);
   nsIDocShell *GetDocShell()
   {
     return mDocShell;
   }
@@ -95,23 +102,27 @@ public:
   void LoadingNewDocument();
   nsresult RefreshMIMEArray();
 
   static bool HasDesktopNotificationSupport();
 
   PRInt64 SizeOf() const;
 
 private:
+  bool IsSmsAllowed() const;
+  bool IsSmsSupported() const;
+
   static bool sDoNotTrackEnabled;
 
   nsRefPtr<nsMimeTypeArray> mMimeTypes;
   nsRefPtr<nsPluginArray> mPlugins;
   nsRefPtr<nsGeolocation> mGeolocation;
   nsRefPtr<nsDesktopNotificationCenter> mNotification;
   nsRefPtr<battery::BatteryManager> mBatteryManager;
+  nsRefPtr<sms::SmsManager> mSmsManager;
   nsIDocShell* mDocShell; // weak reference
 };
 
 } // namespace dom
 } // namespace mozilla
 
 nsresult NS_GetNavigatorUserAgent(nsAString& aUserAgent);
 nsresult NS_GetNavigatorPlatform(nsAString& aPlatform);
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -506,16 +506,19 @@
 #include "nsDOMTouchEvent.h"
 #include "nsIDOMCustomEvent.h"
 
 #include "nsWrapperCacheInlines.h"
 #include "dombindings.h"
 
 #include "nsIDOMBatteryManager.h"
 #include "BatteryManager.h"
+#include "nsIDOMSmsManager.h"
+#include "nsIDOMSmsMessage.h"
+#include "nsIDOMSmsEvent.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 static NS_DEFINE_CID(kDOMSOF_CID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
 
 static const char kDOMStringBundleURL[] =
   "chrome://global/locale/dom/dom.properties";
@@ -1383,16 +1386,25 @@ static nsDOMClassInfoData sClassInfoData
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(GeoPositionError, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MozBatteryManager, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
+  NS_DEFINE_CLASSINFO_DATA(MozSmsManager, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
+  NS_DEFINE_CLASSINFO_DATA(MozSmsMessage, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
+  NS_DEFINE_CLASSINFO_DATA(MozSmsEvent, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
   NS_DEFINE_CLASSINFO_DATA(CSSFontFaceRule, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(CSSFontFaceStyleDecl, nsCSSStyleDeclSH,
                            ARRAY_SCRIPTABLE_FLAGS)
 
 #if defined(MOZ_MEDIA)
   NS_DEFINE_CLASSINFO_DATA(HTMLVideoElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
@@ -2284,16 +2296,17 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(Navigator, nsIDOMNavigator)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigator)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorGeolocation)
     DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIDOMNavigatorDesktopNotification,
                                         Navigator::HasDesktopNotificationSupport())
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMClientInformation)
     DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIDOMMozNavigatorBattery,
                                         battery::BatteryManager::HasSupport())
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozNavigatorSms)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Plugin, nsIDOMPlugin)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMPlugin)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(PluginArray, nsIDOMPluginArray)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMPluginArray)
@@ -3866,16 +3879,29 @@ nsDOMClassInfo::Init()
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionError)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(MozBatteryManager, nsIDOMMozBatteryManager)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozBatteryManager)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(MozSmsManager, nsIDOMMozSmsManager)
+     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozSmsManager)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(MozSmsMessage, nsIDOMMozSmsMessage)
+     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozSmsMessage)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(MozSmsEvent, nsIDOMMozSmsEvent)
+     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozSmsEvent)
+     DOM_CLASSINFO_EVENT_MAP_ENTRIES
+  DOM_CLASSINFO_MAP_END
+
   DOM_CLASSINFO_MAP_BEGIN(CSSFontFaceRule, nsIDOMCSSFontFaceRule)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSFontFaceRule)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(CSSFontFaceStyleDecl,
                                       nsIDOMCSSStyleDeclaration)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSStyleDeclaration)
   DOM_CLASSINFO_MAP_END
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -423,16 +423,20 @@ DOMCI_CLASS(MessageEvent)
 DOMCI_CLASS(GeoGeolocation)
 DOMCI_CLASS(GeoPosition)
 DOMCI_CLASS(GeoPositionCoords)
 DOMCI_CLASS(GeoPositionAddress)
 DOMCI_CLASS(GeoPositionError)
 
 DOMCI_CLASS(MozBatteryManager)
 
+DOMCI_CLASS(MozSmsManager)
+DOMCI_CLASS(MozSmsMessage)
+DOMCI_CLASS(MozSmsEvent)
+
 // @font-face in CSS
 DOMCI_CLASS(CSSFontFaceRule)
 DOMCI_CLASS(CSSFontFaceStyleDecl)
 
 #if defined(MOZ_MEDIA)
 // WhatWG Video Element
 DOMCI_CLASS(HTMLVideoElement)
 DOMCI_CLASS(HTMLSourceElement)
--- a/dom/base/nsDOMScriptObjectHolder.h
+++ b/dom/base/nsDOMScriptObjectHolder.h
@@ -81,26 +81,36 @@ public:
     return !mObject;
   }
   operator void *() const {
     return mObject;
   }
   JSScript* getScript() const {
     return static_cast<JSScript*>(mObject);
   }
+  JSObject* getObject() const {
+    return static_cast<JSObject*>(mObject);
+  }
 
   // Drop the script object - but *not* the nsIScriptContext.
   nsresult drop() {
     nsresult rv = NS_OK;
     if (mObject) {
       rv = mContext->DropScriptObject(mObject);
       mObject = nsnull;
     }
     return rv;
   }
+
+  nsresult setScript(JSScript* aScript) {
+    return set(aScript);
+  }
+  nsresult setObject(JSObject* aObject) {
+    return set(aObject);
+  }
   nsresult set(void *object) {
     NS_ASSERTION(getScriptTypeID() != nsIProgrammingLanguage::UNKNOWN,
                  "Must know the language!");
     nsresult rv = drop();
     if (NS_FAILED(rv))
       return rv;
     if (object) {
       rv = mContext->HoldScriptObject(object);
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -81,16 +81,17 @@
 
 #include "Layers.h"
 #include "nsIIOService.h"
 
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::layers;
+using namespace mozilla::widget;
 
 static bool IsUniversalXPConnectCapable()
 {
   bool hasCap = false;
   nsresult rv = nsContentUtils::GetSecurityManager()->
                   IsCapabilityEnabled("UniversalXPConnect", &hasCap);
   NS_ENSURE_SUCCESS(rv, false);
   return hasCap;
@@ -1034,56 +1035,53 @@ nsDOMWindowUtils::GetIMEIsOpen(bool *aSt
 {
   NS_ENSURE_ARG_POINTER(aState);
 
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget)
     return NS_ERROR_FAILURE;
 
   // Open state should not be available when IME is not enabled.
-  IMEContext context;
-  nsresult rv = widget->GetInputMode(context);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (context.mStatus != nsIWidget::IME_STATUS_ENABLED)
+  InputContext context = widget->GetInputContext();
+  if (context.mIMEState.mEnabled != IMEState::ENABLED) {
     return NS_ERROR_NOT_AVAILABLE;
+  }
 
-  return widget->GetIMEOpenState(aState);
+  if (context.mIMEState.mOpen == IMEState::OPEN_STATE_NOT_SUPPORTED) {
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+  *aState = (context.mIMEState.mOpen == IMEState::OPEN);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetIMEStatus(PRUint32 *aState)
 {
   NS_ENSURE_ARG_POINTER(aState);
 
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget)
     return NS_ERROR_FAILURE;
 
-  IMEContext context;
-  nsresult rv = widget->GetInputMode(context);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *aState = context.mStatus;
+  InputContext context = widget->GetInputContext();
+  *aState = static_cast<PRUint32>(context.mIMEState.mEnabled);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetFocusedInputType(char** aType)
 {
   NS_ENSURE_ARG_POINTER(aType);
 
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget) {
     return NS_ERROR_FAILURE;
   }
 
-  IMEContext context;
-  nsresult rv = widget->GetInputMode(context);
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  InputContext context = widget->GetInputContext();
   *aType = ToNewCString(context.mHTMLInputType);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::FindElementWithViewId(nsViewID aID,
                                         nsIDOMElement** aResult)
 {
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -67,17 +67,16 @@
 #include "nsIContentViewer.h"
 #include "nsFrameTraversal.h"
 #include "nsObjectFrame.h"
 #include "nsEventDispatcher.h"
 #include "nsEventStateManager.h"
 #include "nsIMEStateManager.h"
 #include "nsIWebNavigation.h"
 #include "nsCaret.h"
-#include "nsIWidget.h"
 #include "nsIBaseWindow.h"
 #include "nsIViewManager.h"
 #include "nsFrameSelection.h"
 #include "nsXULPopupManager.h"
 #include "nsIDOMNodeFilter.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIPrincipal.h"
 #include "mozilla/dom/Element.h"
@@ -91,16 +90,17 @@
 #endif
 
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::dom;
+using namespace mozilla::widget;
 
 //#define DEBUG_FOCUS 1
 //#define DEBUG_FOCUS_NAVIGATION 1
 #define PRINTTAGF(format, content)                     \
   {                                                    \
     nsAutoString tag(NS_LITERAL_STRING("(none)"));     \
     if (content)                                       \
       content->Tag()->ToString(tag);                   \
@@ -332,29 +332,25 @@ nsFocusManager::GetRedirectedFocus(nsICo
     }
   }
 #endif
 
   return nsnull;
 }
 
 // static
-PRUint32
-nsFocusManager::GetFocusMoveReason(PRUint32 aFlags)
+InputContextAction::Cause
+nsFocusManager::GetFocusMoveActionCause(PRUint32 aFlags)
 {
-  PRUint32 reason = IMEContext::FOCUS_MOVED_UNKNOWN;
   if (aFlags & nsIFocusManager::FLAG_BYMOUSE) {
-    reason = IMEContext::FOCUS_MOVED_BY_MOUSE;
+    return InputContextAction::CAUSE_MOUSE;
   } else if (aFlags & nsIFocusManager::FLAG_BYKEY) {
-    reason = IMEContext::FOCUS_MOVED_BY_KEY;
-  } else if (aFlags & nsIFocusManager::FLAG_BYMOVEFOCUS) {
-    reason = IMEContext::FOCUS_MOVED_BY_MOVEFOCUS;
+    return InputContextAction::CAUSE_KEY;
   }
-
-  return reason;
+  return InputContextAction::CAUSE_UNKNOWN;
 }
 
 NS_IMETHODIMP
 nsFocusManager::GetActiveWindow(nsIDOMWindow** aWindow)
 {
   NS_IF_ADDREF(*aWindow = mActiveWindow);
   return NS_OK;
 }
@@ -959,17 +955,18 @@ nsFocusManager::WindowHidden(nsIDOMWindo
   }
 
   nsCOMPtr<nsIDocShell> focusedDocShell = mFocusedWindow->GetDocShell();
   nsCOMPtr<nsIPresShell> presShell;
   focusedDocShell->GetPresShell(getter_AddRefs(presShell));
 
   nsIMEStateManager::OnTextStateBlur(nsnull, nsnull);
   if (presShell) {
-    nsIMEStateManager::OnChangeFocus(presShell->GetPresContext(), nsnull, IMEContext::FOCUS_REMOVED);
+    nsIMEStateManager::OnChangeFocus(presShell->GetPresContext(), nsnull,
+                                     GetFocusMoveActionCause(0));
     SetCaretVisible(presShell, false, nsnull);
   }
 
   // if the docshell being hidden is being destroyed, then we want to move
   // focus somewhere else. Call ClearFocus on the toplevel window, which
   // will have the effect of clearing the focus and moving the focused window
   // to the toplevel window. But if the window isn't being destroyed, we are
   // likely just loading a new document in it, so we want to maintain the
@@ -1518,18 +1515,20 @@ nsFocusManager::Blur(nsPIDOMWindow* aWin
     mFirstBlurEvent = content;
     clearFirstBlurEvent = true;
   }
 
   // if there is still an active window, adjust the IME state.
   // This has to happen before the focus is cleared below, otherwise, the IME
   // compositionend event won't get fired at the element being blurred.
   nsIMEStateManager::OnTextStateBlur(nsnull, nsnull);
-  if (mActiveWindow)
-    nsIMEStateManager::OnChangeFocus(presShell->GetPresContext(), nsnull, IMEContext::FOCUS_REMOVED);
+  if (mActiveWindow) {
+    nsIMEStateManager::OnChangeFocus(presShell->GetPresContext(), nsnull,
+                                     GetFocusMoveActionCause(0));
+  }
 
   // now adjust the actual focus, by clearing the fields in the focus manager
   // and in the window.
   mFocusedContent = nsnull;
   bool shouldShowFocusRing = window->ShouldShowFocusRing();
   if (aWindowToClear)
     aWindowToClear->SetFocusedNode(nsnull);
 
@@ -1781,34 +1780,35 @@ nsFocusManager::Focus(nsPIDOMWindow* aWi
         if (remote) {
           remote->Activate();
 #ifdef DEBUG_FOCUS
           printf("*Remote browser activated\n");
 #endif
         }
       }
 
-      PRUint32 reason = GetFocusMoveReason(aFlags);
-      nsIMEStateManager::OnChangeFocus(presContext, aContent, reason);
+      nsIMEStateManager::OnChangeFocus(presContext, aContent,
+                                       GetFocusMoveActionCause(aFlags));
 
       // as long as this focus wasn't because a window was raised, update the
       // commands
       // XXXndeakin P2 someone could adjust the focus during the update
       if (!aWindowRaised)
         aWindow->UpdateCommands(NS_LITERAL_STRING("focus"));
 
       SendFocusOrBlurEvent(NS_FOCUS_CONTENT, presShell,
                            aContent->GetCurrentDoc(),
                            aContent, aFlags & FOCUSMETHOD_MASK,
                            aWindowRaised, isRefocus);
 
       nsIMEStateManager::OnTextStateFocus(presContext, aContent);
     } else {
       nsIMEStateManager::OnTextStateBlur(presContext, nsnull);
-      nsIMEStateManager::OnChangeFocus(presContext, nsnull, IMEContext::FOCUS_REMOVED);
+      nsIMEStateManager::OnChangeFocus(presContext, nsnull,
+                                       GetFocusMoveActionCause(aFlags));
       if (!aWindowRaised) {
         aWindow->UpdateCommands(NS_LITERAL_STRING("focus"));
       }
     }
   }
   else {
     // If the window focus event (fired above when aIsNewDocument) caused
     // the plugin not to be focusable, update the system focus by focusing
@@ -1821,17 +1821,18 @@ nsFocusManager::Focus(nsPIDOMWindow* aWi
         vm->GetRootWidget(getter_AddRefs(widget));
         if (widget)
           widget->SetFocus(false);
       }
     }
 
     nsPresContext* presContext = presShell->GetPresContext();
     nsIMEStateManager::OnTextStateBlur(presContext, nsnull);
-    nsIMEStateManager::OnChangeFocus(presContext, nsnull, IMEContext::FOCUS_REMOVED);
+    nsIMEStateManager::OnChangeFocus(presContext, nsnull,
+                                     GetFocusMoveActionCause(aFlags));
 
     if (!aWindowRaised)
       aWindow->UpdateCommands(NS_LITERAL_STRING("focus"));
   }
 
   // update the caret visibility and position to match the newly focused
   // element. However, don't update the position if this was a focus due to a
   // mouse click as the selection code would already have moved the caret as
--- a/dom/base/nsFocusManager.h
+++ b/dom/base/nsFocusManager.h
@@ -36,16 +36,17 @@
 
 #ifndef nsFocusManager_h___
 #define nsFocusManager_h___
 
 #include "nsIFocusManager.h"
 #include "nsWeakReference.h"
 #include "nsIObserver.h"
 #include "nsIContent.h"
+#include "nsIWidget.h"
 
 #define FOCUSMETHOD_MASK 0xF000
 #define FOCUSMETHODANDRING_MASK 0xF0F000
 
 #define FOCUSMANAGER_CONTRACTID "@mozilla.org/focus-manager;1"
 
 class nsIDocShellTreeItem;
 class nsPIDOMWindow;
@@ -62,16 +63,18 @@ struct nsDelayedBlurOrFocusEvent;
  * The focus manager keeps track of where the focus is, that is, the node
  * which receives key events.
  */
 
 class nsFocusManager : public nsIFocusManager,
                        public nsIObserver,
                        public nsSupportsWeakReference
 {
+  typedef mozilla::widget::InputContextAction InputContextAction;
+
 public:
 
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFocusManager, nsIFocusManager)
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_NSIOBSERVER
   NS_DECL_NSIFOCUSMANAGER
 
   // called to initialize and stop the focus manager at startup and shutdown
@@ -126,21 +129,19 @@ public:
    * aContent must be non-null.
    *
    * XXXndeakin this should be removed eventually but I want to do that as
    * followup work.
    */
   static nsIContent* GetRedirectedFocus(nsIContent* aContent);
 
   /**
-   * Returns a flag indicating the source and/or reason of the focus change.
-   * This is used to indicate to the IME code if the focus come from a user 
-   * input or a script for example.
+   * Returns an InputContextAction cause for aFlags.
    */
-  static PRUint32 GetFocusMoveReason(PRUint32 aFlags);
+  static InputContextAction::Cause GetFocusMoveActionCause(PRUint32 aFlags);
 
   static bool sMouseFocusesFormControl;
 
 protected:
 
   nsFocusManager();
   ~nsFocusManager();
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1487,17 +1487,17 @@ struct TraceData
   TraceData(TraceCallback& aCallback, void* aClosure) :
     callback(aCallback), closure(aClosure) {}
 
   TraceCallback& callback;
   void* closure;
 };
 
 static PLDHashOperator
-TraceXBLHandlers(const void* aKey, void* aData, void* aClosure)
+TraceXBLHandlers(const void* aKey, JSObject* aData, void* aClosure)
 {
   TraceData* data = static_cast<TraceData*>(aClosure);
   data->callback(nsIProgrammingLanguage::JAVASCRIPT, aData,
                  "Cached XBL prototype handler", data->closure);
   return PL_DHASH_NEXT;
 }
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGlobalWindow)
@@ -2072,23 +2072,22 @@ nsGlobalWindow::SetNewDocument(nsIDocume
       // cx->globalObject, i.e. this outer window].
 
       mInnerWindow = nsnull;
 
       Freeze();
       mCreatingInnerWindow = true;
       // Every script context we are initialized with must create a
       // new global.
-      void *&newGlobal = (void *&)newInnerWindow->mJSObject;
       nsCOMPtr<nsIXPConnectJSObjectHolder> &holder = mInnerWindowHolder;
       rv = mContext->CreateNativeGlobalForInner(sgo, isChrome,
                                                 aDocument->NodePrincipal(),
-                                                &newGlobal,
+                                                &newInnerWindow->mJSObject,
                                                 getter_AddRefs(holder));
-      NS_ASSERTION(NS_SUCCEEDED(rv) && newGlobal && holder,
+      NS_ASSERTION(NS_SUCCEEDED(rv) && newInnerWindow->mJSObject && holder,
                    "Failed to get script global and holder");
 
       mCreatingInnerWindow = false;
       Thaw();
 
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
@@ -3953,26 +3952,26 @@ nsGlobalWindow::GetMozPaintCount(PRUint6
   if (!presShell)
     return NS_OK;
 
   *aResult = presShell->GetPaintCount();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsGlobalWindow::MozRequestAnimationFrame(nsIAnimationFrameListener* aListener)
-{
-  FORWARD_TO_INNER(MozRequestAnimationFrame, (aListener),
+nsGlobalWindow::MozRequestAnimationFrame(nsIFrameRequestCallback* aCallback)
+{
+  FORWARD_TO_INNER(MozRequestAnimationFrame, (aCallback),
                    NS_ERROR_NOT_INITIALIZED);
 
   if (!mDoc) {
     return NS_OK;
   }
 
-  mDoc->ScheduleBeforePaintEvent(aListener);
+  mDoc->ScheduleFrameRequestCallback(aCallback);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::GetMozAnimationStartTime(PRInt64 *aTime)
 {
   FORWARD_TO_INNER(GetMozAnimationStartTime, (aTime), NS_ERROR_NOT_INITIALIZED);
 
@@ -5558,25 +5557,33 @@ nsGlobalWindow::ScrollByPages(PRInt32 nu
     sf->ScrollBy(nsIntPoint(0, numPages), nsIScrollableFrame::PAGES,
                  nsIScrollableFrame::INSTANT);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsGlobalWindow::ClearTimeout()
-{
-  return ClearTimeoutOrInterval();
-}
-
-NS_IMETHODIMP
-nsGlobalWindow::ClearInterval()
-{
-  return ClearTimeoutOrInterval();
+nsGlobalWindow::ClearTimeout(PRInt32 aHandle)
+{
+  if (aHandle <= 0) {
+    return NS_OK;
+  }
+
+  return ClearTimeoutOrInterval(aHandle);
+}
+
+NS_IMETHODIMP
+nsGlobalWindow::ClearInterval(PRInt32 aHandle)
+{
+  if (aHandle <= 0) {
+    return NS_OK;
+  }
+
+  return ClearTimeoutOrInterval(aHandle);
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::SetTimeout(PRInt32 *_retval)
 {
   return SetTimeoutOrInterval(false, _retval);
 }
 
@@ -6928,20 +6935,20 @@ nsGlobalWindow::InitJavaProperties()
     return;
   }
 
   // No NPRuntime enabled Java plugin found, null out the owner we
   // would have used in that case as it's no longer needed.
   mDummyJavaPluginOwner = nsnull;
 }
 
-void*
+JSObject*
 nsGlobalWindow::GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey)
 {
-  void* handler = nsnull;
+  JSObject* handler = nsnull;
   if (mCachedXBLPrototypeHandlers.IsInitialized()) {
     mCachedXBLPrototypeHandlers.Get(aKey, &handler);
   }
   return handler;
 }
 
 void
 nsGlobalWindow::CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
@@ -6968,17 +6975,17 @@ nsGlobalWindow::CacheXBLPrototypeHandler
 
     nsresult rv = nsContentUtils::HoldJSObjects(thisSupports, participant);
     if (NS_FAILED(rv)) {
       NS_ERROR("nsContentUtils::HoldJSObjects failed!");
       return;
     }
   }
 
-  mCachedXBLPrototypeHandlers.Put(aKey, aHandler);
+  mCachedXBLPrototypeHandlers.Put(aKey, aHandler.getObject());
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::GetFrameElement(nsIDOMElement** aFrameElement)
 {
   FORWARD_TO_OUTER(GetFrameElement, (aFrameElement), NS_ERROR_NOT_INITIALIZED);
 
   *aFrameElement = nsnull;
@@ -7374,16 +7381,18 @@ nsGlobalWindow::RemoveEventListener(cons
 {
   nsRefPtr<nsEventListenerManager> elm = GetListenerManager(false);
   if (elm) {
     elm->RemoveEventListener(aType, aListener, aUseCapture);
   }
   return NS_OK;
 }
 
+NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsGlobalWindow)
+
 NS_IMETHODIMP
 nsGlobalWindow::DispatchEvent(nsIDOMEvent* aEvent, bool* aRetVal)
 {
   FORWARD_TO_INNER(DispatchEvent, (aEvent, aRetVal), NS_OK);
 
   if (!mDoc) {
     return NS_ERROR_FAILURE;
   }
@@ -7427,16 +7436,42 @@ nsGlobalWindow::AddEventListener(const n
   }
 
   nsEventListenerManager* manager = GetListenerManager(true);
   NS_ENSURE_STATE(manager);
   manager->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsGlobalWindow::AddSystemEventListener(const nsAString& aType,
+                                       nsIDOMEventListener *aListener,
+                                       bool aUseCapture,
+                                       bool aWantsUntrusted,
+                                       PRUint8 aOptionalArgc)
+{
+  NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
+               "Won't check if this is chrome, you want to set "
+               "aWantsUntrusted to false or make the aWantsUntrusted "
+               "explicit by making optional_argc non-zero.");
+
+  if (IsOuterWindow() && mInnerWindow &&
+      !nsContentUtils::CanCallerAccess(mInnerWindow)) {
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+
+  if (!aWantsUntrusted &&
+      (aOptionalArgc < 2 && !nsContentUtils::IsChromeDoc(mDoc))) {
+    aWantsUntrusted = true;
+  }
+
+  return NS_AddSystemEventListener(this, aType, aListener, aUseCapture,
+                                   aWantsUntrusted);
+}
+
 nsEventListenerManager*
 nsGlobalWindow::GetListenerManager(bool aCreateIfNotFound)
 {
   FORWARD_TO_INNER_CREATE(GetListenerManager, (aCreateIfNotFound), nsnull);
 
   if (!mListenerManager && aCreateIfNotFound) {
     mListenerManager =
       new nsEventListenerManager(static_cast<nsIDOMEventTarget*>(this));
@@ -9275,17 +9310,17 @@ nsGlobalWindow::RunTimeout(nsTimeout *aT
     bool trackNestingLevel = !timeout->mIsInterval;
     PRUint32 nestingLevel;
     if (trackNestingLevel) {
       nestingLevel = sNestingLevel;
       sNestingLevel = timeout->mNestingLevel;
     }
 
     nsCOMPtr<nsIScriptTimeoutHandler> handler(timeout->mScriptHandler);
-    void *scriptObject = handler->GetScriptObject();
+    JSObject* scriptObject = static_cast<JSObject*>(handler->GetScriptObject());
     if (!scriptObject) {
       // Evaluate the timeout expression.
       const PRUnichar *script = handler->GetHandlerText();
       NS_ASSERTION(script, "timeout has no script nor handler text!");
 
       const char *filename = nsnull;
       PRUint32 lineNo = 0;
       handler->GetLocation(&filename, &lineNo);
@@ -9619,68 +9654,16 @@ nsresult nsGlobalWindow::ResetTimersForN
     } else {
       timeout = timeout->Next();
     }
   }
 
   return NS_OK;
 }
 
-// A JavaScript specific version.
-nsresult
-nsGlobalWindow::ClearTimeoutOrInterval()
-{
-  FORWARD_TO_INNER(ClearTimeoutOrInterval, (), NS_ERROR_NOT_INITIALIZED);
-
-  nsresult rv = NS_OK;
-  nsAXPCNativeCallContext *ncc = nsnull;
-
-  rv = nsContentUtils::XPConnect()->
-    GetCurrentNativeCallContext(&ncc);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (!ncc)
-    return NS_ERROR_NOT_AVAILABLE;
-
-  JSContext *cx = nsnull;
-
-  rv = ncc->GetJSContext(&cx);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  PRUint32 argc;
-
-  ncc->GetArgc(&argc);
-
-  if (argc < 1) {
-    // No arguments, return early.
-
-    return NS_OK;
-  }
-
-  jsval *argv = nsnull;
-
-  ncc->GetArgvPtr(&argv);
-
-  int32 timer_id;
-
-  JSAutoRequest ar(cx);
-
-  // XXXjst: Can we deal with this w/o using GetCurrentNativeCallContext()
-  if (argv[0] == JSVAL_VOID || !::JS_ValueToInt32(cx, argv[0], &timer_id) ||
-      timer_id <= 0) {
-    // Undefined or non-positive number passed as argument, return
-    // early. Make sure that JS_ValueToInt32 didn't set an exception.
-
-    ::JS_ClearPendingException(cx);
-    return NS_OK;
-  }
-
-  return ClearTimeoutOrInterval(timer_id);
-}
-
 void
 nsGlobalWindow::ClearAllTimeouts()
 {
   nsTimeout *timeout, *nextTimeout;
 
   for (timeout = FirstTimeout(); IsTimeout(timeout); timeout = nextTimeout) {
     /* If RunTimeout() is higher up on the stack for this
        window, e.g. as a result of document.write from a timeout,
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -508,17 +508,17 @@ public:
 
   friend class WindowStateHolder;
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsGlobalWindow,
                                                          nsIScriptGlobalObject)
 
   void InitJavaProperties();
 
-  virtual NS_HIDDEN_(void*)
+  virtual NS_HIDDEN_(JSObject*)
     GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey);
 
   virtual NS_HIDDEN_(void)
     CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
                              nsScriptObjectHolder& aHandler);
 
   virtual bool TakeFocus(bool aFocus, PRUint32 aFocusMethod);
   virtual void SetReadyForFocus();
@@ -679,17 +679,16 @@ protected:
   // |interval| is in milliseconds.
   nsresult SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler,
                                 PRInt32 interval,
                                 bool aIsInterval, PRInt32 *aReturn);
   nsresult ClearTimeoutOrInterval(PRInt32 aTimerID);
 
   // JS specific timeout functions (JS args grabbed from context).
   nsresult SetTimeoutOrInterval(bool aIsInterval, PRInt32* aReturn);
-  nsresult ClearTimeoutOrInterval();
   nsresult ResetTimersForNonBackgroundWindow();
 
   // The timeout implementation functions.
   void RunTimeout(nsTimeout *aTimeout);
   void RunTimeout() { RunTimeout(nsnull); }
 
   void ClearAllTimeouts();
   // Insert aTimeout into the list, before all timeouts that would
@@ -971,17 +970,17 @@ protected:
   bool mSetOpenerWindowCalled;
   nsCOMPtr<nsIURI> mLastOpenedURI;
 #endif
 
   bool mCleanedUp, mCallCleanUpAfterModalDialogCloses;
 
   nsCOMPtr<nsIDOMOfflineResourceList> mApplicationCache;
 
-  nsDataHashtable<nsVoidPtrHashKey, void*> mCachedXBLPrototypeHandlers;
+  nsDataHashtable<nsVoidPtrHashKey, JSObject*> mCachedXBLPrototypeHandlers;
 
   nsCOMPtr<nsIDocument> mSuspendedDoc;
 
   nsCOMPtr<nsIIDBFactory> mIndexedDB;
 
   // In the case of a "trusted" dialog (@see PopupControlState), we
   // set this counter to ensure a max of MAX_DIALOG_LIMIT
   PRUint32                      mDialogAbuseCount;
--- a/dom/base/nsIJSEventListener.h
+++ b/dom/base/nsIJSEventListener.h
@@ -41,45 +41,54 @@
 #include "nsIScriptContext.h"
 #include "jsapi.h"
 #include "nsIDOMEventListener.h"
 
 class nsIScriptObjectOwner;
 class nsIAtom;
 
 #define NS_IJSEVENTLISTENER_IID \
-{ 0xafc5d047, 0xdb6b, 0x4076, \
-  { 0xb3, 0xfa, 0x57, 0x96, 0x1e, 0x21, 0x48, 0x42 } }
+{ 0x92f9212b, 0xa6aa, 0x4867, \
+  { 0x93, 0x8a, 0x56, 0xbe, 0x17, 0x67, 0x4f, 0xd4 } }
 
 // Implemented by script event listeners. Used to retrieve the
 // script object corresponding to the event target and the handler itself.
 // (Note this interface is now used to store script objects for all
 // script languages, so is no longer JS specific)
+//
+// Note, mTarget is a raw pointer and the owner of the nsIJSEventListener object
+// is expected to call Disconnect()!
 class nsIJSEventListener : public nsIDOMEventListener
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IJSEVENTLISTENER_IID)
 
   nsIJSEventListener(nsIScriptContext* aContext, JSObject* aScopeObject,
                      nsISupports *aTarget, JSObject *aHandler)
-    : mContext(aContext), mScopeObject(aScopeObject),
-      mTarget(do_QueryInterface(aTarget)), mHandler(aHandler)
+    : mContext(aContext), mScopeObject(aScopeObject), mHandler(aHandler)
   {
+    nsCOMPtr<nsISupports> base = do_QueryInterface(aTarget);
+    mTarget = base.get();
   }
 
   nsIScriptContext *GetEventContext() const
   {
     return mContext;
   }
 
   nsISupports *GetEventTarget() const
   {
     return mTarget;
   }
 
+  void Disconnect()
+  {
+    mTarget = nsnull;
+  }
+
   JSObject* GetEventScope() const
   {
     return mScopeObject;
   }
 
   JSObject *GetHandler() const
   {
     return mHandler;
@@ -89,24 +98,25 @@ public:
   // there is already a handler!  The handler must already be bound to
   // the right target.
   virtual void SetHandler(JSObject *aHandler) = 0;
 
   virtual PRInt64 SizeOf() const = 0;
 protected:
   virtual ~nsIJSEventListener()
   {
+    NS_ASSERTION(!mTarget, "Should have called Disconnect()!");
   }
   nsCOMPtr<nsIScriptContext> mContext;
   JSObject* mScopeObject;
-  nsCOMPtr<nsISupports> mTarget;
+  nsISupports* mTarget;
   JSObject *mHandler;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIJSEventListener, NS_IJSEVENTLISTENER_IID)
 
 /* factory function.  aHandler must already be bound to aTarget */
 nsresult NS_NewJSEventListener(nsIScriptContext *aContext,
                                JSObject* aScopeObject, nsISupports* aTarget,
                                nsIAtom* aType, JSObject* aHandler,
-                               nsIDOMEventListener **aReturn);
+                               nsIJSEventListener **aReturn);
 
 #endif // nsIJSEventListener_h__
--- a/dom/base/nsIScriptContext.h
+++ b/dom/base/nsIScriptContext.h
@@ -69,18 +69,18 @@ public:
 
   virtual nsIScriptObjectPrincipal* GetObjectPrincipal() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContextPrincipal,
                               NS_ISCRIPTCONTEXTPRINCIPAL_IID)
 
 #define NS_ISCRIPTCONTEXT_IID \
-{ 0x164ea909, 0x5cee, 0x4e20, \
-  { 0x9f, 0xed, 0x43, 0x13, 0xab, 0xac, 0x1c, 0xd3 } }
+{ 0x39b3ea7c, 0xdc26, 0x4756, \
+  { 0xa0, 0x3c, 0x13, 0xa0, 0x42, 0x03, 0x07, 0x6a } }
 
 /* This MUST match JSVERSION_DEFAULT.  This version stuff if we don't
    know what language we have is a little silly... */
 #define SCRIPTVERSION_DEFAULT JSVERSION_DEFAULT
 
 /**
  * It is used by the application to initialize a runtime and run scripts.
  * A script runtime would implement this interface.
@@ -216,17 +216,17 @@ public:
    * @param aScript an object telling the scope in which to call the compiled
    *        event handler function.
    * @param aHandler function object (function and static scope) to invoke.
    * @param argv array of arguments.  Note each element is assumed to
    *        be an nsIVariant.
    * @param rval out parameter returning result
    **/
   virtual nsresult CallEventHandler(nsISupports* aTarget,
-                                    JSObject* aScope, void* aHandler,
+                                    JSObject* aScope, JSObject* aHandler,
                                     nsIArray *argv, nsIVariant **rval) = 0;
 
   /**
    * Bind an already-compiled event handler function to the given
    * target.  Scripting languages with static scoping must re-bind the
    * scope chain for aHandler to begin (after the activation scope for
    * aHandler itself, typically) with aTarget's scope.
    *
@@ -242,36 +242,36 @@ public:
    *        looked for.
    * @param aHandler the function object to bind, created by an earlier call to
    *        CompileEventHandler
    * @param aBoundHandler [out] the result of the bind operation.
    * @return NS_OK if the function was successfully bound
    */
   virtual nsresult BindCompiledEventHandler(nsISupports* aTarget,
                                             JSObject* aScope,
-                                            void* aHandler,
+                                            JSObject* aHandler,
                                             nsScriptObjectHolder& aBoundHandler) = 0;
 
   /**
    * Compile a function that isn't used as an event handler.
    *
    * NOTE: Not yet language agnostic (main problem is XBL - not yet agnostic)
    * Caller must make sure aFunctionObject is a JS GC root.
    *
    **/
-  virtual nsresult CompileFunction(void* aTarget,
+  virtual nsresult CompileFunction(JSObject* aTarget,
                                    const nsACString& aName,
                                    PRUint32 aArgCount,
                                    const char** aArgArray,
                                    const nsAString& aBody,
                                    const char* aURL,
                                    PRUint32 aLineNo,
                                    PRUint32 aVersion,
                                    bool aShared,
-                                   void **aFunctionObject) = 0;
+                                   JSObject** aFunctionObject) = 0;
 
   /**
    * Set the default scripting language version for this context, which must
    * be a context specific to a particular scripting language.
    *
    **/
   virtual void SetDefaultLanguageVersion(PRUint32 aVersion) = 0;
 
@@ -297,26 +297,26 @@ public:
    * Create a new global object that will be used for an inner window.
    * Return the native global and an nsISupports 'holder' that can be used
    * to manage the lifetime of it.
    */
   virtual nsresult CreateNativeGlobalForInner(
                                       nsIScriptGlobalObject *aNewInner,
                                       bool aIsChrome,
                                       nsIPrincipal *aPrincipal,
-                                      void **aNativeGlobal,
+                                      JSObject** aNativeGlobal,
                                       nsISupports **aHolder) = 0;
 
   /**
    * Connect this context to a new inner window, to allow "prototype"
    * chaining from the inner to the outer.
    * Called after both the the inner and outer windows are initialized
    **/
   virtual nsresult ConnectToInner(nsIScriptGlobalObject *aNewInner,
-                                  void *aOuterGlobal) = 0;
+                                  JSObject *aOuterGlobal) = 0;
 
 
   /**
    * Initialize the context generally. Does not create a global object.
    **/
   virtual nsresult InitContext() = 0;
 
   /**
@@ -325,17 +325,17 @@ public:
    * @param aGlobalObject The script global object to use as our global.
    */
   virtual nsresult CreateOuterObject(nsIScriptGlobalObject *aGlobalObject,
                                      nsIScriptGlobalObject *aCurrentInner) = 0;
 
   /**
    * Given an outer object, updates this context with that outer object.
    */
-  virtual nsresult SetOuterObject(void *aOuterObject) = 0;
+  virtual nsresult SetOuterObject(JSObject* aOuterObject) = 0;
 
   /**
    * Prepares this context for use with the current inner window for the
    * context's global object. This must be called after CreateOuterObject.
    */
   virtual nsresult InitOuterWindow() = 0;
 
   /**
@@ -423,17 +423,17 @@ public:
   virtual void SetGCOnDestruction(bool aGCOnDestruction) = 0;
 
   /**
    * Initialize DOM classes on aGlobalObj, always call
    * WillInitializeContext() before calling InitContext(), and always
    * call DidInitializeContext() when a context is fully
    * (successfully) initialized.
    */
-  virtual nsresult InitClasses(void *aGlobalObj) = 0;
+  virtual nsresult InitClasses(JSObject* aGlobalObj) = 0;
 
   /**
    * Clear the scope object - may be called either as we are being torn down,
    * or before we are attached to a different document.
    *
    * aClearFromProtoChain is probably somewhat JavaScript specific.  It
    * indicates that the global scope polluter should be removed from the
    * prototype chain and that the objects in the prototype chain should
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -189,17 +189,17 @@ public:
 
 NS_IMPL_ISUPPORTS1(nsMemoryPressureObserver, nsIObserver)
 
 NS_IMETHODIMP
 nsMemoryPressureObserver::Observe(nsISupports* aSubject, const char* aTopic,
                                   const PRUnichar* aData)
 {
   if (sGCOnMemoryPressure) {
-    nsJSContext::GarbageCollectNow();
+    nsJSContext::GarbageCollectNow(true);
     nsJSContext::CycleCollectNow();
   }
   return NS_OK;
 }
 
 class nsRootedJSValueArray {
 public:
   explicit nsRootedJSValueArray(JSContext *cx) : avr(cx, vals.Length(), vals.Elements()) {}
@@ -924,18 +924,16 @@ static const char js_werror_option_str[]
 static const char js_relimit_option_str[]= JS_OPTIONS_DOT_STR "relimit";
 #ifdef JS_GC_ZEAL
 static const char js_zeal_option_str[]        = JS_OPTIONS_DOT_STR "gczeal";
 static const char js_zeal_frequency_str[]     = JS_OPTIONS_DOT_STR "gczeal.frequency";
 static const char js_zeal_compartment_str[]   = JS_OPTIONS_DOT_STR "gczeal.compartment_gc";
 #endif
 static const char js_methodjit_content_str[]  = JS_OPTIONS_DOT_STR "methodjit.content";
 static const char js_methodjit_chrome_str[]   = JS_OPTIONS_DOT_STR "methodjit.chrome";
-static const char js_profiling_content_str[]  = JS_OPTIONS_DOT_STR "jitprofiling.content";
-static const char js_profiling_chrome_str[]   = JS_OPTIONS_DOT_STR "jitprofiling.chrome";
 static const char js_methodjit_always_str[]   = JS_OPTIONS_DOT_STR "methodjit_always";
 static const char js_typeinfer_str[]          = JS_OPTIONS_DOT_STR "typeinference";
 static const char js_pccounts_content_str[]   = JS_OPTIONS_DOT_STR "pccounts.content";
 static const char js_pccounts_chrome_str[]    = JS_OPTIONS_DOT_STR "pccounts.chrome";
 static const char js_jit_hardening_str[]      = JS_OPTIONS_DOT_STR "jit_hardening";
 static const char js_memlog_option_str[] = JS_OPTIONS_DOT_STR "mem.log";
 
 int
@@ -956,49 +954,40 @@ nsJSContext::JSOptionChangedCallback(con
   nsIScriptGlobalObject *global = context->GetGlobalObject();
   // XXX should we check for sysprin instead of a chrome window, to make
   // XXX components be covered by the chrome pref instead of the content one?
   nsCOMPtr<nsIDOMChromeWindow> chromeWindow(do_QueryInterface(global));
 
   bool useMethodJIT = Preferences::GetBool(chromeWindow ?
                                                js_methodjit_chrome_str :
                                                js_methodjit_content_str);
-  bool useProfiling = Preferences::GetBool(chromeWindow ?
-                                               js_profiling_chrome_str :
-                                               js_profiling_content_str);
   bool usePCCounts = Preferences::GetBool(chromeWindow ?
                                             js_pccounts_chrome_str :
                                             js_pccounts_content_str);
   bool useMethodJITAlways = Preferences::GetBool(js_methodjit_always_str);
   bool useTypeInference = !chromeWindow && Preferences::GetBool(js_typeinfer_str);
   bool useHardening = Preferences::GetBool(js_jit_hardening_str);
   nsCOMPtr<nsIXULRuntime> xr = do_GetService(XULRUNTIME_SERVICE_CONTRACTID);
   if (xr) {
     bool safeMode = false;
     xr->GetInSafeMode(&safeMode);
     if (safeMode) {
       useMethodJIT = false;
-      useProfiling = false;
       usePCCounts = false;
       useTypeInference = false;
       useMethodJITAlways = true;
       useHardening = false;
     }
   }    
 
   if (useMethodJIT)
     newDefaultJSOptions |= JSOPTION_METHODJIT;
   else
     newDefaultJSOptions &= ~JSOPTION_METHODJIT;
 
-  if (useProfiling)
-    newDefaultJSOptions |= JSOPTION_PROFILING;
-  else
-    newDefaultJSOptions &= ~JSOPTION_PROFILING;
-
   if (usePCCounts)
     newDefaultJSOptions |= JSOPTION_PCCOUNT;
   else
     newDefaultJSOptions &= ~JSOPTION_PCCOUNT;
 
   if (useMethodJITAlways)
     newDefaultJSOptions |= JSOPTION_METHODJIT_ALWAYS;
   else
@@ -1573,17 +1562,17 @@ nsJSContext::CompileScript(const PRUnich
                                                  static_cast<const jschar*>(aText),
                                                  aTextLength,
                                                  aURL,
                                                  aLineNo,
                                                  JSVersion(aVersion));
     if (script) {
       NS_ASSERTION(aScriptObject.getScriptTypeID()==JAVASCRIPT,
                    "Expecting JS script object holder");
-      rv = aScriptObject.set(script);
+      rv = aScriptObject.setScript(script);
     } else {
       rv = NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   // Whew!  Finally done.
   JSPRINCIPALS_DROP(mContext, jsprin);
   return rv;
@@ -1773,36 +1762,39 @@ nsJSContext::CompileEventHandler(nsIAtom
   if (!fun) {
     ReportPendingException();
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
   JSObject *handler = ::JS_GetFunctionObject(fun);
   NS_ASSERTION(aHandler.getScriptTypeID()==JAVASCRIPT,
                "Expecting JS script object holder");
-  return aHandler.set((void *)handler);
+  return aHandler.setObject(handler);
 }
 
 // XXX - note that CompileFunction doesn't yet play the nsScriptObjectHolder
 // game - caller must still ensure JS GC root.
 nsresult
-nsJSContext::CompileFunction(void* aTarget,
+nsJSContext::CompileFunction(JSObject* aTarget,
                              const nsACString& aName,
                              PRUint32 aArgCount,
                              const char** aArgArray,
                              const nsAString& aBody,
                              const char* aURL,
                              PRUint32 aLineNo,
                              PRUint32 aVersion,
                              bool aShared,
-                             void** aFunctionObject)
+                             JSObject** aFunctionObject)
 {
   NS_TIME_FUNCTION_FMT(1.0, "%s (line %d) (function: %s, url: %s, line: %d)", MOZ_FUNCTION_NAME,
                        __LINE__, aName.BeginReading(), aURL, aLineNo);
 
+  NS_ABORT_IF_FALSE(aFunctionObject,
+    "Shouldn't call CompileFunction with null return value.");
+
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
 
   // Don't compile if aVersion is unknown.  Since the caller is responsible for
   // parsing the version strings, we just check it isn't JSVERSION_UNKNOWN.
   if ((JSVersion)aVersion == JSVERSION_UNKNOWN) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
@@ -1815,54 +1807,53 @@ nsJSContext::CompileFunction(void* aTarg
     if (globalData) {
       nsIPrincipal *prin = globalData->GetPrincipal();
       if (!prin)
         return NS_ERROR_FAILURE;
       prin->GetJSPrincipals(mContext, &jsprin);
     }
   }
 
-  JSObject *target = (JSObject*)aTarget;
+  JSObject *target = aTarget;
 
   JSAutoRequest ar(mContext);
 
   JSFunction* fun =
       ::JS_CompileUCFunctionForPrincipalsVersion(mContext,
                                                  aShared ? nsnull : target, jsprin,
                                                  PromiseFlatCString(aName).get(),
                                                  aArgCount, aArgArray,
-                                                 (jschar*)PromiseFlatString(aBody).get(),
+                                                 static_cast<const jschar*>(PromiseFlatString(aBody).get()),
                                                  aBody.Length(),
                                                  aURL, aLineNo,
                                                  JSVersion(aVersion));
 
   if (jsprin)
     JSPRINCIPALS_DROP(mContext, jsprin);
   if (!fun)
     return NS_ERROR_FAILURE;
 
-  JSObject *handler = ::JS_GetFunctionObject(fun);
-  if (aFunctionObject)
-    *aFunctionObject = (void*) handler;
+  *aFunctionObject = JS_GetFunctionObject(fun);
   return NS_OK;
 }
 
 nsresult
 nsJSContext::CallEventHandler(nsISupports* aTarget, JSObject* aScope,
-                              void *aHandler, nsIArray *aargv, nsIVariant **arv)
+                              JSObject* aHandler, nsIArray* aargv,
+                              nsIVariant** arv)
 {
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
 
   if (!mScriptsEnabled) {
     return NS_OK;
   }
 
 #ifdef NS_FUNCTION_TIMER
   {
-    JSObject *obj = static_cast<JSObject *>(aHandler);
+    JSObject *obj = aHandler;
     if (js::IsFunctionProxy(obj))
       obj = js::UnwrapObject(obj);
     JSString *id = JS_GetFunctionId(static_cast<JSFunction *>(JS_GetPrivate(mContext, obj)));
     JSAutoByteString bytes;
     const char *name = !id ? "anonymous" : bytes.encode(mContext, id) ? bytes.ptr() : "<error>";
     NS_TIME_FUNCTION_FMT(1.0, "%s (line %d) (function: %s)", MOZ_FUNCTION_NAME, __LINE__, name);
   }
 #endif
@@ -1889,17 +1880,17 @@ nsJSContext::CallEventHandler(nsISupport
 
   nsJSContext::TerminationFuncHolder holder(this);
 
   if (NS_SUCCEEDED(rv)) {
     // Convert args to jsvals.
     PRUint32 argc = 0;
     jsval *argv = nsnull;
 
-    JSObject *funobj = static_cast<JSObject *>(aHandler);
+    JSObject *funobj = aHandler;
     nsCOMPtr<nsIPrincipal> principal;
     rv = sSecurityManager->GetObjectPrincipal(mContext, funobj,
                                               getter_AddRefs(principal));
     NS_ENSURE_SUCCESS(rv, rv);
 
     JSStackFrame *currentfp = nsnull;
     rv = sSecurityManager->PushContextPrincipal(mContext,
                                                 JS_FrameIterator(mContext, &currentfp),
@@ -1959,58 +1950,60 @@ nsJSContext::CallEventHandler(nsISupport
   // ScriptEvaluated needs to come after we pop the stack
   ScriptEvaluated(true);
 
   return rv;
 }
 
 nsresult
 nsJSContext::BindCompiledEventHandler(nsISupports* aTarget, JSObject* aScope,
-                                      void *aHandler,
+                                      JSObject* aHandler,
                                       nsScriptObjectHolder& aBoundHandler)
 {
   NS_ENSURE_ARG(aHandler);
   NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
   NS_PRECONDITION(!aBoundHandler, "Shouldn't already have a bound handler!");
 
   JSAutoRequest ar(mContext);
 
   // Get the jsobject associated with this target
   JSObject *target = nsnull;
   nsresult rv = JSObjectFromInterface(aTarget, aScope, &target);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  JSObject *funobj = (JSObject*) aHandler;
-
 #ifdef DEBUG
   {
     JSAutoEnterCompartment ac;
-    if (!ac.enter(mContext, funobj)) {
+    if (!ac.enter(mContext, aHandler)) {
       return NS_ERROR_FAILURE;
     }
 
     NS_ASSERTION(JS_TypeOfValue(mContext,
-                                OBJECT_TO_JSVAL(funobj)) == JSTYPE_FUNCTION,
+                                OBJECT_TO_JSVAL(aHandler)) == JSTYPE_FUNCTION,
                  "Event handler object not a function");
   }
 #endif
 
   JSAutoEnterCompartment ac;
   if (!ac.enter(mContext, target)) {
     return NS_ERROR_FAILURE;
   }
 
+  JSObject* funobj;
   // Make sure the handler function is parented by its event target object
-  if (funobj) { // && ::JS_GetParent(mContext, funobj) != target) {
-    funobj = ::JS_CloneFunctionObject(mContext, funobj, target);
-    if (!funobj)
+  if (aHandler) {
+    funobj = JS_CloneFunctionObject(mContext, aHandler, target);
+    if (!funobj) {
       rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+  } else {
+    funobj = NULL;
   }
 
-  aBoundHandler.set(funobj);
+  aBoundHandler.setObject(funobj);
 
   return rv;
 }
 
 // serialization
 nsresult
 nsJSContext::Serialize(nsIObjectOutputStream* aStream, JSScript* aScriptObject)
 {
@@ -2058,32 +2051,30 @@ nsJSContext::Serialize(nsIObjectOutputSt
 
     return rv;
 }
 
 nsresult
 nsJSContext::Deserialize(nsIObjectInputStream* aStream,
                          nsScriptObjectHolder &aResult)
 {
-    JSScript *result = nsnull;
-    nsresult rv;
-
     NS_TIME_FUNCTION_MIN(1.0);
 
     PRUint32 size;
-    rv = aStream->Read32(&size);
+    nsresult rv = aStream->Read32(&size);
     if (NS_FAILED(rv)) return rv;
 
     char* data;
     rv = aStream->ReadBytes(size, &data);
     if (NS_FAILED(rv)) return rv;
 
     JSContext* cx = mContext;
 
     JSXDRState *xdr = ::JS_XDRNewMem(cx, JSXDR_DECODE);
+    JSScript *result = nsnull;
     if (! xdr) {
         rv = NS_ERROR_OUT_OF_MEMORY;
     } else {
         xdr->userdata = (void*) aStream;
         JSAutoRequest ar(cx);
         ::JS_XDRMemSetData(xdr, data, size);
 
         if (! ::JS_XDRScript(xdr, &result)) {
@@ -2123,17 +2114,17 @@ nsJSContext::Deserialize(nsIObjectInputS
         nsMemory::Free(data);
     NS_ASSERTION(aResult.getScriptTypeID()==JAVASCRIPT,
                  "Expecting JS script object holder");
 
     // Now that we've cleaned up, handle the case when rv is a failure
     // code, which could happen for all sorts of reasons above.
     NS_ENSURE_SUCCESS(rv, rv);
 
-    return aResult.set(result);
+    return aResult.setScript(result);
 }
 
 void
 nsJSContext::SetDefaultLanguageVersion(PRUint32 aVersion)
 {
   ::JS_SetVersion(mContext, (JSVersion)aVersion);
 }
 
@@ -2192,57 +2183,56 @@ nsJSContext::GetNativeGlobal()
     return JS_GetGlobalObject(mContext);
 }
 
 nsresult
 nsJSContext::CreateNativeGlobalForInner(
                                 nsIScriptGlobalObject *aNewInner,
                                 bool aIsChrome,
                                 nsIPrincipal *aPrincipal,
-                                void **aNativeGlobal, nsISupports **aHolder)
+                                JSObject** aNativeGlobal, nsISupports **aHolder)
 {
   nsIXPConnect *xpc = nsContentUtils::XPConnect();
   PRUint32 flags = aIsChrome? nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT : 0;
-  nsCOMPtr<nsIXPConnectJSObjectHolder> jsholder;
 
   nsCOMPtr<nsIPrincipal> systemPrincipal;
   if (aIsChrome) {
     nsIScriptSecurityManager *ssm = nsContentUtils::GetSecurityManager();
     ssm->GetSystemPrincipal(getter_AddRefs(systemPrincipal));
   }
 
+  nsRefPtr<nsIXPConnectJSObjectHolder> jsholder;
   nsresult rv = xpc->
           InitClassesWithNewWrappedGlobal(mContext,
                                           aNewInner, NS_GET_IID(nsISupports),
                                           aIsChrome ? systemPrincipal.get() : aPrincipal,
                                           nsnull, flags,
                                           getter_AddRefs(jsholder));
-  if (NS_FAILED(rv))
+  if (NS_FAILED(rv)) {
     return rv;
-  jsholder->GetJSObject(reinterpret_cast<JSObject **>(aNativeGlobal));
-  *aHolder = jsholder.get();
-  NS_ADDREF(*aHolder);
+  }
+  jsholder->GetJSObject(aNativeGlobal);
+  jsholder.forget(aHolder);
   return NS_OK;
 }
 
 nsresult
-nsJSContext::ConnectToInner(nsIScriptGlobalObject *aNewInner, void *aOuterGlobal)
+nsJSContext::ConnectToInner(nsIScriptGlobalObject *aNewInner, JSObject *aOuterGlobal)
 {
   NS_ENSURE_ARG(aNewInner);
 #ifdef DEBUG
   JSObject *newInnerJSObject = aNewInner->GetGlobalJSObject();
 #endif
-  JSObject *outerGlobal = (JSObject *)aOuterGlobal;
 
   // Now that we're connecting the outer global to the inner one,
   // we must have transplanted it. The JS engine tries to maintain
   // the global object's compartment as its default compartment,
   // so update that now since it might have changed.
-  JS_SetGlobalObject(mContext, outerGlobal);
-  NS_ASSERTION(JS_GetPrototype(mContext, outerGlobal) ==
+  JS_SetGlobalObject(mContext, aOuterGlobal);
+  NS_ASSERTION(JS_GetPrototype(mContext, aOuterGlobal) ==
                JS_GetPrototype(mContext, newInnerJSObject),
                "outer and inner globals should have the same prototype");
 
   return NS_OK;
 }
 
 JSContext*
 nsJSContext::GetNativeContext()
@@ -2288,35 +2278,33 @@ nsJSContext::CreateOuterObject(nsIScript
   }
 
   js::SetProxyExtra(outer, 0, js::PrivateValue(aGlobalObject));
 
   return SetOuterObject(outer);
 }
 
 nsresult
-nsJSContext::SetOuterObject(void *aOuterObject)
+nsJSContext::SetOuterObject(JSObject* aOuterObject)
 {
-  JSObject *outer = static_cast<JSObject *>(aOuterObject);
-
   // Force our context's global object to be the outer.
-  JS_SetGlobalObject(mContext, outer);
+  JS_SetGlobalObject(mContext, aOuterObject);
 
   // NB: JS_SetGlobalObject sets mContext->compartment.
-  JSObject *inner = JS_GetParent(mContext, outer);
+  JSObject *inner = JS_GetParent(mContext, aOuterObject);
 
   nsIXPConnect *xpc = nsContentUtils::XPConnect();
   nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
   nsresult rv = xpc->GetWrappedNativeOfJSObject(mContext, inner,
                                                 getter_AddRefs(wrapper));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ABORT_IF_FALSE(wrapper, "bad wrapper");
 
   wrapper->RefreshPrototype();
-  JS_SetPrototype(mContext, outer, JS_GetPrototype(mContext, inner));
+  JS_SetPrototype(mContext, aOuterObject, JS_GetPrototype(mContext, inner));
 
   return NS_OK;
 }
 
 nsresult
 nsJSContext::InitOuterWindow()
 {
   JSObject *global = JS_ObjectToInnerObject(mContext, JS_GetGlobalObject(mContext));
@@ -2946,54 +2934,37 @@ static JSFunctionSpec JProfFunctions[] =
     {"JProfStopProfiling",         JProfStopProfilingJS,       0, 0},
     {"JProfClearCircular",         JProfClearCircularJS,       0, 0},
     {"JProfSaveCircular",          JProfSaveCircularJS,        0, 0},
     {nsnull,                       nsnull,                     0, 0}
 };
 
 #endif /* defined(MOZ_JPROF) */
 
-#ifdef MOZ_TRACEVIS
-static JSFunctionSpec EthogramFunctions[] = {
-    {"initEthogram",               js_InitEthogram,            0, 0},
-    {"shutdownEthogram",           js_ShutdownEthogram,        0, 0},
-    {nsnull,                       nsnull,                     0, 0}
-};
-#endif
-
 nsresult
-nsJSContext::InitClasses(void *aGlobalObj)
+nsJSContext::InitClasses(JSObject* aGlobalObj)
 {
-  nsresult rv = NS_OK;
-
-  JSObject *globalObj = static_cast<JSObject *>(aGlobalObj);
-
-  rv = InitializeExternalClasses();
+  nsresult rv = InitializeExternalClasses();
   NS_ENSURE_SUCCESS(rv, rv);
 
   JSAutoRequest ar(mContext);
 
   ::JS_SetOptions(mContext, mDefaultJSOptions);
 
   // Attempt to initialize profiling functions
-  ::JS_DefineProfilingFunctions(mContext, globalObj);
+  ::JS_DefineProfilingFunctions(mContext, aGlobalObj);
 
 #ifdef NS_TRACE_MALLOC
   // Attempt to initialize TraceMalloc functions
-  ::JS_DefineFunctions(mContext, globalObj, TraceMallocFunctions);
+  ::JS_DefineFunctions(mContext, aGlobalObj, TraceMallocFunctions);
 #endif
 
 #ifdef MOZ_JPROF
   // Attempt to initialize JProf functions
-  ::JS_DefineFunctions(mContext, globalObj, JProfFunctions);
-#endif
-
-#ifdef MOZ_TRACEVIS
-  // Attempt to initialize Ethogram functions
-  ::JS_DefineFunctions(mContext, globalObj, EthogramFunctions);
+  ::JS_DefineFunctions(mContext, aGlobalObj, JProfFunctions);
 #endif
 
   JSOptionChangedCallback(js_options_dot_str, this);
 
   return rv;
 }
 
 void
@@ -3187,33 +3158,33 @@ nsJSContext::ScriptExecuted()
 {
   ScriptEvaluated(!::JS_IsRunning(mContext));
 
   return NS_OK;
 }
 
 //static
 void
-nsJSContext::GarbageCollectNow()
+nsJSContext::GarbageCollectNow(bool shrinkingGC)
 {
   NS_TIME_FUNCTION_MIN(1.0);
 
   KillGCTimer();
 
   // Reset sPendingLoadCount in case the timer that fired was a
   // timer we scheduled due to a normal GC timer firing while
   // documents were loading. If this happens we're waiting for a
   // document that is taking a long time to load, and we effectively
   // ignore the fact that the currently loading documents are still
   // loading and move on as if they weren't.
   sPendingLoadCount = 0;
   sLoadingInProgress = false;
 
   if (nsContentUtils::XPConnect()) {
-    nsContentUtils::XPConnect()->GarbageCollect();
+    nsContentUtils::XPConnect()->GarbageCollect(shrinkingGC);
   }
 }
 
 //Static
 void
 nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener)
 {
   if (!NS_IsMainThread()) {
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -104,49 +104,49 @@ public:
   virtual nsresult CompileEventHandler(nsIAtom *aName,
                                        PRUint32 aArgCount,
                                        const char** aArgNames,
                                        const nsAString& aBody,
                                        const char *aURL, PRUint32 aLineNo,
                                        PRUint32 aVersion,
                                        nsScriptObjectHolder &aHandler);
   virtual nsresult CallEventHandler(nsISupports* aTarget, JSObject* aScope,
-                                    void* aHandler,
+                                    JSObject* aHandler,
                                     nsIArray *argv, nsIVariant **rv);
   virtual nsresult BindCompiledEventHandler(nsISupports *aTarget,
                                             JSObject *aScope,
-                                            void *aHandler,
+                                            JSObject* aHandler,
                                             nsScriptObjectHolder& aBoundHandler);
-  virtual nsresult CompileFunction(void* aTarget,
+  virtual nsresult CompileFunction(JSObject* aTarget,
                                    const nsACString& aName,
                                    PRUint32 aArgCount,
                                    const char** aArgArray,
                                    const nsAString& aBody,
                                    const char* aURL,
                                    PRUint32 aLineNo,
                                    PRUint32 aVersion,
                                    bool aShared,
-                                   void** aFunctionObject);
+                                   JSObject** aFunctionObject);
 
   virtual void SetDefaultLanguageVersion(PRUint32 aVersion);
   virtual nsIScriptGlobalObject *GetGlobalObject();
   virtual JSContext* GetNativeContext();
   virtual JSObject* GetNativeGlobal();
   virtual nsresult CreateNativeGlobalForInner(
                                       nsIScriptGlobalObject *aGlobal,
                                       bool aIsChrome,
                                       nsIPrincipal *aPrincipal,
-                                      void **aNativeGlobal,
+                                      JSObject** aNativeGlobal,
                                       nsISupports **aHolder);
   virtual nsresult ConnectToInner(nsIScriptGlobalObject *aNewInner,
-                                  void *aOuterGlobal);
+                                  JSObject *aOuterGlobal);
   virtual nsresult InitContext();
   virtual nsresult CreateOuterObject(nsIScriptGlobalObject *aGlobalObject,
                                      nsIScriptGlobalObject *aCurrentInner);
-  virtual nsresult SetOuterObject(void *aOuterObject);
+  virtual nsresult SetOuterObject(JSObject* aOuterObject);
   virtual nsresult InitOuterWindow();
   virtual bool IsContextInitialized();
   virtual void FinalizeContext();
 
   virtual void ScriptEvaluated(bool aTerminated);
   virtual nsresult SetTerminationFunction(nsScriptTerminationFunc aFunc,
                                           nsISupports* aRef);
   virtual bool GetScriptsEnabled();
@@ -156,17 +156,17 @@ public:
 
   virtual bool GetProcessingScriptTag();
   virtual void SetProcessingScriptTag(bool aResult);
 
   virtual bool GetExecutingScript();
 
   virtual void SetGCOnDestruction(bool aGCOnDestruction);
 
-  virtual nsresult InitClasses(void *aGlobalObj);
+  virtual nsresult InitClasses(JSObject* aGlobalObj);
   virtual void ClearScope(void* aGlobalObj, bool bClearPolluters);
 
   virtual void WillInitializeContext();
   virtual void DidInitializeContext();
 
   virtual nsresult Serialize(nsIObjectOutputStream* aStream, JSScript* aScriptObject);
   virtual nsresult Deserialize(nsIObjectInputStream* aStream,
                                nsScriptObjectHolder &aResult);
@@ -177,17 +177,17 @@ public:
   virtual void EnterModalState();
   virtual void LeaveModalState();
 
   NS_DECL_NSIXPCSCRIPTNOTIFY
 
   static void LoadStart();
   static void LoadEnd();
 
-  static void GarbageCollectNow();
+  static void GarbageCollectNow(bool shrinkingGC = false);
   static void CycleCollectNow(nsICycleCollectorListener *aListener = nsnull);
 
   static void PokeGC();
   static void KillGCTimer();
 
   static void PokeCC();
   static void MaybePokeCC();
   static void KillCCTimer();
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -75,18 +75,18 @@ class nsIDocument;
 class nsIScriptTimeoutHandler;
 struct nsTimeout;
 class nsScriptObjectHolder;
 class nsXBLPrototypeHandler;
 class nsIArray;
 class nsPIWindowRoot;
 
 #define NS_PIDOMWINDOW_IID \
-{ 0x9db588f7, 0x3472, 0x45d0, \
-  { 0x9f, 0x9b, 0x95, 0xca, 0xf6, 0x4d, 0x1a, 0xb1 } }
+{ 0x29e6cc54, 0x10da, 0x4a68, \
+  { 0xb7, 0x68, 0xfe, 0xa7, 0x71, 0x17, 0x93, 0x81 } }
 
 class nsPIDOMWindow : public nsIDOMWindowInternal
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMWINDOW_IID)
 
   virtual nsPIDOMWindow* GetPrivateRoot() = 0;
 
@@ -481,17 +481,17 @@ public:
     mMayHaveMouseEnterLeaveEventListener = true;
   }  
 
   /**
    * Initialize window.java and window.Packages.
    */
   virtual void InitJavaProperties() = 0;
 
-  virtual void* GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey) = 0;
+  virtual JSObject* GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey) = 0;
   virtual void CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
                                         nsScriptObjectHolder& aHandler) = 0;
 
   /*
    * Get and set the currently focused element within the document. If
    * aNeedsFocus is true, then set mNeedsFocus to true to indicate that a
    * document focus event is needed.
    *
--- a/dom/base/nsPIWindowRoot.h
+++ b/dom/base/nsPIWindowRoot.h
@@ -45,18 +45,18 @@
 
 class nsPIDOMWindow;
 class nsIControllers;
 class nsIController;
 struct JSContext;
 
 // 426C1B56-E38A-435E-B291-BE1557F2A0A2
 #define NS_IWINDOWROOT_IID \
-{ 0x426c1b56, 0xe38a, 0x435e, \
-  { 0xb2, 0x91, 0xbe, 0x15, 0x57, 0xf2, 0xa0, 0xa2 } }
+{ 0xc89780f2, 0x8905, 0x417f, \
+  { 0xa6, 0x62, 0xf6, 0xc, 0xa6, 0xd7, 0xc, 0x91 } }
 
 class nsPIWindowRoot : public nsIDOMEventTarget
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IWINDOWROOT_IID)
 
   virtual nsPIDOMWindow* GetWindow()=0;
 
--- a/dom/base/nsWindowRoot.cpp
+++ b/dom/base/nsWindowRoot.cpp
@@ -106,16 +106,18 @@ nsWindowRoot::RemoveEventListener(const 
 {
   nsRefPtr<nsEventListenerManager> elm = GetListenerManager(false);
   if (elm) {
     elm->RemoveEventListener(aType, aListener, aUseCapture);
   }
   return NS_OK;
 }
 
+NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsWindowRoot)
+
 NS_IMETHODIMP
 nsWindowRoot::DispatchEvent(nsIDOMEvent* aEvt, bool *aRetVal)
 {
   nsEventStatus status = nsEventStatus_eIgnore;
   nsresult rv =  nsEventDispatcher::DispatchDOMEvent(
     static_cast<nsIDOMEventTarget*>(this), nsnull, aEvt, nsnull, &status);
   *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
   return rv;
@@ -144,16 +146,32 @@ nsWindowRoot::AddEventListener(const nsA
                "explicit by making optional_argc non-zero.");
 
   nsEventListenerManager* elm = GetListenerManager(true);
   NS_ENSURE_STATE(elm);
   elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsWindowRoot::AddSystemEventListener(const nsAString& aType,
+                                     nsIDOMEventListener *aListener,
+                                     bool aUseCapture,
+                                     bool aWantsUntrusted,
+                                     PRUint8 aOptionalArgc)
+{
+  NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
+               "Won't check if this is chrome, you want to set "
+               "aWantsUntrusted to false or make the aWantsUntrusted "
+               "explicit by making optional_argc non-zero.");
+
+  return NS_AddSystemEventListener(this, aType, aListener, aUseCapture,
+                                   aWantsUntrusted);
+}
+
 nsEventListenerManager*
 nsWindowRoot::GetListenerManager(bool aCreateIfNotFound)
 {
   if (!mListenerManager && aCreateIfNotFound) {
     mListenerManager =
       new nsEventListenerManager(static_cast<nsIDOMEventTarget*>(this));
   }
 
--- a/dom/battery/nsIDOMBatteryManager.idl
+++ b/dom/battery/nsIDOMBatteryManager.idl
@@ -33,17 +33,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMEventListener;
 
-[scriptable, function, uuid(98b6237b-9654-43de-97e0-acf4b091b4e7)]
+[scriptable, function, uuid(41e88f87-42cb-4db1-8724-f5456a16c410)]
 interface nsIDOMMozBatteryManager : nsIDOMEventTarget
 {
   readonly attribute double     level;
   readonly attribute boolean    charging;
   readonly attribute double     dischargingTime;
   readonly attribute double     chargingTime;
 
   attribute nsIDOMEventListener onlevelchange;
--- a/dom/dom-config.mk
+++ b/dom/dom-config.mk
@@ -1,11 +1,12 @@
 DOM_SRCDIRS = \
   dom/base \
   dom/battery \
+  dom/sms/src \
   dom/src/events \
   dom/src/storage \
   dom/src/offline \
   dom/src/geolocation \
   dom/src/notification \
   dom/workers \
   content/xbl/src \
   content/xul/document/src \
--- a/dom/indexedDB/OpenDatabaseHelper.cpp
+++ b/dom/indexedDB/OpenDatabaseHelper.cpp
@@ -1543,16 +1543,17 @@ OpenDatabaseHelper::DispatchErrorEvent()
 
 void
 OpenDatabaseHelper::ReleaseMainThreadObjects()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   mOpenDBRequest = nsnull;
   mDatabase = nsnull;
+  mDatabaseId = nsnull;
 
   HelperBase::ReleaseMainThreadObjects();
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(SetVersionHelper, AsyncConnectionHelper);
 
 nsresult
 SetVersionHelper::Init()
--- a/dom/interfaces/base/Makefile.in
+++ b/dom/interfaces/base/Makefile.in
@@ -50,17 +50,17 @@ SDK_XPIDLSRCS =                         
 	domstubs.idl				\
 	nsIDOMBarProp.idl			\
 	nsIDOMWindow.idl			\
 	nsIDOMWindowCollection.idl		\
 	nsIDOMWindowUtils.idl			\
 	$(NULL)
 
 XPIDLSRCS =					\
-	nsIAnimationFrameListener.idl           \
+	nsIFrameRequestCallback.idl             \
 	nsIBrowserDOMWindow.idl			\
     nsIContentPermissionPrompt.idl  \
 	nsIContentPrefService.idl		\
 	nsIContentURIGrouper.idl		\
 	nsIDOMClientInformation.idl		\
 	nsIDOMConstructor.idl			\
 	nsIDOMCRMFObject.idl			\
 	nsIDOMCrypto.idl			\
--- a/dom/interfaces/base/nsIDOMJSWindow.idl
+++ b/dom/interfaces/base/nsIDOMJSWindow.idl
@@ -33,17 +33,17 @@
  * 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 "domstubs.idl"
 
-[scriptable, uuid(14efb76c-5bd6-449e-b36f-0cbd22981f20)]
+[scriptable, uuid(6652c4d2-6b49-424b-aaf9-91f91006fab7)]
 interface nsIDOMJSWindow : nsISupports
 {
   void                      dump(in DOMString str);
 
   /**
    * These methods take typeless arguments and optional arguments, the
    * first argument is either a function or a string, the second
    * argument must be a number (ms) and the rest of the arguments (2
@@ -52,18 +52,18 @@ interface nsIDOMJSWindow : nsISupports
   long                      setTimeout();
   long                      setInterval();
 
   /**
    * These methods take one optional argument that's the timer ID to
    * clear. Often in existing code these methods are passed undefined,
    * which is a nop so we need to support that as well.
    */
-  void                      clearTimeout();
-  void                      clearInterval();
+  void                      clearTimeout([optional] in long handle);
+  void                      clearInterval([optional] in long handle);
 
   /**
    * This method is here for backwards compatibility with 4.x only,
    * its implementation is a no-op
    */
   void                      setResizable(in boolean resizable);
 
   /**
--- a/dom/interfaces/base/nsIDOMWindow.idl
+++ b/dom/interfaces/base/nsIDOMWindow.idl
@@ -36,17 +36,17 @@
  * 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 "domstubs.idl"
 
-interface nsIAnimationFrameListener;
+interface nsIFrameRequestCallback;
 interface nsIControllers;
 interface nsIDOMBlob;
 interface nsIDOMLocation;
 interface nsIDOMMediaQueryList;
 interface nsIDOMOfflineResourceList;
 interface nsIDOMPerformance;
 interface nsIDOMStorage;
 interface nsIDOMStorageList;
@@ -413,17 +413,17 @@ interface nsIDOMWindow : nsISupports
   readonly attribute unsigned long long mozPaintCount;
 
   /**
    * Request a refresh of this browser window.
    *
    * @see <http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/RequestAnimationFrame/Overview.html>
    */
   void
-    mozRequestAnimationFrame([optional] in nsIAnimationFrameListener aListener);
+    mozRequestAnimationFrame(in nsIFrameRequestCallback aCallback);
 
   /**
    * The current animation start time in milliseconds since the epoch.
    */
   readonly attribute long long mozAnimationStartTime;
 
   /**
    * @see <http://dev.w3.org/2006/webapi/FileAPI/#creating-revoking>
rename from dom/interfaces/base/nsIAnimationFrameListener.idl
rename to dom/interfaces/base/nsIFrameRequestCallback.idl
--- a/dom/interfaces/base/nsIAnimationFrameListener.idl
+++ b/dom/interfaces/base/nsIFrameRequestCallback.idl
@@ -31,23 +31,21 @@
  * 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 ***** */
 
 /**
- * Interface that represents a listener to be passed to
- * mozRequestAnimationFrame
+ * Interface that represents a callback to be passed to requestAnimationFrame
  */
 
 #include "domstubs.idl"
 
-[scriptable, function, uuid(ba240e38-c15a-4fb2-802a-8a48f09331bd)]
-interface nsIAnimationFrameListener : nsISupports
+[scriptable, function, uuid(e8d887f0-2ed7-406f-9f1d-edeb2c54c0a2)]
+interface nsIFrameRequestCallback : nsISupports
 {
   /**
-   * The timestamp is the same as it would be for the a corresponding
-   * MozBeforePaint event.
+   * The timestamp is the time to be used for the animation sample.
    */
-  void onBeforePaint(in DOMTimeStamp timeStamp);
+  void sample(in DOMTimeStamp timeStamp);
 };
--- a/dom/interfaces/events/nsIDOMEventTarget.idl
+++ b/dom/interfaces/events/nsIDOMEventTarget.idl
@@ -64,17 +64,17 @@ class nsEventListenerManager;
 [ptr] native nsEventStatusPtr(nsEventStatus);
 [ptr] native JSContextPtr(JSContext);
 [ptr] native nsEventListenerManagerPtr(nsEventListenerManager);
 
 interface nsIScriptContext;
 interface nsIDOMEventListener;
 interface nsIDOMEvent;
 
-[scriptable, builtinclass, uuid(1797d5a4-b12a-428d-9eef-a0e13839728c)]
+[scriptable, builtinclass, uuid(8e375931-298d-4d0a-9cb4-5668f0cdc5a8)]
 interface nsIDOMEventTarget : nsISupports
 {
   /**
    * This method allows the registration of event listeners on the event target.
    * If an EventListener is added to an EventTarget while it is processing an
    * event, it will not be triggered by the current actions but may be 
    * triggered during a later stage of event flow, such as the bubbling phase.
    * 
@@ -101,32 +101,70 @@ interface nsIDOMEventTarget : nsISupport
    *                         listener will receive events whether or not
    *                         they're trusted
    */
   [optional_argc] void addEventListener(in DOMString type,
                                         in nsIDOMEventListener listener,
                                         [optional] in boolean useCapture,
                                         [optional] in boolean wantsUntrusted);
 
+  /**
+   * addSystemEventListener() adds an event listener of aType to the system
+   * group.  Typically, core code should use system group for listening to
+   * content (i.e., non-chrome) element's events.  If core code uses
+   * nsIDOMEventTarget::AddEventListener for a content node, it means
+   * that the listener cannot listen the event when web content calls
+   * stopPropagation() of the event.
+   *
+   * @param aType            An event name you're going to handle.
+   * @param aListener        An event listener.
+   * @param aUseCapture      TRUE if you want to listen the event in capturing
+   *                         phase.  Otherwise, FALSE.
+   * @param aWantsUntrusted  TRUE if you want to handle untrusted events.
+   *                         Otherwise, FALSE.
+   * @return                 NS_OK if succeed.  Otherwise, NS_ERROR_*.
+   */
+  [noscript, optional_argc] void addSystemEventListener(
+                                   in DOMString type,
+                                   in nsIDOMEventListener listener,
+                                   [optional] in boolean aUseCapture,
+                                   [optional] in boolean aWantsUntrusted);
+
 %{C++
   // non-virtual so it won't affect the vtable
   nsresult AddEventListener(const nsAString& aType,
                             nsIDOMEventListener* aListener,
                             bool aUseCapture)
   {
     return AddEventListener(aType, aListener, aUseCapture, PR_FALSE, 1);
   }
   // non-virtual so it won't affect the vtable
   nsresult AddEventListener(const nsAString& aType,
                             nsIDOMEventListener* aListener,
                             bool aUseCapture,
                             bool aWantsUntrusted)
   {
     return AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted, 2);
   }
+  // non-virtual so it won't affect the vtable
+  nsresult AddSystemEventListener(const nsAString& aType,
+                                  nsIDOMEventListener* aListener,
+                                  bool aUseCapture)
+  {
+    return AddSystemEventListener(aType, aListener, aUseCapture, PR_FALSE, 1);
+  }
+  // non-virtual so it won't affect the vtable
+  nsresult AddSystemEventListener(const nsAString& aType,
+                                  nsIDOMEventListener* aListener,
+                                  bool aUseCapture,
+                                  bool aWantsUntrusted)
+  {
+    return AddSystemEventListener(aType, aListener, aUseCapture,
+                                  aWantsUntrusted, 2);
+  }
 %}
 
   /**
    * This method allows the removal of event listeners from the event 
    * target. If an EventListener is removed from an EventTarget while it 
    * is processing an event, it will not be triggered by the current actions. 
    * EventListeners can never be invoked after being removed.
    * Calling removeEventListener with arguments which do not identify any 
@@ -144,16 +182,25 @@ interface nsIDOMEventTarget : nsISupport
    *                     not affect a non-capturing version of the same 
    *                     listener, and vice versa.
    */
   void                     removeEventListener(in DOMString type,
                                                in nsIDOMEventListener listener,
                                                [optional] in boolean useCapture);
 
   /**
+   * removeSystemEventListener() should be used if you have used
+   * addSystemEventListener().
+   */
+  [noscript] void          removeSystemEventListener(
+                             in DOMString type,
+                             in nsIDOMEventListener listener,
+                             [optional] in boolean aUseCapture);
+
+  /**
    * This method allows the dispatch of events into the implementations 
    * event model. Events dispatched in this manner will have the same 
    * capturing and bubbling behavior as events dispatched directly by the 
    * implementation. The target of the event is the EventTarget on which 
    * dispatchEvent is called.
    *
    * @param   evt Specifies the event type, behavior, and contextual 
    *              information to be used in processing the event.
@@ -273,9 +320,25 @@ interface nsIDOMEventTarget : nsISupport
 typedef nsIDOMEventTarget nsPIDOMEventTarget;
 
 #define NS_IMPL_DOMTARGET_DEFAULTS(_class) \
 nsPIDOMEventTarget* _class::GetTargetForDOMEvent() { return this; } \
 nsPIDOMEventTarget* _class::GetTargetForEventTargetChain() { return this; } \
 nsresult _class::WillHandleEvent(nsEventChainPostVisitor& aVisitor) { return NS_OK; } \
 JSContext* _class::GetJSContextForEventHandlers() { return nsnull; }
 
+#define NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(aClass) \
+NS_IMETHODIMP \
+aClass::RemoveSystemEventListener(const nsAString& aType, \
+                                  nsIDOMEventListener *aListener, \
+                                  bool aUseCapture) \
+{ \
+  nsEventListenerManager* listenerManager = GetListenerManager(false); \
+  if (!listenerManager) { \
+    return NS_OK; \
+  } \
+  PRUint32 flags = NS_EVENT_FLAG_SYSTEM_EVENT; \
+  flags |= aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE; \
+  listenerManager->RemoveEventListenerByType(aListener, aType, flags); \
+  return NS_OK; \
+}
+
 %}
--- a/dom/interfaces/json/nsIJSON.idl
+++ b/dom/interfaces/json/nsIJSON.idl
@@ -43,46 +43,50 @@ interface nsIOutputStream;
 interface nsIScriptGlobalObject;
 
 [ptr] native JSValPtr(jsval);
 [ptr] native JSContext(JSContext);
 
 /**
  * Encode and decode JSON text.
  */
-[scriptable, uuid(a4d68b4e-0c0b-4c7c-b540-ef2f9834171f)]
+[scriptable, uuid(43845d58-1054-47fb-8be3-970b3f7bd7ea)]
 interface nsIJSON : nsISupports
 {
   /**
    * New users should use JSON.stringify!
    * The encode() method is only present for backward compatibility.
    * encode() is not a conforming JSON stringify implementation!
    */
-  [deprecated] AString encode(/* in JSObject value */);
+  [deprecated,implicit_jscontext,optional_argc]
+  AString encode([optional] in jsval value);
 
   /**
    * New users should use JSON.stringify.
    * You may also want to have a look at nsIConverterOutputStream.
    *
    * The encodeToStream() method is only present for backward compatibility.
    * encodeToStream() is not a conforming JSON stringify implementation!
    */
-  [deprecated] void encodeToStream(in nsIOutputStream stream,
-                                   in string charset,
-                                   in boolean writeBOM
-                                   /* in JSObject value */);
+  [deprecated,implicit_jscontext,optional_argc]
+  void encodeToStream(in nsIOutputStream stream,
+                      in string charset,
+                      in boolean writeBOM,
+                      [optional] in jsval value);
 
   /**
    * New users should use JSON.parse!
    * The decode() method is only present for backward compatibility.
    */
-  [deprecated] void /* JSObject */ decode(in AString str);
+  [deprecated,implicit_jscontext]
+  jsval decode(in AString str);
 
-  void /* JSObject */ decodeFromStream(in nsIInputStream stream,
-                                       in long contentLength);
+  [implicit_jscontext]
+  jsval decodeFromStream(in nsIInputStream stream,
+                         in long contentLength);
 
   [noscript] AString  encodeFromJSVal(in JSValPtr value, in JSContext cx);
 
   // Make sure you GCroot the result of this function before using it.
   [noscript] jsval    decodeToJSVal(in AString str, in JSContext cx);
 
 
   /*
@@ -92,18 +96,20 @@ interface nsIJSON : nsISupports
    * This method is provided only as a temporary transition path for users of
    * the old code who depended on the ability to decode leniently; new users
    * should use JSON.parse.
    *
    * This method must only be called from script.
    *
    * @param str the string to parse
    */
-  void /* jsval */ legacyDecode(in AString str);
+  [implicit_jscontext]
+  jsval legacyDecode(in AString str);
 
   /* Identical to legacyDecode, but decode the contents of stream. */
-  void /* jsval */ legacyDecodeFromStream(in nsIInputStream stream,
-                                          in long contentLength);
+  [implicit_jscontext]
+  jsval legacyDecodeFromStream(in nsIInputStream stream,
+                               in long contentLength);
 
   /* Identical to legacyDecode, but decode into a jsval. */
   // Make sure you GCroot the result of this function before using it.
   [noscript] jsval    legacyDecodeToJSVal(in AString str, in JSContext cx);
 };
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -106,21 +106,24 @@
 #include <process.h>
 #define getpid _getpid
 #endif
 
 #ifdef ACCESSIBILITY
 #include "nsIAccessibilityService.h"
 #endif
 
+#include "mozilla/dom/sms/SmsChild.h"
+
 using namespace mozilla::hal_sandbox;
 using namespace mozilla::ipc;
 using namespace mozilla::net;
 using namespace mozilla::places;
 using namespace mozilla::docshell;
+using namespace mozilla::dom::sms;
 
 namespace mozilla {
 namespace dom {
 
 nsString* gIndexedDBPath = nsnull;
 
 class MemoryReportRequestChild : public PMemoryReportRequestChild
 {
@@ -530,16 +533,29 @@ ContentChild::AllocPExternalHelperApp(co
 bool
 ContentChild::DeallocPExternalHelperApp(PExternalHelperAppChild* aService)
 {
     ExternalHelperAppChild *child = static_cast<ExternalHelperAppChild*>(aService);
     child->Release();
     return true;
 }
 
+PSmsChild*
+ContentChild::AllocPSms()
+{
+    return new SmsChild();
+}
+
+bool
+ContentChild::DeallocPSms(PSmsChild* aSms)
+{
+    delete aSms;
+    return true;
+}
+
 PStorageChild*
 ContentChild::AllocPStorage(const StorageConstructData& aData)
 {
     NS_NOTREACHED("We should never be manually allocating PStorageChild actors");
     return nsnull;
 }
 
 bool
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -124,16 +124,19 @@ public:
             const IPC::URI& uri,
             const nsCString& aMimeContentType,
             const nsCString& aContentDisposition,
             const bool& aForceSave,
             const PRInt64& aContentLength,
             const IPC::URI& aReferrer);
     virtual bool DeallocPExternalHelperApp(PExternalHelperAppChild *aService);
 
+    virtual PSmsChild* AllocPSms();
+    virtual bool DeallocPSms(PSmsChild*);
+
     virtual PStorageChild* AllocPStorage(const StorageConstructData& aData);
     virtual bool DeallocPStorage(PStorageChild* aActor);
 
     virtual bool RecvRegisterChrome(const InfallibleTArray<ChromePackage>& packages,
                                     const InfallibleTArray<ResourceMapping>& resources,
                                     const InfallibleTArray<OverrideMapping>& overrides,
                                     const nsCString& locale);
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -109,26 +109,29 @@
 #endif
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
 #endif
 
 #include "nsIClipboard.h"
 #include "nsWidgetsCID.h"
 #include "nsISupportsPrimitives.h"
+#include "mozilla/dom/sms/SmsParent.h"
+
 static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
 static const char* sClipboardTextFlavors[] = { kUnicodeMime };
 
 using mozilla::Preferences;
 using namespace mozilla::ipc;
 using namespace mozilla::hal_sandbox;
 using namespace mozilla::net;
 using namespace mozilla::places;
 using mozilla::unused; // heh
 using base::KillProcess;
+using namespace mozilla::dom::sms;
 
 namespace mozilla {
 namespace dom {
 
 #define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
 
 class MemoryReportRequestParent : public PMemoryReportRequestParent
 {
@@ -927,16 +930,29 @@ ContentParent::AllocPExternalHelperApp(c
 bool
 ContentParent::DeallocPExternalHelperApp(PExternalHelperAppParent* aService)
 {
     ExternalHelperAppParent *parent = static_cast<ExternalHelperAppParent *>(aService);
     parent->Release();
     return true;
 }
 
+PSmsParent*
+ContentParent::AllocPSms()
+{
+    return new SmsParent();
+}
+
+bool
+ContentParent::DeallocPSms(PSmsParent* aSms)
+{
+    delete aSms;
+    return true;
+}
+
 PStorageParent*
 ContentParent::AllocPStorage(const StorageConstructData& aData)
 {
     return new StorageParent(aData);
 }
 
 bool
 ContentParent::DeallocPStorage(PStorageParent* aActor)
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -156,16 +156,19 @@ private:
             const IPC::URI& uri,
             const nsCString& aMimeContentType,
             const nsCString& aContentDisposition,
             const bool& aForceSave,
             const PRInt64& aContentLength,
             const IPC::URI& aReferrer);
     virtual bool DeallocPExternalHelperApp(PExternalHelperAppParent* aService);
 
+    virtual PSmsParent* AllocPSms();
+    virtual bool DeallocPSms(PSmsParent*);
+
     virtual PStorageParent* AllocPStorage(const StorageConstructData& aData);
     virtual bool DeallocPStorage(PStorageParent* aActor);
 
     virtual bool RecvReadPrefsArray(InfallibleTArray<PrefTuple> *retValue);
     virtual bool RecvReadFontList(InfallibleTArray<FontListEntry>* retValue);
 
     void EnsurePrefService();
 
--- a/dom/ipc/Makefile.in
+++ b/dom/ipc/Makefile.in
@@ -104,16 +104,17 @@ LOCAL_INCLUDES += \
 	-I$(srcdir)/../src/base \
 	-I$(srcdir)/../src/storage \
 	-I$(srcdir)/../../xpcom/base \
 	-I$(srcdir)/../indexedDB \
 	-I$(topsrcdir)/extensions/cookie \
 	-I$(topsrcdir)/dom/base \
 	-I$(topsrcdir)/toolkit/xre \
 	-I$(topsrcdir)/hal/sandbox \
+	-I$(topsrcdir)/dom/sms/src/ipc \
 	$(NULL)
 
 DEFINES += -DBIN_SUFFIX='"$(BIN_SUFFIX)"'
 
 ifdef MOZ_PERMISSIONS
 DEFINES += -DMOZ_PERMISSIONS
 endif
 
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -167,23 +167,24 @@ parent:
      *
      *  if cancel is PR_TRUE,
      *    widget should return empty string for composition
      *  if cancel is PR_FALSE,
      *    widget should return the current composition text
      */
     sync EndIMEComposition(bool cancel) returns (nsString composition);
 
-    sync GetIMEEnabled() returns (PRUint32 value);
-
-    SetInputMode(PRUint32 value, nsString type, nsString actionHint, PRUint32 reason);
+    sync GetInputContext() returns (PRInt32 IMEEnabled, PRInt32 IMEOpen);
 
-    sync GetIMEOpenState() returns (bool value);
-
-    SetIMEOpenState(bool value);
+    SetInputContext(PRInt32 IMEEnabled,
+                    PRInt32 IMEOpen,
+                    nsString type,
+                    nsString actionHint,
+                    PRInt32 cause,
+                    PRInt32 focusChange);
 
     /**
      * Gets the DPI of the screen corresponding to this browser.
      */
     sync GetDPI() returns (float value);
 
     /**
      * Return native data of root widget
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -38,16 +38,17 @@
 
 include protocol PAudio;
 include protocol PBrowser;
 include protocol PCrashReporter;
 include protocol PExternalHelperApp;
 include protocol PHal;
 include protocol PMemoryReportRequest;
 include protocol PNecko;
+include protocol PSms;
 include protocol PStorage;
 include protocol PTestShell;
 
 include "mozilla/chrome/RegistryMessageUtils.h";
 include "mozilla/net/NeckoMessageUtils.h";
 include "mozilla/dom/TabMessageUtils.h";
 
 include "nsGeoPositionIPCSerialiser.h";
@@ -99,16 +100,17 @@ rpc protocol PContent
 {
     manages PAudio;
     manages PBrowser;
     manages PCrashReporter;
     manages PExternalHelperApp;
     manages PHal;
     manages PMemoryReportRequest;
     manages PNecko;
+    manages PSms;
     manages PStorage;
     manages PTestShell;
 
 child:
     PBrowser(PRUint32 chromeFlags);
 
     PMemoryReportRequest();
 
@@ -152,16 +154,18 @@ child:
 parent:
     PAudio(PRInt32 aNumChannels, PRInt32 aRate, PRInt32 aFormat);
 
     sync PCrashReporter(NativeThreadId tid, PRUint32 processType);
 
     PHal();
 
     PNecko();
+
+    PSms();
     
     PStorage(StorageConstructData data);
 
     // Services remoting
 
     async StartVisitedQuery(URI uri);
     async VisitURI(URI uri, URI referrer, PRUint32 flags);
     async SetURITitle(URI uri, nsString title);
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -910,17 +910,17 @@ TabChild::InitTabChildGlobal()
 
   mCx = cx;
 
   nsContentUtils::XPConnect()->SetSecurityManagerForJSContext(cx, nsContentUtils::GetSecurityManager(), 0);
   nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(mPrincipal));
 
   JS_SetNativeStackQuota(cx, 128 * sizeof(size_t) * 1024);
 
-  JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_JIT | JSOPTION_PRIVATE_IS_NSISUPPORTS);
+  JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_PRIVATE_IS_NSISUPPORTS);
   JS_SetVersion(cx, JSVERSION_LATEST);
   JS_SetErrorReporter(cx, ContentScriptErrorReporter);
 
   xpc_LocalizeContext(cx);
 
   JSAutoRequest ar(cx);
   nsIXPConnect* xpc = nsContentUtils::XPConnect();
   const PRUint32 flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES |
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -69,16 +69,17 @@
 #include "nsIWidget.h"
 #include "nsIViewManager.h"
 #include "mozilla/unused.h"
 #include "nsDebug.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::ipc;
 using namespace mozilla::layout;
+using namespace mozilla::widget;
 
 // The flags passed by the webProgress notifications are 16 bits shifted
 // from the ones registered by webProgressListeners.
 #define NOTIFY_FLAG_SHIFT 16
 
 namespace mozilla {
 namespace dom {
 
@@ -558,77 +559,71 @@ TabParent::RecvEndIMEComposition(const b
 
   mIMECompositionEnding = false;
   *aComposition = mIMECompositionText;
   mIMECompositionText.Truncate(0);  
   return true;
 }
 
 bool
-TabParent::RecvGetIMEEnabled(PRUint32* aValue)
+TabParent::RecvGetInputContext(PRInt32* aIMEEnabled,
+                               PRInt32* aIMEOpen)
 {
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget) {
-    *aValue = nsIWidget::IME_STATUS_DISABLED;
+    *aIMEEnabled = IMEState::DISABLED;
+    *aIMEOpen = IMEState::OPEN_STATE_NOT_SUPPORTED;
     return true;
   }
 
-  IMEContext context;
-  widget->GetInputMode(context);
-  *aValue = context.mStatus;
+  InputContext context = widget->GetInputContext();
+  *aIMEEnabled = static_cast<PRInt32>(context.mIMEState.mEnabled);
+  *aIMEOpen = static_cast<PRInt32>(context.mIMEState.mOpen);
   return true;
 }
 
 bool
-TabParent::RecvSetInputMode(const PRUint32& aValue, const nsString& aType, const nsString& aAction, const PRUint32& aReason)
+TabParent::RecvSetInputContext(const PRInt32& aIMEEnabled,
+                               const PRInt32& aIMEOpen,
+                               const nsString& aType,
+                               const nsString& aActionHint,
+                               const PRInt32& aCause,
+                               const PRInt32& aFocusChange)
 {
   // mIMETabParent (which is actually static) tracks which if any TabParent has IMEFocus
-  // When the input mode is set to anything but IME_STATUS_NONE, mIMETabParent should be set to this
-  mIMETabParent = aValue & nsIContent::IME_STATUS_MASK_ENABLED ? this : nsnull;
+  // When the input mode is set to anything but IMEState::DISABLED,
+  // mIMETabParent should be set to this
+  mIMETabParent =
+    aIMEEnabled != static_cast<PRInt32>(IMEState::DISABLED) ? this : nsnull;
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget || !AllowContentIME())
     return true;
 
-  IMEContext context;
-  context.mStatus = aValue;
+  InputContext context;
+  context.mIMEState.mEnabled = static_cast<IMEState::Enabled>(aIMEEnabled);
+  context.mIMEState.mOpen = static_cast<IMEState::Open>(aIMEOpen);
   context.mHTMLInputType.Assign(aType);
-  context.mActionHint.Assign(aAction);
-  context.mReason = aReason;
-  widget->SetInputMode(context);
+  context.mActionHint.Assign(aActionHint);
+  InputContextAction action(
+    static_cast<InputContextAction::Cause>(aCause),
+    static_cast<InputContextAction::FocusChange>(aFocusChange));
+  widget->SetInputContext(context, action);
 
   nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
   if (!observerService)
     return true;
 
   nsAutoString state;
-  state.AppendInt(aValue);
+  state.AppendInt(aIMEEnabled);
   observerService->NotifyObservers(nsnull, "ime-enabled-state-changed", state.get());
 
   return true;
 }
 
 bool
-TabParent::RecvGetIMEOpenState(bool* aValue)
-{
-  nsCOMPtr<nsIWidget> widget = GetWidget();
-  if (widget)
-    widget->GetIMEOpenState(aValue);
-  return true;
-}
-
-bool
-TabParent::RecvSetIMEOpenState(const bool& aValue)
-{
-  nsCOMPtr<nsIWidget> widget = GetWidget();
-  if (widget && AllowContentIME())
-    widget->SetIMEOpenState(aValue);
-  return true;
-}
-
-bool
 TabParent::RecvGetDPI(float* aValue)
 {
   NS_ABORT_IF_FALSE(mDPI > 0, 
                     "Must not ask for DPI before OwnerElement is received!");
   *aValue = mDPI;
   return true;
 }
 
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -98,20 +98,24 @@ public:
                                          const PRUint32& aEnd,
                                          const PRUint32& aNewEnd);
     virtual bool RecvNotifyIMESelection(const PRUint32& aSeqno,
                                         const PRUint32& aAnchor,
                                         const PRUint32& aFocus);
     virtual bool RecvNotifyIMETextHint(const nsString& aText);
     virtual bool RecvEndIMEComposition(const bool& aCancel,
                                        nsString* aComposition);
-    virtual bool RecvGetIMEEnabled(PRUint32* aValue);
-    virtual bool RecvSetInputMode(const PRUint32& aValue, const nsString& aType, const nsString& aAction, const PRUint32& aReason);
-    virtual bool RecvGetIMEOpenState(bool* aValue);
-    virtual bool RecvSetIMEOpenState(const bool& aValue);
+    virtual bool RecvGetInputContext(PRInt32* aIMEEnabled,
+                                     PRInt32* aIMEOpen);
+    virtual bool RecvSetInputContext(const PRInt32& aIMEEnabled,
+                                     const PRInt32& aIMEOpen,
+                                     const nsString& aType,
+                                     const nsString& aActionHint,
+                                     const PRInt32& aCause,
+                                     const PRInt32& aFocusChange);
     virtual bool RecvSetCursor(const PRUint32& aValue);
     virtual bool RecvSetBackgroundColor(const nscolor& aValue);
     virtual bool RecvGetDPI(float* aValue);
     virtual bool RecvGetWidgetNativeData(WindowsHandle* aValue);
     virtual PContentDialogParent* AllocPContentDialog(const PRUint32& aType,
                                                       const nsCString& aName,
                                                       const nsCString& aFeatures,
                                                       const InfallibleTArray<int>& aIntParams,
--- a/dom/locales/en-US/chrome/layout/htmlparser.properties
+++ b/dom/locales/en-US/chrome/layout/htmlparser.properties
@@ -49,19 +49,19 @@ errGtInPublicId=