Merge m-c to s-c.
authorRichard Newman <rnewman@mozilla.com>
Thu, 14 Feb 2013 14:33:37 -0800
changeset 131801 d710f8eefa353762123b87ac6504478eb120496b
parent 131800 baa43b00de2bf7a044f997d33e420a836e13afbf (current diff)
parent 131798 a373379d43cf427d0e1ebba808d391be5a4c6104 (diff)
child 131802 1725b56ec1a3ec1b357d7fd68da49b69aa530a08
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone21.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to s-c.
accessible/public/msaa/nsIWinAccessNode.idl
browser/metro/base/content/helperui/SharingUI.js
browser/metro/base/content/prompt/share.xul
browser/metro/theme/header.css
browser/metro/theme/images/aboutBackground.jpg
browser/metro/theme/images/check-30.png
browser/metro/theme/images/check-selected-30.png
browser/metro/theme/images/check-unselected-30.png
browser/metro/theme/images/checkmark-hdpi.png
browser/metro/theme/images/homescreen-blank-hdpi.png
browser/metro/theme/images/homescreen-default-hdpi.png
browser/metro/theme/images/loading.png
browser/metro/theme/images/more-active.png
browser/metro/theme/images/mozilla-32.png
browser/metro/theme/images/search-clear-30.png
browser/metro/theme/images/section-collapsed-16.png
browser/metro/theme/images/section-expanded-16.png
config/nspr/build.mk
content/html/content/src/nsMediaError.cpp
content/html/content/src/nsMediaError.h
content/html/content/test/test_bug585508.html
mobile/android/base/resources/drawable-hdpi/address_bar_texture_port.png
mobile/android/base/resources/drawable-hdpi/address_bar_texture_port_pb.png
mobile/android/base/resources/drawable-hdpi/remote_tabs_off.png
mobile/android/base/resources/drawable-hdpi/remote_tabs_on.png
mobile/android/base/resources/drawable-land-hdpi-v14/address_bar_texture_land.png
mobile/android/base/resources/drawable-land-hdpi-v14/address_bar_texture_land_pb.png
mobile/android/base/resources/drawable-land-hdpi-v14/address_bar_url_default.9.png
mobile/android/base/resources/drawable-land-hdpi-v14/address_bar_url_default_pb.9.png
mobile/android/base/resources/drawable-land-hdpi-v14/address_bar_url_pressed.9.png
mobile/android/base/resources/drawable-land-hdpi-v14/address_bar_url_pressed_pb.9.png
mobile/android/base/resources/drawable-land-hdpi-v14/remote_tabs_off.png
mobile/android/base/resources/drawable-land-hdpi-v14/remote_tabs_on.png
mobile/android/base/resources/drawable-land-mdpi-v14/address_bar_texture_land.png
mobile/android/base/resources/drawable-land-mdpi-v14/address_bar_texture_land_pb.png
mobile/android/base/resources/drawable-land-mdpi-v14/address_bar_url_default.9.png
mobile/android/base/resources/drawable-land-mdpi-v14/address_bar_url_default_pb.9.png
mobile/android/base/resources/drawable-land-mdpi-v14/address_bar_url_pressed.9.png
mobile/android/base/resources/drawable-land-mdpi-v14/address_bar_url_pressed_pb.9.png
mobile/android/base/resources/drawable-land-mdpi-v14/remote_tabs_off.png
mobile/android/base/resources/drawable-land-mdpi-v14/remote_tabs_on.png
mobile/android/base/resources/drawable-land-v14/address_bar_bg_normal.xml
mobile/android/base/resources/drawable-land-v14/address_bar_bg_private.xml
mobile/android/base/resources/drawable-land-xhdpi-v14/address_bar_texture_land.png
mobile/android/base/resources/drawable-land-xhdpi-v14/address_bar_texture_land_pb.png
mobile/android/base/resources/drawable-land-xhdpi-v14/address_bar_url_default.9.png
mobile/android/base/resources/drawable-land-xhdpi-v14/address_bar_url_default_pb.9.png
mobile/android/base/resources/drawable-land-xhdpi-v14/address_bar_url_pressed.9.png
mobile/android/base/resources/drawable-land-xhdpi-v14/address_bar_url_pressed_pb.9.png
mobile/android/base/resources/drawable-land-xhdpi-v14/remote_tabs_off.png
mobile/android/base/resources/drawable-land-xhdpi-v14/remote_tabs_on.png
mobile/android/base/resources/drawable-large-hdpi-v11/address_bar_texture_tablet.png
mobile/android/base/resources/drawable-large-hdpi-v11/address_bar_texture_tablet_pb.png
mobile/android/base/resources/drawable-large-hdpi-v11/address_bar_url_default.9.png
mobile/android/base/resources/drawable-large-hdpi-v11/address_bar_url_default_pb.9.png
mobile/android/base/resources/drawable-large-hdpi-v11/address_bar_url_pressed.9.png
mobile/android/base/resources/drawable-large-hdpi-v11/address_bar_url_pressed_pb.9.png
mobile/android/base/resources/drawable-large-hdpi-v11/remote_tabs_off.png
mobile/android/base/resources/drawable-large-hdpi-v11/remote_tabs_on.png
mobile/android/base/resources/drawable-large-mdpi-v11/address_bar_bg_normal.xml
mobile/android/base/resources/drawable-large-mdpi-v11/address_bar_bg_private.xml
mobile/android/base/resources/drawable-large-mdpi-v11/address_bar_texture_tablet.png
mobile/android/base/resources/drawable-large-mdpi-v11/address_bar_texture_tablet_pb.png
mobile/android/base/resources/drawable-large-mdpi-v11/address_bar_url_default.9.png
mobile/android/base/resources/drawable-large-mdpi-v11/address_bar_url_default_pb.9.png
mobile/android/base/resources/drawable-large-mdpi-v11/address_bar_url_pressed.9.png
mobile/android/base/resources/drawable-large-mdpi-v11/address_bar_url_pressed_pb.9.png
mobile/android/base/resources/drawable-large-mdpi-v11/remote_tabs_off.png
mobile/android/base/resources/drawable-large-mdpi-v11/remote_tabs_on.png
mobile/android/base/resources/drawable-large-xhdpi-v11/address_bar_texture_tablet.png
mobile/android/base/resources/drawable-large-xhdpi-v11/address_bar_texture_tablet_pb.png
mobile/android/base/resources/drawable-large-xhdpi-v11/address_bar_url_default.9.png
mobile/android/base/resources/drawable-large-xhdpi-v11/address_bar_url_default_pb.9.png
mobile/android/base/resources/drawable-large-xhdpi-v11/address_bar_url_pressed.9.png
mobile/android/base/resources/drawable-large-xhdpi-v11/address_bar_url_pressed_pb.9.png
mobile/android/base/resources/drawable-large-xhdpi-v11/remote_tabs_off.png
mobile/android/base/resources/drawable-large-xhdpi-v11/remote_tabs_on.png
mobile/android/base/resources/drawable-nodpi/abouthome_bg_pb.png
mobile/android/base/resources/drawable-nodpi/tabs_tray_bg.png
mobile/android/base/resources/drawable-nodpi/tabs_tray_dark_bg.png
mobile/android/base/resources/drawable-xhdpi/address_bar_texture_port.png
mobile/android/base/resources/drawable-xhdpi/address_bar_texture_port_pb.png
mobile/android/base/resources/drawable-xhdpi/remote_tabs_off.png
mobile/android/base/resources/drawable-xhdpi/remote_tabs_on.png
mobile/android/base/resources/drawable/abouthome_bg_pb_repeat.xml
mobile/android/base/resources/drawable/abouthome_bg_repeat.xml
mobile/android/base/resources/drawable/address_bar_bg_normal.xml
mobile/android/base/resources/drawable/address_bar_bg_private.xml
mobile/android/base/resources/drawable/address_bar_texture_port.png
mobile/android/base/resources/drawable/address_bar_texture_port_pb.png
mobile/android/base/resources/drawable/awesomebar_tabs_bg.xml.in
mobile/android/base/resources/drawable/remote_tabs_level.xml
mobile/android/base/resources/drawable/remote_tabs_off.png
mobile/android/base/resources/drawable/remote_tabs_on.png
mobile/android/base/resources/drawable/tabs_tray_bg_repeat.xml
mobile/android/base/resources/drawable/tabs_tray_dark_bg_repeat.xml
mobile/android/base/tests/robocop_input.html
mobile/android/themes/core/images/about-bg-darkblue.png
mobile/android/themes/core/images/about-bg-lightblue.png
mobile/android/themes/core/images/privatebrowsing-bg-textured.png
mobile/android/themes/core/images/reader-toolbar-bg-land-hdpi.png
mobile/android/themes/core/images/reader-toolbar-bg-land-mdpi.png
mobile/android/themes/core/images/reader-toolbar-bg-land-xhdpi.png
mobile/android/themes/core/images/reader-toolbar-bg-port-hdpi.png
mobile/android/themes/core/images/reader-toolbar-bg-port-mdpi.png
mobile/android/themes/core/images/reader-toolbar-bg-port-xhdpi.png
mobile/android/themes/core/images/reader-toolbar-bg-xlarge-hdpi.png
mobile/android/themes/core/images/reader-toolbar-bg-xlarge-mdpi.png
mobile/android/themes/core/images/reader-toolbar-bg-xlarge-xhdpi.png
mobile/android/themes/core/images/row-bg-light.png
mobile/android/themes/core/images/row-bg-normal.png
testing/tests/memtest.py
toolkit/crashreporter/google-breakpad/src/tools/solaris/dump_syms/testdata/dump_syms_regtest.o
--- a/accessible/public/msaa/Makefile.in
+++ b/accessible/public/msaa/Makefile.in
@@ -4,26 +4,21 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 LIBRARY_NAME	= AccessibleMarshal
 MODULE    = accessibility
-XPIDL_MODULE = accessibility-msaa
 GRE_MODULE   = 1
 DEFFILE = $(win_srcdir)/AccessibleMarshal.def
 
 include $(DEPTH)/config/autoconf.mk
 
-XPIDLSRCS = \
-      nsIWinAccessNode.idl \
-      $(NULL)
-
 DEFINES += -DREGISTER_PROXY_DLL
 
 GARBAGE += $(MIDL_GENERATED_FILES) done_gen dlldata.c
 
 FORCE_SHARED_LIB = 1
 
 SRCS_IN_OBJDIR	= 1
 
deleted file mode 100644
--- a/accessible/public/msaa/nsIWinAccessNode.idl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-%{C++
-#include "guiddef.h"
-%}
-
-[ref] native MSCOMIIDRef(IID);
-
-[uuid(63efe9c5-2610-4d2f-861b-e4ddfe1b70d9)]
-interface nsIWinAccessNode : nsISupports
-{
-  voidPtr queryNativeInterface([const] in MSCOMIIDRef aIID);
-};
-
--- a/accessible/src/base/ARIAStateMap.cpp
+++ b/accessible/src/base/ARIAStateMap.cpp
@@ -267,16 +267,26 @@ aria::MapToState(EStateRule aRule, dom::
       static const TokenTypeData data(
         nsGkAtoms::aria_readonly, eBoolType | eDefinedIfAbsent,
         0, states::READONLY, states::EDITABLE);
 
       MapTokenType(aElement, aState, data);
       return true;
     }
 
+    case eARIAReadonlyOrEditableIfDefined:
+    {
+      static const TokenTypeData data(
+        nsGkAtoms::aria_readonly, eBoolType,
+        0, states::READONLY, states::EDITABLE);
+
+      MapTokenType(aElement, aState, data);
+      return true;
+    }
+
     case eARIARequired:
     {
       static const TokenTypeData data(
         nsGkAtoms::aria_required, eBoolType,
         0, states::REQUIRED);
 
       MapTokenType(aElement, aState, data);
       return true;
--- a/accessible/src/base/ARIAStateMap.h
+++ b/accessible/src/base/ARIAStateMap.h
@@ -34,16 +34,17 @@ enum EStateRule
   eARIAHasPopup,
   eARIAInvalid,
   eARIAMultiline,
   eARIAMultiSelectable,
   eARIAOrientation,
   eARIAPressed,
   eARIAReadonly,
   eARIAReadonlyOrEditable,
+  eARIAReadonlyOrEditableIfDefined,
   eARIARequired,
   eARIASelectable,
   eReadonlyUntilEditable,
   eIndeterminateIfNoValue
 };
 
 /**
  * Expose the accessible states for the given element accordingly to state
--- a/accessible/src/base/AccEvent.cpp
+++ b/accessible/src/base/AccEvent.cpp
@@ -48,17 +48,17 @@ AccEvent::CreateXPCOMObject()
   nsAccEvent* event = new nsAccEvent(this);
   NS_IF_ADDREF(event);
   return event;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccEvent cycle collection
 
-NS_IMPL_CYCLE_COLLECTION_NATIVE_1(AccEvent, mAccessible)
+NS_IMPL_CYCLE_COLLECTION_1(AccEvent, mAccessible)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AccEvent, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AccEvent, Release)
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccStateChangeEvent
 ////////////////////////////////////////////////////////////////////////////////
 
--- a/accessible/src/base/nsARIAMap.cpp
+++ b/accessible/src/base/nsARIAMap.cpp
@@ -173,29 +173,29 @@ static nsRoleMapEntry sWAIRoleMaps[] =
     roles::TABLE,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     eSelect | eTable,
     states::FOCUSABLE,
     eARIAMultiSelectable,
-    eARIAReadonly
+    eARIAReadonlyOrEditable
   },
   { // gridcell
     &nsGkAtoms::gridcell,
     roles::GRID_CELL,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     eTableCell,
     kNoReqStates,
     eARIASelectable,
-    eARIAReadonly
+    eARIAReadonlyOrEditableIfDefined
   },
   { // group
     &nsGkAtoms::group,
     roles::GROUPING,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
--- a/accessible/src/generic/Accessible.cpp
+++ b/accessible/src/generic/Accessible.cpp
@@ -17,16 +17,18 @@
 #include "nsIAccessibleRelation.h"
 #include "nsEventShell.h"
 #include "nsTextEquivUtils.h"
 #include "Relation.h"
 #include "Role.h"
 #include "RootAccessible.h"
 #include "States.h"
 #include "StyleInfo.h"
+#include "TableAccessible.h"
+#include "TableCellAccessible.h"
 #include "TreeWalker.h"
 
 #include "nsContentUtils.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMNodeFilter.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMTreeWalker.h"
@@ -1592,16 +1594,32 @@ Accessible::ApplyARIAState(uint64_t* aSt
   if (!mRoleMapEntry)
     return;
 
   *aState |= mRoleMapEntry->state;
 
   if (aria::MapToState(mRoleMapEntry->attributeMap1, element, aState) &&
       aria::MapToState(mRoleMapEntry->attributeMap2, element, aState))
     aria::MapToState(mRoleMapEntry->attributeMap3, element, aState);
+
+  // ARIA gridcell inherits editable/readonly states from the grid until it's
+  // overridden.
+  if (mRoleMapEntry->Is(nsGkAtoms::gridcell) &&
+      !(*aState & (states::READONLY | states::EDITABLE))) {
+    const TableCellAccessible* cell = AsTableCell();
+    if (cell) {
+      TableAccessible* table = cell->Table();
+      if (table) {
+        Accessible* grid = table->AsAccessible();
+        uint64_t gridState = 0;
+        grid->ApplyARIAState(&gridState);
+        *aState |= (gridState & (states::READONLY | states::EDITABLE));
+      }
+    }
+  }
 }
 
 NS_IMETHODIMP
 Accessible::GetValue(nsAString& aValue)
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -509,16 +509,18 @@ public:
   a11y::RootAccessible* AsRoot();
 
   bool IsSelect() const { return HasGenericType(eSelect); }
 
   bool IsTable() const { return HasGenericType(eTable); }
   virtual TableAccessible* AsTable() { return nullptr; }
 
   virtual TableCellAccessible* AsTableCell() { return nullptr; }
+  const TableCellAccessible* AsTableCell() const
+    { return const_cast<Accessible*>(this)->AsTableCell(); }
 
   bool IsTableRow() const { return HasGenericType(eTableRow); }
 
   bool IsTextLeaf() const { return mType == eTextLeafType; }
   TextLeafAccessible* AsTextLeaf();
 
   bool IsXULTabpanels() const { return mType == eXULTabpanelsType; }
 
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -40,28 +40,17 @@ nsAccessNodeWrap::
 nsAccessNodeWrap::~nsAccessNodeWrap()
 {
 }
 
 //-----------------------------------------------------
 // nsISupports methods
 //-----------------------------------------------------
 
-NS_IMPL_ISUPPORTS_INHERITED1(nsAccessNodeWrap, nsAccessNode, nsIWinAccessNode)
-
-//-----------------------------------------------------
-// nsIWinAccessNode methods
-//-----------------------------------------------------
-
-NS_IMETHODIMP
-nsAccessNodeWrap::QueryNativeInterface(REFIID aIID, void** aInstancePtr)
-{
-  // XXX Wrong for E_NOINTERFACE
-  return static_cast<nsresult>(QueryInterface(aIID, aInstancePtr));
-}
+NS_IMPL_ISUPPORTS_INHERITED0(nsAccessNodeWrap, nsAccessNode)
 
 STDMETHODIMP nsAccessNodeWrap::QueryInterface(REFIID iid, void** ppv)
 {
   *ppv = nullptr;
 
   if (IID_IUnknown == iid) {
     *ppv = static_cast<IUnknown*>(this);
   } else {
@@ -117,22 +106,22 @@ nsAccessNodeWrap::QueryService(REFGUID g
 
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
   // Can get to IAccessibleApplication from any node via QS
   if (guidService == IID_IAccessibleApplication ||
       (Compatibility::IsJAWS() && iid == IID_IAccessibleApplication)) {
-    ApplicationAccessible* applicationAcc = ApplicationAcc();
+    ApplicationAccessibleWrap* applicationAcc =
+      static_cast<ApplicationAccessibleWrap*>(ApplicationAcc());
     if (!applicationAcc)
       return E_NOINTERFACE;
 
-    nsresult rv = applicationAcc->QueryNativeInterface(iid, ppv);
-    return NS_SUCCEEDED(rv) ? S_OK : E_NOINTERFACE;
+    return applicationAcc->QueryInterface(iid, ppv);
   }
 
   /**
    * To get an ISimpleDOMNode, ISimpleDOMDocument, ISimpleDOMText
    * or any IAccessible2 interface on should use IServiceProvider like this:
    * -----------------------------------------------------------------------
    * ISimpleDOMDocument *pAccDoc = NULL;
    * IServiceProvider *pServProv = NULL;
--- a/accessible/src/msaa/nsAccessNodeWrap.h
+++ b/accessible/src/msaa/nsAccessNodeWrap.h
@@ -17,17 +17,16 @@
 // importance than the missing dereference for the nsCOMPtr<>
 #ifdef _MSC_VER
 #pragma warning( disable : 4509 )
 #endif
 
 #include "nsCOMPtr.h"
 #include "nsIAccessible.h"
 #include "nsIAccessibleEvent.h"
-#include "nsIWinAccessNode.h"
 #include "nsIDOMElement.h"
 #include "nsIContent.h"
 #include "nsAccessNode.h"
 #include "oleidl.h"
 #include "oleacc.h"
 #include <winuser.h>
 #ifdef MOZ_CRASHREPORTER
 #include "nsICrashReporter.h"
@@ -50,22 +49,20 @@ namespace a11y {
 #ifdef __GNUC__
 // Inheriting from both XPCOM and MSCOM interfaces causes a lot of warnings
 // about virtual functions being hidden by each other. This is done by
 // design, so silence the warning.
 #pragma GCC diagnostic ignored "-Woverloaded-virtual"
 #endif
 
 class nsAccessNodeWrap : public nsAccessNode,
-                         public nsIWinAccessNode,
                          public IServiceProvider
 {
   public:
     NS_DECL_ISUPPORTS_INHERITED
-    NS_DECL_NSIWINACCESSNODE
 
 public: // construction, destruction
   nsAccessNodeWrap(nsIContent* aContent, DocAccessible* aDoc);
   virtual ~nsAccessNodeWrap();
 
   // IUnknown
   virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID aIID,
                                                    void** aInstancePtr);
--- a/accessible/src/msaa/nsWinUtils.cpp
+++ b/accessible/src/msaa/nsWinUtils.cpp
@@ -38,69 +38,16 @@ nsWinUtils::GetComputedStyleDeclaration(
     return nullptr;
 
   nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
   nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(elm));
   window->GetComputedStyle(domElement, EmptyString(), getter_AddRefs(cssDecl));
   return cssDecl.forget();
 }
 
-HRESULT
-nsWinUtils::ConvertToIA2Array(nsIArray *aGeckoArray, IUnknown ***aIA2Array,
-                              long *aIA2ArrayLen)
-{
-  *aIA2Array = NULL;
-  *aIA2ArrayLen = 0;
-
-  if (!aGeckoArray)
-    return S_FALSE;
-
-  uint32_t length = 0;
-  nsresult rv = aGeckoArray->GetLength(&length);
-  if (NS_FAILED(rv))
-    return GetHRESULT(rv);
-
-  if (length == 0)
-    return S_FALSE;
-
-  *aIA2Array =
-    static_cast<IUnknown**>(::CoTaskMemAlloc((length) * sizeof(IUnknown*)));
-  if (!*aIA2Array)
-    return E_OUTOFMEMORY;
-
-  uint32_t idx = 0;
-  for (; idx < length; ++idx) {
-    nsCOMPtr<nsIWinAccessNode> winAccessNode =
-      do_QueryElementAt(aGeckoArray, idx, &rv);
-    if (NS_FAILED(rv))
-      break;
-
-    void *instancePtr = NULL;
-    nsresult rv = winAccessNode->QueryNativeInterface(IID_IUnknown,
-                                                      &instancePtr);
-    if (NS_FAILED(rv))
-      break;
-
-    (*aIA2Array)[idx] = static_cast<IUnknown*>(instancePtr);
-  }
-
-  if (NS_FAILED(rv)) {
-    for (uint32_t idx2 = 0; idx2 < idx; idx2++) {
-      (*aIA2Array)[idx2]->Release();
-      (*aIA2Array)[idx2] = NULL;
-    }
-
-    ::CoTaskMemFree(*aIA2Array);
-    return GetHRESULT(rv);
-  }
-
-  *aIA2ArrayLen = length;
-  return S_OK;
-}
-
 bool
 nsWinUtils::MaybeStartWindowEmulation()
 {
   // Register window class that'll be used for document accessibles associated
   // with tabs.
   if (Compatibility::IsJAWS() || Compatibility::IsWE() ||
       Compatibility::IsDolphin() ||
       Preferences::GetBool("browser.tabs.remote")) {
--- a/accessible/src/msaa/nsWinUtils.h
+++ b/accessible/src/msaa/nsWinUtils.h
@@ -26,23 +26,16 @@ public:
    *
    * @note Please use it carefully since it can shutdown the accessible tree
    *       you operate on.
    */
   static already_AddRefed<nsIDOMCSSStyleDeclaration>
     GetComputedStyleDeclaration(nsIContent* aContent);
 
   /**
-   * Convert nsIArray array of accessible objects to an array of IUnknown*
-   * objects used in IA2 methods.
-   */
-  static HRESULT ConvertToIA2Array(nsIArray *aCollection,
-                                   IUnknown ***aAccessibles, long *aCount);
-
-  /**
    * Start window emulation if presence of specific AT is detected.
    */
   static bool MaybeStartWindowEmulation();
 
   /**
    * Free resources used for window emulation.
    */
   static void ShutdownWindowEmulation();
--- a/accessible/src/windows/ia2/ia2AccessibleHyperlink.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleHyperlink.cpp
@@ -5,17 +5,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "Accessible2.h"
 #include "AccessibleHyperlink.h"
 #include "AccessibleHyperlink_i.c"
 
 #include "AccessibleWrap.h"
-#include "nsIWinAccessNode.h"
 
 using namespace mozilla::a11y;
 
 // IUnknown
 
 STDMETHODIMP
 ia2AccessibleHyperlink::QueryInterface(REFIID iid, void** ppv)
 {
--- a/accessible/src/windows/ia2/ia2AccessibleHypertext.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleHypertext.cpp
@@ -40,27 +40,22 @@ ia2AccessibleHypertext::get_hyperlink(lo
 
   *aHyperlink = NULL;
 
   HyperTextAccessibleWrap* hyperText = static_cast<HyperTextAccessibleWrap*>(this);
   if (hyperText->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   Accessible* hyperLink = hyperText->GetLinkAt(aLinkIndex);
-  nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryObject(hyperLink));
-  if (!winAccessNode)
+  if (!hyperText)
     return E_FAIL;
 
-  void *instancePtr = NULL;
-  nsresult rv =  winAccessNode->QueryNativeInterface(IID_IAccessibleHyperlink,
-                                                     &instancePtr);
-  if (NS_FAILED(rv))
-    return E_FAIL;
-
-  *aHyperlink = static_cast<IAccessibleHyperlink*>(instancePtr);
+  *aHyperlink =
+    static_cast<IAccessibleHyperlink*>(static_cast<AccessibleWrap*>(hyperLink));
+  (*aHyperlink)->AddRef();
   return S_OK;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleHypertext::get_hyperlinkIndex(long aCharIndex, long* aHyperlinkIndex)
 {
--- a/accessible/src/windows/ia2/ia2AccessibleRelation.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleRelation.cpp
@@ -158,17 +158,21 @@ ia2AccessibleRelation::get_nTargets(long
 STDMETHODIMP
 ia2AccessibleRelation::get_target(long aTargetIndex, IUnknown **aTarget)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (aTargetIndex < 0 || (uint32_t)aTargetIndex >= mTargets.Length() || !aTarget)
     return E_INVALIDARG;
 
-  mTargets[aTargetIndex]->QueryNativeInterface(IID_IUnknown, (void**) aTarget);
+  AccessibleWrap* target =
+    static_cast<AccessibleWrap*>(mTargets[aTargetIndex].get());
+  *aTarget = static_cast<IAccessible*>(target);
+  (*aTarget)->AddRef();
+
   return S_OK;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleRelation::get_targets(long aMaxTargets, IUnknown **aTargets,
                                    long *aNTargets)
--- a/accessible/tests/mochitest/states/test_aria.html
+++ b/accessible/tests/mochitest/states/test_aria.html
@@ -105,16 +105,30 @@
                  STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
 
       // aria-pressed
       testStates("aria_pressed_button", STATE_PRESSED | STATE_CHECKABLE);
 
       // aria-readonly
       testStates("aria_readonly_textbox", STATE_READONLY);
 
+      // readonly/editable on grid and gridcell
+      testStates("aria_grid_default", 0, EXT_STATE_EDITABLE,
+                 STATE_READONLY, 0);
+      testStates("aria_grid_default_cell_readonly", STATE_READONLY, 0,
+                 0, EXT_STATE_EDITABLE);
+      testStates("aria_grid_default_cell_inherited", 0, EXT_STATE_EDITABLE,
+                 STATE_READONLY, 0);
+      testStates("aria_grid_readonly", STATE_READONLY, 0,
+                 0, EXT_STATE_EDITABLE);
+      testStates("aria_grid_readonly_cell_editable", 0, EXT_STATE_EDITABLE,
+                 STATE_READONLY, 0);
+      testStates("aria_grid_readonly_cell_inherited", STATE_READONLY, 0,
+                 0, EXT_STATE_EDITABLE);
+
       // aria-selectable
       testStates("aria_selectable_listitem", STATE_SELECTABLE | STATE_SELECTED);
 
       // active state caused by aria-activedescendant
       testStates("as_item1", 0, EXT_STATE_ACTIVE);
       testStates("as_item2", 0, 0, 0, EXT_STATE_ACTIVE);
 
       // universal ARIA properties inherited from file input control
@@ -225,16 +239,21 @@
      title="ARIA undetermined progressmeters should expose mixed state">
     Mozilla Bug 740851
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=762876
      title="fix default horizontal / vertical state of role=scrollbar and ensure only one of horizontal / vertical states is exposed">
     Mozilla Bug 762876
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=835121
+     title="ARIA grid should be editable by default">
+    Mozilla Bug 835121
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <div id="textbox_autocomplete_inline" role="textbox" aria-autocomplete="inline"></div>
   <div id="textbox_autocomplete_list" role="textbox" aria-autocomplete="list"></div>
   <div id="textbox_autocomplete_both" role="textbox" aria-autocomplete="both"></div>
@@ -260,17 +279,36 @@
   </div>
 
   <div id="aria_mixed_checkbox" role="checkbox" aria-checked="mixed">
     I might agree
   </div>
   <div id="aria_multiline_textbox" role="textbox" aria-multiline="true"></div>
   <div id="aria_multiselectable_listbox" role="listbox" aria-multiselectable="true"></div>
   <div id="aria_pressed_button" role="button" aria-pressed="true">Button</div>
-  <div id="aria_readonly_textbox" role="textbox" aria-readonly="true">This text should be readonly</div>
+
+  <div id="aria_readonly_textbox"
+       role="textbox" aria-readonly="true">This text should be readonly</div>
+
+  <div id="aria_grid_default" role="grid">
+    <div role="row">
+      <div id="aria_grid_default_cell_readonly"
+           role="gridcell" aria-readonly="true">gridcell1</div>
+      <div id="aria_grid_default_cell_inherited"
+           role="gridcell">gridcell2</div>
+  </div>
+
+  <div id="aria_grid_readonly" role="grid" aria-readonly="true">
+    <div role="row">
+      <div id="aria_grid_readonly_cell_editable"
+           role="gridcell" aria-readonly="false">gridcell1</div>
+      <div id="aria_grid_readonly_cell_inherited"
+           role="gridcell">gridcell2</div>
+  </div>
+
   <div role="listbox">
     <div id="aria_selectable_listitem" role="option" aria-selected="true">Item1</div>
   </div>
 
   <!-- Test that aria-disabled state gets propagated to all descendants -->
   <div id="group" role="group" aria-disabled="true">
     <button>hi</button>
     <div tabindex="0" role="listbox" aria-activedescendant="item1">
@@ -308,17 +346,17 @@
   <!-- strange edge case: please don't do this in the wild -->
   <a id="aria_link_link" role="link" href="foo">link</a>
   <a id="aria_link_anchor" role="link" name="link_anchor">link</a>
 
   <!-- landmarks: links -->
   <a id="aria_application_link" role="application" href="foo">app</a>
   <a id="aria_main_link" role="main" href="foo">main</a>
   <a id="aria_navigation_link" role="navigation" href="foo">nav</a>
-  
+
   <!-- landmarks: anchors -->
   <a id="aria_application_anchor" role="application" name="app_anchor">app</a>
   <a id="aria_main_anchor" role="main" name="main_anchor">main</a>
   <a id="aria_navigation_anchor" role="navigation" name="nav_anchor">nav</a>
 
   <!-- aria-orientation -->
   <div id="aria_scrollbar" role="scrollbar">scrollbar</div>
   <div id="aria_hscrollbar" role="scrollbar" aria-orientation="horizontal">horizontal scrollbar</div>
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -124,17 +124,16 @@
 #endif
 
 ; [Components]
 @BINPATH@/components/components.manifest
 @BINPATH@/components/alerts.xpt
 #ifdef ACCESSIBILITY
 #ifdef XP_WIN32
 @BINPATH@/AccessibleMarshal.dll
-@BINPATH@/components/accessibility-msaa.xpt
 #endif
 @BINPATH@/components/accessibility.xpt
 #endif
 @BINPATH@/components/appshell.xpt
 @BINPATH@/components/appstartup.xpt
 @BINPATH@/components/autocomplete.xpt
 @BINPATH@/components/autoconfig.xpt
 @BINPATH@/components/browsercompsbase.xpt
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -114,20 +114,16 @@ ifeq ($(OS_ARCH),WINNT) #{
 #
 # The default heap size is 1MB on Win32.
 # The heap will grow if need be.
 #
 # Set it to 256k.  See bug 127069.
 #
 ifndef GNU_CC #{
 LDFLAGS += /HEAP:0x40000
-ifeq ($(OS_TEST),x86_64) #{
-# set stack to 2MB on x64 build.  See bug 582910
-LDFLAGS += -STACK:2097152
-endif #}
 endif #}
 endif #}
 
 ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH)))
 
 libs:: 
 	cp -p $(MOZ_APP_NAME)$(BIN_SUFFIX) $(DIST)/bin/$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)
 
--- a/browser/base/content/abouthome/aboutHome.js
+++ b/browser/base/content/abouthome/aboutHome.js
@@ -99,23 +99,32 @@ window.addEventListener("load", function
   fitToWidth();
   window.addEventListener("resize", fitToWidth);
 });
 
 function onSearchSubmit(aEvent)
 {
   let searchTerms = document.getElementById("searchText").value;
   let searchURL = document.documentElement.getAttribute("searchEngineURL");
+
   if (searchURL && searchTerms.length > 0) {
     const SEARCH_TOKENS = {
       "_searchTerms_": encodeURIComponent(searchTerms)
     }
     for (let key in SEARCH_TOKENS) {
       searchURL = searchURL.replace(key, SEARCH_TOKENS[key]);
     }
+
+    // Send an event that a search was performed. This was originally
+    // added so Firefox Health Report could record that a search from
+    // about:home had occurred.
+    let engineName = document.documentElement.getAttribute("searchEngineName");
+    let event = new CustomEvent("AboutHomeSearchEvent", {detail: engineName});
+    document.dispatchEvent(event);
+
     window.location.href = searchURL;
   }
 
   aEvent.preventDefault();
 }
 
 
 function setupSearchEngine()
--- a/browser/base/content/browser-context.inc
+++ b/browser/base/content/browser-context.inc
@@ -230,18 +230,17 @@
                 accesskey="&selectAllCmd.accesskey;"
                 command="cmd_selectAll"/>
       <menuseparator id="context-sep-selectall"/>
       <menuitem id="context-keywordfield"
                 label="&keywordfield.label;"
                 accesskey="&keywordfield.accesskey;"
                 oncommand="AddKeywordForSearchField();"/>
       <menuitem id="context-searchselect"
-                oncommand="BrowserSearch.loadSearch(getBrowserSelection(), true,
-                                                    'contextmenu');"/>
+                oncommand="BrowserSearch.loadSearchFromContext(getBrowserSelection());"/>
       <menuseparator id="frame-sep"/>
       <menu id="frame" label="&thisFrameMenu.label;" accesskey="&thisFrameMenu.accesskey;">
         <menupopup>
           <menuitem id="context-showonlythisframe"
                     label="&showOnlyThisFrameCmd.label;"
                     accesskey="&showOnlyThisFrameCmd.accesskey;"
                     oncommand="gContextMenu.showOnlyThisFrame();"/>
           <menuitem id="context-openframeintab"
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2601,36 +2601,42 @@ function PageProxyClickHandler(aEvent)
   if (aEvent.button == 1 && gPrefService.getBoolPref("middlemouse.paste"))
     middleMousePaste(aEvent);
 }
 
 /**
  *  Handle load of some pages (about:*) so that we can make modifications
  *  to the DOM for unprivileged pages.
  */
-function BrowserOnAboutPageLoad(document) {
-  if (document.documentURI.toLowerCase() == "about:home") {
+function BrowserOnAboutPageLoad(doc) {
+  if (doc.documentURI.toLowerCase() == "about:home") {
     // XXX bug 738646 - when Marketplace is launched, remove this statement and
     // the hidden attribute set on the apps button in aboutHome.xhtml
     if (getBoolPref("browser.aboutHome.apps", false))
-      document.getElementById("apps").removeAttribute("hidden");
+      doc.getElementById("apps").removeAttribute("hidden");
 
     let ss = Components.classes["@mozilla.org/browser/sessionstore;1"].
              getService(Components.interfaces.nsISessionStore);
     if (ss.canRestoreLastSession &&
         !PrivateBrowsingUtils.isWindowPrivate(window))
-      document.getElementById("launcher").setAttribute("session", "true");
+      doc.getElementById("launcher").setAttribute("session", "true");
 
     // Inject search engine and snippets URL.
-    let docElt = document.documentElement;
+    let docElt = doc.documentElement;
     docElt.setAttribute("snippetsURL", AboutHomeUtils.snippetsURL);
     docElt.setAttribute("searchEngineName",
                         AboutHomeUtils.defaultSearchEngine.name);
     docElt.setAttribute("searchEngineURL",
                         AboutHomeUtils.defaultSearchEngine.searchURL);
+
+#ifdef MOZ_SERVICES_HEALTHREPORT
+    doc.addEventListener("AboutHomeSearchEvent", function onSearch(e) {
+      BrowserSearch.recordSearchInHealthReport(e.detail, "abouthome");
+    }, true, true);
+#endif
   }
 }
 
 /**
  * Handle command events bubbling up from error page content
  */
 let BrowserOnClick = {
   handleEvent: function BrowserOnClick_handleEvent(aEvent) {
@@ -3460,16 +3466,19 @@ const BrowserSearch = {
    * @param useNewTab
    *        Boolean indicating whether or not the search should load in a new
    *        tab.
    *
    * @param purpose [optional]
    *        A string meant to indicate the context of the search request. This
    *        allows the search service to provide a different nsISearchSubmission
    *        depending on e.g. where the search is triggered in the UI.
+   *
+   * @return string Name of the search engine used to perform a search or null
+   *         if a search was not performed.
    */
   loadSearch: function BrowserSearch_search(searchText, useNewTab, purpose) {
     var engine;
 
     // If the search bar is visible, use the current engine, otherwise, fall
     // back to the default engine.
     if (isElementVisible(this.searchBar))
       engine = Services.search.currentEngine;
@@ -3477,41 +3486,92 @@ const BrowserSearch = {
       engine = Services.search.defaultEngine;
 
     var submission = engine.getSubmission(searchText, null, purpose); // HTML response
 
     // getSubmission can return null if the engine doesn't have a URL
     // with a text/html response type.  This is unlikely (since
     // SearchService._addEngineToStore() should fail for such an engine),
     // but let's be on the safe side.
-    if (!submission)
-      return;
+    if (!submission) {
+      return null;
+    }
 
     let inBackground = Services.prefs.getBoolPref("browser.search.context.loadInBackground");
     openLinkIn(submission.uri.spec,
                useNewTab ? "tab" : "current",
                { postData: submission.postData,
                  inBackground: inBackground,
                  relatedToCurrent: true });
+
+    return engine.name;
+  },
+
+  /**
+   * Perform a search initiated from the context menu.
+   *
+   * This should only be called from the context menu. See
+   * BrowserSearch.loadSearch for the preferred API.
+   */
+  loadSearchFromContext: function (terms) {
+    let engine = BrowserSearch.loadSearch(terms, true, "contextmenu");
+    if (engine) {
+      BrowserSearch.recordSearchInHealthReport(engine, "contextmenu");
+    }
   },
 
   /**
    * Returns the search bar element if it is present in the toolbar, null otherwise.
    */
   get searchBar() {
     return document.getElementById("searchbar");
   },
 
   loadAddEngines: function BrowserSearch_loadAddEngines() {
     var newWindowPref = gPrefService.getIntPref("browser.link.open_newwindow");
     var where = newWindowPref == 3 ? "tab" : "window";
     var searchEnginesURL = formatURL("browser.search.searchEnginesURL", true);
     openUILinkIn(searchEnginesURL, where);
-  }
-}
+  },
+
+  /**
+   * Helper to record a search with Firefox Health Report.
+   *
+   * FHR records only search counts and nothing pertaining to the search itself.
+   *
+   * @param engine
+   *        (string) The name of the engine used to perform the search. This
+   *        is typically nsISearchEngine.name.
+   * @param source
+   *        (string) Where the search originated from. See the FHR
+   *        SearchesProvider for allowed values.
+   */
+  recordSearchInHealthReport: function (engine, source) {
+#ifdef MOZ_SERVICES_HEALTHREPORT
+    let reporter = Cc["@mozilla.org/datareporting/service;1"]
+                     .getService()
+                     .wrappedJSObject
+                     .healthReporter;
+
+    // This can happen if the FHR component of the data reporting service is
+    // disabled. This is controlled by a pref that most will never use.
+    if (!reporter) {
+      return;
+    }
+
+    reporter.onInit().then(function record() {
+      try {
+        reporter.getProvider("org.mozilla.searches").recordSearch(engine, source);
+      } catch (ex) {
+        Cu.reportError(ex);
+      }
+    });
+#endif
+  },
+};
 
 function FillHistoryMenu(aParent) {
   // Lazily add the hover listeners on first showing and never remove them
   if (!aParent.hasStatusListener) {
     // Show history item's uri in the status bar when hovering, and clear on exit
     aParent.addEventListener("DOMMenuItemActive", function(aEvent) {
       // Only the current page should have the checked attribute, so skip it
       if (!aEvent.target.hasAttribute("checked"))
@@ -7445,8 +7505,9 @@ var MousePosTracker = {
 
 function focusNextFrame(event) {
   let fm = Services.focus;
   let dir = event.shiftKey ? fm.MOVEFOCUS_BACKWARDDOC : fm.MOVEFOCUS_FORWARDDOC;
   let element = fm.moveFocus(window, null, dir, fm.FLAG_BYKEY);
   if (element.ownerDocument == document)
     focusAndSelectUrlBar();
 }
+
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -260,17 +260,16 @@
 #endif
       </hbox>
     </panel>
 
     <panel id="social-notification-panel"
            class="social-panel"
            type="arrow"
            hidden="true"
-           consumeoutsideclicks="false"
            noautofocus="true"/>
     <panel id="social-flyout-panel"
            class="social-panel"
            onpopupshown="SocialFlyout.onShown()"
            onpopuphidden="SocialFlyout.onHidden()"
            side="right"
            type="arrow"
            hidden="true"
--- a/browser/base/content/socialchat.xml
+++ b/browser/base/content/socialchat.xml
@@ -340,27 +340,29 @@
         ]]></body>
       </method>
 
       <method name="remove">
         <parameter name="aChatbox"/>
         <body><![CDATA[
           this._remove(aChatbox);
           // The removal of a chat may mean a collapsed one can spring up,
-          // or that the popup should be hidden.
+          // or that the popup should be hidden.  We also defer the selection
+          // of another chat until after a resize, as a new candidate may
+          // become uncollapsed after the resize.
           this.resize();
+          if (this.selectedChat == aChatbox) {
+            this._selectAnotherChat();
+          }
         ]]></body>
       </method>
 
       <method name="_remove">
         <parameter name="aChatbox"/>
         <body><![CDATA[
-          if (this.selectedChat == aChatbox) {
-            this._selectAnotherChat();
-          }
           aChatbox.iframe.socialErrorListener.remove();
           this.removeChild(aChatbox);
           // child might have been collapsed.
           let menuitem = this.menuitemMap.get(aChatbox);
           if (menuitem) {
             this.menuitemMap.delete(aChatbox);
             this.menupopup.removeChild(menuitem);
           }
--- a/browser/base/content/test/browser_aboutHome.js
+++ b/browser/base/content/test/browser_aboutHome.js
@@ -84,16 +84,83 @@ let gTests = [
        "Search engine logo's alt text is a nonempty string");
 
     isnot(altText, "undefined",
           "Search engine logo's alt text shouldn't be the string 'undefined'");
 
     executeSoon(runNextTest);
   }
 },
+{
+  desc: "Check that performing a search fires a search event.",
+  setup: function () { },
+  run: function () {
+    let doc = gBrowser.contentDocument;
+
+    doc.addEventListener("AboutHomeSearchEvent", function onSearch(e) {
+      is(e.detail, doc.documentElement.getAttribute("searchEngineName"), "Detail is search engine name");
+
+      gBrowser.stop();
+      executeSoon(runNextTest);
+    }, true, true);
+
+    doc.getElementById("searchText").value = "it works";
+    doc.getElementById("searchSubmit").click();
+  },
+},
+{
+  desc: "Check that performing a search records to Firefox Health Report.",
+  setup: function () { },
+  run: function () {
+    if (!("@mozilla.org/datareporting/service;1" in Components.classes)) {
+      runNextTest();
+      return;
+    }
+
+
+    let doc = gBrowser.contentDocument;
+
+    // We rely on the listener in browser.js being installed and fired before
+    // this one. If this ever changes, we should add an executeSoon() or similar.
+    doc.addEventListener("AboutHomeSearchEvent", function onSearch(e) {
+      executeSoon(gBrowser.stop.bind(gBrowser));
+      let reporter = Components.classes["@mozilla.org/datareporting/service;1"]
+                                       .getService()
+                                       .wrappedJSObject
+                                       .healthReporter;
+      ok(reporter, "Health Reporter instance available.");
+
+      reporter.onInit().then(function onInit() {
+        let provider = reporter.getProvider("org.mozilla.searches");
+        ok(provider, "Searches provider is available.");
+
+        let engineName = doc.documentElement.getAttribute("searchEngineName").toLowerCase();
+
+        let m = provider.getMeasurement("counts", 1);
+        m.getValues().then(function onValues(data) {
+          let now = new Date();
+          ok(data.days.hasDay(now), "Have data for today.");
+
+          let day = data.days.getDay(now);
+          let field = engineName + ".abouthome";
+          ok(day.has(field), "Have data for about home on this engine.");
+
+          // Note the search from the previous test.
+          is(day.get(field), 2, "Have searches recorded.");
+
+          executeSoon(runNextTest);
+        });
+
+      });
+    }, true, true);
+
+    doc.getElementById("searchText").value = "a search";
+    doc.getElementById("searchSubmit").click();
+  },
+},
 ];
 
 function test()
 {
   waitForExplicitFinish();
 
   // Ensure that by default we don't try to check for remote snippets since that
   // could be tricky due to network bustages or slowness.
--- a/browser/base/content/test/browser_contextSearchTabPosition.js
+++ b/browser/base/content/test/browser_contextSearchTabPosition.js
@@ -1,26 +1,63 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 function test() {
+  waitForExplicitFinish();
+
   function tabAdded(event) {
     let tab = event.target;
     tabs.push(tab);
   }
 
   let tabs = [];
 
   let container = gBrowser.tabContainer;
   container.addEventListener("TabOpen", tabAdded, false);
 
   gBrowser.addTab("about:blank");
-  BrowserSearch.loadSearch("mozilla", true);
-  BrowserSearch.loadSearch("firefox", true);
-  
+  BrowserSearch.loadSearchFromContext("mozilla");
+  BrowserSearch.loadSearchFromContext("firefox");
+
   is(tabs[0], gBrowser.tabs[3], "blank tab has been pushed to the end");
   is(tabs[1], gBrowser.tabs[1], "first search tab opens next to the current tab");
   is(tabs[2], gBrowser.tabs[2], "second search tab opens next to the first search tab");
 
   container.removeEventListener("TabOpen", tabAdded, false);
   tabs.forEach(gBrowser.removeTab, gBrowser);
+
+  if (!"@mozilla.org/datareporting/service;1" in Components.classes) {
+    finish();
+    return;
+  }
+
+  let reporter = Components.classes["@mozilla.org/datareporting/service;1"]
+                                   .getService()
+                                   .wrappedJSObject
+                                   .healthReporter;
+
+  // reporter should always be available in automation.
+  ok(reporter, "Health Reporter available.");
+  reporter.onInit().then(function onInit() {
+    let provider = reporter.getProvider("org.mozilla.searches");
+    ok(provider, "Searches provider is available.");
+
+    let m = provider.getMeasurement("counts", 1);
+    m.getValues().then(function onValues(data) {
+      let now = new Date();
+      ok(data.days.hasDay(now), "Have data for today.");
+      let day = data.days.getDay(now);
+
+      // Will need changed if Google isn't the default search engine.
+      let field = "google.contextmenu";
+      ok(day.has(field), "Have search recorded for context menu.");
+
+      // If any other mochitests perform a context menu search, this will fail.
+      // The solution will be to look up count at test start and ensure it is
+      // incremented by two.
+      is(day.get(field), 2, "2 searches recorded in FHR.");
+      finish();
+    });
+  });
 }
+
--- a/browser/base/content/test/browser_urlbarAutoFillTrimURLs.js
+++ b/browser/base/content/test/browser_urlbarAutoFillTrimURLs.js
@@ -67,22 +67,16 @@ function waitForClearHistory(aCallback) 
     Services.obs.removeObserver(observeCH, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
     aCallback();
   }, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
   PlacesUtils.bhistory.removeAllPages();
 }
 
 function waitForSearchComplete(aCallback) {
   info("Waiting for onSearchComplete");
-  // onSearchComplete is implemented as an XBL method, which is readonly on
-  // the prototype. This means that setting it on the derived/bound object
-  // is an error in strict mode if there's no |own| property. Use defineProperty
-  // to explicitly make it so.
-  Object.defineProperty(gURLBar, 'onSearchComplete', { value: gURLBar.onSearchComplete,
-                                                       writable: true, configurable: true });
   let onSearchComplete = gURLBar.onSearchComplete;
   registerCleanupFunction(function () {
     gURLBar.onSearchComplete = onSearchComplete;
   });
   gURLBar.onSearchComplete = function () {
     ok(gURLBar.popupOpen, "The autocomplete popup is correctly open");
     is(gURLBar.controller.matchCount, 1, "Found the expected number of matches")
     onSearchComplete.apply(gURLBar);
--- a/browser/base/content/test/social/browser_social_chatwindow.js
+++ b/browser/base/content/test/social/browser_social_chatwindow.js
@@ -9,20 +9,23 @@ function test() {
   let manifest = { // normal provider
     name: "provider 1",
     origin: "https://example.com",
     sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
     workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
     iconURL: "https://example.com/browser/browser/base/content/test/moz.png"
   };
   let oldwidth = window.outerWidth; // we futz with this, so we restore it
+  let postSubTest = function(cb) {
+    let chats = document.getElementById("pinnedchats");
+    ok(chats.children.length == 0, "no chatty children left behind");
+    cb();
+  };
   runSocialTestWithProvider(manifest, function (finishcb) {
-    runSocialTests(tests, undefined, undefined, function () {
-      let chats = document.getElementById("pinnedchats");
-      ok(chats.children.length == 0, "no chatty children left behind");
+    runSocialTests(tests, undefined, postSubTest, function() {
       window.resizeTo(oldwidth, window.outerHeight);
       finishcb();
     });
   });
 }
 
 var tests = {
   testOpenCloseChat: function(next) {
@@ -139,46 +142,52 @@ var tests = {
       }
     }
     port.postMessage({topic: "test-worker-chat", data: chatUrl});
   },
   testManyChats: function(next) {
     // open enough chats to overflow the window, then check
     // if the menupopup is visible
     let port = Social.provider.getWorkerPort();
+    let chats = document.getElementById("pinnedchats");
     ok(port, "provider has a port");
+    ok(chats.menupopup.parentNode.collapsed, "popup nub collapsed at start");
     port.postMessage({topic: "test-init"});
-    let width = document.documentElement.boxObject.width;
-    let numToOpen = (width / 200) + 1;
+    // we should *never* find a test box that needs more than this to cause
+    // an overflow!
+    let maxToOpen = 20;
+    let numOpened = 0;
+    let maybeOpenAnother = function() {
+      if (numOpened++ >= maxToOpen) {
+        ok(false, "We didn't find a collapsed chat after " + maxToOpen + "chats!");
+        closeAllChats();
+        next();
+      }
+      port.postMessage({topic: "test-chatbox-open", data: { id: numOpened }});
+    }
     port.onmessage = function (e) {
       let topic = e.data.topic;
       switch (topic) {
         case "got-chatbox-message":
-          numToOpen--;
-          if (numToOpen >= 0) {
-            // we're waiting for all to open
-            ok(true, "got a chat window opened");
+          if (!chats.menupopup.parentNode.collapsed) {
+            maybeOpenAnother();
             break;
           }
+          ok(true, "popup nub became visible");
           // close our chats now
-          let chats = document.getElementById("pinnedchats");
-          ok(!chats.menupopup.parentNode.collapsed, "menu selection is visible");
           while (chats.selectedChat) {
             chats.selectedChat.close();
           }
           ok(!chats.selectedChat, "chats are all closed");
           port.close();
           next();
           break;
       }
     }
-    let num = numToOpen;
-    while (num-- > 0) {
-      port.postMessage({topic: "test-chatbox-open", data: { id: num }});
-    }
+    maybeOpenAnother();
   },
   testWorkerChatWindow: function(next) {
     const chatUrl = "https://example.com/browser/browser/base/content/test/social/social_chat.html";
     let port = Social.provider.getWorkerPort();
     ok(port, "provider has a port");
     port.postMessage({topic: "test-init"});
     port.onmessage = function (e) {
       let topic = e.data.topic;
@@ -274,16 +283,52 @@ var tests = {
       next();
     });
   },
 
   testRemoveAllMinimized: function(next) {
     this.testRemoveAll(next, "minimized");
   },
 
+  // Check what happens when you close the only visible chat.
+  testCloseOnlyVisible: function(next) {
+    let chatbar = window.SocialChatBar.chatbar;
+    let chatWidth = undefined;
+    let num = 0;
+    is(chatbar.childNodes.length, 0, "chatbar starting empty");
+    is(chatbar.menupopup.childNodes.length, 0, "popup starting empty");
+
+    makeChat("normal", "first chat", function() {
+      // got the first one.
+      checkPopup();
+      ok(chatbar.menupopup.parentNode.collapsed, "menu selection isn't visible");
+      // we kinda cheat here and get the width of the first chat, assuming
+      // that all future chats will have the same width when open.
+      chatWidth = chatbar.calcTotalWidthOf(chatbar.selectedChat);
+      let desired = chatWidth * 1.5;
+      resizeWindowToChatAreaWidth(desired, function(sizedOk) {
+        ok(sizedOk, "can't do any tests without this width");
+        checkPopup();
+        makeChat("normal", "second chat", function() {
+          is(chatbar.childNodes.length, 2, "now have 2 chats");
+          let first = chatbar.childNodes[0];
+          let second = chatbar.childNodes[1];
+          is(chatbar.selectedChat, first, "first chat is selected");
+          ok(second.collapsed, "second chat is currently collapsed");
+          // closing the first chat will leave enough room for the second
+          // chat to appear, and thus become selected.
+          chatbar.selectedChat.close();
+          is(chatbar.selectedChat, second, "second chat is selected");
+          closeAllChats();
+          next();
+        });
+      });
+    });
+  },
+
   // resize and collapse testing.
   testBrowserResize: function(next, mode) {
     let chats = document.getElementById("pinnedchats");
     let port = Social.provider.getWorkerPort();
     port.postMessage({topic: "test-init"});
     get3ChatsForCollapsing(mode || "normal", function(first, second, third) {
       let chatWidth = chats.getTotalChildWidth(first);
       ok(chatWidth, "have a chatwidth");
--- a/browser/branding/aurora/locales/jar.mn
+++ b/browser/branding/aurora/locales/jar.mn
@@ -3,10 +3,10 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
 @AB_CD@.jar:
 % locale branding @AB_CD@ %locale/branding/
 # Aurora branding only exists in en-US
   locale/branding/brand.dtd        (en-US/brand.dtd)
-* locale/branding/brand.properties (en-US/brand.properties)
-* locale/branding/browserconfig.properties (browserconfig.properties)
+  locale/branding/brand.properties (en-US/brand.properties)
+  locale/branding/browserconfig.properties (browserconfig.properties)
--- a/browser/branding/nightly/locales/jar.mn
+++ b/browser/branding/nightly/locales/jar.mn
@@ -3,10 +3,10 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
 @AB_CD@.jar:
 % locale branding @AB_CD@ %locale/branding/
 # Nightly branding only exists in en-US
   locale/branding/brand.dtd        (en-US/brand.dtd)
-* locale/branding/brand.properties (en-US/brand.properties)
-* locale/branding/browserconfig.properties (browserconfig.properties)
+  locale/branding/brand.properties (en-US/brand.properties)
+  locale/branding/browserconfig.properties (browserconfig.properties)
--- a/browser/branding/unofficial/locales/jar.mn
+++ b/browser/branding/unofficial/locales/jar.mn
@@ -3,10 +3,10 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
 @AB_CD@.jar:
 % locale branding @AB_CD@ %locale/branding/
 # Unofficial branding only exists in en-US
   locale/branding/brand.dtd        (en-US/brand.dtd)
-* locale/branding/brand.properties (en-US/brand.properties)
-* locale/branding/browserconfig.properties (browserconfig.properties)
+  locale/branding/brand.properties (en-US/brand.properties)
+  locale/branding/browserconfig.properties (browserconfig.properties)
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -450,16 +450,17 @@
       </method>
 
       <method name="doSearch">
         <parameter name="aData"/>
         <parameter name="aWhere"/>
         <body><![CDATA[
           // null parameter below specifies HTML response for search
           var submission = this.currentEngine.getSubmission(aData);
+          BrowserSearch.recordSearchInHealthReport(this.currentEngine.name, "searchbar");
           openUILinkIn(submission.uri.spec, aWhere, null, submission.postData);
         ]]></body>
       </method>
     </implementation>
 
     <handlers>
       <handler event="command"><![CDATA[
         const target = event.originalTarget;
--- a/browser/components/search/test/Makefile.in
+++ b/browser/components/search/test/Makefile.in
@@ -10,16 +10,17 @@ relativesrcdir  = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_BROWSER_FILES = \
   head.js \
   browser_405664.js \
   browser_addEngine.js \
   browser_contextmenu.js \
+  browser_healthreport.js \
   browser_private_search_perwindowpb.js \
   testEngine.xml \
   testEngine_mozsearch.xml \
   testEngine.src \
   browser_426329.js \
   426329.xml \
   browser_483086.js \
   483086-1.xml \
new file mode 100644
--- /dev/null
+++ b/browser/components/search/test/browser_healthreport.js
@@ -0,0 +1,96 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+function test() {
+  waitForExplicitFinish();
+
+  if (!("@mozilla.org/datareporting/service;1" in Components.classes)) {
+    // We need a test or else we'll be marked as failure.
+    ok(true, "Firefox Health Report is not enabled.");
+    finish();
+    return;
+  }
+
+  function testFHR() {
+    let reporter = Components.classes["@mozilla.org/datareporting/service;1"]
+                                     .getService()
+                                     .wrappedJSObject
+                                     .healthReporter;
+    ok(reporter, "Health Reporter available.");
+    reporter.onInit().then(function onInit() {
+      let provider = reporter.getProvider("org.mozilla.searches");
+      let m = provider.getMeasurement("counts", 1);
+
+      m.getValues().then(function onData(data) {
+        let now = new Date();
+        let oldCount = 0;
+
+        // Foo engine goes into "other" bucket.
+        let field = "other.searchbar";
+
+        if (data.days.hasDay(now)) {
+          let day = data.days.getDay(now);
+          if (day.has(field)) {
+            oldCount = day.get(field);
+          }
+        }
+
+        // Now perform a search and ensure the count is incremented.
+        let tab = gBrowser.addTab();
+        gBrowser.selectedTab = tab;
+        let searchBar = BrowserSearch.searchBar;
+
+        searchBar.value = "firefox health report";
+        searchBar.focus();
+
+        function afterSearch() {
+          searchBar.value = "";
+          gBrowser.removeTab(tab);
+
+          m.getValues().then(function onData(data) {
+            ok(data.days.hasDay(now), "Have data for today.");
+            let day = data.days.getDay(now);
+
+            is(day.get(field), oldCount + 1, "Performing a search increments FHR count by 1.");
+
+            let engine = Services.search.getEngineByName("Foo");
+            Services.search.removeEngine(engine);
+          });
+        }
+
+        EventUtils.synthesizeKey("VK_RETURN", {});
+        executeSoon(afterSearch);
+      });
+    });
+  }
+
+  function observer(subject, topic, data) {
+    switch (data) {
+      case "engine-added":
+        let engine = Services.search.getEngineByName("Foo");
+        ok(engine, "Engine was added.");
+        Services.search.currentEngine = engine;
+        break;
+
+      case "engine-current":
+        is(Services.search.currentEngine.name, "Foo", "Current engine is Foo");
+        testFHR();
+        break;
+
+      case "engine-removed":
+        Services.obs.removeObserver(observer, "browser-search-engine-modified");
+        finish();
+        break;
+    }
+  }
+
+  Services.obs.addObserver(observer, "browser-search-engine-modified", false);
+  Services.search.addEngine("http://mochi.test:8888/browser/browser/components/search/test/testEngine.xml",
+                            Ci.nsISearchEngine.DATA_XML,
+                            "data:image/x-icon,%00",
+                            false);
+
+}
+
--- a/browser/config/mozconfigs/linux32/l10n-mozconfig
+++ b/browser/config/mozconfigs/linux32/l10n-mozconfig
@@ -2,10 +2,11 @@ ac_add_options --with-l10n-base=../../l1
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 . $topsrcdir/build/unix/mozconfig.linux
 
+export MOZILLA_OFFICIAL=1
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/linux64/l10n-mozconfig
+++ b/browser/config/mozconfigs/linux64/l10n-mozconfig
@@ -2,10 +2,11 @@ ac_add_options --with-l10n-base=../../l1
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 . $topsrcdir/build/unix/mozconfig.linux
 
+export MOZILLA_OFFICIAL=1
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/macosx-universal/l10n-mozconfig
+++ b/browser/config/mozconfigs/macosx-universal/l10n-mozconfig
@@ -1,12 +1,11 @@
 . "$topsrcdir/browser/config/mozconfigs/common"
 
-ac_add_options --with-l10n-base=../../l10n-central
-
-if [ "${MOZ_UPDATE_CHANNEL}" = "release" -o "${MOZ_UPDATE_CHANNEL}" = "beta" ]; then
-fi
-
+ac_add_options --with-l10n-base=../../../l10n-central
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
+ac_add_options --with-macbundlename-prefix=Firefox
 ac_add_options --with-ccache
 
+export MOZILLA_OFFICIAL=1
+
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/win32/l10n-mozconfig
+++ b/browser/config/mozconfigs/win32/l10n-mozconfig
@@ -1,13 +1,16 @@
 . "$topsrcdir/browser/config/mozconfigs/common"
 
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --with-l10n-base=../../l10n-central
+ac_add_options --enable-metro
+
+export MOZILLA_OFFICIAL=1
 
 if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
   . $topsrcdir/build/win32/mozconfig.vs2010-win64
 else
   . $topsrcdir/build/win32/mozconfig.vs2010
 fi
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -134,17 +134,16 @@
 #endif
 
 ; [Components]
 @BINPATH@/browser/components/components.manifest
 @BINPATH@/components/alerts.xpt
 #ifdef ACCESSIBILITY
 #ifdef XP_WIN32
 @BINPATH@/AccessibleMarshal.dll
-@BINPATH@/components/accessibility-msaa.xpt
 #endif
 @BINPATH@/components/accessibility.xpt
 #endif
 @BINPATH@/components/appshell.xpt
 @BINPATH@/components/appstartup.xpt
 @BINPATH@/components/autocomplete.xpt
 @BINPATH@/components/autoconfig.xpt
 @BINPATH@/browser/components/browsercompsbase.xpt
--- a/browser/installer/windows/nsis/shared.nsh
+++ b/browser/installer/windows/nsis/shared.nsh
@@ -1,16 +1,47 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 ; The registration ID of the COM server which is used for choosing wether
 ; to launch the Win8 metro browser or desktop browser.
 !define DELEGATE_EXECUTE_HANDLER_ID {5100FEC1-212B-4BF5-9BF8-3E650FD794A3}
 
+; Does metro registration for the command execute handler
+Function RegisterCEH
+!ifdef MOZ_METRO
+  ${If} ${AtLeastWin8}
+    ${CleanupMetroBrowserHandlerValues} ${DELEGATE_EXECUTE_HANDLER_ID}
+    ${AddMetroBrowserHandlerValues} ${DELEGATE_EXECUTE_HANDLER_ID} \
+                                    "$INSTDIR\CommandExecuteHandler.exe" \
+                                    $AppUserModelID \
+                                    "FirefoxURL" \
+                                    "FirefoxHTML"
+  ${EndIf}
+!endif
+FunctionEnd
+
+; If MOZ_METRO is defined and we're at least win8, then we should re-create
+; the start menu shortcut so that the Metro browser is accessible.
+; This is also for zip builds who won't have a start menu shortcut yet.
+Function CreateStartMenuTile
+!ifdef MOZ_METRO
+    Delete "$SMPROGRAMS\${BrandFullName}.lnk"
+    CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}"
+    ${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk"
+      ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \
+                                             "$INSTDIR"
+      ${If} "$AppUserModelID" != ""
+        ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "$AppUserModelID" "true"
+      ${EndIf}
+    ${EndIf}
+!endif
+FunctionEnd
+
 !macro PostUpdate
   ${CreateShortcutsLog}
 
   ; Remove registry entries for non-existent apps and for apps that point to our
   ; install location in the Software\Mozilla key and uninstall registry entries
   ; that point to our install location for both HKCU and HKLM.
   SetShellVarContext current  ; Set SHCTX to the current user (e.g. HKCU)
   ${RegCleanMain} "Software\Mozilla"
@@ -18,16 +49,20 @@
   ${UpdateProtocolHandlers}
 
   ; setup the application model id registration value
   ${InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs"
 
   ; Win7 taskbar and start menu link maintenance
   Call FixShortcutAppModelIDs
 
+  ; Win8 specific registration
+  Call RegisterCEH
+  Call CreateStartMenuTile
+
   ClearErrors
   WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" "Write Test"
   ${If} ${Errors}
     StrCpy $TmpVal "HKCU" ; used primarily for logging
   ${Else}
     SetShellVarContext all    ; Set SHCTX to all users (e.g. HKLM)
     DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest"
     StrCpy $TmpVal "HKLM" ; used primarily for logging
@@ -337,26 +372,17 @@
 
   ; An empty string is used for the 5th param because FirefoxHTML is not a
   ; protocol handler
   ${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" \
                                  "${AppRegName} HTML Document" ""
 
   ${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" \
                                  "true"
-!ifdef MOZ_METRO
-  ${If} ${AtLeastWin8}
-    ${CleanupMetroBrowserHandlerValues} ${DELEGATE_EXECUTE_HANDLER_ID}
-    ${AddMetroBrowserHandlerValues} ${DELEGATE_EXECUTE_HANDLER_ID} \
-                                    "$INSTDIR\CommandExecuteHandler.exe" \
-                                    $AppUserModelID \
-                                    "FirefoxURL" \
-                                    "FirefoxHTML"
-  ${EndIf}
-!endif
+  Call RegisterCEH
 
   ; An empty string is used for the 4th & 5th params because the following
   ; protocol handlers already have a display name and the additional keys
   ; required for a protocol handler.
   ${AddDisabledDDEHandlerValues} "ftp" "$2" "$8,1" "" ""
   ${AddDisabledDDEHandlerValues} "http" "$2" "$8,1" "" ""
   ${AddDisabledDDEHandlerValues} "https" "$2" "$8,1" "" ""
 !macroend
@@ -1144,30 +1170,17 @@ Function SetAsDefaultAppUserHKCU
   ${EndUnless}
 
   SetShellVarContext current  ; Set SHCTX to the current user (e.g. HKCU)
 
   ${If} ${AtLeastWin8}
     ${SetStartMenuInternet} "HKCU"
     ${FixShellIconHandler} "HKCU"
     ${FixClassKeys} ; Does not use SHCTX
-; If MOZ_METRO is defined and we're at least win8, then we should re-create
-; the start menu shortcut so that the Metro browser is accessible.
-; This is also for zip builds who won't have a start menu shortcut yet.
-!ifdef MOZ_METRO
-    Delete "$SMPROGRAMS\${BrandFullName}.lnk"
-    CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}"
-    ${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk"
-      ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \
-                                             "$INSTDIR"
-      ${If} "$AppUserModelID" != ""
-        ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "$AppUserModelID" "true"
-      ${EndIf}
-    ${EndIf}
-!endif
+    Call CreateStartMenuTile
   ${EndIf}
 
   ${SetHandlers}
 
   ${If} ${AtLeastWinVista}
     ; Only register as the handler on Vista and above if the app registry name
     ; exists under the RegisteredApplications registry key. The protocol and
     ; file handlers set previously at the user level will associate this install
--- a/browser/metro/base/content/BrowserTouchHandler.js
+++ b/browser/metro/base/content/BrowserTouchHandler.js
@@ -15,16 +15,18 @@ const BrowserTouchHandler = {
     document.addEventListener("CancelTouchSequence", this, false);
 
     // Messages sent from content.js
     messageManager.addMessageListener("Content:ContextMenu", this);
   },
 
   // Content forwarding the contextmenu command
   onContentContextMenu: function onContentContextMenu(aMessage) {
+    // Note, target here is the target of the message manager message,
+    // usually the browser.
     let contextInfo = { name: aMessage.name,
                         json: aMessage.json,
                         target: aMessage.target };
     // Touch input selection handling
     if (!InputSourceHelper.isPrecise) {
       if (SelectionHelperUI.isActive()) {
         // Selection handler is active.
         if (aMessage.json.types.indexOf("selected-text") != -1) {
--- a/browser/metro/base/content/ContextCommands.js
+++ b/browser/metro/base/content/ContextCommands.js
@@ -142,19 +142,18 @@ var ContextCommands = {
                               this.docRef);
   },
 
   copyPhone: function cc_copyPhone() {
     this.clipboard.copyString(ContextMenuUI.popupState.linkURL.substr(ContextMenuUI.popupState.linkURL.indexOf(':')+1),
                               this.docRef);
   },
 
-  copyImageLocation: function cc_copyImageLocation() {
-    this.clipboard.copyString(ContextMenuUI.popupState.mediaURL,
-                              this.docRef);
+  copyImage: function cc_copyImage() {
+    this.sendCommand("copy-image-contents");
   },
 
   bookmarkLink: function cc_bookmarkLink() {
     let state = ContextMenuUI.popupState;
     let uri = Util.makeURI(state.linkURL);
     let title = state.linkTitle || state.linkURL;
 
     try {
@@ -164,42 +163,36 @@ var ContextCommands = {
     }
 
     let message = Strings.browser.GetStringFromName("alertLinkBookmarked");
     let toaster = Cc["@mozilla.org/toaster-alerts-service;1"].getService(Ci.nsIAlertsService);
     toaster.showAlertNotification(null, message, "", false, "", null);
   },
 
   sendCommand: function cc_playVideo(aCommand) {
+    // Send via message manager over to ContextMenuHandler
     let browser = ContextMenuUI.popupState.target;
     browser.messageManager.sendAsyncMessage("Browser:ContextCommand", { command: aCommand });
   },
 
   editBookmark: function cc_editBookmark() {
     let target = ContextMenuUI.popupState.target;
     target.startEditing();
   },
 
   removeBookmark: function cc_removeBookmark() {
     let target = ContextMenuUI.popupState.target;
     target.remove();
   },
 
-  shortcutBookmark: function cc_shortcutBookmark() {
-    let target = ContextMenuUI.popupState.target;
-    Util.createShortcut(target.getAttribute("title"), target.getAttribute("uri"), target.getAttribute("src"), "bookmark");
-  },
-
   findInPage: function cc_findInPage() {
-    dump('ContextCommand: findInPage');
     FindHelperUI.show();
   },
 
   viewOnDesktop: function cc_viewOnDesktop() {
-    dump('ContextCommand: viewOnDesktop');
     Appbar.onViewOnDesktop();
   },
 
   /*
    * Utilities
    */
 
   /*
--- a/browser/metro/base/content/PageActions.js
+++ b/browser/metro/base/content/PageActions.js
@@ -9,20 +9,16 @@ var PageActions = {
     if (this._handlers)
       return;
 
     this._handlers = [];
     document.getElementById("pageactions-container").addEventListener("click", this, true);
 
     this.register("pageaction-reset", this.updatePagePermissions, this);
     this.register("pageaction-password", this.updateForgetPassword, this);
-#ifdef NS_PRINTING
-    this.register("pageaction-saveas", this.updatePageSaveAs, this);
-#endif
-    this.register("pageaction-share", this.updateShare, this);
 
     CharsetMenu.init();
   },
 
   handleEvent: function handleEvent(aEvent) {
     switch (aEvent.type) {
       case "click":
         IdentityUI.hide();
@@ -129,40 +125,16 @@ var PageActions = {
     let lm = this._loginManager;
     if (!lm.getLoginSavingEnabled(host.prePath))
       lm.setLoginSavingEnabled(host.prePath, true);
 
     this.hideItem(aEvent.target);
     aEvent.stopPropagation(); // Don't hide the site menu.
   },
 
-  pinSite : function pinCurrentSite() {
-    if (Browser.selectedBrowser.currentURI.spec.length == 0) {
-      return;
-    }
-    Browser.pinSite();
-  },
-
-  unpinSite : function unpinCurrentSite() {
-    if (Browser.selectedBrowser.currentURI.spec.length == 0) {
-      return;
-    }
-    Browser.unpinSite();
-  },
-
-  updatePageSaveAs: function updatePageSaveAs(aNode) {
-    // Check for local XUL content
-    let contentWindow = Browser.selectedBrowser.contentWindow;
-    return !(contentWindow && contentWindow.document instanceof XULDocument);
-  },
-
-  updateShare: function updateShare(aNode) {
-    return Util.isShareableScheme(Browser.selectedBrowser.currentURI.scheme);
-  },
-
   hideItem: function hideItem(aNode) {
     aNode.hidden = true;
     this._updateAttributes();
   },
 
   _updateAttributes: function _updateAttributes() {
     let container = document.getElementById("pageactions-container");
     let visibleNodes = container.querySelectorAll("pageaction:not([hidden=true])");
--- a/browser/metro/base/content/Util.js
+++ b/browser/metro/base/content/Util.js
@@ -276,73 +276,36 @@ let Util = {
     //dm.resumeDownload(download);
     //Services.obs.notifyObservers(download, "dl-start", null);
   },
 
   /*
    * Local system utilities
    */
 
-  createShortcut: function Util_createShortcut(aTitle, aURL, aIconURL, aType) {
-    // The background images are 72px, but Android will resize as needed.
-    // Bigger is better than too small.
-    const kIconSize = 72;
-    const kOverlaySize = 32;
-    const kOffset = 20;
-
-    // We have to fallback to something
-    aTitle = aTitle || aURL;
-
-    let canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
-    canvas.setAttribute("style", "display: none");
-
-    function _createShortcut() {
-      let icon = canvas.toDataURL("image/png", "");
-      canvas = null;
-      try {
-        let shell = Cc["@mozilla.org/browser/shell-service;1"].createInstance(Ci.nsIShellService);
-        shell.createShortcut(aTitle, aURL, icon, aType);
-      } catch(e) {
-        Cu.reportError(e);
-      }
+  copyImageToClipboard: function Util_copyImageToClipboard(aImageLoadingContent) {
+    let image = aImageLoadingContent.QueryInterface(Ci.nsIImageLoadingContent);
+    if (!image) {
+      Util.dumpLn("copyImageToClipboard error: image is not an nsIImageLoadingContent");
+      return;
     }
-
-    // Load the main background image first
-    let image = new Image();
-    image.onload = function() {
-      canvas.width = canvas.height = kIconSize;
-      let ctx = canvas.getContext("2d");
-      ctx.drawImage(image, 0, 0, kIconSize, kIconSize);
-
-      // If we have a favicon, lets draw it next
-      if (aIconURL) {
-        let favicon = new Image();
-        favicon.onload = function() {
-          // Center the favicon and overlay it on the background
-          ctx.drawImage(favicon, kOffset, kOffset, kOverlaySize, kOverlaySize);
-          _createShortcut();
-        }
-
-        favicon.onerror = function() {
-          Cu.reportError("CreateShortcut: favicon image load error");
-        }
-
-        favicon.src = aIconURL;
-      } else {
-        _createShortcut();
-      }
+    try {
+      let xferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
+      xferable.init(null);
+      let imgRequest = aImageLoadingContent.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
+      let mimeType = imgRequest.mimeType;
+      let imgContainer = imgRequest.image;
+      let imgPtr = Cc["@mozilla.org/supports-interface-pointer;1"].createInstance(Ci.nsISupportsInterfacePointer);
+      imgPtr.data = imgContainer;
+      xferable.setTransferData(mimeType, imgPtr, null);
+      let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
+      clip.setData(xferable, null, Ci.nsIClipboard.kGlobalClipboard);
+    } catch (e) {
+      Util.dumpLn(e.message);
     }
-
-    image.onerror = function() {
-      Cu.reportError("CreateShortcut: background image load error");
-    }
-
-    // Pick the right background
-    image.src = aIconURL ? "chrome://browser/skin/images/homescreen-blank-hdpi.png"
-                         : "chrome://browser/skin/images/homescreen-default-hdpi.png";
   },
 };
 
 
 /*
  * Timeout
  *
  * Helper class to nsITimer that adds a little more pizazz.  Callback can be an
--- a/browser/metro/base/content/browser-scripts.js
+++ b/browser/metro/base/content/browser-scripts.js
@@ -96,17 +96,16 @@ Cu.import("resource://gre/modules/Geomet
   ["MenuControlUI", "chrome://browser/content/helperui/MenuUI.js"],
   ["MenuPopup", "chrome://browser/content/helperui/MenuUI.js"],
   ["IdentityUI", "chrome://browser/content/helperui/IdentityUI.js"],
   ["IndexedDB", "chrome://browser/content/helperui/IndexedDB.js"],
   ["MasterPasswordUI", "chrome://browser/content/helperui/MasterPasswordUI.js"],
   ["OfflineApps", "chrome://browser/content/helperui/OfflineApps.js"],
   ["SelectHelperUI", "chrome://browser/content/helperui/SelectHelperUI.js"],
   ["SelectionHelperUI", "chrome://browser/content/helperui/SelectionHelperUI.js"],
-  ["SharingUI", "chrome://browser/content/helperui/SharingUI.js"],
   ["FullScreenVideo", "chrome://browser/content/video.js"],
   ["AnimatedZoom", "chrome://browser/content/AnimatedZoom.js"],
   ["CommandUpdater", "chrome://browser/content/commandUtil.js"],
   ["ContextCommands", "chrome://browser/content/ContextCommands.js"],
   ["Bookmarks", "chrome://browser/content/bookmarks.js"],
   ["Downloads", "chrome://browser/content/downloads.js"],
   ["BookmarksPanelView", "chrome://browser/content/bookmarks.js"],
   ["ConsolePanelView", "chrome://browser/content/console.js"],
--- a/browser/metro/base/content/browser.xul
+++ b/browser/metro/base/content/browser.xul
@@ -353,27 +353,20 @@
         </vbox>
         <box id="identity-popup-encryption-box">
           <image id="identity-popup-encryption-icon"/>
           <description id="identity-popup-encryption-label"/>
         </box>
       </box>
 
       <hbox id="pageactions-container" hidden="true">
-        <pageaction id="pageaction-findinpage" title="&pageactions.findInPage;"
-          onclick="FindHelperUI.show();"/>
-        <pageaction id="pageaction-share" title="&pageactions.share.page;"
-          onclick="SharingUI.show(getBrowser().currentURI.spec, getBrowser().contentTitle);"/>
-        <pageaction id="pageaction-pinsite" title="&pageactions.pin.site;"
-          onclick="PageActions.pinSite();"/>
         <pageaction id="pageaction-password" title="&pageactions.password.forget;"
           onclick="PageActions.forgetPassword(event);"/>
         <pageaction id="pageaction-reset" title="&pageactions.reset;"
           onclick="PageActions.clearPagePermissions(event);"/>
-        <pageaction id="pageaction-search" title="&pageactions.search.addNew;"/>
         <pageaction id="pageaction-charset" title="&pageactions.charEncoding;" onclick="CharsetMenu.show();"/>
       </hbox>
     </arrowbox>
 
     <vbox id="panel-container" hidden="true" class="window-width window-height meta">
       <hbox id="panel-header">
         <toolbarbutton id="panel-close-button" command="cmd_panel"/>
 
@@ -582,25 +575,25 @@
           <richlistitem id="context-select-all" type="select-all" onclick="ContextCommands.selectAll();">
             <label value="&selectAll.label;"/>
           </richlistitem>
 
           <!-- Image related -->
           <richlistitem id="context-viewinnewtab" type="image" onclick="ContextCommands.openInNewTab();">
             <label value="&contextViewInNewTab.label;"/>
           </richlistitem>
-          <richlistitem id="context-saveimage" type="image-loaded" onclick="ContextCommands.saveImage();">
+          <richlistitem id="context-copy-image" type="image-loaded" onclick="ContextCommands.copyImage();">
+            <label value="&contextCopyImage.label;"/>
+          </richlistitem>
+          <richlistitem id="context-save-image" type="image-loaded" onclick="ContextCommands.saveImage();">
             <label value="&contextSaveImage.label;"/>
           </richlistitem>
-          <richlistitem id="context-saveimage" type="image-loaded" onclick="ContextCommands.saveImageTo();">
+          <richlistitem id="context-save-image-to" type="image-loaded" onclick="ContextCommands.saveImageTo();">
             <label value="&contextSaveImageTo.label;"/>
           </richlistitem>
-          <richlistitem id="context-copy-image-location" type="image" onclick="ContextCommands.copyImageLocation();">
-            <label value="&contextCopyImageLocation.label;"/>
-          </richlistitem>
 
           <!-- Link related -->
           <richlistitem id="context-openinnewtab" type="link-openable" onclick="ContextCommands.openInNewTab();">
             <label value="&contextOpenInNewTab.label;"/>
           </richlistitem>
           <richlistitem id="context-bookmark-link" type="link" onclick="ContextCommands.bookmarkLink();">
             <label value="&contextBookmarkLink.label;"/>
           </richlistitem>
@@ -622,17 +615,17 @@
             <label value="&contextPauseMedia.label;"/>
           </richlistitem>
           <richlistitem id="context-videotab" type="video" onclick="ContextCommands.sendCommand('videotab');">
             <label value="&contextVideoTab.label;"/>
           </richlistitem>
           <richlistitem id="context-save-video" type="video" onclick="ContextCommands.saveVideo();">
             <label value="&contextSaveVideo.label;"/>
           </richlistitem>
-          <richlistitem id="context-save-video" type="video" onclick="ContextCommands.saveVideoTo();">
+          <richlistitem id="context-save-video-to" type="video" onclick="ContextCommands.saveVideoTo();">
             <label value="&contextSaveVideoTo.label;"/>
           </richlistitem>
 
           <!-- Misc. related -->
           <richlistitem id="context-editbookmark" type="edit-bookmark" onclick="ContextCommands.editBookmark();">
             <label value="&contextEditBookmark.label;"/>
           </richlistitem>
           <richlistitem id="context-removebookmark" type="edit-bookmark" onclick="ContextCommands.removeBookmark();">
--- a/browser/metro/base/content/contenthandlers/ContextMenuHandler.js
+++ b/browser/metro/base/content/contenthandlers/ContextMenuHandler.js
@@ -85,16 +85,20 @@ var ContextMenuHandler = {
 
       case "select-all":
         this._onSelectAll();
         break;
 
       case "paste":
         this._onPaste();
         break;
+
+      case "copy-image-contents":
+        this._onCopyImage();
+        break;
     }
   },
 
   /******************************************************
    * Event handlers
    */
 
   reset: function ch_reset() {
@@ -127,16 +131,17 @@ var ContextMenuHandler = {
 
     // Do checks for nodes that never have children.
     if (popupNode.nodeType == Ci.nsIDOMNode.ELEMENT_NODE) {
       // See if the user clicked on an image.
       if (popupNode instanceof Ci.nsIImageLoadingContent && popupNode.currentURI) {
         state.types.push("image");
         state.label = state.mediaURL = popupNode.currentURI.spec;
         imageUrl = state.mediaURL;
+        this._target = popupNode;
 
         // Retrieve the type of image from the cache since the url can fail to
         // provide valuable informations
         try {
           let imageCache = Cc["@mozilla.org/image/cache;1"].getService(Ci.imgICache);
           let props = imageCache.findEntryProperties(popupNode.currentURI,
                                                      content.document.characterSet);
           if (props) {
@@ -225,26 +230,26 @@ var ContextMenuHandler = {
     if (isText) {
       // If this is text and has a selection, we want to bring
       // up the copy option on the context menu.
       if (content && content.getSelection() &&
           content.getSelection().toString().length > 0) {
         state.string = content.getSelection().toString();
         state.types.push("copy");
         state.types.push("selected-text");
-        } else {
-          // Add general content text if this isn't anything specific
-          if (state.types.indexOf("image") == -1 &&
-              state.types.indexOf("media") == -1 &&
-              state.types.indexOf("video") == -1 &&
-              state.types.indexOf("link") == -1 &&
-              state.types.indexOf("input-text") == -1) {
-            state.types.push("content-text");
-          }
+      } else {
+        // Add general content text if this isn't anything specific
+        if (state.types.indexOf("image") == -1 &&
+            state.types.indexOf("media") == -1 &&
+            state.types.indexOf("video") == -1 &&
+            state.types.indexOf("link") == -1 &&
+            state.types.indexOf("input-text") == -1) {
+          state.types.push("content-text");
         }
+      }
     }
 
     // populate position and event source
     state.xPos = aEvent.clientX;
     state.yPos = aEvent.clientY;
     state.source = aEvent.mozInputSource;
 
     for (let i = 0; i < this._types.length; i++)
@@ -273,16 +278,20 @@ var ContextMenuHandler = {
         edit.editor.paste(Ci.nsIClipboard.kGlobalClipboard);
       } else {
         Util.dumpLn("error: target element does not support nsIDOMNSEditableElement");
       }
     }
     this.reset();
   },
 
+  _onCopyImage: function _onCopyImage() {
+    Util.copyImageToClipboard(this._target);
+  },
+
   /*
    * Utility routines used in testing for various
    * HTML element types.
    */
 
   _isTextInput: function _isTextInput(element) {
     return ((element instanceof Ci.nsIDOMHTMLInputElement &&
              element.mozIsTextField(false)) ||
--- a/browser/metro/base/content/helperui/MenuUI.js
+++ b/browser/metro/base/content/helperui/MenuUI.js
@@ -111,17 +111,16 @@ var ContextMenuUI = {
    * @returns true if the context menu was displayed,
    * false otherwise.
    *
    * json: TBD
    */
   showContextMenu: function ch_showContextMenu(aMessage) {
     this._popupState = aMessage.json;
     this._popupState.target = aMessage.target;
-
     let contentTypes = this._popupState.types;
 
     let optionsAvailable = false;
     for (let i = 0; i < this._commands.childElementCount; i++) {
       let command = this._commands.childNodes[i];
       command.hidden = true;
 
       let types = command.getAttribute("type").split(/\s+/);
deleted file mode 100644
--- a/browser/metro/base/content/helperui/SharingUI.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var SharingUI = {
-  _dialog: null,
-
-  show: function show(aURL, aTitle) {
-    try {
-      this.showSharingUI(aURL, aTitle);
-    } catch (ex) {
-      this.showFallback(aURL, aTitle);
-    }
-  },
-
-  showSharingUI: function showSharingUI(aURL, aTitle) {
-    let sharingSvc = Cc["@mozilla.org/uriloader/external-sharing-app-service;1"].getService(Ci.nsIExternalSharingAppService);
-    sharingSvc.shareWithDefault(aURL, "text/plain", aTitle);
-  },
-
-  showFallback: function showFallback(aURL, aTitle) {
-    this._dialog = DialogUI.importModal(window, "chrome://browser/content/prompt/share.xul", null);
-    document.getElementById("share-title").value = aTitle || aURL;
-
-    DialogUI.pushPopup(this, this._dialog);
-
-    let bbox = document.getElementById("share-buttons-box");
-    this._handlers.forEach(function(handler) {
-      let button = document.createElement("button");
-      button.className = "action-button";
-      button.setAttribute("label", handler.name);
-      button.addEventListener("command", function() {
-        SharingUI.hide();
-        handler.callback(aURL || "", aTitle || "");
-      }, false);
-      bbox.appendChild(button);
-    });
-
-    this._dialog.waitForClose();
-    DialogUI.popPopup(this);
-  },
-
-  hide: function hide() {
-    this._dialog.close();
-    this._dialog = null;
-  },
-
-  _handlers: [
-    {
-      name: "Email",
-      callback: function callback(aURL, aTitle) {
-        let url = "mailto:?subject=" + encodeURIComponent(aTitle) +
-                  "&body=" + encodeURIComponent(aURL);
-        let uri = Services.io.newURI(url, null, null);
-        let extProtocolSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"]
-                             .getService(Ci.nsIExternalProtocolService);
-        extProtocolSvc.loadUrl(uri);
-      }
-    },
-    {
-      name: "Twitter",
-      callback: function callback(aURL, aTitle) {
-        let url = "http://twitter.com/home?status=" + encodeURIComponent((aTitle ? aTitle+": " : "")+aURL);
-        BrowserUI.newTab(url, Browser.selectedTab);
-      }
-    },
-    {
-      name: "Google Reader",
-      callback: function callback(aURL, aTitle) {
-        let url = "http://www.google.com/reader/link?url=" + encodeURIComponent(aURL) +
-                  "&title=" + encodeURIComponent(aTitle);
-        BrowserUI.newTab(url, Browser.selectedTab);
-      }
-    },
-    {
-      name: "Facebook",
-      callback: function callback(aURL, aTitle) {
-        let url = "http://www.facebook.com/share.php?u=" + encodeURIComponent(aURL);
-        BrowserUI.newTab(url, Browser.selectedTab);
-      }
-    }
-  ]
-};
--- a/browser/metro/base/content/pages/aboutRights.xhtml
+++ b/browser/metro/base/content/pages/aboutRights.xhtml
@@ -2,38 +2,40 @@
 <!DOCTYPE html [
   <!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
   %htmlDTD;
   <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
   %brandDTD;
   <!ENTITY % aboutRightsDTD SYSTEM "chrome://global/locale/aboutRights.dtd">
   %aboutRightsDTD;
 ]>
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 <html xmlns="http://www.w3.org/1999/xhtml">
 
 <head>
   <title>&rights.pagetitle;</title>
   <link rel="stylesheet" href="chrome://global/skin/about.css" type="text/css"/>
 </head>
 
 <body id="your-rights" dir="&rights.locale-direction;" class="aboutPageWideContainer">
 
 <h1>&rights.intro-header;</h1>
 
 <p>&rights.intro;</p>
 
 <ul>
   <li>&rights.intro-point1a;<a href="http://www.mozilla.org/MPL/">&rights.intro-point1b;</a>&rights.intro-point1c;</li>
-# Point 2 discusses Mozilla trademarks, and isn't needed when the build is unbranded.
-# Point 3 discusses privacy policy, unbranded builds get a placeholder (for the vendor to replace)
-# Point 4 discusses web service terms, unbranded builds gets a placeholder (for the vendor to replace)
+  <!--
+    Point 2 discusses Mozilla trademarks, and isn't needed when the build is unbranded.
+    Point 3 discusses privacy policy, unbranded builds get a placeholder (for the vendor to replace)
+    Point 4 discusses web service terms, unbranded builds gets a placeholder (for the vendor to replace)
+  -->
   <li>&rights.intro-point2-a;<a href="http://www.mozilla.org/foundation/trademarks/policy.html">&rights.intro-point2-b;</a>&rights.intro-point2-c;</li>
   <li>&rights.intro-point2.5;</li>
   <li>&rights2.intro-point3a;<a href="http://www.mozilla.com/legal/privacy/">&rights2.intro-point3b;</a>&rights.intro-point3c;</li>
   <li>&rights2.intro-point4a;<a href="about:rights#webservices" onclick="showServices();">&rights.intro-point4b;</a>&rights.intro-point4c;</li>
 </ul>
 
 <div id="webservices-container">
   <a name="webservices"/>
@@ -59,17 +61,17 @@
       <li>&rights.locationawarebrowsing-term1a;<code>&rights.locationawarebrowsing-term1b;</code></li>
       <li>&rights.locationawarebrowsing-term2;</li>
       <li>&rights.locationawarebrowsing-term3;</li>
       <li>&rights.locationawarebrowsing-term4;</li>
     </ul>
   </div>
 
   <ol>
-# Terms only apply to official builds, unbranded builds get a placeholder.
+    <!-- Terms only apply to official builds, unbranded builds get a placeholder. -->
     <li>&rights2.webservices-term1;</li>
     <li>&rights.webservices-term2;</li>
     <li>&rights2.webservices-term3;</li>
     <li><strong>&rights.webservices-term4;</strong></li>
     <li><strong>&rights.webservices-term5;</strong></li>
     <li>&rights.webservices-term6;</li>
     <li>&rights.webservices-term7;</li>
   </ol>
deleted file mode 100644
--- a/browser/metro/base/content/prompt/share.xul
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-
-<!DOCTYPE prompt SYSTEM "chrome://browser/locale/prompt.dtd">
-
-<dialog id="share-dialog"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-  <keyset>
-    <key keycode="VK_ESCAPE" command="cmd_cancel"/>
-  </keyset>
-
-  <commandset>
-    <command id="cmd_cancel" oncommand="SharingUI.hide();"/>
-  </commandset>
-
-  <vbox class="prompt-inner">
-    <hbox class="prompt-header">
-      <label id="share-title" crop="center" flex="1"/>
-    </hbox>
-  
-    <hbox id="share-buttons-box" class="prompt-buttons"/>
-  </vbox>
-</dialog>
--- a/browser/metro/base/jar.mn
+++ b/browser/metro/base/jar.mn
@@ -3,26 +3,26 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
 chrome.jar:
 % content browser %content/
 
   content/aboutCertError.xhtml                 (content/pages/aboutCertError.xhtml)
-* content/aboutRights.xhtml                    (content/pages/aboutRights.xhtml)
+  content/aboutRights.xhtml                    (content/pages/aboutRights.xhtml)
   content/aboutCrash.xhtml                     (content/pages/aboutCrash.xhtml)
   content/blockedSite.xhtml                    (content/pages/blockedSite.xhtml)
   content/fullscreen-video.xhtml               (content/pages/fullscreen-video.xhtml)
   content/netError.xhtml                       (content/pages/netError.xhtml)
 
-* content/bindings/bindings.xml                (content/bindings/bindings.xml)
+  content/bindings/bindings.xml                (content/bindings/bindings.xml)
   content/bindings/tabs.xml                    (content/bindings/tabs.xml)
   content/bindings/toggleswitch.xml            (content/bindings/toggleswitch.xml)
-* content/bindings/browser.xml                 (content/bindings/browser.xml)
+  content/bindings/browser.xml                 (content/bindings/browser.xml)
   content/bindings/browser.js                  (content/bindings/browser.js)
   content/bindings/downloads.xml               (content/bindings/downloads.xml)
   content/bindings/console.xml                 (content/bindings/console.xml)
   content/bindings/dialog.xml                  (content/bindings/dialog.xml)
   content/bindings/pageaction.xml              (content/bindings/pageaction.xml)
   content/bindings/arrowbox.xml                (content/bindings/arrowbox.xml)
   content/bindings/grid.xml                    (content/bindings/grid.xml)
   content/bindings/autocomplete.xml            (content/bindings/autocomplete.xml)
@@ -32,68 +32,66 @@ chrome.jar:
 
   content/prompt/CaptureDialog.xul             (content/prompt/CaptureDialog.xul)
   content/prompt/alert.xul                     (content/prompt/alert.xul)
   content/prompt/confirm.xul                   (content/prompt/confirm.xul)
   content/prompt/prompt.xul                    (content/prompt/prompt.xul)
   content/prompt/promptPassword.xul            (content/prompt/promptPassword.xul)
   content/prompt/select.xul                    (content/prompt/select.xul)
   content/prompt/prompt.js                     (content/prompt/prompt.js)
-  content/prompt/share.xul                     (content/prompt/share.xul)
   content/prompt/masterPassword.xul            (content/prompt/masterPassword.xul)
   content/prompt/removeMasterPassword.xul      (content/prompt/removeMasterPassword.xul)
 
-* content/helperui/AlertsHelper.js             (content/helperui/AlertsHelper.js)
+  content/helperui/AlertsHelper.js             (content/helperui/AlertsHelper.js)
   content/helperui/CaptureDialog.js            (content/helperui/CaptureDialog.js)
   content/helperui/CapturePickerUI.js          (content/helperui/CapturePickerUI.js)
   content/helperui/CharsetMenu.js              (content/helperui/CharsetMenu.js)
   content/helperui/IdentityUI.js               (content/helperui/IdentityUI.js)
   content/helperui/IndexedDB.js                (content/helperui/IndexedDB.js)
   content/helperui/MasterPasswordUI.js         (content/helperui/MasterPasswordUI.js)
   content/helperui/MenuUI.js                   (content/helperui/MenuUI.js)
   content/helperui/OfflineApps.js              (content/helperui/OfflineApps.js)
   content/helperui/SelectHelperUI.js           (content/helperui/SelectHelperUI.js)
   content/helperui/SelectionHelperUI.js        (content/helperui/SelectionHelperUI.js)
-  content/helperui/SharingUI.js                (content/helperui/SharingUI.js)
   content/helperui/FormHelperUI.js             (content/helperui/FormHelperUI.js)
   content/helperui/FindHelperUI.js             (content/helperui/FindHelperUI.js)
 
   content/contenthandlers/ContextMenuHandler.js (content/contenthandlers/ContextMenuHandler.js)
   content/contenthandlers/PluginCTPHandler.js  (content/contenthandlers/PluginCTPHandler.js)
   content/contenthandlers/SelectionHandler.js  (content/contenthandlers/SelectionHandler.js)
   content/contenthandlers/FormHelper.js        (content/contenthandlers/FormHelper.js)
   content/contenthandlers/FindHandler.js       (content/contenthandlers/FindHandler.js)
   content/contenthandlers/ViewportHandler.js   (content/contenthandlers/ViewportHandler.js)
   content/contenthandlers/ConsoleAPIObserver.js (content/contenthandlers/ConsoleAPIObserver.js)
-* content/contenthandlers/Content.js           (content/contenthandlers/Content.js)
+  content/contenthandlers/Content.js           (content/contenthandlers/Content.js)
 
   content/BrowserTouchHandler.js               (content/BrowserTouchHandler.js)
 * content/WebProgress.js                       (content/WebProgress.js)
   content/config.xul                           (content/config.xul)
   content/config.js                            (content/config.js)
 * content/browser.xul                          (content/browser.xul)
-* content/browser.js                           (content/browser.js)
+  content/browser.js                           (content/browser.js)
 * content/browser-ui.js                        (content/browser-ui.js)
 * content/browser-scripts.js                   (content/browser-scripts.js)
-* content/ContextCommands.js                   (content/ContextCommands.js)
-* content/PageActions.js                       (content/PageActions.js)
+  content/ContextCommands.js                   (content/ContextCommands.js)
+  content/PageActions.js                       (content/PageActions.js)
   content/commandUtil.js                       (content/commandUtil.js)
   content/appbar.js                            (content/appbar.js)
   content/shell.xul                            (content/jsshell/shell.xul)
   content/shell.html                           (content/jsshell/shell.html)
   content/browser.css                          (content/browser.css)
   content/cursor.css                           (content/cursor.css)
 % content branding %content/branding/
   content/sanitize.js                          (content/sanitize.js)
-* content/input.js                             (content/input.js)
-* content/Util.js                              (content/Util.js)
+  content/input.js                             (content/input.js)
+  content/Util.js                              (content/Util.js)
   content/bookmarks.js                         (content/bookmarks.js)
-* content/preferences.js                       (content/preferences.js)
+  content/preferences.js                       (content/preferences.js)
   content/exceptions.js                        (content/exceptions.js)
-* content/downloads.js                         (content/downloads.js)
+  content/downloads.js                         (content/downloads.js)
   content/history.js                           (content/history.js)
   content/TopSites.js                          (content/TopSites.js)
   content/console.js                           (content/console.js)
   content/AnimatedZoom.js                      (content/AnimatedZoom.js)
   content/LoginManagerChild.js                 (content/LoginManagerChild.js)
   content/video.js                             (content/video.js)
 #ifdef MOZ_SERVICES_SYNC
   content/sync.js                              (content/sync.js)
--- a/browser/metro/locales/en-US/chrome/browser.dtd
+++ b/browser/metro/locales/en-US/chrome/browser.dtd
@@ -78,30 +78,25 @@
 
 <!ENTITY contextOpenInNewTab.label    "Open Link in New Tab">
 <!ENTITY contextViewInNewTab.label    "View in New Tab">
 <!ENTITY contextSaveImage.label       "Save Image">
 <!ENTITY contextSaveImageTo.label     "Save Image To">
 <!ENTITY contextCopyLink.label        "Copy Link">
 <!ENTITY contextCopyEmail.label       "Copy Email Address">
 <!ENTITY contextCopyPhone.label       "Copy Phone Number">
-<!ENTITY contextCopyImageLocation.label "Copy Image Location">
+<!ENTITY contextCopyImage.label       "Copy Image">
 <!ENTITY contextShareLink.label       "Share Link">
 <!ENTITY contextShareImage.label      "Share Image">
 <!ENTITY contextBookmarkLink.label    "Bookmark Link">
 <!ENTITY contextSaveVideo.label       "Save Video">
 <!ENTITY contextSaveVideoTo.label       "Save Video To">
 <!ENTITY contextShareVideo.label      "Share Video">
 <!ENTITY contextPlayMedia.label       "Play">
 <!ENTITY contextPauseMedia.label      "Pause">
 <!ENTITY contextVideoTab.label        "Open In New Tab">
 <!ENTITY contextEditBookmark.label    "Edit">
 <!ENTITY contextRemoveBookmark.label  "Remove">
 <!ENTITY contextShortcutBookmark.label "Add to Home Screen">
 
-<!ENTITY pageactions.pin.site        "Pin Site">
-<!ENTITY pageactions.share.page      "Share Page">
 <!ENTITY pageactions.password.forget "Forget Password">
-<!ENTITY pageactions.quit            "Quit">
 <!ENTITY pageactions.reset           "Clear Site Preferences">
-<!ENTITY pageactions.findInPage      "Find In Page">
-<!ENTITY pageactions.search.addNew   "Add Search Engine">
 <!ENTITY pageactions.charEncoding    "Character Encoding">
--- a/browser/metro/locales/en-US/chrome/browser.properties
+++ b/browser/metro/locales/en-US/chrome/browser.properties
@@ -97,18 +97,17 @@ tabs.closeWarningPromptMe=Warn me when I
 tabs.emptyTabTitle=New Tab
 
 # Homepage
 # LOCALIZATION NOTE: homepage.custom2 is the text displayed on the selector button if
 # the user selects a webpage to be the startpage. We can't display the entire URL
 # or webpage title on the menulist
 homepage.custom2=Custom Page
 
-# Page Actions
-pageactions.pin.site=Pin Site
+# "Clear Permissions" items
 pageactions.geolocation=Location
 pageactions.popup=Popups
 pageactions.offline-app=Offline Storage
 pageactions.password=Password
 pageactions.desktop-notification=Web Notifications
 pageactions.openWebappsManage=Manage Web Apps
 
 # Open Search
--- a/browser/metro/locales/jar.mn
+++ b/browser/metro/locales/jar.mn
@@ -19,22 +19,22 @@
   locale/browser/sync.dtd                 (%chrome/sync.dtd)
   locale/browser/sync.properties          (%chrome/sync.properties)
   locale/browser/prompt.dtd               (%chrome/prompt.dtd)
   locale/browser/phishing.dtd             (%chrome/phishing.dtd)
 
 @AB_CD@.jar:
 % locale browser @AB_CD@ %locale/browser/
   locale/browser/bookmarks.json           (bookmarks.json)
-* locale/browser/passwordmgr.properties   (%overrides/passwordmgr.properties)
+  locale/browser/passwordmgr.properties   (%overrides/passwordmgr.properties)
 % override chrome://passwordmgr/locale/passwordmgr.properties chrome://browser/locale/passwordmgr.properties
 
 #
 # Browser jar resources
 #
 
 @AB_CD@.jar:
 relativesrcdir browser/locales:
   locale/browser/region.properties        (%chrome/browser-region/region.properties)
-* locale/browser/netError.dtd             (%chrome/overrides/netError.dtd)
+  locale/browser/netError.dtd             (%chrome/overrides/netError.dtd)
 % override chrome://global/locale/netError.dtd chrome://browser/locale/netError.dtd
-* locale/browser/appstrings.properties    (%chrome/overrides/appstrings.properties)
+  locale/browser/appstrings.properties    (%chrome/overrides/appstrings.properties)
 % override chrome://global/locale/appstrings.properties chrome://browser/locale/appstrings.properties
deleted file mode 100644
--- a/browser/metro/theme/header.css
+++ /dev/null
@@ -1,14 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-body {
-  font-family: helvetica,arial,clean,sans-serif;
-  color: #69645c;
-  background: white url("images/aboutBackground.jpg") top center repeat-x;
-}
-
-#wrapper {
-  max-width: 600px;
-  margin: 0 auto;
-}
deleted file mode 100644
index 5dba1c58eb5afa5f929f09d61a46dbe7bb277cd1..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 82cf8f415fa7e89918c521e474c6729e66ecf95a..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index a29f65655ef5292621f3eb8094e9836c8fee1a0d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 054c7373b405de8da050c35d8b817ed4dd29c31d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index affc84c69603a663e32bda7b5ca5569897ff3adf..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 066864cf79ef33372ac318185545824d32357e87..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 963b5770fd95a84c25216a13157ee2292bf0a572..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index ba54836e9834f2c495bcfb05738b56481b2dbed0..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 1a41a5ad23aefb7804c48a12ef0f44488e8cecb7..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 98d8789e274a3a705fe6d7c89a342ef49a4db042..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 8bab39a08d350a1915c2fd1ae871333be1c9dd72..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index c9805f654c79b22ce0d8435d030e775f3b7492ac..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 128cef90af66bdf67d9d88d3b161fca8f6fe3788..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/metro/theme/jar.mn
+++ b/browser/metro/theme/jar.mn
@@ -8,17 +8,16 @@ chrome.jar:
 % skin browser classic/1.0 %skin/
   skin/aboutPage.css                        (aboutPage.css)
   skin/about.css                            (about.css)
   skin/flyoutpanel.css                      (flyoutpanel.css)
 * skin/browser.css                          (browser.css)
 * skin/content.css                          (content.css)
   skin/config.css                           (config.css)
 * skin/forms.css                            (forms.css)
-  skin/header.css                           (header.css)
 * skin/platform.css                         (platform.css)
   skin/touchcontrols.css                    (touchcontrols.css)
   skin/netError.css                         (netError.css)
 % override chrome://global/skin/about.css chrome://browser/skin/about.css
 % override chrome://global/skin/media/videocontrols.css chrome://browser/skin/touchcontrols.css
 % override chrome://global/skin/netError.css chrome://browser/skin/netError.css
 
   skin/images/panel-light.png               (images/panel-light.png)
@@ -37,54 +36,43 @@ chrome.jar:
   skin/images/tab-selection-right.png       (images/tab-selection-right.png)
   skin/images/identity-icons-generic.png    (images/identity-icons-generic.png)
   skin/images/identity-icons-https-ev.png   (images/identity-icons-https-ev.png)
   skin/images/identity-icons-https-mixed.png  (images/identity-icons-https-mixed.png)
   skin/images/identity-icons-https.png      (images/identity-icons-https.png)
   skin/images/firefox-watermark.png         (images/firefox-watermark.png)
   skin/images/flyout-back-button.png        (images/flyout-back-button.png)
   skin/images/about-footer.png              (images/about-footer.png)
-  skin/images/aboutBackground.jpg           (images/aboutBackground.jpg)
   skin/images/button-bg.png                 (images/button-bg.png)
   skin/images/arrowleft-16.png              (images/arrowleft-16.png)
   skin/images/arrowright-16.png             (images/arrowright-16.png)
   skin/images/arrowup-16.png                (images/arrowup-16.png)
   skin/images/arrowdown-16.png              (images/arrowdown-16.png)
   skin/images/arrowleftdark-16.png          (images/arrowleftdark-16.png)
   skin/images/arrowrightdark-16.png         (images/arrowrightdark-16.png)
   skin/images/arrowupdark-16.png            (images/arrowupdark-16.png)
   skin/images/arrowdowndark-16.png          (images/arrowdowndark-16.png)
   skin/images/popup-bg-hdpi.png             (images/popup-bg-hdpi.png)
   skin/images/popup-selected-item-hdpi.png  (images/popup-selected-item-hdpi.png)
   skin/images/arrowbox-up.png               (images/arrowbox-up.png)
   skin/images/arrowbox-down.png             (images/arrowbox-down.png)
   skin/images/arrowbox-horiz.png            (images/arrowbox-horiz.png)
-  skin/images/checkmark-hdpi.png                 (images/checkmark-hdpi.png)
-  skin/images/check-selected-30.png         (images/check-selected-30.png)
-  skin/images/check-unselected-30.png       (images/check-unselected-30.png)
   skin/images/favicon-default-32.png        (images/favicon-default-32.png)
   skin/images/errorpage-warning.png         (images/errorpage-warning.png)
   skin/images/errorpage-warning.png         (images/errorpage-warning.png)
   skin/images/errorpage-larry-white.png     (images/errorpage-larry-white.png)
   skin/images/errorpage-larry-black.png     (images/errorpage-larry-black.png)
   skin/images/throbber.png                  (images/throbber.png)
   skin/images/stop-hdpi.png                 (images/stop-hdpi.png)
   skin/images/alert-downloads-30.png        (images/alert-downloads-30.png)
-  skin/images/mozilla-32.png                (images/mozilla-32.png)
   skin/images/identity-default-hdpi.png     (images/identity-default-hdpi.png)
   skin/images/identity-ssl-hdpi.png         (images/identity-ssl-hdpi.png)
   skin/images/identity-ev-hdpi.png          (images/identity-ev-hdpi.png)
   skin/images/unlocked-hdpi.png             (images/unlocked-hdpi.png)
   skin/images/locked-hdpi.png               (images/locked-hdpi.png)
-  skin/images/check-30.png                  (images/check-30.png)
   skin/images/search-glass-30.png           (images/search-glass-30.png)
-  skin/images/search-clear-30.png           (images/search-clear-30.png)
-  skin/images/section-expanded-16.png       (images/section-expanded-16.png)
-  skin/images/section-collapsed-16.png      (images/section-collapsed-16.png)
   skin/images/play-hdpi.png                 (images/play-hdpi.png)
   skin/images/pause-hdpi.png                (images/pause-hdpi.png)
   skin/images/mute-hdpi.png                 (images/mute-hdpi.png)
   skin/images/unmute-hdpi.png               (images/unmute-hdpi.png)
   skin/images/scrubber-hdpi.png             (images/scrubber-hdpi.png)
   skin/images/selection-monocle.png         (images/selection-monocle.png)
-  skin/images/homescreen-blank-hdpi.png     (images/homescreen-blank-hdpi.png)
-  skin/images/homescreen-default-hdpi.png   (images/homescreen-default-hdpi.png)
   skin/images/appbar-icons.png              (images/appbar-icons.png)
--- a/build/autoconf/toolchain.m4
+++ b/build/autoconf/toolchain.m4
@@ -51,20 +51,20 @@ if test "$GXX" = yes; then
    if test "`$CXX -help 2>&1 | grep -c 'Intel(R) C++ Compiler'`" != "0"; then
      INTEL_CXX=1
    fi
 fi
 
 CLANG_CC=
 CLANG_CXX=
 if test "$GCC" = yes; then
-   if test "`$CC -v 2>&1 | grep -c 'clang version'`" != "0"; then
+   if test "`$CC -v 2>&1 | grep -c 'clang version\|Apple.*clang'`" != "0"; then
      CLANG_CC=1
    fi
 fi
 
 if test "$GXX" = yes; then
-   if test "`$CXX -v 2>&1 | grep -c 'clang version'`" != "0"; then
+   if test "`$CXX -v 2>&1 | grep -c 'clang version\|Apple.*clang'`" != "0"; then
      CLANG_CXX=1
    fi
 fi
 AC_SUBST(CLANG_CXX)
 ])
--- a/build/mobile/remoteautomation.py
+++ b/build/mobile/remoteautomation.py
@@ -82,17 +82,51 @@ class RemoteAutomation(Automation):
                       "allowed maximum time of %s seconds" % (self.lastTestSeen, maxTime)
             else:
                 print "TEST-UNEXPECTED-FAIL | %s | application ran for longer than " \
                       "allowed maximum time" % (self.lastTestSeen)
             proc.kill()
 
         return status
 
+    def checkForJavaException(self, logcat):
+        found_exception = False
+        for i, line in enumerate(logcat):
+            if "REPORTING UNCAUGHT EXCEPTION" in line:
+                # Strip away the date, time, logcat tag and pid from the next two lines and
+                # concatenate the remainder to form a concise summary of the exception. 
+                #
+                # For example:
+                #
+                # 01-30 20:15:41.937 E/GeckoAppShell( 1703): >>> REPORTING UNCAUGHT EXCEPTION FROM THREAD 9 ("GeckoBackgroundThread")
+                # 01-30 20:15:41.937 E/GeckoAppShell( 1703): java.lang.NullPointerException
+                # 01-30 20:15:41.937 E/GeckoAppShell( 1703): 	at org.mozilla.gecko.GeckoApp$21.run(GeckoApp.java:1833)
+                # 01-30 20:15:41.937 E/GeckoAppShell( 1703): 	at android.os.Handler.handleCallback(Handler.java:587)
+                # 01-30 20:15:41.937 E/GeckoAppShell( 1703): 	at android.os.Handler.dispatchMessage(Handler.java:92)
+                # 01-30 20:15:41.937 E/GeckoAppShell( 1703): 	at android.os.Looper.loop(Looper.java:123)
+                # 01-30 20:15:41.937 E/GeckoAppShell( 1703): 	at org.mozilla.gecko.util.GeckoBackgroundThread.run(GeckoBackgroundThread.java:31)
+                #
+                #   -> java.lang.NullPointerException at org.mozilla.gecko.GeckoApp$21.run(GeckoApp.java:1833)
+                found_exception = True
+                logre = re.compile(r".*\):\s(.*)")
+                m = logre.search(logcat[i+1])
+                if m and m.group(1):
+                    top_frame = m.group(1)
+                m = logre.search(logcat[i+2])
+                if m and m.group(1):
+                    top_frame = top_frame + m.group(1)
+                print "PROCESS-CRASH | java-exception | %s" % top_frame
+                break
+        return found_exception
+
     def checkForCrashes(self, directory, symbolsPath):
+        logcat = self._devicemanager.getLogcat(filterOutRegexps=fennecLogcatFilters)
+        javaException = self.checkForJavaException(logcat)
+        if javaException:
+            return True
         try:
             remoteCrashDir = self._remoteProfile + '/minidumps/'
             if not self._devicemanager.dirExists(remoteCrashDir):
                 # As of this writing, the minidumps directory is automatically
                 # created when fennec (first) starts, so its lack of presence
                 # is a hint that something went wrong.
                 print "Automation Error: No crash directory (%s) found on remote device" % remoteCrashDir
                 # Whilst no crash was found, the run should still display as a failure
--- a/config/config.mk
+++ b/config/config.mk
@@ -584,16 +584,23 @@ ifdef GNU_CC
 WIN32_EXE_LDFLAGS	+= -mwindows
 else
 WIN32_EXE_LDFLAGS	+= -SUBSYSTEM:WINDOWS
 endif
 endif
 endif
 endif
 
+ifdef _MSC_VER
+ifeq ($(CPU_ARCH),x86_64)
+# set stack to 2MB on x64 build.  See bug 582910
+WIN32_EXE_LDFLAGS	+= -STACK:2097152
+endif
+endif
+
 # If we're building a component on MSVC, we don't want to generate an
 # import lib, because that import lib will collide with the name of a
 # static version of the same library.
 ifeq ($(GNU_LD)$(OS_ARCH),WINNT)
 ifdef IS_COMPONENT
 LDFLAGS += -IMPLIB:fake.lib
 DELETE_AFTER_LINK = fake.lib fake.exp
 endif
--- a/config/expandlibs_exec.py
+++ b/config/expandlibs_exec.py
@@ -124,17 +124,17 @@ class ExpandArgsMore(ExpandArgs):
         # gold's --print-icf-sections output looks like the following:
         # ld: ICF folding section '.section' in file 'file.o'into '.section' in file 'file.o'
         # In terms of words, chances are this will change in the future,
         # especially considering "into" is misplaced. Splitting on quotes
         # seems safer.
         for l in stderr.split('\n'):
             quoted = l.split("'")
             if len(quoted) > 5 and quoted[1] != quoted[5]:
-                result[quoted[1]] = quoted[5]
+                result[quoted[1]] = [quoted[5]]
                 if quoted[5] in result:
                     result[quoted[5]].append(quoted[1])
                 else:
                     result[quoted[5]] = [quoted[1]]
         return result
 
     def _getOrderedSections(self, ordered_symbols):
         '''Given an ordered list of symbols, returns the corresponding list
@@ -262,16 +262,24 @@ class SectionFinder(object):
             # We only need to consider cases where "<section>\t<length> <symbol>" is present,
             # and where the [FfO] flag is either F (function) or O (object).
             if len(tmp) > 1 and len(tmp[1]) > 6 and tmp[1][6] in ['O', 'F']:
                 tmp = tmp[1][8:].split()
                 # That gives us ["<section>","<length>", "<symbol>"]
                 syms.append((tmp[-1], tmp[0]))
         return syms
 
+def print_command(out, args):
+    print >>out, "Executing: " + " ".join(args)
+    for tmp in [f for f in args.tmp if os.path.isfile(f)]:
+        print >>out, tmp + ":"
+        with open(tmp) as file:
+            print >>out, "".join(["    " + l for l in file.readlines()])
+    out.flush()
+
 def main():
     parser = OptionParser()
     parser.add_option("--depend", dest="depend", metavar="FILE",
         help="generate dependencies for the given execution and store it in the given file")
     parser.add_option("--target", dest="target", metavar="FILE",
         help="designate the target for dependencies")
     parser.add_option("--extract", action="store_true", dest="extract",
         help="when a library has no descriptor file, extract it first, when possible")
@@ -297,25 +305,25 @@ def main():
         if options.extract:
             args.extract()
         if options.symbol_order:
             args.orderSymbols(options.symbol_order)
         if options.uselist:
             args.makelist()
 
         if options.verbose:
-            print >>sys.stderr, "Executing: " + " ".join(args)
-            for tmp in [f for f in args.tmp if os.path.isfile(f)]:
-                print >>sys.stderr, tmp + ":"
-                with open(tmp) as file:
-                    print >>sys.stderr, "".join(["    " + l for l in file.readlines()])
-            sys.stderr.flush()
-        ret = subprocess.call(args)
-        if ret:
-            exit(ret)
+            print_command(sys.stderr, args)
+        proc = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
+        (stdout, stderr) = proc.communicate()
+        if proc.returncode and not options.verbose:
+            print_command(sys.stderr, args)
+        sys.stderr.write(stdout)
+        sys.stderr.flush()
+        if proc.returncode:
+            exit(proc.returncode)
     if not options.depend:
         return
     ensureParentDir(options.depend)
     with open(options.depend, 'w') as depfile:
         depfile.write("%s : %s\n" % (options.target, ' '.join(dep for dep in deps if os.path.isfile(dep) and dep != options.target)))
 
 
 if __name__ == '__main__':
--- a/config/nspr/Makefile.in
+++ b/config/nspr/Makefile.in
@@ -27,13 +27,8 @@ libs::
 	$(INSTALL) $(DEPTH)/nsprpub/config/nspr-config $(DIST)/sdk/bin
 	$(RM) -rf $(DIST)/sdk/dummy
 ifneq (,$(filter OS2 WINNT,$(OS_ARCH))) # {
 	$(RM) -f $(DIST)/sdk/lib/$(DLL_PREFIX)nspr4$(DLL_SUFFIX) $(DIST)/sdk/lib/$(DLL_PREFIX)plc4$(DLL_SUFFIX) $(DIST)/sdk/lib/$(DLL_PREFIX)plds4$(DLL_SUFFIX)
 	$(RM) -f $(DIST)/sdk/lib/$(LIB_PREFIX)nspr4_s.$(LIB_SUFFIX) $(DIST)/sdk/lib/$(LIB_PREFIX)plc4_s.$(LIB_SUFFIX) $(DIST)/sdk/lib/$(LIB_PREFIX)plds4_s.$(LIB_SUFFIX)
 else # } {
 	$(RM) -f $(DIST)/sdk/lib/$(LIB_PREFIX)nspr4.$(LIB_SUFFIX) $(DIST)/sdk/lib/$(LIB_PREFIX)plc4.$(LIB_SUFFIX) $(DIST)/sdk/lib/$(LIB_PREFIX)plds4.$(LIB_SUFFIX)
 endif # }
-
-install::
-	$(MAKE) -C $(DEPTH)/nsprpub install DESTDIR=$(DESTDIR) libdir=$(mozappdir) includedir=$(includedir)/nspr
-	$(RM) -f $(addprefix $(DESTDIR)$(mozappdir)/$(LIB_PREFIX), $(addsuffix .$(LIB_SUFFIX), nspr4 plds4 plc4))
-	$(RM) -f $(addprefix $(DESTDIR)$(bindir)/,nspr-config compile-et.pl prerr.properties)
deleted file mode 100644
--- a/config/nspr/build.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-TIERS += nspr
-
-ifndef MOZ_NATIVE_NSPR
-tier_nspr_staticdirs += nsprpub
-tier_nspr_dirs += config/nspr
-endif
--- a/config/tests/unit-expandlibs.py
+++ b/config/tests/unit-expandlibs.py
@@ -360,28 +360,28 @@ class TestSymbolOrder(unittest.TestCase)
 
     def test_getFoldedSections(self):
         '''Test ExpandMoreArgs' _getFoldedSections'''
         # Divert subprocess.Popen
         subprocess_popen = subprocess.Popen
         subprocess.Popen = SubprocessPopen(self)
         config.LD_PRINT_ICF_SECTIONS = '-Wl,--print-icf-sections'
         args = ExpandArgsMore(['foo', '-bar', 'bar.o', 'foo.o'])
-        self.assertEqual(args._getFoldedSections(), {'.text.hello': '.text.hi', '.text.hi': ['.text.hello']})
+        self.assertEqual(args._getFoldedSections(), {'.text.hello': ['.text.hi'], '.text.hi': ['.text.hello']})
         subprocess.Popen = subprocess_popen
 
     def test_getOrderedSectionsWithICF(self):
         '''Test ExpandMoreArgs' _getOrderedSections, with ICF'''
         # Divert subprocess.Popen
         subprocess_popen = subprocess.Popen
         subprocess.Popen = SubprocessPopen(self)
         config.EXPAND_LIBS_ORDER_STYLE = 'linkerscript'
         config.OBJ_SUFFIX = '.o'
         config.LIB_SUFFIX = '.a'
         config.LD_PRINT_ICF_SECTIONS = '-Wl,--print-icf-sections'
         args = ExpandArgsMore(['foo', '-bar', 'bar.o', 'foo.o'])
-        self.assertEqual(args._getOrderedSections(['hello', '_Z6barbazv']), ['.text.hi', '.text.hello', '.text.hot._Z6barbazv'])
+        self.assertEqual(args._getOrderedSections(['hello', '_Z6barbazv']), ['.text.hello', '.text.hi', '.text.hot._Z6barbazv'])
         self.assertEqual(args._getOrderedSections(['_ZThn4_6foobarv', 'hi', '_Z6barbazv']), ['.text._Z6foobarv', '.text._ZThn4_6foobarv', '.text.hi', '.text.hello', '.text.hot._Z6barbazv'])
         subprocess.Popen = subprocess_popen
 
 
 if __name__ == '__main__':
     mozunit.main()
--- a/configure.in
+++ b/configure.in
@@ -5715,19 +5715,17 @@ MOZ_ARG_ENABLE_BOOL(gstreamer,
 [  --enable-gstreamer           Enable GStreamer support],
 MOZ_GSTREAMER=1,
 MOZ_GSTREAMER=)
 
 if test "$MOZ_GSTREAMER"; then
     # API version, eg 0.10, 1.0 etc
     GST_API_VERSION=0.10
     # core/base release number
-    # depend on >= 0.10.33 as that's when the playbin2 source-setup signal was
-    # introduced
-    GST_VERSION=0.10.33
+    GST_VERSION=0.10.25
     PKG_CHECK_MODULES(GSTREAMER,
                       gstreamer-$GST_API_VERSION >= $GST_VERSION
                       gstreamer-app-$GST_API_VERSION
                       gstreamer-plugins-base-$GST_API_VERSION)
     if test -n "$GSTREAMER_LIBS"; then
        _SAVE_LDFLAGS=$LDFLAGS
        LDFLAGS="$LDFLAGS $GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION"
        AC_TRY_LINK(,[return 0;],_HAVE_LIBGSTVIDEO=1,_HAVE_LIBGSTVIDEO=)
@@ -8457,16 +8455,17 @@ AC_SUBST(MOZ_PROFILELOCKING)
 
 AC_SUBST(ENABLE_TESTS)
 AC_SUBST(ENABLE_MARIONETTE)
 AC_SUBST(IBMBIDI)
 AC_SUBST(MOZ_UNIVERSALCHARDET)
 AC_SUBST(ACCESSIBILITY)
 AC_SUBST(MOZ_SPELLCHECK)
 AC_SUBST(MOZ_ANDROID_OMTC)
+AC_SUBST(MOZ_ANDROID_ANR_REPORTER)
 AC_SUBST(MOZ_ONLY_TOUCH_EVENTS)
 AC_SUBST(MOZ_CRASHREPORTER)
 AC_SUBST(MOZ_CRASHREPORTER_INJECTOR)
 AC_SUBST(MOZ_MAINTENANCE_SERVICE)
 AC_SUBST(MOZ_STUB_INSTALLER)
 AC_SUBST(MOZ_VERIFY_MAR_SIGNATURE)
 AC_SUBST(MOZ_ENABLE_SIGNMAR)
 AC_SUBST(MOZ_UPDATER)
--- a/content/base/public/nsISelection.idl
+++ b/content/base/public/nsISelection.idl
@@ -13,17 +13,17 @@ interface nsINode;
 
 /**
  * Interface for manipulating and querying the current selected range
  * of nodes within the document.
  *
  * @version 1.0
  */
 
-[scriptable, uuid(12cf5a4d-fffb-4f2f-9cec-c65195661d76)]
+[scriptable, builtinclass, uuid(12cf5a4d-fffb-4f2f-9cec-c65195661d76)]
 interface nsISelection : nsISupports
 {
     /**
      * Returns the node in which the selection begins.
      */
     readonly attribute nsIDOMNode anchorNode;
 
     /**
--- a/content/base/public/nsISelectionPrivate.idl
+++ b/content/base/public/nsISelectionPrivate.idl
@@ -26,17 +26,17 @@ struct ScrollAxis;
 [ptr] native nsFrameSelection(nsFrameSelection);
 [ptr] native nsIFrame(nsIFrame);
 [ptr] native RangeArray(nsTArray<nsRange*>);
 [ref] native constTextRangeStyleRef(const nsTextRangeStyle);
 [ref] native nsPointRef(nsPoint);
 native nsDirection(nsDirection);
 native ScrollAxis(nsIPresShell::ScrollAxis);
 
-[scriptable, uuid(2e44b10f-7d6d-4bf4-92e2-f9551d22f422)]
+[scriptable, builtinclass, uuid(2e44b10f-7d6d-4bf4-92e2-f9551d22f422)]
 interface nsISelectionPrivate : nsISelection
  {
     const short ENDOFPRECEDINGLINE=0;
     const short STARTOFNEXTLINE=1;
     
     attribute boolean interlinePosition;
 
     /* startBatchChanges
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -6118,25 +6118,25 @@ nsContentUtils::CheckCCWrapperTraversal(
   JSObject* wrapper = aCache->GetWrapper();
   if (!wrapper) {
     return;
   }
 
   DebugWrapperTraversalCallback callback(wrapper);
 
   aTracer->Traverse(aScriptObjectHolder, callback);
-  NS_ASSERTION(callback.mFound,
-               "Cycle collection participant didn't traverse to preserved "
-               "wrapper! This will probably crash.");
+  MOZ_ASSERT(callback.mFound,
+             "Cycle collection participant didn't traverse to preserved "
+             "wrapper! This will probably crash.");
 
   callback.mFound = false;
   aTracer->Trace(aScriptObjectHolder, DebugWrapperTraceCallback, &callback);
-  NS_ASSERTION(callback.mFound,
-               "Cycle collection participant didn't trace preserved wrapper! "
-               "This will probably crash.");
+  MOZ_ASSERT(callback.mFound,
+             "Cycle collection participant didn't trace preserved wrapper! "
+             "This will probably crash.");
 }
 #endif
 
 // static
 bool
 nsContentUtils::IsFocusedContent(const nsIContent* aContent)
 {
   nsFocusManager* fm = nsFocusManager::GetFocusManager();
--- a/content/base/src/nsDocumentEncoder.cpp
+++ b/content/base/src/nsDocumentEncoder.cpp
@@ -29,22 +29,21 @@
 #include "nsIDOMDocumentType.h"
 #include "nsIDOMNodeList.h"
 #include "nsRange.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMDocument.h"
 #include "nsICharsetConverterManager.h"
 #include "nsGkAtoms.h"
 #include "nsIContent.h"
-#include "nsIEnumerator.h"
 #include "nsIParserService.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptSecurityManager.h"
-#include "nsISelection.h"
+#include "mozilla/Selection.h"
 #include "nsISelectionPrivate.h"
 #include "nsITransferable.h" // for kUnicodeMime
 #include "nsContentUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsReadableUtils.h"
 #include "nsTArray.h"
 #include "nsIFrame.h"
 #include "nsStringBuffer.h"
@@ -1343,29 +1342,27 @@ nsHTMLCopyEncoder::SetSelection(nsISelec
   // we don't tweak the selection to be outside of the magic
   // div that ender-lite text widgets are embedded in.
   
   if (!aSelection) 
     return NS_ERROR_NULL_POINTER;
   
   nsCOMPtr<nsIDOMRange> range;
   nsCOMPtr<nsIDOMNode> commonParent;
-  int32_t count = 0;
-
-  nsresult rv = aSelection->GetRangeCount(&count);
-  NS_ENSURE_SUCCESS(rv, rv);
+  Selection* selection = static_cast<Selection*>(aSelection);
+  uint32_t rangeCount = selection->GetRangeCount();
 
   // if selection is uninitialized return
-  if (!count)
+  if (!rangeCount)
     return NS_ERROR_FAILURE;
   
   // we'll just use the common parent of the first range.  Implicit assumption
   // here that multi-range selections are table cell selections, in which case
   // the common parent is somewhere in the table and we don't really care where.
-  rv = aSelection->GetRangeAt(0, getter_AddRefs(range));
+  nsresult rv = aSelection->GetRangeAt(0, getter_AddRefs(range));
   NS_ENSURE_SUCCESS(rv, rv);
   if (!range)
     return NS_ERROR_NULL_POINTER;
   range->GetCommonAncestorContainer(getter_AddRefs(commonParent));
 
   for (nsCOMPtr<nsIContent> selContent(do_QueryInterface(commonParent));
        selContent;
        selContent = selContent->GetParent())
@@ -1407,48 +1404,31 @@ nsHTMLCopyEncoder::SetSelection(nsISelec
     return NS_OK;
   }
   
   // there's no Clone() for selection! fix...
   //nsresult rv = aSelection->Clone(getter_AddRefs(mSelection);
   //NS_ENSURE_SUCCESS(rv, rv);
   NS_NewDomSelection(getter_AddRefs(mSelection));
   NS_ENSURE_TRUE(mSelection, NS_ERROR_FAILURE);
-  nsCOMPtr<nsISelectionPrivate> privSelection( do_QueryInterface(aSelection) );
-  NS_ENSURE_TRUE(privSelection, NS_ERROR_FAILURE);
   
-  // get selection range enumerator
-  nsCOMPtr<nsIEnumerator> enumerator;
-  rv = privSelection->GetEnumerator(getter_AddRefs(enumerator));
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
-
   // loop thru the ranges in the selection
-  enumerator->First(); 
-  nsCOMPtr<nsISupports> currentItem;
-  while (static_cast<nsresult>(NS_ENUMERATOR_FALSE) == enumerator->IsDone())
-  {
-    rv = enumerator->CurrentItem(getter_AddRefs(currentItem));
-    NS_ENSURE_SUCCESS(rv, rv);
-    NS_ENSURE_TRUE(currentItem, NS_ERROR_FAILURE);
-    
-    range = do_QueryInterface(currentItem);
+  for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
+    range = selection->GetRangeAt(rangeIdx);
     NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
     nsCOMPtr<nsIDOMRange> myRange;
     range->CloneRange(getter_AddRefs(myRange));
     NS_ENSURE_TRUE(myRange, NS_ERROR_FAILURE);
 
     // adjust range to include any ancestors who's children are entirely selected
     rv = PromoteRange(myRange);
     NS_ENSURE_SUCCESS(rv, rv);
     
     rv = mSelection->AddRange(myRange);
     NS_ENSURE_SUCCESS(rv, rv);
-
-    enumerator->Next();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLCopyEncoder::EncodeToStringWithContext(nsAString& aContextString,
                                              nsAString& aInfoString,
--- a/content/base/src/nsImageLoadingContent.cpp
+++ b/content/base/src/nsImageLoadingContent.cpp
@@ -374,16 +374,31 @@ NS_IMETHODIMP_(void)
 nsImageLoadingContent::FrameCreated(nsIFrame* aFrame)
 {
   NS_ASSERTION(aFrame, "aFrame is null");
 
   // We need to make sure that our image request is registered, if it should
   // be registered.
   nsPresContext* presContext = aFrame->PresContext();
 
+  if (mCurrentRequest && !(mCurrentRequestFlags & REQUEST_IS_TRACKED)) {
+    nsIDocument* doc = GetOurCurrentDoc();
+    if (doc) {
+      mCurrentRequestFlags |= REQUEST_IS_TRACKED;
+      doc->AddImage(mCurrentRequest);
+    }
+  }
+  if (mPendingRequest && !(mPendingRequestFlags & REQUEST_IS_TRACKED)) {
+    nsIDocument* doc = GetOurCurrentDoc();
+    if (doc) {
+      mPendingRequestFlags |= REQUEST_IS_TRACKED;
+      doc->AddImage(mPendingRequest);
+    }
+  }
+
   if (mCurrentRequest) {
     nsLayoutUtils::RegisterImageRequestIfAnimated(presContext, mCurrentRequest,
                                                   &mCurrentRequestRegistered);
   }
 
   if (mPendingRequest) {
     nsLayoutUtils::RegisterImageRequestIfAnimated(presContext, mPendingRequest,
                                                   &mPendingRequestRegistered);
@@ -402,16 +417,31 @@ nsImageLoadingContent::FrameDestroyed(ns
                                           &mCurrentRequestRegistered);
   }
 
   if (mPendingRequest) {
     nsLayoutUtils::DeregisterImageRequest(GetFramePresContext(),
                                           mPendingRequest,
                                           &mPendingRequestRegistered);
   }
+
+  if (mCurrentRequest && (mCurrentRequestFlags & REQUEST_IS_TRACKED)) {
+    nsIDocument* doc = GetOurCurrentDoc();
+    if (doc) {
+      mCurrentRequestFlags &= ~REQUEST_IS_TRACKED;
+      doc->RemoveImage(mCurrentRequest);
+    }
+  }
+  if (mPendingRequest && (mPendingRequestFlags & REQUEST_IS_TRACKED)) {
+    nsIDocument* doc = GetOurCurrentDoc();
+    if (doc) {
+      mPendingRequestFlags &= ~REQUEST_IS_TRACKED;
+      doc->RemoveImage(mPendingRequest);
+    }
+  }
 }
 
 int32_t
 nsImageLoadingContent::GetRequestType(imgIRequest* aRequest,
                                       ErrorResult& aError)
 {
   if (aRequest == mCurrentRequest) {
     return CURRENT_REQUEST;
@@ -493,16 +523,17 @@ nsImageLoadingContent::LoadImageWithChan
   nsresult rv = nsContentUtils::GetImgLoaderForChannel(aChannel)->
     LoadImageWithChannel(aChannel, this, doc,
                          getter_AddRefs(listener),
                          getter_AddRefs(req));
   if (NS_SUCCEEDED(rv)) {
     TrackImage(req);
     ResetAnimationIfNeeded();
   } else {
+    MOZ_ASSERT(!req, "Shouldn't have non-null request here");
     // If we don't have a current URI, we might as well store this URI so people
     // know what we tried (and failed) to load.
     if (!mCurrentRequest)
       aChannel->GetURI(getter_AddRefs(mCurrentURI));
     FireEvent(NS_LITERAL_STRING("error"));
     aError.Throw(rv);
   }
   return listener.forget();
@@ -730,16 +761,17 @@ nsImageLoadingContent::LoadImage(nsIURI*
 
         nsImageFrame *f = do_QueryFrame(GetOurPrimaryFrame());
         if (f) {
           f->NotifyNewCurrentRequest(mCurrentRequest, NS_OK);
         }
       }
     }
   } else {
+    MOZ_ASSERT(!req, "Shouldn't have non-null request here");
     // If we don't have a current URI, we might as well store this URI so people
     // know what we tried (and failed) to load.
     if (!mCurrentRequest)
       mCurrentURI = aNewURI;
     FireEvent(NS_LITERAL_STRING("error"));
     return NS_OK;
   }
 
@@ -842,20 +874,22 @@ nsImageLoadingContent::UseAsPrimaryReque
 
   // Get rid if our existing images
   ClearPendingRequest(NS_BINDING_ABORTED);
   ClearCurrentRequest(NS_BINDING_ABORTED);
 
   // Clone the request we were given.
   nsRefPtr<imgRequestProxy>& req = PrepareNextRequest();
   nsresult rv = aRequest->Clone(this, getter_AddRefs(req));
-  if (NS_SUCCEEDED(rv))
+  if (NS_SUCCEEDED(rv)) {
     TrackImage(req);
-  else
+  } else {
+    MOZ_ASSERT(!req, "Shouldn't have non-null request here");
     return rv;
+  }
 
   return NS_OK;
 }
 
 nsIDocument*
 nsImageLoadingContent::GetOurOwnerDoc()
 {
   nsCOMPtr<nsIContent> thisContent =
@@ -1144,20 +1178,26 @@ nsImageLoadingContent::BindToTree(nsIDoc
   if (!aDocument)
     return;
 
   // Push a null JSContext on the stack so that callbacks triggered by the
   // below code won't think they're being called from JS.
   nsCxPusher pusher;
   pusher.PushNull();
 
-  if (mCurrentRequestFlags & REQUEST_SHOULD_BE_TRACKED)
-    aDocument->AddImage(mCurrentRequest);
-  if (mPendingRequestFlags & REQUEST_SHOULD_BE_TRACKED)
-    aDocument->AddImage(mPendingRequest);
+  if (GetOurPrimaryFrame()) {
+    if (mCurrentRequest && !(mCurrentRequestFlags & REQUEST_IS_TRACKED)) {
+      mCurrentRequestFlags |= REQUEST_IS_TRACKED;
+      aDocument->AddImage(mCurrentRequest);
+    }
+    if (mPendingRequest && !(mPendingRequestFlags & REQUEST_IS_TRACKED)) {
+      mPendingRequestFlags |= REQUEST_IS_TRACKED;
+      aDocument->AddImage(mPendingRequest);
+    }
+  }
 
   if (mCurrentRequestFlags & REQUEST_BLOCKS_ONLOAD)
     aDocument->BlockOnload();
 }
 
 void
 nsImageLoadingContent::UnbindFromTree(bool aDeep, bool aNullParent)
 {
@@ -1166,65 +1206,75 @@ nsImageLoadingContent::UnbindFromTree(bo
   if (!doc)
     return;
 
   // Push a null JSContext on the stack so that callbacks triggered by the
   // below code won't think they're being called from JS.
   nsCxPusher pusher;
   pusher.PushNull();
 
-  if (mCurrentRequestFlags & REQUEST_SHOULD_BE_TRACKED)
+  if (mCurrentRequest && (mCurrentRequestFlags & REQUEST_IS_TRACKED)) {
+    mCurrentRequestFlags &= ~REQUEST_IS_TRACKED;
     doc->RemoveImage(mCurrentRequest);
-  if (mPendingRequestFlags & REQUEST_SHOULD_BE_TRACKED)
+  }
+  if (mPendingRequest && (mPendingRequestFlags & REQUEST_IS_TRACKED)) {
+    mPendingRequestFlags &= ~REQUEST_IS_TRACKED;
     doc->RemoveImage(mPendingRequest);
+  }
 
   if (mCurrentRequestFlags & REQUEST_BLOCKS_ONLOAD)
     doc->UnblockOnload(false);
 }
 
 nsresult
 nsImageLoadingContent::TrackImage(imgIRequest* aImage)
 {
   if (!aImage)
     return NS_OK;
 
   MOZ_ASSERT(aImage == mCurrentRequest || aImage == mPendingRequest,
              "Why haven't we heard of this request?");
-  if (aImage == mCurrentRequest) {
-    mCurrentRequestFlags |= REQUEST_SHOULD_BE_TRACKED;
-  } else {
-    mPendingRequestFlags |= REQUEST_SHOULD_BE_TRACKED;
-  }
 
   nsIDocument* doc = GetOurCurrentDoc();
-  if (doc)
-    return doc->AddImage(aImage);
+  if (doc && GetOurPrimaryFrame()) {
+    if (aImage == mCurrentRequest && !(mCurrentRequestFlags & REQUEST_IS_TRACKED)) {
+      mCurrentRequestFlags |= REQUEST_IS_TRACKED;
+      doc->AddImage(mCurrentRequest);
+    }
+    if (aImage == mPendingRequest && !(mPendingRequestFlags & REQUEST_IS_TRACKED)) {
+      mPendingRequestFlags |= REQUEST_IS_TRACKED;
+      doc->AddImage(mPendingRequest);
+    }
+  }
   return NS_OK;
 }
 
 nsresult
 nsImageLoadingContent::UntrackImage(imgIRequest* aImage)
 {
   if (!aImage)
     return NS_OK;
 
   MOZ_ASSERT(aImage == mCurrentRequest || aImage == mPendingRequest,
              "Why haven't we heard of this request?");
-  if (aImage == mCurrentRequest) {
-    mCurrentRequestFlags &= ~REQUEST_SHOULD_BE_TRACKED;
-  } else {
-    mPendingRequestFlags &= ~REQUEST_SHOULD_BE_TRACKED;
-  }
 
   // If GetOurDocument() returns null here, we've outlived our document.
   // That's fine, because the document empties out the tracker and unlocks
   // all locked images on destruction.
   nsIDocument* doc = GetOurCurrentDoc();
-  if (doc)
-    return doc->RemoveImage(aImage, nsIDocument::REQUEST_DISCARD);
+  if (doc) {
+    if (aImage == mCurrentRequest && (mCurrentRequestFlags & REQUEST_IS_TRACKED)) {
+      mCurrentRequestFlags &= ~REQUEST_IS_TRACKED;
+      doc->RemoveImage(mCurrentRequest, nsIDocument::REQUEST_DISCARD);
+    }
+    if (aImage == mPendingRequest && (mPendingRequestFlags & REQUEST_IS_TRACKED)) {
+      mPendingRequestFlags &= ~REQUEST_IS_TRACKED;
+      doc->RemoveImage(mPendingRequest, nsIDocument::REQUEST_DISCARD);
+    }
+  }
   return NS_OK;
 }
 
 
 void
 nsImageLoadingContent::CreateStaticImageClone(nsImageLoadingContent* aDest) const
 {
   aDest->mCurrentRequest = nsContentUtils::GetStaticRequest(mCurrentRequest);
--- a/content/base/src/nsImageLoadingContent.h
+++ b/content/base/src/nsImageLoadingContent.h
@@ -332,23 +332,22 @@ protected:
 
   /* MEMBERS */
   nsRefPtr<imgRequestProxy> mCurrentRequest;
   nsRefPtr<imgRequestProxy> mPendingRequest;
   uint32_t mCurrentRequestFlags;
   uint32_t mPendingRequestFlags;
 
   enum {
-    // Set if the request needs 
+    // Set if the request needs ResetAnimation called on it.
     REQUEST_NEEDS_ANIMATION_RESET = 0x00000001U,
-    // Set if the request should be tracked.  This is true if the request is
-    // not tracked iff this node is not in the document.
-    REQUEST_SHOULD_BE_TRACKED = 0x00000002U,
     // Set if the request is blocking onload.
-    REQUEST_BLOCKS_ONLOAD = 0x00000004U
+    REQUEST_BLOCKS_ONLOAD = 0x00000002U,
+    // Set if the request is currently tracked with the document.
+    REQUEST_IS_TRACKED = 0x00000004U
   };
 
   // If the image was blocked or if there was an error loading, it's nice to
   // still keep track of what the URI was despite not having an imgIRequest.
   // We only maintain this in those situations (in the common case, this is
   // always null).
   nsCOMPtr<nsIURI>      mCurrentURI;
 
--- a/content/html/content/public/nsITextControlElement.h
+++ b/content/html/content/public/nsITextControlElement.h
@@ -13,18 +13,18 @@ class nsIContent;
 class nsAString;
 class nsIEditor;
 class nsISelectionController;
 class nsFrameSelection;
 class nsTextControlFrame;
 
 // IID for the nsITextControl interface
 #define NS_ITEXTCONTROLELEMENT_IID    \
-{ 0x3dd53b59, 0x9d8f, 0x40a3, \
-  { 0x81, 0xd7, 0xb3, 0x43, 0xa0, 0x51, 0xfc, 0xb5 } }
+{ 0x3558afa1, 0x6136, 0x4421, \
+  { 0xbd, 0xdc, 0x2c, 0x9d, 0x5f, 0xc1, 0xfb, 0x91 } }
 
 /**
  * This interface is used for the text control frame to get the editor and
  * selection controller objects, and some helper properties.
  */
 class nsITextControlElement : public nsISupports {
 public:
 
@@ -72,21 +72,16 @@ public:
 
   /**
    * Get the rows attribute (if textarea) or a default
    * @return the number of rows to use
    */
   NS_IMETHOD_(int32_t) GetRows() = 0;
 
   /**
-   * Get the default value of the text control
-   */
-  NS_IMETHOD_(void) GetDefaultValueFromContent(nsAString& aValue) = 0;
-
-  /**
    * Return true if the value of the control has been changed.
    */
   NS_IMETHOD_(bool) ValueChanged() const = 0;
 
   /**
    * Get the current value of the text editor.
    *
    * @param aValue the buffer to retrieve the value in
--- a/content/html/content/src/Makefile.in
+++ b/content/html/content/src/Makefile.in
@@ -137,22 +137,23 @@ CPPSRCS		= \
 		nsRadioVisitor.cpp \
 		nsDOMStringMap.cpp \
 		UndoManager.cpp \
 		$(NULL)
 
 ifdef MOZ_MEDIA
 EXPORTS_mozilla/dom += \
 		HTMLSourceElement.h \
+		MediaError.h \
 		$(NULL)
 
 CPPSRCS		+= \
 		nsHTMLAudioElement.cpp \
 		nsHTMLMediaElement.cpp \
-		nsMediaError.cpp \
+		MediaError.cpp \
 		nsMediaFragmentURIParser.cpp \
 		HTMLSourceElement.cpp \
 		nsTimeRanges.cpp \
 		nsHTMLVideoElement.cpp \
 		$(NULL)
 endif
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
rename from content/html/content/src/nsMediaError.cpp
rename to content/html/content/src/MediaError.cpp
--- a/content/html/content/src/nsMediaError.cpp
+++ b/content/html/content/src/MediaError.cpp
@@ -1,31 +1,50 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "nsMediaError.h"
-#include "nsDOMClassInfoID.h"
 
-NS_IMPL_ADDREF(nsMediaError)
-NS_IMPL_RELEASE(nsMediaError)
+#include "mozilla/dom/MediaError.h"
+#include "nsDOMClassInfoID.h"
+#include "mozilla/dom/MediaErrorBinding.h"
+
+DOMCI_DATA(MediaError, mozilla::dom::MediaError)
 
-DOMCI_DATA(MediaError, nsMediaError)
+namespace mozilla {
+namespace dom {
 
-NS_INTERFACE_MAP_BEGIN(nsMediaError)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(MediaError, mParent)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaError)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaError)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaError)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsIDOMMediaError)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMediaError)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MediaError)
 NS_INTERFACE_MAP_END
 
-nsMediaError::nsMediaError(uint16_t aCode) :
-  mCode(aCode)
+MediaError::MediaError(nsHTMLMediaElement* aParent, uint16_t aCode)
+  : mParent(aParent)
+  , mCode(aCode)
 {
+  SetIsDOMBinding();
 }
 
-NS_IMETHODIMP nsMediaError::GetCode(uint16_t* aCode)
+NS_IMETHODIMP MediaError::GetCode(uint16_t* aCode)
 {
   if (aCode)
-    *aCode = mCode;
+    *aCode = Code();
 
   return NS_OK;
 }
+
+JSObject*
+MediaError::WrapObject(JSContext* aCx, JSObject* aScope,
+                       bool* aTriedToWrap)
+{
+  return MediaErrorBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
+
+} // namespace dom
+} // namespace mozilla
rename from content/html/content/src/nsMediaError.h
rename to content/html/content/src/MediaError.h
--- a/content/html/content/src/nsMediaError.h
+++ b/content/html/content/src/MediaError.h
@@ -1,24 +1,54 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_MediaError_h
+#define mozilla_dom_MediaError_h
+
 #include "nsIDOMMediaError.h"
+#include "nsHTMLMediaElement.h"
+#include "nsWrapperCache.h"
 #include "nsISupports.h"
 #include "mozilla/Attributes.h"
 
-class nsMediaError MOZ_FINAL : public nsIDOMMediaError
+namespace mozilla {
+namespace dom {
+
+class MediaError MOZ_FINAL : public nsIDOMMediaError,
+                             public nsWrapperCache
 {
 public:
-  nsMediaError(uint16_t aCode);
+  MediaError(nsHTMLMediaElement* aParent, uint16_t aCode);
 
   // nsISupports
-  NS_DECL_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaError)
 
   // nsIDOMMediaError
   NS_DECL_NSIDOMMEDIAERROR
 
+  nsHTMLMediaElement* GetParentObject() const
+  {
+    return mParent;
+  }
+
+  virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope, bool* aTriedToWrap);
+
+  uint16_t Code() const
+  {
+    return mCode;
+  }
+
 private:
+  nsRefPtr<nsHTMLMediaElement> mParent;
+
   // Error code
-  uint16_t mCode;
+  const uint16_t mCode;
 };
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_MediaError_h
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -5187,30 +5187,16 @@ nsHTMLInputElement::GetWrapCols()
 }
 
 NS_IMETHODIMP_(int32_t)
 nsHTMLInputElement::GetRows()
 {
   return DEFAULT_ROWS;
 }
 
-NS_IMETHODIMP_(void)
-nsHTMLInputElement::GetDefaultValueFromContent(nsAString& aValue)
-{
-  nsTextEditorState *state = GetEditorState();
-  if (state) {
-    GetDefaultValue(aValue);
-    // This is called by the frame to show the value.
-    // We have to sanitize it when needed.
-    if (!mParserCreating) {
-      SanitizeValue(aValue);
-    }
-  }
-}
-
 NS_IMETHODIMP_(bool)
 nsHTMLInputElement::ValueChanged() const
 {
   return mValueChanged;
 }
 
 NS_IMETHODIMP_(void)
 nsHTMLInputElement::GetTextEditorValue(nsAString& aValue,
--- a/content/html/content/src/nsHTMLInputElement.h
+++ b/content/html/content/src/nsHTMLInputElement.h
@@ -137,17 +137,16 @@ public:
   NS_IMETHOD SetValueChanged(bool aValueChanged);
   NS_IMETHOD_(bool) IsSingleLineTextControl() const;
   NS_IMETHOD_(bool) IsTextArea() const;
   NS_IMETHOD_(bool) IsPlainTextControl() const;
   NS_IMETHOD_(bool) IsPasswordTextControl() const;
   NS_IMETHOD_(int32_t) GetCols();
   NS_IMETHOD_(int32_t) GetWrapCols();
   NS_IMETHOD_(int32_t) GetRows();
-  NS_IMETHOD_(void) GetDefaultValueFromContent(nsAString& aValue);
   NS_IMETHOD_(bool) ValueChanged() const;
   NS_IMETHOD_(void) GetTextEditorValue(nsAString& aValue, bool aIgnoreWrap) const;
   NS_IMETHOD_(nsIEditor*) GetTextEditor();
   NS_IMETHOD_(nsISelectionController*) GetSelectionController();
   NS_IMETHOD_(nsFrameSelection*) GetConstFrameSelection();
   NS_IMETHOD BindToFrame(nsTextControlFrame* aFrame);
   NS_IMETHOD_(void) UnbindFromFrame(nsTextControlFrame* aFrame);
   NS_IMETHOD CreateEditor();
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -33,17 +33,17 @@
 #include "nsFrameManager.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
 
 #include "nsITimer.h"
 
 #include "nsEventDispatcher.h"
-#include "nsMediaError.h"
+#include "MediaError.h"
 #include "MediaDecoder.h"
 #include "nsICategoryManager.h"
 #include "MediaResource.h"
 
 #include "nsIDOMHTMLVideoElement.h"
 #include "nsIContentPolicy.h"
 #include "nsContentPolicyUtils.h"
 #include "nsCrossSiteListenerProxy.h"
@@ -431,31 +431,33 @@ NS_IMPL_ADDREF_INHERITED(nsHTMLMediaElem
 NS_IMPL_RELEASE_INHERITED(nsHTMLMediaElement, nsGenericHTMLElement)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLMediaElement, nsGenericHTMLElement)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSrcStream)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSrcAttrStream)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourcePointer)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoadBlockedDoc)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceLoadCandidate)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mError)
   for (uint32_t i = 0; i < tmp->mOutputStreams.Length(); ++i) {
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOutputStreams[i].mStream);
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLMediaElement, nsGenericHTMLElement)
   if (tmp->mSrcStream) {
     // Need to EndMediaStreamPlayback to clear mStream and make sure everything
     // gets unhooked correctly.
     tmp->EndSrcMediaStreamPlayback();
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSrcAttrStream)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourcePointer)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoadBlockedDoc)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceLoadCandidate)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mError)
   for (uint32_t i = 0; i < tmp->mOutputStreams.Length(); ++i) {
     NS_IMPL_CYCLE_COLLECTION_UNLINK(mOutputStreams[i].mStream);
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsHTMLMediaElement)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
   NS_INTERFACE_MAP_ENTRY(nsIAudioChannelAgentCallback)
@@ -655,17 +657,17 @@ void nsHTMLMediaElement::AbortExistingLo
 
   mIsRunningSelectResource = false;
 }
 
 void nsHTMLMediaElement::NoSupportedMediaSourceError()
 {
   NS_ASSERTION(mDelayingLoadEvent, "Load event not delayed during source selection?");
 
-  mError = new nsMediaError(nsIDOMMediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
+  mError = new MediaError(this, nsIDOMMediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
   mNetworkState = nsIDOMHTMLMediaElement::NETWORK_NO_SOURCE;
   DispatchAsyncEvent(NS_LITERAL_STRING("error"));
   // This clears mDelayingLoadEvent, so AddRemoveSelfReference will be called
   ChangeDelayLoadStatus(false);
 }
 
 typedef void (nsHTMLMediaElement::*SyncSectionFn)();
 
@@ -2735,17 +2737,17 @@ void nsHTMLMediaElement::LoadAborted()
 }
 
 void nsHTMLMediaElement::Error(uint16_t aErrorCode)
 {
   NS_ASSERTION(aErrorCode == nsIDOMMediaError::MEDIA_ERR_DECODE ||
                aErrorCode == nsIDOMMediaError::MEDIA_ERR_NETWORK ||
                aErrorCode == nsIDOMMediaError::MEDIA_ERR_ABORTED,
                "Only use nsIDOMMediaError codes!");
-  mError = new nsMediaError(aErrorCode);
+  mError = new MediaError(this, aErrorCode);
   mBegun = false;
   DispatchAsyncEvent(NS_LITERAL_STRING("error"));
   if (mReadyState == nsIDOMHTMLMediaElement::HAVE_NOTHING) {
     mNetworkState = nsIDOMHTMLMediaElement::NETWORK_EMPTY;
     DispatchAsyncEvent(NS_LITERAL_STRING("emptied"));
   } else {
     mNetworkState = nsIDOMHTMLMediaElement::NETWORK_IDLE;
   }
--- a/content/html/content/src/nsHTMLTextAreaElement.cpp
+++ b/content/html/content/src/nsHTMLTextAreaElement.cpp
@@ -107,17 +107,16 @@ public:
   NS_IMETHOD SetValueChanged(bool aValueChanged);
   NS_IMETHOD_(bool) IsSingleLineTextControl() const;
   NS_IMETHOD_(bool) IsTextArea() const;
   NS_IMETHOD_(bool) IsPlainTextControl() const;
   NS_IMETHOD_(bool) IsPasswordTextControl() const;
   NS_IMETHOD_(int32_t) GetCols();
   NS_IMETHOD_(int32_t) GetWrapCols();
   NS_IMETHOD_(int32_t) GetRows();
-  NS_IMETHOD_(void) GetDefaultValueFromContent(nsAString& aValue);
   NS_IMETHOD_(bool) ValueChanged() const;
   NS_IMETHOD_(void) GetTextEditorValue(nsAString& aValue, bool aIgnoreWrap) const;
   NS_IMETHOD_(nsIEditor*) GetTextEditor();
   NS_IMETHOD_(nsISelectionController*) GetSelectionController();
   NS_IMETHOD_(nsFrameSelection*) GetConstFrameSelection();
   NS_IMETHOD BindToFrame(nsTextControlFrame* aFrame);
   NS_IMETHOD_(void) UnbindFromFrame(nsTextControlFrame* aFrame);
   NS_IMETHOD CreateEditor();
@@ -574,19 +573,16 @@ nsHTMLTextAreaElement::SetUserInput(cons
 }
 
 NS_IMETHODIMP
 nsHTMLTextAreaElement::SetValueChanged(bool aValueChanged)
 {
   bool previousValue = mValueChanged;
 
   mValueChanged = aValueChanged;
-  if (!aValueChanged && !mState.IsEmpty()) {
-    mState.EmptyValue();
-  }
 
   if (mValueChanged != previousValue) {
     UpdateState(true);
   }
 
   return NS_OK;
 }
 
@@ -1487,22 +1483,16 @@ nsHTMLTextAreaElement::GetRows()
   if (attr && attr->Type() == nsAttrValue::eInteger) {
     int32_t rows = attr->GetIntegerValue();
     return (rows <= 0) ? DEFAULT_ROWS_TEXTAREA : rows;
   }
 
   return DEFAULT_ROWS_TEXTAREA;
 }
 
-NS_IMETHODIMP_(void)
-nsHTMLTextAreaElement::GetDefaultValueFromContent(nsAString& aValue)
-{
-  GetDefaultValue(aValue);
-}
-
 NS_IMETHODIMP_(bool)
 nsHTMLTextAreaElement::ValueChanged() const
 {
   return mValueChanged;
 }
 
 NS_IMETHODIMP_(void)
 nsHTMLTextAreaElement::GetTextEditorValue(nsAString& aValue,
--- a/content/html/content/src/nsHTMLVideoElement.cpp
+++ b/content/html/content/src/nsHTMLVideoElement.cpp
@@ -24,17 +24,17 @@
 #include "nsIScriptSecurityManager.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
 
 #include "nsITimer.h"
 
 #include "nsEventDispatcher.h"
 #include "nsIDOMProgressEvent.h"
-#include "nsMediaError.h"
+#include "MediaError.h"
 #include "MediaDecoder.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Video)
 
 NS_IMPL_ADDREF_INHERITED(nsHTMLVideoElement, nsHTMLMediaElement)
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -1742,19 +1742,17 @@ nsTextEditorState::GetValue(nsAString& a
                               aValue);
     }
     if (canCache) {
       mCachedValue = aValue;
     } else {
       mCachedValue.Truncate();
     }
   } else {
-    if (!mTextCtrlElement->ValueChanged() || !mValue) {
-      mTextCtrlElement->GetDefaultValueFromContent(aValue);
-    } else {
+    if (mValue) {
       aValue = NS_ConvertUTF8toUTF16(*mValue);
     }
   }
 }
 
 void
 nsTextEditorState::SetValue(const nsAString& aValue, bool aUserInput,
                             bool aSetValueChanged)
--- a/content/html/content/src/nsTextEditorState.h
+++ b/content/html/content/src/nsTextEditorState.h
@@ -132,18 +132,16 @@ public:
   nsresult BindToFrame(nsTextControlFrame* aFrame);
   void UnbindFromFrame(nsTextControlFrame* aFrame);
   nsresult PrepareEditor(const nsAString *aValue = nullptr);
   void InitializeKeyboardEventListeners();
 
   void SetValue(const nsAString& aValue, bool aUserInput,
                 bool aSetValueAsChanged);
   void GetValue(nsAString& aValue, bool aIgnoreWrap) const;
-  void EmptyValue() { if (mValue) mValue->Truncate(); }
-  bool IsEmpty() const { return mValue ? mValue->IsEmpty() : true; }
 
   nsresult CreatePlaceholderNode();
 
   nsIContent* GetRootNode() {
     if (!mRootNode)
       CreateRootNode();
     return mRootNode;
   }
--- a/content/media/MediaDecoderStateMachine.cpp
+++ b/content/media/MediaDecoderStateMachine.cpp
@@ -988,32 +988,33 @@ void MediaDecoderStateMachine::AudioLoop
   bool setPreservesPitch;
   int32_t minWriteFrames = -1;
   AudioChannelType audioChannelType;
 
   {
     ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
     mAudioCompleted = false;
     audioStartTime = mAudioStartTime;
+    NS_ASSERTION(audioStartTime != -1, "Should have audio start time by now");
     channels = mInfo.mAudioChannels;
     rate = mInfo.mAudioRate;
+
     audioChannelType = mDecoder->GetAudioChannelType();
-    NS_ASSERTION(audioStartTime != -1, "Should have audio start time by now");
-
     volume = mVolume;
     preservesPitch = mPreservesPitch;
     playbackRate = mPlaybackRate;
   }
 
   {
     // AudioStream initialization can block for extended periods in unusual
     // circumstances, so we take care to drop the decoder monitor while
     // initializing.
     nsAutoPtr<AudioStream> audioStream(AudioStream::AllocateStream());
     audioStream->Init(channels, rate, audioChannelType);
+    audioStream->SetVolume(volume);
     audioStream->SetPreservesPitch(preservesPitch);
     if (playbackRate != 1.0) {
       NS_ASSERTION(playbackRate != 0,
                    "Don't set the playbackRate to 0 on an AudioStream.");
       audioStream->SetPlaybackRate(playbackRate);
     }
 
     {
@@ -2299,21 +2300,18 @@ int64_t MediaDecoderStateMachine::GetVid
   // The playbackRate has been just been changed, reset the playstartTime.
   if (mResetPlayStartTime) {
     mPlayStartTime = TimeStamp::Now();
     mResetPlayStartTime = false;
   }
 
   int64_t pos = DurationToUsecs(TimeStamp::Now() - mPlayStartTime) + mPlayDuration;
   pos -= mBasePosition;
-  if (pos >= 0) {
-    int64_t final = mBasePosition + pos * mPlaybackRate + mStartTime;
-    return final;
-  }
-  return mPlayDuration + mStartTime;
+  NS_ASSERTION(pos >= 0, "Video stream position should be positive.");
+  return mBasePosition + pos * mPlaybackRate + mStartTime;
 }
 
 int64_t MediaDecoderStateMachine::GetClock() {
   NS_ASSERTION(OnStateMachineThread(), "Should be on state machine thread.");
   mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   // Determine the clock time. If we've got audio, and we've not reached
   // the end of the audio, use the audio clock. However if we've finished
@@ -2762,22 +2760,24 @@ void MediaDecoderStateMachine::SetPlayba
 
   if (mPlaybackRate == aPlaybackRate) {
     return;
   }
 
   // Get position of the last time we changed the rate.
   if (!HasAudio()) {
     // mBasePosition is a position in the video stream, not an absolute time.
-    mBasePosition = GetVideoStreamPosition();
-    if (IsPlaying()) {
-      mPlayDuration = mBasePosition - mStartTime;
-      mResetPlayStartTime = true;
-      mPlayStartTime = TimeStamp::Now();
+    if (mState == DECODER_STATE_SEEKING) {
+      mBasePosition = mSeekTime;
+    } else {
+      mBasePosition = GetVideoStreamPosition();
     }
+    mPlayDuration = mBasePosition - mStartTime;
+    mResetPlayStartTime = true;
+    mPlayStartTime = TimeStamp::Now();
   }
 
   mPlaybackRate = aPlaybackRate;
 }
 
 void MediaDecoderStateMachine::SetPreservesPitch(bool aPreservesPitch)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
--- a/content/media/gstreamer/GStreamerReader.cpp
+++ b/content/media/gstreamer/GStreamerReader.cpp
@@ -83,16 +83,18 @@ GStreamerReader::GStreamerReader(Abstrac
 
 GStreamerReader::~GStreamerReader()
 {
   MOZ_COUNT_DTOR(GStreamerReader);
   ResetDecode();
 
   if (mPlayBin) {
     gst_app_src_end_of_stream(mSource);
+    if (mSource)
+      gst_object_unref(mSource);
     gst_element_set_state(mPlayBin, GST_STATE_NULL);
     gst_object_unref(mPlayBin);
     mPlayBin = NULL;
     mVideoSink = NULL;
     mVideoAppSink = NULL;
     mAudioSink = NULL;
     mAudioAppSink = NULL;
     gst_object_unref(mBus);
@@ -129,54 +131,57 @@ nsresult GStreamerReader::Init(MediaDeco
   gst_pad_add_event_probe(sinkpad,
       G_CALLBACK(&GStreamerReader::EventProbeCb), this);
   gst_object_unref(sinkpad);
 
   mAudioSink = gst_parse_bin_from_description("capsfilter name=filter ! "
 #ifdef MOZ_SAMPLE_TYPE_FLOAT32
         "appsink name=audiosink sync=true caps=audio/x-raw-float,"
 #ifdef IS_LITTLE_ENDIAN
-        "channels={1,2},rate=44100,width=32,endianness=1234", TRUE, NULL);
+        "channels={1,2},width=32,endianness=1234", TRUE, NULL);
 #else
-        "channels={1,2},rate=44100,width=32,endianness=4321", TRUE, NULL);
+        "channels={1,2},width=32,endianness=4321", TRUE, NULL);
 #endif
 #else
         "appsink name=audiosink sync=true caps=audio/x-raw-int,"
 #ifdef IS_LITTLE_ENDIAN
-        "channels={1,2},rate=48000,width=16,endianness=1234", TRUE, NULL);
+        "channels={1,2},width=16,endianness=1234", TRUE, NULL);
 #else
-        "channels={1,2},rate=48000,width=16,endianness=4321", TRUE, NULL);
+        "channels={1,2},width=16,endianness=4321", TRUE, NULL);
 #endif
 #endif
   mAudioAppSink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(mAudioSink),
         "audiosink"));
   gst_app_sink_set_callbacks(mAudioAppSink, &mSinkCallbacks,
       (gpointer) this, NULL);
   sinkpad = gst_element_get_pad(GST_ELEMENT(mAudioAppSink), "sink");
   gst_pad_add_event_probe(sinkpad,
       G_CALLBACK(&GStreamerReader::EventProbeCb), this);
   gst_object_unref(sinkpad);
 
   g_object_set(mPlayBin, "uri", "appsrc://",
       "video-sink", mVideoSink,
       "audio-sink", mAudioSink,
       NULL);
 
-  g_object_connect(mPlayBin, "signal::source-setup",
-      GStreamerReader::PlayBinSourceSetupCb, this, NULL);
+  g_signal_connect(G_OBJECT(mPlayBin), "notify::source",
+    G_CALLBACK(GStreamerReader::PlayBinSourceSetupCb), this);
 
   return NS_OK;
 }
 
 void GStreamerReader::PlayBinSourceSetupCb(GstElement *aPlayBin,
-                                             GstElement *aSource,
+                                             GParamSpec *pspec,
                                              gpointer aUserData)
 {
+  GstElement *source;
   GStreamerReader *reader = reinterpret_cast<GStreamerReader*>(aUserData);
-  reader->PlayBinSourceSetup(GST_APP_SRC(aSource));
+
+  g_object_get(aPlayBin, "source", &source, NULL);
+  reader->PlayBinSourceSetup(GST_APP_SRC(source));
 }
 
 void GStreamerReader::PlayBinSourceSetup(GstAppSrc *aSource)
 {
   mSource = GST_APP_SRC(aSource);
   gst_app_src_set_callbacks(mSource, &mSrcCallbacks, (gpointer) this, NULL);
   MediaResource* resource = mDecoder->GetResource();
   int64_t len = resource->GetLength();
--- a/content/media/gstreamer/GStreamerReader.h
+++ b/content/media/gstreamer/GStreamerReader.h
@@ -52,17 +52,17 @@ private:
   int64_t QueryDuration();
 
   /* Gst callbacks */
 
   /* Called on the source-setup signal emitted by playbin. Used to
    * configure appsrc .
    */
   static void PlayBinSourceSetupCb(GstElement *aPlayBin,
-                                   GstElement *aSource,
+                                   GParamSpec *pspec,
                                    gpointer aUserData);
   void PlayBinSourceSetup(GstAppSrc *aSource);
 
   /* Called from appsrc when we need to read more data from the resource */
   static void NeedDataCb(GstAppSrc *aSrc, guint aLength, gpointer aUserData);
   void NeedData(GstAppSrc *aSrc, guint aLength);
 
   /* Called when appsrc has enough data and we can stop reading */
--- a/content/media/webaudio/AudioDestinationNode.cpp
+++ b/content/media/webaudio/AudioDestinationNode.cpp
@@ -9,26 +9,30 @@
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "MediaStreamGraph.h"
 #include "nsContentUtils.h"
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_ISUPPORTS_INHERITED0(AudioDestinationNode, AudioNode)
-
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(AudioDestinationNode, AudioNode)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(AudioDestinationNode, AudioNode)              \
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(AudioDestinationNode, AudioNode)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(AudioDestinationNode)
 
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(AudioDestinationNode)
+NS_INTERFACE_MAP_END_INHERITING(AudioNode)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(AudioDestinationNode)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(AudioDestinationNode)
+
 AudioDestinationNode::AudioDestinationNode(AudioContext* aContext, MediaStreamGraph* aGraph)
   : AudioNode(aContext)
 {
   mStream = aGraph->CreateAudioNodeStream(new AudioNodeEngine());
   SetIsDOMBinding();
 }
 
 JSObject*
--- a/content/media/webaudio/test/Makefile.in
+++ b/content/media/webaudio/test/Makefile.in
@@ -9,16 +9,17 @@ VPATH          := @srcdir@
 relativesrcdir := @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_FILES := \
   webaudio.js \
   test_bug808374.html \
   test_bug827541.html \
+  test_bug839753.html \
   test_AudioBuffer.html \
   test_AudioContext.html \
   test_AudioListener.html \
   test_badConnect.html \
   test_biquadFilterNode.html \
   test_delayNode.html \
   test_decodeAudioData.html \
   test_dynamicsCompressorNode.html \
new file mode 100644
--- /dev/null
+++ b/content/media/webaudio/test/test_bug839753.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Crashtest for bug 839753</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+SpecialPowers.setBoolPref("media.webaudio.enabled", true);
+AudioContext().destination.expando = null;
+ok(true, "The test should not trigger wrapper cache assertions");
+SpecialPowers.clearUserPref("media.webaudio.enabled");
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/media/webm/WebMBufferedParser.cpp
+++ b/content/media/webm/WebMBufferedParser.cpp
@@ -136,18 +136,18 @@ void WebMBufferedParser::Append(const un
         mBlockTimecode <<= 8;
         mBlockTimecode |= *p++;
         mBlockTimecodeLength -= 1;
       } else {
         // It's possible we've parsed this data before, so avoid inserting
         // duplicate WebMTimeDataOffset entries.
         {
           ReentrantMonitorAutoEnter mon(aReentrantMonitor);
-          uint32_t idx;
-          if (!aMapping.GreatestIndexLtEq(mBlockOffset, idx)) {
+          uint32_t idx = aMapping.IndexOfFirstElementGt(mBlockOffset);
+          if (idx == 0 || !(aMapping[idx-1] == mBlockOffset)) {
             WebMTimeDataOffset entry(mBlockOffset, mClusterTimecode + mBlockTimecode);
             aMapping.InsertElementAt(idx, entry);
           }
         }
 
         // Skip rest of block header and the block's payload.
         mBlockSize -= mVIntLength;
         mBlockSize -= 2;
@@ -179,27 +179,24 @@ void WebMBufferedParser::Append(const un
 }
 
 bool WebMBufferedState::CalculateBufferedForRange(int64_t aStartOffset, int64_t aEndOffset,
                                                     uint64_t* aStartTime, uint64_t* aEndTime)
 {
   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   // Find the first WebMTimeDataOffset at or after aStartOffset.
-  uint32_t start;
-  mTimeMapping.GreatestIndexLtEq(aStartOffset, start);
+  uint32_t start = mTimeMapping.IndexOfFirstElementGt(aStartOffset-1);
   if (start == mTimeMapping.Length()) {
     return false;
   }
 
   // Find the first WebMTimeDataOffset at or before aEndOffset.
-  uint32_t end;
-  if (!mTimeMapping.GreatestIndexLtEq(aEndOffset, end) && end > 0) {
-    // No exact match, so adjust end to be the first entry before
-    // aEndOffset.
+  uint32_t end = mTimeMapping.IndexOfFirstElementGt(aEndOffset-1);
+  if (end > 0) {
     end -= 1;
   }
 
   // Range is empty.
   if (end <= start) {
     return false;
   }
 
@@ -222,18 +219,18 @@ bool WebMBufferedState::CalculateBuffere
   *aStartTime = mTimeMapping[start].mTimecode;
   *aEndTime = mTimeMapping[end].mTimecode;
   return true;
 }
 
 void WebMBufferedState::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  uint32_t idx;
-  if (!mRangeParsers.GreatestIndexLtEq(aOffset, idx)) {
+  uint32_t idx = mRangeParsers.IndexOfFirstElementGt(aOffset - 1);
+  if (idx == 0 || !(mRangeParsers[idx-1] == aOffset)) {
     // If the incoming data overlaps an already parsed range, adjust the
     // buffer so that we only reparse the new data.  It's also possible to
     // have an overlap where the end of the incoming data is within an
     // already parsed range, but we don't bother handling that other than by
     // avoiding storing duplicate timecodes when the parser runs.
     if (idx != mRangeParsers.Length() && mRangeParsers[idx].mStartOffset <= aOffset) {
       // Complete overlap, skip parsing.
       if (aOffset + aLength <= mRangeParsers[idx].mCurrentOffset) {
--- a/content/media/webrtc/MediaEngineWebRTCVideo.cpp
+++ b/content/media/webrtc/MediaEngineWebRTCVideo.cpp
@@ -1,16 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MediaEngineWebRTC.h"
 #include "Layers.h"
 #include "ImageTypes.h"
 #include "ImageContainer.h"
+#include "mtransport/runnable_utils.h"
 
 namespace mozilla {
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* GetMediaManagerLog();
 #define LOG(msg) PR_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
 #define LOGFRAME(msg) PR_LOG(GetMediaManagerLog(), 6, msg)
 #else
@@ -222,17 +223,36 @@ nsresult
 MediaEngineWebRTCVideoSource::Deallocate()
 {
   LOG((__FUNCTION__));
   if (mSources.IsEmpty()) {
     if (mState != kStopped && mState != kAllocated) {
       return NS_ERROR_FAILURE;
     }
 
+#ifdef XP_MACOSX
+    // Bug 829907 - on mac, in shutdown, the mainthread stops processing
+    // 'native' events, and the QTKit code uses events to the main native CFRunLoop
+    // in order to provide thread safety.  In order to avoid this locking us up,
+    // release the ViE capture device synchronously on MainThread (so the native
+    // event isn't needed).
+    // XXX Note if MainThread Dispatch()es NS_DISPATCH_SYNC to us we can deadlock.
+    // XXX It might be nice to only do this if we're in shutdown...  Hard to be
+    // sure when that is though.
+    // Thread safety: a) we call this synchronously, and don't use ViECapture from
+    // another thread anywhere else, b) ViEInputManager::DestroyCaptureDevice() grabs
+    // an exclusive object lock and deletes it in a critical section, so all in all
+    // this should be safe threadwise.
+    NS_DispatchToMainThread(WrapRunnable(mViECapture,
+                                         &webrtc::ViECapture::ReleaseCaptureDevice,
+                                         mCaptureIndex),
+                            NS_DISPATCH_SYNC);
+#else
     mViECapture->ReleaseCaptureDevice(mCaptureIndex);
+#endif
     mState = kReleased;
     LOG(("Video device %d deallocated", mCaptureIndex));
   } else {
     LOG(("Video device %d deallocated but still in use", mCaptureIndex));
   }
   return NS_OK;
 }
 
--- a/content/svg/content/src/SVGComponentTransferFunctionElement.h
+++ b/content/svg/content/src/SVGComponentTransferFunctionElement.h
@@ -11,31 +11,26 @@
 #include "nsSVGNumber2.h"
 #include "SVGAnimatedNumberList.h"
 
 
 #define NS_SVG_FE_COMPONENT_TRANSFER_FUNCTION_ELEMENT_CID \
 { 0xafab106d, 0xbc18, 0x4f7f, \
   { 0x9e, 0x29, 0xfe, 0xb4, 0xb0, 0x16, 0x5f, 0xf4 } }
 
-nsresult NS_NewSVGComponentTransferFunctionElement(
-  nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo);
-
 namespace mozilla {
 
 class DOMSVGAnimatedNumberList;
 
 namespace dom {
 
 typedef SVGFEUnstyledElement SVGComponentTransferFunctionElementBase;
 
 class SVGComponentTransferFunctionElement : public SVGComponentTransferFunctionElementBase
 {
-  friend nsresult (::NS_NewSVGComponentTransferFunctionElement(
-    nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo));
 protected:
   SVGComponentTransferFunctionElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : SVGComponentTransferFunctionElementBase(aNodeInfo)
   {
     SetIsDOMBinding();
   }
 
 public:
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -1199,24 +1199,16 @@ nsXBLBinding::DoInitJSClass(JSContext *c
 
       (nsXBLService::gClassTable)->Remove(&key);
 
       c->Drop();
 
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
-    // Make the class object a permanent and read-only property on the global.
-    // Xrays rely on this to find the correct binding functions.
-    JSBool found = false;
-    if (!JS_SetPropertyAttributes(cx, global, c->name,
-                                  JSPROP_READONLY | JSPROP_PERMANENT, &found))
-      return NS_ERROR_FAILURE;
-    MOZ_ASSERT(found);
-
     // Keep this proto binding alive while we're alive.  Do this first so that
     // we can guarantee that in XBLFinalize this will be non-null.
     // Note that we can't just store aProtoBinding in the private and
     // addref/release the nsXBLDocumentInfo through it, because cycle
     // collection doesn't seem to work right if the private is not an
     // nsISupports.
     nsXBLDocumentInfo* docInfo = aProtoBinding->XBLDocumentInfo();
     ::JS_SetPrivate(proto, docInfo);
@@ -1430,55 +1422,58 @@ nsXBLBinding::LookupMember(JSContext* aC
   }
   nsDependentJSString name(aId);
 
   // We have a weak reference to our bound element, so make sure it's alive.
   if (!mBoundElement || !mBoundElement->GetWrapper()) {
     return false;
   }
 
-  // Get the scope of mBoundElement.
+  // Get the scope of mBoundElement and the associated XBL scope. We should only
+  // be calling into this machinery if we're running in a separate XBL scope.
   JSObject* boundScope =
     js::GetGlobalForObjectCrossCompartment(mBoundElement->GetWrapper());
+  JSObject* xblScope = xpc::GetXBLScope(aCx, boundScope);
+  MOZ_ASSERT(boundScope != xblScope);
 
-  // Enter the compartment of mBoundElement and invoke the internal version.
+  // Enter the xbl scope and invoke the internal version.
   {
-    JSAutoCompartment ac(aCx, boundScope);
+    JSAutoCompartment ac(aCx, xblScope);
     js::RootedId id(aCx, aId);
     if (!JS_WrapId(aCx, id.address()) ||
-        !LookupMemberInternal(aCx, name, id, aDesc, boundScope))
+        !LookupMemberInternal(aCx, name, id, aDesc, xblScope))
     {
       return false;
     }
   }
 
   // Wrap into the caller's scope.
   return JS_WrapPropertyDescriptor(aCx, aDesc);
 }
 
 bool
 nsXBLBinding::LookupMemberInternal(JSContext* aCx, nsString& aName,
                                    JS::HandleId aNameAsId,
                                    JSPropertyDescriptor* aDesc,
-                                   JSObject* aBoundScope)
+                                   JSObject* aXBLScope)
 {
   // First, see if we have a JSClass. If we don't, it means that this binding
   // doesn't have a class object, and thus doesn't have any members. Skip it.
   if (!mJSClass) {
     if (!mNextBinding) {
       return true;
     }
     return mNextBinding->LookupMemberInternal(aCx, aName, aNameAsId,
-                                              aDesc, aBoundScope);
+                                              aDesc, aXBLScope);
   }
 
-  // Find our class object. It's permanent, so it should be there no matter
-  // what.
+  // Find our class object. It's in a protected scope and permanent just in case,
+  // so should be there no matter what.
   js::RootedValue classObject(aCx);
-  if (!JS_GetProperty(aCx, aBoundScope, mJSClass->name, classObject.address())) {
+  if (!JS_GetProperty(aCx, aXBLScope, mJSClass->name, classObject.address())) {
     return false;
   }
   MOZ_ASSERT(classObject.isObject());
 
   // Look for the property on this binding. If it's not there, try the next
   // binding on the chain.
   nsXBLProtoImpl* impl = mPrototypeBinding->GetImplementation();
   if (impl && !impl->LookupMember(aCx, aName, aNameAsId, aDesc,
@@ -1486,17 +1481,17 @@ nsXBLBinding::LookupMemberInternal(JSCon
   {
     return false;
   }
   if (aDesc->obj || !mNextBinding) {
     return true;
   }
 
   return mNextBinding->LookupMemberInternal(aCx, aName, aNameAsId, aDesc,
-                                            aBoundScope);
+                                            aXBLScope);
 }
 
 bool
 nsXBLBinding::HasField(nsString& aName)
 {
   // See if this binding has such a field.
   return mPrototypeBinding->FindField(aName) ||
     (mNextBinding && mNextBinding->HasField(aName));
--- a/content/xbl/src/nsXBLBinding.h
+++ b/content/xbl/src/nsXBLBinding.h
@@ -67,31 +67,34 @@ public:
 
   bool IsStyleBinding() const { return mIsStyleBinding; }
   void SetIsStyleBinding(bool aIsStyle) { mIsStyleBinding = aIsStyle; }
 
   /*
    * Does a lookup for a method or attribute provided by one of the bindings'
    * prototype implementation. If found, |desc| will be set up appropriately,
    * and wrapped into cx->compartment.
+   *
+   * May only be called when XBL code is being run in a separate scope, because
+   * otherwise we don't have untainted data with which to do a proper lookup.
    */
   bool LookupMember(JSContext* aCx, JS::HandleId aId, JSPropertyDescriptor* aDesc);
 
   /*
    * Determines whether the binding has a field with the given name.
    */
   bool HasField(nsString& aName);
 
 protected:
 
   /*
-   * Internal version. Requires that aCx is in the compartment of aBoundScope.
+   * Internal version. Requires that aCx is in appropriate xbl scope.
    */
   bool LookupMemberInternal(JSContext* aCx, nsString& aName, JS::HandleId aNameAsId,
-                            JSPropertyDescriptor* aDesc, JSObject* aBoundScope);
+                            JSPropertyDescriptor* aDesc, JSObject* aXBLScope);
 
 public:
 
   void MarkForDeath();
   bool MarkedForDeath() const { return mMarkedForDeath; }
 
   bool HasStyleSheets() const;
   bool InheritsStyle() const;
--- a/content/xbl/src/nsXBLProtoImpl.cpp
+++ b/content/xbl/src/nsXBLProtoImpl.cpp
@@ -92,16 +92,52 @@ nsXBLProtoImpl::InstallImplementation(ns
   AutoVersionChecker avc(cx);
 
   // Walk our member list and install each one in turn.
   for (nsXBLProtoImplMember* curr = mMembers;
        curr;
        curr = curr->GetNext())
     curr->InstallMember(cx, targetClassObject);
 
+  // If we're using a separate XBL scope, make a safe copy of the target class
+  // object in the XBL scope that we can use for Xray lookups. We don't need
+  // the field accessors, so do this before installing them.
+  JSObject* globalObject = JS_GetGlobalForObject(cx, targetClassObject);
+  JSObject* scopeObject = xpc::GetXBLScope(cx, globalObject);
+  if (scopeObject != globalObject) {
+    JSAutoCompartment ac2(cx, scopeObject);
+
+    // Create the object. This is just a property holder, so it doesn't need
+    // any special JSClass.
+    JSObject *shadowProto = JS_NewObjectWithGivenProto(cx, nullptr, nullptr,
+                                                       scopeObject);
+    NS_ENSURE_TRUE(shadowProto, NS_ERROR_OUT_OF_MEMORY);
+
+    // Define it as a property on the scopeObject, using the same name used on
+    // the content side.
+    bool ok = JS_DefineProperty(cx, scopeObject,
+                                js::GetObjectClass(targetClassObject)->name,
+                                JS::ObjectValue(*shadowProto), JS_PropertyStub,
+                                JS_StrictPropertyStub,
+                                JSPROP_PERMANENT | JSPROP_READONLY);
+    NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
+
+    // Copy all the properties from the content-visible prototype to the shadow
+    // object. This rewraps them appropriately, which should result in vanilla
+    // functions, since the properties on the content prototype were cross-
+    // compartment wrappers.
+    ok = JS_CopyPropertiesFrom(cx, shadowProto, targetClassObject);
+    NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
+
+    // Content shouldn't have any way to touch this object, but freeze it just
+    // to be safe.
+    ok = JS_FreezeObject(cx, shadowProto);
+    NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
+  }
+
   // Install all of our field accessors.
   for (nsXBLProtoImplField* curr = mFields;
        curr;
        curr = curr->GetNext())
     curr->InstallAccessors(cx, targetClassObject);
 
   return NS_OK;
 }
--- a/content/xbl/src/nsXBLProtoImplField.h
+++ b/content/xbl/src/nsXBLProtoImplField.h
@@ -39,18 +39,17 @@ public:
 
   nsresult Read(nsIScriptContext* aContext, nsIObjectInputStream* aStream);
   nsresult Write(nsIScriptContext* aContext, nsIObjectOutputStream* aStream);
 
   const PRUnichar* GetName() const { return mName; }
 
   unsigned AccessorAttributes() const {
     return JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER |
-           JSPROP_READONLY | JSPROP_PERMANENT |
-           (mJSAttributes & JSPROP_ENUMERATE);
+           (mJSAttributes & (JSPROP_ENUMERATE | JSPROP_PERMANENT));
   }
 
   bool IsEmpty() const { return mFieldTextLength == 0; }
 
 protected:
   nsXBLProtoImplField* mNext;
   PRUnichar* mName;
   PRUnichar* mFieldText;
--- a/content/xbl/src/nsXBLProtoImplMethod.cpp
+++ b/content/xbl/src/nsXBLProtoImplMethod.cpp
@@ -116,18 +116,17 @@ nsXBLProtoImplMethod::InstallMember(JSCo
 
     // Then, enter the content compartment, wrap the method pointer, and define
     // the wrapped version on the class object.
     JSAutoCompartment ac2(aCx, aTargetClassObject);
     if (!JS_WrapObject(aCx, &method) ||
         !::JS_DefineUCProperty(aCx, aTargetClassObject,
                                static_cast<const jschar*>(mName),
                                name.Length(), OBJECT_TO_JSVAL(method),
-                               NULL, NULL,
-                               JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) {
+                               NULL, NULL, JSPROP_ENUMERATE)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
   return NS_OK;
 }
 
 nsresult 
 nsXBLProtoImplMethod::CompileMember(nsIScriptContext* aContext, const nsCString& aClassStr,
--- a/content/xbl/src/nsXBLProtoImplProperty.cpp
+++ b/content/xbl/src/nsXBLProtoImplProperty.cpp
@@ -166,17 +166,17 @@ nsXBLProtoImplProperty::InstallMember(JS
     nsDependentString name(mName);
     if (!JS_WrapObject(aCx, &getter) ||
         !JS_WrapObject(aCx, &setter) ||
         !::JS_DefineUCProperty(aCx, aTargetClassObject,
                                static_cast<const jschar*>(mName),
                                name.Length(), JSVAL_VOID,
                                JS_DATA_TO_FUNC_PTR(JSPropertyOp, getter),
                                JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, setter),
-                               mJSAttributes | JSPROP_PERMANENT | JSPROP_READONLY))
+                               mJSAttributes))
       return NS_ERROR_OUT_OF_MEMORY;
   }
   return NS_OK;
 }
 
 nsresult 
 nsXBLProtoImplProperty::CompileMember(nsIScriptContext* aContext, const nsCString& aClassStr,
                                       JSObject* aClassObject)
--- a/content/xbl/test/test_bug821850.xhtml
+++ b/content/xbl/test/test_bug821850.xhtml
@@ -124,75 +124,75 @@ https://bugzilla.mozilla.org/show_bug.cg
     //
     // Try sticking a bunch of stuff on the prototype object.
     //
 
     var proto = bound.__proto__;
     proto.someExpando = 201;
     is(bound.someExpando, 201, "Can stick non-XBL properties on the proto");
 
-    function checkTamperProof(obj, propName, desc) {
+    // Previously, this code checked that content couldn't tamper with its XBL
+    // prototype. But we decided to allow this to reduce regression risk, so for
+    // now just check that this works.
+    function checkMayTamper(obj, propName, desc) {
       var accessor = !('value' in Object.getOwnPropertyDescriptor(obj, propName));
       if (!accessor)
-        checkRejected(function() { obj[propName] = function() {} }, desc + ": assign");
-      checkRejected(function() { Object.defineProperty(obj, propName, {value: 3}) }, desc + ": define with value");
-      checkRejected(function() { Object.defineProperty(obj, propName, {writable: true}) }, desc + ": make writable");
-      checkRejected(function() { Object.defineProperty(obj, propName, {configurable: true}) }, desc + ": make configurable");
-      checkRejected(function() { Object.defineProperty(obj, propName, {get: function() {}}) }, desc + ": define with getter");
-      checkRejected(function() { Object.defineProperty(obj, propName, {set: function() {}}) }, desc + ": define with setter");
+        checkAllowed(function() { obj[propName] = function() {} }, desc + ": assign");
+      checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true, value: 3}) }, desc + ": define with value");
+      checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true, writable: true}) }, desc + ": make writable");
+      checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true}) }, desc + ": make configurable");
+      checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true, get: function() {}}) }, desc + ": define with getter");
+      checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true, set: function() {}}) }, desc + ": define with setter");
 
       // Windows are implemented as proxies, and Proxy::delete_ doesn't currently
       // pass strict around. Work around it in the window.binding case by just
       // checking if delete returns false.
       // manually.
-      if (/testBinding/.exec(propName))
-        is(delete obj[propName], false, "deleting prototype from window fails");
-      else
-        checkRejected(function() { delete obj[propName]; }, desc + ": delete");
+      checkAllowed(function() { delete obj[propName]; }, desc + ": delete");
 
       if (!accessor)
-        checkRejected(function() { obj[propName] = function() {} }, desc + ": assign (again)");
+        checkAllowed(function() { obj[propName] = function() {} }, desc + ": assign (again)");
     }
 
-    // Make sure we can't modify XBL props on the prototype object, since Xrays
-    // use it to perform lookups.
-    checkTamperProof(proto, 'method', "XBL Proto Method");
-    checkTamperProof(proto, 'prop', "XBL Proto Prop");
-    checkTamperProof(proto, 'primitiveField', "XBL Field Accessor");
+    // Make sure content can do whatever it wants with the prototype.
+    checkMayTamper(proto, 'method', "XBL Proto Method");
+    checkMayTamper(proto, 'prop', "XBL Proto Prop");
+    checkMayTamper(proto, 'primitiveField', "XBL Field Accessor");
 
-    // Make sure that callers can't tamper with the prototype's definition on
-    // the window.
+    // As above, check that content can do what it wants with the prototype's
+    // property on the global.
     var protoName, count = 0;
     for (var k of Object.getOwnPropertyNames(window)) {
       if (!/testBinding/.exec(k))
         continue;
       count++;
       protoName = k;
     }
     is(count, 1, "Should be exactly one prototype object");
-    checkTamperProof(window, protoName, "XBL prototype prop on window");
+    checkMayTamper(window, protoName, "XBL prototype prop on window");
 
     // Tamper with the derived object. This doesn't affect the XBL scope thanks
     // to Xrays.
+    bound.method = function() { return "heh"; };
     Object.defineProperty(bound, 'method', {value: function() { return "hah" }});
     Object.defineProperty(bound, 'prop', {value: "redefined"});
     bound.primitiveField = 321;
 
     // Hand control back to the XBL scope by dispatching an event on the bound element.
     bound.dispatchEvent(new CustomEvent('testevent'));
   }
 
   function checkThrows(fn) {
     try { fn(); ok(false, "Should have thrown"); }
     catch (e) { ok(!!/denied|insecure/.exec(e), "Should have thrown security exception: " + e); }
   }
 
-  function checkRejected(fn, desc) {
-    try { fn(); ok(false, desc + ": Should have thrown"); }
-    catch (e) { ok(!!/configurable|read-only/.exec(e), desc + ": Threw correctly: " + e); }
+  function checkAllowed(fn, desc) {
+    try { fn(); ok(true, desc + ": Didn't throw"); }
+    catch (e) { ok(false, desc + ": Threw: " + e); }
   }
 
   function setup() {
     SpecialPowers.pushPrefEnv({set: [['dom.xbl_scopes', true]] }, continueSetup);
   }
 
   function continueSetup() {
     // When the bindings are applied, the constructor will be invoked and the
--- a/dom/apps/src/AppsUtils.jsm
+++ b/dom/apps/src/AppsUtils.jsm
@@ -230,19 +230,16 @@ this.AppsUtils = {
           }
           if (isAbsoluteURI(item[keys[0]])) {
             return false;
           }
         }
       }
     }
 
-    // Ensure that non-updatable fields contains the current app value
-    AppsUtils.normalizeManifest(aManifest, app);
-
     return true;
   },
 
   checkManifestContentType: function
      checkManifestContentType(aInstallOrigin, aWebappOrigin, aContentType) {
     let hadCharset = { };
     let charset = { };
     let contentType = NetUtil.parseContentType(aContentType, charset, hadCharset);
@@ -252,43 +249,34 @@ this.AppsUtils = {
     }
     return true;
   },
 
   /**
    * Method to apply modifications to webapp manifests file saved internally.
    * For now, only ensure app can't rename itself.
    */
-  normalizeManifest: function normalizeManifest(aManifest, aApp) {
-    // As normalizeManifest isn't only called on update but also
-    // during app install, we need to bail out on install.
-    if (aApp.installState != "installed" &&
-        aApp.installState != "updating") {
-      return;
-    }
-
-    let previousManifest = aApp.manifest;
-
+  ensureSameAppName: function ensureSameAppName(aOldManifest, aNewManifest, aApp) {
     // Ensure that app name can't be updated
-    aManifest.name = aApp.name;
+    aNewManifest.name = aApp.name;
 
     // Nor through localized names
-    if ('locales' in aManifest) {
-      let defaultName = new ManifestHelper(aManifest, aApp.origin).name;
-      for (let locale in aManifest.locales) {
-        let entry = aManifest.locales[locale];
+    if ('locales' in aNewManifest) {
+      let defaultName = new ManifestHelper(aOldManifest, aApp.origin).name;
+      for (let locale in aNewManifest.locales) {
+        let entry = aNewManifest.locales[locale];
         if (!entry.name) {
           continue;
         }
         // In case previous manifest didn't had a name,
         // we use the default app name
         let localizedName = defaultName;
-        if (previousManifest && 'locales' in previousManifest &&
-            locale in previousManifest.locales) {
-          localizedName = previousManifest.locales[locale].name;
+        if (aOldManifest && 'locales' in aOldManifest &&
+            locale in aOldManifest.locales) {
+          localizedName = aOldManifest.locales[locale].name;
         }
         entry.name = localizedName;
       }
     }
   },
 
   /**
    * Determines whether the manifest allows installs for the given origin.
--- a/dom/apps/src/Webapps.js
+++ b/dom/apps/src/Webapps.js
@@ -40,16 +40,18 @@ WebappsRegistry.prototype = {
       return
     let req = this.getRequest(msg.requestID);
     if (!req)
       return;
     let app = msg.app;
     switch (aMessage.name) {
       case "Webapps:Install:Return:OK":
         Services.DOMRequest.fireSuccess(req, createApplicationObject(this._window, app));
+        cpmm.sendAsyncMessage("Webapps:Install:Return:Ack",
+                              { manifestURL : app.manifestURL });
         break;
       case "Webapps:Install:Return:KO":
         Services.DOMRequest.fireError(req, msg.error || "DENIED");
         break;
       case "Webapps:GetSelf:Return:OK":
         if (msg.apps.length) {
           app = msg.apps[0];
           Services.DOMRequest.fireSuccess(req, createApplicationObject(this._window, app));
@@ -386,16 +388,17 @@ WebappsApplication.prototype = {
     this._ondownloadavailable = null;
     this._ondownloadapplied = null;
 
     this._downloadError = null;
 
     this.initHelper(aWindow, ["Webapps:OfflineCache",
                               "Webapps:CheckForUpdate:Return:OK",
                               "Webapps:CheckForUpdate:Return:KO",
+                              "Webapps:Launch:Return:KO",
                               "Webapps:PackageEvent"]);
 
     cpmm.sendAsyncMessage("Webapps:RegisterForMessages",
                           ["Webapps:OfflineCache",
                            "Webapps:PackageEvent",
                            "Webapps:CheckForUpdate:Return:OK"]);
   },
 
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -75,16 +75,17 @@ this.DOMApplicationRegistry = {
                      "Webapps:GetSelf", "Webapps:CheckInstalled",
                      "Webapps:GetInstalled", "Webapps:GetNotInstalled",
                      "Webapps:Launch", "Webapps:GetAll",
                      "Webapps:InstallPackage",
                      "Webapps:GetList", "Webapps:RegisterForMessages",
                      "Webapps:UnregisterForMessages",
                      "Webapps:CancelDownload", "Webapps:CheckForUpdate",
                      "Webapps:Download", "Webapps:ApplyDownload",
+                     "Webapps:Install:Return:Ack",
                      "child-process-shutdown"];
 
     this.frameMessages = ["Webapps:ClearBrowserData"];
 
     this.messages.forEach((function(msgName) {
       ppmm.addMessageListener(msgName, this);
     }).bind(this));
 
@@ -848,16 +849,19 @@ this.DOMApplicationRegistry = {
         this.checkForUpdate(msg, mm);
         break;
       case "Webapps:ApplyDownload":
         this.applyDownload(msg.manifestURL);
         break;
       case "Activities:Register:OK":
         this.notifyAppsRegistryReady();
         break;
+      case "Webapps:Install:Return:Ack":
+        this.onInstallSuccessAck(msg.manifestURL);
+        break;
     }
   },
 
   getAppInfo: function getAppInfo(aAppId) {
     if (!this.webapps[aAppId]) {
       debug("No webapp for " + aAppId);
       return null;
     }
@@ -1473,30 +1477,18 @@ this.DOMApplicationRegistry = {
         debug("onlyCheckAppCache - launch updateSvc.checkForUpdate for " +
               helper.fullAppcachePath());
         updateSvc.checkForUpdate(Services.io.newURI(helper.fullAppcachePath(), null, null),
                                  app.localId, false, updateObserver);
       });
       return;
     }
 
-    // Try to download a new manifest.
-    let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
-                .createInstance(Ci.nsIXMLHttpRequest);
-    xhr.open("GET", aData.manifestURL, true);
-    xhr.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
-    xhr.responseType = "json";
-    if (app.etag) {
-      debug("adding manifest etag:" + app.etag);
-      xhr.setRequestHeader("If-None-Match", app.etag);
-    }
-    xhr.channel.notificationCallbacks =
-      this.createLoadContext(app.installerAppId, app.installerIsBrowser);
-
-    xhr.addEventListener("load", (function() {
+    // On xhr load request event
+    function onload(xhr, oldManifest) {
       debug("Got http status=" + xhr.status + " for " + aData.manifestURL);
       let oldHash = app.manifestHash;
       let isPackage = app.origin.startsWith("app://");
 
       if (xhr.status == 200) {
         let manifest = xhr.response;
         if (manifest == null) {
           sendError("MANIFEST_PARSE_ERROR");
@@ -1505,16 +1497,18 @@ this.DOMApplicationRegistry = {
 
         if (!AppsUtils.checkManifest(manifest, app)) {
           sendError("INVALID_MANIFEST");
           return;
         } else if (!AppsUtils.checkInstallAllowed(manifest, app.installOrigin)) {
           sendError("INSTALL_FROM_DENIED");
           return;
         } else {
+          AppsUtils.ensureSameAppName(oldManifest, manifest, app);
+
           let hash = this.computeManifestHash(manifest);
           debug("Manifest hash = " + hash);
           if (isPackage) {
             if (!app.staged) {
               app.staged = { };
             }
             app.staged.manifestHash = hash;
             app.staged.etag = xhr.getResponseHeader("Etag");
@@ -1534,22 +1528,20 @@ this.DOMApplicationRegistry = {
                                                   : "downloadapplied";
               aData.app = {
                 lastCheckedUpdate: app.lastCheckedUpdate
               }
               aMm.sendAsyncMessage("Webapps:CheckForUpdate:Return:OK", aData);
               this._saveApps();
             }
           } else {
-            this._readManifests([{ id: id }], (function(aResult) {
-              // Update only the appcache if the manifest has not changed
-              // based on the hash value.
-              updateHostedApp.call(this, aResult[0].manifest,
-                                   oldHash == hash ? null : manifest);
-            }).bind(this));
+            // Update only the appcache if the manifest has not changed
+            // based on the hash value.
+            updateHostedApp.call(this, oldManifest,
+                                 oldHash == hash ? null : manifest);
           }
         }
       } else if (xhr.status == 304) {
         // The manifest has not changed.
         if (isPackage) {
           // If the app is a packaged app, we just send a 'downloadapplied'
           // or downloadavailable event.
           app.lastCheckedUpdate = Date.now();
@@ -1558,31 +1550,50 @@ this.DOMApplicationRegistry = {
           aData.app = {
             lastCheckedUpdate: app.lastCheckedUpdate
           }
           aMm.sendAsyncMessage("Webapps:CheckForUpdate:Return:OK", aData);
           this._saveApps();
         } else {
           // For hosted apps, even if the manifest has not changed, we check
           // for offline cache updates.
-          this._readManifests([{ id: id }], (function(aResult) {
-            updateHostedApp.call(this, aResult[0].manifest, null);
-          }).bind(this));
+          updateHostedApp.call(this, oldManifest, null);
         }
       } else {
         sendError("MANIFEST_URL_ERROR");
       }
-    }).bind(this), false);
-
-    xhr.addEventListener("error", (function() {
-      sendError("NETWORK_ERROR");
-    }).bind(this), false);
-
-    debug("Checking manifest at " + aData.manifestURL);
-    xhr.send(null);
+    }
+
+    // Try to download a new manifest.
+    function doRequest(oldManifest) {
+      let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
+                  .createInstance(Ci.nsIXMLHttpRequest);
+      xhr.open("GET", aData.manifestURL, true);
+      xhr.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
+      xhr.responseType = "json";
+      if (app.etag) {
+        debug("adding manifest etag:" + app.etag);
+        xhr.setRequestHeader("If-None-Match", app.etag);
+      }
+      xhr.channel.notificationCallbacks =
+        this.createLoadContext(app.installerAppId, app.installerIsBrowser);
+
+      xhr.addEventListener("load", onload.bind(this, xhr, oldManifest), false);
+      xhr.addEventListener("error", (function() {
+        sendError("NETWORK_ERROR");
+      }).bind(this), false);
+
+      debug("Checking manifest at " + aData.manifestURL);
+      xhr.send(null);
+    }
+
+    // Read the current app manifest file
+    this._readManifests([{ id: id }], (function(aResult) {
+      doRequest.call(this, aResult[0].manifest);
+    }).bind(this));
   },
 
   // Creates a nsILoadContext object with a given appId and isBrowser flag.
   createLoadContext: function createLoadContext(aAppId, aIsBrowser) {
     return {
        associatedWindow: null,
        topWindow : null,
        appId: aAppId,
@@ -1759,16 +1770,33 @@ this.DOMApplicationRegistry = {
       try {
         dir.remove(true);
       } catch(e) {
       }
     }
     aData.mm.sendAsyncMessage("Webapps:Install:Return:KO", aData);
   },
 
+  // This function is called after we called the onsuccess callback on the
+  // content side. This let the webpage the opportunity to set event handlers
+  // on the app before we start firing progress events.
+  queuedDownload: {},
+
+  onInstallSuccessAck: function onInstallSuccessAck(aManifestURL) {
+    let download = this.queuedDownload[aManifestURL];
+    if (!download) {
+      return;
+    }
+    this.startOfflineCacheDownload(download.manifest,
+                                   download.app,
+                                   download.profileDir,
+                                   download.offlineCacheObserver);
+    delete this.queuedDownload[aManifestURL];
+  },
+
   confirmInstall: function(aData, aFromSync, aProfileDir, aOfflineCacheObserver) {
     let isReinstall = false;
     let app = aData.app;
     app.removable = true;
 
     let origin = Services.io.newURI(app.origin, null, null);
     let manifestURL = origin.resolve(app.manifestURL);
 
@@ -1861,16 +1889,23 @@ this.DOMApplicationRegistry = {
       }).bind(this));
     }
 
     ["installState", "downloadAvailable",
      "downloading", "downloadSize", "readyToApplyDownload"].forEach(function(aProp) {
       aData.app[aProp] = appObject[aProp];
      });
 
+    this.queuedDownload[app.manifestURL] = {
+      manifest: manifest,
+      app: appObject,
+      profileDir: aProfileDir,
+      offlineCacheObserver: aOfflineCacheObserver
+    }
+
     if (!aFromSync)
       this._saveApps((function() {
         this.broadcastMessage("Webapps:Install:Return:OK", aData);
         Services.obs.notifyObservers(this, "webapps-sync-install", appNote);
         this.broadcastMessage("Webapps:AddApp", { id: id, app: appObject });
       }).bind(this));
 
     if (!aData.isPackage) {
@@ -1879,17 +1914,16 @@ this.DOMApplicationRegistry = {
       this._registerSystemMessages(app.manifest, app);
       this._registerActivities(app.manifest, app, true);
 #else
       // Nothing else to do but notifying we're ready.
       this.notifyAppsRegistryReady();
 #endif
     }
 
-    this.startOfflineCacheDownload(manifest, appObject, aProfileDir, aOfflineCacheObserver);
     if (manifest.package_path) {
       // origin for install apps is meaningless here, since it's app:// and this
       // can't be used to resolve package paths.
       manifest = new ManifestHelper(jsonManifest, app.manifestURL);
       this.downloadPackage(manifest, appObject, false, function(aId, aManifest) {
         // Success! Move the zip out of TmpD.
         let app = DOMApplicationRegistry.webapps[id];
         let zipFile = FileUtils.getFile("TmpD", ["webapps", aId, "application.zip"], true);
@@ -2273,23 +2307,24 @@ this.DOMApplicationRegistry = {
                 // Obtain a converter to read from a UTF-8 encoded input stream.
                 let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
                                   .createInstance(Ci.nsIScriptableUnicodeConverter);
                 converter.charset = "UTF-8";
 
                 let manifest = JSON.parse(converter.ConvertToUnicode(NetUtil.readInputStreamToString(istream,
                                                                      istream.available()) || ""));
 
-                // Call checkManifest before compareManifests, as checkManifest
-                // will normalize some attributes that has already been normalized
-                // for aManifest during checkForUpdate.
                 if (!AppsUtils.checkManifest(manifest, app)) {
                   throw "INVALID_MANIFEST";
                 }
 
+                // Call ensureSameAppName before compareManifests, as `manifest`,
+                // has been normalized to avoid app rename.
+                AppsUtils.ensureSameAppName(aManifest._manifest, manifest, app);
+
                 if (!AppsUtils.compareManifests(manifest,
                                                 aManifest._manifest)) {
                   throw "MANIFEST_MISMATCH";
                 }
 
                 if (!AppsUtils.checkInstallAllowed(manifest, aApp.installOrigin)) {
                   throw "INSTALL_FROM_DENIED";
                 }
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -523,17 +523,17 @@ nsPIDOMWindow::~nsPIDOMWindow() {}
 
 //*****************************************************************************
 // nsOuterWindowProxy: Outer Window Proxy
 //*****************************************************************************
 
 class nsOuterWindowProxy : public js::Wrapper
 {
 public:
-  nsOuterWindowProxy() : js::Wrapper(0) { setSafeToUnwrap(false); }
+  nsOuterWindowProxy() : js::Wrapper(0) { }
 
   virtual bool isOuterWindow() {
     return true;
   }
   virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE;
   virtual void finalize(JSFreeOp *fop, JSObject *proxy) MOZ_OVERRIDE;
 
   // Fundamental traps
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -596,16 +596,20 @@ DOMInterfaces = {
 'Location': {
     # NOTE: Before you turn on codegen for Location, make sure all the
     # Unforgeable stuff is dealt with.
     'nativeType': 'nsIDOMLocation',
     'skipGen': True,
     'register': False
 },
 
+'MediaError': {
+    'hasInstanceInterface': 'nsIDOMMediaError',
+},
+
 'MediaStream': [{
     'nativeType': 'nsIDOMMediaStream',
 },
 {
     'nativeType': 'JSObject',
     'workers': True,
     'skipGen': True
 }],
--- a/dom/bluetooth/linux/BluetoothDBusService.cpp
+++ b/dom/bluetooth/linux/BluetoothDBusService.cpp
@@ -139,16 +139,18 @@ static const char* sBluetoothDBusSignals
  * DBus Connection held for the BluetoothCommandThread to use. Should never be
  * used by any other thread.
  *
  */
 static nsAutoPtr<RawDBusConnection> gThreadConnection;
 static nsDataHashtable<nsStringHashKey, DBusMessage* > sPairingReqTable;
 static nsDataHashtable<nsStringHashKey, DBusMessage* > sAuthorizeReqTable;
 static PRInt32 sIsPairing = 0;
+static nsString sAdapterPath;
+
 typedef void (*UnpackFunc)(DBusMessage*, DBusError*, BluetoothValue&, nsAString&);
 
 class RemoveDeviceTask : public nsRunnable {
 public:
   RemoveDeviceTask(const nsAString& aAdapterPath,
                    const char* aDeviceObjectPath,
                    BluetoothReplyRunnable* aRunnable)
     : mAdapterPath(aAdapterPath)
@@ -775,16 +777,32 @@ BluetoothDBusService::AddReservedService
     BT_WARNING("Null DBus message. Couldn't extract handles.");
     return false;
   }
 
   ExtractHandles(reply, aServiceHandlesContainer);
   return true;
 }
 
+void
+BluetoothDBusService::DisconnectAllAcls(const nsAString& aAdapterPath)
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  DBusMessage* reply =
+    dbus_func_args(gThreadConnection->GetConnection(),
+                   NS_ConvertUTF16toUTF8(aAdapterPath).get(),
+                   DBUS_ADAPTER_IFACE, "DisconnectAllConnections",
+                   DBUS_TYPE_INVALID);
+
+  if (reply) {
+    dbus_message_unref(reply);
+  }
+}
+
 class PrepareProfileManagersRunnable : public nsRunnable
 {
 public:
   NS_IMETHOD
   Run()
   {
     BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
     if (!hfp || !hfp->Listen()) {
@@ -1648,17 +1666,20 @@ UnrefDBusMessages(const nsAString& key, 
 }
 
 nsresult
 BluetoothDBusService::StopInternal()
 {
   // This could block. It should never be run on the main thread.
   MOZ_ASSERT(!NS_IsMainThread());
 
-  NS_DispatchToMainThread(new ShutdownProfileManagersRunnable());
+  // If Bluetooth is turned off while connections exist, in order not to only
+  // disconnect with profile connections with low level ACL connections alive,
+  // we disconnect ACLs directly instead of closing each socket.
+  DisconnectAllAcls(sAdapterPath);
 
   if (!mConnection) {
     StopDBus();
     return NS_OK;
   }
 
   DBusError err;
   dbus_error_init(&err);
@@ -2404,16 +2425,19 @@ BluetoothDBusService::PrepareAdapterInte
 {
   NS_ASSERTION(NS_IsMainThread(), "Must be called from main thread!");
 
   if (!mConnection || !gThreadConnection) {
     NS_ERROR("Bluetooth service not started yet!");
     return NS_ERROR_FAILURE;
   }
 
+  // Keep the adapter path for further use
+  sAdapterPath = aPath;
+
   nsRefPtr<nsRunnable> func(new PrepareAdapterRunnable(aPath));
   if (NS_FAILED(mBluetoothCommandThread->Dispatch(func, NS_DISPATCH_NORMAL))) {
     NS_WARNING("Cannot dispatch task!");
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
--- a/dom/bluetooth/linux/BluetoothDBusService.h
+++ b/dom/bluetooth/linux/BluetoothDBusService.h
@@ -162,13 +162,15 @@ private:
                                   void (*aCB)(DBusMessage *, void *),
                                   BluetoothReplyRunnable* aRunnable);
   nsresult SendDiscoveryMessage(const nsAString& aAdapterPath,
                                 const char* aMessageName,
                                 BluetoothReplyRunnable* aRunnable);
   nsresult SendSetPropertyMessage(const nsString& aPath, const char* aInterface,
                                   const BluetoothNamedValue& aValue,
                                   BluetoothReplyRunnable* aRunnable);
+
+  void DisconnectAllAcls(const nsAString& aAdapterPath);
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif
--- a/dom/browser-element/mochitest/browserElement_Auth.js
+++ b/dom/browser-element/mochitest/browserElement_Auth.js
@@ -130,31 +130,37 @@ function testAuthJarInterfere(e) {
   // Set some auth data that should overwrite the successful stored details.
   var principal = secMan.getAppCodebasePrincipal(uri, secMan.NO_APP_ID, true);
   authMgr.setAuthIdentity('http', 'test', -1, 'basic', 'http_realm',
                           'tests/dom/browser-element/mochitest/file_http_401_response.sjs',
                           '', 'httpuser', 'wrongpass', false, principal);
 
   // Will authenticate with correct password, prompt should not be
   // called again.
-  iframe.addEventListener("mozbrowserusernameandpasswordrequired", testFinish);
+  var gotusernamepasswordrequired = false;
+  function onUserNameAndPasswordRequired() {
+      gotusernamepasswordrequired = true;
+  }
+  iframe.addEventListener("mozbrowserusernameandpasswordrequired",
+                          onUserNameAndPasswordRequired);
   iframe.addEventListener("mozbrowsertitlechange", function onTitleChange(e) {
     iframe.removeEventListener("mozbrowsertitlechange", onTitleChange);
-    iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFinish);
-    SimpleTest.execute(testFail);
+    iframe.removeEventListener("mozbrowserusernameandpasswordrequired",
+                               onUserNameAndPasswordRequired);
+    ok(gotusernamepasswordrequired,
+       "Should have dispatched mozbrowserusernameandpasswordrequired event");
+    testFinish();
   });
 
   // Once more with feeling. Ensure that our new auth data interferes with this mozbrowser's
   // auth data.
   iframe.src = 'http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs';
 }
 
 function testFinish() {
-  iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFinish);
-
   // Clear login information stored in password manager.
   var authMgr = SpecialPowers.Cc['@mozilla.org/network/http-auth-manager;1']
     .getService(SpecialPowers.Ci.nsIHttpAuthManager);
   authMgr.clearAll();
 
   var pwmgr = SpecialPowers.Cc["@mozilla.org/login-manager;1"]
     .getService(SpecialPowers.Ci.nsILoginManager);
   pwmgr.removeAllLogins();
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -346,16 +346,19 @@ private:
 };
 
 class MediaManager MOZ_FINAL : public nsIMediaManagerService,
                                public nsIObserver
 {
 public:
   static already_AddRefed<MediaManager> GetInstance();
 
+  // NOTE: never Dispatch(....,NS_DISPATCH_SYNC) to the MediaManager
+  // thread from the MainThread, as we NS_DISPATCH_SYNC to MainThread
+  // from MediaManager thread.
   static MediaManager* Get() {
     if (!sSingleton) {
       sSingleton = new MediaManager();
 
       NS_NewThread(getter_AddRefs(sSingleton->mMediaThread));
       MM_LOG(("New Media thread for gum"));
 
       NS_ASSERTION(NS_IsMainThread(), "Only create MediaManager on main thread");
--- a/dom/media/tests/mochitest/Makefile.in
+++ b/dom/media/tests/mochitest/Makefile.in
@@ -27,16 +27,17 @@ MOCHITEST_FILES = \
   test_getUserMedia_stopVideoAudioStream.html \
   test_peerConnection_basicAudio.html \
   test_peerConnection_basicAudioVideo.html \
   test_peerConnection_basicAudioVideoCombined.html \
   test_peerConnection_basicVideo.html \
   test_peerConnection_bug827843.html \
   test_peerConnection_bug825703.html \
   test_peerConnection_bug834153.html \
+  test_peerConnection_bug840344.html \
   head.js \
   mediaStreamPlayback.js \
   pc.js \
   $(NULL)
 
 # The following tests are leaking and cannot be run by default yet
 ifdef MOZ_WEBRTC_LEAKING_TESTS
 MOCHITEST_FILES += \
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_bug840344.html
@@ -0,0 +1,129 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=840344
+-->
+<head>
+  <meta charset="utf-8">
+    <title>Bug 840344: Assertion failure</title>
+    <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+    <script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
+    <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
+    </script>
+    <script type="application/javascript" src="head.js"></script>
+  </meta>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=840344">
+Bug 840344</a>
+<p id="display"></p>
+<pre id="test">
+
+<script class="testbody" type="application/javascript">
+
+  runTest(function () {
+    var answerCount = 0;
+    var setLocalCount = 0;
+
+    // SDP to stand in for an offer coming from a (theoretical) remote endpoint
+    var offer = { sdp: "v=0\r\n"+
+          "o=Mozilla-SIPUA 23597 0 IN IP4 0.0.0.0\r\n"+
+          "s=SIP Call\r\n"+
+          "t=0 0\r\n"+
+          "a=ice-ufrag:f5fda439\r\n"+
+          "a=ice-pwd:d0df8e2904bdbd29587966e797655970\r\n"+
+          "a=fingerprint:sha-256 DF:69:78:20:8D:2E:08:CE:49:82:A3:11:79:1D:BF:"+
+            "B5:49:49:2D:32:82:2F:0D:88:84:A7:C6:63:23:63:A9:0F\r\n"+
+          "m=audio 52757 RTP/SAVPF 109 0 8 101\r\n"+
+          "c=IN IP4 192.168.129.33\r\n"+
+          "a=rtpmap:109 opus/48000/2\r\n"+
+          "a=ptime:20\r\n"+
+          "a=rtpmap:0 PCMU/8000\r\n"+
+          "a=rtpmap:8 PCMA/8000\r\n"+
+          "a=rtpmap:101 telephone-event/8000\r\n"+
+          "a=fmtp:101 0-15\r\n"+
+          "a=sendrecv\r\n"+
+          "a=candidate:0 1 UDP 2113601791 192.168.129.33 52757 typ host\r\n"+
+          "a=candidate:0 2 UDP 2113601790 192.168.129.33 59738 typ host\r\n"+
+          "m=video 63901 RTP/SAVPF 120\r\n"+
+          "c=IN IP4 192.168.129.33\r\n"+
+          "a=rtpmap:120 VP8/90000\r\n"+
+          "a=sendrecv\r\n"+
+          "a=candidate:0 1 UDP 2113601791 192.168.129.33 63901 typ host\r\n"+
+          "a=candidate:0 2 UDP 2113601790 192.168.129.33 54165 typ host\r\n"+
+          "m=application 65080 SCTP/DTLS 5000 \r\n"+
+          "c=IN IP4 192.168.129.33\r\n"+
+          "a=fmtp:5000 protocol=webrtc-datachannel;streams=16\r\n"+
+          "a=sendrecv\r\n"+
+          "a=candidate:0 1 UDP 2113601791 192.168.129.33 65080 typ host\r\n"+
+          "a=candidate:0 2 UDP 2113601790 192.168.129.33 62658 typ host\r\n",
+          type: "offer" };
+
+    info("Step 0: Instantiate a Peer Connection");
+    var pc = new mozRTCPeerConnection();
+
+    // First: Kick off the chain of events by asking for a mic and camera
+    var start = function() {
+      info("Step 1: Get User Media for Audio and Video");
+      getUserMedia({audio:true, video:true},
+                   gumSuccess, unexpectedCallbackAndFinish);
+    };
+
+    // Second: set the remote description
+    var gumSuccess = function(x) {
+      info("Step 2a: Add stream");
+      pc.addStream(x);
+      info("Step 2b: Create Session Description");
+      var osd = new mozRTCSessionDescription(offer);
+      info("Step 2c: Set Remote Description");
+      pc.setRemoteDescription(osd,
+                              setRemoteSuccess,
+                              unexpectedCallbackAndFinish);
+    };
+
+    // Third: Attempt to create an answer. Twice.
+    var setRemoteSuccess = function() {
+      info("Step 3a: Create answer #1");
+      pc.createAnswer(answerSuccess, unexpectedCallbackAndFinish);
+      info("Step 3b: Create answer #2");
+      pc.createAnswer(answerSuccess, unexpectedCallbackAndFinish);
+    };
+
+    // Fourth: Count the answers and push them into the local description
+    var answerSuccess = function(answer) {
+      answerCount++;
+      ok (answerCount < 3, "Answer count is less than three.")
+      info("got answer #" + answerCount);
+      is(answer.type,'answer',"Answer is of type 'answer'");
+      ok(answer.sdp.length > 10, "Answer has length " + answer.sdp.length);
+      info("Step 4: Set local description");
+      pc.setLocalDescription(answer,
+                             setLocalSuccess,
+                             unexpectedCallbackAndFinish);
+    };
+
+    // Fifth: Once we have two successful rounds through here, we're done.
+    var setLocalSuccess = function(x) {
+      setLocalCount++;
+      info("Set local description #" + setLocalCount);
+      // Then shalt thou count to two, no more, no less. Two shall be the
+      // number thou shalt count, and the number of the counting shall be
+      // two. Three shalt thou not count, neither count thou one, excepting
+      // that thou then proceed to two. Four is right out. Once the number two,
+      // being the second number, be reached, then thou shalt declare success.
+      ok (setLocalCount < 3, "Set local count is less than three.")
+      if (setLocalCount === 2) {
+        is (answerCount, 2, "Answer count is 2.")
+        info("Step 5: Finished");
+        SimpleTest.finish();
+      }
+    };
+
+    start();
+
+  }, true);
+
+</script>
+</pre>
+</body>
+</html>
--- a/dom/phonenumberutils/PhoneNumberUtils.jsm
+++ b/dom/phonenumberutils/PhoneNumberUtils.jsm
@@ -41,18 +41,18 @@ this.PhoneNumberUtils = {
     }
 
     // Get SIM mcc
     if (!mcc) {
       mcc = ril.iccInfo.mcc;
     }
 
     // Get previous mcc
-    if (!mcc && ril.voiceConnectionInfo && ril.voiceConnectionInfo.network) {
-      mcc = ril.voiceConnectionInfo.network.previousMcc;
+    if (!mcc && ril.voiceConnectionInfo) {
+      mcc = ril.voiceConnectionInfo.lastKnownMcc;
     }
 
     // Set to default mcc
     if (!mcc) {
       mcc = this._mcc;
     }
 #else
     mcc = this._mcc;
--- a/dom/plugins/test/mochitest/Makefile.in
+++ b/dom/plugins/test/mochitest/Makefile.in
@@ -60,16 +60,17 @@ MOCHITEST_FILES = \
   test_GCrace.html \
   test_propertyAndMethod.html \
   test_bug539565-1.html \
   test_bug539565-2.html \
   test_bug771202.html \
   file_bug771202.html \
   test_bug777098.html \
   test_bug751809.html \
+  test_bug813906.html \
   test_enumerate.html \
   test_npruntime_construct.html \
   307-xo-redirect.sjs \
   test_redirect_handling.html \
   test_zero_opacity.html \
   test_NPPVpluginWantsAllNetworkStreams.html \
   test_npruntime_npnsetexception.html \
   test_NPNVdocumentOrigin.html \
new file mode 100644
--- /dev/null
+++ b/dom/plugins/test/mochitest/test_bug813906.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<html>
+<head>
+  <title>Test for Bug 813906</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+  <meta http-equiv="content-type" content="text/html; charset=utf-8">
+  <base href="chrome://browser/content/">
+</head>
+<body>
+
+<script type="application/javascript">
+function f() {
+  document.getElementsByTagName("base")[0].href = "http://www.safe.com/";
+}
+</script>
+
+<svg>
+  <symbol id="a">
+    <foreignObject>
+      <object bugmode="813906" frame="frame1"></object>
+    </foreignObject>
+  </symbol>
+  <use />
+</svg>
+
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+var frameLoadCount = 0;
+function frameLoaded() {
+  frameLoadCount++;
+  if (frameLoadCount == 1) {
+    document.getElementsByTagName("object")[0].type = "application/x-test";
+    document.getElementsByTagName("use")[0].setAttributeNS("http://www.w3.org/1999/xlink", "href", location.href + "#a");
+  } else if (frameLoadCount == 2) {
+    isnot(SpecialPowers.wrap(window.frame1).location.href.indexOf('chrome://'),
+          0, 'plugin shouldnt be able to cause navigation to chrome URLs');
+    SimpleTest.finish();
+  }
+}
+</script>
+
+<iframe name="frame1" onload="frameLoaded()"></iframe>
+</body>
+</html>
--- a/dom/plugins/test/testplugin/nptest.cpp
+++ b/dom/plugins/test/testplugin/nptest.cpp
@@ -52,16 +52,18 @@
 #include <float.h>
 #include <windows.h>
 #define getpid _getpid
 #else
 #include <unistd.h>
 #include <pthread.h>
 #endif
 
+#include "mozilla/NullPtr.h"
+
 using namespace std;
 
 #define PLUGIN_VERSION     "1.0.0.0"
 #define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0]))
 #define STATIC_ASSERT(condition)                                \
     extern void np_static_assert(int arg[(condition) ? 1 : -1])
 
 extern const char *sPluginName;
@@ -578,16 +580,42 @@ drawAsyncBitmapColor(InstanceData* insta
   }
 
   NPN_SetCurrentAsyncSurface(npp, instanceData->backBuffer, NULL);
   NPAsyncSurface *oldFront = instanceData->frontBuffer;
   instanceData->frontBuffer = instanceData->backBuffer;
   instanceData->backBuffer = oldFront;
 }
 
+static bool bug813906(NPP npp, const char* const function, const char* const url, const char* const frame)
+{
+  NPObject *windowObj = nullptr;
+  NPError err = NPN_GetValue(npp, NPNVWindowNPObject, &windowObj);
+  if (err != NPERR_NO_ERROR) {
+    return false;
+  }
+
+  NPVariant result;
+  bool res = NPN_Invoke(npp, windowObj, NPN_GetStringIdentifier(function), nullptr, 0, &result);
+  NPN_ReleaseObject(windowObj);
+  if (!res) {
+    return false;
+  }
+
+  NPN_ReleaseVariantValue(&result);
+
+  err = NPN_GetURL(npp, url, frame);
+  if (err != NPERR_NO_ERROR) {
+    err = NPN_GetURL(npp, "about:blank", frame);
+    return false;
+  }
+
+  return true;
+}
+
 //
 // function signatures
 //
 
 NPObject* scriptableAllocate(NPP npp, NPClass* aClass);
 void scriptableDeallocate(NPObject* npobj);
 void scriptableInvalidate(NPObject* npobj);
 bool scriptableHasMethod(NPObject* npobj, NPIdentifier name);
@@ -789,16 +817,17 @@ NPP_New(NPMIMEType pluginType, NPP insta
   instanceData->focusEventCount = 0;
   instanceData->eventModel = 0;
   instanceData->closeStream = false;
   instanceData->wantsAllStreams = false;
   instanceData->asyncDrawing = AD_NONE;
   instanceData->frontBuffer = NULL;
   instanceData->backBuffer = NULL;
   instanceData->mouseUpEventCount = 0;
+  instanceData->bugMode = -1;
   instance->pdata = instanceData;
 
   TestNPObject* scriptableObject = (TestNPObject*)NPN_CreateObject(instance, &sNPClass);
   if (!scriptableObject) {
     printf("NPN_CreateObject failed to create an object, can't create a plugin instance\n");
     free(instanceData);
     return NPERR_GENERIC_ERROR;
   }
@@ -919,16 +948,19 @@ NPP_New(NPMIMEType pluginType, NPP insta
     // window gets destroyed).
     if (strcmp(argn[i], "cleanupwidget") == 0 &&
         strcmp(argv[i], "false") == 0) {
       instanceData->cleanupWidget = false;
     }
     if (!strcmp(argn[i], "closestream")) {
       instanceData->closeStream = true;
     }
+    if (strcmp(argn[i], "bugmode") == 0) {
+      instanceData->bugMode = atoi(argv[i]);
+    }
   }
 
   if (!browserSupportsWindowless || !pluginSupportsWindowlessMode()) {
     requestWindow = true;
   } else if (!pluginSupportsWindowMode()) {
     requestWindow = false;
   }
   if (requestWindow) {
@@ -1011,16 +1043,20 @@ NPP_New(NPMIMEType pluginType, NPP insta
   else if (instanceData->testFunction == FUNCTION_NPP_GETURLNOTIFY) {
     NPError err = NPN_GetURLNotify(instance, instanceData->testUrl.c_str(), 
                                    NULL, static_cast<void*>(&kNotifyData));
     if (err != NPERR_NO_ERROR) {
       instanceData->err << "NPN_GetURLNotify returned " << err;
     }
   }
 
+  if ((instanceData->bugMode == 813906) && instanceData->frame.length()) {
+    bug813906(instance, "f", "browser.xul", instanceData->frame.c_str());
+  }
+
   return NPERR_NO_ERROR;
 }
 
 NPError
 NPP_Destroy(NPP instance, NPSavedData** save)
 {
   printf("NPP_Destroy\n");
   InstanceData* instanceData = (InstanceData*)(instance->pdata);
--- a/dom/plugins/test/testplugin/nptest.h
+++ b/dom/plugins/test/testplugin/nptest.h
@@ -146,13 +146,14 @@ typedef struct InstanceData {
   int32_t eventModel;
   bool closeStream;
   std::string lastKeyText;
   bool wantsAllStreams;
   AsyncDrawing asyncDrawing;
   NPAsyncSurface *frontBuffer;
   NPAsyncSurface *backBuffer;
   int32_t mouseUpEventCount;
+  int32_t bugMode;
 } InstanceData;
 
 void notifyDidPaint(InstanceData* instanceData);
 
 #endif // nptest_h_
--- a/dom/tests/browser/browser_xhr_sandbox.js
+++ b/dom/tests/browser/browser_xhr_sandbox.js
@@ -34,16 +34,16 @@ function test() {
     let workerWindow = frame.contentWindow;
     workerWindow.addEventListener("message", function(evt) {
       is(evt.data.result, "ok", "check the sandbox code was happy");
       finish();
     }, true);
     let sandbox = new Cu.Sandbox(workerWindow);
     // inject some functions from the window into the sandbox.
     // postMessage so the async code in the sandbox can report a result.
-    sandbox.importFunction(workerWindow.postMessage, "postMessage");
+    sandbox.importFunction(workerWindow.postMessage.bind(workerWindow), "postMessage");
     sandbox.importFunction(workerWindow.XMLHttpRequest, "XMLHttpRequest");
     Cu.evalInSandbox(sandboxCode, sandbox, "1.8");
   }, true);
 
   let container = doc.body ? doc.body : doc.documentElement;
   container.appendChild(frame);
 }
new file mode 100644
--- /dev/null
+++ b/dom/webidl/MediaError.webidl
@@ -0,0 +1,22 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * The origin of this IDL file is
+ * http://www.whatwg.org/html/#mediaerror
+ *
+ *  Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
+ * Opera Software ASA. You are granted a license to use, reproduce
+ * and create derivative works of this document.
+ */
+
+interface MediaError {
+  const unsigned short MEDIA_ERR_ABORTED = 1;
+  const unsigned short MEDIA_ERR_NETWORK = 2;
+  const unsigned short MEDIA_ERR_DECODE = 3;
+  const unsigned short MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
+
+  [Constant]
+  readonly attribute unsigned short code;
+};
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -218,16 +218,17 @@ ifdef MOZ_AUDIO_CHANNEL_MANAGER
 webidl_files += \
   AudioChannelManager.webidl \
   $(NULL)
 endif
 
 ifdef MOZ_MEDIA
 webidl_files += \
   HTMLSourceElement.webidl \
+  MediaError.webidl \
   $(NULL)
 endif
 
 ifdef MOZ_WEBGL
 webidl_files += \
   WebGLRenderingContext.webidl \
   $(NULL)
 endif
--- a/editor/libeditor/base/nsEditor.cpp
+++ b/editor/libeditor/base/nsEditor.cpp
@@ -67,17 +67,16 @@
 #include "nsIDOMNodeList.h"             // for nsIDOMNodeList
 #include "nsIDOMRange.h"                // for nsIDOMRange
 #include "nsIDOMText.h"                 // for nsIDOMText
 #include "nsIDocument.h"                // for nsIDocument
 #include "nsIDocumentStateListener.h"   // for nsIDocumentStateListener
 #include "nsIEditActionListener.h"      // for nsIEditActionListener
 #include "nsIEditorObserver.h"          // for nsIEditorObserver
 #include "nsIEditorSpellCheck.h"        // for nsIEditorSpellCheck
-#include "nsIEnumerator.h"              // for nsIEnumerator, etc
 #include "nsIFrame.h"                   // for nsIFrame
 #include "nsIInlineSpellChecker.h"      // for nsIInlineSpellChecker, etc
 #include "nsIMEStateManager.h"          // for nsIMEStateManager
 #include "nsINameSpaceManager.h"        // for kNameSpaceID_None, etc
 #include "nsINode.h"                    // for nsINode, etc
 #include "nsIObserverService.h"         // for nsIObserverService
 #include "nsIPlaintextEditor.h"         // for nsIPlaintextEditor, etc
 #include "nsIPresShell.h"               // for nsIPresShell
@@ -3887,31 +3886,23 @@ nsEditor::GetStartNodeAndOffset(nsISelec
                                        nsIDOMNode **outStartNode,
                                        int32_t *outStartOffset)
 {
   NS_ENSURE_TRUE(outStartNode && outStartOffset && aSelection, NS_ERROR_NULL_POINTER);
 
   *outStartNode = nullptr;
   *outStartOffset = 0;
 
-  nsCOMPtr<nsISelectionPrivate>selPrivate(do_QueryInterface(aSelection));
-  nsCOMPtr<nsIEnumerator> enumerator;
-  nsresult result = selPrivate->GetEnumerator(getter_AddRefs(enumerator));
-  NS_ENSURE_SUCCESS(result, result);
-  NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
-
-  enumerator->First(); 
-  nsCOMPtr<nsISupports> currentItem;
-  result = enumerator->CurrentItem(getter_AddRefs(currentItem));
-  NS_ENSURE_SUCCESS(result, result);
-
-  nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
+  Selection* selection = static_cast<Selection*>(aSelection);
+  NS_ENSURE_TRUE(selection->GetRangeCount(), NS_ERROR_FAILURE);
+
+  nsRange* range = selection->GetRangeAt(0);
   NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
 
-  result = range->GetStartContainer(outStartNode);
+  nsresult result = range->GetStartContainer(outStartNode);
   NS_ENSURE_SUCCESS(result, result);
 
   result = range->GetStartOffset(outStartOffset);
   NS_ENSURE_SUCCESS(result, result);
 
   return NS_OK;
 }
 
@@ -3923,28 +3914,21 @@ nsresult
 nsEditor::GetEndNodeAndOffset(nsISelection *aSelection,
                                        nsIDOMNode **outEndNode,
                                        int32_t *outEndOffset)
 {
   NS_ENSURE_TRUE(outEndNode && outEndOffset, NS_ERROR_NULL_POINTER);
 
   *outEndNode = nullptr;
     
-  nsCOMPtr<nsISelectionPrivate>selPrivate(do_QueryInterface(aSelection));
-  nsCOMPtr<nsIEnumerator> enumerator;
-  nsresult result = selPrivate->GetEnumerator(getter_AddRefs(enumerator));
-  if (NS_FAILED(result) || !enumerator)
-    return NS_ERROR_FAILURE;
-    
-  enumerator->First(); 
-  nsCOMPtr<nsISupports> currentItem;
-  if (NS_FAILED(enumerator->CurrentItem(getter_AddRefs(currentItem))))
-    return NS_ERROR_FAILURE;
-
-  nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
+  Selection* selection = static_cast<Selection*>(aSelection);
+  NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(selection->GetRangeCount(), NS_ERROR_FAILURE);
+
+  nsRange* range = selection->GetRangeAt(0);
   NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
     
   if (NS_FAILED(range->GetEndContainer(outEndNode)))
     return NS_ERROR_FAILURE;
     
   if (NS_FAILED(range->GetEndOffset(outEndOffset)))
     return NS_ERROR_FAILURE;
     
--- a/editor/libeditor/html/nsHTMLEditRules.cpp
+++ b/editor/libeditor/html/nsHTMLEditRules.cpp
@@ -33,17 +33,16 @@
 #include "nsIContentIterator.h"
 #include "nsID.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMText.h"
-#include "nsIEnumerator.h"
 #include "nsIHTMLAbsPosEditor.h"
 #include "nsIHTMLDocument.h"
 #include "nsINode.h"
 #include "nsISelection.h"
 #include "nsISelectionPrivate.h"
 #include "nsLiteralString.h"
 #include "nsPlaintextEditor.h"
 #include "nsRange.h"
@@ -2301,32 +2300,23 @@ nsHTMLEditRules::WillDeleteSelection(Sel
             // fix up selection
             res = aSelection->Collapse(selNode,selOffset);
             return res;
           }
         }
         
         // else blocks not same type, or not siblings.  Delete everything except
         // table elements.
-        nsCOMPtr<nsIEnumerator> enumerator;
-        res = aSelection->GetEnumerator(getter_AddRefs(enumerator));
-        NS_ENSURE_SUCCESS(res, res);
-        NS_ENSURE_TRUE(enumerator, NS_ERROR_UNEXPECTED);
-
         join = true;
 
-        for (enumerator->First(); NS_OK!=enumerator->IsDone(); enumerator->Next())
-        {
-          nsCOMPtr<nsISupports> currentItem;
-          res = enumerator->CurrentItem(getter_AddRefs(currentItem));
-          NS_ENSURE_SUCCESS(res, res);
-          NS_ENSURE_TRUE(currentItem, NS_ERROR_UNEXPECTED);
+        uint32_t rangeCount = aSelection->GetRangeCount();
+        for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
+          nsRefPtr<nsRange> range = aSelection->GetRangeAt(rangeIdx);
 
           // build a list of nodes in the range
-          nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
           nsCOMArray<nsIDOMNode> arrayOfNodes;
           nsTrivialFunctor functor;
           nsDOMSubtreeIterator iter;
           res = iter.Init(range);
           NS_ENSURE_SUCCESS(res, res);
           res = iter.AppendList(functor, arrayOfNodes);
           NS_ENSURE_SUCCESS(res, res);
       
@@ -5771,35 +5761,25 @@ nsHTMLEditRules::GetListActionNodes(nsCO
                                     bool aEntireList,
                                     bool aDontTouchContent)
 {
   nsresult res = NS_OK;
   
   nsCOMPtr<nsISelection>selection;
   res = mHTMLEditor->GetSelection(getter_AddRefs(selection));
   NS_ENSURE_SUCCESS(res, res);
-  nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
-  NS_ENSURE_TRUE(selPriv, NS_ERROR_FAILURE);
+  Selection* sel = static_cast<Selection*>(selection.get());
+  NS_ENSURE_TRUE(sel, NS_ERROR_FAILURE);
   // added this in so that ui code can ask to change an entire list, even if selection
   // is only in part of it.  used by list item dialog.
   if (aEntireList)
   {       
-    nsCOMPtr<nsIEnumerator> enumerator;
-    res = selPriv->GetEnumerator(getter_AddRefs(enumerator));
-    NS_ENSURE_SUCCESS(res, res);
-    NS_ENSURE_TRUE(enumerator, NS_ERROR_UNEXPECTED);
-
-    for (enumerator->First(); NS_OK!=enumerator->IsDone(); enumerator->Next())
-    {
-      nsCOMPtr<nsISupports> currentItem;
-      res = enumerator->CurrentItem(getter_AddRefs(currentItem));
-      NS_ENSURE_SUCCESS(res, res);
-      NS_ENSURE_TRUE(currentItem, NS_ERROR_UNEXPECTED);
-
-      nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
+    uint32_t rangeCount = sel->GetRangeCount();
+    for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
+      nsRefPtr<nsRange> range = sel->GetRangeAt(rangeIdx);
       nsCOMPtr<nsIDOMNode> commonParent, parent, tmp;
       range->GetCommonAncestorContainer(getter_AddRefs(commonParent));
       if (commonParent)
       {
         parent = commonParent;
         while (parent)
         {
           if (nsHTMLEditUtils::IsList(parent))
@@ -7792,31 +7772,21 @@ nsHTMLEditRules::SelectionEndpointInNode
 
   nsIDOMNode* node = aNode->AsDOMNode();
   
   *aResult = false;
   
   nsCOMPtr<nsISelection>selection;
   nsresult res = mHTMLEditor->GetSelection(getter_AddRefs(selection));
   NS_ENSURE_SUCCESS(res, res);
-  nsCOMPtr<nsISelectionPrivate>selPriv(do_QueryInterface(selection));
-  
-  nsCOMPtr<nsIEnumerator> enumerator;
-  res = selPriv->GetEnumerator(getter_AddRefs(enumerator));
-  NS_ENSURE_SUCCESS(res, res);
-  NS_ENSURE_TRUE(enumerator, NS_ERROR_UNEXPECTED);
-
-  for (enumerator->First(); NS_OK!=enumerator->IsDone(); enumerator->Next())
-  {
-    nsCOMPtr<nsISupports> currentItem;
-    res = enumerator->CurrentItem(getter_AddRefs(currentItem));
-    NS_ENSURE_SUCCESS(res, res);
-    NS_ENSURE_TRUE(currentItem, NS_ERROR_UNEXPECTED);
-
-    nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
+  
+  Selection* sel = static_cast<Selection*>(selection.get());
+  uint32_t rangeCount = sel->GetRangeCount();
+  for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
+    nsRefPtr<nsRange> range = sel->GetRangeAt(rangeIdx);
     nsCOMPtr<nsIDOMNode> startParent, endParent;
     range->GetStartContainer(getter_AddRefs(startParent));
     if (startParent)
     {
       if (node == startParent) {
         *aResult = true;
         return NS_OK;
       }
--- a/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/editor/libeditor/html/nsHTMLEditor.cpp
@@ -32,17 +32,16 @@
 #include "nsIDOMHTMLDocument.h"
 #include "nsILinkHandler.h"
 #include "nsIInlineSpellChecker.h"
 
 #include "mozilla/css/Loader.h"
 #include "nsCSSStyleSheet.h"
 #include "nsIDOMStyleSheet.h"
 
-#include "nsIEnumerator.h"
 #include "nsIContent.h"
 #include "nsIContentIterator.h"
 #include "nsIDOMRange.h"
 #include "nsISupportsArray.h"
 #include "nsContentUtils.h"
 #include "nsIDocumentEncoder.h"
 #include "nsIDOMDocumentFragment.h"
 #include "nsIPresShell.h"
@@ -2383,17 +2382,17 @@ nsHTMLEditor::GetSelectedElement(const n
   // default is null - no element found
   *aReturn = nullptr;
   
   // First look for a single element in selection
   nsCOMPtr<nsISelection>selection;
   nsresult res = GetSelection(getter_AddRefs(selection));
   NS_ENSURE_SUCCESS(res, res);
   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
-  nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
+  Selection* sel = static_cast<Selection*>(selection.get());
 
   bool bNodeFound = false;
   bool isCollapsed = selection->Collapsed();
 
   nsAutoString domTagName;
   nsAutoString TagName(aTagName);
   ToLowerCase(TagName);
   // Empty string indicates we should match any element tag
@@ -2448,57 +2447,44 @@ nsHTMLEditor::GetSelectedElement(const n
       //  found for any selection that is totally within a link,
       //  included a collapsed selection (just a caret in a link)
       nsCOMPtr<nsIDOMNode> anchorNode;
       res = selection->GetAnchorNode(getter_AddRefs(anchorNode));
       NS_ENSURE_SUCCESS(res, res);
       int32_t anchorOffset = -1;
       if (anchorNode)
         selection->GetAnchorOffset(&anchorOffset);
-    
+
       nsCOMPtr<nsIDOMNode> focusNode;
       res = selection->GetFocusNode(getter_AddRefs(focusNode));
       NS_ENSURE_SUCCESS(res, res);
       int32_t focusOffset = -1;
       if (focusNode)
         selection->GetFocusOffset(&focusOffset);
 
       // Link node must be the same for both ends of selection
       if (NS_SUCCEEDED(res) && anchorNode)
       {
-  #ifdef DEBUG_cmanske
-        {
-        nsAutoString name;
-        anchorNode->GetNodeName(name);
-        printf("GetSelectedElement: Anchor node of selection: ");
-        wprintf(name.get());
-        printf(" Offset: %d\n", anchorOffset);
-        focusNode->GetNodeName(name);
-        printf("Focus node of selection: ");
-        wprintf(name.get());
-        printf(" Offset: %d\n", focusOffset);
-        }
-  #endif
         nsCOMPtr<nsIDOMElement> parentLinkOfAnchor;
         res = GetElementOrParentByTagName(NS_LITERAL_STRING("href"), anchorNode, getter_AddRefs(parentLinkOfAnchor));
         // XXX: ERROR_HANDLING  can parentLinkOfAnchor be null?
         if (NS_SUCCEEDED(res) && parentLinkOfAnchor)
         {
           if (isCollapsed)
           {
             // We have just a caret in the link
             bNodeFound = true;
           } else if(focusNode) 
           {  // Link node must be the same for both ends of selection
             nsCOMPtr<nsIDOMElement> parentLinkOfFocus;
             res = GetElementOrParentByTagName(NS_LITERAL_STRING("href"), focusNode, getter_AddRefs(parentLinkOfFocus));
             if (NS_SUCCEEDED(res) && parentLinkOfFocus == parentLinkOfAnchor)
               bNodeFound = true;
           }
-      
+
           // We found a link node parent
           if (bNodeFound) {
             // GetElementOrParentByTagName addref'd this, so we don't need to do it here
             *aReturn = parentLinkOfAnchor;
             NS_IF_ADDREF(*aReturn);
             return NS_OK;
           }
         }
@@ -2513,87 +2499,73 @@ nsHTMLEditor::GetSelectedElement(const n
             bNodeFound = true;
           }
         }
       }
     } 
 
     if (!isCollapsed)   // Don't bother to examine selection if it is collapsed
     {
-      nsCOMPtr<nsIEnumerator> enumerator;
-      res = selPriv->GetEnumerator(getter_AddRefs(enumerator));
-      if (NS_SUCCEEDED(res))
-      {
-        if(!enumerator)
-          return NS_ERROR_NULL_POINTER;
-
-        enumerator->First(); 
-        nsCOMPtr<nsISupports> currentItem;
-        res = enumerator->CurrentItem(getter_AddRefs(currentItem));
-        if ((NS_SUCCEEDED(res)) && currentItem)
+      nsRefPtr<nsRange> currange = sel->GetRangeAt(0);
+      if (currange) {
+        nsCOMPtr<nsIContentIterator> iter =
+          do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &res);
+        NS_ENSURE_SUCCESS(res, res);
+
+        iter->Init(currange);
+        // loop through the content iterator for each content node
+        while (!iter->IsDone())
         {
-          nsCOMPtr<nsIDOMRange> currange( do_QueryInterface(currentItem) );
-          nsCOMPtr<nsIContentIterator> iter =
-            do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &res);
-          NS_ENSURE_SUCCESS(res, res);
-
-          iter->Init(currange);
-          // loop through the content iterator for each content node
-          while (!iter->IsDone())
+          // Query interface to cast nsIContent to nsIDOMNode
+          //  then get tagType to compare to  aTagName
+          // Clone node of each desired type and append it to the aDomFrag
+          selectedElement = do_QueryInterface(iter->GetCurrentNode());
+          if (selectedElement)
           {
-            // Query interface to cast nsIContent to nsIDOMNode
-            //  then get tagType to compare to  aTagName
-            // Clone node of each desired type and append it to the aDomFrag
-            selectedElement = do_QueryInterface(iter->GetCurrentNode());
-            if (selectedElement)
+            // If we already found a node, then we have another element,
+            //  thus there's not just one element selected
+            if (bNodeFound)
             {
-              // If we already found a node, then we have another element,
-              //  thus there's not just one element selected
-              if (bNodeFound)
-              {
-                bNodeFound = false;
-                break;
-              }
-
-              selectedElement->GetNodeName(domTagName);
-              ToLowerCase(domTagName);
-
-              if (anyTag)
-              {
-                // Get name of first selected element
-                selectedElement->GetTagName(TagName);
-                ToLowerCase(TagName);
-                anyTag = false;
-              }
-
-              // The "A" tag is a pain,
-              //  used for both link(href is set) and "Named Anchor"
-              nsCOMPtr<nsIDOMNode> selectedNode = do_QueryInterface(selectedElement);
-              if ( (isLinkTag && nsHTMLEditUtils::IsLink(selectedNode)) ||
-                   (isNamedAnchorTag && nsHTMLEditUtils::IsNamedAnchor(selectedNode)) )
-              {
-                bNodeFound = true;
-              } else if (TagName == domTagName) { // All other tag names are handled here
-                bNodeFound = true;
-              }
-              if (!bNodeFound)
-              {
-                // Check if node we have is really part of the selection???
-                break;
-              }
+              bNodeFound = false;
+              break;
+            }
+
+            selectedElement->GetNodeName(domTagName);
+            ToLowerCase(domTagName);
+
+            if (anyTag)
+            {
+              // Get name of first selected element
+              selectedElement->GetTagName(TagName);
+              ToLowerCase(TagName);
+              anyTag = false;
             }
-            iter->Next();
+
+            // The "A" tag is a pain,
+            //  used for both link(href is set) and "Named Anchor"
+            nsCOMPtr<nsIDOMNode> selectedNode = do_QueryInterface(selectedElement);
+            if ( (isLinkTag && nsHTMLEditUtils::IsLink(selectedNode)) ||
+                (isNamedAnchorTag && nsHTMLEditUtils::IsNamedAnchor(selectedNode)) )
+            {
+              bNodeFound = true;
+            } else if (TagName == domTagName) { // All other tag names are handled here
+              bNodeFound = true;
+            }
+            if (!bNodeFound)
+            {
+              // Check if node we have is really part of the selection???
+              break;
+            }
           }
-        } else {
-          // Should never get here?
-          isCollapsed = true;
-          printf("isCollapsed was FALSE, but no elements found in selection\n");
+          iter->Next();
         }
       } else {
-        printf("Could not create enumerator for GetSelectionProperties\n");
+        // Should never get here?
+        isCollapsed = true;
+        NS_WARNING("isCollapsed was FALSE, but no elements found in selection\n");
       }
     }
   }
   if (bNodeFound)
   {
     
     *aReturn = selectedElement;
     if (selectedElement)
@@ -4673,33 +4645,23 @@ nsHTMLEditor::SetCSSBackgroundColor(cons
   nsAutoTxnsConserveSelection dontSpazMySelection(this);
   
   bool cancel, handled;
   nsTextRulesInfo ruleInfo(EditAction::setTextProperty);
   nsresult res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
   NS_ENSURE_SUCCESS(res, res);
   if (!cancel && !handled)
   {
-    // get selection range enumerator
-    nsCOMPtr<nsIEnumerator> enumerator;
-    res = selection->GetEnumerator(getter_AddRefs(enumerator));
-    NS_ENSURE_SUCCESS(res, res);
-    NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
-
     // loop thru the ranges in the selection
-    enumerator->First(); 
-    nsCOMPtr<nsISupports> currentItem;
     nsAutoString bgcolor; bgcolor.AssignLiteral("bgcolor");
-    nsCOMPtr<nsIDOMNode> cachedBlockParent = nullptr;
-    while (static_cast<nsresult>(NS_ENUMERATOR_FALSE) == enumerator->IsDone()) {
-      res = enumerator->CurrentItem(getter_AddRefs(currentItem));
-      NS_ENSURE_SUCCESS(res, res);
-      NS_ENSURE_TRUE(currentItem, NS_ERROR_FAILURE);
-      
-      nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
+    uint32_t rangeCount = selection->GetRangeCount();
+    for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
+      nsCOMPtr<nsIDOMNode> cachedBlockParent = nullptr;
+      nsRefPtr<nsRange> range = selection->GetRangeAt(rangeIdx);
+      NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
       
       // check for easy case: both range endpoints in same text node
       nsCOMPtr<nsIDOMNode> startNode, endNode;
       int32_t startOffset, endOffset;
       res = range->GetStartContainer(getter_AddRefs(startNode));
       NS_ENSURE_SUCCESS(res, res);
       res = range->GetEndContainer(getter_AddRefs(endNode));
       NS_ENSURE_SUCCESS(res, res);
@@ -4849,17 +4811,16 @@ nsHTMLEditor::SetCSSBackgroundColor(cons
             cachedBlockParent = blockParent;
             nsCOMPtr<nsIDOMElement> element = do_QueryInterface(blockParent);
             int32_t count;
             res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
             NS_ENSURE_SUCCESS(res, res);
           }
         }
       }
-      enumerator->Next();
     }
   }
   if (!cancel)
   {
     // post-process
     res = mRules->DidDoAction(selection, &ruleInfo, res);
   }
   return res;
--- a/editor/libeditor/html/nsHTMLEditorStyle.cpp
+++ b/editor/libeditor/html/nsHTMLEditorStyle.cpp
@@ -28,17 +28,16 @@
 #include "nsIContent.h"
 #include "nsIContentIterator.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMRange.h"
 #include "nsIEditor.h"
 #include "nsIEditorIMESupport.h"
-#include "nsIEnumerator.h"
 #include "nsINameSpaceManager.h"
 #include "nsINode.h"
 #include "nsISelection.h"
 #include "nsISelectionPrivate.h"
 #include "nsISupportsImpl.h"
 #include "nsLiteralString.h"
 #include "nsReadableUtils.h"
 #include "nsSelectionState.h"
@@ -139,32 +138,20 @@ nsHTMLEditor::SetInlineProperty(nsIAtom 
   nsAutoSelectionReset selectionResetter(selection, this);
   nsAutoTxnsConserveSelection dontSpazMySelection(this);
 
   bool cancel, handled;
   nsTextRulesInfo ruleInfo(EditAction::setTextProperty);
   nsresult res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
   NS_ENSURE_SUCCESS(res, res);
   if (!cancel && !handled) {
-    // get selection range enumerator
-    nsCOMPtr<nsIEnumerator> enumerator;
-    res = selection->GetEnumerator(getter_AddRefs(enumerator));
-    NS_ENSURE_SUCCESS(res, res);
-    NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
-
     // loop thru the ranges in the selection
-    nsCOMPtr<nsISupports> currentItem;
-    for (enumerator->First();
-         static_cast<nsresult>(NS_ENUMERATOR_FALSE) == enumerator->IsDone();
-         enumerator->Next()) {
-      res = enumerator->CurrentItem(getter_AddRefs(currentItem));
-      NS_ENSURE_SUCCESS(res, res);
-      NS_ENSURE_TRUE(currentItem, NS_ERROR_FAILURE);
-
-      nsCOMPtr<nsIDOMRange> range(do_QueryInterface(currentItem));
+    uint32_t rangeCount = selection->GetRangeCount();
+    for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
+      nsRefPtr<nsRange> range = selection->GetRangeAt(rangeIdx);
 
       // adjust range to include any ancestors whose children are entirely
       // selected
       res = PromoteInlineRange(range);
       NS_ENSURE_SUCCESS(res, res);
 
       // check for easy case: both range endpoints in same text node
       nsCOMPtr<nsIDOMNode> startNode, endNode;
@@ -1110,33 +1097,25 @@ nsHTMLEditor::GetInlinePropertyBase(nsIA
   *aAll = true;
   *aFirst = false;
   bool first = true;
 
   nsCOMPtr<nsISelection> selection;
   result = GetSelection(getter_AddRefs(selection));
   NS_ENSURE_SUCCESS(result, result);
   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
-  nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
+  Selection* sel = static_cast<Selection*>(selection.get());
 
   bool isCollapsed = selection->Collapsed();
   nsCOMPtr<nsIDOMNode> collapsedNode;
-  nsCOMPtr<nsIEnumerator> enumerator;
-  result = selPriv->GetEnumerator(getter_AddRefs(enumerator));
-  NS_ENSURE_SUCCESS(result, result);
-  NS_ENSURE_TRUE(enumerator, NS_ERROR_NULL_POINTER);
-
-  enumerator->First(); 
-  nsCOMPtr<nsISupports> currentItem;
-  result = enumerator->CurrentItem(getter_AddRefs(currentItem));
+  nsRefPtr<nsRange> range = sel->GetRangeAt(0);
   // XXX: should be a while loop, to get each separate range
   // XXX: ERROR_HANDLING can currentItem be null?
-  if (NS_SUCCEEDED(result) && currentItem) {
+  if (range) {
     bool firstNodeInRange = true; // for each range, set a flag 
-    nsCOMPtr<nsIDOMRange> range(do_QueryInterface(currentItem));
 
     if (isCollapsed) {
       range->GetStartContainer(getter_AddRefs(collapsedNode));
       NS_ENSURE_TRUE(collapsedNode, NS_ERROR_FAILURE);
       bool isSet, theSetting;
       nsString tOutString;
       if (aAttribute) {
         nsString tString(*aAttribute);
@@ -1374,32 +1353,20 @@ nsresult nsHTMLEditor::RemoveInlinePrope
   nsAutoTxnsConserveSelection dontSpazMySelection(this);
   
   bool cancel, handled;
   nsTextRulesInfo ruleInfo(EditAction::removeTextProperty);
   res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
   NS_ENSURE_SUCCESS(res, res);
   if (!cancel && !handled)
   {
-    // get selection range enumerator
-    nsCOMPtr<nsIEnumerator> enumerator;
-    res = selection->GetEnumerator(getter_AddRefs(enumerator));
-    NS_ENSURE_SUCCESS(res, res);
-    NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
-
     // loop thru the ranges in the selection
-    enumerator->First(); 
-    nsCOMPtr<nsISupports> currentItem;
-    while (static_cast<nsresult>(NS_ENUMERATOR_FALSE) == enumerator->IsDone()) {
-      res = enumerator->CurrentItem(getter_AddRefs(currentItem));
-      NS_ENSURE_SUCCESS(res, res);
-      NS_ENSURE_TRUE(currentItem, NS_ERROR_FAILURE);
-      
-      nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
-
+    uint32_t rangeCount = selection->GetRangeCount();
+    for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
+      nsRefPtr<nsRange> range = selection->GetRangeAt(rangeIdx);
       if (aProperty == nsEditProperty::name)
       {
         // promote range if it starts or end in a named anchor and we
         // want to remove named anchors
         res = PromoteRangeIfStartsOrEndsInNamedAnchor(range);
       }
       else {
         // adjust range to include any ancestors who's children are entirely selected
@@ -1495,17 +1462,16 @@ nsresult nsHTMLEditor::RemoveInlinePrope
                 nsAutoString value; value.AssignLiteral("-moz-editor-invert-value");
                 SetInlinePropertyOnNode(node, aProperty, aAttribute, &value);
               }
             }
           }
         }
         arrayOfNodes.Clear();
       }
-      enumerator->Next();
     }
   }
   if (!cancel)
   {
     // post-process 
     res = mRules->DidDoAction(selection, &ruleInfo, res);
   }
   return res;
@@ -1561,34 +1527,23 @@ nsHTMLEditor::RelativeFontChange( int32_
   }
   
   // wrap with txn batching, rules sniffing, and selection preservation code
   nsAutoEditBatch batchIt(this);
   nsAutoRules beginRulesSniffing(this, EditAction::setTextProperty, nsIEditor::eNext);
   nsAutoSelectionReset selectionResetter(selection, this);
   nsAutoTxnsConserveSelection dontSpazMySelection(this);
 
-  // get selection range enumerator
-  nsCOMPtr<nsIEnumerator> enumerator;
-  nsresult res = selection->GetEnumerator(getter_AddRefs(enumerator));
-  NS_ENSURE_SUCCESS(res, res);
-  NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
-
   // loop thru the ranges in the selection
-  enumerator->First(); 
-  nsCOMPtr<nsISupports> currentItem;
-  while (static_cast<nsresult>(NS_ENUMERATOR_FALSE) == enumerator->IsDone()) {
-    res = enumerator->CurrentItem(getter_AddRefs(currentItem));
-    NS_ENSURE_SUCCESS(res, res);
-    NS_ENSURE_TRUE(currentItem, NS_ERROR_FAILURE);
-    
-    nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
+  uint32_t rangeCount = selection->GetRangeCount();
+  for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
+    nsRefPtr<nsRange> range = selection->GetRangeAt(rangeIdx);
 
     // adjust range to include any ancestors who's children are entirely selected
-    res = PromoteInlineRange(range);
+    nsresult res = PromoteInlineRange(range);
     NS_ENSURE_SUCCESS(res, res);
     
     // check for easy case: both range endpoints in same text node
     nsCOMPtr<nsIDOMNode> startNode, endNode;
     res = range->GetStartContainer(getter_AddRefs(startNode));
     NS_ENSURE_SUCCESS(res, res);
     res = range->GetEndContainer(getter_AddRefs(endNode));
     NS_ENSURE_SUCCESS(res, res);
@@ -1660,20 +1615,19 @@ nsHTMLEditor::RelativeFontChange( int32_
       {
         nsCOMPtr<nsIDOMCharacterData> nodeAsText = do_QueryInterface(endNode);
         int32_t endOffset;
         range->GetEndOffset(&endOffset);
         res = RelativeFontChangeOnTextNode(aSizeChange, nodeAsText, 0, endOffset);
         NS_ENSURE_SUCCESS(res, res);
       }
     }
-    enumerator->Next();
   }
   
-  return res;  
+  return NS_OK;  
 }
 
 nsresult
 nsHTMLEditor::RelativeFontChangeOnTextNode( int32_t aSizeChange, 
                                             nsIDOMCharacterData *aTextNode, 
                                             int32_t aStartOffset,
                                             int32_t aEndOffset)
 {
--- a/embedding/tests/winEmbed/Makefile.in
+++ b/embedding/tests/winEmbed/Makefile.in
@@ -71,18 +71,14 @@ include $(topsrcdir)/config/rules.mk
 #
 # The default heap size is 1MB on Win32.
 # The heap will grow if need be.
 #
 # Set it to 256k.  See bug 127069.
 #
 ifndef GNU_CC
 LDFLAGS += /HEAP:0x40000
-ifeq ($(OS_TEST),x86_64)
-# set stack to 2MB on x64 build.  See bug 582910
-LDFLAGS += -STACK:2097152
-endif
 endif
 
 # Get rid of console window
 ifdef GNU_CC
 LDFLAGS += -mwindows
 endif
--- a/gfx/angle/README.mozilla
+++ b/gfx/angle/README.mozilla
@@ -25,16 +25,19 @@ In this order:
   angle-faceforward-emu.patch:
     Adds emulation for faceforward(float,float,float), which is needed to
     prevent crashing on Mac+Intel. See bug 771406.
 
   angle-r1638.patch
     Adds uniform array index clamping on non-Windows platforms.
     Windows would require r1719, r1733, r1734.
 
+  angle-cross-compilation.patch
+    Fixes cross compilation on case sensitive OSes.
+
 In addition to these patches, the Makefile.in files are ours, they're not present in
 upsteam ANGLE. Therefore, changes made to the Makefile.in files should not be stored
 in the local .patch files.
 
 
 == How to do a clean-slate upgrade ==
 1.  Backup our moz-specific files:
       README.mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/angle/angle-cross-compilation.patch
@@ -0,0 +1,27 @@
+From: Jacek Caban <jacek@codeweavers.com>
+Fixed ANGLE cross compilation on case sensitive OSes
+
+
+diff --git a/gfx/angle/src/libEGL/Display.h b/gfx/angle/src/libEGL/Display.h
+index aedc8e7..2162265 100644
+--- a/gfx/angle/src/libEGL/Display.h
++++ b/gfx/angle/src/libEGL/Display.h
+@@ -11,17 +11,17 @@
+ #ifndef LIBEGL_DISPLAY_H_
+ #define LIBEGL_DISPLAY_H_
+ 
+ #ifndef WIN32_LEAN_AND_MEAN
+ #define WIN32_LEAN_AND_MEAN
+ #endif
+ #include <windows.h>
+ #include <d3d9.h>
+-#include <D3Dcompiler.h>
++#include <d3dcompiler.h>
+ 
+ #include <set>
+ #include <vector>
+ 
+ #include "libGLESv2/Context.h"
+ 
+ #include "libEGL/Config.h"
+ #include "libEGL/ShaderCache.h"
--- a/gfx/angle/src/libEGL/Display.h
+++ b/gfx/angle/src/libEGL/Display.h
@@ -11,17 +11,17 @@
 #ifndef LIBEGL_DISPLAY_H_
 #define LIBEGL_DISPLAY_H_
 
 #ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN
 #endif
 #include <windows.h>
 #include <d3d9.h>
-#include <D3Dcompiler.h>
+#include <d3dcompiler.h>
 
 #include <set>
 #include <vector>
 
 #include "libGLESv2/Context.h"
 
 #include "libEGL/Config.h"
 #include "libEGL/ShaderCache.h"
--- a/gfx/src/nsRegion.cpp
+++ b/gfx/src/nsRegion.cpp
@@ -1554,18 +1554,18 @@ nsIntRegion nsRegion::ScaleToInsidePixel
 namespace {
   // This class represents a partitioning of an axis delineated by coordinates.
   // It internally maintains a sorted array of coordinates.
   class AxisPartition {
   public:
     // Adds a new partition at the given coordinate to this partitioning. If
     // the coordinate is already present in the partitioning, this does nothing.
     void InsertCoord(nscoord c) {
-      uint32_t i;
-      if (!mStops.GreatestIndexLtEq(c, i)) {
+      uint32_t i = mStops.IndexOfFirstElementGt(c);
+      if (i == 0 || mStops[i-1] != c) {
         mStops.InsertElementAt(i, c);
       }
     }
 
     // Returns the array index of the given partition point. The partition
     // point must already be present in the partitioning.
     int32_t IndexOf(nscoord p) const {
       return mStops.BinaryIndexOf(p);
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -1264,33 +1264,37 @@ gfxContext::ClipContainsRect(const gfxRe
 
 void
 gfxContext::SetColor(const gfxRGBA& c)
 {
   if (mCairo) {
     if (gfxPlatform::GetCMSMode() == eCMSMode_All) {
 
         gfxRGBA cms;
-        gfxPlatform::TransformPixel(c, cms, gfxPlatform::GetCMSRGBTransform());
+        qcms_transform *transform = gfxPlatform::GetCMSRGBTransform();
+        if (transform)
+          gfxPlatform::TransformPixel(c, cms, transform);
 
         // Use the original alpha to avoid unnecessary float->byte->float
         // conversion errors
         cairo_set_source_rgba(mCairo, cms.r, cms.g, cms.b, c.a);
     }
     else
         cairo_set_source_rgba(mCairo, c.r, c.g, c.b, c.a);
   } else {
     CurrentState().pattern = NULL;
     CurrentState().sourceSurfCairo = NULL;
     CurrentState().sourceSurface = NULL;
 
     if (gfxPlatform::GetCMSMode() == eCMSMode_All) {
 
         gfxRGBA cms;
-        gfxPlatform::TransformPixel(c, cms, gfxPlatform::GetCMSRGBTransform());
+        qcms_transform *transform = gfxPlatform::GetCMSRGBTransform();
+        if (transform)
+          gfxPlatform::TransformPixel(c, cms, transform);
 
         // Use the original alpha to avoid unnecessary float->byte->float
         // conversion errors
         CurrentState().color = ToColor(cms);
     }
     else
         CurrentState().color = ToColor(c);
   }
--- a/gfx/thebes/gfxGraphiteShaper.cpp
+++ b/gfx/thebes/gfxGraphiteShaper.cpp
@@ -194,18 +194,21 @@ gfxGraphiteShaper::ShapeText(gfxContext 
 
     if (MergeFontFeatures(style->featureSettings, entry->mFeatureSettings,
                           aShapedText->DisableLigatures(), mergedFeatures)) {
         // enumerate result and insert into Graphite feature list
         GrFontFeatures f = {mGrFace, grFeatures};
         mergedFeatures.Enumerate(AddFeature, &f);
     }
 
+    size_t numChars = gr_count_unicode_characters(gr_utf16,
+                                                  aText, aText + aLength,
+                                                  nullptr);
     gr_segment *seg = gr_make_seg(mGrFont, mGrFace, 0, grFeatures,
-                                  gr_utf16, aText, aLength,
+                                  gr_utf16, aText, numChars,
                                   aShapedText->IsRightToLeft());
 
     gr_featureval_destroy(grFeatures);
 
     if (!seg) {
         return false;
     }
 
@@ -216,19 +219,19 @@ gfxGraphiteShaper::ShapeText(gfxContext 
 
     return NS_SUCCEEDED(rv);
 }
 
 #define SMALL_GLYPH_RUN 256 // avoid heap allocation of per-glyph data arrays
                             // for short (typical) runs up to this length
 
 struct Cluster {
-    uint32_t baseChar;
+    uint32_t baseChar; // in UTF16 code units, not Unicode character indices
     uint32_t baseGlyph;
-    uint32_t nChars;
+    uint32_t nChars; // UTF16 code units
     uint32_t nGlyphs;
     Cluster() : baseChar(0), baseGlyph(0), nChars(0), nGlyphs(0) { }
 };
 
 nsresult
 gfxGraphiteShaper::SetGlyphsFromSegment(gfxContext      *aContext,
                                         gfxShapedText   *aShapedText,
                                         uint32_t         aOffset,
@@ -258,18 +261,20 @@ gfxGraphiteShaper::SetGlyphsFromSegment(
     // walk through the glyph slots and check which original character
     // each is associated with
     uint32_t gIndex = 0; // glyph slot index
     uint32_t cIndex = 0; // current cluster index
     for (const gr_slot *slot = gr_seg_first_slot(aSegment);
          slot != nullptr;
          slot = gr_slot_next_in_segment(slot), gIndex++)
     {
-        uint32_t before = gr_slot_before(slot);
-        uint32_t after = gr_slot_after(slot);
+        uint32_t before =
+            gr_cinfo_base(gr_seg_cinfo(aSegment, gr_slot_before(slot)));
+        uint32_t after =
+            gr_cinfo_base(gr_seg_cinfo(aSegment, gr_slot_after(slot)));
         gids[gIndex] = gr_slot_gid(slot);
         xLocs[gIndex] = gr_slot_origin_X(slot);
         yLocs[gIndex] = gr_slot_origin_Y(slot);
 
         // if this glyph has a "before" character index that precedes the
         // current cluster's char index, we need to merge preceding
         // clusters until it gets included
         while (before < clusters[cIndex].baseChar && cIndex > 0) {
@@ -325,19 +330,18 @@ gfxGraphiteShaper::SetGlyphsFromSegment(
                 adv = gr_seg_advance_X(aSegment) - xLocs[c.baseGlyph];
             } else {
                 adv = xLocs[clusters[i+1].baseGlyph] - xLocs[c.baseGlyph];
             }
         }
 
         // Check for default-ignorable char that didn't get filtered, combined,
         // etc by the shaping process, and skip it.
-        uint32_t offs = gr_cinfo_base(gr_seg_cinfo(aSegment, c.baseChar));
-        NS_ASSERTION(offs >= c.baseChar && offs < aLength,
-                     "unexpected offset");
+        uint32_t offs = c.baseChar;
+        NS_ASSERTION(offs < aLength, "unexpected offset");
         if (c.nGlyphs == 1 && c.nChars == 1 &&
             aShapedText->FilterIfIgnorable(aOffset + offs, aText[offs])) {
             continue;
         }
 
         uint32_t appAdvance = roundX ? NSToIntRound(adv) * dev2appUnits :
                                        NSToIntRound(adv * dev2appUnits);
         if (c.nGlyphs == 1 &&
@@ -370,20 +374,18 @@ gfxGraphiteShaper::SetGlyphsFromSegment(
             }
             gfxShapedText::CompressedGlyph g;
             g.SetComplex(charGlyphs[offs].IsClusterStart(),
                          true, details.Length());
             aShapedText->SetGlyphs(aOffset + offs, g, details.Elements());
         }
 
         for (uint32_t j = c.baseChar + 1; j < c.baseChar + c.nChars; ++j) {
-            offs = gr_cinfo_base(gr_seg_cinfo(aSegment, j));
-            NS_ASSERTION(offs >= j && offs < aLength,
-                         "unexpected offset");
-            gfxShapedText::CompressedGlyph &g = charGlyphs[offs];
+            NS_ASSERTION(j < aLength, "unexpected offset");
+            gfxShapedText::CompressedGlyph &g = charGlyphs[j];
             NS_ASSERTION(!g.IsSimpleGlyph(), "overwriting a simple glyph");
             g.SetComplex(g.IsClusterStart(), false, 0);
         }
     }
 
     return NS_OK;
 }
 
--- a/gfx/thebes/gfxPattern.cpp
+++ b/gfx/thebes/gfxPattern.cpp
@@ -75,17 +75,19 @@ gfxPattern::CairoPattern()
 
 void
 gfxPattern::AddColorStop(gfxFloat offset, const gfxRGBA& c)
 {
   if (mPattern) {
     mStops = NULL;
     if (gfxPlatform::GetCMSMode() == eCMSMode_All) {
         gfxRGBA cms;
-        gfxPlatform::TransformPixel(c, cms, gfxPlatform::GetCMSRGBTransform());
+        qcms_transform *transform = gfxPlatform::GetCMSRGBTransform();
+        if (transform)
+          gfxPlatform::TransformPixel(c, cms, transform);
 
         // Use the original alpha to avoid unnecessary float->byte->float
         // conversion errors
         cairo_pattern_add_color_stop_rgba(mPattern, offset,
                                           cms.r, cms.g, cms.b, c.a);
     }
     else
         cairo_pattern_add_color_stop_rgba(mPattern, offset, c.r, c.g, c.b, c.a);
@@ -426,9 +428,9 @@ gfxPattern::AdjustTransformForPattern(Ma
   mat.Invert();
   // mat maps from device space to current user space
 
   // First, transform from pattern space to original user space. Then transform
   // from original user space to device space. Then transform from
   // device space to current user space.
   aPatternTransform = aPatternTransform * *aOriginalTransform * mat;
   aPatternTransform.NudgeToIntegers();
-}
\ No newline at end of file
+}
--- a/image/src/Decoder.cpp
+++ b/image/src/Decoder.cpp
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "Decoder.h"
 #include "nsIServiceManager.h"
 #include "nsIConsoleService.h"
 #include "nsIScriptError.h"
+#include "sampler.h"
 
 namespace mozilla {
 namespace image {
 
 Decoder::Decoder(RasterImage &aImage, imgDecoderObserver* aObserver)
   : mImage(aImage)
   , mObserver(aObserver)
   , mDecodeFlags(0)
@@ -62,16 +63,18 @@ Decoder::InitSharedDecoder()
   // Implementation-specific initialization
   InitInternal();
   mInitialized = true;
 }
 
 void
 Decoder::Write(const char* aBuffer, uint32_t aCount)
 {
+  SAMPLE_LABEL("ImageDecoder", "Write");
+
   // We're strict about decoder errors
   NS_ABORT_IF_FALSE(!HasDecoderError(),
                     "Not allowed to make more decoder calls after error!");
 
   // If a data error occured, just ignore future data
   if (HasDataError())
     return;
 
@@ -110,17 +113,17 @@ Decoder::Finish(RasterImage::eShutdownIn
                          EmptyString(), 0, 0, nsIScriptError::errorFlag,
                          "Image", mImage.InnerWindowID()
                        ))) {
         consoleService->LogMessage(errorObject);
       }
     }
 
     bool usable = true;
-    if (aShutdownIntent != RasterImage::eShutdownIntent_Interrupted && !HasDecoderError()) {
+    if (aShutdownIntent != RasterImage::eShutdownIntent_NotNeeded && !HasDecoderError()) {
       // If we only have a data error, we're usable if we have at least one frame.
       if (mImage.GetNumFrames() == 0) {
         usable = false;
       }
     }
 
     // If we're usable, do exactly what we should have when the decoder
     // completed.
--- a/image/src/ImageFactory.cpp
+++ b/image/src/ImageFactory.cpp
@@ -1,26 +1,32 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include <algorithm>
+
 #include "mozilla/Preferences.h"
 #include "mozilla/Likely.h"
 
 #include "nsIHttpChannel.h"
 #include "nsSimpleURI.h"
 #include "nsMimeTypes.h"
+#include "nsIURI.h"
+#include "nsIRequest.h"
 
+#include "imgIContainer.h"
+#include "imgStatusTracker.h"
 #include "RasterImage.h"
 #include "VectorImage.h"
+#include "Image.h"
 
 #include "ImageFactory.h"
-#include <algorithm>
 
 namespace mozilla {
 namespace image {
 
 // Global preferences related to image containers.
 static bool gInitializedPrefCaches = false;
 static bool gDecodeOnDraw = false;
 static bool gDiscardable = false;
@@ -33,22 +39,22 @@ InitPrefCaches()
   gInitializedPrefCaches = true;
 }
 
 static uint32_t
 ComputeImageFlags(nsIURI* uri, bool isMultiPart)
 {
   nsresult rv;
 
-  // We default to the static globals
+  // We default to the static globals.
   bool isDiscardable = gDiscardable;
   bool doDecodeOnDraw = gDecodeOnDraw;
 
   // We want UI to be as snappy as possible and not to flicker. Disable discarding
-  // and decode-on-draw for chrome URLS
+  // and decode-on-draw for chrome URLS.
   bool isChrome = false;
   rv = uri->SchemeIs("chrome", &isChrome);
   if (NS_SUCCEEDED(rv) && isChrome)
     isDiscardable = doDecodeOnDraw = false;
 
   // We don't want resources like the "loading" icon to be discardable or
   // decode-on-draw either.
   bool isResource = false;
@@ -56,17 +62,17 @@ ComputeImageFlags(nsIURI* uri, bool isMu
   if (NS_SUCCEEDED(rv) && isResource)
     isDiscardable = doDecodeOnDraw = false;
 
   // For multipart/x-mixed-replace, we basically want a direct channel to the
   // decoder. Disable both for this case as well.
   if (isMultiPart)
     isDiscardable = doDecodeOnDraw = false;
 
-  // We have all the information we need
+  // We have all the information we need.
   uint32_t imageFlags = Image::INIT_FLAG_NONE;
   if (isDiscardable)
     imageFlags |= Image::INIT_FLAG_DISCARDABLE;
   if (doDecodeOnDraw)
     imageFlags |= Image::INIT_FLAG_DECODE_ON_DRAW;
   if (isMultiPart)
     imageFlags |= Image::INIT_FLAG_MULTIPART;
 
@@ -118,17 +124,16 @@ ImageFactory::CreateAnonymousImage(const
 
   rv = newImage->Init(nullptr, aMimeType.get(), Image::INIT_FLAG_NONE);
   NS_ENSURE_SUCCESS(rv, BadImage(newImage));
 
   return newImage.forget();
 }
 
 /* static */ already_AddRefed<Image>
-
 ImageFactory::CreateRasterImage(nsIRequest* aRequest,
                                 imgStatusTracker* aStatusTracker,
                                 const nsCString& aMimeType,
                                 nsIURI* aURI,
                                 uint32_t aImageFlags,
                                 uint32_t aInnerWindowId)
 {
   nsresult rv;
@@ -146,26 +151,26 @@ ImageFactory::CreateRasterImage(nsIReque
   if (httpChannel) {
     nsAutoCString contentLength;
     rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("content-length"),
                                         contentLength);
     if (NS_SUCCEEDED(rv)) {
       int32_t len = contentLength.ToInteger(&rv);
 
       // Pass anything usable on so that the RasterImage can preallocate
-      // its source buffer
+      // its source buffer.
       if (len > 0) {
         uint32_t sizeHint = (uint32_t) len;
         sizeHint = std::min<uint32_t>(sizeHint, 20000000); // Bound by something reasonable
         rv = newImage->SetSourceSizeHint(sizeHint);
         if (NS_FAILED(rv)) {
-          // Flush memory, try to get some back, and try again
+          // Flush memory, try to get some back, and try again.
           rv = nsMemory::HeapMinimize(true);
           nsresult rv2 = newImage->SetSourceSizeHint(sizeHint);
-          // If we've still failed at this point, things are going downhill
+          // If we've still failed at this point, things are going downhill.
           if (NS_FAILED(rv) || NS_FAILED(rv2)) {
             NS_WARNING("About to hit OOM in imagelib!");
           }
         }
       }
     }
   }
 
--- a/image/src/ImageFactory.h
+++ b/image/src/ImageFactory.h
@@ -1,25 +1,26 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsIURI.h"
-#include "nsIRequest.h"
+#ifndef MOZILLA_IMAGELIB_IMAGEFACTORY_H_
+#define MOZILLA_IMAGELIB_IMAGEFACTORY_H_
 
-#include "imgIContainer.h"
-#include "imgStatusTracker.h"
-
-#include "Image.h"
+class nsIRequest;
+class nsIURI;
+class imgStatusTracker;
 
 namespace mozilla {
 namespace image {
 
+class Image;
+
 class ImageFactory
 {
 public:
   /**
    * Creates a new image with the given properties.
    *
    * @param aRequest       The associated request.
    * @param aStatusTracker A status tracker for the image to use.
@@ -60,8 +61,10 @@ private:
                                                    uint32_t aInnerWindowId);
 
   // This is a static factory class, so disallow instantiation.
   virtual ~ImageFactory() = 0;
 };
 
 } // namespace image
 } // namespace mozilla
+
+#endif // MOZILLA_IMAGELIB_IMAGEFACTORY_H_
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -437,17 +437,17 @@ RasterImage::~RasterImage()
   num_containers--;
   total_source_bytes -= mSourceData.Length();
 
   if (NS_IsMainThread()) {
     DiscardTracker::Remove(&mDiscardTrackerNode);
   }
 }
 
-void
+/* static */ void
 RasterImage::Initialize()
 {
   InitPrefCaches();
 
   // Create our singletons now, so we don't have to worry about what thread
   // they're created on.
   DecodeWorker::Singleton();
 }
@@ -2610,17 +2610,17 @@ RasterImage::InitDecoder(bool aDoSizeDec
 }
 
 // Flushes, closes, and nulls-out a decoder. Cleans up any related decoding
 // state. It is an error to call this function when there is no initialized
 // decoder.
 // 
 // aIntent specifies the intent of the shutdown. If aIntent is
 // eShutdownIntent_Done, an error is flagged if we didn't get what we should
-// have out of the decode. If aIntent is eShutdownIntent_Interrupted, we don't
+// have out of the decode. If aIntent is eShutdownIntent_NotNeeded, we don't
 // check this. If aIntent is eShutdownIntent_Error, we shut down in error mode.
 nsresult
 RasterImage::ShutdownDecoder(eShutdownIntent aIntent)
 {
   // Ensure that our intent is valid
   NS_ABORT_IF_FALSE((aIntent >= 0) && (aIntent < eShutdownIntent_AllCount),
                     "Invalid shutdown intent");
 
@@ -2791,17 +2791,17 @@ RasterImage::RequestDecodeCore(RequestDe
   }
 
 
   // If we have a size decode open, interrupt it and shut it down; or if
   // the decoder has different flags than what we need
   if (mDecoder &&
       (mDecoder->IsSizeDecode() || mDecoder->GetDecodeFlags() != mFrameDecodeFlags))
   {
-    rv = ShutdownDecoder(eShutdownIntent_Interrupted);
+    rv = ShutdownDecoder(eShutdownIntent_NotNeeded);
     CONTAINER_ENSURE_SUCCESS(rv);
   }
 
   // If we don't have a decoder, create one 
   if (!mDecoder) {
     NS_ABORT_IF_FALSE(mFrames.IsEmpty(), "Trying to decode to non-empty frame-array");
     rv = InitDecoder(/* aDoSizeDecode = */ false);
     CONTAINER_ENSURE_SUCCESS(rv);
@@ -2850,17 +2850,17 @@ RasterImage::SyncDecode()
   // disallow this type of call in the API, and check for it in API methods.
   NS_ABORT_IF_FALSE(!mInDecoder, "Yikes, forcing sync in reentrant call!");
 
   // If we have a size decoder open, or one with different flags than
   // what we need, shut it down
   if (mDecoder &&
       (mDecoder->IsSizeDecode() || mDecoder->GetDecodeFlags() != mFrameDecodeFlags))
   {
-    rv = ShutdownDecoder(eShutdownIntent_Interrupted);
+    rv = ShutdownDecoder(eShutdownIntent_NotNeeded);
     CONTAINER_ENSURE_SUCCESS(rv);
   }
 
   // If we don't have a decoder, create one 
   if (!mDecoder) {
     NS_ABORT_IF_FALSE(mFrames.IsEmpty(), "Trying to decode to non-empty frame-array");
     rv = InitDecoder(/* aDoSizeDecode = */ false);
     CONTAINER_ENSURE_SUCCESS(rv);
@@ -3157,17 +3157,17 @@ RasterImage::UnlockImage()
   // and our lock count is now zero (so nothing is forcing us to keep the
   // decoded data around), try to cancel the decode and throw away whatever
   // we've decoded.
   if (mHasBeenDecoded && mDecoder &&
       mLockCount == 0 && CanForciblyDiscard()) {
     PR_LOG(GetCompressedImageAccountingLog(), PR_LOG_DEBUG,
            ("RasterImage[0x%p] canceling decode because image "
             "is now unlocked.", this));
-    ShutdownDecoder(eShutdownIntent_Interrupted);
+    ShutdownDecoder(eShutdownIntent_NotNeeded);
     ForceDiscard();
     return NS_OK;
   }
 
   // Otherwise, we might still be a candidate for discarding in the future.  If
   // we are, add ourselves to the discard tracker.
   if (CanDiscard()) {
     nsresult rv = DiscardTracker::Reset(&mDiscardTrackerNode);
--- a/image/src/RasterImage.h
+++ b/image/src/RasterImage.h
@@ -316,17 +316,17 @@ public:
   // Call this with a finished ScaleRequest to set this RasterImage's scale
   // result. Give it a ScaleStatus of SCALE_DONE if everything succeeded, and
   // SCALE_INVALID otherwise.
   void ScalingDone(ScaleRequest* request, ScaleStatus status);
 
   // Decoder shutdown
   enum eShutdownIntent {
     eShutdownIntent_Done        = 0,
-    eShutdownIntent_Interrupted = 1,
+    eShutdownIntent_NotNeeded   = 1,
     eShutdownIntent_Error       = 2,
     eShutdownIntent_AllCount    = 3
   };
 
 private:
   struct Anim
   {
     //! Area of the first frame that needs to be redrawn on subsequent loops.
--- a/image/src/imgRequest.cpp
+++ b/image/src/imgRequest.cpp
@@ -12,17 +12,19 @@
  * gets changed.
  * This #undef needs to be in multiple places because we don't always pull
  * headers in in the same order.
  */
 #undef LoadImage
 
 #include "imgLoader.h"
 #include "imgRequestProxy.h"
+#include "imgStatusTracker.h"
 #include "ImageFactory.h"
+#include "Image.h"
 
 #include "imgILoader.h"
 
 #include "netCore.h"
 
 #include "nsIChannel.h"
 #include "nsICachingChannel.h"
 #include "nsILoadGroup.h"
--- a/image/src/imgTools.cpp
+++ b/image/src/imgTools.cpp
@@ -16,16 +16,17 @@
 #include "nsStringStream.h"
 #include "nsComponentManagerUtils.h"
 #include "nsWeakReference.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsStreamUtils.h"
 #include "nsNetUtil.h"
 #include "nsContentUtils.h"
 #include "ImageFactory.h"
+#include "Image.h"
 #include "ScriptedNotificationObserver.h"
 #include "imgIScriptedNotificationObserver.h"
 
 using namespace mozilla::image;
 
 class nsIDOMDocument;
 class nsIDocument;
 
--- a/image/test/crashtests/ownerdiscard.html
+++ b/image/test/crashtests/ownerdiscard.html
@@ -33,11 +33,15 @@
     imgLoadingContent.addObserver(gObserver);
 
     SpecialPowers.setBoolPref('min_discard_timeout_ms', 1);
 
     function initCF() {
       setTimeout(function() { document.adoptNode(tCF0); }, 0);
     }
     document.addEventListener("DOMContentLoaded", initCF, false);
+    function finish() {
+      setTimeout("document.documentElement.className = '';", 30000);
+    }
+    window.addEventListener("load", finish, false);
   </script>
 </body>
 </html>
--- a/ipc/app/Makefile.in
+++ b/ipc/app/Makefile.in
@@ -72,20 +72,16 @@ ifeq ($(OS_ARCH),WINNT) #{
 #
 # The default heap size is 1MB on Win32.
 # The heap will grow if need be.
 #
 # Set it to 256k.  See bug 127069.
 #
 ifndef GNU_CC #{
 LDFLAGS += /HEAP:0x40000
-ifeq ($(OS_TEST),x86_64) #{
-# set stack to 2MB on x64 build.  See bug 582910
-LDFLAGS += -STACK:2097152
-endif #}
 endif #}
 endif #}
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) #{
 
 libs::
 	$(NSINSTALL) -D $(DIST)/bin/$(PROGRAM).app
 	rsync -a -C --exclude "*.in" $(srcdir)/macbuild/Contents $(DIST)/bin/$(PROGRAM).app 
--- a/js/public/HashTable.h
+++ b/js/public/HashTable.h
@@ -166,16 +166,19 @@ class HashMap
     // Table resize may occur in Enum's destructor. Also see the definition of
     // Enum in HashTable above (with T = Entry).
     typedef typename Impl::Enum Enum;
 
     // Remove all entries. This does not shrink the table. For that consider
     // using the finish() method.
     void clear()                                      { impl.clear(); }
 
+    // Remove all entries without triggering destructors. This method is unsafe.
+    void clearWithoutCallingDestructors()             { impl.clearWithoutCallingDestructors(); }
+
     // Remove all the entries and release all internal buffers. The map must
     // be initialized again before any use.
     void finish()                                     { impl.finish(); }
 
     // Does the table contain any entries?
     bool empty() const                                { return impl.empty(); }
 
     // Number of live elements in the map.
@@ -615,16 +618,17 @@ class HashTableEntry
         Swap(mem, other->mem);
     }
 
     T &get() { JS_ASSERT(isLive()); return *mem.addr(); }
 
     bool isFree() const    { return keyHash == sFreeKey; }
     void clearLive()       { JS_ASSERT(isLive()); keyHash = sFreeKey; mem.addr()->~T(); }
     void clear()           { if (isLive()) mem.addr()->~T(); keyHash = sFreeKey; }
+    void clearNoDtor()     { keyHash = sFreeKey; }
     bool isRemoved() const { return keyHash == sRemovedKey; }
     void removeLive()      { JS_ASSERT(isLive()); keyHash = sRemovedKey; mem.addr()->~T(); }
     bool isLive() const    { return isLiveHash(keyHash); }
     void setCollision()               { JS_ASSERT(isLive()); keyHash |= sCollisionBit; }
     void setCollision(HashNumber bit) { JS_ASSERT(isLive()); keyHash |= bit; }
     void unsetCollision()             { keyHash &= ~sCollisionBit; }
     bool hasCollision() const         { return keyHash & sCollisionBit; }
     bool matchHash(HashNumber hn)     { return (keyHash & ~sCollisionBit) == hn; }
@@ -1257,16 +1261,30 @@ class HashTable : private AllocPolicy
             for (Entry *e = table, *end = table + tableCapacity; e < end; ++e)
                 e->clear();
         }
         removedCount = 0;
         entryCount = 0;
         mutationCount++;
     }
 
+    void clearWithoutCallingDestructors()
+    {
+        if (mozilla::IsPod<Entry>::value) {
+            memset(table, 0, sizeof(*table) * capacity());
+        } else {
+            uint32_t tableCapacity = capacity();
+            for (Entry *e = table, *end = table + tableCapacity; e < end; ++e)
+                e->clearNoDtor();
+        }
+        removedCount = 0;
+        entryCount = 0;
+        mutationCount++;
+    }
+
     void finish()
     {
         JS_ASSERT(!entered);
 
         if (!table)
             return;
 
         destroyTable(*this, table, capacity());
--- a/js/public/MemoryMetrics.h
+++ b/js/public/MemoryMetrics.h
@@ -131,16 +131,17 @@ struct RuntimeSizes
     size_t ionCode;
     size_t regexpCode;
     size_t unusedCode;
     size_t regexpData;
     size_t stack;
     size_t gcMarker;
     size_t mathCache;
     size_t scriptFilenames;
+    size_t scriptData;
     size_t scriptSources;
 };
 
 struct CompartmentStats
 {
     CompartmentStats()
       : extra1(0)
       , extra2(0)
new file mode 100644
--- /dev/null
+++ b/js/public/RequiredDefines.h
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=79:
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Various #defines required to build SpiderMonkey.  Embedders should add this
+ * file to the start of the command line via -include or a similar mechanism,
+ * or SpiderMonkey public headers may not work correctly.
+ */
+
+#ifndef js_RequiredDefines_h___
+#define js_RequiredDefines_h___
+
+/*
+ * The c99 defining the limit macros (UINT32_MAX for example), says:
+ * C++ implementations should define these macros only when __STDC_LIMIT_MACROS
+ * is defined before <stdint.h> is included.
+ */
+#define __STDC_LIMIT_MACROS
+
+#endif /* js_RequiredDefines_h___ */
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -228,16 +228,17 @@ EXPORTS_js = \
 		Anchor.h \
 		CharacterEncoding.h \
 		GCAPI.h \
 		HashTable.h \
 		HeapAPI.h \
 		LegacyIntTypes.h \
 		MemoryMetrics.h \
 		PropertyKey.h \
+		RequiredDefines.h \
 		TemplateLib.h \
 		Utility.h \
 		Value.h \
 		Vector.h \
 		$(NULL)
 
 ###############################################
 # BEGIN enable non-releasable features
@@ -836,19 +837,80 @@ js-config: js-config.in Makefile $(DEPTH
 	-e 's|$(at)NSPR_CFLAGS$(at)|$(NSPR_CFLAGS)|' \
 	-e 's|$(at)JS_CONFIG_LIBS$(at)|$(JS_CONFIG_LIBS)|' \
 	-e 's|$(at)MOZ_JS_LIBS$(at)|$(MOZ_JS_LIBS)|' \
 	&& mv js-config.tmp $@ && chmod +x $@
 
 SCRIPTS = js-config
 SDK_BINARY = js-config
 
+######################################################
+# BEGIN SpiderMonkey header installation
+#
+# Mozilla/Gecko/Firefox mostly doesn't concern itself with defining a sensible
+# install target, because it's shipping primarily packaged builds.  And even if
+# it did, those builds wouldn't really have reason to include header files.  So
+# we have to install public headers ourselves, rather than using something from
+# config/rules.mk or similar.
+#
+# The overall directory structure of the installed headers looks like so:
+#
+#   $(includedir)/
+#      $(MODULE)/
+#        jsapi.h, jspubtd.h, etc. (all of INSTALLED_HEADERS)
+#        js/
+#          js/public/* headers (all are public)
+#        ds/
+#          js/src/ds/* public headers
+#        gc/
+#          js/src/gc/* public headers
+#        mozilla/
+#          mfbt headers
+#
+# Currently $(MODULE) is just js, but we'll soon be changing it to include the
+# SpiderMonkey version, so that headers for multiple SpiderMonkey installs can
+# exist on a system at once.  (This permits embedders depending on system
+# SpiderMonkey to independently update their embeddings to newer SpiderMonkey
+# releases at different paces.)
+#
+# It is expected that embedders will then add -I$(includedir)/$(MODULE) to
+# their compiler invocations, which will then expose all of jsapi.h and friends
+# as they've always been exported.  (This will happen naturally for anyone using
+# pkgconfig systems to determine compiler/linker flags and the like.)  Headers
+# in subdirectories will show up as "mozilla/Assertions.h" and so on.  Also,
+# this system keeps #include "js/CharacterEncoding.h" in internal headers
+# working -- not that this is required, but it does simplify things.  (At some
+# point we may want to convert SpiderMonkey, and maybe Gecko, to this system, in
+# the interest of being a more conventional embedder, but it's probably a ways
+# off.)
+#
+# Eventually we'll probably trim this structure down to having the mfbt headers
+# in mozilla/, and every SpiderMonkey-specific header in js/*.  In the meantime
+# this is the structure implemented below.
+#
+
 install:: $(INSTALLED_HEADERS)
 	$(SYSINSTALL) $^ $(DESTDIR)$(includedir)/$(MODULE)
 
+install:: $(EXPORTS_ds)
+	$(SYSINSTALL) $^ $(DESTDIR)$(includedir)/$(MODULE)/ds
+
+install:: $(EXPORTS_gc)
+	$(SYSINSTALL) $^ $(DESTDIR)$(includedir)/$(MODULE)/gc
+
+install:: $(EXPORTS_js)
+	$(SYSINSTALL) $^ $(DESTDIR)$(includedir)/$(MODULE)/js
+
+install:: $(EXPORTS_mozilla)
+	$(SYSINSTALL) $^ $(DESTDIR)$(includedir)/$(MODULE)/mozilla
+
+#
+# END SpiderMonkey header installation
+#############################################
+
 install:: $(SCRIPTS)
 	$(SYSINSTALL) $^ $(DESTDIR)$(bindir)
 
 install:: $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY)
 ifneq (,$(LIBRARY))
 	$(SYSINSTALL) $(LIBRARY) $(DESTDIR)$(libdir)
 endif
 ifneq (,$(SHARED_LIBRARY))
@@ -912,16 +974,17 @@ endif
 # Prepare self-hosted JS code for embedding
 export:: selfhosting
 selfhosting:: selfhosted.out.h
 
 selfhosting_srcs := \
   $(srcdir)/builtin/Utilities.js \
   $(srcdir)/builtin/Array.js \
   $(srcdir)/builtin/Intl.js \
+  $(srcdir)/builtin/IntlData.js \
   $(NULL)
 
 selfhosted_out_h_deps := \
   $(selfhosting_srcs) \
   $(srcdir)/js.msg \
   $(srcdir)/builtin/macros.py \
   $(srcdir)/builtin/js2c.py \
   $(srcdir)/builtin/embedjs.py
--- a/js/src/assembler/assembler/MacroAssemblerARM.h
+++ b/js/src/assembler/assembler/MacroAssemblerARM.h
@@ -505,17 +505,17 @@ public:
             JS_ASSERT("What are you trying to do with 16 bits of a pointer?");
         else
             m_assembler.moveImm(imm.m_value, ARMRegisters::S1);
         m_assembler.mem_imm_off(false, false, 16, true, ARMRegisters::S1, ARMRegisters::S0, 0);
     }
 
     void store8(RegisterID src, ImplicitAddress address)
     {
-        m_assembler.dataTransferN(false, false, 16,  src, address.base, address.offset);
+        m_assembler.dataTransferN(false, false, 8,  src, address.base, address.offset);
     }
 
     void store8(RegisterID src, BaseIndex address)
     {
         m_assembler.baseIndexTransferN(false, false, 8, src, address.base, address.index, static_cast<int>(address.scale), address.offset);
     }
 
     void store8(TrustedImm32 imm, BaseIndex address)
@@ -1152,35 +1152,36 @@ public:
     }
 
     void fastLoadDouble(RegisterID lo, RegisterID hi, FPRegisterID fpReg) {
         m_assembler.vmov64(false, true, lo, hi, fpReg);
     }
 
     void loadFloat(ImplicitAddress address, FPRegisterID dest)
     {
+        ASSERT((address.offset & 0x3) == 0);
         // as long as this is a sane mapping, (*2) should just work
-        dest = (FPRegisterID) (dest * 2);
-        ASSERT((address.offset & 0x3) == 0);
-        m_assembler.floatTransfer(true, dest, address.base, address.offset);
-        m_assembler.vcvt(m_assembler.FloatReg32, m_assembler.FloatReg64, (FPRegisterID)(dest*2), dest);
+        m_assembler.floatTransfer(true, floatShadow(dest), address.base, address.offset);
+        m_assembler.vcvt(m_assembler.FloatReg32, m_assembler.FloatReg64, floatShadow(dest), dest);
     }
     void loadFloat(BaseIndex address, FPRegisterID dest)
     {
-        m_assembler.baseIndexFloatTransfer(true, false, (FPRegisterID)(dest*2),
+        FPRegisterID dest_s = floatShadow(dest);
+        m_assembler.baseIndexFloatTransfer(true, false, dest_s,
                                            address.base, address.index,
                                            address.scale, address.offset);
-        m_assembler.vcvt(m_assembler.FloatReg32, m_assembler.FloatReg64, (FPRegisterID)(dest*2), dest);
+        m_assembler.vcvt(m_assembler.FloatReg32, m_assembler.FloatReg64, dest_s, dest);
     }
 
     DataLabelPtr loadFloat(const void* address, FPRegisterID dest)
     {
+        FPRegisterID dest_s = floatShadow(dest);
         DataLabelPtr label = moveWithPatch(ImmPtr(address), ARMRegisters::S0);
-        m_assembler.fmem_imm_off(true, false, true, (FPRegisterID)(dest*2), ARMRegisters::S0, 0);
-        m_assembler.vcvt(m_assembler.FloatReg32, m_assembler.FloatReg64, (FPRegisterID)(dest*2), dest);
+        m_assembler.fmem_imm_off(true, false, true, dest_s, ARMRegisters::S0, 0);
+        m_assembler.vcvt(m_assembler.FloatReg32, m_assembler.FloatReg64, dest_s, dest);
         return label;
     }
  
     void storeDouble(FPRegisterID src, ImplicitAddress address)
     {
         // Store a double at base+offset.
         m_assembler.doubleTransfer(false, src, address.base, address.offset);
     }
@@ -1203,24 +1204,26 @@ public:
         store32(Imm32(imm.u.s.lsb), address);
         store32(Imm32(imm.u.s.msb),
                 BaseIndex(address.base, address.index, address.scale, address.offset + 4));
     }
     void fastStoreDouble(FPRegisterID fpReg, RegisterID lo, RegisterID hi) {
         m_assembler.vmov64(true, true, lo, hi, fpReg);
     }
 
+    // the StoreFloat functions take an FPRegisterID that is really of the corresponding Double register.
+    // but the double has already been converted into a float
     void storeFloat(FPRegisterID src, ImplicitAddress address)
     {
-        m_assembler.floatTransfer(false, src, address.base, address.offset);
+        m_assembler.floatTransfer(false, floatShadow(src), address.base, address.offset);
     }
 
     void storeFloat(FPRegisterID src, BaseIndex address)
     {
-        m_assembler.baseIndexFloatTransfer(false, false, src,
+        m_assembler.baseIndexFloatTransfer(false, false, floatShadow(src),
                                            address.base, address.index,
                                            address.scale, address.offset);
     }
     void storeFloat(ImmDouble imm, Address address)
     {
         union {
             float f;
             uint32_t u32;
@@ -1324,17 +1327,17 @@ public:
         // flds does not worth the effort here
         m_assembler.ldr_un_imm(ARMRegisters::S1, (ARMWord)src.m_ptr);
         m_assembler.dtr_u(true, ARMRegisters::S1, ARMRegisters::S1, 0);
         convertInt32ToDouble(ARMRegisters::S1, dest);
     }
 
     void convertDoubleToFloat(FPRegisterID src, FPRegisterID dest)
     {
-        m_assembler.vcvt(m_assembler.FloatReg64, m_assembler.FloatReg32, src, dest);
+        m_assembler.vcvt(m_assembler.FloatReg64, m_assembler.FloatReg32, src, floatShadow(dest));
     }
 
     Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
     {
         m_assembler.fcmpd_r(left, right);
         m_assembler.fmstat();
         if (cond & DoubleConditionBitSpecial)
             m_assembler.cmp_r(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::VS);
--- a/js/src/build/autoconf/toolchain.m4
+++ b/js/src/build/autoconf/toolchain.m4
@@ -51,20 +51,20 @@ if test "$GXX" = yes; then
    if test "`$CXX -help 2>&1 | grep -c 'Intel(R) C++ Compiler'`" != "0"; then
      INTEL_CXX=1
    fi
 fi
 
 CLANG_CC=
 CLANG_CXX=
 if test "$GCC" = yes; then
-   if test "`$CC -v 2>&1 | grep -c 'clang version'`" != "0"; then
+   if test "`$CC -v 2>&1 | grep -c 'clang version\|Apple.*clang'`" != "0"; then
      CLANG_CC=1
    fi
 fi
 
 if test "$GXX" = yes; then
-   if test "`$CXX -v 2>&1 | grep -c 'clang version'`" != "0"; then
+   if test "`$CXX -v 2>&1 | grep -c 'clang version\|Apple.*clang'`" != "0"; then
      CLANG_CXX=1
    fi
 fi
 AC_SUBST(CLANG_CXX)
 ])
--- a/js/src/builtin/Intl.js
+++ b/js/src/builtin/Intl.js
@@ -430,33 +430,18 @@ function CanonicalizeLocaleList(locales)
     var O = ToObject(locales);
     var len = TO_UINT32(O.length);
     var k = 0;
     while (k < len) {
         // Don't call ToString(k) - SpiderMonkey is faster with integers.
         var kPresent = HasProperty(O, k);
         if (kPresent) {
             var kValue = O[k];
-            if (!(typeof kValue === "string" ||
-                  (typeof kValue === "object" && kValue !== null) ||
-                  // The following is here only because Waldo thinks we really
-                  // have to have it in order to be spec-conformant:
-                  // document.all is an object first implemented in Explorer
-                  // and then in Firefox and other fine browsers, whose
-                  // presence is also used by applications to identify Explorer
-                  // and which therefore has to be falsy in non-Explorer
-                  // browsers. It cloaks itself by pretending its type is
-                  // undefined. Just in case somebody thinks of decorating it
-                  // with a toString method that returns a language tag and
-                  // then passes it in as a locale, we check for its cloak
-                  // here.
-                  (typeof kValue === "undefined" && kValue !== undefined)))
-            {
+            if (!(typeof kValue === "string" || IsObject(kValue)))
                 ThrowError(JSMSG_INVALID_LOCALES_ELEMENT);
-            }
             var tag = ToString(kValue);
             if (!IsStructurallyValidLanguageTag(tag))
                 ThrowError(JSMSG_INVALID_LANGUAGE_TAG, tag);
             tag = CanonicalizeLanguageTag(tag);
             if (seen.indexOf(tag) === -1)
                 seen.push(tag);
         }
         k++;
new file mode 100644
--- /dev/null
+++ b/js/src/builtin/IntlData.js
@@ -0,0 +1,331 @@
+// Generated by make_intl_data.py. DO NOT EDIT.
+
+// Mappings from complete tags to preferred values.
+// Derived from IANA Language Subtag Registry, file date 2013-01-25.
+// http://www.iana.org/assignments/language-subtag-registry
+var langTagMappings = {
+    "art-lojban": "jbo",
+    "cel-gaulish": "cel-gaulish",
+    "en-gb-oed": "en-GB-oed",
+    "i-ami": "ami",
+    "i-bnn": "bnn",
+    "i-default": "i-default",
+    "i-enochian": "i-enochian",
+    "i-hak": "hak",
+    "i-klingon": "tlh",
+    "i-lux": "lb",
+    "i-mingo": "i-mingo",
+    "i-navajo": "nv",
+    "i-pwn": "pwn",
+    "i-tao": "tao",
+    "i-tay": "tay",
+    "i-tsu": "tsu",
+    "ja-latn-hepburn-heploc": "ja-Latn-alalc97",
+    "no-bok": "nb",
+    "no-nyn": "nn",
+    "sgn-be-fr": "sfb",
+    "sgn-be-nl": "vgt",
+    "sgn-br": "bzs",
+    "sgn-ch-de": "sgg",
+    "sgn-co": "csn",
+    "sgn-de": "gsg",
+    "sgn-dk": "dsl",
+    "sgn-es": "ssp",
+    "sgn-fr": "fsl",
+    "sgn-gb": "bfi",
+    "sgn-gr": "gss",
+    "sgn-ie": "isg",
+    "sgn-it": "ise",
+    "sgn-jp": "jsl",
+    "sgn-mx": "mfs",
+    "sgn-ni": "ncs",
+    "sgn-nl": "dse",
+    "sgn-no": "nsl",
+    "sgn-pt": "psr",
+    "sgn-se": "swl",
+    "sgn-us": "ase",
+    "sgn-za": "sfs",
+    "zh-cmn": "cmn",
+    "zh-cmn-hans": "cmn-Hans",
+    "zh-cmn-hant": "cmn-Hant",
+    "zh-gan": "gan",
+    "zh-guoyu": "cmn",
+    "zh-hakka": "hak",
+    "zh-min": "zh-min",
+    "zh-min-nan": "nan",
+    "zh-wuu": "wuu",
+    "zh-xiang": "hsn",
+    "zh-yue": "yue",
+};
+
+// Mappings from non-extlang subtags to preferred values.
+// Derived from IANA Language Subtag Registry, file date 2013-01-25.
+// http://www.iana.org/assignments/language-subtag-registry
+var langSubtagMappings = {
+    "BU": "MM",
+    "DD": "DE",
+    "FX": "FR",
+    "TP": "TL",
+    "YD": "YE",
+    "ZR": "CD",
+    "ayx": "nun",
+    "bjd": "drl",
+    "ccq": "rki",
+    "cjr": "mom",
+    "cka": "cmr",
+    "cmk": "xch",
+    "drh": "khk",
+    "drw": "prs",
+    "gav": "dev",
+    "hrr": "jal",
+    "ibi": "opa",
+    "in": "id",
+    "iw": "he",
+    "ji": "yi",
+    "jw": "jv",
+    "kgh": "kml",
+    "lcq": "ppr",
+    "mo": "ro",
+    "mst": "mry",
+    "myt": "mry",
+    "sca": "hle",
+    "tie": "ras",
+    "tkk": "twm",
+    "tlw": "weo",
+    "tnf": "prs",
+    "ybd": "rki",
+    "yma": "lrr",
+};
+
+// Mappings from extlang subtags to preferred values.
+// Derived from IANA Language Subtag Registry, file date 2013-01-25.
+// http://www.iana.org/assignments/language-subtag-registry
+var extlangMappings = {
+    "aao": {preferred: "aao", prefix: "ar"},
+    "abh": {preferred: "abh", prefix: "ar"},
+    "abv": {preferred: "abv", prefix: "ar"},
+    "acm": {preferred: "acm", prefix: "ar"},
+    "acq": {preferred: "acq", prefix: "ar"},
+    "acw": {preferred: "acw", prefix: "ar"},
+    "acx": {preferred: "acx", prefix: "ar"},
+    "acy": {preferred: "acy", prefix: "ar"},
+    "adf": {preferred: "adf", prefix: "ar"},
+    "ads": {preferred: "ads", prefix: "sgn"},
+    "aeb": {preferred: "aeb", prefix: "ar"},
+    "aec": {preferred: "aec", prefix: "ar"},
+    "aed": {preferred: "aed", prefix: "sgn"},
+    "aen": {preferred: "aen", prefix: "sgn"},
+    "afb": {preferred: "afb", prefix: "ar"},
+    "afg": {preferred: "afg", prefix: "sgn"},
+    "ajp": {preferred: "ajp", prefix: "ar"},
+    "apc": {preferred: "apc", prefix: "ar"},
+    "apd": {preferred: "apd", prefix: "ar"},
+    "arb": {preferred: "arb", prefix: "ar"},
+    "arq": {preferred: "arq", prefix: "ar"},
+    "ars": {preferred: "ars", prefix: "ar"},
+    "ary": {preferred: "ary", prefix: "ar"},
+    "arz": {preferred: "arz", prefix: "ar"},
+    "ase": {preferred: "ase", prefix: "sgn"},
+    "asf": {preferred: "asf", prefix: "sgn"},
+    "asp": {preferred: "asp", prefix: "sgn"},
+    "asq": {preferred: "asq", prefix: "sgn"},
+    "asw": {preferred: "asw", prefix: "sgn"},
+    "auz": {preferred: "auz", prefix: "ar"},
+    "avl": {preferred: "avl", prefix: "ar"},
+    "ayh": {preferred: "ayh", prefix: "ar"},
+    "ayl": {preferred: "ayl", prefix: "ar"},
+    "ayn": {preferred: "ayn", prefix: "ar"},
+    "ayp": {preferred: "ayp", prefix: "ar"},
+    "bbz": {preferred: "bbz", prefix: "ar"},
+    "bfi": {preferred: "bfi", prefix: "sgn"},
+    "bfk": {preferred: "bfk", prefix: "sgn"},
+    "bjn": {preferred: "bjn", prefix: "ms"},
+    "bog": {preferred: "bog", prefix: "sgn"},
+    "bqn": {preferred: "bqn", prefix: "sgn"},
+    "bqy": {preferred: "bqy", prefix: "sgn"},
+    "btj": {preferred: "btj", prefix: "ms"},
+    "bve": {preferred: "bve", prefix: "ms"},
+    "bvl": {preferred: "bvl", prefix: "sgn"},
+    "bvu": {preferred: "bvu", prefix: "ms"},
+    "bzs": {preferred: "bzs", prefix: "sgn"},
+    "cdo": {preferred: "cdo", prefix: "zh"},
+    "cds": {preferred: "cds", prefix: "sgn"},
+    "cjy": {preferred: "cjy", prefix: "zh"},
+    "cmn": {preferred: "cmn", prefix: "zh"},
+    "coa": {preferred: "coa", prefix: "ms"},
+    "cpx": {preferred: "cpx", prefix: "zh"},
+    "csc": {preferred: "csc", prefix: "sgn"},
+    "csd": {preferred: "csd", prefix: "sgn"},
+    "cse": {preferred: "cse", prefix: "sgn"},
+    "csf": {preferred: "csf", prefix: "sgn"},
+    "csg": {preferred: "csg", prefix: "sgn"},
+    "csl": {preferred: "csl", prefix: "sgn"},
+    "csn": {preferred: "csn", prefix: "sgn"},
+    "csq": {preferred: "csq", prefix: "sgn"},
+    "csr": {preferred: "csr", prefix: "sgn"},
+    "czh": {preferred: "czh", prefix: "zh"},
+    "czo": {preferred: "czo", prefix: "zh"},
+    "doq": {preferred: "doq", prefix: "sgn"},
+    "dse": {preferred: "dse", prefix: "sgn"},
+    "dsl": {preferred: "dsl", prefix: "sgn"},
+    "dup": {preferred: "dup", prefix: "ms"},
+    "ecs": {preferred: "ecs", prefix: "sgn"},
+    "esl": {preferred: "esl", prefix: "sgn"},
+    "esn": {preferred: "esn", prefix: "sgn"},
+    "eso": {preferred: "eso", prefix: "sgn"},
+    "eth": {preferred: "eth", prefix: "sgn"},
+    "fcs": {preferred: "fcs", prefix: "sgn"},
+    "fse": {preferred: "fse", prefix: "sgn"},
+    "fsl": {preferred: "fsl", prefix: "sgn"},
+    "fss": {preferred: "fss", prefix: "sgn"},
+    "gan": {preferred: "gan", prefix: "zh"},
+    "gds": {preferred: "gds", prefix: "sgn"},
+    "gom": {preferred: "gom", prefix: "kok"},
+    "gse": {preferred: "gse", prefix: "sgn"},
+    "gsg": {preferred: "gsg", prefix: "sgn"},
+    "gsm": {preferred: "gsm", prefix: "sgn"},
+    "gss": {preferred: "gss", prefix: "sgn"},
+    "gus": {preferred: "gus", prefix: "sgn"},
+    "hab": {preferred: "hab", prefix: "sgn"},
+    "haf": {preferred: "haf", prefix: "sgn"},
+    "hak": {preferred: "hak", prefix: "zh"},
+    "hds": {preferred: "hds", prefix: "sgn"},
+    "hji": {preferred: "hji", prefix: "ms"},
+    "hks": {preferred: "hks", prefix: "sgn"},
+    "hos": {preferred: "hos", prefix: "sgn"},
+    "hps": {preferred: "hps", prefix: "sgn"},
+    "hsh": {preferred: "hsh", prefix: "sgn"},
+    "hsl": {preferred: "hsl", prefix: "sgn"},
+    "hsn": {preferred: "hsn", prefix: "zh"},
+    "icl": {preferred: "icl", prefix: "sgn"},
+    "ils": {preferred: "ils", prefix: "sgn"},
+    "inl": {preferred: "inl", prefix: "sgn"},
+    "ins": {preferred: "ins", prefix: "sgn"},
+    "ise": {preferred: "ise", prefix: "sgn"},
+    "isg": {preferred: "isg", prefix: "sgn"},
+    "isr": {preferred: "isr", prefix: "sgn"},
+    "jak": {preferred: "jak", prefix: "ms"},
+    "jax": {preferred: "jax", prefix: "ms"},
+    "jcs": {preferred: "jcs", prefix: "sgn"},
+    "jhs": {preferred: "jhs", prefix: "sgn"},
+    "jls": {preferred: "jls", prefix: "sgn"},
+    "jos": {preferred: "jos", prefix: "sgn"},
+    "jsl": {preferred: "jsl", prefix: "sgn"},
+    "jus": {preferred: "jus", prefix: "sgn"},
+    "kgi": {preferred: "kgi", prefix: "sgn"},
+    "knn": {preferred: "knn", prefix: "kok"},
+    "kvb": {preferred: "kvb", prefix: "ms"},
+    "kvk": {preferred: "kvk", prefix: "sgn"},
+    "kvr": {preferred: "kvr", prefix: "ms"},
+    "kxd": {preferred: "kxd", prefix: "ms"},
+    "lbs": {preferred: "lbs", prefix: "sgn"},
+    "lce": {preferred: "lce", prefix: "ms"},
+    "lcf": {preferred: "lcf", prefix: "ms"},
+    "liw": {preferred: "liw", prefix: "ms"},
+    "lls": {preferred: "lls", prefix: "sgn"},
+    "lsg": {preferred: "lsg", prefix: "sgn"},
+    "lsl": {preferred: "lsl", prefix: "sgn"},
+    "lso": {preferred: "lso", prefix: "sgn"},
+    "lsp": {preferred: "lsp", prefix: "sgn"},
+    "lst": {preferred: "lst", prefix: "sgn"},
+    "lsy": {preferred: "lsy", prefix: "sgn"},
+    "ltg": {preferred: "ltg", prefix: "lv"},
+    "lvs": {preferred: "lvs", prefix: "lv"},
+    "lzh": {preferred: "lzh", prefix: "zh"},
+    "max": {preferred: "max", prefix: "ms"},
+    "mdl": {preferred: "mdl", prefix: "sgn"},
+    "meo": {preferred: "meo", prefix: "ms"},
+    "mfa": {preferred: "mfa", prefix: "ms"},
+    "mfb": {preferred: "mfb", prefix: "ms"},
+    "mfs": {preferred: "mfs", prefix: "sgn"},
+    "min": {preferred: "min", prefix: "ms"},
+    "mnp": {preferred: "mnp", prefix: "zh"},
+    "mqg": {preferred: "mqg", prefix: "ms"},
+    "mre": {preferred: "mre", prefix: "sgn"},
+    "msd": {preferred: "msd", prefix: "sgn"},
+    "msi": {preferred: "msi", prefix: "ms"},
+    "msr": {preferred: "msr", prefix: "sgn"},
+    "mui": {preferred: "mui", prefix: "ms"},
+    "mzc": {preferred: "mzc", prefix: "sgn"},
+    "mzg": {preferred: "mzg", prefix: "sgn"},
+    "mzy": {preferred: "mzy", prefix: "sgn"},
+    "nan": {preferred: "nan", prefix: "zh"},
+    "nbs": {preferred: "nbs", prefix: "sgn"},
+    "ncs": {preferred: "ncs", prefix: "sgn"},
+    "nsi": {preferred: "nsi", prefix: "sgn"},
+    "nsl": {preferred: "nsl", prefix: "sgn"},
+    "nsp": {preferred: "nsp", prefix: "sgn"},
+    "nsr": {preferred: "nsr", prefix: "sgn"},
+    "nzs": {preferred: "nzs", prefix: "sgn"},
+    "okl": {preferred: "okl", prefix: "sgn"},
+    "orn": {preferred: "orn", prefix: "ms"},
+    "ors": {preferred: "ors", prefix: "ms"},
+    "pel": {preferred: "pel", prefix: "ms"},
+    "pga": {preferred: "pga", prefix: "ar"},
+    "pks": {preferred: "pks", prefix: "sgn"},
+    "prl": {preferred: "prl", prefix: "sgn"},
+    "prz": {preferred: "prz", prefix: "sgn"},
+    "psc": {preferred: "psc", prefix: "sgn"},
+    "psd": {preferred: "psd", prefix: "sgn"},
+    "pse": {preferred: "pse", prefix: "ms"},
+    "psg": {preferred: "psg", prefix: "sgn"},
+    "psl": {preferred: "psl", prefix: "sgn"},
+    "pso": {preferred: "pso", prefix: "sgn"},
+    "psp": {preferred: "psp", prefix: "sgn"},
+    "psr": {preferred: "psr", prefix: "sgn"},
+    "pys": {preferred: "pys", prefix: "sgn"},
+    "rms": {preferred: "rms", prefix: "sgn"},
+    "rsi": {preferred: "rsi", prefix: "sgn"},
+    "rsl": {preferred: "rsl", prefix: "sgn"},
+    "sdl": {preferred: "sdl", prefix: "sgn"},
+    "sfb": {preferred: "sfb", prefix: "sgn"},
+    "sfs": {preferred: "sfs", prefix: "sgn"},
+    "sgg": {preferred: "sgg", prefix: "sgn"},
+    "sgx": {preferred: "sgx", prefix: "sgn"},
+    "shu": {preferred: "shu", prefix: "ar"},
+    "slf": {preferred: "slf", prefix: "sgn"},
+    "sls": {preferred: "sls", prefix: "sgn"},
+    "sqk": {preferred: "sqk", prefix: "sgn"},
+    "sqs": {preferred: "sqs", prefix: "sgn"},
+    "ssh": {preferred: "ssh", prefix: "ar"},
+    "ssp": {preferred: "ssp", prefix: "sgn"},
+    "ssr": {preferred: "ssr", prefix: "sgn"},
+    "svk": {preferred: "svk", prefix: "sgn"},
+    "swc": {preferred: "swc", prefix: "sw"},
+    "swh": {preferred: "swh", prefix: "sw"},
+    "swl": {preferred: "swl", prefix: "sgn"},
+    "syy": {preferred: "syy", prefix: "sgn"},
+    "tmw": {preferred: "tmw", prefix: "ms"},
+    "tse": {preferred: "tse", prefix: "sgn"},
+    "tsm": {preferred: "tsm", prefix: "sgn"},
+    "tsq": {preferred: "tsq", prefix: "sgn"},
+    "tss": {preferred: "tss", prefix: "sgn"},
+    "tsy": {preferred: "tsy", prefix: "sgn"},
+    "tza": {preferred: "tza", prefix: "sgn"},
+    "ugn": {preferred: "ugn", prefix: "sgn"},
+    "ugy": {preferred: "ugy", prefix: "sgn"},
+    "ukl": {preferred: "ukl", prefix: "sgn"},
+    "uks": {preferred: "uks", prefix: "sgn"},
+    "urk": {preferred: "urk", prefix: "ms"},
+    "uzn": {preferred: "uzn", prefix: "uz"},
+    "uzs": {preferred: "uzs", prefix: "uz"},
+    "vgt": {preferred: "vgt", prefix: "sgn"},
+    "vkk": {preferred: "vkk", prefix: "ms"},
+    "vkt": {preferred: "vkt", prefix: "ms"},
+    "vsi": {preferred: "vsi", prefix: "sgn"},
+    "vsl": {preferred: "vsl", prefix: "sgn"},
+    "vsv": {preferred: "vsv", prefix: "sgn"},
+    "wuu": {preferred: "wuu", prefix: "zh"},
+    "xki": {preferred: "xki", prefix: "sgn"},
+    "xml": {preferred: "xml", prefix: "sgn"},
+    "xmm": {preferred: "xmm", prefix: "ms"},
+    "xms": {preferred: "xms", prefix: "sgn"},
+    "yds": {preferred: "yds", prefix: "sgn"},
+    "ysl": {preferred: "ysl", prefix: "sgn"},
+    "yue": {preferred: "yue", prefix: "zh"},
+    "zib": {preferred: "zib", prefix: "sgn"},
+    "zlm": {preferred: "zlm", prefix: "ms"},
+    "zmi": {preferred: "zmi", prefix: "ms"},
+    "zsl": {preferred: "zsl", prefix: "sgn"},
+    "zsm": {preferred: "zsm", prefix: "ms"},
+};
--- a/js/src/builtin/Utilities.js
+++ b/js/src/builtin/Utilities.js
@@ -1,16 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/*jshint bitwise: true, camelcase: false, curly: false, eqeqeq: true, forin: true,
-         immed: true, indent: 4, latedef: false, newcap: false, noarg: true,
-         noempty: true, nonew: true, plusplus: false, quotmark: false, regexp: true,
-         undef: true, unused: false, strict: false, trailing: true,
+/*jshint bitwise: true, camelcase: false, curly: false, eqeqeq: true,
+         es5: true, forin: true, immed: true, indent: 4, latedef: false,
+         newcap: false, noarg: true, noempty: true, nonew: true,
+         plusplus: false, quotmark: false, regexp: true, undef: true,
+         unused: false, strict: false, trailing: true,
 */
 
 /*global ToObject: false, ToInteger: false, IsCallable: false, ThrowError: false,
          AssertionFailed: false, MakeConstructible: false, DecompileArg: false,
          RuntimeDefaultLocale: false,
          callFunction: false,
          IS_UNDEFINED: false, TO_UINT32: false,
          JSMSG_NOT_FUNCTION: false, JSMSG_MISSING_FUN_ARG: false,
@@ -102,16 +103,30 @@ function ToNumber(v) {
 
 /* Spec: ECMAScript Language Specification, 5.1 edition, 9.8 and 15.2.1.1 */
 function ToString(v) {
     assert(arguments.length > 0, "__toString");
     return Std_String(v);
 }
 
 
+/********** Various utility functions **********/
+
+
+/** Returns true iff Type(v) is Object; see ES5 8.6. */
+function IsObject(v) {
+    // Watch out for |typeof null === "object"| as the most obvious pitfall.
+    // But also be careful of SpiderMonkey's objects that emulate undefined
+    // (i.e. |document.all|), which have bogus |typeof| behavior.  Detect
+    // these objects using strict equality, which said bogosity doesn't affect.
+    return (typeof v === "object" && v !== null) ||
+           (typeof v === "undefined" && v !== undefined);
+}
+
+
 /********** Assertions **********/
 
 
 function assert(b, info) {
     if (!b)
         AssertionFailed(info);
 }
 
new file mode 100755
--- /dev/null
+++ b/js/src/builtin/make_intl_data.py
@@ -0,0 +1,199 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+""" Usage: make_intl_data.py [language-subtag-registry.txt]
+
+    This script extracts information about mappings between deprecated and
+    current BCP 47 language tags from the IANA Language Subtag Registry and
+    converts it to JavaScript object definitions in IntlData.js. The definitions
+    are used in Intl.js.
+
+    The IANA Language Subtag Registry is imported from
+    http://www.iana.org/assignments/language-subtag-registry
+    and uses the syntax specified in
+    http://tools.ietf.org/html/rfc5646#section-3
+"""
+
+def readRegistryRecord(registry):
+    """ Yields the records of the IANA Language Subtag Registry as dictionaries. """
+    record = {}
+    for line in registry:
+        line = line.strip()
+        if line == "":
+            continue
+        if line == "%%":
+            yield record
+            record = {}
+        else:
+            if ":" in line:
+                key, value = line.split(":", 1)
+                key, value = key.strip(), value.strip()
+                record[key] = value
+            else:
+                # continuation line
+                record[key] += " " + line
+    if record:
+        yield record
+    return
+
+
+def readRegistry(registry):
+    """ Reads IANA Language Subtag Registry and extracts information for Intl.js.
+
+        Information extracted:
+        - langTagMappings: mappings from complete language tags to preferred
+          complete language tags
+        - langSubtagMappings: mappings from subtags to preferred subtags
+        - extlangMappings: mappings from extlang subtags to preferred subtags,
+          with prefix to be removed
+        Returns these three mappings as dictionaries, along with the registry's
+        file date.
+
+        We also check that mappings for language subtags don't affect extlang
+        subtags and vice versa, so that CanonicalizeLanguageTag doesn't have
+        to separate them for processing. Region codes are separated by case,
+        and script codes by length, so they're unproblematic.
+    """
+    langTagMappings = {}
+    langSubtagMappings = {}
+    extlangMappings = {}
+    languageSubtags = set()
+    extlangSubtags = set()
+
+    for record in readRegistryRecord(registry):
+        if "File-Date" in record:
+            fileDate = record["File-Date"]
+            continue
+
+        if record["Type"] == "grandfathered":
+            # Grandfathered tags don't use standard syntax, so
+            # CanonicalizeLanguageTag expects the mapping table to provide
+            # the final form for all.
+            # For langTagMappings, keys must be in lower case; values in
+            # the case used in the registry.
+            tag = record["Tag"]
+            if "Preferred-Value" in record:
+                langTagMappings[tag.lower()] = record["Preferred-Value"]
+            else:
+                langTagMappings[tag.lower()] = tag
+        elif record["Type"] == "redundant":
+            # For langTagMappings, keys must be in lower case; values in
+            # the case used in the registry.
+            if "Preferred-Value" in record:
+                langTagMappings[record["Tag"].lower()] = record["Preferred-Value"]
+        elif record["Type"] in ("language", "script", "region", "variant"):
+            # For langSubtagMappings, keys and values must be in the case used
+            # in the registry.
+            subtag = record["Subtag"]
+            if record["Type"] == "language":
+                languageSubtags.add(subtag)
+            if "Preferred-Value" in record:
+                if subtag == "heploc":
+                    # The entry for heploc is unique in its complexity; handle
+                    # it as special case below.
+                    continue
+                if "Prefix" in record:
+                    # This might indicate another heploc-like complex case.
+                    raise Exception("Please evaluate: subtag mapping with prefix value.")
+                langSubtagMappings[subtag] = record["Preferred-Value"]
+        elif record["Type"] == "extlang":
+            # For extlangMappings, keys must be in the case used in the
+            # registry; values are records with the preferred value and the
+            # prefix to be removed.
+            subtag = record["Subtag"]
+            extlangSubtags.add(subtag)
+            if "Preferred-Value" in record:
+                preferred = record["Preferred-Value"]
+                prefix = record["Prefix"]
+                extlangMappings[subtag] = {"preferred": preferred, "prefix": prefix}
+        else:
+            # No other types are allowed by
+            # http://tools.ietf.org/html/rfc5646#section-3.1.3
+            assert False, "Unrecognized Type: {0}".format(record["Type"])
+
+    # Check that mappings for language subtags and extlang subtags don't affect
+    # each other.
+    for lang in languageSubtags:
+        if lang in extlangMappings and extlangMappings[lang]["preferred"] != lang:
+            raise Exception("Conflict: lang with extlang mapping: " + lang)
+    for extlang in extlangSubtags:
+        if extlang in langSubtagMappings:
+            raise Exception("Conflict: extlang with lang mapping: " + extlang)
+
+    # Special case for heploc.
+    langTagMappings["ja-latn-hepburn-heploc"] = "ja-Latn-alalc97"
+
+    return {"fileDate": fileDate,
+            "langTagMappings": langTagMappings,
+            "langSubtagMappings": langSubtagMappings,
+            "extlangMappings": extlangMappings}
+
+
+def writeMappingsVar(intlData, dict, name, description, fileDate, url):
+    """ Writes a variable definition with a mapping table to file intlData.
+
+        Writes the contents of dictionary dict to file intlData with the given
+        variable name and a comment with description, fileDate, and URL.
+    """
+    intlData.write("\n")
+    intlData.write("// {0}.\n".format(description))
+    intlData.write("// Derived from IANA Language Subtag Registry, file date {0}.\n".format(fileDate))
+    intlData.write("// {0}\n".format(url))
+    intlData.write("var {0} = {{\n".format(name))
+    keys = sorted(dict)
+    for key in keys:
+        if isinstance(dict[key], basestring):
+            value = '"{0}"'.format(dict[key])
+        else:
+            preferred = dict[key]["preferred"]
+            prefix = dict[key]["prefix"]
+            value = '{{preferred: "{0}", prefix: "{1}"}}'.format(preferred, prefix)
+        intlData.write('    "{0}": {1},\n'.format(key, value))
+    intlData.write("};\n")
+
+
+def writeLanguageTagData(intlData, fileDate, url, langTagMappings, langSubtagMappings, extlangMappings):
+    """ Writes the language tag data to the Intl data file. """
+    writeMappingsVar(intlData, langTagMappings, "langTagMappings",
+                     "Mappings from complete tags to preferred values", fileDate, url)
+    writeMappingsVar(intlData, langSubtagMappings, "langSubtagMappings",
+                     "Mappings from non-extlang subtags to preferred values", fileDate, url)
+    writeMappingsVar(intlData, extlangMappings, "extlangMappings",
+                     "Mappings from extlang subtags to preferred values", fileDate, url)
+
+
+if __name__ == '__main__':
+    import codecs
+    import sys
+    import urllib2
+
+    url = "http://www.iana.org/assignments/language-subtag-registry"
+    if len(sys.argv) > 1:
+        print("Always make sure you have the newest language-subtag-registry.txt!")
+        registry = codecs.open(sys.argv[1], "r", encoding="utf-8")
+    else:
+        print("Downloading IANA Language Subtag Registry...")
+        reader = urllib2.urlopen(url)
+        text = reader.read().decode("utf-8")
+        reader.close()
+        registry = codecs.open("language-subtag-registry.txt", "w+", encoding="utf-8")
+        registry.write(text)
+        registry.seek(0)
+
+    print("Processing IANA Language Subtag Registry...")
+    data = readRegistry(registry)
+    fileDate = data["fileDate"]
+    langTagMappings = data["langTagMappings"]
+    langSubtagMappings = data["langSubtagMappings"]
+    extlangMappings = data["extlangMappings"]
+    registry.close()
+
+    print("Writing Intl data...")
+    intlData = codecs.open("IntlData.js", "w", encoding="utf-8")
+    intlData.write("// Generated by make_intl_data.py. DO NOT EDIT.\n")
+    writeLanguageTagData(intlData, fileDate, url, langTagMappings, langSubtagMappings, extlangMappings)
+    intlData.close()
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -584,16 +584,23 @@ ifdef GNU_CC
 WIN32_EXE_LDFLAGS	+= -mwindows
 else
 WIN32_EXE_LDFLAGS	+= -SUBSYSTEM:WINDOWS
 endif
 endif
 endif
 endif
 
+ifdef _MSC_VER
+ifeq ($(CPU_ARCH),x86_64)
+# set stack to 2MB on x64 build.  See bug 582910
+WIN32_EXE_LDFLAGS	+= -STACK:2097152
+endif
+endif
+
 # If we're building a component on MSVC, we don't want to generate an
 # import lib, because that import lib will collide with the name of a
 # static version of the same library.
 ifeq ($(GNU_LD)$(OS_ARCH),WINNT)
 ifdef IS_COMPONENT
 LDFLAGS += -IMPLIB:fake.lib
 DELETE_AFTER_LINK = fake.lib fake.exp
 endif
--- a/js/src/config/expandlibs_exec.py
+++ b/js/src/config/expandlibs_exec.py
@@ -124,17 +124,17 @@ class ExpandArgsMore(ExpandArgs):
         # gold's --print-icf-sections output looks like the following:
         # ld: ICF folding section '.section' in file 'file.o'into '.section' in file 'file.o'
         # In terms of words, chances are this will change in the future,
         # especially considering "into" is misplaced. Splitting on quotes
         # seems safer.
         for l in stderr.split('\n'):
             quoted = l.split("'")
             if len(quoted) > 5 and quoted[1] != quoted[5]:
-                result[quoted[1]] = quoted[5]
+                result[quoted[1]] = [quoted[5]]
                 if quoted[5] in result:
                     result[quoted[5]].append(quoted[1])
                 else:
                     result[quoted[5]] = [quoted[1]]
         return result
 
     def _getOrderedSections(self, ordered_symbols):
         '''Given an ordered list of symbols, returns the corresponding list
@@ -262,16 +262,24 @@ class SectionFinder(object):
             # We only need to consider cases where "<section>\t<length> <symbol>" is present,
             # and where the [FfO] flag is either F (function) or O (object).
             if len(tmp) > 1 and len(tmp[1]) > 6 and tmp[1][6] in ['O', 'F']:
                 tmp = tmp[1][8:].split()
                 # That gives us ["<section>","<length>", "<symbol>"]
                 syms.append((tmp[-1], tmp[0]))
         return syms
 
+def print_command(out, args):
+    print >>out, "Executing: " + " ".join(args)
+    for tmp in [f for f in args.tmp if os.path.isfile(f)]:
+        print >>out, tmp + ":"
+        with open(tmp) as file:
+            print >>out, "".join(["    " + l for l in file.readlines()])
+    out.flush()
+
 def main():
     parser = OptionParser()
     parser.add_option("--depend", dest="depend", metavar="FILE",
         help="generate dependencies for the given execution and store it in the given file")
     parser.add_option("--target", dest="target", metavar="FILE",
         help="designate the target for dependencies")
     parser.add_option("--extract", action="store_true", dest="extract",
         help="when a library has no descriptor file, extract it first, when possible")
@@ -297,25 +305,25 @@ def main():
         if options.extract:
             args.extract()
         if options.symbol_order:
             args.orderSymbols(options.symbol_order)
         if options.uselist:
             args.makelist()
 
         if options.verbose:
-            print >>sys.stderr, "Executing: " + " ".join(args)
-            for tmp in [f for f in args.tmp if os.path.isfile(f)]:
-                print >>sys.stderr, tmp + ":"
-                with open(tmp) as file:
-                    print >>sys.stderr, "".join(["    " + l for l in file.readlines()])
-            sys.stderr.flush()
-        ret = subprocess.call(args)
-        if ret:
-            exit(ret)
+            print_command(sys.stderr, args)
+        proc = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
+        (stdout, stderr) = proc.communicate()
+        if proc.returncode and not options.verbose:
+            print_command(sys.stderr, args)
+        sys.stderr.write(stdout)
+        sys.stderr.flush()
+        if proc.returncode:
+            exit(proc.returncode)
     if not options.depend:
         return
     ensureParentDir(options.depend)
     with open(options.depend, 'w') as depfile:
         depfile.write("%s : %s\n" % (options.target, ' '.join(dep for dep in deps if os.path.isfile(dep) and dep != options.target)))
 
 
 if __name__ == '__main__':
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -2086,17 +2086,17 @@ x86_64*-*)
     AC_DEFINE(JS_CPU_X64)
     AC_DEFINE(JS_PUNBOX64)
     ;;
 arm*-*)
     ENABLE_METHODJIT=1
     ENABLE_ION=1
     ENABLE_MONOIC=1
     ENABLE_POLYIC=1
-    ENABLE_POLYIC_TYPED_ARRAY=1
+    ENABLE_METHODJIT_TYPED_ARRAY=1
     AC_DEFINE(JS_CPU_ARM)
     AC_DEFINE(JS_NUNBOX32)
     ;;
 sparc*-*)
     if test ! "$HAVE_64BIT_OS" ; then
     ENABLE_METHODJIT=1
     ENABLE_MONOIC=1
     ENABLE_POLYIC=1
--- a/js/src/ion/Bailouts.cpp
+++ b/js/src/ion/Bailouts.cpp
@@ -489,17 +489,17 @@ ion::RecompileForInlining()
     IonSpew(IonSpew_Inlining, "Recompiling script to inline calls %s:%d", script->filename,
             script->lineno);
 
     // Invalidate the script to force a recompile.
     if (!Invalidate(cx, script, /* resetUses */ false))
         return BAILOUT_RETURN_FATAL_ERROR;
 
     // Invalidation should not reset the use count.
-    JS_ASSERT(script->getUseCount() >= js_IonOptions.usesBeforeInlining);
+    JS_ASSERT(script->getUseCount() >= js_IonOptions.usesBeforeInlining());
 
     return true;
 }
 
 // Initialize the decl env Object and the call object of the current frame.
 bool
 ion::EnsureHasScopeObjects(JSContext *cx, StackFrame *fp)
 {
--- a/js/src/ion/Ion.h
+++ b/js/src/ion/Ion.h
@@ -94,20 +94,20 @@ struct IonOptions
 
     // How many invocations or loop iterations are needed before functions
     // are compiled when JM is disabled.
     //
     // Default: 40
     uint32_t usesBeforeCompileNoJaeger;
 
     // How many invocations or loop iterations are needed before calls
-    // are inlined.
+    // are inlined, as a fraction of usesBeforeCompile.
     //
-    // Default: 10,240
-    uint32_t usesBeforeInlining;
+    // Default: .125
+    double usesBeforeInliningFactor;
 
     // How many actual arguments are accepted on the C stack.
     //
     // Default: 4,096
     uint32_t maxStackArgs;
 
     // The maximum inlining depth.
     //
@@ -128,33 +128,24 @@ struct IonOptions
     //
     // The default for this was arrived at empirically via benchmarking.
     // We may want to tune it further after other optimizations have gone
     // in.
     //
     // Default: 100
     uint32_t smallFunctionMaxBytecodeLength;
 
-    // The inlining limit for small functions.
-    //
-    // This value has been arrived at empirically via benchmarking.
-    // We may want to revisit this tuning after other optimizations have
-    // gone in.
-    //
-    // Default: usesBeforeInlining / 4
-    uint32_t smallFunctionUsesBeforeInlining;
-
     // The maximum number of functions to polymorphically inline at a call site.
     //
     // Default: 4
     uint32_t polyInlineMax;
 
     // The maximum total bytecode size of an inline call site.
     //
-    // Default: 800
+    // Default: 1000
     uint32_t inlineMaxTotalBytecodeLength;
 
     // Minimal ratio between the use counts of the caller and the callee to
     // enable inlining of functions.
     //
     // Default: 128
     uint32_t inlineUseCountRatio;
 
@@ -179,20 +170,16 @@ struct IonOptions
     //
     // Default: 1
     uint32_t usesBeforeCompileParallel;
 
     void setEagerCompilation() {
         eagerCompilation = true;
         usesBeforeCompile = usesBeforeCompileNoJaeger = 0;
 
-        // Eagerly inline calls to improve test coverage.
-        usesBeforeInlining = 0;
-        smallFunctionUsesBeforeInlining = 0;
-
         parallelCompilation = false;
     }
 
     IonOptions()
       : gvn(true),
         gvnIsOptimistic(true),
         licm(true),
         osr(true),
@@ -200,31 +187,34 @@ struct IonOptions
         registerAllocator(RegisterAllocator_LSRA),
         inlining(true),
         edgeCaseAnalysis(true),
         rangeAnalysis(true),
         uce(true),
         parallelCompilation(false),
         usesBeforeCompile(10240),
         usesBeforeCompileNoJaeger(40),
-        usesBeforeInlining(usesBeforeCompile),
+        usesBeforeInliningFactor(.125),
         maxStackArgs(4096),
         maxInlineDepth(3),
         smallFunctionMaxInlineDepth(10),
         smallFunctionMaxBytecodeLength(100),
-        smallFunctionUsesBeforeInlining(usesBeforeInlining / 4),
         polyInlineMax(4),
-        inlineMaxTotalBytecodeLength(800),
+        inlineMaxTotalBytecodeLength(1000),
         inlineUseCountRatio(128),
         eagerCompilation(false),
         slowCallLimit(512),
         slowCallIncUseCount(5),
         usesBeforeCompileParallel(1)
     {
     }
+
+    uint32_t usesBeforeInlining() {
+        return usesBeforeCompile * usesBeforeInliningFactor;
+    }
 };
 
 enum MethodStatus
 {
     Method_Error,
     Method_CantCompile,
     Method_Skipped,
     Method_Compiled
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -3094,17 +3094,16 @@ IonBuilder::makeInliningDecision(AutoObj
     //     and size expansion of the ultimately generated code, will be
     //     less significant.
     //  3. Do not inline functions which are not called as frequently as their
     //     callers.
 
     uint32_t callerUses = script()->getUseCount();
 
     uint32_t totalSize = 0;
-    uint32_t checkUses = js_IonOptions.usesBeforeInlining;
     uint32_t maxInlineDepth = js_IonOptions.maxInlineDepth;
     bool allFunctionsAreSmall = true;
     RootedFunction target(cx);
     RootedScript targetScript(cx);
     for (size_t i = 0; i < targets.length(); i++) {
         target = targets[i]->toFunction();
         if (!target->isInterpreted())
             return false;
@@ -3121,25 +3120,23 @@ IonBuilder::makeInliningDecision(AutoObj
 
         if (targetScript->length > 1 && // Always inline the empty script.
             calleeUses * js_IonOptions.inlineUseCountRatio < callerUses)
         {
             IonSpew(IonSpew_Inlining, "Not inlining, callee is not hot");
             return false;
         }
     }
-    if (allFunctionsAreSmall) {
-        checkUses = js_IonOptions.smallFunctionUsesBeforeInlining;
+    if (allFunctionsAreSmall)
         maxInlineDepth = js_IonOptions.smallFunctionMaxInlineDepth;
-    }
 
     if (inliningDepth >= maxInlineDepth)
         return false;
 
-    if (script()->getUseCount() < checkUses) {
+    if (script()->getUseCount() < js_IonOptions.usesBeforeInlining()) {
         IonSpew(IonSpew_Inlining, "Not inlining, caller is not hot");
         return false;
     }
 
     RootedScript scriptRoot(cx, script());
     if (!oracle->canInlineCall(scriptRoot, pc)) {
         IonSpew(IonSpew_Inlining, "Cannot inline due to uninlineable call site");
         return false;
@@ -4784,17 +4781,17 @@ IonBuilder::insertRecompileCheck()
 {
     if (!inliningEnabled())
         return;
 
     if (inliningDepth > 0)
         return;
 
     // Don't recompile if we are already inlining.
-    if (script()->getUseCount() >= js_IonOptions.usesBeforeInlining)
+    if (script()->getUseCount() >= js_IonOptions.usesBeforeInlining())
         return;
 
     // Don't recompile if the oracle cannot provide inlining information
     // or if the script has no calls.
     if (!oracle->canInlineCalls())
         return;
 
     uint32_t minUses = UsesBeforeIonRecompile(script(), pc);
--- a/js/src/ion/IonMacroAssembler.cpp
+++ b/js/src/ion/IonMacroAssembler.cpp
@@ -68,50 +68,94 @@ MacroAssembler::guardTypeSet(const T &ad
 template void MacroAssembler::guardTypeSet(const Address &address, const types::TypeSet *types,
                                            Register scratch, Label *mismatched);
 template void MacroAssembler::guardTypeSet(const ValueOperand &value, const types::TypeSet *types,
                                            Register scratch, Label *mismatched);
 
 void
 MacroAssembler::PushRegsInMask(RegisterSet set)
 {
-    size_t diff = set.gprs().size() * STACK_SLOT_SIZE +
-                  set.fpus().size() * sizeof(double);
-
-    reserveStack(diff);
+    int32_t diffF = set.fpus().size() * sizeof(double);
+    int32_t diffG = set.gprs().size() * STACK_SLOT_SIZE;
 
-    for (GeneralRegisterIterator iter(set.gprs()); iter.more(); iter++) {
-        diff -= STACK_SLOT_SIZE;
-        storePtr(*iter, Address(StackPointer, diff));
+    reserveStack(diffG);
+#ifdef JS_CPU_ARM
+    if (set.gprs().size() > 1) {
+        startDataTransferM(IsStore, StackPointer, IA, NoWriteBack);
+        for (GeneralRegisterIterator iter(set.gprs()); iter.more(); iter++) {
+            diffG -= STACK_SLOT_SIZE;
+            transferReg(*iter);
+        }
+        finishDataTransfer();
+    } else
+#endif
+    {
+        for (GeneralRegisterIterator iter(set.gprs()); iter.more(); iter++) {
+            diffG -= STACK_SLOT_SIZE;
+            storePtr(*iter, Address(StackPointer, diffG));
+        }
     }
+    JS_ASSERT(diffG == 0);
+
+    reserveStack(diffF);
+#ifdef JS_CPU_ARM
+    diffF -= transferMultipleByRuns(set.fpus(), IsStore, StackPointer, IA);
+#else
     for (FloatRegisterIterator iter(set.fpus()); iter.more(); iter++) {
-        diff -= sizeof(double);
-        storeDouble(*iter, Address(StackPointer, diff));
+        diffF -= sizeof(double);
+        storeDouble(*iter, Address(StackPointer, diffF));
     }
+#endif
+    JS_ASSERT(diffF == 0);
 }
 
 void
 MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore)
 {
-    size_t diff = set.gprs().size() * STACK_SLOT_SIZE +
-                  set.fpus().size() * sizeof(double);
-    size_t reserved = diff;
+    int32_t diffG = set.gprs().size() * STACK_SLOT_SIZE;
+    int32_t diffF = set.fpus().size() * sizeof(double);
+    const int32_t reservedG = diffG;
+    const int32_t reservedF = diffF;
 
-    for (GeneralRegisterIterator iter(set.gprs()); iter.more(); iter++) {
-        diff -= STACK_SLOT_SIZE;
-        if (!ignore.has(*iter))
-            loadPtr(Address(StackPointer, diff), *iter);
+#ifdef JS_CPU_ARM
+    // ARM can load multiple registers at once, but only if we want back all
+    // the registers we previously saved to the stack.
+    if (ignore.empty(true)) {
+        diffF -= transferMultipleByRuns(set.fpus(), IsLoad, StackPointer, IA);
+    } else
+#endif
+    {
+        for (FloatRegisterIterator iter(set.fpus()); iter.more(); iter++) {
+            diffF -= sizeof(double);
+            if (!ignore.has(*iter))
+                loadDouble(Address(StackPointer, diffF), *iter);
+        }
     }
-    for (FloatRegisterIterator iter(set.fpus()); iter.more(); iter++) {
-        diff -= sizeof(double);
-        if (!ignore.has(*iter))
-            loadDouble(Address(StackPointer, diff), *iter);
+    freeStack(reservedF);
+    JS_ASSERT(diffF == 0);
+
+#ifdef JS_CPU_ARM
+    if (set.gprs().size() > 1 && ignore.empty(false)) {
+        startDataTransferM(IsLoad, StackPointer, IA, NoWriteBack);
+        for (GeneralRegisterIterator iter(set.gprs()); iter.more(); iter++) {
+            diffG -= STACK_SLOT_SIZE;
+            transferReg(*iter);
+        }
+        finishDataTransfer();
+    } else
+#endif
+    {
+        for (GeneralRegisterIterator iter(set.gprs()); iter.more(); iter++) {
+            diffG -= STACK_SLOT_SIZE;
+            if (!ignore.has(*iter))
+                loadPtr(Address(StackPointer, diffG), *iter);
+        }
     }
-
-    freeStack(reserved);
+    freeStack(reservedG);
+    JS_ASSERT(diffG == 0);
 }
 
 template<typename T>
 void
 MacroAssembler::loadFromTypedArray(int arrayType, const T &src, AnyRegister dest, Register temp,
                                    Label *fail)
 {
     switch (arrayType) {
--- a/js/src/ion/ParallelArrayAnalysis.cpp
+++ b/js/src/ion/ParallelArrayAnalysis.cpp
@@ -64,17 +64,16 @@ using parallel::SpewCompile;
         if (prop->racy())                                                     \
             return true;                                                      \
         return insertWriteGuard(prop, prop->obj());                           \
     }
 
 class ParallelArrayVisitor : public MInstructionVisitor
 {
     JSContext *cx_;
-    ParallelCompileContext &compileContext_;
     MIRGraph &graph_;
     bool unsafe_;
     MDefinition *parSlice_;
 
     bool insertWriteGuard(MInstruction *writeInstruction,
                           MDefinition *valueBeingWritten);
 
     bool replaceWithParNew(MInstruction *newInstruction,
@@ -92,20 +91,19 @@ class ParallelArrayVisitor : public MIns
         JS_ASSERT(!unsafe_);
         unsafe_ = true;
         return true;
     }
 
   public:
     AutoObjectVector callTargets;
 
-    ParallelArrayVisitor(JSContext *cx, ParallelCompileContext &compileContext,
+    ParallelArrayVisitor(JSContext *cx,
                          MIRGraph &graph)
       : cx_(cx),
-        compileContext_(compileContext),
         graph_(graph),
         unsafe_(false),
         parSlice_(NULL),
         callTargets(cx)
     { }
 
     void clearUnsafe() { unsafe_ = false; }
     bool unsafe() { return unsafe_; }
@@ -326,17 +324,17 @@ ParallelCompileContext::analyzeAndGrowWo
 {
     // Walk the basic blocks in a DFS.  When we encounter a block with an
     // unsafe instruction, then we know that this block will bailout when
     // executed.  Therefore, we replace the block.
     //
     // We don't need a worklist, though, because the graph is sorted
     // in RPO.  Therefore, we just use the marked flags to tell us
     // when we visited some predecessor of the current block.
-    ParallelArrayVisitor visitor(cx_, *this, graph);
+    ParallelArrayVisitor visitor(cx_, graph);
     graph.entryBlock()->mark();  // Note: in par. exec., we never enter from OSR.
     uint32_t marked = 0;
     for (ReversePostorderIterator block(graph.rpoBegin()); block != graph.rpoEnd(); block++) {
         if (mir->shouldCancel("ParallelArrayAnalysis"))
             return false;
 
         if (block->isMarked()) {
             // Iterate through and transform the instructions.  Stop
--- a/js/src/ion/RegisterSets.h
+++ b/js/src/ion/RegisterSets.h
@@ -313,16 +313,21 @@ class TypedRegisterSet
         return TypedRegisterSet(T::Codes::AllocatableMask & T::Codes::VolatileMask);
     }
     void intersect(TypedRegisterSet other) {
         bits_ &= ~other.bits_;
     }
     bool has(T reg) const {
         return !!(bits_ & (1 << reg.code()));
     }
+    bool hasNextRegister(T reg) const {
+        if (reg.code() == sizeof(bits_)*8)
+            return false;
+        return !!(bits_ & (1 << (reg.code()+1)));
+    }
     void addUnchecked(T reg) {
         bits_ |= (1 << reg.code());
     }
     void add(T reg) {
         JS_ASSERT(!has(reg));
         addUnchecked(reg);
     }
     // Determemine if some register are still allocated.  This function should
@@ -339,22 +344,33 @@ class TypedRegisterSet
         bits_ &= ~(1 << reg.code());
     }
     T getAny() const {
         JS_ASSERT(!empty());
         int ireg;
         JS_FLOOR_LOG2(ireg, bits_);
         return T::FromCode(ireg);
     }
+    T getFirst() const {
+        JS_ASSERT(!empty());
+        int ireg = js_bitscan_ctz32(bits_);
+        return T::FromCode(ireg);
+    }
     T takeAny() {
         JS_ASSERT(!empty());
         T reg = getAny();
         take(reg);
         return reg;
     }
+    T takeFirst() {
+        JS_ASSERT(!empty());
+        T reg = getFirst();
+        take(reg);
+        return reg;
+    }
     void clear() {
         bits_ = 0;
     }
     uint32_t bits() const {
         return bits_;
     }
     uint32_t size() const {
         uint32_t sum2  = (bits_ & 0x55555555) + ((bits_ & 0xaaaaaaaa) >> 1);
@@ -528,16 +544,17 @@ class RegisterSet {
     void maybeTake(TypedOrValueRegister reg) {
         if (reg.hasValue())
             maybeTake(reg.valueReg());
         else if (reg.hasTyped())
             maybeTake(reg.typedReg());
     }
 };
 
+// iterates backwards, that is, rn to r0
 template <typename T>
 class TypedRegisterIterator
 {
     TypedRegisterSet<T> regset_;
 
   public:
     TypedRegisterIterator(TypedRegisterSet<T> regset) : regset_(regset)
     { }
@@ -547,23 +564,58 @@ class TypedRegisterIterator
     bool more() const {
         return !regset_.empty();
     }
     TypedRegisterIterator<T> operator ++(int) {
         TypedRegisterIterator<T> old(*this);
         regset_.takeAny();
         return old;
     }
+    TypedRegisterIterator<T>& operator ++() {
+        regset_.takeAny();
+        return *this;
+    }
     T operator *() const {
         return regset_.getAny();
     }
 };
 
+// iterates forwards, that is r0 to rn
+template <typename T>
+class TypedRegisterForwardIterator
+{
+    TypedRegisterSet<T> regset_;
+
+  public:
+    TypedRegisterForwardIterator(TypedRegisterSet<T> regset) : regset_(regset)
+    { }
+    TypedRegisterForwardIterator(const TypedRegisterForwardIterator &other) : regset_(other.regset_)
+    { }
+
+    bool more() const {
+        return !regset_.empty();
+    }
+    TypedRegisterForwardIterator<T> operator ++(int) {
+        TypedRegisterIterator<T> old(*this);
+        regset_.takeFirst();
+        return old;
+    }
+    TypedRegisterForwardIterator<T>& operator ++() {
+        regset_.takeFirst();
+        return *this;
+    }
+    T operator *() const {
+        return regset_.getFirst();
+    }
+};
+
 typedef TypedRegisterIterator<Register> GeneralRegisterIterator;
 typedef TypedRegisterIterator<FloatRegister> FloatRegisterIterator;
+typedef TypedRegisterForwardIterator<Register> GeneralRegisterForwardIterator;
+typedef TypedRegisterForwardIterator<FloatRegister> FloatRegisterForwardIterator;
 
 class AnyRegisterIterator
 {
     GeneralRegisterIterator geniter_;
     FloatRegisterIterator floatiter_;
 
   public:
     AnyRegisterIterator()
--- a/js/src/ion/arm/Assembler-arm.cpp
+++ b/js/src/ion/arm/Assembler-arm.cpp
@@ -558,17 +558,17 @@ Assembler::getCF32Target(Iter *iter)
         // see if we have a simple case, b #offset
         BOffImm imm;
         InstBranchImm *jumpB = inst1->as<InstBranchImm>();
         jumpB->extractImm(&imm);
         return imm.getDest(inst1)->raw();
     }
 
     if (inst1->is<InstMovW>() && inst2->is<InstMovT>() &&
-        (inst3->is<InstBranchReg>() || inst4->is<InstBranchReg>()))
+        (inst3->is<InstNOP>() || inst3->is<InstBranchReg>() || inst4->is<InstBranchReg>()))
     {
         // see if we have the complex case,
         // movw r_temp, #imm1
         // movt r_temp, #imm2
         // bx r_temp
         // OR
         // movw r_temp, #imm1
         // movt r_temp, #imm2
@@ -587,19 +587,25 @@ Assembler::getCF32Target(Iter *iter)
         // Extract the top part of the immediate.
         InstMovT *top = inst2->as<InstMovT>();
         top->extractImm(&targ_top);
 
         // Make sure they are being loaded into the same register.
         JS_ASSERT(top->checkDest(temp));
 
         // Make sure we're branching to the same register.
-        InstBranchReg *realBranch = inst3->is<InstBranchReg>() ? inst3->as<InstBranchReg>()
-                                                               : inst4->as<InstBranchReg>();
-        JS_ASSERT(realBranch->checkDest(temp));
+#ifdef DEBUG
+        // A toggled call sometimes has a NOP instead of a branch for the third instruction.
+        // No way to assert that it's valid in that situation.
+        if (!inst3->is<InstNOP>()) {
+            InstBranchReg *realBranch = inst3->is<InstBranchReg>() ? inst3->as<InstBranchReg>()
+                                                                   : inst4->as<InstBranchReg>();
+            JS_ASSERT(realBranch->checkDest(temp));
+        }
+#endif
 
         uint32_t *dest = (uint32_t*) (targ_bot.decode() | (targ_top.decode() << 16));
         return dest;
     }
     
     if (inst1->is<InstLDR>()) {
         JS_NOT_REACHED("ldr-based relocs NYI");
     }
--- a/js/src/ion/arm/MacroAssembler-arm.cpp
+++ b/js/src/ion/arm/MacroAssembler-arm.cpp
@@ -1378,16 +1378,47 @@ MacroAssemblerARM::ma_vstr(VFPRegister s
 }
 void
 MacroAssemblerARM::ma_vstr(VFPRegister src, Register base, Register index, int32_t shift, Condition cc)
 {
     as_add(ScratchRegister, base, lsl(index, shift), NoSetCond, cc);
     ma_vstr(src, Operand(ScratchRegister, 0), cc);
 }
 
+
+int32_t
+MacroAssemblerARM::transferMultipleByRuns(FloatRegisterSet set, LoadStore ls,
+                                          Register rm, DTMMode mode)
+{
+    int32_t delta;
+    if (mode == IA) {
+        delta = sizeof(double);
+    } else if (mode == DB) {
+        delta = -sizeof(double);
+    } else {
+        JS_NOT_REACHED("Invalid data transfer addressing mode");
+    }
+
+    int32_t offset = 0;
+    FloatRegisterForwardIterator iter(set);
+    while (iter.more()) {
+        startFloatTransferM(ls, rm, mode, WriteBack);
+        int32_t reg = (*iter).code_;
+        do {
+            offset += delta;
+            transferFloatReg(*iter);
+        } while ((++iter).more() && (*iter).code_ == ++reg);
+        finishFloatTransfer();
+    }
+
+    JS_ASSERT(offset == set.size() * sizeof(double) * (mode == DB ? -1 : 1));
+    ma_sub(Imm32(offset), rm);
+    return offset;
+}
+
 bool
 MacroAssemblerARMCompat::buildFakeExitFrame(const Register &scratch, uint32_t *offset)
 {
     DebugOnly<uint32_t> initialDepth = framePushed();
     uint32_t descriptor = MakeFrameDescriptor(framePushed(), IonFrame_OptimizedJS);
 
     Push(Imm32(descriptor)); // descriptor_
 
@@ -2485,51 +2516,61 @@ MacroAssemblerARMCompat::moveValue(const
 /////////////////////////////////////////////////////////////////
 void
 MacroAssemblerARMCompat::storeValue(ValueOperand val, Operand dst) {
     ma_str(val.payloadReg(), ToPayload(dst));
     ma_str(val.typeReg(), ToType(dst));
 }
 
 void
-MacroAssemblerARMCompat::storeValue(ValueOperand val, Register base, Register index, int32_t shift)
+MacroAssemblerARMCompat::storeValue(ValueOperand val, const BaseIndex &dest)
 {
-    if (isValueDTRDCandidate(val)) {
+    if (isValueDTRDCandidate(val) && (abs(dest.offset) <= 255)) {
         Register tmpIdx;
-        if (shift == 0) {
-            tmpIdx = index;
-        } else if (shift < 0) {
-            ma_asr(Imm32(-shift), index, ScratchRegister);
-            tmpIdx = ScratchRegister;
+        if (dest.offset == 0) {
+            if (dest.scale == TimesOne) {
+                tmpIdx = dest.index;
+            } else {
+                ma_lsl(Imm32(dest.scale), dest.index, ScratchRegister);
+                tmpIdx = ScratchRegister;
+            }
+            ma_strd(val.payloadReg(), val.typeReg(), EDtrAddr(dest.base, EDtrOffReg(tmpIdx)));
         } else {
-            ma_lsl(Imm32(shift), index, ScratchRegister);
-            tmpIdx = ScratchRegister;
+            ma_alu(dest.base, lsl(dest.index, dest.scale), ScratchRegister, op_add);
+            ma_strd(val.payloadReg(), val.typeReg(),
+                    EDtrAddr(ScratchRegister, EDtrOffImm(dest.offset)));
         }
-        ma_strd(val.payloadReg(), val.typeReg(), EDtrAddr(base, EDtrOffReg(tmpIdx)));
     } else {
-        // The ideal case is the base is dead so the sequence:
-        // str val.payloadReg(), [base, index LSL shift]!
-        // str val.typeReg(), [base, #4]
-        // only clobbers dead registers
-        // Sadly, this information is not available, so the scratch register is necessary.
-        ma_alu(base, lsl(index, shift), ScratchRegister, op_add);
-
-        // This case is handled by a simpler function.
-        storeValue(val, Address(ScratchRegister, 0));
+        ma_alu(dest.base, lsl(dest.index, dest.scale), ScratchRegister, op_add);
+        storeValue(val, Address(ScratchRegister, dest.offset));
     }
 }
 
 void
-MacroAssemblerARMCompat::loadValue(Register base, Register index, ValueOperand val, Imm32 off)
+MacroAssemblerARMCompat::loadValue(const BaseIndex &addr, ValueOperand val)
 {
-
-    ma_alu(base, lsl(index, TimesEight), ScratchRegister, op_add);
-
-    // This case is handled by a simpler function.
-    loadValue(Address(ScratchRegister, off.value), val);
+    if (isValueDTRDCandidate(val) && (abs(addr.offset) <= 255)) {
+        Register tmpIdx;
+        if (addr.offset == 0) {
+            if (addr.scale == TimesOne) {
+                tmpIdx = addr.index;
+            } else {
+                ma_lsl(Imm32(addr.scale), addr.index, ScratchRegister);
+                tmpIdx = ScratchRegister;
+            }
+            ma_ldrd(EDtrAddr(addr.base, EDtrOffReg(tmpIdx)), val.payloadReg(), val.typeReg());
+        } else {
+            ma_alu(addr.base, lsl(addr.index, addr.scale), ScratchRegister, op_add);
+            ma_ldrd(EDtrAddr(ScratchRegister, EDtrOffImm(addr.offset)),
+                    val.payloadReg(), val.typeReg());
+        }
+    } else {
+        ma_alu(addr.base, lsl(addr.index, addr.scale), ScratchRegister, op_add);
+        loadValue(Address(ScratchRegister, addr.offset), val);
+    }
 }
 
 void
 MacroAssemblerARMCompat::loadValue(Address src, ValueOperand val)
 {
     Operand srcOp = Operand(src);
     Operand payload = ToPayload(srcOp);
     Operand type = ToType(srcOp);
--- a/js/src/ion/arm/MacroAssembler-arm.h
+++ b/js/src/ion/arm/MacroAssembler-arm.h
@@ -325,16 +325,24 @@ class MacroAssemblerARM : public Assembl
     // calls an Ion function, assumes that the stack is untouched (8 byte alinged)
     void ma_callIon(const Register reg);
     // callso an Ion function, assuming that sp has already been decremented
     void ma_callIonNoPush(const Register reg);
     // calls an ion function, assuming that the stack is currently not 8 byte aligned
     void ma_callIonHalfPush(const Register reg);
 
     void ma_call(void *dest);
+
+    // Float registers can only be loaded/stored in continuous runs
+    // when using vstm/vldm.
+    // This function breaks set into continuous runs and loads/stores
+    // them at [rm]. rm will be modified, but returned to its initial value.
+    // Returns the offset from [dm] for the logical next load/store.
+    int32_t transferMultipleByRuns(FloatRegisterSet set, LoadStore ls,
+                                   Register rm, DTMMode mode);
 };
 
 class MacroAssemblerARMCompat : public MacroAssemblerARM
 {
     // Number of bytes the stack is adjusted inside a call to C. Calls to C may
     // not be nested.
     bool inCall_;
     uint32_t args_;
@@ -777,36 +785,31 @@ class MacroAssemblerARMCompat : public M
             loadInt32OrDouble(address.base, address.index, dest.fpu(), address.scale);
         else
             load32(address, dest.gpr());
     }
 
     void moveValue(const Value &val, const ValueOperand &dest);
 
     void storeValue(ValueOperand val, Operand dst);
-    void storeValue(ValueOperand val, Register base, Register index, int32_t shift = defaultShift);
+    void storeValue(ValueOperand val, const BaseIndex &dest);
+    void storeValue(JSValueType type, Register reg, BaseIndex dest) {
+        // Harder cases not handled yet.
+        JS_ASSERT(dest.offset == 0);
+        ma_alu(dest.base, lsl(dest.index, dest.scale), ScratchRegister, op_add);
+        storeValue(type, reg, Address(ScratchRegister, 0));
+    }
     void storeValue(ValueOperand val, const Address &dest) {
         storeValue(val, Operand(dest));
     }
     void storeValue(JSValueType type, Register reg, Address dest) {
         ma_mov(ImmTag(JSVAL_TYPE_TO_TAG(type)), secondScratchReg_);
         ma_str(secondScratchReg_, Address(dest.base, dest.offset + 4));
         ma_str(reg, dest);
     }
-    void storeValue(JSValueType type, Register reg, BaseIndex dest) {
-        // Harder cases not handled yet.
-        JS_ASSERT(dest.offset == 0);
-        ma_alu(dest.base, lsl(dest.index, dest.scale), ScratchRegister, op_add);
-        storeValue(type, reg, Address(ScratchRegister, 0));
-    }
-    void storeValue(ValueOperand val, const BaseIndex &dest) {
-        // Harder cases not handled yet.
-        JS_ASSERT(dest.offset == 0);
-        storeValue(val, dest.base, dest.index);
-    }
     void storeValue(const Value &val, Address dest) {
         jsval_layout jv = JSVAL_TO_IMPL(val);
         ma_mov(Imm32(jv.s.tag), secondScratchReg_);
         ma_str(secondScratchReg_, Address(dest.base, dest.offset + 4));
         if (val.isMarkable())
             ma_mov(ImmGCPtr(reinterpret_cast<gc::Cell *>(val.toGCThing())), secondScratchReg_);
         else
             ma_mov(Imm32(jv.s.payload.i32), secondScratchReg_);
@@ -818,20 +821,17 @@ class MacroAssemblerARMCompat : public M
         ma_alu(dest.base, lsl(dest.index, dest.scale), ScratchRegister, op_add);
         storeValue(val, Address(ScratchRegister, 0));
     }
 
     void loadValue(Address src, ValueOperand val);
     void loadValue(Operand dest, ValueOperand val) {
         loadValue(dest.toAddress(), val);
     }
-    void loadValue(Register base, Register index, ValueOperand val, Imm32 of);
-    void loadValue(const BaseIndex &addr, ValueOperand val) {
-        loadValue(addr.base, addr.index, val, Imm32(addr.offset));
-    }
+    void loadValue(const BaseIndex &addr, ValueOperand val);
     void tagValue(JSValueType type, Register payload, ValueOperand dest);
 
     void pushValue(ValueOperand val);
     void popValue(ValueOperand val);
     void pushValue(const Value &val) {
         jsval_layout jv = JSVAL_TO_IMPL(val);
         push(Imm32(jv.s.tag));
         if (val.isMarkable())
--- a/js/src/jit-test/tests/basic/testOverRecursed3.js
+++ b/js/src/jit-test/tests/basic/testOverRecursed3.js
@@ -1,6 +1,6 @@
 // |jit-test| error:InternalError
 
-x = [];
-x.push(x);
+var x = [];
+x.push(x, x); // more than one so the sort can't be optimized away
 x.toString = x.sort;
 x.toString();
--- a/js/src/js-confdefs.h.in
+++ b/js/src/js-confdefs.h.in
@@ -3,15 +3,11 @@
  * Do not edit.
  */
 
 #ifndef _JS_CONFDEFS_H_
 #define _JS_CONFDEFS_H_
 
 @ALLDEFINES@
 
-/* The c99 defining the limit macros (UINT32_MAX for example), says:
- * C++ implementations should define these macros only when __STDC_LIMIT_MACROS
- * is defined before <stdint.h> is included. */
-#define __STDC_LIMIT_MACROS
+#include "js/RequiredDefines.h"
 
 #endif /* _JS_CONFDEFS_H_ */
-
--- a/js/src/jsanalyze.cpp
+++ b/js/src/jsanalyze.cpp
@@ -452,16 +452,17 @@ ScriptAnalysis::analyzeBytecode(JSContex
           case JSOP_GETELEM:
           case JSOP_CALLELEM:
             numPropertyReads_++;
             break;
 
           /* Additional opcodes which can be compiled but which can't be inlined. */
           case JSOP_ARGUMENTS:
           case JSOP_FUNAPPLY:
+          case JSOP_CALLEE:
             isJaegerInlineable = false;
             break;
           case JSOP_THROW:
           case JSOP_EXCEPTION:
           case JSOP_DEBUGGER:
           case JSOP_FUNCALL:
             isIonInlineable = isJaegerInlineable = false;
             break;
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -941,16 +941,19 @@ JSRuntime::init(uint32_t maxbytes)
     dateTimeInfo.updateTimeZoneAdjustment();
 
     if (!stackSpace.init())
         return false;
 
     if (!scriptFilenameTable.init())
         return false;
 
+    if (!scriptDataTable.init())
+        return false;
+
     if (!threadPool.init())
         return false;
 
 #ifdef JS_THREADSAFE
     if (useHelperThreads() && !sourceCompressorThread.init())
         return false;
 #endif
 
@@ -967,16 +970,17 @@ JSRuntime::~JSRuntime()
     clearOwnerThread();
 #endif
 
     /*
      * Even though all objects in the compartment are dead, we may have keep
      * some filenames around because of gcKeepAtoms.
      */
     FreeScriptFilenames(this);
+    FreeScriptData(this);
 
 #ifdef JS_THREADSAFE
 # ifdef JS_ION
     if (workerThreadState)
         js_delete(workerThreadState);
 # endif
     sourceCompressorThread.finish();
 #endif
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -1253,16 +1253,248 @@ SortComparatorFunction::operator()(const
      * XXX eport some kind of error here if cmp is NaN? ECMA talks about
      * 'consistent compare functions' that don't return NaN, but is silent
      * about what the result should be. So we currently ignore it.
      */
     *lessOrEqualp = (MOZ_DOUBLE_IS_NaN(cmp) || cmp <= 0);
     return true;
 }
 
+struct NumericElement
+{
+    double dv;
+    size_t elementIndex;
+};
+
+bool
+ComparatorNumericLeftMinusRight(const NumericElement &a, const NumericElement &b,
+                                bool *lessOrEqualp)
+{
+    *lessOrEqualp = (a.dv <= b.dv);
+    return true;
+}
+
+bool
+ComparatorNumericRightMinusLeft(const NumericElement &a, const NumericElement &b,
+                                bool *lessOrEqualp)
+{
+    *lessOrEqualp = (b.dv <= a.dv);
+    return true;
+}
+
+typedef bool (*ComparatorNumeric)(const NumericElement &a, const NumericElement &b,
+                                  bool *lessOrEqualp);
+
+ComparatorNumeric SortComparatorNumerics[] = {
+    NULL,
+    ComparatorNumericLeftMinusRight,
+    ComparatorNumericRightMinusLeft
+};
+
+bool
+ComparatorInt32LeftMinusRight(const Value &a, const Value &b, bool *lessOrEqualp)
+{
+    *lessOrEqualp = (a.toInt32() <= b.toInt32());
+    return true;
+}
+
+bool
+ComparatorInt32RightMinusLeft(const Value &a, const Value &b, bool *lessOrEqualp)
+{
+    *lessOrEqualp = (b.toInt32() <= a.toInt32());
+    return true;
+}
+
+typedef bool (*ComparatorInt32)(const Value &a, const Value &b, bool *lessOrEqualp);
+
+ComparatorInt32 SortComparatorInt32s[] = {
+    NULL,
+    ComparatorInt32LeftMinusRight,
+    ComparatorInt32RightMinusLeft
+};
+
+enum ComparatorMatchResult {
+    Match_None = 0,
+    Match_LeftMinusRight,
+    Match_RightMinusLeft
+};
+
+/*
+ * Specialize behavior for comparator functions with particular common bytecode
+ * patterns: namely, |return x - y| and |return y - x|.
+ */
+ComparatorMatchResult
+MatchNumericComparator(const Value &v)
+{
+    AutoAssertNoGC nogc;
+
+    if (!v.isObject())
+        return Match_None;
+
+    JSObject &obj = v.toObject();
+    if (!obj.isFunction())
+        return Match_None;
+
+    JSFunction *fun = obj.toFunction();
+    if (!fun->hasScript())
+        return Match_None;
+
+    UnrootedScript script = fun->nonLazyScript();
+    jsbytecode *pc = script->code;
+
+    uint16_t arg0, arg1;
+    if (JSOp(*pc) != JSOP_GETARG)
+        return Match_None;
+    arg0 = GET_ARGNO(pc);
+    pc += JSOP_GETARG_LENGTH;
+
+    if (JSOp(*pc) != JSOP_GETARG)
+        return Match_None;
+    arg1 = GET_ARGNO(pc);
+    pc += JSOP_GETARG_LENGTH;
+
+    if (JSOp(*pc) != JSOP_SUB)
+        return Match_None;
+    pc += JSOP_SUB_LENGTH;
+
+    if (JSOp(*pc) != JSOP_RETURN)
+        return Match_None;
+
+    if (arg0 == 0 && arg1 == 1)
+        return Match_LeftMinusRight;
+
+    if (arg0 == 1 && arg1 == 0)
+        return Match_RightMinusLeft;
+
+    return Match_None;
+}
+
+template<typename K, typename C>
+inline bool
+MergeSortByKey(K keys, size_t len, K scratch, C comparator, AutoValueVector *vec)
+{
+    MOZ_ASSERT(vec->length() >= len);
+
+    /* Sort keys. */
+    if (!MergeSort(keys, len, scratch, comparator))
+        return false;
+
+    /*
+     * Reorder vec by keys in-place, going element by element.  When an out-of-
+     * place element is encountered, move that element to its proper position,
+     * displacing whatever element was at *that* point to its proper position,
+     * and so on until an element must be moved to the current position.
+     *
+     * At each outer iteration all elements up to |i| are sorted.  If
+     * necessary each inner iteration moves some number of unsorted elements
+     * (including |i|) directly to sorted position.  Thus on completion |*vec|
+     * is sorted, and out-of-position elements have moved once.  Complexity is
+     * Θ(len) + O(len) == O(2*len), with each element visited at most twice.
+     */
+    for (size_t i = 0; i < len; i++) {
+        size_t j = keys[i].elementIndex;
+        if (i == j)
+            continue; // fixed point
+
+        MOZ_ASSERT(j > i, "Everything less than |i| should be in the right place!");
+        Value tv = (*vec)[j];
+        do {
+            size_t k = keys[j].elementIndex;
+            keys[j].elementIndex = j;
+            (*vec)[j] = (*vec)[k];
+            j = k;
+        } while (j != i);
+
+        // We could assert the loop invariant that |i == keys[i].elementIndex|
+        // here if we synced |keys[i].elementIndex|.  But doing so would render
+        // the assertion vacuous, so don't bother, even in debug builds.
+        (*vec)[i] = tv;
+    }
+
+    return true;
+}
+
+/*
+ * Sort Values as strings.
+ *
+ * To minimize #conversions, SortLexicographically() first converts all Values
+ * to strings at once, then sorts the elements by these cached strings.
+ */
+bool
+SortLexicograp