Merge m-c to fx-team.
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 07 Mar 2013 17:39:11 -0500
changeset 124248 4ada9533c6d5fc52aa33cda967bcb0ec486ab375
parent 124247 da4d6e7cbb2b03311010edb57c34bf831845f5b0 (current diff)
parent 124160 0e7639e3bdfbe56b5e788f234cafb3c5074954cc (diff)
child 124249 7952fadd1732442445aef29332d74e8ab0a5ecaa
push id24315
push userryanvm@gmail.com
push dateFri, 08 Mar 2013 19:30:04 +0000
treeherdermozilla-inbound@b4bfc1c0829c [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 m-c to fx-team.
accessible/src/base/nsCaretAccessible.cpp
accessible/src/base/nsCaretAccessible.h
content/svg/content/src/nsSVGFilters.cpp
content/svg/content/src/nsSVGFilters.h
mobile/android/base/sync/StubActivity.java
mobile/android/branding/aurora/res/values/defaults.xml
mobile/android/branding/beta/res/values/defaults.xml
mobile/android/branding/nightly/res/values/defaults.xml
mobile/android/branding/official/res/values/defaults.xml
mobile/android/branding/unofficial/res/values/defaults.xml
services/metrics/collector.jsm
services/metrics/tests/xpcshell/test_metrics_collector.js
--- a/accessible/public/Makefile.in
+++ b/accessible/public/Makefile.in
@@ -6,17 +6,16 @@
 DEPTH   = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH   = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE    = accessibility
-XPIDL_MODULE= accessibility
 GRE_MODULE	= 1
 
 XPIDLSRCS = \
       nsIAccessibleTypes.idl \
       nsIAccessibleRetrieval.idl \
       nsIAccessible.idl \
       nsIAccessibleApplication.idl \
       nsIAccessibleRelation.idl \
--- a/accessible/src/base/FocusManager.cpp
+++ b/accessible/src/base/FocusManager.cpp
@@ -122,21 +122,18 @@ FocusManager::NotifyOfDOMFocus(nsISuppor
   mActiveItem = nullptr;
 
   nsCOMPtr<nsINode> targetNode(do_QueryInterface(aTarget));
   if (targetNode) {
     DocAccessible* document =
       GetAccService()->GetDocAccessible(targetNode->OwnerDoc());
     if (document) {
       // Set selection listener for focused element.
-      if (targetNode->IsElement()) {
-        RootAccessible* root = document->RootAccessible();
-        nsCaretAccessible* caretAcc = root->GetCaretAccessible();
-        caretAcc->SetControlSelectionListener(targetNode->AsElement());
-      }
+      if (targetNode->IsElement())
+        SelectionMgr()->SetControlSelectionListener(targetNode->AsElement());
 
       document->HandleNotification<FocusManager, nsINode>
         (this, &FocusManager::ProcessDOMFocus, targetNode);
     }
   }
 }
 
 void
--- a/accessible/src/base/Makefile.in
+++ b/accessible/src/base/Makefile.in
@@ -27,19 +27,19 @@ CPPSRCS = \
   NotificationController.cpp \
   nsAccessNode.cpp \
   nsARIAMap.cpp \
   nsCoreUtils.cpp \
   nsAccUtils.cpp \
   nsAccessibilityService.cpp \
   nsAccessiblePivot.cpp \
   nsEventShell.cpp \
-  nsCaretAccessible.cpp \
   nsTextEquivUtils.cpp \
   RoleAsserts.cpp \
+  SelectionManager.cpp \
   StyleInfo.cpp \
   TextAttrs.cpp \
   TextUpdater.cpp \
   TreeWalker.cpp \
   $(NULL)
 
 ifneq ($(A11Y_LOG),0)
 CPPSRCS += \
@@ -56,16 +56,17 @@ EXPORTS = \
 EXPORTS_NAMESPACES = mozilla/a11y
 
 EXPORTS_mozilla/a11y = \
   DocManager.h \
   FocusManager.h \
   AccTypes.h \
   Platform.h \
   States.h \
+  SelectionManager.h \
   Role.h \
   $(NULL)
 
 ifdef MOZ_DEBUG
 EXPORTS_mozilla/a11y += \
   Logging.h \
   $(NULL)
 endif
rename from accessible/src/base/nsCaretAccessible.cpp
rename to accessible/src/base/SelectionManager.cpp
--- a/accessible/src/base/nsCaretAccessible.cpp
+++ b/accessible/src/base/SelectionManager.cpp
@@ -1,223 +1,180 @@
 /* -*- Mode: C++; tab-width: 4; 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 "nsCaretAccessible.h"
+#include "mozilla/a11y/SelectionManager.h"
 
 #include "DocAccessible-inl.h"
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
 #include "nsCoreUtils.h"
 #include "nsIAccessibleEvent.h"
 #include "RootAccessible.h"
 
 #include "nsCaret.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsIFrame.h"
 #include "nsIPresShell.h"
 #include "nsISelectionPrivate.h"
 #include "nsServiceManagerUtils.h"
+#include "mozilla/Selection.h"
 
-class nsIWidget;
-
+using namespace mozilla;
 using namespace mozilla::a11y;
 
-NS_IMPL_ISUPPORTS1(nsCaretAccessible, nsISelectionListener)
-  
-nsCaretAccessible::nsCaretAccessible(RootAccessible* aRootAccessible) :
-mLastCaretOffset(-1), mRootAccessible(aRootAccessible)
+void
+SelectionManager::Shutdown()
 {
-}
-
-nsCaretAccessible::~nsCaretAccessible()
-{
+  ClearControlSelectionListener();
+  mLastTextAccessible = nullptr;
+  mLastUsedSelection = nullptr;
 }
 
-void nsCaretAccessible::Shutdown()
+void
+SelectionManager::ClearControlSelectionListener()
 {
-  // The caret accessible isn't shut down until the RootAccessible owning it is shut down
-  // Each DocAccessible, including the RootAccessible, is responsible for clearing the
-  // doc selection listeners they registered in this nsCaretAccessible
+  if (!mCurrentControl)
+    return;
 
-  ClearControlSelectionListener(); // Clear the selection listener for the currently focused control
-  mLastTextAccessible = nullptr;
-  mLastUsedSelection = nullptr;
-  mRootAccessible = nullptr;
-}
-
-nsresult nsCaretAccessible::ClearControlSelectionListener()
-{
-  nsCOMPtr<nsISelectionController> controller =
-    GetSelectionControllerForNode(mCurrentControl);
+  nsIFrame* frame = mCurrentControl->GetPrimaryFrame();
+  if (!frame)
+    return;
 
   mCurrentControl = nullptr;
 
-  if (!controller)
-    return NS_OK;
+  const nsFrameSelection* frameSel = frame->GetConstFrameSelection();
+  NS_ASSERTION(frameSel, "No frame selection for the element!");
+  if (!frameSel)
+    return;
 
   // Remove 'this' registered as selection listener for the normal selection.
-  nsCOMPtr<nsISelection> normalSel;
-  controller->GetSelection(nsISelectionController::SELECTION_NORMAL,
-                           getter_AddRefs(normalSel));
-  nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(normalSel));
-  NS_ENSURE_TRUE(selPrivate, NS_ERROR_FAILURE);
-
-  nsresult rv = selPrivate->RemoveSelectionListener(this);
-  NS_ENSURE_SUCCESS(rv, rv);
+  Selection* normalSel =
+    frameSel->GetSelection(nsISelectionController::SELECTION_NORMAL);
+  normalSel->RemoveSelectionListener(this);
 
   // Remove 'this' registered as selection listener for the spellcheck
   // selection.
-  nsCOMPtr<nsISelection> spellcheckSel;
-  controller->GetSelection(nsISelectionController::SELECTION_SPELLCHECK,
-                           getter_AddRefs(spellcheckSel));
-  selPrivate = do_QueryInterface(spellcheckSel);
-  NS_ENSURE_TRUE(selPrivate, NS_ERROR_FAILURE);
-
-  return selPrivate->RemoveSelectionListener(this);
+  Selection* spellSel =
+    frameSel->GetSelection(nsISelectionController::SELECTION_SPELLCHECK);
+  spellSel->RemoveSelectionListener(this);
 }
 
-nsresult
-nsCaretAccessible::SetControlSelectionListener(nsIContent *aCurrentNode)
+void
+SelectionManager::SetControlSelectionListener(dom::Element* aFocusedElm)
 {
-  NS_ENSURE_TRUE(mRootAccessible, NS_ERROR_FAILURE);
-
-  ClearControlSelectionListener();
-
-  mCurrentControl = aCurrentNode;
-  mLastTextAccessible = nullptr;
-
   // 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();
 
-  nsCOMPtr<nsISelectionController> controller =
-    GetSelectionControllerForNode(mCurrentControl);
-  NS_ASSERTION(controller || aCurrentNode->IsNodeOfType(nsINode::eDOCUMENT),
-               "No selection controller for non document node!");
-  if (!controller)
-    return NS_OK;
+  mCurrentControl = aFocusedElm;
+  mLastTextAccessible = nullptr;
+
+  nsIFrame* frame = aFocusedElm->GetPrimaryFrame();
+  if (!frame)
+    return;
+
+  const nsFrameSelection* frameSel = frame->GetConstFrameSelection();
+  NS_ASSERTION(frameSel, "No frame selection for focused element!");
+  if (!frameSel)
+    return;
 
   // Register 'this' as selection listener for the normal selection.
-  nsCOMPtr<nsISelection> normalSel;
-  controller->GetSelection(nsISelectionController::SELECTION_NORMAL,
-                           getter_AddRefs(normalSel));
-  nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(normalSel));
-  NS_ENSURE_TRUE(selPrivate, NS_ERROR_FAILURE);
-
-  nsresult rv = selPrivate->AddSelectionListener(this);
-  NS_ENSURE_SUCCESS(rv, rv);
+  Selection* normalSel =
+    frameSel->GetSelection(nsISelectionController::SELECTION_NORMAL);
+  normalSel->AddSelectionListener(this);
 
-  // Register 'this' as selection listener for the spellcheck selection.
-  nsCOMPtr<nsISelection> spellcheckSel;
-  controller->GetSelection(nsISelectionController::SELECTION_SPELLCHECK,
-                           getter_AddRefs(spellcheckSel));
-  selPrivate = do_QueryInterface(spellcheckSel);
-  NS_ENSURE_TRUE(selPrivate, NS_ERROR_FAILURE);
-  
-  return selPrivate->AddSelectionListener(this);
+  // Register 'this' as selection listener for the spell check selection.
+  Selection* spellSel =
+    frameSel->GetSelection(nsISelectionController::SELECTION_SPELLCHECK);
+  spellSel->AddSelectionListener(this);
 }
 
-nsresult
-nsCaretAccessible::AddDocSelectionListener(nsIPresShell *aShell)
+void
+SelectionManager::AddDocSelectionListener(nsIPresShell* aPresShell)
 {
-  NS_ENSURE_TRUE(mRootAccessible, NS_ERROR_FAILURE);
-
-  nsCOMPtr<nsISelectionController> selCon = do_QueryInterface(aShell);
-  NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
+  const nsFrameSelection* frameSel = aPresShell->ConstFrameSelection();
 
-  nsCOMPtr<nsISelection> domSel;
-  selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(domSel));
-  nsCOMPtr<nsISelectionPrivate> selPrivate = do_QueryInterface(domSel);
-  NS_ENSURE_TRUE(selPrivate, NS_ERROR_FAILURE);
-
-  nsresult rv = selPrivate->AddSelectionListener(this);
-  NS_ENSURE_SUCCESS(rv, rv);
+  // Register 'this' as selection listener for the normal selection.
+  Selection* normalSel =
+    frameSel->GetSelection(nsISelectionController::SELECTION_NORMAL);
+  normalSel->AddSelectionListener(this);
 
-  nsCOMPtr<nsISelection> spellcheckSel;
-  selCon->GetSelection(nsISelectionController::SELECTION_SPELLCHECK,
-                       getter_AddRefs(spellcheckSel));
-  selPrivate = do_QueryInterface(spellcheckSel);
-  NS_ENSURE_TRUE(selPrivate, NS_ERROR_FAILURE);
-  
-  return selPrivate->AddSelectionListener(this);
+  // Register 'this' as selection listener for the spell check selection.
+  Selection* spellSel =
+    frameSel->GetSelection(nsISelectionController::SELECTION_SPELLCHECK);
+  spellSel->AddSelectionListener(this);
 }
 
-nsresult
-nsCaretAccessible::RemoveDocSelectionListener(nsIPresShell *aShell)
+void
+SelectionManager::RemoveDocSelectionListener(nsIPresShell* aPresShell)
 {
-  nsCOMPtr<nsISelectionController> selCon = do_QueryInterface(aShell);
-  NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
+  const nsFrameSelection* frameSel = aPresShell->ConstFrameSelection();
 
-  nsCOMPtr<nsISelection> domSel;
-  selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(domSel));
-  nsCOMPtr<nsISelectionPrivate> selPrivate = do_QueryInterface(domSel);
-  NS_ENSURE_TRUE(selPrivate, NS_ERROR_FAILURE);
-
-  selPrivate->RemoveSelectionListener(this);
+  // Remove 'this' registered as selection listener for the normal selection.
+  Selection* normalSel =
+    frameSel->GetSelection(nsISelectionController::SELECTION_NORMAL);
+  normalSel->RemoveSelectionListener(this);
 
-  nsCOMPtr<nsISelection> spellcheckSel;
-  selCon->GetSelection(nsISelectionController::SELECTION_SPELLCHECK,
-                       getter_AddRefs(spellcheckSel));
-  selPrivate = do_QueryInterface(spellcheckSel);
-  NS_ENSURE_TRUE(selPrivate, NS_ERROR_FAILURE);
-
-  return selPrivate->RemoveSelectionListener(this);
+  // Remove 'this' registered as selection listener for the spellcheck
+  // selection.
+  Selection* spellSel =
+    frameSel->GetSelection(nsISelectionController::SELECTION_SPELLCHECK);
+  spellSel->RemoveSelectionListener(this);
 }
 
 NS_IMETHODIMP
-nsCaretAccessible::NotifySelectionChanged(nsIDOMDocument* aDOMDocument,
-                                          nsISelection* aSelection,
-                                          int16_t aReason)
+SelectionManager::NotifySelectionChanged(nsIDOMDocument* aDOMDocument,
+                                         nsISelection* aSelection,
+                                         int16_t aReason)
 {
   NS_ENSURE_ARG(aDOMDocument);
-  NS_ENSURE_STATE(mRootAccessible);
 
   nsCOMPtr<nsIDocument> documentNode(do_QueryInterface(aDOMDocument));
   DocAccessible* document = GetAccService()->GetDocAccessible(documentNode);
 
 #ifdef A11Y_LOG
   if (logging::IsEnabled(logging::eSelection))
     logging::SelChange(aSelection, document);
 #endif
 
   // Don't fire events until document is loaded.
   if (document && document->IsContentLoaded()) {
-    // The caret accessible has the same lifetime as the root accessible, and
-    // this outlives all its descendant document accessibles, so that we are
-    // guaranteed that the notification is processed before the caret accessible
-    // is destroyed.
-    document->HandleNotification<nsCaretAccessible, nsISelection>
-      (this, &nsCaretAccessible::ProcessSelectionChanged, aSelection);
+    // Selection manager has longer lifetime than any document accessible,
+    // so that we are guaranteed that the notification is processed before
+    // the selection manager is destroyed.
+    document->HandleNotification<SelectionManager, nsISelection>
+      (this, &SelectionManager::ProcessSelectionChanged, aSelection);
   }
 
   return NS_OK;
 }
 
 void
-nsCaretAccessible::ProcessSelectionChanged(nsISelection* aSelection)
+SelectionManager::ProcessSelectionChanged(nsISelection* aSelection)
 {
   nsCOMPtr<nsISelectionPrivate> privSel(do_QueryInterface(aSelection));
 
   int16_t type = 0;
   privSel->GetType(&type);
 
   if (type == nsISelectionController::SELECTION_NORMAL)
     NormalSelectionChanged(aSelection);
 
   else if (type == nsISelectionController::SELECTION_SPELLCHECK)
     SpellcheckSelectionChanged(aSelection);
 }
 
 void
-nsCaretAccessible::NormalSelectionChanged(nsISelection* aSelection)
+SelectionManager::NormalSelectionChanged(nsISelection* aSelection)
 {
   mLastUsedSelection = do_GetWeakReference(aSelection);
 
   int32_t rangeCount = 0;
   aSelection->GetRangeCount(&rangeCount);
   if (rangeCount == 0) {
     mLastTextAccessible = nullptr;
     return; // No selection
@@ -243,17 +200,17 @@ nsCaretAccessible::NormalSelectionChange
   mLastCaretOffset = caretOffset;
   mLastTextAccessible = textAcc;
 
   nsRefPtr<AccEvent> event = new AccCaretMoveEvent(mLastTextAccessible);
   mLastTextAccessible->Document()->FireDelayedEvent(event);
 }
 
 void
-nsCaretAccessible::SpellcheckSelectionChanged(nsISelection* aSelection)
+SelectionManager::SpellcheckSelectionChanged(nsISelection* aSelection)
 {
   // XXX: fire an event for accessible of focus node of the selection. If
   // spellchecking is enabled then we will fire the number of events for
   // the same accessible for newly appended range of the selection (for every
   // misspelled word). If spellchecking is disabled (for example,
   // @spellcheck="false" on html:body) then we won't fire any event.
 
   HyperTextAccessible* hyperText =
@@ -261,22 +218,21 @@ nsCaretAccessible::SpellcheckSelectionCh
   if (hyperText) {
     hyperText->Document()->
       FireDelayedEvent(nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED,
                        hyperText);
   }
 }
 
 nsIntRect
-nsCaretAccessible::GetCaretRect(nsIWidget **aOutWidget)
+SelectionManager::GetCaretRect(nsIWidget** aWidget)
 {
   nsIntRect caretRect;
-  NS_ENSURE_TRUE(aOutWidget, caretRect);
-  *aOutWidget = nullptr;
-  NS_ENSURE_TRUE(mRootAccessible, caretRect);
+  NS_ENSURE_TRUE(aWidget, caretRect);
+  *aWidget = nullptr;
 
   if (!mLastTextAccessible) {
     return caretRect;    // Return empty rect
   }
 
   nsINode *lastNodeWithCaret = mLastTextAccessible->GetNode();
   NS_ENSURE_TRUE(lastNodeWithCaret, caretRect);
 
@@ -299,53 +255,29 @@ nsCaretAccessible::GetCaretRect(nsIWidge
   nsIFrame* frame = caret->GetGeometry(caretSelection, &rect);
   if (!frame || rect.IsEmpty()) {
     return nsIntRect(); // Return empty rect
   }
 
   nsPoint offset;
   // Offset from widget origin to the frame origin, which includes chrome
   // on the widget.
-  *aOutWidget = frame->GetNearestWidget(offset);
-  NS_ENSURE_TRUE(*aOutWidget, nsIntRect());
+  *aWidget = frame->GetNearestWidget(offset);
+  NS_ENSURE_TRUE(*aWidget, nsIntRect());
   rect.MoveBy(offset);
 
   caretRect = rect.ToOutsidePixels(frame->PresContext()->AppUnitsPerDevPixel());
   // ((content screen origin) - (content offset in the widget)) = widget origin on the screen
-  caretRect.MoveBy((*aOutWidget)->WidgetToScreenOffset() - (*aOutWidget)->GetClientOffset());
+  caretRect.MoveBy((*aWidget)->WidgetToScreenOffset() - (*aWidget)->GetClientOffset());
 
   // Correct for character size, so that caret always matches the size of the character
   // This is important for font size transitions, and is necessary because the Gecko caret uses the
   // previous character's size as the user moves forward in the text by character.
   int32_t charX, charY, charWidth, charHeight;
   if (NS_SUCCEEDED(mLastTextAccessible->GetCharacterExtents(mLastCaretOffset, &charX, &charY,
                                                             &charWidth, &charHeight,
                                                             nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE))) {
     caretRect.height -= charY - caretRect.y;
     caretRect.y = charY;
   }
 
   return caretRect;
 }
-
-already_AddRefed<nsISelectionController>
-nsCaretAccessible::GetSelectionControllerForNode(nsIContent *aContent)
-{
-  if (!aContent)
-    return nullptr;
-
-  nsIPresShell *presShell = aContent->OwnerDoc()->GetShell();
-  if (!presShell)
-    return nullptr;
-
-  nsIFrame *frame = aContent->GetPrimaryFrame();
-  if (!frame)
-    return nullptr;
-
-  nsPresContext *presContext = presShell->GetPresContext();
-  if (!presContext)
-    return nullptr;
-
-  nsISelectionController *controller = nullptr;
-  frame->GetSelectionController(presContext, &controller);
-  return controller;
-}
-
rename from accessible/src/base/nsCaretAccessible.h
rename to accessible/src/base/SelectionManager.h
--- a/accessible/src/base/nsCaretAccessible.h
+++ b/accessible/src/base/SelectionManager.h
@@ -1,90 +1,91 @@
 /* -*- Mode: C++; tab-width: 4; 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 __nsCaretAccessible_h__
-#define __nsCaretAccessible_h__
+#ifndef mozilla_a11y_SelectionManager_h__
+#define mozilla_a11y_SelectionManager_h__
 
-#include "HyperTextAccessible.h"
-
+#include "nsAutoPtr.h"
 #include "nsISelectionListener.h"
 
-/*
- * This special accessibility class is for the caret, which is really the currently focused selection.
- * There is only 1 visible caret per top level window (RootAccessible),
- * However, there may be several visible selections.
- *
- * The important selections are the one owned by each document, and the one in the currently focused control.
+class nsIContent;
+class nsIntRect;
+class nsIPresShell;
+class nsIWeakReference;
+class nsIWidget;
+
+namespace mozilla {
+
+namespace dom {
+class Element;
+}
+
+namespace a11y {
+
+class HyperTextAccessible;
+
+/**
+ * This special accessibility class is for the caret and selection management.
+ * There is only 1 visible caret per top level window. However, there may be
+ * several visible selections.
  *
- * The caret accessible is no longer an accessible object in its own right.
- * On Windows it is used to move an invisible system caret that shadows the Mozilla caret. Windows will
- * also automatically map this to the MSAA caret accessible object (via OBJID_CARET).
- * (as opposed to the root accessible tree for a window which is retrieved with OBJID_CLIENT)
- * For ATK and Iaccessible2, the caret accessible is used to fire
- * caret move and selection change events.
+ * The important selections are the one owned by each document, and the one in
+ * the currently focused control.
  *
- * The caret accessible is owned by the RootAccessible for the top level window that it's in.
- * The RootAccessible needs to tell the nsCaretAccessible about focus changes via
- * setControlSelectionListener().
- * Each DocAccessible needs to tell the nsCaretAccessible owned by the root to
- * listen for selection events via addDocSelectionListener() and then needs to remove the 
- * selection listener when the doc goes away via removeDocSelectionListener().
+ * On Windows this class is used to move an invisible system caret that
+ * shadows the Mozilla caret. Windows will also automatically map this to
+ * the MSAA caret accessible object (via OBJID_CARET) (as opposed to the root
+ * accessible tree for a window which is retrieved with OBJID_CLIENT).
+ *
+ * For ATK and IAccessible2, this class is used to fire caret move and
+ * selection change events.
  */
 
-class nsCaretAccessible : public nsISelectionListener
+class SelectionManager : public nsISelectionListener
 {
 public:
-  NS_DECL_ISUPPORTS
+  // nsISupports
+  // implemented by derived nsAccessibilityService
 
-  nsCaretAccessible(mozilla::a11y::RootAccessible* aRootAccessible);
-  virtual ~nsCaretAccessible();
+  // nsISelectionListener
+  NS_DECL_NSISELECTIONLISTENER
+
+  // SelectionManager
   void Shutdown();
 
-  /* ----- nsISelectionListener ---- */
-  NS_DECL_NSISELECTIONLISTENER
-
   /**
    * Listen to selection events on the focused control.
-   * Only one control's selection events are listened to at a time, per top-level window.
-   * This will remove the previous control's selection listener.
-   * It will fail if aFocusedNode is a document node -- document selection must be listened
-   * to via AddDocSelectionListener().
-   * @param aFocusedNode   The node for the focused control
+   *
+   * Note: only one control's selection events are listened to at a time. This
+   * will remove the previous control's selection listener.
    */
-  nsresult SetControlSelectionListener(nsIContent *aCurrentNode);
+  void SetControlSelectionListener(dom::Element* aFocusedElm);
 
   /**
-   * Stop listening to selection events for any control.
-   * This does not have to be called explicitly in Shutdown() procedures,
-   * because the nsCaretAccessible implementation guarantees that.
+   * Stop listening to selection events on the control.
    */
-  nsresult ClearControlSelectionListener();
+  void ClearControlSelectionListener();
 
   /**
-   * Start listening to selection events for a given document
-   * More than one document's selection events can be listened to
-   * at the same time, by a given nsCaretAccessible
-   * @param aShell   PresShell for document to listen to selection events from.
+   * Listen to selection events on the document.
    */
-  nsresult AddDocSelectionListener(nsIPresShell *aShell);
+  void AddDocSelectionListener(nsIPresShell* aPresShell);
 
   /**
    * Stop listening to selection events for a given document
-   * If the document goes away, this method needs to be called for 
-   * that document by the owner of the caret. We use presShell because
-   * instead of document because it is more direct than getting it from
-   * the document, and in any case it is unavailable from the doc after a pagehide.
-   * @param aShell   PresShell for document to no longer listen to selection events from.
    */
-  nsresult RemoveDocSelectionListener(nsIPresShell *aShell);
+  void RemoveDocSelectionListener(nsIPresShell* aShell);
 
-  nsIntRect GetCaretRect(nsIWidget **aOutWidget);
+  /**
+   * Return the caret rect and the widget containing the caret.
+   */
+  nsIntRect GetCaretRect(nsIWidget** aWidget);
 
 protected:
   /**
    * Process DOM selection change. Fire selection and caret move events.
    */
   void ProcessSelectionChanged(nsISelection* aSelection);
 
   /**
@@ -93,34 +94,24 @@ protected:
   void NormalSelectionChanged(nsISelection* aSelection);
 
   /**
    * Process spellcheck selection change and fire text attribute changed event
    * for invalid text attribute.
    */
   void SpellcheckSelectionChanged(nsISelection* aSelection);
 
-  /**
-   * Return selection controller for the given node.
-   */
-  already_AddRefed<nsISelectionController>
-    GetSelectionControllerForNode(nsIContent *aNode);
-
 private:
-  // The currently focused control -- never a document.
-  // We listen to selection for one control at a time (the focused one)
-  // Document selection is handled separately via additional listeners on all active documents
-  // The current control is set via SetControlSelectionListener()
-
   // Currently focused control.
   nsCOMPtr<nsIContent> mCurrentControl;
 
   // 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<mozilla::a11y::HyperTextAccessible> mLastTextAccessible;
+  nsRefPtr<HyperTextAccessible> mLastTextAccessible;
   int32_t mLastCaretOffset;
-
-  mozilla::a11y::RootAccessible* mRootAccessible;
 };
 
+} // namespace a11y
+} // namespace mozilla
+
 #endif
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -136,21 +136,22 @@ nsAccessibilityService::~nsAccessibility
 {
   NS_ASSERTION(gIsShutdown, "Accessibility wasn't shutdown!");
   gAccessibilityService = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports
 
-NS_IMPL_ISUPPORTS_INHERITED3(nsAccessibilityService,
+NS_IMPL_ISUPPORTS_INHERITED4(nsAccessibilityService,
                              DocManager,
                              nsIAccessibilityService,
                              nsIAccessibleRetrieval,
-                             nsIObserver)
+                             nsIObserver,
+                             nsISelectionListener) // from SelectionManager
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIObserver
 
 NS_IMETHODIMP
 nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
                          const PRUnichar *aData)
 {
@@ -1019,16 +1020,18 @@ nsAccessibilityService::Shutdown()
 
     static const PRUnichar kShutdownIndicator[] = { '0', 0 };
     observerService->NotifyObservers(nullptr, "a11y-init-or-shutdown", kShutdownIndicator);
   }
 
   // Stop accessible document loader.
   DocManager::Shutdown();
 
+  SelectionManager::Shutdown();
+
   // Application is going to be closed, shutdown accessibility and mark
   // accessibility service as shutdown to prevent calls of its methods.
   // Don't null accessibility service static member at this point to be safe
   // if someone will try to operate with it.
 
   NS_ASSERTION(!gIsShutdown, "Accessibility was shutdown already");
 
   gIsShutdown = true;
@@ -1603,16 +1606,22 @@ namespace mozilla {
 namespace a11y {
 
 FocusManager*
 FocusMgr()
 {
   return nsAccessibilityService::gAccessibilityService;
 }
 
+SelectionManager*
+SelectionMgr()
+{
+  return nsAccessibilityService::gAccessibilityService;
+}
+
 ApplicationAccessible*
 ApplicationAcc()
 {
   return nsAccessibilityService::gApplicationAccessible;
 }
 
 EPlatformDisabledState
 PlatformDisabledState()
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -5,16 +5,17 @@
 
 #ifndef __nsAccessibilityService_h__
 #define __nsAccessibilityService_h__
 
 #include "nsIAccessibilityService.h"
 
 #include "mozilla/a11y/DocManager.h"
 #include "mozilla/a11y/FocusManager.h"
+#include "mozilla/a11y/SelectionManager.h"
 
 #include "nsIObserver.h"
 
 class nsImageFrame;
 class nsObjectFrame;
 class nsITreeView;
 
 namespace mozilla {
@@ -23,25 +24,31 @@ namespace a11y {
 class ApplicationAccessible;
 
 /**
  * Return focus manager.
  */
 FocusManager* FocusMgr();
 
 /**
+ * Return selection manager.
+ */
+SelectionManager* SelectionMgr();
+
+/**
  * Returns the application accessible.
  */
 ApplicationAccessible* ApplicationAcc();
 
 } // namespace a11y
 } // namespace mozilla
 
 class nsAccessibilityService : public mozilla::a11y::DocManager,
                                public mozilla::a11y::FocusManager,
+                               public mozilla::a11y::SelectionManager,
                                public nsIAccessibilityService,
                                public nsIObserver
 {
 public:
   typedef mozilla::a11y::Accessible Accessible;
   typedef mozilla::a11y::DocAccessible DocAccessible;
 
   virtual ~nsAccessibilityService();
@@ -206,16 +213,17 @@ private:
 
   /**
    * Indicates whether accessibility service was shutdown.
    */
   static bool gIsShutdown;
 
   friend nsAccessibilityService* GetAccService();
   friend mozilla::a11y::FocusManager* mozilla::a11y::FocusMgr();
+  friend mozilla::a11y::SelectionManager* mozilla::a11y::SelectionMgr();
   friend mozilla::a11y::ApplicationAccessible* mozilla::a11y::ApplicationAcc();
 
   friend nsresult NS_GetAccessibilityService(nsIAccessibilityService** aResult);
 };
 
 /**
  * Return the accessibility service instance. (Handy global function)
  */
--- a/accessible/src/generic/DocAccessible.cpp
+++ b/accessible/src/generic/DocAccessible.cpp
@@ -700,21 +700,17 @@ DocAccessible::AddEventListeners()
   int32_t itemType;
   docShellTreeItem->GetItemType(&itemType);
   if (itemType == nsIDocShellTreeItem::typeContent) {
     nsCOMPtr<nsICommandManager> commandManager = do_GetInterface(docShellTreeItem);
     if (commandManager)
       commandManager->AddCommandObserver(this, "obs_documentCreated");
   }
 
-  a11y::RootAccessible* rootAccessible = RootAccessible();
-  NS_ENSURE_TRUE(rootAccessible, NS_ERROR_FAILURE);
-  nsRefPtr<nsCaretAccessible> caretAccessible = rootAccessible->GetCaretAccessible();
-  if (caretAccessible)
-    caretAccessible->AddDocSelectionListener(mPresShell);
+  SelectionMgr()->AddDocSelectionListener(mPresShell);
 
   // Add document observer.
   mDocumentNode->AddObserver(this);
   return NS_OK;
 }
 
 // DocAccessible protected member
 nsresult
@@ -746,23 +742,17 @@ DocAccessible::RemoveEventListeners()
   }
 
   if (mScrollWatchTimer) {
     mScrollWatchTimer->Cancel();
     mScrollWatchTimer = nullptr;
     NS_RELEASE_THIS(); // Kung fu death grip
   }
 
-  a11y::RootAccessible* rootAccessible = RootAccessible();
-  if (rootAccessible) {
-    nsRefPtr<nsCaretAccessible> caretAccessible = rootAccessible->GetCaretAccessible();
-    if (caretAccessible)
-      caretAccessible->RemoveDocSelectionListener(mPresShell);
-  }
-
+  SelectionMgr()->RemoveDocSelectionListener(mPresShell);
   return NS_OK;
 }
 
 void
 DocAccessible::ScrollTimerCallback(nsITimer* aTimer, void* aClosure)
 {
   DocAccessible* docAcc = reinterpret_cast<DocAccessible*>(aClosure);
 
--- a/accessible/src/generic/RootAccessible.cpp
+++ b/accessible/src/generic/RootAccessible.cpp
@@ -192,20 +192,16 @@ RootAccessible::AddEventListeners()
                    * const* e_end = ArrayEnd(kEventTypes);
          e < e_end; ++e) {
       nsresult rv = nstarget->AddEventListener(NS_ConvertASCIItoUTF16(*e),
                                                this, true, true, 2);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
-  if (!mCaretAccessible) {
-    mCaretAccessible = new nsCaretAccessible(this);
-  }
-
   return DocAccessible::AddEventListeners();
 }
 
 nsresult
 RootAccessible::RemoveEventListeners()
 {
   nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(mDocumentNode));
   if (target) { 
@@ -215,34 +211,22 @@ RootAccessible::RemoveEventListeners()
       nsresult rv = target->RemoveEventListener(NS_ConvertASCIItoUTF16(*e), this, true);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   // Do this before removing clearing caret accessible, so that it can use
   // shutdown the caret accessible's selection listener
   DocAccessible::RemoveEventListeners();
-
-  if (mCaretAccessible) {
-    mCaretAccessible->Shutdown();
-    mCaretAccessible = nullptr;
-  }
-
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // public
 
-nsCaretAccessible*
-RootAccessible::GetCaretAccessible()
-{
-  return mCaretAccessible;
-}
-
 void
 RootAccessible::DocumentActivated(DocAccessible* aDocument)
 {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIDOMEventListener
 
--- a/accessible/src/generic/RootAccessible.h
+++ b/accessible/src/generic/RootAccessible.h
@@ -1,21 +1,20 @@
 /* -*- 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 mozilla_a11y_RootAccessible_h__
 #define mozilla_a11y_RootAccessible_h__
 
-#include "nsCaretAccessible.h"
+#include "HyperTextAccessible.h"
 #include "DocAccessibleWrap.h"
 
 #include "nsHashtable.h"
-#include "nsCaretAccessible.h"
 #include "nsIDocument.h"
 #include "nsIDOMEventListener.h"
 
 namespace mozilla {
 namespace a11y {
 
 class RootAccessible : public DocAccessibleWrap,
                        public nsIDOMEventListener
@@ -35,17 +34,16 @@ public:
 
   // Accessible
   virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
   virtual Relation RelationByType(uint32_t aType);
   virtual mozilla::a11y::role NativeRole();
   virtual uint64_t NativeState();
 
   // RootAccessible
-  nsCaretAccessible* GetCaretAccessible();
 
   /**
    * Notify that the sub document presshell was activated.
    */
   virtual void DocumentActivated(DocAccessible* aDocument);
 
 protected:
 
@@ -73,18 +71,16 @@ protected:
 #ifdef MOZ_XUL
     void HandleTreeRowCountChangedEvent(nsIDOMEvent* aEvent,
                                         XULTreeAccessible* aAccessible);
     void HandleTreeInvalidatedEvent(nsIDOMEvent* aEvent,
                                     XULTreeAccessible* aAccessible);
 
     uint32_t GetChromeFlags();
 #endif
-
-    nsRefPtr<nsCaretAccessible> mCaretAccessible;
 };
 
 inline RootAccessible*
 Accessible::AsRoot()
 {
   return IsRoot() ? static_cast<mozilla::a11y::RootAccessible*>(this) : nullptr;
 }
 
--- a/accessible/src/windows/msaa/AccessibleWrap.cpp
+++ b/accessible/src/windows/msaa/AccessibleWrap.cpp
@@ -1775,23 +1775,18 @@ AccessibleWrap::UpdateSystemCaret()
   // off-screen model can follow the caret
   ::DestroyCaret();
 
   a11y::RootAccessible* rootAccessible = RootAccessible();
   if (!rootAccessible) {
     return;
   }
 
-  nsRefPtr<nsCaretAccessible> caretAccessible = rootAccessible->GetCaretAccessible();
-  if (!caretAccessible) {
-    return;
-  }
-
-  nsIWidget *widget;
-  nsIntRect caretRect = caretAccessible->GetCaretRect(&widget);
+  nsIWidget* widget = nullptr;
+  nsIntRect caretRect = SelectionMgr()->GetCaretRect(&widget);
   HWND caretWnd; 
   if (caretRect.IsEmpty() || !(caretWnd = (HWND)widget->GetNativeData(NS_NATIVE_WINDOW))) {
     return;
   }
 
   // Create invisible bitmap for caret, otherwise its appearance interferes
   // with Gecko caret
   HBITMAP caretBitMap = CreateBitmap(1, caretRect.height, 1, 1, NULL);
--- a/accessible/tests/mochitest/focus/test_takeFocus.html
+++ b/accessible/tests/mochitest/focus/test_takeFocus.html
@@ -37,38 +37,41 @@
       {
         return "takeFocus for " + prettyName(aID);
       }
     }
 
     ////////////////////////////////////////////////////////////////////////////
     // Test
 
-    gA11yEventDumpToConsole = true; // debug stuff
+    //gA11yEventDumpToConsole = true; // debug stuff
 
     var gQueue = null;
     function doTest()
     {
-      enableLogging("tree");
       gQueue = new eventQueue();
 
       gQueue.push(new takeFocusInvoker("aria-link"));
       gQueue.push(new takeFocusInvoker("aria-link2"));
       gQueue.push(new takeFocusInvoker("link"));
       gQueue.push(new takeFocusInvoker("item2"));
       gQueue.push(new takeFocusInvoker("plugin"));
       gQueue.push(new takeFocusInvoker(document));
       gQueue.push(new takeFocusInvoker("lb_item2"));
 
-      gQueue.onFinish = function() { disableLogging(); }
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
+    function waitForPlugin()
+    {
+      window.setTimeout((isAccessible("plugin") ? doTest : waitForPlugin), 0);
+    }
+
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
+    addA11yLoadEvent(waitForPlugin);
   </script>
 </head>
 
 <body>
 
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=429547"
      title="Support aria-activedescendant usage in nsIAccesible::TakeFocus()">
@@ -92,17 +95,17 @@
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <span id="aria-link" role="link" tabindex="0">link</span>
   <span id="aria-link2" role="link" tabindex="0">link</span>
 
-  <a id="link" href="">link</span>
+  <a id="link" href="">link</a>
 
   <div role="listbox" aria-activedescendant="item1" id="container" tabindex="1">
     <div role="option" id="item1">item1</div>
     <div role="option" id="item2">item2</div>
     <div role="option" id="item3">item3</div>
   </div>
 
   <embed id="plugin" type="application/x-test" width="200" height="200" wmode="window"></embed>
--- a/accessible/tests/mochitest/focus/test_takeFocus.xul
+++ b/accessible/tests/mochitest/focus/test_takeFocus.xul
@@ -54,18 +54,16 @@
     // Tests
 
     //gA11yEventDumpID = "eventdump"; // debug stuff
     //gA11yEventDumpToConsole = true; // debug stuff
 
     var gQueue = null;
     function doTests()
     {
-      disableLogging(); // from test_takeFocus.html
-
       // Test focus events.
       gQueue = new eventQueue();
 
       gQueue.push(new takeFocusInvoker("tree", getLastChild));
       gQueue.push(new takeFocusInvoker("listitem2"));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
--- a/accessible/tests/mochitest/states/test_tree.xul
+++ b/accessible/tests/mochitest/states/test_tree.xul
@@ -30,21 +30,23 @@
 
     /**
      * Event queue invoker object to test accessible states for XUL tree
      * accessible.
      */
     function statesChecker(aTreeID, aView)
     {
       this.DOMNode = getNode(aTreeID);
-      this.invoke = function invoke()
+
+      this.invoke = function statesChecker_invoke()
       {
         this.DOMNode.treeBoxObject.view = aView;
       }
-      this.check = function check()
+
+      this.check = function statesChecker_check()
       {
         var tree = getAccessible(this.DOMNode);
 
         // tree states
         testStates(tree, STATE_READONLY);
 
         if (this.DOMNode.getAttribute("seltype") != "single")
           testStates(tree, STATE_MULTISELECTABLE);
@@ -67,19 +69,20 @@
             var cell = cells.queryElementAt(idx, nsIAccessible);
             testStates(cell, STATE_SELECTABLE);
           }
 
           var checkboxCell = cells.queryElementAt(3, nsIAccessible);
           testStates(checkboxCell, STATE_CHECKABLE | STATE_CHECKED);
         }
       }
-      this.getID = function getID()
+
+      this.getID = function statesChecker_getID()
       {
-        "tree processor for " + prettyName(aTreeID);
+        return "tree processor for " + prettyName(aTreeID);
       }
     }
 
     gA11yEventDumpToConsole = true; // debug stuff
 
     var gQueue = null;
 
     function doTest()
--- a/addon-sdk/Makefile.in
+++ b/addon-sdk/Makefile.in
@@ -4,16 +4,18 @@
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(topsrcdir)/config/config.mk
 
+export PYMAKE = $(.PYMAKE)
+
 libs::
 	$(PYTHON) $(srcdir)/copy_source.py $(topsrcdir) $(srcdir)/source/lib $(FINAL_TARGET)/modules/commonjs >copy_source.mk
 	$(MAKE) -f copy_source.mk libs
 
 include $(topsrcdir)/config/rules.mk
 
 TEST_FILES = \
   source/app-extension \
--- a/addon-sdk/copy_source.py
+++ b/addon-sdk/copy_source.py
@@ -1,21 +1,38 @@
 # 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/.
 
 import os
+import posixpath
 import sys
 
+
+def normpath(path):
+    """Ensure UNIX style paths are used with GNU make on Windows.
+
+    This can be removed once we no longer support GNU make on Windows (bug
+    828317).
+    """
+    if os.environ.get('PYMAKE') or os.name not in ('nt', 'ce'):
+        return path
+
+    if len(path) > 2 and path[1] == ':':
+        path = '/' + path[0] + path[2:]
+
+    return posixpath.normpath(path)
+
+
 if len(sys.argv) != 4:
     print >> sys.stderr, "Usage: copy_source.py " \
                          "<topsrcdir> <source directory> <target directory>"
     sys.exit(1)
 
-topsrcdir = sys.argv[1]
+topsrcdir = normpath(sys.argv[1])
 source_dir = sys.argv[2]
 target_dir = sys.argv[3]
 
 print """
 DEPTH     = ..
 topsrcdir = %(topsrcdir)s
 srcdir    = %(topsrcdir)s/addon-sdk
 VPATH     = %(topsrcdir)s/addon-sdk
--- a/b2g/chrome/content/forms.js
+++ b/b2g/chrome/content/forms.js
@@ -259,19 +259,24 @@ let FormAssistant = {
           this.showKeyboard(this.getTopLevelEditable(target));
           break;
         }
 
         if (this.isFocusableElement(target))
           this.showKeyboard(target);
         break;
 
+      case "pagehide":
+        // We are only interested to the pagehide event from the root document.
+        if (target && target != content.document) {
+          break;
+        }
+        // fall through
       case "blur":
       case "submit":
-      case "pagehide":
         if (this.focusedElement)
           this.hideKeyboard();
         break;
 
       case 'mousedown':
         // We only listen for this event on the currently focused element.
         // When the mouse goes down, note the cursor/selection position
         range = getSelectionRange(this.focusedElement);
--- a/b2g/components/Makefile.in
+++ b/b2g/components/Makefile.in
@@ -5,17 +5,16 @@
 DEPTH      = @DEPTH@
 topsrcdir  = @top_srcdir@
 srcdir     = @srcdir@
 VPATH      = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = B2GComponents
-XPIDL_MODULE = B2GComponents
 
 XPIDLSRCS = \
         b2g.idl \
         $(NULL)
 
 EXTRA_PP_COMPONENTS = \
         ActivitiesGlue.js \
         AlertsService.js \
--- a/b2g/config/otoro/releng-otoro.tt
+++ b/b2g/config/otoro/releng-otoro.tt
@@ -1,12 +1,12 @@
 [
 {
-"size": 896038748,
-"digest": "a153b55e13938c608d0d449073142322470aaf6c77375165df83dc845d9c357d0cf4754db3b058d4707442cd6252fe3076e81a22c32cb34bd3df6432ad5b99f1",
+"size": 896095824,
+"digest": "c19f6ab2af72a3156c60daf061c6845ab1ae2071cf04fadcfaa9dddb15f9f58d4a67022f8ec8a978ddf7f6f08e1bb86fdc35d5b5a935bb90dec983280d2878e2",
 "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
@@ -11,86 +11,86 @@
   <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="43434d6cdbf702e6197e0791f19406860284edf6">
     <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="c6fc2e70b2586fe45db4b676567be2aa94cf420e"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8e68d41728675fc72502dc572dec523c2c8abb8a"/>
   <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="62f94a26d34c1f1e1846efd58d34363c051e8c66"/>
 
   <!-- Stock Android things -->
-  <!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
+  <!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.032 --><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"/>
   <!-- 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.01.01.00.19.013 --><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_V1.01.00.01.19.032 --><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 A8064AAAAANLYA102313 --><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.013 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
+  <!-- Information: platform/external/bsdiff is tagged with M8930AAAAANLYA2217182 --><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.032 --><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 A8064AAAAANLYA102313 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
+  <!-- Information: platform/external/dnsmasq is tagged with M8930AAAAANLYA2217182 --><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.01.01.00.19.013 --><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.013 --><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.013 --><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.013 --><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.013 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
-  <!-- Information: platform/external/giflib is tagged with A8064AAAAANLYA102313 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
+  <!-- Information: platform/external/e2fsprogs is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.032 --><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.032 --><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.032 --><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.032 --><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.032 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
+  <!-- Information: platform/external/giflib is tagged with M8930AAAAANLYA2217182 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
   <project name="platform/external/gtest" path="external/gtest" remote="linaro" revision="8c212ebe53bb2baab3575f03069016f1fb11e449"/>
-  <!-- Information: platform/external/harfbuzz is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><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.013 --><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.013 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
+  <!-- Information: platform/external/harfbuzz is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.032 --><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.032 --><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.032 --><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 A8064AAAAANLYA102313 --><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.134 --><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.013 --><project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="3a912b065a31a72c63ad56ac224cfeaa933423b6"/>
-  <!-- Information: platform/external/libnl-headers is tagged with AU_LINUX_ANDROID_JB_MR1.04.02.02.49.134 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
+  <!-- Information: platform/external/libgsm is tagged with M8930AAAAANLYA2217182 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
+  <!-- Information: platform/external/liblzf is tagged with M8930AAAAANLYA2217182 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
+  <!-- Information: platform/external/libnfc-nxp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.032 --><project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="3a912b065a31a72c63ad56ac224cfeaa933423b6"/>
+  <!-- Information: platform/external/libnl-headers is tagged with M8930AAAAANLYA2217182 --><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 A8064AAAAANLYA102313 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
-  <!-- Information: platform/external/safe-iop is tagged with A8064AAAAANLYA102313 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
+  <!-- Information: platform/external/protobuf is tagged with M8930AAAAANLYA2217182 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
+  <!-- Information: platform/external/safe-iop is tagged with M8930AAAAANLYA2217182 --><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 A8064AAAAANLYA102313 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
+  <!-- Information: platform/external/speex is tagged with M8930AAAAANLYA2217182 --><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.01.01.00.19.013 --><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.013 --><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.134 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
+  <!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.032 --><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.032 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
+  <!-- Information: platform/external/tagsoup is tagged with M8930AAAAANLYA2217182 --><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 A8064AAAAANLYA102313 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
+  <!-- Information: platform/external/tremolo is tagged with M8930AAAAANLYA2217182 --><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 A8064AAAAANLYA102313 --><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.013 --><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.013 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
+  <!-- Information: platform/external/webp is tagged with M8930AAAAANLYA2217182 --><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.032 --><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.032 --><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.01.01.00.19.013 --><project name="platform/external/yaffs2" path="external/yaffs2" revision="0afa916204c664b3114429637b63af1321a0aeca"/>
+  <!-- Information: platform/external/yaffs2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.032 --><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.01.01.00.19.013 --><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_V1.01.00.01.19.032 --><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.01.01.00.19.013 --><project name="platform/ndk" path="ndk" revision="9f555971e1481854d5b4dc11b3e6af9fff4f241f"/>
+  <!-- Information: platform/ndk is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.032 --><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"/>
 
--- a/b2g/config/unagi/releng-unagi.tt
+++ b/b2g/config/unagi/releng-unagi.tt
@@ -1,12 +1,12 @@
 [
 {
-"size": 832866776,
-"digest": "27b9e0754de94537d664d12f5e3a2767582ceedb4ee96eb06abe405e6e9b8a0937d56ffd84cb6ce4d197c25168124296806b1ad638175b004a11ab5293b99f08",
+"size": 832974796,
+"digest": "0d400c33d769af9573299628c8cc33516ffd21558e4625b4e4d4ce79c23293ea10a62dbd5a6056d2df3ca059bb5950309a667a64d08f35f896c2f30ae63285f6",
 "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
@@ -11,86 +11,86 @@
   <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="43434d6cdbf702e6197e0791f19406860284edf6">
     <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="8f016ce56fc7d7ef0aa7428ed509f6fb7cbde5b7"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="8e68d41728675fc72502dc572dec523c2c8abb8a"/>
   <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="62f94a26d34c1f1e1846efd58d34363c051e8c66"/>
 
   <!-- Stock Android things -->
-  <!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
+  <!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.032 --><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"/>
   <!-- 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.01.01.00.19.013 --><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_V1.01.00.01.19.032 --><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.01.01.00.19.013 --><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.013 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
+  <!-- Information: platform/external/bsdiff is tagged with M8930AAAAANLYA2217182 --><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.032 --><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.013 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
+  <!-- Information: platform/external/dnsmasq is tagged with M8930AAAAANLYA2217182 --><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.01.01.00.19.013 --><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.013 --><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.013 --><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.013 --><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.013 --><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.013 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
+  <!-- Information: platform/external/e2fsprogs is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.032 --><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.032 --><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.032 --><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.032 --><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.032 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
+  <!-- Information: platform/external/giflib is tagged with M8930AAAAANLYA2217182 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
   <project name="platform/external/gtest" path="external/gtest" remote="linaro" revision="8c212ebe53bb2baab3575f03069016f1fb11e449"/>
-  <!-- Information: platform/external/harfbuzz is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><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.013 --><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.013 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
+  <!-- Information: platform/external/harfbuzz is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.032 --><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.032 --><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.032 --><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.01.01.00.19.013 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
-  <!-- Information: platform/external/liblzf is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><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.013 --><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.01.01.00.19.013 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
+  <!-- Information: platform/external/libgsm is tagged with M8930AAAAANLYA2217182 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
+  <!-- Information: platform/external/liblzf is tagged with M8930AAAAANLYA2217182 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
+  <!-- Information: platform/external/libnfc-nxp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.032 --><project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="3a912b065a31a72c63ad56ac224cfeaa933423b6"/>
+  <!-- Information: platform/external/libnl-headers is tagged with M8930AAAAANLYA2217182 --><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.01.01.00.19.013 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
-  <!-- Information: platform/external/safe-iop is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
+  <!-- Information: platform/external/protobuf is tagged with M8930AAAAANLYA2217182 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
+  <!-- Information: platform/external/safe-iop is tagged with M8930AAAAANLYA2217182 --><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.01.01.00.19.013 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
+  <!-- Information: platform/external/speex is tagged with M8930AAAAANLYA2217182 --><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.01.01.00.19.013 --><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.013 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
-  <!-- Information: platform/external/tagsoup is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.01.00.19.013 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
+  <!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.032 --><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.032 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
+  <!-- Information: platform/external/tagsoup is tagged with M8930AAAAANLYA2217182 --><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.01.01.00.19.013 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
+  <!-- Information: platform/external/tremolo is tagged with M8930AAAAANLYA2217182 --><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.013 --><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.013 --><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.013 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
+  <!-- Information: platform/external/webp is tagged with M8930AAAAANLYA2217182 --><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.032 --><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.032 --><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.01.01.00.19.013 --><project name="platform/external/yaffs2" path="external/yaffs2" revision="0afa916204c664b3114429637b63af1321a0aeca"/>
+  <!-- Information: platform/external/yaffs2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.032 --><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.01.01.00.19.013 --><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_V1.01.00.01.19.032 --><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.01.01.00.19.013 --><project name="platform/ndk" path="ndk" revision="9f555971e1481854d5b4dc11b3e6af9fff4f241f"/>
+  <!-- Information: platform/ndk is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY_V1.01.00.01.19.032 --><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"/>
 
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1214,8 +1214,11 @@ pref("social.directories", "https://addo
 // necessary. This does not affect whitelisted and directory installs.
 pref("social.remote-install.enabled", true);
 
 pref("social.sidebar.open", true);
 pref("social.sidebar.unload_timeout_ms", 10000);
 pref("social.toast-notifications.enabled", true);
 
 pref("dom.identity.enabled", false);
+
+// Override the Gecko-default value of false for Firefox.
+pref("plain_text.wrap_long_lines", true);
--- a/browser/base/content/aboutDialog.js
+++ b/browser/base/content/aboutDialog.js
@@ -40,20 +40,22 @@ function init(aEvent)
     document.getElementById("version").textContent += " (" + buildDate + ")";
     document.getElementById("experimental").hidden = false;
     document.getElementById("communityDesc").hidden = true;
   }
 
 #ifdef MOZ_UPDATER
   gAppUpdater = new appUpdater();
 
+#if MOZ_UPDATE_CHANNEL != release
   let defaults = Services.prefs.getDefaultBranch("");
   let channelLabel = document.getElementById("currentChannel");
   channelLabel.value = defaults.getCharPref("app.update.channel");
 #endif
+#endif
 
 #ifdef XP_MACOSX
   // it may not be sized at this point, and we need its width to calculate its position
   window.sizeToContent();
   window.moveTo((screen.availWidth / 2) - (window.outerWidth / 2), screen.availHeight / 5);
 #endif
 }
 
--- a/browser/base/content/aboutDialog.xul
+++ b/browser/base/content/aboutDialog.xul
@@ -78,21 +78,23 @@
               </hbox>
               <hbox id="manualUpdate" align="center">
                 <label>&update.manual.start;</label><label id="manualLink" class="text-link"/><label>&update.manual.end;</label>
               </hbox>
             </deck>
 #endif
           </vbox>
 
+#if MOZ_UPDATE_CHANNEL != release
 #ifdef MOZ_UPDATER
           <description class="text-blurb" id="currentChannelText">
             &channel.description.start;<label id="currentChannel"/>&channel.description.end;
           </description>
 #endif
+#endif
           <vbox id="experimental" hidden="true">
             <description class="text-blurb" id="warningDesc">
               &warningDesc.version;
 #ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
               &warningDesc.telemetryDesc;
 #endif
             </description>
             <description class="text-blurb" id="communityExperimentalDesc">
--- a/browser/base/content/abouthealthreport/abouthealth.js
+++ b/browser/base/content/abouthealthreport/abouthealth.js
@@ -55,17 +55,17 @@ function updateView(state="default") {
 
 function refreshDataView(data) {
   let noData = document.getElementById("data-no-data");
   let dataEl = document.getElementById("raw-data");
 
   noData.style.display = data ? "none" : "inline";
   dataEl.style.display = data ? "block" : "none";
   if (data) {
-    dataEl.innerHTML = JSON.stringify(data, null, 2);
+    dataEl.textContent = JSON.stringify(data, null, 2);
   }
 }
 
 /**
  * Ensure the page has the latest version of the uploaded JSON payload.
  */
 function refreshJSONPayload() {
   reporter.getLastPayload().then(refreshDataView);
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -7,17 +7,16 @@ const PANEL_MIN_HEIGHT = 100;
 const PANEL_MIN_WIDTH = 330;
 
 XPCOMUtils.defineLazyModuleGetter(this, "SharedFrame",
   "resource:///modules/SharedFrame.jsm");
 
 let SocialUI = {
   // Called on delayed startup to initialize the UI
   init: function SocialUI_init() {
-    Services.obs.addObserver(this, "social:pref-changed", false);
     Services.obs.addObserver(this, "social:ambient-notification-changed", false);
     Services.obs.addObserver(this, "social:profile-changed", false);
     Services.obs.addObserver(this, "social:recommend-info-changed", false);
     Services.obs.addObserver(this, "social:frameworker-error", false);
     Services.obs.addObserver(this, "social:provider-set", false);
     Services.obs.addObserver(this, "social:providers-changed", false);
 
     Services.prefs.addObserver("social.sidebar.open", this, false);
@@ -32,99 +31,78 @@ let SocialUI = {
     });
 
     SocialChatBar.init();
     SocialShareButton.init();
     SocialMenu.init();
     SocialToolbar.init();
     SocialSidebar.init();
 
-    Social.init();
-    // If social was previously initialized it isn't going to notify observers
-    // about the provider being set or the list of providers changing, so
-    // handle those now.
-    if (Social.provider) {
-      this.observe(null, "social:provider-set", Social.provider.origin);
+    if (!Social.initialized) {
+      Social.init();
+    } else {
+      // social was previously initialized, so it's not going to notify us of
+      // anything, so handle that now.
       this.observe(null, "social:providers-changed", null);
+      this.observe(null, "social:provider-set", Social.provider ? Social.provider.origin : null);
     }
   },
 
   // Called on window unload
   uninit: function SocialUI_uninit() {
-    Services.obs.removeObserver(this, "social:pref-changed");
     Services.obs.removeObserver(this, "social:ambient-notification-changed");
     Services.obs.removeObserver(this, "social:profile-changed");
     Services.obs.removeObserver(this, "social:recommend-info-changed");
     Services.obs.removeObserver(this, "social:frameworker-error");
     Services.obs.removeObserver(this, "social:provider-set");
     Services.obs.removeObserver(this, "social:providers-changed");
 
     Services.prefs.removeObserver("social.sidebar.open", this);
     Services.prefs.removeObserver("social.toast-notifications.enabled", this);
   },
 
-  // Social.provider has changed, update any state that depends on it.
-  // Note: this method is not called when Social.provider is first set, during
-  // the first window load.
-  _updateProvider: function () {
-    // XXX audit for handling nullness of social.provider
-    this._updateActiveUI();
-    this._updateMenuItems();
-
-    SocialChatBar.update();
-    SocialShareButton.updateProvider();
-    SocialMenu.populate();
-    SocialToolbar.updateProvider();
-    SocialSidebar.update();
-  },
-
-  // The entire feature is being turned on/off.
-  _updateEnabledState: function () {
-    this._updateActiveUI();
-    SocialChatBar.update();
-    SocialSidebar.update();
-    SocialShareButton.updateButtonHiddenState();
-    SocialMenu.populate();
-    SocialToolbar.updateButtonHiddenState();
-    SocialToolbar.populateProviderMenus();
-  },
-
   _matchesCurrentProvider: function (origin) {
     return Social.provider && Social.provider.origin == origin;
   },
 
   observe: function SocialUI_observe(subject, topic, data) {
     // Exceptions here sometimes don't get reported properly, report them
     // manually :(
     try {
       switch (topic) {
         case "social:provider-set":
-          this._updateProvider();
+          // Social.provider has changed (possibly to null), update any state
+          // which depends on it.
+          this._updateActiveUI();
+          this._updateMenuItems();
+
+          SocialChatBar.update();
+          SocialSidebar.update();
+          SocialShareButton.update();
+          SocialToolbar.update();
+          SocialMenu.populate();
           break;
         case "social:providers-changed":
           // the list of providers changed - this may impact the "active" UI.
           this._updateActiveUI();
           // and the multi-provider menu
           SocialToolbar.populateProviderMenus();
           break;
-        case "social:pref-changed":
-          this._updateEnabledState();
-          break;
 
         // Provider-specific notifications
         case "social:ambient-notification-changed":
           if (this._matchesCurrentProvider(data)) {
             SocialToolbar.updateButton();
             SocialMenu.populate();
           }
           break;
         case "social:profile-changed":
           if (this._matchesCurrentProvider(data)) {
             SocialToolbar.updateProfile();
-            SocialShareButton.updateProfileInfo();
+            SocialShareButton.update();
             SocialChatBar.update();
           }
           break;
         case "social:recommend-info-changed":
           if (this._matchesCurrentProvider(data)) {
             SocialShareButton.updateShareState();
           }
           break;
@@ -590,41 +568,32 @@ let SocialFlyout = {
 }
 
 let SocialShareButton = {
   // Called once, after window load, when the Social.provider object is initialized
   init: function SSB_init() {
   },
 
   // Called when the Social.provider changes
-  updateProvider: function () {
-    this.updateButtonHiddenState();
-    if (!Social.provider)
-      return;
-    this.updateProfileInfo();
-  },
-
-  // Called when the provider's profile info changes (or when the provider
-  // changes, via updateProvider)
-  updateProfileInfo: function SSB_updateProfileInfo() {
+  update: function() {
+    this._updateButtonHiddenState();
     let profileRow = document.getElementById("unsharePopupHeader");
     let profile = SocialUI.enabled ? Social.provider.profile : null;
     if (profile && profile.displayName) {
       profileRow.hidden = false;
       let portrait = document.getElementById("socialUserPortrait");
       if (profile.portrait) {
         portrait.setAttribute("src", profile.portrait);
       } else {
         portrait.removeAttribute("src");
       }
       let displayName = document.getElementById("socialUserDisplayName");
       displayName.setAttribute("label", profile.displayName);
     } else {
       profileRow.hidden = true;
-      this.updateButtonHiddenState();
     }
   },
 
   get shareButton() {
     return document.getElementById("share-button");
   },
   get unsharePopup() {
     return document.getElementById("unsharePopup");
@@ -634,17 +603,17 @@ let SocialShareButton = {
     this.unsharePopup.hidePopup();
   },
 
   canSharePage: function SSB_canSharePage(aURI) {
     // We only allow sharing of http or https
     return aURI && (aURI.schemeIs('http') || aURI.schemeIs('https'));
   },
 
-  updateButtonHiddenState: function SSB_updateButtonHiddenState() {
+  _updateButtonHiddenState: function SSB_updateButtonHiddenState() {
     let shareButton = this.shareButton;
     if (shareButton)
       shareButton.hidden = !SocialUI.enabled || Social.provider.recommendInfo == null ||
                            !Social.haveLoggedInUser() ||
                            !this.canSharePage(gBrowser.currentURI);
 
     // also update the relevent command's disabled state so the keyboard
     // shortcut only works when available.
@@ -698,17 +667,17 @@ let SocialShareButton = {
 
   unsharePage: function SSB_unsharePage() {
     Social.unsharePage(gBrowser.currentURI);
     this.updateShareState();
     this.dismissUnsharePopup();
   },
 
   updateShareState: function SSB_updateShareState() {
-    this.updateButtonHiddenState();
+    this._updateButtonHiddenState();
 
     let shareButton = this.shareButton;
     let currentPageShared = shareButton && !shareButton.hidden && Social.isPageShared(gBrowser.currentURI);
 
     let recommendInfo = SocialUI.enabled ? Social.provider.recommendInfo : null;
     // Provide a11y-friendly notification of share.
     let status = document.getElementById("share-button-status");
     if (status) {
@@ -777,56 +746,63 @@ var SocialMenu = {
 // XXX Need to audit that this is being initialized correctly
 var SocialToolbar = {
   // Called once, after window load, when the Social.provider object is
   // initialized.
   init: function SocialToolbar_init() {
     this._dynamicResizer = new DynamicResizeWatcher();
   },
 
+  update: function() {
+    this._updateButtonHiddenState();
+    this.updateProvider();
+    this.populateProviderMenus();
+  },
+
   // Called when the Social.provider changes
   updateProvider: function () {
     let provider = Social.provider || Social.defaultProvider;
     if (provider) {
       this.button.setAttribute("label", provider.name);
       this.button.setAttribute("tooltiptext", provider.name);
       this.button.style.listStyleImage = "url(" + provider.iconURL + ")";
 
       this.updateProfile();
     }
     this.updateButton();
-    this.populateProviderMenus();
   },
 
   get button() {
     return document.getElementById("social-provider-button");
   },
 
   // Note: this doesn't actually handle hiding the toolbar button,
   // socialActiveBroadcaster is responsible for that.
-  updateButtonHiddenState: function SocialToolbar_updateButtonHiddenState() {
-    let tbi = document.getElementById("social-toolbar-item");
+  _updateButtonHiddenState: function SocialToolbar_updateButtonHiddenState() {
     let socialEnabled = SocialUI.enabled;
     for (let className of ["social-statusarea-separator", "social-statusarea-user"]) {
       for (let element of document.getElementsByClassName(className))
         element.hidden = !socialEnabled;
     }
     let toggleNotificationsCommand = document.getElementById("Social:ToggleNotifications");
     toggleNotificationsCommand.setAttribute("hidden", !socialEnabled);
 
     if (!Social.haveLoggedInUser() || !socialEnabled) {
       let parent = document.getElementById("social-notification-panel");
       while (parent.hasChildNodes()) {
         let frame = parent.firstChild;
         SharedFrame.forgetGroup(frame.id);
         parent.removeChild(frame);
       }
 
-      while (tbi.lastChild != tbi.firstChild)
-        tbi.removeChild(tbi.lastChild);
+      let tbi = document.getElementById("social-toolbar-item");
+      if (tbi) {
+        while (tbi.lastChild != tbi.firstChild)
+          tbi.removeChild(tbi.lastChild);
+      }
     }
   },
 
   updateProfile: function SocialToolbar_updateProfile() {
     // Profile may not have been initialized yet, since it depends on a worker
     // response. In that case we'll be called again when it's available, via
     // social:profile-changed
     if (!Social.provider)
@@ -849,17 +825,17 @@ var SocialToolbar = {
     }
 
     userDetailsBroadcaster.setAttribute("value", loggedInStatusValue);
     userDetailsBroadcaster.setAttribute("label", loggedInStatusValue);
   },
 
   // XXX doesn't this need to be called for profile changes, given its use of provider.profile?
   updateButton: function SocialToolbar_updateButton() {
-    this.updateButtonHiddenState();
+    this._updateButtonHiddenState();
     let panel = document.getElementById("social-notification-panel");
     panel.hidden = !SocialUI.enabled;
 
     let command = document.getElementById("Social:ToggleNotifications");
     command.setAttribute("checked", Services.prefs.getBoolPref("social.toast-notifications.enabled"));
 
     const CACHE_PREF_NAME = "social.cached.ambientNotificationIcons";
     // provider.profile == undefined means no response yet from the provider
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -6398,45 +6398,46 @@ function warnAboutClosingWindow() {
   // Popups aren't considered full browser windows.
   let isPBWindow = PrivateBrowsingUtils.isWindowPrivate(window);
   if (!isPBWindow && !toolbar.visible)
     return gBrowser.warnAboutClosingTabs(true);
 
   // Figure out if there's at least one other browser window around.
   let e = Services.wm.getEnumerator("navigator:browser");
   let otherPBWindowExists = false;
-  let warnAboutClosingTabs = false;
+  let nonPopupPresent = false;
   while (e.hasMoreElements()) {
     let win = e.getNext();
     if (win != window) {
       if (isPBWindow && PrivateBrowsingUtils.isWindowPrivate(win))
         otherPBWindowExists = true;
       if (win.toolbar.visible)
-        warnAboutClosingTabs = true;
+        nonPopupPresent = true;
       // If the current window is not in private browsing mode we don't need to 
       // look for other pb windows, we can leave the loop when finding the 
       // first non-popup window. If however the current window is in private 
       // browsing mode then we need at least one other pb and one non-popup 
       // window to break out early.
-      if ((!isPBWindow || otherPBWindowExists) && warnAboutClosingTabs)
+      if ((!isPBWindow || otherPBWindowExists) && nonPopupPresent)
         break;
     }
   }
 
   if (isPBWindow && !otherPBWindowExists) {
     let exitingCanceled = Cc["@mozilla.org/supports-PRBool;1"].
                           createInstance(Ci.nsISupportsPRBool);
     exitingCanceled.data = false;
     Services.obs.notifyObservers(exitingCanceled,
                                  "last-pb-context-exiting",
                                  null);
     if (exitingCanceled.data)
       return false;
   }
-  if (warnAboutClosingTabs)
+
+  if (!isPBWindow && nonPopupPresent)
     return gBrowser.warnAboutClosingTabs(true);
 
   let os = Services.obs;
 
   let closingCanceled = Cc["@mozilla.org/supports-PRBool;1"].
                         createInstance(Ci.nsISupportsPRBool);
   os.notifyObservers(closingCanceled,
                      "browser-lastwindow-close-requested", null);
@@ -6444,17 +6445,17 @@ function warnAboutClosingWindow() {
     return false;
 
   os.notifyObservers(null, "browser-lastwindow-close-granted", null);
 
 #ifdef XP_MACOSX
   // OS X doesn't quit the application when the last window is closed, but keeps
   // the session alive. Hence don't prompt users to save tabs, but warn about
   // closing multiple tabs.
-  return gBrowser.warnAboutClosingTabs(true);
+  return isPBWindow || gBrowser.warnAboutClosingTabs(true);
 #else
   return true;
 #endif
 }
 
 var MailIntegration = {
   sendLinkForWindow: function (aWindow) {
     this.sendMessage(aWindow.location.href,
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -778,17 +778,20 @@
       <method name="getWindowTitleForBrowser">
         <parameter name="aBrowser"/>
         <body>
           <![CDATA[
             var newTitle = "";
             var docElement = this.ownerDocument.documentElement;
             var sep = docElement.getAttribute("titlemenuseparator");
 
-            var docTitle = aBrowser.contentTitle;
+            // Strip out any null bytes in the content title, since the
+            // underlying widget implementations of nsWindow::SetTitle pass
+            // null-terminated strings to system APIs.
+            var docTitle = aBrowser.contentTitle.replace("\0", "");
 
             if (!docTitle)
               docTitle = docElement.getAttribute("titledefault");
 
             var modifier = docElement.getAttribute("titlemodifier");
             if (docTitle) {
               newTitle += docElement.getAttribute("titlepreface");
               newTitle += docTitle;
@@ -1253,39 +1256,24 @@
             t.setAttribute("onerror", "this.removeAttribute('image');");
             t.className = "tabbrowser-tab";
 
             this.tabContainer._unlockTabSizing();
 
             // When overflowing, new tabs are scrolled into view smoothly, which
             // doesn't go well together with the width transition. So we skip the
             // transition in that case.
-            if (aSkipAnimation ||
-                this.tabContainer.getAttribute("overflow") == "true" ||
-                !Services.prefs.getBoolPref("browser.tabs.animate")) {
+            let animate = !aSkipAnimation &&
+                          this.tabContainer.getAttribute("overflow") != "true" &&
+                          Services.prefs.getBoolPref("browser.tabs.animate");
+            if (!animate) {
               t.setAttribute("fadein", "true");
               setTimeout(function (tabContainer) {
                 tabContainer._handleNewTab(t);
               }, 0, this.tabContainer);
-            } else {
-              setTimeout(function (tabContainer) {
-                if (t.pinned)
-                  tabContainer._handleNewTab(t);
-                else {
-                  tabContainer._handleTabTelemetryStart(tabContainer, t, aURI);
-
-                  t.setAttribute("fadein", "true");
-
-                  // This call to adjustTabstrip is redundant but needed so that
-                  // when opening a second tab, the first tab's close buttons
-                  // appears immediately rather than when the transition ends.
-                  if (tabContainer.childNodes.length == 2)
-                    tabContainer.adjustTabstrip();
-                }
-              }, 0, this.tabContainer);
             }
 
             // invalidate caches
             this._browsers = null;
             this._visibleTabs = null;
 
             this.tabContainer.appendChild(t);
 
@@ -1438,16 +1426,30 @@
               if (this._lastRelatedTab)
                 this._lastRelatedTab.owner = null;
               else
                 t.owner = this.selectedTab;
               this.moveTabTo(t, newTabPos);
               this._lastRelatedTab = t;
             }
 
+            if (animate) {
+              this.tabContainer._handleTabTelemetryStart(this.tabContainer, t, aURI);
+
+              // kick the animation off
+              t.clientTop;
+              t.setAttribute("fadein", "true");
+
+              // This call to adjustTabstrip is redundant but needed so that
+              // when opening a second tab, the first tab's close buttons
+              // appears immediately rather than when the transition ends.
+              if (this.tabContainer.childNodes.length == 2)
+                this.tabContainer.adjustTabstrip();
+            }
+
             return t;
           ]]>
         </body>
       </method>
 
       <method name="warnAboutClosingTabs">
       <parameter name="aAll"/>
       <body>
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -308,16 +308,17 @@ endif
                  download_page.html \
                  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 \
                  $(NULL)
 
 # Disable test on Windows due to frequent failures (bug 841341)
 ifneq (windows,$(MOZ_WIDGET_TOOLKIT))
 _BROWSER_FILES += \
                 browser_popupNotification.js \
                 $(NULL)
 endif
--- a/browser/base/content/test/browser_bug585785.js
+++ b/browser/base/content/test/browser_bug585785.js
@@ -1,26 +1,21 @@
 var tab;
 
 function test() {
   waitForExplicitFinish();
 
   tab = gBrowser.addTab();
-  isnot(tab.getAttribute("fadein"), "true", "newly opened tab is yet to fade in");
+  is(tab.getAttribute("fadein"), "true", "tab opening animation initiated");
 
   // Try to remove the tab right before the opening animation's first frame
   window.mozRequestAnimationFrame(checkAnimationState);
 }
 
 function checkAnimationState() {
-  if (tab.getAttribute("fadein") != "true") {
-    window.mozRequestAnimationFrame(checkAnimationState);
-    return;
-  }
-
   info(window.getComputedStyle(tab).maxWidth);
   gBrowser.removeTab(tab, { animate: true });
   if (!tab.parentNode) {
     ok(true, "tab removed synchronously since the opening animation hasn't moved yet");
     finish();
     return;
   }
 
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_private_no_prompt.js
@@ -0,0 +1,13 @@
+function test() {
+  waitForExplicitFinish();
+  var privateWin = OpenBrowserWindow({private: true});
+  privateWin.addEventListener("load", function onload() {
+    privateWin.removeEventListener("load", onload, false);
+    ok(true, "Load listener called");
+
+    privateWin.BrowserOpenTab();
+    privateWin.BrowserTryToCloseWindow();
+    ok(true, "didn't prompt");
+    finish();                        
+  }, false);
+}
\ No newline at end of file
--- a/browser/base/content/test/social/Makefile.in
+++ b/browser/base/content/test/social/Makefile.in
@@ -23,16 +23,17 @@ include $(DEPTH)/config/autoconf.mk
                  browser_social_sidebar.js \
                  browser_social_flyout.js \
                  browser_social_mozSocial_API.js \
                  browser_social_isVisible.js \
                  browser_social_chatwindow.js \
                  browser_social_chatwindowfocus.js \
                  browser_social_multiprovider.js \
                  browser_social_errorPage.js \
+                 browser_social_window.js \
                  social_activate.html \
                  social_activate_iframe.html \
                  social_panel.html \
                  social_share_image.png \
                  social_sidebar.html \
                  social_chat.html \
                  social_flyout.html \
                  social_window.html \
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/social/browser_social_window.js
@@ -0,0 +1,145 @@
+// 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/.
+
+// Test the top-level window UI for social.
+
+// This function should "reset" Social such that the next time Social.init()
+// is called (eg, when a new window is opened), it re-performs all
+// initialization.
+function resetSocial() {
+  Social.initialized = false;
+  Social._provider = null;
+  Social.providers = [];
+  // *sob* - listeners keep getting added...
+  let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
+  SocialService._providerListeners.clear();
+}
+
+let createdWindows = [];
+
+function openWindowAndWaitForInit(callback) {
+  // this notification tells us SocialUI.init() has been run...
+  let topic = "browser-delayed-startup-finished";
+  let w = OpenBrowserWindow();
+  createdWindows.push(w);
+  Services.obs.addObserver(function providerSet(subject, topic, data) {
+    Services.obs.removeObserver(providerSet, topic);
+    info(topic + " observer was notified - continuing test");
+    // executeSoon to let the browser UI observers run first
+    executeSoon(function() {callback(w)});
+  }, topic, false);
+}
+
+function postTestCleanup(cb) {
+  for (let w of createdWindows)
+    w.close();
+  createdWindows = [];
+  Services.prefs.clearUserPref("social.enabled");
+  cb();
+}
+
+let manifest = { // normal provider
+  name: "provider 1",
+  origin: "https://example.com",
+  sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
+  workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
+  iconURL: "https://example.com/browser/browser/base/content/test/social/moz.png"
+};
+
+function test() {
+  waitForExplicitFinish();
+  runSocialTests(tests, undefined, postTestCleanup);
+}
+
+let tests = {
+  // check when social is totally disabled at startup (ie, no providers)
+  testInactiveStartup: function(cbnext) {
+    is(Social.providers.length, 0, "needs zero providers to start this test.");
+    resetSocial();
+    openWindowAndWaitForInit(function(w1) {
+      checkSocialUI(w1);
+      // Now social is (re-)initialized, open a secondary window and check that.
+      openWindowAndWaitForInit(function(w2) {
+        checkSocialUI(w2);
+        checkSocialUI(w1);
+        cbnext();
+      });
+    });
+  },
+
+  // Check when providers exist and social is turned on at startup.
+  testEnabledStartup: function(cbnext) {
+    runSocialTestWithProvider(manifest, function (finishcb) {
+      resetSocial();
+      openWindowAndWaitForInit(function(w1) {
+        ok(Social.enabled, "social is enabled");
+        checkSocialUI(w1);
+        // now init is complete, open a second window
+        openWindowAndWaitForInit(function(w2) {
+          checkSocialUI(w2);
+          checkSocialUI(w1);
+          // disable social and re-check
+          Services.prefs.setBoolPref("social.enabled", false);
+          executeSoon(function() { // let all the UI observers run...
+            ok(!Social.enabled, "social is disabled");
+            checkSocialUI(w2);
+            checkSocialUI(w1);
+            finishcb();
+          });
+        });
+      });
+    }, cbnext);
+  },
+
+  // Check when providers exist but social is turned off at startup.
+  testDisabledStartup: function(cbnext) {
+    runSocialTestWithProvider(manifest, function (finishcb) {
+      Services.prefs.setBoolPref("social.enabled", false);
+      resetSocial();
+      openWindowAndWaitForInit(function(w1) {
+        ok(!Social.enabled, "social is disabled");
+        checkSocialUI(w1);
+        // now init is complete, open a second window
+        openWindowAndWaitForInit(function(w2) {
+          checkSocialUI(w2);
+          checkSocialUI(w1);
+          // enable social and re-check
+          Services.prefs.setBoolPref("social.enabled", true);
+          executeSoon(function() { // let all the UI observers run...
+            ok(Social.enabled, "social is enabled");
+            checkSocialUI(w2);
+            checkSocialUI(w1);
+            finishcb();
+          });
+        });
+      });
+    }, cbnext);
+  },
+
+  // Check when the last provider is removed.
+  testRemoveProvider: function(cbnext) {
+    runSocialTestWithProvider(manifest, function (finishcb) {
+      openWindowAndWaitForInit(function(w1) {
+        checkSocialUI(w1);
+        // now init is complete, open a second window
+        openWindowAndWaitForInit(function(w2) {
+          checkSocialUI(w2);
+          // remove the current provider.
+          let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
+          SocialService.removeProvider(manifest.origin, function() {
+            ok(!Social.enabled, "social is disabled");
+            is(Social.providers.length, 0, "no providers");
+            checkSocialUI(w2);
+            checkSocialUI(w1);
+            // *sob* - runSocialTestWithProvider's cleanup fails when it can't
+            // remove the provider, so re-add it.
+            SocialService.addProvider(manifest, function() {
+              finishcb();
+            });
+          });
+        });
+      });
+    }, cbnext);
+  },
+}
--- a/browser/base/content/test/social/head.js
+++ b/browser/base/content/test/social/head.js
@@ -35,17 +35,17 @@ function promiseSocialUrlNotRemembered(u
     ok(!aIsVisited, "social URL " + url + " should not be in global history");
     deferred.resolve();
   });
   return deferred.promise;
 }
 
 let gURLsNotRemembered = [];
 
-function runSocialTestWithProvider(manifest, callback) {
+function runSocialTestWithProvider(manifest, callback, finishcallback) {
   let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
 
   let manifests = Array.isArray(manifest) ? manifest : [manifest];
 
   // Check that none of the provider's content ends up in history.
   function finishCleanUp() {
     for (let i = 0; i < manifests.length; i++) {
       let m = manifests[i];
@@ -62,17 +62,17 @@ function runSocialTestWithProvider(manif
   }
 
   info("runSocialTestWithProvider: " + manifests.toSource());
 
   let finishCount = 0;
   function finishIfDone(callFinish) {
     finishCount++;
     if (finishCount == manifests.length)
-      Task.spawn(finishCleanUp).then(finish);
+      Task.spawn(finishCleanUp).then(finishcallback || finish);
   }
   function removeAddedProviders(cleanup) {
     manifests.forEach(function (m) {
       // If we're "cleaning up", don't call finish when done.
       let callback = cleanup ? function () {} : finishIfDone;
       // Similarly, if we're cleaning up, catch exceptions from removeProvider
       let removeProvider = SocialService.removeProvider.bind(SocialService);
       if (cleanup) {
@@ -168,38 +168,48 @@ function runSocialTests(tests, cbPreTest
 
 // A fairly large hammer which checks all aspects of the SocialUI for
 // internal consistency.
 function checkSocialUI(win) {
   let win = win || window;
   let doc = win.document;
   let provider = Social.provider;
   let enabled = win.SocialUI.enabled;
+  let active = Social.providers.length > 0 && !win.SocialUI._chromeless &&
+               !PrivateBrowsingUtils.isWindowPrivate(win);
+
   function isbool(a, b, msg) {
     is(!!a, !!b, msg);
   }
   isbool(win.SocialSidebar.canShow, enabled, "social sidebar active?");
   if (enabled)
     isbool(win.SocialSidebar.opened, enabled, "social sidebar open?");
   isbool(win.SocialChatBar.isAvailable, enabled && Social.haveLoggedInUser(), "chatbar available?");
   isbool(!win.SocialChatBar.chatbar.hidden, enabled && Social.haveLoggedInUser(), "chatbar visible?");
-  isbool(!win.SocialShareButton.shareButton.hidden, enabled && Social.haveLoggedInUser() && provider.recommendInfo, "share button visible?");
-  isbool(!doc.getElementById("social-toolbar-item").hidden, enabled, "toolbar items visible?");
-  if (enabled)
-    is(win.SocialToolbar.button.style.listStyleImage, 'url("' + provider.iconURL + '")', "toolbar button has provider icon");
+
+  let canShare = enabled && provider.recommendInfo && Social.haveLoggedInUser() && win.SocialShareButton.canSharePage(win.gBrowser.currentURI)
+  isbool(!win.SocialShareButton.shareButton.hidden, canShare, "share button visible?");
+  isbool(!doc.getElementById("social-toolbar-item").hidden, active, "toolbar items visible?");
+  if (active)
+    is(win.SocialToolbar.button.style.listStyleImage, 'url("' + Social.defaultProvider.iconURL + '")', "toolbar button has provider icon");
+  // the menus should always have the provider name
+  if (provider) {
+    for (let id of ["menu_socialSidebar", "menu_socialAmbientMenu"])
+      is(document.getElementById(id).getAttribute("label"), Social.provider.name, "element has the provider name");
+  }
 
   // and for good measure, check all the social commands.
-  isbool(!doc.getElementById("Social:Toggle").hidden, enabled, "Social:Toggle visible?");
+  isbool(!doc.getElementById("Social:Toggle").hidden, active, "Social:Toggle visible?");
   isbool(!doc.getElementById("Social:ToggleNotifications").hidden, enabled, "Social:ToggleNotifications visible?");
   isbool(!doc.getElementById("Social:FocusChat").hidden, enabled && Social.haveLoggedInUser(), "Social:FocusChat visible?");
   isbool(doc.getElementById("Social:FocusChat").getAttribute("disabled"), enabled ? "false" : "true", "Social:FocusChat disabled?");
-  is(doc.getElementById("Social:SharePage").getAttribute("disabled"), enabled && Social.haveLoggedInUser() && provider.recommendInfo ? "false" : "true", "Social:SharePage visible?");
+  is(doc.getElementById("Social:SharePage").getAttribute("disabled"), canShare ? "false" : "true", "Social:SharePage visible?");
 
   // broadcasters.
-  isbool(!doc.getElementById("socialActiveBroadcaster").hidden, enabled, "socialActiveBroadcaster hidden?");
+  isbool(!doc.getElementById("socialActiveBroadcaster").hidden, active, "socialActiveBroadcaster hidden?");
 }
 
 // blocklist testing
 function updateBlocklist(aCallback) {
   var blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"]
                           .getService(Ci.nsITimerCallback);
   var observer = function() {
     Services.obs.removeObserver(observer, "blocklist-updated");
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -526,17 +526,17 @@ function openHealthReport()
 }
 #endif
 
 /**
  * Opens the feedback page for this version of the application.
  */
 function openFeedbackPage()
 {
-  openUILinkIn("http://input.mozilla.com/feedback", "tab");
+  openUILinkIn("https://input.mozilla.org/feedback", "tab");
 }
 
 function buildHelpMenu()
 {
   // Enable/disable the "Report Web Forgery" menu item.
   if (typeof gSafeBrowsing != "undefined")
     gSafeBrowsing.setReportPhishingMenu();
 }
--- a/browser/components/feeds/public/Makefile.in
+++ b/browser/components/feeds/public/Makefile.in
@@ -6,13 +6,12 @@
 DEPTH   = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH   = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = browser-feeds
-XPIDL_MODULE  = browser-feeds
 
 XPIDLSRCS = nsIFeedResultService.idl nsIWebContentConverterRegistrar.idl nsIFeedWriter.idl
 
 include $(topsrcdir)/config/rules.mk
--- a/browser/components/migration/public/Makefile.in
+++ b/browser/components/migration/public/Makefile.in
@@ -5,14 +5,13 @@
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= migration
-XPIDL_MODULE	= migration
 
 XPIDLSRCS	= nsIBrowserProfileMigrator.idl
 
 include $(topsrcdir)/config/rules.mk
 
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -19,19 +19,17 @@ var gPrivacyPane = {
    * label of the "Clear Now..." button.
    */
   init: function ()
   {
     this._updateSanitizeSettingsButton();
     this.initializeHistoryMode();
     this.updateHistoryModePane();
     this.updatePrivacyMicroControls();
-    this.initAutoStartPrivateBrowsingObserver();
-
-    window.addEventListener("unload", this.removeASPBObserver.bind(this), false);
+    this.initAutoStartPrivateBrowsingReverter();
   },
 
   // HISTORY MODE
 
   /**
    * The list of preferences which affect the initial history mode settings.
    * If the auto start private browsing mode pref is active, the initial
    * history mode would be set to "Don't remember anything".
@@ -227,88 +225,82 @@ var gPrivacyPane = {
         this._updateSanitizeSettingsButton();
       }
     }
   },
 
   // PRIVATE BROWSING
 
   /**
-   * Install the observer for the auto-start private browsing mode pref.
+   * Initialize the starting state for the auto-start private browsing mode pref reverter.
    */
-  initAutoStartPrivateBrowsingObserver: function PPP_initAutoStartPrivateBrowsingObserver()
+  initAutoStartPrivateBrowsingReverter: function PPP_initAutoStartPrivateBrowsingReverter()
   {
-    let prefService = document.getElementById("privacyPreferences")
-                              .service
-                              .QueryInterface(Components.interfaces.nsIPrefBranch);
-    prefService.addObserver("browser.privatebrowsing.autostart",
-                            this.autoStartPrivateBrowsingObserver,
-                            false);
+    let mode = document.getElementById("historyMode");
+    let autoStart = document.getElementById("privateBrowsingAutoStart");
+    this._lastMode = mode.selectedIndex;
+    this._lastCheckState = autoStart.hasAttribute('checked');
   },
 
-  /**
-   * Install the observer for the auto-start private browsing mode pref.
-   */
-  removeASPBObserver: function PPP_removeASPBObserver()
-  {
-    let prefService = document.getElementById("privacyPreferences")
-                              .service
-                              .QueryInterface(Components.interfaces.nsIPrefBranch);
-    prefService.removeObserver("browser.privatebrowsing.autostart",
-                               this.autoStartPrivateBrowsingObserver);
-  },
+  _lastMode: null,
+  _lasCheckState: null,
+  updateAutostart: function PPP_updateAutostart() {
+      let mode = document.getElementById("historyMode");
+      let autoStart = document.getElementById("privateBrowsingAutoStart");
+      let pref = document.getElementById("browser.privatebrowsing.autostart");
+      if ((mode.value == "custom" && this._lastCheckState == autoStart.checked) ||
+          (mode.value == "remember" && !this._lastCheckState) ||
+          (mode.value == "dontremember" && this._lastCheckState)) {
+          // These are all no-op changes, so we don't need to prompt.
+          this._lastMode = mode.selectedIndex;
+          this._lastCheckState = autoStart.hasAttribute('checked');
+          return;
+      }
 
-  autoStartPrivateBrowsingObserver:
-  {
-    QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIObserver]),
-
-    observe: function PPP_observe(aSubject, aTopic, aData)
-    {
-      if (!gPrivacyPane._shouldPromptForRestart) {
+      if (!this._shouldPromptForRestart) {
         // We're performing a revert. Just let it happen.
-        gPrivacyPane._shouldPromptForRestart = true;
         return;
       }
 
       const Cc = Components.classes, Ci = Components.interfaces;
-      let pref = document.getElementById("browser.privatebrowsing.autostart");
       let brandName = document.getElementById("bundleBrand").getString("brandShortName");
       let bundle = document.getElementById("bundlePreferences");
       let msg = bundle.getFormattedString(pref.value ?
                                           "featureEnableRequiresRestart" : "featureDisableRequiresRestart",
                                           [brandName]);
       let title = bundle.getFormattedString("shouldRestartTitle", [brandName]);
       let prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
       let shouldProceed = prompts.confirm(window, title, msg)
       if (shouldProceed) {
         let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
                            .createInstance(Ci.nsISupportsPRBool);
         Services.obs.notifyObservers(cancelQuit, "quit-application-requested",
                                      "restart");
         shouldProceed = !cancelQuit.data;
 
         if (shouldProceed) {
+          document.documentElement.acceptDialog();
           let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
                              .getService(Ci.nsIAppStartup);
           appStartup.quit(Ci.nsIAppStartup.eAttemptQuit |  Ci.nsIAppStartup.eRestart);
           return;
         }
       }
-      gPrivacyPane._shouldPromptForRestart = false;
-      pref.value = !pref.value;
+
+      this._shouldPromptForRestart = false;
 
-      let mode = document.getElementById("historyMode");
-      if (mode.value != "custom") {
-        mode.selectedIndex = pref.value ? 1 : 0;
-        mode.doCommand();
+      if (this._lastCheckState) {
+        autoStart.checked = "checked";
       } else {
-        let rememberHistoryCheckbox = document.getElementById("rememberHistory");
-        rememberHistory.checked = pref.value;
+        autoStart.removeAttribute('checked');
       }
-    }
+      mode.selectedIndex = this._lastMode;
+      mode.doCommand();
+
+      this._shouldPromptForRestart = true;
   },
 
   // HISTORY
 
   /**
    * Read the location bar enabled and suggestion prefs
    * @return Int value for suggestion menulist
    */
--- a/browser/components/preferences/in-content/privacy.xul
+++ b/browser/components/preferences/in-content/privacy.xul
@@ -56,17 +56,16 @@
               type="bool"/>
   <preference id="privacy.sanitize.timeSpan"
               name="privacy.sanitize.timeSpan"
               type="int"/>
   <!-- Private Browsing -->
   <preference id="browser.privatebrowsing.autostart"
               name="browser.privatebrowsing.autostart"
               onchange="gPrivacyPane.updatePrivacyMicroControls();"
-              instantApply="true"
               type="bool"/>
 
 </preferences>
 
 <hbox class="heading" data-category="panePrivacy" hidden="true">
   <image class="preference-icon" type="privacy"/>
   <html:h1>&panePrivacy.title;</html:h1>
 </hbox>
@@ -96,17 +95,18 @@
   <hbox align="center">
     <label id="historyModeLabel"
            control="historyMode"
            accesskey="&historyHeader.pre.accesskey;">&historyHeader.pre.label;
     </label>
     <menulist id="historyMode"
               oncommand="gPrivacyPane.updateHistoryModePane();
                         gPrivacyPane.updateHistoryModePrefs();
-                        gPrivacyPane.updatePrivacyMicroControls();">
+                        gPrivacyPane.updatePrivacyMicroControls();
+                        gPrivacyPane.updateAutostart();">
       <menupopup>
         <menuitem label="&historyHeader.remember.label;" value="remember"/>
         <menuitem label="&historyHeader.dontremember.label;" value="dontremember"/>
         <menuitem label="&historyHeader.custom.label;" value="custom"/>
       </menupopup>
     </menulist>
     <label>&historyHeader.post.label;</label>
   </hbox>
@@ -143,17 +143,18 @@
       </hbox>
     </vbox>
     <vbox id="historyCustomPane">
       <separator class="thin"/>
       <vbox class="indent">
         <checkbox id="privateBrowsingAutoStart"
                   label="&privateBrowsingPermanent2.label;"
                   accesskey="&privateBrowsingPermanent2.accesskey;"
-                  preference="browser.privatebrowsing.autostart"/>
+                  preference="browser.privatebrowsing.autostart"
+                  oncommand="gPrivacyPane.updateAutostart()"/>
 
         <vbox class="indent">
           <checkbox id="rememberHistory"
                     label="&rememberHistory2.label;"
                     accesskey="&rememberHistory2.accesskey;"
                     preference="places.history.enabled"/>
           <checkbox id="rememberForms"
                     label="&rememberSearchForm.label;"
--- a/browser/components/preferences/privacy.js
+++ b/browser/components/preferences/privacy.js
@@ -22,19 +22,17 @@ var gPrivacyPane = {
    * label of the "Clear Now..." button.
    */
   init: function ()
   {
     this._updateSanitizeSettingsButton();
     this.initializeHistoryMode();
     this.updateHistoryModePane();
     this.updatePrivacyMicroControls();
-    this.initAutoStartPrivateBrowsingObserver();
-
-    window.addEventListener("unload", this.removeASPBObserver.bind(this), false);
+    this.initAutoStartPrivateBrowsingReverter();
   },
 
   // HISTORY MODE
 
   /**
    * The list of preferences which affect the initial history mode settings.
    * If the auto start private browsing mode pref is active, the initial
    * history mode would be set to "Don't remember anything".
@@ -230,88 +228,82 @@ var gPrivacyPane = {
         this._updateSanitizeSettingsButton();
       }
     }
   },
 
   // PRIVATE BROWSING
 
   /**
-   * Install the observer for the auto-start private browsing mode pref.
+   * Initialize the starting state for the auto-start private browsing mode pref reverter.
    */
-  initAutoStartPrivateBrowsingObserver: function PPP_initAutoStartPrivateBrowsingObserver()
+  initAutoStartPrivateBrowsingReverter: function PPP_initAutoStartPrivateBrowsingReverter()
   {
-    let prefService = document.getElementById("privacyPreferences")
-                              .service
-                              .QueryInterface(Components.interfaces.nsIPrefBranch);
-    prefService.addObserver("browser.privatebrowsing.autostart",
-                            this.autoStartPrivateBrowsingObserver,
-                            false);
+    let mode = document.getElementById("historyMode");
+    let autoStart = document.getElementById("privateBrowsingAutoStart");
+    this._lastMode = mode.selectedIndex;
+    this._lastCheckState = autoStart.hasAttribute('checked');
   },
 
-  /**
-   * Install the observer for the auto-start private browsing mode pref.
-   */
-  removeASPBObserver: function PPP_removeASPBObserver()
-  {
-    let prefService = document.getElementById("privacyPreferences")
-                              .service
-                              .QueryInterface(Components.interfaces.nsIPrefBranch);
-    prefService.removeObserver("browser.privatebrowsing.autostart",
-                               this.autoStartPrivateBrowsingObserver);
-  },
+  _lastMode: null,
+  _lasCheckState: null,
+  updateAutostart: function PPP_updateAutostart() {
+      let mode = document.getElementById("historyMode");
+      let autoStart = document.getElementById("privateBrowsingAutoStart");
+      let pref = document.getElementById("browser.privatebrowsing.autostart");
+      if ((mode.value == "custom" && this._lastCheckState == autoStart.checked) ||
+          (mode.value == "remember" && !this._lastCheckState) ||
+          (mode.value == "dontremember" && this._lastCheckState)) {
+          // These are all no-op changes, so we don't need to prompt.
+          this._lastMode = mode.selectedIndex;
+          this._lastCheckState = autoStart.hasAttribute('checked');
+          return;
+      }
 
-  autoStartPrivateBrowsingObserver:
-  {
-    QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIObserver]),
-
-    observe: function PPP_observe(aSubject, aTopic, aData)
-    {
-      if (!gPrivacyPane._shouldPromptForRestart) {
+      if (!this._shouldPromptForRestart) {
         // We're performing a revert. Just let it happen.
-        gPrivacyPane._shouldPromptForRestart = true;
         return;
       }
 
       const Cc = Components.classes, Ci = Components.interfaces;
-      let pref = document.getElementById("browser.privatebrowsing.autostart");
       let brandName = document.getElementById("bundleBrand").getString("brandShortName");
       let bundle = document.getElementById("bundlePreferences");
       let msg = bundle.getFormattedString(pref.value ?
                                           "featureEnableRequiresRestart" : "featureDisableRequiresRestart",
                                           [brandName]);
       let title = bundle.getFormattedString("shouldRestartTitle", [brandName]);
       let prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
       let shouldProceed = prompts.confirm(window, title, msg)
       if (shouldProceed) {
         let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
                            .createInstance(Ci.nsISupportsPRBool);
         Services.obs.notifyObservers(cancelQuit, "quit-application-requested",
                                      "restart");
         shouldProceed = !cancelQuit.data;
 
         if (shouldProceed) {
+          document.documentElement.acceptDialog();
           let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
                              .getService(Ci.nsIAppStartup);
           appStartup.quit(Ci.nsIAppStartup.eAttemptQuit |  Ci.nsIAppStartup.eRestart);
           return;
         }
       }
-      gPrivacyPane._shouldPromptForRestart = false;
-      pref.value = !pref.value;
+
+      this._shouldPromptForRestart = false;
 
-      let mode = document.getElementById("historyMode");
-      if (mode.value != "custom") {
-        mode.selectedIndex = pref.value ? 1 : 0;
-        mode.doCommand();
+      if (this._lastCheckState) {
+        autoStart.checked = "checked";
       } else {
-        let rememberHistoryCheckbox = document.getElementById("rememberHistory");
-        rememberHistory.checked = pref.value;
+        autoStart.removeAttribute('checked');
       }
-    }
+      mode.selectedIndex = this._lastMode;
+      mode.doCommand();
+
+      this._shouldPromptForRestart = true;
   },
 
   // HISTORY
 
   /**
    * Read the location bar enabled and suggestion prefs
    * @return Int value for suggestion menulist
    */
--- a/browser/components/preferences/privacy.xul
+++ b/browser/components/preferences/privacy.xul
@@ -68,17 +68,16 @@
       <preference id="privacy.sanitize.timeSpan"
                   name="privacy.sanitize.timeSpan"
                   type="int"/>
 
       <!-- Private Browsing -->
       <preference id="browser.privatebrowsing.autostart"
                   name="browser.privatebrowsing.autostart"
                   onchange="gPrivacyPane.updatePrivacyMicroControls();"
-                  instantApply="true"
                   type="bool"/>
 
     </preferences>
     
     <stringbundle id="bundlePreferences" src="chrome://browser/locale/preferences/preferences.properties"/>
     
     <script type="application/javascript" src="chrome://browser/content/preferences/privacy.js"/>
 
@@ -108,17 +107,18 @@
 
       <hbox align="center">
         <label id="historyModeLabel"
                control="historyMode"
                accesskey="&historyHeader.pre.accesskey;">&historyHeader.pre.label;</label>
         <menulist id="historyMode"
                   oncommand="gPrivacyPane.updateHistoryModePane();
                              gPrivacyPane.updateHistoryModePrefs();
-                             gPrivacyPane.updatePrivacyMicroControls();">
+                             gPrivacyPane.updatePrivacyMicroControls();
+                             gPrivacyPane.updateAutostart();">
           <menupopup>
             <menuitem label="&historyHeader.remember.label;" value="remember"/>
             <menuitem label="&historyHeader.dontremember.label;" value="dontremember"/>
             <menuitem label="&historyHeader.custom.label;" value="custom"/>
           </menupopup>
         </menulist>
         <label>&historyHeader.post.label;</label>
       </hbox>
@@ -155,17 +155,18 @@
             <spacer flex="1" class="indent"/>
           </hbox>
         </vbox>
         <vbox id="historyCustomPane">
           <separator class="thin"/>
           <checkbox id="privateBrowsingAutoStart" class="indent"
                     label="&privateBrowsingPermanent2.label;"
                     accesskey="&privateBrowsingPermanent2.accesskey;"
-                    preference="browser.privatebrowsing.autostart"/>
+                    preference="browser.privatebrowsing.autostart"
+                    oncommand="gPrivacyPane.updateAutostart()"/>
 
           <vbox class="indent">
             <vbox class="indent">
               <checkbox id="rememberHistory"
                         label="&rememberHistory2.label;"
                         accesskey="&rememberHistory2.accesskey;"
                         preference="places.history.enabled"/>
               <checkbox id="rememberForms"
--- a/browser/components/sessionstore/Makefile.in
+++ b/browser/components/sessionstore/Makefile.in
@@ -6,16 +6,15 @@
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = sessionstore
-XPIDL_MODULE = sessionstore
 
 XPIDLSRCS = \
 	nsISessionStartup.idl \
 	nsISessionStore.idl \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/browser/components/shell/public/Makefile.in
+++ b/browser/components/shell/public/Makefile.in
@@ -6,17 +6,16 @@
 DEPTH   = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH   = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = shellservice
-XPIDL_MODULE  = shellservice
 
 XPIDLSRCS = nsIShellService.idl
 
 ifeq ($(OS_ARCH),WINNT)
 XPIDLSRCS += nsIWindowsShellService.idl
 endif
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
--- a/browser/devtools/debugger/test/browser_dbg_bug723069_editor-breakpoints.js
+++ b/browser/devtools/debugger/test/browser_dbg_bug723069_editor-breakpoints.js
@@ -268,19 +268,28 @@ function test()
     executeSoon(function() {
       info("remove the second breakpoint using the mouse");
 
       gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
                                onEditorBreakpointRemoveSecond);
 
       let iframe = gEditor.editorElement;
       let testWin = iframe.ownerDocument.defaultView;
+
       // flush the layout for the iframe
       info("rect " + iframe.contentDocument.documentElement.getBoundingClientRect());
-      EventUtils.synthesizeMouse(iframe, 10, 70, {}, testWin);
+
+      let utils = testWin.QueryInterface(Ci.nsIInterfaceRequestor)
+                  .getInterface(Ci.nsIDOMWindowUtils);
+
+      let rect = iframe.getBoundingClientRect();
+      let left = rect.left + 10;
+      let top = rect.top + 70;
+      utils.sendMouseEventToWindow("mousedown", left, top, 0, 1, 0, false, 0, 0);
+      utils.sendMouseEventToWindow("mouseup", left, top, 0, 1, 0, false, 0, 0);
     });
 
   }
 
   function onEditorBreakpointRemoveSecond(aEvent)
   {
     gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
                                 onEditorBreakpointRemoveSecond);
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_595350_multiple_windows_and_tabs.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_595350_multiple_windows_and_tabs.js
@@ -94,16 +94,17 @@ function closeConsoles() {
   openTabs = win1 = win2 = null;
 
   function onTimeout() {
     Services.obs.removeObserver(onWebConsoleClose, "web-console-destroyed");
     executeSoon(finishTest);
   }
 
   waitForSuccess({
+    timeout: 10000,
     name: "4 web consoles closed",
     validatorFn: function()
     {
       return consolesClosed == 4;
     },
     successFn: onTimeout,
     failureFn: onTimeout,
   });
--- a/browser/fuel/public/Makefile.in
+++ b/browser/fuel/public/Makefile.in
@@ -5,13 +5,12 @@
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE        = fuel
-XPIDL_MODULE  = fuel
 
 XPIDLSRCS = fuelIApplication.idl
 
 include $(topsrcdir)/config/rules.mk
--- a/browser/metro/base/content/Util.js
+++ b/browser/metro/base/content/Util.js
@@ -32,16 +32,54 @@ let Util = {
   },
 
   // Put the Mozilla networking code into a state that will kick the
   // auto-connection process.
   forceOnline: function forceOnline() {
     Services.io.offline = false;
   },
 
+  // Pass several objects in and it will combine them all into the first object and return it.
+  // NOTE: Deep copy is not supported
+  extend: function extend() {
+    // copy reference to target object
+    let target = arguments[0] || {};
+    let length = arguments.length;
+
+    if (length === 1) {
+      return target;
+    }
+
+    // Handle case when target is a string or something
+    if (typeof target != "object" && typeof target != "function") {
+      target = {};
+    }
+
+    for (let i = 1; i < length; i++) {
+      // Only deal with non-null/undefined values
+      let options = arguments[i];
+      if (options != null) {
+        // Extend the base object
+        for (let name in options) {
+          let copy = options[name];
+
+          // Prevent never-ending loop
+          if (target === copy)
+            continue;
+
+          if (copy !== undefined)
+            target[name] = copy;
+        }
+      }
+    }
+
+    // Return the modified object
+    return target;
+  },
+
   /*
    * Timing utilties
    */
 
   // Executes aFunc after other events have been processed.
   executeSoon: function executeSoon(aFunc) {
     Services.tm.mainThread.dispatch({
       run: function() {
--- a/browser/metro/base/content/contenthandlers/Content.js
+++ b/browser/metro/base/content/contenthandlers/Content.js
@@ -380,16 +380,17 @@ let Content = {
         let manifestURI = Services.io.newURI(json.manifest, json.charset, currentURI);
         let updateService = Cc["@mozilla.org/offlinecacheupdate-service;1"]
                             .getService(Ci.nsIOfflineCacheUpdateService);
         updateService.scheduleUpdate(manifestURI, currentURI, content);
         break;
       }
 
       case "Browser:SetCharset": {
+        docShell.gatherCharsetMenuTelemetry();
         docShell.charset = json.charset;
 
         let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
         webNav.reload(Ci.nsIWebNavigation.LOAD_FLAGS_CHARSET_CHANGE);
         break;
       }
 
       case "Browser:PanBegin":
--- a/browser/metro/base/content/helperui/MenuUI.js
+++ b/browser/metro/base/content/helperui/MenuUI.js
@@ -70,16 +70,23 @@ var AutofillMenuUI = {
   hide: function hide () {
     this._menuPopup.hide();
   }
 };
 
 var ContextMenuUI = {
   _popupState: null,
   __menuPopup: null,
+  _defaultPositionOptions: {
+    forcePosition: true,
+    bottomAligned: true,
+    rightAligned: false,
+    centerHorizontally: true,
+    moveBelowToFit: true
+  },
 
   get _panel() { return document.getElementById("context-container"); },
   get _popup() { return document.getElementById("context-popup"); },
   get _commands() { return this._popup.childNodes[0]; },
 
   get _menuPopup() {
     if (!this.__menuPopup)
       this.__menuPopup = new MenuPopup(this._panel, this._popup);
@@ -177,17 +184,21 @@ var ContextMenuUI = {
       }
     }
 
     if (!optionsAvailable) {
       this._popupState = null;
       return false;
     }
 
-    this._menuPopup.show(this._popupState);
+    this._menuPopup.show(Util.extend({}, this._defaultPositionOptions, {
+      xPos: aMessage.json.xPos,
+      yPos: aMessage.json.yPos,
+      source: aMessage.json.source
+    }));
     return true;
   },
 
   hide: function hide () {
     this._menuPopup.hide();
     this._popupState = null;
   },
 
@@ -374,33 +385,33 @@ MenuPopup.prototype = {
 
     this._panel.removeAttribute("showing");
   },
 
   _position: function _position(aPositionOptions) {
     let aX = aPositionOptions.xPos;
     let aY = aPositionOptions.yPos;
     let aSource = aPositionOptions.source;
-    let forcePosition = aPositionOptions.forcePosition || false;
-    let isRightAligned = aPositionOptions.rightAligned || false;
-    let isBottomAligned = aPositionOptions.bottomAligned || false;
 
     let width = this._popup.boxObject.width;
     let height = this._popup.boxObject.height;
     let halfWidth = width / 2;
     let halfHeight = height / 2;
     let screenWidth = ContentAreaObserver.width;
     let screenHeight = ContentAreaObserver.height;
 
-    if (forcePosition) {
-      if (isRightAligned)
+    if (aPositionOptions.forcePosition) {
+      if (aPositionOptions.rightAligned)
         aX -= width;
 
-      if (isBottomAligned)
+      if (aPositionOptions.bottomAligned)
         aY -= height;
+
+      if (aPositionOptions.centerHorizontally)
+        aX -= halfWidth;
     } else {
       let leftHand = MetroUtils.handPreference == MetroUtils.handPreferenceLeft;
 
       // Add padding on the side of the menu per the user's hand preference
       if (aSource && aSource == Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH) {
         if (leftHand) {
           this._commands.setAttribute("left-hand", true);
           this._commands.removeAttribute("right-hand");
@@ -441,18 +452,22 @@ MenuPopup.prototype = {
       } else {
         dump('None, left hand: ' + leftHand + '!\n');
       }
     }
 
     if (aX < 0)
       aX = 0;
 
-    if (aY < 0)
+    if (aY < 0 && aPositionOptions.moveBelowToFit) {
+      // show context menu below when it doesn't fit.
+      aY = aPositionOptions.yPos;
+    } else if (aY < 0) {
       aY = 0;
+    }
 
     this._panel.left = aX;
     this._panel.top = aY;
 
     let excessY = (aY + height + kPositionPadding - screenHeight);
     this._popup.style.maxHeight = (excessY > 0) ? (height - excessY) + "px" : "none";
 
     let excessX = (aX + width + kPositionPadding - screenWidth);
--- a/browser/metro/base/tests/Makefile.in
+++ b/browser/metro/base/tests/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 relativesrcdir  = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/config/rules.mk
 
 BROWSER_TESTS = \
   head.js \
   browser_test.js \
   browser_canonizeURL.js \
   browser_context_ui.js \
   browser_onscreen_keyboard.js \
   browser_onscreen_keyboard.html \
@@ -29,13 +28,26 @@ BROWSER_TESTS = \
   browser_context_menu_tests_03.html \
   text-block.html \
   $(NULL)
 
 BROWSER_TEST_RESOURCES = \
   res/image01.png \
   $(NULL)
 
+XPCSHELL_TESTS = unit
+
+# For now we're copying the actual Util code.
+# We should make this into a jsm module. See bug 848137
+XPCSHELL_RESOURCES = \
+  $(DEPTH)/browser/metro/base/content/Util.js \
+  $(NULL)
+
 libs:: $(BROWSER_TESTS)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/metro/
 
 libs:: $(BROWSER_TEST_RESOURCES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/metro/res
+
+libs:: $(XPCSHELL_RESOURCES)
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit/
+
+include $(topsrcdir)/config/rules.mk
--- a/browser/metro/base/tests/browser_context_menu_tests.js
+++ b/browser/metro/base/tests/browser_context_menu_tests.js
@@ -1,9 +1,9 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 function debugClipFlavors(aClip)
 {
@@ -21,16 +21,24 @@ function debugClipFlavors(aClip)
 }
 
 // XXX won't work with out of process content
 function emptyClipboard() {
   Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard)
                                        .emptyClipboard(Ci.nsIClipboard.kGlobalClipboard);
 }
 
+function checkContextMenuPositionRange(aElement, aMinLeft, aMaxLeft, aMinTop, aMaxTop) {
+  ok(aElement.left > aMinLeft && aElement.left < aMaxLeft,
+    "Left position is " + aElement.left + ", expected between " + aMinLeft + " and " + aMaxLeft);
+
+  ok(aElement.top > aMinTop && aElement.top < aMaxTop, 
+    "Top position is " + aElement.top + ", expected between " + aMinTop + " and " + aMaxTop);
+}
+
 gTests.push({
   desc: "text context menu",
   run: function test() {
     netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 
     info(chromeRoot + "browser_context_menu_tests_02.html");
     yield addTab(chromeRoot + "browser_context_menu_tests_02.html");
 
@@ -419,72 +427,68 @@ gTests.push({
     let promise = waitForEvent(document, "popupshown");
     sendContextMenuClickToElement(frame1.contentDocument.defaultView, link1, 85, 10);
     yield promise;
     ok(promise && !(promise instanceof Error), "promise error");
 
     // should be visible
     ok(ContextMenuUI._menuPopup._visible, "is visible");
 
-    ok(ContextMenuUI._panel.left > 375 && ContextMenuUI._panel.left < 390, "position");
-    ok(ContextMenuUI._panel.top > 235 && ContextMenuUI._panel.top < 245, "position");
+    checkContextMenuPositionRange(ContextMenuUI._panel, 560, 570, 175, 190);
 
     promise = waitForEvent(document, "popuphidden");
     ContextMenuUI.hide();
     yield promise;
     ok(promise && !(promise instanceof Error), "promise error");
 
     frame1.contentDocument.defaultView.scrollBy(0, 200);
 
     promise = waitForEvent(document, "popupshown");
     sendContextMenuClickToElement(frame1.contentDocument.defaultView, link1, 85, 10);
     yield promise;
     ok(promise && !(promise instanceof Error), "promise error");
 
     // should be visible
     ok(ContextMenuUI._menuPopup._visible, "is visible");
 
-    ok(ContextMenuUI._panel.left > 375 && ContextMenuUI._panel.left < 390, "position");
-    ok(ContextMenuUI._panel.top > 35 && ContextMenuUI._panel.top < 45, "position");
+    checkContextMenuPositionRange(ContextMenuUI._panel, 560, 570, 95, 110);
 
     promise = waitForEvent(document, "popuphidden");
     ContextMenuUI.hide();
     yield promise;
     ok(promise && !(promise instanceof Error), "promise error");
 
     let rlink1 = win.document.getElementById("rlink1");
 
     promise = waitForEvent(document, "popupshown");
     sendContextMenuClickToElement(win, rlink1, 40, 10);
     yield promise;
     ok(promise && !(promise instanceof Error), "promise error");
 
     // should be visible
     ok(ContextMenuUI._menuPopup._visible, "is visible");
 
-    ok(ContextMenuUI._panel.left > 730 && ContextMenuUI._panel.left < 745, "position");
-    ok(ContextMenuUI._panel.top > 600 && ContextMenuUI._panel.top < 610, "position");
+    checkContextMenuPositionRange(ContextMenuUI._panel, 910, 925, 540, 555);
 
     promise = waitForEvent(document, "popuphidden");
     ContextMenuUI.hide();
     yield promise;
     ok(promise && !(promise instanceof Error), "promise error");
 
     win.scrollBy(0, 200);
 
     promise = waitForEvent(document, "popupshown");
     sendContextMenuClickToElement(win, rlink1, 40, 10);
     yield promise;
     ok(promise && !(promise instanceof Error), "promise error");
 
     // should be visible
     ok(ContextMenuUI._menuPopup._visible, "is visible");
 
-    ok(ContextMenuUI._panel.left > 730 && ContextMenuUI._panel.left < 745, "position");
-    ok(ContextMenuUI._panel.top > 400 && ContextMenuUI._panel.top < 410, "position");
+    checkContextMenuPositionRange(ContextMenuUI._panel, 910, 925, 340, 355);
 
     promise = waitForEvent(document, "popuphidden");
     ContextMenuUI.hide();
     yield promise;
     ok(promise && !(promise instanceof Error), "promise error");
 
     let link2 = frame1.contentDocument.getElementById("link2");
 
@@ -494,18 +498,17 @@ gTests.push({
     ok(promise && !(promise instanceof Error), "promise error");
 
     // should be visible
     ok(ContextMenuUI._menuPopup._visible, "is visible");
 
     info(ContextMenuUI._panel.left);
     info(ContextMenuUI._panel.top);
 
-    ok(ContextMenuUI._panel.left > 380 && ContextMenuUI._panel.left < 390, "position");
-    ok(ContextMenuUI._panel.top > 170 && ContextMenuUI._panel.top < 185, "position");
+    checkContextMenuPositionRange(ContextMenuUI._panel, 560, 570, 110, 125);
 
     promise = waitForEvent(document, "popuphidden");
     ContextMenuUI.hide();
     yield promise;
     ok(promise && !(promise instanceof Error), "promise error");
   }
 });
 
new file mode 100644
--- /dev/null
+++ b/browser/metro/base/tests/unit/test_util_extend.js
@@ -0,0 +1,38 @@
+load('Util.js');
+
+function run_test() {
+  do_print("Testing Util.extend");
+  
+  do_print("Check if function is defined");
+  do_check_true(!!Util.extend);
+
+  do_print("No parameter or null should return a new object");
+  let noArgRes = Util.extend();
+  do_check_true(noArgRes && typeof noArgRes == "object");
+
+  let nullRes = Util.extend(null);
+  do_check_true(nullRes && typeof nullRes == "object");
+  
+  do_print("Simple extend");
+  let simpleExtend = {a: 1, b: 2};
+  let simpleExtendResult = Util.extend(simpleExtend, {b: 3, c: 4});
+
+  do_check_true(simpleExtend.a === 1 && simpleExtend.b === 3 && simpleExtend.c === 4);
+  do_check_true(simpleExtendResult === simpleExtend);
+
+  do_print("Cloning");
+  let cloneExtend = {a: 1, b: 2};
+  let cloned = Util.extend({}, cloneExtend);
+
+  do_check_true(cloneExtend.a === cloned.a && cloneExtend.b === cloned.b);
+  do_check_true(cloneExtend !== cloned);
+
+  do_print("Multiple extend");
+  let multiExtend1 = {a: 1, b: 2};
+  let multiExtend2 = {c: 3, d: 4};
+  let multiExtend3 = {b: 5, e: 6};
+  let multiExtend4 = {e: 7, a: 8};
+  let multiResult = Util.extend({}, multiExtend1, multiExtend2, multiExtend3, multiExtend4);
+
+  do_check_true(multiResult.a === 8 && multiResult.b === 5 && multiResult.c === 3 && multiResult.d === 4 && multiResult.e === 7);
+}
new file mode 100644
--- /dev/null
+++ b/browser/metro/base/tests/unit/xpcshell.ini
@@ -0,0 +1,5 @@
+[DEFAULT]
+head = 
+tail =
+
+[test_util_extend.js]
--- a/browser/metro/components/Makefile.in
+++ b/browser/metro/components/Makefile.in
@@ -7,17 +7,16 @@ topsrcdir  = @top_srcdir@
 srcdir     = @srcdir@
 VPATH      = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/config.mk
 
 # metro/components.manifest
 MODULE = components
-XPIDL_MODULE = components
 
 XPIDLSRCS = \
         SessionStore.idl \
         LoginManagerPrompter.idl \
         $(NULL)
 
 EXTRA_PP_COMPONENTS = \
         components.manifest \
--- a/browser/modules/Social.jsm
+++ b/browser/modules/Social.jsm
@@ -28,16 +28,17 @@ function prefObserver(subject, topic, da
 
 Services.prefs.addObserver("social.enabled", prefObserver, false);
 Services.obs.addObserver(function xpcomShutdown() {
   Services.obs.removeObserver(xpcomShutdown, "xpcom-shutdown");
   Services.prefs.removeObserver("social.enabled", prefObserver);
 }, "xpcom-shutdown", false);
 
 this.Social = {
+  initialized: false,
   lastEventReceived: 0,
   providers: null,
   _disabledForSafeMode: false,
 
   get _currentProviderPref() {
     try {
       return Services.prefs.getComplexValue("social.provider.current",
                                             Ci.nsISupportsString).data;
@@ -92,19 +93,20 @@ this.Social = {
       return null;
     let provider = this._getProviderFromOrigin(this._currentProviderPref);
     return provider || this.providers[0];
   },
 
   init: function Social_init() {
     this._disabledForSafeMode = Services.appinfo.inSafeMode && this.enabled;
 
-    if (this.providers) {
+    if (this.initialized) {
       return;
     }
+    this.initialized = true;
 
     // Retrieve the current set of providers, and set the current provider.
     SocialService.getProviderList(function (providers) {
       this._updateProviderCache(providers);
     }.bind(this));
 
     // Register an observer for changes to the provider list
     SocialService.registerProviderListener(function providerListener(topic, data) {
@@ -115,19 +117,22 @@ this.Social = {
       }
     }.bind(this));
   },
 
   // Called to update our cache of providers and set the current provider
   _updateProviderCache: function (providers) {
     this.providers = providers;
 
-    // If social is currently disabled there's nothing else to do.
-    if (!SocialService.enabled)
+    // If social is currently disabled there's nothing else to do other than
+    // to notify about the lack of a provider.
+    if (!SocialService.enabled) {
+      Services.obs.notifyObservers(null, "social:provider-set", null);
       return;
+    }
     // Otherwise set the provider.
     this._setProvider(this.defaultProvider);
   },
 
   set enabled(val) {
     // Setting .enabled is just a shortcut for setting the provider to either
     // the default provider or null...
     if (val) {
--- a/build/mach_bootstrap.py
+++ b/build/mach_bootstrap.py
@@ -1,9 +1,8 @@
-#!/usr/bin/env python
 # 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/.
 
 from __future__ import print_function, unicode_literals
 
 import os
 import platform
@@ -36,27 +35,30 @@ MACH_MODULES = [
     'python/mozbuild/mozbuild/config.py',
     'python/mozbuild/mozbuild/mach_commands.py',
     'python/mozbuild/mozbuild/frontend/mach_commands.py',
     'testing/mochitest/mach_commands.py',
     'testing/xpcshell/mach_commands.py',
     'tools/mach_commands.py',
 ]
 
-def bootstrap(topsrcdir):
+def bootstrap(topsrcdir, mozilla_dir=None):
+    if mozilla_dir is None:
+        mozilla_dir = topsrcdir
+
     # Ensure we are running Python 2.7+. We put this check here so we generate a
     # user-friendly error message rather than a cryptic stack trace on module
     # import.
     if sys.version_info[0] != 2 or sys.version_info[1] < 7:
         print('Python 2.7 or above (but not Python 3) is required to run mach.')
         print('You are running Python', platform.python_version())
         sys.exit(1)
 
     try:
         import mach.main
     except ImportError:
-        sys.path[0:0] = [os.path.join(topsrcdir, path) for path in SEARCH_PATHS]
+        sys.path[0:0] = [os.path.join(mozilla_dir, path) for path in SEARCH_PATHS]
         import mach.main
 
     mach = mach.main.Mach(topsrcdir)
     for path in MACH_MODULES:
-        mach.load_commands_from_file(os.path.join(topsrcdir, path))
+        mach.load_commands_from_file(os.path.join(mozilla_dir, path))
     return mach
--- a/build/mobile/b2gautomation.py
+++ b/build/mobile/b2gautomation.py
@@ -235,17 +235,17 @@ class B2GRemoteAutomation(Automation):
                 raise Exception("network did not come up, please configure the network" +
                                 " prior to running before running the automation framework")
 
         # stop b2g
         self._devicemanager._runCmd(['shell', 'stop', 'b2g'])
         time.sleep(5)
 
         # relaunch b2g inside b2g instance
-        instance = self.B2GInstance(self._devicemanager)
+        instance = self.B2GInstance(self._devicemanager, env=env)
 
         time.sleep(5)
 
         # Set up port forwarding again for Marionette, since any that
         # existed previously got wiped out by the reboot.
         if not self._is_emulator:
             self._devicemanager._checkCmd(['forward',
                                            'tcp:%s' % self.marionette.port,
@@ -293,29 +293,32 @@ class B2GRemoteAutomation(Automation):
 
     # be careful here as this inner class doesn't have access to outer class members
     class B2GInstance(object):
         """Represents a B2G instance running on a device, and exposes
            some process-like methods/properties that are expected by the
            automation.
         """
 
-        def __init__(self, dm):
+        def __init__(self, dm, env=None):
             self.dm = dm
+            self.env = env or {}
             self.stdout_proc = None
             self.queue = Queue.Queue()
 
             # Launch b2g in a separate thread, and dump all output lines
             # into a queue.  The lines in this queue are
             # retrieved and returned by accessing the stdout property of
             # this class.
             cmd = [self.dm._adbPath]
             if self.dm._deviceSerial:
                 cmd.extend(['-s', self.dm._deviceSerial])
             cmd.append('shell')
+            for k, v in self.env.iteritems():
+                cmd.append("%s=%s" % (k, v))
             cmd.append('/system/bin/b2g.sh')
             proc = threading.Thread(target=self._save_stdout_proc, args=(cmd, self.queue))
             proc.daemon = True
             proc.start()
 
         def _save_stdout_proc(self, cmd, queue):
             self.stdout_proc = StdOutProc(cmd, queue)
             self.stdout_proc.run()
--- a/build/unix/stdc++compat/stdc++compat.cpp
+++ b/build/unix/stdc++compat/stdc++compat.cpp
@@ -29,16 +29,17 @@ namespace std {
     template ostream& ostream::_M_insert(bool);
     template ostream& ostream::_M_insert(const void*);
     template ostream& __ostream_insert(ostream&, const char*, streamsize);
     template istream& istream::_M_extract(double&);
     template istream& istream::_M_extract(float&);
     template istream& istream::_M_extract(unsigned int&);
     template istream& istream::_M_extract(unsigned long&);
     template istream& istream::_M_extract(unsigned short&);
+    template istream& istream::_M_extract(unsigned long long&);
 #endif
 #if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 14)
     /* Instantiate these templates to avoid GLIBCXX_3.4.14 symbol versions
      * depending on optimization level */
     template char *string::_S_construct_aux_2(size_type, char, allocator<char> const&);
 #ifdef _GLIBCXX_USE_WCHAR_T
     template wchar_t *wstring::_S_construct_aux_2(size_type, wchar_t, allocator<wchar_t> const&);
 #endif /* _GLIBCXX_USE_WCHAR_T */
--- a/configure.in
+++ b/configure.in
@@ -5976,19 +5976,22 @@ if test -n "$MOZ_CRASHREPORTER"; then
     AC_SUBST(MOZ_GTHREAD_CFLAGS)
     AC_SUBST(MOZ_GTHREAD_LIBS)
   fi
 
   if test "$OS_ARCH" != "$HOST_OS_ARCH"; then
     AC_MSG_ERROR([Breakpad tools do not support compiling on $HOST_OS_ARCH while targeting $OS_ARCH.  Use --disable-crashreporter.])
   fi
 
-  if test "$OS_ARCH" = "WINNT" -a -z "$HAVE_64BIT_OS"; then
-    MOZ_CRASHREPORTER_INJECTOR=1
-    AC_DEFINE(MOZ_CRASHREPORTER_INJECTOR)
+  if test "$OS_ARCH" = "WINNT"; then
+    AC_DEFINE_UNQUOTED(BREAKPAD_CUSTOM_STDINT_H, "mozilla/StandardInteger.h")
+    if test -z "$HAVE_64BIT_OS"; then
+      MOZ_CRASHREPORTER_INJECTOR=1
+      AC_DEFINE(MOZ_CRASHREPORTER_INJECTOR)
+    fi
   fi
 fi
 
 MOZ_ARG_WITH_STRING(crashreporter-enable-percent,
 [  --with-crashreporter-enable-percent=NN
                           Enable sending crash reports by default on NN% of users. (default=100)],
 [ val=`echo $withval | sed 's/[^0-9]//g'`
     MOZ_CRASHREPORTER_ENABLE_PERCENT="$val"])
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -358,17 +358,19 @@ public:
     /** document fragments */
     eDOCUMENT_FRAGMENT   = 1 << 7,
     /** data nodes (comments, PIs, text). Nodes of this type always
      returns a non-null value for nsIContent::GetText() */
     eDATA_NODE           = 1 << 8,
     /** nsHTMLMediaElement */
     eMEDIA               = 1 << 9,
     /** animation elements */
-    eANIMATION           = 1 << 10
+    eANIMATION           = 1 << 10,
+    /** filter elements that implement SVGFilterPrimitiveStandardAttributes */
+    eFILTER              = 1 << 11
   };
 
   /**
    * API for doing a quick check if a content is of a given
    * type, such as Text, Document, Comment ...  Use this when you can instead of
    * checking the tag.
    *
    * @param aFlags what types you want to test for (see above)
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -7614,17 +7614,17 @@ nsDocument::CanSavePresentation(nsIReque
 #endif
         return false;
       }
     }
   }
 
   // Check if we have running IndexedDB transactions
   indexedDB::IndexedDatabaseManager* idbManager =
-    indexedDB::IndexedDatabaseManager::Get();
+    win ? indexedDB::IndexedDatabaseManager::Get() : nullptr;
   if (idbManager && idbManager->HasOpenTransactions(win)) {
     return false;
   }
 
 #ifdef MOZ_WEBRTC
   // Check if we have active PeerConnections
   nsCOMPtr<IPeerConnectionManager> pcManager =
     do_GetService(IPEERCONNECTION_MANAGER_CONTRACTID);
--- a/content/base/src/nsImageLoadingContent.cpp
+++ b/content/base/src/nsImageLoadingContent.cpp
@@ -78,16 +78,17 @@ nsImageLoadingContent::nsImageLoadingCon
     mImageBlockingStatus(nsIContentPolicy::ACCEPT),
     mLoadingEnabled(true),
     mIsImageStateForced(false),
     mLoading(false),
     // mBroken starts out true, since an image without a URI is broken....
     mBroken(true),
     mUserDisabled(false),
     mSuppressed(false),
+    mFireEventsOnDecode(false),
     mNewRequestsWillNeedAnimationReset(false),
     mStateChangerDepth(0),
     mCurrentRequestRegistered(false),
     mPendingRequestRegistered(false),
     mVisibleCount(0)
 {
   if (!nsContentUtils::GetImgLoaderForChannel(nullptr)) {
     mLoadingEnabled = false;
@@ -156,16 +157,30 @@ nsImageLoadingContent::Notify(imgIReques
   if (aType == imgINotificationObserver::LOAD_COMPLETE) {
     uint32_t reqStatus;
     aRequest->GetImageStatus(&reqStatus);
     nsresult status =
         reqStatus & imgIRequest::STATUS_ERROR ? NS_ERROR_FAILURE : NS_OK;
     return OnStopRequest(aRequest, status);
   }
 
+  if (aType == imgINotificationObserver::DECODE_COMPLETE && mFireEventsOnDecode) {
+    mFireEventsOnDecode = false;
+
+    uint32_t reqStatus;
+    aRequest->GetImageStatus(&reqStatus);
+    if (reqStatus & imgIRequest::STATUS_ERROR) {
+      FireEvent(NS_LITERAL_STRING("error"));
+    } else {
+      FireEvent(NS_LITERAL_STRING("load"));
+    }
+
+    UpdateImageState(true);
+  }
+
   return NS_OK;
 }
 
 nsresult
 nsImageLoadingContent::OnStopRequest(imgIRequest* aRequest,
                                      nsresult aStatus)
 {
   uint32_t oldStatus;
@@ -208,29 +223,44 @@ nsImageLoadingContent::OnStopRequest(img
   // (*) IsPaintingSuppressed returns false if we haven't gotten the initial
   // reflow yet, so we have to test !DidInitialize || IsPaintingSuppressed.
   // It's possible for painting to be suppressed for reasons other than the
   // initial paint delay (for example, being in the bfcache), but we probably
   // aren't loading images in those situations.
 
   // XXXkhuey should this be GetOurCurrentDoc?  Decoding if we're not in
   // the document seems silly.
+  bool startedDecoding = false;
   nsIDocument* doc = GetOurOwnerDoc();
   nsIPresShell* shell = doc ? doc->GetShell() : nullptr;
   if (shell && shell->IsVisible() &&
       (!shell->DidInitialize() || shell->IsPaintingSuppressed())) {
 
-    mCurrentRequest->StartDecoding();
+    if (NS_SUCCEEDED(mCurrentRequest->StartDecoding())) {
+      startedDecoding = true;
+    }
   }
 
-  // Fire the appropriate DOM event.
-  if (NS_SUCCEEDED(aStatus)) {
-    FireEvent(NS_LITERAL_STRING("load"));
+  // We want to give the decoder a chance to find errors. If we haven't found
+  // an error yet and we've started decoding, either from the above
+  // StartDecoding or from some other place, we must only fire these events
+  // after we finish decoding.
+  uint32_t reqStatus;
+  aRequest->GetImageStatus(&reqStatus);
+  if (NS_SUCCEEDED(aStatus) && !(reqStatus & imgIRequest::STATUS_ERROR) &&
+      (reqStatus & imgIRequest::STATUS_DECODE_STARTED ||
+       (startedDecoding && !(reqStatus & imgIRequest::STATUS_DECODE_COMPLETE)))) {
+    mFireEventsOnDecode = true;
   } else {
-    FireEvent(NS_LITERAL_STRING("error"));
+    // Fire the appropriate DOM event.
+    if (NS_SUCCEEDED(aStatus)) {
+      FireEvent(NS_LITERAL_STRING("load"));
+    } else {
+      FireEvent(NS_LITERAL_STRING("error"));
+    }
   }
 
   nsCOMPtr<nsINode> thisNode = do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
   nsSVGEffects::InvalidateDirectRenderingObservers(thisNode->AsElement());
 
   return NS_OK;
 }
 
--- a/content/base/src/nsImageLoadingContent.h
+++ b/content/base/src/nsImageLoadingContent.h
@@ -392,16 +392,17 @@ private:
   /**
    * The state we had the last time we checked whether we needed to notify the
    * document of a state change.  These are maintained by UpdateImageState.
    */
   bool mLoading : 1;
   bool mBroken : 1;
   bool mUserDisabled : 1;
   bool mSuppressed : 1;
+  bool mFireEventsOnDecode : 1;
 
 protected:
   /**
    * A hack to get animations to reset, see bug 594771. On requests
    * that originate from setting .src, we mark them for needing their animation
    * reset when they are ready. mNewRequestsWillNeedAnimationReset is set to
    * true while preparing such requests (as a hack around needing to change an
    * interface), and the other two booleans store which of the current
--- a/content/base/src/nsNodeInfo.cpp
+++ b/content/base/src/nsNodeInfo.cpp
@@ -19,17 +19,16 @@
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsIAtom.h"
 #include "nsDOMString.h"
 #include "nsCRT.h"
 #include "nsContentUtils.h"
 #include "nsReadableUtils.h"
 #include "nsAutoPtr.h"
-#include NEW_H
 #include "prprf.h"
 #include "nsIDocument.h"
 #include "nsGkAtoms.h"
 #include "nsCCUncollectableMarker.h"
 
 using namespace mozilla;
 
 nsNodeInfo::~nsNodeInfo()
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -1,82 +1,101 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "nsEventDispatcher.h"
 #include "nsDOMEvent.h"
 #include "nsIDOMEventTarget.h"
 #include "nsPresContext.h"
 #include "nsEventListenerManager.h"
 #include "nsContentUtils.h"
 #include "nsError.h"
 #include "nsMutationEvent.h"
 #include NEW_H
-#include "nsFixedSizeAllocator.h"
 #include "nsINode.h"
 #include "nsPIDOMWindow.h"
 #include "nsFrameLoader.h"
 #include "nsDOMTouchEvent.h"
 #include "nsDOMStorage.h"
 #include "sampler.h"
 #include "GeneratedEvents.h"
 
 using namespace mozilla;
 
 #define NS_TARGET_CHAIN_FORCE_CONTENT_DISPATCH  (1 << 0)
 #define NS_TARGET_CHAIN_WANTS_WILL_HANDLE_EVENT (1 << 1)
 #define NS_TARGET_CHAIN_MAY_HAVE_MANAGER        (1 << 2)
 
-static nsEventTargetChainItem* gCachedETCI = nullptr;
-
 // nsEventTargetChainItem represents a single item in the event target chain.
 class nsEventTargetChainItem
 {
 private:
   nsEventTargetChainItem(nsIDOMEventTarget* aTarget,
                          nsEventTargetChainItem* aChild = nullptr);
 
+  // This is the ETCI recycle pool, which is used to avoid some malloc/free
+  // churn.  It's implemented as a linked list.
+  static nsEventTargetChainItem* sEtciRecyclePool;
+  static uint32_t sNumRecycledEtcis;
+  static const uint32_t kMaxNumRecycledEtcis = 128;
+
 public:
-  static nsEventTargetChainItem* Create(nsFixedSizeAllocator* aAllocator, 
-                                        nsIDOMEventTarget* aTarget,
+  static nsEventTargetChainItem* Create(nsIDOMEventTarget* aTarget,
                                         nsEventTargetChainItem* aChild = nullptr)
   {
+    // Allocate from the ETCI recycle pool if possible.
     void* place = nullptr;
-    if (gCachedETCI) {
-      place = gCachedETCI;
-      gCachedETCI = gCachedETCI->mNext;
+    if (sNumRecycledEtcis > 0) {
+      MOZ_ASSERT(sEtciRecyclePool);
+      place = sEtciRecyclePool;
+      sEtciRecyclePool = sEtciRecyclePool->mNext;
+      --sNumRecycledEtcis;
     } else {
-      place = aAllocator->Alloc(sizeof(nsEventTargetChainItem));
+      place = malloc(sizeof(nsEventTargetChainItem));
     }
     return place
       ? ::new (place) nsEventTargetChainItem(aTarget, aChild)
       : nullptr;
   }
 
-  static void Destroy(nsFixedSizeAllocator* aAllocator,
-                      nsEventTargetChainItem* aItem)
+  static void Destroy(nsEventTargetChainItem* aItem)
   {
     // ::Destroy deletes ancestor chain.
     nsEventTargetChainItem* item = aItem;
     if (item->mChild) {
       item->mChild->mParent = nullptr;
       item->mChild = nullptr;
     }
+    // Put destroyed ETCIs into the recycle pool if it's not already full.
     while (item) {
       nsEventTargetChainItem* parent = item->mParent;
       item->~nsEventTargetChainItem();
-      item->mNext = gCachedETCI;
-      gCachedETCI = item;
-      --sCurrentEtciCount;
+      if (sNumRecycledEtcis < kMaxNumRecycledEtcis) {
+        item->mNext = sEtciRecyclePool;
+        sEtciRecyclePool = item;
+        ++sNumRecycledEtcis;
+      } else {
+        free(item);
+      }
       item = parent;
     }
   }
 
+  static void ShutdownRecyclePool()
+  {
+    while (sEtciRecyclePool) {
+      nsEventTargetChainItem* tmp = sEtciRecyclePool;
+      sEtciRecyclePool = sEtciRecyclePool->mNext;
+      free(tmp);
+    }
+  }
+
   bool IsValid()
   {
     NS_WARN_IF_FALSE(!!(mTarget), "Event target is not valid!");
     return !!(mTarget);
   }
 
   nsIDOMEventTarget* GetNewTarget()
   {
@@ -200,46 +219,42 @@ public:
     MOZ_ASSERT(!sCurrentEtciCount, "Wrong time to call ResetMaxEtciCount()!");
     sMaxEtciCount = 0;
   }
 
   nsCOMPtr<nsIDOMEventTarget>       mTarget;
   nsEventTargetChainItem*           mChild;
   union {
     nsEventTargetChainItem*         mParent;
-     // This is used only when caching ETCI objects.
+     // This is used only when recycling ETCIs.
     nsEventTargetChainItem*         mNext;
   };
   uint16_t                          mFlags;
   uint16_t                          mItemFlags;
   nsCOMPtr<nsISupports>             mItemData;
   // Event retargeting must happen whenever mNewTarget is non-null.
   nsCOMPtr<nsIDOMEventTarget>       mNewTarget;
   // Cache mTarget's event listener manager.
   nsRefPtr<nsEventListenerManager>  mManager;
 
   static uint32_t                   sMaxEtciCount;
   static uint32_t                   sCurrentEtciCount;
 };
 
-uint32_t nsEventTargetChainItem::sMaxEtciCount = 0;
-uint32_t nsEventTargetChainItem::sCurrentEtciCount = 0;
+nsEventTargetChainItem* nsEventTargetChainItem::sEtciRecyclePool = nullptr;
+uint32_t nsEventTargetChainItem::sNumRecycledEtcis = 0;
 
 nsEventTargetChainItem::nsEventTargetChainItem(nsIDOMEventTarget* aTarget,
                                                nsEventTargetChainItem* aChild)
 : mTarget(aTarget), mChild(aChild), mParent(nullptr), mFlags(0), mItemFlags(0)
 {
   MOZ_ASSERT(!aTarget || mTarget == aTarget->GetTargetForEventTargetChain());
   if (mChild) {
     mChild->mParent = this;
   }
-
-  if (++sCurrentEtciCount > sMaxEtciCount) {
-    sMaxEtciCount = sCurrentEtciCount;
-  }
 }
 
 nsresult
 nsEventTargetChainItem::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   aVisitor.Reset();
   nsresult rv = mTarget->PreHandleEvent(aVisitor);
   SetForceContentDispatch(aVisitor.mForceContentDispatch);
@@ -373,95 +388,38 @@ nsEventTargetChainItem::HandleEventTarge
     // system group listeners don't affect to the event.
     aVisitor.mEvent->mFlags.mPropagationStopped = false;
     aVisitor.mEvent->mFlags.mImmediatePropagationStopped = false;
   }
 
   return NS_OK;
 }
 
-#define NS_CHAIN_POOL_SIZE 128
-
-class ChainItemPool {
-public:
-  ChainItemPool() {
-    if (!sEtciPool) {
-      sEtciPool = new nsFixedSizeAllocator();
-      if (sEtciPool) {
-        static const size_t kBucketSizes[] = { sizeof(nsEventTargetChainItem) };
-        static const int32_t kNumBuckets = sizeof(kBucketSizes) / sizeof(size_t);
-        static const int32_t kInitialPoolSize =
-          sizeof(nsEventTargetChainItem) * NS_CHAIN_POOL_SIZE;
-        nsresult rv = sEtciPool->Init("EventTargetChainItem Pool", kBucketSizes,
-                                      kNumBuckets, kInitialPoolSize);
-        if (NS_FAILED(rv)) {
-          delete sEtciPool;
-          sEtciPool = nullptr;
-        }
-      }
-    }
-    if (sEtciPool) {
-      ++sEtciPoolUsers;
-    }
-  }
-
-  ~ChainItemPool() {
-    if (sEtciPool) {
-      --sEtciPoolUsers;
-    }
-    if (!sEtciPoolUsers) {
-      if (nsEventTargetChainItem::MaxEtciCount() > NS_CHAIN_POOL_SIZE) {
-        gCachedETCI = nullptr;
-        delete sEtciPool;
-        sEtciPool = nullptr;
-        nsEventTargetChainItem::ResetMaxEtciCount();
-      }
-    }
-  }
-
-  static void Shutdown()
-  {
-    if (!sEtciPoolUsers) {
-      gCachedETCI = nullptr;
-      delete sEtciPool;
-      sEtciPool = nullptr;
-      nsEventTargetChainItem::ResetMaxEtciCount();
-    }
-  }
-
-  nsFixedSizeAllocator* GetPool() { return sEtciPool; }
-
-  static nsFixedSizeAllocator* sEtciPool;
-  static int32_t               sEtciPoolUsers;
-};
-
-nsFixedSizeAllocator* ChainItemPool::sEtciPool = nullptr;
-int32_t ChainItemPool::sEtciPoolUsers = 0;
-
-void NS_ShutdownChainItemPool() { ChainItemPool::Shutdown(); }
+void NS_ShutdownEventTargetChainItemRecyclePool()
+{
+  nsEventTargetChainItem::ShutdownRecyclePool();
+}
 
 nsEventTargetChainItem*
-EventTargetChainItemForChromeTarget(ChainItemPool& aPool,
-                                    nsINode* aNode,
+EventTargetChainItemForChromeTarget(nsINode* aNode,
                                     nsEventTargetChainItem* aChild = nullptr)
 {
   if (!aNode->IsInDoc()) {
     return nullptr;
   }
   nsPIDOMWindow* win = aNode->OwnerDoc()->GetInnerWindow();
   nsIDOMEventTarget* piTarget = win ? win->GetParentTarget() : nullptr;
   NS_ENSURE_TRUE(piTarget, nullptr);
 
   nsEventTargetChainItem* etci =
-    nsEventTargetChainItem::Create(aPool.GetPool(),
-                                   piTarget->GetTargetForEventTargetChain(),
+    nsEventTargetChainItem::Create(piTarget->GetTargetForEventTargetChain(),
                                    aChild);
   NS_ENSURE_TRUE(etci, nullptr);
   if (!etci->IsValid()) {
-    nsEventTargetChainItem::Destroy(aPool.GetPool(), etci);
+    nsEventTargetChainItem::Destroy(etci);
     return nullptr;
   }
   return etci;
 }
 
 /* static */ nsresult
 nsEventDispatcher::Dispatch(nsISupports* aTarget,
                             nsPresContext* aPresContext,
@@ -546,26 +504,23 @@ nsEventDispatcher::Dispatch(nsISupports*
 #endif
 
   nsresult rv = NS_OK;
   bool externalDOMEvent = !!(aDOMEvent);
 
   // If we have a PresContext, make sure it doesn't die before
   // event dispatching is finished.
   nsRefPtr<nsPresContext> kungFuDeathGrip(aPresContext);
-  ChainItemPool pool;
-  NS_ENSURE_TRUE(pool.GetPool(), NS_ERROR_OUT_OF_MEMORY);
 
   // Create the event target chain item for the event target.
   nsEventTargetChainItem* targetEtci =
-    nsEventTargetChainItem::Create(pool.GetPool(),
-                                   target->GetTargetForEventTargetChain());
+    nsEventTargetChainItem::Create(target->GetTargetForEventTargetChain());
   NS_ENSURE_TRUE(targetEtci, NS_ERROR_OUT_OF_MEMORY);
   if (!targetEtci->IsValid()) {
-    nsEventTargetChainItem::Destroy(pool.GetPool(), targetEtci);
+    nsEventTargetChainItem::Destroy(targetEtci);
     return NS_ERROR_FAILURE;
   }
 
   // Make sure that nsIDOMEvent::target and nsIDOMEvent::originalTarget
   // point to the last item in the chain.
   if (!aEvent->target) {
     // Note, CurrentTarget() points always to the object returned by
     // GetTargetForEventTargetChain().
@@ -598,32 +553,31 @@ nsEventDispatcher::Dispatch(nsISupports*
   // PreHandleEvent for the original target.
   nsEventStatus status = aEventStatus ? *aEventStatus : nsEventStatus_eIgnore;
   nsEventChainPreVisitor preVisitor(aPresContext, aEvent, aDOMEvent, status,
                                     isInAnon);
   targetEtci->PreHandleEvent(preVisitor);
 
   if (!preVisitor.mCanHandle && preVisitor.mAutomaticChromeDispatch && content) {
     // Event target couldn't handle the event. Try to propagate to chrome.
-    nsEventTargetChainItem::Destroy(pool.GetPool(), targetEtci);
-    targetEtci = EventTargetChainItemForChromeTarget(pool, content);
+    nsEventTargetChainItem::Destroy(targetEtci);
+    targetEtci = EventTargetChainItemForChromeTarget(content);
     NS_ENSURE_STATE(targetEtci);
     targetEtci->PreHandleEvent(preVisitor);
   }
   if (preVisitor.mCanHandle) {
     // At least the original target can handle the event.
     // Setting the retarget to the |target| simplifies retargeting code.
     nsCOMPtr<nsIDOMEventTarget> t = aEvent->target;
     targetEtci->SetNewTarget(t);
     nsEventTargetChainItem* topEtci = targetEtci;
     while (preVisitor.mParentTarget) {
       nsIDOMEventTarget* parentTarget = preVisitor.mParentTarget;
       nsEventTargetChainItem* parentEtci =
-        nsEventTargetChainItem::Create(pool.GetPool(), preVisitor.mParentTarget,
-                                       topEtci);
+        nsEventTargetChainItem::Create(preVisitor.mParentTarget, topEtci);
       if (!parentEtci) {
         rv = NS_ERROR_OUT_OF_MEMORY;
         break;
       }
       if (!parentEtci->IsValid()) {
         rv = NS_ERROR_FAILURE;
         break;
       }
@@ -635,25 +589,24 @@ nsEventDispatcher::Dispatch(nsISupports*
         preVisitor.mEvent->target = preVisitor.mEventTargetAtParent;
         parentEtci->SetNewTarget(preVisitor.mEventTargetAtParent);
       }
 
       parentEtci->PreHandleEvent(preVisitor);
       if (preVisitor.mCanHandle) {
         topEtci = parentEtci;
       } else {
-        nsEventTargetChainItem::Destroy(pool.GetPool(), parentEtci);
+        nsEventTargetChainItem::Destroy(parentEtci);
         parentEtci = nullptr;
         if (preVisitor.mAutomaticChromeDispatch && content) {
           // Even if the current target can't handle the event, try to
           // propagate to chrome.
           nsCOMPtr<nsINode> disabledTarget = do_QueryInterface(parentTarget);
           if (disabledTarget) {
-            parentEtci = EventTargetChainItemForChromeTarget(pool,
-                                                             disabledTarget,
+            parentEtci = EventTargetChainItemForChromeTarget(disabledTarget,
                                                              topEtci);
             if (parentEtci) {
               parentEtci->PreHandleEvent(preVisitor);
               if (preVisitor.mCanHandle) {
                 targetEtci->SetNewTarget(parentTarget);
                 topEtci = parentEtci;
                 continue;
               }
@@ -674,27 +627,27 @@ nsEventDispatcher::Dispatch(nsISupports*
       } else {
         // Event target chain is created. Handle the chain.
         nsEventChainPostVisitor postVisitor(preVisitor);
         nsCxPusher pusher;
         rv = topEtci->HandleEventTargetChain(postVisitor,
                                              aCallback,
                                              false,
                                              &pusher);
-  
+
         preVisitor.mEventStatus = postVisitor.mEventStatus;
         // If the DOM event was created during event flow.
         if (!preVisitor.mDOMEvent && postVisitor.mDOMEvent) {
           preVisitor.mDOMEvent = postVisitor.mDOMEvent;
         }
       }
     }
   }
 
-  nsEventTargetChainItem::Destroy(pool.GetPool(), targetEtci);
+  nsEventTargetChainItem::Destroy(targetEtci);
   targetEtci = nullptr;
 
   aEvent->mFlags.mIsBeingDispatched = false;
   aEvent->mFlags.mDispatchedAtLeastOnce = true;
 
   if (!externalDOMEvent && preVisitor.mDOMEvent) {
     // An nsDOMEvent was created while dispatching the event.
     // Duplicate private data if someone holds a pointer to it.
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -4148,42 +4148,53 @@ nsEventStateManager::NotifyMouseOver(nsG
   // Turn recursion protection back off
   mFirstMouseOverEventElement = nullptr;
 }
 
 // Returns the center point of the window's inner content area.
 // This is in widget coordinates, i.e. relative to the widget's top
 // left corner, not in screen coordinates, the same units that
 // nsDOMUIEvent::refPoint is in.
+//
+// XXX Hack alert: XXX
+// However, we do the computation in integer CSS pixels, NOT device pix,
+// in order to fudge around the one-pixel error in innerHeight in fullscreen
+// mode (see bug 799523 comment 35, and bug 729011). Using integer CSS pix
+// makes us throw away the fractional error that results, rather than having
+// it manifest as a potential one-device-pix discrepancy.
 static nsIntPoint
 GetWindowInnerRectCenter(nsPIDOMWindow* aWindow,
                          nsIWidget* aWidget,
                          nsPresContext* aContext)
 {
   NS_ENSURE_TRUE(aWindow && aWidget && aContext, nsIntPoint(0,0));
 
   float cssInnerX = 0.0;
   aWindow->GetMozInnerScreenX(&cssInnerX);
-  int32_t innerX = int32_t(NS_round(aContext->CSSPixelsToDevPixels(cssInnerX)));
+  int32_t innerX = int32_t(NS_round(cssInnerX));
 
   float cssInnerY = 0.0;
   aWindow->GetMozInnerScreenY(&cssInnerY);
-  int32_t innerY = int32_t(NS_round(aContext->CSSPixelsToDevPixels(cssInnerY)));
+  int32_t innerY = int32_t(NS_round(cssInnerY));
  
   int32_t innerWidth = 0;
   aWindow->GetInnerWidth(&innerWidth);
 
   int32_t innerHeight = 0;
   aWindow->GetInnerHeight(&innerHeight);
- 
+
   nsIntRect screen;
   aWidget->GetScreenBounds(screen);
 
-  return nsIntPoint(innerX - screen.x + innerWidth / 2,
-                    innerY - screen.y + innerHeight / 2);
+  int32_t cssScreenX = aContext->DevPixelsToIntCSSPixels(screen.x);
+  int32_t cssScreenY = aContext->DevPixelsToIntCSSPixels(screen.y);
+
+  return nsIntPoint(
+    aContext->CSSPixelsToDevPixels(innerX - cssScreenX + innerWidth / 2),
+    aContext->CSSPixelsToDevPixels(innerY - cssScreenY + innerHeight / 2));
 }
 
 void
 nsEventStateManager::GenerateMouseEnterExit(nsGUIEvent* aEvent)
 {
   EnsureDocument(mPresContext);
   if (!mDocument)
     return;
--- a/content/svg/content/src/Makefile.in
+++ b/content/svg/content/src/Makefile.in
@@ -74,16 +74,21 @@ CPPSRCS		= \
 		SVGAttrValueWrapper.cpp \
 		SVGClipPathElement.cpp \
 		SVGCircleElement.cpp \
 		SVGContentUtils.cpp \
 		SVGDefsElement.cpp \
 		SVGDescElement.cpp \
 		SVGElementFactory.cpp \
 		SVGEllipseElement.cpp \
+		SVGFEBlendElement.cpp \
+		SVGFEFloodElement.cpp \
+		SVGFEImageElement.cpp \
+		SVGFEMergeElement.cpp \
+		SVGFEMergeNodeElement.cpp \
 		SVGFilterElement.cpp \
 		SVGForeignObjectElement.cpp \
 		SVGFragmentIdentifier.cpp \
 		SVGGElement.cpp \
 		SVGGradientElement.cpp \
 		SVGGraphicsElement.cpp \
 		SVGImageElement.cpp \
 		SVGIntegerPairSMILType.cpp \
@@ -165,16 +170,21 @@ EXPORTS_mozilla/dom = \
 	SVGAnimateMotionElement.h \
 	SVGAnimationElement.h \
 	SVGClipPathElement.h \
 	SVGCircleElement.h \
 	SVGComponentTransferFunctionElement.h \
 	SVGDefsElement.h \
 	SVGDescElement.h \
 	SVGEllipseElement.h \
+	SVGFEBlendElement.h \
+	SVGFEFloodElement.h \
+	SVGFEImageElement.h \
+	SVGFEMergeElement.h \
+	SVGFEMergeNodeElement.h \
 	SVGFilterElement.h \
 	SVGForeignObjectElement.h \
 	SVGGElement.h \
 	SVGGradientElement.h \
 	SVGGraphicsElement.h \
 	SVGImageElement.h \
 	SVGLineElement.h \
 	SVGMarkerElement.h \
copy from content/svg/content/src/nsSVGFilters.cpp
copy to content/svg/content/src/SVGFEBlendElement.cpp
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/SVGFEBlendElement.cpp
@@ -1,947 +1,89 @@
 /* -*- 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 "nsSVGElement.h"
-#include "nsGkAtoms.h"
-#include "nsSVGNumber2.h"
-#include "nsSVGNumberPair.h"
-#include "nsSVGInteger.h"
-#include "nsSVGIntegerPair.h"
-#include "nsSVGBoolean.h"
-#include "nsIDOMSVGFilters.h"
-#include "nsCOMPtr.h"
-#include "nsSVGFilterInstance.h"
-#include "nsSVGEnum.h"
-#include "SVGNumberList.h"
-#include "SVGAnimatedNumberList.h"
-#include "DOMSVGAnimatedNumberList.h"
-#include "nsSVGFilters.h"
-#include "nsLayoutUtils.h"
+#include "mozilla/dom/SVGFEBlendElement.h"
+#include "mozilla/dom/SVGFEBlendElementBinding.h"
 #include "nsSVGUtils.h"
-#include "nsStyleContext.h"
-#include "nsIDocument.h"
-#include "nsIFrame.h"
-#include "gfxContext.h"
-#include "gfxMatrix.h"
-#include "imgIContainer.h"
-#include "nsNetUtil.h"
-#include "nsIInterfaceRequestorUtils.h"
-#include "mozilla/dom/SVGFilterElement.h"
-#include "nsSVGString.h"
-#include "nsSVGEffects.h"
-#include "gfxUtils.h"
-#include "SVGContentUtils.h"
-#include <algorithm>
-#include "nsContentUtils.h"
-#include "mozilla/dom/SVGComponentTransferFunctionElement.h"
-#include "mozilla/dom/SVGFEFuncAElementBinding.h"
-#include "mozilla/dom/SVGFEFuncBElementBinding.h"
-#include "mozilla/dom/SVGFEFuncGElementBinding.h"
-#include "mozilla/dom/SVGFEFuncRElementBinding.h"
-
-#if defined(XP_WIN) 
-// Prevent Windows redefining LoadImage
-#undef LoadImage
-#endif
-
-#define NUM_ENTRIES_IN_4x5_MATRIX 20
-
-using namespace mozilla;
-using namespace mozilla::dom;
-
-static void
-CopyDataRect(uint8_t *aDest, const uint8_t *aSrc, uint32_t aStride,
-             const nsIntRect& aDataRect)
-{
-  for (int32_t y = aDataRect.y; y < aDataRect.YMost(); y++) {
-    memcpy(aDest + y * aStride + 4 * aDataRect.x,
-           aSrc + y * aStride + 4 * aDataRect.x,
-           4 * aDataRect.width);
-  }
-}
-
-static void
-CopyRect(const nsSVGFE::Image* aDest, const nsSVGFE::Image* aSrc, const nsIntRect& aDataRect)
-{
-  NS_ASSERTION(aDest->mImage->Stride() == aSrc->mImage->Stride(), "stride mismatch");
-  NS_ASSERTION(aDest->mImage->GetSize() == aSrc->mImage->GetSize(), "size mismatch");
-  NS_ASSERTION(nsIntRect(0, 0, aDest->mImage->Width(), aDest->mImage->Height()).Contains(aDataRect),
-               "aDataRect out of bounds");
-
-  CopyDataRect(aDest->mImage->Data(), aSrc->mImage->Data(),
-               aSrc->mImage->Stride(), aDataRect);
-}
-
-static void
-CopyAndScaleDeviceOffset(const gfxImageSurface *aImage, gfxImageSurface *aResult,
-                         gfxFloat kernelX, gfxFloat kernelY)
-{
-  gfxPoint deviceOffset = aImage->GetDeviceOffset();
-  deviceOffset.x /= kernelX;
-  deviceOffset.y /= kernelY;
-  aResult->SetDeviceOffset(deviceOffset);
-}
-
-//--------------------Filter Element Base Class-----------------------
-
-nsSVGElement::LengthInfo nsSVGFE::sLengthInfo[4] =
-{
-  { &nsGkAtoms::x, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X },
-  { &nsGkAtoms::y, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::Y },
-  { &nsGkAtoms::width, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X },
-  { &nsGkAtoms::height, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::Y }
-};
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFE,nsSVGFEBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFE,nsSVGFEBase)
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsSVGFE, NS_SVG_FE_CID)
 
-NS_INTERFACE_MAP_BEGIN(nsSVGFE)
-   // nsISupports is an ambiguous base of nsSVGFE so we have to work
-   // around that
-   if ( aIID.Equals(NS_GET_IID(nsSVGFE)) )
-     foundInterface = static_cast<nsISupports*>(static_cast<void*>(this));
-   else
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFEBase)
-
-//----------------------------------------------------------------------
-// Implementation
-
-nsSVGFE::ScaleInfo
-nsSVGFE::SetupScalingFilter(nsSVGFilterInstance *aInstance,
-                            const Image *aSource, const Image *aTarget,
-                            const nsIntRect& aDataRect,
-                            nsSVGNumberPair *aKernelUnitLength)
-{
-  ScaleInfo result;
-  result.mRescaling = aKernelUnitLength->IsExplicitlySet();
-  if (!result.mRescaling) {
-    result.mSource = aSource->mImage;
-    result.mTarget = aTarget->mImage;
-    result.mDataRect = aDataRect;
-    return result;
-  }
-
-  gfxFloat kernelX = aInstance->GetPrimitiveNumber(SVGContentUtils::X,
-                                                   aKernelUnitLength,
-                                                   nsSVGNumberPair::eFirst);
-  gfxFloat kernelY = aInstance->GetPrimitiveNumber(SVGContentUtils::Y,
-                                                   aKernelUnitLength,
-                                                   nsSVGNumberPair::eSecond);
-  if (kernelX <= 0 || kernelY <= 0)
-    return result;
-
-  bool overflow = false;
-  gfxIntSize scaledSize =
-    nsSVGUtils::ConvertToSurfaceSize(gfxSize(aTarget->mImage->Width() / kernelX,
-                                             aTarget->mImage->Height() / kernelY),
-                                     &overflow);
-  // If the requested size based on the kernel unit is too big, we
-  // need to bail because the effect is pixel size dependent.  Also
-  // need to check if we ended up with a negative size (arithmetic
-  // overflow) or zero size (large kernel unit)
-  if (overflow || scaledSize.width <= 0 || scaledSize.height <= 0)
-    return result;
-
-  gfxRect r(aDataRect.x, aDataRect.y, aDataRect.width, aDataRect.height);
-  r.Scale(1 / kernelX, 1 / kernelY);
-  r.RoundOut();
-  if (!gfxUtils::GfxRectToIntRect(r, &result.mDataRect))
-    return result;
-
-  // Rounding in the code above can mean that result.mDataRect is not contained
-  // within the bounds of the surfaces that we're about to create. We must
-  // clamp to these bounds to prevent out-of-bounds reads and writes:
-  result.mDataRect.IntersectRect(result.mDataRect,
-                                 nsIntRect(nsIntPoint(), scaledSize));
-
-  result.mSource = new gfxImageSurface(scaledSize,
-                                       gfxASurface::ImageFormatARGB32);
-  result.mTarget = new gfxImageSurface(scaledSize,
-                                       gfxASurface::ImageFormatARGB32);
-  if (!result.mSource || result.mSource->CairoStatus() ||
-      !result.mTarget || result.mTarget->CairoStatus()) {
-    result.mSource = nullptr;
-    result.mTarget = nullptr;
-    return result;
-  }
-
-  CopyAndScaleDeviceOffset(aSource->mImage, result.mSource, kernelX, kernelY);
-  CopyAndScaleDeviceOffset(aTarget->mImage, result.mTarget, kernelX, kernelY);
-
-  result.mRealTarget = aTarget->mImage;
-
-  gfxContext ctx(result.mSource);
-  ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
-  ctx.Scale(double(scaledSize.width) / aTarget->mImage->Width(),
-            double(scaledSize.height) / aTarget->mImage->Height());
-  ctx.SetSource(aSource->mImage);
-  ctx.Paint();
-
-  // mTarget was already cleared when it was created
-
-  return result;
-}
-
-void
-nsSVGFE::FinishScalingFilter(ScaleInfo *aScaleInfo)
-{
-  if (!aScaleInfo->mRescaling)
-    return;
-
-  gfxIntSize scaledSize = aScaleInfo->mTarget->GetSize();
-
-  gfxContext ctx(aScaleInfo->mRealTarget);
-  ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
-  ctx.Scale(double(aScaleInfo->mRealTarget->Width()) / scaledSize.width,
-            double(aScaleInfo->mRealTarget->Height()) / scaledSize.height);
-  ctx.SetSource(aScaleInfo->mTarget);
-  ctx.Paint();
-}
-
-nsIntRect
-nsSVGFE::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-                           const nsSVGFilterInstance& aInstance)
-{
-  nsIntRect r;
-  for (uint32_t i = 0; i < aSourceBBoxes.Length(); ++i) {
-    r.UnionRect(r, aSourceBBoxes[i]);
-  }
-  return r;
-}
+NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEBlend)
 
-void
-nsSVGFE::ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-                                   nsTArray<nsIntRect>& aSourceBBoxes,
-                                   const nsSVGFilterInstance& aInstance)
-{
-  for (uint32_t i = 0; i < aSourceBBoxes.Length(); ++i) {
-    aSourceBBoxes[i] = aTargetBBox;
-  }
-}
-
-nsIntRect
-nsSVGFE::ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-                           const nsSVGFilterInstance& aInstance)
-{
-  nsIntRect r;
-  for (uint32_t i = 0; i < aSourceChangeBoxes.Length(); ++i) {
-    r.UnionRect(r, aSourceChangeBoxes[i]);
-  }
-  return r;
-}
-
-void
-nsSVGFE::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
-{
-}
-
-bool
-nsSVGFE::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                   nsIAtom* aAttribute) const
-{
-  return aNameSpaceID == kNameSpaceID_None &&
-         (aAttribute == nsGkAtoms::x ||
-          aAttribute == nsGkAtoms::y ||
-          aAttribute == nsGkAtoms::width ||
-          aAttribute == nsGkAtoms::height ||
-          aAttribute == nsGkAtoms::result);
-}
-
-//----------------------------------------------------------------------
-// nsIDOMSVGFilterPrimitiveStandardAttributes methods
-
-/* readonly attribute nsIDOMSVGAnimatedLength x; */
-NS_IMETHODIMP nsSVGFE::GetX(nsIDOMSVGAnimatedLength * *aX)
-{
-  return mLengthAttributes[X].ToDOMAnimatedLength(aX, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedLength y; */
-NS_IMETHODIMP nsSVGFE::GetY(nsIDOMSVGAnimatedLength * *aY)
-{
-  return mLengthAttributes[Y].ToDOMAnimatedLength(aY, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedLength width; */
-NS_IMETHODIMP nsSVGFE::GetWidth(nsIDOMSVGAnimatedLength * *aWidth)
-{
-  return mLengthAttributes[WIDTH].ToDOMAnimatedLength(aWidth, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedLength height; */
-NS_IMETHODIMP nsSVGFE::GetHeight(nsIDOMSVGAnimatedLength * *aHeight)
-{
-  return mLengthAttributes[HEIGHT].ToDOMAnimatedLength(aHeight, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedString result; */
-NS_IMETHODIMP nsSVGFE::GetResult(nsIDOMSVGAnimatedString * *aResult)
-{
-  return GetResultImageName().ToDOMAnimatedString(aResult, this);
-}
-
-//----------------------------------------------------------------------
-// nsIContent methods
-
-NS_IMETHODIMP_(bool)
-nsSVGFE::IsAttributeMapped(const nsIAtom* name) const
-{
-  static const MappedAttributeEntry* const map[] = {
-    sFiltersMap
-  };
-  
-  return FindAttributeDependence(name, map) ||
-    nsSVGFEBase::IsAttributeMapped(name);
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-/* virtual */ bool
-nsSVGFE::HasValidDimensions() const
-{
-  return (!mLengthAttributes[WIDTH].IsExplicitlySet() ||
-           mLengthAttributes[WIDTH].GetAnimValInSpecifiedUnits() > 0) &&
-         (!mLengthAttributes[HEIGHT].IsExplicitlySet() || 
-           mLengthAttributes[HEIGHT].GetAnimValInSpecifiedUnits() > 0);
-}
-
-nsSVGElement::LengthAttributesInfo
-nsSVGFE::GetLengthInfo()
-{
-  return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
-                              ArrayLength(sLengthInfo));
-}
-
-//---------------------Gaussian Blur------------------------
-
-typedef nsSVGFE nsSVGFEGaussianBlurElementBase;
+namespace mozilla {
+namespace dom {
 
-class nsSVGFEGaussianBlurElement : public nsSVGFEGaussianBlurElementBase,
-                                   public nsIDOMSVGFEGaussianBlurElement
+JSObject*
+SVGFEBlendElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
 {
-  friend nsresult NS_NewSVGFEGaussianBlurElement(nsIContent **aResult,
-                                                 already_AddRefed<nsINodeInfo> aNodeInfo);
-protected:
-  nsSVGFEGaussianBlurElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFEGaussianBlurElementBase(aNodeInfo) {}
-
-public:
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // FE Base
-  NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFEGaussianBlurElementBase::)
-
-  virtual nsresult Filter(nsSVGFilterInstance* aInstance,
-                          const nsTArray<const Image*>& aSources,
-                          const Image* aTarget,
-                          const nsIntRect& aDataRect);
-  virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo >& aSources);
-  virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
-  virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance);
-  virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-          const nsSVGFilterInstance& aInstance);
-
-  // Gaussian
-  NS_DECL_NSIDOMSVGFEGAUSSIANBLURELEMENT
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEGaussianBlurElementBase::)
-
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-  virtual NumberPairAttributesInfo GetNumberPairInfo();
-  virtual StringAttributesInfo GetStringInfo();
-
-  enum { STD_DEV };
-  nsSVGNumberPair mNumberPairAttributes[1];
-  static NumberPairInfo sNumberPairInfo[1];
-
-  enum { RESULT, IN1 };
-  nsSVGString mStringAttributes[2];
-  static StringInfo sStringInfo[2];
-
-private:
-  nsresult GetDXY(uint32_t *aDX, uint32_t *aDY, const nsSVGFilterInstance& aInstance);
-  nsIntRect InflateRectForBlur(const nsIntRect& aRect, const nsSVGFilterInstance& aInstance);
-
-  void GaussianBlur(const Image *aSource, const Image *aTarget,
-                    const nsIntRect& aDataRect,
-                    uint32_t aDX, uint32_t aDY);
-};
-
-nsSVGElement::NumberPairInfo nsSVGFEGaussianBlurElement::sNumberPairInfo[1] =
-{
-  { &nsGkAtoms::stdDeviation, 0, 0 }
-};
-
-nsSVGElement::StringInfo nsSVGFEGaussianBlurElement::sStringInfo[2] =
-{
-  { &nsGkAtoms::result, kNameSpaceID_None, true },
-  { &nsGkAtoms::in, kNameSpaceID_None, true }
-};
-
-NS_IMPL_NS_NEW_SVG_ELEMENT(FEGaussianBlur)
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFEGaussianBlurElement,nsSVGFEGaussianBlurElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFEGaussianBlurElement,nsSVGFEGaussianBlurElementBase)
-
-DOMCI_NODE_DATA(SVGFEGaussianBlurElement, nsSVGFEGaussianBlurElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGFEGaussianBlurElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGFEGaussianBlurElement, nsIDOMNode,
-                           nsIDOMElement, nsIDOMSVGElement,
-                           nsIDOMSVGFilterPrimitiveStandardAttributes,
-                           nsIDOMSVGFEGaussianBlurElement)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEGaussianBlurElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFEGaussianBlurElementBase)
-
-//----------------------------------------------------------------------
-// nsIDOMNode methods
-
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFEGaussianBlurElement)
-
-
-//----------------------------------------------------------------------
-// nsIDOMSVGFEGaussianBlurElement methods
-
-/* readonly attribute nsIDOMSVGAnimatedString in1; */
-NS_IMETHODIMP nsSVGFEGaussianBlurElement::GetIn1(nsIDOMSVGAnimatedString * *aIn)
-{
-  return mStringAttributes[IN1].ToDOMAnimatedString(aIn, this);
+  return SVGFEBlendElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
 }
 
-/* readonly attribute nsIDOMSVGAnimatedNumber stdDeviationX; */
-NS_IMETHODIMP nsSVGFEGaussianBlurElement::GetStdDeviationX(nsIDOMSVGAnimatedNumber * *aX)
-{
-  return mNumberPairAttributes[STD_DEV].ToDOMAnimatedNumber(aX, nsSVGNumberPair::eFirst, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber stdDeviationY; */
-NS_IMETHODIMP nsSVGFEGaussianBlurElement::GetStdDeviationY(nsIDOMSVGAnimatedNumber * *aY)
-{
-  return mNumberPairAttributes[STD_DEV].ToDOMAnimatedNumber(aY, nsSVGNumberPair::eSecond, this);
-}
-
-NS_IMETHODIMP
-nsSVGFEGaussianBlurElement::SetStdDeviation(float stdDeviationX, float stdDeviationY)
-{
-  NS_ENSURE_FINITE2(stdDeviationX, stdDeviationY, NS_ERROR_ILLEGAL_VALUE);
-  mNumberPairAttributes[STD_DEV].SetBaseValues(stdDeviationX, stdDeviationY, this);
-  return NS_OK;
-}
-
-/**
- * We want to speed up 1/N integer divisions --- integer division is
- * often rather slow.
- * We know that our input numerators V are constrained to be <= 255*N,
- * so the result of dividing by N always fits in 8 bits.
- * So we can try approximating the division V/N as V*K/(2^24) (integer
- * division, 32-bit multiply). Dividing by 2^24 is a simple shift so it's
- * fast. The main problem is choosing a value for K; this function returns
- * K's value.
- * 
- * If the result is correct for the extrema, V=0 and V=255*N, then we'll
- * be in good shape since both the original function and our approximation
- * are linear. V=0 always gives 0 in both cases, no problem there.
- * For V=255*N, let's choose the largest K that doesn't cause overflow
- * and ensure that it gives the right answer. The constraints are
- *     (1)   255*N*K < 2^32
- * and (2)   255*N*K >= 255*(2^24)
- * 
- * From (1) we find the best value of K is floor((2^32 - 1)/(255*N)).
- * (2) tells us when this will be valid:
- *    N*floor((2^32 - 1)/(255*N)) >= 2^24
- * Now, floor(X) > X - 1, so (2) holds if
- *    N*((2^32 - 1)/(255*N) - 1) >= 2^24
- *         (2^32 - 1)/255 - 2^24 >= N
- *                             N <= 65793
- * 
- * If all that math confuses you, this should convince you:
- * > perl -e 'for($N=1;(255*$N*int(0xFFFFFFFF/(255*$N)))>>24==255;++$N){}print"$N\n"'
- * 66052
- * 
- * So this is fine for all reasonable values of N. For larger values of N
- * we may as well just use the same approximation and accept the fact that
- * the output channel values will be a little low.
- */
-static uint32_t ComputeScaledDivisor(uint32_t aDivisor)
-{
-  return UINT32_MAX/(255*aDivisor);
-}
-  
-static void
-BoxBlur(const uint8_t *aInput, uint8_t *aOutput,
-        int32_t aStrideMinor, int32_t aStartMinor, int32_t aEndMinor,
-        int32_t aLeftLobe, int32_t aRightLobe, bool aAlphaOnly)
-{
-  int32_t boxSize = aLeftLobe + aRightLobe + 1;
-  int32_t scaledDivisor = ComputeScaledDivisor(boxSize);
-  int32_t sums[4] = {0, 0, 0, 0};
-
-  for (int32_t i=0; i < boxSize; i++) {
-    int32_t pos = aStartMinor - aLeftLobe + i;
-    pos = std::max(pos, aStartMinor);
-    pos = std::min(pos, aEndMinor - 1);
-#define SUM(j)     sums[j] += aInput[aStrideMinor*pos + j];
-    SUM(0); SUM(1); SUM(2); SUM(3);
-#undef SUM
-  }
-
-  aOutput += aStrideMinor*aStartMinor;
-  if (aStartMinor + int32_t(boxSize) <= aEndMinor) {
-    const uint8_t *lastInput = aInput + aStartMinor*aStrideMinor;
-    const uint8_t *nextInput = aInput + (aStartMinor + aRightLobe + 1)*aStrideMinor;
-#define OUTPUT(j)     aOutput[j] = (sums[j]*scaledDivisor) >> 24;
-#define SUM(j)        sums[j] += nextInput[j] - lastInput[j];
-    // process pixels in B, G, R, A order because that's 0, 1, 2, 3 for x86
-#define OUTPUT_PIXEL() \
-        if (!aAlphaOnly) { OUTPUT(GFX_ARGB32_OFFSET_B); \
-                           OUTPUT(GFX_ARGB32_OFFSET_G); \
-                           OUTPUT(GFX_ARGB32_OFFSET_R); } \
-        OUTPUT(GFX_ARGB32_OFFSET_A);
-#define SUM_PIXEL() \
-        if (!aAlphaOnly) { SUM(GFX_ARGB32_OFFSET_B); \
-                           SUM(GFX_ARGB32_OFFSET_G); \
-                           SUM(GFX_ARGB32_OFFSET_R); } \
-        SUM(GFX_ARGB32_OFFSET_A);
-    for (int32_t minor = aStartMinor;
-         minor < aStartMinor + aLeftLobe;
-         minor++) {
-      OUTPUT_PIXEL();
-      SUM_PIXEL();
-      nextInput += aStrideMinor;
-      aOutput += aStrideMinor;
-    }
-    for (int32_t minor = aStartMinor + aLeftLobe;
-         minor < aEndMinor - aRightLobe - 1;
-         minor++) {
-      OUTPUT_PIXEL();
-      SUM_PIXEL();
-      lastInput += aStrideMinor;
-      nextInput += aStrideMinor;
-      aOutput += aStrideMinor;
-    }
-    // nextInput is now aInput + aEndMinor*aStrideMinor. Set it back to
-    // aInput + (aEndMinor - 1)*aStrideMinor so we read the last pixel in every
-    // iteration of the next loop.
-    nextInput -= aStrideMinor;
-    for (int32_t minor = aEndMinor - aRightLobe - 1; minor < aEndMinor; minor++) {
-      OUTPUT_PIXEL();
-      SUM_PIXEL();
-      lastInput += aStrideMinor;
-      aOutput += aStrideMinor;
-#undef SUM_PIXEL
-#undef SUM
-    }
-  } else {
-    for (int32_t minor = aStartMinor; minor < aEndMinor; minor++) {
-      int32_t tmp = minor - aLeftLobe;
-      int32_t last = std::max(tmp, aStartMinor);
-      int32_t next = std::min(tmp + int32_t(boxSize), aEndMinor - 1);
-
-      OUTPUT_PIXEL();
-#define SUM(j)     sums[j] += aInput[aStrideMinor*next + j] - \
-                              aInput[aStrideMinor*last + j];
-      if (!aAlphaOnly) { SUM(GFX_ARGB32_OFFSET_B);
-                         SUM(GFX_ARGB32_OFFSET_G);
-                         SUM(GFX_ARGB32_OFFSET_R); }
-      SUM(GFX_ARGB32_OFFSET_A);
-      aOutput += aStrideMinor;
-#undef SUM
-#undef OUTPUT_PIXEL
-#undef OUTPUT
-    }
-  }
-}
-
-static uint32_t
-GetBlurBoxSize(double aStdDev)
-{
-  NS_ASSERTION(aStdDev >= 0, "Negative standard deviations not allowed");
-
-  double size = aStdDev*3*sqrt(2*M_PI)/4;
-  // Doing super-large blurs accurately isn't very important.
-  uint32_t max = 1024;
-  if (size > max)
-    return max;
-  return uint32_t(floor(size + 0.5));
-}
-
-nsresult
-nsSVGFEGaussianBlurElement::GetDXY(uint32_t *aDX, uint32_t *aDY,
-                                   const nsSVGFilterInstance& aInstance)
-{
-  float stdX = aInstance.GetPrimitiveNumber(SVGContentUtils::X,
-                                            &mNumberPairAttributes[STD_DEV],
-                                            nsSVGNumberPair::eFirst);
-  float stdY = aInstance.GetPrimitiveNumber(SVGContentUtils::Y,
-                                            &mNumberPairAttributes[STD_DEV],
-                                            nsSVGNumberPair::eSecond);
-  if (stdX < 0 || stdY < 0)
-    return NS_ERROR_FAILURE;
-
-  // If the box size is greater than twice the temporary surface size
-  // in an axis, then each pixel will be set to the average of all the
-  // other pixel values.
-  *aDX = GetBlurBoxSize(stdX);
-  *aDY = GetBlurBoxSize(stdY);
-  return NS_OK;
-}
-
-static bool
-AreAllColorChannelsZero(const nsSVGFE::Image* aTarget)
-{
-  return aTarget->mConstantColorChannels &&
-         aTarget->mImage->GetDataSize() >= 4 &&
-         (*reinterpret_cast<uint32_t*>(aTarget->mImage->Data()) & 0x00FFFFFF) == 0;
-}
-
-void
-nsSVGFEGaussianBlurElement::GaussianBlur(const Image *aSource,
-                                         const Image *aTarget,                                         
-                                         const nsIntRect& aDataRect,
-                                         uint32_t aDX, uint32_t aDY)
-{
-  NS_ASSERTION(nsIntRect(0, 0, aTarget->mImage->Width(), aTarget->mImage->Height()).Contains(aDataRect),
-               "aDataRect out of bounds");
-
-  nsAutoArrayPtr<uint8_t> tmp(new uint8_t[aTarget->mImage->GetDataSize()]);
-  if (!tmp)
-    return;
-  memset(tmp, 0, aTarget->mImage->GetDataSize());
-
-  bool alphaOnly = AreAllColorChannelsZero(aTarget);
-  
-  const uint8_t* sourceData = aSource->mImage->Data();
-  uint8_t* targetData = aTarget->mImage->Data();
-  uint32_t stride = aTarget->mImage->Stride();
-
-  if (aDX == 0) {
-    CopyDataRect(tmp, sourceData, stride, aDataRect);
-  } else {
-    int32_t longLobe = aDX/2;
-    int32_t shortLobe = (aDX & 1) ? longLobe : longLobe - 1;
-    for (int32_t major = aDataRect.y; major < aDataRect.YMost(); ++major) {
-      int32_t ms = major*stride;
-      BoxBlur(sourceData + ms, tmp + ms, 4, aDataRect.x, aDataRect.XMost(), longLobe, shortLobe, alphaOnly);
-      BoxBlur(tmp + ms, targetData + ms, 4, aDataRect.x, aDataRect.XMost(), shortLobe, longLobe, alphaOnly);
-      BoxBlur(targetData + ms, tmp + ms, 4, aDataRect.x, aDataRect.XMost(), longLobe, longLobe, alphaOnly);
-    }
-  }
-
-  if (aDY == 0) {
-    CopyDataRect(targetData, tmp, stride, aDataRect);
-  } else {
-    int32_t longLobe = aDY/2;
-    int32_t shortLobe = (aDY & 1) ? longLobe : longLobe - 1;
-    for (int32_t major = aDataRect.x; major < aDataRect.XMost(); ++major) {
-      int32_t ms = major*4;
-      BoxBlur(tmp + ms, targetData + ms, stride, aDataRect.y, aDataRect.YMost(), longLobe, shortLobe, alphaOnly);
-      BoxBlur(targetData + ms, tmp + ms, stride, aDataRect.y, aDataRect.YMost(), shortLobe, longLobe, alphaOnly);
-      BoxBlur(tmp + ms, targetData + ms, stride, aDataRect.y, aDataRect.YMost(), longLobe, longLobe, alphaOnly);
-    }
-  }
-}
-
-static void
-InflateRectForBlurDXY(nsIntRect* aRect, uint32_t aDX, uint32_t aDY)
-{
-  aRect->Inflate(3*(aDX/2), 3*(aDY/2));
-}
-
-static void
-ClearRect(gfxImageSurface* aSurface, int32_t aX, int32_t aY,
-          int32_t aXMost, int32_t aYMost)
-{
-  NS_ASSERTION(aX <= aXMost && aY <= aYMost, "Invalid rectangle");
-  NS_ASSERTION(aX >= 0 && aY >= 0 && aXMost <= aSurface->Width() && aYMost <= aSurface->Height(),
-               "Rectangle out of bounds");
-
-  if (aX == aXMost || aY == aYMost)
-    return;
-  for (int32_t y = aY; y < aYMost; ++y) {
-    memset(aSurface->Data() + aSurface->Stride()*y + aX*4, 0, (aXMost - aX)*4);
-  }
-}
-
-// Clip aTarget's image to its filter primitive subregion.
-// aModifiedRect contains all the pixels which might not be RGBA(0,0,0,0),
-// it's relative to the surface data.
-static void
-ClipTarget(nsSVGFilterInstance* aInstance, const nsSVGFE::Image* aTarget,
-           const nsIntRect& aModifiedRect)
-{
-  nsIntPoint surfaceTopLeft = aInstance->GetSurfaceRect().TopLeft();
-
-  NS_ASSERTION(aInstance->GetSurfaceRect().Contains(aModifiedRect + surfaceTopLeft),
-               "Modified data area overflows the surface?");
-
-  nsIntRect clip = aModifiedRect;
-  nsSVGUtils::ClipToGfxRect(&clip,
-    aTarget->mFilterPrimitiveSubregion - gfxPoint(surfaceTopLeft.x, surfaceTopLeft.y));
-
-  ClearRect(aTarget->mImage, aModifiedRect.x, aModifiedRect.y, aModifiedRect.XMost(), clip.y);
-  ClearRect(aTarget->mImage, aModifiedRect.x, clip.y, clip.x, clip.YMost());
-  ClearRect(aTarget->mImage, clip.XMost(), clip.y, aModifiedRect.XMost(), clip.YMost());
-  ClearRect(aTarget->mImage, aModifiedRect.x, clip.YMost(), aModifiedRect.XMost(), aModifiedRect.YMost());
-}
-
-static void
-ClipComputationRectToSurface(nsSVGFilterInstance* aInstance,
-                             nsIntRect* aDataRect)
-{
-  aDataRect->IntersectRect(*aDataRect,
-          nsIntRect(nsIntPoint(0, 0), aInstance->GetSurfaceRect().Size()));
-}
-
-nsresult
-nsSVGFEGaussianBlurElement::Filter(nsSVGFilterInstance* aInstance,
-                                   const nsTArray<const Image*>& aSources,
-                                   const Image* aTarget,
-                                   const nsIntRect& rect)
-{
-  uint32_t dx, dy;
-  nsresult rv = GetDXY(&dx, &dy, *aInstance);
-  if (NS_FAILED(rv))
-    return rv;
-
-  nsIntRect computationRect = rect;
-  InflateRectForBlurDXY(&computationRect, dx, dy);
-  ClipComputationRectToSurface(aInstance, &computationRect);
-  GaussianBlur(aSources[0], aTarget, computationRect, dx, dy);
-  ClipTarget(aInstance, aTarget, computationRect);
-  return NS_OK;
-}
-
-bool
-nsSVGFEGaussianBlurElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                                      nsIAtom* aAttribute) const
-{
-  return nsSVGFEGaussianBlurElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
-         (aNameSpaceID == kNameSpaceID_None &&
-          (aAttribute == nsGkAtoms::in ||
-           aAttribute == nsGkAtoms::stdDeviation));
-}
-
-void
-nsSVGFEGaussianBlurElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
-{
-  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
-}
-
-nsIntRect
-nsSVGFEGaussianBlurElement::InflateRectForBlur(const nsIntRect& aRect,
-                                               const nsSVGFilterInstance& aInstance)
-{
-  uint32_t dX, dY;
-  nsresult rv = GetDXY(&dX, &dY, aInstance);
-  nsIntRect result = aRect;
-  if (NS_SUCCEEDED(rv)) {
-    InflateRectForBlurDXY(&result, dX, dY);
-  }
-  return result;
-}
-
-nsIntRect
-nsSVGFEGaussianBlurElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-        const nsSVGFilterInstance& aInstance)
-{
-  return InflateRectForBlur(aSourceBBoxes[0], aInstance);
-}
-
-void
-nsSVGFEGaussianBlurElement::ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance)
-{
-  aSourceBBoxes[0] = InflateRectForBlur(aTargetBBox, aInstance);
-}
-
-nsIntRect
-nsSVGFEGaussianBlurElement::ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-                                              const nsSVGFilterInstance& aInstance)
-{
-  return InflateRectForBlur(aSourceChangeBoxes[0], aInstance);
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::NumberPairAttributesInfo
-nsSVGFEGaussianBlurElement::GetNumberPairInfo()
-{
-  return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
-                                  ArrayLength(sNumberPairInfo));
-}
-
-nsSVGElement::StringAttributesInfo
-nsSVGFEGaussianBlurElement::GetStringInfo()
-{
-  return StringAttributesInfo(mStringAttributes, sStringInfo,
-                              ArrayLength(sStringInfo));
-}
-
-//---------------------Blend------------------------
-
-typedef nsSVGFE nsSVGFEBlendElementBase;
-
-class nsSVGFEBlendElement : public nsSVGFEBlendElementBase,
-                            public nsIDOMSVGFEBlendElement
-{
-  friend nsresult NS_NewSVGFEBlendElement(nsIContent **aResult,
-                                          already_AddRefed<nsINodeInfo> aNodeInfo);
-protected:
-  nsSVGFEBlendElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFEBlendElementBase(aNodeInfo) {}
-
-public:
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // FE Base
-  NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFEBlendElementBase::)
-
-  virtual nsresult Filter(nsSVGFilterInstance* aInstance,
-                          const nsTArray<const Image*>& aSources,
-                          const Image* aTarget,
-                          const nsIntRect& aDataRect);
-  virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
-
-  // Blend
-  NS_DECL_NSIDOMSVGFEBLENDELEMENT
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEBlendElementBase::)
-
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
-
-  enum { MODE };
-  nsSVGEnum mEnumAttributes[1];
-  static nsSVGEnumMapping sModeMap[];
-  static EnumInfo sEnumInfo[1];
-
-  enum { RESULT, IN1, IN2 };
-  nsSVGString mStringAttributes[3];
-  static StringInfo sStringInfo[3];
-};
-
-nsSVGEnumMapping nsSVGFEBlendElement::sModeMap[] = {
-  {&nsGkAtoms::normal, nsSVGFEBlendElement::SVG_MODE_NORMAL},
-  {&nsGkAtoms::multiply, nsSVGFEBlendElement::SVG_MODE_MULTIPLY},
-  {&nsGkAtoms::screen, nsSVGFEBlendElement::SVG_MODE_SCREEN},
-  {&nsGkAtoms::darken, nsSVGFEBlendElement::SVG_MODE_DARKEN},
-  {&nsGkAtoms::lighten, nsSVGFEBlendElement::SVG_MODE_LIGHTEN},
+nsSVGEnumMapping SVGFEBlendElement::sModeMap[] = {
+  {&nsGkAtoms::normal, SVG_FEBLEND_MODE_NORMAL},
+  {&nsGkAtoms::multiply, SVG_FEBLEND_MODE_MULTIPLY},
+  {&nsGkAtoms::screen, SVG_FEBLEND_MODE_SCREEN},
+  {&nsGkAtoms::darken, SVG_FEBLEND_MODE_DARKEN},
+  {&nsGkAtoms::lighten, SVG_FEBLEND_MODE_LIGHTEN},
   {nullptr, 0}
 };
 
-nsSVGElement::EnumInfo nsSVGFEBlendElement::sEnumInfo[1] =
+nsSVGElement::EnumInfo SVGFEBlendElement::sEnumInfo[1] =
 {
   { &nsGkAtoms::mode,
     sModeMap,
-    nsSVGFEBlendElement::SVG_MODE_NORMAL
+    SVG_FEBLEND_MODE_NORMAL
   }
 };
 
-nsSVGElement::StringInfo nsSVGFEBlendElement::sStringInfo[3] =
+nsSVGElement::StringInfo SVGFEBlendElement::sStringInfo[3] =
 {
   { &nsGkAtoms::result, kNameSpaceID_None, true },
   { &nsGkAtoms::in, kNameSpaceID_None, true },
   { &nsGkAtoms::in2, kNameSpaceID_None, true }
 };
 
-NS_IMPL_NS_NEW_SVG_ELEMENT(FEBlend)
-
 //----------------------------------------------------------------------
 // nsISupports methods
 
-NS_IMPL_ADDREF_INHERITED(nsSVGFEBlendElement,nsSVGFEBlendElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFEBlendElement,nsSVGFEBlendElementBase)
-
-DOMCI_NODE_DATA(SVGFEBlendElement, nsSVGFEBlendElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGFEBlendElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGFEBlendElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement,
-                           nsIDOMSVGFilterPrimitiveStandardAttributes,
-                           nsIDOMSVGFEBlendElement)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEBlendElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFEBlendElementBase)
-
+NS_IMPL_ISUPPORTS_INHERITED3(SVGFEBlendElement, SVGFEBlendElementBase,
+                             nsIDOMNode, nsIDOMElement,
+                             nsIDOMSVGElement)
 //----------------------------------------------------------------------
 // nsIDOMNode methods
 
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFEBlendElement)
+NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEBlendElement)
 
 //----------------------------------------------------------------------
 // nsIDOMSVGFEBlendElement methods
 
-/* readonly attribute nsIDOMSVGAnimatedString in1; */
-NS_IMETHODIMP nsSVGFEBlendElement::GetIn1(nsIDOMSVGAnimatedString * *aIn)
+already_AddRefed<nsIDOMSVGAnimatedString>
+SVGFEBlendElement::In1()
 {
-  return mStringAttributes[IN1].ToDOMAnimatedString(aIn, this);
+  return mStringAttributes[IN1].ToDOMAnimatedString(this);
 }
 
-/* readonly attribute nsIDOMSVGAnimatedString in2; */
-NS_IMETHODIMP nsSVGFEBlendElement::GetIn2(nsIDOMSVGAnimatedString * *aIn)
+already_AddRefed<nsIDOMSVGAnimatedString>
+SVGFEBlendElement::In2()
 {
-  return mStringAttributes[IN2].ToDOMAnimatedString(aIn, this);
+  return mStringAttributes[IN2].ToDOMAnimatedString(this);
 }
 
-/* readonly attribute nsIDOMSVGAnimatedEnumeration mode; */
-NS_IMETHODIMP nsSVGFEBlendElement::GetMode(nsIDOMSVGAnimatedEnumeration * *aMode)
+already_AddRefed<nsIDOMSVGAnimatedEnumeration>
+SVGFEBlendElement::Mode()
 {
-  return mEnumAttributes[MODE].ToDOMAnimatedEnum(aMode, this);
+  return mEnumAttributes[MODE].ToDOMAnimatedEnum(this);
 }
 
 nsresult
-nsSVGFEBlendElement::Filter(nsSVGFilterInstance* aInstance,
-                            const nsTArray<const Image*>& aSources,
-                            const Image* aTarget,
-                            const nsIntRect& rect)
+SVGFEBlendElement::Filter(nsSVGFilterInstance* aInstance,
+                          const nsTArray<const Image*>& aSources,
+                          const Image* aTarget,
+                          const nsIntRect& rect)
 {
   CopyRect(aTarget, aSources[0], rect);
 
   uint8_t* sourceData = aSources[1]->mImage->Data();
   uint8_t* targetData = aTarget->mImage->Data();
   uint32_t stride = aTarget->mImage->Stride();
 
   uint16_t mode = mEnumAttributes[MODE].GetAnimValue();
@@ -952,30 +94,30 @@ nsSVGFEBlendElement::Filter(nsSVGFilterI
       uint32_t qa = targetData[targIndex + GFX_ARGB32_OFFSET_A];
       uint32_t qb = sourceData[targIndex + GFX_ARGB32_OFFSET_A];
       for (int32_t i = std::min(GFX_ARGB32_OFFSET_B, GFX_ARGB32_OFFSET_R);
            i <= std::max(GFX_ARGB32_OFFSET_B, GFX_ARGB32_OFFSET_R); i++) {
         uint32_t ca = targetData[targIndex + i];
         uint32_t cb = sourceData[targIndex + i];
         uint32_t val;
         switch (mode) {
-          case nsSVGFEBlendElement::SVG_MODE_NORMAL:
+          case SVG_FEBLEND_MODE_NORMAL:
             val = (255 - qa) * cb + 255 * ca;
             break;
-          case nsSVGFEBlendElement::SVG_MODE_MULTIPLY:
+          case SVG_FEBLEND_MODE_MULTIPLY:
             val = ((255 - qa) * cb + (255 - qb + cb) * ca);
             break;
-          case nsSVGFEBlendElement::SVG_MODE_SCREEN:
+          case SVG_FEBLEND_MODE_SCREEN:
             val = 255 * (cb + ca) - ca * cb;
             break;
-          case nsSVGFEBlendElement::SVG_MODE_DARKEN:
+          case SVG_FEBLEND_MODE_DARKEN:
             val = std::min((255 - qa) * cb + 255 * ca,
                          (255 - qb) * ca + 255 * cb);
             break;
-          case nsSVGFEBlendElement::SVG_MODE_LIGHTEN:
+          case SVG_FEBLEND_MODE_LIGHTEN:
             val = std::max((255 - qa) * cb + 255 * ca,
                          (255 - qb) * ca + 255 * cb);
             break;
           default:
             return NS_ERROR_FAILURE;
             break;
         }
         val = std::min(val / 255, 255U);
@@ -984,5355 +126,44 @@ nsSVGFEBlendElement::Filter(nsSVGFilterI
       uint32_t alpha = 255 * 255 - (255 - qa) * (255 - qb);
       FAST_DIVIDE_BY_255(targetData[targIndex + GFX_ARGB32_OFFSET_A], alpha);
     }
   }
   return NS_OK;
 }
 
 bool
-nsSVGFEBlendElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                               nsIAtom* aAttribute) const
+SVGFEBlendElement::AttributeAffectsRendering(int32_t aNameSpaceID,
+                                             nsIAtom* aAttribute) const
 {
-  return nsSVGFEBlendElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
+  return SVGFEBlendElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
          (aNameSpaceID == kNameSpaceID_None &&
           (aAttribute == nsGkAtoms::in ||
            aAttribute == nsGkAtoms::in2 ||
            aAttribute == nsGkAtoms::mode));
 }
 
 void
-nsSVGFEBlendElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
+SVGFEBlendElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
 {
   aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
   aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN2], this));
 }
 
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
 nsSVGElement::EnumAttributesInfo
-nsSVGFEBlendElement::GetEnumInfo()
-{
-  return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
-                            ArrayLength(sEnumInfo));
-}
-
-nsSVGElement::StringAttributesInfo
-nsSVGFEBlendElement::GetStringInfo()
-{
-  return StringAttributesInfo(mStringAttributes, sStringInfo,
-                              ArrayLength(sStringInfo));
-}
-
-//---------------------Color Matrix------------------------
-
-typedef nsSVGFE nsSVGFEColorMatrixElementBase;
-
-class nsSVGFEColorMatrixElement : public nsSVGFEColorMatrixElementBase,
-                                  public nsIDOMSVGFEColorMatrixElement
-{
-  friend nsresult NS_NewSVGFEColorMatrixElement(nsIContent **aResult,
-                                                already_AddRefed<nsINodeInfo> aNodeInfo);
-protected:
-  nsSVGFEColorMatrixElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFEColorMatrixElementBase(aNodeInfo) {}
-
-public:
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // FE Base
-  NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFEColorMatrixElementBase::)
-
-  virtual nsresult Filter(nsSVGFilterInstance* aInstance,
-                          const nsTArray<const Image*>& aSources,
-                          const Image* aTarget,
-                          const nsIntRect& aDataRect);
-  virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
-
-  // Color Matrix
-  NS_DECL_NSIDOMSVGFECOLORMATRIXELEMENT
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEColorMatrixElementBase::)
-
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-  virtual bool OperatesOnPremultipledAlpha(int32_t) { return false; }
-
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
-  virtual NumberListAttributesInfo GetNumberListInfo();
-
-  enum { TYPE };
-  nsSVGEnum mEnumAttributes[1];
-  static nsSVGEnumMapping sTypeMap[];
-  static EnumInfo sEnumInfo[1];
-
-  enum { RESULT, IN1 };
-  nsSVGString mStringAttributes[2];
-  static StringInfo sStringInfo[2];
-
-  enum { VALUES };
-  SVGAnimatedNumberList mNumberListAttributes[1];
-  static NumberListInfo sNumberListInfo[1];
-};
-
-nsSVGEnumMapping nsSVGFEColorMatrixElement::sTypeMap[] = {
-  {&nsGkAtoms::matrix, nsSVGFEColorMatrixElement::SVG_FECOLORMATRIX_TYPE_MATRIX},
-  {&nsGkAtoms::saturate, nsSVGFEColorMatrixElement::SVG_FECOLORMATRIX_TYPE_SATURATE},
-  {&nsGkAtoms::hueRotate, nsSVGFEColorMatrixElement::SVG_FECOLORMATRIX_TYPE_HUE_ROTATE},
-  {&nsGkAtoms::luminanceToAlpha, nsSVGFEColorMatrixElement::SVG_FECOLORMATRIX_TYPE_LUMINANCE_TO_ALPHA},
-  {nullptr, 0}
-};
-
-nsSVGElement::EnumInfo nsSVGFEColorMatrixElement::sEnumInfo[1] =
-{
-  { &nsGkAtoms::type,
-    sTypeMap,
-    nsSVGFEColorMatrixElement::SVG_FECOLORMATRIX_TYPE_MATRIX
-  }
-};
-
-nsSVGElement::StringInfo nsSVGFEColorMatrixElement::sStringInfo[2] =
-{
-  { &nsGkAtoms::result, kNameSpaceID_None, true },
-  { &nsGkAtoms::in, kNameSpaceID_None, true }
-};
-
-nsSVGElement::NumberListInfo nsSVGFEColorMatrixElement::sNumberListInfo[1] =
-{
-  { &nsGkAtoms::values }
-};
-
-NS_IMPL_NS_NEW_SVG_ELEMENT(FEColorMatrix)
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFEColorMatrixElement,nsSVGFEColorMatrixElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFEColorMatrixElement,nsSVGFEColorMatrixElementBase)
-
-DOMCI_NODE_DATA(SVGFEColorMatrixElement, nsSVGFEColorMatrixElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGFEColorMatrixElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGFEColorMatrixElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement,
-                           nsIDOMSVGFilterPrimitiveStandardAttributes,
-                           nsIDOMSVGFEColorMatrixElement)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEColorMatrixElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFEColorMatrixElementBase)
-
-
-//----------------------------------------------------------------------
-// nsIDOMNode methods
-
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFEColorMatrixElement)
-
-
-//----------------------------------------------------------------------
-// nsSVGFEColorMatrixElement methods
-
-/* readonly attribute nsIDOMSVGAnimatedString in1; */
-NS_IMETHODIMP nsSVGFEColorMatrixElement::GetIn1(nsIDOMSVGAnimatedString * *aIn)
-{
-  return mStringAttributes[IN1].ToDOMAnimatedString(aIn, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedEnumeration type; */
-NS_IMETHODIMP nsSVGFEColorMatrixElement::GetType(nsIDOMSVGAnimatedEnumeration * *aType)
-{
-  return mEnumAttributes[TYPE].ToDOMAnimatedEnum(aType, this);
-}
-
-/* readonly attribute DOMSVGAnimatedNumberList values; */
-NS_IMETHODIMP nsSVGFEColorMatrixElement::GetValues(nsISupports * *aValues)
-{
-  *aValues = DOMSVGAnimatedNumberList::GetDOMWrapper(&mNumberListAttributes[VALUES],
-                                                     this, VALUES).get();
-  return NS_OK;
-}
-
-void
-nsSVGFEColorMatrixElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
-{
-  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
-}
-
-nsresult
-nsSVGFEColorMatrixElement::Filter(nsSVGFilterInstance *instance,
-                                  const nsTArray<const Image*>& aSources,
-                                  const Image* aTarget,
-                                  const nsIntRect& rect)
-{
-  uint8_t* sourceData = aSources[0]->mImage->Data();
-  uint8_t* targetData = aTarget->mImage->Data();
-  uint32_t stride = aTarget->mImage->Stride();
-
-  uint16_t type = mEnumAttributes[TYPE].GetAnimValue();
-  const SVGNumberList &values = mNumberListAttributes[VALUES].GetAnimValue();
-
-  if (!mNumberListAttributes[VALUES].IsExplicitlySet() &&
-      (type == nsSVGFEColorMatrixElement::SVG_FECOLORMATRIX_TYPE_MATRIX ||
-       type == nsSVGFEColorMatrixElement::SVG_FECOLORMATRIX_TYPE_SATURATE ||
-       type == nsSVGFEColorMatrixElement::SVG_FECOLORMATRIX_TYPE_HUE_ROTATE)) {
-    // identity matrix filter
-    CopyRect(aTarget, aSources[0], rect);
-    return NS_OK;
-  }
-
-  static const float identityMatrix[] = 
-    { 1, 0, 0, 0, 0,
-      0, 1, 0, 0, 0,
-      0, 0, 1, 0, 0,
-      0, 0, 0, 1, 0 };
-
-  static const float luminanceToAlphaMatrix[] = 
-    { 0,       0,       0,       0, 0,
-      0,       0,       0,       0, 0,
-      0,       0,       0,       0, 0,
-      0.2125f, 0.7154f, 0.0721f, 0, 0 };
-
-  float colorMatrix[NUM_ENTRIES_IN_4x5_MATRIX];
-  float s, c;
-
-  switch (type) {
-  case nsSVGFEColorMatrixElement::SVG_FECOLORMATRIX_TYPE_MATRIX:
-
-    if (values.Length() != NUM_ENTRIES_IN_4x5_MATRIX)
-      return NS_ERROR_FAILURE;
-
-    for(uint32_t j = 0; j < values.Length(); j++) {
-      colorMatrix[j] = values[j];
-    }
-    break;
-  case nsSVGFEColorMatrixElement::SVG_FECOLORMATRIX_TYPE_SATURATE:
-
-    if (values.Length() != 1)
-      return NS_ERROR_FAILURE;
-
-    s = values[0];
-
-    if (s > 1 || s < 0)
-      return NS_ERROR_FAILURE;
-
-    memcpy(colorMatrix, identityMatrix, sizeof(colorMatrix));
-
-    colorMatrix[0] = 0.213f + 0.787f * s;
-    colorMatrix[1] = 0.715f - 0.715f * s;
-    colorMatrix[2] = 0.072f - 0.072f * s;
-
-    colorMatrix[5] = 0.213f - 0.213f * s;
-    colorMatrix[6] = 0.715f + 0.285f * s;
-    colorMatrix[7] = 0.072f - 0.072f * s;
-
-    colorMatrix[10] = 0.213f - 0.213f * s;
-    colorMatrix[11] = 0.715f - 0.715f * s;
-    colorMatrix[12] = 0.072f + 0.928f * s;
-
-    break;
-
-  case nsSVGFEColorMatrixElement::SVG_FECOLORMATRIX_TYPE_HUE_ROTATE:
-  {
-    memcpy(colorMatrix, identityMatrix, sizeof(colorMatrix));
-
-    if (values.Length() != 1)
-      return NS_ERROR_FAILURE;
-
-    float hueRotateValue = values[0];
-
-    c = static_cast<float>(cos(hueRotateValue * M_PI / 180));
-    s = static_cast<float>(sin(hueRotateValue * M_PI / 180));
-
-    memcpy(colorMatrix, identityMatrix, sizeof(colorMatrix));
-
-    colorMatrix[0] = 0.213f + 0.787f * c - 0.213f * s;
-    colorMatrix[1] = 0.715f - 0.715f * c - 0.715f * s;
-    colorMatrix[2] = 0.072f - 0.072f * c + 0.928f * s;
-
-    colorMatrix[5] = 0.213f - 0.213f * c + 0.143f * s;
-    colorMatrix[6] = 0.715f + 0.285f * c + 0.140f * s;
-    colorMatrix[7] = 0.072f - 0.072f * c - 0.283f * s;
-
-    colorMatrix[10] = 0.213f - 0.213f * c - 0.787f * s;
-    colorMatrix[11] = 0.715f - 0.715f * c + 0.715f * s;
-    colorMatrix[12] = 0.072f + 0.928f * c + 0.072f * s;
-
-    break;
-  }
-
-  case nsSVGFEColorMatrixElement::SVG_FECOLORMATRIX_TYPE_LUMINANCE_TO_ALPHA:
-
-    memcpy(colorMatrix, luminanceToAlphaMatrix, sizeof(colorMatrix));
-    break;
-
-  default:
-    return NS_ERROR_FAILURE;
-  }
-
-  for (int32_t x = rect.x; x < rect.XMost(); x++) {
-    for (int32_t y = rect.y; y < rect.YMost(); y++) {
-      uint32_t targIndex = y * stride + 4 * x;
-
-      float col[4];
-      for (int i = 0, row = 0; i < 4; i++, row += 5) {
-        col[i] =
-          sourceData[targIndex + GFX_ARGB32_OFFSET_R] * colorMatrix[row + 0] +
-          sourceData[targIndex + GFX_ARGB32_OFFSET_G] * colorMatrix[row + 1] +
-          sourceData[targIndex + GFX_ARGB32_OFFSET_B] * colorMatrix[row + 2] +
-          sourceData[targIndex + GFX_ARGB32_OFFSET_A] * colorMatrix[row + 3] +
-          255 *                                         colorMatrix[row + 4];
-        col[i] = clamped(col[i], 0.f, 255.f);
-      }
-      targetData[targIndex + GFX_ARGB32_OFFSET_R] =
-        static_cast<uint8_t>(col[0]);
-      targetData[targIndex + GFX_ARGB32_OFFSET_G] =
-        static_cast<uint8_t>(col[1]);
-      targetData[targIndex + GFX_ARGB32_OFFSET_B] =
-        static_cast<uint8_t>(col[2]);
-      targetData[targIndex + GFX_ARGB32_OFFSET_A] =
-        static_cast<uint8_t>(col[3]);
-    }
-  }
-  return NS_OK;
-}
-
-bool
-nsSVGFEColorMatrixElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                                     nsIAtom* aAttribute) const
-{
-  return nsSVGFEColorMatrixElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
-         (aNameSpaceID == kNameSpaceID_None &&
-          (aAttribute == nsGkAtoms::in ||
-           aAttribute == nsGkAtoms::type ||
-           aAttribute == nsGkAtoms::values));
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::EnumAttributesInfo
-nsSVGFEColorMatrixElement::GetEnumInfo()
-{
-  return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
-                            ArrayLength(sEnumInfo));
-}
-
-nsSVGElement::StringAttributesInfo
-nsSVGFEColorMatrixElement::GetStringInfo()
-{
-  return StringAttributesInfo(mStringAttributes, sStringInfo,
-                              ArrayLength(sStringInfo));
-}
-
-nsSVGElement::NumberListAttributesInfo
-nsSVGFEColorMatrixElement::GetNumberListInfo()
-{
-  return NumberListAttributesInfo(mNumberListAttributes, sNumberListInfo,
-                                  ArrayLength(sNumberListInfo));
-}
-
-//---------------------Composite------------------------
-
-typedef nsSVGFE nsSVGFECompositeElementBase;
-
-class nsSVGFECompositeElement : public nsSVGFECompositeElementBase,
-                                public nsIDOMSVGFECompositeElement
-{
-  friend nsresult NS_NewSVGFECompositeElement(nsIContent **aResult,
-                                              already_AddRefed<nsINodeInfo> aNodeInfo);
-protected:
-  nsSVGFECompositeElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFECompositeElementBase(aNodeInfo) {}
-
-public:
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // FE Base
-  NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFECompositeElementBase::)
-
-  virtual nsresult Filter(nsSVGFilterInstance* aInstance,
-                          const nsTArray<const Image*>& aSources,
-                          const Image* aTarget,
-                          const nsIntRect& aDataRect);
-  virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
-  virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
-
-  // Composite
-  NS_DECL_NSIDOMSVGFECOMPOSITEELEMENT
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFECompositeElementBase::)
-
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-  virtual NumberAttributesInfo GetNumberInfo();
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
-
-  enum { K1, K2, K3, K4 };
-  nsSVGNumber2 mNumberAttributes[4];
-  static NumberInfo sNumberInfo[4];
-
-  enum { OPERATOR };
-  nsSVGEnum mEnumAttributes[1];
-  static nsSVGEnumMapping sOperatorMap[];
-  static EnumInfo sEnumInfo[1];
-
-  enum { RESULT, IN1, IN2 };
-  nsSVGString mStringAttributes[3];
-  static StringInfo sStringInfo[3];
-};
-
-nsSVGElement::NumberInfo nsSVGFECompositeElement::sNumberInfo[4] =
-{
-  { &nsGkAtoms::k1, 0, false },
-  { &nsGkAtoms::k2, 0, false },
-  { &nsGkAtoms::k3, 0, false },
-  { &nsGkAtoms::k4, 0, false }
-};
-
-nsSVGEnumMapping nsSVGFECompositeElement::sOperatorMap[] = {
-  {&nsGkAtoms::over, nsSVGFECompositeElement::SVG_OPERATOR_OVER},
-  {&nsGkAtoms::in, nsSVGFECompositeElement::SVG_OPERATOR_IN},
-  {&nsGkAtoms::out, nsSVGFECompositeElement::SVG_OPERATOR_OUT},
-  {&nsGkAtoms::atop, nsSVGFECompositeElement::SVG_OPERATOR_ATOP},
-  {&nsGkAtoms::xor_, nsSVGFECompositeElement::SVG_OPERATOR_XOR},
-  {&nsGkAtoms::arithmetic, nsSVGFECompositeElement::SVG_OPERATOR_ARITHMETIC},
-  {nullptr, 0}
-};
-
-nsSVGElement::EnumInfo nsSVGFECompositeElement::sEnumInfo[1] =
-{
-  { &nsGkAtoms::_operator,
-    sOperatorMap,
-    nsIDOMSVGFECompositeElement::SVG_OPERATOR_OVER
-  }
-};
-
-nsSVGElement::StringInfo nsSVGFECompositeElement::sStringInfo[3] =
-{
-  { &nsGkAtoms::result, kNameSpaceID_None, true },
-  { &nsGkAtoms::in, kNameSpaceID_None, true },
-  { &nsGkAtoms::in2, kNameSpaceID_None, true }
-};
-
-NS_IMPL_NS_NEW_SVG_ELEMENT(FEComposite)
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFECompositeElement,nsSVGFECompositeElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFECompositeElement,nsSVGFECompositeElementBase)
-
-DOMCI_NODE_DATA(SVGFECompositeElement, nsSVGFECompositeElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGFECompositeElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGFECompositeElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement,
-                           nsIDOMSVGFilterPrimitiveStandardAttributes,
-                           nsIDOMSVGFECompositeElement)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFECompositeElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFECompositeElementBase)
-
-//----------------------------------------------------------------------
-// nsIDOMNode methods
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFECompositeElement)
-
-//----------------------------------------------------------------------
-// nsSVGFECompositeElement methods
-
-/* readonly attribute nsIDOMSVGAnimatedString in1; */
-NS_IMETHODIMP nsSVGFECompositeElement::GetIn1(nsIDOMSVGAnimatedString * *aIn)
-{
-  return mStringAttributes[IN1].ToDOMAnimatedString(aIn, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedString in2; */
-NS_IMETHODIMP nsSVGFECompositeElement::GetIn2(nsIDOMSVGAnimatedString * *aIn)
-{
-  return mStringAttributes[IN2].ToDOMAnimatedString(aIn, this);
-}
-
-
-/* readonly attribute nsIDOMSVGAnimatedEnumeration operator; */
-NS_IMETHODIMP nsSVGFECompositeElement::GetOperator(nsIDOMSVGAnimatedEnumeration * *aOperator)
-{
-  return mEnumAttributes[OPERATOR].ToDOMAnimatedEnum(aOperator, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber K1; */
-NS_IMETHODIMP nsSVGFECompositeElement::GetK1(nsIDOMSVGAnimatedNumber * *aK1)
-{
-  return mNumberAttributes[K1].ToDOMAnimatedNumber(aK1, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber K2; */
-NS_IMETHODIMP nsSVGFECompositeElement::GetK2(nsIDOMSVGAnimatedNumber * *aK2)
-{
-  return mNumberAttributes[K2].ToDOMAnimatedNumber(aK2, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber K3; */
-NS_IMETHODIMP nsSVGFECompositeElement::GetK3(nsIDOMSVGAnimatedNumber * *aK3)
-{
-  return mNumberAttributes[K3].ToDOMAnimatedNumber(aK3, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber K4; */
-NS_IMETHODIMP nsSVGFECompositeElement::GetK4(nsIDOMSVGAnimatedNumber * *aK4)
-{
-  return mNumberAttributes[K4].ToDOMAnimatedNumber(aK4, this);
-}
-
-NS_IMETHODIMP
-nsSVGFECompositeElement::SetK(float k1, float k2, float k3, float k4)
-{
-  NS_ENSURE_FINITE4(k1, k2, k3, k4, NS_ERROR_ILLEGAL_VALUE);
-  mNumberAttributes[K1].SetBaseValue(k1, this);
-  mNumberAttributes[K2].SetBaseValue(k2, this);
-  mNumberAttributes[K3].SetBaseValue(k3, this);
-  mNumberAttributes[K4].SetBaseValue(k4, this);
-  return NS_OK;
-}
-
-nsresult
-nsSVGFECompositeElement::Filter(nsSVGFilterInstance *instance,
-                                const nsTArray<const Image*>& aSources,
-                                const Image* aTarget,
-                                const nsIntRect& rect)
-{
-  uint16_t op = mEnumAttributes[OPERATOR].GetAnimValue();
-
-  // Cairo does not support arithmetic operator
-  if (op == nsSVGFECompositeElement::SVG_OPERATOR_ARITHMETIC) {
-    float k1, k2, k3, k4;
-    GetAnimatedNumberValues(&k1, &k2, &k3, &k4, nullptr);
-
-    // Copy the first source image
-    CopyRect(aTarget, aSources[0], rect);
-
-    uint8_t* sourceData = aSources[1]->mImage->Data();
-    uint8_t* targetData = aTarget->mImage->Data();
-    uint32_t stride = aTarget->mImage->Stride();
-
-    // Blend in the second source image
-    float k1Scaled = k1 / 255.0f;
-    float k4Scaled = k4*255.0f;
-    for (int32_t x = rect.x; x < rect.XMost(); x++) {
-      for (int32_t y = rect.y; y < rect.YMost(); y++) {
-        uint32_t targIndex = y * stride + 4 * x;
-        for (int32_t i = 0; i < 4; i++) {
-          uint8_t i1 = targetData[targIndex + i];
-          uint8_t i2 = sourceData[targIndex + i];
-          float result = k1Scaled*i1*i2 + k2*i1 + k3*i2 + k4Scaled;
-          targetData[targIndex + i] =
-                       static_cast<uint8_t>(clamped(result, 0.f, 255.f));
-        }
-      }
-    }
-    return NS_OK;
-  }
-
-  // Cairo supports the operation we are trying to perform
-
-  gfxContext ctx(aTarget->mImage);
-  ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
-  ctx.SetSource(aSources[1]->mImage);
-  // Ensure rendering is limited to the filter primitive subregion
-  ctx.Clip(aTarget->mFilterPrimitiveSubregion);
-  ctx.Paint();
-
-  if (op < SVG_OPERATOR_OVER || op > SVG_OPERATOR_XOR) {
-    return NS_ERROR_FAILURE;
-  }
-  static const gfxContext::GraphicsOperator opMap[] = {
-                                           gfxContext::OPERATOR_DEST,
-                                           gfxContext::OPERATOR_OVER,
-                                           gfxContext::OPERATOR_IN,
-                                           gfxContext::OPERATOR_OUT,
-                                           gfxContext::OPERATOR_ATOP,
-                                           gfxContext::OPERATOR_XOR };
-  ctx.SetOperator(opMap[op]);
-  ctx.SetSource(aSources[0]->mImage);
-  ctx.Paint();
-  return NS_OK;
-}
-
-bool
-nsSVGFECompositeElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                                   nsIAtom* aAttribute) const
-{
-  return nsSVGFECompositeElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
-         (aNameSpaceID == kNameSpaceID_None &&
-          (aAttribute == nsGkAtoms::in ||
-           aAttribute == nsGkAtoms::in2 ||
-           aAttribute == nsGkAtoms::k1 ||
-           aAttribute == nsGkAtoms::k2 ||
-           aAttribute == nsGkAtoms::k3 ||
-           aAttribute == nsGkAtoms::k4 ||
-           aAttribute == nsGkAtoms::_operator));
-}
-
-void
-nsSVGFECompositeElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
-{
-  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
-  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN2], this));
-}
-
-nsIntRect
-nsSVGFECompositeElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-        const nsSVGFilterInstance& aInstance)
-{
-  uint16_t op = mEnumAttributes[OPERATOR].GetAnimValue();
-
-  if (op == nsSVGFECompositeElement::SVG_OPERATOR_ARITHMETIC) {
-    // "arithmetic" operator can produce non-zero alpha values even where
-    // all input alphas are zero, so we can actually render outside the
-    // union of the source bboxes.
-    // XXX we could also check that k4 is nonzero and check for other
-    // cases like k1/k2 or k1/k3 zero.
-    return GetMaxRect();
-  }
-
-  if (op == nsSVGFECompositeElement::SVG_OPERATOR_IN ||
-      op == nsSVGFECompositeElement::SVG_OPERATOR_ATOP) {
-    // We will only draw where in2 has nonzero alpha, so it's a good
-    // bounding box for us
-    return aSourceBBoxes[1];
-  }
-
-  // The regular Porter-Duff operators always compute zero alpha values
-  // where all sources have zero alpha, so the union of their bounding
-  // boxes is also a bounding box for our rendering
-  return nsSVGFECompositeElementBase::ComputeTargetBBox(aSourceBBoxes, aInstance);
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::NumberAttributesInfo
-nsSVGFECompositeElement::GetNumberInfo()
-{
-  return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
-                              ArrayLength(sNumberInfo));
-}
-
-nsSVGElement::EnumAttributesInfo
-nsSVGFECompositeElement::GetEnumInfo()
+SVGFEBlendElement::GetEnumInfo()
 {
   return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
                             ArrayLength(sEnumInfo));
 }
 
 nsSVGElement::StringAttributesInfo
-nsSVGFECompositeElement::GetStringInfo()
-{
-  return StringAttributesInfo(mStringAttributes, sStringInfo,
-                              ArrayLength(sStringInfo));
-}
-
-//---------------------Component Transfer------------------------
-
-typedef nsSVGFE nsSVGFEComponentTransferElementBase;
-
-class nsSVGFEComponentTransferElement : public nsSVGFEComponentTransferElementBase,
-                                        public nsIDOMSVGFEComponentTransferElement
-{
-  friend nsresult NS_NewSVGFEComponentTransferElement(nsIContent **aResult,
-                                                      already_AddRefed<nsINodeInfo> aNodeInfo);
-protected:
-  nsSVGFEComponentTransferElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFEComponentTransferElementBase(aNodeInfo) {}
-
-public:
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // FE Base
-  NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFEComponentTransferElementBase::)
-
-  virtual nsresult Filter(nsSVGFilterInstance* aInstance,
-                          const nsTArray<const Image*>& aSources,
-                          const Image* aTarget,
-                          const nsIntRect& aDataRect);
-  virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
-
-  // Component Transfer
-  NS_DECL_NSIDOMSVGFECOMPONENTTRANSFERELEMENT
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEComponentTransferElementBase::)
-
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIContent
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-  virtual bool OperatesOnPremultipledAlpha(int32_t) { return false; }
-
-  virtual StringAttributesInfo GetStringInfo();
-
-  enum { RESULT, IN1 };
-  nsSVGString mStringAttributes[2];
-  static StringInfo sStringInfo[2];
-};
-
-nsSVGElement::StringInfo nsSVGFEComponentTransferElement::sStringInfo[2] =
-{
-  { &nsGkAtoms::result, kNameSpaceID_None, true },
-  { &nsGkAtoms::in, kNameSpaceID_None, true }
-};
-
-NS_IMPL_NS_NEW_SVG_ELEMENT(FEComponentTransfer)
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFEComponentTransferElement,nsSVGFEComponentTransferElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFEComponentTransferElement,nsSVGFEComponentTransferElementBase)
-
-DOMCI_NODE_DATA(SVGFEComponentTransferElement, nsSVGFEComponentTransferElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGFEComponentTransferElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGFEComponentTransferElement, nsIDOMNode,
-                           nsIDOMElement, nsIDOMSVGElement,
-                           nsIDOMSVGFilterPrimitiveStandardAttributes,
-                           nsIDOMSVGFEComponentTransferElement)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEComponentTransferElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFEComponentTransferElementBase)
-
-//----------------------------------------------------------------------
-// nsIDOMNode methods
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFEComponentTransferElement)
-
-//----------------------------------------------------------------------
-// nsIDOMSVGFEComponentTransferElement methods
-
-/* readonly attribute nsIDOMSVGAnimatedString in1; */
-NS_IMETHODIMP
-nsSVGFEComponentTransferElement::GetIn1(nsIDOMSVGAnimatedString * *aIn)
-{
-  return mStringAttributes[IN1].ToDOMAnimatedString(aIn, this);
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::StringAttributesInfo
-nsSVGFEComponentTransferElement::GetStringInfo()
-{
-  return StringAttributesInfo(mStringAttributes, sStringInfo,
-                              ArrayLength(sStringInfo));
-}
-
-//--------------------------------------------
-
-nsresult
-nsSVGFEComponentTransferElement::Filter(nsSVGFilterInstance *instance,
-                                        const nsTArray<const Image*>& aSources,
-                                        const Image* aTarget,
-                                        const nsIntRect& rect)
-{
-  uint8_t* sourceData = aSources[0]->mImage->Data();
-  uint8_t* targetData = aTarget->mImage->Data();
-  uint32_t stride = aTarget->mImage->Stride();
-
-  uint8_t tableR[256], tableG[256], tableB[256], tableA[256];
-  for (int i=0; i<256; i++)
-    tableR[i] = tableG[i] = tableB[i] = tableA[i] = i;
-  uint8_t* tables[] = { tableR, tableG, tableB, tableA };
-  for (nsIContent* childContent = nsINode::GetFirstChild();
-       childContent;
-       childContent = childContent->GetNextSibling()) {
-
-    nsRefPtr<SVGComponentTransferFunctionElement> child;
-    CallQueryInterface(childContent,
-            (SVGComponentTransferFunctionElement**)getter_AddRefs(child));
-    if (child) {
-      if (!child->GenerateLookupTable(tables[child->GetChannel()])) {
-        return NS_ERROR_FAILURE;
-      }
-    }
-  }
-
-  for (int32_t y = rect.y; y < rect.YMost(); y++) {
-    for (int32_t x = rect.x; x < rect.XMost(); x++) {
-      int32_t targIndex = y * stride + x * 4;
-      targetData[targIndex + GFX_ARGB32_OFFSET_B] =
-        tableB[sourceData[targIndex + GFX_ARGB32_OFFSET_B]];
-      targetData[targIndex + GFX_ARGB32_OFFSET_G] =
-        tableG[sourceData[targIndex + GFX_ARGB32_OFFSET_G]];
-      targetData[targIndex + GFX_ARGB32_OFFSET_R] =
-        tableR[sourceData[targIndex + GFX_ARGB32_OFFSET_R]];
-      targetData[targIndex + GFX_ARGB32_OFFSET_A] =
-        tableA[sourceData[targIndex + GFX_ARGB32_OFFSET_A]];
-    }
-  }
-  return NS_OK;
-}
-
-bool
-nsSVGFEComponentTransferElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                                           nsIAtom* aAttribute) const
-{
-  return nsSVGFEComponentTransferElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
-         (aNameSpaceID == kNameSpaceID_None &&
-          aAttribute == nsGkAtoms::in);
-}
-
-void
-nsSVGFEComponentTransferElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
-{
-  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
-}
-
-namespace mozilla {
-namespace dom {
-
-nsSVGElement::NumberListInfo SVGComponentTransferFunctionElement::sNumberListInfo[1] =
-{
-  { &nsGkAtoms::tableValues }
-};
-
-nsSVGElement::NumberInfo SVGComponentTransferFunctionElement::sNumberInfo[5] =
-{
-  { &nsGkAtoms::slope,     1, false },
-  { &nsGkAtoms::intercept, 0, false },
-  { &nsGkAtoms::amplitude, 1, false },
-  { &nsGkAtoms::exponent,  1, false },
-  { &nsGkAtoms::offset,    0, false }
-};
-
-nsSVGEnumMapping SVGComponentTransferFunctionElement::sTypeMap[] = {
-  {&nsGkAtoms::identity,
-   nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY},
-  {&nsGkAtoms::table,
-   nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_TABLE},
-  {&nsGkAtoms::discrete,
-   nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE},
-  {&nsGkAtoms::linear,
-   nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_LINEAR},
-  {&nsGkAtoms::gamma,
-   nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_GAMMA},
-  {nullptr, 0}
-};
-
-nsSVGElement::EnumInfo SVGComponentTransferFunctionElement::sEnumInfo[1] =
-{
-  { &nsGkAtoms::type,
-    sTypeMap,
-    nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY
-  }
-};
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(SVGComponentTransferFunctionElement,SVGComponentTransferFunctionElementBase)
-NS_IMPL_RELEASE_INHERITED(SVGComponentTransferFunctionElement,SVGComponentTransferFunctionElementBase)
-
-NS_DEFINE_STATIC_IID_ACCESSOR(SVGComponentTransferFunctionElement, NS_SVG_FE_COMPONENT_TRANSFER_FUNCTION_ELEMENT_CID)
-
-NS_INTERFACE_MAP_BEGIN(SVGComponentTransferFunctionElement)
-   // nsISupports is an ambiguous base of nsSVGFE so we have to work
-   // around that
-   if ( aIID.Equals(NS_GET_IID(SVGComponentTransferFunctionElement)) )
-     foundInterface = static_cast<nsISupports*>(static_cast<void*>(this));
-   else
-NS_INTERFACE_MAP_END_INHERITING(SVGComponentTransferFunctionElementBase)
-
-
-//----------------------------------------------------------------------
-// nsFEUnstyledElement methods
-
-bool
-SVGComponentTransferFunctionElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                                                 nsIAtom* aAttribute) const
-{
-  return aNameSpaceID == kNameSpaceID_None &&
-         (aAttribute == nsGkAtoms::tableValues ||
-          aAttribute == nsGkAtoms::slope ||
-          aAttribute == nsGkAtoms::intercept ||
-          aAttribute == nsGkAtoms::amplitude ||
-          aAttribute == nsGkAtoms::exponent ||
-          aAttribute == nsGkAtoms::offset ||
-          aAttribute == nsGkAtoms::type);
-}
-
-//----------------------------------------------------------------------
-// nsIDOMSVGComponentTransferFunctionElement methods
-
-/* readonly attribute nsIDOMSVGAnimatedEnumeration type; */
-already_AddRefed<nsIDOMSVGAnimatedEnumeration>
-SVGComponentTransferFunctionElement::Type()
-{
-  return mEnumAttributes[TYPE].ToDOMAnimatedEnum(this);
-}
-NS_IMETHODIMP SVGComponentTransferFunctionElement::GetType(nsIDOMSVGAnimatedEnumeration * *aType)
-{
-  *aType = Type().get();
-  return NS_OK;
-}
-
-/* readonly attribute DOMSVGAnimatedNumberList tableValues; */
-already_AddRefed<DOMSVGAnimatedNumberList>
-SVGComponentTransferFunctionElement::TableValues()
-{
-  return DOMSVGAnimatedNumberList::GetDOMWrapper(
-    &mNumberListAttributes[TABLEVALUES], this, TABLEVALUES);
-}
-NS_IMETHODIMP SVGComponentTransferFunctionElement::GetTableValues(nsISupports * *aTableValues)
-{
-  *aTableValues = TableValues().get();
-  return NS_OK;
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber slope; */
-already_AddRefed<nsIDOMSVGAnimatedNumber>
-SVGComponentTransferFunctionElement::Slope()
-{
-  return mNumberAttributes[SLOPE].ToDOMAnimatedNumber(this);
-}
-NS_IMETHODIMP SVGComponentTransferFunctionElement::GetSlope(nsIDOMSVGAnimatedNumber * *aSlope)
-{
-  *aSlope = Slope().get();
-  return NS_OK;
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber intercept; */
-already_AddRefed<nsIDOMSVGAnimatedNumber>
-SVGComponentTransferFunctionElement::Intercept()
-{
-  return mNumberAttributes[INTERCEPT].ToDOMAnimatedNumber(this);
-}
-NS_IMETHODIMP SVGComponentTransferFunctionElement::GetIntercept(nsIDOMSVGAnimatedNumber * *aIntercept)
-{
-  *aIntercept = Intercept().get();
-  return NS_OK;
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber amplitude; */
-already_AddRefed<nsIDOMSVGAnimatedNumber>
-SVGComponentTransferFunctionElement::Amplitude()
-{
-  return mNumberAttributes[AMPLITUDE].ToDOMAnimatedNumber(this);
-}
-NS_IMETHODIMP SVGComponentTransferFunctionElement::GetAmplitude(nsIDOMSVGAnimatedNumber * *aAmplitude)
-{
-  *aAmplitude = Amplitude().get();
-  return NS_OK;
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber exponent; */
-already_AddRefed<nsIDOMSVGAnimatedNumber>
-SVGComponentTransferFunctionElement::Exponent()
-{
-  return mNumberAttributes[EXPONENT].ToDOMAnimatedNumber(this);
-}
-NS_IMETHODIMP SVGComponentTransferFunctionElement::GetExponent(nsIDOMSVGAnimatedNumber * *aExponent)
-{
-  *aExponent = Exponent().get();
-  return NS_OK;
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber offset; */
-already_AddRefed<nsIDOMSVGAnimatedNumber>
-SVGComponentTransferFunctionElement::Offset()
-{
-  return mNumberAttributes[OFFSET].ToDOMAnimatedNumber(this);
-}
-NS_IMETHODIMP SVGComponentTransferFunctionElement::GetOffset(nsIDOMSVGAnimatedNumber * *aOffset)
-{
-  *aOffset = Offset().get();
-  return NS_OK;
-}
-
-bool
-SVGComponentTransferFunctionElement::GenerateLookupTable(uint8_t *aTable)
-{
-  uint16_t type = mEnumAttributes[TYPE].GetAnimValue();
-
-  float slope, intercept, amplitude, exponent, offset;
-  GetAnimatedNumberValues(&slope, &intercept, &amplitude, 
-                          &exponent, &offset, nullptr);
-
-  const SVGNumberList &tableValues =
-    mNumberListAttributes[TABLEVALUES].GetAnimValue();
-  uint32_t tvLength = tableValues.Length();
-
-  uint32_t i;
-
-  switch (type) {
-  case nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_TABLE:
-  {
-    if (tableValues.Length() < 2)
-      return false;
-
-    for (i = 0; i < 256; i++) {
-      uint32_t k = (i * (tvLength - 1)) / 255;
-      float v1 = tableValues[k];
-      float v2 = tableValues[std::min(k + 1, tvLength - 1)];
-      int32_t val =
-        int32_t(255 * (v1 + (i/255.0f - k/float(tvLength-1))*(tvLength - 1)*(v2 - v1)));
-      val = std::min(255, val);
-      val = std::max(0, val);
-      aTable[i] = val;
-    }
-    break;
-  }
-
-  case nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE:
-  {
-    if (tableValues.Length() < 1)
-      return false;
-
-    for (i = 0; i < 256; i++) {
-      uint32_t k = (i * tvLength) / 255;
-      k = std::min(k, tvLength - 1);
-      float v = tableValues[k];
-      int32_t val = int32_t(255 * v);
-      val = std::min(255, val);
-      val = std::max(0, val);
-      aTable[i] = val;
-    }
-    break;
-  }
-
-  case nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_LINEAR:
-  {
-    for (i = 0; i < 256; i++) {
-      int32_t val = int32_t(slope * i + 255 * intercept);
-      val = std::min(255, val);
-      val = std::max(0, val);
-      aTable[i] = val;
-    }
-    break;
-  }
-
-  case nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_GAMMA:
-  {
-    for (i = 0; i < 256; i++) {
-      int32_t val = int32_t(255 * (amplitude * pow(i / 255.0f, exponent) + offset));
-      val = std::min(255, val);
-      val = std::max(0, val);
-      aTable[i] = val;
-    }
-    break;
-  }
-
-  case nsIDOMSVGComponentTransferFunctionElement::SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY:
-  default:
-    break;
-  }
-  return true;
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::NumberListAttributesInfo
-SVGComponentTransferFunctionElement::GetNumberListInfo()
-{
-  return NumberListAttributesInfo(mNumberListAttributes, sNumberListInfo,
-                                  ArrayLength(sNumberListInfo));
-}
-
-nsSVGElement::EnumAttributesInfo
-SVGComponentTransferFunctionElement::GetEnumInfo()
-{
-  return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
-                            ArrayLength(sEnumInfo));
-}
-
-nsSVGElement::NumberAttributesInfo
-SVGComponentTransferFunctionElement::GetNumberInfo()
-{
-  return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
-                              ArrayLength(sNumberInfo));
-}
-
-NS_IMPL_ISUPPORTS_INHERITED5(SVGFEFuncRElement,
-                             SVGComponentTransferFunctionElement,
-                             nsIDOMNode, nsIDOMElement,
-                             nsIDOMSVGElement,
-                             nsIDOMSVGComponentTransferFunctionElement,
-                             nsIDOMSVGFEFuncRElement)
-
-/* virtual */ JSObject*
-SVGFEFuncRElement::WrapNode(JSContext* aCx, JSObject* aScope,
-                            bool* aTriedToWrap)
-{
-  return SVGFEFuncRElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
-}
-
-} // namespace dom
-} // namespace mozilla
-
-NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEFuncR)
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEFuncRElement)
-
-NS_IMPL_ISUPPORTS_INHERITED5(SVGFEFuncGElement,
-                             SVGComponentTransferFunctionElement,
-                             nsIDOMNode, nsIDOMElement,
-                             nsIDOMSVGElement,
-                             nsIDOMSVGComponentTransferFunctionElement,
-                             nsIDOMSVGFEFuncGElement)
-
-/* virtual */ JSObject*
-SVGFEFuncGElement::WrapNode(JSContext* aCx, JSObject* aScope,
-                            bool* aTriedToWrap)
-{
-  return SVGFEFuncGElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
-}
-
-} // namespace dom
-} // namespace mozilla
-
-NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEFuncG)
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEFuncGElement)
-
-NS_IMPL_ISUPPORTS_INHERITED5(SVGFEFuncBElement,
-                             SVGComponentTransferFunctionElement,
-                             nsIDOMNode, nsIDOMElement,
-                             nsIDOMSVGElement,
-                             nsIDOMSVGComponentTransferFunctionElement,
-                             nsIDOMSVGFEFuncBElement)
-
-/* virtual */ JSObject*
-SVGFEFuncBElement::WrapNode(JSContext* aCx, JSObject* aScope,
-                            bool* aTriedToWrap)
-{
-  return SVGFEFuncBElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
-}
-
-} // namespace dom
-} // namespace mozilla
-
-NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEFuncB)
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEFuncBElement)
-
-NS_IMPL_ISUPPORTS_INHERITED5(SVGFEFuncAElement,
-                             SVGComponentTransferFunctionElement,
-                             nsIDOMNode, nsIDOMElement,
-                             nsIDOMSVGElement,
-                             nsIDOMSVGComponentTransferFunctionElement,
-                             nsIDOMSVGFEFuncAElement)
-
-/* virtual */ JSObject*
-SVGFEFuncAElement::WrapNode(JSContext* aCx, JSObject* aScope,
-                            bool* aTriedToWrap)
-{
-  return SVGFEFuncAElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
-}
-
-} // namespace dom
-} // namespace mozilla
-
-NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(FEFuncA)
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGFEFuncAElement)
-
-} // namespace dom
-} // namespace mozilla
-
-//---------------------Merge------------------------
-
-typedef nsSVGFE nsSVGFEMergeElementBase;
-
-class nsSVGFEMergeElement : public nsSVGFEMergeElementBase,
-                            public nsIDOMSVGFEMergeElement
-{
-  friend nsresult NS_NewSVGFEMergeElement(nsIContent **aResult,
-                                          already_AddRefed<nsINodeInfo> aNodeInfo);
-protected:
-  nsSVGFEMergeElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFEMergeElementBase(aNodeInfo) {}
-
-public:
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // FE Base
-  NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFEMergeElementBase::)
-
-  virtual nsresult Filter(nsSVGFilterInstance* aInstance,
-                          const nsTArray<const Image*>& aSources,
-                          const Image* aTarget,
-                          const nsIntRect& aDataRect);
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
-
-  // Merge
-  NS_DECL_NSIDOMSVGFEMERGEELEMENT
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEMergeElementBase::)
-
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIContent
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-  virtual StringAttributesInfo GetStringInfo();
-
-  enum { RESULT };
-  nsSVGString mStringAttributes[1];
-  static StringInfo sStringInfo[1];
-};
-
-typedef SVGFEUnstyledElement nsSVGFEMergeNodeElementBase;
-
-#define NS_SVG_FE_MERGE_NODE_CID \
-    { 0x413687ec, 0x77fd, 0x4077, \
-  { 0x9d, 0x7a, 0x97, 0x51, 0xa8, 0x4b, 0x7b, 0x40 } }
-
-class nsSVGFEMergeNodeElement : public nsSVGFEMergeNodeElementBase,
-                                public nsIDOMSVGFEMergeNodeElement
-{
-  friend nsresult NS_NewSVGFEMergeNodeElement(nsIContent **aResult,
-                                          already_AddRefed<nsINodeInfo> aNodeInfo);
-protected:
-  nsSVGFEMergeNodeElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFEMergeNodeElementBase(aNodeInfo) {}
-
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_SVG_FE_MERGE_NODE_CID)
-
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  NS_DECL_NSIDOMSVGFEMERGENODEELEMENT
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEMergeNodeElementBase::)
-
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-
-  const nsSVGString* In1() { return &mStringAttributes[IN1]; }
-  
-  operator nsISupports*() { return static_cast<nsIContent*>(this); }
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-  virtual StringAttributesInfo GetStringInfo();
-
-  enum { IN1 };
-  nsSVGString mStringAttributes[1];
-  static StringInfo sStringInfo[1];
-};
-
-nsSVGElement::StringInfo nsSVGFEMergeElement::sStringInfo[1] =
-{
-  { &nsGkAtoms::result, kNameSpaceID_None, true }
-};
-
-NS_IMPL_NS_NEW_SVG_ELEMENT(FEMerge)
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFEMergeElement,nsSVGFEMergeElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFEMergeElement,nsSVGFEMergeElementBase)
-
-DOMCI_NODE_DATA(SVGFEMergeElement, nsSVGFEMergeElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGFEMergeElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGFEMergeElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement,
-                           nsIDOMSVGFilterPrimitiveStandardAttributes,
-                           nsIDOMSVGFEMergeElement)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEMergeElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFEMergeElementBase)
-
-//----------------------------------------------------------------------
-// nsIDOMNode methods
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFEMergeElement)
-
-nsresult
-nsSVGFEMergeElement::Filter(nsSVGFilterInstance *instance,
-                            const nsTArray<const Image*>& aSources,
-                            const Image* aTarget,
-                            const nsIntRect& rect)
-{
-  gfxContext ctx(aTarget->mImage);
-  ctx.Clip(aTarget->mFilterPrimitiveSubregion);
-
-  for (uint32_t i = 0; i < aSources.Length(); i++) {
-    ctx.SetSource(aSources[i]->mImage);
-    ctx.Paint();
-  }
-  return NS_OK;
-}
-
-void
-nsSVGFEMergeElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
-{
-  for (nsIContent* child = nsINode::GetFirstChild();
-       child;
-       child = child->GetNextSibling()) {
-    nsRefPtr<nsSVGFEMergeNodeElement> node;
-    CallQueryInterface(child, (nsSVGFEMergeNodeElement**)getter_AddRefs(node));
-    if (node) {
-      aSources.AppendElement(nsSVGStringInfo(node->In1(), node));
-    }
-  }
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::StringAttributesInfo
-nsSVGFEMergeElement::GetStringInfo()
-{
-  return StringAttributesInfo(mStringAttributes, sStringInfo,
-                              ArrayLength(sStringInfo));
-}
-
-//---------------------Merge Node------------------------
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsSVGFEMergeNodeElement, NS_SVG_FE_MERGE_NODE_CID)
-
-nsSVGElement::StringInfo nsSVGFEMergeNodeElement::sStringInfo[1] =
-{
-  { &nsGkAtoms::in, kNameSpaceID_None, true }
-};
-
-NS_IMPL_NS_NEW_SVG_ELEMENT(FEMergeNode)
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFEMergeNodeElement,nsSVGFEMergeNodeElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFEMergeNodeElement,nsSVGFEMergeNodeElementBase)
-
-DOMCI_NODE_DATA(SVGFEMergeNodeElement, nsSVGFEMergeNodeElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGFEMergeNodeElement)
-  NS_NODE_INTERFACE_TABLE4(nsSVGFEMergeNodeElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement, nsIDOMSVGFEMergeNodeElement)
-   // nsISupports is an ambiguous base of nsSVGFE so we have to work
-   // around that
-   if ( aIID.Equals(NS_GET_IID(nsSVGFEMergeNodeElement)) )
-     foundInterface = static_cast<nsISupports*>(static_cast<void*>(this));
-   else
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEMergeNodeElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFEMergeNodeElementBase)
-
-//----------------------------------------------------------------------
-// nsIDOMNode methods
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFEMergeNodeElement)
-
-//----------------------------------------------------------------------
-// nsFEUnstyledElement methods
-
-bool
-nsSVGFEMergeNodeElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                                   nsIAtom* aAttribute) const
-{
-  return aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::in;
-}
-
-//----------------------------------------------------------------------
-// nsIDOMSVGFEMergeNodeElement methods
-
-/* readonly attribute nsIDOMSVGAnimatedString in1; */
-NS_IMETHODIMP nsSVGFEMergeNodeElement::GetIn1(nsIDOMSVGAnimatedString * *aIn)
-{
-  return mStringAttributes[IN1].ToDOMAnimatedString(aIn, this);
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::StringAttributesInfo
-nsSVGFEMergeNodeElement::GetStringInfo()
-{
-  return StringAttributesInfo(mStringAttributes, sStringInfo,
-                              ArrayLength(sStringInfo));
-}
-
-//---------------------Offset------------------------
-
-typedef nsSVGFE nsSVGFEOffsetElementBase;
-
-class nsSVGFEOffsetElement : public nsSVGFEOffsetElementBase,
-                             public nsIDOMSVGFEOffsetElement
-{
-  friend nsresult NS_NewSVGFEOffsetElement(nsIContent **aResult,
-                                           already_AddRefed<nsINodeInfo> aNodeInfo);
-protected:
-  nsSVGFEOffsetElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFEOffsetElementBase(aNodeInfo) {}
-
-public:
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // FE Base
-  NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFEOffsetElementBase::)
-
-  virtual nsresult Filter(nsSVGFilterInstance* aInstance,
-                          const nsTArray<const Image*>& aSources,
-                          const Image* aTarget,
-                          const nsIntRect& aDataRect);
-  virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
-  virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
-  virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance);
-  virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-          const nsSVGFilterInstance& aInstance);
-
-  // Offset
-  NS_DECL_NSIDOMSVGFEOFFSETELEMENT
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEOffsetElementBase::)
-
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-  nsIntPoint GetOffset(const nsSVGFilterInstance& aInstance);
-  
-  virtual NumberAttributesInfo GetNumberInfo();
-  virtual StringAttributesInfo GetStringInfo();
-
-  enum { DX, DY };
-  nsSVGNumber2 mNumberAttributes[2];
-  static NumberInfo sNumberInfo[2];
-
-  enum { RESULT, IN1 };
-  nsSVGString mStringAttributes[2];
-  static StringInfo sStringInfo[2];
-};
-
-nsSVGElement::NumberInfo nsSVGFEOffsetElement::sNumberInfo[2] =
-{
-  { &nsGkAtoms::dx, 0, false },
-  { &nsGkAtoms::dy, 0, false }
-};
-
-nsSVGElement::StringInfo nsSVGFEOffsetElement::sStringInfo[2] =
-{
-  { &nsGkAtoms::result, kNameSpaceID_None, true },
-  { &nsGkAtoms::in, kNameSpaceID_None, true }
-};
-
-NS_IMPL_NS_NEW_SVG_ELEMENT(FEOffset)
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFEOffsetElement,nsSVGFEOffsetElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFEOffsetElement,nsSVGFEOffsetElementBase)
-
-DOMCI_NODE_DATA(SVGFEOffsetElement, nsSVGFEOffsetElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGFEOffsetElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGFEOffsetElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement,
-                           nsIDOMSVGFilterPrimitiveStandardAttributes,
-                           nsIDOMSVGFEOffsetElement)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEOffsetElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFEOffsetElementBase)
-
-//----------------------------------------------------------------------
-// nsIDOMNode methods
-
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFEOffsetElement)
-
-
-//----------------------------------------------------------------------
-// nsIDOMSVGFEOffsetElement methods
-
-/* readonly attribute nsIDOMSVGAnimatedString in1; */
-NS_IMETHODIMP nsSVGFEOffsetElement::GetIn1(nsIDOMSVGAnimatedString * *aIn)
-{
-  return mStringAttributes[IN1].ToDOMAnimatedString(aIn, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber dx; */
-NS_IMETHODIMP nsSVGFEOffsetElement::GetDx(nsIDOMSVGAnimatedNumber * *aDx)
-{
-  return mNumberAttributes[DX].ToDOMAnimatedNumber(aDx, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber dy; */
-NS_IMETHODIMP nsSVGFEOffsetElement::GetDy(nsIDOMSVGAnimatedNumber * *aDy)
-{
-  return mNumberAttributes[DY].ToDOMAnimatedNumber(aDy, this);
-}
-
-nsIntPoint
-nsSVGFEOffsetElement::GetOffset(const nsSVGFilterInstance& aInstance)
-{
-  return nsIntPoint(int32_t(aInstance.GetPrimitiveNumber(
-                              SVGContentUtils::X, &mNumberAttributes[DX])),
-                    int32_t(aInstance.GetPrimitiveNumber(
-                              SVGContentUtils::Y, &mNumberAttributes[DY])));
-}
-
-nsresult
-nsSVGFEOffsetElement::Filter(nsSVGFilterInstance *instance,
-                             const nsTArray<const Image*>& aSources,
-                             const Image* aTarget,
-                             const nsIntRect& rect)
-{
-  nsIntPoint offset = GetOffset(*instance);
-
-  gfxContext ctx(aTarget->mImage);
-  ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
-  // Ensure rendering is limited to the filter primitive subregion
-  ctx.Clip(aTarget->mFilterPrimitiveSubregion);
-  ctx.Translate(gfxPoint(offset.x, offset.y));
-  ctx.SetSource(aSources[0]->mImage);
-  ctx.Paint();
-
-  return NS_OK;
-}
-
-bool
-nsSVGFEOffsetElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                                nsIAtom* aAttribute) const
-{
-  return nsSVGFEOffsetElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
-         (aNameSpaceID == kNameSpaceID_None &&
-          (aAttribute == nsGkAtoms::in ||
-           aAttribute == nsGkAtoms::dx ||
-           aAttribute == nsGkAtoms::dy));
-}
-
-void
-nsSVGFEOffsetElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
-{
-  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
-}
-
-nsIntRect
-nsSVGFEOffsetElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-        const nsSVGFilterInstance& aInstance)
-{
-  return aSourceBBoxes[0] + GetOffset(aInstance);
-}
-
-nsIntRect
-nsSVGFEOffsetElement::ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-                                        const nsSVGFilterInstance& aInstance)
-{
-  return aSourceChangeBoxes[0] + GetOffset(aInstance);
-}
-
-void
-nsSVGFEOffsetElement::ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance)
-{
-  aSourceBBoxes[0] = aTargetBBox - GetOffset(aInstance);
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::NumberAttributesInfo
-nsSVGFEOffsetElement::GetNumberInfo()
-{
-  return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
-                              ArrayLength(sNumberInfo));
-}
-
-nsSVGElement::StringAttributesInfo
-nsSVGFEOffsetElement::GetStringInfo()
-{
-  return StringAttributesInfo(mStringAttributes, sStringInfo,
-                              ArrayLength(sStringInfo));
-}
-
-//---------------------Flood------------------------
-
-typedef nsSVGFE nsSVGFEFloodElementBase;
-
-class nsSVGFEFloodElement : public nsSVGFEFloodElementBase,
-                            public nsIDOMSVGFEFloodElement
-{
-  friend nsresult NS_NewSVGFEFloodElement(nsIContent **aResult,
-                                          already_AddRefed<nsINodeInfo> aNodeInfo);
-protected:
-  nsSVGFEFloodElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFEFloodElementBase(aNodeInfo) {}
-
-public:
-  virtual bool SubregionIsUnionOfRegions() { return false; }
-
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // FE Base
-  NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFEFloodElementBase::)
-
-  virtual nsresult Filter(nsSVGFilterInstance* aInstance,
-                          const nsTArray<const Image*>& aSources,
-                          const Image* aTarget,
-                          const nsIntRect& aDataRect);
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
-
-  // Flood
-  NS_DECL_NSIDOMSVGFEFLOODELEMENT
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEFloodElementBase::)
-  
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  // nsIContent interface
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-  virtual bool OperatesOnSRGB(nsSVGFilterInstance*,
-                              int32_t, Image*) { return true; }
-
-  virtual StringAttributesInfo GetStringInfo();
-
-  enum { RESULT };
-  nsSVGString mStringAttributes[1];
-  static StringInfo sStringInfo[1];
-};
-
-nsSVGElement::StringInfo nsSVGFEFloodElement::sStringInfo[1] =
-{
-  { &nsGkAtoms::result, kNameSpaceID_None, true }
-};
-
-NS_IMPL_NS_NEW_SVG_ELEMENT(FEFlood)
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFEFloodElement,nsSVGFEFloodElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFEFloodElement,nsSVGFEFloodElementBase)
-
-DOMCI_NODE_DATA(SVGFEFloodElement, nsSVGFEFloodElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGFEFloodElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGFEFloodElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement,
-                           nsIDOMSVGFilterPrimitiveStandardAttributes,
-                           nsIDOMSVGFEFloodElement)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEFloodElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFEFloodElementBase)
-
-//----------------------------------------------------------------------
-// nsIDOMNode methods
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFEFloodElement)
-
-
-//----------------------------------------------------------------------
-// nsIDOMSVGFEFloodElement methods
-
-nsresult
-nsSVGFEFloodElement::Filter(nsSVGFilterInstance *instance,
-                            const nsTArray<const Image*>& aSources,
-                            const Image* aTarget,
-                            const nsIntRect& aDataRect)
-{
-  nsIFrame* frame = GetPrimaryFrame();
-  if (!frame) return NS_ERROR_FAILURE;
-  nsStyleContext* style = frame->StyleContext();
-
-  nscolor floodColor = style->StyleSVGReset()->mFloodColor;
-  float floodOpacity = style->StyleSVGReset()->mFloodOpacity;
-
-  gfxContext ctx(aTarget->mImage);
-  ctx.SetColor(gfxRGBA(NS_GET_R(floodColor) / 255.0,
-                       NS_GET_G(floodColor) / 255.0,
-                       NS_GET_B(floodColor) / 255.0,
-                       NS_GET_A(floodColor) / 255.0 * floodOpacity));
-  ctx.Rectangle(aTarget->mFilterPrimitiveSubregion);
-  ctx.Fill();
-  return NS_OK;
-}
-
-nsIntRect
-nsSVGFEFloodElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-        const nsSVGFilterInstance& aInstance)
-{
-  return GetMaxRect();
-}
-
-//----------------------------------------------------------------------
-// nsIContent methods
-
-NS_IMETHODIMP_(bool)
-nsSVGFEFloodElement::IsAttributeMapped(const nsIAtom* name) const
-{
-  static const MappedAttributeEntry* const map[] = {
-    sFEFloodMap
-  };
-  
-  return FindAttributeDependence(name, map) ||
-    nsSVGFEFloodElementBase::IsAttributeMapped(name);
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::StringAttributesInfo
-nsSVGFEFloodElement::GetStringInfo()
-{
-  return StringAttributesInfo(mStringAttributes, sStringInfo,
-                              ArrayLength(sStringInfo));
-}
-
-//---------------------Tile------------------------
-
-typedef nsSVGFE nsSVGFETileElementBase;
-
-class nsSVGFETileElement : public nsSVGFETileElementBase,
-                           public nsIDOMSVGFETileElement
-{
-  friend nsresult NS_NewSVGFETileElement(nsIContent **aResult,
-                                         already_AddRefed<nsINodeInfo> aNodeInfo);
-protected:
-  nsSVGFETileElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFETileElementBase(aNodeInfo) {}
-
-public:
-  virtual bool SubregionIsUnionOfRegions() { return false; }
-
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // FE Base
-  NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFETileElementBase::)
-
-  virtual nsresult Filter(nsSVGFilterInstance* aInstance,
-                          const nsTArray<const Image*>& aSources,
-                          const Image* aTarget,
-                          const nsIntRect& aDataRect);
-  virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
-  virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
-  virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance);
-  virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-          const nsSVGFilterInstance& aInstance);
-
-  // Tile
-  NS_DECL_NSIDOMSVGFETILEELEMENT
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFETileElementBase::)
-
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-  virtual StringAttributesInfo GetStringInfo();
-  
-  enum { RESULT, IN1 };
-  nsSVGString mStringAttributes[2];
-  static StringInfo sStringInfo[2];
-};
-
-nsSVGElement::StringInfo nsSVGFETileElement::sStringInfo[2] =
-{
-  { &nsGkAtoms::result, kNameSpaceID_None, true },
-  { &nsGkAtoms::in, kNameSpaceID_None, true }
-};
-
-NS_IMPL_NS_NEW_SVG_ELEMENT(FETile)
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFETileElement,nsSVGFETileElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFETileElement,nsSVGFETileElementBase)
-
-DOMCI_NODE_DATA(SVGFETileElement, nsSVGFETileElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGFETileElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGFETileElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement,
-                           nsIDOMSVGFilterPrimitiveStandardAttributes,
-                           nsIDOMSVGFETileElement)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFETileElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFETileElementBase)
-
-//----------------------------------------------------------------------
-// nsIDOMNode methods
-
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFETileElement)
-
-
-//----------------------------------------------------------------------
-// nsSVGFETileElement methods
-
-/* readonly attribute nsIDOMSVGAnimatedString in1; */
-NS_IMETHODIMP nsSVGFETileElement::GetIn1(nsIDOMSVGAnimatedString * *aIn)
-{
-  return mStringAttributes[IN1].ToDOMAnimatedString(aIn, this);
-}
-
-void
-nsSVGFETileElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
-{
-  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
-}
-
-nsIntRect
-nsSVGFETileElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-        const nsSVGFilterInstance& aInstance)
-{
-  return GetMaxRect();
-}
-
-void
-nsSVGFETileElement::ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance)
-{
-  // Just assume we need the entire source bounding box, so do nothing.
-}
-
-nsIntRect
-nsSVGFETileElement::ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-                                      const nsSVGFilterInstance& aInstance)
-{
-  return GetMaxRect();
-}
-
-static int32_t WrapInterval(int32_t aVal, int32_t aMax)
-{
-  aVal = aVal % aMax;
-  return aVal < 0 ? aMax + aVal : aVal;
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-/*
- * This function computes the size of partial match on either side of the tile.
- * eg: If we are talking about the X-axis direction, then it computes, the 
- * size of the tile that would be copied to the lesser X-axis side (usually
- * left), the higher X-axis side (usualy right) and the centre.
- * This is needed because often, the tile doesn't exactly align to the target
- * region and is partially copied on the edges. This function computes the
- * dimensions of the partially copied regions in one axis.
- *
- * OUTPUT:
- * aLesserSidePartialMatchSize: The size of the partial match on the lesser
- *                              side of the axis being considered.
- *                              eg: for X-axis, usually left side and
- *                                  for Y-axis, usually top
- * aHigherSidePartialMatchSize: The size of the partial match on the higher
- *                              side of the axis being considered.
- *                              eg: for X-axis, usually right side and
- *                                  for Y-axis, usually bottom
- * aCentreSize: The size of the target area where the tile is copied in full.
- *              This lies between the lesser and higher side partial matches.
- *              (the partially matched areas may be of zero width)
- *
- * INPUT:
- * aLesserTargetExtent: Edge of the target area on the axis being considered
- *                      on the lesser side. (eg: usually left on the X-axis)
- * aTargetSize: Size of the target area on the axis being considered (eg:
- *              usually width for X-axis)
- * aLesserTileExtent: Edge of the tile on the axis being considered on the
- *                    lesser side.
- * aTileSize: Size of the tile on the axis being considered.
- */
-static inline void
-ComputePartialTileExtents(int32_t *aLesserSidePartialMatchSize,
-                          int32_t *aHigherSidePartialMatchSize,
-                          int32_t *aCentreSize,
-                          int32_t aLesserTargetExtent,
-                          int32_t aTargetSize,
-                          int32_t aLesserTileExtent,
-                          int32_t aTileSize)
-{
-  int32_t targetExtentMost = aLesserTargetExtent + aTargetSize;
-  int32_t tileExtentMost = aLesserTileExtent + aTileSize;
-
-  int32_t lesserSidePartialMatchSize;
-  if (aLesserTileExtent < aLesserTargetExtent) {
-    lesserSidePartialMatchSize = tileExtentMost - aLesserTargetExtent;
-  } else {
-    lesserSidePartialMatchSize = (aLesserTileExtent - aLesserTargetExtent) %
-                                    aTileSize;
-  }
-
-  int32_t higherSidePartialMatchSize;
-  if (lesserSidePartialMatchSize > aTargetSize) {
-    lesserSidePartialMatchSize = aTargetSize;
-    higherSidePartialMatchSize = 0;
-  } else if (tileExtentMost > targetExtentMost) {
-      higherSidePartialMatchSize = targetExtentMost - aLesserTileExtent;
-  } else {
-    higherSidePartialMatchSize = (targetExtentMost - tileExtentMost) %
-                                    aTileSize;
-  }
-
-  if (lesserSidePartialMatchSize + higherSidePartialMatchSize >
-        aTargetSize) {
-    higherSidePartialMatchSize = aTargetSize - lesserSidePartialMatchSize;
-  }
-
-  /*
-   * To understand the conditon below, let us consider the X-Axis:
-   * Lesser side is left and the Higher side is right.
-   * This implies:
-   * aTargetSize is rect.width.
-   * lesserSidePartialMatchSize would mean leftPartialTileWidth.
-   * higherSidePartialMatchSize would mean rightPartialTileWidth.
-   *
-   * leftPartialTileWidth == rect.width only happens when the tile entirely
-   * overlaps with the target area in the X-axis and exceeds its bounds by at
-   * least one pixel on the lower X-Axis side.
-   *
-   * leftPartialTileWidth + rightPartialTileWidth == rect.width only happens
-   * when the tile overlaps the target area in such a way that the edge of the
-   * tile on the higher X-Axis side cuts through the target area and there is no
-   * space for a complete tile in the X-Axis in the target area on either side
-   * of that edge. In this scenario, centre will be of zero width and the
-   * partial widths on left and right will add up to the width of the rect. In
-   * case the tile is bigger than the rect in the X-axis, it will get clipped
-   * and remain equal to rect.width.
-   *
-   * Therefore, those two conditions are separate cases which lead to centre
-   * being of zero width.
-   *
-   * The condition below is the same logic as above expressed independent of
-   * the axis in consideration.
-   */
-
-  int32_t centreSize;
-  if (lesserSidePartialMatchSize == aTargetSize ||
-        lesserSidePartialMatchSize + higherSidePartialMatchSize ==
-        aTargetSize) {
-    centreSize = 0;
-  } else {
-    centreSize = aTargetSize -
-                   (lesserSidePartialMatchSize + higherSidePartialMatchSize);
-  }
-
-  *aLesserSidePartialMatchSize = lesserSidePartialMatchSize;
-  *aHigherSidePartialMatchSize = higherSidePartialMatchSize;
-  *aCentreSize = centreSize;
-}
-
-static inline void
-TilePixels(uint8_t *aTargetData,
-           const uint8_t *aSourceData,
-           const nsIntRect &targetRegion,
-           const nsIntRect &aTile,
-           uint32_t aStride)
-{
-  if (targetRegion.IsEmpty()) {
-    return;
-  }
-
-  uint32_t tileRowCopyMemSize = aTile.width * 4;
-  uint32_t numTimesToCopyTileRows = targetRegion.width / aTile.width;
-
-  uint8_t *targetFirstRowOffset = aTargetData + 4 * targetRegion.x;
-  const uint8_t *tileFirstRowOffset = aSourceData + 4 * aTile.x;
-
-  int32_t tileYOffset = 0;
-  for (int32_t targetY = targetRegion.y;
-       targetY < targetRegion.YMost();
-       ++targetY) {
-    uint8_t *targetRowOffset = targetFirstRowOffset + aStride * targetY;
-    const uint8_t *tileRowOffset = tileFirstRowOffset +
-                                             aStride * (aTile.y + tileYOffset);
-
-    for (uint32_t i = 0; i < numTimesToCopyTileRows; ++i) {
-      memcpy(targetRowOffset + i * tileRowCopyMemSize,
-             tileRowOffset,
-             tileRowCopyMemSize);
-    }
-
-    tileYOffset = (tileYOffset + 1) % aTile.height;
-  }
-}
-
-nsresult
-nsSVGFETileElement::Filter(nsSVGFilterInstance *instance,
-                           const nsTArray<const Image*>& aSources,
-                           const Image* aTarget,
-                           const nsIntRect& rect)
-{
-  // XXX This code depends on the surface rect containing the filter
-  // primitive subregion. ComputeTargetBBox, ComputeNeededSourceBBoxes
-  // and ComputeChangeBBox are all pessimal, so that will normally be OK,
-  // but nothing clips mFilterPrimitiveSubregion so this should be changed.
-
-  nsIntRect tile;
-  bool res = gfxUtils::GfxRectToIntRect(aSources[0]->mFilterPrimitiveSubregion,
-                                        &tile);
-
-  NS_ENSURE_TRUE(res, NS_ERROR_FAILURE); // asserts on failure (not 
-  if (tile.IsEmpty())
-    return NS_OK;
-
-  const nsIntRect &surfaceRect = instance->GetSurfaceRect();
-  if (!tile.Intersects(surfaceRect)) {
-    // nothing to draw
-    return NS_OK;
-  }
-
-  // clip tile
-  tile = tile.Intersect(surfaceRect);
-
-  // Get it into surface space
-  tile -= surfaceRect.TopLeft();
-
-  uint8_t* sourceData = aSources[0]->mImage->Data();
-  uint8_t* targetData = aTarget->mImage->Data();
-  uint32_t stride = aTarget->mImage->Stride();
-
-  /*
-   * priority: left before right before centre
-   *             and
-   *           top before bottom before centre
-   *
-   * eg: If we have a target area which is 1.5 times the width of a tile,
-   *     then, based on alignment, we get:
-   *       'left and right'
-   *         or
-   *       'left and centre'
-   *
-   */
-
-  int32_t leftPartialTileWidth;
-  int32_t rightPartialTileWidth;
-  int32_t centreWidth;
-  ComputePartialTileExtents(&leftPartialTileWidth,
-                            &rightPartialTileWidth,
-                            &centreWidth,
-                            rect.x,
-                            rect.width,
-                            tile.x,
-                            tile.width);
-
-  int32_t topPartialTileHeight;
-  int32_t bottomPartialTileHeight;
-  int32_t centreHeight;
-  ComputePartialTileExtents(&topPartialTileHeight,
-                            &bottomPartialTileHeight,
-                            &centreHeight,
-                            rect.y,
-                            rect.height,
-                            tile.y,
-                            tile.height);
-
-  /* We have nine regions of the target area which have to be tiled differetly:
-   *
-   * Top Left,    Top Middle,    Top Right,
-   * Left Middle, Centre,        Right Middle,
-   * Bottom Left, Bottom Middle, Bottom Right
-   *
-   * + Centre is tiled by repeating the tiled image in full.
-   * + Top Left, Top Middle and Top Right:
-   *     Some of the rows from the top of the tile will be clipped here.
-   * + Bottom Left, Bottom Middle and Bottom Right:
-   *     Some of the rows from the bottom of the tile will be clipped here.
-   * + Top Left, Left Middle and Bottom left:
-   *     Some of the columns from the Left of the tile will be clipped here.
-   * + Top Right, Right Middle and Bottom Right:
-   *     Some of the columns from the right of the tile will be clipped here.
-   *
-   * If the sizes and positions of the target and tile are such that the tile
-   * aligns exactly on any (or all) of the edges, then some (or all) of the
-   * regions above (except Centre) will be zero sized.
-   */
-
-  nsIntRect targetRects[] = {
-    // Top Left
-    nsIntRect(rect.x, rect.y, leftPartialTileWidth, topPartialTileHeight),
-    // Top Middle
-    nsIntRect(rect.x + leftPartialTileWidth,
-              rect.y,
-              centreWidth,
-              topPartialTileHeight),
-    // Top Right
-    nsIntRect(rect.XMost() - rightPartialTileWidth,
-              rect.y,
-              rightPartialTileWidth,
-              topPartialTileHeight),
-    // Left Middle
-    nsIntRect(rect.x,
-              rect.y + topPartialTileHeight,
-              leftPartialTileWidth,
-              centreHeight),
-    // Centre
-    nsIntRect(rect.x + leftPartialTileWidth,
-              rect.y + topPartialTileHeight,
-              centreWidth,
-              centreHeight),
-    // Right Middle
-    nsIntRect(rect.XMost() - rightPartialTileWidth,
-              rect.y + topPartialTileHeight,
-              rightPartialTileWidth,
-              centreHeight),
-    // Bottom Left
-    nsIntRect(rect.x,
-              rect.YMost() - bottomPartialTileHeight,
-              leftPartialTileWidth,
-              bottomPartialTileHeight),
-    // Bottom Middle
-    nsIntRect(rect.x + leftPartialTileWidth,
-              rect.YMost() - bottomPartialTileHeight,
-              centreWidth,
-              bottomPartialTileHeight),
-    // Bottom Right
-    nsIntRect(rect.XMost() - rightPartialTileWidth,
-              rect.YMost() - bottomPartialTileHeight,
-              rightPartialTileWidth,
-              bottomPartialTileHeight)
-  };
-
-  nsIntRect tileRects[] = {
-    // Top Left
-    nsIntRect(tile.XMost() - leftPartialTileWidth,
-              tile.YMost() - topPartialTileHeight,
-              leftPartialTileWidth,
-              topPartialTileHeight),
-    // Top Middle
-    nsIntRect(tile.x,
-              tile.YMost() - topPartialTileHeight,
-              tile.width,
-              topPartialTileHeight),
-    // Top Right
-    nsIntRect(tile.x,
-              tile.YMost() - topPartialTileHeight,
-              rightPartialTileWidth,
-              topPartialTileHeight),
-    // Left Middle
-    nsIntRect(tile.XMost() - leftPartialTileWidth,
-              tile.y,
-              leftPartialTileWidth,
-              tile.height),
-    // Centre
-    nsIntRect(tile.x,
-              tile.y,
-              tile.width,
-              tile.height),
-    // Right Middle
-    nsIntRect(tile.x,
-              tile.y,
-              rightPartialTileWidth,
-              tile.height),
-    // Bottom Left
-    nsIntRect(tile.XMost() - leftPartialTileWidth,
-              tile.y,
-              leftPartialTileWidth,
-              bottomPartialTileHeight),
-    // Bottom Middle
-    nsIntRect(tile.x,
-              tile.y,
-              tile.width,
-              bottomPartialTileHeight),
-    // Bottom Right
-    nsIntRect(tile.x,
-              tile.y,
-              rightPartialTileWidth,
-              bottomPartialTileHeight)
-  };
-
-  for (uint32_t i = 0; i < ArrayLength(targetRects); ++i) {
-    TilePixels(targetData,
-               sourceData,
-               targetRects[i],
-               tileRects[i],
-               stride);
-  }
-
-  return NS_OK;
-}
-
-bool
-nsSVGFETileElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                              nsIAtom* aAttribute) const
-{
-  return nsSVGFETileElementBase::AttributeAffectsRendering(aNameSpaceID, 
-                                                           aAttribute) ||
-           (aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::in);
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::StringAttributesInfo
-nsSVGFETileElement::GetStringInfo()
-{
-  return StringAttributesInfo(mStringAttributes, sStringInfo,
-                              ArrayLength(sStringInfo));
-}
-
-//---------------------Turbulence------------------------
-
-typedef nsSVGFE nsSVGFETurbulenceElementBase;
-
-class nsSVGFETurbulenceElement : public nsSVGFETurbulenceElementBase,
-                                 public nsIDOMSVGFETurbulenceElement
-{
-  friend nsresult NS_NewSVGFETurbulenceElement(nsIContent **aResult,
-                                               already_AddRefed<nsINodeInfo> aNodeInfo);
-protected:
-  nsSVGFETurbulenceElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFETurbulenceElementBase(aNodeInfo) {}
-
-public:
-  virtual bool SubregionIsUnionOfRegions() { return false; }
-
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // FE Base
-  NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFETurbulenceElementBase::)
-
-  virtual nsresult Filter(nsSVGFilterInstance* aInstance,
-                          const nsTArray<const Image*>& aSources,
-                          const Image* aTarget,
-                          const nsIntRect& aDataRect);
-  virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
-
-  // Turbulence
-  NS_DECL_NSIDOMSVGFETURBULENCEELEMENT
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFETurbulenceElementBase::)
-
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-  virtual NumberAttributesInfo GetNumberInfo();
-  virtual NumberPairAttributesInfo GetNumberPairInfo();
-  virtual IntegerAttributesInfo GetIntegerInfo();
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
-
-  enum { SEED }; // floating point seed?!
-  nsSVGNumber2 mNumberAttributes[1];
-  static NumberInfo sNumberInfo[1];
-
-  enum { BASE_FREQ };
-  nsSVGNumberPair mNumberPairAttributes[1];
-  static NumberPairInfo sNumberPairInfo[1];
-
-  enum { OCTAVES };
-  nsSVGInteger mIntegerAttributes[1];
-  static IntegerInfo sIntegerInfo[1];
-
-  enum { TYPE, STITCHTILES };
-  nsSVGEnum mEnumAttributes[2];
-  static nsSVGEnumMapping sTypeMap[];
-  static nsSVGEnumMapping sStitchTilesMap[];
-  static EnumInfo sEnumInfo[2];
-
-  enum { RESULT };
-  nsSVGString mStringAttributes[1];
-  static StringInfo sStringInfo[1];
-
-private:
-
-  /* The turbulence calculation code is an adapted version of what
-     appears in the SVG 1.1 specification:
-         http://www.w3.org/TR/SVG11/filters.html#feTurbulence
-  */
-
-  /* Produces results in the range [1, 2**31 - 2].
-     Algorithm is: r = (a * r) mod m
-     where a = 16807 and m = 2**31 - 1 = 2147483647
-     See [Park & Miller], CACM vol. 31 no. 10 p. 1195, Oct. 1988
-     To test: the algorithm should produce the result 1043618065
-     as the 10,000th generated number if the original seed is 1.
-  */
-#define RAND_M 2147483647	/* 2**31 - 1 */
-#define RAND_A 16807		/* 7**5; primitive root of m */
-#define RAND_Q 127773		/* m / a */
-#define RAND_R 2836		/* m % a */
-
-  int32_t SetupSeed(int32_t aSeed) {
-    if (aSeed <= 0)
-      aSeed = -(aSeed % (RAND_M - 1)) + 1;
-    if (aSeed > RAND_M - 1)
-      aSeed = RAND_M - 1;
-    return aSeed;
-  }
-
-  uint32_t Random(uint32_t aSeed) {
-    int32_t result = RAND_A * (aSeed % RAND_Q) - RAND_R * (aSeed / RAND_Q);
-    if (result <= 0)
-      result += RAND_M;
-    return result;
-  }
-#undef RAND_M
-#undef RAND_A
-#undef RAND_Q
-#undef RAND_R
-
-  const static int sBSize = 0x100;
-  const static int sBM = 0xff;
-  const static int sPerlinN = 0x1000;
-  const static int sNP = 12;			/* 2^PerlinN */
-  const static int sNM = 0xfff;
-
-  int32_t mLatticeSelector[sBSize + sBSize + 2];
-  double mGradient[4][sBSize + sBSize + 2][2];
-  struct StitchInfo {
-    int mWidth;			// How much to subtract to wrap for stitching.
-    int mHeight;
-    int mWrapX;			// Minimum value to wrap.
-    int mWrapY;
-  };
-
-  void InitSeed(int32_t aSeed);
-  double Noise2(int aColorChannel, double aVec[2], StitchInfo *aStitchInfo);
-  double
-  Turbulence(int aColorChannel, double *aPoint, double aBaseFreqX,
-             double aBaseFreqY, int aNumOctaves, bool aFractalSum,
-             bool aDoStitching, double aTileX, double aTileY,
-             double aTileWidth, double aTileHeight);
-};
-
-nsSVGElement::NumberInfo nsSVGFETurbulenceElement::sNumberInfo[1] =
-{
-  { &nsGkAtoms::seed, 0, false }
-};
-
-nsSVGElement::NumberPairInfo nsSVGFETurbulenceElement::sNumberPairInfo[1] =
-{
-  { &nsGkAtoms::baseFrequency, 0, 0 }
-};
-
-nsSVGElement::IntegerInfo nsSVGFETurbulenceElement::sIntegerInfo[1] =
-{
-  { &nsGkAtoms::numOctaves, 1 }
-};
-
-nsSVGEnumMapping nsSVGFETurbulenceElement::sTypeMap[] = {
-  {&nsGkAtoms::fractalNoise,
-   nsIDOMSVGFETurbulenceElement::SVG_TURBULENCE_TYPE_FRACTALNOISE},
-  {&nsGkAtoms::turbulence,
-   nsIDOMSVGFETurbulenceElement::SVG_TURBULENCE_TYPE_TURBULENCE},
-  {nullptr, 0}
-};
-
-nsSVGEnumMapping nsSVGFETurbulenceElement::sStitchTilesMap[] = {
-  {&nsGkAtoms::stitch,
-   nsIDOMSVGFETurbulenceElement::SVG_STITCHTYPE_STITCH},
-  {&nsGkAtoms::noStitch,
-   nsIDOMSVGFETurbulenceElement::SVG_STITCHTYPE_NOSTITCH},
-  {nullptr, 0}
-};
-
-nsSVGElement::EnumInfo nsSVGFETurbulenceElement::sEnumInfo[2] =
-{
-  { &nsGkAtoms::type,
-    sTypeMap,
-    nsIDOMSVGFETurbulenceElement::SVG_TURBULENCE_TYPE_TURBULENCE
-  },
-  { &nsGkAtoms::stitchTiles,
-    sStitchTilesMap,
-    nsIDOMSVGFETurbulenceElement::SVG_STITCHTYPE_NOSTITCH
-  }
-};
-
-nsSVGElement::StringInfo nsSVGFETurbulenceElement::sStringInfo[1] =
-{
-  { &nsGkAtoms::result, kNameSpaceID_None, true }
-};
-
-NS_IMPL_NS_NEW_SVG_ELEMENT(FETurbulence)
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFETurbulenceElement,nsSVGFETurbulenceElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFETurbulenceElement,nsSVGFETurbulenceElementBase)
-
-DOMCI_NODE_DATA(SVGFETurbulenceElement, nsSVGFETurbulenceElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGFETurbulenceElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGFETurbulenceElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement,
-                           nsIDOMSVGFilterPrimitiveStandardAttributes,
-                           nsIDOMSVGFETurbulenceElement)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFETurbulenceElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFETurbulenceElementBase)
-
-//----------------------------------------------------------------------
-// nsIDOMNode methods
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFETurbulenceElement)
-
-//----------------------------------------------------------------------
-// nsIDOMSVGFETurbulenceElement methods
-
-/* readonly attribute nsIDOMSVGAnimatedNumber baseFrequencyX; */
-NS_IMETHODIMP nsSVGFETurbulenceElement::GetBaseFrequencyX(nsIDOMSVGAnimatedNumber * *aX)
-{
-  return mNumberPairAttributes[BASE_FREQ].ToDOMAnimatedNumber(aX, nsSVGNumberPair::eFirst, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber baseFrequencyY; */
-NS_IMETHODIMP nsSVGFETurbulenceElement::GetBaseFrequencyY(nsIDOMSVGAnimatedNumber * *aY)
-{
-  return mNumberPairAttributes[BASE_FREQ].ToDOMAnimatedNumber(aY, nsSVGNumberPair::eSecond, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedInteger numOctaves; */
-NS_IMETHODIMP nsSVGFETurbulenceElement::GetNumOctaves(nsIDOMSVGAnimatedInteger * *aNum)
-{
-  return mIntegerAttributes[OCTAVES].ToDOMAnimatedInteger(aNum, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber seed; */
-NS_IMETHODIMP nsSVGFETurbulenceElement::GetSeed(nsIDOMSVGAnimatedNumber * *aSeed)
-{
-  return mNumberAttributes[SEED].ToDOMAnimatedNumber(aSeed, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedEnumeration stitchTiles; */
-NS_IMETHODIMP nsSVGFETurbulenceElement::GetStitchTiles(nsIDOMSVGAnimatedEnumeration * *aStitch)
-{
-  return mEnumAttributes[STITCHTILES].ToDOMAnimatedEnum(aStitch, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedEnumeration type; */
-NS_IMETHODIMP nsSVGFETurbulenceElement::GetType(nsIDOMSVGAnimatedEnumeration * *aType)
-{
-  return mEnumAttributes[TYPE].ToDOMAnimatedEnum(aType, this);
-}
-
-nsresult
-nsSVGFETurbulenceElement::Filter(nsSVGFilterInstance *instance,
-                                 const nsTArray<const Image*>& aSources,
-                                 const Image* aTarget,
-                                 const nsIntRect& rect)
-{
-  uint8_t* targetData = aTarget->mImage->Data();
-  uint32_t stride = aTarget->mImage->Stride();
-
-  nsIntRect filterSubregion(int32_t(aTarget->mFilterPrimitiveSubregion.X()),
-                            int32_t(aTarget->mFilterPrimitiveSubregion.Y()),
-                            int32_t(aTarget->mFilterPrimitiveSubregion.Width()),
-                            int32_t(aTarget->mFilterPrimitiveSubregion.Height()));
-
-  float fX = mNumberPairAttributes[BASE_FREQ].GetAnimValue(nsSVGNumberPair::eFirst);
-  float fY = mNumberPairAttributes[BASE_FREQ].GetAnimValue(nsSVGNumberPair::eSecond);
-  float seed = mNumberAttributes[OCTAVES].GetAnimValue();
-  int32_t octaves = mIntegerAttributes[OCTAVES].GetAnimValue();
-  uint16_t type = mEnumAttributes[TYPE].GetAnimValue();
-  uint16_t stitch = mEnumAttributes[STITCHTILES].GetAnimValue();
-
-  InitSeed((int32_t)seed);
-
-  // XXXroc this makes absolutely no sense to me.
-  float filterX = instance->GetFilterRegion().X();
-  float filterY = instance->GetFilterRegion().Y();
-  float filterWidth = instance->GetFilterRegion().Width();
-  float filterHeight = instance->GetFilterRegion().Height();
-
-  bool doStitch = false;
-  if (stitch == nsIDOMSVGFETurbulenceElement::SVG_STITCHTYPE_STITCH) {
-    doStitch = true;
-
-    float lowFreq, hiFreq;
-
-    lowFreq = floor(filterWidth * fX) / filterWidth;
-    hiFreq = ceil(filterWidth * fX) / filterWidth;
-    if (fX / lowFreq < hiFreq / fX)
-      fX = lowFreq;
-    else
-      fX = hiFreq;
-
-    lowFreq = floor(filterHeight * fY) / filterHeight;
-    hiFreq = ceil(filterHeight * fY) / filterHeight;
-    if (fY / lowFreq < hiFreq / fY)
-      fY = lowFreq;
-    else
-      fY = hiFreq;
-  }
-  for (int32_t y = rect.y; y < rect.YMost(); y++) {
-    for (int32_t x = rect.x; x < rect.XMost(); x++) {
-      int32_t targIndex = y * stride + x * 4;
-      double point[2];
-      point[0] = filterX + (filterWidth * (x + instance->GetSurfaceRect().x)) / (filterSubregion.width - 1);
-      point[1] = filterY + (filterHeight * (y + instance->GetSurfaceRect().y)) / (filterSubregion.height - 1);
-
-      float col[4];
-      if (type == nsIDOMSVGFETurbulenceElement::SVG_TURBULENCE_TYPE_TURBULENCE) {
-        for (int i = 0; i < 4; i++)
-          col[i] = Turbulence(i, point, fX, fY, octaves, false,
-                              doStitch, filterX, filterY, filterWidth, filterHeight) * 255;
-      } else {
-        for (int i = 0; i < 4; i++)
-          col[i] = (Turbulence(i, point, fX, fY, octaves, true,
-                               doStitch, filterX, filterY, filterWidth, filterHeight) * 255 + 255) / 2;
-      }
-      for (int i = 0; i < 4; i++) {
-        col[i] = std::min(col[i], 255.f);
-        col[i] = std::max(col[i], 0.f);
-      }
-
-      uint8_t r, g, b, a;
-      a = uint8_t(col[3]);
-      FAST_DIVIDE_BY_255(r, unsigned(col[0]) * a);
-      FAST_DIVIDE_BY_255(g, unsigned(col[1]) * a);
-      FAST_DIVIDE_BY_255(b, unsigned(col[2]) * a);
-
-      targetData[targIndex + GFX_ARGB32_OFFSET_B] = b;
-      targetData[targIndex + GFX_ARGB32_OFFSET_G] = g;
-      targetData[targIndex + GFX_ARGB32_OFFSET_R] = r;
-      targetData[targIndex + GFX_ARGB32_OFFSET_A] = a;
-    }
-  }
-
-  return NS_OK;
-}
-
-bool
-nsSVGFETurbulenceElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                                    nsIAtom* aAttribute) const
-{
-  return nsSVGFETurbulenceElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
-         (aNameSpaceID == kNameSpaceID_None &&
-          (aAttribute == nsGkAtoms::seed ||
-           aAttribute == nsGkAtoms::baseFrequency ||
-           aAttribute == nsGkAtoms::numOctaves ||
-           aAttribute == nsGkAtoms::type ||
-           aAttribute == nsGkAtoms::stitchTiles));
-}
-
-void
-nsSVGFETurbulenceElement::InitSeed(int32_t aSeed)
-{
-  double s;
-  int i, j, k;
-  aSeed = SetupSeed(aSeed);
-  for (k = 0; k < 4; k++) {
-    for (i = 0; i < sBSize; i++) {
-      mLatticeSelector[i] = i;
-      for (j = 0; j < 2; j++) {
-        mGradient[k][i][j] =
-          (double) (((aSeed =
-                      Random(aSeed)) % (sBSize + sBSize)) - sBSize) / sBSize;
-      }
-      s = double (sqrt
-                  (mGradient[k][i][0] * mGradient[k][i][0] +
-                   mGradient[k][i][1] * mGradient[k][i][1]));
-      mGradient[k][i][0] /= s;
-      mGradient[k][i][1] /= s;
-    }
-  }
-  while (--i) {
-    k = mLatticeSelector[i];
-    mLatticeSelector[i] = mLatticeSelector[j =
-                                           (aSeed =
-                                            Random(aSeed)) % sBSize];
-    mLatticeSelector[j] = k;
-  }
-  for (i = 0; i < sBSize + 2; i++) {
-    mLatticeSelector[sBSize + i] = mLatticeSelector[i];
-    for (k = 0; k < 4; k++)
-      for (j = 0; j < 2; j++)
-        mGradient[k][sBSize + i][j] = mGradient[k][i][j];
-  }
-}
-
-#define S_CURVE(t) ( t * t * (3. - 2. * t) )
-#define LERP(t, a, b) ( a + t * (b - a) )
-double
-nsSVGFETurbulenceElement::Noise2(int aColorChannel, double aVec[2],
-                                 StitchInfo *aStitchInfo)
-{
-  int bx0, bx1, by0, by1, b00, b10, b01, b11;
-  double rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
-  register long i, j;
-  t = aVec[0] + sPerlinN;
-  bx0 = (int) t;
-  bx1 = bx0 + 1;
-  rx0 = t - (int) t;
-  rx1 = rx0 - 1.0f;
-  t = aVec[1] + sPerlinN;
-  by0 = (int) t;
-  by1 = by0 + 1;
-  ry0 = t - (int) t;
-  ry1 = ry0 - 1.0f;
-  // If stitching, adjust lattice points accordingly.
-  if (aStitchInfo != NULL) {
-    if (bx0 >= aStitchInfo->mWrapX)
-      bx0 -= aStitchInfo->mWidth;
-    if (bx1 >= aStitchInfo->mWrapX)
-      bx1 -= aStitchInfo->mWidth;
-    if (by0 >= aStitchInfo->mWrapY)
-      by0 -= aStitchInfo->mHeight;
-    if (by1 >= aStitchInfo->mWrapY)
-      by1 -= aStitchInfo->mHeight;
-  }
-  bx0 &= sBM;
-  bx1 &= sBM;
-  by0 &= sBM;
-  by1 &= sBM;
-  i = mLatticeSelector[bx0];
-  j = mLatticeSelector[bx1];
-  b00 = mLatticeSelector[i + by0];
-  b10 = mLatticeSelector[j + by0];
-  b01 = mLatticeSelector[i + by1];
-  b11 = mLatticeSelector[j + by1];
-  sx = double (S_CURVE(rx0));
-  sy = double (S_CURVE(ry0));
-  q = mGradient[aColorChannel][b00];
-  u = rx0 * q[0] + ry0 * q[1];
-  q = mGradient[aColorChannel][b10];
-  v = rx1 * q[0] + ry0 * q[1];
-  a = LERP(sx, u, v);
-  q = mGradient[aColorChannel][b01];
-  u = rx0 * q[0] + ry1 * q[1];
-  q = mGradient[aColorChannel][b11];
-  v = rx1 * q[0] + ry1 * q[1];
-  b = LERP(sx, u, v);
-  return LERP(sy, a, b);
-}
-#undef S_CURVE
-#undef LERP
-
-double
-nsSVGFETurbulenceElement::Turbulence(int aColorChannel, double *aPoint,
-                                     double aBaseFreqX, double aBaseFreqY,
-                                     int aNumOctaves, bool aFractalSum,
-                                     bool aDoStitching,
-                                     double aTileX, double aTileY,
-                                     double aTileWidth, double aTileHeight)
-{
-  StitchInfo stitch;
-  StitchInfo *stitchInfo = NULL; // Not stitching when NULL.
-  // Adjust the base frequencies if necessary for stitching.
-  if (aDoStitching) {
-    // When stitching tiled turbulence, the frequencies must be adjusted
-    // so that the tile borders will be continuous.
-    if (aBaseFreqX != 0.0) {
-      double loFreq = double (floor(aTileWidth * aBaseFreqX)) / aTileWidth;
-      double hiFreq = double (ceil(aTileWidth * aBaseFreqX)) / aTileWidth;
-      if (aBaseFreqX / loFreq < hiFreq / aBaseFreqX)
-        aBaseFreqX = loFreq;
-      else
-        aBaseFreqX = hiFreq;
-    }
-    if (aBaseFreqY != 0.0) {
-      double loFreq = double (floor(aTileHeight * aBaseFreqY)) / aTileHeight;
-      double hiFreq = double (ceil(aTileHeight * aBaseFreqY)) / aTileHeight;
-      if (aBaseFreqY / loFreq < hiFreq / aBaseFreqY)
-        aBaseFreqY = loFreq;
-      else
-        aBaseFreqY = hiFreq;
-    }
-    // Set up initial stitch values.
-    stitchInfo = &stitch;
-    stitch.mWidth = int (aTileWidth * aBaseFreqX + 0.5f);
-    stitch.mWrapX = int (aTileX * aBaseFreqX + sPerlinN + stitch.mWidth);
-    stitch.mHeight = int (aTileHeight * aBaseFreqY + 0.5f);
-    stitch.mWrapY = int (aTileY * aBaseFreqY + sPerlinN + stitch.mHeight);
-  }
-  double sum = 0.0f;
-  double vec[2];
-  vec[0] = aPoint[0] * aBaseFreqX;
-  vec[1] = aPoint[1] * aBaseFreqY;
-  double ratio = 1;
-  for (int octave = 0; octave < aNumOctaves; octave++) {
-    if (aFractalSum)
-      sum += double (Noise2(aColorChannel, vec, stitchInfo) / ratio);
-    else
-      sum += double (fabs(Noise2(aColorChannel, vec, stitchInfo)) / ratio);
-    vec[0] *= 2;
-    vec[1] *= 2;
-    ratio *= 2;
-    if (stitchInfo != NULL) {
-      // Update stitch values. Subtracting sPerlinN before the multiplication
-      // and adding it afterward simplifies to subtracting it once.
-      stitch.mWidth *= 2;
-      stitch.mWrapX = 2 * stitch.mWrapX - sPerlinN;
-      stitch.mHeight *= 2;
-      stitch.mWrapY = 2 * stitch.mWrapY - sPerlinN;
-    }
-  }
-  return sum;
-}
-
-nsIntRect
-nsSVGFETurbulenceElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-        const nsSVGFilterInstance& aInstance)
-{
-  return GetMaxRect();
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::NumberAttributesInfo
-nsSVGFETurbulenceElement::GetNumberInfo()
-{
-  return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
-                              ArrayLength(sNumberInfo));
-}
-
-nsSVGElement::NumberPairAttributesInfo
-nsSVGFETurbulenceElement::GetNumberPairInfo()
-{
-  return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
-                                 ArrayLength(sNumberPairInfo));
-}
-
-nsSVGElement::IntegerAttributesInfo
-nsSVGFETurbulenceElement::GetIntegerInfo()
-{
-  return IntegerAttributesInfo(mIntegerAttributes, sIntegerInfo,
-                               ArrayLength(sIntegerInfo));
-}
-
-nsSVGElement::EnumAttributesInfo
-nsSVGFETurbulenceElement::GetEnumInfo()
-{
-  return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
-                            ArrayLength(sEnumInfo));
-}
-
-nsSVGElement::StringAttributesInfo
-nsSVGFETurbulenceElement::GetStringInfo()
+SVGFEBlendElement::GetStringInfo()
 {
   return StringAttributesInfo(mStringAttributes, sStringInfo,
                               ArrayLength(sStringInfo));
 }
 
-//---------------------Morphology------------------------
-
-typedef nsSVGFE nsSVGFEMorphologyElementBase;
-
-class nsSVGFEMorphologyElement : public nsSVGFEMorphologyElementBase,
-                                 public nsIDOMSVGFEMorphologyElement
-{
-  friend nsresult NS_NewSVGFEMorphologyElement(nsIContent **aResult,
-                                               already_AddRefed<nsINodeInfo> aNodeInfo);
-protected:
-  nsSVGFEMorphologyElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFEMorphologyElementBase(aNodeInfo) {}
-
-public:
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // FE Base
-  NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFEMorphologyElementBase::)
-
-  virtual nsresult Filter(nsSVGFilterInstance* aInstance,
-                          const nsTArray<const Image*>& aSources,
-                          const Image* aTarget,
-                          const nsIntRect& aDataRect);
-  virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
-  virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
-  virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance);
-  virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-          const nsSVGFilterInstance& aInstance);
-
-  // Morphology
-  NS_DECL_NSIDOMSVGFEMORPHOLOGYELEMENT
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEMorphologyElementBase::)
-
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-  void GetRXY(int32_t *aRX, int32_t *aRY, const nsSVGFilterInstance& aInstance);
-  nsIntRect InflateRect(const nsIntRect& aRect, const nsSVGFilterInstance& aInstance);
-
-  virtual NumberPairAttributesInfo GetNumberPairInfo();
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
-
-  enum { RADIUS };
-  nsSVGNumberPair mNumberPairAttributes[1];
-  static NumberPairInfo sNumberPairInfo[1];
-
-  enum { OPERATOR };
-  nsSVGEnum mEnumAttributes[1];
-  static nsSVGEnumMapping sOperatorMap[];
-  static EnumInfo sEnumInfo[1];
-
-  enum { RESULT, IN1 };
-  nsSVGString mStringAttributes[2];
-  static StringInfo sStringInfo[2];
-};
-
-nsSVGElement::NumberPairInfo nsSVGFEMorphologyElement::sNumberPairInfo[1] =
-{
-  { &nsGkAtoms::radius, 0, 0 }
-};
-
-nsSVGEnumMapping nsSVGFEMorphologyElement::sOperatorMap[] = {
-  {&nsGkAtoms::erode, nsSVGFEMorphologyElement::SVG_OPERATOR_ERODE},
-  {&nsGkAtoms::dilate, nsSVGFEMorphologyElement::SVG_OPERATOR_DILATE},
-  {nullptr, 0}
-};
-
-nsSVGElement::EnumInfo nsSVGFEMorphologyElement::sEnumInfo[1] =
-{
-  { &nsGkAtoms::_operator,
-    sOperatorMap,
-    nsSVGFEMorphologyElement::SVG_OPERATOR_ERODE
-  }
-};
-
-nsSVGElement::StringInfo nsSVGFEMorphologyElement::sStringInfo[2] =
-{
-  { &nsGkAtoms::result, kNameSpaceID_None, true },
-  { &nsGkAtoms::in, kNameSpaceID_None, true }
-};
-
-NS_IMPL_NS_NEW_SVG_ELEMENT(FEMorphology)
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFEMorphologyElement,nsSVGFEMorphologyElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFEMorphologyElement,nsSVGFEMorphologyElementBase)
-
-DOMCI_NODE_DATA(SVGFEMorphologyElement, nsSVGFEMorphologyElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGFEMorphologyElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGFEMorphologyElement, nsIDOMNode, nsIDOMElement,
-                           nsIDOMSVGElement,
-                           nsIDOMSVGFilterPrimitiveStandardAttributes,
-                           nsIDOMSVGFEMorphologyElement)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEMorphologyElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFEMorphologyElementBase)
-
-//----------------------------------------------------------------------
-// nsIDOMNode methods
-
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFEMorphologyElement)
-
-
-//----------------------------------------------------------------------
-// nsSVGFEMorphologyElement methods
-
-/* readonly attribute nsIDOMSVGAnimatedString in1; */
-NS_IMETHODIMP nsSVGFEMorphologyElement::GetIn1(nsIDOMSVGAnimatedString * *aIn)
-{
-  return mStringAttributes[IN1].ToDOMAnimatedString(aIn, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedEnumeration operator; */
-NS_IMETHODIMP nsSVGFEMorphologyElement::GetOperator(nsIDOMSVGAnimatedEnumeration * *aOperator)
-{
-  return mEnumAttributes[OPERATOR].ToDOMAnimatedEnum(aOperator, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber radiusX; */
-NS_IMETHODIMP nsSVGFEMorphologyElement::GetRadiusX(nsIDOMSVGAnimatedNumber * *aX)
-{
-  return mNumberPairAttributes[RADIUS].ToDOMAnimatedNumber(aX, nsSVGNumberPair::eFirst, this);
-}
-
-/* readonly attribute nsIDOMSVGAnimatedNumber radiusY; */
-NS_IMETHODIMP nsSVGFEMorphologyElement::GetRadiusY(nsIDOMSVGAnimatedNumber * *aY)
-{
-  return mNumberPairAttributes[RADIUS].ToDOMAnimatedNumber(aY, nsSVGNumberPair::eSecond, this);
-}
-
-NS_IMETHODIMP
-nsSVGFEMorphologyElement::SetRadius(float rx, float ry)
-{
-  NS_ENSURE_FINITE2(rx, ry, NS_ERROR_ILLEGAL_VALUE);
-  mNumberPairAttributes[RADIUS].SetBaseValues(rx, ry, this);
-  return NS_OK;
-}
-
-void
-nsSVGFEMorphologyElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
-{
-  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
-}
-
-nsIntRect
-nsSVGFEMorphologyElement::InflateRect(const nsIntRect& aRect,
-                                      const nsSVGFilterInstance& aInstance)
-{
-  int32_t rx, ry;
-  GetRXY(&rx, &ry, aInstance);
-  nsIntRect result = aRect;
-  result.Inflate(std::max(0, rx), std::max(0, ry));
-  return result;
-}
-
-nsIntRect
-nsSVGFEMorphologyElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-        const nsSVGFilterInstance& aInstance)
-{
-  return InflateRect(aSourceBBoxes[0], aInstance);
-}
-
-void
-nsSVGFEMorphologyElement::ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance)
-{
-  aSourceBBoxes[0] = InflateRect(aTargetBBox, aInstance);
-}
-
-nsIntRect
-nsSVGFEMorphologyElement::ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-                                            const nsSVGFilterInstance& aInstance)
-{
-  return InflateRect(aSourceChangeBoxes[0], aInstance);
-}
-
-#define MORPHOLOGY_EPSILON 0.0001
-
-void
-nsSVGFEMorphologyElement::GetRXY(int32_t *aRX, int32_t *aRY,
-                                 const nsSVGFilterInstance& aInstance)
-{
-  // Subtract an epsilon here because we don't want a value that's just
-  // slightly larger than an integer to round up to the next integer; it's
-  // probably meant to be the integer it's close to, modulo machine precision
-  // issues.
-  *aRX = NSToIntCeil(aInstance.GetPrimitiveNumber(SVGContentUtils::X,
-                                                  &mNumberPairAttributes[RADIUS],
-                                                  nsSVGNumberPair::eFirst) -
-                     MORPHOLOGY_EPSILON);
-  *aRY = NSToIntCeil(aInstance.GetPrimitiveNumber(SVGContentUtils::Y,
-                                                  &mNumberPairAttributes[RADIUS],
-                                                  nsSVGNumberPair::eSecond) -
-                     MORPHOLOGY_EPSILON);
-}
-
-nsresult
-nsSVGFEMorphologyElement::Filter(nsSVGFilterInstance *instance,
-                                 const nsTArray<const Image*>& aSources,
-                                 const Image* aTarget,
-                                 const nsIntRect& rect)
-{
-  int32_t rx, ry;
-  GetRXY(&rx, &ry, *instance);
-
-  if (rx < 0 || ry < 0) {
-    // XXX SVGContentUtils::ReportToConsole()
-    return NS_OK;
-  }
-  if (rx == 0 && ry == 0) {
-    return NS_OK;
-  }
-
-  // Clamp radii to prevent completely insane values:
-  rx = std::min(rx, 100000);
-  ry = std::min(ry, 100000);
-
-  uint8_t* sourceData = aSources[0]->mImage->Data();
-  uint8_t* targetData = aTarget->mImage->Data();
-  int32_t stride = aTarget->mImage->Stride();
-  uint8_t extrema[4];         // RGBA magnitude of extrema
-  uint16_t op = mEnumAttributes[OPERATOR].GetAnimValue();
-
-  // Scan the kernel for each pixel to determine max/min RGBA values.
-  for (int32_t y = rect.y; y < rect.YMost(); y++) {
-    int32_t startY = std::max(0, y - ry);
-    // We need to read pixels not just in 'rect', which is limited to
-    // the dirty part of our filter primitive subregion, but all pixels in
-    // the given radii from the source surface, so use the surface size here.
-    int32_t endY = std::min(y + ry, instance->GetSurfaceHeight() - 1);
-    for (int32_t x = rect.x; x < rect.XMost(); x++) {
-      int32_t startX = std::max(0, x - rx);
-      int32_t endX = std::min(x + rx, instance->GetSurfaceWidth() - 1);
-      int32_t targIndex = y * stride + 4 * x;
-
-      for (int32_t i = 0; i < 4; i++) {
-        extrema[i] = sourceData[targIndex + i];
-      }
-      for (int32_t y1 = startY; y1 <= endY; y1++) {
-        for (int32_t x1 = startX; x1 <= endX; x1++) {
-          for (int32_t i = 0; i < 4; i++) {
-            uint8_t pixel = sourceData[y1 * stride + 4 * x1 + i];
-            if ((extrema[i] > pixel &&
-                 op == nsSVGFEMorphologyElement::SVG_OPERATOR_ERODE) ||
-                (extrema[i] < pixel &&
-                 op == nsSVGFEMorphologyElement::SVG_OPERATOR_DILATE)) {
-              extrema[i] = pixel;
-            }
-          }
-        }
-      }
-      targetData[targIndex  ] = extrema[0];
-      targetData[targIndex+1] = extrema[1];
-      targetData[targIndex+2] = extrema[2];
-      targetData[targIndex+3] = extrema[3];
-    }
-  }
-  return NS_OK;
-}
-
-bool
-nsSVGFEMorphologyElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                                    nsIAtom* aAttribute) const
-{
-  return nsSVGFEMorphologyElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
-         (aNameSpaceID == kNameSpaceID_None &&
-          (aAttribute == nsGkAtoms::in ||
-           aAttribute == nsGkAtoms::radius ||
-           aAttribute == nsGkAtoms::_operator));
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::NumberPairAttributesInfo
-nsSVGFEMorphologyElement::GetNumberPairInfo()
-{
-  return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
-                                  ArrayLength(sNumberPairInfo));
-}
-
-nsSVGElement::EnumAttributesInfo
-nsSVGFEMorphologyElement::GetEnumInfo()
-{
-  return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
-                            ArrayLength(sEnumInfo));
-}
-
-nsSVGElement::StringAttributesInfo
-nsSVGFEMorphologyElement::GetStringInfo()
-{
-  return StringAttributesInfo(mStringAttributes, sStringInfo,
-                              ArrayLength(sStringInfo));
-}
-
-//---------------------Convolve Matrix------------------------
-
-typedef nsSVGFE nsSVGFEConvolveMatrixElementBase;
-
-class nsSVGFEConvolveMatrixElement : public nsSVGFEConvolveMatrixElementBase,
-                                     public nsIDOMSVGFEConvolveMatrixElement
-{
-  friend nsresult NS_NewSVGFEConvolveMatrixElement(nsIContent **aResult,
-                                                   already_AddRefed<nsINodeInfo> aNodeInfo);
-protected:
-  nsSVGFEConvolveMatrixElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFEConvolveMatrixElementBase(aNodeInfo) {}
-
-public:
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // FE Base
-  NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFEConvolveMatrixElementBase::)
-
-  virtual nsresult Filter(nsSVGFilterInstance* aInstance,
-                          const nsTArray<const Image*>& aSources,
-                          const Image* aTarget,
-                          const nsIntRect& aDataRect);
-  virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
-  virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
-  virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance);
-  virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-          const nsSVGFilterInstance& aInstance);
-
-  // Color Matrix
-  NS_DECL_NSIDOMSVGFECONVOLVEMATRIXELEMENT
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEConvolveMatrixElementBase::)
-
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-  virtual bool OperatesOnPremultipledAlpha(int32_t) {
-    return !mBooleanAttributes[PRESERVEALPHA].GetAnimValue();
-  }
-
-  virtual NumberAttributesInfo GetNumberInfo();
-  virtual NumberPairAttributesInfo GetNumberPairInfo();
-  virtual IntegerAttributesInfo GetIntegerInfo();
-  virtual IntegerPairAttributesInfo GetIntegerPairInfo();
-  virtual BooleanAttributesInfo GetBooleanInfo();
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
-  virtual NumberListAttributesInfo GetNumberListInfo();
-
-  enum { DIVISOR, BIAS };
-  nsSVGNumber2 mNumberAttributes[2];
-  static NumberInfo sNumberInfo[2];
-
-  enum { KERNEL_UNIT_LENGTH };
-  nsSVGNumberPair mNumberPairAttributes[1];
-  static NumberPairInfo sNumberPairInfo[1];
-
-  enum { TARGET_X, TARGET_Y };
-  nsSVGInteger mIntegerAttributes[2];
-  static IntegerInfo sIntegerInfo[2];
-
-  enum { ORDER };
-  nsSVGIntegerPair mIntegerPairAttributes[1];
-  static IntegerPairInfo sIntegerPairInfo[1];
-
-  enum { PRESERVEALPHA };
-  nsSVGBoolean mBooleanAttributes[1];
-  static BooleanInfo sBooleanInfo[1];
-
-  enum { EDGEMODE };
-  nsSVGEnum mEnumAttributes[1];
-  static nsSVGEnumMapping sEdgeModeMap[];
-  static EnumInfo sEnumInfo[1];
-
-  enum { RESULT, IN1 };
-  nsSVGString mStringAttributes[2];
-  static StringInfo sStringInfo[2];
-
-  enum { KERNELMATRIX };
-  SVGAnimatedNumberList mNumberListAttributes[1];
-  static NumberListInfo sNumberListInfo[1];
-};
-
-nsSVGElement::NumberInfo nsSVGFEConvolveMatrixElement::sNumberInfo[2] =
-{
-  { &nsGkAtoms::divisor, 1, false },
-  { &nsGkAtoms::bias, 0, false }
-};
-
-nsSVGElement::NumberPairInfo nsSVGFEConvolveMatrixElement::sNumberPairInfo[1] =
-{
-  { &nsGkAtoms::kernelUnitLength, 0, 0 }
-};
-
-nsSVGElement::IntegerInfo nsSVGFEConvolveMatrixElement::sIntegerInfo[2] =
-{
-  { &nsGkAtoms::targetX, 0 },
-  { &nsGkAtoms::targetY, 0 }
-};
-
-nsSVGElement::IntegerPairInfo nsSVGFEConvolveMatrixElement::sIntegerPairInfo[1] =
-{
-  { &nsGkAtoms::order, 3, 3 }
-};
-
-nsSVGElement::BooleanInfo nsSVGFEConvolveMatrixElement::sBooleanInfo[1] =
-{
-  { &nsGkAtoms::preserveAlpha, false }
-};
-
-nsSVGEnumMapping nsSVGFEConvolveMatrixElement::sEdgeModeMap[] = {
-  {&nsGkAtoms::duplicate, nsSVGFEConvolveMatrixElement::SVG_EDGEMODE_DUPLICATE},
-  {&nsGkAtoms::wrap, nsSVGFEConvolveMatrixElement::SVG_EDGEMODE_WRAP},
-  {&nsGkAtoms::none, nsSVGFEConvolveMatrixElement::SVG_EDGEMODE_NONE},
-  {nullptr, 0}
-};
-
-nsSVGElement::EnumInfo nsSVGFEConvolveMatrixElement::sEnumInfo[1] =
-{
-  { &nsGkAtoms::edgeMode,
-    sEdgeModeMap,
-    nsSVGFEConvolveMatrixElement::SVG_EDGEMODE_DUPLICATE
-  }
-};
-
-nsSVGElement::StringInfo nsSVGFEConvolveMatrixElement::sStringInfo[2] =
-{
-  { &nsGkAtoms::result, kNameSpaceID_None, true },
-  { &nsGkAtoms::in, kNameSpaceID_None, true }
-};
-
-nsSVGElement::NumberListInfo nsSVGFEConvolveMatrixElement::sNumberListInfo[1] =
-{
-  { &nsGkAtoms::kernelMatrix }
-};
-
-NS_IMPL_NS_NEW_SVG_ELEMENT(FEConvolveMatrix)
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFEConvolveMatrixElement,nsSVGFEConvolveMatrixElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFEConvolveMatrixElement,nsSVGFEConvolveMatrixElementBase)
-
-DOMCI_NODE_DATA(SVGFEConvolveMatrixElement, nsSVGFEConvolveMatrixElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGFEConvolveMatrixElement)
-  NS_NODE_INTERFACE_TABLE5(nsSVGFEConvolveMatrixElement, nsIDOMNode,
-                           nsIDOMElement, nsIDOMSVGElement,
-                           nsIDOMSVGFilterPrimitiveStandardAttributes,
-                           nsIDOMSVGFEConvolveMatrixElement)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEConvolveMatrixElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFEConvolveMatrixElementBase)
-
-
-//----------------------------------------------------------------------
-// nsIDOMNode methods
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFEConvolveMatrixElement)
-
-//----------------------------------------------------------------------
-// nsSVGFEConvolveMatrixElement methods
-
-NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetIn1(nsIDOMSVGAnimatedString * *aIn)
-{
-  return mStringAttributes[IN1].ToDOMAnimatedString(aIn, this);
-}
-
-NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetOrderX(nsIDOMSVGAnimatedInteger * *aOrderX)
-{
-  return mIntegerPairAttributes[ORDER].ToDOMAnimatedInteger(aOrderX, nsSVGIntegerPair::eFirst, this);
-}
-
-NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetOrderY(nsIDOMSVGAnimatedInteger * *aOrderY)
-{
-  return mIntegerPairAttributes[ORDER].ToDOMAnimatedInteger(aOrderY, nsSVGIntegerPair::eSecond, this);
-}
-
-NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetKernelMatrix(nsISupports * *aKernelMatrix)
-{
-  *aKernelMatrix = DOMSVGAnimatedNumberList::GetDOMWrapper(&mNumberListAttributes[KERNELMATRIX],
-                                                           this, KERNELMATRIX).get();
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetTargetX(nsIDOMSVGAnimatedInteger * *aTargetX)
-{
-  return mIntegerAttributes[TARGET_X].ToDOMAnimatedInteger(aTargetX, this);
-}
-
-NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetTargetY(nsIDOMSVGAnimatedInteger * *aTargetY)
-{
-  return mIntegerAttributes[TARGET_Y].ToDOMAnimatedInteger(aTargetY, this);
-}
-
-NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetEdgeMode(nsIDOMSVGAnimatedEnumeration * *aEdgeMode)
-{
-  return mEnumAttributes[EDGEMODE].ToDOMAnimatedEnum(aEdgeMode, this);
-}
-
-NS_IMETHODIMP nsSVGFEConvolveMatrixElement::GetPreserveAlpha(nsISupports * *aPreserveAlpha)
-{
-  return mBooleanAttributes[PRESERVEALPHA].ToDOMAnimatedBoolean(aPreserveAlpha, this);
-}
-
-NS_IMETHODIMP
-nsSVGFEConvolveMatrixElement::GetDivisor(nsIDOMSVGAnimatedNumber **aDivisor)
-{
-  return mNumberAttributes[DIVISOR].ToDOMAnimatedNumber(aDivisor, this);
-}
-
-NS_IMETHODIMP
-nsSVGFEConvolveMatrixElement::GetBias(nsIDOMSVGAnimatedNumber **aBias)
-{
-  return mNumberAttributes[BIAS].ToDOMAnimatedNumber(aBias, this);
-}
-
-NS_IMETHODIMP
-nsSVGFEConvolveMatrixElement::GetKernelUnitLengthX(nsIDOMSVGAnimatedNumber **aKernelX)
-{
-  return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(aKernelX,
-                                                                       nsSVGNumberPair::eFirst,
-                                                                       this);
-}
-
-NS_IMETHODIMP
-nsSVGFEConvolveMatrixElement::GetKernelUnitLengthY(nsIDOMSVGAnimatedNumber **aKernelY)
-{
-  return mNumberPairAttributes[KERNEL_UNIT_LENGTH].ToDOMAnimatedNumber(aKernelY,
-                                                                       nsSVGNumberPair::eSecond,
-                                                                       this);
-}
-
-void
-nsSVGFEConvolveMatrixElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
-{
-  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
-}
-
-nsIntRect
-nsSVGFEConvolveMatrixElement::ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-        const nsSVGFilterInstance& aInstance)
-{
-  // XXX A more precise box is possible when 'bias' is zero and 'edgeMode' is
-  // 'none', but it requires analysis of 'kernelUnitLength', 'order' and
-  // 'targetX/Y', so it's quite a lot of work. Don't do it for now.
-  return GetMaxRect();
-}
-
-void
-nsSVGFEConvolveMatrixElement::ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance)
-{
-  // XXX Precise results are possible but we're going to skip that work
-  // for now. Do nothing, which means the needed-box remains the
-  // source's output bounding box.
-}
-
-nsIntRect
-nsSVGFEConvolveMatrixElement::ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-                                                const nsSVGFilterInstance& aInstance)
-{
-  // XXX Precise results are possible but we're going to skip that work
-  // for now.
-  return GetMaxRect();
-}
-
-static int32_t BoundInterval(int32_t aVal, int32_t aMax)
-{
-  aVal = std::max(aVal, 0);
-  return std::min(aVal, aMax - 1);
-}
-
-static void
-ConvolvePixel(const uint8_t *aSourceData,
-              uint8_t *aTargetData,
-              int32_t aWidth, int32_t aHeight,
-              int32_t aStride,
-              int32_t aX, int32_t aY,
-              uint16_t aEdgeMode,
-              const float *aKernel,
-              float aDivisor, float aBias,
-              bool aPreserveAlpha,
-              int32_t aOrderX, int32_t aOrderY,
-              int32_t aTargetX, int32_t aTargetY)
-{
-  float sum[4] = {0, 0, 0, 0};
-  aBias *= 255;
-  int32_t offsets[4] = {GFX_ARGB32_OFFSET_R,
-                        GFX_ARGB32_OFFSET_G,
-                        GFX_ARGB32_OFFSET_B,
-                        GFX_ARGB32_OFFSET_A } ;
-  int32_t channels = aPreserveAlpha ? 3 : 4;
-
-  for (int32_t y = 0; y < aOrderY; y++) {
-    int32_t sampleY = aY + y - aTargetY;
-    bool overscanY = sampleY < 0 || sampleY >= aHeight;
-    for (int32_t x = 0; x < aOrderX; x++) {
-      int32_t sampleX = aX + x - aTargetX;
-      bool overscanX = sampleX < 0 || sampleX >= aWidth;
-      for (int32_t i = 0; i < channels; i++) {
-        if (overscanY || overscanX) {
-          switch (aEdgeMode) {
-            case nsSVGFEConvolveMatrixElement::SVG_EDGEMODE_DUPLICATE:
-              sum[i] +=
-                aSourceData[BoundInterval(sampleY, aHeight) * aStride +
-                            BoundInterval(sampleX, aWidth) * 4 + offsets[i]] *
-                aKernel[aOrderX * y + x];
-              break;
-            case nsSVGFEConvolveMatrixElement::SVG_EDGEMODE_WRAP:
-              sum[i] +=
-                aSourceData[WrapInterval(sampleY, aHeight) * aStride +
-                            WrapInterval(sampleX, aWidth) * 4 + offsets[i]] *
-                aKernel[aOrderX * y + x];
-              break;
-            default:
-              break;
-          }
-        } else {
-          sum[i] +=
-            aSourceData[sampleY * aStride + 4 * sampleX + offsets[i]] *
-            aKernel[aOrderX * y + x];
-        }
-      }
-    }
-  }
-  for (int32_t i = 0; i < channels; i++) {
-    aTargetData[aY * aStride + 4 * aX + offsets[i]] =
-      BoundInterval(static_cast<int32_t>(sum[i] / aDivisor + aBias), 256);
-  }
-  if (aPreserveAlpha) {
-    aTargetData[aY * aStride + 4 * aX + GFX_ARGB32_OFFSET_A] =
-      aSourceData[aY * aStride + 4 * aX + GFX_ARGB32_OFFSET_A];
-  }
-}
-
-nsresult
-nsSVGFEConvolveMatrixElement::Filter(nsSVGFilterInstance *instance,
-                                     const nsTArray<const Image*>& aSources,
-                                     const Image* aTarget,
-                                     const nsIntRect& rect)
-{
-  const SVGNumberList &kernelMatrix =
-    mNumberListAttributes[KERNELMATRIX].GetAnimValue();
-  uint32_t kmLength = kernelMatrix.Length();
-
-  int32_t orderX = mIntegerPairAttributes[ORDER].GetAnimValue(nsSVGIntegerPair::eFirst);
-  int32_t orderY = mIntegerPairAttributes[ORDER].GetAnimValue(nsSVGIntegerPair::eSecond);
-
-  if (orderX <= 0 || orderY <= 0 ||
-      static_cast<uint32_t>(orderX * orderY) != kmLength) {
-    return NS_ERROR_FAILURE;
-  }
-
-  int32_t targetX, targetY;
-  GetAnimatedIntegerValues(&targetX, &targetY, nullptr);
-
-  if (mIntegerAttributes[TARGET_X].IsExplicitlySet()) {
-    if (targetX < 0 || targetX >= orderX)
-      return NS_ERROR_FAILURE;
-  } else {
-    targetX = orderX / 2;
-  }
-  if (mIntegerAttributes[TARGET_Y].IsExplicitlySet()) {
-    if (targetY < 0 || targetY >= orderY)
-      return NS_ERROR_FAILURE;
-  } else {
-    targetY = orderY / 2;
-  }
-
-  if (orderX > NS_SVG_OFFSCREEN_MAX_DIMENSION ||
-      orderY > NS_SVG_OFFSCREEN_MAX_DIMENSION)
-    return NS_ERROR_FAILURE;
-  nsAutoArrayPtr<float> kernel(new float[orderX * orderY]);
-  if (!kernel)
-    return NS_ERROR_FAILURE;
-  for (uint32_t i = 0; i < kmLength; i++) {
-    kernel[kmLength - 1 - i] = kernelMatrix[i];
-  }
-
-  float divisor;
-  if (mNumberAttributes[DIVISOR].IsExplicitlySet()) {
-    divisor = mNumberAttributes[DIVISOR].GetAnimValue();
-    if (divisor == 0)
-      return NS_ERROR_FAILURE;
-  } else {
-    divisor = kernel[0];
-    for (uint32_t i = 1; i < kmLength; i++)
-      divisor += kernel[i];
-    if (divisor == 0)
-      divisor = 1;
-  }
-
-  ScaleInfo info = SetupScalingFilter(instance, aSources[0], aTarget, rect,
-                                      &mNumberPairAttributes[KERNEL_UNIT_LENGTH]);
-  if (!info.mTarget)
-    return NS_ERROR_FAILURE;
-
-  uint16_t edgeMode = mEnumAttributes[EDGEMODE].GetAnimValue();
-  bool preserveAlpha = mBooleanAttributes[PRESERVEALPHA].GetAnimValue();
-
-  float bias = mNumberAttributes[BIAS].GetAnimValue();
-
-  const nsIntRect& dataRect = info.mDataRect;
-  int32_t stride = info.mSource->Stride();
-  int32_t width = info.mSource->GetSize().width;
-  int32_t height = info.mSource->GetSize().height;
-  uint8_t *sourceData = info.mSource->Data();
-  uint8_t *targetData = info.mTarget->Data();
-
-  for (int32_t y = dataRect.y; y < dataRect.YMost(); y++) {
-    for (int32_t x = dataRect.x; x < dataRect.XMost(); x++) {
-      ConvolvePixel(sourceData, targetData,
-                    width, height, stride,
-                    x, y,
-                    edgeMode, kernel, divisor, bias, preserveAlpha,
-                    orderX, orderY, targetX, targetY);
-    }
-  }
-
-  FinishScalingFilter(&info);
-
-  return NS_OK;
-}
-
-bool
-nsSVGFEConvolveMatrixElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                                        nsIAtom* aAttribute) const
-{
-  return nsSVGFEConvolveMatrixElementBase::AttributeAffectsRendering(aNameSpaceID, aAttribute) ||
-         (aNameSpaceID == kNameSpaceID_None &&
-          (aAttribute == nsGkAtoms::in ||
-           aAttribute == nsGkAtoms::divisor ||
-           aAttribute == nsGkAtoms::bias ||
-           aAttribute == nsGkAtoms::kernelUnitLength ||
-           aAttribute == nsGkAtoms::targetX ||
-           aAttribute == nsGkAtoms::targetY ||
-           aAttribute == nsGkAtoms::order ||
-           aAttribute == nsGkAtoms::preserveAlpha||
-           aAttribute == nsGkAtoms::edgeMode ||
-           aAttribute == nsGkAtoms::kernelMatrix));
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::NumberAttributesInfo
-nsSVGFEConvolveMatrixElement::GetNumberInfo()
-{
-  return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
-                              ArrayLength(sNumberInfo));
-}
-
-nsSVGElement::NumberPairAttributesInfo
-nsSVGFEConvolveMatrixElement::GetNumberPairInfo()
-{
-  return NumberPairAttributesInfo(mNumberPairAttributes, sNumberPairInfo,
-                                  ArrayLength(sNumberPairInfo));
-}
-
-nsSVGElement::IntegerAttributesInfo
-nsSVGFEConvolveMatrixElement::GetIntegerInfo()
-{
-  return IntegerAttributesInfo(mIntegerAttributes, sIntegerInfo,
-                               ArrayLength(sIntegerInfo));
-}
-
-nsSVGElement::IntegerPairAttributesInfo
-nsSVGFEConvolveMatrixElement::GetIntegerPairInfo()
-{
-  return IntegerPairAttributesInfo(mIntegerPairAttributes, sIntegerPairInfo,
-                                   ArrayLength(sIntegerPairInfo));
-}
-
-nsSVGElement::BooleanAttributesInfo
-nsSVGFEConvolveMatrixElement::GetBooleanInfo()
-{
-  return BooleanAttributesInfo(mBooleanAttributes, sBooleanInfo,
-                               ArrayLength(sBooleanInfo));
-}
-
-nsSVGElement::EnumAttributesInfo
-nsSVGFEConvolveMatrixElement::GetEnumInfo()
-{
-  return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
-                            ArrayLength(sEnumInfo));
-}
-
-nsSVGElement::StringAttributesInfo
-nsSVGFEConvolveMatrixElement::GetStringInfo()
-{
-  return StringAttributesInfo(mStringAttributes, sStringInfo,
-                              ArrayLength(sStringInfo));
-}
-
-nsSVGElement::NumberListAttributesInfo
-nsSVGFEConvolveMatrixElement::GetNumberListInfo()
-{
-  return NumberListAttributesInfo(mNumberListAttributes, sNumberListInfo,
-                                  ArrayLength(sNumberListInfo));
-}
-
-//---------------------DistantLight------------------------
-
-typedef SVGFEUnstyledElement nsSVGFEDistantLightElementBase;
-
-class nsSVGFEDistantLightElement : public nsSVGFEDistantLightElementBase,
-                                   public nsIDOMSVGFEDistantLightElement
-{
-  friend nsresult NS_NewSVGFEDistantLightElement(nsIContent **aResult,
-                                                 already_AddRefed<nsINodeInfo> aNodeInfo);
-protected:
-  nsSVGFEDistantLightElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFEDistantLightElementBase(aNodeInfo) {}
-
-public:
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIDOMSVGFEDISTANTLIGHTELEMENT
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEDistantLightElementBase::)
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-  virtual NumberAttributesInfo GetNumberInfo();
-
-  enum { AZIMUTH, ELEVATION };
-  nsSVGNumber2 mNumberAttributes[2];
-  static NumberInfo sNumberInfo[2];
-};
-
-NS_IMPL_NS_NEW_SVG_ELEMENT(FEDistantLight)
-
-nsSVGElement::NumberInfo nsSVGFEDistantLightElement::sNumberInfo[2] =
-{
-  { &nsGkAtoms::azimuth,   0, false },
-  { &nsGkAtoms::elevation, 0, false }
-};
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFEDistantLightElement,nsSVGFEDistantLightElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFEDistantLightElement,nsSVGFEDistantLightElementBase)
-
-DOMCI_NODE_DATA(SVGFEDistantLightElement, nsSVGFEDistantLightElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGFEDistantLightElement)
-  NS_NODE_INTERFACE_TABLE4(nsSVGFEDistantLightElement, nsIDOMNode,
-                           nsIDOMElement, nsIDOMSVGElement,
-                           nsIDOMSVGFEDistantLightElement)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEDistantLightElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFEDistantLightElementBase)
-
-//----------------------------------------------------------------------
-// nsIDOMNode methods
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFEDistantLightElement)
-
-//----------------------------------------------------------------------
-// nsFEUnstyledElement methods
-
-bool
-nsSVGFEDistantLightElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                                      nsIAtom* aAttribute) const
-{
-  return aNameSpaceID == kNameSpaceID_None &&
-         (aAttribute == nsGkAtoms::azimuth ||
-          aAttribute == nsGkAtoms::elevation);
-}
-
-//----------------------------------------------------------------------
-// nsIDOMSVGFEDistantLightElement methods
-
-NS_IMETHODIMP
-nsSVGFEDistantLightElement::GetAzimuth(nsIDOMSVGAnimatedNumber **aAzimuth)
-{
-  return mNumberAttributes[AZIMUTH].ToDOMAnimatedNumber(aAzimuth,
-                                                        this);
-}
-
-NS_IMETHODIMP
-nsSVGFEDistantLightElement::GetElevation(nsIDOMSVGAnimatedNumber **aElevation)
-{
-  return mNumberAttributes[ELEVATION].ToDOMAnimatedNumber(aElevation,
-                                                          this);
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::NumberAttributesInfo
-nsSVGFEDistantLightElement::GetNumberInfo()
-{
-  return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
-                              ArrayLength(sNumberInfo));
-}
-
-//---------------------PointLight------------------------
-
-typedef SVGFEUnstyledElement nsSVGFEPointLightElementBase;
-
-class nsSVGFEPointLightElement : public nsSVGFEPointLightElementBase,
-                                 public nsIDOMSVGFEPointLightElement
-{
-  friend nsresult NS_NewSVGFEPointLightElement(nsIContent **aResult,
-                                                 already_AddRefed<nsINodeInfo> aNodeInfo);
-protected:
-  nsSVGFEPointLightElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFEPointLightElementBase(aNodeInfo) {}
-
-public:
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIDOMSVGFEPOINTLIGHTELEMENT
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEPointLightElementBase::)
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-  virtual NumberAttributesInfo GetNumberInfo();
-
-  enum { X, Y, Z };
-  nsSVGNumber2 mNumberAttributes[3];
-  static NumberInfo sNumberInfo[3];
-};
-
-NS_IMPL_NS_NEW_SVG_ELEMENT(FEPointLight)
-
-nsSVGElement::NumberInfo nsSVGFEPointLightElement::sNumberInfo[3] =
-{
-  { &nsGkAtoms::x, 0, false },
-  { &nsGkAtoms::y, 0, false },
-  { &nsGkAtoms::z, 0, false }
-};
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFEPointLightElement,nsSVGFEPointLightElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFEPointLightElement,nsSVGFEPointLightElementBase)
-
-DOMCI_NODE_DATA(SVGFEPointLightElement, nsSVGFEPointLightElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGFEPointLightElement)
-  NS_NODE_INTERFACE_TABLE4(nsSVGFEPointLightElement, nsIDOMNode,
-                           nsIDOMElement, nsIDOMSVGElement,
-                           nsIDOMSVGFEPointLightElement)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEPointLightElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFEPointLightElementBase)
-
-//----------------------------------------------------------------------
-// nsIDOMNode methods
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFEPointLightElement)
-
-//----------------------------------------------------------------------
-// nsFEUnstyledElement methods
-
-bool
-nsSVGFEPointLightElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                                    nsIAtom* aAttribute) const
-{
-  return aNameSpaceID == kNameSpaceID_None &&
-         (aAttribute == nsGkAtoms::x ||
-          aAttribute == nsGkAtoms::y ||
-          aAttribute == nsGkAtoms::z);
-}
-
-//----------------------------------------------------------------------
-// nsIDOMSVGFEPointLightElement methods
-
-NS_IMETHODIMP
-nsSVGFEPointLightElement::GetX(nsIDOMSVGAnimatedNumber **aX)
-{
-  return mNumberAttributes[X].ToDOMAnimatedNumber(aX, this);
-}
-
-NS_IMETHODIMP
-nsSVGFEPointLightElement::GetY(nsIDOMSVGAnimatedNumber **aY)
-{
-  return mNumberAttributes[Y].ToDOMAnimatedNumber(aY, this);
-}
-
-NS_IMETHODIMP
-nsSVGFEPointLightElement::GetZ(nsIDOMSVGAnimatedNumber **aZ)
-{
-  return mNumberAttributes[Z].ToDOMAnimatedNumber(aZ, this);
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::NumberAttributesInfo
-nsSVGFEPointLightElement::GetNumberInfo()
-{
-  return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
-                              ArrayLength(sNumberInfo));
-}
-
-//---------------------SpotLight------------------------
-
-typedef SVGFEUnstyledElement nsSVGFESpotLightElementBase;
-
-class nsSVGFESpotLightElement : public nsSVGFESpotLightElementBase,
-                                public nsIDOMSVGFESpotLightElement
-{
-  friend nsresult NS_NewSVGFESpotLightElement(nsIContent **aResult,
-                                              already_AddRefed<nsINodeInfo> aNodeInfo);
-  friend class nsSVGFELightingElement;
-protected:
-  nsSVGFESpotLightElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFESpotLightElementBase(aNodeInfo) {}
-
-public:
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIDOMSVGFESPOTLIGHTELEMENT
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFESpotLightElementBase::)
-  NS_FORWARD_NSIDOMNODE_TO_NSINODE
-  NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-
-  virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  virtual nsIDOMNode* AsDOMNode() { return this; }
-protected:
-  virtual NumberAttributesInfo GetNumberInfo();
-
-  enum { X, Y, Z, POINTS_AT_X, POINTS_AT_Y, POINTS_AT_Z,
-         SPECULAR_EXPONENT, LIMITING_CONE_ANGLE };
-  nsSVGNumber2 mNumberAttributes[8];
-  static NumberInfo sNumberInfo[8];
-};
-
-NS_IMPL_NS_NEW_SVG_ELEMENT(FESpotLight)
-
-nsSVGElement::NumberInfo nsSVGFESpotLightElement::sNumberInfo[8] =
-{
-  { &nsGkAtoms::x, 0, false },
-  { &nsGkAtoms::y, 0, false },
-  { &nsGkAtoms::z, 0, false },
-  { &nsGkAtoms::pointsAtX, 0, false },
-  { &nsGkAtoms::pointsAtY, 0, false },
-  { &nsGkAtoms::pointsAtZ, 0, false },
-  { &nsGkAtoms::specularExponent, 1, false },
-  { &nsGkAtoms::limitingConeAngle, 0, false }
-};
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFESpotLightElement,nsSVGFESpotLightElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFESpotLightElement,nsSVGFESpotLightElementBase)
-
-DOMCI_NODE_DATA(SVGFESpotLightElement, nsSVGFESpotLightElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGFESpotLightElement)
-  NS_NODE_INTERFACE_TABLE4(nsSVGFESpotLightElement, nsIDOMNode,
-                           nsIDOMElement, nsIDOMSVGElement,
-                           nsIDOMSVGFESpotLightElement)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFESpotLightElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFESpotLightElementBase)
-
-//----------------------------------------------------------------------
-// nsIDOMNode methods
-
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGFESpotLightElement)
-
-//----------------------------------------------------------------------
-// nsFEUnstyledElement methods
-
-bool
-nsSVGFESpotLightElement::AttributeAffectsRendering(int32_t aNameSpaceID,
-                                                   nsIAtom* aAttribute) const
-{
-  return aNameSpaceID == kNameSpaceID_None &&
-         (aAttribute == nsGkAtoms::x ||
-          aAttribute == nsGkAtoms::y ||
-          aAttribute == nsGkAtoms::z ||
-          aAttribute == nsGkAtoms::pointsAtX ||
-          aAttribute == nsGkAtoms::pointsAtY ||
-          aAttribute == nsGkAtoms::pointsAtZ ||
-          aAttribute == nsGkAtoms::specularExponent ||
-          aAttribute == nsGkAtoms::limitingConeAngle);
-}
-
-//----------------------------------------------------------------------
-// nsIDOMSVGFESpotLightElement methods
-
-NS_IMETHODIMP
-nsSVGFESpotLightElement::GetX(nsIDOMSVGAnimatedNumber **aX)
-{
-  return mNumberAttributes[X].ToDOMAnimatedNumber(aX, this);
-}
-
-NS_IMETHODIMP
-nsSVGFESpotLightElement::GetY(nsIDOMSVGAnimatedNumber **aY)
-{
-  return mNumberAttributes[Y].ToDOMAnimatedNumber(aY, this);
-}
-
-NS_IMETHODIMP
-nsSVGFESpotLightElement::GetZ(nsIDOMSVGAnimatedNumber **aZ)
-{
-  return mNumberAttributes[Z].ToDOMAnimatedNumber(aZ, this);
-}
-
-NS_IMETHODIMP
-nsSVGFESpotLightElement::GetPointsAtX(nsIDOMSVGAnimatedNumber **aX)
-{
-  return mNumberAttributes[POINTS_AT_X].ToDOMAnimatedNumber(aX, this);
-}
-
-NS_IMETHODIMP
-nsSVGFESpotLightElement::GetPointsAtY(nsIDOMSVGAnimatedNumber **aY)
-{
-  return mNumberAttributes[POINTS_AT_Y].ToDOMAnimatedNumber(aY, this);
-}
-
-NS_IMETHODIMP
-nsSVGFESpotLightElement::GetPointsAtZ(nsIDOMSVGAnimatedNumber **aZ)
-{
-  return mNumberAttributes[POINTS_AT_Z].ToDOMAnimatedNumber(aZ, this);
-}
-
-NS_IMETHODIMP
-nsSVGFESpotLightElement::GetSpecularExponent(nsIDOMSVGAnimatedNumber **aExponent)
-{
-  return mNumberAttributes[SPECULAR_EXPONENT].ToDOMAnimatedNumber(aExponent,
-                                                                  this);
-}
-
-NS_IMETHODIMP
-nsSVGFESpotLightElement::GetLimitingConeAngle(nsIDOMSVGAnimatedNumber **aAngle)
-{
-  return mNumberAttributes[LIMITING_CONE_ANGLE].ToDOMAnimatedNumber(aAngle,
-                                                                    this);
-}
-
-//----------------------------------------------------------------------
-// nsSVGElement methods
-
-nsSVGElement::NumberAttributesInfo
-nsSVGFESpotLightElement::GetNumberInfo()
-{
-  return NumberAttributesInfo(mNumberAttributes, sNumberInfo,
-                              ArrayLength(sNumberInfo));
-}
-
-//------------------------------------------------------------
-
-typedef nsSVGFE nsSVGFELightingElementBase;
-
-class nsSVGFELightingElement : public nsSVGFELightingElementBase
-{
-protected:
-  nsSVGFELightingElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsSVGFELightingElementBase(aNodeInfo) {}
-
-public:
-  // interfaces:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // FE Base
-  NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFELightingElementBase::)
-
-  virtual nsresult Filter(nsSVGFilterInstance* aInstance,
-                          const nsTArray<const Image*>& aSources,
-                          const Image* aTarget,
-                          const nsIntRect& aDataRect);
-  virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
-  // XXX shouldn't we have ComputeTargetBBox here, since the output can
-  // extend beyond the bounds of the inputs thanks to the convolution kernel?
-  virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance);
-  virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-          const nsSVGFilterInstance& aInstance);
-
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFELightingElementBase::)
-
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
-
-protected:
-  virtual bool OperatesOnSRGB(nsSVGFilterInstance*,
-                              int32_t, Image*) { return true; }
-  virtual void
-  LightPixel(const float *N, const float *L,
-             nscolor color, uint8_t *targetData) = 0;
-
-  virtual NumberAttributesInfo GetNumberInfo();
-  virtual NumberPairAttributesInfo GetNumberPairInfo();
-  virtual StringAttributesInfo GetStringInfo();
-
-  enum { SURFACE_SCALE, DIFFUSE_CONSTANT, SPECULAR_CONSTANT, SPECULAR_EXPONENT };
-  nsSVGNumber2 mNumberAttributes[4];
-  static NumberInfo sNumberInfo[4];
-
-  enum { KERNEL_UNIT_LENGTH };
-  nsSVGNumberPair mNumberPairAttributes[1];
-  static NumberPairInfo sNumberPairInfo[1];
-
-  enum { RESULT, IN1 };
-  nsSVGString mStringAttributes[2];
-  static StringInfo sStringInfo[2];
-};
-
-nsSVGElement::NumberInfo nsSVGFELightingElement::sNumberInfo[4] =
-{
-  { &nsGkAtoms::surfaceScale, 1, false },
-  { &nsGkAtoms::diffuseConstant, 1, false },
-  { &nsGkAtoms::specularConstant, 1, false },
-  { &nsGkAtoms::specularExponent, 1, false }
-};
-
-nsSVGElement::NumberPairInfo nsSVGFELightingElement::sNumberPairInfo[1] =
-{
-  { &nsGkAtoms::kernelUnitLength, 0, 0 }
-};
-
-nsSVGElement::StringInfo nsSVGFELightingElement::sStringInfo[2] =
-{
-  { &nsGkAtoms::result, kNameSpaceID_None, true },
-  { &nsGkAtoms::in, kNameSpaceID_None, true }
-};
-
-//----------------------------------------------------------------------
-// nsISupports methods
-
-NS_IMPL_ADDREF_INHERITED(nsSVGFELightingElement,nsSVGFELightingElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGFELightingElement,nsSVGFELightingElementBase)
-
-NS_INTERFACE_MAP_BEGIN(nsSVGFELightingElement) 
-NS_INTERFACE_MAP_END_INHERITING(nsSVGFELightingElementBase)
-
-//----------------------------------------------------------------------
-// Implementation
-
-NS_IMETHODIMP_(bool)
-nsSVGFELightingElement::IsAttributeMapped(const nsIAtom* name) const
-{
-  static const MappedAttributeEntry* const map[] = {
-    sLightingEffectsMap
-  };
-
-  return FindAttributeDependence(name, map) ||
-    nsSVGFELightingElementBase::IsAttributeMapped(name);
-}
-
-void
-nsSVGFELightingElement::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
-{
-  aSources.AppendElement(nsSVGStringInfo(&mStringAttributes[IN1], this));
-}
-
-void
-nsSVGFELightingElement::ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance)
-{
-  // XXX lighting can depend on more than the target area, because
-  // of the kernels it uses. We could compute something precise here
-  // but just leave it and assume we use the entire source bounding box.
-}
-
-nsIntRect
-nsSVGFELightingElement::ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-                                          const nsSVGFilterInstance& aInstance)
-{
-  // XXX be conservative for now
-  return GetMaxRect();
-}
-
-#define DOT(a,b) (a[0] * b[0] + a[1] * b[1] + a[2] * b[2])
-#define NORMALIZE(vec) \
-  PR_BEGIN_MACRO \
-    float norm = sqrt(DOT(vec, vec)); \
-    vec[0] /= norm; \
-    vec[1] /= norm; \
-    vec[2] /= norm; \
-  PR_END_MACRO
-
-static int32_t
-Convolve3x3(const uint8_t *index, int32_t stride,
-            const int8_t kernel[3][3]
-#ifdef DEBUG
-            , const uint8_t *minData, const uint8_t *maxData
-#endif // DEBUG
-)
-{
-  int32_t sum = 0;
-  for (int32_t y = 0; y < 3; y++) {
-    for (int32_t x = 0; x < 3; x++) {
-      int8_t k = kernel[y][x];
-      if (k) {
-        const uint8_t *valPtr = index + (4 * (x - 1) + stride * (y - 1));
-        NS_ASSERTION(valPtr >= minData, "out of bounds read (before buffer)");
-        NS_ASSERTION(valPtr < maxData,  "out of bounds read (after buffer)");
-        sum += k * (*valPtr);
-      }
-    }
-  }
-  return sum;
-}
-
-static void
-GenerateNormal(float *N, const uint8_t *data, int32_t stride,
-               int32_t surfaceWidth, int32_t surfaceHeight,
-               int32_t x, int32_t y, float surfaceScale)
-{
-  // See this for source of constants:
-  //   http://www.w3.org/TR/SVG11/filters.html#feDiffuseLightingElement
-  static const int8_t Kx[3][3][3][3] =
-    { { { {  0,  0,  0}, { 0, -2,  2}, { 0, -1,  1} },
-        { {  0,  0,  0}, {-2,  0,  2}, {-1,  0,  1} },
-        { {  0,  0,  0}, {-2,  2,  0}, {-1,  1,  0} } },
-      { { {  0, -1,  1}, { 0, -2,  2}, { 0, -1,  1} },
-        { { -1,  0,  1}, {-2,  0,  2}, {-1,  0,  1} },
-        { { -1,  1,  0}, {-2,  2,  0}, {-1,  1,  0} } },
-      { { {  0, -1,  1}, { 0, -2,  2}, { 0,  0,  0} },
-        { { -1,  0,  1}, {-2,  0,  2}, { 0,  0,  0} },
-        { { -1,  1,  0}, {-2,  2,  0}, { 0,  0,  0} } } };
-  static const int8_t Ky[3][3][3][3] =
-    { { { {  0,  0,  0}, { 0, -2, -1}, { 0,  2,  1} },
-        { {  0,  0,  0}, {-1, -2, -1}, { 1,  2,  1} },
-        { {  0,  0,  0}, {-1, -2,  1}, { 1,  2,  0} } },
-      { { {  0, -2, -1}, { 0,  0,  0}, { 0,  2,  1} },
-        { { -1, -2, -1}, { 0,  0,  0}, { 1,  2,  1} },
-        { { -1, -2,  0}, { 0,  0,  0}, { 1,  2,  0} } },
-      { { {  0, -2, -1}, { 0,  2,  1}, { 0,  0,  0} },
-        { { -1, -2, -1}, { 1,  2,  1}, { 0,  0,  0} },
-        { { -1, -2,  0}, { 1,  2,  0}, { 0,  0,  0} } } };
-  static const float FACTORx[3][3] =
-    { { 2.0 / 3.0, 1.0 / 3.0, 2.0 / 3.0 },
-      { 1.0 / 2.0, 1.0 / 4.0, 1.0 / 2.0 },
-      { 2.0 / 3.0, 1.0 / 3.0, 2.0 / 3.0 } };
-  static const float FACTORy[3][3] =
-    { { 2.0 / 3.0, 1.0 / 2.0, 2.0 / 3.0 },
-      { 1.0 / 3.0, 1.0 / 4.0, 1.0 / 3.0 },
-      { 2.0 / 3.0, 1.0 / 2.0, 2.0 / 3.0 } };
-
-  // degenerate cases
-  if (surfaceWidth == 1 || surfaceHeight == 1) {
-    // just return a unit vector pointing towards the viewer
-    N[0] = 0;