Merge from mozilla-inbound.
authorJan de Mooij <jdemooij@mozilla.com>
Mon, 25 Mar 2013 10:27:13 +0100
changeset 127440 492e87516012a79a258cd6b40c6872510406f1ee
parent 127437 d4656be592193788b86288abab6fbdf73c4aca3a (current diff)
parent 126103 5b7ed1616c6229c10e6ce8f20cbf463835c1a36c (diff)
child 127441 63c079713c45354b16cfef357446ffca523ee809
push id24503
push userjandemooij@gmail.com
push dateWed, 03 Apr 2013 15:43:00 +0000
treeherdermozilla-central@b5cb88ccd907 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone22.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 from mozilla-inbound.
accessible/src/windows/msaa/nsAccessNodeWrap.h
content/svg/content/src/SVGFEConvolveMatrixElement.cpp
content/svg/content/src/SVGFEConvolveMatrixElement.h
content/svg/content/src/SVGFEDiffuseLightingElement.cpp
content/svg/content/src/SVGFEDiffuseLightingElement.h
content/svg/content/src/SVGFEDisplacementMapElement.cpp
content/svg/content/src/SVGFEDisplacementMapElement.h
content/svg/content/src/SVGFEOffsetElement.cpp
content/svg/content/src/SVGFEOffsetElement.h
content/svg/content/src/SVGFESpecularLightingElement.cpp
content/svg/content/src/SVGFESpecularLightingElement.h
content/svg/content/src/SVGFESpotLightElement.cpp
content/svg/content/src/SVGFESpotLightElement.h
content/svg/content/src/nsSVGFilters.cpp
dom/base/nsJSEnvironment.cpp
js/src/Makefile.in
js/src/gc/RootMarking.cpp
js/src/gc/Zone.cpp
js/src/ion/CodeGenerator.cpp
js/src/ion/Ion.cpp
js/src/ion/Ion.h
js/src/ion/IonBuilder.cpp
js/src/ion/IonBuilder.h
js/src/ion/IonCaches.cpp
js/src/ion/IonCode.h
js/src/ion/IonMacroAssembler.cpp
js/src/ion/IonMacroAssembler.h
js/src/ion/RegisterSets.h
js/src/ion/arm/MacroAssembler-arm.cpp
js/src/ion/arm/MacroAssembler-arm.h
js/src/ion/shared/Assembler-shared.h
js/src/jsapi.h
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jsfun.cpp
js/src/jsgc.cpp
js/src/jsinfer.cpp
js/src/jsinterp.cpp
js/src/jsobj.cpp
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jsscriptinlines.h
js/src/tests/ecma_3/Number/15.7.4.3-02.js
js/src/vm/Debugger.cpp
js/src/vm/ObjectImpl-inl.h
js/src/vm/ObjectImpl.h
js/src/vm/ParallelDo.cpp
js/src/vm/ScopeObject.cpp
js/src/vm/SelfHosting.cpp
js/src/vm/Stack.h
js/xpconnect/src/XPCJSRuntime.cpp
mobile/android/base/GeckoAppWidgetProvider.java.in
mobile/android/base/NotificationService.java
mobile/android/base/NotificationServiceClient.java
mobile/android/base/resources/drawable-hdpi/appwidget_bg.9.png
mobile/android/base/resources/drawable-mdpi/appwidget_bg.9.png
mobile/android/base/resources/drawable-xhdpi/appwidget_bg.9.png
mobile/android/base/resources/layout/gecko_appwidget.xml
mobile/android/base/resources/xml/gecko_appwidget_info.xml
mobile/android/branding/aurora/android-resources-hdpi.mn
mobile/android/branding/aurora/android-resources-xhdpi.mn
mobile/android/branding/aurora/content/hdpi/widget_icon.png
mobile/android/branding/aurora/content/mdpi/widget_icon.png
mobile/android/branding/aurora/content/xhdpi/widget_icon.png
mobile/android/branding/beta/android-resources-hdpi.mn
mobile/android/branding/beta/android-resources-xhdpi.mn
mobile/android/branding/beta/content/hdpi/widget_icon.png
mobile/android/branding/beta/content/mdpi/widget_icon.png
mobile/android/branding/beta/content/xhdpi/widget_icon.png
mobile/android/branding/nightly/android-resources-hdpi.mn
mobile/android/branding/nightly/android-resources-xhdpi.mn
mobile/android/branding/nightly/content/hdpi/widget_icon.png
mobile/android/branding/nightly/content/mdpi/widget_icon.png
mobile/android/branding/nightly/content/xhdpi/widget_icon.png
mobile/android/branding/official/android-resources-hdpi.mn
mobile/android/branding/official/android-resources-xhdpi.mn
mobile/android/branding/official/content/hdpi/widget_icon.png
mobile/android/branding/official/content/mdpi/widget_icon.png
mobile/android/branding/official/content/xhdpi/widget_icon.png
mobile/android/branding/unofficial/android-resources-hdpi.mn
mobile/android/branding/unofficial/android-resources-xhdpi.mn
mobile/android/branding/unofficial/content/hdpi/widget_icon.png
mobile/android/branding/unofficial/content/mdpi/widget_icon.png
mobile/android/branding/unofficial/content/xhdpi/widget_icon.png
modules/libpref/src/init/all.js
netwerk/base/src/nsMediaFragmentURIParser.cpp
netwerk/base/src/nsMediaFragmentURIParser.h
xpcom/stub/Makefile.in
xpcom/tests/static-checker/OverrideFail1.cpp
xpcom/tests/static-checker/OverrideFail2.cpp
xpcom/tests/static-checker/OverrideFail3.cpp
xpcom/tests/static-checker/OverrideFail4.cpp
xpcom/tests/static-checker/OverrideOK1.cpp
xpcom/tests/static-checker/OverrideOK2.cpp
xpcom/tests/static-checker/OverrideOK3-NamespaceTypedef.cpp
--- a/CLOBBER
+++ b/CLOBBER
@@ -14,9 +14,9 @@
 #          O <-- Clobber   O  <-- Clobber
 #
 # Note: The description below will be part of the error message shown to users.
 #
 #  *** Important! ***
 #  If changing this file you must manually clobber immediately before landing,
 #  (due to bug 837323), using: https://secure.pub.build.mozilla.org/clobberer/
 #
-Bug 844654 changed all the Makefiles.
+Bug 737100 broke Windows builds.
--- a/accessible/build/Makefile.in
+++ b/accessible/build/Makefile.in
@@ -10,17 +10,16 @@ VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 LIBRARY_NAME	= accessibility
 EXPORT_LIBRARY = 1
 SHORT_LIBNAME	= access
 IS_COMPONENT	= 1
 MODULE_NAME	= nsAccessibilityModule
-GRE_MODULE	= 1
 LIBXUL_LIBRARY	= 1
 
 CPPSRCS		= nsAccessibilityFactory.cpp
 
 LOCAL_INCLUDES	= -I$(srcdir)/../src
 
 SHARED_LIBRARY_LIBS = \
   ../src/base/$(LIB_PREFIX)accessibility_base_s.$(LIB_SUFFIX) \
--- a/accessible/public/Makefile.in
+++ b/accessible/public/Makefile.in
@@ -5,16 +5,15 @@
 
 DEPTH   = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH   = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-GRE_MODULE	= 1
 
 EXPORTS		= \
       nsIAccessibilityService.h \
       $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
--- a/accessible/public/ia2/Makefile.in
+++ b/accessible/public/ia2/Makefile.in
@@ -3,17 +3,16 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 LIBRARY_NAME  = IA2Marshal
-GRE_MODULE    = 1
 DEFFILE       = $(win_srcdir)/IA2Marshal.def
 
 IA2DIR        = $(topsrcdir)/other-licenses/ia2
 
 include $(DEPTH)/config/autoconf.mk
 
 DEFINES       += -DREGISTER_PROXY_DLL
 
--- a/accessible/public/msaa/Makefile.in
+++ b/accessible/public/msaa/Makefile.in
@@ -3,17 +3,16 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 LIBRARY_NAME	= AccessibleMarshal
-GRE_MODULE   = 1
 DEFFILE = $(win_srcdir)/AccessibleMarshal.def
 
 include $(DEPTH)/config/autoconf.mk
 
 DEFINES += -DREGISTER_PROXY_DLL
 
 GARBAGE += $(MIDL_GENERATED_FILES) done_gen dlldata.c
 
--- a/accessible/src/base/FocusManager.cpp
+++ b/accessible/src/base/FocusManager.cpp
@@ -149,16 +149,20 @@ FocusManager::NotifyOfDOMBlur(nsISupport
   // If DOM document stays focused then fire accessible focus event to process
   // the case when no element within this DOM document will be focused.
   nsCOMPtr<nsINode> targetNode(do_QueryInterface(aTarget));
   if (targetNode && targetNode->OwnerDoc() == FocusedDOMDocument()) {
     nsIDocument* DOMDoc = targetNode->OwnerDoc();
     DocAccessible* document =
       GetAccService()->GetDocAccessible(DOMDoc);
     if (document) {
+      // Clear selection listener for previously focused element.
+      if (targetNode->IsElement())
+        SelectionMgr()->ClearControlSelectionListener();
+
       document->HandleNotification<FocusManager, nsINode>
         (this, &FocusManager::ProcessDOMFocus, DOMDoc);
     }
   }
 }
 
 void
 FocusManager::ActiveItemChanged(Accessible* aItem, bool aCheckIfActive)
--- a/accessible/src/base/SelectionManager.cpp
+++ b/accessible/src/base/SelectionManager.cpp
@@ -31,27 +31,23 @@ SelectionManager::Shutdown()
   ClearControlSelectionListener();
   mLastTextAccessible = nullptr;
   mLastUsedSelection = nullptr;
 }
 
 void
 SelectionManager::ClearControlSelectionListener()
 {
-  if (!mCurrentControl)
+  if (!mCurrCtrlFrame)
     return;
 
-  nsIFrame* frame = mCurrentControl->GetPrimaryFrame();
-  if (!frame)
-    return;
+  const nsFrameSelection* frameSel = mCurrCtrlFrame->GetConstFrameSelection();
+  NS_ASSERTION(frameSel, "No frame selection for the element!");
 
-  mCurrentControl = nullptr;
-
-  const nsFrameSelection* frameSel = frame->GetConstFrameSelection();
-  NS_ASSERTION(frameSel, "No frame selection for the element!");
+  mCurrCtrlFrame = nullptr;
   if (!frameSel)
     return;
 
   // Remove 'this' registered as selection listener for the normal selection.
   Selection* normalSel =
     frameSel->GetSelection(nsISelectionController::SELECTION_NORMAL);
   normalSel->RemoveSelectionListener(this);
 
@@ -65,24 +61,23 @@ SelectionManager::ClearControlSelectionL
 void
 SelectionManager::SetControlSelectionListener(dom::Element* aFocusedElm)
 {
   // When focus moves such that the caret is part of a new frame selection
   // this removes the old selection listener and attaches a new one for
   // the current focus.
   ClearControlSelectionListener();
 
-  mCurrentControl = aFocusedElm;
   mLastTextAccessible = nullptr;
 
-  nsIFrame* frame = aFocusedElm->GetPrimaryFrame();
-  if (!frame)
+  mCurrCtrlFrame = aFocusedElm->GetPrimaryFrame();
+  if (!mCurrCtrlFrame)
     return;
 
-  const nsFrameSelection* frameSel = frame->GetConstFrameSelection();
+  const nsFrameSelection* frameSel = mCurrCtrlFrame->GetConstFrameSelection();
   NS_ASSERTION(frameSel, "No frame selection for focused element!");
   if (!frameSel)
     return;
 
   // Register 'this' as selection listener for the normal selection.
   Selection* normalSel =
     frameSel->GetSelection(nsISelectionController::SELECTION_NORMAL);
   normalSel->AddSelectionListener(this);
--- a/accessible/src/base/SelectionManager.h
+++ b/accessible/src/base/SelectionManager.h
@@ -2,16 +2,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/. */
 
 #ifndef mozilla_a11y_SelectionManager_h__
 #define mozilla_a11y_SelectionManager_h__
 
 #include "nsAutoPtr.h"
+#include "nsIFrame.h"
 #include "nsISelectionListener.h"
 
 class nsIContent;
 class nsIntRect;
 class nsIPresShell;
 class nsIWeakReference;
 class nsIWidget;
 
@@ -96,17 +97,17 @@ protected:
   /**
    * Process spellcheck selection change and fire text attribute changed event
    * for invalid text attribute.
    */
   void SpellcheckSelectionChanged(nsISelection* aSelection);
 
 private:
   // Currently focused control.
-  nsCOMPtr<nsIContent> mCurrentControl;
+  nsWeakFrame mCurrCtrlFrame;
 
   // Info for the the last selection event.
   // If it was on a control, then its control's selection. Otherwise, it's for
   // a document where the selection changed.
   nsCOMPtr<nsIWeakReference> mLastUsedSelection; // Weak ref to nsISelection
   nsRefPtr<HyperTextAccessible> mLastTextAccessible;
   int32_t mLastCaretOffset;
 };
--- a/accessible/src/base/TreeWalker.h
+++ b/accessible/src/base/TreeWalker.h
@@ -2,17 +2,18 @@
 /* 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_a11y_TreeWalker_h_
 #define mozilla_a11y_TreeWalker_h_
 
 #include "nsAutoPtr.h"
-#include "nsIContent.h"
+
+class nsIContent;
 
 namespace mozilla {
 namespace a11y {
 
 class Accessible;
 class DocAccessible;
 
 struct WalkState;
--- a/accessible/src/base/nsTextEquivUtils.h
+++ b/accessible/src/base/nsTextEquivUtils.h
@@ -4,20 +4,20 @@
 /* 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 _nsTextEquivUtils_H_
 #define _nsTextEquivUtils_H_
 
 #include "Accessible.h"
+#include "nsIStringBundle.h"
 #include "Role.h"
 
-#include "nsIContent.h"
-#include "nsIStringBundle.h"
+class nsIContent;
 
 /**
  * Text equivalent computation rules (see nsTextEquivUtils::gRoleToNameRulesMap)
  */
 enum ETextEquivRule
 {
   // No rule.
   eNoNameRule = 0x00,
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -11,26 +11,25 @@
 #include "mozilla/a11y/States.h"
 #include "nsAccessNodeWrap.h"
 
 #include "nsIAccessible.h"
 #include "nsIAccessibleHyperLink.h"
 #include "nsIAccessibleSelectable.h"
 #include "nsIAccessibleValue.h"
 #include "nsIAccessibleStates.h"
+
 #include "nsIContent.h"
-
 #include "nsStringGlue.h"
 #include "nsTArray.h"
 #include "nsRefPtrHashtable.h"
 
 struct nsRoleMapEntry;
 
 struct nsRect;
-class nsIContent;
 class nsIFrame;
 class nsIAtom;
 class nsView;
 
 namespace mozilla {
 namespace a11y {
 
 class Accessible;
--- a/accessible/src/generic/BaseAccessibles.h
+++ b/accessible/src/generic/BaseAccessibles.h
@@ -3,17 +3,18 @@
  * 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_a11y_BaseAccessibles_h__
 #define mozilla_a11y_BaseAccessibles_h__
 
 #include "AccessibleWrap.h"
 #include "HyperTextAccessibleWrap.h"
-#include "nsIContent.h"
+
+class nsIContent;
 
 /**
   * This file contains a number of classes that are used as base
   *  classes for the different accessibility implementations of
   *  the HTML and XUL widget sets.  --jgaunt
   */
 
 namespace mozilla {
--- a/accessible/src/generic/DocAccessible.cpp
+++ b/accessible/src/generic/DocAccessible.cpp
@@ -1510,25 +1510,25 @@ DocAccessible::ProcessLoad()
   // b) document load event on sub documents causes screen readers to act is if
   // entire page is reloaded.
   if (!IsLoadEventTarget())
     return;
 
   // Fire complete/load stopped if the load event type is given.
   if (mLoadEventType) {
     nsRefPtr<AccEvent> loadEvent = new AccEvent(mLoadEventType, this);
-    nsEventShell::FireEvent(loadEvent);
+    FireDelayedEvent(loadEvent);
 
     mLoadEventType = 0;
   }
 
   // Fire busy state change event.
   nsRefPtr<AccEvent> stateEvent =
     new AccStateChangeEvent(this, states::BUSY, false);
-  nsEventShell::FireEvent(stateEvent);
+  FireDelayedEvent(stateEvent);
 }
 
 void
 DocAccessible::AddDependentIDsFor(dom::Element* aRelProviderElm,
                                   nsIAtom* aRelAttr)
 {
   for (uint32_t idx = 0; idx < kRelationAttrsLen; idx++) {
     nsIAtom* relAttr = *kRelationAttrs[idx];
--- a/accessible/src/generic/HyperTextAccessible.cpp
+++ b/accessible/src/generic/HyperTextAccessible.cpp
@@ -282,17 +282,18 @@ HyperTextAccessible::GetPosAndText(int32
                                           ourContentStart) - ourRenderedStart;
         }
       }
       if (substringEndOffset < 0) {
         // XXX for non-textframe text like list bullets,
         // should go away after list bullet rewrite
         substringEndOffset = nsAccUtils::TextLength(childAcc);
       }
-      if (startOffset < substringEndOffset) {
+      if (startOffset < substringEndOffset ||
+          (startOffset == substringEndOffset && (childIdx == childCount - 1))) {
         // Our start is within this substring
         if (startOffset > 0 || endOffset < substringEndOffset) {
           // We don't want the whole string for this accessible
           // Get out the continuing text frame with this offset
           int32_t outStartLineUnused;
           int32_t contentOffset;
           if (frame->GetType() == nsGkAtoms::textFrame) {
             contentOffset = iter.ConvertSkippedToOriginal(startOffset) +
@@ -687,43 +688,39 @@ HyperTextAccessible::HypertextOffsetsToD
 
 int32_t
 HyperTextAccessible::GetRelativeOffset(nsIPresShell* aPresShell,
                                        nsIFrame* aFromFrame,
                                        int32_t aFromOffset,
                                        Accessible* aFromAccessible,
                                        nsSelectionAmount aAmount,
                                        nsDirection aDirection,
-                                       bool aNeedsStart)
+                                       bool aNeedsStart,
+                                       EWordMovementType aWordMovementType)
 {
   const bool kIsJumpLinesOk = true;          // okay to jump lines
   const bool kIsScrollViewAStop = false;     // do not stop at scroll views
   const bool kIsKeyboardSelect = true;       // is keyboard selection
   const bool kIsVisualBidi = false;          // use visual order for bidi text
 
-  EWordMovementType wordMovementType = aNeedsStart ? eStartWord : eEndWord;
-  if (aAmount == eSelectLine) {
-    aAmount = (aDirection == eDirNext) ? eSelectEndLine : eSelectBeginLine;
-  }
-
   // Ask layout for the new node and offset, after moving the appropriate amount
 
   nsresult rv;
   int32_t contentOffset = aFromOffset;
   nsIFrame *frame = aFromAccessible->GetFrame();
   NS_ENSURE_TRUE(frame, -1);
 
   if (frame->GetType() == nsGkAtoms::textFrame) {
     rv = RenderedToContentOffset(frame, aFromOffset, &contentOffset);
     NS_ENSURE_SUCCESS(rv, -1);
   }
 
   nsPeekOffsetStruct pos(aAmount, aDirection, contentOffset,
                          0, kIsJumpLinesOk, kIsScrollViewAStop, kIsKeyboardSelect, kIsVisualBidi,
-                         wordMovementType);
+                         aWordMovementType);
   rv = aFromFrame->PeekOffset(&pos);
   if (NS_FAILED(rv)) {
     if (aDirection == eDirPrevious) {
       // Use passed-in frame as starting point in failure case for now,
       // this is a hack to deal with starting on a list bullet frame,
       // which fails in PeekOffset() because the line iterator doesn't see it.
       // XXX Need to look at our overall handling of list bullets, which are an odd case
       pos.mResultContent = aFromFrame->GetContent();
@@ -788,65 +785,50 @@ Gets the specified text relative to aBou
 BOUNDARY_CHAR             The character before/at/after the offset is returned.
 BOUNDARY_WORD_START       From the word start before/at/after the offset to the next word start.
 BOUNDARY_WORD_END         From the word end before/at/after the offset to the next work end.
 BOUNDARY_LINE_START       From the line start before/at/after the offset to the next line start.
 BOUNDARY_LINE_END         From the line end before/at/after the offset to the next line start.
 */
 
 nsresult
-HyperTextAccessible::GetTextHelper(EGetTextType aType, AccessibleTextBoundary aBoundaryType,
-                                   int32_t aOffset, int32_t* aStartOffset, int32_t* aEndOffset,
+HyperTextAccessible::GetTextHelper(EGetTextType aType,
+                                   AccessibleTextBoundary aBoundaryType,
+                                   int32_t aOffset,
+                                   int32_t* aStartOffset, int32_t* aEndOffset,
                                    nsAString& aText)
 {
   aText.Truncate();
 
   NS_ENSURE_ARG_POINTER(aStartOffset);
   NS_ENSURE_ARG_POINTER(aEndOffset);
   *aStartOffset = *aEndOffset = 0;
 
-  if (!mDoc)
-    return NS_ERROR_FAILURE;
-
-  nsIPresShell* presShell = mDoc->PresShell();
-  if (!presShell) {
-    return NS_ERROR_FAILURE;
-  }
+  int32_t offset = ConvertMagicOffset(aOffset);
+  if (offset < 0)
+    return NS_ERROR_INVALID_ARG;
 
-  if (aOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT) {
-    aOffset = CharacterCount();
-  }
-  if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET) {
-    GetCaretOffset(&aOffset);
-    if (aOffset > 0 && (aBoundaryType == BOUNDARY_LINE_START ||
-                        aBoundaryType == BOUNDARY_LINE_END)) {
-      // It is the same character offset when the caret is visually at the very end of a line
-      // or the start of a new line. Getting text at the line should provide the line with the visual caret,
-      // otherwise screen readers will announce the wrong line as the user presses up or down arrow and land
-      // at the end of a line.
-      nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
-      if (frameSelection &&
-          frameSelection->GetHint() == nsFrameSelection::HINTLEFT) {
-        -- aOffset;  // We are at the start of a line
-      }
+  if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET && offset > 0 &&
+      (aBoundaryType == BOUNDARY_LINE_START ||
+       aBoundaryType == BOUNDARY_LINE_END)) {
+    // It is the same character offset when the caret is visually at
+    // the very end of a line or the start of a new line. Getting text at
+    // the line should provide the line with the visual caret,
+    // otherwise screen readers will announce the wrong line as the user
+    // presses up or down arrow and land at the end of a line.
+    nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
+    if (frameSelection &&
+        frameSelection->GetHint() == nsFrameSelection::HINTLEFT) {
+      -- offset;  // We are at the start of a line
     }
   }
-  else if (aOffset < 0) {
-    return NS_ERROR_FAILURE;
-  }
 
   nsSelectionAmount amount;
   bool needsStart = false;
   switch (aBoundaryType) {
-    case BOUNDARY_CHAR:
-      amount = eSelectCluster;
-      if (aType == eGetAt)
-        aType = eGetAfter; // Avoid returning 2 characters
-      break;
-
     case BOUNDARY_WORD_START:
       needsStart = true;
       amount = eSelectWord;
       break;
 
     case BOUNDARY_WORD_END:
       amount = eSelectWord;
       break;
@@ -863,67 +845,71 @@ HyperTextAccessible::GetTextHelper(EGetT
       // Newlines are considered at the end of a line. Since getting
       // the BOUNDARY_END_START gets the text from the line-end to the next
       //line-end, the newline is included at the beginning of the string.
       amount = eSelectLine;
       break;
 
     case BOUNDARY_ATTRIBUTE_RANGE:
     {
-      nsresult rv = GetTextAttributes(false, aOffset,
+      nsresult rv = GetTextAttributes(false, offset,
                                       aStartOffset, aEndOffset, nullptr);
       NS_ENSURE_SUCCESS(rv, rv);
       
       return GetText(*aStartOffset, *aEndOffset, aText);
     }
 
     default:  // Note, sentence support is deprecated and falls through to here
       return NS_ERROR_INVALID_ARG;
   }
 
-  int32_t startOffset = aOffset + (aBoundaryType == BOUNDARY_LINE_END);  // Avoid getting the previous line
+  int32_t startOffset = offset + (aBoundaryType == BOUNDARY_LINE_END);  // Avoid getting the previous line
   int32_t endOffset = startOffset;
 
   // Convert offsets to frame-relative
   nsRefPtr<Accessible> startAcc;
   nsIFrame *startFrame = GetPosAndText(startOffset, endOffset, nullptr, nullptr,
                                        nullptr, getter_AddRefs(startAcc));
 
   if (!startFrame) {
     int32_t textLength = CharacterCount();
-    if (aBoundaryType == BOUNDARY_LINE_START && aOffset > 0 && aOffset == textLength) {
+    if (aBoundaryType == BOUNDARY_LINE_START && offset > 0 && offset == textLength) {
       // Asking for start of line, while on last character
       if (startAcc)
         startFrame = startAcc->GetFrame();
     }
     if (!startFrame) {
-      return aOffset > textLength ? NS_ERROR_FAILURE : NS_OK;
+      return offset > textLength ? NS_ERROR_FAILURE : NS_OK;
     }
     else {
       // We're on the last continuation since we're on the last character
       startFrame = startFrame->GetLastContinuation();
     }
   }
 
-  int32_t finalStartOffset, finalEndOffset;
+  int32_t finalStartOffset = 0, finalEndOffset = 0;
+  EWordMovementType wordMovementType = needsStart ? eStartWord : eEndWord;
 
+  nsIPresShell* presShell = mDoc->PresShell();
   // If aType == eGetAt we'll change both the start and end offset from
   // the original offset
   if (aType == eGetAfter) {
-    finalStartOffset = aOffset;
+    finalStartOffset = offset;
   }
   else {
     finalStartOffset = GetRelativeOffset(presShell, startFrame, startOffset,
-                                         startAcc, amount, eDirPrevious,
-                                         needsStart);
+                                         startAcc,
+                                         (amount == eSelectLine ? eSelectBeginLine : amount),
+                                         eDirPrevious, needsStart,
+                                         wordMovementType);
     NS_ENSURE_TRUE(finalStartOffset >= 0, NS_ERROR_FAILURE);
   }
 
   if (aType == eGetBefore) {
-    finalEndOffset = aOffset;
+    finalEndOffset = offset;
   }
   else {
     // Start moving forward from the start so that we don't get 
     // 2 words/lines if the offset occurred on whitespace boundary
     // Careful, startOffset and endOffset are passed by reference to GetPosAndText() and changed
     // For BOUNDARY_LINE_END, make sure we start of this line
     startOffset = endOffset = finalStartOffset + (aBoundaryType == BOUNDARY_LINE_END);
     nsRefPtr<Accessible> endAcc;
@@ -938,86 +924,206 @@ HyperTextAccessible::GetTextHelper(EGetT
 
       endFrame = GetPosAndText(startOffset, endOffset, nullptr, nullptr,
                                nullptr, getter_AddRefs(endAcc));
     }
     if (!endFrame) {
       return NS_ERROR_FAILURE;
     }
     finalEndOffset = GetRelativeOffset(presShell, endFrame, endOffset, endAcc,
-                                       amount, eDirNext, needsStart);
+                                       (amount == eSelectLine ? eSelectEndLine : amount),
+                                       eDirNext, needsStart, wordMovementType);
     NS_ENSURE_TRUE(endOffset >= 0, NS_ERROR_FAILURE);
-    if (finalEndOffset == aOffset) {
+    if (finalEndOffset == offset) {
       if (aType == eGetAt && amount == eSelectWord) { 
         // Fix word error for the first character in word: PeekOffset() will return the previous word when 
-        // aOffset points to the first character of the word, but accessibility APIs want the current word 
+        // offset points to the first character of the word, but accessibility APIs want the current word
         // that the first character is in
-        return GetTextHelper(eGetAfter, aBoundaryType, aOffset, aStartOffset, aEndOffset, aText);
+        return GetTextHelper(eGetAfter, aBoundaryType, offset,
+                             aStartOffset, aEndOffset, aText);
       }
       int32_t textLength = CharacterCount();
       if (finalEndOffset < textLength) {
         // This happens sometimes when current character at finalStartOffset 
         // is an embedded object character representing another hypertext, that
         // the AT really needs to dig into separately
         ++ finalEndOffset;
       }
     }
   }
 
   *aStartOffset = finalStartOffset;
   *aEndOffset = finalEndOffset;
 
-  NS_ASSERTION((finalStartOffset < aOffset && finalEndOffset >= aOffset) || aType != eGetBefore, "Incorrect results for GetTextHelper");
-  NS_ASSERTION((finalStartOffset <= aOffset && finalEndOffset > aOffset) || aType == eGetBefore, "Incorrect results for GetTextHelper");
+  NS_ASSERTION((finalStartOffset < offset && finalEndOffset >= offset) || aType != eGetBefore, "Incorrect results for GetTextHelper");
+  NS_ASSERTION((finalStartOffset <= offset && finalEndOffset > offset) || aType == eGetBefore, "Incorrect results for GetTextHelper");
 
   GetPosAndText(finalStartOffset, finalEndOffset, &aText);
   return NS_OK;
 }
 
 /**
   * nsIAccessibleText impl.
   */
 NS_IMETHODIMP
 HyperTextAccessible::GetTextBeforeOffset(int32_t aOffset,
                                          AccessibleTextBoundary aBoundaryType,
                                          int32_t* aStartOffset,
                                          int32_t* aEndOffset, nsAString& aText)
 {
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
   if (aBoundaryType == BOUNDARY_CHAR) {
     GetCharAt(aOffset, eGetBefore, aText, aStartOffset, aEndOffset);
     return NS_OK;
   }
 
-  return GetTextHelper(eGetBefore, aBoundaryType, aOffset, aStartOffset, aEndOffset, aText);
+  return GetTextHelper(eGetBefore, aBoundaryType, aOffset,
+                       aStartOffset, aEndOffset, aText);
 }
 
 NS_IMETHODIMP
 HyperTextAccessible::GetTextAtOffset(int32_t aOffset,
                                      AccessibleTextBoundary aBoundaryType,
                                      int32_t* aStartOffset,
                                      int32_t* aEndOffset, nsAString& aText)
 {
-  if (aBoundaryType == BOUNDARY_CHAR) {
-    GetCharAt(aOffset, eGetAt, aText, aStartOffset, aEndOffset);
-    return NS_OK;
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsSelectionAmount selectionAmount = eSelectWord;
+  EWordMovementType wordMovementType = eDefaultBehavior;
+  bool forwardBack = true;
+
+  switch (aBoundaryType) {
+    case BOUNDARY_CHAR:
+      return GetCharAt(aOffset, eGetAt, aText, aStartOffset, aEndOffset) ?
+        NS_OK : NS_ERROR_INVALID_ARG;
+
+    case BOUNDARY_WORD_START:
+      wordMovementType = eStartWord;
+      break;
+
+    case BOUNDARY_WORD_END:
+      wordMovementType = eEndWord;
+      forwardBack = false;
+      break;
+
+    case BOUNDARY_LINE_START:
+    case BOUNDARY_LINE_END:
+      return GetTextHelper(eGetAt, aBoundaryType, aOffset,
+                           aStartOffset, aEndOffset, aText);
+      break;
+
+    case BOUNDARY_ATTRIBUTE_RANGE:
+    {
+      nsresult rv = GetTextAttributes(false, aOffset,
+                                      aStartOffset, aEndOffset, nullptr);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      return GetText(*aStartOffset, *aEndOffset, aText);
+    }
+
+    default:
+      return NS_ERROR_INVALID_ARG;
+  }
+
+  int32_t offset = ConvertMagicOffset(aOffset);
+  if (offset < 0)
+    return NS_ERROR_INVALID_ARG;
+
+  uint32_t textLen =  CharacterCount();
+  if (forwardBack) {
+    if (offset == textLen) {
+      *aStartOffset = *aEndOffset = textLen;
+      return NS_OK;
+    }
+  } else {
+    if (offset == 0) {
+      *aStartOffset = *aEndOffset = 0;
+      return NS_OK;
+    }
   }
 
-  return GetTextHelper(eGetAt, aBoundaryType, aOffset, aStartOffset, aEndOffset, aText);
+  // Convert offsets to frame-relative
+  int32_t startOffset = offset, endOffset = offset;
+  nsRefPtr<Accessible> startAcc;
+  nsIFrame* startFrame = GetPosAndText(startOffset, endOffset, nullptr, nullptr,
+                                       nullptr, getter_AddRefs(startAcc));
+  if (!startFrame) {
+    if (offset == textLen) {
+      // Asking for start of line, while on last character
+      if (startAcc)
+        startFrame = startAcc->GetFrame();
+    }
+    NS_ASSERTION(startFrame, "No start frame for text getting!");
+    if (!startFrame)
+      return NS_ERROR_FAILURE;
+
+    // We're on the last continuation since we're on the last character.
+    startFrame = startFrame->GetLastContinuation();
+  }
+
+  offset = GetRelativeOffset(mDoc->PresShell(), startFrame, startOffset,
+                             startAcc, selectionAmount,
+                             (forwardBack ? eDirNext : eDirPrevious),
+                             forwardBack, wordMovementType);
+
+  if (forwardBack)
+    *aEndOffset = offset;
+  else
+    *aStartOffset = offset;
+
+  startOffset = endOffset = offset;
+  startFrame = GetPosAndText(startOffset, endOffset, nullptr, nullptr,
+                             nullptr, getter_AddRefs(startAcc));
+  if (!startFrame) {
+    if (offset == textLen) {
+      // Asking for start of line, while on last character
+      if (startAcc)
+        startFrame = startAcc->GetFrame();
+    }
+    NS_ASSERTION(startFrame, "No start frame for text getting!");
+    if (!startFrame)
+      return NS_ERROR_FAILURE;
+
+    // We're on the last continuation since we're on the last character.
+    startFrame = startFrame->GetLastContinuation();
+  }
+
+  offset = GetRelativeOffset(mDoc->PresShell(), startFrame, startOffset,
+                             startAcc, selectionAmount,
+                             (forwardBack ? eDirPrevious : eDirNext),
+                             forwardBack, wordMovementType);
+
+  if (forwardBack)
+    *aStartOffset = offset;
+  else
+    *aEndOffset = offset;
+
+  return GetText(*aStartOffset, *aEndOffset, aText);
 }
 
 NS_IMETHODIMP
-HyperTextAccessible::GetTextAfterOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType,
-                                        int32_t* aStartOffset, int32_t* aEndOffset, nsAString& aText)
+HyperTextAccessible::GetTextAfterOffset(int32_t aOffset,
+                                        AccessibleTextBoundary aBoundaryType,
+                                        int32_t* aStartOffset,
+                                        int32_t* aEndOffset, nsAString& aText)
 {
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
   if (aBoundaryType == BOUNDARY_CHAR) {
     GetCharAt(aOffset, eGetAfter, aText, aStartOffset, aEndOffset);
     return NS_OK;
   }
 
-  return GetTextHelper(eGetAfter, aBoundaryType, aOffset, aStartOffset, aEndOffset, aText);
+  return GetTextHelper(eGetAfter, aBoundaryType, aOffset,
+                       aStartOffset, aEndOffset, aText);
 }
 
 // nsIPersistentProperties
 // nsIAccessibleText::getTextAttributes(in boolean includeDefAttrs,
 //                                      in long offset,
 //                                      out long rangeStartOffset,
 //                                      out long rangeEndOffset);
 NS_IMETHODIMP
--- a/accessible/src/generic/HyperTextAccessible.h
+++ b/accessible/src/generic/HyperTextAccessible.h
@@ -289,17 +289,18 @@ protected:
     * @param  aDirection       forward or backward?
     * @param  aNeedsStart      for word and line cases, are we basing this on
     *                          the start or end?
     * @return                  the resulting offset into this hypertext
     */
   int32_t GetRelativeOffset(nsIPresShell *aPresShell, nsIFrame *aFromFrame,
                             int32_t aFromOffset, Accessible* aFromAccessible,
                             nsSelectionAmount aAmount, nsDirection aDirection,
-                            bool aNeedsStart);
+                            bool aNeedsStart,
+                            EWordMovementType aWordMovementType);
 
   /**
     * Provides information for substring that is defined by the given start
     * and end offsets for this hyper text.
     *
     * @param  aStartOffset  [inout] the start offset into the hyper text. This
     *                       is also an out parameter used to return the offset
     *                       into the start frame's rendered text content
--- a/accessible/src/generic/RootAccessible.h
+++ b/accessible/src/generic/RootAccessible.h
@@ -4,19 +4,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_a11y_RootAccessible_h__
 #define mozilla_a11y_RootAccessible_h__
 
 #include "HyperTextAccessible.h"
 #include "DocAccessibleWrap.h"
 
-#include "nsIDocument.h"
 #include "nsIDOMEventListener.h"
 
+class nsIDocument;
+
 namespace mozilla {
 namespace a11y {
 
 class RootAccessible : public DocAccessibleWrap,
                        public nsIDOMEventListener
 {
   NS_DECL_ISUPPORTS_INHERITED
 
--- a/accessible/src/windows/msaa/nsAccessNodeWrap.h
+++ b/accessible/src/windows/msaa/nsAccessNodeWrap.h
@@ -18,17 +18,16 @@
 #ifdef _MSC_VER
 #pragma warning( disable : 4509 )
 #endif
 
 #include "nsCOMPtr.h"
 #include "nsIAccessible.h"
 #include "nsIAccessibleEvent.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"
 #endif
 
@@ -38,16 +37,18 @@
   MOZ_SEH_TRY {
 
 #define A11Y_TRYBLOCK_END                                                             \
   } MOZ_SEH_EXCEPT(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),       \
                                                           GetExceptionInformation())) \
   { }                                                                                 \
   return E_FAIL;
 
+class nsIContent;
+
 namespace mozilla {
 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"
--- a/accessible/tests/mochitest/actions/test_link.html
+++ b/accessible/tests/mochitest/actions/test_link.html
@@ -12,22 +12,18 @@
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../events.js"></script>
   <script type="application/javascript"
           src="../actions.js"></script>
 
   <script type="application/javascript">
-    if (navigator.platform.startsWith("Win")) {
-      SimpleTest.expectAssertions(13, 14);
-    } else if (navigator.platform.startsWith("Linux")) {
-      SimpleTest.expectAssertions(18);
-    } else if (navigator.platform.startsWith("Mac")) {
-      SimpleTest.expectAssertions(0, 14);
+    if (navigator.platform.startsWith("Linux")) {
+      SimpleTest.expectAssertions(2);
     }
 
     function getAnchorTargetDocumentAcc()
     {
       var thisTabDocAcc = getTabDocAccessible();
       var thisDocTabPanelAcc = thisTabDocAcc.parent.parent;
       var tabPanelsAcc = thisDocTabPanelAcc.parent;
       var newDocTabPanelAcc = tabPanelsAcc.lastChild.firstChild;
--- a/accessible/tests/mochitest/events.js
+++ b/accessible/tests/mochitest/events.js
@@ -1092,16 +1092,19 @@ function synthKey(aNodeOrID, aKey, aArgs
         key = "left";
         break;
       case "VK_RIGHT":
         key = "right";
         break;
       case "VK_HOME":
         key = "home";
         break;
+      case "VK_END":
+        key = "end";
+        break;
       case "VK_ESCAPE":
         key = "escape";
         break;
       case "VK_RETURN":
         key = "enter";
         break;
     }
     if (aArgs) {
@@ -1178,16 +1181,24 @@ function synthRightKey(aNodeOrID, aCheck
  * Home key invoker.
  */
 function synthHomeKey(aNodeOrID, aCheckerOrEventSeq)
 {
   this.__proto__ = new synthKey(aNodeOrID, "VK_HOME", null, aCheckerOrEventSeq);
 }
 
 /**
+ * End key invoker.
+ */
+function synthEndKey(aNodeOrID, aCheckerOrEventSeq)
+{
+  this.__proto__ = new synthKey(aNodeOrID, "VK_END", null, aCheckerOrEventSeq);
+}
+
+/**
  * Enter key invoker
  */
 function synthEnterKey(aID, aCheckerOrEventSeq)
 {
   this.__proto__ = new synthKey(aID, "VK_RETURN", null, aCheckerOrEventSeq);
 }
 
 /**
@@ -1403,16 +1414,73 @@ function synthSelectAll(aNodeOrID, aChec
 
   this.getID = function synthSelectAll_getID()
   {
     return aNodeOrID + " selectall";
   }
 }
 
 /**
+ * Move the caret to the end of line.
+ */
+function moveToLineEnd(aID, aCaretOffset)
+{
+  if (MAC) {
+    this.__proto__ = new synthKey(aID, "VK_RIGHT", { metaKey: true },
+                                  new caretMoveChecker(aCaretOffset, aID));
+  } else {
+    this.__proto__ = new synthEndKey(aID,
+                                     new caretMoveChecker(aCaretOffset, aID));
+  }
+
+  this.getID = function moveToLineEnd_getID()
+  {
+    return "move to line end in " + prettyName(aID);
+  }
+}
+
+/**
+ * Move the caret to begining of the line.
+ */
+function moveToLineStart(aID, aCaretOffset)
+{
+  if (MAC) {
+    this.__proto__ = new synthKey(aID, "VK_LEFT", { metaKey: true },
+                                  new caretMoveChecker(aCaretOffset, aID));
+  } else {
+    this.__proto__ = new synthHomeKey(aID,
+                                      new caretMoveChecker(aCaretOffset, aID));
+  }
+
+  this.getID = function moveToLineEnd_getID()
+  {
+    return "move to line start in " + prettyName(aID);
+  }
+}
+
+/**
+ * Move the caret to begining of the text.
+ */
+function moveToTextStart(aID)
+{
+  if (MAC) {
+    this.__proto__ = new synthKey(aID, "VK_UP", { metaKey: true },
+                                  new caretMoveChecker(0, aID));
+  } else {
+    this.__proto__ = new synthKey(aID, "VK_HOME", { ctrlKey: true },
+                                  new caretMoveChecker(0, aID));
+  }
+
+  this.getID = function moveToTextStart_getID()
+  {
+    return "move to text start in " + prettyName(aID);
+  }
+}
+
+/**
  * Move the caret in text accessible.
  */
 function moveCaretToDOMPoint(aID, aNode, aOffset, aExpectedOffset,
                              aFocusTargetID)
 {
   this.target = getAccessible(aID, [nsIAccessibleText]);
   this.focus = aFocusTargetID ? getAccessible(aFocusTargetID) : null;
   this.focusNode = this.focus ? this.focus.DOMNode : null;
--- a/accessible/tests/mochitest/events/test_scroll.xul
+++ b/accessible/tests/mochitest/events/test_scroll.xul
@@ -32,18 +32,18 @@
     {
       var tabDoc = aTabIdx ? tabDocumentAt(aTabIdx) : currentTabDocument();
       return tabDoc.querySelector("a[name='link1']");
     }
 
     function loadTab(aURL)
     {
       this.eventSeq = [
-        new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument),
-        new invokerChecker(EVENT_SCROLLING_START, getAnchorJumpInTabDocument)
+        new asyncInvokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument),
+        new asyncInvokerChecker(EVENT_SCROLLING_START, getAnchorJumpInTabDocument)
       ];
 
       this.invoke = function loadTab_invoke()
       {
         tabBrowser().loadURI(aURL);
       }
 
       this.getID = function loadTab_getID()
@@ -90,46 +90,29 @@
       }
     }
 
     //gA11yEventDumpToConsole = true; // debug stuff
 
     var gQueue = null;
     function doTest()
     {
-      var rootDir = getRootDirectory(window.location.href);
-
-      /*
-       * When tests are packed in a .jar, we need to extract them so we 
-       * can access the specific url with a file:// protocol which appears
-       * to be required by loadURI() (at least a file without an embedded .jar)
-       */
-      var jar = getJar(rootDir);
-      if (jar) {
-        var tmpdir = extractJarToTmp(jar);
-        rootDir = "file://" + tmpdir.path + '/';
-      }
-      var url = rootDir + "scroll.html#link1";
-
       gQueue = new eventQueue();
 
+      var url = "http://mochi.test:8888/a11y/accessible/events/scroll.html#link1";
       gQueue.push(new loadTab(url));
       gQueue.push(new loadTabInBackground(url));
       gQueue.push(new switchToBackgroundTab());
       gQueue.onFinish = function() { closeBrowserWindow(); }
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
-    if (!MAC) {
-      SimpleTest.waitForExplicitFinish();
-      openBrowserWindow(doTest);
-    } else {
-      todo(false, "Re-enable on Mac after fixing bug 835338");
-    }
+    SimpleTest.waitForExplicitFinish();
+    openBrowserWindow(doTest);
   ]]>
   </script>
 
   <vbox flex="1" style="overflow: auto;">
     <body xmlns="http://www.w3.org/1999/xhtml">
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=691734"
          title="Make sure scrolling start event is fired when document receive focus">
--- a/accessible/tests/mochitest/text.js
+++ b/accessible/tests/mochitest/text.js
@@ -3,16 +3,19 @@
 
 const BOUNDARY_CHAR = nsIAccessibleText.BOUNDARY_CHAR;
 const BOUNDARY_WORD_START = nsIAccessibleText.BOUNDARY_WORD_START;
 const BOUNDARY_WORD_END = nsIAccessibleText.BOUNDARY_WORD_END;
 const BOUNDARY_LINE_START = nsIAccessibleText.BOUNDARY_LINE_START;
 const BOUNDARY_LINE_END = nsIAccessibleText.BOUNDARY_LINE_END;
 const BOUNDARY_ATTRIBUTE_RANGE = nsIAccessibleText.BOUNDARY_ATTRIBUTE_RANGE;
 
+const kTextEndOffset = nsIAccessibleText.TEXT_OFFSET_END_OF_TEXT;
+const kCaretOffset = nsIAccessibleText.TEXT_OFFSET_CARET;
+
 const kTodo = 1;
 const kOk = 2;
 
 /**
  * Test characterCount for the given array of accessibles.
  *
  * @param aCount  [in] the expected character count
  * @param aIDs    [in] array of accessible identifiers to test
@@ -104,26 +107,39 @@ function testCharAtOffset(aIDs, aOffset,
 /**
  * Test getTextAtOffset function over different elements
  *
  * @param aOffset         [in] the offset to get the text at
  * @param aBoundaryType   [in] Boundary type for text to be retrieved
  * @param aText           [in] expected return text for getTextAtOffset
  * @param aStartOffset    [in] expected return start offset for getTextAtOffset
  * @param aEndOffset      [in] expected return end offset for getTextAtOffset
- * @param ...             [in] list of tuples made of:
+ * @param ...             [in] list of ids or list of tuples made of:
  *                              element identifier
  *                              kTodo or kOk for returned text
  *                              kTodo or kOk for returned start offset
  *                              kTodo or kOk for returned offset result
- *          
  */
 function testTextAtOffset(aOffset, aBoundaryType, aText,
                           aStartOffset, aEndOffset)
 {
+  // List of IDs.
+  if (arguments[5] instanceof Array) {
+    var ids = arguments[5];
+    for (var i = 0; i < ids.length; i++) {
+      var acc = getAccessible(ids[i], nsIAccessibleText);
+      testTextHelper(ids[i], aOffset, aBoundaryType,
+                     aText, aStartOffset, aEndOffset,
+                     kOk, kOk, kOk,
+                     acc.getTextAtOffset, "getTextAtOffset ");
+    }
+
+    return;
+  }
+
   for (var i = 5; i < arguments.length; i = i + 4) {
     var ID = arguments[i];
     var acc = getAccessible(ID, nsIAccessibleText);
     var toDoFlag1 = arguments[i + 1];
     var toDoFlag2 = arguments[i + 2];
     var toDoFlag3 = arguments[i + 3];
 
     testTextHelper(ID, aOffset, aBoundaryType,
@@ -158,25 +174,40 @@ function testCharAfterOffset(aIDs, aOffs
 /**
  * Test getTextAfterOffset function over different elements
  *
  * @param aOffset         [in] the offset to get the text after
  * @param aBoundaryType   [in] Boundary type for text to be retrieved
  * @param aText           [in] expected return text for getTextAfterOffset
  * @param aStartOffset    [in] expected return start offset for getTextAfterOffset
  * @param aEndOffset      [in] expected return end offset for getTextAfterOffset
- * @param ...             [in] list of tuples made of:
+ * @param ...             [in] list of ids or list of tuples made of:
  *                              element identifier
  *                              kTodo or kOk for returned text
  *                              kTodo or kOk for returned start offset
  *                              kTodo or kOk for returned offset result
  */
 function testTextAfterOffset(aOffset, aBoundaryType,
                              aText, aStartOffset, aEndOffset)
 {
+  // List of IDs.
+  if (arguments[5] instanceof Array) {
+    var ids = arguments[5];
+    for (var i = 0; i < ids.length; i++) {
+      var acc = getAccessible(ids[i], nsIAccessibleText);
+      testTextHelper(ids[i], aOffset, aBoundaryType,
+                     aText, aStartOffset, aEndOffset,
+                     kOk, kOk, kOk,
+                     acc.getTextAfterOffset, "getTextAfterOffset ");
+    }
+
+    return;
+  }
+
+  // List of tuples.
   for (var i = 5; i < arguments.length; i = i + 4) {
     var ID = arguments[i];
     var acc = getAccessible(ID, nsIAccessibleText);
     var toDoFlag1 = arguments[i + 1];
     var toDoFlag2 = arguments[i + 2];
     var toDoFlag3 = arguments[i + 3];
 
     testTextHelper(ID, aOffset, aBoundaryType,
@@ -211,26 +242,39 @@ function testCharBeforeOffset(aIDs, aOff
 /**
  * Test getTextBeforeOffset function over different elements
  *
  * @param aOffset         [in] the offset to get the text before
  * @param aBoundaryType   [in] Boundary type for text to be retrieved
  * @param aText           [in] expected return text for getTextBeforeOffset
  * @param aStartOffset    [in] expected return start offset for getTextBeforeOffset
  * @param aEndOffset      [in] expected return end offset for getTextBeforeOffset
- * @param ...             [in] list of tuples made of:
+ * @param ...             [in] list of ids or list of tuples made of:
  *                              element identifier
  *                              kTodo or kOk for returned text
  *                              kTodo or kOk for returned start offset
  *                              kTodo or kOk for returned offset result
- *          
  */
 function testTextBeforeOffset(aOffset, aBoundaryType,
                               aText, aStartOffset, aEndOffset)
 {
+  // List of IDs.
+  if (arguments[5] instanceof Array) {
+    var ids = arguments[5];
+    for (var i = 0; i < ids.length; i++) {
+      var acc = getAccessible(ids[i], nsIAccessibleText);
+      testTextHelper(ids[i], aOffset, aBoundaryType,
+                     aText, aStartOffset, aEndOffset,
+                     kOk, kOk, kOk,
+                     acc.getTextBeforeOffset, "getTextBeforeOffset ");
+    }
+
+    return;
+  }
+
   for (var i = 5; i < arguments.length; i = i + 4) {
     var ID = arguments[i];
     var acc = getAccessible(ID, nsIAccessibleText);
     var toDoFlag1 = arguments[i + 1];
     var toDoFlag2 = arguments[i + 2];
     var toDoFlag3 = arguments[i + 3];
 
     testTextHelper(ID, aOffset, aBoundaryType,
@@ -259,68 +303,74 @@ function testWordCount(aElement, aCount,
     var text = acc.getTextAtOffset(offset, BOUNDARY_WORD_START,
                                    startOffsetObj, endOffsetObj);
     if (offset >= length)
       break;
 
     wordCount++;
     offset = endOffsetObj.value;
   }
-  isFunc(wordCount, aCount,  "wrong words count for '" + acc.getText(0, -1) + "': " +
-         wordCount);
+  isFunc(wordCount, aCount,
+        "wrong words count for '" + acc.getText(0, -1) + "': " + wordCount +
+        " in " + prettyName(aElement));
 }
 
 /**
  * Test word at a position for an element.
  *
  * @param aElement    [in] element identifier
  * @param aWordIndex  [in] index of the word to test
  * @param aText       [in] expected text for that word
  * @param aToDoFlag   [in] kTodo or kOk for returned text
  */
 function testWordAt(aElement, aWordIndex, aText, aToDoFlag)
 {
   var isFunc = (aToDoFlag == kTodo) ? todo_is : is;
   var acc = getAccessible(aElement, nsIAccessibleText);
-  var startOffsetObj = {}, endOffsetObj = {};
-  var length = acc.characterCount;
-  var offset = 0;
-  var wordIndex = -1;
-  var wordFountAtOffset = -1;
-  while (true) {
-    var text = acc.getTextAtOffset(offset, BOUNDARY_WORD_START,
-                                   startOffsetObj, endOffsetObj);
-    if (offset >= length)
+
+  var textLength = acc.characterCount;
+  var wordIdx = aWordIndex;
+  var startOffsetObj = { value: 0 }, endOffsetObj = { value: 0 };
+  for (offset = 0; offset < textLength; offset = endOffsetObj.value) {
+    acc.getTextAtOffset(offset, BOUNDARY_WORD_START,
+                        startOffsetObj, endOffsetObj);
+
+    wordIdx--;
+    if (wordIdx < 0)
       break;
+  }
+
+  if (wordIdx >= 0) {
+    ok(false,
+       "the given word index '" + aWordIndex + "' exceeds words amount in " +
+       prettyName(aElement));
+
+    return;
+  }
 
-    wordIndex++;
-    offset = endOffsetObj.value;
-    if (wordIndex == aWordIndex) {
-       wordFountAtOffset = startOffsetObj.value;
-       break;
-    }
-  } 
-  if (wordFountAtOffset >= 0) {
-    var text = acc.getTextAtOffset(wordFountAtOffset, BOUNDARY_WORD_END,
-                                   startOffsetObj, endOffsetObj);
+  var startWordOffset = startOffsetObj.value;
+  var endWordOffset = endOffsetObj.value;
+
+  // Calculate the end word offset.
+  acc.getTextAtOffset(endOffsetObj.value, BOUNDARY_WORD_END,
+                      startOffsetObj, endOffsetObj);
+  if (startOffsetObj.value != textLength)
+    endWordOffset = startOffsetObj.value
 
-    if (endOffsetObj.value < wordFountAtOffset) {
-      todo(false,  "wrong start and end offset for word '" + aWordIndex + "': " +
-           " of text '" + acc.getText(0, -1) + "'");
-      return;
-    }
+  if (endWordOffset <= startWordOffset) {
+    todo(false,
+         "wrong start and end offset for word at index '" + aWordIndex + "': " +
+         " of text '" + acc.getText(0, -1) + "' in " + prettyName(aElement));
 
-    text = acc.getText(wordFountAtOffset, endOffsetObj.value);
-    isFunc(text, aText,  "wrong text for word at pos '" + aWordIndex + "': " +
-           " of text '" + acc.getText(0, -1) + "'");
+    return;
   }
-  else {
-    isFunc(false, "failed to find word " + aText + " at word pos " + aWordIndex +
-           " of text '" + acc.getText(0, -1) + "'");
-  }
+
+  text = acc.getText(startWordOffset, endWordOffset);
+  isFunc(text, aText,  "wrong text for word at index '" + aWordIndex + "': " +
+         " of text '" + acc.getText(0, -1) + "' in " + prettyName(aElement));
 }
 
 /**
  * Test words in a element.
  *
  * @param aElement   [in]           element identifier
  * @param aWords     [in]           array of expected words
  * @param aToDoFlag  [in, optional] kTodo or kOk for returned text
@@ -455,36 +505,41 @@ function testTextGetSelection(aID, aStar
 function testTextHelper(aID, aOffset, aBoundaryType,
                         aText, aStartOffset, aEndOffset,
                         aToDoFlag1, aToDoFlag2, aToDoFlag3,
                         aTextFunc, aTextFuncName)
 {
   var exceptionFlag = aToDoFlag1 == undefined ||
                       aToDoFlag2 == undefined ||
                       aToDoFlag3 == undefined;
+
+  var startMsg = aTextFuncName + "(" + boundaryToString(aBoundaryType) + "): ";
+  var endMsg = ", id: " + prettyName(aID) + ";";
+
   try {
     var startOffsetObj = {}, endOffsetObj = {};
     var text = aTextFunc(aOffset, aBoundaryType,
                          startOffsetObj, endOffsetObj);
-    
+
+    if (exceptionFlag) {
+      ok(false, startMsg + "no expected failure at offset " + aOffset + endMsg);
+      return;
+    }
+
     var isFunc1 = (aToDoFlag1 == kTodo) ? todo_is : is;
     var isFunc2 = (aToDoFlag2 == kTodo) ? todo_is : is;
     var isFunc3 = (aToDoFlag3 == kTodo) ? todo_is : is;
 
-    var startMsg = aTextFuncName + "(" + boundaryToString(aBoundaryType) + "): ";
-
-    var endMsg = ", id: '" + prettyName(aID) + "';";
-    
     isFunc1(text, aText,
             startMsg + "wrong text, offset: " + aOffset + endMsg);
     isFunc2(startOffsetObj.value, aStartOffset,
             startMsg + "wrong start offset, offset: " + aOffset + endMsg);
     isFunc3(endOffsetObj.value, aEndOffset,
             startMsg + "wrong end offset, offset: " + aOffset + endMsg);
-    
+
   } catch (e) {
     var okFunc = exceptionFlag ? todo : ok;
     okFunc(false, startMsg + "failed at offset " + aOffset + endMsg);
   }
 }
 
 function boundaryToString(aBoundaryType)
 {
--- a/accessible/tests/mochitest/text/Makefile.in
+++ b/accessible/tests/mochitest/text/Makefile.in
@@ -8,16 +8,17 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = accessible/text
 
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_A11Y_FILES = \
 		doc.html \
+		test_atcaretoffset.html \
 		test_doc.html \
 		test_hypertext.html \
 		test_label.xul \
 		test_multiline.html \
 		test_passwords.html \
 		test_selection.html \
 		test_singleline.html \
 		test_whitespaces.html \
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/text/test_atcaretoffset.html
@@ -0,0 +1,258 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Test: nsIAccessibleText getText* functions at caret offset</title>
+
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../role.js"></script>
+  <script type="application/javascript"
+          src="../states.js"></script>
+  <script type="application/javascript"
+          src="../events.js"></script>
+  <script type="application/javascript"
+          src="../text.js"></script>
+
+  <script type="application/javascript">
+    //gA11yEventDumpToConsole = true; // debugging
+
+    // __a__w__o__r__d__\n
+    //  0  1  2  3  4  5
+    // __t__w__o__ (soft line break)
+    //  6  7  8  9
+    // __w__o__r__d__s
+    // 10 11 12 13 14 15
+
+    function moveToLastLineEnd()
+    {
+      this.__proto__ = new synthFocus("textarea");
+
+      this.finalCheck = function moveToLastLineEnd_finalCheck()
+      {
+        testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_START, "", 15, 15,
+                            "textarea", kTodo, kOk, kTodo);
+
+        testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_END, "", 15, 15,
+                            "textarea", kTodo, kOk, kTodo);
+
+        testTextAtOffset(kCaretOffset, BOUNDARY_LINE_START, "", 15, 15,
+                         "textarea", kTodo, kTodo, kTodo);
+
+        testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "words", 10, 15,
+                         "textarea", kTodo, kTodo, kTodo);
+
+        testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_START, "words", 10, 15,
+                             "textarea", kOk, kOk, kOk);
+
+        testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_END, "\ntwo ", 5, 10,
+                             "textarea", kTodo, kTodo, kTodo);
+      }
+
+      this.getID = function moveToLastLineEnd_getID()
+      {
+        return "move to last line end";
+      }
+    }
+
+    function moveToLastLineStart()
+    {
+      this.__proto__ = new moveToLineStart("textarea", 10);
+
+      this.finalCheck = function moveToLastLineStart_finalCheck()
+      {
+        testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_START, "", 15, 15,
+                            "textarea", kTodo, kTodo, kTodo);
+
+        testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_END, "", 15, 15,
+                            "textarea", kTodo, kTodo, kOk);
+
+        testTextAtOffset(kCaretOffset, BOUNDARY_LINE_START, "words", 10, 15,
+                         "textarea", kTodo, kOk, kTodo);
+
+        testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "\ntwo ", 5, 10,
+                         "textarea", kTodo, kTodo, kTodo);
+
+        testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_START, "two ", 6, 10,
+                             "textarea", kTodo, kTodo, kOk);
+
+        testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_END, "\ntwo ", 5, 10,
+                             "textarea", kTodo, kTodo, kOk);
+      }
+
+      this.getID = function moveToLastLineStart_getID()
+      {
+        return "move to last line start";
+      }
+    }
+
+    function moveToMiddleLineStart()
+    {
+      this.__proto__ = new synthUpKey("textarea",
+                                      new caretMoveChecker(6, "textarea"));
+
+      this.finalCheck = function moveToMiddleLineStart_finalCheck()
+      {
+        testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_START, "words", 10, 15,
+                            "textarea", kTodo, kTodo, kTodo);
+
+        testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_END, "words", 10, 15,
+                            "textarea", kTodo, kTodo, kTodo);
+
+        testTextAtOffset(kCaretOffset, BOUNDARY_LINE_START, "two ", 6, 10,
+                         "textarea", kOk, kOk, kOk);
+
+        testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "\ntwo ", 5, 10,
+                         "textarea", kTodo, kOk, kTodo);
+
+        testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_START, "aword\n", 0, 6,
+                             "textarea", kTodo, kTodo, kOk);
+
+        testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_END, "aword", 0, 5,
+                             "textarea", kTodo, kTodo, kTodo);
+      }
+
+      this.getID = function moveToMiddleLineStart_getID()
+      {
+        return "move to middle line start";
+      }
+    }
+
+    function moveToMiddleLineEnd()
+    {
+      this.__proto__ = new moveToLineEnd("textarea", 10);
+
+      this.finalCheck = function moveToMiddleLineEnd_finalCheck()
+      {
+        testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_START, "words", 10, 15,
+                            "textarea", kTodo, kTodo, kTodo);
+
+        testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_END, "words", 10, 15,
+                            "textarea", kTodo, kTodo, kOk);
+
+        testTextAtOffset(kCaretOffset, BOUNDARY_LINE_START, "two ", 6, 10,
+                         "textarea", kOk, kOk, kOk);
+
+        testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "\ntwo ", 5, 10,
+                         "textarea", kTodo, kTodo, kTodo);
+
+        testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_START, "aword\n", 0, 6,
+                             "textarea", kTodo, kTodo, kTodo);
+
+        testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_END, "aword", 0, 5,
+                             "textarea", kTodo, kTodo, kTodo);
+      }
+
+      this.getID = function moveToMiddleLineEnd_getID()
+      {
+        return "move to middle line end";
+      }
+    }
+
+    function moveToFirstLineStart()
+    {
+      this.__proto__ = new moveToTextStart("textarea");
+
+      this.finalCheck = function moveToFirstLineStart_finalCheck()
+      {
+        testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_START, "two ", 6, 10,
+                            "textarea", kTodo, kTodo, kTodo);
+
+        testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_END, "aword", 0, 5,
+                            "textarea", kTodo, kOk, kTodo);
+
+        testTextAtOffset(kCaretOffset, BOUNDARY_LINE_START, "aword\n", 0, 6,
+                         "textarea", kTodo, kOk, kTodo);
+
+        testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "", 0, 0,
+                         "textarea", kTodo, kOk, kTodo);
+
+        testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_START, "", 0, 0,
+                             "textarea", kOk, kOk, kOk);
+
+        testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_END, "", 0, 0,
+                             "textarea", kOk, kOk, kOk);
+      }
+
+      this.getID = function moveToFirstLineStart_getID()
+      {
+        return "move to first line start";
+      }
+    }
+
+    function moveToFirstLineEnd()
+    {
+      this.__proto__ = new moveToLineEnd("textarea", 5);
+
+      this.finalCheck = function moveToFirstLineStart_finalCheck()
+      {
+        testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_START, "two ", 6, 10,
+                            "textarea", kTodo, kTodo, kTodo);
+
+        testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_END, "\ntwo ", 5, 10,
+                            "textarea", kTodo, kTodo, kTodo);
+
+        testTextAtOffset(kCaretOffset, BOUNDARY_LINE_START, "aword\n", 0, 6,
+                         "textarea", kTodo, kOk, kTodo);
+
+        testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "aword", 0, 5,
+                         "textarea", kOk, kOk, kOk);
+
+        testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_START, "", 0, 0,
+                             "textarea", kTodo, kOk, kTodo);
+
+        testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_END, "", 0, 0,
+                             "textarea", kTodo, kOk, kTodo);
+      }
+
+      this.getID = function moveToFirstLineEnd_getID()
+      {
+        return "move to first line end";
+      }
+    }
+
+    var gQueue = null;
+    function doTest()
+    {
+      SimpleTest.expectAssertions(5);
+
+      gQueue = new eventQueue();
+      gQueue.push(new moveToLastLineEnd());
+      gQueue.push(new moveToLastLineStart());
+      gQueue.push(new moveToMiddleLineStart());
+      gQueue.push(new moveToMiddleLineEnd());
+      gQueue.push(new moveToFirstLineStart());
+      gQueue.push(new moveToFirstLineEnd());
+      gQueue.invoke(); // will call SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+</head>
+<body>
+
+  <a target="_blank"
+     title="nsIAccessibleText getText related functions tests at caret offset"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=852021">
+   Bug 852021
+  </a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+
+  <textarea id="textarea" cols="5">aword
+two words</textarea>
+  </pre>
+</body>
+</html>
--- a/accessible/tests/mochitest/text/test_multiline.html
+++ b/accessible/tests/mochitest/text/test_multiline.html
@@ -11,17 +11,17 @@
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../text.js"></script>
   <script type="application/javascript">
 
     function doTest()
     {
-      SimpleTest.expectAssertions(52);
+      SimpleTest.expectAssertions(54);
 
       // __o__n__e__w__o__r__d__\n
       //  0  1  2  3  4  5  6  7
       // __\n
       //  8
       // __t__w__o__ __w__o__r__d__s__\n
       //  9 10 11 12 13 14 15 16 17 18
 
@@ -124,21 +124,21 @@
                           "textarea", kTodo, kTodo, kTodo);
       testTextAfterOffset(9, BOUNDARY_LINE_START, "", 19, 19,
                           "div", kTodo, kTodo, kTodo,
                           "divbr", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kTodo,
                           "editablebr", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(19, BOUNDARY_LINE_START, "", 19, 19,
-                          "div", undefined, undefined, undefined,
-                          "divbr", undefined, undefined, undefined,
-                          "editable", undefined, undefined, undefined,
-                          "editablebr", undefined, undefined, undefined,
-                          "textarea", kTodo, undefined, kTodo);
+                          "div", kOk, kOk, kTodo,
+                          "divbr", kOk, kOk, kOk,
+                          "editable", kOk, kOk, kTodo,
+                          "editablebr", kOk, kOk, kOk,
+                          "textarea", kOk, kOk, kOk);
 
       // BOUNDARY_LINE_END
       testTextAfterOffset(0, BOUNDARY_LINE_END, "\n", 7, 8,
                           "div", kTodo, kTodo, kTodo,
                           "divbr", kTodo, kTodo, kTodo,
                           "editable", kTodo, kTodo, kTodo,
                           "editablebr", kTodo, kTodo, kTodo,
                           "textarea", kTodo, kTodo, kTodo);
@@ -156,21 +156,21 @@
                           "textarea", kOk, kOk, kOk);
       testTextAfterOffset(9, BOUNDARY_LINE_END, "\n", 18, 19,
                           "div", kTodo, kTodo, kTodo,
                           "divbr", kTodo, kTodo, kTodo,
                           "editable", kTodo, kTodo, kTodo,
                           "editablebr", kTodo, kTodo, kTodo,
                           "textarea", kTodo, kTodo, kTodo);
       testTextAfterOffset(18, BOUNDARY_LINE_END, "\n", 18, 19,
-                          "div", kTodo, kTodo, kTodo,
-                          "divbr", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "editablebr", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
+                          "div", kTodo, kOk, kTodo,
+                          "divbr", kOk, kOk, kOk,
+                          "editable", kTodo, kOk, kTodo,
+                          "editablebr", kOk, kOk, kOk,
+                          "textarea", kOk, kOk, kOk);
       testTextAfterOffset(19, BOUNDARY_LINE_END, "", 19, 19,
                           "div", kOk, kTodo, kTodo,
                           "divbr", kOk, kTodo, kTodo,
                           "editable", kOk, kTodo, kTodo,
                           "editablebr", kOk, kTodo, kTodo,
                           "textarea", kOk, kTodo, kTodo);
 
       ////////////////////////////////////////////////////////////////////////
@@ -386,59 +386,49 @@
       // BOUNDARY_WORD_START
       testTextAtOffset(0, BOUNDARY_WORD_START, "oneword\n\n", 0, 9,
                        "div", kTodo, kOk, kTodo,
                        "divbr", kOk, kOk, kOk,
                        "editable", kTodo, kOk, kTodo,
                        "editablebr", kOk, kOk, kOk,
                        "textarea", kTodo, kOk, kTodo);
       testTextAtOffset(8, BOUNDARY_WORD_START, "oneword\n\n", 0, 9,
-                       "div", kTodo, kTodo, kOk,
-                       "divbr", kOk, kOk, kOk,
-                       "editable", kTodo, kTodo, kOk,
-                       "editablebr", kOk, kOk, kOk,
-                       "textarea", kTodo, kTodo, kOk);
-      testTextAtOffset(9, BOUNDARY_WORD_START, "two ", 9, 13,
-                       "div", kTodo, kTodo, kTodo,
-                       "divbr", kOk, kOk, kOk,
-                       "editable", kTodo, kTodo, kTodo,
-                       "editablebr", kOk, kOk, kOk,
-                       "textarea", kTodo, kTodo, kTodo);
-      testTextAtOffset(13, BOUNDARY_WORD_START, "words\n", 13, 19,
                        "div", kOk, kOk, kOk,
-                       "divbr", kOk, kOk, kOk,
+                       "divbr", kTodo, kTodo, kTodo,
                        "editable", kOk, kOk, kOk,
-                       "editablebr", kOk, kOk, kOk,
+                       "editablebr", kTodo, kTodo, kTodo,
                        "textarea", kOk, kOk, kOk);
+      testTextAtOffset(9, BOUNDARY_WORD_START, "two ", 9, 13, IDs);
+      testTextAtOffset(13, BOUNDARY_WORD_START, "words\n", 13, 19, IDs);
 
       // BOUNDARY_WORD_END
       testTextAtOffset(0, BOUNDARY_WORD_END, "oneword", 0, 7,
-                       "div", kOk, kOk, kOk,
-                       "divbr", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "editablebr", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
+                       "div", kTodo, kOk, kTodo,
+                       "divbr", kTodo, kOk, kTodo,
+                       "editable", kTodo, kOk, kTodo,
+                       "editablebr", kTodo, kOk, kTodo,
+                       "textarea", kTodo, kOk, kTodo);
       testTextAtOffset(8, BOUNDARY_WORD_END, "\n\ntwo", 7, 12,
                        "div", kOk, kOk, kOk,
                        "divbr", kTodo, kTodo, kTodo,
                        "editable", kOk, kOk, kOk,
                        "editablebr", kTodo, kTodo, kTodo,
                        "textarea", kOk, kOk, kOk);
       testTextAtOffset(9, BOUNDARY_WORD_END, "\n\ntwo", 7, 12,
                        "div", kTodo, kTodo, kOk,
                        "divbr", kTodo, kTodo, kTodo,
                        "editable", kTodo, kTodo, kOk,
                        "editablebr", kTodo, kTodo, kTodo,
                        "textarea", kTodo, kTodo, kOk);
       testTextAtOffset(12, BOUNDARY_WORD_END, "\n\ntwo", 7, 12,
-                       "div", kTodo, kTodo, kTodo,
-                       "divbr", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "editablebr", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kTodo);
+                       "div", kTodo, kTodo, kOk,
+                       "divbr", kOk, kOk, kOk,
+                       "editable", kTodo, kTodo, kOk,
+                       "editablebr", kOk, kOk, kOk,
+                       "textarea", kTodo, kTodo, kOk);
       testTextAtOffset(13, BOUNDARY_WORD_END, " words", 12, 18,
                        "div", kOk, kOk, kOk,
                        "divbr", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
                        "editablebr", kOk, kOk, kOk,
                        "textarea", kOk, kOk, kOk);
 
       // BOUNDARY_LINE_START
@@ -512,21 +502,21 @@
                        "textarea", kOk, kOk, kOk);
       testTextAtOffset(17, BOUNDARY_LINE_END, "\ntwo words", 8, 18,
                        "div", kOk, kOk, kOk,
                        "divbr", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
                        "editablebr", kOk, kOk, kOk,
                        "textarea", kOk, kOk, kOk);
       testTextAtOffset(18, BOUNDARY_LINE_END, "\ntwo words", 8, 18,
-                       "div", kTodo, kTodo, kTodo,
-                       "divbr", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "editablebr", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kTodo);
+                       "div", kTodo, kOk, kTodo,
+                       "divbr", kTodo, kOk, kTodo,
+                       "editable", kTodo, kOk, kTodo,
+                       "editablebr", kTodo, kOk, kTodo,
+                       "textarea", kTodo, kOk, kTodo);
       testTextAtOffset(19, BOUNDARY_LINE_END, "\n", 18, 19,
                        "div", kTodo, kTodo, kTodo,
                        "divbr", kTodo, kTodo, kTodo,
                        "editable", kTodo, kTodo, kTodo,
                        "editablebr", kTodo, kTodo, kTodo,
                        "textarea", kTodo, kTodo, kTodo);
 
       SimpleTest.finish();
@@ -541,16 +531,17 @@
   <a target="_blank"
      title="nsIAccessibleText getText related functions test in multiline text"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=612331">
    Bug 612331
   </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
+
   <div id="div">oneword
 
 two words
 </div>
   <div id="divbr">oneword<br/><br/>two words<br/></div>
   <div id="editable" contenteditable="true">oneword
 
 two words
--- a/accessible/tests/mochitest/text/test_singleline.html
+++ b/accessible/tests/mochitest/text/test_singleline.html
@@ -7,19 +7,19 @@
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../text.js"></script>
   <script type="application/javascript">
     if (navigator.platform.startsWith("Mac")) {
-      SimpleTest.expectAssertions(0, 19);
+      SimpleTest.expectAssertions(0, 28);
     } else {
-      SimpleTest.expectAssertions(19);
+      SimpleTest.expectAssertions(28);
     }
 
     function doTest()
     {
       // __h__e__l__l__o__ __m__y__ __f__r__i__e__n__d__
       //  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
 
       ////////////////////////////////////////////////////////////////////////
@@ -100,19 +100,19 @@
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(14, BOUNDARY_WORD_START, "", 15, 15,
                           "input", kTodo, kTodo, kOk,
                           "div", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(15, BOUNDARY_WORD_START, "", 15, 15,
-                          "input", kOk, kTodo, kTodo,
-                          "div", kOk, kTodo, kTodo,
-                          "editable", kOk, kTodo, kTodo,
+                          "input", kOk, kOk, kOk,
+                          "div", kOk, kOk, kOk,
+                          "editable", kOk, kOk, kOk,
                           "textarea", kTodo, kOk, kTodo);
 
       // BOUNDARY_WORD_END
       testTextAfterOffset(0, BOUNDARY_WORD_END, " my", 5, 8,
                           "input", kTodo, kTodo, kTodo,
                           "div", kTodo, kTodo, kTodo,
                           "editable", kTodo, kTodo, kTodo,
                           "textarea", kTodo, kTodo, kTodo);
@@ -152,19 +152,19 @@
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(14, BOUNDARY_WORD_END, "", 15, 15,
                           "input", kTodo, kTodo, kOk,
                           "div", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(15, BOUNDARY_WORD_END, "", 15, 15,
-                          "input", kOk, kTodo, kTodo,
-                          "div", kOk, kTodo, kTodo,
-                          "editable", kOk, kTodo, kTodo,
+                          "input", kOk, kOk, kOk,
+                          "div", kOk, kOk, kOk,
+                          "editable", kOk, kOk, kOk,
                           "textarea", kTodo, kOk, kTodo);
 
       // BOUNDARY_LINE_START
       testTextAfterOffset(0, BOUNDARY_LINE_START, "", 15, 15,
                           "input", kTodo, kTodo, kOk,
                           "div", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kTodo);
@@ -174,42 +174,42 @@
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kTodo);
       testTextAfterOffset(14, BOUNDARY_LINE_START, "", 15, 15,
                           "input", kTodo, kTodo, kOk,
                           "div", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kTodo);
       testTextAfterOffset(15, BOUNDARY_LINE_START, "", 15, 15,
-                          "input", undefined, undefined, undefined,
-                          "div", undefined, undefined, undefined,
-                          "editable", undefined, undefined, undefined,
-                          "textarea", kTodo, undefined, kTodo);
+                          "input", kOk, kOk, kOk,
+                          "div", kOk, kOk, kOk,
+                          "editable", kOk, kOk, kOk,
+                          "textarea", kTodo, kOk, kTodo);
 
       // BOUNDARY_LINE_END
       testTextAfterOffset(0, BOUNDARY_LINE_END, "", 15, 15,
                           "input", kTodo, kTodo, kOk,
                           "div", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(1, BOUNDARY_LINE_END, "", 15, 15,
                           "input", kTodo, kTodo, kOk,
                           "div", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(14, BOUNDARY_LINE_END, "", 15, 15,
-                          "input", kOk, kTodo, kTodo,
-                          "div", kOk, kTodo, kTodo,
-                          "editable", kOk, kTodo, kTodo,
+                          "input", kTodo, kTodo, kOk,
+                          "div", kTodo, kTodo, kOk,
+                          "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(15, BOUNDARY_LINE_END, "", 15, 15,
                           "input", kOk, kTodo, kTodo,
                           "div", kOk, kTodo, kTodo,
                           "editable", kOk, kTodo, kTodo,
-                          "textarea", kOk, kTodo, kTodo);
+                          "textarea", kTodo, kOk, kTodo);
 
       ////////////////////////////////////////////////////////////////////////
       // getTextBeforeOffset
 
       var IDs = [ "input", "div", "editable", "textarea" ];
 
       // BOUNDARY_CHAR
       testCharBeforeOffset(IDs, 0, "", 0, 0);
@@ -350,25 +350,25 @@
                            "editable", kOk, kOk, kOk,
                            "textarea", kOk, kOk, kOk);
       testTextBeforeOffset(1, BOUNDARY_LINE_END, "", 0, 0,
                            "input", kTodo, kOk, kTodo,
                            "div", kTodo, kOk, kTodo,
                            "editable", kTodo, kOk, kTodo,
                            "textarea", kTodo, kOk, kTodo);
       testTextBeforeOffset(14, BOUNDARY_LINE_END, "", 0, 0,
-                           "input", kOk, kOk, kOk,
-                           "div", kOk, kOk, kOk,
-                           "editable", kOk, kOk, kOk,
+                           "input", kTodo, kOk, kTodo,
+                           "div", kTodo, kOk, kTodo,
+                           "editable", kTodo, kOk, kTodo,
                            "textarea", kTodo, kOk, kTodo);
       testTextBeforeOffset(15, BOUNDARY_LINE_END, "", 0, 0,
                            "input", kOk, kOk, kOk,
                            "div", kOk, kOk, kOk,
                            "editable", kOk, kOk, kOk,
-                           "textarea", kOk, kOk, kOk);
+                           "textarea", kTodo, kOk, kTodo);
 
       ////////////////////////////////////////////////////////////////////////
       // getTextAtOffset
 
       IDs = [ "input", "div", "editable", "textarea" ];
       regularIDs = [ "input", "div", "editable" ];
 
       // BOUNDARY_CHAR
@@ -376,135 +376,59 @@
       testCharAtOffset(IDs, 0, "h", 0, 1);
       testCharAtOffset(IDs, 1, "e", 1, 2);
       testCharAtOffset(IDs, 14, "d", 14, 15);
       testCharAtOffset(regularIDs, 15, "", 15, 15);
       testCharAtOffset("textarea", 15, "\n", 15, 16);
       testCharAtOffset("textarea", 16, "", 16, 16);
 
       // BOUNDARY_WORD_START
-      testTextAtOffset(0, BOUNDARY_WORD_START, "hello ", 0, 6,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(1, BOUNDARY_WORD_START, "hello ", 0, 6,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(5, BOUNDARY_WORD_START, "hello ", 0, 6,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(6, BOUNDARY_WORD_START, "my ", 6, 9,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(7, BOUNDARY_WORD_START, "my ", 6, 9,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(8, BOUNDARY_WORD_START, "my ", 6, 9,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(9, BOUNDARY_WORD_START, "friend", 9, 15,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(10, BOUNDARY_WORD_START, "friend", 9, 15,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(14, BOUNDARY_WORD_START, "friend", 9, 15,
+      testTextAtOffset(0, BOUNDARY_WORD_START, "hello ", 0, 6, IDs);
+      testTextAtOffset(1, BOUNDARY_WORD_START, "hello ", 0, 6, IDs);
+      testTextAtOffset(5, BOUNDARY_WORD_START, "hello ", 0, 6, IDs);
+      testTextAtOffset(6, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
+      testTextAtOffset(7, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
+      testTextAtOffset(8, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
+      testTextAtOffset(9, BOUNDARY_WORD_START, "friend", 9, 15, IDs);
+      testTextAtOffset(10, BOUNDARY_WORD_START, "friend", 9, 15, IDs);
+      testTextAtOffset(14, BOUNDARY_WORD_START, "friend", 9, 15, IDs);
+      testTextAtOffset(15, BOUNDARY_WORD_START, "", 15, 15,
                        "input", kOk, kOk, kOk,
                        "div", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(15, BOUNDARY_WORD_START, "friend", 9, 15,
-                       "input", kTodo, kTodo, kTodo,
-                       "div", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kTodo);
+                       "textarea", kTodo, kTodo, kOk);
 
       // BOUNDARY_WORD_END
-      testTextAtOffset(0, BOUNDARY_WORD_END, "hello", 0, 5,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(1, BOUNDARY_WORD_END, "hello", 0, 5,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(5, BOUNDARY_WORD_END, "hello", 0, 5,
-                       "input", kTodo, kTodo, kTodo,
-                       "div", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kTodo);
-      testTextAtOffset(6, BOUNDARY_WORD_END, " my", 5, 8,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(7, BOUNDARY_WORD_END, " my", 5, 8,
-                        "input", kOk, kOk, kOk,
-                        "div", kOk, kOk, kOk,
-                        "editable", kOk, kOk, kOk,
-                        "textarea", kOk, kOk, kOk);
-      testTextAtOffset(8, BOUNDARY_WORD_END, " my", 5, 8,
-                       "input", kTodo, kTodo, kTodo,
-                       "div", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kTodo);
-      testTextAtOffset(9, BOUNDARY_WORD_END, " friend", 8, 15,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(10, BOUNDARY_WORD_END, " friend", 8, 15,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(14, BOUNDARY_WORD_END, " friend", 8, 15,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(15, BOUNDARY_WORD_END, " friend", 8, 15,
-                        "input", kTodo, kTodo, kTodo,
-                        "div", kTodo, kTodo, kTodo,
-                        "editable", kTodo, kTodo, kTodo,
-                        "textarea", kTodo, kTodo, kTodo);
+      testTextAtOffset(0, BOUNDARY_WORD_END, "", 0, 0, IDs);
+      testTextAtOffset(1, BOUNDARY_WORD_END, "hello", 0, 5, IDs);
+      testTextAtOffset(5, BOUNDARY_WORD_END, "hello", 0, 5, IDs);
+      testTextAtOffset(6, BOUNDARY_WORD_END, " my", 5, 8, IDs);
+      testTextAtOffset(7, BOUNDARY_WORD_END, " my", 5, 8, IDs);
+      testTextAtOffset(8, BOUNDARY_WORD_END, " my", 5, 8, IDs);
+      testTextAtOffset(9, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
+      testTextAtOffset(10, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
+      testTextAtOffset(14, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
+      testTextAtOffset(15, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
 
       // BOUNDARY_LINE_START
       testTextAtOffset(0, BOUNDARY_LINE_START, "hello my friend", 0, 15,
                        "input", kOk, kOk, kOk,
                        "div", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
                        "textarea", kTodo, kOk, kTodo);
       testTextAtOffset(1, BOUNDARY_LINE_START, "hello my friend", 0, 15,
                        "input", kOk, kOk, kOk,
                        "div", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
                        "textarea", kTodo, kOk, kTodo);
       testTextAtOffset(14, BOUNDARY_LINE_START, "hello my friend", 0, 15,
                        "input", kOk, kOk, kOk,
                        "div", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
-			       "textarea", kTodo, kOk, kTodo);
+                       "textarea", kTodo, kOk, kTodo);
       testTextAtOffset(15, BOUNDARY_LINE_START, "hello my friend", 0, 15,
 		       "input", kOk, kOk, kOk,
 		       "div", kOk, kOk, kOk,
 		       "editable", kOk, kOk, kOk,
 		       "textarea", kTodo, kOk, kTodo);
 
       // BOUNDARY_LINE_END
       testTextAtOffset(0, BOUNDARY_LINE_END, "hello my friend", 0, 15,
@@ -513,19 +437,19 @@
 		       "editable", kOk, kOk, kOk,
 		       "textarea", kOk, kOk, kOk);
       testTextAtOffset(1, BOUNDARY_LINE_END, "hello my friend", 0, 15,
 		       "input", kOk, kOk, kOk,
 		       "div", kOk, kOk, kOk,
 		       "editable", kOk, kOk, kOk,
 		       "textarea", kOk, kOk, kOk);
       testTextAtOffset(14, BOUNDARY_LINE_END, "hello my friend", 0, 15,
-		       "input", kTodo, kOk, kTodo,
-		       "div", kTodo, kOk, kTodo,
-		       "editable", kTodo, kOk, kTodo,
+		       "input", kOk, kOk, kOk,
+		       "div", kOk, kOk, kOk,
+		       "editable", kOk, kOk, kOk,
 		       "textarea", kOk, kOk, kOk);
       testTextAtOffset(15, BOUNDARY_LINE_END, "hello my friend", 0, 15,
 		       "input", kTodo, kOk, kTodo,
 		       "div", kTodo, kOk, kTodo,
 		       "editable", kTodo, kOk, kTodo,
 		       "textarea", kTodo, kOk, kTodo);
 
       SimpleTest.finish();
--- a/accessible/tests/mochitest/text/test_whitespaces.html
+++ b/accessible/tests/mochitest/text/test_whitespaces.html
@@ -9,19 +9,19 @@
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript"
           src="../common.js"></script>
 
   <script type="application/javascript"
           src="../text.js"></script>
   <script type="application/javascript">
     if (navigator.platform.startsWith("Mac")) {
-      SimpleTest.expectAssertions(0, 8);
+      SimpleTest.expectAssertions(0, 11);
     } else {
-      SimpleTest.expectAssertions(8);
+      SimpleTest.expectAssertions(11);
     }
 
     function doTest()
     {
       // __B__r__a__v__e__ __S__i__r__ __ __R__o__b__i__n__ __ __ __r__a__n
       //  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21
 
       ////////////////////////////////////////////////////////////////////////
@@ -173,19 +173,19 @@
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(21, BOUNDARY_WORD_END, "", 22, 22,
                           "input", kTodo, kTodo, kOk,
                           "div", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(22, BOUNDARY_WORD_END, "", 22, 22,
-                          "input", kOk, kTodo, kTodo,
-                          "div", kOk, kTodo, kTodo,
-                          "editable", kOk, kTodo, kTodo,
+                          "input", kOk, kOk, kOk,
+                          "div", kOk, kOk, kOk,
+                          "editable", kOk, kOk, kOk,
                           "textarea", kTodo, kOk, kTodo);
 
       ////////////////////////////////////////////////////////////////////////
       // getTextBeforeOffset
 
       var IDs = [ "input", "div", "editable", "textarea" ];
 
       // BOUNDARY_CHAR
@@ -452,103 +452,39 @@
                        "div", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
                        "textarea", kTodo, kOk, kTodo);
       testTextAtOffset(21, BOUNDARY_WORD_START, "ran", 19, 22,
                        "input", kOk, kOk, kOk,
                        "div", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
                        "textarea", kTodo, kOk, kTodo);
-      testTextAtOffset(22, BOUNDARY_WORD_START, "ran", 19, 22,
-                       "input", kTodo, kTodo, kTodo,
-                       "div", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kOk, kTodo);
-
-      // BOUNDARY_WORD_END
-      testTextAtOffset(0, BOUNDARY_WORD_END, "Brave", 0, 5,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(4, BOUNDARY_WORD_END, "Brave", 0, 5,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(5, BOUNDARY_WORD_END, "Brave", 0, 5,
-                       "input", kTodo, kTodo, kTodo,
-                       "div", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kTodo);
-      testTextAtOffset(6, BOUNDARY_WORD_END, " Sir", 5, 9,
-                        "input", kOk, kOk, kOk,
-                        "div", kOk, kOk, kOk,
-                        "editable", kOk, kOk, kOk,
-                        "textarea", kOk, kOk, kOk);
-      testTextAtOffset(8, BOUNDARY_WORD_END, " Sir", 5, 9,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(9, BOUNDARY_WORD_END, " Sir", 5, 9,
-                       "input", kTodo, kTodo, kTodo,
-                       "div", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kTodo);
-      testTextAtOffset(10, BOUNDARY_WORD_END, "  Robin", 9, 16,
+      testTextAtOffset(22, BOUNDARY_WORD_START, "", 22, 22,
                        "input", kOk, kOk, kOk,
                        "div", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(11, BOUNDARY_WORD_END, "  Robin", 9, 16,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(15, BOUNDARY_WORD_END, "  Robin", 9, 16,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(16, BOUNDARY_WORD_END, "  Robin", 9, 16,
-                       "input", kTodo, kTodo, kTodo,
-                       "div", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
                        "textarea", kTodo, kTodo, kTodo);
-      testTextAtOffset(17, BOUNDARY_WORD_END, "   ran", 16, 22,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(18, BOUNDARY_WORD_END, "   ran", 16, 22,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(19, BOUNDARY_WORD_END, "   ran", 16, 22,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(20, BOUNDARY_WORD_END, "   ran", 16, 22,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(21, BOUNDARY_WORD_END, "   ran", 16, 22,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(22, BOUNDARY_WORD_END, "   ran", 16, 22,
-                       "input", kTodo, kTodo, kTodo,
-                       "div", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kTodo);
+
+      // BOUNDARY_WORD_END
+      testTextAtOffset(0, BOUNDARY_WORD_END, "", 0, 0, IDs);
+      testTextAtOffset(4, BOUNDARY_WORD_END, "Brave", 0, 5, IDs);
+      testTextAtOffset(5, BOUNDARY_WORD_END, "Brave", 0, 5, IDs);
+      testTextAtOffset(6, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
+      testTextAtOffset(8, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
+      testTextAtOffset(9, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
+      testTextAtOffset(10, BOUNDARY_WORD_END, "  Robin", 9, 16, IDs);
+      testTextAtOffset(11, BOUNDARY_WORD_END, "  Robin", 9, 16, IDs);
+      testTextAtOffset(15, BOUNDARY_WORD_END, "  Robin", 9, 16, IDs);
+      testTextAtOffset(16, BOUNDARY_WORD_END, "  Robin", 9, 16, IDs);
+      testTextAtOffset(17, BOUNDARY_WORD_END, "   ran", 16, 22, IDs);
+      testTextAtOffset(18, BOUNDARY_WORD_END, "   ran", 16, 22, IDs);
+      testTextAtOffset(19, BOUNDARY_WORD_END, "   ran", 16, 22, IDs);
+      testTextAtOffset(20, BOUNDARY_WORD_END, "   ran", 16, 22, IDs);
+      testTextAtOffset(21, BOUNDARY_WORD_END, "   ran", 16, 22, IDs);
+      testTextAtOffset(22, BOUNDARY_WORD_END, "   ran", 16, 22, IDs);
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
--- a/accessible/tests/mochitest/text/test_words.html
+++ b/accessible/tests/mochitest/text/test_words.html
@@ -10,17 +10,17 @@
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../text.js"></script>
   <script type="application/javascript">
     if (navigator.platform.startsWith("Mac")) {
       SimpleTest.expectAssertions(0, 1);
     } else {
-      SimpleTest.expectAssertions(1);
+      SimpleTest.expectAssertions(0, 1);
     }
 
     function doTest()
     {
       // "one two"
       testWords("div1", ["one", "two"]);
 
       // "one  two"
new file mode 100644
--- /dev/null
+++ b/b2g/chrome/content/ErrorPage.js
@@ -0,0 +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/. */
+
+'use strict';
+
+let Cu = Components.utils;
+let Cc = Components.classes;
+let Ci = Components.interfaces;
+
+let ErrorPageHandler = {
+  _reload: function() {
+    docShell.QueryInterface(Ci.nsIWebNavigation).reload(Ci.nsIWebNavigation.LOAD_FLAGS_NONE);
+  },
+
+  _certErrorPageEventHandler: function(e) {
+    let target = e.originalTarget;
+    let errorDoc = target.ownerDocument;
+
+    // If the event came from an ssl error page, it is one of the "Add
+    // Exception…" buttons.
+    if (/^about:certerror\?e=nssBadCert/.test(errorDoc.documentURI)) {
+      let permanent = errorDoc.getElementById("permanentExceptionButton");
+      let temp = errorDoc.getElementById("temporaryExceptionButton");
+      if (target == temp || target == permanent) {
+        sendAsyncMessage("ErrorPage:AddCertException", {
+          url: errorDoc.location.href,
+          isPermanent: target == permanent
+        });
+      }
+    }
+  },
+
+  domContentLoadedHandler: function(e) {
+    let target = e.originalTarget;
+    let targetDocShell = target.defaultView
+                               .QueryInterface(Ci.nsIInterfaceRequestor)
+                               .getInterface(Ci.nsIWebNavigation);
+    if (targetDocShell != docShell) {
+      return;
+    }
+
+    if (/^about:certerror/.test(target.documentURI)) {
+      let errorPageEventHandler = this._certErrorPageEventHandler.bind(this);
+      addEventListener("click", errorPageEventHandler, true, false);
+      let listener = function() {
+        removeEventListener("click", errorPageEventHandler, true);
+        removeEventListener("pagehide", listener, true);
+      }.bind(this);
+
+      addEventListener("pagehide", listener, true);
+    }
+  },
+
+  init: function() {
+    addMessageListener("ErrorPage:ReloadPage", this._reload.bind(this));
+    addEventListener('DOMContentLoaded',
+                     this.domContentLoadedHandler.bind(this),
+                     true);
+  }
+};
+
+ErrorPageHandler.init();
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -13,16 +13,17 @@ Cu.import('resource://gre/modules/AlarmS
 Cu.import('resource://gre/modules/ActivitiesService.jsm');
 Cu.import('resource://gre/modules/PermissionPromptHelper.jsm');
 Cu.import('resource://gre/modules/ObjectWrapper.jsm');
 Cu.import('resource://gre/modules/accessibility/AccessFu.jsm');
 Cu.import('resource://gre/modules/Payment.jsm');
 Cu.import("resource://gre/modules/AppsUtils.jsm");
 Cu.import('resource://gre/modules/UserAgentOverrides.jsm');
 Cu.import('resource://gre/modules/Keyboard.jsm');
+Cu.import('resource://gre/modules/ErrorPage.jsm');
 #ifdef MOZ_B2G_RIL
 Cu.import('resource://gre/modules/NetworkStatsService.jsm');
 #endif
 
 // identity
 Cu.import('resource://gre/modules/SignInToWebsite.jsm');
 SignInToWebsiteController.init();
 
--- a/b2g/chrome/jar.mn
+++ b/b2g/chrome/jar.mn
@@ -25,16 +25,17 @@ chrome.jar:
   content/payment.js                    (content/payment.js)
   content/identity.js                   (content/identity.js)
 
 % override chrome://global/content/netError.xhtml chrome://browser/content/netError.xhtml
 % override chrome://global/skin/netError.css chrome://browser/content/netError.css
 % override chrome://global/skin/media/videocontrols.css chrome://browser/content/touchcontrols.css
 % override chrome://global/content/aboutCertError.xhtml chrome://browser/content/aboutCertError.xhtml
 
+  content/ErrorPage.js                  (content/ErrorPage.js)
   content/netError.xhtml                (content/netError.xhtml)
   content/netError.css                  (content/netError.css)
   content/aboutCertError.xhtml          (content/aboutCertError.xhtml)
   content/images/errorpage-larry-black.png (content/images/errorpage-larry-black.png)
   content/images/errorpage-larry-white.png (content/images/errorpage-larry-white.png)
   content/images/errorpage-warning.png (content/images/errorpage-warning.png)
   content/images/scrubber-hdpi.png     (content/images/scrubber-hdpi.png)
   content/images/unmute-hdpi.png       (content/images/unmute-hdpi.png)
new file mode 100644
--- /dev/null
+++ b/b2g/components/ErrorPage.jsm
@@ -0,0 +1,169 @@
+/* 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/. */
+
+'use strict';
+
+this.EXPORTED_SYMBOLS = ['ErrorPage'];
+
+const Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const kErrorPageFrameScript = 'chrome://browser/content/ErrorPage.js';
+
+Cu.import('resource://gre/modules/Services.jsm');
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "CertOverrideService", function () {
+  return Cc["@mozilla.org/security/certoverride;1"]
+         .getService(Ci.nsICertOverrideService);
+});
+
+/**
+ * A class to add exceptions to override SSL certificate problems.
+ * The functionality itself is borrowed from exceptionDialog.js.
+ */
+function SSLExceptions(aCallback, aUri, aWindow) {
+  this._finishCallback = aCallback;
+  this._uri = aUri;
+  this._window = aWindow;
+};
+
+SSLExceptions.prototype = {
+  _finishCallback: null,
+  _window: null,
+  _uri: null,
+  _temporary: null,
+  _sslStatus: null,
+
+  getInterface: function SSLE_getInterface(aIID) {
+    return this.QueryInterface(aIID);
+  },
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIBadCertListener2]),
+
+  /**
+   * To collect the SSL status we intercept the certificate error here
+   * and store the status for later use.
+   */
+  notifyCertProblem: function SSLE_notifyCertProblem(aSocketInfo,
+                                                     aSslStatus,
+                                                     aTargetHost) {
+    this._sslStatus = aSslStatus.QueryInterface(Ci.nsISSLStatus);
+    Services.tm.currentThread.dispatch({
+      run: this._addOverride.bind(this)
+    }, Ci.nsIThread.DISPATCH_NORMAL);
+    return true; // suppress error UI
+  },
+
+  /**
+   * Attempt to download the certificate for the location specified to get
+   * the SSLState for the certificate and the errors.
+   */
+  _checkCert: function SSLE_checkCert() {
+    this._sslStatus = null;
+    if (!this._uri) {
+      return;
+    }
+    let req = new this._window.XMLHttpRequest();
+    try {
+      req.open("GET", this._uri.prePath, true);
+      req.channel.notificationCallbacks = this;
+      let xhrHandler = (function() {
+        req.removeEventListener("load", xhrHandler);
+        req.removeEventListener("error", xhrHandler);
+        if (!this._sslStatus) {
+          // Got response from server without an SSL error.
+          if (this._finishCallback) {
+            this._finishCallback();
+          }
+        }
+      }).bind(this);
+      req.addEventListener("load", xhrHandler);
+      req.addEventListener("error", xhrHandler);
+      req.send(null);
+    } catch (e) {
+      // We *expect* exceptions if there are problems with the certificate
+      // presented by the site.  Log it, just in case, but we can proceed here,
+      // with appropriate sanity checks
+      Components.utils.reportError("Attempted to connect to a site with a bad certificate in the add exception dialog. " +
+                                   "This results in a (mostly harmless) exception being thrown. " +
+                                   "Logged for information purposes only: " + e);
+    }
+  },
+
+  /**
+   * Internal method to create an override.
+   */
+  _addOverride: function SSLE_addOverride() {
+    let SSLStatus = this._sslStatus;
+    let uri = this._uri;
+    let flags = 0;
+
+    if (SSLStatus.isUntrusted) {
+      flags |= Ci.nsICertOverrideService.ERROR_UNTRUSTED;
+    }
+    if (SSLStatus.isDomainMismatch) {
+      flags |= Ci.nsICertOverrideService.ERROR_MISMATCH;
+    }
+    if (SSLStatus.isNotValidAtThisTime) {
+      flags |= Ci.nsICertOverrideService.ERROR_TIME;
+    }
+
+    CertOverrideService.rememberValidityOverride(
+      uri.asciiHost,
+      uri.port,
+      SSLStatus.serverCert,
+      flags,
+      this._temporary);
+
+    if (this._finishCallback) {
+      this._finishCallback();
+    }
+  },
+
+  /**
+   * Creates a permanent exception to override all overridable errors for
+   * the given URL.
+   */
+  addException: function SSLE_addException(aTemporary) {
+    this._temporary = aTemporary;
+    this._checkCert();
+  }
+};
+
+let ErrorPage = {
+  _addCertException: function(aMessage) {
+    let frameLoaderOwner = aMessage.target.QueryInterface(Ci.nsIFrameLoaderOwner);
+    let win = frameLoaderOwner.ownerDocument.defaultView;
+    let mm = frameLoaderOwner.frameLoader.messageManager;
+
+    let uri = Services.io.newURI(aMessage.data.url, null, null);
+    let sslExceptions = new SSLExceptions((function() {
+      mm.sendAsyncMessage('ErrorPage:ReloadPage');
+    }).bind(this), uri, win);
+    try {
+      sslExceptions.addException(!aMessage.data.isPermanent);
+    } catch (e) {
+      dump("Failed to set cert exception: " + e + "\n");
+    }
+  },
+
+  init: function errorPageInit() {
+    Services.obs.addObserver(this, 'in-process-browser-or-app-frame-shown', false);
+    Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
+  },
+
+  observe: function errorPageObserve(aSubject, aTopic, aData) {
+    let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
+    let mm = frameLoader.messageManager;
+    try {
+      mm.loadFrameScript(kErrorPageFrameScript, true);
+    } catch (e) {
+      dump('Error loading ' + kErrorPageFrameScript + ' as frame script: ' + e + '\n');
+    }
+    mm.addMessageListener('ErrorPage:AddCertException', this._addCertException.bind(this));
+  }
+};
+
+ErrorPage.init();
--- a/b2g/components/Makefile.in
+++ b/b2g/components/Makefile.in
@@ -27,15 +27,16 @@ EXTRA_PP_COMPONENTS = \
         YoutubeProtocolHandler.js \
         RecoveryService.js \
         $(NULL)
 
 EXTRA_JS_MODULES = \
 	Keyboard.jsm \
 	TelURIParser.jsm \
 	SignInToWebsite.jsm \
+	ErrorPage.jsm \
 	$(NULL)
 
 ifdef MOZ_UPDATER
 EXTRA_PP_COMPONENTS += UpdatePrompt.js
 endif
 
 include $(topsrcdir)/config/rules.mk
--- a/b2g/config/otoro/releng-otoro.tt
+++ b/b2g/config/otoro/releng-otoro.tt
@@ -1,12 +1,12 @@
 [
 {
-"size": 896434664,
-"digest": "bce8b7264948f1c97749a1c678b7635a9fc13c73ab6c2cf4557737b12cc523c0c51a52efbc73854f8d63d35667e8853345172f7c61a6d4f200fd3c295e483e3e",
+"size": 896338804,
+"digest": "b9609e56607af44de60c70c8570712167245c5597dc87921326c646a78fabf569d3a79f8cea350f2addeb7d9e749612cae870874ca9359297b2c0e1af7ae3993",
 "algorithm": "sha512",
 "filename": "gonk.tar.xz"
 },
 {
 "size": 4139008,
 "digest": "6f65553e882316582b944e46c659915a1b907c4a326104cb31d81356330dddacba757e3eafbd282063da0e670c3c5d6b9a0905ab88da84b47848d810c37571cb",
 "algorithm": "sha512",
 "filename": "boot.img"
--- a/b2g/config/otoro/sources.xml
+++ b/b2g/config/otoro/sources.xml
@@ -1,108 +1,109 @@
 <?xml version="1.0" ?><manifest>
   <!-- This is only a record of which revisions were pulled to generate the
        gonk.tar.xz snapshot referred to by releng-otoro.tt -->
 
   <remote fetch="https://android.googlesource.com/" name="aosp"/>
-  <remote fetch="https://git.mozilla.org/b2g" name="b2g"/>
-  <remote fetch="git://github.com/mozilla-b2g/" name="b2ggithub"/>
+  <remote fetch="https://git.mozilla.org/b2g" name="b2gmozilla"/>
+  <remote fetch="git://github.com/mozilla-b2g/" name="b2g"/>
   <remote fetch="git://github.com/mozilla/" name="mozilla"/>
   <remote fetch="git://codeaurora.org/" name="caf"/>
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
 
   <!-- Gonk specific things and forks -->
-  <project name="platform_build" path="build" remote="b2g" revision="777bee02feb43f8f29644f9d09ea7fe01d03f127">
+  <project name="platform_build" path="build" remote="b2g" revision="c647d5f967a5f17aaa27c792ea0ee35a2d44b113">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <!-- Information: fake-dalvik is tagged with B2G_1_0_0_20130125190500 --><project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8e68d41728675fc72502dc572dec523c2c8abb8a"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9429d142f7f46add49f4665ce81ac0c0416dd9c1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="f634b3d50effdd42828cc757c01fdbf74e562a36"/>
   <!-- Information: librecovery is tagged with B2G_1_0_0_20130125190500 --><project name="librecovery" path="librecovery" remote="b2g" revision="601fc18b28c9d7cf6954b281ddd3b705c74a9215"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="e1569feeb10891a55193e36b4a3939742151b05f"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="302ab954f16d0ad708e87a1cf5e94f5d93f174c9"/>
 
   <!-- Stock Android things -->
-  <!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
+  <!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <!-- Information: platform/bionic is tagged with M8960AAAAANLYA100715A --><project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
   <!-- Information: platform/bootable/recovery is tagged with M8960AAAAANLYA100715A --><project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/>
   <!-- Information: platform/development is tagged with M8960AAAAANLYA100715A --><project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/>
   <!-- Information: device/common is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
   <!-- Information: device/sample is tagged with M8960AAAAANLYA100715A --><project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
-  <project name="platform_external_apriori" path="external/apriori" remote="b2ggithub" revision="2c3a7113299eb789a076be23449d868b3bfa07fd"/>
+  <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="2c3a7113299eb789a076be23449d868b3bfa07fd"/>
   <!-- Information: platform/external/bluetooth/bluez is tagged with M76XXUSNEKNLYA2040 --><project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="1023c91c66e9c3bd1132480051993bf7827770f6"/>
-  <!-- Information: platform/external/bluetooth/glib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/bluetooth/glib" path="external/bluetooth/glib" revision="c6b49241cc1a8950723a5f74f8f4b4f4c3fa970e"/>
+  <!-- Information: platform/external/bluetooth/glib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/bluetooth/glib" path="external/bluetooth/glib" revision="c6b49241cc1a8950723a5f74f8f4b4f4c3fa970e"/>
   <!-- Information: platform/external/bluetooth/hcidump is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/bluetooth/hcidump" path="external/bluetooth/hcidump" revision="02b1eb24fbb3d0135a81edb4a2175b1397308d7d"/>
-  <!-- Information: platform/external/bsdiff is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/bsdiff" path="external/bsdiff" revision="81872540236d9bb15cccf963d05b9de48baa5375"/>
-  <!-- Information: platform/external/bzip2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
+  <!-- Information: platform/external/bsdiff is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/bsdiff" path="external/bsdiff" revision="81872540236d9bb15cccf963d05b9de48baa5375"/>
+  <!-- Information: platform/external/bzip2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
   <!-- Information: platform/external/dbus is tagged with M8960AAAAANLYA100715A --><project name="platform/external/dbus" path="external/dbus" revision="c7517b6195dc6926728352113e6cc335da3f9c9e"/>
   <!-- Information: platform/external/dhcpcd is tagged with M8960AAAAANLYA100715A --><project name="platform/external/dhcpcd" path="external/dhcpcd" revision="1e00fb67022d0921af0fead263f81762781b9ffa"/>
-  <!-- Information: platform/external/dnsmasq is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
-  <project name="platform_external_elfcopy" path="external/elfcopy" remote="b2ggithub" revision="62c1bed1c4505369cac2e72fbe30452a598fb690"/>
-  <project name="platform_external_elfutils" path="external/elfutils" remote="b2ggithub" revision="72940dec691fa3255e13df01f8c53b620e446066"/>
-  <!-- Information: platform/external/e2fsprogs is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="d5f550bb2f556c5d287f7c8d2b77223654bcec37"/>
-  <!-- Information: platform/external/expat is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/expat" path="external/expat" revision="6df134250feab71edb5915ecaa6268210bca76c5"/>
-  <!-- Information: platform/external/fdlibm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/fdlibm" path="external/fdlibm" revision="988ffeb12a6e044ae3504838ef1fee3fe0716934"/>
-  <!-- Information: platform/external/flac is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/flac" path="external/flac" revision="5893fbe890f5dab8e4146d2baa4bd2691c0739e0"/>
-  <!-- Information: platform/external/freetype is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
-  <!-- Information: platform/external/giflib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
+  <!-- Information: platform/external/dnsmasq is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
+  <project name="platform_external_elfcopy" path="external/elfcopy" remote="b2g" revision="62c1bed1c4505369cac2e72fbe30452a598fb690"/>
+  <project name="platform_external_elfutils" path="external/elfutils" remote="b2g" revision="72940dec691fa3255e13df01f8c53b620e446066"/>
+  <!-- Information: platform/external/e2fsprogs is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="d5f550bb2f556c5d287f7c8d2b77223654bcec37"/>
+  <!-- Information: platform/external/expat is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/expat" path="external/expat" revision="6df134250feab71edb5915ecaa6268210bca76c5"/>
+  <!-- Information: platform/external/fdlibm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/fdlibm" path="external/fdlibm" revision="988ffeb12a6e044ae3504838ef1fee3fe0716934"/>
+  <!-- Information: platform/external/flac is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/flac" path="external/flac" revision="5893fbe890f5dab8e4146d2baa4bd2691c0739e0"/>
+  <!-- Information: platform/external/freetype is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
+  <!-- Information: platform/external/giflib is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
   <project name="platform/external/gtest" path="external/gtest" revision="8c212ebe53bb2baab3575f03069016f1fb11e449"/>
-  <!-- Information: platform/external/harfbuzz is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/harfbuzz" path="external/harfbuzz" revision="116610d63a859521dacf00fb6818ee9ab2e666f6"/>
-  <!-- Information: platform/external/icu4c is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/icu4c" path="external/icu4c" revision="0fa67b93b831c6636ca18b152a1b1b14cc99b034"/>
-  <!-- Information: platform/external/iptables is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
+  <!-- Information: platform/external/harfbuzz is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/harfbuzz" path="external/harfbuzz" revision="116610d63a859521dacf00fb6818ee9ab2e666f6"/>
+  <!-- Information: platform/external/icu4c is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/icu4c" path="external/icu4c" revision="0fa67b93b831c6636ca18b152a1b1b14cc99b034"/>
+  <!-- Information: platform/external/iptables is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
   <!-- Information: platform/external/jpeg is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/jpeg" path="external/jpeg" revision="a62e464d672a4623233180e4023034bf825f066e"/>
-  <!-- Information: platform/external/libgsm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
-  <!-- Information: platform/external/liblzf is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
-  <!-- Information: platform/external/libnfc-nxp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.028 --><project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="3a912b065a31a72c63ad56ac224cfeaa933423b6"/>
-  <!-- Information: platform/external/libnl-headers is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
+  <!-- Information: platform/external/libgsm is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
+  <!-- Information: platform/external/liblzf is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
+  <!-- Information: platform/external/libnfc-nxp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="3a912b065a31a72c63ad56ac224cfeaa933423b6"/>
+  <!-- Information: platform/external/libnl-headers is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
   <!-- Information: platform/external/libpng is tagged with M8960AAAAANLYA100715A --><project name="platform/external/libpng" path="external/libpng" revision="9c3730f0efa69f580f03463c237cd928f3196404"/>
   <!-- Information: platform/external/libvpx is tagged with M8960AAAAANLYA1519349 --><project name="platform/external/libvpx" path="external/libvpx" revision="3a40da0d96da5c520e7707aa14f48a80956e20d7"/>
   <!-- Information: platform/external/llvm is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/llvm" path="external/llvm" revision="bff5923831940309f7d8ddbff5826ca6ed2dc050"/>
   <!-- Information: platform/external/mksh is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/mksh" path="external/mksh" revision="ec646e8f5e7dac9a77d1de549c6ed92c04d0cd4b"/>
   <!-- Information: platform_external_opensans is tagged with B2G_1_0_0_20130125190500 --><project name="platform_external_opensans" path="external/opensans" remote="b2g" revision="b5b4c226ca1d71e936153cf679dda6d3d60e2354"/>
   <!-- Information: platform/external/openssl is tagged with AU_LINUX_ANDROID_ICS.04.00.04.00.110 --><project name="platform/external/openssl" path="external/openssl" revision="27d333cce9a31c806b4bfa042925f045c727aecd"/>
-  <!-- Information: platform/external/protobuf is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
-  <!-- Information: platform/external/safe-iop is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
+  <!-- Information: platform/external/protobuf is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
+  <!-- Information: platform/external/safe-iop is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
   <!-- Information: screencap-gonk is tagged with B2G_1_0_0_20130125190500 --><project name="screencap-gonk" path="external/screencap-gonk" remote="b2g" revision="e6403c71e9eca8cb943739d5a0a192deac60fc51"/>
   <!-- Information: platform/external/skia is tagged with M8960AAAAANLYA100715A --><project name="platform/external/skia" path="external/skia" revision="7d90c85f2c0e3b747f7c7eff8bc9253b0063b439"/>
   <!-- Information: platform/external/sonivox is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/sonivox" path="external/sonivox" revision="7c967779dfc61ac1f346e972de91d4bfce7dccbb"/>
-  <!-- Information: platform/external/speex is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
+  <!-- Information: platform/external/speex is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
   <project name="platform/external/sqlite" path="external/sqlite" revision="fb30e613139b8836fdc8e81e166cf3a76e5fa17f"/>
-  <!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/stlport" path="external/stlport" revision="a6734e0645fce81c9610de0488b729207bfa576e"/>
-  <!-- Information: platform/external/strace is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
-  <!-- Information: platform/external/tagsoup is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
+  <!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/stlport" path="external/stlport" revision="a6734e0645fce81c9610de0488b729207bfa576e"/>
+  <!-- Information: platform/external/strace is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
+  <!-- Information: platform/external/tagsoup is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
   <!-- Information: platform/external/tinyalsa is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/tinyalsa" path="external/tinyalsa" revision="06cc244ee512c1352215e543615738bc8ac82814"/>
-  <!-- Information: platform/external/tremolo is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
+  <!-- Information: platform/external/tremolo is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
   <!-- Information: unbootimg is tagged with B2G_1_0_0_20130125190500 --><project name="unbootimg" path="external/unbootimg" remote="b2g" revision="9464623d92eb8668544916dc5a8f4f6337d0bc08"/>
-  <!-- Information: platform/external/webp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/webp" path="external/webp" revision="88fe2b83c4b9232cd08729556fd0485d6a6a92cd"/>
-  <!-- Information: platform/external/webrtc is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/webrtc" path="external/webrtc" revision="137024dc8a2e9251a471e20518a9c3ae06f81f23"/>
-  <!-- Information: platform/external/wpa_supplicant is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
+  <!-- Information: platform/external/webp is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/webp" path="external/webp" revision="88fe2b83c4b9232cd08729556fd0485d6a6a92cd"/>
+  <!-- Information: platform/external/webrtc is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/webrtc" path="external/webrtc" revision="137024dc8a2e9251a471e20518a9c3ae06f81f23"/>
+  <!-- Information: platform/external/wpa_supplicant is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
   <!-- Information: platform/external/hostap is tagged with M8960AAAAANLYA1047 --><project name="platform/external/hostap" path="external/hostap" revision="bf04b0faadbdeb4b7943f2e2c4c5aa59df872bb1"/>
   <!-- Information: platform/external/zlib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.01.19.008 --><project name="platform/external/zlib" path="external/zlib" revision="f96a1d1ebfdf1cd582210fd09c23d8f59e0ae094"/>
-  <!-- Information: platform/external/yaffs2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/yaffs2" path="external/yaffs2" revision="0afa916204c664b3114429637b63af1321a0aeca"/>
+  <!-- Information: platform/external/yaffs2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/yaffs2" path="external/yaffs2" revision="0afa916204c664b3114429637b63af1321a0aeca"/>
   <!-- Information: platform/frameworks/base is tagged with M76XXUSNEKNLYA2040 --><project name="platform/frameworks/base" path="frameworks/base" revision="eb2bc75803ca179353c24c364a9c8a8ce23e8b78"/>
-  <!-- Information: platform/frameworks/opt/emoji is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="a95d8db002770469d72dfaf59ff37ac96db29a87"/>
+  <!-- Information: platform/frameworks/opt/emoji is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="a95d8db002770469d72dfaf59ff37ac96db29a87"/>
   <!-- Information: platform/frameworks/support is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/frameworks/support" path="frameworks/support" revision="27208692b001981f1806f4f396434f4eac78b909"/>
   <!-- Information: platform/hardware/libhardware is tagged with M8960AAAAANLYA1049B --><project name="platform/hardware/libhardware" path="hardware/libhardware" revision="4a619901847621f8a7305edf42dd07347a140484"/>
   <!-- Information: platform/hardware/libhardware_legacy is tagged with M8960AAAAANLYA153611 --><project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="87b4d7afa8f854b445e2d0d95091f6f6069f2b30"/>
   <!-- Information: platform/libcore is tagged with M8960AAAAANLYA100715A --><project name="platform/libcore" path="libcore" revision="30841f9fba9ccd5c54f4f079f495994db97f283e"/>
-  <!-- Information: platform/ndk is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/ndk" path="ndk" revision="9f555971e1481854d5b4dc11b3e6af9fff4f241f"/>
+  <!-- Information: platform/ndk is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/ndk" path="ndk" revision="9f555971e1481854d5b4dc11b3e6af9fff4f241f"/>
   <!-- Information: platform/prebuilt is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/prebuilt" path="prebuilt" revision="447ea790fcc957dde59730ecc2a65ca263bdc733"/>
   <!-- Information: platform/system/bluetooth is tagged with M8960AAAAANLYA100703 --><project name="platform/system/bluetooth" path="system/bluetooth" revision="7772cad4823f1f427ce1d4df84a55982386d6d18"/>
   <!-- Information: platform/system/core is tagged with M76XXUSNEKNLYA2040 --><project name="platform/system/core" path="system/core" revision="bf1970408676ce570b8f4dc3efa038e47552137f"/>
   <!-- Information: platform/system/extras is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/system/extras" path="system/extras" revision="01db6c1254e1407740a543f24317fc540fc4c049"/>
   <!-- Information: platform/system/media is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/system/media" path="system/media" revision="7f71c7fd362bbd992ff2e0e80f7af5859ad116ad"/>
   <!-- Information: platform/system/netd is tagged with M8960AAAAANLYA1049 --><project name="platform/system/netd" path="system/netd" revision="306e765248e3900041bf2737e9f57b1b5694a4ce"/>
   <!-- Information: platform/system/vold is tagged with M8960AAAAANLYA100715A --><project name="platform/system/vold" path="system/vold" revision="99fff257d53cc045d1460841edca5d901dacfcf5"/>
 
-  <!-- Otoro/Unagi specific things -->
+  <!-- Otoro/Unagi/Inari specific things -->
   <!-- Information: device/qcom/common is tagged with M8960AAAAANLYA100715A --><project name="device/qcom/common" path="device/qcom/common" revision="b9cdab8e1e1a215a8c65b8d5816f666bec7be205"/>
   <!-- Information: platform/vendor/qcom/msm7627a is tagged with M8960AAAAANLYA100715A --><project name="platform/vendor/qcom/msm7627a" path="device/qcom/msm7627a" revision="d920a502ba17cf4d716f8b1a615f07e796b0501a"/>
-  <!-- Information: android-device-otoro is tagged with B2G_1_0_0_20130125190500 --><project name="android-device-otoro" path="device/qcom/otoro" remote="b2g" revision="7662275433fc0b1d8b035f03185b24b7ca965ab4"/>
+  <project name="android-device-otoro" path="device/qcom/otoro" remote="b2g" revision="89f106ed6a538f2868bb873d11b68ea7b2e62f26"/>
   <!-- Information: android-device-unagi is tagged with B2G_1_0_0_20130125190500 --><project name="android-device-unagi" path="device/qcom/unagi" remote="b2g" revision="6c014552d1b26bee611d9a9b23bd4cd014e392ee"/>
+  <project name="device-inari" path="device/qcom/inari" remote="b2g" revision="6b5d034f86da7938af9887308ecff6e391e6928a"/>
   <!-- Information: codeaurora_kernel_msm is tagged with B2G_1_0_0_20130125190500 --><project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="0a01247e4b0880f93424b27251cd3a1f6b19dbb2"/>
   <!-- Information: platform/hardware/qcom/camera is tagged with M76XXUSNEKNLYA2040 --><project name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="1acf77a75e30f3fc8b1eed2057c97adf1cb1633f"/>
   <!-- Information: hardware_qcom_display is tagged with B2G_1_0_0_20130125190500 --><project name="hardware_qcom_display" path="hardware/qcom/display" remote="b2g" revision="6405d30f2fac7d8a1f2cb17b99fb7dd0a8bcfdac"/>
   <!-- Information: platform/hardware/qcom/media is tagged with M8960AAAAANLYA100715A --><project name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="552c3ddb7174a01f3508782d40c4d8c845ab441a"/>
   <!-- Information: platform/hardware/qcom/gps is tagged with M8960AAAAANLYA100705 --><project name="platform/hardware/qcom/gps" path="hardware/qcom/gps" revision="23d5707b320d7fc69f8ba3b7d84d78a1c5681708"/>
   <!-- Information: platform/hardware/msm7k is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.01.19.008 --><project name="platform/hardware/msm7k" path="hardware/msm7k" revision="8892d46805c5639b55dd07547745c5180da861e7"/>
   <!-- Information: platform/vendor/qcom-opensource/omx/mm-core is tagged with M8960AAAAANLYA100715A --><project name="platform/vendor/qcom-opensource/omx/mm-core" path="vendor/qcom/opensource/omx/mm-core" revision="ab17ac9a074b4bb69986a8436336bdfbbaf9cd39"/>
   <!-- Information: platform/hardware/ril is tagged with M76XXUSNEKNLYA1610 --><project name="platform/hardware/ril" path="hardware/ril" remote="caf" revision="fe9a3f63922143b57e79ed570bab2328df8c83a5"/>
--- a/b2g/config/panda/releng-pandaboard.tt
+++ b/b2g/config/panda/releng-pandaboard.tt
@@ -1,12 +1,12 @@
 [
 {
-"size": 677817512,
-"digest": "746a6acd08be2065a077ba860df4be8ca53bca16ea868911407b8d3dc4fc2becd8cee2c88d51e8bfce4f07caa37184b91ba4d6afba937a25b424142a6e605fdc",
+"size": 677944136,
+"digest": "229b264aefa4831c7b0498097c87ae9a33baaa0ad3680b54263f4d9c8008f91bf031261f740d11259921c2805f4707cfa5f3d977e38b83c7b221b6617af8a3b1",
 "algorithm": "sha512",
 "filename": "gonk.tar.xz"
 },
 {
 "size": 2116507,
 "digest": "be67a012963a5c162834f9fcb989bcebd2d047dcb4e17ee23031b694dcf7cdfd6d7a6545d7a1f5e7293b6d24415403972f4ea1ab8c6c78fefcabfaf3f6875214",
 "algorithm": "sha512",
 "filename": "download-panda.tar.bz2"
--- a/b2g/config/panda/sources.xml
+++ b/b2g/config/panda/sources.xml
@@ -6,82 +6,83 @@
   <remote fetch="git://github.com/mozilla-b2g/" name="b2g"/>
   <remote fetch="http://android.git.linaro.org/git-ro/" name="linaro"/>
   <remote fetch="git://codeaurora.org/" name="caf"/>
   <remote fetch="git://github.com/mozilla/" name="mozilla"/>
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
 
   <!-- Gonk specific things and forks -->
-  <project name="platform_build" path="build" remote="b2g" revision="777bee02feb43f8f29644f9d09ea7fe01d03f127">
+  <project name="platform_build" path="build" remote="b2g" revision="c647d5f967a5f17aaa27c792ea0ee35a2d44b113">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <!-- Information: fake-dalvik is tagged with B2G_1_0_0_20130125190500 --><project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8e68d41728675fc72502dc572dec523c2c8abb8a"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9429d142f7f46add49f4665ce81ac0c0416dd9c1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="f634b3d50effdd42828cc757c01fdbf74e562a36"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="e1569feeb10891a55193e36b4a3939742151b05f"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="302ab954f16d0ad708e87a1cf5e94f5d93f174c9"/>
 
   <!-- Stock Android things -->
-  <!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
+  <!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="c7bab8cb8483e7869eabdbd4add7c9e5beeecc80"/>
   <!-- Information: platform/bootable/recovery is tagged with android-4.0.4_r2.1 --><project name="platform/bootable/recovery" path="bootable/recovery" revision="fadc5ac81d6400ebdd041f7d4ea64021596d6b7d"/>
   <!-- Information: device/common is tagged with android-sdk-adt_r20 --><project name="device/common" path="device/common" revision="7d4526582f88808a3194e1a3b304abb369d2745c"/>
   <!-- Information: device/sample is tagged with android-4.0.4_r2.1 --><project name="device/sample" path="device/sample" revision="ef228b8b377a9663e94be4b1aeb6c2bf7a07d098"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="2c3a7113299eb789a076be23449d868b3bfa07fd"/>
   <!-- Information: platform/external/bluetooth/bluez is tagged with android-4.0.4_r2.1 --><project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="966afbd88f0bfc325bf80274ad2723c238883fa1"/>
   <!-- Information: platform/external/bluetooth/glib is tagged with android-cts-4.1_r2 --><project name="platform/external/bluetooth/glib" path="external/bluetooth/glib" revision="1143b9918eab068401b604eb11c3f651f4e38b25"/>
   <!-- Information: platform/external/bluetooth/hcidump is tagged with android-cts-4.1_r2 --><project name="platform/external/bluetooth/hcidump" path="external/bluetooth/hcidump" revision="7322661808c2006b7848e79e6bb72b37fbcf6710"/>
-  <!-- Information: platform/external/bsdiff is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/bsdiff" path="external/bsdiff" revision="81872540236d9bb15cccf963d05b9de48baa5375"/>
+  <!-- Information: platform/external/bsdiff is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/bsdiff" path="external/bsdiff" revision="81872540236d9bb15cccf963d05b9de48baa5375"/>
   <project name="platform/external/busybox" path="external/busybox" remote="linaro" revision="2e461c8029a50d986dfe4ab07ae5a1834b5c40f0"/>
-  <!-- Information: platform/external/bzip2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
+  <!-- Information: platform/external/bzip2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
   <!-- Information: platform/external/dbus is tagged with android-cts-4.1_r2 --><project name="platform/external/dbus" path="external/dbus" revision="537eaff5de9aace3348436166d4cde7adc1e488e"/>
   <!-- Information: platform/external/dhcpcd is tagged with android-sdk-adt_r20 --><project name="platform/external/dhcpcd" path="external/dhcpcd" revision="ddaa48f57b54b2862b3e6dcf18a44c9647f3baaa"/>
-  <!-- Information: platform/external/dnsmasq is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
+  <!-- Information: platform/external/dnsmasq is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
   <project name="platform_external_elfcopy" path="external/elfcopy" remote="b2g" revision="62c1bed1c4505369cac2e72fbe30452a598fb690"/>
   <project name="platform_external_elfutils" path="external/elfutils" remote="b2g" revision="72940dec691fa3255e13df01f8c53b620e446066"/>
-  <!-- Information: platform/external/expat is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/expat" path="external/expat" revision="6df134250feab71edb5915ecaa6268210bca76c5"/>
-  <!-- Information: platform/external/fdlibm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/fdlibm" path="external/fdlibm" revision="988ffeb12a6e044ae3504838ef1fee3fe0716934"/>
-  <!-- Information: platform/external/flac is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/flac" path="external/flac" revision="5893fbe890f5dab8e4146d2baa4bd2691c0739e0"/>
-  <!-- Information: platform/external/freetype is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
-  <!-- Information: platform/external/giflib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
+  <!-- Information: platform/external/expat is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/expat" path="external/expat" revision="6df134250feab71edb5915ecaa6268210bca76c5"/>
+  <!-- Information: platform/external/fdlibm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/fdlibm" path="external/fdlibm" revision="988ffeb12a6e044ae3504838ef1fee3fe0716934"/>
+  <!-- Information: platform/external/flac is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/flac" path="external/flac" revision="5893fbe890f5dab8e4146d2baa4bd2691c0739e0"/>
+  <!-- Information: platform/external/freetype is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
+  <!-- Information: platform/external/giflib is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
   <project name="platform/external/gtest" path="external/gtest" revision="8c212ebe53bb2baab3575f03069016f1fb11e449"/>
   <!-- Information: platform/external/harfbuzz is tagged with android-sdk-adt_r20 --><project name="platform/external/harfbuzz" path="external/harfbuzz" revision="bae491c03a00757d83ede8d855b7d85d246bde3d"/>
-  <!-- Information: platform/external/icu4c is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/icu4c" path="external/icu4c" revision="0fa67b93b831c6636ca18b152a1b1b14cc99b034"/>
-  <!-- Information: platform/external/iptables is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
-  <!-- Information: platform/external/jhead is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/jhead" path="external/jhead" revision="754078052c687f6721536009c816644c73e4f145"/>
+  <!-- icu4c is missing the default tag in caf, that's the *only* reason for the hardcode -->
+  <!-- Information: platform/external/icu4c is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/icu4c" path="external/icu4c" revision="0fa67b93b831c6636ca18b152a1b1b14cc99b034"/>
+  <!-- Information: platform/external/iptables is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
+  <!-- Information: platform/external/jhead is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/jhead" path="external/jhead" revision="754078052c687f6721536009c816644c73e4f145"/>
   <!-- Information: platform/external/jpeg is tagged with android-cts-4.1_r2 --><project name="platform/external/jpeg" path="external/jpeg" revision="d4fad7f50f79626455d88523207e05b868819cd8"/>
-  <!-- Information: platform/external/libgsm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
-  <!-- Information: platform/external/liblzf is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
+  <!-- Information: platform/external/libgsm is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
+  <!-- Information: platform/external/liblzf is tagged with AU_LINUX_ANDROID_JB_MR1.04.02.02.49.187 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
   <!-- Information: platform/external/libnfc-nxp is tagged with android-4.0.4_r2.1 --><project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="533c14450e6239cce8acb74f4e4dea2c89f8f219"/>
-  <!-- Information: platform/external/libnl-headers is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
+  <!-- Information: platform/external/libnl-headers is tagged with AU_LINUX_ANDROID_JB_MR1.04.02.02.49.187 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
   <!-- Information: platform/external/libpng is tagged with android-4.0.4_r2.1 --><project name="platform/external/libpng" path="external/libpng" revision="84d92c718ab9f48faec0f640747c4b6f7a995607"/>
   <!-- Information: platform/external/libvpx is tagged with M8960AAAAANLYA1519349 --><project name="platform/external/libvpx" path="external/libvpx" revision="3a40da0d96da5c520e7707aa14f48a80956e20d7"/>
   <!-- Information: platform/external/mksh is tagged with M8960AAAAANLYA1099D --><project name="platform/external/mksh" path="external/mksh" revision="5155f1c7438ef540d7b25eb70aa1639579795b07"/>
   <!-- Information: platform_external_opensans is tagged with B2G_1_0_0_20130125190500 --><project name="platform_external_opensans" path="external/opensans" remote="b2g" revision="b5b4c226ca1d71e936153cf679dda6d3d60e2354"/>
   <!-- Information: platform/external/openssl is tagged with android-4.0.4_r2.1 --><project name="platform/external/openssl" path="external/openssl" revision="ce96fb211b9a44bbd7fb5ef7ed0e6c1244045c2e"/>
-  <!-- Information: platform/external/protobuf is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
-  <!-- Information: platform/external/safe-iop is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
+  <!-- Information: platform/external/protobuf is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
+  <!-- Information: platform/external/safe-iop is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
   <!-- Information: screencap-gonk is tagged with B2G_1_0_0_20130125190500 --><project name="screencap-gonk" path="external/screencap-gonk" remote="b2g" revision="e6403c71e9eca8cb943739d5a0a192deac60fc51"/>
   <!-- Information: platform/external/skia is tagged with android-4.0.4_r2.1 --><project name="platform/external/skia" path="external/skia" revision="5c67a309e16bffe7013defda8f1217b3ce2420b4"/>
   <!-- Information: platform/external/sonivox is tagged with android-sdk-adt_r20 --><project name="platform/external/sonivox" path="external/sonivox" revision="5f9600971859fe072f31b38a51c38157f5f9b381"/>
-  <!-- Information: platform/external/speex is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
+  <!-- Information: platform/external/speex is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
   <!-- Information: platform/external/sqlite is tagged with android-4.0.4_r2.1 --><project name="platform/external/sqlite" path="external/sqlite" revision="c999ff8c12a4cf81cb9ad628f47b2720effba5e5"/>
-  <!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/stlport" path="external/stlport" revision="a6734e0645fce81c9610de0488b729207bfa576e"/>
-  <!-- Information: platform/external/strace is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
-  <!-- Information: platform/external/tagsoup is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
+  <!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/stlport" path="external/stlport" revision="a6734e0645fce81c9610de0488b729207bfa576e"/>
+  <!-- Information: platform/external/strace is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
+  <!-- Information: platform/external/tagsoup is tagged with AU_LINUX_ANDROID_JB_MR1.04.02.02.49.187 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
   <!-- Information: platform/external/tinyalsa is tagged with android-4.0.4_r2.1 --><project name="platform/external/tinyalsa" path="external/tinyalsa" revision="495239e683a728957c890c124b239f9b7b8ef5a8"/>
-  <!-- Information: platform/external/tremolo is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
-  <!-- Information: platform/external/webp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/webp" path="external/webp" revision="88fe2b83c4b9232cd08729556fd0485d6a6a92cd"/>
+  <!-- Information: platform/external/tremolo is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
+  <!-- Information: platform/external/webp is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/webp" path="external/webp" revision="88fe2b83c4b9232cd08729556fd0485d6a6a92cd"/>
   <!-- Information: platform/external/webrtc is tagged with android-sdk-adt_r20 --><project name="platform/external/webrtc" path="external/webrtc" revision="4b6dc1ec58105d17dc8c2f550124cc0621dc93b7"/>
-  <!-- Information: platform/external/wpa_supplicant is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
+  <!-- Information: platform/external/wpa_supplicant is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
   <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="6dd24fc3792d71edccef9b09140f9a44b063a553"/>
   <!-- Information: platform/external/zlib is tagged with android-4.0.4_r2.1 --><project name="platform/external/zlib" path="external/zlib" revision="69e5801bd16a495e1c1666669fe827b1ddb8d56b"/>
   <!-- Information: platform/external/yaffs2 is tagged with android-4.0.4-aah_r1 --><project name="platform/external/yaffs2" path="external/yaffs2" revision="6232e2d5ab34a40d710e4b05ab0ec6e3727804e7"/>
   <!-- Information: platform/frameworks/base is tagged with android-4.0.4_r2.1 --><project name="platform/frameworks/base" path="frameworks/base" revision="df331873c8576e0ae34ae1ee3cc258beed373535"/>
-  <!-- Information: platform/frameworks/opt/emoji is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="a95d8db002770469d72dfaf59ff37ac96db29a87"/>
+  <!-- Information: platform/frameworks/opt/emoji is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="a95d8db002770469d72dfaf59ff37ac96db29a87"/>
   <!-- Information: platform/frameworks/support is tagged with android-4.0.4_r2.1 --><project name="platform/frameworks/support" path="frameworks/support" revision="bfc8e01b7b0d5ea70ce89d0409b72b7f7d540f43"/>
   <!-- Information: platform/hardware/libhardware is tagged with android-4.0.4_r2.1 --><project name="platform/hardware/libhardware" path="hardware/libhardware" revision="a9b677fce432b29ab8f61e13796f34880dc0fe0f"/>
   <!-- Information: platform/hardware/libhardware_legacy is tagged with android-4.0.4_r2.1 --><project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="153d0f1a27e0a157cabb6ca9d0d88248630f5695"/>
   <!-- Information: platform/hardware/ril is tagged with android-4.0.4_r2.1 --><project name="platform/hardware/ril" path="hardware/ril" revision="300105d1487f5238940c18792b879793826b61f4"/>
   <!-- Information: platform/libcore is tagged with android-4.0.4_r2.1 --><project name="platform/libcore" path="libcore" revision="fc294a48d80d9e2b2ac126edf93ad316f5f6cf72"/>
   <!-- Information: platform/ndk is tagged with android-4.0.4_r2.1 --><project name="platform/ndk" path="ndk" revision="2d77f5a05f60029c981f299b222cfe28db18ccf7"/>
   <!-- Information: platform/prebuilt is tagged with tungsten-bootloader-ics-aah --><project name="platform/prebuilt" path="prebuilt" revision="0e104261b6d33f87e9f86ff4249bcc0306ab278b"/>
   <!-- Information: platform/system/bluetooth is tagged with android-4.0.4_r2.1 --><project name="platform/system/bluetooth" path="system/bluetooth" revision="2588cd802f322650ed737dfb7a10e9ad94064e99"/>
--- a/b2g/config/unagi/releng-unagi.tt
+++ b/b2g/config/unagi/releng-unagi.tt
@@ -1,12 +1,12 @@
 [
 {
-"size": 833575768,
-"digest": "c8362a7cbfa1aa99eb0931fe9b6432496918e362b9ac675107c4177ea1a7ae0cc094970580c804213fb4cbe7ca4c40c30c92e2031482a425dff0a17bea3c94da",
+"size": 833339832,
+"digest": "c5bc3424d9a52bd12dc6d849e8bd111514a7edfb84180bf8dd67f77e925fea95e9f41afade187694e1724b3d9b817e7cf2ba62be000a9f11db1e7ff689bb85fd",
 "algorithm": "sha512",
 "filename": "gonk.tar.xz"
 },
 {
 "size": 8622080,
 "digest": "36681be904b20a52dbebf38b86466026430d59adb0e72428ae7557a442d037eb378d278aab181b04a753821ff0a99b6228380d59f86ddd5fbf291284fe54932b",
 "algorithm": "sha512",
 "filename": "boot.img"
--- a/b2g/config/unagi/sources.xml
+++ b/b2g/config/unagi/sources.xml
@@ -1,108 +1,109 @@
 <?xml version="1.0" ?><manifest>
   <!-- This is only a record of which revisions were pulled to generate the
        gonk.tar.xz snapshot referred to by releng-unagi.tt -->
 
   <remote fetch="https://android.googlesource.com/" name="aosp"/>
-  <remote fetch="https://git.mozilla.org/b2g" name="b2g"/>
-  <remote fetch="git://github.com/mozilla-b2g/" name="b2ggithub"/>
+  <remote fetch="https://git.mozilla.org/b2g" name="b2gmozilla"/>
+  <remote fetch="git://github.com/mozilla-b2g/" name="b2g"/>
   <remote fetch="git://github.com/mozilla/" name="mozilla"/>
   <remote fetch="git://codeaurora.org/" name="caf"/>
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
 
   <!-- Gonk specific things and forks -->
-  <project name="platform_build" path="build" remote="b2g" revision="777bee02feb43f8f29644f9d09ea7fe01d03f127">
+  <project name="platform_build" path="build" remote="b2g" revision="c647d5f967a5f17aaa27c792ea0ee35a2d44b113">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <!-- Information: fake-dalvik is tagged with B2G_1_0_0_20130125190500 --><project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8e68d41728675fc72502dc572dec523c2c8abb8a"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9429d142f7f46add49f4665ce81ac0c0416dd9c1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="f634b3d50effdd42828cc757c01fdbf74e562a36"/>
   <!-- Information: librecovery is tagged with B2G_1_0_0_20130125190500 --><project name="librecovery" path="librecovery" remote="b2g" revision="601fc18b28c9d7cf6954b281ddd3b705c74a9215"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="e1569feeb10891a55193e36b4a3939742151b05f"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="302ab954f16d0ad708e87a1cf5e94f5d93f174c9"/>
 
   <!-- Stock Android things -->
-  <!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.028 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
+  <!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <!-- Information: platform/bionic is tagged with M8960AAAAANLYA100715A --><project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
   <!-- Information: platform/bootable/recovery is tagged with M8960AAAAANLYA100715A --><project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/>
   <!-- Information: platform/development is tagged with M8960AAAAANLYA100715A --><project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/>
   <!-- Information: device/common is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
   <!-- Information: device/sample is tagged with M8960AAAAANLYA100715A --><project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
-  <project name="platform_external_apriori" path="external/apriori" remote="b2ggithub" revision="2c3a7113299eb789a076be23449d868b3bfa07fd"/>
+  <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="2c3a7113299eb789a076be23449d868b3bfa07fd"/>
   <!-- Information: platform/external/bluetooth/bluez is tagged with M76XXUSNEKNLYA2040 --><project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="1023c91c66e9c3bd1132480051993bf7827770f6"/>
-  <!-- Information: platform/external/bluetooth/glib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/bluetooth/glib" path="external/bluetooth/glib" revision="c6b49241cc1a8950723a5f74f8f4b4f4c3fa970e"/>
+  <!-- Information: platform/external/bluetooth/glib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/bluetooth/glib" path="external/bluetooth/glib" revision="c6b49241cc1a8950723a5f74f8f4b4f4c3fa970e"/>
   <!-- Information: platform/external/bluetooth/hcidump is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/bluetooth/hcidump" path="external/bluetooth/hcidump" revision="02b1eb24fbb3d0135a81edb4a2175b1397308d7d"/>
-  <!-- Information: platform/external/bsdiff is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/bsdiff" path="external/bsdiff" revision="81872540236d9bb15cccf963d05b9de48baa5375"/>
-  <!-- Information: platform/external/bzip2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
+  <!-- Information: platform/external/bsdiff is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/bsdiff" path="external/bsdiff" revision="81872540236d9bb15cccf963d05b9de48baa5375"/>
+  <!-- Information: platform/external/bzip2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
   <!-- Information: platform/external/dbus is tagged with M8960AAAAANLYA100715A --><project name="platform/external/dbus" path="external/dbus" revision="c7517b6195dc6926728352113e6cc335da3f9c9e"/>
   <!-- Information: platform/external/dhcpcd is tagged with M8960AAAAANLYA100715A --><project name="platform/external/dhcpcd" path="external/dhcpcd" revision="1e00fb67022d0921af0fead263f81762781b9ffa"/>
-  <!-- Information: platform/external/dnsmasq is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.028 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
-  <project name="platform_external_elfcopy" path="external/elfcopy" remote="b2ggithub" revision="62c1bed1c4505369cac2e72fbe30452a598fb690"/>
-  <project name="platform_external_elfutils" path="external/elfutils" remote="b2ggithub" revision="72940dec691fa3255e13df01f8c53b620e446066"/>
-  <!-- Information: platform/external/e2fsprogs is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="d5f550bb2f556c5d287f7c8d2b77223654bcec37"/>
-  <!-- Information: platform/external/expat is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/expat" path="external/expat" revision="6df134250feab71edb5915ecaa6268210bca76c5"/>
-  <!-- Information: platform/external/fdlibm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/fdlibm" path="external/fdlibm" revision="988ffeb12a6e044ae3504838ef1fee3fe0716934"/>
-  <!-- Information: platform/external/flac is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/flac" path="external/flac" revision="5893fbe890f5dab8e4146d2baa4bd2691c0739e0"/>
-  <!-- Information: platform/external/freetype is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
-  <!-- Information: platform/external/giflib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.028 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
+  <!-- Information: platform/external/dnsmasq is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
+  <project name="platform_external_elfcopy" path="external/elfcopy" remote="b2g" revision="62c1bed1c4505369cac2e72fbe30452a598fb690"/>
+  <project name="platform_external_elfutils" path="external/elfutils" remote="b2g" revision="72940dec691fa3255e13df01f8c53b620e446066"/>
+  <!-- Information: platform/external/e2fsprogs is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="d5f550bb2f556c5d287f7c8d2b77223654bcec37"/>
+  <!-- Information: platform/external/expat is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/expat" path="external/expat" revision="6df134250feab71edb5915ecaa6268210bca76c5"/>
+  <!-- Information: platform/external/fdlibm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/fdlibm" path="external/fdlibm" revision="988ffeb12a6e044ae3504838ef1fee3fe0716934"/>
+  <!-- Information: platform/external/flac is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/flac" path="external/flac" revision="5893fbe890f5dab8e4146d2baa4bd2691c0739e0"/>
+  <!-- Information: platform/external/freetype is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
+  <!-- Information: platform/external/giflib is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
   <project name="platform/external/gtest" path="external/gtest" revision="8c212ebe53bb2baab3575f03069016f1fb11e449"/>
-  <!-- Information: platform/external/harfbuzz is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/harfbuzz" path="external/harfbuzz" revision="116610d63a859521dacf00fb6818ee9ab2e666f6"/>
-  <!-- Information: platform/external/icu4c is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/icu4c" path="external/icu4c" revision="0fa67b93b831c6636ca18b152a1b1b14cc99b034"/>
-  <!-- Information: platform/external/iptables is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
+  <!-- Information: platform/external/harfbuzz is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/harfbuzz" path="external/harfbuzz" revision="116610d63a859521dacf00fb6818ee9ab2e666f6"/>
+  <!-- Information: platform/external/icu4c is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/icu4c" path="external/icu4c" revision="0fa67b93b831c6636ca18b152a1b1b14cc99b034"/>
+  <!-- Information: platform/external/iptables is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
   <!-- Information: platform/external/jpeg is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/jpeg" path="external/jpeg" revision="a62e464d672a4623233180e4023034bf825f066e"/>
-  <!-- Information: platform/external/libgsm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
-  <!-- Information: platform/external/liblzf is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
-  <!-- Information: platform/external/libnfc-nxp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.028 --><project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="3a912b065a31a72c63ad56ac224cfeaa933423b6"/>
-  <!-- Information: platform/external/libnl-headers is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
+  <!-- Information: platform/external/libgsm is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
+  <!-- Information: platform/external/liblzf is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
+  <!-- Information: platform/external/libnfc-nxp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="3a912b065a31a72c63ad56ac224cfeaa933423b6"/>
+  <!-- Information: platform/external/libnl-headers is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
   <!-- Information: platform/external/libpng is tagged with M8960AAAAANLYA100715A --><project name="platform/external/libpng" path="external/libpng" revision="9c3730f0efa69f580f03463c237cd928f3196404"/>
   <!-- Information: platform/external/libvpx is tagged with M8960AAAAANLYA1519349 --><project name="platform/external/libvpx" path="external/libvpx" revision="3a40da0d96da5c520e7707aa14f48a80956e20d7"/>
   <!-- Information: platform/external/llvm is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/llvm" path="external/llvm" revision="bff5923831940309f7d8ddbff5826ca6ed2dc050"/>
   <!-- Information: platform/external/mksh is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/mksh" path="external/mksh" revision="ec646e8f5e7dac9a77d1de549c6ed92c04d0cd4b"/>
   <!-- Information: platform_external_opensans is tagged with B2G_1_0_0_20130125190500 --><project name="platform_external_opensans" path="external/opensans" remote="b2g" revision="b5b4c226ca1d71e936153cf679dda6d3d60e2354"/>
   <!-- Information: platform/external/openssl is tagged with AU_LINUX_ANDROID_ICS.04.00.04.00.110 --><project name="platform/external/openssl" path="external/openssl" revision="27d333cce9a31c806b4bfa042925f045c727aecd"/>
-  <!-- Information: platform/external/protobuf is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
-  <!-- Information: platform/external/safe-iop is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
+  <!-- Information: platform/external/protobuf is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
+  <!-- Information: platform/external/safe-iop is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
   <!-- Information: screencap-gonk is tagged with B2G_1_0_0_20130125190500 --><project name="screencap-gonk" path="external/screencap-gonk" remote="b2g" revision="e6403c71e9eca8cb943739d5a0a192deac60fc51"/>
   <!-- Information: platform/external/skia is tagged with M8960AAAAANLYA100715A --><project name="platform/external/skia" path="external/skia" revision="7d90c85f2c0e3b747f7c7eff8bc9253b0063b439"/>
   <!-- Information: platform/external/sonivox is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/sonivox" path="external/sonivox" revision="7c967779dfc61ac1f346e972de91d4bfce7dccbb"/>
-  <!-- Information: platform/external/speex is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
+  <!-- Information: platform/external/speex is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
   <project name="platform/external/sqlite" path="external/sqlite" revision="fb30e613139b8836fdc8e81e166cf3a76e5fa17f"/>
-  <!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/stlport" path="external/stlport" revision="a6734e0645fce81c9610de0488b729207bfa576e"/>
-  <!-- Information: platform/external/strace is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
-  <!-- Information: platform/external/tagsoup is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
+  <!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/stlport" path="external/stlport" revision="a6734e0645fce81c9610de0488b729207bfa576e"/>
+  <!-- Information: platform/external/strace is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
+  <!-- Information: platform/external/tagsoup is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
   <!-- Information: platform/external/tinyalsa is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/external/tinyalsa" path="external/tinyalsa" revision="06cc244ee512c1352215e543615738bc8ac82814"/>
-  <!-- Information: platform/external/tremolo is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
+  <!-- Information: platform/external/tremolo is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
   <!-- Information: unbootimg is tagged with B2G_1_0_0_20130125190500 --><project name="unbootimg" path="external/unbootimg" remote="b2g" revision="9464623d92eb8668544916dc5a8f4f6337d0bc08"/>
-  <!-- Information: platform/external/webp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.028 --><project name="platform/external/webp" path="external/webp" revision="88fe2b83c4b9232cd08729556fd0485d6a6a92cd"/>
-  <!-- Information: platform/external/webrtc is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/webrtc" path="external/webrtc" revision="137024dc8a2e9251a471e20518a9c3ae06f81f23"/>
-  <!-- Information: platform/external/wpa_supplicant is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
+  <!-- Information: platform/external/webp is tagged with AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.123 --><project name="platform/external/webp" path="external/webp" revision="88fe2b83c4b9232cd08729556fd0485d6a6a92cd"/>
+  <!-- Information: platform/external/webrtc is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/webrtc" path="external/webrtc" revision="137024dc8a2e9251a471e20518a9c3ae06f81f23"/>
+  <!-- Information: platform/external/wpa_supplicant is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
   <!-- Information: platform/external/hostap is tagged with M8960AAAAANLYA1047 --><project name="platform/external/hostap" path="external/hostap" revision="bf04b0faadbdeb4b7943f2e2c4c5aa59df872bb1"/>
   <!-- Information: platform/external/zlib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.01.19.008 --><project name="platform/external/zlib" path="external/zlib" revision="f96a1d1ebfdf1cd582210fd09c23d8f59e0ae094"/>
-  <!-- Information: platform/external/yaffs2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/external/yaffs2" path="external/yaffs2" revision="0afa916204c664b3114429637b63af1321a0aeca"/>
+  <!-- Information: platform/external/yaffs2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/external/yaffs2" path="external/yaffs2" revision="0afa916204c664b3114429637b63af1321a0aeca"/>
   <!-- Information: platform/frameworks/base is tagged with M76XXUSNEKNLYA2040 --><project name="platform/frameworks/base" path="frameworks/base" revision="eb2bc75803ca179353c24c364a9c8a8ce23e8b78"/>
-  <!-- Information: platform/frameworks/opt/emoji is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="a95d8db002770469d72dfaf59ff37ac96db29a87"/>
+  <!-- Information: platform/frameworks/opt/emoji is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="a95d8db002770469d72dfaf59ff37ac96db29a87"/>
   <!-- Information: platform/frameworks/support is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/frameworks/support" path="frameworks/support" revision="27208692b001981f1806f4f396434f4eac78b909"/>
   <!-- Information: platform/hardware/libhardware is tagged with M8960AAAAANLYA1049B --><project name="platform/hardware/libhardware" path="hardware/libhardware" revision="4a619901847621f8a7305edf42dd07347a140484"/>
   <!-- Information: platform/hardware/libhardware_legacy is tagged with M8960AAAAANLYA153611 --><project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="87b4d7afa8f854b445e2d0d95091f6f6069f2b30"/>
   <!-- Information: platform/libcore is tagged with M8960AAAAANLYA100715A --><project name="platform/libcore" path="libcore" revision="30841f9fba9ccd5c54f4f079f495994db97f283e"/>
-  <!-- Information: platform/ndk is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.039 --><project name="platform/ndk" path="ndk" revision="9f555971e1481854d5b4dc11b3e6af9fff4f241f"/>
+  <!-- Information: platform/ndk is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.035 --><project name="platform/ndk" path="ndk" revision="9f555971e1481854d5b4dc11b3e6af9fff4f241f"/>
   <!-- Information: platform/prebuilt is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/prebuilt" path="prebuilt" revision="447ea790fcc957dde59730ecc2a65ca263bdc733"/>
   <!-- Information: platform/system/bluetooth is tagged with M8960AAAAANLYA100703 --><project name="platform/system/bluetooth" path="system/bluetooth" revision="7772cad4823f1f427ce1d4df84a55982386d6d18"/>
   <!-- Information: platform/system/core is tagged with M76XXUSNEKNLYA2040 --><project name="platform/system/core" path="system/core" revision="bf1970408676ce570b8f4dc3efa038e47552137f"/>
   <!-- Information: platform/system/extras is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/system/extras" path="system/extras" revision="01db6c1254e1407740a543f24317fc540fc4c049"/>
   <!-- Information: platform/system/media is tagged with AU_LINUX_ANDROID_ICS_CHOCOLATE.04.00.04.05.324 --><project name="platform/system/media" path="system/media" revision="7f71c7fd362bbd992ff2e0e80f7af5859ad116ad"/>
   <!-- Information: platform/system/netd is tagged with M8960AAAAANLYA1049 --><project name="platform/system/netd" path="system/netd" revision="306e765248e3900041bf2737e9f57b1b5694a4ce"/>
   <!-- Information: platform/system/vold is tagged with M8960AAAAANLYA100715A --><project name="platform/system/vold" path="system/vold" revision="99fff257d53cc045d1460841edca5d901dacfcf5"/>
 
-  <!-- Otoro/Unagi specific things -->
+  <!-- Otoro/Unagi/Inari specific things -->
   <!-- Information: device/qcom/common is tagged with M8960AAAAANLYA100715A --><project name="device/qcom/common" path="device/qcom/common" revision="b9cdab8e1e1a215a8c65b8d5816f666bec7be205"/>
   <!-- Information: platform/vendor/qcom/msm7627a is tagged with M8960AAAAANLYA100715A --><project name="platform/vendor/qcom/msm7627a" path="device/qcom/msm7627a" revision="d920a502ba17cf4d716f8b1a615f07e796b0501a"/>
-  <!-- Information: android-device-otoro is tagged with B2G_1_0_0_20130125190500 --><project name="android-device-otoro" path="device/qcom/otoro" remote="b2g" revision="7662275433fc0b1d8b035f03185b24b7ca965ab4"/>
+  <project name="android-device-otoro" path="device/qcom/otoro" remote="b2g" revision="89f106ed6a538f2868bb873d11b68ea7b2e62f26"/>
   <!-- Information: android-device-unagi is tagged with B2G_1_0_0_20130125190500 --><project name="android-device-unagi" path="device/qcom/unagi" remote="b2g" revision="6c014552d1b26bee611d9a9b23bd4cd014e392ee"/>
+  <project name="device-inari" path="device/qcom/inari" remote="b2g" revision="6b5d034f86da7938af9887308ecff6e391e6928a"/>
   <!-- Information: codeaurora_kernel_msm is tagged with B2G_1_0_0_20130125190500 --><project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="0a01247e4b0880f93424b27251cd3a1f6b19dbb2"/>
   <!-- Information: platform/hardware/qcom/camera is tagged with M76XXUSNEKNLYA2040 --><project name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="1acf77a75e30f3fc8b1eed2057c97adf1cb1633f"/>
   <!-- Information: hardware_qcom_display is tagged with B2G_1_0_0_20130125190500 --><project name="hardware_qcom_display" path="hardware/qcom/display" remote="b2g" revision="6405d30f2fac7d8a1f2cb17b99fb7dd0a8bcfdac"/>
   <!-- Information: platform/hardware/qcom/media is tagged with M8960AAAAANLYA100715A --><project name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="552c3ddb7174a01f3508782d40c4d8c845ab441a"/>
   <!-- Information: platform/hardware/qcom/gps is tagged with M8960AAAAANLYA100705 --><project name="platform/hardware/qcom/gps" path="hardware/qcom/gps" revision="23d5707b320d7fc69f8ba3b7d84d78a1c5681708"/>
   <!-- Information: platform/hardware/msm7k is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.01.19.008 --><project name="platform/hardware/msm7k" path="hardware/msm7k" revision="8892d46805c5639b55dd07547745c5180da861e7"/>
   <!-- Information: platform/vendor/qcom-opensource/omx/mm-core is tagged with M8960AAAAANLYA100715A --><project name="platform/vendor/qcom-opensource/omx/mm-core" path="vendor/qcom/opensource/omx/mm-core" revision="ab17ac9a074b4bb69986a8436336bdfbbaf9cd39"/>
   <!-- Information: platform/hardware/ril is tagged with M76XXUSNEKNLYA1610 --><project name="platform/hardware/ril" path="hardware/ril" remote="caf" revision="fe9a3f63922143b57e79ed570bab2328df8c83a5"/>
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1363293518000">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1363988948000">
   <emItems>
       <emItem  blockID="i58" id="webmaster@buzzzzvideos.info">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i41" id="{99079a25-328f-4bd4-be04-00955acaa0a7}">
                         <versionRange  minVersion="0.1" maxVersion="4.3.1.00" severity="1">
                     </versionRange>
@@ -24,18 +24,18 @@
       <emItem  blockID="i88" id="anttoolbar@ant.com">
                         <versionRange  minVersion="2.4.6.4" maxVersion="2.4.6.4" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i65" id="activity@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
-                        <versionRange  minVersion="1.1b1" maxVersion="1.1b1">
+      <emItem  blockID="i66" id="youtubeer@youtuber.com">
+                        <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i105" id="{95ff02bc-ffc6-45f0-a5c8-619b8226a9de}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i117" id="{ce7e73df-6a44-4028-8079-5927a588c948}">
                         <versionRange  minVersion="0" maxVersion="1.0.8" severity="1">
@@ -44,16 +44,23 @@
       <emItem  blockID="i100" id="{394DCBA4-1F92-4f8e-8EC9-8D2CB90CB69B}">
                         <versionRange  minVersion="2.5.0" maxVersion="2.5.0" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i236" id="{EEE6C361-6118-11DC-9C72-001320C79847}">
                         <versionRange  minVersion="0" maxVersion="1.7.999" severity="1">
                     </versionRange>
                   </emItem>
+      <emItem  blockID="i24" id="{6E19037A-12E3-4295-8915-ED48BC341614}">
+                        <versionRange  minVersion="0.1" maxVersion="1.3.328.4" severity="1">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                  </emItem>
       <emItem  blockID="i64" id="royal@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i72" os="WINNT" id="{4ED1F68A-5463-4931-9384-8FFF5ED91D92}">
                         <versionRange  minVersion="3.4.1" maxVersion="3.4.1.194" severity="1">
                     </versionRange>
                   </emItem>
@@ -106,18 +113,18 @@
       <emItem  blockID="i62" id="jid0-EcdqvFOgWLKHNJPuqAnawlykCGZ@jetpack">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i99" id="pfzPXmnzQRXX6@2iABkVe.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i66" id="youtubeer@youtuber.com">
-                        <versionRange  minVersion="0" maxVersion="*">
+      <emItem  blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
+                        <versionRange  minVersion="1.1b1" maxVersion="1.1b1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i111" os="WINNT" id="{C3949AC2-4B17-43ee-B4F1-D26B9D42404D}">
                         <versionRange  minVersion="0" maxVersion="15.0.5" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i136" id="Adobe@flash.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
@@ -352,16 +359,20 @@
                     </versionRange>
                   </emItem>
       <emItem  blockID="i47" id="youtube@youtube2.com">
                         </emItem>
       <emItem  blockID="i103" id="kdrgun@gmail.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
+      <emItem  blockID="i320" id="torntv@torntv.com">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+                    </versionRange>
+                  </emItem>
       <emItem  blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
                         <versionRange  minVersion="2.0" maxVersion="2.0">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i162" id="{EB7508CA-C7B2-46E0-8C04-3E94A035BD49}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                   </emItem>
@@ -379,20 +390,32 @@
       <emItem  blockID="i304" id="{f0e59437-6148-4a98-b0a6-60d557ef57f4}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i86" id="{45147e67-4020-47e2-8f7a-55464fb535aa}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
+      <emItem  blockID="i326" id="/^((support2_en@adobe14\.com)|(XN4Xgjw7n4@yUWgc\.com)|(C7yFVpIP@WeolS3acxgS\.com)|(Kbeu4h0z@yNb7QAz7jrYKiiTQ3\.com)|(aWQzX@a6z4gWdPu8FF\.com)|(CBSoqAJLYpCbjTP90@JoV0VMywCjsm75Y0toAd\.com))$/">
+                        <versionRange  minVersion="0" maxVersion="*" severity="3">
+                    </versionRange>
+                  </emItem>
       <emItem  blockID="i312" id="extension21804@extension21804.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                   </emItem>
+      <emItem  blockID="i324" id="/^((34qEOefiyYtRJT@IM5Munavn\.com)|(Mro5Fm1Qgrmq7B@ByrE69VQfZvZdeg\.com)|(KtoY3KGxrCe5ie@yITPUzbBtsHWeCdPmGe\.com)|(9NgIdLK5Dq4ZMwmRo6zk@FNt2GCCLGyUuOD\.com)|(NNux7bWWW@RBWyXdnl6VGls3WAwi\.com)|(E3wI2n@PEHTuuNVu\.com)|(2d3VuWrG6JHBXbQdbr@3BmSnQL\.com))$/">
+                        <versionRange  minVersion="0" maxVersion="*" severity="3">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i318" id="ffxtlbr@incredibar.com">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+                    </versionRange>
+                  </emItem>
       <emItem  blockID="i108" id="{28bfb930-7620-11e1-b0c4-0800200c9a66}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i61" id="youtube@youtube3.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                                 <versionRange  minVersion="0" maxVersion="*">
@@ -467,37 +490,34 @@
                               <versionRange  minVersion="8.0a1" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
                   </emItem>
       <emItem  blockID="i82" id="{8f42fb8b-b6f6-45de-81c0-d6d39f54f971}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i24" id="{6E19037A-12E3-4295-8915-ED48BC341614}">
-                        <versionRange  minVersion="0.1" maxVersion="1.3.328.4" severity="1">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
-                          </targetApplication>
+      <emItem  blockID="i314" id="crossriderapp8812@crossrider.com">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i73" id="a1g0a9g219d@a1.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i96" id="youtubeee@youtuber3.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i163" id="info@allpremiumplay.info">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i314" id="crossriderapp8812@crossrider.com">
-                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+      <emItem  blockID="i322" id="jid0-Y6TVIzs0r7r4xkOogmJPNAGFGBw@jetpack">
+                        <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i21" id="support@update-firefox.com">
                         </emItem>
     </emItems>
 
   <pluginItems>
       <pluginItem  blockID="p26">
@@ -624,19 +644,19 @@
       <pluginItem  blockID="p176">
                   <match name="filename" exp="(NPSWF32\.dll)|(Flash\ Player\.plugin)" />                                    <versionRange  minVersion="10.3" maxVersion="10.3.183.18.999" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="19.0a1" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
                   </pluginItem>
       <pluginItem  blockID="p178">
-                  <match name="filename" exp="(NPSWF[0-9_]*\.dll)|(Flash\ Player\.plugin)" />                                    <versionRange  minVersion="11.0" maxVersion="11.4.402.286.999" severity="0" vulnerabilitystatus="1">
+                  <match name="filename" exp="(NPSWF[0-9_]*\.dll)|(Flash\ Player\.plugin)" />                                    <versionRange  minVersion="11.0" maxVersion="11.2.202.274.9999" severity="0" vulnerabilitystatus="1">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="20.0a1" maxVersion="*" />
+                              <versionRange  minVersion="19.0a1" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
                   </pluginItem>
       <pluginItem  blockID="p180">
                   <match name="filename" exp="JavaAppletPlugin\.plugin" />                                    <versionRange  minVersion="Java 7 Update 0" maxVersion="Java 7 Update 11" severity="0" vulnerabilitystatus="2">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
@@ -775,16 +795,23 @@
                   </pluginItem>
       <pluginItem  blockID="p302">
       <match name="name" exp="Java\(TM\) Plug-in 1\.6\.0_(39|40|41)([^\d\._]|$)" />            <match name="filename" exp="libnpjp2\.so" />                                    <versionRange  severity="0" vulnerabilitystatus="2">
                                 <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="17.0" maxVersion="*" />
                           </targetApplication>
                   </versionRange>
                   </pluginItem>
+      <pluginItem  blockID="p316">
+                  <match name="filename" exp="(NPSWF[0-9_]*\.dll)|(Flash\ Player\.plugin)" />                                    <versionRange  minVersion="11.2.202.275" maxVersion="11.4.402.286.9999" severity="0" vulnerabilitystatus="1">
+                                <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="20.0a1" maxVersion="*" />
+                          </targetApplication>
+                  </versionRange>
+                  </pluginItem>
     </pluginItems>
 
   <gfxItems>
     <gfxBlacklistEntry  blockID="g35">      <os>WINNT 6.1</os>      <vendor>0x10de</vendor>              <devices>
                       <device>0x0a6c</device>
                   </devices>
             <feature>DIRECT2D</feature>      <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>      <driverVersion>8.17.12.5896</driverVersion>      <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>    </gfxBlacklistEntry>
     <gfxBlacklistEntry  blockID="g36">      <os>WINNT 6.1</os>      <vendor>0x10de</vendor>              <devices>
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -186,16 +186,20 @@ static int do_main(int argc, char* argv[
     // This command-line flag is passed to our executable when it is to be
     // launched in metro mode (i.e. our EXE is registered as the default
     // browser and the user has tapped our EXE's tile)
     if (IsArg(argv[1], "ServerName:DefaultBrowserServer")) {
       mainFlags = XRE_MAIN_FLAG_USE_METRO;
       argv[1] = argv[0];
       argv++;
       argc--;
+    } else if (IsArg(argv[1], "BackgroundSessionClosed")) {
+      // This command line flag is used for indirect shutdowns, the OS
+      // relaunches Metro Firefox with this command line arg.
+      mainFlags = XRE_MAIN_FLAG_USE_METRO;
     } else {
       // This command-line flag is used to test the metro browser in a desktop
       // environment.
       for (int idx = 1; idx < argc; idx++) {
         if (IsArg(argv[idx], "metrodesktop")) {
           metroOnDesktop = true;
           break;
         } 
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -290,17 +290,17 @@ var PlacesCommandHook = {
                    aParent : PlacesUtils.unfiledBookmarksFolderId;
       var descAnno = { name: PlacesUIUtils.DESCRIPTION_ANNO, value: description };
       var txn = new PlacesCreateBookmarkTransaction(uri, parent, 
                                                     PlacesUtils.bookmarks.DEFAULT_INDEX,
                                                     title, null, [descAnno]);
       PlacesUtils.transactionManager.doTransaction(txn);
       // Set the character-set
       if (charset && !PrivateBrowsingUtils.isWindowPrivate(aBrowser.contentWindow))
-        PlacesUtils.history.setCharsetForURI(uri, charset);
+        PlacesUtils.setCharsetForURI(uri, charset);
       itemId = PlacesUtils.getMostRecentBookmarkForURI(uri);
     }
 
     // Revert the contents of the location bar
     if (gURLBar)
       gURLBar.handleRevert();
 
     // dock the panel to the star icon when possible, otherwise dock
--- a/browser/base/content/browser-plugins.js
+++ b/browser/base/content/browser-plugins.js
@@ -465,17 +465,23 @@ var gPluginHandler = {
     }
 
     if (overlay) {
       overlay.addEventListener("click", function(aEvent) {
         // Have to check that the target is not the link to update the plugin
         if (!(aEvent.originalTarget instanceof HTMLAnchorElement) &&
             (aEvent.originalTarget.getAttribute('anonid') != 'closeIcon') &&
             aEvent.button == 0 && aEvent.isTrusted) {
-          gPluginHandler.activateSinglePlugin(aEvent.target.ownerDocument.defaultView.top, aPlugin);
+          if (objLoadingContent.pluginFallbackType ==
+                Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE ||
+              objLoadingContent.pluginFallbackType ==
+                Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE)
+            gPluginHandler._showClickToPlayNotification(browser, true);
+          else
+            gPluginHandler.activateSinglePlugin(aEvent.target.ownerDocument.defaultView.top, aPlugin);
           aEvent.stopPropagation();
           aEvent.preventDefault();
         }
       }, true);
 
       let closeIcon = doc.getAnonymousElementByAttribute(aPlugin, "anonid", "closeIcon");
       closeIcon.addEventListener("click", function(aEvent) {
         if (aEvent.button == 0 && aEvent.isTrusted)
@@ -643,17 +649,17 @@ var gPluginHandler = {
       // so the pluginHost.getPermissionStringForType call is protected
       if (gPluginHandler.canActivatePlugin(objLoadingContent)) {
         let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
         Services.perms.add(aBrowser.currentURI, permissionString, aPermission);
       }
     }
   },
 
-  _showClickToPlayNotification: function PH_showClickToPlayNotification(aBrowser) {
+  _showClickToPlayNotification: function PH_showClickToPlayNotification(aBrowser, aForceOpenNotification) {
     let contentWindow = aBrowser.contentWindow;
     let messageString = gNavigatorBundle.getString("activatePluginsMessage.message");
     let mainAction = {
       label: gNavigatorBundle.getString("activateAllPluginsMessage.label"),
       accessKey: gNavigatorBundle.getString("activatePluginsMessage.accesskey"),
       callback: function() { gPluginHandler.activatePlugins(contentWindow); }
     };
     let centerActions = gPluginHandler._makeCenterActions(aBrowser);
@@ -684,17 +690,17 @@ var gPluginHandler = {
         if (notification)
           notification.remove();
         gPluginHandler._removeClickToPlayOverlays(contentWindow);
       }
     }];
     let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
     let dismissed = notification ? notification.dismissed : true;
     // Always show the doorhanger if the anchor is not available.
-    if (!isElementVisible(gURLBar))
+    if (!isElementVisible(gURLBar) || aForceOpenNotification)
       dismissed = false;
     let options = { dismissed: dismissed, centerActions: centerActions };
     let icon = haveVulnerablePlugin ? "blocked-plugins-notification-icon" : "plugins-notification-icon"
     PopupNotifications.show(aBrowser, "click-to-play-plugins",
                             messageString, icon,
                             mainAction, secondaryActions, options);
   },
 
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -411,29 +411,28 @@ var gPopupBlockerObserver = {
 
     // Only show the notification again if we've not already shown it. Since
     // notifications are per-browser, we don't need to worry about re-adding
     // it.
     if (!gBrowser.pageReport.reported) {
       if (gPrefService.getBoolPref("privacy.popups.showBrowserMessage")) {
         var brandBundle = document.getElementById("bundle_brand");
         var brandShortName = brandBundle.getString("brandShortName");
-        var message;
         var popupCount = gBrowser.pageReport.length;
 #ifdef XP_WIN
         var popupButtonText = gNavigatorBundle.getString("popupWarningButton");
         var popupButtonAccesskey = gNavigatorBundle.getString("popupWarningButton.accesskey");
 #else
         var popupButtonText = gNavigatorBundle.getString("popupWarningButtonUnix");
         var popupButtonAccesskey = gNavigatorBundle.getString("popupWarningButtonUnix.accesskey");
 #endif
-        if (popupCount > 1)
-          message = gNavigatorBundle.getFormattedString("popupWarningMultiple", [brandShortName, popupCount]);
-        else
-          message = gNavigatorBundle.getFormattedString("popupWarning", [brandShortName]);
+        var messageBase = gNavigatorBundle.getString("popupWarning.message");
+        var message = PluralForm.get(popupCount, messageBase)
+                                .replace("#1", brandShortName)
+                                .replace("#2", popupCount);
 
         var notificationBox = gBrowser.getNotificationBox();
         var notification = notificationBox.getNotificationWithValue("popup-blocked");
         if (notification) {
           notification.label = message;
         }
         else {
           var buttons = [{
@@ -3637,18 +3636,20 @@ function OpenBrowserWindow(options)
   var handler = Components.classes["@mozilla.org/browser/clh;1"]
                           .getService(Components.interfaces.nsIBrowserHandler);
   var defaultArgs = handler.defaultArgs;
   var wintype = document.documentElement.getAttribute('windowtype');
 
   var extraFeatures = "";
   if (options && options.private) {
     extraFeatures = ",private";
-    // Force the new window to load about:privatebrowsing instead of the default home page
-    defaultArgs = "about:privatebrowsing";
+    if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
+      // Force the new window to load about:privatebrowsing instead of the default home page
+      defaultArgs = "about:privatebrowsing";
+    }
   } else {
     extraFeatures = ",non-private";
   }
 
   // if and only if the current window is a browser window and it has a document with a character
   // set, then extract the current charset menu setting from the current document and use it to
   // initialize the new browser window...
   var win;
@@ -5620,17 +5621,17 @@ function SelectDetector(event, doReload)
 }
 
 function BrowserSetForcedCharacterSet(aCharset)
 {
   gBrowser.docShell.gatherCharsetMenuTelemetry();
   gBrowser.docShell.charset = aCharset;
   // Save the forced character-set
   if (!PrivateBrowsingUtils.isWindowPrivate(window))
-    PlacesUtils.history.setCharsetForURI(getWebNavigation().currentURI, aCharset);
+    PlacesUtils.setCharsetForURI(getWebNavigation().currentURI, aCharset);
   BrowserCharsetReload();
 }
 
 function BrowserCharsetReload()
 {
   BrowserReloadWithFlags(nsIWebNavigation.LOAD_FLAGS_CHARSET_CHANGE);
 }
 
@@ -7133,20 +7134,22 @@ let gPrivateBrowsingUI = {
 #ifdef XP_MACOSX
       if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
         document.documentElement.setAttribute("drawintitlebar", true);
       }
 #endif
 
       // Adjust the window's title
       let docElement = document.documentElement;
-      docElement.setAttribute("title",
-        docElement.getAttribute("title_privatebrowsing"));
-      docElement.setAttribute("titlemodifier",
-        docElement.getAttribute("titlemodifier_privatebrowsing"));
+      if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
+        docElement.setAttribute("title",
+          docElement.getAttribute("title_privatebrowsing"));
+        docElement.setAttribute("titlemodifier",
+          docElement.getAttribute("titlemodifier_privatebrowsing"));
+      }
       docElement.setAttribute("privatebrowsingmode",
         PrivateBrowsingUtils.permanentPrivateBrowsing ? "permanent" : "temporary");
       gBrowser.updateTitlebar();
 
       if (PrivateBrowsingUtils.permanentPrivateBrowsing) {
         // Adjust the New Window menu entries
         [
           { normal: "menu_newNavigator", private: "menu_newPrivateWindow" },
@@ -7459,17 +7462,16 @@ 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();
 }
-
 let BrowserChromeTest = {
   _cb: null,
   _ready: false,
   markAsReady: function () {
     this._ready = true;
     if (this._cb) {
       this._cb();
       this._cb = null;
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -445,16 +445,23 @@
 
     <popupnotification id="geolocation-notification" hidden="true">
       <popupnotificationcontent orient="vertical" align="start">
         <separator class="thin"/>
         <label id="geolocation-learnmore-link" class="text-link"/>
       </popupnotificationcontent>
     </popupnotification>
 
+    <popupnotification id="pointerLock-notification" hidden="true">
+      <popupnotificationcontent orient="vertical" align="start">
+        <separator class="thin"/>
+        <label id="pointerLock-cancel" value="&pointerLock.notification.message;"/>
+      </popupnotificationcontent>
+    </popupnotification>
+
     <popupnotification id="mixed-content-blocked-notification" hidden="true">
       <popupnotificationcontent orient="vertical" align="start">
         <separator/>
         <description id="mixed-content-blocked-moreinfo">&mixedContentBlocked.moreinfo;</description>
         <separator/>
         <label id="mixed-content-blocked-helplink" class="text-link"
                value="&mixedContentBlocked.helplink;"/>
       </popupnotificationcontent>
@@ -575,16 +582,17 @@
             <image id="password-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="webapps-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="plugins-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="web-notifications-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="blocked-plugins-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="mixed-content-blocked-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="webRTC-shareDevices-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="webRTC-sharingDevices-notification-icon" class="notification-anchor-icon" role="button"/>
+            <image id="pointerLock-notification-icon" class="notification-anchor-icon" role="button"/>
           </box>
           <!-- Use onclick instead of normal popup= syntax since the popup
                code fires onmousedown, and hence eats our favicon drag events.
                We only add the identity-box button to the tab order when the location bar
                has focus, otherwise pressing F6 focuses it instead of the location bar -->
           <box id="identity-box" role="button"
                align="center"
                onclick="gIdentityHandler.handleIdentityButtonEvent(event);"
--- a/browser/base/content/pageinfo/pageInfo.xul
+++ b/browser/base/content/pageinfo/pageInfo.xul
@@ -59,16 +59,18 @@
     <command id="cmd_popupToggle"   oncommand="onRadioClick('popup');"/>
     <command id="cmd_cookieToggle"  oncommand="onRadioClick('cookie');"/>
     <command id="cmd_desktop-notificationToggle" oncommand="onRadioClick('desktop-notification');"/>
     <command id="cmd_installToggle" oncommand="onRadioClick('install');"/>
     <command id="cmd_fullscreenToggle" oncommand="onRadioClick('fullscreen');"/>
     <command id="cmd_geoToggle"     oncommand="onRadioClick('geo');"/>
     <command id="cmd_indexedDBToggle" oncommand="onRadioClick('indexedDB');"/>
     <command id="cmd_pluginsToggle" oncommand="onPluginRadioClick(event);"/>
+    <command id="cmd_pointerLockDef"    oncommand="onCheckboxClick('pointerLock');"/>
+    <command id="cmd_pointerLockToggle" oncommand="onRadioClick('pointerLock');"/>
   </commandset>
 
   <keyset id="pageInfoKeySet">
     <key key="&closeWindow.key;" modifiers="accel" command="cmd_close"/>
     <key keycode="VK_ESCAPE"                       command="cmd_close"/>
 #ifdef XP_MACOSX
     <key key="."                 modifiers="meta"  command="cmd_close"/>
 #else
@@ -408,16 +410,28 @@
             <spacer flex="1"/>
             <radiogroup id="fullscreenRadioGroup" orient="horizontal">
               <radio id="fullscreen#0" command="cmd_fullscreenToggle" label="&permAskAlways;"/>
               <radio id="fullscreen#1" command="cmd_fullscreenToggle" label="&permAllow;"/>
               <radio id="fullscreen#2" command="cmd_fullscreenToggle" label="&permBlock;"/>
             </radiogroup>
           </hbox>
         </vbox>
+        <vbox class="permission" id="permPointerLockRow" >
+          <label class="permissionLabel" id="permPointerLockLabel"
+                 value="&permPointerLock;" control="pointerLockRadioGroup"/>
+          <hbox id="permPointerLockBox" role="group" aria-labelledby="permPointerLockLabel">
+            <checkbox id="pointerLockDef" command="cmd_pointerLockDef" label="&permAskAlways;"/>
+            <spacer flex="1"/>
+            <radiogroup id="pointerLockRadioGroup" orient="horizontal">
+              <radio id="pointerLock#1" command="cmd_pointerLockToggle" label="&permAllow;"/>
+              <radio id="pointerLock#2" command="cmd_pointerLockToggle" label="&permBlock;"/>
+            </radiogroup>
+          </hbox>
+        </vbox>
       </vbox>
     </vbox>
 
     <!-- Security & Privacy -->
     <vbox id="securityPanel">
       <!-- Identity Section -->
       <groupbox id="security-identity-groupbox" flex="1">
         <caption id="security-identity" label="&securityView.identity.header;"/>
--- a/browser/base/content/pageinfo/permissions.js
+++ b/browser/base/content/pageinfo/permissions.js
@@ -59,17 +59,21 @@ var gPermObj = {
   },
   plugins: function getPluginsDefaultPermissions()
   {
     return UNKNOWN;
   },
   fullscreen: function getFullscreenDefaultPermissions()
   {
     return UNKNOWN;  
-  }
+  },
+  pointerLock: function getPointerLockPermissions()
+  {
+    return BLOCK;
+  },
 };
 
 var permissionObserver = {
   observe: function (aSubject, aTopic, aData)
   {
     if (aTopic == "perm-changed") {
       var permission = aSubject.QueryInterface(Components.interfaces.nsIPermission);
       if (permission.host == gPermURI.host) {
@@ -124,19 +128,23 @@ function initRow(aPartId)
     return;
   }
 
   var permissionManager = Components.classes[PERMISSION_CONTRACTID]
                                     .getService(nsIPermissionManager);
 
   var checkbox = document.getElementById(aPartId + "Def");
   var command  = document.getElementById("cmd_" + aPartId + "Toggle");
-  // Geolocation permission consumers use testExactPermission, not testPermission. 
-  var perm = aPartId == "geo" ? permissionManager.testExactPermission(gPermURI, aPartId) :
-                                permissionManager.testPermission(gPermURI, aPartId);
+  // Geolocation and PointerLock permission consumers use testExactPermission, not testPermission.
+  var perm;
+  if (aPartId == "geo" || aPartId == "pointerLock")
+    perm = permissionManager.testExactPermission(gPermURI, aPartId);
+  else
+    perm = permissionManager.testPermission(gPermURI, aPartId);
+
   if (perm) {
     checkbox.checked = false;
     command.removeAttribute("disabled");
   }
   else {
     checkbox.checked = true;
     command.setAttribute("disabled", "true");
     perm = gPermObj[aPartId]();
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -4481,16 +4481,17 @@
     </handlers>
   </binding>
 
   <binding id="statuspanel" display="xul:hbox">
     <content>
       <xul:hbox class="statuspanel-inner">
         <xul:label class="statuspanel-label"
                    role="status"
+                   aria-live="off"
                    xbl:inherits="value=label,crop,mirror"
                    flex="1"
                    crop="end"/>
       </xul:hbox>
     </content>
 
     <implementation implements="nsIDOMEventListener">
       <constructor><![CDATA[
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -311,16 +311,17 @@ endif
                  browser_URLBarSetURI.js \
                  browser_bookmark_titles.js \
                  browser_pageInfo_plugins.js \
                  browser_pageInfo.js \
                  feed_tab.html \
                  browser_pluginCrashCommentAndURL.js \
                  pluginCrashCommentAndURL.html \
                  browser_private_no_prompt.js \
+                 browser_blob-channelname.js
                  $(NULL)
 
 # Disable test on Windows due to frequent failures (bug 841341)
 ifneq (windows,$(MOZ_WIDGET_TOOLKIT))
 _BROWSER_FILES += \
                 browser_popupNotification.js \
                 $(NULL)
 endif
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_blob-channelname.js
@@ -0,0 +1,11 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+Cu.import("resource://gre/modules/NetUtil.jsm");
+
+function test() {
+    var file = new File(new Blob(['test'], {type: 'text/plain'}), {name: 'test-name'});
+    var url = URL.createObjectURL(file);
+    var channel = NetUtil.newChannel(url);
+
+    is(channel.contentDispositionFilename, 'test-name', "filename matches");
+}
--- a/browser/base/content/test/browser_pluginnotification.js
+++ b/browser/base/content/test/browser_pluginnotification.js
@@ -678,16 +678,42 @@ function test18d() {
 function test18e() {
   var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
   ok(!popupNotification, "Test 18e, Should not have a click-to-play notification");
   var plugin = gTestBrowser.contentDocument.getElementById("test");
   var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
   ok(objLoadingContent.activated, "Test 18e, Plugin should be activated");
 
   Services.perms.remove("127.0.0.1:8888", gPluginHost.getPermissionStringForType("application/x-test"));
+  prepareTest(test18f, gHttpTestRoot + "plugin_test.html");
+}
+
+// clicking the in-content overlay of a vulnerable plugin should bring
+// up the notification and not directly activate the plugin
+function test18f() {
+  var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
+  ok(notification, "Test 18f, Should have a click-to-play notification");
+  ok(notification.dismissed, "Test 18f, notification should start dismissed");
+  var plugin = gTestBrowser.contentDocument.getElementById("test");
+  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+  ok(!objLoadingContent.activated, "Test 18f, Plugin should not be activated");
+
+  notification.options.eventCallback = function() { executeSoon(test18g); };
+  EventUtils.synthesizeMouseAtCenter(plugin, {}, gTestBrowser.contentWindow);
+}
+
+function test18g() {
+  var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
+  ok(notification, "Test 18g, Should have a click-to-play notification");
+  ok(!notification.dismissed, "Test 18g, notification should be open");
+  notification.options.eventCallback = null;
+  var plugin = gTestBrowser.contentDocument.getElementById("test");
+  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+  ok(!objLoadingContent.activated, "Test 18g, Plugin should not be activated");
+
   setAndUpdateBlocklist(gHttpTestRoot + "blockNoPlugins.xml",
   function() {
     resetBlocklist();
     prepareTest(test19a, gTestRoot + "plugin_test.html");
   });
 }
 
 // Tests that clicking the icon of the overlay activates the plugin
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1635,16 +1635,20 @@ ContentPermissionPrompt.prototype = {
    *                               [main action, secondary actions, ...]
    *                               Actions are of the form { stringId, action, expireType, callback }
    *                               Permission is granted if action is null or ALLOW_ACTION.
    * @param aNotificationId        The id of the PopupNotification.
    * @param aAnchorId              The id for the PopupNotification anchor.
    */
   _showPrompt: function CPP_showPrompt(aRequest, aMessage, aPermission, aActions,
                                        aNotificationId, aAnchorId) {
+    function onFullScreen() {
+      popup.remove();
+    }
+
     var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
 
     var requestingWindow = aRequest.window.top;
     var chromeWin = this._getChromeWindow(requestingWindow).wrappedJSObject;
     var browser = chromeWin.gBrowser.getBrowserForDocument(requestingWindow.document);
     var requestPrincipal = aRequest.principal;
 
     // Transform the prompt actions into PopupNotification actions.
@@ -1680,20 +1684,44 @@ ContentPermissionPrompt.prototype = {
             aRequest.cancel();
           }
         },
       };
 
       popupNotificationActions.push(action);
     }
 
-    var mainAction = popupNotificationActions[0];
+    var mainAction = popupNotificationActions.length ?
+                       popupNotificationActions[0] : null;
     var secondaryActions = popupNotificationActions.splice(1);
-    chromeWin.PopupNotifications.show(browser, aNotificationId, aMessage, aAnchorId,
-                                      mainAction, secondaryActions);
+    var options = null;
+
+    if (aRequest.type == "pointerLock") {
+      // If there's no mainAction, this is the autoAllow warning prompt.
+      let autoAllow = !mainAction;
+      options = { removeOnDismissal: autoAllow,
+                  eventCallback: function (type) {
+                                   if (type == "removed") {
+                                     browser.removeEventListener("mozfullscreenchange", onFullScreen, true);
+                                     if (autoAllow)
+                                       aRequest.allow();
+                                   }
+                                 },
+                };
+    }
+
+    var popup = chromeWin.PopupNotifications.show(browser, aNotificationId, aMessage, aAnchorId,
+                                                  mainAction, secondaryActions, options);
+    if (aRequest.type == "pointerLock") {
+      // pointerLock is automatically allowed in fullscreen mode (and revoked
+      // upon exit), so if the page enters fullscreen mode after requesting
+      // pointerLock (but before the user has granted permission), we should
+      // remove the now-impotent notification.
+      browser.addEventListener("mozfullscreenchange", onFullScreen, true);
+    }
   },
 
   _promptGeo : function(aRequest) {
     var secHistogram = Services.telemetry.getHistogramById("SECURITY_UI");
     var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
     var requestingURI = aRequest.principal.URI;
 
     var message;
@@ -1774,51 +1802,101 @@ ContentPermissionPrompt.prototype = {
       },
     ];
 
     this._showPrompt(aRequest, message, "desktop-notification", actions,
                      "web-notifications",
                      "web-notifications-notification-icon");
   },
 
+  _promptPointerLock: function CPP_promtPointerLock(aRequest, autoAllow) {
+
+    let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
+    let requestingURI = aRequest.principal.URI;
+
+    let originString = requestingURI.schemeIs("file") ? requestingURI.path : requestingURI.host;
+    let message = browserBundle.formatStringFromName(autoAllow ?
+                                  "pointerLock.autoLock.title" : "pointerLock.title",
+                                  [originString], 1);
+    // If this is an autoAllow info prompt, offer no actions.
+    // _showPrompt() will allow the request when it's dismissed.
+    let actions = [];
+    if (!autoAllow) {
+      actions = [
+        {
+          stringId: "pointerLock.allow",
+          action: null,
+          expireType: null,
+          callback: function() {},
+        },
+        {
+          stringId: "pointerLock.alwaysAllow",
+          action: Ci.nsIPermissionManager.ALLOW_ACTION,
+          expireType: null,
+          callback: function() {},
+        },
+        {
+          stringId: "pointerLock.neverAllow",
+          action: Ci.nsIPermissionManager.DENY_ACTION,
+          expireType: null,
+          callback: function() {},
+        },
+      ];
+    }
+
+    this._showPrompt(aRequest, message, "pointerLock", actions, "pointerLock", "pointerLock-notification-icon");
+  },
+
   prompt: function CPP_prompt(request) {
+
     const kFeatureKeys = { "geolocation" : "geo",
-                           "desktop-notification" : "desktop-notification" };
+                           "desktop-notification" : "desktop-notification",
+                           "pointerLock" : "pointerLock",
+                         };
 
     // Make sure that we support the request.
     if (!(request.type in kFeatureKeys)) {
         return;
     }
 
     var requestingPrincipal = request.principal;
     var requestingURI = requestingPrincipal.URI;
 
     // Ignore requests from non-nsIStandardURLs
     if (!(requestingURI instanceof Ci.nsIStandardURL))
       return;
 
+    var autoAllow = false;
     var permissionKey = kFeatureKeys[request.type];
     var result = Services.perms.testExactPermissionFromPrincipal(requestingPrincipal, permissionKey);
 
-    if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
-      request.allow();
-      return;
-    }
-
     if (result == Ci.nsIPermissionManager.DENY_ACTION) {
       request.cancel();
       return;
     }
 
+    if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
+      autoAllow = true;
+      // For pointerLock, we still want to show a warning prompt.
+      if (request.type != "pointerLock") {
+        request.allow();
+        return;
+      }
+    }
+
     // Show the prompt.
     switch (request.type) {
     case "geolocation":
       this._promptGeo(request);
       break;
     case "desktop-notification":
       this._promptWebNotifications(request);
       break;
+    case "pointerLock":
+      this._promptPointerLock(request, autoAllow);
+      break;
     }
-  }
+  },
+
 };
 
 var components = [BrowserGlue, ContentPermissionPrompt];
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
--- a/browser/components/places/content/bookmarkProperties.js
+++ b/browser/components/places/content/bookmarkProperties.js
@@ -567,17 +567,17 @@ var BookmarkPropertiesPanel = {
 
     if (this._postData) {
       let postDataTxn = new PlacesEditBookmarkPostDataTransaction(-1, this._postData);
       childTransactions.push(postDataTxn);
     }
 
     //XXX TODO: this should be in a transaction!
     if (this._charSet && !PrivateBrowsingUtils.isWindowPrivate(window))
-      PlacesUtils.history.setCharsetForURI(this._uri, this._charSet);
+      PlacesUtils.setCharsetForURI(this._uri, this._charSet);
 
     let createTxn = new PlacesCreateBookmarkTransaction(this._uri,
                                                         aContainer,
                                                         aIndex,
                                                         this._title,
                                                         this._keyword,
                                                         annotations,
                                                         childTransactions);
--- a/browser/components/search/test/browser_google.js
+++ b/browser/components/search/test/browser_google.js
@@ -89,17 +89,17 @@ function test() {
   const EXPECTED_ENGINE = {
     name: "Google",
     alias: null,
     description: "Google Search",
     searchForm: "https://www.google.com/",
     type: Ci.nsISearchEngine.TYPE_MOZSEARCH,
     hidden: false,
     wrappedJSObject: {
-      "_iconURL": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABUUlEQVR42pWTzUsCYRCH9y9zu3SooCCkjhIRRLeIykXokiWCJ7PvDpZRlz6si1lIQZ3SQxQdOhREpgSm0JeQvfu0+i6I7LKLh4F5h5nnnRl+o6jTdHn8omAYbVqhXqvYFXcEBKFDwcoZZB8B4LkEB9cwGGmFKHb01A1EU9JXzfdvDYZi1lwLwBcVAIwsNWPesIwls7gDtB2Z7N9ujVe+IX2LO2AgItB1OL9vJqsmILDrOoK02IkBAdYy4FsQJC5h+VQCHQDWTqYSgo8fuHuRxS4Ae3stQ7UGE5ttAHqCUgfxC7m4ryrowOyeO6CxqHwZxtYFqtYc5+kNan/gDTsAeueEIRj7n/rmRQMwueUAGF0VAAT3rQBTC0Y3DoDOGbm00icML4oWHYSTgo0MFqjlmPpDgqMcFCuQf4erBzjOwXjcriu9qHg0uutO2+es6fl67T9ptebvFRjBVgAAAABJRU5ErkJggg==",
+      "_iconURL": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACuUlEQVRYw8VX60sUURSffybWv6MloxeV0Jug+hJB0YMoCCII1E3LnlYKlVkkUZKaRFEGFlgfMntYhlopVpaP1HXuPPbOzOmcOw/XZbed3ZndvXBYlr17zu+8fudcaWmlLKEsQWlFmUOBAsucY4tsSmQ8gjJTBMOpQjYjkoMGSiStUpHCnknmpXz+uLdJgY5eDsN/TJA1C9KdkUkTjraoWXXlBGDNaQZd/VwoP3xHhbVnGOxvVuHLL1MY5QZArEODbfUMllX70+kbACl8N2qAxgE2XmCLfltZI8O3CRtEXLVg00Xm2ynfAOoeacLA2+9G2t8P3lK98Lf3JsIH8OmH7eEzTEGmO6NT9p3JuBU+ADUB/40ASdsb+5KiFxAAw6pfHkt/p/G5Lu6MTZvhAyDP3VPdrqW90/zSRnmjWw8fwLG7C0VGOV5/dnGll2OXfEVeoFpZcUoOHwBJ0wvdA0FtdwS5YF0dg93XFHg1ZMDrYQNW17KcSC1nJtx3U4XH77nwdui3CaZDhAM/TSiP5c6qUhAu33qJeRFp6UnkpSMQgC1JAKZlC3Y1KsUFQEJ5dw/1/8kHWuEARKtk2HNdgctPdTENewYN0fPJxypUG1Zh74/PWsDQS2K8E/c12NmgQMU5BhXYksT/yaehSw8PgEuxn7HSUydhKkjuZIQ+N5xnwQEcv2cTkIGR3uxjzNY81LwoVLZpwQF0D3ChjCad33RRqujQchIYgDuG/2KbRX0CcDckP22ZFUBnH/dCWtuZ3SMqygTmv3/MCKcIt19RvFHMTbu6M1Eu7Yh9IwbMMEt0SGhdcOi2ClPzC9vvLBp48oELMLSq1SMv0HfakD+i5zuuKuHzwCqccmSMph6NY1pOqdWoNgbHTcEDB3AvjOZBxSV/mJT8aVZWwsdpmeQ8zyNOJOJFMBx3bJFN6R++on7RvMlpZAAAAABJRU5ErkJggg==",
       _urls : [
         {
           type: "application/x-suggestions+json",
           method: "GET",
           template: "https://www.google.com/complete/search?client=firefox&q={searchTerms}",
           params: "",
         },
         {
--- a/browser/devtools/profiler/test/Makefile.in
+++ b/browser/devtools/profiler/test/Makefile.in
@@ -6,25 +6,27 @@ DEPTH          = @DEPTH@
 topsrcdir      = @top_srcdir@
 srcdir         = @srcdir@
 VPATH          = @srcdir@
 relativesrcdir = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_BROWSER_TESTS = \
-		browser_profiler_run.js \
-		browser_profiler_controller.js \
 		browser_profiler_profiles.js \
 		browser_profiler_remote.js \
-		browser_profiler_bug_830664_multiple_profiles.js \
 		browser_profiler_bug_834878_source_buttons.js \
 		head.js \
 		$(NULL)
 
+# Naughty corner (bug 822041 & bug 822287)
+#		browser_profiler_run.js \
+#		browser_profiler_controller.js \
+#		browser_profiler_bug_830664_multiple_profiles.js \
+
 MOCHITEST_BROWSER_PAGES = \
 		mock_profiler_bug_834878_page.html \
 		mock_profiler_bug_834878_script.js \
 		$(NULL)
 
 MOCHITEST_BROWSER_FILES_PARTS = MOCHITEST_BROWSER_TESTS MOCHITEST_BROWSER_PAGES
 
 include $(topsrcdir)/config/rules.mk
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -642,8 +642,10 @@ just addresses the organization to follo
 <!ENTITY getUserMedia.selectMicrophone.label "Microphone to share:">
 <!ENTITY getUserMedia.selectMicrophone.accesskey "M">
 
 <!ENTITY webrtcIndicatorButton.label "Camera / Microphone Access">
 <!ENTITY webrtcIndicatorButton.tooltip "Display sites you are currently sharing your camera or microphone with">
 
 <!ENTITY mixedContentBlocked.helplink "Learn more">
 <!ENTITY mixedContentBlocked.moreinfo "Most websites will still work properly even when this content is blocked.">
+
+<!ENTITY pointerLock.notification.message "Press ESC at any time to show it again.">
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -79,18 +79,19 @@ lwthemePostInstallNotification.manageButton=Manage Themes…
 lwthemePostInstallNotification.manageButton.accesskey=M
 
 # LOCALIZATION NOTE (lwthemeNeedsRestart.message):
 # %S will be replaced with the new theme name.
 lwthemeNeedsRestart.message=%S will be installed after you restart.
 lwthemeNeedsRestart.button=Restart Now
 lwthemeNeedsRestart.accesskey=R
 
-popupWarning=%S prevented this site from opening a pop-up window.
-popupWarningMultiple=%S prevented this site from opening %S pop-up windows.
+# LOCALIZATION NOTE (popupWarning.message): Semicolon-separated list of plural forms.
+# #1 is brandShortName and #2 is the number of pop-ups blocked.
+popupWarning.message=#1 prevented this site from opening a pop-up window.;#1 prevented this site from opening #2 pop-up windows.
 popupWarningButton=Options
 popupWarningButton.accesskey=O
 popupWarningButtonUnix=Preferences
 popupWarningButtonUnix.accesskey=P
 popupAllow=Allow pop-ups for %S
 popupBlock=Block pop-ups for %S
 popupWarningDontShowFromMessage=Don't show this message when pop-ups are blocked
 popupWarningDontShowFromLocationbar=Don't show info bar when pop-ups are blocked
@@ -269,16 +270,27 @@ geolocation.learnMore=Learn More…
 webNotifications.showForSession=Show for this session
 webNotifications.showForSession.accesskey=s
 webNotifications.alwaysShow=Always Show Notifications
 webNotifications.alwaysShow.accesskey=A
 webNotifications.neverShow=Always Block Notifications
 webNotifications.neverShow.accesskey=N
 webNotifications.showFromSite=Would you like to show notifications from %S?
 
+# Pointer lock UI
+
+pointerLock.allow=Hide mouse cursor
+pointerLock.allow.accesskey=H
+pointerLock.alwaysAllow=Always allow hiding
+pointerLock.alwaysAllow.accesskey=A
+pointerLock.neverAllow=Never allow hiding
+pointerLock.neverAllow.accesskey=N
+pointerLock.title=Would you like to allow the mouse cursor to be hidden on %S?
+pointerLock.autoLock.title=%S will hide the mouse cursor.
+
 # Phishing/Malware Notification Bar.
 # LOCALIZATION NOTE (notAForgery, notAnAttack)
 # The two button strings will never be shown at the same time, so
 # it's okay for them to have the same access key
 safebrowsing.getMeOutOfHereButton.label=Get me out of here!
 safebrowsing.getMeOutOfHereButton.accessKey=G
 safebrowsing.reportedWebForgery=Reported Web Forgery!
 safebrowsing.notAForgeryButton.label=This isn't a web forgery…
--- a/browser/locales/en-US/chrome/browser/pageInfo.dtd
+++ b/browser/locales/en-US/chrome/browser/pageInfo.dtd
@@ -61,16 +61,17 @@
 <!ENTITY  permImage             "Load Images">
 <!ENTITY  permPopup             "Open Pop-up Windows">
 <!ENTITY  permCookie            "Set Cookies">
 <!ENTITY  permNotifications     "Show Notifications">
 <!ENTITY  permInstall           "Install Extensions or Themes">
 <!ENTITY  permGeo               "Share Location">
 <!ENTITY  permPlugins           "Activate Plugins">
 <!ENTITY  permFullscreen        "Enter Fullscreen">
+<!ENTITY  permPointerLock       "Hide the Mouse Cursor">
 
 <!ENTITY  permIndexedDB              "Maintain Offline Storage">
 <!ENTITY  permClearStorage           "Clear Storage">
 <!ENTITY  permClearStorage.accesskey "C">
 
 <!ENTITY  securityTab           "Security">
 <!ENTITY  securityTab.accesskey "S">
 <!ENTITY  securityHeader        "Security information for this page">
--- a/browser/locales/en-US/searchplugins/google.xml
+++ b/browser/locales/en-US/searchplugins/google.xml
@@ -1,17 +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/. -->
 
 <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
 <ShortName>Google</ShortName>
 <Description>Google Search</Description>
 <InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABUUlEQVR42pWTzUsCYRCH9y9zu3SooCCkjhIRRLeIykXokiWCJ7PvDpZRlz6si1lIQZ3SQxQdOhREpgSm0JeQvfu0+i6I7LKLh4F5h5nnnRl+o6jTdHn8omAYbVqhXqvYFXcEBKFDwcoZZB8B4LkEB9cwGGmFKHb01A1EU9JXzfdvDYZi1lwLwBcVAIwsNWPesIwls7gDtB2Z7N9ujVe+IX2LO2AgItB1OL9vJqsmILDrOoK02IkBAdYy4FsQJC5h+VQCHQDWTqYSgo8fuHuRxS4Ae3stQ7UGE5ttAHqCUgfxC7m4ryrowOyeO6CxqHwZxtYFqtYc5+kNan/gDTsAeueEIRj7n/rmRQMwueUAGF0VAAT3rQBTC0Y3DoDOGbm00icML4oWHYSTgo0MFqjlmPpDgqMcFCuQf4erBzjOwXjcriu9qHg0uutO2+es6fl67T9ptebvFRjBVgAAAABJRU5ErkJggg==</Image>
+<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACuUlEQVRYw8VX60sUURSffybWv6MloxeV0Jug+hJB0YMoCCII1E3LnlYKlVkkUZKaRFEGFlgfMntYhlopVpaP1HXuPPbOzOmcOw/XZbed3ZndvXBYlr17zu+8fudcaWmlLKEsQWlFmUOBAsucY4tsSmQ8gjJTBMOpQjYjkoMGSiStUpHCnknmpXz+uLdJgY5eDsN/TJA1C9KdkUkTjraoWXXlBGDNaQZd/VwoP3xHhbVnGOxvVuHLL1MY5QZArEODbfUMllX70+kbACl8N2qAxgE2XmCLfltZI8O3CRtEXLVg00Xm2ynfAOoeacLA2+9G2t8P3lK98Lf3JsIH8OmH7eEzTEGmO6NT9p3JuBU+ADUB/40ASdsb+5KiFxAAw6pfHkt/p/G5Lu6MTZvhAyDP3VPdrqW90/zSRnmjWw8fwLG7C0VGOV5/dnGll2OXfEVeoFpZcUoOHwBJ0wvdA0FtdwS5YF0dg93XFHg1ZMDrYQNW17KcSC1nJtx3U4XH77nwdui3CaZDhAM/TSiP5c6qUhAu33qJeRFp6UnkpSMQgC1JAKZlC3Y1KsUFQEJ5dw/1/8kHWuEARKtk2HNdgctPdTENewYN0fPJxypUG1Zh74/PWsDQS2K8E/c12NmgQMU5BhXYksT/yaehSw8PgEuxn7HSUydhKkjuZIQ+N5xnwQEcv2cTkIGR3uxjzNY81LwoVLZpwQF0D3ChjCad33RRqujQchIYgDuG/2KbRX0CcDckP22ZFUBnH/dCWtuZ3SMqygTmv3/MCKcIt19RvFHMTbu6M1Eu7Yh9IwbMMEt0SGhdcOi2ClPzC9vvLBp48oELMLSq1SMv0HfakD+i5zuuKuHzwCqccmSMph6NY1pOqdWoNgbHTcEDB3AvjOZBxSV/mJT8aVZWwsdpmeQ8zyNOJOJFMBx3bJFN6R++on7RvMlpZAAAAABJRU5ErkJggg==</Image>
 <Url type="application/x-suggestions+json" method="GET" template="https://www.google.com/complete/search?client=firefox&amp;q={searchTerms}"/>
 <Url type="text/html" method="GET" template="https://www.google.com/search">
   <Param name="q" value="{searchTerms}"/>
   <Param name="ie" value="utf-8"/>
   <Param name="oe" value="utf-8"/>
   <Param name="aq" value="t"/>
   <Param name="rls" value="{moz:distributionID}:{moz:locale}:{moz:official}"/>
 #if MOZ_UPDATE_CHANNEL == beta
--- a/browser/metro/base/content/TopSites.js
+++ b/browser/metro/base/content/TopSites.js
@@ -154,17 +154,18 @@ TopSitesView.prototype = {
       item.setAttribute("iconURI", node.icon);
       item.setAttribute("data-itemid", node[identifier]);
       // here is where we could add verbs based on pinned etc. state
       item.setAttribute("data-contextactions", supportedActions.join(','));
 
       if (this._useThumbs) {
         let thumbnail = PageThumbs.getThumbnailURL(uri);
         let cssthumbnail = 'url("'+thumbnail+'")';
-        item.backgroundImage = cssthumbnail;
+        // Use setAttribute because binding properties may not be available yet.
+        item.setAttribute("customImage", cssthumbnail);
       }
     }
     rootNode.containerOpen = false;
   },
 
   forceReloadOfThumbnail: function forceReloadOfThumbnail(url) {
       let nodes = this._set.querySelectorAll('richgriditem[value="'+url+'"]');
       for (let item of nodes) {
--- a/browser/metro/base/content/bindings/grid.xml
+++ b/browser/metro/base/content/bindings/grid.xml
@@ -489,77 +489,73 @@
         </body>
       </method>
 
     </implementation>
   </binding>
 
   <binding id="richgrid-item">
     <content>
-      <xul:vbox anonid="anon-richgrid-item" class="richgrid-item-content" xbl:inherits="customImagePresent">
-        <xul:hbox class="richgrid-icon-container" xbl:inherits="customImagePresent">
+      <xul:vbox anonid="anon-richgrid-item" class="richgrid-item-content" xbl:inherits="customImage">
+        <xul:hbox class="richgrid-icon-container" xbl:inherits="customImage">
           <xul:box class="richgrid-icon-box"><xul:image xbl:inherits="src=iconURI"/></xul:box>
           <xul:box flex="1" />
         </xul:hbox>
         <xul:description class="richgrid-item-desc" xbl:inherits="value=label" crop="end"/>
       </xul:vbox>
     </content>
 
     <implementation>
       <property name="_box" onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'anon-richgrid-item');"/>
-      <property name="color" onset="this._color = val; this.setColor();" onget="return this._color;"/>
-      <property name="backgroundimage"
-                onset="this._backgroundimage = val; this.setBackgroundImage();"
-                onget="return this._backgroundimage;" />
-      <property name="selected"
-                onget="return this.getAttribute('selected') == 'true';" />
+
+      <property name="selected" onget="return this.hasAttribute('selected');" />
 
       <constructor>
         <![CDATA[
+          this.color = this.getAttribute("customColor");
+          this.backgroundImage = this.getAttribute("customImage");
         ]]>
       </constructor>
 
       <property name="control">
         <getter><![CDATA[
           var parent = this.parentNode;
           while (parent) {
             if (parent instanceof Components.interfaces.nsIDOMXULSelectControlElement)
               return parent;
             parent = parent.parentNode;
           }
           return null;
         ]]></getter>
       </property>
 
-      <method name="setColor">
-        <body>
-          <![CDATA[
-            if (this._color != undefined) {
-              this._box.parentNode.setAttribute("customColorPresent", "true");
-              this._box.style.backgroundColor = this.color;
-            } else {
-              this._box.parentNode.removeAttribute("customColorPresent");
-            }
-          ]]>
-        </body>
-      </method>
+      <property name="color" onget="return this.getAttribute('customColor');">
+        <setter><![CDATA[
+          if (val) {
+            this.setAttribute("customColor", val);
+            this._box.style.backgroundColor = val;
+          } else {
+            this.removeAttribute("customColor");
+            this._box.style.removeProperty("background-color");
+          }
+        ]]></setter>
+      </property>
 
-      <method name="setBackgroundImage">
-        <body>
-          <![CDATA[
-            if (this._backgroundImage != undefined) {
-              this._box.parentNode.setAttribute("customImagePresent", "true");
-              this._box.style.backgroundImage = this.backgroundImage;
-            } else {
-              this._box.parentNode.removeAttribute("customImagePresent");
-              this._box.style.removeProperty("background-image");
-            }
-          ]]>
-        </body>
-      </method>
+      <property name="backgroundImage" onget="return this.getAttribute('customImage');">
+        <setter><![CDATA[
+          if (val) {
+            this.setAttribute("customImage", val);
+            this._box.style.backgroundImage = val;
+          } else {
+            this.removeAttribute("customImage");
+            this._box.style.removeProperty("background-image");
+          }
+        ]]></setter>
+      </property>
+
       <method name="refreshBackgroundImage">
         <body><![CDATA[
           if (this.backgroundImage) {
             this._box.style.removeProperty("background-image");
             this._box.style.setProperty("background-image", this.backgroundImage);
           }
         ]]></body>
       </method>
--- a/browser/metro/base/content/browser.js
+++ b/browser/metro/base/content/browser.js
@@ -1273,24 +1273,22 @@ var PopupBlockerObserver = {
       return;
 
     // Only show the notification again if we've not already shown it. Since
     // notifications are per-browser, we don't need to worry about re-adding
     // it.
     if (!cBrowser.pageReport.reported) {
       if (Services.prefs.getBoolPref("privacy.popups.showBrowserMessage")) {
         var brandShortName = Strings.brand.GetStringFromName("brandShortName");
-        var message;
         var popupCount = cBrowser.pageReport.length;
 
         let strings = Strings.browser;
-        if (popupCount > 1)
-          message = strings.formatStringFromName("popupWarningMultiple", [brandShortName, popupCount], 2);
-        else
-          message = strings.formatStringFromName("popupWarning", [brandShortName], 1);
+        let message = PluralForm.get(popupCount, strings.GetStringFromName("popupWarning.message"))
+                                .replace("#1", brandShortName)
+                                .replace("#2", popupCount);
 
         var notificationBox = Browser.getNotificationBox();
         var notification = notificationBox.getNotificationWithValue("popup-blocked");
         if (notification) {
           notification.label = message;
         }
         else {
           var buttons = [
--- a/browser/metro/base/content/contenthandlers/SelectionHandler.js
+++ b/browser/metro/base/content/contenthandlers/SelectionHandler.js
@@ -59,16 +59,17 @@ var SelectionHandler = {
     addMessageListener("Browser:SelectionUpdate", this);
     addMessageListener("Browser:SelectionClose", this);
     addMessageListener("Browser:SelectionClear", this);
     addMessageListener("Browser:SelectionCopy", this);
     addMessageListener("Browser:SelectionDebug", this);
     addMessageListener("Browser:CaretAttach", this);
     addMessageListener("Browser:CaretMove", this);
     addMessageListener("Browser:CaretUpdate", this);
+    addMessageListener("Browser:SelectionSwitchMode", this);
   },
 
   shutdown: function shutdown() {
     removeMessageListener("Browser:SelectionStart", this);
     removeMessageListener("Browser:SelectionAttach", this);
     removeMessageListener("Browser:SelectionEnd", this);
     removeMessageListener("Browser:SelectionMoveStart", this);
     removeMessageListener("Browser:SelectionMove", this);
@@ -76,16 +77,17 @@ var SelectionHandler = {
     removeMessageListener("Browser:SelectionUpdate", this);
     removeMessageListener("Browser:SelectionClose", this);
     removeMessageListener("Browser:SelectionClear", this);
     removeMessageListener("Browser:SelectionCopy", this);
     removeMessageListener("Browser:SelectionDebug", this);
     removeMessageListener("Browser:CaretAttach", this);
     removeMessageListener("Browser:CaretMove", this);
     removeMessageListener("Browser:CaretUpdate", this);
+    removeMessageListener("Browser:SelectionSwitchMode", this);
   },
 
   /*************************************************
    * Properties
    */
 
   /*
    * snap - enable or disable word snap for the active marker when a
@@ -133,16 +135,49 @@ var SelectionHandler = {
       return;
     }
 
     // Update the position of our selection monocles
     this._updateSelectionUI(true, true);
   },
 
   /*
+   * Switch selection modes. Currently we only support switching
+   * from "caret" to "selection".
+   */
+  _onSwitchMode: function _onSwitchMode(aMode, aMarker, aX, aY) {
+    if (aMode != "selection") {
+      this._onFail("unsupported mode switch");
+      return;
+    }
+    
+    // Sanity check to be sure we are initialized
+    if (!this._targetElement) {
+      this._onFail("not initialized");
+      return;
+    }
+
+    // Similar to _onSelectionStart - we need to create initial selection
+    // but without the initialization bits.
+    let framePoint = this._clientPointToFramePoint({ xPos: aX, yPos: aY });
+    if (!this._domWinUtils.selectAtPoint(framePoint.xPos, framePoint.yPos,
+                                         Ci.nsIDOMWindowUtils.SELECT_CHARACTER)) {
+      this._onFail("failed to set selection at point");
+      return;
+    }
+
+    // We bail if things get out of sync here implying we missed a message.
+    this._selectionMoveActive = true;
+
+    // Update the position of the selection marker that is *not*
+    // being dragged.
+    this._updateSelectionUI(aMarker == "end", aMarker == "start");
+  },
+
+  /*
    * Selection monocle start move event handler
    */
   _onSelectionMoveStart: function _onSelectionMoveStart(aMsg) {
     if (!this._contentWindow) {
       this._onFail("_onSelectionMoveStart was called without proper view set up");
       return;
     }
 
@@ -389,18 +424,22 @@ var SelectionHandler = {
    * _closeSelection
    *
    * Shuts SelectionHandler down.
    */
   _closeSelection: function _closeSelection() {
     this._clearTimers();
     this._cache = null;
     this._contentWindow = null;
+    this._targetElement = null;
     this.selectedText = "";
     this._selectionMoveActive = false;
+    this._contentOffset = null;
+    this._domWinUtils = null;
+    this._targetIsEditable = false;
   },
 
   /*
    * _updateSelectionUI
    *
    * Informs SelectionHelperUI about selection marker position
    * so that our selection monocles can be positioned properly.
    *
@@ -417,21 +456,21 @@ var SelectionHandler = {
     if (!selection) {
       this._onFail("no selection was present");
       return;
     }
 
     // Updates this._cache content selection position data which we send over
     // to SelectionHelperUI. Note updateUIMarkerRects will fail if there isn't
     // any selection in the page. This can happen when we start a monocle drag
-    // but haven't dragged enough to create selection. Just return. 
+    // but haven't dragged enough to create selection. Just return.
     try {
       this._updateUIMarkerRects(selection);
     } catch (ex) {
-      Util.dumpLn(ex.message);
+      Util.dumpLn("_updateUIMarkerRects:", ex.message);
       return;
     }
 
     this._cache.updateStart = aUpdateStart;
     this._cache.updateEnd = aUpdateEnd;
     this._cache.updateCaret = aUpdateCaret || false;
     this._cache.targetIsEditable = this._targetIsEditable;
 
@@ -995,29 +1034,33 @@ var SelectionHandler = {
     let json = aMessage.json;
     switch (aMessage.name) {
       case "Browser:SelectionStart":
         this._onSelectionStart(json.xPos, json.yPos);
         break;
 
       case "Browser:SelectionAttach":
         this._onSelectionAttach(json.xPos, json.yPos);
-      break;
+        break;
 
       case "Browser:CaretAttach":
         this._onCaretAttach(json.xPos, json.yPos);
-      break;
+        break;
 
       case "Browser:CaretMove":
         this._onCaretMove(json.caret.xPos, json.caret.yPos);
-      break;
+        break;
 
       case "Browser:CaretUpdate":
         this._onCaretPositionUpdate(json.caret.xPos, json.caret.yPos);
-      break;
+        break;
+
+      case "Browser:SelectionSwitchMode":
+        this._onSwitchMode(json.newMode, json.change, json.xPos, json.yPos);
+        break;
 
       case "Browser:SelectionClose":
         this._onSelectionClose();
         break;
 
       case "Browser:SelectionMoveStart":
         this._onSelectionMoveStart(json);
         break;
--- a/browser/metro/base/content/helperui/SelectionHelperUI.js
+++ b/browser/metro/base/content/helperui/SelectionHelperUI.js
@@ -1,19 +1,30 @@
 /* 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/. */
 
- /*
+/*
+ * selection management
+ */
+
+/*
+ * Current monocle image:
+ *  dimensions: 32 x 24
+ *  circle center: 16 x 14
+ *  padding top: 6
+ */
+
+// Y axis scroll distance that will disable this module and cancel selection
+const kDisableOnScrollDistance = 25;
+
+/*
  * Markers
  */
 
- // Y axis scroll distance that will disable this module and cancel selection
- const kDisableOnScrollDistance = 25;
-
 function MarkerDragger(aMarker) {
   this._marker = aMarker;
 }
 
 MarkerDragger.prototype = {
   _selectionHelperUI: null,
   _marker: null,
   _shutdown: false,
@@ -168,17 +179,17 @@ Marker.prototype = {
 
   dragStop: function dragStop(aDx, aDy) {
     this._selectionHelperUI.markerDragStop(this);
   },
 
   moveBy: function moveBy(aDx, aDy, aClientX, aClientY) {
     this._xPos -= aDx;
     this._yPos -= aDy;
-    let direction = (aDx < 0 || aDy < 0 ? "end" : "start");
+    let direction = (aDx >= 0 && aDy >= 0 ? "start" : "end");
     // We may swap markers in markerDragMove. If markerDragMove
     // returns true keep processing, otherwise get out of here.
     if (this._selectionHelperUI.markerDragMove(this, direction)) {
       this._setPosition();
     }
   },
 
   hitTest: function hitTest(aX, aY) {
@@ -384,19 +395,17 @@ var SelectionHelperUI = {
    * Init and shutdown
    */
 
   _init: function _init(aMsgTarget) {
     // store the target message manager
     this._msgTarget = aMsgTarget;
 
     // Init our list of available monocle ids
-    this._selectionMarkIds = ["selectionhandle-mark1",
-                              "selectionhandle-mark2",
-                              "selectionhandle-mark3"];
+    this._setupMonocleIdArray();
 
     // Init selection rect info
     this._activeSelectionRect = Util.getCleanRect();
     this._targetElementRect = Util.getCleanRect();
 
     // SelectionHandler messages
     messageManager.addMessageListener("Content:SelectionRange", this);
     messageManager.addMessageListener("Content:SelectionCopied", this);
@@ -445,26 +454,17 @@ var SelectionHelperUI = {
 
     window.removeEventListener("keypress", this, true);
     Elements.browsers.removeEventListener("URLChanged", this, true);
     Elements.browsers.removeEventListener("SizeChanged", this, true);
     Elements.browsers.removeEventListener("ZoomChanged", this, true);
 
     window.removeEventListener("MozPrecisePointer", this, true);
 
-    if (this.startMark != null)
-      this.startMark.shutdown();
-    if (this.endMark != null)
-      this.endMark.shutdown();
-    if (this._caretMark != null)
-      this._caretMark.shutdown();
-
-    this._startMark = null;
-    this._endMark = null;
-    this._caretMark = null;
+    this._shutdownAllMarkers();
 
     this._selectionMarkIds = [];
     this._msgTarget = null;
     this._activeSelectionRect = null;
     this._selectionHandlerActive = false;
 
     this.overlay.displayDebugLayer = false;
     this.overlay.enabled = false;
@@ -508,23 +508,61 @@ var SelectionHelperUI = {
     // on direction.
     this._swapCaretMarker(aDirection);
 
     let targetMark = null;
     if (aDirection == "start")
       targetMark = this.startMark;
     else
       targetMark = this.endMark;
+
+    // Position both in the same starting location.
+    this.startMark.position(targetMark.xPos, targetMark.yPos);
+    this.endMark.position(targetMark.xPos, targetMark.yPos);
+
     // Start the selection monocle drag. SelectionHandler relies on this
     // for getting initialized. This will also trigger a message back for
     // monocle positioning. Note, markerDragMove is still on the stack in
     // this call!
-    targetMark._setPosition();
-    this.markerDragStart(targetMark);
-    this.markerDragMove(targetMark, aDirection);
+    this._sendAsyncMessage("Browser:SelectionSwitchMode", {
+      newMode: "selection",
+      change: targetMark.tag,
+      xPos: targetMark.xPos,
+      yPos: targetMark.yPos,
+    });
+  },
+
+  /*
+   * _transitionFromSelectionToCaret
+   *
+   * Transitions from text selection mode to caret mode.
+   */
+  _transitionFromSelectionToCaret: function _transitionFromSelectionToCaret(aX, aY) {
+    // clear existing selection and shutdown SelectionHandler
+    this._sendAsyncMessage("Browser:SelectionClear", { clearFocus: false });
+    this._sendAsyncMessage("Browser:SelectionClose");
+
+    // Reset some of our state
+    this._selectionHandlerActive = false;
+    this._activeSelectionRect = null;
+
+    // Reset the monocles
+    this._shutdownAllMarkers();
+    this._setupMonocleIdArray();
+
+    // Init SelectionHandler and turn on caret selection. Note the focus caret
+    // will have been removed from the target element due to the shutdown call.
+    // This won't set the caret position on its own.
+    this._sendAsyncMessage("Browser:CaretAttach", {
+      xPos: aX,
+      yPos: aY
+    });
+
+    // Set the caret position
+    this._setCaretPositionAtPoint(aX, aY);
   },
 
   /*
    * _setupDebugOptions
    *
    * Sends a message over to content instructing it to
    * turn on various debug features.
    */
@@ -550,18 +588,19 @@ var SelectionHelperUI = {
       // Turn on the debug layer
       this.overlay.displayDebugLayer = true;
       // Tell SelectionHandler what to do
       this._sendAsyncMessage("Browser:SelectionDebug", debugOpts);
     }
   },
 
   /*
-   * _sendAsyncMessage - helper for sending a message to
-   * SelectionHandler.
+   * _sendAsyncMessage
+   *
+   * Helper for sending a message to SelectionHandler.
    */
   _sendAsyncMessage: function _sendAsyncMessage(aMsg, aJson) {
     if (!this._msgTarget) {
       if (this._debugEvents)
         Util.dumpLn("SelectionHelperUI sendAsyncMessage could not send", aMsg);
       return;
     }
     this._msgTarget.messageManager.sendAsyncMessage(aMsg, aJson);
@@ -585,22 +624,52 @@ var SelectionHelperUI = {
     let json = this._getMarkerBaseMessage();
     json.change = "caret";
     json.caret.xPos = aX;
     json.caret.yPos = aY;
     this._sendAsyncMessage("Browser:CaretUpdate", json);
   },
 
   /*
+   * _shutdownAllMarkers
+   *
+   * Helper for shutting down all markers and
+   * freeing the objects associated with them.
+   */
+  _shutdownAllMarkers: function _shutdownAllMarkers() {
+    if (this._startMark)
+      this._startMark.shutdown();
+    if (this._endMark)
+      this._endMark.shutdown();
+    if (this._caretMark)
+      this._caretMark.shutdown();
+
+    this._startMark = null;
+    this._endMark = null;
+    this._caretMark = null;
+  },
+
+  /*
+   * _setupMonocleIdArray
+   *
+   * Helper for initing the array of monocle ids.
+   */
+  _setupMonocleIdArray: function _setupMonocleIdArray() {
+    this._selectionMarkIds = ["selectionhandle-mark1",
+                              "selectionhandle-mark2",
+                              "selectionhandle-mark3"];
+  },
+
+  /*
    * Event handlers for document events
    */
 
   /*
    * _onTap
-   * 
+   *
    * Handles taps that move the current caret around in text edits,
    * clear active selection and focus when neccessary, or change
    * modes.
    * Future: changing selection modes by tapping on a monocle.
    */
   _onTap: function _onTap(aEvent) {
     // Check for a tap on a monocle
     if (this.startMark.hitTest(aEvent.clientX, aEvent.clientY) ||
@@ -636,16 +705,34 @@ var SelectionHelperUI = {
     // If the target is editable, we have active selection, and
     // the user taps off the input, clear selection and shutdown.
     if (this.startMark.visible && !pointInTargetElement &&
         this._targetIsEditable) {
       this.closeEditSessionAndClear(true);
       return;
     }
 
+    let selectionTap = this._hitTestSelection(aEvent);
+
+    // If the tap is in the selection, just ignore it. We disallow this
+    // since we always get a single tap before a double, and double tap
+    // copies selected text.
+    if (selectionTap) {
+      aEvent.stopPropagation();
+      aEvent.preventDefault();
+      return;
+    }
+
+    // A tap within an editable but outside active selection, clear the
+    // selection and flip back to caret mode.
+    if (this.startMark.visible && pointInTargetElement &&
+        this._targetIsEditable) {
+      this._transitionFromSelectionToCaret(aEvent.clientX, aEvent.clientY);
+    }
+
     // If we have active selection in anything else don't let the event get
     // to content. Prevents random taps from killing active selection.
     aEvent.stopPropagation();
     aEvent.preventDefault();
   },
 
   /*
    * Checks to see if the tap event was on our selection rect.
@@ -834,21 +921,21 @@ var SelectionHelperUI = {
     if (aMarker.tag == "caret") {
       this._sendAsyncMessage("Browser:CaretUpdate", json);
       return;
     }
     this._sendAsyncMessage("Browser:SelectionMoveEnd", json);
   },
 
   markerDragMove: function markerDragMove(aMarker, aDirection) {
-    let json = this._getMarkerBaseMessage();
-    json.change = aMarker.tag;
     if (aMarker.tag == "caret") {
-      // We are going to transition from caret browsing mode to selection mode
-      // on a drag. So swap the caret monocle for a start or end monocle
+      // We are going to transition from caret browsing mode to selection
+      // mode on drag. So swap the caret monocle for a start or end monocle
       // depending on the direction of the drag, and start selecting text.
       this._transitionFromCaretToSelection(aDirection);
       return false;
     }
+    let json = this._getMarkerBaseMessage();
+    json.change = aMarker.tag;
     this._sendAsyncMessage("Browser:SelectionMove", json);
     return true;
   },
 };
--- a/browser/metro/locales/en-US/chrome/browser.properties
+++ b/browser/metro/locales/en-US/chrome/browser.properties
@@ -34,18 +34,19 @@ alertLinkBookmarked=Bookmark added
 alertDownloads=Downloads
 alertDownloadsStart=Downloading: %S
 alertDownloadsDone=%S has finished downloading
 alertCantOpenDownload=Can't open file. Tap to save it.
 alertDownloadsSize=Download too big
 alertDownloadsNoSpace=Not enough storage space
 
 # Popup Blocker
-popupWarning=%S prevented this site from opening a pop-up window.
-popupWarningMultiple=%S prevented this site from opening %S pop-up windows.
+# LOCALIZATION NOTE (popupWarning.message): Semicolon-separated list of plural forms.
+# #1 is brandShortName and #2 is the number of pop-ups blocked.
+popupWarning.message=#1 prevented this site from opening a pop-up window.;#1 prevented this site from opening #2 pop-up windows.
 popupButtonAllowOnce2=Allow once
 popupButtonAlwaysAllow3=Always allow
 popupButtonNeverWarn3=Never allow
 
 # ContentPermissionsPrompt
 contentPermissions.alwaysForSite=Always for this site
 contentPermissions.neverForSite=Never for this site
 
--- a/browser/metro/theme/platform.css
+++ b/browser/metro/theme/platform.css
@@ -480,52 +480,52 @@ richgriditem .richgrid-icon-container {
 
 richgriditem .richgrid-icon-box {
   padding: 4px;
   background: #fff;
   opacity: 1.0;
 }
 
 
-richgriditem[customColorPresent] {
+richgriditem[customColor] {
   color: #f1f1f1;
 }
-richgriditem[customImagePresent] {
+richgriditem[customImage] {
   color: #1a1a1a;
 }
 
 
-richgriditem[customColorPresent] .richgrid-icon-box {
+richgriditem[customColor] .richgrid-icon-box {
   opacity: 0.8;
   background-color: #fff;
 }
 
-.richgrid-item-content[customImagePresent] {
+.richgrid-item-content[customImage] {
   height: 120px;
   width: 200px;
   background-size: cover;
   background-position: center;
   background-repeat: no-repeat;
   -moz-box-pack: end;
   padding: 0px;
 }
 
 /* hide icon if there is an image background */
-.richgrid-icon-container[customImagePresent] {
+.richgrid-icon-container[customImage] {
   visibility: collapse;
 }
 
 .richgrid-item-desc {
   width: @tile_width@;
   font-size: @metro_font_normal@;
   margin-left: 0px !important;
   padding-left: 0px !important;
 }
 
-.richgrid-item-content[customImagePresent] > .richgrid-item-desc {
+.richgrid-item-content[customImage] > .richgrid-item-desc {
   background: hsla(0,2%,98%,.95);
   /*margin-bottom: 0px;
   margin-right: 0px;*/
   margin: 0px;
 }
 
 richgriditem image {
   width: 24px;
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -1221,16 +1221,20 @@ toolbar[iconsize="small"] #webrtc-status
   list-style-image: url(chrome://browser/skin/mixed-content-blocked-64.png);
 }
 
 .popup-notification-icon[popupid="webRTC-sharingDevices"],
 .popup-notification-icon[popupid="webRTC-shareDevices"] {
   list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
 }
 
+.popup-notification-icon[popupid="pointerLock"] {
+  list-style-image: url(chrome://browser/skin/pointerLock-64.png);
+}
+
 /* Notification icon box */
 #notification-popup-box {
   position: relative;
   background-color: #fff;
   background-clip: padding-box;
   padding-left: 4px;
   border-radius: 2.5px 0 0 2.5px;
   border-width: 0 8px 0 0;
@@ -1328,16 +1332,23 @@ toolbar[iconsize="small"] #webrtc-status
 #webRTC-sharingDevices-notification-icon {
   list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png);
 }
 
 #web-notifications-notification-icon {
   list-style-image: url(chrome://browser/skin/notification-16.png);
 }
 
+#pointerLock-notification-icon {
+  list-style-image: url(chrome://browser/skin/pointerLock-16.png);
+}
+#pointerLock-cancel {
+  margin: 0px;
+}
+
 #treecolAutoCompleteImage {
   max-width : 36px;
 }
 
 .ac-result-type-bookmark,
 .autocomplete-treebody::-moz-tree-image(bookmark, treecolAutoCompleteImage) {
   list-style-image: url("chrome://browser/skin/places/pageStarred.png");
   width: 16px;
--- a/browser/themes/linux/jar.mn
+++ b/browser/themes/linux/jar.mn
@@ -34,16 +34,18 @@ browser.jar:
   skin/classic/browser/mixed-content-blocked-64.png
   skin/classic/browser/monitor.png
   skin/classic/browser/monitor_16-10.png
   skin/classic/browser/notification-16.png
   skin/classic/browser/notification-64.png
 * skin/classic/browser/pageInfo.css
   skin/classic/browser/pageInfo.png
   skin/classic/browser/page-livemarks.png
+  skin/classic/browser/pointerLock-16.png
+  skin/classic/browser/pointerLock-64.png
   skin/classic/browser/Privacy-16.png
   skin/classic/browser/Privacy-48.png
   skin/classic/browser/privatebrowsing-mask.png
   skin/classic/browser/searchbar.css
   skin/classic/browser/Secure.png
   skin/classic/browser/Security-broken.png
   skin/classic/browser/setDesktopBackground.css
   skin/classic/browser/slowStartup-16.png
new file mode 100644
index 0000000000000000000000000000000000000000..862cd11c6a2156d74505f977b822ad99616fb96a
GIT binary patch
literal 249
zc$@+G00#ewP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0002MNkl<Zc-p1V
zu?m7v6vpv_aBA-XTH1Snw&vy@qxQIph{y#IQ4}0|3F#Hu8he4}rXuj`8}1;c-m48i
z&OK-N4|f9KFF%Jo&m~Pq2eK>!oyi&%NYfNbN%O&hBuP+nrNy8?9LH$5)6zH)MG;y&
zXl)b-!w?;wwABWrl<4uMeQzKL0%%lp><sw6kD8B~FIpM>f#-Qp1RZL7X%ui>7bMhs
zMmK`8(*_*J5siIA6@e~o0WI6M3p$ad2@LlI1gFnNmTo(O00000NkvXXu0mjfra@r8
new file mode 100644
index 0000000000000000000000000000000000000000..a35ce040c87d03153ab1bef60fa4fefdb0e3a0b2
GIT binary patch
literal 1119
zc$@)W1fctgP)<h;3K|Lk000e1NJLTq002M$002M;1ONa40ARUQ000CgNkl<ZcwX(9
zYitx%6vzMb*x83$%Wij<q!k}AAx48Gf&%qXYh!%@CZfiOAAAI2sf)B)6JsN3Y$~zZ
z0!<TRP#TJ&f__kp5(*)-RzRuMKE$wA3rcIdvuOimc6a8^bw6yF%mlJVXXk!l&bLW!
z&dKlm^S|fJa1?AG9*m#M1&Fy0H2%*78*L!a0g-77T<Zcq_(RNEKp}xI<%dG|PYp04
zz`+G+ZmKW*I71&0;q|6=g_;=p01q#(y%zielH(f4M79-fq*oOFh|1{+Mn=Rzf_Nhx
z4By6pfN_8eDTl*rCwDNjVgWvPva{$NhIauEA4lo}``~fB1xC1`Ru%rlS0?^+o`509
z`Q+!w9eE}ID*>}01ImF&bn-oB^MC-aq`VvI0QX-B<eUi`;HUl^gi_!RsmssJUhI5R
zUI|=qNbYWNFmP=?jVMRBpk0?92tP7;kl9Qq!d;l$7l|?;V06<hDqD&c#@9e+G!^sk
za^%@y&lLp>2pDQm%f#V8W#Xi5Mg(gCxdk~d-5+^u@*8H0i3qn}*&D8B(E>w|Lh`NP
z&GOSAj8-!q9+0O3M>Yjm5HQrRm=3j8)eSpNz}P5+;`7H^A7(^A&jbba#XoP^Sl{GG
z0Tg;Rtqu^6?2`-RBDpwzjUTt-`%4h8CkRv!D$RIhe<B!<$XCf%&+sbbOe7#94%z03
z$jV7bEdTU+*`s0xayDTC)Ah6^mk-z_Hzjyh@w7v(*BIS~0**ekwC!chp?QEp2elM1
zJ^$E~4oyTlRJ~;2%q@}y=F!z}cfRy@-U}d5)$-ltzrGRH<_RX4Q#TDfN;~r00s=Mp
zz|M*h{^PR^n$`FCzGqs4c_lzVW>@W8@CSC)j$u@57E5@O4ki|!SV=qcMnHo;z50U%
zF?43q1KMn}YGEJ>hu5@SX}qy@B2pntJ=axy8eO$=_WgFPQ4E<GoL)S7A9mYLfI@}z
zSM~Pd-|&8|VX8{9RkJdX4n5!IvsnW=RQN{MeNr%r4>u^LrnIZC3I)8Wr@xntSJ1C)
zB%njZoL@G4RB!@2%;^D~OKv3=q`arQX0zKy0x6XASML>u@!5;yBEsC9t`oeRNe8hz
z<G0g;wh<sLHD3zHvByYnig<dPW?`WFyKA<%Y$JeIxO>sP{*pIRdXuYK5IGapk$cWB
zqDO4=f%W@M>8)`_>mpVLbH09IEAQB1l4@3o8ITJ@Rq0Y&zL5O8ecQ9gyGk?{g(cfo
zu8q=mXI8Uhqe`j8l8!%!8=Tt>2lf5rf@}$rkS3OVOYd^51pt=$``lUE@}FAPQxW6F
z(TfpKM}|@W-;us_nT|lLyl3etjG-5?C<WT#Q~^+4pZn&D{?ZAYL~nG=c<)#NIMDC}
l7G;u;+wh^%xw!oA_#fI%r+B^f!^i*t002ovPDHLkV1jl_2hIQh
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -3150,16 +3150,27 @@ toolbarbutton.chevron > .toolbarbutton-m
   list-style-image: url(chrome://browser/skin/notification-16.png);
 }
 @media (min-resolution: 2dppx) {
   #web-notifications-notification-icon {
     list-style-image: url(chrome://browser/skin/notification-16@2x.png);
   }
 }
 
+#pointerLock-notification-icon {
+  list-style-image: url(chrome://browser/skin/pointerLock-16.png);
+}
+@media (min-resolution: 2dppx) {
+  #pointerLock-notification-icon {
+    list-style-image: url(chrome://browser/skin/pointerLock-16@2x.png);
+  }
+}
+
+
+
 .popup-notification-icon {
   width: 64px;
   height: 64px;
   -moz-margin-end: 10px;
 }
 
 .popup-notification-icon[popupid="geolocation"] {
   list-style-image: url(chrome://browser/skin/Geolocation-64.png);
@@ -3243,16 +3254,29 @@ toolbarbutton.chevron > .toolbarbutton-m
   list-style-image: url(chrome://browser/skin/mixed-content-blocked-64.png);
 }
 @media (min-resolution: 2dppx) {
   .popup-notification-icon[popupid="mixed-content-blocked"] {
     list-style-image: url(chrome://browser/skin/mixed-content-blocked-64@2x.png);
   }
 }
 
+.popup-notification-icon[popupid="pointerLock"] {
+  list-style-image: url(chrome://browser/skin/pointerLock-64.png);
+}
+@media (min-resolution: 2dppx) {
+  .popup-notification-icon[popupid="pointerLock"] {
+    list-style-image: url(chrome://browser/skin/pointerLock-64@2x.png);
+  }
+}
+#pointerLock-cancel {
+  margin: 0px;
+}
+
+
 #mixed-content-blocked-helplink {
   margin: 0px;
 }
 
 .popup-notification-icon[popupid="webRTC-sharingDevices"],
 .popup-notification-icon[popupid="webRTC-shareDevices"] {
   list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
 }
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -52,16 +52,20 @@ browser.jar:
   skin/classic/browser/panel-expander-closed.png
   skin/classic/browser/panel-expander-closed@2x.png
   skin/classic/browser/panel-expander-open.png
   skin/classic/browser/panel-expander-open@2x.png
   skin/classic/browser/panel-plus-sign.png
   skin/classic/browser/page-livemarks.png
   skin/classic/browser/page-livemarks@2x.png
   skin/classic/browser/pageInfo.css
+  skin/classic/browser/pointerLock-16.png
+  skin/classic/browser/pointerLock-16@2x.png
+  skin/classic/browser/pointerLock-64.png
+  skin/classic/browser/pointerLock-64@2x.png
   skin/classic/browser/Privacy-16.png
   skin/classic/browser/Privacy-48.png
   skin/classic/browser/privatebrowsing-mask.png
   skin/classic/browser/privatebrowsing-mask@2x.png
   skin/classic/browser/reload-stop-go.png
   skin/classic/browser/reload-stop-go@2x.png
   skin/classic/browser/searchbar-dropmarker.png
   skin/classic/browser/searchbar-dropmarker@2x.png
new file mode 100644
index 0000000000000000000000000000000000000000..862cd11c6a2156d74505f977b822ad99616fb96a
GIT binary patch
literal 249
zc$@+G00#ewP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0002MNkl<Zc-p1V
zu?m7v6vpv_aBA-XTH1Snw&vy@qxQIph{y#IQ4}0|3F#Hu8he4}rXuj`8}1;c-m48i
z&OK-N4|f9KFF%Jo&m~Pq2eK>!oyi&%NYfNbN%O&hBuP+nrNy8?9LH$5)6zH)MG;y&
zXl)b-!w?;wwABWrl<4uMeQzKL0%%lp><sw6kD8B~FIpM>f#-Qp1RZL7X%ui>7bMhs
zMmK`8(*_*J5siIA6@e~o0WI6M3p$ad2@LlI1gFnNmTo(O00000NkvXXu0mjfra@r8
new file mode 100644
index 0000000000000000000000000000000000000000..584c8b1924ccc7141ec69f33609ce9e273bf709e
GIT binary patch
literal 411
zc$@*70c8G(P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80004ENkl<Zc-rmP
zt4;$!7=~d8q(PvXAi!WT7_MMgg~D+QcpS3l!*-k99=3;oBq;6xM7I?nxPvB`-T(mv
z0`l>RisnyKw%eIq1mZFCXELvtOfqW#67}~3`u)C7n~4SVdOgqsrIQQ*jp-ovfNr;o
z8LxB_Ye1*df$&8aNd!pOlrkRR`#u&J(vH!9cDs#VywIVsfL5!85Z>w3NI<jML`dIs
zsXd_4XkbY<w52V;^E^cGNV{4BT-QZJ6FOQspkA+I1s`;_Qh?()i0F-;>6Z2*2h?gc
zgz!lYos*(HZI{rtZG>bQc?YW1D(09FgrSjuN~HqfiPAJ82$uGMa=DBd_q07-w+KR@
zJ)l%7Vd{=jVm2ZO$65o5#Ukj6Hs;JMf)Hp8C=?1dtuL4d1VP32FUaTf7C{J%21vPF
zE+7ahwt#Fls|dotbbyQ)%pOiE)__bVqi8^CnSKAi;~#q$c3=HV_A>wg002ovPDHLk
FV1i*XuTB5}
new file mode 100644
index 0000000000000000000000000000000000000000..a35ce040c87d03153ab1bef60fa4fefdb0e3a0b2
GIT binary patch
literal 1119
zc$@)W1fctgP)<h;3K|Lk000e1NJLTq002M$002M;1ONa40ARUQ000CgNkl<ZcwX(9
zYitx%6vzMb*x83$%Wij<q!k}AAx48Gf&%qXYh!%@CZfiOAAAI2sf)B)6JsN3Y$~zZ
z0!<TRP#TJ&f__kp5(*)-RzRuMKE$wA3rcIdvuOimc6a8^bw6yF%mlJVXXk!l&bLW!
z&dKlm^S|fJa1?AG9*m#M1&Fy0H2%*78*L!a0g-77T<Zcq_(RNEKp}xI<%dG|PYp04
zz`+G+ZmKW*I71&0;q|6=g_;=p01q#(y%zielH(f4M79-fq*oOFh|1{+Mn=Rzf_Nhx
z4By6pfN_8eDTl*rCwDNjVgWvPva{$NhIauEA4lo}``~fB1xC1`Ru%rlS0?^+o`509
z`Q+!w9eE}ID*>}01ImF&bn-oB^MC-aq`VvI0QX-B<eUi`;HUl^gi_!RsmssJUhI5R
zUI|=qNbYWNFmP=?jVMRBpk0?92tP7;kl9Qq!d;l$7l|?;V06<hDqD&c#@9e+G!^sk
za^%@y&lLp>2pDQm%f#V8W#Xi5Mg(gCxdk~d-5+^u@*8H0i3qn}*&D8B(E>w|Lh`NP
z&GOSAj8-!q9+0O3M>Yjm5HQrRm=3j8)eSpNz}P5+;`7H^A7(^A&jbba#XoP^Sl{GG
z0Tg;Rtqu^6?2`-RBDpwzjUTt-`%4h8CkRv!D$RIhe<B!<$XCf%&+sbbOe7#94%z03
z$jV7bEdTU+*`s0xayDTC)Ah6^mk-z_Hzjyh@w7v(*BIS~0**ekwC!chp?QEp2elM1
zJ^$E~4oyTlRJ~;2%q@}y=F!z}cfRy@-U}d5)$-ltzrGRH<_RX4Q#TDfN;~r00s=Mp
zz|M*h{^PR^n$`FCzGqs4c_lzVW>@W8@CSC)j$u@57E5@O4ki|!SV=qcMnHo;z50U%
zF?43q1KMn}YGEJ>hu5@SX}qy@B2pntJ=axy8eO$=_WgFPQ4E<GoL)S7A9mYLfI@}z
zSM~Pd-|&8|VX8{9RkJdX4n5!IvsnW=RQN{MeNr%r4>u^LrnIZC3I)8Wr@xntSJ1C)
zB%njZoL@G4RB!@2%;^D~OKv3=q`arQX0zKy0x6XASML>u@!5;yBEsC9t`oeRNe8hz
z<G0g;wh<sLHD3zHvByYnig<dPW?`WFyKA<%Y$JeIxO>sP{*pIRdXuYK5IGapk$cWB
zqDO4=f%W@M>8)`_>mpVLbH09IEAQB1l4@3o8ITJ@Rq0Y&zL5O8ecQ9gyGk?{g(cfo
zu8q=mXI8Uhqe`j8l8!%!8=Tt>2lf5rf@}$rkS3OVOYd^51pt=$``lUE@}FAPQxW6F
z(TfpKM}|@W-;us_nT|lLyl3etjG-5?C<WT#Q~^+4pZn&D{?ZAYL~nG=c<)#NIMDC}
l7G;u;+wh^%xw!oA_#fI%r+B^f!^i*t002ovPDHLkV1jl_2hIQh
new file mode 100644
index 0000000000000000000000000000000000000000..25a8cbab0f2012e0d86840795aa4eb4e885e78f6
GIT binary patch
literal 2201
zc$@*52xj+*P)<h;3K|Lk000e1NJLTq004jh004jp1ONa4X*a1r000PJNkl<ZcwX&Y
zZERE58Gg>SeeX@k7fus39T}y36-LIC{D6*y4UjszvScko+Dh36k*1aswxolEmJT}t
zRcW;`4R!kip)^@H#z&_WtzoQ!DFGTIp+PiSz<h*;#tFU=1`=ZX-g{<U3`cNQ+ua(?
zz9-L-oZrur=Y7sO?|b493b7$UaEu8sCV=1=6JSgLu`woq6Qc|-Mi(2?!2#YkyiT!8
zU=`ZEZlN<kT12|Mj|wY*12WVpt}gFlK|_$h2?v~cWWVR<o?qi0P!SwJAl-I>L*3%t
z=8**}0VaV9Dza*%zk7;=Dgh<|KoDD%;Vw_Lr(3*}VB7@?vL?yLJXL}Tz<l6@40W9H
zj;B#10eA_dtXI9Q9#x18pz(FD2mqc9PcfcCK)~Ce1gDh->Rjh>lnZ$sCU*jHg4}^+
zA_>5!LAJ6B8$rYofR}(|dB`qg+cN}N41THzE&x~-nXFf%R~QHI$0N1e<-;7|1Ym(E
zLoHDbW4V9=uryFqwUxXINgM%q35eP#?L&@jPl7!7KqS@Sqk0uC2{;#!?xaDP%ZIOt
zBmf_XMauhFDUtwu8p!H)@=G`b$pGF500F5F&osY>P?`xa`XC_jPqH|C%&3B2h!Wrf
z(Fp}vGh99_6ifhC2-an3ynF!93zGr72o!LV--c(=pF$VN0W1yT-J?}fJKO?<V1htg
z6zS5xjgLfe0Don+MyyyYPzLa41LTqY;kDQzjsy4;qC@=^*#=pV4B*qi`dJg6W-i55
zaU8(U7b~4zC=)3I__@*~=~(y~{6!cC@M$2&MyzNQNdP_&V<T3n4XSNJFnJ(KAj`v(
zji=EkNCxmH0~web@kOg~LXZ;R?~4kQ2}%c+2`B)2fhMyNYue8SN2wGDA)fG;=#MaL
z-w;fGUyO}djcW7?Qv!SgO)Yo&Fjpi2_y$^ud<e@0*ai~}*HpBIXW?a-VmN?*lFLS{
z!U(`i0HxY-6b}nj0{q#4ltp|EPd9f8;{ZMol_L55h8jDc1CqZ^m&vw<nON6s2;%@g
z4YKN`{SEp5*9^d@W<c`p5si&l*Hyjd7svq=6edj2J2K25zI6+2odNVdw^3^`A?SD<
zShwc2-`Q##r2mmJVBV!pL5wV|K+Dq#wFj@D%LWc$gt^~z{1a3T<!ZTug~4KNg7(Fb
z#I#=m2aad30F0=4A8p62Y%MQXpcQE)gOfE?2Lqr(gN8w92tvzn2T&N$VZZ><vj%f5
zYnKEc)(UUkr&I`9obVv7f!gFKY{EeP`3YwWwNkCrvNi*TF=!FC*4nrSUbkCEh{7b*
zK4xvU)(#6Y7r6S!G4ru@i*#r$6>>J%QMI=T4B}0PL*-xjhM)qF+gBVCu&V=-7Yl(S
zwg%@_l-uNwrg-wi(w!u<r6hf_nLc4F2T*H|*FhuF4Fe`<l5UT-sA9TJ1Yq=|Fo&yl
z&N{5aNF;zIf#e$4Y>Q`djD7@;>(8`K3r@d$e7>Gf0FZ<(7+CVv(jy;dv;!D@9TCXd
z%9d$C3@a@K+jXu8_+}STdN*Zw2{8ImsD01vm>5C`E%l$!CJY%#C2(S3X=PCc3&8Gn
z5#(H2v$J>zLF}jx0=*&kA5!rE#`SK@=nOF9zkT<a)q7MOeQ2v2f`xG}2UqAyvK)}m
z|Lo(92X1Dd0~q}XN>2XlPpXbfc=HZ@;LLz~pOJzGjQsN(GO`31{YhP`|Linz25og=
zFu?Va5j8=Ro(KACDwPZqfbIHW%sBLub^@Hlt~wp}py$%~_EgRT(FX=z%&-ig@#u@v
ziuaZs2k-$7)KPHASwHxsLy`cHgc1Z^_+j%-BO@HZ=tmJXE8nr`AF6A&=yUM@EB|mR
zd%?&<zUMQf1ep1a=r{lPWH%`OTK5lpDso>ksF5%SB<nm7sM|s^K>$X7<U4H(&cVPw
z_>ce>x^lac?*$Tu9@)Mk12Vvj(<ejUZ~JlpQS8Q9fFcnJesTS84iJzeWzg3^-%4u-
zF!MXE{kSDYe*|qfi=^-$%;`>^15R9@IlDTY1z;DRtIxGe8N^Mzi5{ec{3hM<4w6XF
z_e$Cdz%D%5S88{B;Rddu1p%api+i%qrE(?=l~*iC*9@?%54bO^-jy4{09tY5vwWxM
z_~t9yB*a!iqY`q(OAn=~1589v{9*muG5WpO!RV)k3oS~o0V8P+X!9y6(l!GopQzuh
z7`TA9a0{Om)V(EH5L&%rDX=MB1$e#oT?fT!{2mef7cjQEuBOr;2`-xRC_ZNpiq8ce
zoWOpV;IIa%VB*Gpj|^7=Lt48Giud+>7x&;d=}`hWf_HiPsY7mdgv=E7g8n6yrD>S~
zIEeqrO6Nx0DK<(kZ?fxbu!#(%avm61I={%40(=~DznzKzlr>5-<ADT4s>s<8{DGk)
zAD9GIEN*=7ru|9)9}N`lOC<-4JpTrpz7LSso2*fqK!QNc*A-g|aIweT&U=72?Z^ZD
zFWOQ7AiL2t`6e0vjI#HIl@419aQ<}uVYU~5Z@5^?6`Fl&YMD)+$>pxU_JKs$Ucj2}
zhP6~}PUp9}6$6iLJy}a_=K$cmFOM}!?{*q>L=c7=Sh&0Cji>&p7zp76i0vG}8l?uL
zyA^N1gpPvC^EwvzEzTM`ajMn;Y$|~Npu784nRM6oCJOxvI_6#m0Q8{~r<wI_DFBe~
zy}pM+f(es8_~GLnvjYHt9(2Ob$lF+ei+l6V-I(eyCU!s3Ib8!l;YVj}k3e6dQoQ-0
zRZEUe3|Zt)$H?~y_AN60om-tKg@IEzQX9l5f>5L>reG?LB7{-K*ngge;20BNOaQSl
bCcwV|J{_RM3DW`J00000NkvXXu0mjfJlEa^
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -2278,16 +2278,20 @@ toolbarbutton.bookmark-item[dragover="tr
   list-style-image: url(chrome://browser/skin/mixed-content-blocked-64.png);
 }
 
 .popup-notification-icon[popupid="webRTC-sharingDevices"],
 .popup-notification-icon[popupid="webRTC-shareDevices"] {
   list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
 }
 
+.popup-notification-icon[popupid="pointerLock"] {
+  list-style-image: url(chrome://browser/skin/pointerLock-64.png);
+}
+
 /* Notification icon box */
 #notification-popup-box {
   position: relative;
   background-color: #fff;
   background-clip: padding-box;
   padding-left: 3px;
   border-radius: 2.5px 0 0 2.5px;
   border-width: 0 8px 0 0;
@@ -2383,16 +2387,23 @@ toolbarbutton.bookmark-item[dragover="tr
 #webRTC-sharingDevices-notification-icon {
   list-style-image: url(chrome://browser/skin/webRTC-sharingDevice-16.png);
 }
 
 #web-notifications-notification-icon {
   list-style-image: url(chrome://browser/skin/notification-16.png);
 }
 
+#pointerLock-notification-icon {
+  list-style-image: url(chrome://browser/skin/pointerLock-16.png);
+}
+#pointerLock-cancel {
+  margin: 0px;
+}
+
 #identity-popup-container {
   min-width: 280px;
 }
 
 /* Bookmarks roots menu-items */
 #appmenu_subscribeToPage:not([disabled]),
 #appmenu_subscribeToPageMenu,
 #subscribeToPageMenuitem:not([disabled]),
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -42,16 +42,18 @@ browser.jar:
         skin/classic/browser/mixed-content-blocked-64.png
         skin/classic/browser/monitor.png
         skin/classic/browser/monitor_16-10.png
         skin/classic/browser/notification-16.png
         skin/classic/browser/notification-64.png
         skin/classic/browser/pageInfo.css
         skin/classic/browser/pageInfo.png
         skin/classic/browser/page-livemarks.png                      (feeds/feedIcon16.png)
+        skin/classic/browser/pointerLock-16.png
+        skin/classic/browser/pointerLock-64.png
         skin/classic/browser/Privacy-16.png
         skin/classic/browser/Privacy-48.png
         skin/classic/browser/privatebrowsing-light.png
         skin/classic/browser/privatebrowsing-dark.png
         skin/classic/browser/reload-stop-go.png
         skin/classic/browser/searchbar.css
         skin/classic/browser/searchbar-dropdown-arrow.png
         skin/classic/browser/Secure24.png
@@ -275,16 +277,18 @@ browser.jar:
         skin/classic/aero/browser/mixed-content-blocked-64.png
         skin/classic/aero/browser/monitor.png
         skin/classic/aero/browser/monitor_16-10.png
         skin/classic/aero/browser/notification-16.png
         skin/classic/aero/browser/notification-64.png
         skin/classic/aero/browser/pageInfo.css
         skin/classic/aero/browser/pageInfo.png                       (pageInfo-aero.png)
         skin/classic/aero/browser/page-livemarks.png                 (feeds/feedIcon16-aero.png)
+        skin/classic/aero/browser/pointerLock-16.png                 (pointerLock-16.png)
+        skin/classic/aero/browser/pointerLock-64.png                 (pointerLock-64.png)
         skin/classic/aero/browser/Privacy-16.png                     (Privacy-16-aero.png)
         skin/classic/aero/browser/Privacy-48.png                     (Privacy-48-aero.png)
         skin/classic/aero/browser/privatebrowsing-light.png
         skin/classic/aero/browser/privatebrowsing-dark.png
         skin/classic/aero/browser/reload-stop-go.png
         skin/classic/aero/browser/searchbar.css
         skin/classic/aero/browser/searchbar-dropdown-arrow.png       (searchbar-dropdown-arrow-aero.png)
         skin/classic/aero/browser/Secure24.png                       (Secure24-aero.png)
new file mode 100644
index 0000000000000000000000000000000000000000..862cd11c6a2156d74505f977b822ad99616fb96a
GIT binary patch
literal 249
zc$@+G00#ewP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0002MNkl<Zc-p1V
zu?m7v6vpv_aBA-XTH1Snw&vy@qxQIph{y#IQ4}0|3F#Hu8he4}rXuj`8}1;c-m48i
z&OK-N4|f9KFF%Jo&m~Pq2eK>!oyi&%NYfNbN%O&hBuP+nrNy8?9LH$5)6zH)MG;y&
zXl)b-!w?;wwABWrl<4uMeQzKL0%%lp><sw6kD8B~FIpM>f#-Qp1RZL7X%ui>7bMhs
zMmK`8(*_*J5siIA6@e~o0WI6M3p$ad2@LlI1gFnNmTo(O00000NkvXXu0mjfra@r8
new file mode 100644
index 0000000000000000000000000000000000000000..a35ce040c87d03153ab1bef60fa4fefdb0e3a0b2
GIT binary patch
literal 1119
zc$@)W1fctgP)<h;3K|Lk000e1NJLTq002M$002M;1ONa40ARUQ000CgNkl<ZcwX(9
zYitx%6vzMb*x83$%Wij<q!k}AAx48Gf&%qXYh!%@CZfiOAAAI2sf)B)6JsN3Y$~zZ
z0!<TRP#TJ&f__kp5(*)-RzRuMKE$wA3rcIdvuOimc6a8^bw6yF%mlJVXXk!l&bLW!
z&dKlm^S|fJa1?AG9*m#M1&Fy0H2%*78*L!a0g-77T<Zcq_(RNEKp}xI<%dG|PYp04
zz`+G+ZmKW*I71&0;q|6=g_;=p01q#(y%zielH(f4M79-fq*oOFh|1{+Mn=Rzf_Nhx
z4By6pfN_8eDTl*rCwDNjVgWvPva{$NhIauEA4lo}``~fB1xC1`Ru%rlS0?^+o`509
z`Q+!w9eE}ID*>}01ImF&bn-oB^MC-aq`VvI0QX-B<eUi`;HUl^gi_!RsmssJUhI5R
zUI|=qNbYWNFmP=?jVMRBpk0?92tP7;kl9Qq!d;l$7l|?;V06<hDqD&c#@9e+G!^sk
za^%@y&lLp>2pDQm%f#V8W#Xi5Mg(gCxdk~d-5+^u@*8H0i3qn}*&D8B(E>w|Lh`NP
z&GOSAj8-!q9+0O3M>Yjm5HQrRm=3j8)eSpNz}P5+;`7H^A7(^A&jbba#XoP^Sl{GG
z0Tg;Rtqu^6?2`-RBDpwzjUTt-`%4h8CkRv!D$RIhe<B!<$XCf%&+sbbOe7#94%z03
z$jV7bEdTU+*`s0xayDTC)Ah6^mk-z_Hzjyh@w7v(*BIS~0**ekwC!chp?QEp2elM1
zJ^$E~4oyTlRJ~;2%q@}y=F!z}cfRy@-U}d5)$-ltzrGRH<_RX4Q#TDfN;~r00s=Mp
zz|M*h{^PR^n$`FCzGqs4c_lzVW>@W8@CSC)j$u@57E5@O4ki|!SV=qcMnHo;z50U%
zF?43q1KMn}YGEJ>hu5@SX}qy@B2pntJ=axy8eO$=_WgFPQ4E<GoL)S7A9mYLfI@}z
zSM~Pd-|&8|VX8{9RkJdX4n5!IvsnW=RQN{MeNr%r4>u^LrnIZC3I)8Wr@xntSJ1C)
zB%njZoL@G4RB!@2%;^D~OKv3=q`arQX0zKy0x6XASML>u@!5;yBEsC9t`oeRNe8hz
z<G0g;wh<sLHD3zHvByYnig<dPW?`WFyKA<%Y$JeIxO>sP{*pIRdXuYK5IGapk$cWB
zqDO4=f%W@M>8)`_>mpVLbH09IEAQB1l4@3o8ITJ@Rq0Y&zL5O8ecQ9gyGk?{g(cfo
zu8q=mXI8Uhqe`j8l8!%!8=Tt>2lf5rf@}$rkS3OVOYd^51pt=$``lUE@}FAPQxW6F
z(TfpKM}|@W-;us_nT|lLyl3etjG-5?C<WT#Q~^+4pZn&D{?ZAYL~nG=c<)#NIMDC}
l7G;u;+wh^%xw!oA_#fI%r+B^f!^i*t002ovPDHLkV1jl_2hIQh
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -543,16 +543,24 @@ user_pref("extensions.getAddons.search.u
 user_pref("plugins.update.url", "http://%(server)s/plugins-dummy/updateCheckURL");
 
 // Existing tests don't wait for the notification button security delay
 user_pref("security.notification_enable_delay", 0);
 
 // Make enablePrivilege continue to work for test code. :-(
 user_pref("security.turn_off_all_security_so_that_viruses_can_take_over_this_computer", true);
 
+// In the default configuration, we bypass XBL scopes (a security feature) for
+// domains whitelisted for remote XUL, so that intranet apps and such continue
+// to work without major rewrites. However, we also use the whitelist mechanism
+// to run our XBL tests in automation, in which case we really want to be testing
+// the configuration that we ship to users without special whitelisting. So we
+// use an additional pref here to allow automation to use the "normal" behavior.
+user_pref("dom.use_xbl_scopes_for_remote_xul", true);
+
 // Get network events.
 user_pref("network.activity.blipIntervalMilliseconds", 250);
 
 // Don't allow the Data Reporting service to prompt for policy acceptance.
 user_pref("datareporting.policy.dataSubmissionPolicyBypassAcceptance", true);
 
 // Point Firefox Health Report at a local server. We don't care if it actually
 // works. It just can't hit the default production endpoint.
new file mode 100644
--- /dev/null
+++ b/build/clang-plugin/Makefile.in
@@ -0,0 +1,40 @@
+# 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/.
+
+CXX      := @CXX@
+CXXFLAGS := @CXXFLAGS@
+LDFLAGS  := @LDFLAGS@
+VPATH		 := @srcdir@
+
+# Helper for end
+NULL :=
+
+CPPSRCS := \
+	clang-plugin.cpp \
+	$(NULL)
+
+TESTSRCS := \
+	TestMustOverride.cpp \
+	$(NULL)
+
+OBJS := $(patsubst %.cpp,%.o,$(CPPSRCS))
+TESTS := $(patsubst %.cpp,test-%,$(TESTSRCS))
+
+PLUGIN := libclang-plugin.so
+
+all: $(PLUGIN) $(TESTS)
+
+$(OBJS): %.o: %.cpp Makefile
+	$(CXX) -o $@ -c $(CXXFLAGS) $<
+
+$(PLUGIN): $(OBJS)
+	rm -f $@
+	$(CXX) -shared -o $@ $(CXXFLAGS) $(LDFLAGS) $(OBJS)
+
+TESTFLAGS := -fsyntax-only -Xclang -verify \
+	-Xclang -load -Xclang $(CURDIR)/$(PLUGIN) \
+	-Xclang -add-plugin -Xclang moz-check
+
+$(TESTS): test-%: tests/%.cpp $(PLUGIN)
+	$(CXX) $(TESTFLAGS) $<
new file mode 100644
--- /dev/null
+++ b/build/clang-plugin/clang-plugin.cpp
@@ -0,0 +1,102 @@
+/* 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 "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Basic/Version.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendPluginRegistry.h"
+#include "clang/Sema/Sema.h"
+
+#define CLANG_VERSION_FULL (CLANG_VERSION_MAJOR * 100 + CLANG_VERSION_MINOR)
+
+using namespace llvm;
+using namespace clang;
+
+namespace {
+class MozChecker : public ASTConsumer, public RecursiveASTVisitor<MozChecker> {
+  DiagnosticsEngine &Diag;
+  const CompilerInstance &CI;
+public:
+  MozChecker(const CompilerInstance &CI) : Diag(CI.getDiagnostics()), CI(CI) {}
+  virtual void HandleTranslationUnit(ASTContext &ctx) {
+    TraverseDecl(ctx.getTranslationUnitDecl());
+  }
+
+  static bool hasCustomAnnotation(const Decl *d, const char *spelling) {
+    AnnotateAttr *attr = d->getAttr<AnnotateAttr>();
+    if (!attr)
+      return false;
+
+    return attr->getAnnotation() == spelling;
+  }
+
+  bool VisitCXXRecordDecl(CXXRecordDecl *d) {
+    // We need definitions, not declarations
+    if (!d->isThisDeclarationADefinition()) return true;
+
+    // Look through all of our immediate bases to find methods that need to be
+    // overridden
+    typedef std::vector<CXXMethodDecl *> OverridesVector;
+    OverridesVector must_overrides;
+    for (CXXRecordDecl::base_class_iterator base = d->bases_begin(),
+         e = d->bases_end(); base != e; ++base) {
+      // The base is either a class (CXXRecordDecl) or it's a templated class...
+      CXXRecordDecl *parent = base->getType()
+        .getDesugaredType(d->getASTContext())->getAsCXXRecordDecl();
+      // The parent might not be resolved to a type yet. In this case, we can't
+      // do any checking here. For complete correctness, we should visit
+      // template instantiations, but this case is likely to be rare, so we will
+      // ignore it until it becomes important.
+      if (!parent) {
+        continue;
+      }
+      parent = parent->getDefinition();
+      for (CXXRecordDecl::method_iterator M = parent->method_begin();
+          M != parent->method_end(); ++M) {
+        if (hasCustomAnnotation(*M, "moz_must_override"))
+          must_overrides.push_back(*M);
+      }
+    }
+
+    for (OverridesVector::iterator it = must_overrides.begin();
+        it != must_overrides.end(); ++it) {
+      bool overridden = false;
+      for (CXXRecordDecl::method_iterator M = d->method_begin();
+          !overridden && M != d->method_end(); ++M) {
+        // The way that Clang checks if a method M overrides its parent method
+        // is if the method has the same name but would not overload.
+        if (M->getName() == (*it)->getName() &&
+            !CI.getSema().IsOverload(*M, (*it), false))
+          overridden = true;
+      }
+      if (!overridden) {
+        unsigned overrideID = Diag.getDiagnosticIDs()->getCustomDiagID(
+            DiagnosticIDs::Error, "%0 must override %1");
+        unsigned overrideNote = Diag.getDiagnosticIDs()->getCustomDiagID(
+            DiagnosticIDs::Note, "function to override is here");
+        Diag.Report(d->getLocation(), overrideID) << d->getDeclName() <<
+          (*it)->getDeclName();
+        Diag.Report((*it)->getLocation(), overrideNote);
+      }
+    }
+    return true;
+  }
+};
+
+class MozCheckAction : public PluginASTAction {
+public:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI, StringRef fileName) {
+    return new MozChecker(CI);
+  }
+
+  bool ParseArgs(const CompilerInstance &CI,
+                 const std::vector<std::string> &args) {
+    return true;
+  }
+};
+}
+
+static FrontendPluginRegistry::Add<MozCheckAction>
+X("moz-check", "check moz action");
new file mode 100755
--- /dev/null
+++ b/build/clang-plugin/configure
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+# Default srcdir to this directory
+srcdir=
+
+for option; do
+  case "$option" in
+  -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case "$option" in
+  --srcdir=*) srcdir="$optarg";;
+  esac
+done
+
+if test -z "$CXX"; then
+  CXX=`which clang++`
+fi
+
+echo -n "checking for llvm-config... "
+
+if test -z "$LLVMCONFIG"; then
+  LLVMCONFIG=`which llvm-config`
+fi
+
+if test -z "$LLVMCONFIG"; then
+  LLVMCONFIG=`dirname $CXX`/llvm-config
+fi
+
+if test ! -x "$LLVMCONFIG"; then
+  echo "configure: error: Cannot find an llvm-config binary for building a clang plugin" 1>&2
+  exit 1
+fi
+
+echo "$LLVMCONFIG"
+
+LLVMCXXFLAGS=`$LLVMCONFIG --cxxflags`
+LLVMLDFLAGS=`$LLVMCONFIG --ldflags`
+CXXFLAGS="$CXXFLAGS $LLVMCXXFLAGS -fno-rtti -fno-exceptions"
+LDFLAGS="$LDFLAGS $LLVMLDFLAGS"
+
+cat $srcdir/Makefile.in | sed \
+  -e "s%@CXX@%$CXX%" \
+  -e "s%@CXXFLAGS@%$CXXFLAGS%" \
+  -e "s%@LDFLAGS@%$LDFLAGS%" \
+  -e "s%@srcdir@%$srcdir%" \
+  > Makefile
new file mode 100644
--- /dev/null
+++ b/build/clang-plugin/tests/TestMustOverride.cpp
@@ -0,0 +1,63 @@
+#define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override")))
+// Ignore warnings not related to static analysis here
+#pragma GCC diagnostic ignored "-Woverloaded-virtual"
+
+struct S {
+  virtual void f() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}}
+  virtual void g() MOZ_MUST_OVERRIDE;
+  virtual void h() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}}
+};
+struct C : S { // expected-error {{'C' must override 'f'}} expected-error {{'C' must override 'h'}}
+  virtual void g() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}}
+  virtual void h(int);
+  void q() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}}
+};
+struct D : C { // expected-error {{'D' must override 'g'}} expected-error {{'D' must override 'q'}}
+  virtual void f();
+};
+
+struct Base {
+  virtual void VirtMethod() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}}
+  void NonVirtMethod() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}}
+  static void StaticMethod() MOZ_MUST_OVERRIDE;
+};
+
+struct DoesNotPropagate : Base {
+  virtual void VirtMethod();
+  void NonVirtMethod();
+  static void StaticMethod();
+};
+
+struct Final : DoesNotPropagate { };
+
+struct Propagates : Base {
+  virtual void VirtMethod() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}}
+  void NonVirtMethod() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}}
+  static void StaticMethod() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}}
+};
+
+struct FailsFinal : Propagates { }; // expected-error {{'FailsFinal' must override 'VirtMethod'}} expected-error {{'FailsFinal' must override 'NonVirtMethod'}} expected-error {{'FailsFinal' must override 'StaticMethod'}}
+
+struct WrongOverload : Base { // expected-error {{'WrongOverload' must override 'VirtMethod'}} expected-error {{'WrongOverload' must override 'NonVirtMethod'}}
+  virtual void VirtMethod() const;
+  void NonVirtMethod(int param);
+  static void StaticMethod();
+};
+
+namespace A { namespace B { namespace C {
+  struct Param {};
+  struct Base {
+    void f(Param p) MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}}
+  };
+}}}
+
+struct Param {};
+
+struct Derived : A::B::C::Base {
+  typedef A::B::C::Param Typedef;
+  void f(Typedef t);
+};
+
+struct BadDerived : A::B::C::Base { // expected-error {{'BadDerived' must override 'f'}}
+  void f(Param p);
+};
--- a/build/mach_bootstrap.py
+++ b/build/mach_bootstrap.py
@@ -8,20 +8,21 @@ import os
 import platform
 import sys
 
 # TODO Bug 794506 Integrate with the in-tree virtualenv configuration.
 SEARCH_PATHS = [
     'python/mach',
     'python/mozboot',
     'python/mozbuild',
-    'build/pymake',
     'python/blessings',
     'python/psutil',
     'python/which',
+    'build/pymake',
+    'config',
     'other-licenses/ply',
     'xpcom/idl-parser',
     'testing',
     'testing/xpcshell',
     'testing/mozbase/mozprocess',
     'testing/mozbase/mozfile',
     'testing/mozbase/mozinfo',
 ]
old mode 100755
new mode 100644
--- a/caps/idl/Makefile.in
+++ b/caps/idl/Makefile.in
@@ -5,12 +5,11 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-GRE_MODULE	= 1
 
 include $(topsrcdir)/config/rules.mk
 
--- a/config/static-checking-config.mk
+++ b/config/static-checking-config.mk
@@ -31,8 +31,14 @@ DEHYDRA_ARGS = \
   $(DEHYDRA_ARG_PREFIX)treehydra-modules=$(subst $(NULL) ,$(COMMA),$(strip $(TREEHYDRA_MODULES))) \
   $(NULL)
 
 DEHYDRA_FLAGS = -fplugin=$(DEHYDRA_PATH) $(DEHYDRA_ARGS)
 
 ifdef DEHYDRA_PATH
 OS_CXXFLAGS += $(DEHYDRA_FLAGS)
 endif
+
+ifdef ENABLE_CLANG_PLUGIN
+CLANG_PLUGIN := $(DEPTH)/build/clang-plugin/$(DLL_PREFIX)clang-plugin$(DLL_SUFFIX)
+OS_CXXFLAGS += -Xclang -load -Xclang $(CLANG_PLUGIN) -Xclang -add-plugin -Xclang moz-check
+OS_CFLAGS += -Xclang -load -Xclang $(CLANG_PLUGIN) -Xclang -add-plugin -Xclang moz-check
+endif
--- a/configure.in
+++ b/configure.in
@@ -2227,17 +2227,19 @@ ia64*-hpux*)
 
     dnl set NO_X11 defines here as the general check is skipped on win32
     no_x=yes
     AC_DEFINE(NO_X11)
 
     case "$host" in
     *-mingw*)
         MOZ_BUILD_ROOT=`cd $MOZ_BUILD_ROOT && pwd -W`
-        L10NBASEDIR=`cd $L10NBASEDIR && pwd -W`
+        if test -n "$L10NBASEDIR"; then
+            L10NBASEDIR=`cd $L10NBASEDIR && pwd -W`
+        fi
         ;;
     esac
 
     case "$host" in
     *-mingw*)
         if test -z "$MOZ_TOOLS"; then
             AC_MSG_ERROR([MOZ_TOOLS is not set])
         fi
@@ -4274,16 +4276,17 @@ NSS_DISABLE_DBM=
 NECKO_WIFI=1
 NECKO_COOKIES=1
 NECKO_PROTOCOLS_DEFAULT="about data file ftp http res viewsource websocket wyciwyg device"
 USE_ARM_KUSER=
 BUILD_CTYPES=1
 MOZ_USE_NATIVE_POPUP_WINDOWS=
 MOZ_ANDROID_HISTORY=
 MOZ_WEBSMS_BACKEND=
+MOZ_ANDROID_WALLPAPER=
 ACCESSIBILITY=1
 MOZ_SYS_MSG=
 MOZ_TIME_MANAGER=
 MOZ_PAY=
 MOZ_AUDIO_CHANNEL_MANAGER=
 
 case "$target_os" in
     mingw*)
@@ -4388,17 +4391,17 @@ fi
 if test -f "${srcdir}/${MOZ_BUILD_APP}/configure.in" ; then
   do_output_subdirs() {
     if test -n "$_subconfigure_subdirs"; then
       AC_MSG_ERROR([Cannot specify more than one sub-sub-configure])
      fi
     _subconfigure_subdir="$1"
     _subconfigure_config_args="$ac_configure_args"
   }
-  tmpscript=`mktemp -t subscript.XXXXXX` || exit 1
+  tmpscript=`python -c 'import os, tempfile; print tempfile.mktemp(prefix="subscript.").replace(os.sep, "/")'` || exit 1
   m4 "${srcdir}/build/autoconf/subconfigure.m4" \
      "${srcdir}/build/autoconf/altoptions.m4" \
      "${srcdir}/${MOZ_BUILD_APP}/configure.in" > $tmpscript
   . $tmpscript
   rm -f $tmpscript
 fi
 
 # Allow someone to change MOZ_APP_NAME and MOZ_APP_BASENAME in mozconfig
@@ -5146,16 +5149,23 @@ MOZ_ARG_DISABLE_BOOL(websms-backend,
     MOZ_WEBSMS_BACKEND=,
     MOZ_WEBSMS_BACKEND=1)
 
 if test -n "$MOZ_WEBSMS_BACKEND"; then
     AC_DEFINE(MOZ_WEBSMS_BACKEND)
 fi
 
 dnl ========================================================
+dnl = Enable SET_WALLPAPER permission on Android
+dnl ========================================================
+if test -n "$MOZ_ANDROID_WALLPAPER"; then
+    AC_DEFINE(MOZ_ANDROID_WALLPAPER)
+fi
+
+dnl ========================================================
 dnl = Build Personal Security Manager
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(crypto,
 [  --disable-crypto        Disable crypto support (Personal Security Manager)],
     MOZ_PSM=,
     MOZ_PSM=1 )
 
 dnl ========================================================
@@ -7407,33 +7417,16 @@ JSGC_INCREMENTAL=1
 MOZ_ARG_DISABLE_BOOL(gcincremental,
 [  --disable-gcincremental Disable incremental GC],
     JSGC_INCREMENTAL= )
 if test -n "$JSGC_INCREMENTAL"; then
     AC_DEFINE(JSGC_INCREMENTAL)
 fi
 
 dnl ========================================================
-dnl ETW - Event Tracing for Windows
-dnl ========================================================
-MOZ_ARG_ENABLE_BOOL(ETW,
-[  --enable-ETW            Enable ETW (Event Tracing for Windows) event reporting],
-    MOZ_ETW=1,
-    MOZ_ETW= )
-if test -n "$MOZ_ETW"; then
-    AC_DEFINE(MOZ_ETW)
-fi
-
-if test -n "$MOZ_ETW"; then
-    if test -z "$MOZ_WINSDK_TARGETVER"; then
-        AC_MSG_ERROR([--enable-ETW is only valid on Windows])
-    fi
-fi
-
-dnl ========================================================
 dnl Zealous JavaScript GC
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(gczeal,
 [  --enable-gczeal         Enable zealous JavaScript GCing],
     JS_GC_ZEAL=1,
     JS_GC_ZEAL= )
 if test -n "$JS_GC_ZEAL"; then
     AC_DEFINE(JS_GC_ZEAL)
@@ -7467,16 +7460,33 @@ if test -n "$DEHYDRA_PATH"; then
     if test ! -f "$DEHYDRA_PATH"; then
         AC_MSG_ERROR([The dehydra plugin is not at the specified path.])
     fi
     AC_DEFINE(NS_STATIC_CHECKING)
 fi
 AC_SUBST(DEHYDRA_PATH)
 
 dnl ========================================================
+dnl = Enable using the clang plugin to build
+dnl ========================================================
+
+MOZ_ARG_ENABLE_BOOL(clang-plugin,
+[  --enable-clang-plugin   Enable building with the mozilla clang plugin ],
+   ENABLE_CLANG_PLUGIN=1,
+   ENABLE_CLANG_PLUGIN= )
+if test -n "$ENABLE_CLANG_PLUGIN"; then
+    if test -z "$CLANG_CC"; then
+        AC_MSG_ERROR([Can't use clang plugin without clang.])
+    fi
+    AC_DEFINE(MOZ_CLANG_PLUGIN)
+fi
+
+AC_SUBST(ENABLE_CLANG_PLUGIN)
+
+dnl ========================================================
 dnl = Enable stripping of libs & executables
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(strip,
 [  --enable-strip          Enable stripping of libs & executables ],
     ENABLE_STRIP=1,
     ENABLE_STRIP= )
 
 dnl ========================================================
@@ -8326,16 +8336,22 @@ if test "$MOZ_ENABLE_SKIA"; then
   AC_DEFINE(MOZ_ENABLE_SKIA)
   AC_DEFINE(USE_SKIA)
   if test "${MOZ_WIDGET_TOOLKIT}" = "android" -o x"$MOZ_WIDGET_TOOLKIT" = x"gonk"; then
     AC_DEFINE(SK_BUILD_FOR_ANDROID_NDK)
   elif test "$OS_ARCH" = "WINNT"; then
     AC_DEFINE(SKIA_DLL)
     AC_DEFINE(GR_DLL)
   fi
+
+  if test "${CPU_ARCH}" != "ppc" -a "${CPU_ARCH}" != "ppc64"; then
+    MOZ_ENABLE_SKIA_GPU=1
+    AC_DEFINE(USE_SKIA_GPU)
+    AC_SUBST(MOZ_ENABLE_SKIA_GPU)
+  fi
 else
   MOZ_SKIA_LIBS=
 fi
 AC_SUBST(MOZ_ENABLE_SKIA)
 AC_SUBST(MOZ_SKIA_LIBS)
 
 dnl ========================================================
 dnl disable xul
@@ -8550,17 +8566,16 @@ AC_SUBST(WARNINGS_AS_ERRORS)
 AC_SUBST(MOZ_EXTENSIONS)
 AC_SUBST(MOZ_JSDEBUGGER)
 AC_SUBST(MOZ_ENABLE_PROFILER_SPS)
 AC_SUBST(MOZ_JPROF)
 AC_SUBST(MOZ_SHARK)
 AC_SUBST(MOZ_INSTRUMENTS)
 AC_SUBST(MOZ_CALLGRIND)
 AC_SUBST(MOZ_VTUNE)
-AC_SUBST(MOZ_ETW)
 AC_SUBST(MOZ_PROFILING)
 AC_SUBST(LIBICONV)
 AC_SUBST(MOZ_PLACES)
 AC_SUBST(MOZ_TOOLKIT_SEARCH)
 AC_SUBST(MOZ_FEEDS)
 AC_SUBST(NS_PRINTING)
 AC_SUBST(MOZ_WEBGL)
 AC_SUBST(MOZ_HELP_VIEWER)
@@ -8594,16 +8609,17 @@ AC_SUBST(MOZ_DIRECTX_SDK_PATH)
 AC_SUBST(MOZ_DIRECTX_SDK_CPU_SUFFIX)
 AC_SUBST(MOZ_D3DX9_VERSION)
 AC_SUBST(MOZ_D3DCOMPILER_CAB)
 AC_SUBST(MOZ_D3DCOMPILER_DLL)
 AC_SUBST(MOZ_METRO)
 
 AC_SUBST(MOZ_ANDROID_HISTORY)
 AC_SUBST(MOZ_WEBSMS_BACKEND)
+AC_SUBST(MOZ_ANDROID_WALLPAPER)
 AC_SUBST(ENABLE_STRIP)
 AC_SUBST(PKG_SKIP_STRIP)
 AC_SUBST(STRIP_FLAGS)
 AC_SUBST(USE_ELF_DYNSTR_GC)
 AC_SUBST(USE_ELF_HACK)
 AC_SUBST(INCREMENTAL_LINKER)
 AC_SUBST(MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS)
 AC_SUBST(MOZ_COMPONENT_NSPR_LIBS)
@@ -9384,16 +9400,22 @@ CFLAGS="$_SUBDIR_CFLAGS"
 CPPFLAGS="$_SUBDIR_CPPFLAGS"
 CXXFLAGS="$_SUBDIR_CXXFLAGS"
 LDFLAGS="$_SUBDIR_LDFLAGS"
 HOST_CC="$_SUBDIR_HOST_CC"
 HOST_CFLAGS="$_SUBDIR_HOST_CFLAGS"
 HOST_LDFLAGS="$_SUBDIR_HOST_LDFLAGS"
 RC=
 
+if test -n "$ENABLE_CLANG_PLUGIN"; then
+    ac_configure_args="$_SUBDIR_CONFIG_ARGS"
+    AC_OUTPUT_SUBDIRS(build/clang-plugin)
+fi
+
+
 # Run the SpiderMonkey 'configure' script.
 dist=$MOZ_BUILD_ROOT/dist
 ac_configure_args="$_SUBDIR_CONFIG_ARGS"
 ac_configure_args="$ac_configure_args --enable-threadsafe"
 if test "$BUILD_CTYPES"; then
     # Build js-ctypes on the platforms we can.
     ac_configure_args="$ac_configure_args --enable-ctypes"
 fi
--- a/content/base/public/Makefile.in
+++ b/content/base/public/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-GRE_MODULE	= 1
 
 EXPORTS		= \
 mozFlushType.h \
 nsIContent.h \
 nsIAttribute.h \
 nsIContentIterator.h \
 nsContentPolicyUtils.h \
 nsContentUtils.h \
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -329,16 +329,22 @@ public:
    *
    * We define whitespace using the list in HTML5 and css3-selectors:
    * U+0009, U+000A, U+000C, U+000D, U+0020
    *
    * HTML 4.01 also lists U+200B (zero-width space).
    */
   static bool IsHTMLWhitespace(PRUnichar aChar);
 
+  /*
+   * Returns whether the character is an HTML whitespace (see IsHTMLWhitespace)
+   * or a nbsp character (U+00A0).
+   */
+  static bool IsHTMLWhitespaceOrNBSP(PRUnichar aChar);
+
   /**
    * Is the HTML local name a block element?
    */
   static bool IsHTMLBlock(nsIAtom* aLocalName);
 
   /**
    * Is the HTML local name a void element?
    */
@@ -1872,16 +1878,22 @@ public:
    * Returns the document that is the closest ancestor to aDoc that is
    * fullscreen. If aDoc is fullscreen this returns aDoc. If aDoc is not
    * fullscreen and none of aDoc's ancestors are fullscreen this returns
    * nullptr.
    */
   static nsIDocument* GetFullscreenAncestor(nsIDocument* aDoc);
 
   /**
+   * Returns true if aWin and the current pointer lock document
+   * have common scriptable top window.
+   */
+  static bool IsInPointerLockContext(nsIDOMWindow* aWin);
+
+  /**
    * Returns the time limit on handling user input before
    * nsEventStateManager::IsHandlingUserInput() stops returning true.
    * This enables us to detect long running user-generated event handlers.
    */
   static TimeDuration HandlingUserInputTimeout();
 
   static void GetShiftText(nsAString& text);
   static void GetControlText(nsAString& text);
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -964,17 +964,17 @@ public:
    *
    * Note if aDocument is not fullscreen this function has no effect, even if
    * aDocument has fullscreen ancestors.
    */
   static void ExitFullscreen(nsIDocument* aDocument, bool aRunAsync);
 
   virtual void RequestPointerLock(Element* aElement) = 0;
 
-  static void UnlockPointer();
+  static void UnlockPointer(nsIDocument* aDoc = nullptr);
 
 
   //----------------------------------------------------------------------
 
   // Document notification API's
 
   /**
    * Add a new observer of document change notifications. Whenever
@@ -2016,17 +2016,17 @@ public:
   bool MozFullScreen()
   {
     return IsFullScreenDoc();
   }
   void MozCancelFullScreen();
   Element* GetMozPointerLockElement();
   void MozExitPointerLock()
   {
-    UnlockPointer();
+    UnlockPointer(this);
   }
   bool Hidden() const
   {
     return mVisibilityState != mozilla::dom::VisibilityStateValues::Visible;
   }
   bool MozHidden() // Not const because of WarnOnceAbout
   {
     WarnOnceAbout(ePrefixedVisibilityAPI);
--- a/content/base/public/nsIFrameLoader.idl
+++ b/content/base/public/nsIFrameLoader.idl
@@ -1,15 +1,16 @@
 /* -*- 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/. */
 
 #include "nsISupports.idl"
 
+interface nsFrameLoader;
 interface nsIDocShell;
 interface nsIURI;
 interface nsIFrame;
 interface nsSubDocumentFrame;
 interface nsIMessageSender;
 interface nsIVariant;
 interface nsIDOMElement;
 
--- a/content/base/public/nsIObjectLoadingContent.idl
+++ b/content/base/public/nsIObjectLoadingContent.idl
@@ -20,17 +20,17 @@ interface nsIURI;
 
 /**
  * This interface represents a content node that loads objects.
  *
  * Please make sure to update the MozObjectLoadingContent WebIDL
  * interface to mirror this interface when changing it.
  */
 
-[scriptable, uuid(b6c5ae8a-5e30-41f1-975a-be73cd6f71db)]
+[scriptable, uuid(e2ef99fe-f7d3-422f-a7b4-834e8bdde710)]
 interface nsIObjectLoadingContent : nsISupports
 {
   /**
    * See notes in nsObjectLoadingContent.h
    */
   const unsigned long TYPE_LOADING  = 0;
   const unsigned long TYPE_IMAGE    = 1;
   const unsigned long TYPE_PLUGIN   = 2;
--- a/content/base/public/nsTreeSanitizer.h
+++ b/content/base/public/nsTreeSanitizer.h
@@ -1,20 +1,21 @@
 /* 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 nsTreeSanitizer_h_
 #define nsTreeSanitizer_h_
 
-#include "nsIContent.h"
 #include "mozilla/css/StyleRule.h"
 #include "nsIPrincipal.h"
 #include "mozilla/dom/Element.h"
 
+class nsIContent;
+
 /**
  * See the documentation of nsIParserUtils::sanitize for documentation
  * about the default behavior and the configuration options of this sanitizer.
  */
 class NS_STACK_CLASS nsTreeSanitizer {
 
   public:
 
--- a/content/base/src/DirectionalityUtils.cpp
+++ b/content/base/src/DirectionalityUtils.cpp
@@ -492,18 +492,21 @@ private:
 
   static PLDHashOperator ResetNodeDirection(nsPtrHashKey<Element>* aEntry, void* aData)
   {
     MOZ_ASSERT(aEntry->GetKey()->IsElement(), "Must be an Element");
     // run the downward propagation algorithm
     // and remove the text node from the map
     nsINode* oldTextNode = static_cast<Element*>(aData);
     Element* rootNode = aEntry->GetKey();
-    nsINode* newTextNode = WalkDescendantsSetDirectionFromText(rootNode, true,
-                                                               oldTextNode);
+    nsINode* newTextNode = nullptr;
+    if (rootNode->HasDirAuto()) {
+      newTextNode = WalkDescendantsSetDirectionFromText(rootNode, true,
+                                                        oldTextNode);
+    }
     if (newTextNode) {
       nsTextNodeDirectionalityMap::AddEntryToMap(newTextNode, rootNode);
     } else {
       rootNode->ClearHasDirAutoSet();
       rootNode->UnsetProperty(nsGkAtoms::dirAutoSetBy);
     }
     return PL_DHASH_REMOVE;
   }
@@ -655,18 +658,23 @@ WalkDescendantsResetAutoDirection(Elemen
     }
     child = child->GetNextNode(aElement);
   }
 }
 
 void
 WalkDescendantsSetDirAuto(Element* aElement, bool aNotify)
 {
-  if (!DoesNotParticipateInAutoDirection(aElement) &&
-      !IsBdiWithoutDirAuto(aElement)) {
+  // Only test for DoesNotParticipateInAutoDirection -- in other words, if
+  // aElement is a <bdi> which is having its dir attribute set to auto (or
+  // removed or set to an invalid value, which are equivalent to dir=auto for
+  // <bdi>, we *do* want to set AncestorHasDirAuto on its descendants, unlike
+  // in SetDirOnBind where we don't propagate AncestorHasDirAuto to a <bdi>
+  // being bound to an existing node with dir=auto.
+  if (!DoesNotParticipateInAutoDirection(aElement)) {
 
     bool setAncestorDirAutoFlag =
 #ifdef DEBUG
       true;
 #else
       !aElement->AncestorHasDirAuto();
 #endif
 
@@ -677,17 +685,17 @@ WalkDescendantsSetDirAuto(Element* aElem
             DoesNotAffectDirectionOfAncestors(child->AsElement())) {
           child = child->GetNextNonChildNode(aElement);
           continue;
         }
 
         MOZ_ASSERT(!aElement->AncestorHasDirAuto() ||
                    child->AncestorHasDirAuto(),
                    "AncestorHasDirAuto set on node but not its children");
-        child->SetHasDirAuto();
+        child->SetAncestorHasDirAuto();
         child = child->GetNextNode(aElement);
       }
     }
   }
 
   nsINode* textNode = WalkDescendantsSetDirectionFromText(aElement, aNotify);
   if (textNode) {
     nsTextNodeDirectionalityMap::AddEntryToMap(textNode, aElement);
--- a/content/base/src/nsCCUncollectableMarker.cpp
+++ b/content/base/src/nsCCUncollectableMarker.cpp
@@ -429,18 +429,31 @@ TraceActiveWindowGlobal(const uint64_t& 
       xulDoc->TraceProtos(closure->mTrc, closure->mGCNumber);
     }
 #endif
   }
   return PL_DHASH_NEXT;
 }
 
 void
-mozilla::dom::TraceBlackJS(JSTracer* aTrc, uint32_t aGCNumber)
+mozilla::dom::TraceBlackJS(JSTracer* aTrc, uint32_t aGCNumber, bool aIsShutdownGC)
 {
+#ifdef MOZ_XUL
+  // Mark the scripts held in the XULPrototypeCache. This is required to keep
+  // the JS script in the cache live across GC.
+  nsXULPrototypeCache* cache = nsXULPrototypeCache::MaybeGetInstance();
+  if (cache) {
+    if (aIsShutdownGC) {
+      cache->FlushScripts();
+    } else {
+      cache->MarkInGC(aTrc);
+    }
+  }
+#endif
+
   if (!nsCCUncollectableMarker::sGeneration) {
     return;
   }
 
   TraceClosure closure(aTrc, aGCNumber);
 
   // Mark globals of active windows black.
   nsGlobalWindow::WindowByIdTable* windowsById =
--- a/content/base/src/nsCCUncollectableMarker.h
+++ b/content/base/src/nsCCUncollectableMarker.h
@@ -40,13 +40,13 @@ class nsCCUncollectableMarker MOZ_FINAL 
 
 private:
   nsCCUncollectableMarker() {}
 
 };
 
 namespace mozilla {
 namespace dom {
-void TraceBlackJS(JSTracer* aTrc, uint32_t aGCNumber);
+void TraceBlackJS(JSTracer* aTrc, uint32_t aGCNumber, bool aIsShutdownGC);
 }
 }
 
 #endif
--- a/content/base/src/nsContentIterator.cpp
+++ b/content/base/src/nsContentIterator.cpp
@@ -987,19 +987,17 @@ nsContentIterator::PositionAt(nsINode* a
 
   // Get a list of the parents up to the root, then compare the new node with
   // entries in that array until we find a match (lowest common ancestor).  If
   // no match, use IndexOf, take the parent, and repeat.  This avoids using
   // IndexOf() N times on possibly large arrays.  We still end up doing it a
   // fair bit.  It's better to use Clone() if possible.
 
   // we know the depth we're down (though we may not have started at the top).
-  if (!oldParentStack.SetCapacity(mIndexes.Length() + 1)) {
-    return NS_ERROR_FAILURE;
-  }
+  oldParentStack.SetCapacity(mIndexes.Length() + 1);
 
   // We want to loop mIndexes.Length() + 1 times here, because we want to make
   // sure we include mCommonParent in the oldParentStack, for use in the next
   // for loop, and mIndexes only has entries for nodes from tempNode up through
   // an ancestor of tempNode that's a child of mCommonParent.
   for (int32_t i = mIndexes.Length() + 1; i > 0 && tempNode; i--) {
     // Insert at head since we're walking up
     oldParentStack.InsertElementAt(0, tempNode);
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -1196,16 +1196,23 @@ nsContentUtils::IsHTMLWhitespace(PRUnich
          aChar == PRUnichar(0x000A) ||
          aChar == PRUnichar(0x000C) ||
          aChar == PRUnichar(0x000D) ||
          aChar == PRUnichar(0x0020);
 }
 
 /* static */
 bool
+nsContentUtils::IsHTMLWhitespaceOrNBSP(PRUnichar aChar)
+{
+  return IsHTMLWhitespace(aChar) || aChar == PRUnichar(0xA0);
+}
+
+/* static */
+bool
 nsContentUtils::IsHTMLBlock(nsIAtom* aLocalName)
 {
   return
     (aLocalName == nsGkAtoms::address) ||
     (aLocalName == nsGkAtoms::article) ||
     (aLocalName == nsGkAtoms::aside) ||
     (aLocalName == nsGkAtoms::blockquote) ||
     (aLocalName == nsGkAtoms::center) ||
@@ -1763,18 +1770,19 @@ bool
 nsContentUtils::IsCallerXBL()
 {
     JSScript *script;
     JSContext *cx = GetCurrentJSContext();
     if (!cx)
         return false;
 
     // New Hotness.
-    if (XPCJSRuntime::Get()->XBLScopesEnabled())
-        return xpc::IsXBLScope(js::GetContextCompartment(cx));
+    JSCompartment *c = js::GetContextCompartment(cx);
+    if (xpc::AllowXBLScope(c))
+        return xpc::IsXBLScope(c);
 
     // XBL scopes are behind a pref, so check the XBL bit as well.
     if (!JS_DescribeScriptedCaller(cx, &script, nullptr) || !script)
         return false;
     return JS_GetScriptUserBit(script);
 }
 
 
@@ -2153,16 +2161,19 @@ nsContentUtils::TrimWhitespace(const nsA
 // inlining the method. Considering there is not so much spaces checking
 // methods we can consider this to be better than inlining.
 template
 const nsDependentSubstring
 nsContentUtils::TrimWhitespace<nsCRT::IsAsciiSpace>(const nsAString&, bool);
 template
 const nsDependentSubstring
 nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(const nsAString&, bool);
+template
+const nsDependentSubstring
+nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespaceOrNBSP>(const nsAString&, bool);
 
 static inline void KeyAppendSep(nsACString& aKey)
 {
   if (!aKey.IsEmpty()) {
     aKey.Append('>');
   }
 }
 
@@ -6636,16 +6647,39 @@ nsContentUtils::GetFullscreenAncestor(ns
     if (doc->IsFullScreenDoc()) {
       return doc;
     }
     doc = doc->GetParentDocument();
   }
   return nullptr;
 }
 
+/* static */
+bool
+nsContentUtils::IsInPointerLockContext(nsIDOMWindow* aWin)
+{
+  if (!aWin) {
+    return false;
+  }
+
+  nsCOMPtr<nsIDocument> pointerLockedDoc =
+    do_QueryReferent(nsEventStateManager::sPointerLockedDoc);
+  if (!pointerLockedDoc || !pointerLockedDoc->GetWindow()) {
+    return false;
+  }
+
+  nsCOMPtr<nsIDOMWindow> lockTop;
+  pointerLockedDoc->GetWindow()->GetScriptableTop(getter_AddRefs(lockTop));
+
+  nsCOMPtr<nsIDOMWindow> top;
+  aWin->GetScriptableTop(getter_AddRefs(top));
+
+  return top == lockTop;
+}
+
 // static
 void
 nsContentUtils::ReleaseWrapper(void* aScriptObjectHolder,
                                nsWrapperCache* aCache)
 {
   if (aCache->PreservingWrapper()) {
     // PreserveWrapper puts new DOM bindings in the JS holders hash, but they
     // can also be in the DOM expando hash, so we need to try to remove them
--- a/content/base/src/nsDOMParser.h
+++ b/content/base/src/nsDOMParser.h
@@ -1,25 +1,27 @@
 /* -*- 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/. */
 
 #ifndef nsDOMParser_h_
 #define nsDOMParser_h_
 
+#include "nsCOMPtr.h"
+#include "nsIDocument.h"
 #include "nsIDOMParser.h"
-#include "nsCOMPtr.h"
 #include "nsWeakReference.h"
-#include "nsIDocument.h"
 #include "nsWrapperCache.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/DOMParserBinding.h"
 #include "mozilla/dom/TypedArray.h"
 
+class nsIDocument;
+
 class nsDOMParser MOZ_FINAL : public nsIDOMParser,
                               public nsSupportsWeakReference,
                               public nsWrapperCache
 {
 public: 
   nsDOMParser();
   virtual ~nsDOMParser();
 
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -193,16 +193,18 @@
 #include "mozilla/dom/HTMLBodyElement.h"
 #include "mozilla/dom/NodeFilterBinding.h"
 #include "mozilla/dom/UndoManager.h"
 #include "nsFrame.h"
 #include "nsDOMCaretPosition.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsViewportInfo.h"
 #include "nsDOMEvent.h"
+#include "nsIContentPermissionPrompt.h"
+#include "mozilla/StaticPtr.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 typedef nsTArray<Link*> LinkArray;
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gDocumentLeakPRLog;
@@ -8037,16 +8039,18 @@ nsDocument::OnPageHide(bool aPersisted,
   if (mAnimationController) {
     mAnimationController->OnPageHide();
   }
 
   if (aPersisted) {
     SetImagesNeedAnimating(false);
   }
 
+  MozExitPointerLock();
+
   // Now send out a PageHide event.
   nsCOMPtr<nsIDOMEventTarget> target = aDispatchStartTarget;
   if (!target) {
     target = do_QueryInterface(GetWindow());
   }
   DispatchPageTransition(target, NS_LITERAL_STRING("pagehide"), aPersisted);
 
   mVisible = false;
@@ -9853,32 +9857,39 @@ nsDocument::IsFullScreenDoc()
 }
 
 class nsCallRequestFullScreen : public nsRunnable
 {
 public:
   nsCallRequestFullScreen(Element* aElement)
     : mElement(aElement),
       mDoc(aElement->OwnerDoc()),
-      mWasCallerChrome(nsContentUtils::IsCallerChrome())
+      mWasCallerChrome(nsContentUtils::IsCallerChrome()),
+      mHadRequestPending(static_cast<nsDocument*>(mDoc.get())->
+                           mAsyncFullscreenPending)
   {
+    static_cast<nsDocument*>(mDoc.get())->
+      mAsyncFullscreenPending = true;
   }
 
   NS_IMETHOD Run()
   {
+    static_cast<nsDocument*>(mDoc.get())->
+      mAsyncFullscreenPending = mHadRequestPending;
     nsDocument* doc = static_cast<nsDocument*>(mDoc.get());
     doc->RequestFullScreen(mElement,
                            mWasCallerChrome,
                            /* aNotifyOnOriginChange */ true);
     return NS_OK;
   }
 
   nsRefPtr<Element> mElement;
   nsCOMPtr<nsIDocument> mDoc;
   bool mWasCallerChrome;
+  bool mHadRequestPending;
 };
 
 void
 nsDocument::AsyncRequestFullScreen(Element* aElement)
 {
   NS_ASSERTION(aElement,
     "Must pass non-null element to nsDocument::AsyncRequestFullScreen");
   if (!aElement) {
@@ -10408,147 +10419,219 @@ nsDocument::IsFullScreenEnabled(bool aCa
   }
 
   return allowed;
 }
 
 static void
 DispatchPointerLockChange(nsIDocument* aTarget)
 {
+  if (!aTarget) {
+    return;
+  }
+
   nsRefPtr<nsAsyncDOMEvent> e =
     new nsAsyncDOMEvent(aTarget,
                         NS_LITERAL_STRING("mozpointerlockchange"),
                         true,
                         false);
   e->PostDOMEvent();
 }
 
 static void
 DispatchPointerLockError(nsIDocument* aTarget)
 {
+  if (!aTarget) {
+    return;
+  }
+
   nsRefPtr<nsAsyncDOMEvent> e =
     new nsAsyncDOMEvent(aTarget,
                         NS_LITERAL_STRING("mozpointerlockerror"),
                         true,
                         false);
   e->PostDOMEvent();
 }
 
-// Manages asynchronously requesting pointer lock. Used to dispatch an
-// event to request pointer lock once fullscreen has been approved.
-class nsAsyncPointerLockRequest : public nsRunnable
+mozilla::StaticRefPtr<nsPointerLockPermissionRequest> gPendingPointerLockRequest;
+
+class nsPointerLockPermissionRequest : public nsRunnable,
+                                       public nsIContentPermissionRequest
 {
 public:
+  nsPointerLockPermissionRequest(Element* aElement, bool aUserInputOrChromeCaller)
+  : mElement(do_GetWeakReference(aElement)),
+    mDocument(do_GetWeakReference(aElement->OwnerDoc())),
+    mUserInputOrChromeCaller(aUserInputOrChromeCaller) {}
+
+  virtual ~nsPointerLockPermissionRequest() {}
+
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSICONTENTPERMISSIONREQUEST
+
   NS_IMETHOD Run()
   {
-    sInstance = nullptr;
-    if (mDocument && mElement) {
-      mDocument->RequestPointerLock(mElement);
-    }
+    nsCOMPtr<Element> e = do_QueryReferent(mElement);
+    nsCOMPtr<nsIDocument> d = do_QueryReferent(mDocument);
+    if (!e || !d || gPendingPointerLockRequest != this ||
+        e->GetCurrentDoc() != d) {
+      Handled();
+      DispatchPointerLockError(d);
+      return NS_OK;
+    }
+
+    // We're about to enter fullscreen mode.
+    nsDocument* doc = static_cast<nsDocument*>(d.get());
+    if (doc->mAsyncFullscreenPending ||
+        (doc->mHasFullscreenApprovedObserver && !doc->mIsApprovedForFullscreen)) {
+      // We're still waiting for approval.
+      return NS_OK;
+    }
+
+    if (doc->mIsApprovedForFullscreen || doc->mAllowRelocking) {
+      Allow();
+      return NS_OK;
+    }
+
+    // In non-fullscreen mode user input (or chrome caller) is required!
+    // Also, don't let the page to try to get the permission too many times.
+    if (!mUserInputOrChromeCaller ||
+        doc->mCancelledPointerLockRequests > 2) {
+      Handled();
+      DispatchPointerLockError(d);
+      return NS_OK;
+    }
+
+    // Handling a request from user input in non-fullscreen mode.
+    // Do a normal permission check.
+    nsCOMPtr<nsIContentPermissionPrompt> prompt =
+      do_CreateInstance(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
+    if (prompt) {
+      prompt->Prompt(this);
+    }
+
     return NS_OK;
   }
 
-  static void Request(Element* aElement, nsIDocument* aDocument)
-  {
-    if (sInstance) {
-      // We already have an event instance pending. Change the requestee
-      // to the new pointer lock requestee.
-      sInstance->mElement = aElement;
-      sInstance->mDocument = aDocument;
-    } else {
-      // Create a new event instance. Owning ref is held by the nsIEventTarget
-      // to which this is dispatched.
-      sInstance = new nsAsyncPointerLockRequest(aElement, aDocument);
-      NS_DispatchToCurrentThread(sInstance);
-    }
-  }
-
-  static void Cancel()
-  {
-    if (sInstance) {
-      // Revoke references to requesting element/document, when the
-      // dispatched event runs. The event will do nothing, and then be
-      // destroyed.
-      sInstance->mElement = nullptr;
-      sInstance->mDocument = nullptr;
-    }
-  }
-
-private:
-  nsAsyncPointerLockRequest(Element* aElement, nsIDocument* aDocument)
-    : mElement(aElement),
-      mDocument(aDocument)
+  void Handled()
   {
-    MOZ_COUNT_CTOR(nsAsyncPointerLockRequest);
-  }
-
-  ~nsAsyncPointerLockRequest()
-  {
-    MOZ_COUNT_DTOR(nsAsyncPointerLockRequest);
-  }
-
-  // Reference to the instance of any pending event. This is not an owning
-  // reference; the nsIEventTarget to which this is dispatched holds the only
-  // owning reference to this instance. This reference is valid between
-  // an instance being created, and its Run() method being called.
-  static nsAsyncPointerLockRequest* sInstance;
-
-  // Element and document which reqested pointer lock.
-  nsCOMPtr<Element> mElement;
-  nsCOMPtr<nsIDocument> mDocument;
+    mElement = nullptr;
+    mDocument = nullptr;
+    if (gPendingPointerLockRequest == this) {
+      gPendingPointerLockRequest = nullptr;
+    }
+  }
+
+  nsWeakPtr mElement;
+  nsWeakPtr mDocument;
+  bool mUserInputOrChromeCaller;
 };
 
-nsAsyncPointerLockRequest* nsAsyncPointerLockRequest::sInstance = nullptr;
-nsWeakPtr nsDocument::sPendingPointerLockDoc;
-nsWeakPtr nsDocument::sPendingPointerLockElement;
-
-/* static */
-void
-nsDocument::ClearPendingPointerLockRequest(bool aDispatchErrorEvents)
-{
-  nsAsyncPointerLockRequest::Cancel();
-
-  if (!sPendingPointerLockDoc) {
-    // No pending request.
-    return;
-  }
-  nsCOMPtr<nsIDocument> doc(do_QueryReferent(sPendingPointerLockDoc));
-  if (aDispatchErrorEvents) {
-    DispatchPointerLockError(doc);
-  }
-  nsCOMPtr<Element> element(do_QueryReferent(sPendingPointerLockElement));
-#ifdef DEBUG
+NS_IMPL_ISUPPORTS_INHERITED1(nsPointerLockPermissionRequest,
+                             nsRunnable,
+                             nsIContentPermissionRequest)
+
+NS_IMETHODIMP
+nsPointerLockPermissionRequest::GetType(nsACString& aType)
+{
+  aType = "pointerLock";
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPointerLockPermissionRequest::GetAccess(nsACString& aAccess)
+{
+  aAccess = "unused";
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPointerLockPermissionRequest::GetPrincipal(nsIPrincipal** aPrincipal)
+{
+  nsCOMPtr<nsIDocument> d = do_QueryReferent(mDocument);
+  if (d) {
+    NS_ADDREF(*aPrincipal = d->NodePrincipal());
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPointerLockPermissionRequest::GetWindow(nsIDOMWindow** aWindow)
+{
+  nsCOMPtr<nsIDocument> d = do_QueryReferent(mDocument);
+  if (d) {
+    NS_IF_ADDREF(*aWindow = d->GetInnerWindow());
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPointerLockPermissionRequest::GetElement(nsIDOMElement** aElement)
+{
+  // It is enough to implement GetWindow.
+  *aElement = nullptr;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPointerLockPermissionRequest::Cancel()
+{
+  nsCOMPtr<nsIDocument> d = do_QueryReferent(mDocument);
+  Handled();
+  if (d) {
+    static_cast<nsDocument*>(d.get())->mCancelledPointerLockRequests++;
+    DispatchPointerLockError(d);
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPointerLockPermissionRequest::Allow()
+{
+  nsCOMPtr<Element> e = do_QueryReferent(mElement);
+  nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocument);
+  nsDocument* d = static_cast<nsDocument*>(doc.get());
+  if (!e || !d || gPendingPointerLockRequest != this ||
+      e->GetCurrentDoc() != d ||
+      (!mUserInputOrChromeCaller && !d->mIsApprovedForFullscreen)) {
+    Handled();
+    DispatchPointerLockError(d);
+    return NS_OK;
+  }
+
+  // Mark handled here so that we don't need to call it everywhere below.
+  Handled();
+
   nsCOMPtr<Element> pointerLockedElement =
     do_QueryReferent(nsEventStateManager::sPointerLockedElement);
-  NS_ASSERTION(pointerLockedElement != element,
-    "We shouldn't be clearing pointer locked flag on pointer locked element!");
-#endif
-  if (element) {
-    element->ClearPointerLock();
-  }
-  sPendingPointerLockDoc = nullptr;
-  sPendingPointerLockElement = nullptr;
-}
-
-/* static */
-nsresult
-nsDocument::SetPendingPointerLockRequest(Element* aElement)
-{
-  // If there's an existing pending pointer lock request, deny it.
-  ClearPendingPointerLockRequest(true);
-
-  NS_ENSURE_TRUE(aElement != nullptr, NS_ERROR_FAILURE);
-
-  sPendingPointerLockDoc = do_GetWeakReference(aElement->OwnerDoc());
-  sPendingPointerLockElement = do_GetWeakReference(aElement);
-
-  // Set the pointer lock flag, so that if the element is removed from
-  // its document we know to cancel the pending request.
-  aElement->SetPointerLock();
-
+  if (e == pointerLockedElement) {
+    DispatchPointerLockChange(d);
+    return NS_OK;
+  }
+
+  // Note, we must bypass focus change, so pass true as the last parameter!
+  if (!d->ShouldLockPointer(e, pointerLockedElement, true)) {
+    DispatchPointerLockError(d);
+    return NS_OK;
+  }
+
+  if (!d->SetPointerLock(e, NS_STYLE_CURSOR_NONE)) {
+    DispatchPointerLockError(d);
+    return NS_OK;
+  }
+
+  d->mCancelledPointerLockRequests = 0;
+  e->SetPointerLock();
+  nsEventStateManager::sPointerLockedElement = do_GetWeakReference(e);
+  nsEventStateManager::sPointerLockedDoc = do_GetWeakReference(doc);
+  NS_ASSERTION(nsEventStateManager::sPointerLockedElement &&
+               nsEventStateManager::sPointerLockedDoc,
+               "aElement and this should support weak references!");
+
+  DispatchPointerLockChange(d);
   return NS_OK;
 }
 
 void
 nsDocument::SetApprovedForFullscreen(bool aIsApproved)
 {
   mIsApprovedForFullscreen = aIsApproved;
 }
@@ -10559,23 +10642,33 @@ nsDocument::Observe(nsISupports *aSubjec
                     const PRUnichar *aData)
 {
   if (strcmp("fullscreen-approved", aTopic) == 0) {
     nsCOMPtr<nsIDocument> subject(do_QueryInterface(aSubject));
     if (subject != this) {
       return NS_OK;
     }
     SetApprovedForFullscreen(true);
-    nsCOMPtr<nsIDocument> doc(do_QueryReferent(sPendingPointerLockDoc));
-    if (this == doc) {
-      // This doc has a pointer lock request, waiting for fullscreen to be
-      // approved before it can be granted. Process the pointer lock request.
-      nsCOMPtr<Element> element(do_QueryReferent(sPendingPointerLockElement));
-      nsDocument::ClearPendingPointerLockRequest(false);
-      nsAsyncPointerLockRequest::Request(element, this);
+    if (gPendingPointerLockRequest) {
+      // We have a request pending. Create a clone of it and re-dispatch so that
+      // Run() method gets called again.
+      nsCOMPtr<Element> el =
+        do_QueryReferent(gPendingPointerLockRequest->mElement);
+      nsCOMPtr<nsIDocument> doc =
+        do_QueryReferent(gPendingPointerLockRequest->mDocument);
+      bool userInputOrChromeCaller =
+        gPendingPointerLockRequest->mUserInputOrChromeCaller;
+      gPendingPointerLockRequest->Handled();
+      if (doc == this && el && el->GetCurrentDoc() == doc) {
+        nsPointerLockPermissionRequest* clone =
+          new nsPointerLockPermissionRequest(el, userInputOrChromeCaller);
+        gPendingPointerLockRequest = clone;
+        nsCOMPtr<nsIRunnable> r = gPendingPointerLockRequest.get();
+        NS_DispatchToMainThread(r);
+      }
     }
   }
   return NS_OK;
 }
 
 void
 nsDocument::RequestPointerLock(Element* aElement)
 {
@@ -10584,94 +10677,89 @@ nsDocument::RequestPointerLock(Element* 
 
   nsCOMPtr<Element> pointerLockedElement =
     do_QueryReferent(nsEventStateManager::sPointerLockedElement);
   if (aElement == pointerLockedElement) {
     DispatchPointerLockChange(this);
     return;
   }
 
-  if (!ShouldLockPointer(aElement)) {
+  if (!ShouldLockPointer(aElement, pointerLockedElement)) {
     DispatchPointerLockError(this);
     return;
   }
 
-  if (!mIsApprovedForFullscreen) {
-    // Document isn't yet approved for fullscreen, so we must wait until
-    // it's been approved.
-    if (NS_FAILED(SetPendingPointerLockRequest(aElement))) {
-      NS_WARNING("Failed to make pointer lock request pending!");
-      DispatchPointerLockError(this);
-    }
-    return;
-  }
-
-  // If there's an existing pending pointer lock request, deny it.
-  nsDocument::ClearPendingPointerLockRequest(true);
-
-  if (!SetPointerLock(aElement, NS_STYLE_CURSOR_NONE)) {
-    DispatchPointerLockError(this);
-    return;
-  }
-
-  aElement->SetPointerLock();
-  nsEventStateManager::sPointerLockedElement = do_GetWeakReference(aElement);
-  nsEventStateManager::sPointerLockedDoc =
-    do_GetWeakReference(static_cast<nsIDocument*>(this));
-  NS_ASSERTION(nsEventStateManager::sPointerLockedElement &&
-               nsEventStateManager::sPointerLockedDoc,
-               "aElement and this should support weak references!");
-
-  DispatchPointerLockChange(this);
+  bool userInputOrChromeCaller = nsEventStateManager::IsHandlingUserInput() ||
+                                 nsContentUtils::IsCallerChrome();
+
+  gPendingPointerLockRequest =
+    new nsPointerLockPermissionRequest(aElement, userInputOrChromeCaller);
+  nsCOMPtr<nsIRunnable> r = gPendingPointerLockRequest.get();
+  NS_DispatchToMainThread(r);
 }
 
 bool
-nsDocument::ShouldLockPointer(Element* aElement)
+nsDocument::ShouldLockPointer(Element* aElement, Element* aCurrentLock,
+                              bool aNoFocusCheck)
 {
   // Check if pointer lock pref is enabled
   if (!Preferences::GetBool("full-screen-api.pointer-lock.enabled")) {
     NS_WARNING("ShouldLockPointer(): Pointer Lock pref not enabled");
     return false;
   }
 
-  if (aElement != GetFullScreenElement()) {
-    NS_WARNING("ShouldLockPointer(): Element not in fullscreen");
+  if (aCurrentLock && aCurrentLock->OwnerDoc() != aElement->OwnerDoc()) {
+    NS_WARNING("ShouldLockPointer(): Existing pointer lock element in a different document");
     return false;
   }
 
   if (!aElement->IsInDoc()) {
     NS_WARNING("ShouldLockPointer(): Element without Document");
     return false;
   }
 
   if (mSandboxFlags & SANDBOXED_POINTER_LOCK) {
     NS_WARNING("ShouldLockPointer(): Document is sandboxed and doesn't allow pointer-lock");
     return false;
   }
 
   // Check if the element is in a document with a docshell.
   nsCOMPtr<nsIDocument> ownerDoc = aElement->OwnerDoc();
-  if (!ownerDoc) {
-    return false;
-  }
   if (!nsCOMPtr<nsISupports>(ownerDoc->GetContainer())) {
     return false;
   }
   nsCOMPtr<nsPIDOMWindow> ownerWindow = ownerDoc->GetWindow();
   if (!ownerWindow) {
     return false;
   }
   nsCOMPtr<nsPIDOMWindow> ownerInnerWindow = ownerDoc->GetInnerWindow();
   if (!ownerInnerWindow) {
     return false;
   }
   if (ownerWindow->GetCurrentInnerWindow() != ownerInnerWindow) {
     return false;
   }
 
+  nsCOMPtr<nsIDOMWindow> top;
+  ownerWindow->GetScriptableTop(getter_AddRefs(top));
+  nsCOMPtr<nsPIDOMWindow> piTop = do_QueryInterface(top);
+  if (!piTop || !piTop->GetExtantDoc() ||
+      piTop->GetExtantDoc()->Hidden()) {
+    NS_WARNING("ShouldLockPointer(): Top document isn't visible.");
+    return false;
+  }
+
+  if (!aNoFocusCheck) {
+    mozilla::ErrorResult rv;
+    if (!piTop->GetExtantDoc()->HasFocus(rv)) {
+      NS_WARNING("ShouldLockPointer(): Top document isn't focused.");
+      return false;
+    }
+  }
+
   return true;
 }
 
 bool
 nsDocument::SetPointerLock(Element* aElement, int aCursorStyle)
 {
   // NOTE: aElement will be nullptr when unlocking.
   nsCOMPtr<nsPIDOMWindow> window = GetWindow();
@@ -10723,52 +10811,49 @@ nsDocument::SetPointerLock(Element* aEle
   esm->SetCursor(aCursorStyle, nullptr, false,
                  0.0f, 0.0f, widget, true);
   esm->SetPointerLock(widget, aElement);
 
   return true;
 }
 
 void
-nsDocument::UnlockPointer()
-{
-  // If our pointer lock request is pending awaiting authorization, deny the
-  // request.
-  ClearPendingPointerLockRequest(true);
-
+nsDocument::UnlockPointer(nsIDocument* aDoc)
+{
   if (!nsEventStateManager::sIsPointerLocked) {
     return;
   }
 
   nsCOMPtr<nsIDocument> pointerLockedDoc =
     do_QueryReferent(nsEventStateManager::sPointerLockedDoc);
-  if (!pointerLockedDoc) {
+  if (!pointerLockedDoc || (aDoc && aDoc != pointerLockedDoc)) {
     return;
   }
   nsDocument* doc = static_cast<nsDocument*>(pointerLockedDoc.get());
   if (!doc->SetPointerLock(nullptr, NS_STYLE_CURSOR_AUTO)) {
     return;
   }
 
   nsCOMPtr<Element> pointerLockedElement =
     do_QueryReferent(nsEventStateManager::sPointerLockedElement);
-  if (!pointerLockedElement) {
-    return;
+  if (pointerLockedElement) {
+    pointerLockedElement->ClearPointerLock();
   }
 
   nsEventStateManager::sPointerLockedElement = nullptr;
   nsEventStateManager::sPointerLockedDoc = nullptr;
-  pointerLockedElement->ClearPointerLock();
+  static_cast<nsDocument*>(pointerLockedDoc.get())->mAllowRelocking = !!aDoc;
+  gPendingPointerLockRequest = nullptr;
   DispatchPointerLockChange(pointerLockedDoc);
 }
 
 void
-nsIDocument::UnlockPointer()
-{
-  nsDocument::UnlockPointer();
+nsIDocument::UnlockPointer(nsIDocument* aDoc)
+{
+  nsDocument::UnlockPointer(aDoc);
 }
 
 NS_IMETHODIMP
 nsDocument::MozExitPointerLock()
 {
   nsIDocument::MozExitPointerLock();
   return NS_OK;
 }
@@ -10800,16 +10885,22 @@ nsIDocument::GetMozPointerLockElement()
   nsresult rv = nsContentUtils::CheckSameOrigin(this, pointerLockedElement);
   if (NS_FAILED(rv)) {
     return nullptr;
   }
 
   return pointerLockedElement;
 }
 
+void
+nsDocument::XPCOMShutdown()
+{
+  gPendingPointerLockRequest = nullptr;
+}
+
 #define EVENT(name_, id_, type_, struct_)                                 \
   NS_IMETHODIMP nsDocument::GetOn##name_(JSContext *cx, jsval *vp) {      \
     return nsINode::GetOn##name_(cx, vp);                                 \
   }                                                                       \
   NS_IMETHODIMP nsDocument::SetOn##name_(JSContext *cx, const jsval &v) { \
     return nsINode::SetOn##name_(cx, v);                                  \
   }
 #define TOUCH_EVENT EVENT
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -89,16 +89,17 @@ class nsOnloadBlocker;
 class nsUnblockOnloadEvent;
 class nsChildContentList;
 class nsHTMLStyleSheet;
 class nsHTMLCSSStyleSheet;
 class nsDOMNavigationTiming;
 class nsWindowSizes;
 class nsHtml5TreeOpExecutor;
 class nsDocumentOnStack;
+class nsPointerLockPermissionRequest;
 
 namespace mozilla {
 namespace dom {
 class UndoManager;
 }
 }
 
 /**
@@ -997,19 +998,20 @@ public:
   // Returns the top element from the full-screen stack.
   Element* FullScreenStackTop();
 
   // DOM-exposed fullscreen API
   virtual bool MozFullScreenEnabled();
   virtual Element* GetMozFullScreenElement(mozilla::ErrorResult& rv);
 
   void RequestPointerLock(Element* aElement);
-  bool ShouldLockPointer(Element* aElement);
+  bool ShouldLockPointer(Element* aElement, Element* aCurrentLock,
+                         bool aNoFocusCheck = false);
   bool SetPointerLock(Element* aElement, int aCursorStyle);
-  static void UnlockPointer();
+  static void UnlockPointer(nsIDocument* aDoc = nullptr);
 
   // This method may fire a DOM event; if it does so it will happen
   // synchronously.
   void UpdateVisibilityState();
   // Posts an event to call UpdateVisibilityState
   virtual void PostVisibilityUpdateEvent();
 
   virtual void DocSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const;
@@ -1108,16 +1110,17 @@ protected:
   // nothing if there is no such element.
   void GetTitleFromElement(uint32_t aNodeType, nsAString& aTitle);
 public:
   // Get our title
   virtual void GetTitle(nsString& aTitle);
   // Set our title
   virtual void SetTitle(const nsAString& aTitle, mozilla::ErrorResult& rv);
 
+  static void XPCOMShutdown();
 protected:
   nsresult doCreateShell(nsPresContext* aContext,
                          nsViewManager* aViewManager, nsStyleSet* aStyleSet,
                          nsCompatibility aCompatMode,
                          nsIPresShell** aInstancePtrResult);
 
   void RemoveDocStyleSheetsFromStyleSets();
   void RemoveStyleSheetsFromStyleSets(nsCOMArray<nsIStyleSheet>& aSheets, 
@@ -1178,25 +1181,16 @@ protected:
   // the script global object of the original document.
   nsWeakPtr mScriptObject;
 
   // Weak reference to the scope object (aka the script global object)
   // that, unlike mScriptGlobalObject, is never unset once set. This
   // is a weak reference to avoid leaks due to circular references.
   nsWeakPtr mScopeObject;
 
-  // Weak reference to the document which owned the pending pointer lock
-  // element, at the time it requested pointer lock.
-  static nsWeakPtr sPendingPointerLockDoc;
-
-  // Weak reference to the element which requested pointer lock. This request
-  // is "pending", and will be processed once the element's document has had
-  // the "fullscreen" permission granted.
-  static nsWeakPtr sPendingPointerLockElement;
-
   // Stack of full-screen elements. When we request full-screen we push the
   // full-screen element onto this stack, and when we cancel full-screen we
   // pop one off this stack, restoring the previous full-screen state
   nsTArray<nsWeakPtr> mFullScreenStack;
 
   // The root of the doc tree in which this document is in. This is only
   // non-null when this document is in fullscreen mode.
   nsWeakPtr mFullscreenRoot;
@@ -1274,16 +1268,26 @@ protected:
   // permissions in the permission manager) have been approved for fullscreen.
   bool mIsApprovedForFullscreen:1;
 
   // Whether this document has a fullscreen approved observer. Only documents
   // which request fullscreen and which don't have a pre-existing approval for
   // fullscreen will have an observer.
   bool mHasFullscreenApprovedObserver:1;
 
+  friend class nsPointerLockPermissionRequest;
+  friend class nsCallRequestFullScreen;
+  // When set, trying to lock the pointer doesn't require permission from the
+  // user.
+  bool mAllowRelocking:1;
+
+  bool mAsyncFullscreenPending:1;
+
+  uint32_t mCancelledPointerLockRequests;
+
   uint8_t mXMLDeclarationBits;
 
   nsInterfaceHashtable<nsPtrHashKey<nsIContent>, nsPIBoxObject> *mBoxObjectTable;
 
   // The channel that got passed to StartDocumentLoad(), if any
   nsCOMPtr<nsIChannel> mChannel;
   nsRefPtr<nsHTMLCSSStyleSheet> mStyleAttrStyleSheet;
 
@@ -1306,26 +1310,16 @@ private:
   mozilla::dom::VisibilityState GetVisibilityState() const;
 
   void PostUnblockOnloadEvent();
   void DoUnblockOnload();
 
   nsresult CheckFrameOptions();
   nsresult InitCSP(nsIChannel* aChannel);
 
-  // Sets aElement to be the pending pointer lock element. Once this document's
-  // node principal's URI is granted the "fullscreen" permission, the pointer
-  // lock request will be processed. At any one time there can be only one
-  // pending pointer lock request; calling this clears the previous pending
-  // request.
-  static nsresult SetPendingPointerLockRequest(Element* aElement);
-
-  // Clears any pending pointer lock request.
-  static void ClearPendingPointerLockRequest(bool aDispatchErrorEvents);
-
   /**
    * Find the (non-anonymous) content in this document for aFrame. It will
    * be aFrame's content node if that content is in this document and not
    * anonymous. Otherwise, when aFrame is in a subdocument, we use the frame
    * element containing the subdocument containing aFrame, and/or find the
    * nearest non-anonymous ancestor in this document.
    * Returns null if there is no such element.
    */
--- a/content/base/src/nsHostObjectProtocolHandler.cpp
+++ b/content/base/src/nsHostObjectProtocolHandler.cpp
@@ -185,20 +185,28 @@ nsHostObjectProtocolHandler::NewChannel(
   nsCOMPtr<nsIChannel> channel;
   rv = NS_NewInputStreamChannel(getter_AddRefs(channel),
                                 uri,
                                 stream);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsISupports> owner = do_QueryInterface(info->mPrincipal);
 
-  nsAutoString type;
+  nsString type;
   rv = blob->GetType(type);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  nsCOMPtr<nsIDOMFile> file = do_QueryInterface(info->mObject);
+  if (file) {
+    nsString filename;
+    rv = file->GetName(filename);
+    NS_ENSURE_SUCCESS(rv, rv);
+    channel->SetContentDispositionFilename(filename);
+  }
+
   uint64_t size;
   rv = blob->GetSize(&size);
   NS_ENSURE_SUCCESS(rv, rv);
 
   channel->SetOwner(owner);
   channel->SetOriginalURI(uri);
   channel->SetContentType(NS_ConvertUTF16toUTF8(type));
   channel->SetContentLength(size);
--- a/content/base/src/nsPlainTextSerializer.h
+++ b/content/base/src/nsPlainTextSerializer.h
@@ -7,25 +7,27 @@
  * nsIContentSerializer implementation that can be used with an
  * nsIDocumentEncoder to convert a DOM into plaintext in a nice way
  * (eg for copy/paste as plaintext).
  */
 
 #ifndef nsPlainTextSerializer_h__
 #define nsPlainTextSerializer_h__
 
-#include "nsIContentSerializer.h"
+#include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
-#include "nsString.h"
+#include "nsIAtom.h"
+#include "nsIContentSerializer.h"
+#include "nsIDocumentEncoder.h"
 #include "nsILineBreaker.h"
-#include "nsIContent.h"
-#include "nsIAtom.h"
-#include "nsIDocumentEncoder.h"
+#include "nsString.h"
 #include "nsTArray.h"
 
+class nsIContent;
+
 namespace mozilla {
 namespace dom {
 class Element;
 } // namespace dom
 } // namespace mozilla
 
 class nsPlainTextSerializer : public nsIContentSerializer
 {
--- a/content/base/src/nsXMLContentSerializer.h
+++ b/content/base/src/nsXMLContentSerializer.h
@@ -7,28 +7,28 @@
  * nsIContentSerializer implementation that can be used with an
  * nsIDocumentEncoder to convert an XML DOM to an XML string that
  * could be parsed into more or less the original DOM.
  */
 
 #ifndef nsXMLContentSerializer_h__
 #define nsXMLContentSerializer_h__
 
-#include "nsIContent.h"
 #include "nsIContentSerializer.h"
 #include "nsISupportsUtils.h"
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
 #include "nsString.h"
 
 #define kIndentStr NS_LITERAL_STRING("  ")
 #define kEndTag NS_LITERAL_STRING("</")
 
+class nsIAtom;
 class nsIDOMNode;
-class nsIAtom;
+class nsINode;
 
 class nsXMLContentSerializer : public nsIContentSerializer {
  public:
   nsXMLContentSerializer();
   virtual ~nsXMLContentSerializer();
 
   NS_DECL_ISUPPORTS
 
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -91,17 +91,17 @@
 #include "nsWrapperCacheInlines.h"
 #include "nsJSUtils.h"
 #include "XPCQuickStubs.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/HTMLImageElement.h"
 #include "mozilla/dom/HTMLVideoElement.h"
 #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 
-#ifdef USE_SKIA
+#ifdef USE_SKIA_GPU
 #include "GLContext.h"
 #include "GLContextProvider.h"
 #include "SurfaceTypes.h"
 #endif
 
 #ifdef XP_WIN
 #include "gfxWindowsPlatform.h"
 #endif
@@ -462,17 +462,17 @@ public:
   }
   ~CanvasRenderingContext2DUserData()
   {
     if (mContext) {
       mContext->mUserDatas.RemoveElement(this);
     }
   }
 
-#ifdef USE_SKIA
+#ifdef USE_SKIA_GPU
   static void PreTransactionCallback(void* aData)
   {
     CanvasRenderingContext2DUserData* self =
       static_cast<CanvasRenderingContext2DUserData*>(aData);
     CanvasRenderingContext2D* context = self->mContext;
     if (self->mContext && context->mGLContext) {
       context->mGLContext->MakeCurrent();
       context->mGLContext->PublishFrame();
@@ -794,17 +794,17 @@ CanvasRenderingContext2D::EnsureTarget()
     nsRefPtr<LayerManager> layerManager = nullptr;
 
     if (ownerDoc) {
       layerManager =
         nsContentUtils::PersistentLayerManagerForDocument(ownerDoc);
     }
 
      if (layerManager) {
-#ifdef USE_SKIA
+#ifdef USE_SKIA_GPU
        if (gfxPlatform::GetPlatform()->UseAcceleratedSkiaCanvas()) {
          mGLContext = mozilla::gl::GLContextProvider::CreateOffscreen(gfxIntSize(size.width,
                                                                                  size.height),
                                                                       SurfaceCaps::ForRGBA(),
                                                                       mozilla::gl::GLContext::ContextFlagsNone);
          mTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForFBO(0, mGLContext, size, format);
        } else
 #endif
@@ -3781,17 +3781,17 @@ CanvasRenderingContext2D::GetCanvasLayer
   // The userData will receive DidTransactionCallbacks, which flush the
   // the invalidation state to indicate that the canvas is up to date.
   userData = new CanvasRenderingContext2DUserData(this);
   canvasLayer->SetDidTransactionCallback(
           CanvasRenderingContext2DUserData::DidTransactionCallback, userData);
   canvasLayer->SetUserData(&g2DContextLayerUserData, userData);
 
   CanvasLayer::Data data;
-#ifdef USE_SKIA
+#ifdef USE_SKIA_GPU
   if (mGLContext) {
     canvasLayer->SetPreTransactionCallback(
             CanvasRenderingContext2DUserData::PreTransactionCallback, userData);
     data.mGLContext = mGLContext;
   } else
 #endif
   {
     data.mDrawTarget = mTarget;
--- a/content/canvas/src/CanvasRenderingContext2D.h
+++ b/content/canvas/src/CanvasRenderingContext2D.h
@@ -711,17 +711,17 @@ protected:
 
   /**
     * Number of times we've invalidated before calling redraw
     */
   uint32_t mInvalidateCount;
   static const uint32_t kCanvasMaxInvalidateCount = 100;
 
 
-#ifdef USE_SKIA
+#ifdef USE_SKIA_GPU
   nsRefPtr<gl::GLContext> mGLContext;
 #endif
 
   /**
     * Returns true if a shadow should be drawn along with a
     * drawing operation.
     */
   bool NeedToDrawShadow()
--- a/content/events/src/TextComposition.cpp
+++ b/content/events/src/TextComposition.cpp
@@ -4,16 +4,17 @@
  * 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 "TextComposition.h"
 #include "nsContentEventHandler.h"
 #include "nsContentUtils.h"
 #include "nsEventDispatcher.h"
 #include "nsGUIEvent.h"
+#include "nsIContent.h"
 #include "nsIMEStateManager.h"
 #include "nsIPresShell.h"
 #include "nsIWidget.h"
 #include "nsPresContext.h"
 
 namespace mozilla {
 
 /******************************************************************************
--- a/content/events/src/nsContentEventHandler.h
+++ b/content/events/src/nsContentEventHandler.h
@@ -6,24 +6,25 @@
 #ifndef nsContentEventHandler_h__
 #define nsContentEventHandler_h__
 
 #include "nscore.h"
 #include "nsCOMPtr.h"
 
 #include "nsISelection.h"
 #include "nsRange.h"
-#include "nsIContent.h"
 #include "nsIDOMTreeWalker.h"
 
+class nsCaret;
+class nsIContent;
+class nsIPresShell;
 class nsPresContext;
-class nsIPresShell;
 class nsQueryContentEvent;
 class nsSelectionEvent;
-class nsCaret;
+
 struct nsRect;
 
 /*
  * Query Content Event Handler
  *   nsContentEventHandler is a helper class for nsEventStateManager.
  *   The platforms request some content informations, e.g., the selected text,
  *   the offset of the selected text and the text for specified range.
  *   This class answers to NS_QUERY_* events from actual contents.
--- a/content/events/src/nsEventStateManager.h
+++ b/content/events/src/nsEventStateManager.h
@@ -5,34 +5,33 @@
 
 #ifndef nsEventStateManager_h__
 #define nsEventStateManager_h__
 
 #include "mozilla/TypedEnum.h"
 
 #include "nsEvent.h"
 #include "nsGUIEvent.h"
-#include "nsIContent.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
 #include "nsITimer.h"
 #include "nsCOMPtr.h"
-#include "nsIDocument.h"
 #include "nsCOMArray.h"
 #include "nsIFrameLoader.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIMarkupDocumentViewer.h"
 #include "nsIScrollableFrame.h"
 #include "nsFocusManager.h"
-#include "nsIDocument.h"
 #include "nsEventStates.h"
 #include "mozilla/TimeStamp.h"
 #include "nsIFrame.h"
 
 class nsIPresShell;
+class nsIContent;
+class nsIDocument;
 class nsIDocShell;
 class nsIDocShellTreeNode;
 class nsIDocShellTreeItem;
 class imgIContainer;
 class nsDOMDataTransfer;
 class MouseEnterLeaveDispatcher;
 class nsIFrame;
 
--- a/content/html/content/src/HTMLAreaElement.h
+++ b/content/html/content/src/HTMLAreaElement.h
@@ -7,19 +7,20 @@
 #ifndef mozilla_dom_HTMLAreaElement_h
 #define mozilla_dom_HTMLAreaElement_h
 
 #include "nsIDOMHTMLAreaElement.h"
 #include "nsGenericHTMLElement.h"
 #include "nsILink.h"
 #include "nsGkAtoms.h"
 #include "nsIURL.h"
-#include "nsIDocument.h"
 #include "Link.h"
 
+class nsIDocument;
+
 namespace mozilla {
 namespace dom {
 
 class HTMLAreaElement : public nsGenericHTMLElement,
                         public nsIDOMHTMLAreaElement,
                         public nsILink,
                         public Link
 {
--- a/content/html/content/src/HTMLIFrameElement.cpp
+++ b/content/html/content/src/HTMLIFrameElement.cpp
@@ -1,16 +1,17 @@
 /* -*- 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 "mozilla/Util.h"
 
 #include "mozilla/dom/HTMLIFrameElement.h"
+#include "mozilla/dom/HTMLIFrameElementBinding.h"
 #include "nsIDOMSVGDocument.h"
 #include "nsMappedAttributes.h"
 #include "nsAttrValueInlines.h"
 #include "nsError.h"
 #include "nsRuleData.h"
 #include "nsStyleConsts.h"
 #include "nsContentUtils.h"
 
@@ -20,16 +21,17 @@ DOMCI_NODE_DATA(HTMLIFrameElement, mozil
 
 namespace mozilla {
 namespace dom {
 
 HTMLIFrameElement::HTMLIFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                                      FromParser aFromParser)
   : nsGenericHTMLFrameElement(aNodeInfo, aFromParser)
 {
+  SetIsDOMBinding();
 }
 
 HTMLIFrameElement::~HTMLIFrameElement()
 {
 }
 
 NS_IMPL_ADDREF_INHERITED(HTMLIFrameElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLIFrameElement, Element)
@@ -244,10 +246,16 @@ HTMLIFrameElement::GetSandboxFlags()
   if (GetAttr(kNameSpaceID_None, nsGkAtoms::sandbox, sandboxAttr)) {
     return nsContentUtils::ParseSandboxAttributeToFlags(sandboxAttr);
   }
 
   // No sandbox attribute, no sandbox flags.
   return 0;
 }
 
+JSObject*
+HTMLIFrameElement::WrapNode(JSContext* aCx, JSObject* aScope)
+{
+  return HTMLIFrameElementBinding::Wrap(aCx, aScope, this);
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/content/html/content/src/HTMLIFrameElement.h
+++ b/content/html/content/src/HTMLIFrameElement.h
@@ -55,17 +55,124 @@ public:
   virtual nsIDOMNode* AsDOMNode() { return this; }
 
   virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                                 const nsAttrValue* aValue,
                                 bool aNotify);
 
   uint32_t GetSandboxFlags();
 
+  // Web IDL binding methods
+  // The XPCOM GetSrc is fine for our purposes
+  void SetSrc(const nsAString& aSrc, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::src, aSrc, aError);
+  }
+  void GetName(DOMString& aName)
+  {
+    GetHTMLAttr(nsGkAtoms::name, aName);
+  }
+  void SetName(const nsAString& aName, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::name, aName, aError);
+  }
+  void GetSandbox(DOMString& aSandbox)
+  {
+    GetHTMLAttr(nsGkAtoms::sandbox, aSandbox);
+  }
+  bool AllowFullscreen() const
+  {
+    return GetBoolAttr(nsGkAtoms::allowfullscreen);
+  }
+  void SetAllowFullscreen(bool aAllow, ErrorResult& aError)
+  {
+    SetHTMLBoolAttr(nsGkAtoms::allowfullscreen, aAllow, aError);
+  }
+  void GetWidth(DOMString& aWidth)
+  {
+    GetHTMLAttr(nsGkAtoms::width, aWidth);
+  }
+  void SetWidth(const nsAString& aWidth, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::width, aWidth, aError);
+  }
+  void GetHeight(DOMString& aHeight)
+  {
+    GetHTMLAttr(nsGkAtoms::height, aHeight);
+  }
+  void SetHeight(const nsAString& aHeight, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::height, aHeight, aError);
+  }
+  using nsGenericHTMLFrameElement::GetContentDocument;
+  using nsGenericHTMLFrameElement::GetContentWindow;
+  void GetAlign(DOMString& aAlign)
+  {
+    GetHTMLAttr(nsGkAtoms::align, aAlign);
+  }
+  void SetAlign(const nsAString& aAlign, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::align, aAlign, aError);
+  }
+  void GetScrolling(DOMString& aScrolling)
+  {
+    GetHTMLAttr(nsGkAtoms::scrolling, aScrolling);
+  }
+  void SetScrolling(const nsAString& aScrolling, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::scrolling, aScrolling, aError);
+  }
+  void GetFrameBorder(DOMString& aFrameBorder)
+  {
+    GetHTMLAttr(nsGkAtoms::frameborder, aFrameBorder);
+  }
+  void SetFrameBorder(const nsAString& aFrameBorder, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::frameborder, aFrameBorder, aError);
+  }
+  // The XPCOM GetLongDesc is fine
+  void SetLongDesc(const nsAString& aLongDesc, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::longdesc, aLongDesc, aError);
+  }
+  void GetMarginWidth(DOMString& aMarginWidth)
+  {
+    GetHTMLAttr(nsGkAtoms::marginwidth, aMarginWidth);
+  }
+  void SetMarginWidth(const nsAString& aMarginWidth, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::marginwidth, aMarginWidth, aError);
+  }
+  void GetMarginHeight(DOMString& aMarginHeight)
+  {
+    GetHTMLAttr(nsGkAtoms::marginheight, aMarginHeight);
+  }
+  void SetMarginHeight(const nsAString& aMarginHeight, ErrorResult& aError)
+  {
+    SetHTMLAttr(nsGkAtoms::marginheight, aMarginHeight, aError);
+  }
+  nsIDocument* GetSVGDocument()
+  {
+    return GetContentDocument();
+  }
+  bool Mozbrowser() const
+  {
+    return GetBoolAttr(nsGkAtoms::mozbrowser);
+  }
+  void SetMozbrowser(bool aAllow, ErrorResult& aError)
+  {
+    SetHTMLBoolAttr(nsGkAtoms::mozbrowser, aAllow, aError);
+  }
+  using nsGenericHTMLFrameElement::SetMozbrowser;
+  // nsGenericHTMLFrameElement::GetFrameLoader is fine
+  // nsGenericHTMLFrameElement::GetAppManifestURL is fine
+
 protected:
   virtual void GetItemValueText(nsAString& text);
   virtual void SetItemValueText(const nsAString& text);
+
+  virtual JSObject* WrapNode(JSContext* aCx, JSObject* aScope) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif
--- a/content/html/content/src/UndoManager.h
+++ b/content/html/content/src/UndoManager.h
@@ -5,20 +5,20 @@
 #ifndef mozilla_dom_UndoManager_h
 #define mozilla_dom_UndoManager_h
 
 #include "mozilla/dom/UndoManagerBinding.h"
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
+#include "nsIContent.h"
 #include "nsTArray.h"
 #include "nsWrapperCache.h"
 #include "mozilla/dom/Nullable.h"
-#include "nsIContent.h"
 
 class nsITransactionManager;
 class nsIMutationObserver;
 
 namespace mozilla {
 class ErrorResult;
 namespace dom {
 
--- a/content/html/content/src/nsGenericHTMLFrameElement.h
+++ b/content/html/content/src/nsGenericHTMLFrameElement.h
@@ -1,15 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set tw=80 expandtab softtabstop=2 ts=2 sw=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/. */
 
+#ifndef nsGenericHTMLFrameElement_h
+#define nsGenericHTMLFrameElement_h
+
 #include "nsGenericHTMLElement.h"
 #include "nsIFrameLoader.h"
 #include "nsIMozBrowserFrame.h"
 #include "nsIDOMEventListener.h"
 #include "mozilla/ErrorResult.h"
 
 #include "nsFrameLoader.h"
 
@@ -104,8 +107,10 @@ protected:
   // True when the element is created by the parser
   // using NS_FROM_PARSER_NETWORK flag.
   // If the element is modified, it may lose the flag.
   bool                    mNetworkCreated;
 
   bool                    mBrowserFrameListenersRegistered;
   bool                    mFrameLoaderCreationDisallowed;
 };
+
+#endif // nsGenericHTMLFrameElement_h
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -2524,31 +2524,36 @@ nsHTMLDocument::GetDesignMode(nsAString 
     aDesignMode.AssignLiteral("off");
   }
   return NS_OK;
 }
 
 void
 nsHTMLDocument::MaybeEditingStateChanged()
 {
-  if (mUpdateNestLevel == 0 && (mContentEditableCount > 0) != IsEditingOn()) {
+  if (!mPendingMaybeEditingStateChanged &&
+      mUpdateNestLevel == 0 && (mContentEditableCount > 0) != IsEditingOn()) {
     if (nsContentUtils::IsSafeToRunScript()) {
       EditingStateChanged();
     } else if (!mInDestructor) {
       nsContentUtils::AddScriptRunner(
         NS_NewRunnableMethod(this, &nsHTMLDocument::MaybeEditingStateChanged));
     }
   }
 }
 
 void
 nsHTMLDocument::EndUpdate(nsUpdateType aUpdateType)
 {
+  const bool reset = !mPendingMaybeEditingStateChanged;
+  mPendingMaybeEditingStateChanged = true;
   nsDocument::EndUpdate(aUpdateType);
-
+  if (reset) {
+    mPendingMaybeEditingStateChanged = false;
+  }
   MaybeEditingStateChanged();
 }
 
 
 // Helper class, used below in ChangeContentEditableCount().
 class DeferredContentEditableCountChangeEvent : public nsRunnable
 {
 public:
--- a/content/html/document/src/nsHTMLDocument.h
+++ b/content/html/document/src/nsHTMLDocument.h
@@ -355,16 +355,22 @@ protected:
   EditingState mEditingState;
 
   nsresult   DoClipboardSecurityCheck(bool aPaste);
   static jsid        sCutCopyInternal_id;
   static jsid        sPasteInternal_id;
 
   // When false, the .cookies property is completely disabled
   bool mDisableCookieAccess;
+
+  /**
+   * Temporary flag that is set in EndUpdate() to ignore
+   * MaybeEditingStateChanged() script runners from a nested scope.
+   */
+  bool mPendingMaybeEditingStateChanged;
 };
 
 #define NS_HTML_DOCUMENT_INTERFACE_TABLE_BEGIN(_class)                        \
     NS_DOCUMENT_INTERFACE_TABLE_BEGIN(_class)                                 \
     NS_INTERFACE_TABLE_ENTRY(_class, nsIHTMLDocument)                         \
     NS_INTERFACE_TABLE_ENTRY(_class, nsIDOMHTMLDocument)
 
 #endif /* nsHTMLDocument_h___ */
--- a/content/media/AudioNodeEngine.cpp
+++ b/content/media/AudioNodeEngine.cpp
@@ -73,9 +73,53 @@ AudioBlockCopyChannelWithScale(const flo
                                const float aScale[WEBAUDIO_BLOCK_SIZE],
                                float aOutput[WEBAUDIO_BLOCK_SIZE])
 {
   for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
     aOutput[i] = aInput[i]*aScale[i];
   }
 }
 
+void
+AudioBlockInPlaceScale(float aBlock[WEBAUDIO_BLOCK_SIZE],
+                       uint32_t aChannelCount,
+                       float aScale)
+{
+  if (aScale == 1.0f) {
+    return;
+  }
+  for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE * aChannelCount; ++i) {
+    *aBlock++ *= aScale;
+  }
 }
+
+void
+AudioBlockPanMonoToStereo(const float aInput[WEBAUDIO_BLOCK_SIZE],
+                          float aGainL, float aGainR,
+                          float aOutputL[WEBAUDIO_BLOCK_SIZE],
+                          float aOutputR[WEBAUDIO_BLOCK_SIZE])
+{
+  AudioBlockCopyChannelWithScale(aInput, aGainL, aOutputL);
+  AudioBlockCopyChannelWithScale(aInput, aGainR, aOutputR);
+}
+
+void
+AudioBlockPanStereoToStereo(const float aInputL[WEBAUDIO_BLOCK_SIZE],
+                            const float aInputR[WEBAUDIO_BLOCK_SIZE],
+                            float aGainL, float aGainR, bool aIsOnTheLeft,
+                            float aOutputL[WEBAUDIO_BLOCK_SIZE],
+                            float aOutputR[WEBAUDIO_BLOCK_SIZE])
+{
+  uint32_t i;
+
+  if (aIsOnTheLeft) {
+    for (i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
+      *aOutputL++ = *aInputL++ + *aInputR * aGainL;
+      *aOutputR++ = *aInputR++ * aGainR;
+    }
+  } else {
+    for (i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
+      *aOutputL++ = *aInputL * aGainL;
+      *aOutputR++ = *aInputR++ + *aInputL++ * aGainR;
+    }
+  }
+}
+}
--- a/content/media/AudioNodeEngine.h
+++ b/content/media/AudioNodeEngine.h
@@ -107,16 +107,45 @@ void AudioBlockCopyChannelWithScale(cons
 /**
  * Vector copy-scaled operation.
  */
 void AudioBlockCopyChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
                                     const float aScale[WEBAUDIO_BLOCK_SIZE],
                                     float aOutput[WEBAUDIO_BLOCK_SIZE]);
 
 /**
+ * In place gain. aScale == 1.0f should be optimized.
+ */
+void AudioBlockInPlaceScale(float aBlock[WEBAUDIO_BLOCK_SIZE],
+                            uint32_t aChannelCount,
+                            float aScale);
+
+/**
+ * Upmix a mono input to a stereo output, scaling the two output channels by two
+ * different gain value.
+ * This algorithm is specified in the WebAudio spec.
+ */
+void
+AudioBlockPanMonoToStereo(const float aInput[WEBAUDIO_BLOCK_SIZE],
+                          float aGainL, float aGainR,
+                          float aOutputL[WEBAUDIO_BLOCK_SIZE],
+                          float aOutputR[WEBAUDIO_BLOCK_SIZE]);
+/**
+ * Pan a stereo source according to right and left gain, and the position
+ * (whether the listener is on the left of the source or not).
+ * This algorithm is specified in the WebAudio spec.
+ */
+void
+AudioBlockPanStereoToStereo(const float aInputL[WEBAUDIO_BLOCK_SIZE],
+                            const float aInputR[WEBAUDIO_BLOCK_SIZE],
+                            float aGainL, float aGainR, bool aIsOnTheLeft,
+                            float aOutputL[WEBAUDIO_BLOCK_SIZE],
+                            float aOutputR[WEBAUDIO_BLOCK_SIZE]);
+
+/**
  * All methods of this class and its subclasses are called on the
  * MediaStreamGraph thread.
  */
 class AudioNodeEngine {
 public:
   AudioNodeEngine() {}
   virtual ~AudioNodeEngine() {}
 
--- a/content/media/AudioNodeStream.cpp
+++ b/content/media/AudioNodeStream.cpp
@@ -250,16 +250,18 @@ AudioNodeStream::ObtainInputBlock(AudioC
 void
 AudioNodeStream::ProduceOutput(GraphTime aFrom, GraphTime aTo)
 {
   StreamBuffer::Track* track = EnsureTrack();
 
   AudioChunk outputChunk;
   AudioSegment* segment = track->Get<AudioSegment>();
 
+  outputChunk.SetNull(0);
+
   if (mInCycle) {
     // XXX DelayNode not supported yet so just produce silence
     outputChunk.SetNull(WEBAUDIO_BLOCK_SIZE);
   } else {
     AudioChunk tmpChunk;
     AudioChunk* inputChunk = ObtainInputBlock(&tmpChunk);
     bool finished = false;
     mEngine->ProduceAudioBlock(this, *inputChunk, &outputChunk, &finished);
--- a/content/media/plugins/MediaPluginHost.cpp
+++ b/content/media/plugins/MediaPluginHost.cpp
@@ -159,17 +159,26 @@ static const char* GetOmxLibraryName()
   }
 
   nsAutoString device;
   rv = infoService->GetPropertyAsAString(NS_LITERAL_STRING("device"), device);
   if (NS_SUCCEEDED(rv)) {
     ALOG("Android Device is: %s", NS_LossyConvertUTF16toASCII(device).get());
   }
 
-  if (version == 15 &&
+  nsAutoString manufacturer;
+  rv = infoService->GetPropertyAsAString(NS_LITERAL_STRING("manufacturer"), manufacturer);
+  if (NS_SUCCEEDED(rv)) {
+    ALOG("Android Manufacturer is: %s", NS_LossyConvertUTF16toASCII(manufacturer).get());
+  }
+
+  if (version >= 16 && manufacturer.Find("HTC") == 0) {
+    return "libomxpluginjb-htc.so";
+  }
+  else if (version == 15 &&
       (device.Find("LT28", false) == 0 ||
        device.Find("LT26", false) == 0 ||
        device.Find("LT22", false) == 0 ||
        device.Find("IS12", false) == 0 ||
        device.Find("MT27", false) == 0)) {
     // Sony Ericsson devices running ICS
     return "libomxpluginsony.so";
   }
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -314,22 +314,18 @@ MOCHITEST_FILES += \
 		contentDuration4.sjs \
 		contentDuration5.sjs \
 		contentDuration6.sjs \
 		contentDuration7.sjs \
 		test_framebuffer.html \
 		test_seekable2.html \
 		test_chaining.html \
 		$(NULL)
-# Temporarily disabled on OS X for bug 754860
-ifneq ($(MOZ_WIDGET_TOOLKIT),cocoa)
-MOCHITEST_FILES += \
-		test_bug726904.html \
-		$(NULL)
-endif
+# Temporarily disabled for bug 754860
+#		test_bug726904.html
 else
 MOCHITEST_FILES += \
 		test_can_play_type_no_ogg.html \
 		$(NULL)
 endif
 
 ifdef MOZ_WEBM
 MOCHITEST_FILES += \
--- a/content/media/webaudio/AudioContext.cpp
+++ b/content/media/webaudio/AudioContext.cpp
@@ -192,10 +192,22 @@ AudioContext::DestinationStream() const
 }
 
 double
 AudioContext::CurrentTime() const
 {
   return MediaTimeToSeconds(Destination()->Stream()->GetCurrentTime());
 }
 
+void
+AudioContext::Suspend()
+{
+  DestinationStream()->ChangeExplicitBlockerCount(1);
+}
+
+void
+AudioContext::Resume()
+{
+  DestinationStream()->ChangeExplicitBlockerCount(-1);
+}
+
 }
 }
--- a/content/media/webaudio/AudioContext.h
+++ b/content/media/webaudio/AudioContext.h
@@ -61,19 +61,23 @@ public:
 
   nsIDOMWindow* GetParentObject() const
   {
     return mWindow;
   }
 
   void Shutdown()
   {
+    Suspend();
     mDecoder.Shutdown();
   }
 
+  void Suspend();
+  void Resume();
+
   virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope) MOZ_OVERRIDE;
 
   static already_AddRefed<AudioContext>
   Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
 
   AudioDestinationNode* Destination() const
   {
     return mDestination;
--- a/content/media/webaudio/AudioListener.h
+++ b/content/media/webaudio/AudioListener.h
@@ -116,16 +116,17 @@ public:
 
   void RegisterPannerNode(PannerNode* aPannerNode);
 
 private:
   void SendDoubleParameterToStream(uint32_t aIndex, double aValue);
   void SendThreeDPointParameterToStream(uint32_t aIndex, const ThreeDPoint& aValue);
 
 private:
+  friend class PannerNode;
   nsRefPtr<AudioContext> mContext;
   ThreeDPoint mPosition;
   ThreeDPoint mOrientation;
   ThreeDPoint mUpVector;
   ThreeDPoint mVelocity;
   double mDopplerFactor;
   double mSpeedOfSound;
   nsTArray<WeakPtr<PannerNode> > mPanners;
--- a/content/media/webaudio/AudioParam.h
+++ b/content/media/webaudio/AudioParam.h
@@ -2,37 +2,34 @@
 /* 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 AudioParam_h_
 #define AudioParam_h_
 
-#include "AudioEventTimeline.h"
+#include "AudioParamTimeline.h"
 #include "nsWrapperCache.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsCOMPtr.h"
 #include "EnableWebAudioCheck.h"
 #include "nsAutoPtr.h"
 #include "AudioNode.h"
 #include "mozilla/dom/TypedArray.h"
 #include "mozilla/Util.h"
-#include "mozilla/ErrorResult.h"
 #include "WebAudioUtils.h"
 
 struct JSContext;
 class nsIDOMWindow;
 
 namespace mozilla {
 
 namespace dom {
 
-typedef AudioEventTimeline<ErrorResult> AudioParamTimeline;
-
 class AudioParam MOZ_FINAL : public nsWrapperCache,
                              public EnableWebAudioCheck,
                              public AudioParamTimeline
 {
 public:
   typedef void (*CallbackType)(AudioNode*);
 
   AudioParam(AudioNode* aNode,
new file mode 100644
--- /dev/null
+++ b/content/media/webaudio/AudioParamTimeline.h
@@ -0,0 +1,26 @@
+/* -*- 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 AudioParamTimeline_h_
+#define AudioParamTimeline_h_
+
+// This header is intended to make it possible to use AudioParamTimeline
+// from multiple places without dealing with #include hell!
+
+#include "AudioEventTimeline.h"
+#include "mozilla/ErrorResult.h"
+
+namespace mozilla {
+
+namespace dom {
+
+typedef AudioEventTimeline<ErrorResult> AudioParamTimeline;
+
+}
+}
+
+#endif
+
--- a/content/media/webaudio/GainNode.cpp
+++ b/content/media/webaudio/GainNode.cpp
@@ -4,47 +4,30 @@
  * 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 "GainNode.h"
 #include "mozilla/dom/GainNodeBinding.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "AudioDestinationNode.h"
+#include "WebAudioUtils.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED_1(GainNode, AudioNode,
                                      mGain)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(GainNode)
 NS_INTERFACE_MAP_END_INHERITING(AudioNode)
 
 NS_IMPL_ADDREF_INHERITED(GainNode, AudioNode)
 NS_IMPL_RELEASE_INHERITED(GainNode, AudioNode)
 
-struct ConvertTimeToTickHelper
-{
-  AudioNodeStream* mSourceStream;
-  AudioNodeStream* mDestinationStream;
-
-  static int64_t Convert(double aTime, void* aClosure)
-  {
-    TrackRate sampleRate = IdealAudioRate();
-
-    ConvertTimeToTickHelper* This = static_cast<ConvertTimeToTickHelper*> (aClosure);
-    TrackTicks tick = This->mSourceStream->GetCurrentPosition();
-    StreamTime streamTime = TicksToTimeRoundDown(sampleRate, tick);
-    GraphTime graphTime = This->mSourceStream->StreamTimeToGraphTime(streamTime);
-    StreamTime destinationStreamTime = This->mDestinationStream->GraphTimeToStreamTime(graphTime);
-    return TimeToTicksRoundDown(sampleRate, destinationStreamTime + SecondsToMediaTime(aTime));
-  }
-};
-
 class GainNodeEngine : public AudioNodeEngine
 {
 public:
   explicit GainNodeEngine(AudioDestinationNode* aDestination)
     : mSource(nullptr)
     , mDestination(static_cast<AudioNodeStream*> (aDestination->Stream()))
     // Keep the default value in sync with the default value in GainNode::GainNode.
     , mGain(1.f)
@@ -60,20 +43,17 @@ public:
     GAIN
   };
   void SetTimelineParameter(uint32_t aIndex, const AudioParamTimeline& aValue) MOZ_OVERRIDE
   {
     switch (aIndex) {
     case GAIN:
       MOZ_ASSERT(mSource && mDestination);
       mGain = aValue;
-      ConvertTimeToTickHelper ctth;
-      ctth.mSourceStream = mSource;
-      ctth.mDestinationStream = mDestination;
-      mGain.ConvertEventTimesToTicks(ConvertTimeToTickHelper::Convert, &ctth);
+      WebAudioUtils::ConvertAudioParamToTicks(mGain, mSource, mDestination);
       break;
     default:
       NS_ERROR("Bad GainNodeEngine TimelineParameter");
     }
   }
 
   virtual void ProduceAudioBlock(AudioNodeStream* aStream,
                                  const AudioChunk& aInput,
--- a/content/media/webaudio/Makefile.in
+++ b/content/media/webaudio/Makefile.in
@@ -26,16 +26,18 @@ CPPSRCS := \
   AudioSourceNode.cpp \
   BiquadFilterNode.cpp \
   DelayNode.cpp \
   DynamicsCompressorNode.cpp \
   EnableWebAudioCheck.cpp \
   GainNode.cpp \
   MediaBufferDecoder.cpp \
   PannerNode.cpp \
+  ThreeDPoint.cpp \
+  WebAudioUtils.cpp \
   $(NULL)
 
 EXPORTS_NAMESPACES := mozilla/dom
 EXPORTS_mozilla/dom := \
   AudioBuffer.h \
   AudioBufferSourceNode.h \
   AudioContext.h \
   AudioDestinationNode.h \
@@ -47,16 +49,17 @@ EXPORTS_mozilla/dom := \
   DelayNode.h \
   DynamicsCompressorNode.h \
   EnableWebAudioCheck.h \
   GainNode.h \
   PannerNode.h \
   $(NULL)
 
 EXPORTS := \
+  AudioParamTimeline.h \
   MediaBufferDecoder.h \
   ThreeDPoint.h \
   WebAudioUtils.h \
   $(NULL)
 
 FORCE_STATIC_LIB := 1
 
 include $(topsrcdir)/config/rules.mk
--- a/content/media/webaudio/PannerNode.cpp
+++ b/content/media/webaudio/PannerNode.cpp
@@ -7,23 +7,27 @@
 #include "PannerNode.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "AudioListener.h"
 
 namespace mozilla {
 namespace dom {
 
+using namespace std;
+
 class PannerNodeEngine : public AudioNodeEngine
 {
 public:
   PannerNodeEngine()
     // Please keep these default values consistent with PannerNode::PannerNode below.
     : mPanningModel(PanningModelTypeValues::HRTF)
+    , mPanningModelFunction(&PannerNodeEngine::HRTFPanningFunction)
     , mDistanceModel(DistanceModelTypeValues::Inverse)
+    , mDistanceModelFunction(&PannerNodeEngine::InverseGainFunction)
     , mPosition()
     , mOrientation(1., 0., 0.)
     , mVelocity()
     , mRefDistance(1.)
     , mMaxDistance(10000.)
     , mRolloffFactor(1.)
     , mConeInnerAngle(360.)
     , mConeOuterAngle(360.)
@@ -35,19 +39,41 @@ public:
   {
   }
 
   virtual void SetInt32Parameter(uint32_t aIndex, int32_t aParam) MOZ_OVERRIDE
   {
     switch (aIndex) {
     case PannerNode::PANNING_MODEL:
       mPanningModel = PanningModelType(aParam);
+      switch (mPanningModel) {
+        case PanningModelTypeValues::Equalpower:
+          mPanningModelFunction = &PannerNodeEngine::EqualPowerPanningFunction;
+          break;
+        case PanningModelTypeValues::HRTF:
+          mPanningModelFunction = &PannerNodeEngine::HRTFPanningFunction;
+          break;
+        case PanningModelTypeValues::Soundfield:
+          mPanningModelFunction = &PannerNodeEngine::SoundfieldPanningFunction;
+          break;
+      }
       break;
     case PannerNode::DISTANCE_MODEL:
       mDistanceModel = DistanceModelType(aParam);
+      switch (mDistanceModel) {
+        case DistanceModelTypeValues::Inverse:
+          mDistanceModelFunction = &PannerNodeEngine::InverseGainFunction;
+          break;
+        case DistanceModelTypeValues::Linear:
+          mDistanceModelFunction = &PannerNodeEngine::LinearGainFunction;
+          break;
+        case DistanceModelTypeValues::Exponential:
+          mDistanceModelFunction = &PannerNodeEngine::ExponentialGainFunction;
+          break;
+      }
       break;
     default:
       NS_ERROR("Bad PannerNodeEngine Int32Parameter");
     }
   }
   virtual void SetThreeDPointParameter(uint32_t aIndex, const ThreeDPoint& aParam) MOZ_OVERRIDE
   {
     switch (aIndex) {
@@ -78,22 +104,46 @@ public:
     }
   }
 
   virtual void ProduceAudioBlock(AudioNodeStream* aStream,
                                  const AudioChunk& aInput,
                                  AudioChunk* aOutput,
                                  bool *aFinished) MOZ_OVERRIDE
   {
-    // TODO: actually do 3D positioning computations here
-    *aOutput = aInput;
+    if (aInput.IsNull()) {
+      *aOutput = aInput;
+      return;
+    }
+    (this->*mPanningModelFunction)(aInput, aOutput);
   }
 
+  void ComputeAzimuthAndElevation(float& aAzimuth, float& aElevation);
+  void DistanceAndConeGain(AudioChunk* aChunk, float aGain);
+  float ComputeConeGain();
+
+  void GainMonoToStereo(const AudioChunk& aInput, AudioChunk* aOutput,
+                        float aGainL, float aGainR);
+  void GainStereoToStereo(const AudioChunk& aInput, AudioChunk* aOutput,
+                          float aGainL, float aGainR, double aAzimuth);
+
+  void EqualPowerPanningFunction(const AudioChunk& aInput, AudioChunk* aOutput);
+  void HRTFPanningFunction(const AudioChunk& aInput, AudioChunk* aOutput);
+  void SoundfieldPanningFunction(const AudioChunk& aInput, AudioChunk* aOutput);
+
+  float LinearGainFunction(float aDistance);
+  float InverseGainFunction(float aDistance);
+  float ExponentialGainFunction(float aDistance);
+
   PanningModelType mPanningModel;
+  typedef void (PannerNodeEngine::*PanningModelFunction)(const AudioChunk& aInput, AudioChunk* aOutput);
+  PanningModelFunction mPanningModelFunction;
   DistanceModelType mDistanceModel;
+  typedef float (PannerNodeEngine::*DistanceModelFunction)(float aDistance);
+  DistanceModelFunction mDistanceModelFunction;
   ThreeDPoint mPosition;
   ThreeDPoint mOrientation;
   ThreeDPoint mVelocity;
   double mRefDistance;
   double mMaxDistance;
   double mRolloffFactor;
   double mConeInnerAngle;
   double mConeOuterAngle;
@@ -133,11 +183,239 @@ PannerNode::~PannerNode()
 }
 
 JSObject*
 PannerNode::WrapObject(JSContext* aCx, JSObject* aScope)
 {
   return PannerNodeBinding::Wrap(aCx, aScope, this);
 }
 
+// Those three functions are described in the spec.
+float
+PannerNodeEngine::LinearGainFunction(float aDistance)
+{
+  return 1 - mRolloffFactor * (aDistance - mRefDistance) / (mMaxDistance - mRefDistance);
+}
+
+float
+PannerNodeEngine::InverseGainFunction(float aDistance)
+{
+  return mRefDistance / (mRefDistance + mRolloffFactor * (aDistance - mRefDistance));
+}
+
+float
+PannerNodeEngine::ExponentialGainFunction(float aDistance)
+{
+  return pow(aDistance / mRefDistance, -mRolloffFactor);
+}
+
+void
+PannerNodeEngine::SoundfieldPanningFunction(const AudioChunk& aInput,
+                                            AudioChunk* aOutput)
+{
+  // not implemented: noop
+  *aOutput = aInput;
+}
+
+void
+PannerNodeEngine::HRTFPanningFunction(const AudioChunk& aInput,
+                                      AudioChunk* aOutput)
+{
+  // not implemented: noop
+  *aOutput = aInput;
+}
+
+void
+PannerNodeEngine::EqualPowerPanningFunction(const AudioChunk& aInput,
+                                            AudioChunk* aOutput)
+{
+  float azimuth, elevation, gainL, gainR, normalizedAzimuth, distance, distanceGain, coneGain;
+  int inputChannels = aInput.mChannelData.Length();
+  ThreeDPoint distanceVec;
+
+  // If both the listener are in the same spot, and no cone gain is specified,
+  // this node is noop.
+  if (mListenerPosition == mPosition &&
+      mConeInnerAngle == 360 &&
+      mConeOuterAngle == 360) {
+    *aOutput = aInput;
+    return;
+  }
+
+  // The output of this node is always stereo, no matter what the inputs are.
+  AllocateAudioBlock(2, aOutput);
+
+  ComputeAzimuthAndElevation(azimuth, elevation);
+  coneGain = ComputeConeGain();
+
+  // The following algorithm is described in the spec.
+  // Clamp azimuth in the [-90, 90] range.
+  azimuth = min(180.f, max(-180.f, azimuth));
+
+  // Wrap around
+  if (azimuth < -90.f) {
+    azimuth = -180.f - azimuth;
+  } else if (azimuth > 90) {
+    azimuth = 180.f - azimuth;
+  }
+
+  // Normalize the value in the [0, 1] range.
+  if (inputChannels == 1) {
+    normalizedAzimuth = (azimuth + 90.f) / 180.f;
+  } else {
+    if (azimuth <= 0) {
+      normalizedAzimuth = (azimuth + 90.f) / 90.f;
+    } else {
+      normalizedAzimuth = azimuth / 90.f;
+    }
+  }
+
+  // Compute how much the distance contributes to the gain reduction.
+  distanceVec = mPosition - mListenerPosition;
+  distance = sqrt(distanceVec.DotProduct(distanceVec));
+  distanceGain = (this->*mDistanceModelFunction)(distance);
+
+  // Actually compute the left and right gain.
+  gainL = cos(0.5 * M_PI * normalizedAzimuth);
+  gainR = sin(0.5 * M_PI * normalizedAzimuth);
+
+  // Compute the output.
+  if (inputChannels == 1) {
+    GainMonoToStereo(aInput, aOutput, gainL, gainR);
+  } else {
+    GainStereoToStereo(aInput, aOutput, gainL, gainR, azimuth);
+  }
+
+  DistanceAndConeGain(aOutput, distanceGain * coneGain);
+}
+
+void
+PannerNodeEngine::GainMonoToStereo(const AudioChunk& aInput, AudioChunk* aOutput,
+                                   float aGainL, float aGainR)
+{
+  float* outputL = static_cast<float*>(const_cast<void*>(aOutput->mChannelData[0]));
+  float* outputR = static_cast<float*>(const_cast<void*>(aOutput->mChannelData[1]));
+  const float* input = static_cast<float*>(const_cast<void*>(aInput.mChannelData[0]));
+
+  AudioBlockPanMonoToStereo(input, aGainL, aGainR, outputL, outputR);
+}
+
+void
+PannerNodeEngine::GainStereoToStereo(const AudioChunk& aInput, AudioChunk* aOutput,
+                                     float aGainL, float aGainR, double aAzimuth)
+{
+  float* outputL = static_cast<float*>(const_cast<void*>(aOutput->mChannelData[0]));
+  float* outputR = static_cast<float*>(const_cast<void*>(aOutput->mChannelData[1]));
+  const float* inputL = static_cast<float*>(const_cast<void*>(aInput.mChannelData[0]));
+  const float* inputR = static_cast<float*>(const_cast<void*>(aInput.mChannelData[1]));
+
+  AudioBlockPanStereoToStereo(inputL, inputR, aGainL, aGainR, aAzimuth <= 0, outputL, outputR);
+}
+
+void
+PannerNodeEngine::DistanceAndConeGain(AudioChunk* aChunk, float aGain)
+{
+  float* samples = static_cast<float*>(const_cast<void*>(*aChunk->mChannelData.Elements()));
+  uint32_t channelCount = aChunk->mChannelData.Length();
+
+  AudioBlockInPlaceScale(samples, channelCount, aGain);
+}
+
+// This algorithm is specicied in the webaudio spec.
+void
+PannerNodeEngine::ComputeAzimuthAndElevation(float& aAzimuth, float& aElevation)
+{
+  ThreeDPoint sourceListener = mPosition - mListenerPosition;
+
+  if (sourceListener.IsZero()) {
+    aAzimuth = 0.0;
+    aElevation = 0.0;
+    return;
+  }
+
+  sourceListener.Normalize();
+
+  // Project the source-listener vector on the x-z plane.
+  ThreeDPoint& listenerFront = mListenerOrientation;
+  ThreeDPoint listenerRightNorm = listenerFront.CrossProduct(mListenerUpVector);
+  listenerRightNorm.Normalize();
+
+  ThreeDPoint listenerFrontNorm(listenerFront);
+  listenerFrontNorm.Normalize();
+
+  ThreeDPoint up = listenerRightNorm.CrossProduct(listenerFrontNorm);
+
+  double upProjection = sourceListener.DotProduct(up);
+
+  ThreeDPoint projectedSource = sourceListener - up * upProjection;
+  projectedSource.Normalize();
+
+  // Actually compute the angle, and convert to degrees
+  double projection = projectedSource.DotProduct(listenerRightNorm);
+  aAzimuth = 180 * acos(projection) / M_PI;
+
+  // Compute whether the source is in front or behind the listener.
+  double frontBack = projectedSource.DotProduct(listenerFrontNorm);
+  if (frontBack < 0) {
+    aAzimuth = 360 - aAzimuth;
+  }
+  // Rotate the azimuth so it is relative to the listener front vector instead
+  // of the right vector.
+  if ((aAzimuth >= 0) && (aAzimuth <= 270)) {
+    aAzimuth = 90 - aAzimuth;
+  } else {
+    aAzimuth = 450 - aAzimuth;
+  }
+
+  aElevation = 90 - 180 * acos(sourceListener.DotProduct(up)) / M_PI;
+
+  if (aElevation > 90) {
+    aElevation = 180 - aElevation;
+  } else if (aElevation < -90) {
+    aElevation = -180 - aElevation;
+  }
+}
+
+// This algorithm is described in the WebAudio spec.
+float
+PannerNodeEngine::ComputeConeGain()
+{
+  // Omnidirectional source
+  if (mOrientation.IsZero() || ((mConeInnerAngle == 360) && (mConeOuterAngle == 360))) {
+    return 1;
+  }
+
+  // Normalized source-listener vector
+  ThreeDPoint sourceToListener = mListenerPosition - mPosition;
+  sourceToListener.Normalize();
+
+  ThreeDPoint normalizedSourceOrientation = mOrientation;
+  normalizedSourceOrientation.Normalize();
+
+  // Angle between the source orientation vector and the source-listener vector
+  double dotProduct = sourceToListener.DotProduct(normalizedSourceOrientation);
+  double angle = 180 * acos(dotProduct) / M_PI;
+  double absAngle = fabs(angle);
+
+  // Divide by 2 here since API is entire angle (not half-angle)
+  double absInnerAngle = fabs(mConeInnerAngle) / 2;
+  double absOuterAngle = fabs(mConeOuterAngle) / 2;
+  double gain = 1;
+
+  if (absAngle <= absInnerAngle) {
+    // No attenuation
+    gain = 1;
+  } else if (absAngle >= absOuterAngle) {
+    // Max attenuation
+    gain = mConeOuterGain;
+  } else {
+    // Between inner and outer cones
+    // inner -> outer, x goes from 0 -> 1
+    double x = (absAngle - absInnerAngle) / (absOuterAngle - absInnerAngle);
+    gain = (1 - x) + mConeOuterGain * x;
+  }
+
+  return gain;
+}
+
 }
 }
 
new file mode 100644
--- /dev/null
+++ b/content/media/webaudio/ThreeDPoint.cpp
@@ -0,0 +1,40 @@
+/* -*- 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/. */
+
+/**
+ * Other similar methods can be added if needed.
+ */
+
+#include "ThreeDPoint.h"
+
+namespace mozilla {
+
+namespace dom {
+
+ThreeDPoint operator-(const ThreeDPoint& lhs, const ThreeDPoint& rhs)
+{
+  return ThreeDPoint(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z);
+}
+
+ThreeDPoint operator*(const ThreeDPoint& lhs, const ThreeDPoint& rhs)
+{
+  return ThreeDPoint(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z);
+}
+
+ThreeDPoint operator*(const ThreeDPoint& lhs, const double rhs)
+{
+  return ThreeDPoint(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs);
+}
+
+bool operator==(const ThreeDPoint& lhs, const ThreeDPoint& rhs)
+{
+  return lhs.x == rhs.x &&
+         lhs.y == rhs.y &&
+         lhs.z == rhs.z;
+}
+
+}
+}
--- a/content/media/webaudio/ThreeDPoint.h
+++ b/content/media/webaudio/ThreeDPoint.h
@@ -2,16 +2,18 @@
 /* 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 ThreeDPoint_h_
 #define ThreeDPoint_h_
 
+#include <cmath>
+
 namespace mozilla {
 
 namespace dom {
 
 struct ThreeDPoint {
   ThreeDPoint()
     : x(0.)
     , y(0.)
@@ -20,16 +22,55 @@ struct ThreeDPoint {
   }
   ThreeDPoint(double aX, double aY, double aZ)
     : x(aX)
     , y(aY)
     , z(aZ)
   {
   }
 
+  double Magnitude() const
+  {
+    return sqrt(x * x + y * y + z * z);
+  }
+
+  void Normalize()
+  {
+    double invDistance = 1 / Magnitude();
+    x *= invDistance;
+    y *= invDistance;
+    z *= invDistance;
+  }
+
+  ThreeDPoint CrossProduct(const ThreeDPoint& rhs) const
+  {
+    return ThreeDPoint(y * rhs.z - z * rhs.y,
+                       z * rhs.x - x * rhs.z,
+                       x * rhs.y - y * rhs.x);
+  }
+
+  double DotProduct(const ThreeDPoint& rhs)
+  {
+    return x * rhs.x + y * rhs.y + z * rhs.z;
+  }
+
+  double Distance(const ThreeDPoint& rhs)
+  {
+    return sqrt(hypot(rhs.x, x) + hypot(rhs.y, y) + hypot(rhs.z, z));
+  }
+
+  bool IsZero() const
+  {
+    return x == 0 && y == 0 && z == 0;
+  }
   double x, y, z;
 };
 
+ThreeDPoint operator-(const ThreeDPoint& lhs, const ThreeDPoint& rhs);
+ThreeDPoint operator*(const ThreeDPoint& lhs, const ThreeDPoint& rhs);
+ThreeDPoint operator*(const ThreeDPoint& lhs, const double rhs);
+bool operator==(const ThreeDPoint& lhs, const ThreeDPoint& rhs);
+
 }
 }
 
 #endif
 
new file mode 100644
--- /dev/null
+++ b/content/media/webaudio/WebAudioUtils.cpp
@@ -0,0 +1,44 @@
+/* -*- 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 "WebAudioUtils.h"
+#include "AudioNodeStream.h"
+
+namespace mozilla {
+
+namespace dom {
+
+struct ConvertTimeToTickHelper
+{
+  AudioNodeStream* mSourceStream;
+  AudioNodeStream* mDestinationStream;
+
+  static int64_t Convert(double aTime, void* aClosure)
+  {
+    TrackRate sampleRate = IdealAudioRate();
+
+    ConvertTimeToTickHelper* This = static_cast<ConvertTimeToTickHelper*> (aClosure);
+    TrackTicks tick = This->mSourceStream->GetCurrentPosition();
+    StreamTime streamTime = TicksToTimeRoundDown(sampleRate, tick);
+    GraphTime graphTime = This->mSourceStream->StreamTimeToGraphTime(streamTime);
+    StreamTime destinationStreamTime = This->mDestinationStream->GraphTimeToStreamTime(graphTime);
+    return TimeToTicksRoundDown(sampleRate, destinationStreamTime + SecondsToMediaTime(aTime));
+  }
+};
+
+void
+WebAudioUtils::ConvertAudioParamToTicks(AudioParamTimeline& aParam,
+                                        AudioNodeStream* aSource,
+                                        AudioNodeStream* aDest)
+{
+  ConvertTimeToTickHelper ctth;
+  ctth.mSourceStream = aSource;
+  ctth.mDestinationStream = aDest;
+  aParam.ConvertEventTimesToTicks(ConvertTimeToTickHelper::Convert, &ctth);
+}
+
+}
+}
--- a/content/media/webaudio/WebAudioUtils.h
+++ b/content/media/webaudio/WebAudioUtils.h
@@ -3,31 +3,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/. */
 
 #ifndef WebAudioUtils_h_
 #define WebAudioUtils_h_
 
 #include <cmath>
+#include "AudioParamTimeline.h"
 
 namespace mozilla {
 
+class AudioNodeStream;
+
 namespace dom {
 
 struct WebAudioUtils {
   static bool FuzzyEqual(float v1, float v2)
   {
     using namespace std;
     return fabsf(v1 - v2) < 1e-7f;
   }
   static bool FuzzyEqual(double v1, double v2)
   {
     using namespace std;
     return fabs(v1 - v2) < 1e-7;
   }
+
+  /**
+   * Converts AudioParamTimeline floating point time values to tick values
+   * with respect to a source and a destination AudioNodeStream.
+   *
+   * This needs to be called for each AudioParamTimeline that gets sent to an
+   * AudioNodeEngine on the engine side where the AudioParamTimeline is
+   * received.  This means that such engines need to be aware of their source
+   * and destination streams as well.
+   */
+  static void ConvertAudioParamToTicks(AudioParamTimeline& aParam,
+                                       AudioNodeStream* aSource,
+                                       AudioNodeStream* aDest);
 };
 
 }
 }
 
 #endif
 
--- a/content/media/webaudio/test/test_AudioBuffer.html
+++ b/content/media/webaudio/test/test_AudioBuffer.html
@@ -32,20 +32,20 @@ addLoadEvent(function() {
         foundNonZero = true;
         break;
       }
     }
     ok(!foundNonZero, "Buffer " + i + " should be initialized to 0");
   }
   expectException(function() {
     context.createBuffer(2, 2048, 7999);
-  }, DOMException.DOM_SYNTAX_ERR);
+  }, DOMException.SYNTAX_ERR);
   expectException(function() {
     context.createBuffer(2, 2048, 96001);
-  }, DOMException.DOM_SYNTAX_ERR);
+  }, DOMException.SYNTAX_ERR);
   context.createBuffer(2, 2048, 8000);  // no exception
   context.createBuffer(2, 2048, 96000); // no exception
   SpecialPowers.clearUserPref("media.webaudio.enabled");
   SimpleTest.finish();
 });
 
 </script>
 </pre>
--- a/content/media/webaudio/test/webaudio.js
+++ b/content/media/webaudio/test/webaudio.js
@@ -2,17 +2,17 @@
 
 function expectException(func, exceptionCode) {
   var threw = false;
   try {
     func();
   } catch (ex) {
     threw = true;
     ok(ex instanceof DOMException, "Expect a DOM exception");
-    ok(ex.code, exceptionCode, "Expect the correct exception code");
+    is(ex.code, exceptionCode, "Expect the correct exception code");
   }
   ok(threw, "The exception was thrown");
 }
 
 function expectTypeError(func) {
   var threw = false;
   try {
     func();
--- a/content/svg/content/src/DOMSVGLengthList.cpp
+++ b/content/svg/content/src/DOMSVGLengthList.cpp
@@ -15,17 +15,17 @@
 
 // See the comment in this file's header.
 
 // local helper functions
 namespace {
 
 using mozilla::DOMSVGLength;
 
-void UpdateListIndicesFromIndex(nsTArray<DOMSVGLength*>& aItemsArray,
+void UpdateListIndicesFromIndex(FallibleTArray<DOMSVGLength*>& aItemsArray,
                                 uint32_t aStartingIndex)
 {
   uint32_t length = aItemsArray.Length();
 
   for (uint32_t i = aStartingIndex; i < length; ++i) {
     if (aItemsArray[i]) {
       aItemsArray[i]->UpdateListIndex(i);
     }
--- a/content/svg/content/src/DOMSVGLengthList.h
+++ b/content/svg/content/src/DOMSVGLengthList.h
@@ -165,16 +165,16 @@ private:
   /// Creates a DOMSVGLength for aIndex, if it doesn't already exist.
   void EnsureItemAt(uint32_t aIndex);
 
   void MaybeInsertNullInAnimValListAt(uint32_t aIndex);
   void MaybeRemoveItemFromAnimValListAt(uint32_t aIndex);
 
   // Weak refs to our DOMSVGLength items. The items are friends and take care
   // of clearing our pointer to them when they die.
-  nsTArray<DOMSVGLength*> mItems;
+  FallibleTArray<DOMSVGLength*> mItems;
 
   nsRefPtr<DOMSVGAnimatedLengthList> mAList;
 };
 
 } // namespace mozilla
 
 #endif // MOZILLA_DOMSVGLENGTHLIST_H__
--- a/content/svg/content/src/DOMSVGNumberList.cpp
+++ b/content/svg/content/src/DOMSVGNumberList.cpp
@@ -17,17 +17,17 @@
 
 namespace mozilla {
 
 // local helper functions
 namespace {
 
 using mozilla::DOMSVGNumber;
 
-void UpdateListIndicesFromIndex(nsTArray<DOMSVGNumber*>& aItemsArray,
+void UpdateListIndicesFromIndex(FallibleTArray<DOMSVGNumber*>& aItemsArray,
                                 uint32_t aStartingIndex)
 {
   uint32_t length = aItemsArray.Length();
 
   for (uint32_t i = aStartingIndex; i < length; ++i) {
     if (aItemsArray[i]) {
       aItemsArray[i]->UpdateListIndex(i);
     }
--- a/content/svg/content/src/DOMSVGNumberList.h
+++ b/content/svg/content/src/DOMSVGNumberList.h
@@ -161,16 +161,16 @@ private:
   /// Creates a DOMSVGNumber for aIndex, if it doesn't already exist.
   void EnsureItemAt(uint32_t aIndex);
 
   void MaybeInsertNullInAnimValListAt(uint32_t aIndex);
   void MaybeRemoveItemFromAnimValListAt(uint32_t aIndex);
 
   // Weak refs to our DOMSVGNumber items. The items are friends and take care
   // of clearing our pointer to them when they die.
-  nsTArray<DOMSVGNumber*> mItems;
+  FallibleTArray<DOMSVGNumber*> mItems;
 
   nsRefPtr<DOMSVGAnimatedNumberList> mAList;
 };
 
 } // namespace mozilla
 
 #endif // MOZILLA_DOMSVGNUMBERLIST_H__
--- a/content/svg/content/src/DOMSVGPathSegList.h
+++ b/content/svg/content/src/DOMSVGPathSegList.h
@@ -241,17 +241,17 @@ private:
     {}
 
     DOMSVGPathSeg *mItem;
     uint32_t mInternalDataIndex;