Merge the last PGO-green inbound changeset to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 19 Oct 2012 21:43:03 -0400
changeset 110960 ff4af83233dc62a9423bfb0a3042a3c7f3eadd79
parent 110891 15b77c491515ef70abb3a5eb75345364b7d49729 (current diff)
parent 110959 441defeeb6533f18a9eaa3c09ddb5e3747987049 (diff)
child 110986 196860475fa98dc0ffca0e5c593cd07afc0540ac
child 111015 0c34dd4742b6a0581009894955fb739693e6474e
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
milestone19.0a1
Merge the last PGO-green inbound changeset to m-c.
dom/tests/mochitest/chrome/file_bug799299.xul
testing/marionette/client/marionette/marionette.py
testing/marionette/client/marionette/marionette_test.py
toolkit/mozapps/update/nsUpdateService.js
--- a/accessible/src/base/Logging.cpp
+++ b/accessible/src/base/Logging.cpp
@@ -679,17 +679,17 @@ logging::Node(const char* aDescr, nsINod
     return;
   }
 
   if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {
     printf("%s: %p, document\n", aDescr, static_cast<void*>(aNode));
     return;
   }
 
-  nsINode* parentNode = aNode->GetNodeParent();
+  nsINode* parentNode = aNode->GetParentNode();
   int32_t idxInParent = parentNode ? parentNode->IndexOf(aNode) : - 1;
 
   if (aNode->IsNodeOfType(nsINode::eTEXT)) {
     printf("%s: %p, text node, idx in parent: %d\n",
            aDescr, static_cast<void*>(aNode), idxInParent);
     return;
   }
 
--- a/accessible/src/base/NotificationController.cpp
+++ b/accessible/src/base/NotificationController.cpp
@@ -419,18 +419,18 @@ NotificationController::CoalesceEvents()
         }
 
         // Ignore events unattached from DOM since we don't coalesce them.
         if (!thisEvent->mNode->IsInDoc())
           continue;
 
         // Coalesce events by sibling targets (this is a case for reorder
         // events).
-        if (thisEvent->mNode->GetNodeParent() ==
-            tailEvent->mNode->GetNodeParent()) {
+        if (thisEvent->mNode->GetParentNode() ==
+            tailEvent->mNode->GetParentNode()) {
           tailEvent->mEventRule = thisEvent->mEventRule;
           return;
         }
 
         // This and tail events can be anywhere in the tree, make assumptions
         // for mutation events.
 
         // Coalesce tail event if tail node is descendant of this node. Stop
@@ -516,17 +516,17 @@ void
 NotificationController::ApplyToSiblings(uint32_t aStart, uint32_t aEnd,
                                         uint32_t aEventType, nsINode* aNode,
                                         AccEvent::EEventRule aEventRule)
 {
   for (uint32_t index = aStart; index < aEnd; index ++) {
     AccEvent* accEvent = mEvents[index];
     if (accEvent->mEventType == aEventType &&
         accEvent->mEventRule != AccEvent::eDoNotEmit && accEvent->mNode &&
-        accEvent->mNode->GetNodeParent() == aNode->GetNodeParent()) {
+        accEvent->mNode->GetParentNode() == aNode->GetParentNode()) {
       accEvent->mEventRule = aEventRule;
     }
   }
 }
 
 void
 NotificationController::CoalesceSelChangeEvents(AccSelChangeEvent* aTailEvent,
                                                 AccSelChangeEvent* aThisEvent,
@@ -700,17 +700,17 @@ NotificationController::TextEnumerator(n
                                        void* aUserArg)
 {
   DocAccessible* document = static_cast<DocAccessible*>(aUserArg);
   nsIContent* textNode = aEntry->GetKey();
   Accessible* textAcc = document->GetAccessible(textNode);
 
   // If the text node is not in tree or doesn't have frame then this case should
   // have been handled already by content removal notifications.
-  nsINode* containerNode = textNode->GetNodeParent();
+  nsINode* containerNode = textNode->GetParentNode();
   if (!containerNode) {
     NS_ASSERTION(!textAcc,
                  "Text node was removed but accessible is kept alive!");
     return PL_DHASH_NEXT;
   }
 
   nsIFrame* textFrame = textNode->GetPrimaryFrame();
   if (!textFrame) {
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -376,18 +376,19 @@ nsAccUtils::GetScreenCoordsForParent(nsA
   Accessible* parent = document->GetContainerAccessible(aAccessNode->GetNode());
   if (!parent)
     return nsIntPoint(0, 0);
 
   nsIFrame *parentFrame = parent->GetFrame();
   if (!parentFrame)
     return nsIntPoint(0, 0);
 
-  nsIntRect parentRect = parentFrame->GetScreenRectExternal();
-  return nsIntPoint(parentRect.x, parentRect.y);
+  nsRect rect = parentFrame->GetScreenRectInAppUnits();
+  return nsPoint(rect.x, rect.y).
+    ToNearestPixels(parentFrame->PresContext()->AppUnitsPerDevPixel());
 }
 
 uint8_t
 nsAccUtils::GetAttributeCharacteristics(nsIAtom* aAtom)
 {
     for (uint32_t i = 0; i < nsARIAMap::gWAIUnivAttrMapLength; i++)
       if (*nsARIAMap::gWAIUnivAttrMap[i].attributeName == aAtom)
         return nsARIAMap::gWAIUnivAttrMap[i].characteristics;
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -4,16 +4,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCoreUtils.h"
 
 #include "nsIAccessibleTypes.h"
 
 #include "nsAccessNode.h"
 
+#include "nsIBaseWindow.h"
+#include "nsIDocShellTreeOwner.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsRange.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDocShell.h"
@@ -243,17 +245,17 @@ nsCoreUtils::GetRoleContent(nsINode *aNo
 bool
 nsCoreUtils::IsAncestorOf(nsINode *aPossibleAncestorNode,
                           nsINode *aPossibleDescendantNode,
                           nsINode *aRootNode)
 {
   NS_ENSURE_TRUE(aPossibleAncestorNode && aPossibleDescendantNode, false);
 
   nsINode *parentNode = aPossibleDescendantNode;
-  while ((parentNode = parentNode->GetNodeParent()) &&
+  while ((parentNode = parentNode->GetParentNode()) &&
          parentNode != aRootNode) {
     if (parentNode == aPossibleAncestorNode)
       return true;
   }
 
   return false;
 }
 
@@ -298,29 +300,24 @@ nsCoreUtils::ScrollSubstringTo(nsIFrame*
   return NS_OK;
 }
 
 void
 nsCoreUtils::ScrollFrameToPoint(nsIFrame *aScrollableFrame,
                                 nsIFrame *aFrame,
                                 const nsIntPoint& aPoint)
 {
-  nsIScrollableFrame *scrollableFrame = do_QueryFrame(aScrollableFrame);
+  nsIScrollableFrame* scrollableFrame = do_QueryFrame(aScrollableFrame);
   if (!scrollableFrame)
     return;
 
-  nsPresContext *presContext = aFrame->PresContext();
-
-  nsIntRect frameRect = aFrame->GetScreenRectExternal();
-  int32_t devDeltaX = aPoint.x - frameRect.x;
-  int32_t devDeltaY = aPoint.y - frameRect.y;
-
-  nsPoint deltaPoint;
-  deltaPoint.x = presContext->DevPixelsToAppUnits(devDeltaX);
-  deltaPoint.y = presContext->DevPixelsToAppUnits(devDeltaY);
+  nsPoint point =
+    aPoint.ToAppUnits(aFrame->PresContext()->AppUnitsPerDevPixel());
+  nsRect frameRect = aFrame->GetScreenRectInAppUnits();
+  nsPoint deltaPoint(point.x - frameRect.x, point.y - frameRect.y);
 
   nsPoint scrollPoint = scrollableFrame->GetScrollPosition();
   scrollPoint -= deltaPoint;
 
   scrollableFrame->ScrollTo(scrollPoint, nsIScrollableFrame::INSTANT);
 }
 
 void
@@ -381,29 +378,25 @@ nsCoreUtils::ConvertScrollTypeToPercents
 nsIntPoint
 nsCoreUtils::GetScreenCoordsForWindow(nsINode *aNode)
 {
   nsIntPoint coords(0, 0);
   nsCOMPtr<nsIDocShellTreeItem> treeItem(GetDocShellTreeItemFor(aNode));
   if (!treeItem)
     return coords;
 
-  nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
-  treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
-  nsCOMPtr<nsIDOMDocument> domDoc = do_GetInterface(rootTreeItem);
-  if (!domDoc)
+  nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
+  treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
+  if (!treeOwner)
     return coords;
 
-  nsCOMPtr<nsIDOMWindow> window;
-  domDoc->GetDefaultView(getter_AddRefs(window));
-  if (!window)
-    return coords;
+  nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(treeOwner);
+  if (baseWindow)
+    baseWindow->GetPosition(&coords.x, &coords.y); // in device pixels
 
-  window->GetScreenX(&coords.x);
-  window->GetScreenY(&coords.y);
   return coords;
 }
 
 already_AddRefed<nsIDocShellTreeItem>
 nsCoreUtils::GetDocShellTreeItemFor(nsINode *aNode)
 {
   if (!aNode)
     return nullptr;
--- a/accessible/src/base/nsCoreUtils.h
+++ b/accessible/src/base/nsCoreUtils.h
@@ -163,17 +163,18 @@ public:
    * Converts scroll type constant defined in nsIAccessibleScrollType to
    * vertical and horizontal parameters.
    */
   static void ConvertScrollTypeToPercents(uint32_t aScrollType,
                                           nsIPresShell::ScrollAxis *aVertical,
                                           nsIPresShell::ScrollAxis *aHorizontal);
 
   /**
-   * Returns coordinates relative screen for the top level window.
+   * Returns coordinates in device pixels relative screen for the top level
+   * window.
    *
    * @param aNode  the DOM node hosted in the window.
    */
   static nsIntPoint GetScreenCoordsForWindow(nsINode *aNode);
 
   /**
    * Return document shell tree item for the given DOM node.
    */
--- a/accessible/src/generic/DocAccessible.cpp
+++ b/accessible/src/generic/DocAccessible.cpp
@@ -1389,17 +1389,17 @@ Accessible*
 DocAccessible::GetAccessibleOrContainer(nsINode* aNode)
 {
   if (!aNode || !aNode->IsInDoc())
     return nullptr;
 
   nsINode* currNode = aNode;
   Accessible* accessible = nullptr;
   while (!(accessible = GetAccessible(currNode)) &&
-         (currNode = currNode->GetNodeParent()));
+         (currNode = currNode->GetParentNode()));
 
   return accessible;
 }
 
 bool
 DocAccessible::BindToDocument(Accessible* aAccessible,
                               nsRoleMapEntry* aRoleMapEntry)
 {
--- a/accessible/src/generic/DocAccessible.h
+++ b/accessible/src/generic/DocAccessible.h
@@ -264,17 +264,17 @@ public:
    */
   Accessible* GetAccessibleOrContainer(nsINode* aNode);
 
   /**
    * Return a container accessible for the given DOM node.
    */
   Accessible* GetContainerAccessible(nsINode* aNode)
   {
-    return aNode ? GetAccessibleOrContainer(aNode->GetNodeParent()) : nullptr;
+    return aNode ? GetAccessibleOrContainer(aNode->GetParentNode()) : nullptr;
   }
 
   /**
    * Return true if the given ID is referred by relation attribute.
    *
    * @note Different elements may share the same ID if they are hosted inside
    *       XBL bindings. Be careful the result of this method may be  senseless
    *       while it's called for XUL elements (where XBL is used widely).
--- a/accessible/src/html/HTMLTableAccessible.cpp
+++ b/accessible/src/html/HTMLTableAccessible.cpp
@@ -954,17 +954,17 @@ HTMLTableAccessible::Description(nsStrin
 }
 
 bool
 HTMLTableAccessible::HasDescendant(const nsAString& aTagName, bool aAllowEmpty)
 {
   nsCOMPtr<nsIDOMElement> tableElt(do_QueryInterface(mContent));
   NS_ENSURE_TRUE(tableElt, false);
 
-  nsCOMPtr<nsIDOMNodeList> nodeList;
+  nsCOMPtr<nsIDOMHTMLCollection> nodeList;
   tableElt->GetElementsByTagName(aTagName, getter_AddRefs(nodeList));
   NS_ENSURE_TRUE(nodeList, false);
 
   nsCOMPtr<nsIDOMNode> foundItem;
   nodeList->Item(0, getter_AddRefs(foundItem));
   if (!foundItem)
     return false;
 
--- a/accessible/src/jsat/AccessFu.jsm
+++ b/accessible/src/jsat/AccessFu.jsm
@@ -93,18 +93,19 @@ var AccessFu = {
 
     Input.attach(this.chromeWin);
     Output.attach(this.chromeWin);
     this.touchAdapter.attach(this.chromeWin);
 
     Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
     Services.obs.addObserver(this, 'Accessibility:NextObject', false);
     Services.obs.addObserver(this, 'Accessibility:PreviousObject', false);
-    Services.obs.addObserver(this, 'Accessibility:CurrentObject', false);
+    Services.obs.addObserver(this, 'Accessibility:Focus', false);
     this.chromeWin.addEventListener('TabOpen', this);
+    this.chromeWin.addEventListener('TabSelect', this);
   },
 
   /**
    * Disable AccessFu and return to default interaction mode.
    */
   _disable: function _disable() {
     if (!this._enabled)
       return;
@@ -115,32 +116,33 @@ var AccessFu = {
 
     this.chromeWin.document.removeChild(this.stylesheet);
     for each (let mm in Utils.getAllMessageManagers(this.chromeWin))
       mm.sendAsyncMessage('AccessFu:Stop');
 
     Input.detach();
 
     this.chromeWin.removeEventListener('TabOpen', this);
+    this.chromeWin.removeEventListener('TabSelect', this);
 
     Services.obs.removeObserver(this, 'remote-browser-frame-shown');
     Services.obs.removeObserver(this, 'Accessibility:NextObject');
     Services.obs.removeObserver(this, 'Accessibility:PreviousObject');
-    Services.obs.removeObserver(this, 'Accessibility:CurrentObject');
+    Services.obs.removeObserver(this, 'Accessibility:Focus');
   },
 
   _enableOrDisable: function _enableOrDisable() {
     try {
       if (this._activatePref == ACCESSFU_ENABLE ||
           this._systemPref && this._activatePref == ACCESSFU_AUTO)
         this._enable();
       else
         this._disable();
     } catch (x) {
-      Logger.error(x);
+      Logger.logException(x);
     }
   },
 
   receiveMessage: function receiveMessage(aMessage) {
     if (Logger.logLevel >= Logger.DEBUG)
       Logger.debug('Recieved', aMessage.name, JSON.stringify(aMessage.json));
 
     switch (aMessage.name) {
@@ -150,17 +152,17 @@ var AccessFu = {
                           {method: 'start', buildApp: Utils.MozBuildApp});
       break;
       case 'AccessFu:Present':
       try {
         for each (let presenter in aMessage.json) {
           Output[presenter.type](presenter.details, aMessage.target);
         }
       } catch (x) {
-        Logger.error(x);
+        Logger.logException(x);
       }
       break;
       case 'AccessFu:Input':
       Input.setEditState(aMessage.json);
       break;
     }
   },
 
@@ -181,21 +183,23 @@ var AccessFu = {
         this._enableOrDisable();
         break;
       case 'Accessibility:NextObject':
         Input.moveCursor('moveNext', 'Simple', 'gesture');
         break;
       case 'Accessibility:PreviousObject':
         Input.moveCursor('movePrevious', 'Simple', 'gesture');
         break;
-      case 'Accessibility:CurrentObject':
-        let mm = Utils.getCurrentBrowser(this.chromeWin).
-          frameLoader.messageManager;
-        mm.sendAsyncMessage('AccessFu:VirtualCursor',
-                            {action: 'presentLastPivot'});
+      case 'Accessibility:Focus':
+        this._focused = JSON.parse(aData);
+        if (this._focused) {
+          let mm = Utils.getMessageManager(Utils.getCurrentBrowser(this.chromeWin));
+          mm.sendAsyncMessage('AccessFu:VirtualCursor',
+                              {action: 'whereIsIt', move: true});
+        }
         break;
       case 'nsPref:changed':
         if (aData == 'activate') {
           this._activatePref = this.prefsBranch.getIntPref('activate');
           this._enableOrDisable();
         }
         break;
       case 'remote-browser-frame-shown':
@@ -217,21 +221,38 @@ var AccessFu = {
         }
         break;
       }
       case 'TabOpen':
       {
         this._loadFrameScript(Utils.getMessageManager(aEvent.target));
         break;
       }
+      case 'TabSelect':
+      {
+        if (this._focused) {
+          let mm = Utils.getMessageManager(Utils.getCurrentBrowser(this.chromeWin));
+          // We delay this for half a second so the awesomebar could close,
+          // and we could use the current coordinates for the content item.
+          // XXX TODO figure out how to avoid magic wait here.
+          this.chromeWin.setTimeout(
+            function () {
+              mm.sendAsyncMessage('AccessFu:VirtualCursor', {action: 'whereIsIt'});
+            }, 500);
+        }
+        break;
+      }
     }
   },
 
   // So we don't enable/disable twice
-  _enabled: false
+  _enabled: false,
+
+  // Layerview is focused
+  _focused: false
 };
 
 var Output = {
   attach: function attach(aWindow) {
     this.chromeWin = aWindow;
   },
 
   Speech: function Speech(aDetails, aBrowser) {
@@ -315,17 +336,17 @@ var Input = {
       case 'keypress':
         this._handleKeypress(aEvent);
         break;
       case 'mozAccessFuGesture':
         this._handleGesture(aEvent);
         break;
       }
     } catch (x) {
-      Logger.error(x);
+      Logger.logException(x);
     }
   },
 
   _handleGesture: function _handleGesture(aEvent) {
     let detail = aEvent.detail;
     Logger.info('Gesture', detail.type,
                 '(fingers: ' + detail.touches.length + ')');
 
--- a/accessible/src/jsat/EventManager.jsm
+++ b/accessible/src/jsat/EventManager.jsm
@@ -37,17 +37,18 @@ var EventManager = {
       }
 
       this.present(
         function(p) {
           return p.tabStateChanged(null, 'newtab');
         }
       );
     } catch (x) {
-      Logger.error('Failed to start EventManager:', x);
+      Logger.error('Failed to start EventManager');
+      Logger.logException(x);
     }
   },
 
   stop: function stop() {
     Services.obs.removeObserver(this, 'accessible-event');
     this.presenters = [];
     this._started = false;
   },
@@ -72,51 +73,53 @@ var EventManager = {
             return p.actionInvoked(activatedAcc, 'click');
           }
         );
         break;
       }
       case 'scroll':
       case 'resize':
       {
+        // the target could be an element, document or window
+        let window = null;
+        if (aEvent.target instanceof Ci.nsIDOMWindow)
+          window = aEvent.target;
+        else if (aEvent.target instanceof Ci.nsIDOMDocument)
+          window = aEvent.target.defaultView;
+        else if (aEvent.target instanceof Ci.nsIDOMElement)
+          window = aEvent.target.ownerDocument.defaultView;
         this.present(
           function(p) {
-            return p.viewportChanged();;
+            return p.viewportChanged(window);
           }
         );
         break;
       }
       }
     } catch (x) {
-      Logger.error('Error handling DOM event:', x);
+      Logger.error('Error handling DOM event');
+      Logger.logException(x);
     }
   },
 
   observe: function observe(aSubject, aTopic, aData) {
     switch (aTopic) {
       case 'accessible-event':
         var event;
         try {
           event = aSubject.QueryInterface(Ci.nsIAccessibleEvent);
           this.handleAccEvent(event);
         } catch (x) {
-          Logger.error('Error handing accessible event:', x);
+          Logger.error('Error handing accessible event');
+          Logger.logException(x);
           return;
         }
     }
   },
 
-  presentLastPivot: function presentLastPivot() {
-    this.present(
-      function(p) {
-        return p.presentLastPivot();
-      }
-    );
-  },
-
   handleAccEvent: function handleAccEvent(aEvent) {
     if (Logger.logLevel >= Logger.DEBUG)
       Logger.debug('A11yEvent', Logger.eventToString(aEvent),
                    Logger.accessibleToString(aEvent.accessible));
 
     switch (aEvent.eventType) {
       case Ci.nsIAccessibleEvent.EVENT_VIRTUALCURSOR_CHANGED:
       {
@@ -243,20 +246,31 @@ var EventManager = {
 
   present: function present(aPresenterFunc) {
     try {
       this.sendMsgFunc(
         "AccessFu:Present",
         [aPresenterFunc(p) for each (p in this.presenters)].
           filter(function(d) {return !!d;}));
     } catch (x) {
-      Logger.error(x);
+      Logger.logException(x);
     }
   },
 
+  presentVirtualCursorPosition: function presentVirtualCursorPosition(aVirtualCursor) {
+    let presenterContext =
+      new PresenterContext(aVirtualCursor.position, null);
+
+    this.present(
+      function(p) {
+        return p.pivotChanged(presenterContext, Ci.nsIAccessiblePivot.REASON_NONE);
+      }
+    );
+  },
+
   onStateChange: function onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
     let tabstate = '';
 
     let loadingState = Ci.nsIWebProgressListener.STATE_TRANSFERRING |
       Ci.nsIWebProgressListener.STATE_IS_DOCUMENT;
     let loadedState = Ci.nsIWebProgressListener.STATE_STOP |
       Ci.nsIWebProgressListener.STATE_IS_NETWORK;
 
--- a/accessible/src/jsat/Presenters.jsm
+++ b/accessible/src/jsat/Presenters.jsm
@@ -99,22 +99,17 @@ Presenter.prototype = {
    *    landscape/portrait toggle.
    * @param {Window} aWindow window of viewport that changed.
    */
   viewportChanged: function viewportChanged(aWindow) {},
 
   /**
    * We have entered or left text editing mode.
    */
-  editingModeChanged: function editingModeChanged(aIsEditing) {},
-
-  /**
-   * Re-present the last pivot change.
-   */
-  presentLastPivot: function AndroidPresenter_presentLastPivot() {}
+  editingModeChanged: function editingModeChanged(aIsEditing) {}
 };
 
 /**
  * Visual presenter. Draws a box around the virtual cursor's position.
  */
 
 function VisualPresenter() {}
 
@@ -203,18 +198,16 @@ AndroidPresenter.prototype = {
   ANDROID_VIEW_SCROLLED: 0x1000,
   ANDROID_ANNOUNCEMENT: 0x4000,
   ANDROID_VIEW_ACCESSIBILITY_FOCUSED: 0x8000,
 
   pivotChanged: function AndroidPresenter_pivotChanged(aContext, aReason) {
     if (!aContext.accessible)
       return null;
 
-    this._currentContext = aContext;
-
     let androidEvents = [];
 
     let isExploreByTouch = (aReason == Ci.nsIAccessiblePivot.REASON_POINT &&
                             Utils.AndroidSdkVersion >= 14);
     let focusEventType = (Utils.AndroidSdkVersion >= 16) ?
       this.ANDROID_VIEW_ACCESSIBILITY_FOCUSED :
       this.ANDROID_VIEW_FOCUSED;
 
@@ -270,38 +263,35 @@ AndroidPresenter.prototype = {
                                                              aPageState) {
     return this._appAnnounce(
       UtteranceGenerator.genForTabStateChange(aDocObj, aPageState));
   },
 
   textChanged: function AndroidPresenter_textChanged(aIsInserted, aStart,
                                                      aLength, aText,
                                                      aModifiedText) {
-    let androidEvent = {
-      type: this.type,
-      details: [{
-        eventType: this.ANDROID_VIEW_TEXT_CHANGED,
-        text: [aText],
-        fromIndex: aStart,
-        removedCount: 0,
-        addedCount: 0
-      }]
+    let eventDetails = {
+      eventType: this.ANDROID_VIEW_TEXT_CHANGED,
+      text: [aText],
+      fromIndex: aStart,
+      removedCount: 0,
+      addedCount: 0
     };
 
     if (aIsInserted) {
-      androidEvent.addedCount = aLength;
-      androidEvent.beforeText =
+      eventDetails.addedCount = aLength;
+      eventDetails.beforeText =
         aText.substring(0, aStart) + aText.substring(aStart + aLength);
     } else {
-      androidEvent.removedCount = aLength;
-      androidEvent.beforeText =
+      eventDetails.removedCount = aLength;
+      eventDetails.beforeText =
         aText.substring(0, aStart) + aModifiedText + aText.substring(aStart);
     }
 
-    return androidEvent;
+    return {type: this.type, details: [eventDetails]};
   },
 
   viewportChanged: function AndroidPresenter_viewportChanged(aWindow) {
     if (Utils.AndroidSdkVersion < 14)
       return null;
 
     return {
       type: this.type,
@@ -330,23 +320,16 @@ AndroidPresenter.prototype = {
         eventType: (Utils.AndroidSdkVersion >= 16) ?
           this.ANDROID_ANNOUNCEMENT : this.ANDROID_VIEW_TEXT_CHANGED,
         text: aUtterance,
         addedCount: aUtterance.join(' ').length,
         removedCount: 0,
         fromIndex: 0
       }]
     };
-  },
-
-  presentLastPivot: function AndroidPresenter_presentLastPivot() {
-    if (this._currentContext)
-      return this.pivotChanged(this._currentContext);
-    else
-      return null;
   }
 };
 
 /**
  * A speech presenter for direct TTS output
  */
 
 function SpeechPresenter() {}
--- a/accessible/src/jsat/Utils.jsm
+++ b/accessible/src/jsat/Utils.jsm
@@ -84,42 +84,44 @@ var Utils = {
 
   getCurrentBrowser: function getCurrentBrowser(aWindow) {
     if (this.MozBuildApp == 'b2g')
       return this.getBrowserApp(aWindow).contentBrowser;
     return this.getBrowserApp(aWindow).selectedBrowser;
   },
 
   getCurrentContentDoc: function getCurrentContentDoc(aWindow) {
-    return this.getCurrentBrowser(aWindow).contentDocument;
+    let browser = this.getCurrentBrowser(aWindow);
+    return browser ? browser.contentDocument : null;
   },
 
   getMessageManager: function getMessageManager(aBrowser) {
     try {
       return aBrowser.QueryInterface(Ci.nsIFrameLoaderOwner).
          frameLoader.messageManager;
     } catch (x) {
-      Logger.error(x);
+      Logger.logException(x);
       return null;
     }
   },
 
   getAllMessageManagers: function getAllMessageManagers(aWindow) {
     let messageManagers = [];
 
     for (let i = 0; i < aWindow.messageManager.childCount; i++)
       messageManagers.push(aWindow.messageManager.getChildAt(i));
 
-    let remoteframes = this.getCurrentContentDoc(aWindow).
-      querySelectorAll('iframe[remote=true]');
+    let document = this.getCurrentContentDoc(aWindow);
 
-    for (let i = 0; i < remoteframes.length; ++i)
-      messageManagers.push(this.getMessageManager(remoteframes[i]));
+    if (document) {
+      let remoteframes = document.querySelectorAll('iframe[remote=true]');
 
-    Logger.info(messageManagers.length);
+      for (let i = 0; i < remoteframes.length; ++i)
+        messageManagers.push(this.getMessageManager(remoteframes[i]));
+    }
 
     return messageManagers;
   },
 
   getViewport: function getViewport(aWindow) {
     switch (this.MozBuildApp) {
       case 'mobile/android':
         return aWindow.BrowserApp.selectedTab.getViewport();
@@ -187,16 +189,26 @@ var Logger = {
       this, [this.WARNING].concat(Array.prototype.slice.call(arguments)));
   },
 
   error: function error() {
     this.log.apply(
       this, [this.ERROR].concat(Array.prototype.slice.call(arguments)));
   },
 
+  logException: function logException(aException) {
+    try {
+      this.error(
+        aException.message,
+        '(' + aException.fileName + ':' + aException.lineNumber + ')');
+    } catch (x) {
+      this.error(x);
+    }
+  },
+
   accessibleToString: function accessibleToString(aAccessible) {
     let str = '[ defunct ]';
     try {
       str = '[ ' + Utils.AccRetrieval.getStringRole(aAccessible.role) +
         ' | ' + aAccessible.name + ' ]';
     } catch (x) {
     }
 
--- a/accessible/src/jsat/content-script.js
+++ b/accessible/src/jsat/content-script.js
@@ -49,18 +49,24 @@ function virtualCursorControl(aMessage) 
         let acc = Utils.AccRetrieval.
           getAccessibleFor(content.document.activeElement);
         moved = vc.moveNext(rule, acc, true);
       }
       break;
     case 'moveToPoint':
       moved = vc.moveToPoint(rule, details.x, details.y, true);
       break;
-    case 'presentLastPivot':
-      EventManager.presentLastPivot();
+    case 'whereIsIt':
+      if (!forwardMessage(vc, aMessage)) {
+        if (!vc.position && aMessage.json.move)
+          vc.moveFirst(TraversalRules.Simple);
+        else
+          EventManager.presentVirtualCursorPosition(vc);
+      }
+
       break;
     default:
       break;
     }
 
     if (moved == true) {
       forwardMessage(vc, aMessage);
     } else if (moved == false && details.action != 'moveToPoint') {
--- a/accessible/src/mac/mozHTMLAccessible.mm
+++ b/accessible/src/mac/mozHTMLAccessible.mm
@@ -13,18 +13,17 @@
 
 @implementation mozHeadingAccessible
 
 - (NSString*)title
 {
   nsAutoString title;
   // XXX use the flattening API when there are available
   // see bug 768298
-  nsresult rv = mGeckoAccessible->GetContent()->GetTextContent(title);
-  NS_ENSURE_SUCCESS(rv, nil);
+  mGeckoAccessible->GetContent()->GetTextContent(title);
 
   return nsCocoaUtils::ToNSString(title);
 }
 
 - (id)value
 {
   if (!mGeckoAccessible || !mGeckoAccessible->IsHyperText())
     return nil;
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -404,17 +404,17 @@ nsAccessNodeWrap::MakeAccessNode(nsINode
 
 STDMETHODIMP nsAccessNodeWrap::get_parentNode(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
 {
 __try {
   nsINode* node = GetNode();
   if (!node)
     return E_FAIL;
 
-  *aNode = MakeAccessNode(node->GetNodeParent());
+  *aNode = MakeAccessNode(node->GetParentNode());
 
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return S_OK;
 }
 
 STDMETHODIMP nsAccessNodeWrap::get_firstChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
 {
--- a/accessible/src/xforms/nsXFormsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsAccessible.cpp
@@ -55,18 +55,17 @@ nsXFormsAccessible::
 nsresult
 nsXFormsAccessible::GetBoundChildElementValue(const nsAString& aTagName,
                                               nsAString& aValue)
 {
   NS_ENSURE_TRUE(sXFormsService, NS_ERROR_FAILURE);
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsINodeList* nodes = mContent->GetChildNodesList();
-  NS_ENSURE_STATE(nodes);
+  nsINodeList* nodes = mContent->ChildNodes();
 
   uint32_t length;
   nsresult rv = nodes->GetLength(&length);
   NS_ENSURE_SUCCESS(rv, rv);
 
   for (uint32_t index = 0; index < length; index++) {
     nsIContent* content = nodes->GetNodeAt(index);
     if (content->NodeInfo()->Equals(aTagName) &&
@@ -540,17 +539,17 @@ nsXFormsSelectableItemAccessible::DoActi
 }
 
 bool
 nsXFormsSelectableItemAccessible::IsSelected()
 {
   nsresult rv;
 
   nsINode* parent = mContent;
-  while ((parent = parent->GetNodeParent())) {
+  while ((parent = parent->GetParentNode())) {
     nsCOMPtr<nsIContent> content(do_QueryInterface(parent));
     if (!content)
       return false;
 
     nsCOMPtr<nsINodeInfo> nodeinfo = content->NodeInfo();
     if (!nodeinfo->NamespaceEquals(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS)))
       continue;
 
--- a/accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
@@ -151,13 +151,13 @@ void
 nsXFormsComboboxPopupWidgetAccessible::Value(nsString& aValue)
 {
   aValue.Truncate();
 }
 
 void
 nsXFormsComboboxPopupWidgetAccessible::CacheChildren()
 {
-  nsCOMPtr<nsIDOMNode> parent = do_QueryInterface(mContent->GetNodeParent());
+  nsCOMPtr<nsIDOMNode> parent = do_QueryInterface(mContent->GetParentNode());
   // Parent node must be an xforms:select1 element.
   CacheSelectChildren(parent);
 }
 
--- a/accessible/tests/mochitest/Makefile.in
+++ b/accessible/tests/mochitest/Makefile.in
@@ -19,16 +19,17 @@ DIRS	= \
   focus \
   hittest \
   hyperlink \
   hypertext \
   name \
   pivot \
   relations \
   role \
+  scroll \
   selectable \
   states \
   table \
   text \
   textcaret \
   textselection \
   tree \
   treeupdate \
--- a/accessible/tests/mochitest/common.js
+++ b/accessible/tests/mochitest/common.js
@@ -68,16 +68,20 @@ const SEAMONKEY = navigator.userAgent.ma
 
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible general
 
 const STATE_BUSY = nsIAccessibleStates.STATE_BUSY;
 
 const SCROLL_TYPE_ANYWHERE = nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE;
 
+const COORDTYPE_SCREEN_RELATIVE = nsIAccessibleCoordinateType.COORDTYPE_SCREEN_RELATIVE;
+const COORDTYPE_WINDOW_RELATIVE = nsIAccessibleCoordinateType.COORDTYPE_WINDOW_RELATIVE;
+const COORDTYPE_PARENT_RELATIVE = nsIAccessibleCoordinateType.COORDTYPE_PARENT_RELATIVE;
+
 const kEmbedChar = String.fromCharCode(0xfffc);
 
 const kDiscBulletText = String.fromCharCode(0x2022) + " ";
 const kCircleBulletText = String.fromCharCode(0x25e6) + " ";
 const kSquareBulletText = String.fromCharCode(0x25aa) + " ";
 
 /**
  * nsIAccessibleRetrieval service.
--- a/accessible/tests/mochitest/layout.js
+++ b/accessible/tests/mochitest/layout.js
@@ -87,32 +87,57 @@ function getChildAtPoint(aIdentifier, aX
       return acc.getDeepestChildAtPoint(x, y);
     return acc.getChildAtPoint(x, y);
   } catch (e) {  }
 
   return null;
 }
 
 /**
+ * Test the accessible position.
+ */
+function testPos(aID, aPoint)
+{
+  var [expectedX, expectedY] =
+    (aPoint != undefined) ? aPoint : getBoundsForDOMElm(aID);
+
+  var [x, y] = getBounds(aID);
+  is(x, expectedX, "Wrong x coordinate of " + prettyName(aID));
+  is(y, expectedY, "Wrong y coordinate of " + prettyName(aID));
+}
+
+/**
  * Test the accessible boundaries.
  */
 function testBounds(aID, aRect)
 {
   var [expectedX, expectedY, expectedWidth, expectedHeight] =
     (aRect != undefined) ? aRect : getBoundsForDOMElm(aID);
 
   var [x, y, width, height] = getBounds(aID);
   is(x, expectedX, "Wrong x coordinate of " + prettyName(aID));
   is(y, expectedY, "Wrong y coordinate of " + prettyName(aID));
   is(width, expectedWidth, "Wrong width of " + prettyName(aID));
   is(height, expectedHeight, "Wrong height of " + prettyName(aID));
 }
 
 /**
- * Return the accessible coordinates and size relative to the screen.
+ * Return the accessible coordinates relative to the screen in device pixels.
+ */
+function getPos(aID)
+{
+  var accessible = getAccessible(aID);
+  var x = {}, y = {};
+  accessible.getBounds(x, y, {}, {});
+  return [x.value, y.value];
+}
+
+/**
+ * Return the accessible coordinates and size relative to the screen in device
+ * pixels.
  */
 function getBounds(aID)
 {
   var accessible = getAccessible(aID);
   var x = {}, y = {}, width = {}, height = {};
   accessible.getBounds(x, y, width, height);
   return [x.value, y.value, width.value, height.value];
 }
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/scroll/Makefile.in
@@ -0,0 +1,18 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH		= @DEPTH@
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+relativesrcdir  = accessible/scroll
+
+include $(DEPTH)/config/autoconf.mk
+
+MOCHITEST_A11Y_FILES =\
+		test_zoom.html \
+		$(NULL)
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/scroll/test_zoom.html
@@ -0,0 +1,147 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Test scrollToPoint when page is zoomed</title>
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../role.js"></script>
+  <script type="application/javascript"
+          src="../layout.js"></script>
+
+  <script type="application/javascript">
+    function testScrollToPoint()
+    {
+      // scrollToPoint relative screen
+      var anchor = getAccessible("bottom1");
+      var [x, y] = getPos(anchor);
+      var [docX, docY] = getPos(document);
+
+      anchor.scrollToPoint(COORDTYPE_SCREEN_RELATIVE, docX, docY);
+      testPos(anchor, [x, docY]);
+
+      // scrollToPoint relative window
+      anchor = getAccessible("bottom2");
+      var [x, y] = getPos(anchor);
+      var wnd = getRootAccessible().DOMDocument.defaultView;
+      var scrollToX = docX - wnd.screenX, scrollToY = docY - wnd.screenY;
+
+      anchor.scrollToPoint(COORDTYPE_WINDOW_RELATIVE, scrollToX, scrollToY);
+      testPos(anchor, [x, docY]);
+
+      // scrollToPoint relative parent
+      anchor = getAccessible("bottom3");
+      var [x, y] = getPos(anchor);
+      var [parentX, parentY] = getPos(anchor.parent);
+      var scrollToX = parentX - docX, scrollToY = parentY - docY;
+
+      anchor.scrollToPoint(COORDTYPE_PARENT_RELATIVE, scrollToX, scrollToY);
+      testPos(anchor, [x, docY]);
+    }
+
+    function doTest()
+    {
+      testScrollToPoint();
+      zoomDocument(document, 2.0);
+      testScrollToPoint(); // zoom and test again
+
+      zoomDocument(document, 1.0);
+      SimpleTest.finish();
+    }
+
+    addA11yLoadEvent(doTest);
+    SimpleTest.waitForExplicitFinish();
+  </script>
+
+</head>
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=727942"
+     title="scrollToPoint is broken when page is zoomed">
+    Mozilla Bug 727942
+  </a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <h1>Below there is a bunch of named anchors</h1>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  This is in the middle anchor #1<a id="bottom1"></a>
+  <br><br><br><br><br><br><br><br><br><br>
+  This is in the middle anchor #2<a id="bottom2"></a>
+  <br><br><br><br><br><br><br><br><br><br>
+  This is in the middle anchor #3<a id="bottom3"></a>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+</body>
+</html>
--- a/browser/installer/windows/nsis/uninstaller.nsi
+++ b/browser/installer/windows/nsis/uninstaller.nsi
@@ -246,16 +246,17 @@ Section "Uninstall"
     Sleep 5000
     ${DeleteFile} "$INSTDIR\${FileMainEXE}"
     ClearErrors
   ${EndIf}
 
   ${MUI_INSTALLOPTIONS_READ} $0 "unconfirm.ini" "Field 3" "State"
   ${If} "$0" == "1"
     ${un.DeleteRelativeProfiles} "Mozilla\Firefox"
+    ${un.DeleteRelativeProfiles} "Mozilla\MetroFirefox"
     RmDir "$APPDATA\Mozilla\Extensions\{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
     RmDir "$APPDATA\Mozilla\Extensions"
     RmDir "$APPDATA\Mozilla"
   ${EndIf}
 
   ; setup the application model id registration value
   ${un.InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs"
 
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -433,16 +433,18 @@ user_pref("urlclassifier.updateinterval"
 user_pref("browser.safebrowsing.gethashURL", "http://%(server)s/safebrowsing-dummy/gethash");
 user_pref("browser.safebrowsing.keyURL", "http://%(server)s/safebrowsing-dummy/newkey");
 user_pref("browser.safebrowsing.updateURL", "http://%(server)s/safebrowsing-dummy/update");
 // Point update checks to the local testing server for fast failures
 user_pref("extensions.update.url", "http://%(server)s/extensions-dummy/updateURL");
 user_pref("extensions.update.background.url", "http://%(server)s/extensions-dummy/updateBackgroundURL");
 user_pref("extensions.blocklist.url", "http://%(server)s/extensions-dummy/blocklistURL");
 user_pref("extensions.hotfix.url", "http://%(server)s/extensions-dummy/hotfixURL");
+// Turn off extension updates so they don't bother tests
+user_pref("extensions.update.enabled", false);
 // Make sure opening about:addons won't hit the network
 user_pref("extensions.webservice.discoverURL", "http://%(server)s/extensions-dummy/discoveryURL");
 // Make sure AddonRepository won't hit the network
 user_pref("extensions.getAddons.maxResults", 0);
 user_pref("extensions.getAddons.get.url", "http://%(server)s/extensions-dummy/repositoryGetURL");
 user_pref("extensions.getAddons.getWithPerformance.url", "http://%(server)s/extensions-dummy/repositoryGetWithPerformanceURL");
 user_pref("extensions.getAddons.search.browseURL", "http://%(server)s/extensions-dummy/repositoryBrowseURL");
 user_pref("extensions.getAddons.search.url", "http://%(server)s/extensions-dummy/repositorySearchURL");
--- a/config/config.mk
+++ b/config/config.mk
@@ -818,8 +818,10 @@ ifndef MOZ_SYSTEM_PLY
 PLY_INCLUDE = -I$(topsrcdir)/other-licenses/ply
 endif
 
 export CL_INCLUDES_PREFIX
 
 ifeq ($(MOZ_WIDGET_GTK),2)
 MOZ_GTK2_CFLAGS := -I$(topsrcdir)/widget/gtk2/compat $(MOZ_GTK2_CFLAGS)
 endif
+
+DEFINES += -DNO_NSPR_10_SUPPORT
--- a/configure.in
+++ b/configure.in
@@ -58,17 +58,17 @@ MOZPNG=10513
 NSPR_VERSION=4
 NSS_VERSION=3
 
 dnl Set the minimum version of toolkit libs used by mozilla
 dnl ========================================================
 GLIB_VERSION=1.2.0
 PERL_VERSION=5.006
 PYTHON_VERSION_MAJOR=2
-PYTHON_VERSION_MINOR=5
+PYTHON_VERSION_MINOR=6
 CAIRO_VERSION=1.10
 PANGO_VERSION=1.14.0
 GTK2_VERSION=2.10.0
 WINDRES_VERSION=2.14.90
 W32API_VERSION=3.14
 GNOMEVFS_VERSION=2.0
 GNOMEUI_VERSION=2.2.0
 GCONF_VERSION=1.2.1
@@ -798,17 +798,17 @@ AC_MSG_CHECKING([for full perl installat
 _perl_res=$?
 if test "$_perl_res" != 0; then
     AC_MSG_RESULT([no])
     AC_MSG_ERROR([Cannot find Config.pm or \$Config{archlib}.  A full perl installation is required.])
 else
     AC_MSG_RESULT([yes])
 fi
 
-MOZ_PATH_PROGS(PYTHON, $PYTHON python2.7 python2.6 python2.5 python)
+MOZ_PATH_PROGS(PYTHON, $PYTHON python2.7 python2.6 python)
 if test -z "$PYTHON"; then
     AC_MSG_ERROR([python was not found in \$PATH])
 fi
 
 MOZ_ARG_WITH_BOOL(system-ply,
 [  --with-system-ply       Use system installed python ply library],
     [if $PYTHON -c 'import ply' 2>&5; then
          MOZ_SYSTEM_PLY=1
@@ -1834,17 +1834,17 @@ case "$host" in
     ;;
 
 *)
     HOST_CFLAGS="$HOST_CFLAGS -DXP_UNIX"
     HOST_OPTIMIZE_FLAGS="${HOST_OPTIMIZE_FLAGS=-O2}"
     ;;
 esac
 
-dnl We require version 2.5 or newer of Python to build.
+dnl We require version 2.6 or newer of Python to build.
 AC_MSG_CHECKING([for Python version >= $PYTHON_VERSION_MAJOR.$PYTHON_VERSION_MINOR but not 3.x])
 
 changequote(:)
 read python_version_major python_version_minor python_version_micro <<EOF
 `$PYTHON -c 'import sys; print sys.version_info[0], sys.version_info[1], sys.version_info[2]'`
 EOF
 changequote([,])
 
--- a/content/base/public/Element.h
+++ b/content/base/public/Element.h
@@ -343,9 +343,14 @@ inline mozilla::dom::Element* nsINode::A
 }
 
 inline const mozilla::dom::Element* nsINode::AsElement() const
 {
   MOZ_ASSERT(IsElement());
   return static_cast<const mozilla::dom::Element*>(this);
 }
 
+inline bool nsINode::HasAttributes() const
+{
+  return IsElement() && AsElement()->GetAttrCount() > 0;
+}
+
 #endif // mozilla_dom_Element_h__
--- a/content/base/public/FragmentOrElement.h
+++ b/content/base/public/FragmentOrElement.h
@@ -186,18 +186,19 @@ public:
   // nsINode interface methods
   virtual uint32_t GetChildCount() const;
   virtual nsIContent *GetChildAt(uint32_t aIndex) const;
   virtual nsIContent * const * GetChildArray(uint32_t* aChildCount) const;
   virtual int32_t IndexOf(const nsINode* aPossibleChild) const MOZ_OVERRIDE;
   virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex,
                                  bool aNotify);
   virtual void RemoveChildAt(uint32_t aIndex, bool aNotify);
-  NS_IMETHOD GetTextContent(nsAString &aTextContent);
-  NS_IMETHOD SetTextContent(const nsAString& aTextContent);
+  virtual void GetTextContentInternal(nsAString& aTextContent);
+  virtual void SetTextContentInternal(const nsAString& aTextContent,
+                                      mozilla::ErrorResult& aError);
 
   // nsIContent interface methods
   virtual already_AddRefed<nsINodeList> GetChildren(uint32_t aFilter);
   virtual const nsTextFragment *GetText();
   virtual uint32_t TextLength() const;
   virtual nsresult SetText(const PRUnichar* aBuffer, uint32_t aLength,
                            bool aNotify);
   // Need to implement this here too to avoid hiding.
@@ -214,59 +215,16 @@ public:
 
   virtual void DestroyContent();
   virtual void SaveSubtreeState();
 
   virtual const nsAttrValue* DoGetClasses() const;
   NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
 
 public:
-  // nsIDOMNode method implementation
-  NS_IMETHOD GetNodeName(nsAString& aNodeName);
-  NS_IMETHOD GetLocalName(nsAString& aLocalName);
-  NS_IMETHOD GetNodeValue(nsAString& aNodeValue);
-  NS_IMETHOD SetNodeValue(const nsAString& aNodeValue);
-  NS_IMETHOD GetNodeType(uint16_t* aNodeType);
-  NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes);
-  NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI);
-  NS_IMETHOD GetPrefix(nsAString& aPrefix);
-  NS_IMETHOD IsSupported(const nsAString& aFeature,
-                         const nsAString& aVersion, bool* aReturn);
-  NS_IMETHOD HasAttributes(bool* aHasAttributes);
-  NS_IMETHOD HasChildNodes(bool* aHasChildNodes);
-  nsresult InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
-                        nsIDOMNode** aReturn)
-  {
-    return ReplaceOrInsertBefore(false, aNewChild, aRefChild, aReturn);
-  }
-  nsresult ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
-                        nsIDOMNode** aReturn)
-  {
-    return ReplaceOrInsertBefore(true, aNewChild, aOldChild, aReturn);
-  }
-  nsresult RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
-  {
-    return nsINode::RemoveChild(aOldChild, aReturn);
-  }
-  nsresult AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
-  {
-    return InsertBefore(aNewChild, nullptr, aReturn);
-  }
-
-  nsresult CloneNode(bool aDeep, uint8_t aOptionalArgc, nsIDOMNode **aResult)
-  {
-    if (!aOptionalArgc) {
-      aDeep = true;
-    }
-    
-    return nsNodeUtils::CloneNodeImpl(this, aDeep, true, aResult);
-  }
-
-  //----------------------------------------
-
   /**
    * If there are listeners for DOMNodeInserted event, fires the event on all
    * aNodes
    */
   static void FireNodeInserted(nsIDocument* aDoc,
                                nsINode* aParent,
                                nsTArray<nsCOMPtr<nsIContent> >& aNodes);
 
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -32,16 +32,17 @@
 #include "nsIDocument.h"
 #include "nsContentSink.h"
 #include "nsMathUtils.h"
 #include "nsThreadUtils.h"
 #include "nsIContent.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "gfxContext.h"
 #include "gfxFont.h"
+#include "nsContentList.h"
 
 #include "mozilla/AutoRestore.h"
 #include "mozilla/GuardObjects.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Assertions.h"
 
 struct nsNativeKeyEvent; // Don't include nsINativeKeyBindings.h here: it will force strange compilation error!
 
@@ -276,20 +277,19 @@ public:
    */
   static nsINode* GetCommonAncestor(nsINode* aNode1,
                                     nsINode* aNode2);
 
   /**
    * Returns true if aNode1 is before aNode2 in the same connected
    * tree.
    */
-  static bool PositionIsBefore(nsINode* aNode1,
-                                 nsINode* aNode2)
+  static bool PositionIsBefore(nsINode* aNode1, nsINode* aNode2)
   {
-    return (aNode2->CompareDocPosition(aNode1) &
+    return (aNode2->CompareDocumentPosition(*aNode1) &
       (nsIDOMNode::DOCUMENT_POSITION_PRECEDING |
        nsIDOMNode::DOCUMENT_POSITION_DISCONNECTED)) ==
       nsIDOMNode::DOCUMENT_POSITION_PRECEDING;
   }
 
   /**
    *  Utility routine to compare two "points", where a point is a
    *  node/offset pair
@@ -1809,19 +1809,26 @@ public:
   {
     sIsHandlingKeyBoardEvent = aHandling;
   }
 
   /**
    * Utility method for getElementsByClassName.  aRootNode is the node (either
    * document or element), which getElementsByClassName was called on.
    */
-  static nsresult GetElementsByClassName(nsINode* aRootNode,
-                                         const nsAString& aClasses,
-                                         nsIDOMNodeList** aReturn);
+  static already_AddRefed<nsContentList>
+  GetElementsByClassName(nsINode* aRootNode, const nsAString& aClasses)
+  {
+    NS_PRECONDITION(aRootNode, "Must have root node");
+
+    return NS_GetFuncStringHTMLCollection(aRootNode, MatchClassNames,
+                                          DestroyClassNameArray,
+                                          AllocClassMatchingInfo,
+                                          aClasses);
+  }
 
   /**
    * Returns a presshell for this document, if there is one. This will be
    * aDoc's direct presshell if there is one, otherwise we'll look at all
    * ancestor documents to try to find a presshell, so for example this can
    * still find a presshell for documents in display:none frames that have
    * no presentation. So you have to be careful how you use this presshell ---
    * getting generic data like a device context or widget from it is OK, but it
@@ -2175,16 +2182,22 @@ private:
                                 bool aCancelable,
                                 bool aTrusted,
                                 bool *aDefaultAction = nullptr);
 
   static void InitializeModifierStrings();
 
   static void DropFragmentParsers();
 
+  static bool MatchClassNames(nsIContent* aContent, int32_t aNamespaceID,
+                              nsIAtom* aAtom, void* aData);
+  static void DestroyClassNameArray(void* aData);
+  static void* AllocClassMatchingInfo(nsINode* aRootNode,
+                                      const nsString* aClasses);
+
   static nsIDOMScriptObjectFactory *sDOMScriptObjectFactory;
 
   static nsIXPConnect *sXPConnect;
 
   static nsIScriptSecurityManager *sSecurityManager;
 
   static nsIThreadJSContextStack *sThreadJSContextStack;
 
--- a/content/base/public/nsDeprecatedOperationList.h
+++ b/content/base/public/nsDeprecatedOperationList.h
@@ -11,37 +11,17 @@ DEPRECATED_OPERATION(GetAttributeNode)
 DEPRECATED_OPERATION(SetAttributeNode)
 DEPRECATED_OPERATION(GetAttributeNodeNS)
 DEPRECATED_OPERATION(SetAttributeNodeNS)
 DEPRECATED_OPERATION(RemoveAttributeNode)
 DEPRECATED_OPERATION(CreateAttribute)
 DEPRECATED_OPERATION(CreateAttributeNS)
 DEPRECATED_OPERATION(Specified)
 DEPRECATED_OPERATION(OwnerElement)
-DEPRECATED_OPERATION(NodeName)
 DEPRECATED_OPERATION(NodeValue)
-DEPRECATED_OPERATION(NodeType)
-DEPRECATED_OPERATION(ParentNode)
-DEPRECATED_OPERATION(ChildNodes)
-DEPRECATED_OPERATION(HasChildNodes)
-DEPRECATED_OPERATION(HasAttributes)
-DEPRECATED_OPERATION(FirstChild)
-DEPRECATED_OPERATION(LastChild)
-DEPRECATED_OPERATION(PreviousSibling)
-DEPRECATED_OPERATION(NextSibling)
-DEPRECATED_OPERATION(Attributes)
-DEPRECATED_OPERATION(InsertBefore)
-DEPRECATED_OPERATION(ReplaceChild)
-DEPRECATED_OPERATION(RemoveChild)
-DEPRECATED_OPERATION(AppendChild)
-DEPRECATED_OPERATION(CloneNode)
-DEPRECATED_OPERATION(OwnerDocument)
-DEPRECATED_OPERATION(Normalize)
-DEPRECATED_OPERATION(IsSupported)
-DEPRECATED_OPERATION(IsEqualNode)
 DEPRECATED_OPERATION(TextContent)
 DEPRECATED_OPERATION(EnablePrivilege)
 DEPRECATED_OPERATION(Position)
 DEPRECATED_OPERATION(TotalSize)
 DEPRECATED_OPERATION(InputEncoding)
 DEPRECATED_OPERATION(MozBeforePaint)
 DEPRECATED_OPERATION(DOMExceptionCode)
 DEPRECATED_OPERATION(NoExposedProps)
--- a/content/base/public/nsIAttribute.h
+++ b/content/base/public/nsIAttribute.h
@@ -22,17 +22,17 @@ public:
 
   virtual void SetMap(nsDOMAttributeMap *aMap) = 0;
   
   nsDOMAttributeMap *GetMap()
   {
     return mAttrMap;
   }
 
-  nsINodeInfo *NodeInfo()
+  nsINodeInfo *NodeInfo() const
   {
     return mNodeInfo;
   }
 
   virtual nsIContent* GetContent() const = 0;
 
   /**
    * Called when our ownerElement is moved into a new document.
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -1716,16 +1716,21 @@ public:
   {
     if (aSync) {
       ++mInSyncOperationCount;
     } else {
       --mInSyncOperationCount;
     }
   }
 
+  bool CreatingStaticClone() const
+  {
+    return mCreatingStaticClone;
+  }
+
 private:
   uint64_t mWarnedAbout;
 
 protected:
   ~nsIDocument();
   nsPropertyTable* GetExtraPropertyTable(uint16_t aCategory);
 
   // Never ever call this. Only call GetWindow!
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -1,19 +1,21 @@
 /* -*- 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 nsINode_h___
 #define nsINode_h___
 
+#include "mozilla/ErrorResult.h"
 #include "nsCOMPtr.h"               // for member, local
 #include "nsGkAtoms.h"              // for nsGkAtoms::baseURIProperty
 #include "nsIDOMEventTarget.h"      // for base class
+#include "nsIDOMNode.h"
 #include "nsIDOMNodeSelector.h"     // base class
 #include "nsINodeInfo.h"            // member (in nsCOMPtr)
 #include "nsIVariant.h"             // for use in GetUserData()
 #include "nsNodeInfoManager.h"      // for use in NodePrincipal()
 #include "nsPropertyTable.h"        // for typedefs
 #include "nsTObserverArray.h"       // for member
 #include "nsWindowMemoryReporter.h" // for NS_DECL_SIZEOF_EXCLUDING_THIS
 #include "nsWrapperCache.h"         // for base class
@@ -22,36 +24,38 @@
 #ifdef XP_WIN
 #ifdef GetClassInfo
 #undef GetClassInfo
 #endif
 #endif
 
 class nsAttrAndChildArray;
 class nsChildContentList;
+class nsDOMAttributeMap;
 class nsIContent;
 class nsIDocument;
 class nsIDOMElement;
-class nsIDOMNode;
 class nsIDOMNodeList;
 class nsIDOMUserDataHandler;
 class nsIEditor;
 class nsIFrame;
 class nsIMutationObserver;
 class nsINodeList;
 class nsIPresShell;
 class nsIPrincipal;
 class nsIURI;
 class nsNodeSupportsWeakRefTearoff;
 class nsNodeWeakReference;
 class nsXPCClassInfo;
+class nsGenericElement;
 
 namespace mozilla {
 namespace dom {
 class Element;
+template<typename T> class Optional;
 } // namespace dom
 } // namespace mozilla
 
 namespace JS {
 class Value;
 }
 
 inline void SetDOMStringToNull(nsAString& aString);
@@ -238,18 +242,18 @@ private:
 // Categories of node properties
 // 0 is global.
 #define DOM_USER_DATA         1
 #define DOM_USER_DATA_HANDLER 2
 #define SMIL_MAPPED_ATTR_ANIMVAL 3
 
 // IID for the nsINode interface
 #define NS_INODE_IID \
-{ 0x9aede57e, 0xe39e, 0x42e8, \
-  { 0x8d, 0x33, 0x7a, 0xc3, 0xd0, 0xbb, 0x5b, 0xf9 } }
+{ 0xb3ee8053, 0x43b0, 0x44bc, \
+  { 0xa0, 0x97, 0x18, 0x24, 0xd2, 0xac, 0x65, 0xb6 } }
 
 /**
  * An internal interface that abstracts some DOMNode-related parts that both
  * nsIContent and nsIDocument share.  An instance of this interface has a list
  * of nsIContent children and provides access to them.
  */
 class nsINode : public nsIDOMEventTarget,
                 public nsWrapperCache
@@ -356,16 +360,44 @@ public:
    * 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)
    * @return whether the content matches ALL flags passed in
    */
   virtual bool IsNodeOfType(uint32_t aFlags) const = 0;
 
+  virtual JSObject* WrapObject(JSContext *aCx, JSObject *aScope,
+                               bool *aTriedToWrap);
+
+protected:
+  /**
+   * WrapNode is called from WrapObject to actually wrap this node, WrapObject
+   * does some additional checks and fix-up that's common to all nodes. WrapNode
+   * should just call the DOM binding's Wrap function.
+   */
+  virtual JSObject* WrapNode(JSContext *aCx, JSObject *aScope,
+                             bool *aTriedToWrap)
+  {
+    *aTriedToWrap = false;
+    return nullptr;
+  }
+
+public:
+  nsIDocument* GetParentObject() const
+  {
+    // Make sure that we get the owner document of the content node, in case
+    // we're in document teardown.  If we are, it's important to *not* use
+    // globalObj as the node's parent since that would give the node the
+    // principal of globalObj (i.e. the principal of the document that's being
+    // loaded) and not the principal of the document that's being unloaded.
+    // See http://bugzilla.mozilla.org/show_bug.cgi?id=227417
+    return OwnerDoc();
+  }
+
   /**
    * Return whether the node is an Element node
    */
   bool IsElement() const {
     return GetBoolFlag(NodeIsElement);
   }
 
   /**
@@ -483,33 +515,16 @@ public:
    * the non-namespaced tag, and for other nodes it's something like "#text",
    * "#comment", "#document", etc.
    */
   nsIAtom* Tag() const
   {
     return mNodeInfo->NameAtom();
   }
 
-  nsINode*
-  InsertBefore(nsINode *aNewChild, nsINode *aRefChild, nsresult *aReturn)
-  {
-    return ReplaceOrInsertBefore(false, aNewChild, aRefChild, aReturn);
-  }
-  nsINode*
-  ReplaceChild(nsINode *aNewChild, nsINode *aOldChild, nsresult *aReturn)
-  {
-    return ReplaceOrInsertBefore(true, aNewChild, aOldChild, aReturn);
-  }
-  nsINode*
-  AppendChild(nsINode *aNewChild, nsresult *aReturn)
-  {
-    return InsertBefore(aNewChild, nullptr, aReturn);
-  }
-  nsresult RemoveChild(nsINode *aOldChild);
-
   /**
    * Insert a content node at a particular index.  This method handles calling
    * BindToTree on the child appropriately.
    *
    * @param aKid the content to insert
    * @param aIndex the index it is being inserted at (the index it will have
    *        after it is inserted)
    * @param aNotify whether to notify the document (current document for
@@ -727,17 +742,17 @@ public:
       reinterpret_cast<nsIContent*>(mParent) : nullptr;
   }
 
   /**
    * Get the parent nsINode for this node. This can be either an nsIContent,
    * an nsIDocument or an nsIAttribute.
    * @return the parent node
    */
-  nsINode* GetNodeParent() const
+  nsINode* GetParentNode() const
   {
     return mParent;
   }
   
   /**
    * Get the parent nsINode for this node if it is an Element.
    * @return the parent node
    */
@@ -760,17 +775,17 @@ public:
     // 3. nsIAttribute nodes - Are never in the document, and mSubtreeRoot
     //    is always 'this' (as set in nsINode's ctor).
     nsINode* node = IsInDoc() ? OwnerDocAsNode() : mSubtreeRoot;
     NS_ASSERTION(node, "Should always have a node here!");
 #ifdef DEBUG
     {
       const nsINode* slowNode = this;
       const nsINode* iter = slowNode;
-      while ((iter = iter->GetNodeParent())) {
+      while ((iter = iter->GetParentNode())) {
         slowNode = iter;
       }
 
       NS_ASSERTION(slowNode == node, "These should always be in sync!");
     }
 #endif
     return node;
   }
@@ -998,43 +1013,47 @@ public:
    * user does "Select All" while the focus is in this node. Note that if this
    * node is not in an editor, the result comes from the nsFrameSelection that
    * is related to aPresShell, so the result might not be the ancestor of this
    * node. Be aware that if this node and the computed selection limiter are
    * not in same subtree, this returns the root content of the closeset subtree.
    */
   nsIContent* GetSelectionRootContent(nsIPresShell* aPresShell);
 
-  virtual nsINodeList* GetChildNodesList();
+  virtual nsINodeList* ChildNodes();
   nsIContent* GetFirstChild() const { return mFirstChild; }
   nsIContent* GetLastChild() const
   {
     uint32_t count;
     nsIContent* const* children = GetChildArray(&count);
 
     return count > 0 ? children[count - 1] : nullptr;
   }
 
   /**
    * Implementation is in nsIDocument.h, because it needs to cast from
    * nsIDocument* to nsINode*.
    */
   nsIDocument* GetOwnerDocument() const;
 
-  nsresult Normalize();
+  void Normalize();
 
   /**
    * Get the base URI for any relative URIs within this piece of
    * content. Generally, this is the document's base URI, but certain
    * content carries a local base for backward compatibility, and XML
    * supports setting a per-node base URI.
    *
    * @return the base URI
    */
   virtual already_AddRefed<nsIURI> GetBaseURI() const = 0;
+  already_AddRefed<nsIURI> GetBaseURIObject() const
+  {
+    return GetBaseURI();
+  }
 
   /**
    * Facility for explicitly setting a base URI on a node.
    */
   nsresult SetExplicitBaseURI(nsIURI* aURI);
   /**
    * The explicit base URI, if set, otherwise null
    */
@@ -1042,28 +1061,24 @@ protected:
   nsIURI* GetExplicitBaseURI() const {
     if (HasExplicitBaseURI()) {
       return static_cast<nsIURI*>(GetProperty(nsGkAtoms::baseURIProperty));
     }
     return nullptr;
   }
   
 public:
-  nsresult GetDOMBaseURI(nsAString &aURI) const;
-
-  // Note! This function must never fail. It only return an nsresult so that
-  // we can use it to implement nsIDOMNode
-  NS_IMETHOD GetTextContent(nsAString &aTextContent)
+  void GetTextContent(nsAString& aTextContent)
   {
-    SetDOMStringToNull(aTextContent);
-    return NS_OK;
+    GetTextContentInternal(aTextContent);
   }
-  NS_IMETHOD SetTextContent(const nsAString& aTextContent)
+  void SetTextContent(const nsAString& aTextContent,
+                      mozilla::ErrorResult& aError)
   {
-    return NS_OK;
+    SetTextContentInternal(aTextContent, aError);
   }
 
   /**
    * Helper methods for implementing querySelector/querySelectorAll
    */
   nsIContent* QuerySelector(const nsAString& aSelector,
                             nsresult *aResult);
   nsresult QuerySelectorAll(const nsAString& aSelector,
@@ -1106,51 +1121,27 @@ public:
 
   nsresult GetUserData(const nsAString& aKey, nsIVariant** aResult)
   {
     NS_IF_ADDREF(*aResult = GetUserData(aKey));
   
     return NS_OK;
   }
 
-
-  /**
-   * Compares the document position of a node to this node.
-   *
-   * @param aOtherNode The node whose position is being compared to this node
-   *
-   * @return  The document position flags of the nodes. aOtherNode is compared
-   *          to this node, i.e. if aOtherNode is before this node then
-   *          DOCUMENT_POSITION_PRECEDING will be set.
-   *
-   * @see nsIDOMNode
-   */
-  uint16_t CompareDocPosition(nsINode* aOtherNode);
-  nsresult CompareDocPosition(nsINode* aOtherNode, uint16_t* aReturn)
-  {
-    NS_ENSURE_ARG(aOtherNode);
-    *aReturn = CompareDocPosition(aOtherNode);
-    return NS_OK;
-  }
-  nsresult CompareDocumentPosition(nsIDOMNode* aOther,
-                                   uint16_t* aReturn);
-
-  nsresult LookupPrefix(const nsAString& aNamespaceURI, nsAString& aPrefix);
-  nsresult IsDefaultNamespace(const nsAString& aNamespaceURI, bool* aResult)
+  void LookupPrefix(const nsAString& aNamespace, nsAString& aResult);
+  bool IsDefaultNamespace(const nsAString& aNamespaceURI)
   {
     nsAutoString defaultNamespace;
     LookupNamespaceURI(EmptyString(), defaultNamespace);
-    *aResult = aNamespaceURI.Equals(defaultNamespace);
-    return NS_OK;
+    return aNamespaceURI.Equals(defaultNamespace);
   }
-  nsresult LookupNamespaceURI(const nsAString& aNamespacePrefix,
-                              nsAString& aNamespaceURI);
+  void LookupNamespaceURI(const nsAString& aNamespacePrefix,
+                          nsAString& aNamespaceURI);
 
   nsresult IsEqualNode(nsIDOMNode* aOther, bool* aReturn);
-  bool IsEqualTo(nsINode* aOther);
 
   nsIContent* GetNextSibling() const { return mNextSibling; }
   nsIContent* GetPreviousSibling() const { return mPreviousSibling; }
 
   /**
    * Get the next node in the pre-order tree traversal of the DOM.  If
    * aRoot is non-null, then it must be an ancestor of |this|
    * (possibly equal to |this|) and only nodes that are descendants of
@@ -1189,17 +1180,17 @@ private:
   nsIContent* GetNextNodeImpl(const nsINode* aRoot,
                               const bool aSkipChildren) const
   {
     // Can't use nsContentUtils::ContentIsDescendantOf here, since we
     // can't include it here.
 #ifdef DEBUG
     if (aRoot) {
       const nsINode* cur = this;
-      for (; cur; cur = cur->GetNodeParent())
+      for (; cur; cur = cur->GetParentNode())
         if (cur == aRoot) break;
       NS_ASSERTION(cur, "aRoot not an ancestor of |this|?");
     }
 #endif
     if (!aSkipChildren) {
       nsIContent* kid = GetFirstChild();
       if (kid) {
         return kid;
@@ -1209,17 +1200,17 @@ private:
       return nullptr;
     }
     const nsINode* cur = this;
     while (1) {
       nsIContent* next = cur->GetNextSibling();
       if (next) {
         return next;
       }
-      nsINode* parent = cur->GetNodeParent();
+      nsINode* parent = cur->GetParentNode();
       if (parent == aRoot) {
         return nullptr;
       }
       cur = parent;
     }
     NS_NOTREACHED("How did we get here?");
   }
 
@@ -1234,17 +1225,17 @@ public:
    */
   nsIContent* GetPreviousContent(const nsINode* aRoot = nullptr) const
   {
       // Can't use nsContentUtils::ContentIsDescendantOf here, since we
       // can't include it here.
 #ifdef DEBUG
       if (aRoot) {
         const nsINode* cur = this;
-        for (; cur; cur = cur->GetNodeParent())
+        for (; cur; cur = cur->GetParentNode())
           if (cur == aRoot) break;
         NS_ASSERTION(cur, "aRoot not an ancestor of |this|?");
       }
 #endif
 
     if (this == aRoot) {
       return nullptr;
     }
@@ -1420,16 +1411,98 @@ public:
   void UnbindObject(nsISupports* aObject);
 
   /**
    * Returns the length of this node, as specified at
    * <http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length>
    */
   uint32_t Length() const;
 
+  void GetNodeName(nsAString& aNodeName) const
+  {
+    aNodeName = NodeName();
+  }
+  void GetBaseURI(nsAString& aBaseURI) const;
+  nsGenericElement* GetParentElement() const;
+  bool HasChildNodes() const
+  {
+    return HasChildren();
+  }
+  uint16_t CompareDocumentPosition(nsINode& aOther) const;
+  void GetNodeValue(nsAString& aNodeValue)
+  {
+    GetNodeValueInternal(aNodeValue);
+  }
+  void SetNodeValue(const nsAString& aNodeValue,
+                    mozilla::ErrorResult& aError)
+  {
+    SetNodeValueInternal(aNodeValue, aError);
+  }
+  virtual void GetNodeValueInternal(nsAString& aNodeValue)
+  {
+    SetDOMStringToNull(aNodeValue);
+  }
+  virtual void SetNodeValueInternal(const nsAString& aNodeValue,
+                                    mozilla::ErrorResult& aError)
+  {
+    // The DOM spec says that when nodeValue is defined to be null "setting it
+    // has no effect", so we don't throw an exception.
+  }
+  nsINode* InsertBefore(nsINode& aNode, nsINode* aChild,
+                        mozilla::ErrorResult& aError)
+  {
+    return ReplaceOrInsertBefore(false, &aNode, aChild, aError);
+  }
+  nsINode* AppendChild(nsINode& aNode, mozilla::ErrorResult& aError)
+  {
+    return InsertBefore(aNode, nullptr, aError);
+  }
+  nsINode* ReplaceChild(nsINode& aNode, nsINode& aChild,
+                        mozilla::ErrorResult& aError)
+  {
+    return ReplaceOrInsertBefore(true, &aNode, &aChild, aError);
+  }
+  nsINode* RemoveChild(nsINode& aChild, mozilla::ErrorResult& aError);
+  already_AddRefed<nsINode> CloneNode(bool aDeep, mozilla::ErrorResult& aError);
+  bool IsEqualNode(nsINode* aNode);
+  bool IsSupported(const nsAString& aFeature, const nsAString& aVersion);
+  void GetNamespaceURI(nsAString& aNamespaceURI, mozilla::ErrorResult& aError) const
+  {
+    aError = mNodeInfo->GetNamespaceURI(aNamespaceURI);
+  }
+#ifdef MOZILLA_INTERNAL_API
+  void GetPrefix(nsAString& aPrefix)
+  {
+    mNodeInfo->GetPrefix(aPrefix);
+  }
+#endif
+  void GetLocalName(nsAString& aLocalName)
+  {
+    aLocalName = mNodeInfo->LocalName();
+  }
+  // HasAttributes is defined inline in Element.h.
+  bool HasAttributes() const;
+  nsDOMAttributeMap* GetAttributes();
+  JS::Value SetUserData(JSContext* aCx, const nsAString& aKey, JS::Value aData,
+                        nsIDOMUserDataHandler* aHandler,
+                        mozilla::ErrorResult& aError);
+  JS::Value GetUserData(JSContext* aCx, const nsAString& aKey,
+                        mozilla::ErrorResult& aError);
+
+  // Helper method to remove this node from its parent. This is not exposed
+  // through WebIDL.
+  // Only call this if the node has a parent node.
+  nsresult RemoveFromParent()
+  {
+    nsINode* parent = GetParentNode();
+    mozilla::ErrorResult rv;
+    parent->RemoveChild(*this, rv);
+    return rv.ErrorCode();
+  }
+
 protected:
 
   // Override this function to create a custom slots class.
   // Must not return null.
   virtual nsINode::nsSlots* CreateSlots();
 
   bool HasSlots() const
   {
@@ -1456,45 +1529,50 @@ protected:
   }
 
   bool IsEditableInternal() const;
   virtual bool IsEditableExternal() const
   {
     return IsEditableInternal();
   }
 
+  virtual void GetTextContentInternal(nsAString& aTextContent)
+  {
+    SetDOMStringToNull(aTextContent);
+  }
+  virtual void SetTextContentInternal(const nsAString& aTextContent,
+                                      mozilla::ErrorResult& aError)
+  {
+  }
+
 #ifdef DEBUG
   // Note: virtual so that IsInNativeAnonymousSubtree can be called accross
   // module boundaries.
   virtual void CheckNotNativeAnonymous() const;
 #endif
 
+  // These are just used to implement nsIDOMNode using
+  // NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER and for quickstubs.
   nsresult GetParentNode(nsIDOMNode** aParentNode);
   nsresult GetParentElement(nsIDOMElement** aParentElement);
   nsresult GetChildNodes(nsIDOMNodeList** aChildNodes);
   nsresult GetFirstChild(nsIDOMNode** aFirstChild);
   nsresult GetLastChild(nsIDOMNode** aLastChild);
   nsresult GetPreviousSibling(nsIDOMNode** aPrevSibling);
   nsresult GetNextSibling(nsIDOMNode** aNextSibling);
   nsresult GetOwnerDocument(nsIDOMDocument** aOwnerDocument);
+  nsresult CompareDocumentPosition(nsIDOMNode* aOther,
+                                   uint16_t* aReturn);
+  nsresult GetAttributes(nsIDOMNamedNodeMap** aAttributes);
 
   nsresult ReplaceOrInsertBefore(bool aReplace, nsIDOMNode *aNewChild,
                                  nsIDOMNode *aRefChild, nsIDOMNode **aReturn);
-  nsINode* ReplaceOrInsertBefore(bool aReplace, nsINode *aNewChild,
-                                 nsINode *aRefChild, nsresult *aReturn)
-  {
-    *aReturn = ReplaceOrInsertBefore(aReplace, aNewChild, aRefChild);
-    if (NS_FAILED(*aReturn)) {
-      return nullptr;
-    }
-
-    return aReplace ? aRefChild : aNewChild;
-  }
-  virtual nsresult ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
-                                         nsINode* aRefChild);
+  nsINode* ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
+                                 nsINode* aRefChild,
+                                 mozilla::ErrorResult& aError);
   nsresult RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn);
 
   /**
    * Returns the Element that should be used for resolving namespaces
    * on this node (ie the ownerElement for attributes, the documentElement for
    * documents, the node itself for elements and for other nodes the parentNode
    * if it is an element).
    */
@@ -1727,10 +1805,191 @@ extern const nsIID kThisPtrOffsetsSID;
     NS_INTERFACE_TABLE_ENTRY(_class, _i8)                                     \
     NS_INTERFACE_TABLE_ENTRY(_class, _i9)                                     \
   NS_OFFSET_AND_INTERFACE_TABLE_END                                           \
   NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
 
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsINode, NS_INODE_IID)
 
+#define NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER(_final) \
+  NS_IMETHOD GetNodeName(nsAString& aNodeName) _final \
+  { \
+    nsINode::GetNodeName(aNodeName); \
+    return NS_OK; \
+  } \
+  NS_IMETHOD GetNodeValue(nsAString& aNodeValue) _final \
+  { \
+    nsINode::GetNodeValue(aNodeValue); \
+    return NS_OK; \
+  } \
+  NS_IMETHOD SetNodeValue(const nsAString& aNodeValue) _final \
+  { \
+    mozilla::ErrorResult rv; \
+    nsINode::SetNodeValue(aNodeValue, rv); \
+    return rv.ErrorCode(); \
+  } \
+  NS_IMETHOD GetNodeType(uint16_t* aNodeType) _final \
+  { \
+    *aNodeType = nsINode::NodeType(); \
+    return NS_OK; \
+  } \
+  NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode) _final \
+  { \
+    return nsINode::GetParentNode(aParentNode); \
+  } \
+  NS_IMETHOD GetParentElement(nsIDOMElement** aParentElement) _final \
+  { \
+    return nsINode::GetParentElement(aParentElement); \
+  } \
+  NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes) _final \
+  { \
+    return nsINode::GetChildNodes(aChildNodes); \
+  } \
+  NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild) _final \
+  { \
+    return nsINode::GetFirstChild(aFirstChild); \
+  } \
+  NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild) _final \
+  { \
+    return nsINode::GetLastChild(aLastChild); \
+  } \
+  NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling) _final \
+  { \
+    return nsINode::GetPreviousSibling(aPreviousSibling); \
+  } \
+  NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling) _final \
+  { \
+    return nsINode::GetNextSibling(aNextSibling); \
+  } \
+  NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes) _final \
+  { \
+    return nsINode::GetAttributes(aAttributes); \
+  } \
+  NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument) _final \
+  { \
+    return nsINode::GetOwnerDocument(aOwnerDocument); \
+  } \
+  NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aResult) _final \
+  { \
+    return ReplaceOrInsertBefore(false, aNewChild, aRefChild, aResult); \
+  } \
+  NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aResult) _final \
+  { \
+    return ReplaceOrInsertBefore(true, aNewChild, aOldChild, aResult); \
+  } \
+  NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aResult) _final \
+  { \
+    return nsINode::RemoveChild(aOldChild, aResult); \
+  } \
+  NS_IMETHOD AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aResult) _final \
+  { \
+    return InsertBefore(aNewChild, nullptr, aResult); \
+  } \
+  NS_IMETHOD HasChildNodes(bool* aResult) _final \
+  { \
+    *aResult = nsINode::HasChildNodes(); \
+    return NS_OK; \
+  } \
+  NS_IMETHOD CloneNode(bool aDeep, uint8_t aArgc, nsIDOMNode** aResult) _final \
+  { \
+    if (aArgc == 0) { \
+      aDeep = true; \
+    } \
+    mozilla::ErrorResult rv; \
+    nsCOMPtr<nsINode> clone = nsINode::CloneNode(aDeep, rv); \
+    if (rv.Failed()) { \
+      return rv.ErrorCode(); \
+    } \
+    *aResult = clone.forget().get()->AsDOMNode(); \
+    return NS_OK; \
+  } \
+  NS_IMETHOD Normalize() _final \
+  { \
+    nsINode::Normalize(); \
+    return NS_OK; \
+  } \
+  NS_IMETHOD IsSupported(const nsAString& aFeature, const nsAString& aVersion, bool* aResult) _final \
+  { \
+    *aResult = nsINode::IsSupported(aFeature, aVersion); \
+    return NS_OK; \
+  } \
+  NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI) _final \
+  { \
+    mozilla::ErrorResult rv; \
+    nsINode::GetNamespaceURI(aNamespaceURI, rv); \
+    return rv.ErrorCode(); \
+  } \
+  NS_IMETHOD GetPrefix(nsAString& aPrefix) _final \
+  { \
+    nsINode::GetPrefix(aPrefix); \
+    return NS_OK; \
+  } \
+  NS_IMETHOD GetLocalName(nsAString& aLocalName) _final \
+  { \
+    nsINode::GetLocalName(aLocalName); \
+    return NS_OK; \
+  } \
+  using nsINode::HasAttributes; \
+  NS_IMETHOD HasAttributes(bool* aResult) _final \
+  { \
+    *aResult = nsINode::HasAttributes(); \
+    return NS_OK; \
+  } \
+  NS_IMETHOD GetDOMBaseURI(nsAString& aBaseURI) _final \
+  { \
+    nsINode::GetBaseURI(aBaseURI); \
+    return NS_OK; \
+  } \
+  NS_IMETHOD CompareDocumentPosition(nsIDOMNode* aOther, uint16_t* aResult) _final \
+  { \
+    return nsINode::CompareDocumentPosition(aOther, aResult); \
+  } \
+  NS_IMETHOD GetTextContent(nsAString& aTextContent) _final \
+  { \
+    nsINode::GetTextContent(aTextContent); \
+    return NS_OK; \
+  } \
+  NS_IMETHOD SetTextContent(const nsAString& aTextContent) _final \
+  { \
+    mozilla::ErrorResult rv; \
+    nsINode::SetTextContent(aTextContent, rv); \
+    return rv.ErrorCode(); \
+  } \
+  NS_IMETHOD LookupPrefix(const nsAString& aNamespaceURI, nsAString& aResult) _final \
+  { \
+    nsINode::LookupPrefix(aNamespaceURI, aResult); \
+    return NS_OK; \
+  } \
+  NS_IMETHOD IsDefaultNamespace(const nsAString& aNamespaceURI, bool* aResult) _final \
+  { \
+    *aResult = nsINode::IsDefaultNamespace(aNamespaceURI); \
+    return NS_OK; \
+  } \
+  NS_IMETHOD LookupNamespaceURI(const nsAString& aPrefix, nsAString& aResult) _final \
+  { \
+    nsINode::LookupNamespaceURI(aPrefix, aResult); \
+    return NS_OK; \
+  } \
+  NS_IMETHOD IsEqualNode(nsIDOMNode* aArg, bool* aResult) _final \
+  { \
+    return nsINode::IsEqualNode(aArg, aResult); \
+  } \
+  NS_IMETHOD SetUserData(const nsAString& aKey, nsIVariant* aData, nsIDOMUserDataHandler* aHandler, nsIVariant** aResult) _final \
+  { \
+    return nsINode::SetUserData(aKey, aData, aHandler, aResult); \
+  } \
+  NS_IMETHOD GetUserData(const nsAString& aKey, nsIVariant** aResult) _final \
+  { \
+    return nsINode::GetUserData(aKey, aResult); \
+  } \
+  NS_IMETHOD Contains(nsIDOMNode* aOther, bool* aResult) _final \
+  { \
+    return nsINode::Contains(aOther, aResult); \
+  }
+
+#define NS_FORWARD_NSIDOMNODE_TO_NSINODE \
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER(MOZ_FINAL)
+
+#define NS_FORWARD_NSIDOMNODE_TO_NSINODE_OVERRIDABLE \
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER()
 
 #endif /* nsINode_h___ */
--- a/content/base/src/FragmentOrElement.cpp
+++ b/content/base/src/FragmentOrElement.cpp
@@ -449,17 +449,18 @@ NS_INTERFACE_MAP_END_AGGREGATED(mNode)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsNode3Tearoff)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsNode3Tearoff)
 
 NS_IMETHODIMP
 nsNode3Tearoff::LookupNamespaceURI(const nsAString& aNamespacePrefix,
                                    nsAString& aNamespaceURI)
 {
-  return mNode->LookupNamespaceURI(aNamespacePrefix, aNamespaceURI);
+  mNode->LookupNamespaceURI(aNamespacePrefix, aNamespaceURI);
+  return NS_OK;
 }
 
 nsContentList*
 FragmentOrElement::GetChildrenList()
 {
   FragmentOrElement::nsDOMSlots *slots = DOMSlots();
 
   if (!slots->mChildrenList) {
@@ -634,100 +635,16 @@ FragmentOrElement::~FragmentOrElement()
 {
   NS_PRECONDITION(!IsInDoc(),
                   "Please remove this from the document properly");
   if (GetParent()) {
     NS_RELEASE(mParent);
   }
 }
 
-NS_IMETHODIMP
-FragmentOrElement::GetNodeName(nsAString& aNodeName)
-{
-  aNodeName = NodeName();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-FragmentOrElement::GetLocalName(nsAString& aLocalName)
-{
-  aLocalName = LocalName();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-FragmentOrElement::GetNodeValue(nsAString& aNodeValue)
-{
-  SetDOMStringToNull(aNodeValue);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-FragmentOrElement::SetNodeValue(const nsAString& aNodeValue)
-{
-  // The DOM spec says that when nodeValue is defined to be null "setting it
-  // has no effect", so we don't throw an exception.
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-FragmentOrElement::GetNodeType(uint16_t* aNodeType)
-{
-  *aNodeType = NodeType();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-FragmentOrElement::GetNamespaceURI(nsAString& aNamespaceURI)
-{
-  return mNodeInfo->GetNamespaceURI(aNamespaceURI);
-}
-
-NS_IMETHODIMP
-FragmentOrElement::GetPrefix(nsAString& aPrefix)
-{
-  mNodeInfo->GetPrefix(aPrefix);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-FragmentOrElement::IsSupported(const nsAString& aFeature,
-                               const nsAString& aVersion,
-                               bool* aReturn)
-{
-  *aReturn = nsContentUtils::InternalIsSupported(this, aFeature, aVersion);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-FragmentOrElement::HasAttributes(bool* aReturn)
-{
-  NS_ENSURE_ARG_POINTER(aReturn);
-
-  *aReturn = GetAttrCount() > 0;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-FragmentOrElement::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
-{
-  *aAttributes = nullptr;
-  return NS_OK;
-}
-
-nsresult
-FragmentOrElement::HasChildNodes(bool* aReturn)
-{
-  *aReturn = mAttrsAndChildren.ChildCount() > 0;
-
-  return NS_OK;
-}
-
 already_AddRefed<nsINodeList>
 FragmentOrElement::GetChildren(uint32_t aFilter)
 {
   nsRefPtr<nsSimpleContentList> list = new nsSimpleContentList(this);
   if (!list) {
     return nullptr;
   }
 
@@ -746,17 +663,17 @@ FragmentOrElement::GetChildren(uint32_t 
   // anonymous content, otherwise append explicit content with respect to
   // insertion point if any.
   nsINodeList *childList = nullptr;
 
   nsIDocument* document = OwnerDoc();
   if (!(aFilter & eAllButXBL)) {
     childList = document->BindingManager()->GetXBLChildNodesFor(this);
     if (!childList) {
-      childList = GetChildNodesList();
+      childList = ChildNodes();
     }
 
   } else {
     childList = document->BindingManager()->GetContentListFor(this);
   }
 
   if (childList) {
     uint32_t length = 0;
@@ -973,27 +890,27 @@ FragmentOrElement::RemoveChildAt(uint32_
   nsCOMPtr<nsIContent> oldKid = mAttrsAndChildren.GetSafeChildAt(aIndex);
   NS_ASSERTION(oldKid == GetChildAt(aIndex), "Unexpected child in RemoveChildAt");
 
   if (oldKid) {
     doRemoveChildAt(aIndex, aNotify, oldKid, mAttrsAndChildren);
   }
 }
 
-NS_IMETHODIMP
-FragmentOrElement::GetTextContent(nsAString &aTextContent)
+void
+FragmentOrElement::GetTextContentInternal(nsAString& aTextContent)
 {
   nsContentUtils::GetNodeTextContent(this, true, aTextContent);
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-FragmentOrElement::SetTextContent(const nsAString& aTextContent)
+void
+FragmentOrElement::SetTextContentInternal(const nsAString& aTextContent,
+                                          ErrorResult& aError)
 {
-  return nsContentUtils::SetNodeTextContent(this, aTextContent, false);
+  aError = nsContentUtils::SetNodeTextContent(this, aTextContent, false);
 }
 
 void
 FragmentOrElement::DestroyContent()
 {
   nsIDocument *document = OwnerDoc();
   document->BindingManager()->RemovedFromDocument(this, document);
   document->ClearBoxObjectFor(this);
@@ -1203,17 +1120,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Fr
     nsDOMSlots *slots = tmp->GetExistingDOMSlots();
     if (slots) {
       slots->Unlink(tmp->IsXUL());
     }
   }
 
   {
     nsIDocument *doc;
-    if (!tmp->GetNodeParent() && (doc = tmp->OwnerDoc())) {
+    if (!tmp->GetParentNode() && (doc = tmp->OwnerDoc())) {
       doc->BindingManager()->RemovedFromDocument(tmp, doc);
     }
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(FragmentOrElement)
   nsINode::Trace(tmp, aCallback, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
@@ -1254,17 +1171,17 @@ FragmentOrElement::MarkNodeChildren(nsIN
                 &nsCCUncollectableMarker::sGeneration);
   }
 }
 
 nsINode*
 FindOptimizableSubtreeRoot(nsINode* aNode)
 {
   nsINode* p;
-  while ((p = aNode->GetNodeParent())) {
+  while ((p = aNode->GetParentNode())) {
     if (aNode->UnoptimizableCCNode()) {
       return nullptr;
     }
     aNode = p;
   }
   
   if (aNode->UnoptimizableCCNode()) {
     return nullptr;
@@ -1883,17 +1800,17 @@ FragmentOrElement::FireNodeRemovedForChi
         HasMutationListeners(doc, NS_EVENT_BITS_MUTATION_NODEREMOVED)) {
     return;
   }
 
   nsCOMPtr<nsIDocument> owningDoc = doc;
 
   nsCOMPtr<nsINode> child;
   for (child = GetFirstChild();
-       child && child->GetNodeParent() == this;
+       child && child->GetParentNode() == this;
        child = child->GetNextSibling()) {
     nsContentUtils::MaybeFireNodeRemoved(child, this, doc);
   }
 }
 
 size_t
 FragmentOrElement::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
 {
--- a/content/base/src/nsCommentNode.cpp
+++ b/content/base/src/nsCommentNode.cpp
@@ -19,17 +19,17 @@ class nsCommentNode : public nsGenericDO
 public:
   nsCommentNode(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsCommentNode();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericDOMDataNode::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMCharacterData
   NS_FORWARD_NSIDOMCHARACTERDATA(nsGenericDOMDataNode::)
 
   // nsIDOMComment
   // Empty interface
 
   // nsINode
--- a/content/base/src/nsContentIterator.cpp
+++ b/content/base/src/nsContentIterator.cpp
@@ -20,17 +20,17 @@
 // NodeToParentOffset: returns the node's parent and offset.
 //
 
 static nsINode*
 NodeToParentOffset(nsINode* aNode, int32_t* aOffset)
 {
   *aOffset = 0;
 
-  nsINode* parent = aNode->GetNodeParent();
+  nsINode* parent = aNode->GetParentNode();
 
   if (parent) {
     *aOffset = parent->IndexOf(aNode);
   }
 
   return parent;
 }
 
@@ -49,17 +49,17 @@ NodeIsInTraversalRange(nsINode* aNode, b
 
   // If a chardata node contains an end point of the traversal range, it is
   // always in the traversal range.
   if (aNode->IsNodeOfType(nsINode::eDATA_NODE) &&
       (aNode == aStartNode || aNode == aEndNode)) {
     return true;
   }
 
-  nsINode* parent = aNode->GetNodeParent();
+  nsINode* parent = aNode->GetParentNode();
   if (!parent) {
     return false;
   }
 
   int32_t indx = parent->IndexOf(aNode);
 
   if (!aIsPreMode) {
     ++indx;
@@ -456,17 +456,17 @@ nsContentIterator::RebuildIndexStack()
 
   mIndexes.Clear();
   current = mCurNode;
   if (!current) {
     return NS_OK;
   }
 
   while (current != mCommonParent) {
-    parent = current->GetNodeParent();
+    parent = current->GetParentNode();
 
     if (!parent) {
       return NS_ERROR_FAILURE;
     }
 
     mIndexes.InsertElementAt(0, parent->IndexOf(current));
 
     current = parent;
@@ -570,17 +570,17 @@ nsContentIterator::GetDeepLastChild(nsIC
 nsIContent*
 nsContentIterator::GetNextSibling(nsINode* aNode,
                                   nsTArray<int32_t>* aIndexes)
 {
   if (!aNode) {
     return nullptr;
   }
 
-  nsINode* parent = aNode->GetNodeParent();
+  nsINode* parent = aNode->GetParentNode();
   if (!parent) {
     return nullptr;
   }
 
   int32_t indx = 0;
 
   NS_ASSERTION(!aIndexes || !aIndexes->IsEmpty(),
                "ContentIterator stack underflow");
@@ -631,17 +631,17 @@ nsContentIterator::GetNextSibling(nsINod
 nsIContent*
 nsContentIterator::GetPrevSibling(nsINode* aNode,
                                   nsTArray<int32_t>* aIndexes)
 {
   if (!aNode) {
     return nullptr;
   }
 
-  nsINode* parent = aNode->GetNodeParent();
+  nsINode* parent = aNode->GetParentNode();
   if (!parent) {
     return nullptr;
   }
 
   int32_t indx = 0;
 
   NS_ASSERTION(!aIndexes || !aIndexes->IsEmpty(),
                "ContentIterator stack underflow");
@@ -701,17 +701,17 @@ nsContentIterator::NextNode(nsINode* aNo
       return firstChild;
     }
 
     // else next sibling is next
     return GetNextSibling(node, aIndexes);
   }
 
   // post-order
-  nsINode* parent = node->GetNodeParent();
+  nsINode* parent = node->GetParentNode();
   nsIContent* sibling = nullptr;
   int32_t indx = 0;
 
   // get the cached index
   NS_ASSERTION(!aIndexes || !aIndexes->IsEmpty(),
                "ContentIterator stack underflow");
   if (aIndexes && !aIndexes->IsEmpty()) {
     // use the last entry on the Indexes array for the current index
@@ -764,17 +764,17 @@ nsContentIterator::NextNode(nsINode* aNo
 
 nsINode*
 nsContentIterator::PrevNode(nsINode* aNode, nsTArray<int32_t>* aIndexes)
 {
   nsINode* node = aNode;
 
   // if we are a Pre-order iterator, use pre-order
   if (mPre) {
-    nsINode* parent = node->GetNodeParent();
+    nsINode* parent = node->GetParentNode();
     nsIContent* sibling = nullptr;
     int32_t indx = 0;
 
     // get the cached index
     NS_ASSERTION(!aIndexes || !aIndexes->IsEmpty(),
                  "ContentIterator stack underflow");
     if (aIndexes && !aIndexes->IsEmpty()) {
       // use the last entry on the Indexes array for the current index
@@ -999,17 +999,17 @@ nsContentIterator::PositionAt(nsINode* a
   // We want to loop mIndexes.Length() + 1 times here, because we want to make
   // sure we include mCommonParent in the oldParentStack, for use in the next
   // for loop, and mIndexes only has entries for nodes from tempNode up through
   // an ancestor of tempNode that's a child of mCommonParent.
   for (int32_t i = mIndexes.Length() + 1; i > 0 && tempNode; i--) {
     // Insert at head since we're walking up
     oldParentStack.InsertElementAt(0, tempNode);
 
-    nsINode* parent = tempNode->GetNodeParent();
+    nsINode* parent = tempNode->GetParentNode();
 
     if (!parent) {
       // this node has no parent, and thus no index
       break;
     }
 
     if (parent == mCurNode) {
       // The position was moved to a parent of the current position.  All we
@@ -1019,17 +1019,17 @@ nsContentIterator::PositionAt(nsINode* a
       mIsDone = false;
       return NS_OK;
     }
     tempNode = parent;
   }
 
   // Ok.  We have the array of old parents.  Look for a match.
   while (newCurNode) {
-    nsINode* parent = newCurNode->GetNodeParent();
+    nsINode* parent = newCurNode->GetParentNode();
 
     if (!parent) {
       // this node has no parent, and thus no index
       break;
     }
 
     int32_t indx = parent->IndexOf(newCurNode);
 
@@ -1417,17 +1417,17 @@ nsContentSubtreeIterator::PositionAt(nsI
 
 /****************************************************************
  * nsContentSubtreeIterator helper routines
  ****************************************************************/
 
 nsIContent*
 nsContentSubtreeIterator::GetTopAncestorInRange(nsINode* aNode)
 {
-  if (!aNode || !aNode->GetNodeParent()) {
+  if (!aNode || !aNode->GetParentNode()) {
     return nullptr;
   }
 
   // aNode has a parent, so it must be content.
   nsIContent* content = aNode->AsContent();
 
   // sanity check: aNode is itself in the range
   bool nodeBefore, nodeAfter;
@@ -1442,17 +1442,17 @@ nsContentSubtreeIterator::GetTopAncestor
   while (content) {
     nsIContent* parent = content->GetParent();
     // content always has a parent.  If its parent is the root, however --
     // i.e., either it's not content, or it is content but its own parent is
     // null -- then we're finished, since we don't go up to the root.
     //
     // We have to special-case this because CompareNodeToRange treats the root
     // node differently -- see bug 765205.
-    if (!parent || !parent->GetNodeParent()) {
+    if (!parent || !parent->GetParentNode()) {
       return content;
     }
     MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
       nsRange::CompareNodeToRange(parent, mRange, &nodeBefore, &nodeAfter)));
 
     if (nodeBefore || nodeAfter) {
       return content;
     }
--- a/content/base/src/nsContentList.cpp
+++ b/content/base/src/nsContentList.cpp
@@ -409,30 +409,19 @@ GetFuncStringContentList(nsINode* aRootN
     }
   }
 
   if (!list) {
     // We need to create a ContentList and add it to our new entry, if
     // we have an entry
     list = new ListType(aRootNode, aFunc, aDestroyFunc, aDataAllocator,
                         aString);
-    if (list && !list->AllocatedData()) {
-      // Failed to allocate the data
-      delete list;
-      list = nullptr;
+    if (entry) {
+      entry->mContentList = list;
     }
-
-    if (entry) {
-      if (list)
-        entry->mContentList = list;
-      else
-        PL_DHashTableRawRemove(&gContentListHashTable, entry);
-    }
-
-    NS_ENSURE_TRUE(list, nullptr);
   }
 
   NS_ADDREF(list);
 
   // Don't cache these lists globally
 
   return list;
 }
@@ -739,17 +728,17 @@ nsContentList::NamedItem(JSContext* cx, 
 void
 nsContentList::AttributeChanged(nsIDocument *aDocument, Element* aElement,
                                 int32_t aNameSpaceID, nsIAtom* aAttribute,
                                 int32_t aModType)
 {
   NS_PRECONDITION(aElement, "Must have a content node to work with");
   
   if (!mFunc || !mFuncMayDependOnAttr || mState == LIST_DIRTY ||
-      !MayContainRelevantNodes(aElement->GetNodeParent()) ||
+      !MayContainRelevantNodes(aElement->GetParentNode()) ||
       !nsContentUtils::IsInSameAnonymousTree(mRootNode, aElement)) {
     // Either we're already dirty or this notification doesn't affect
     // whether we might match aElement.
     return;
   }
   
   if (Match(aElement)) {
     if (mElements.IndexOf(aElement) == mElements.NoIndex) {
@@ -938,17 +927,17 @@ nsContentList::Match(Element *aElement)
   return matchHTML ? ni->Equals(mHTMLMatchAtom, mMatchNameSpaceId) :
                      ni->Equals(mXMLMatchAtom, mMatchNameSpaceId);
 }
 
 bool 
 nsContentList::MatchSelf(nsIContent *aContent)
 {
   NS_PRECONDITION(aContent, "Can't match null stuff, you know");
-  NS_PRECONDITION(mDeep || aContent->GetNodeParent() == mRootNode,
+  NS_PRECONDITION(mDeep || aContent->GetParentNode() == mRootNode,
                   "MatchSelf called on a node that we can't possibly match");
 
   if (!aContent->IsElement()) {
     return false;
   }
   
   if (Match(aContent->AsElement()))
     return true;
--- a/content/base/src/nsContentList.h
+++ b/content/base/src/nsContentList.h
@@ -474,27 +474,26 @@ private:
  * A function that allocates the matching data for this
  * FuncStringContentList.  Returning aString is perfectly fine; in
  * that case the destructor function should be a no-op.
  */
 typedef void* (*nsFuncStringContentListDataAllocator)(nsINode* aRootNode,
                                                       const nsString* aString);
 
 // aDestroyFunc is allowed to be null
+// aDataAllocator must always return a non-null pointer
 class nsCacheableFuncStringContentList : public nsContentList {
 public:
   virtual ~nsCacheableFuncStringContentList();
 
   bool Equals(const nsFuncStringCacheKey* aKey) {
     return mRootNode == aKey->mRootNode && mFunc == aKey->mFunc &&
       mString == aKey->mString;
   }
 
-  bool AllocatedData() const { return !!mData; }
-
 #ifdef DEBUG
   enum ContentListType {
     eNodeList,
     eHTMLCollection
   };
   ContentListType mType;
 #endif
 
@@ -503,16 +502,17 @@ protected:
                                    nsContentListMatchFunc aFunc,
                                    nsContentListDestroyFunc aDestroyFunc,
                                    nsFuncStringContentListDataAllocator aDataAllocator,
                                    const nsAString& aString) :
     nsContentList(aRootNode, aFunc, aDestroyFunc, nullptr),
     mString(aString)
   {
     mData = (*aDataAllocator)(aRootNode, &mString);
+    MOZ_ASSERT(mData);
   }
 
   virtual void RemoveFromCaches() {
     RemoveFromFuncStringHashtable();
   }
   void RemoveFromFuncStringHashtable();
 
   nsString mString;
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -39,17 +39,16 @@
 #include "nsPIDOMWindow.h"
 #include "nsIJSContextStack.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsParserCIID.h"
 #include "nsIParser.h"
 #include "nsIFragmentContentSink.h"
 #include "nsIContentSink.h"
-#include "nsContentList.h"
 #include "nsIHTMLDocument.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIForm.h"
 #include "nsIFormControl.h"
 #include "nsGkAtoms.h"
 #include "imgINotificationObserver.h"
 #include "imgIRequest.h"
@@ -1671,17 +1670,17 @@ nsContentUtils::CanCallerAccess(nsPIDOMW
 }
 
 //static
 bool
 nsContentUtils::InProlog(nsINode *aNode)
 {
   NS_PRECONDITION(aNode, "missing node to nsContentUtils::InProlog");
 
-  nsINode* parent = aNode->GetNodeParent();
+  nsINode* parent = aNode->GetParentNode();
   if (!parent || !parent->IsNodeOfType(nsINode::eDOCUMENT)) {
     return false;
   }
 
   nsIDocument* doc = static_cast<nsIDocument*>(parent);
   nsIContent* root = doc->GetRootElement();
 
   return !root || doc->IndexOf(aNode) < doc->IndexOf(root);
@@ -1807,17 +1806,17 @@ nsContentUtils::IsImageSrcSetDisabled()
 }
 
 // static
 nsINode*
 nsContentUtils::GetCrossDocParentNode(nsINode* aChild)
 {
   NS_PRECONDITION(aChild, "The child is null!");
 
-  nsINode* parent = aChild->GetNodeParent();
+  nsINode* parent = aChild->GetParentNode();
   if (parent || !aChild->IsNodeOfType(nsINode::eDOCUMENT))
     return parent;
 
   nsIDocument* doc = static_cast<nsIDocument*>(aChild);
   nsIDocument* parentDoc = doc->GetParentDocument();
   return parentDoc ? parentDoc->FindContentForSubDocument(doc) : nullptr;
 }
 
@@ -1827,17 +1826,17 @@ nsContentUtils::ContentIsDescendantOf(co
                                       const nsINode* aPossibleAncestor)
 {
   NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!");
   NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!");
 
   do {
     if (aPossibleDescendant == aPossibleAncestor)
       return true;
-    aPossibleDescendant = aPossibleDescendant->GetNodeParent();
+    aPossibleDescendant = aPossibleDescendant->GetParentNode();
   } while (aPossibleDescendant);
 
   return false;
 }
 
 // static
 bool
 nsContentUtils::ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant,
@@ -1858,17 +1857,17 @@ nsContentUtils::ContentIsCrossDocDescend
 
 // static
 nsresult
 nsContentUtils::GetAncestors(nsINode* aNode,
                              nsTArray<nsINode*>& aArray)
 {
   while (aNode) {
     aArray.AppendElement(aNode);
-    aNode = aNode->GetNodeParent();
+    aNode = aNode->GetParentNode();
   }
   return NS_OK;
 }
 
 // static
 nsresult
 nsContentUtils::GetAncestorsAndOffsets(nsIDOMNode* aNode,
                                        int32_t aOffset,
@@ -1937,21 +1936,21 @@ nsContentUtils::GetCommonAncestor(nsINod
   if (aNode1 == aNode2) {
     return aNode1;
   }
 
   // Build the chain of parents
   nsAutoTArray<nsINode*, 30> parents1, parents2;
   do {
     parents1.AppendElement(aNode1);
-    aNode1 = aNode1->GetNodeParent();
+    aNode1 = aNode1->GetParentNode();
   } while (aNode1);
   do {
     parents2.AppendElement(aNode2);
-    aNode2 = aNode2->GetNodeParent();
+    aNode2 = aNode2->GetParentNode();
   } while (aNode2);
 
   // Find where the parent chain differs
   uint32_t pos1 = parents1.Length();
   uint32_t pos2 = parents2.Length();
   nsINode* parent = nullptr;
   uint32_t len;
   for (len = NS_MIN(pos1, pos2); len > 0; --len) {
@@ -1978,21 +1977,21 @@ nsContentUtils::ComparePoints(nsINode* a
            0;
   }
 
   nsAutoTArray<nsINode*, 32> parents1, parents2;
   nsINode* node1 = aParent1;
   nsINode* node2 = aParent2;
   do {
     parents1.AppendElement(node1);
-    node1 = node1->GetNodeParent();
+    node1 = node1->GetParentNode();
   } while (node1);
   do {
     parents2.AppendElement(node2);
-    node2 = node2->GetNodeParent();
+    node2 = node2->GetParentNode();
   } while (node2);
 
   uint32_t pos1 = parents1.Length() - 1;
   uint32_t pos2 = parents2.Length() - 1;
   
   bool disconnected = parents1.ElementAt(pos1) != parents2.ElementAt(pos2);
   if (aDisconnected) {
     *aDisconnected = disconnected;
@@ -2336,22 +2335,22 @@ nsContentUtils::GenerateStateKey(nsICont
       // Append a character that is not "d" or "f" to disambiguate from
       // the case when we were a form control in an HTML document.
       KeyAppendString(NS_LITERAL_CSTRING("o"), aKey);
     }
 
     // Now start at aContent and append the indices of it and all its ancestors
     // in their containers.  That should at least pin down its position in the
     // DOM...
-    nsINode* parent = aContent->GetNodeParent();
+    nsINode* parent = aContent->GetParentNode();
     nsINode* content = aContent;
     while (parent) {
       KeyAppendInt(parent->IndexOf(content), aKey);
       content = parent;
-      parent = content->GetNodeParent();
+      parent = content->GetParentNode();
     }
   }
 
   return NS_OK;
 }
 
 // static
 nsIPrincipal*
@@ -3854,17 +3853,17 @@ nsContentUtils::HasMutationListeners(nsI
       nsIContent* content = static_cast<nsIContent*>(aNode);
       nsIContent* insertionParent =
         doc->BindingManager()->GetInsertionParent(content);
       if (insertionParent) {
         aNode = insertionParent;
         continue;
       }
     }
-    aNode = aNode->GetNodeParent();
+    aNode = aNode->GetParentNode();
   }
 
   return false;
 }
 
 /* static */
 bool
 nsContentUtils::HasMutationListeners(nsIDocument* aDocument,
@@ -3878,17 +3877,17 @@ nsContentUtils::HasMutationListeners(nsI
   return !window || window->HasMutationListeners(aType);
 }
 
 void
 nsContentUtils::MaybeFireNodeRemoved(nsINode* aChild, nsINode* aParent,
                                      nsIDocument* aOwnerDoc)
 {
   NS_PRECONDITION(aChild, "Missing child");
-  NS_PRECONDITION(aChild->GetNodeParent() == aParent, "Wrong parent");
+  NS_PRECONDITION(aChild->GetParentNode() == aParent, "Wrong parent");
   NS_PRECONDITION(aChild->OwnerDoc() == aOwnerDoc, "Wrong owner-doc");
 
   // This checks that IsSafeToRunScript is true since we don't want to fire
   // events when that is false. We can't rely on nsEventDispatcher to assert
   // this in this situation since most of the time there are no mutation
   // event listeners, in which case we won't even attempt to dispatch events.
   // However this also allows for two exceptions. First off, we don't assert
   // if the mutation happens to native anonymous content since we never fire
@@ -4378,17 +4377,17 @@ nsContentUtils::SetNodeTextContent(nsICo
 
     // Optimize the common case of there being no observers
     if (HasMutationListeners(doc, NS_EVENT_BITS_MUTATION_NODEREMOVED)) {
       subtree.UpdateTarget(doc, nullptr);
       owningContent = aContent;
       nsCOMPtr<nsINode> child;
       bool skipFirst = aTryReuse;
       for (child = aContent->GetFirstChild();
-           child && child->GetNodeParent() == aContent;
+           child && child->GetParentNode() == aContent;
            child = child->GetNextSibling()) {
         if (skipFirst && child->IsNodeOfType(nsINode::eTEXT)) {
           skipFirst = false;
           continue;
         }
         nsContentUtils::MaybeFireNodeRemoved(child, aContent, doc);
       }
     }
@@ -6240,19 +6239,20 @@ nsContentUtils::StripNullChars(const nsA
   }
 }
 
 struct ClassMatchingInfo {
   nsAttrValue::AtomArray mClasses;
   nsCaseTreatment mCaseTreatment;
 };
 
-static bool
-MatchClassNames(nsIContent* aContent, int32_t aNamespaceID, nsIAtom* aAtom,
-                void* aData)
+// static
+bool
+nsContentUtils::MatchClassNames(nsIContent* aContent, int32_t aNamespaceID,
+                                nsIAtom* aAtom, void* aData)
 {
   // We can't match if there are no class names
   const nsAttrValue* classAttr = aContent->GetClasses();
   if (!classAttr) {
     return false;
   }
   
   // need to match *all* of the classes
@@ -6268,67 +6268,47 @@ MatchClassNames(nsIContent* aContent, in
                              info->mCaseTreatment)) {
       return false;
     }
   }
   
   return true;
 }
 
-static void
-DestroyClassNameArray(void* aData)
+// static
+void
+nsContentUtils::DestroyClassNameArray(void* aData)
 {
   ClassMatchingInfo* info = static_cast<ClassMatchingInfo*>(aData);
   delete info;
 }
 
-static void*
-AllocClassMatchingInfo(nsINode* aRootNode,
-                       const nsString* aClasses)
+// static
+void*
+nsContentUtils::AllocClassMatchingInfo(nsINode* aRootNode,
+                                       const nsString* aClasses)
 {
   nsAttrValue attrValue;
   attrValue.ParseAtomArray(*aClasses);
   // nsAttrValue::Equals is sensitive to order, so we'll send an array
   ClassMatchingInfo* info = new ClassMatchingInfo;
-  NS_ENSURE_TRUE(info, nullptr);
-
   if (attrValue.Type() == nsAttrValue::eAtomArray) {
     info->mClasses.SwapElements(*(attrValue.GetAtomArrayValue()));
   } else if (attrValue.Type() == nsAttrValue::eAtom) {
     info->mClasses.AppendElement(attrValue.GetAtomValue());
   }
 
   info->mCaseTreatment =
     aRootNode->OwnerDoc()->GetCompatibilityMode() == eCompatibility_NavQuirks ?
     eIgnoreCase : eCaseMatters;
   return info;
 }
 
 // static
 
-nsresult
-nsContentUtils::GetElementsByClassName(nsINode* aRootNode,
-                                       const nsAString& aClasses,
-                                       nsIDOMNodeList** aReturn)
-{
-  NS_PRECONDITION(aRootNode, "Must have root node");
-  
-  nsContentList* elements =
-    NS_GetFuncStringHTMLCollection(aRootNode, MatchClassNames,
-                                   DestroyClassNameArray,
-                                   AllocClassMatchingInfo,
-                                   aClasses).get();
-  NS_ENSURE_TRUE(elements, NS_ERROR_OUT_OF_MEMORY);
-
-  // Transfer ownership
-  *aReturn = elements;
-
-  return NS_OK;
-}
-
 #ifdef DEBUG
 class DebugWrapperTraversalCallback : public nsCycleCollectionTraversalCallback
 {
 public:
   DebugWrapperTraversalCallback(void* aWrapper) : mFound(false),
                                                   mWrapper(aWrapper)
   {
     mFlags = WANT_ALL_TRACES;
--- a/content/base/src/nsCrossSiteListenerProxy.cpp
+++ b/content/base/src/nsCrossSiteListenerProxy.cpp
@@ -1,30 +1,32 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "mozilla/Assertions.h"
+#include "mozilla/LinkedList.h"
+
 #include "nsCrossSiteListenerProxy.h"
 #include "nsIChannel.h"
 #include "nsIHttpChannel.h"
 #include "nsError.h"
 #include "nsContentUtils.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsNetUtil.h"
 #include "nsMimeTypes.h"
 #include "nsIStreamConverterService.h"
 #include "nsStringStream.h"
 #include "nsGkAtoms.h"
 #include "nsWhitespaceTokenizer.h"
 #include "nsIChannelEventSink.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsAsyncRedirectVerifyHelper.h"
-#include "prclist.h"
 #include "prtime.h"
 #include "nsClassHashtable.h"
 #include "nsHashKeys.h"
 #include "nsStreamUtils.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 
@@ -40,17 +42,17 @@ class nsPreflightCache
 {
 public:
   struct TokenTime
   {
     nsCString token;
     PRTime expirationTime;
   };
 
-  struct CacheEntry : public PRCList
+  struct CacheEntry : public LinkedListElement<CacheEntry>
   {
     CacheEntry(nsCString& aKey)
       : mKey(aKey)
     {
       MOZ_COUNT_CTOR(nsPreflightCache::CacheEntry);
     }
     
     ~CacheEntry()
@@ -65,17 +67,16 @@ public:
     nsCString mKey;
     nsTArray<TokenTime> mMethods;
     nsTArray<TokenTime> mHeaders;
   };
 
   nsPreflightCache()
   {
     MOZ_COUNT_CTOR(nsPreflightCache);
-    PR_INIT_CLIST(&mList);
   }
 
   ~nsPreflightCache()
   {
     Clear();
     MOZ_COUNT_DTOR(nsPreflightCache);
   }
 
@@ -95,17 +96,17 @@ private:
   static PLDHashOperator
     RemoveExpiredEntries(const nsACString& aKey, nsAutoPtr<CacheEntry>& aValue,
                          void* aUserData);
 
   static bool GetCacheKey(nsIURI* aURI, nsIPrincipal* aPrincipal,
                             bool aWithCredentials, nsACString& _retval);
 
   nsClassHashtable<nsCStringHashKey, CacheEntry> mTable;
-  PRCList mList;
+  LinkedList<CacheEntry> mList;
 };
 
 // Will be initialized in EnsurePreflightCache.
 static nsPreflightCache* sPreflightCache = nullptr;
 
 static bool EnsurePreflightCache()
 {
   if (sPreflightCache)
@@ -183,18 +184,18 @@ nsPreflightCache::GetEntry(nsIURI* aURI,
   }
 
   CacheEntry* entry;
 
   if (mTable.Get(key, &entry)) {
     // Entry already existed so just return it. Also update the LRU list.
 
     // Move to the head of the list.
-    PR_REMOVE_LINK(entry);
-    PR_INSERT_LINK(entry, &mList);
+    entry->remove();
+    mList.insertFront(entry);
 
     return entry;
   }
 
   if (!aCreate) {
     return nullptr;
   }
 
@@ -213,71 +214,71 @@ nsPreflightCache::GetEntry(nsIURI* aURI,
   if (mTable.Count() == PREFLIGHT_CACHE_SIZE) {
     // Try to kick out all the expired entries.
     PRTime now = PR_Now();
     mTable.Enumerate(RemoveExpiredEntries, &now);
 
     // If that didn't remove anything then kick out the least recently used
     // entry.
     if (mTable.Count() == PREFLIGHT_CACHE_SIZE) {
-      CacheEntry* lruEntry = static_cast<CacheEntry*>(PR_LIST_TAIL(&mList));
-      PR_REMOVE_LINK(lruEntry);
+      CacheEntry* lruEntry = static_cast<CacheEntry*>(mList.popLast());
+      MOZ_ASSERT(lruEntry);
 
       // This will delete 'lruEntry'.
       mTable.Remove(lruEntry->mKey);
 
       NS_ASSERTION(mTable.Count() == PREFLIGHT_CACHE_SIZE - 1,
                    "Somehow tried to remove an entry that was never added!");
     }
   }
   
   mTable.Put(key, entry);
-  PR_INSERT_LINK(entry, &mList);
+  mList.insertFront(entry);
 
   return entry;
 }
 
 void
 nsPreflightCache::RemoveEntries(nsIURI* aURI, nsIPrincipal* aPrincipal)
 {
   CacheEntry* entry;
   nsCString key;
   if (GetCacheKey(aURI, aPrincipal, true, key) &&
       mTable.Get(key, &entry)) {
-    PR_REMOVE_LINK(entry);
+    entry->remove();
     mTable.Remove(key);
   }
 
   if (GetCacheKey(aURI, aPrincipal, false, key) &&
       mTable.Get(key, &entry)) {
-    PR_REMOVE_LINK(entry);
+    entry->remove();
     mTable.Remove(key);
   }
 }
 
 void
 nsPreflightCache::Clear()
 {
-  PR_INIT_CLIST(&mList);
+  mList.clear();
   mTable.Clear();
 }
 
 /* static */ PLDHashOperator
 nsPreflightCache::RemoveExpiredEntries(const nsACString& aKey,
                                            nsAutoPtr<CacheEntry>& aValue,
                                            void* aUserData)
 {
   PRTime* now = static_cast<PRTime*>(aUserData);
   
   aValue->PurgeExpired(*now);
   
   if (aValue->mHeaders.IsEmpty() &&
       aValue->mMethods.IsEmpty()) {
     // Expired, remove from the list as well as the hash table.
-    PR_REMOVE_LINK(aValue);
+    aValue->remove();
     return PL_DHASH_REMOVE;
   }
   
   return PL_DHASH_NEXT;
 }
 
 /* static */ bool
 nsPreflightCache::GetCacheKey(nsIURI* aURI,
--- a/content/base/src/nsDOMAttribute.cpp
+++ b/content/base/src/nsDOMAttribute.cpp
@@ -24,16 +24,17 @@
 #include "nsNodeUtils.h"
 #include "nsEventListenerManager.h"
 #include "nsTextNode.h"
 #include "mozAutoDocUpdate.h"
 #include "nsMutationEvent.h"
 #include "nsAsyncDOMEvent.h"
 #include "nsWrapperCacheInlines.h"
 
+using namespace mozilla;
 using namespace mozilla::dom;
 
 //----------------------------------------------------------------------
 bool nsDOMAttribute::sInitialized;
 
 nsDOMAttribute::nsDOMAttribute(nsDOMAttributeMap *aAttrMap,
                                already_AddRefed<nsINodeInfo> aNodeInfo,
                                const nsAString   &aValue, bool aNsAware)
@@ -205,177 +206,30 @@ nsDOMAttribute::GetOwnerElement(nsIDOMEl
     return CallQueryInterface(content, aOwnerElement);
   }
 
   *aOwnerElement = nullptr;
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDOMAttribute::GetNodeName(nsAString& aNodeName)
-{
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eNodeName);
-
-  return GetName(aNodeName);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::GetNodeValue(nsAString& aNodeValue)
-{
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eNodeValue);
-
-  return GetValue(aNodeValue);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::SetNodeValue(const nsAString& aNodeValue)
+void
+nsDOMAttribute::GetNodeValueInternal(nsAString& aNodeValue)
 {
   OwnerDoc()->WarnOnceAbout(nsIDocument::eNodeValue);
 
-  return SetValue(aNodeValue);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::GetNodeType(uint16_t* aNodeType)
-{
-  NS_ENSURE_ARG_POINTER(aNodeType);
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eNodeType);
-
-  *aNodeType = (uint16_t)nsIDOMNode::ATTRIBUTE_NODE;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::GetParentNode(nsIDOMNode** aParentNode)
-{
-  NS_ENSURE_ARG_POINTER(aParentNode);
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eParentNode);
-
-  *aParentNode = nullptr;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::GetParentElement(nsIDOMElement** aParentElement)
-{
-  *aParentElement = nullptr;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::GetChildNodes(nsIDOMNodeList** aChildNodes)
-{
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eChildNodes);
-
-  return nsINode::GetChildNodes(aChildNodes);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::HasChildNodes(bool* aHasChildNodes)
-{
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eHasChildNodes);
-
-  *aHasChildNodes = false;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::HasAttributes(bool* aHasAttributes)
-{
-  NS_ENSURE_ARG_POINTER(aHasAttributes);
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eHasAttributes);
-
-  *aHasAttributes = false;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::GetFirstChild(nsIDOMNode** aFirstChild)
-{
-  *aFirstChild = nullptr;
-
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eFirstChild);
-
-  return NS_OK;
+  GetValue(aNodeValue);
 }
 
-NS_IMETHODIMP
-nsDOMAttribute::GetLastChild(nsIDOMNode** aLastChild)
-{
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eLastChild);
-
-  return GetFirstChild(aLastChild);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::GetPreviousSibling(nsIDOMNode** aPreviousSibling)
+void
+nsDOMAttribute::SetNodeValueInternal(const nsAString& aNodeValue, ErrorResult& aError)
 {
-  NS_ENSURE_ARG_POINTER(aPreviousSibling);
-
-  OwnerDoc()->WarnOnceAbout(nsIDocument::ePreviousSibling);
-
-  *aPreviousSibling = nullptr;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::GetNextSibling(nsIDOMNode** aNextSibling)
-{
-  NS_ENSURE_ARG_POINTER(aNextSibling);
-
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eNextSibling);
-
-  *aNextSibling = nullptr;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
-{
-  NS_ENSURE_ARG_POINTER(aAttributes);
+  OwnerDoc()->WarnOnceAbout(nsIDocument::eNodeValue);
 
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eAttributes);
-
-  *aAttributes = nullptr;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn)
-{
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eInsertBefore);
-
-  return ReplaceOrInsertBefore(false, aNewChild, aRefChild, aReturn);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
-{
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eReplaceChild);
-
-  return ReplaceOrInsertBefore(true, aNewChild, aOldChild, aReturn);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
-{
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eRemoveChild);
-
-  return nsINode::RemoveChild(aOldChild, aReturn);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
-{
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eAppendChild);
-
-  return InsertBefore(aNewChild, nullptr, aReturn);
+  aError = SetValue(aNodeValue);
 }
 
 nsresult
 nsDOMAttribute::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
 {
   nsAutoString value;
   const_cast<nsDOMAttribute*>(this)->GetValue(value);
 
@@ -385,164 +239,39 @@ nsDOMAttribute::Clone(nsINodeInfo *aNode
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aResult);
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDOMAttribute::CloneNode(bool aDeep, uint8_t aOptionalArgc, nsIDOMNode** aResult)
-{
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eCloneNode);
-
-  if (!aOptionalArgc) {
-    aDeep = true;
-  }
-
-  return nsNodeUtils::CloneNodeImpl(this, aDeep, true, aResult);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
-{
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eOwnerDocument);
-
-  return nsINode::GetOwnerDocument(aOwnerDocument);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::GetNamespaceURI(nsAString& aNamespaceURI)
-{
-  return mNodeInfo->GetNamespaceURI(aNamespaceURI);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::GetPrefix(nsAString& aPrefix)
-{
-  mNodeInfo->GetPrefix(aPrefix);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::GetLocalName(nsAString& aLocalName)
-{
-  mNodeInfo->GetName(aLocalName);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::Normalize()
-{
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eNormalize);
-
-  // Nothing to do here
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::IsSupported(const nsAString& aFeature,
-                            const nsAString& aVersion,
-                            bool* aReturn)
-{
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eIsSupported);
-
-  *aReturn = nsContentUtils::InternalIsSupported(static_cast<nsIDOMAttr*>(this), 
-                                                 aFeature, aVersion);
-  return NS_OK;
-}
-
 already_AddRefed<nsIURI>
 nsDOMAttribute::GetBaseURI() const
 {
   nsINode *parent = GetContentInternal();
 
   return parent ? parent->GetBaseURI() : nullptr;
 }
 
-NS_IMETHODIMP
-nsDOMAttribute::GetDOMBaseURI(nsAString &aURI)
-{
-  return nsINode::GetDOMBaseURI(aURI);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::CompareDocumentPosition(nsIDOMNode *other,
-                                        uint16_t *aResult)
-{
-  return nsINode::CompareDocumentPosition(other, aResult);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::IsEqualNode(nsIDOMNode* aOther, bool* aResult)
-{
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eIsEqualNode);
-
-  return nsINode::IsEqualNode(aOther, aResult);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::GetTextContent(nsAString &aTextContent)
-{
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eTextContent);
-
-  return GetNodeValue(aTextContent);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::SetTextContent(const nsAString& aTextContent)
+void
+nsDOMAttribute::GetTextContentInternal(nsAString& aTextContent)
 {
   OwnerDoc()->WarnOnceAbout(nsIDocument::eTextContent);
 
-  return SetNodeValue(aTextContent);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::Contains(nsIDOMNode* aOther, bool* aReturn)
-{
-  return nsINode::Contains(aOther, aReturn);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::LookupPrefix(const nsAString & namespaceURI,
-                             nsAString & aResult)
-{
-  SetDOMStringToNull(aResult);
-  return NS_OK;
+  GetValue(aTextContent);
 }
 
-NS_IMETHODIMP
-nsDOMAttribute::IsDefaultNamespace(const nsAString & namespaceURI,
-                                   bool *aResult)
-{
-  *aResult = namespaceURI.IsEmpty();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::LookupNamespaceURI(const nsAString & prefix,
-                              nsAString & aResult)
+void
+nsDOMAttribute::SetTextContentInternal(const nsAString& aTextContent,
+                                       ErrorResult& aError)
 {
-  SetDOMStringToNull(aResult);
-  return NS_OK;
-}
+  OwnerDoc()->WarnOnceAbout(nsIDocument::eTextContent);
 
-NS_IMETHODIMP
-nsDOMAttribute::SetUserData(const nsAString & key,
-                            nsIVariant *data, nsIDOMUserDataHandler *handler,
-                            nsIVariant **aResult)
-{
-  return nsINode::SetUserData(key, data, handler, aResult);
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::GetUserData(const nsAString & key, nsIVariant **aResult)
-{
-  return nsINode::GetUserData(key, aResult);
+  SetNodeValueInternal(aTextContent, aError);
 }
 
 NS_IMETHODIMP
 nsDOMAttribute::GetIsId(bool* aReturn)
 {
   nsIContent* content = GetContentInternal();
   if (!content)
   {
--- a/content/base/src/nsDOMAttribute.h
+++ b/content/base/src/nsDOMAttribute.h
@@ -31,17 +31,23 @@ public:
                  already_AddRefed<nsINodeInfo> aNodeInfo,
                  const nsAString& aValue,
                  bool aNsAware);
   virtual ~nsDOMAttribute() {}
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   // nsIDOMNode interface
-  NS_DECL_NSIDOMNODE
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
+  virtual void GetTextContentInternal(nsAString& aTextContent);
+  virtual void SetTextContentInternal(const nsAString& aTextContent,
+                                      mozilla::ErrorResult& aError);
+  virtual void GetNodeValueInternal(nsAString& aNodeValue);
+  virtual void SetNodeValueInternal(const nsAString& aNodeValue,
+                                    mozilla::ErrorResult& aError);
 
   // nsIDOMAttr interface
   NS_DECL_NSIDOMATTR
 
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
 
   // nsIAttribute interface
   void SetMap(nsDOMAttributeMap *aMap);
--- a/content/base/src/nsDOMDocumentType.h
+++ b/content/base/src/nsDOMDocumentType.h
@@ -26,17 +26,17 @@ class nsDOMDocumentTypeForward : public 
 {
 public:
   nsDOMDocumentTypeForward(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsGenericDOMDataNode(aNodeInfo)
   {
   }
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericDOMDataNode::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 };
 
 class nsDOMDocumentType : public nsDOMDocumentTypeForward
 {
 public:
   nsDOMDocumentType(already_AddRefed<nsINodeInfo> aNodeInfo,
                     const nsAString& aPublicId,
                     const nsAString& aSystemId,
@@ -48,30 +48,27 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
   // Forwarded by base class
 
   // nsIDOMDocumentType
   NS_DECL_NSIDOMDOCUMENTTYPE
 
-  NS_IMETHODIMP GetNodeValue(nsAString& aNodeValue)
+  // nsINode
+  virtual bool IsNodeOfType(uint32_t aFlags) const;
+  virtual void GetNodeValueInternal(nsAString& aNodeValue)
   {
     SetDOMStringToNull(aNodeValue);
-  
-    return NS_OK;
   }
-  NS_IMETHODIMP SetNodeValue(const nsAString& aNodeValue)
+  virtual void SetNodeValueInternal(const nsAString& aNodeValue,
+                                    mozilla::ErrorResult& aError)
   {
-    return NS_OK;
   }
 
-  // nsINode
-  virtual bool IsNodeOfType(uint32_t aFlags) const;
-
   // nsIContent overrides
   virtual const nsTextFragment* GetText();
 
   virtual nsGenericDOMDataNode* CloneDataNode(nsINodeInfo *aNodeInfo,
                                               bool aCloneText) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
--- a/content/base/src/nsDOMMutationObserver.cpp
+++ b/content/base/src/nsDOMMutationObserver.cpp
@@ -480,17 +480,17 @@ nsDOMMutationObserver::GetAllSubtreeObse
             aReceivers.AppendElement(parent);
           }
         }
         if (mReceivers.Count() == int32_t(aReceivers.Length())) {
           return;
         }
       }
     }
-    n = n->GetNodeParent();
+    n = n->GetParentNode();
   }
 }
 
 void
 nsDOMMutationObserver::ScheduleForRun()
 {
   nsDOMMutationObserver::AddCurrentlyHandlingObserver(this);
 
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -3029,17 +3029,18 @@ nsDocument::NodesFromRectHelper(float aX
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocument::GetElementsByClassName(const nsAString& aClasses,
                                    nsIDOMNodeList** aReturn)
 {
-  return nsContentUtils::GetElementsByClassName(this, aClasses, aReturn);
+  *aReturn = nsContentUtils::GetElementsByClassName(this, aClasses).get();
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocument::ReleaseCapture()
 {
   // only release the capture if the caller can access it. This prevents a
   // page from stopping a scrollbar grab for example.
   nsCOMPtr<nsIDOMNode> node = do_QueryInterface(nsIPresShell::GetCapturingContent());
@@ -3490,17 +3491,17 @@ bool
 nsDocument::IsNodeOfType(uint32_t aFlags) const
 {
     return !(aFlags & ~eDOCUMENT);
 }
 
 Element*
 nsIDocument::GetRootElement() const
 {
-  return (mCachedRootElement && mCachedRootElement->GetNodeParent() == this) ?
+  return (mCachedRootElement && mCachedRootElement->GetParentNode() == this) ?
          mCachedRootElement : GetRootElementInternal();
 }
 
 Element*
 nsDocument::GetRootElementInternal() const
 {
   // Loop backwards because any non-elements, such as doctypes and PIs
   // are likely to appear before the root element.
@@ -4975,30 +4976,29 @@ nsDocument::ImportNode(nsIDOMNode* aImpo
     case nsIDOMNode::DOCUMENT_FRAGMENT_NODE:
     case nsIDOMNode::ELEMENT_NODE:
     case nsIDOMNode::PROCESSING_INSTRUCTION_NODE:
     case nsIDOMNode::TEXT_NODE:
     case nsIDOMNode::CDATA_SECTION_NODE:
     case nsIDOMNode::COMMENT_NODE:
     case nsIDOMNode::DOCUMENT_TYPE_NODE:
     {
-      nsCOMPtr<nsIDOMNode> newNode;
+      nsCOMPtr<nsINode> newNode;
       nsCOMArray<nsINode> nodesWithProperties;
       rv = nsNodeUtils::Clone(imported, aDeep, mNodeInfoManager,
                               nodesWithProperties, getter_AddRefs(newNode));
       NS_ENSURE_SUCCESS(rv, rv);
 
       nsIDocument *ownerDoc = imported->OwnerDoc();
       rv = nsNodeUtils::CallUserDataHandlers(nodesWithProperties, ownerDoc,
                                              nsIDOMUserDataHandler::NODE_IMPORTED,
                                              true);
       NS_ENSURE_SUCCESS(rv, rv);
 
-      newNode.swap(*aResult);
-
+      *aResult = newNode.forget().get()->AsDOMNode();
       return NS_OK;
     }
     default:
     {
       NS_WARNING("Don't know how to clone this nodetype for importNode.");
 
       return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
     }
@@ -5790,277 +5790,16 @@ nsDocument::SetDir(const nsAString& aDir
 
       break;
     }
   }
 
   return NS_OK;
 }
 
-
-//
-// nsIDOMNode methods
-//
-NS_IMETHODIMP
-nsDocument::GetNodeName(nsAString& aNodeName)
-{
-  aNodeName.AssignLiteral("#document");
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetNodeValue(nsAString& aNodeValue)
-{
-  SetDOMStringToNull(aNodeValue);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::SetNodeValue(const nsAString& aNodeValue)
-{
-  // The DOM spec says that when nodeValue is defined to be null "setting it
-  // has no effect", so we don't throw an exception.
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetNodeType(uint16_t* aNodeType)
-{
-  *aNodeType = nsIDOMNode::DOCUMENT_NODE;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetParentNode(nsIDOMNode** aParentNode)
-{
-  *aParentNode = nullptr;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetParentElement(nsIDOMElement** aParentElement)
-{
-  *aParentElement = nullptr;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetChildNodes(nsIDOMNodeList** aChildNodes)
-{
-  return nsINode::GetChildNodes(aChildNodes);
-}
-
-NS_IMETHODIMP
-nsDocument::HasChildNodes(bool* aHasChildNodes)
-{
-  NS_ENSURE_ARG(aHasChildNodes);
-
-  *aHasChildNodes = (mChildren.ChildCount() != 0);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::HasAttributes(bool* aHasAttributes)
-{
-  NS_ENSURE_ARG(aHasAttributes);
-
-  *aHasAttributes = false;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetFirstChild(nsIDOMNode** aFirstChild)
-{
-  return nsINode::GetFirstChild(aFirstChild);
-}
-
-NS_IMETHODIMP
-nsDocument::GetLastChild(nsIDOMNode** aLastChild)
-{
-  return nsINode::GetLastChild(aLastChild);
-}
-
-NS_IMETHODIMP
-nsDocument::GetPreviousSibling(nsIDOMNode** aPreviousSibling)
-{
-  *aPreviousSibling = nullptr;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetNextSibling(nsIDOMNode** aNextSibling)
-{
-  *aNextSibling = nullptr;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
-{
-  *aAttributes = nullptr;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetNamespaceURI(nsAString& aNamespaceURI)
-{
-  SetDOMStringToNull(aNamespaceURI);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetPrefix(nsAString& aPrefix)
-{
-  SetDOMStringToNull(aPrefix);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetLocalName(nsAString& aLocalName)
-{
-  SetDOMStringToNull(aLocalName);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
-                         nsIDOMNode** aReturn)
-{
-  return ReplaceOrInsertBefore(false, aNewChild, aRefChild, aReturn);
-}
-
-NS_IMETHODIMP
-nsDocument::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
-                         nsIDOMNode** aReturn)
-{
-  return ReplaceOrInsertBefore(true, aNewChild, aOldChild, aReturn);
-}
-
-NS_IMETHODIMP
-nsDocument::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
-{
-  return nsINode::RemoveChild(aOldChild, aReturn);
-}
-
-NS_IMETHODIMP
-nsDocument::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
-{
-  return nsDocument::InsertBefore(aNewChild, nullptr, aReturn);
-}
-
-NS_IMETHODIMP
-nsDocument::CloneNode(bool aDeep, uint8_t aOptionalArgc, nsIDOMNode** aReturn)
-{
-  if (!aOptionalArgc) {
-    aDeep = true;
-  }
-
-  return nsNodeUtils::CloneNodeImpl(this, aDeep, !mCreatingStaticClone, aReturn);
-}
-
-NS_IMETHODIMP
-nsDocument::Normalize()
-{
-  return nsIDocument::Normalize();
-}
-
-NS_IMETHODIMP
-nsDocument::IsSupported(const nsAString& aFeature, const nsAString& aVersion,
-                        bool* aReturn)
-{
-  *aReturn = nsContentUtils::InternalIsSupported(static_cast<nsIDOMDocument*>(this),
-                                                 aFeature, aVersion);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::GetDOMBaseURI(nsAString &aURI)
-{
-  return nsIDocument::GetDOMBaseURI(aURI);
-}
-
-NS_IMETHODIMP
-nsDocument::GetTextContent(nsAString &aTextContent)
-{
-  SetDOMStringToNull(aTextContent);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::IsEqualNode(nsIDOMNode* aOther, bool* aResult)
-{
-  return nsINode::IsEqualNode(aOther, aResult);
-}
-
-NS_IMETHODIMP
-nsDocument::CompareDocumentPosition(nsIDOMNode *other,
-                                   uint16_t *aResult)
-{
-  return nsINode::CompareDocumentPosition(other, aResult);
-}
-
-NS_IMETHODIMP
-nsDocument::SetTextContent(const nsAString & aTextContent)
-{
-  return nsINode::SetTextContent(aTextContent);
-}
-
-NS_IMETHODIMP
-nsDocument::LookupPrefix(const nsAString & namespaceURI, nsAString & aResult)
-{
-  return nsINode::LookupPrefix(namespaceURI, aResult);
-}
-
-NS_IMETHODIMP
-nsDocument::IsDefaultNamespace(const nsAString & namespaceURI,
-                              bool *aResult)
-{
-  return nsINode::IsDefaultNamespace(namespaceURI, aResult);
-}
-
-NS_IMETHODIMP
-nsDocument::LookupNamespaceURI(const nsAString & prefix,
-                              nsAString & aResult)
-{
-  return nsINode::LookupNamespaceURI(prefix, aResult);
-}
-
-NS_IMETHODIMP
-nsDocument::SetUserData(const nsAString & key,
-                       nsIVariant *data, nsIDOMUserDataHandler *handler,
-                       nsIVariant **aResult)
-{
-  return nsINode::SetUserData(key, data, handler, aResult);
-}
-
-NS_IMETHODIMP
-nsDocument::GetUserData(const nsAString & key,
-                        nsIVariant **aResult)
-{
-  return nsINode::GetUserData(key, aResult);
-}
-
-NS_IMETHODIMP
-nsDocument::Contains(nsIDOMNode* aOther, bool* aReturn)
-{
-  return nsINode::Contains(aOther, aReturn);
-}
-
 NS_IMETHODIMP
 nsDocument::GetInputEncoding(nsAString& aInputEncoding)
 {
   WarnOnceAbout(eInputEncoding);
   if (mHaveInputEncoding) {
     return GetCharacterSet(aInputEncoding);
   }
 
@@ -6268,17 +6007,17 @@ nsDocument::AdoptNode(nsIDOMNode *aAdopt
   NS_ENSURE_TRUE(adoptedNode, NS_ERROR_UNEXPECTED);
 
   nsresult rv = nsContentUtils::CheckSameOrigin(this, adoptedNode);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Scope firing mutation events so that we don't carry any state that
   // might be stale
   {
-    nsINode* parent = adoptedNode->GetNodeParent();
+    nsINode* parent = adoptedNode->GetParentNode();
     if (parent) {
       nsContentUtils::MaybeFireNodeRemoved(adoptedNode, parent,
                                            adoptedNode->OwnerDoc());
     }
   }
 
   nsAutoScriptBlocker scriptBlocker;
 
@@ -6325,17 +6064,17 @@ nsDocument::AdoptNode(nsIDOMNode *aAdopt
           if (node &&
               nsContentUtils::ContentIsDescendantOf(node, adoptedNode)) {
             return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
           }
         }
       } while ((doc = doc->GetParentDocument()));
 
       // Remove from parent.
-      nsCOMPtr<nsINode> parent = adoptedNode->GetNodeParent();
+      nsCOMPtr<nsINode> parent = adoptedNode->GetParentNode();
       if (parent) {
         parent->RemoveChildAt(parent->IndexOf(adoptedNode), true);
       }
 
       break;
     }
     case nsIDOMNode::DOCUMENT_NODE:
     {
@@ -6411,22 +6150,16 @@ nsDocument::AdoptNode(nsIDOMNode *aAdopt
 
   NS_ASSERTION(adoptedNode->OwnerDoc() == this,
                "Should still be in the document we just got adopted into");
 
   NS_ADDREF(*aResult = aAdoptedNode);
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDocument::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
-{
-  return nsINode::GetOwnerDocument(aOwnerDocument);
-}
-
 nsEventListenerManager*
 nsDocument::GetListenerManager(bool aCreateIfNotFound)
 {
   if (!mListenerManager && aCreateIfNotFound) {
     mListenerManager =
       new nsEventListenerManager(static_cast<nsIDOMEventTarget*>(this));
     SetFlags(NODE_HAS_LISTENERMANAGER);
   }
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -730,17 +730,17 @@ public:
   nsRadioGroupStruct* GetRadioGroup(const nsAString& aName) const;
   nsRadioGroupStruct* GetOrCreateRadioGroup(const nsAString& aName);
 
 private:
   nsRadioGroupStruct* GetRadioGroupInternal(const nsAString& aName) const;
 
 public:
   // nsIDOMNode
-  NS_DECL_NSIDOMNODE
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE_OVERRIDABLE
 
   // nsIDOMDocument
   NS_DECL_NSIDOMDOCUMENT
 
   // nsIDOMXMLDocument
   NS_DECL_NSIDOMXMLDOCUMENT
 
   // nsIDOMDocumentXBL
--- a/content/base/src/nsDocumentEncoder.cpp
+++ b/content/base/src/nsDocumentEncoder.cpp
@@ -530,17 +530,17 @@ nsDocumentEncoder::SerializeToStringIter
     node = current->GetFirstChild();
     while (!node && current && current != aNode) {
       rv = SerializeNodeEnd(current, aStr);
       NS_ENSURE_SUCCESS(rv, rv);
       // Check if we have siblings.
       node = current->GetNextSibling();
       if (!node) {
         // Perhaps parent node has siblings.
-        current = current->GetNodeParent();
+        current = current->GetParentNode();
       }
     }
   }
 
   return NS_OK;
 }
 
 bool 
@@ -1086,30 +1086,30 @@ nsDocumentEncoder::EncodeToString(nsAStr
           NS_ENSURE_SUCCESS(rv, rv);
         }
         nsCOMPtr<nsIContent> content = do_QueryInterface(node);
         if (content && content->IsHTML(nsGkAtoms::tr)) {
           nsINode* n = content;
           if (!prevNode) {
             // Went from a non-<tr> to a <tr>
             mCommonAncestors.Clear();
-            nsContentUtils::GetAncestors(n->GetNodeParent(), mCommonAncestors);
+            nsContentUtils::GetAncestors(n->GetParentNode(), mCommonAncestors);
             rv = SerializeRangeContextStart(mCommonAncestors, output);
             NS_ENSURE_SUCCESS(rv, rv);
             // Don't let SerializeRangeToString serialize the context again
             mDisableContextSerialize = true;
           }
 
           rv = SerializeNodeStart(n, 0, -1, output);
           NS_ENSURE_SUCCESS(rv, rv);
           prevNode = node;
         } else if (prevNode) {
           // Went from a <tr> to a non-<tr>
           mCommonAncestors.Clear();
-          nsContentUtils::GetAncestors(p->GetNodeParent(), mCommonAncestors);
+          nsContentUtils::GetAncestors(p->GetParentNode(), mCommonAncestors);
           mDisableContextSerialize = false;
           rv = SerializeRangeContextEnd(mCommonAncestors, output);
           NS_ENSURE_SUCCESS(rv, rv);
           prevNode = nullptr;
         }
       }
 
       nsRange* r = static_cast<nsRange*>(range.get());
@@ -1117,17 +1117,17 @@ nsDocumentEncoder::EncodeToString(nsAStr
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     if (prevNode) {
       nsCOMPtr<nsINode> p = do_QueryInterface(prevNode);
       rv = SerializeNodeEnd(p, output);
       NS_ENSURE_SUCCESS(rv, rv);
       mCommonAncestors.Clear();
-      nsContentUtils::GetAncestors(p->GetNodeParent(), mCommonAncestors);
+      nsContentUtils::GetAncestors(p->GetParentNode(), mCommonAncestors);
       mDisableContextSerialize = false; 
       rv = SerializeRangeContextEnd(mCommonAncestors, output);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     // Just to be safe
     mDisableContextSerialize = false; 
 
--- a/content/base/src/nsDocumentFragment.cpp
+++ b/content/base/src/nsDocumentFragment.cpp
@@ -26,17 +26,17 @@ class nsDocumentFragment : public Fragme
 {
 public:
   using FragmentOrElement::GetFirstChild;
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // interface nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(FragmentOrElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // interface nsIDOMDocumentFragment
   // NS_DECL_NSIDOCUMENTFRAGMENT  Empty
 
   nsDocumentFragment(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsDocumentFragment()
   {
   }
--- a/content/base/src/nsGenericDOMDataNode.cpp
+++ b/content/base/src/nsGenericDOMDataNode.cpp
@@ -109,53 +109,29 @@ NS_INTERFACE_MAP_BEGIN(nsGenericDOMDataN
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContent)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsGenericDOMDataNode)
 NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsGenericDOMDataNode,
                                               nsNodeUtils::LastRelease(this))
 
 
-nsresult
-nsGenericDOMDataNode::GetNodeValue(nsAString& aNodeValue)
+void
+nsGenericDOMDataNode::GetNodeValueInternal(nsAString& aNodeValue)
 {
-  return GetData(aNodeValue);
-}
-
-nsresult
-nsGenericDOMDataNode::SetNodeValue(const nsAString& aNodeValue)
-{
-  return SetTextInternal(0, mText.GetLength(), aNodeValue.BeginReading(),
-                         aNodeValue.Length(), true);
+  DebugOnly<nsresult> rv = GetData(aNodeValue);
+  NS_ASSERTION(NS_SUCCEEDED(rv), "GetData() failed!");
 }
 
-nsresult
-nsGenericDOMDataNode::GetNamespaceURI(nsAString& aNamespaceURI)
-{
-  SetDOMStringToNull(aNamespaceURI);
-
-  return NS_OK;
-}
-
-nsresult
-nsGenericDOMDataNode::GetPrefix(nsAString& aPrefix)
+void
+nsGenericDOMDataNode::SetNodeValueInternal(const nsAString& aNodeValue,
+                                           ErrorResult& aError)
 {
-  SetDOMStringToNull(aPrefix);
-
-  return NS_OK;
-}
-
-nsresult
-nsGenericDOMDataNode::IsSupported(const nsAString& aFeature,
-                                  const nsAString& aVersion,
-                                  bool* aReturn)
-{
-  *aReturn = nsContentUtils::InternalIsSupported(static_cast<nsIContent*>(this),
-                                                 aFeature, aVersion);
-  return NS_OK;
+  aError = SetTextInternal(0, mText.GetLength(), aNodeValue.BeginReading(),
+                           aNodeValue.Length(), true);
 }
 
 //----------------------------------------------------------------------
 
 // Implementation of nsIDOMCharacterData
 
 nsresult
 nsGenericDOMDataNode::GetData(nsAString& aData) const
@@ -741,17 +717,17 @@ nsGenericDOMDataNode::SplitData(uint32_t
     CharacterDataChangeInfo::Details::eSplit, newContent
   };
   rv = SetTextInternal(cutStartOffset, cutLength, nullptr, 0, true,
                        aCloneAfterOriginal ? &details : nullptr);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  nsCOMPtr<nsINode> parent = GetNodeParent();
+  nsCOMPtr<nsINode> parent = GetParentNode();
   if (parent) {
     int32_t insertionIndex = parent->IndexOf(this);
     if (aCloneAfterOriginal) {
       ++insertionIndex;
     }
     parent->InsertChildAt(newContent, insertionIndex, true);
   }
 
--- a/content/base/src/nsGenericDOMDataNode.h
+++ b/content/base/src/nsGenericDOMDataNode.h
@@ -53,83 +53,19 @@ class nsGenericDOMDataNode : public nsIC
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   NS_DECL_SIZEOF_EXCLUDING_THIS
 
   nsGenericDOMDataNode(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsGenericDOMDataNode();
 
-  // Implementation for nsIDOMNode
-  nsresult GetNodeName(nsAString& aNodeName)
-  {
-    aNodeName = NodeName();
-    return NS_OK;
-  }
-  nsresult GetNodeType(uint16_t* aNodeType)
-  {
-    *aNodeType = NodeType();
-    return NS_OK;
-  }
-  nsresult GetNodeValue(nsAString& aNodeValue);
-  nsresult SetNodeValue(const nsAString& aNodeValue);
-  nsresult GetAttributes(nsIDOMNamedNodeMap** aAttributes)
-  {
-    NS_ENSURE_ARG_POINTER(aAttributes);
-    *aAttributes = nullptr;
-    return NS_OK;
-  }
-  nsresult HasChildNodes(bool* aHasChildNodes)
-  {
-    NS_ENSURE_ARG_POINTER(aHasChildNodes);
-    *aHasChildNodes = false;
-    return NS_OK;
-  }
-  nsresult HasAttributes(bool* aHasAttributes)
-  {
-    NS_ENSURE_ARG_POINTER(aHasAttributes);
-    *aHasAttributes = false;
-    return NS_OK;
-  }
-  nsresult InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
-                        nsIDOMNode** aReturn)
-  {
-    return ReplaceOrInsertBefore(false, aNewChild, aRefChild, aReturn);
-  }
-  nsresult ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
-                        nsIDOMNode** aReturn)
-  {
-    return ReplaceOrInsertBefore(true, aNewChild, aOldChild, aReturn);
-  }
-  nsresult RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
-  {
-    return nsINode::RemoveChild(aOldChild, aReturn);
-  }
-  nsresult AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
-  {
-    return InsertBefore(aNewChild, nullptr, aReturn);
-  }
-  nsresult GetNamespaceURI(nsAString& aNamespaceURI);
-  nsresult GetLocalName(nsAString& aLocalName)
-  {
-    aLocalName = LocalName();
-    return NS_OK;
-  }
-  nsresult GetPrefix(nsAString& aPrefix);
-  nsresult IsSupported(const nsAString& aFeature,
-                       const nsAString& aVersion,
-                       bool* aReturn);
-  nsresult CloneNode(bool aDeep, uint8_t aOptionalArgc, nsIDOMNode** aReturn)
-  {
-    if (!aOptionalArgc) {
-      aDeep = true;
-    }
-    
-    return nsNodeUtils::CloneNodeImpl(this, aDeep, true, aReturn);
-  }
+  virtual void GetNodeValueInternal(nsAString& aNodeValue);
+  virtual void SetNodeValueInternal(const nsAString& aNodeValue,
+                                    mozilla::ErrorResult& aError);
 
   // Implementation for nsIDOMCharacterData
   nsresult GetData(nsAString& aData) const;
   nsresult SetData(const nsAString& aData);
   nsresult GetLength(uint32_t* aLength);
   nsresult SubstringData(uint32_t aOffset, uint32_t aCount,
                          nsAString& aReturn);
   nsresult AppendData(const nsAString& aArg);
@@ -137,31 +73,30 @@ public:
   nsresult DeleteData(uint32_t aOffset, uint32_t aCount);
   nsresult ReplaceData(uint32_t aOffset, uint32_t aCount,
                        const nsAString& aArg);
 
   // nsINode methods
   virtual uint32_t GetChildCount() const;
   virtual nsIContent *GetChildAt(uint32_t aIndex) const;
   virtual nsIContent * const * GetChildArray(uint32_t* aChildCount) const;
-  virtual int32_t IndexOf(const nsINode* aPossibleChild) const MOZ_OVERRIDE;
+  virtual int32_t IndexOf(const nsINode* aPossibleChild) const;
   virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex,
                                  bool aNotify);
   virtual void RemoveChildAt(uint32_t aIndex, bool aNotify);
-  NS_IMETHOD GetTextContent(nsAString &aTextContent)
+  virtual void GetTextContentInternal(nsAString& aTextContent)
   {
-    nsresult rv = GetNodeValue(aTextContent);
-    NS_ASSERTION(NS_SUCCEEDED(rv), "GetNodeValue() failed?");
-    return rv;
+    GetNodeValue(aTextContent);
   }
-  NS_IMETHOD SetTextContent(const nsAString& aTextContent)
+  virtual void SetTextContentInternal(const nsAString& aTextContent,
+                                      mozilla::ErrorResult& aError)
   {
     // Batch possible DOMSubtreeModified events.
     mozAutoSubtreeModified subtree(OwnerDoc(), nullptr);
-    return SetNodeValue(aTextContent);
+    return SetNodeValue(aTextContent, aError);
   }
 
   // Implementation for nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers);
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true);
@@ -239,17 +174,17 @@ public:
   void ToCString(nsAString& aBuf, int32_t aOffset, int32_t aLen) const;
 #endif
 
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsGenericDOMDataNode)
 
 protected:
   virtual mozilla::dom::Element* GetNameSpaceElement()
   {
-    nsINode *parent = GetNodeParent();
+    nsINode *parent = GetParentNode();
 
     return parent && parent->IsElement() ? parent->AsElement() : nullptr;
   }
 
   /**
    * There are a set of DOM- and scripting-specific instance variables
    * that may only be instantiated when a content object is accessed
    * through the DOM. Rather than burn actual slots in the content
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -804,19 +804,20 @@ nsGenericElement::GetBoundingClientRect(
           nsLayoutUtils::GetContainingBlockForClientRect(frame),
           nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
   rect->SetLayoutRect(r);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGenericElement::GetElementsByClassName(const nsAString& aClasses,
-                                         nsIDOMNodeList** aReturn)
+                                         nsIDOMHTMLCollection** aReturn)
 {
-  return nsContentUtils::GetElementsByClassName(this, aClasses, aReturn);
+  *aReturn = nsContentUtils::GetElementsByClassName(this, aClasses).get();
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGenericElement::GetClientRects(nsIDOMClientRectList** aResult)
 {
   *aResult = nullptr;
 
   nsRefPtr<nsClientRectList> rectList = new nsClientRectList(this);
@@ -928,22 +929,21 @@ nsGenericElement::GetAttributeNode(const
   NS_ENSURE_ARG_POINTER(aReturn);
   *aReturn = nullptr;
 
   nsIDocument* document = OwnerDoc();
   if (document) {
     document->WarnOnceAbout(nsIDocument::eGetAttributeNode);
   }
 
-  nsCOMPtr<nsIDOMNamedNodeMap> map;
-  nsresult rv = GetAttributes(getter_AddRefs(map));
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsDOMAttributeMap* map = GetAttributes();
+  NS_ENSURE_TRUE(map, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIDOMNode> node;
-  rv = map->GetNamedItem(aName, getter_AddRefs(node));
+  nsresult rv = map->GetNamedItem(aName, getter_AddRefs(node));
 
   if (NS_SUCCEEDED(rv) && node) {
     rv = CallQueryInterface(node, aReturn);
   }
 
   return rv;
 }
 
@@ -953,22 +953,21 @@ nsGenericElement::SetAttributeNode(nsIDO
 {
   NS_ENSURE_ARG_POINTER(aReturn);
   NS_ENSURE_ARG_POINTER(aAttribute);
 
   *aReturn = nullptr;
 
   OwnerDoc()->WarnOnceAbout(nsIDocument::eSetAttributeNode);
 
-  nsCOMPtr<nsIDOMNamedNodeMap> map;
-  nsresult rv = GetAttributes(getter_AddRefs(map));
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsDOMAttributeMap* map = GetAttributes();
+  NS_ENSURE_TRUE(map, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIDOMNode> returnNode;
-  rv = map->SetNamedItem(aAttribute, getter_AddRefs(returnNode));
+  nsresult rv = map->SetNamedItem(aAttribute, getter_AddRefs(returnNode));
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (returnNode) {
     rv = CallQueryInterface(returnNode, aReturn);
   }
 
   return rv;
 }
@@ -979,38 +978,37 @@ nsGenericElement::RemoveAttributeNode(ns
 {
   NS_ENSURE_ARG_POINTER(aReturn);
   NS_ENSURE_ARG_POINTER(aAttribute);
 
   *aReturn = nullptr;
 
   OwnerDoc()->WarnOnceAbout(nsIDocument::eRemoveAttributeNode);
 
-  nsCOMPtr<nsIDOMNamedNodeMap> map;
-  nsresult rv = GetAttributes(getter_AddRefs(map));
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsDOMAttributeMap* map = GetAttributes();
+  NS_ENSURE_TRUE(map, NS_ERROR_FAILURE);
 
   nsAutoString name;
 
-  rv = aAttribute->GetName(name);
+  nsresult rv = aAttribute->GetName(name);
   if (NS_SUCCEEDED(rv)) {
     nsCOMPtr<nsIDOMNode> node;
     rv = map->RemoveNamedItem(name, getter_AddRefs(node));
 
     if (NS_SUCCEEDED(rv) && node) {
       rv = CallQueryInterface(node, aReturn);
     }
   }
 
   return rv;
 }
 
 nsresult
 nsGenericElement::GetElementsByTagName(const nsAString& aTagname,
-                                       nsIDOMNodeList** aReturn)
+                                       nsIDOMHTMLCollection** aReturn)
 {
   nsContentList *list = NS_GetContentList(this, kNameSpaceID_Unknown, 
                                           aTagname).get();
 
   // transfer ref to aReturn
   *aReturn = list;
   return NS_OK;
 }
@@ -1088,22 +1086,22 @@ nsGenericElement::GetAttributeNodeNS(con
   return GetAttributeNodeNSInternal(aNamespaceURI, aLocalName, aReturn);
 }
 
 nsresult
 nsGenericElement::GetAttributeNodeNSInternal(const nsAString& aNamespaceURI,
                                              const nsAString& aLocalName,
                                              nsIDOMAttr** aReturn)
 {
-  nsCOMPtr<nsIDOMNamedNodeMap> map;
-  nsresult rv = GetAttributes(getter_AddRefs(map));
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsDOMAttributeMap* map = GetAttributes();
+  NS_ENSURE_TRUE(map, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIDOMNode> node;
-  rv = map->GetNamedItemNS(aNamespaceURI, aLocalName, getter_AddRefs(node));
+  nsresult rv = map->GetNamedItemNS(aNamespaceURI, aLocalName,
+                                    getter_AddRefs(node));
 
   if (NS_SUCCEEDED(rv) && node) {
     rv = CallQueryInterface(node, aReturn);
   }
 
   return rv;
 }
 
@@ -1112,35 +1110,34 @@ nsGenericElement::SetAttributeNodeNS(nsI
                                      nsIDOMAttr** aReturn)
 {
   NS_ENSURE_ARG_POINTER(aReturn);
   NS_ENSURE_ARG_POINTER(aNewAttr);
   *aReturn = nullptr;
 
   OwnerDoc()->WarnOnceAbout(nsIDocument::eSetAttributeNodeNS);
 
-  nsCOMPtr<nsIDOMNamedNodeMap> map;
-  nsresult rv = GetAttributes(getter_AddRefs(map));
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsDOMAttributeMap* map = GetAttributes();
+  NS_ENSURE_TRUE(map, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIDOMNode> returnNode;
-  rv = map->SetNamedItemNS(aNewAttr, getter_AddRefs(returnNode));
+  nsresult rv = map->SetNamedItemNS(aNewAttr, getter_AddRefs(returnNode));
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (returnNode) {
     rv = CallQueryInterface(returnNode, aReturn);
   }
 
   return rv;
 }
 
 nsresult
 nsGenericElement::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
                                          const nsAString& aLocalName,
-                                         nsIDOMNodeList** aReturn)
+                                         nsIDOMHTMLCollection** aReturn)
 {
   int32_t nameSpaceId = kNameSpaceID_Wildcard;
 
   if (!aNamespaceURI.EqualsLiteral("*")) {
     nsresult rv =
       nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
                                                             nameSpaceId);
     NS_ENSURE_SUCCESS(rv, rv);
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -196,16 +196,25 @@ private:
   static bool
   FindAttributeDependence(const nsIAtom* aAttribute,
                           const MappedAttributeEntry* const aMaps[],
                           uint32_t aMapCount);
 
 public:
   // nsIDOMElement method implementation
   NS_DECL_NSIDOMELEMENT
+  nsDOMAttributeMap* GetAttributes()
+  {
+    nsDOMSlots *slots = DOMSlots();
+    if (!slots->mAttributeMap) {
+      slots->mAttributeMap = new nsDOMAttributeMap(this);
+    }
+
+    return slots->mAttributeMap;
+  }
 
   //----------------------------------------
 
   /**
    * Add a script event listener with the given event handler name
    * (like onclick) and with the value as JS
    * @param aEventName the event listener name
    * @param aValue the JS to attach
--- a/content/base/src/nsINode.cpp
+++ b/content/base/src/nsINode.cpp
@@ -94,16 +94,17 @@
 #include "nsUnicharUtils.h"
 #include "nsXBLBinding.h"
 #include "nsXBLInsertionPoint.h"
 #include "nsXBLPrototypeBinding.h"
 #include "prprf.h"
 #include "xpcpublic.h"
 #include "nsCSSRuleProcessor.h"
 #include "nsCSSParser.h"
+#include "nsHTMLLegendElement.h"
 #include "nsWrapperCacheInlines.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 nsINode::nsSlots::~nsSlots()
 {
   if (mChildNodes) {
@@ -209,17 +210,17 @@ static nsIContent* GetEditorRootContent(
   return rootContent;
 }
 
 nsIContent*
 nsINode::GetTextEditorRootContent(nsIEditor** aEditor)
 {
   if (aEditor)
     *aEditor = nullptr;
-  for (nsINode* node = this; node; node = node->GetNodeParent()) {
+  for (nsINode* node = this; node; node = node->GetParentNode()) {
     if (!node->IsElement() ||
         !node->AsElement()->IsHTML())
       continue;
 
     nsCOMPtr<nsIEditor> editor;
     static_cast<nsGenericHTMLElement*>(node)->
         GetEditorInternal(getter_AddRefs(editor));
     if (!editor)
@@ -304,17 +305,17 @@ nsINode::GetSelectionRootContent(nsIPres
   // This node might be in another subtree, if so, we should find this subtree's
   // root.  Otherwise, we can return the content simply.
   NS_ENSURE_TRUE(content, nullptr);
   return nsContentUtils::IsInSameAnonymousTree(this, content) ?
            content : GetRootForContentSubtree(static_cast<nsIContent*>(this));
 }
 
 nsINodeList*
-nsINode::GetChildNodesList()
+nsINode::ChildNodes()
 {
   nsSlots* slots = Slots();
   if (!slots->mChildNodes) {
     slots->mChildNodes = new nsChildContentList(this);
     if (slots->mChildNodes) {
       NS_ADDREF(slots->mChildNodes);
     }
   }
@@ -339,38 +340,33 @@ nsINode::CheckNotNativeAnonymous() const
 }
 #endif
 
 nsresult
 nsINode::GetParentNode(nsIDOMNode** aParentNode)
 {
   *aParentNode = nullptr;
 
-  nsINode *parent = GetNodeParent();
+  nsINode *parent = GetParentNode();
 
   return parent ? CallQueryInterface(parent, aParentNode) : NS_OK;
 }
 
 nsresult
 nsINode::GetParentElement(nsIDOMElement** aParentElement)
 {
   *aParentElement = nullptr;
   nsINode* parent = GetElementParent();
   return parent ? CallQueryInterface(parent, aParentElement) : NS_OK;
 }
 
 nsresult
 nsINode::GetChildNodes(nsIDOMNodeList** aChildNodes)
 {
-  *aChildNodes = GetChildNodesList();
-  if (!*aChildNodes) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  NS_ADDREF(*aChildNodes);
+  NS_ADDREF(*aChildNodes = ChildNodes());
 
   return NS_OK;
 }
 
 nsresult
 nsINode::GetFirstChild(nsIDOMNode** aNode)
 {
   nsIContent* child = GetFirstChild();
@@ -421,75 +417,57 @@ nsINode::GetOwnerDocument(nsIDOMDocument
 {
   *aOwnerDocument = nullptr;
 
   nsIDocument *ownerDoc = GetOwnerDocument();
 
   return ownerDoc ? CallQueryInterface(ownerDoc, aOwnerDocument) : NS_OK;
 }
 
-nsresult
-nsINode::RemoveChild(nsINode *aOldChild)
+nsINode*
+nsINode::RemoveChild(nsINode& aOldChild, ErrorResult& aError)
 {
-  if (!aOldChild) {
-    return NS_ERROR_NULL_POINTER;
-  }
-
   if (IsNodeOfType(eDATA_NODE)) {
     // aOldChild can't be one of our children.
-    return NS_ERROR_DOM_NOT_FOUND_ERR;
+    aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
+    return nullptr;
   }
 
-  if (aOldChild->GetNodeParent() == this) {
-    nsContentUtils::MaybeFireNodeRemoved(aOldChild, this, OwnerDoc());
+  if (aOldChild.GetParentNode() == this) {
+    nsContentUtils::MaybeFireNodeRemoved(&aOldChild, this, OwnerDoc());
   }
 
-  int32_t index = IndexOf(aOldChild);
+  int32_t index = IndexOf(&aOldChild);
   if (index == -1) {
     // aOldChild isn't one of our children.
-    return NS_ERROR_DOM_NOT_FOUND_ERR;
+    aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
+    return nullptr;
   }
 
   RemoveChildAt(index, true);
-  return NS_OK;
-}
-
-nsresult
-nsINode::ReplaceOrInsertBefore(bool aReplace, nsIDOMNode* aNewChild,
-                               nsIDOMNode* aRefChild, nsIDOMNode** aReturn)
-{
-  nsCOMPtr<nsINode> newChild = do_QueryInterface(aNewChild);
-
-  nsresult rv;
-  nsCOMPtr<nsINode> refChild;
-  if (aRefChild) {
-      refChild = do_QueryInterface(aRefChild, &rv);
-      NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  rv = ReplaceOrInsertBefore(aReplace, newChild, refChild);
-  if (NS_SUCCEEDED(rv)) {
-    NS_ADDREF(*aReturn = aReplace ? aRefChild : aNewChild);
-  }
-
-  return rv;
+  return &aOldChild;
 }
 
 nsresult
 nsINode::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
 {
-  nsCOMPtr<nsIContent> oldChild = do_QueryInterface(aOldChild);
-  nsresult rv = RemoveChild(oldChild);
-  if (NS_SUCCEEDED(rv)) {
+  nsCOMPtr<nsINode> oldChild = do_QueryInterface(aOldChild);
+  if (!oldChild) {
+    return NS_ERROR_NULL_POINTER;
+  }
+
+  ErrorResult rv;
+  RemoveChild(*oldChild, rv);
+  if (!rv.Failed()) {
     NS_ADDREF(*aReturn = aOldChild);
   }
-  return rv;
+  return rv.ErrorCode();
 }
 
-nsresult
+void
 nsINode::Normalize()
 {
   // First collect list of nodes to be removed
   nsAutoTArray<nsCOMPtr<nsIContent>, 50> nodes;
 
   bool canMerge = false;
   for (nsIContent* node = this->GetFirstChild();
        node;
@@ -509,32 +487,32 @@ nsINode::Normalize()
     }
 
     // If there's no following sibling, then we need to ensure that we don't
     // collect following siblings of our (grand)parent as to-be-removed
     canMerge = canMerge && !!node->GetNextSibling();
   }
 
   if (nodes.IsEmpty()) {
-    return NS_OK;
+    return;
   }
 
   // We're relying on mozAutoSubtreeModified to keep the doc alive here.
   nsIDocument* doc = OwnerDoc();
 
   // Batch possible DOMSubtreeModified events.
   mozAutoSubtreeModified subtree(doc, nullptr);
 
   // Fire all DOMNodeRemoved events. Optimize the common case of there being
   // no listeners
   bool hasRemoveListeners = nsContentUtils::
       HasMutationListeners(doc, NS_EVENT_BITS_MUTATION_NODEREMOVED);
   if (hasRemoveListeners) {
     for (uint32_t i = 0; i < nodes.Length(); ++i) {
-      nsContentUtils::MaybeFireNodeRemoved(nodes[i], nodes[i]->GetNodeParent(),
+      nsContentUtils::MaybeFireNodeRemoved(nodes[i], nodes[i]->GetParentNode(),
                                            doc);
     }
   }
 
   mozAutoDocUpdate batch(doc, UPDATE_CONTENT_MODEL, true);
 
   // Merge and remove all nodes
   nsAutoString tmpStr;
@@ -558,44 +536,40 @@ nsINode::Normalize()
           tmpStr.Truncate();
           text->AppendTo(tmpStr);
           t->AppendTextForNormalize(tmpStr.get(), tmpStr.Length(), true, node);
         }
       }
     }
 
     // Remove node
-    nsCOMPtr<nsINode> parent = node->GetNodeParent();
+    nsCOMPtr<nsINode> parent = node->GetParentNode();
     NS_ASSERTION(parent || hasRemoveListeners,
                  "Should always have a parent unless "
                  "mutation events messed us up");
     if (parent) {
       parent->RemoveChildAt(parent->IndexOf(node), true);
     }
   }
-
-  return NS_OK;
 }
 
-nsresult
-nsINode::GetDOMBaseURI(nsAString &aURI) const
+void
+nsINode::GetBaseURI(nsAString &aURI) const
 {
   nsCOMPtr<nsIURI> baseURI = GetBaseURI();
 
   nsAutoCString spec;
   if (baseURI) {
     baseURI->GetSpec(spec);
   }
 
   CopyUTF8toUTF16(spec, aURI);
-
-  return NS_OK;
 }
 
-nsresult
+void
 nsINode::LookupPrefix(const nsAString& aNamespaceURI, nsAString& aPrefix)
 {
   Element *element = GetNameSpaceElement();
   if (element) {
     // XXX Waiting for DOM spec to list error codes.
   
     // Trace up the content parent chain looking for the namespace
     // declaration that defines the aNamespaceURI namespace. Once found,
@@ -615,25 +589,23 @@ nsINode::LookupPrefix(const nsAString& a
           nsIAtom *localName = name->LocalName();
   
           if (localName != nsGkAtoms::xmlns) {
             localName->ToString(aPrefix);
           }
           else {
             SetDOMStringToNull(aPrefix);
           }
-          return NS_OK;
+          return;
         }
       }
     }
   }
 
   SetDOMStringToNull(aPrefix);
-
-  return NS_OK;
 }
 
 static nsresult
 SetUserDataProperty(uint16_t aCategory, nsINode *aNode, nsIAtom *aKey,
                     nsISupports* aValue, void** aOldValue)
 {
   nsresult rv = aNode->SetProperty(aCategory, aKey, aValue,
                                    nsPropertyTable::SupportsDtorFunc, true,
@@ -685,44 +657,83 @@ nsINode::SetUserData(const nsAString &aK
     DeleteProperty(DOM_USER_DATA_HANDLER, key);
   }
 
   oldData.swap(*aResult);
 
   return NS_OK;
 }
 
-uint16_t
-nsINode::CompareDocPosition(nsINode* aOtherNode)
+JS::Value
+nsINode::SetUserData(JSContext* aCx, const nsAString& aKey, JS::Value aData,
+                     nsIDOMUserDataHandler* aHandler, ErrorResult& aError)
 {
-  NS_PRECONDITION(aOtherNode, "don't pass null");
+  nsCOMPtr<nsIVariant> data;
+  aError = nsContentUtils::XPConnect()->JSValToVariant(aCx, &aData,
+                                                       getter_AddRefs(data));
+  if (aError.Failed()) {
+    return JS::UndefinedValue();
+  }
+
+  nsCOMPtr<nsIVariant> oldData;
+  aError = SetUserData(aKey, data, aHandler, getter_AddRefs(oldData));
+  if (aError.Failed()) {
+    return JS::UndefinedValue();
+  }
+
+  if (!oldData) {
+    return JS::NullValue();
+  }
 
-  if (this == aOtherNode) {
+  JS::Value result;
+  aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), oldData,
+                                                    &result);
+  return result;
+}
+
+JS::Value
+nsINode::GetUserData(JSContext* aCx, const nsAString& aKey, ErrorResult& aError)
+{
+  nsIVariant* data = GetUserData(aKey);
+  if (!data) {
+    return JS::NullValue();
+  }
+
+  JS::Value result;
+  aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), data,
+                                                    &result);
+  return result;
+}
+
+uint16_t
+nsINode::CompareDocumentPosition(nsINode& aOtherNode) const
+{
+  if (this == &aOtherNode) {
     return 0;
   }
 
-  nsAutoTArray<nsINode*, 32> parents1, parents2;
+  nsAutoTArray<const nsINode*, 32> parents1, parents2;
 
-  nsINode *node1 = aOtherNode, *node2 = this;
+  const nsINode *node1 = &aOtherNode, *node2 = this;
 
   // Check if either node is an attribute
-  nsIAttribute* attr1 = nullptr;
+  const nsIAttribute* attr1 = nullptr;
   if (node1->IsNodeOfType(nsINode::eATTRIBUTE)) {
-    attr1 = static_cast<nsIAttribute*>(node1);
-    nsIContent* elem = attr1->GetContent();
+    attr1 = static_cast<const nsIAttribute*>(node1);
+    const nsIContent* elem = attr1->GetContent();
     // If there is an owner element add the attribute
     // to the chain and walk up to the element
     if (elem) {
       node1 = elem;
-      parents1.AppendElement(static_cast<nsINode*>(attr1));
+      parents1.AppendElement(attr1);
     }
   }
   if (node2->IsNodeOfType(nsINode::eATTRIBUTE)) {
-    nsIAttribute* attr2 = static_cast<nsIAttribute*>(node2);
-    nsIContent* elem = attr2->GetContent();
+    const nsIAttribute* attr2 = static_cast<const nsIAttribute*>(node2);
+    const nsIContent* elem = attr2->GetContent();
     if (elem == node1 && attr1) {
       // Both nodes are attributes on the same element.
       // Compare position between the attributes.
 
       uint32_t i;
       const nsAttrName* attrName;
       for (i = 0; (attrName = elem->GetAttrNameAt(i)); ++i) {
         if (attrName->Equals(attr1->NodeInfo())) {
@@ -737,56 +748,56 @@ nsINode::CompareDocPosition(nsINode* aOt
         }
       }
       NS_NOTREACHED("neither attribute in the element");
       return nsIDOMNode::DOCUMENT_POSITION_DISCONNECTED;
     }
 
     if (elem) {
       node2 = elem;
-      parents2.AppendElement(static_cast<nsINode*>(attr2));
+      parents2.AppendElement(attr2);
     }
   }
 
   // We now know that both nodes are either nsIContents or nsIDocuments.
   // If either node started out as an attribute, that attribute will have
   // the same relative position as its ownerElement, except if the
   // ownerElement ends up being the container for the other node
 
   // Build the chain of parents
   do {
     parents1.AppendElement(node1);
-    node1 = node1->GetNodeParent();
+    node1 = node1->GetParentNode();
   } while (node1);
   do {
     parents2.AppendElement(node2);
-    node2 = node2->GetNodeParent();
+    node2 = node2->GetParentNode();
   } while (node2);
 
   // Check if the nodes are disconnected.
   uint32_t pos1 = parents1.Length();
   uint32_t pos2 = parents2.Length();
-  nsINode* top1 = parents1.ElementAt(--pos1);
-  nsINode* top2 = parents2.ElementAt(--pos2);
+  const nsINode* top1 = parents1.ElementAt(--pos1);
+  const nsINode* top2 = parents2.ElementAt(--pos2);
   if (top1 != top2) {
     return top1 < top2 ?
       (nsIDOMNode::DOCUMENT_POSITION_PRECEDING |
        nsIDOMNode::DOCUMENT_POSITION_DISCONNECTED |
        nsIDOMNode::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC) :
       (nsIDOMNode::DOCUMENT_POSITION_FOLLOWING |
        nsIDOMNode::DOCUMENT_POSITION_DISCONNECTED |
        nsIDOMNode::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
   }
 
   // Find where the parent chain differs and check indices in the parent.
-  nsINode* parent = top1;
+  const nsINode* parent = top1;
   uint32_t len;
   for (len = NS_MIN(pos1, pos2); len > 0; --len) {
-    nsINode* child1 = parents1.ElementAt(--pos1);
-    nsINode* child2 = parents2.ElementAt(--pos2);
+    const nsINode* child1 = parents1.ElementAt(--pos1);
+    const nsINode* child2 = parents2.ElementAt(--pos2);
     if (child1 != child2) {
       // child1 or child2 can be an attribute here. This will work fine since
       // IndexOf will return -1 for the attribute making the attribute be
       // considered before any child.
       return parent->IndexOf(child1) < parent->IndexOf(child2) ?
         static_cast<uint16_t>(nsIDOMNode::DOCUMENT_POSITION_PRECEDING) :
         static_cast<uint16_t>(nsIDOMNode::DOCUMENT_POSITION_FOLLOWING);
     }
@@ -799,17 +810,17 @@ nsINode::CompareDocPosition(nsINode* aOt
   return pos1 < pos2 ?
     (nsIDOMNode::DOCUMENT_POSITION_PRECEDING |
      nsIDOMNode::DOCUMENT_POSITION_CONTAINS) :
     (nsIDOMNode::DOCUMENT_POSITION_FOLLOWING |
      nsIDOMNode::DOCUMENT_POSITION_CONTAINED_BY);    
 }
 
 bool
-nsINode::IsEqualTo(nsINode* aOther)
+nsINode::IsEqualNode(nsINode* aOther)
 {
   if (!aOther) {
     return false;
   }
 
   nsAutoString string1, string2;
 
   nsINode* node1 = this;
@@ -877,20 +888,18 @@ nsINode::IsEqualTo(nsINode* aOther)
       case nsIDOMNode::DOCUMENT_NODE:
       case nsIDOMNode::DOCUMENT_FRAGMENT_NODE:
         break;
       case nsIDOMNode::ATTRIBUTE_NODE:
       {
         NS_ASSERTION(node1 == this && node2 == aOther,
                      "Did we come upon an attribute node while walking a "
                      "subtree?");
-        nsCOMPtr<nsIDOMNode> domNode1 = do_QueryInterface(node1);
-        nsCOMPtr<nsIDOMNode> domNode2 = do_QueryInterface(node2);
-        domNode1->GetNodeValue(string1);
-        domNode2->GetNodeValue(string2);
+        node1->GetNodeValue(string1);
+        node2->GetNodeValue(string2);
         
         // Returning here as to not bother walking subtree. And there is no
         // risk that we're half way through walking some other subtree since
         // attribute nodes doesn't appear in subtrees.
         return string1.Equals(string2);
       }
       case nsIDOMNode::DOCUMENT_TYPE_NODE:
       {
@@ -952,38 +961,36 @@ nsINode::IsEqualTo(nsINode* aOther)
           break;
         }
 
         if (node2->GetNextSibling()) {
           // node2 has a nextSibling, but node1 doesn't
           return false;
         }
         
-        node1 = node1->GetNodeParent();
-        node2 = node2->GetNodeParent();
+        node1 = node1->GetParentNode();
+        node2 = node2->GetParentNode();
         NS_ASSERTION(node1 && node2, "no parent while walking subtree");
       }
     }
   } while(node2);
 
   return false;
 }
 
-nsresult
+void
 nsINode::LookupNamespaceURI(const nsAString& aNamespacePrefix,
                             nsAString& aNamespaceURI)
 {
   Element *element = GetNameSpaceElement();
   if (!element ||
       NS_FAILED(element->LookupNamespaceURIInternal(aNamespacePrefix,
                                                     aNamespaceURI))) {
     SetDOMStringToNull(aNamespaceURI);
   }
-
-  return NS_OK;
 }
 
 NS_IMPL_DOMTARGET_DEFAULTS(nsINode)
 
 NS_IMETHODIMP
 nsINode::AddEventListener(const nsAString& aType,
                           nsIDOMEventListener *aListener,
                           bool aUseCapture,
@@ -1233,17 +1240,17 @@ nsINode::SetExplicitBaseURI(nsIURI* aURI
     NS_ADDREF(aURI);
   }
   return rv;
 }
 
 static nsresult
 AdoptNodeIntoOwnerDoc(nsINode *aParent, nsINode *aNode)
 {
-  NS_ASSERTION(!aNode->GetNodeParent(),
+  NS_ASSERTION(!aNode->GetParentNode(),
                "Should have removed from parent already");
 
   nsIDocument *doc = aParent->OwnerDoc();
 
   nsresult rv;
   nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(doc, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -1262,17 +1269,17 @@ AdoptNodeIntoOwnerDoc(nsINode *aParent, 
 
   return NS_OK;
 }
 
 nsresult
 nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
                          bool aNotify, nsAttrAndChildArray& aChildArray)
 {
-  NS_PRECONDITION(!aKid->GetNodeParent(),
+  NS_PRECONDITION(!aKid->GetParentNode(),
                   "Inserting node that already has parent");
   nsresult rv;
 
   // The id-handling code, and in the future possibly other code, need to
   // react to unexpected attribute changes.
   nsMutationGuard::DidMutate();
 
   // Do this before checking the child-count since this could cause mutations
@@ -1304,17 +1311,17 @@ nsINode::doInsertChildAt(nsIContent* aKi
     if (GetFirstChild() == aKid) {
       mFirstChild = aKid->GetNextSibling();
     }
     aChildArray.RemoveChildAt(aIndex);
     aKid->UnbindFromTree();
     return rv;
   }
 
-  NS_ASSERTION(aKid->GetNodeParent() == this,
+  NS_ASSERTION(aKid->GetParentNode() == this,
                "Did we run script inappropriately?");
 
   if (aNotify) {
     // Note that we always want to call ContentInserted when things are added
     // as kids to documents
     if (parent && isAppend) {
       nsNodeUtils::ContentAppended(parent, aKid, aIndex);
     } else {
@@ -1333,17 +1340,17 @@ nsINode::doInsertChildAt(nsIContent* aKi
 
   return NS_OK;
 }
 
 void
 nsINode::doRemoveChildAt(uint32_t aIndex, bool aNotify,
                          nsIContent* aKid, nsAttrAndChildArray& aChildArray)
 {
-  NS_PRECONDITION(aKid && aKid->GetNodeParent() == this &&
+  NS_PRECONDITION(aKid && aKid->GetParentNode() == this &&
                   aKid == GetChildAt(aIndex) &&
                   IndexOf(aKid) == (int32_t)aIndex, "Bogus aKid");
 
   nsMutationGuard::DidMutate();
 
   nsIDocument* doc = GetCurrentDoc();
 
   mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, aNotify);
@@ -1510,90 +1517,93 @@ bool IsAllowedAsChild(nsIContent* aNewCh
      * aNewChild is of invalid type.
      */
     break;
   }
 
   return false;
 }
 
-nsresult
+nsINode*
 nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
-                               nsINode* aRefChild)
+                               nsINode* aRefChild, ErrorResult& aError)
 {
   // XXXbz I wish I could assert that nsContentUtils::IsSafeToRunScript() so we
   // could rely on scriptblockers going out of scope to actually run XBL
   // teardown, but various crud adds nodes under scriptblockers (e.g. native
   // anonymous content).  The only good news is those insertions can't trigger
   // the bad XBL cases.
-  if (!aNewChild || (aReplace && !aRefChild)) {
-    return NS_ERROR_NULL_POINTER;
-  }
+  MOZ_ASSERT_IF(aReplace, aRefChild);
 
   if ((!IsNodeOfType(eDOCUMENT) &&
        !IsNodeOfType(eDOCUMENT_FRAGMENT) &&
        !IsElement()) ||
-      !aNewChild->IsNodeOfType(eCONTENT)){
-    return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
+      !aNewChild->IsNodeOfType(eCONTENT)) {
+    aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
+    return nullptr;
   }
 
   uint16_t nodeType = aNewChild->NodeType();
 
   // Before we do anything else, fire all DOMNodeRemoved mutation events
   // We do this up front as to avoid having to deal with script running
   // at random places further down.
   // Scope firing mutation events so that we don't carry any state that
   // might be stale
   {
     // This check happens again further down (though then using IndexOf).
     // We're only checking this here to avoid firing mutation events when
     // none should be fired.
     // It's ok that we do the check twice in the case when firing mutation
     // events as we need to recheck after running script anyway.
-    if (aRefChild && aRefChild->GetNodeParent() != this) {
-      return NS_ERROR_DOM_NOT_FOUND_ERR;
+    if (aRefChild && aRefChild->GetParentNode() != this) {
+      aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
+      return nullptr;
     }
 
     // If we're replacing, fire for node-to-be-replaced.
     // If aRefChild == aNewChild then we'll fire for it in check below
     if (aReplace && aRefChild != aNewChild) {
       nsContentUtils::MaybeFireNodeRemoved(aRefChild, this, OwnerDoc());
     }
 
     // If the new node already has a parent, fire for removing from old
     // parent
-    nsINode* oldParent = aNewChild->GetNodeParent();
+    nsINode* oldParent = aNewChild->GetParentNode();
     if (oldParent) {
       nsContentUtils::MaybeFireNodeRemoved(aNewChild, oldParent,
                                            aNewChild->OwnerDoc());
     }
 
     // If we're inserting a fragment, fire for all the children of the
     // fragment
     if (nodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
       static_cast<nsGenericElement*>(aNewChild)->FireNodeRemovedForChildren();
     }
     // Verify that our aRefChild is still sensible
-    if (aRefChild && aRefChild->GetNodeParent() != this) {
-      return NS_ERROR_DOM_NOT_FOUND_ERR;
+    if (aRefChild && aRefChild->GetParentNode() != this) {
+      aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
+      return nullptr;
     }
   }
 
   nsIDocument* doc = OwnerDoc();
   nsIContent* newContent = static_cast<nsIContent*>(aNewChild);
   if (newContent->IsRootOfAnonymousSubtree()) {
     // This is anonymous content.  Don't allow its insertion
     // anywhere, since it might have UnbindFromTree calls coming
     // its way.
-    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+    aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    return nullptr;
   }
 
   // Make sure that the inserted node is allowed as a child of its new parent.
   if (!IsAllowedAsChild(newContent, this, aReplace, aRefChild)) {
-    return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
+    aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
+    return nullptr;
   }
 
   // Record the node to insert before, if any
   nsINode* nodeToInsertBefore;
   if (aReplace) {
     nodeToInsertBefore = aRefChild->GetNextSibling();
   } else {
     nodeToInsertBefore = aRefChild;
@@ -1602,23 +1612,24 @@ nsINode::ReplaceOrInsertBefore(bool aRep
     // We're going to remove aNewChild from its parent, so use its next sibling
     // as the node to insert before.
     nodeToInsertBefore = nodeToInsertBefore->GetNextSibling();
   }
 
   Maybe<nsAutoTArray<nsCOMPtr<nsIContent>, 50> > fragChildren;
 
   // Remove the new child from the old parent if one exists
-  nsCOMPtr<nsINode> oldParent = newContent->GetNodeParent();
+  nsCOMPtr<nsINode> oldParent = newContent->GetParentNode();
   if (oldParent) {
     int32_t removeIndex = oldParent->IndexOf(newContent);
     if (removeIndex < 0) {
       // newContent is anonymous.  We can't deal with this, so just bail
       NS_ERROR("How come our flags didn't catch this?");
-      return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+      aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+      return nullptr;
     }
 
     // Hold a strong ref to nodeToInsertBefore across the removal of newContent
     nsCOMPtr<nsINode> kungFuDeathGrip = nodeToInsertBefore;
 
     // Removing a child can run script, via XBL destructors.
     nsMutationGuard guard;
 
@@ -1638,35 +1649,39 @@ nsINode::ReplaceOrInsertBefore(bool aRep
 
     // We expect one mutation (the removal) to have happened.
     if (guard.Mutated(1)) {
       // XBL destructors, yuck.
       
       // Verify that nodeToInsertBefore, if non-null, is still our child.  If
       // it's not, there's no way we can do this insert sanely; just bail out.
       if (nodeToInsertBefore && nodeToInsertBefore->GetParent() != this) {
-        return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
+        aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
+        return nullptr;
       }
 
       // Verify that newContent has no parent.
       if (newContent->GetParent()) {
-        return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
+        aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
+        return nullptr;
       }
 
       // And verify that newContent is still allowed as our child.
       if (aNewChild == aRefChild) {
         // We've already removed aRefChild.  So even if we were doing a replace,
         // now we're doing a simple insert before nodeToInsertBefore.
         if (!IsAllowedAsChild(newContent, this, false, nodeToInsertBefore)) {
-          return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
+          aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
+          return nullptr;
         }
       } else {
         if ((aRefChild && aRefChild->GetParent() != this) ||
             !IsAllowedAsChild(newContent, this, aReplace, aRefChild)) {
-          return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
+          aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
+          return nullptr;
         }
         // And recompute nodeToInsertBefore, just in case.
         if (aReplace) {
           nodeToInsertBefore = aRefChild->GetNextSibling();
         } else {
           nodeToInsertBefore = aRefChild;
         }
       }
@@ -1710,34 +1725,37 @@ nsINode::ReplaceOrInsertBefore(bool aRep
 
     // We expect |count| removals
     if (guard.Mutated(count)) {
       // XBL destructors, yuck.
       
       // Verify that nodeToInsertBefore, if non-null, is still our child.  If
       // it's not, there's no way we can do this insert sanely; just bail out.
       if (nodeToInsertBefore && nodeToInsertBefore->GetParent() != this) {
-        return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
+        aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
+        return nullptr;
       }
 
       // Verify that all the things in fragChildren have no parent.
       for (uint32_t i = 0; i < count; ++i) {
         if (fragChildren.ref().ElementAt(i)->GetParent()) {
-          return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
+          aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
+          return nullptr;
         }
       }
 
       // Note that unlike the single-element case above, none of our kids can
       // be aRefChild, so we can always pass through aReplace in the
       // IsAllowedAsChild checks below and don't have to worry about whether
       // recomputing nodeToInsertBefore is OK.
 
       // Verify that our aRefChild is still sensible
       if (aRefChild && aRefChild->GetParent() != this) {
-        return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
+        aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
+        return nullptr;
       }
 
       // Recompute nodeToInsertBefore, just in case.
       if (aReplace) {
         nodeToInsertBefore = aRefChild->GetNextSibling();
       } else {
         nodeToInsertBefore = aRefChild;
       }      
@@ -1748,22 +1766,24 @@ nsINode::ReplaceOrInsertBefore(bool aRep
       // change the code there.
       if (IsNodeOfType(nsINode::eDOCUMENT)) {
         bool sawElement = false;
         for (uint32_t i = 0; i < count; ++i) {
           nsIContent* child = fragChildren.ref().ElementAt(i);
           if (child->IsElement()) {
             if (sawElement) {
               // No good
-              return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
+              aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
+              return nullptr;
             }
             sawElement = true;
           }
           if (!IsAllowedAsChild(child, this, aReplace, aRefChild)) {
-            return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
+            aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
+            return nullptr;
           }
         }
       }
     }
   }
 
   mozAutoDocUpdate batch(GetCurrentDoc(), UPDATE_CONTENT_MODEL, true);
   nsAutoMutationBatch mb;
@@ -1772,17 +1792,18 @@ nsINode::ReplaceOrInsertBefore(bool aRep
   // nodeToInsertBefore to determine this, because it's possible that
   // aRefChild == aNewChild, in which case we just removed it from the
   // parent list.
   int32_t insPos;
   if (nodeToInsertBefore) {
     insPos = IndexOf(nodeToInsertBefore);
     if (insPos < 0) {
       // XXXbz How the heck would _that_ happen, exactly?
-      return NS_ERROR_DOM_NOT_FOUND_ERR;
+      aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
+      return nullptr;
     }
   }
   else {
     insPos = GetChildCount();
   }
 
   // If we're replacing and we haven't removed aRefChild yet, do so now
   if (aReplace && aRefChild != aNewChild) {
@@ -1795,67 +1816,70 @@ nsINode::ReplaceOrInsertBefore(bool aRep
 
     // An since nodeToInsertBefore is at index insPos, we want to remove
     // at the previous index.
     NS_ASSERTION(insPos >= 1, "insPos too small");
     RemoveChildAt(insPos-1, true);
     --insPos;
   }
 
-  nsresult res = NS_OK;
   // Move new child over to our document if needed. Do this after removing
   // it from its parent so that AdoptNode doesn't fire DOMNodeRemoved
   // DocumentType nodes are the only nodes that can have a null
   // ownerDocument according to the DOM spec, and we need to allow
   // inserting them w/o calling AdoptNode().
   if (!HasSameOwnerDoc(newContent)) {
-    res = AdoptNodeIntoOwnerDoc(this, aNewChild);
-    NS_ENSURE_SUCCESS(res, res);
+    aError = AdoptNodeIntoOwnerDoc(this, aNewChild);
+    if (aError.Failed()) {
+      return nullptr;
+    }
   }
 
   /*
    * Check if we're inserting a document fragment. If we are, we need
    * to actually add its children individually (i.e. we don't add the
    * actual document fragment).
    */
+  nsINode* result = aReplace ? aRefChild : aNewChild;
   if (nodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
     if (!aReplace) {
       mb.Init(this, true, true);
     }
     nsAutoMutationBatch* mutationBatch = nsAutoMutationBatch::GetCurrentBatch();
     if (mutationBatch) {
       mutationBatch->RemovalDone();
       mutationBatch->SetPrevSibling(GetChildAt(insPos - 1));
       mutationBatch->SetNextSibling(GetChildAt(insPos));
     }
 
     uint32_t count = fragChildren.ref().Length();
     if (!count) {
-      return NS_OK;
+      return result;
     }
 
     bool appending =
       !IsNodeOfType(eDOCUMENT) && uint32_t(insPos) == GetChildCount();
     int32_t firstInsPos = insPos;
     nsIContent* firstInsertedContent = fragChildren.ref().ElementAt(0);
 
     // Iterate through the fragment's children, and insert them in the new
     // parent
     for (uint32_t i = 0; i < count; ++i, ++insPos) {
       // XXXbz how come no reparenting here?  That seems odd...
       // Insert the child.
-      res = InsertChildAt(fragChildren.ref().ElementAt(i), insPos, !appending);
-      if (NS_FAILED(res)) {
+      aError = InsertChildAt(fragChildren.ref().ElementAt(i), insPos,
+                             !appending);
+      if (aError.Failed()) {
         // Make sure to notify on any children that we did succeed to insert
         if (appending && i != 0) {
           nsNodeUtils::ContentAppended(static_cast<nsIContent*>(this),
                                        firstInsertedContent,
                                        firstInsPos);
         }
-        return res;
+        return nullptr;
       }
     }
 
     if (mutationBatch && !appending) {
       mutationBatch->NodesAdded();
     }
 
     // Notify and fire mutation events when appending
@@ -1880,39 +1904,65 @@ nsINode::ReplaceOrInsertBefore(bool aRep
     //       wrapper is not the wrapper for their ownerDocument (XUL elements,
     //       form controls, ...). Also applies in the fragment code above.
 
     if (nsAutoMutationBatch::GetCurrentBatch() == &mb) {
       mb.RemovalDone();
       mb.SetPrevSibling(GetChildAt(insPos - 1));
       mb.SetNextSibling(GetChildAt(insPos));
     }
-    res = InsertChildAt(newContent, insPos, true);
-    NS_ENSURE_SUCCESS(res, res);
+    aError = InsertChildAt(newContent, insPos, true);
+    if (aError.Failed()) {
+      return nullptr;
+    }
   }
 
-  return NS_OK;
+  return result;
+}
+
+nsresult
+nsINode::ReplaceOrInsertBefore(bool aReplace, nsIDOMNode *aNewChild,
+                               nsIDOMNode *aRefChild, nsIDOMNode **aReturn)
+{
+  nsCOMPtr<nsINode> newChild = do_QueryInterface(aNewChild);
+  if (!newChild) {
+    return NS_ERROR_NULL_POINTER;
+  }
+
+  if (aReplace && !aRefChild) {
+    return NS_ERROR_NULL_POINTER;
+  }
+
+  nsCOMPtr<nsINode> refChild = do_QueryInterface(aRefChild);
+  if (aRefChild && !refChild) {
+    return NS_NOINTERFACE;
+  }
+
+  ErrorResult rv;
+  nsINode* result = ReplaceOrInsertBefore(aReplace, newChild, refChild, rv);
+  if (result) {
+    NS_ADDREF(*aReturn = result->AsDOMNode());
+  }
+  return rv.ErrorCode();
 }
 
 nsresult
 nsINode::CompareDocumentPosition(nsIDOMNode* aOther, uint16_t* aReturn)
 {
   nsCOMPtr<nsINode> other = do_QueryInterface(aOther);
-  if (!other) {
-    return NS_ERROR_NULL_POINTER;
-  }
-  *aReturn = CompareDocPosition(other);
+  NS_ENSURE_ARG(other);
+  *aReturn = CompareDocumentPosition(*other);
   return NS_OK;
 }
 
 nsresult
 nsINode::IsEqualNode(nsIDOMNode* aOther, bool* aReturn)
 {
   nsCOMPtr<nsINode> other = do_QueryInterface(aOther);
-  *aReturn = IsEqualTo(other);
+  *aReturn = IsEqualNode(other);
   return NS_OK;
 }
 
 static void
 nsCOMArrayDeleter(void* aObject, nsIAtom* aPropertyName,
                   void* aPropertyValue, void* aData)
 {
   nsCOMArray<nsISupports>* objects =
@@ -2236,8 +2286,85 @@ nsINode::QuerySelectorAll(const nsAStrin
 
   nsSimpleContentList* contentList = new nsSimpleContentList(this);
   NS_ENSURE_TRUE(contentList, NS_ERROR_OUT_OF_MEMORY);
   NS_ADDREF(*aReturn = contentList);
 
   return FindMatchingElements<false>(this, aSelector, *contentList);
 }
 
+JSObject*
+nsINode::WrapObject(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
+{
+  // Not all nodes have been converted
+  if (!IsDOMBinding()) {
+    *aTriedToWrap = false;
+    return nullptr;
+  }
+
+  // Make sure one of these is true
+  // (1) our owner document has a script handling object,
+  // (2) Our owner document has had a script handling object, or has been marked
+  //     to have had one,
+  // (3) we are running a privileged script.
+  // Event handling is possible only if (1). If (2) event handling is
+  // prevented.
+  // If the document has never had a script handling object, untrusted
+  // scripts (3) shouldn't touch it!
+  bool hasHadScriptHandlingObject = false;
+  bool enabled;
+  nsIScriptSecurityManager* securityManager;
+  if (!OwnerDoc()->GetScriptHandlingObject(hasHadScriptHandlingObject) &&
+      !hasHadScriptHandlingObject &&
+      !((securityManager = nsContentUtils::GetSecurityManager()) &&
+        NS_SUCCEEDED(securityManager->IsCapabilityEnabled("UniversalXPConnect",
+                                                          &enabled)) &&
+        enabled)) {
+    Throw<true>(aCx, NS_ERROR_UNEXPECTED);
+    *aTriedToWrap = true;
+    return nullptr;
+  }
+
+  return WrapNode(aCx, aScope, aTriedToWrap);
+}
+
+bool
+nsINode::IsSupported(const nsAString& aFeature, const nsAString& aVersion)
+{
+  return nsContentUtils::InternalIsSupported(this, aFeature, aVersion);
+}
+
+nsGenericElement*
+nsINode::GetParentElement() const
+{
+  return static_cast<nsGenericElement*>(GetElementParent());
+}
+
+already_AddRefed<nsINode>
+nsINode::CloneNode(bool aDeep, ErrorResult& aError)
+{
+  bool callUserDataHandlers = NodeType() != nsIDOMNode::DOCUMENT_NODE ||
+                              !static_cast<nsIDocument*>(this)->CreatingStaticClone();
+
+  nsCOMPtr<nsINode> result;
+  aError = nsNodeUtils::CloneNodeImpl(this, aDeep, callUserDataHandlers,
+                                      getter_AddRefs(result));
+  return result.forget();
+}
+
+nsDOMAttributeMap*
+nsINode::GetAttributes()
+{
+  if (!IsElement()) {
+    return nullptr;
+  }
+  return static_cast<nsGenericElement*>(nsINode::AsElement())->GetAttributes();
+}
+
+nsresult
+nsINode::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
+{
+  if (!IsElement()) {
+    *aAttributes = nullptr;
+    return NS_OK;
+  }
+  return CallQueryInterface(GetAttributes(), aAttributes);
+}
--- a/content/base/src/nsNodeInfo.cpp
+++ b/content/base/src/nsNodeInfo.cpp
@@ -102,16 +102,21 @@ nsNodeInfo::nsNodeInfo(nsIAtom *aName, n
   if (aPrefix) {
     mQualifiedName = nsDependentAtomString(mInner.mPrefix) +
                      NS_LITERAL_STRING(":") +
                      nsDependentAtomString(mInner.mName);
   } else {
     mInner.mName->ToString(mQualifiedName);
   }
 
+  MOZ_ASSERT_IF(aNodeType != nsIDOMNode::ELEMENT_NODE &&
+                aNodeType != nsIDOMNode::ATTRIBUTE_NODE &&
+                aNodeType != UINT16_MAX,
+                aNamespaceID == kNameSpaceID_None && !aPrefix);
+
   switch (aNodeType) {
     case nsIDOMNode::ELEMENT_NODE:
     case nsIDOMNode::ATTRIBUTE_NODE:
       // Correct the case for HTML
       if (aNodeType == nsIDOMNode::ELEMENT_NODE &&
           aNamespaceID == kNameSpaceID_XHTML && GetDocument() &&
           GetDocument()->IsHTML()) {
         nsContentUtils::ASCIIToUpper(mQualifiedName, mNodeName);
--- a/content/base/src/nsNodeIterator.cpp
+++ b/content/base/src/nsNodeIterator.cpp
@@ -57,17 +57,17 @@ bool nsNodeIterator::NodePointer::MoveTo
     if (!mBeforeNode) {
         mBeforeNode = true;
         return true;
     }
 
     if (mNode == aRoot)
         return false;
 
-    MoveBackward(mNode->GetNodeParent(), mNode->GetPreviousSibling());
+    MoveBackward(mNode->GetParentNode(), mNode->GetPreviousSibling());
 
     return true;
 }
 
 void nsNodeIterator::NodePointer::AdjustAfterRemoval(nsINode *aRoot,
                                                      nsINode *aContainer,
                                                      nsIContent *aChild,
                                                      nsIContent *aPreviousSibling)
@@ -108,17 +108,17 @@ bool nsNodeIterator::NodePointer::MoveFo
         if (aNode == aRoot)
             break;
 
         nsINode *sibling = aNode->GetNextSibling();
         if (sibling) {
             mNode = sibling;
             return true;
         }
-        aNode = aNode->GetNodeParent();
+        aNode = aNode->GetParentNode();
     }
 
     return false;
 }
 
 void nsNodeIterator::NodePointer::MoveBackward(nsINode *aParent, nsINode *aNode)
 {
     if (aNode) {
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -53,17 +53,17 @@ using namespace mozilla::dom;
     nsINode::nsSlots* slots = node->GetExistingSlots();           \
     if (slots && !slots->mMutationObservers.IsEmpty()) {          \
       /* No need to explicitly notify the first observer first    \
          since that'll happen anyway. */                          \
       NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(                         \
         slots->mMutationObservers, nsIMutationObserver,           \
         func_, params_);                                          \
     }                                                             \
-    node = node->GetNodeParent();                                 \
+    node = node->GetParentNode();                                 \
   } while (node);                                                 \
   if (needsEnterLeave) {                                          \
     nsDOMMutationObserver::LeaveMutationHandling();               \
   }                                                               \
   PR_END_MACRO
 
 void
 nsNodeUtils::CharacterDataWillChange(nsIContent* aContent,
@@ -354,21 +354,21 @@ nsNodeUtils::TraverseUserData(nsINode* a
   ownerDoc->PropertyTable(DOM_USER_DATA)->Enumerate(aNode, NoteUserData, &aCb);
   ownerDoc->PropertyTable(DOM_USER_DATA_HANDLER)->Enumerate(aNode, NoteUserData, &aCb);
 }
 
 /* static */
 nsresult
 nsNodeUtils::CloneNodeImpl(nsINode *aNode, bool aDeep,
                            bool aCallUserDataHandlers,
-                           nsIDOMNode **aResult)
+                           nsINode **aResult)
 {
   *aResult = nullptr;
 
-  nsCOMPtr<nsIDOMNode> newNode;
+  nsCOMPtr<nsINode> newNode;
   nsCOMArray<nsINode> nodesWithProperties;
   nsresult rv = Clone(aNode, aDeep, nullptr, nodesWithProperties,
                       getter_AddRefs(newNode));
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aCallUserDataHandlers) {
     rv = CallUserDataHandlers(nodesWithProperties, aNode->OwnerDoc(),
                               nsIDOMUserDataHandler::NODE_CLONED, true);
--- a/content/base/src/nsNodeUtils.h
+++ b/content/base/src/nsNodeUtils.h
@@ -145,20 +145,20 @@ public:
    * @param aNodesWithProperties All nodes (from amongst aNode and its
    *                             descendants) with properties. Every node will
    *                             be followed by its clone.
    * @param aResult *aResult will contain the cloned node.
    */
   static nsresult Clone(nsINode *aNode, bool aDeep,
                         nsNodeInfoManager *aNewNodeInfoManager,
                         nsCOMArray<nsINode> &aNodesWithProperties,
-                        nsIDOMNode **aResult)
+                        nsINode **aResult)
   {
     return CloneAndAdopt(aNode, true, aDeep, aNewNodeInfoManager, nullptr,
-                         nullptr, aNodesWithProperties, aResult);
+                         nullptr, aNodesWithProperties, nullptr, aResult);
   }
 
   /**
    * Walks aNode, its attributes and descendant nodes. If aNewNodeInfoManager is
    * not null, it is used to create new nodeinfos for the nodes. Also reparents
    * the XPConnect wrappers for the nodes in aNewScope if aCx is not null.
    * aNodesWithProperties will be filled with all the nodes that have
    * properties.
@@ -174,19 +174,20 @@ public:
    * @param aNewScope New scope for the wrappers. May be null if aCx is null.
    * @param aNodesWithProperties All nodes (from amongst aNode and its
    *                             descendants) with properties.
    */
   static nsresult Adopt(nsINode *aNode, nsNodeInfoManager *aNewNodeInfoManager,
                         JSContext *aCx, JSObject *aNewScope,
                         nsCOMArray<nsINode> &aNodesWithProperties)
   {
+    nsCOMPtr<nsINode> node;
     nsresult rv = CloneAndAdopt(aNode, false, true, aNewNodeInfoManager,
                                 aCx, aNewScope, aNodesWithProperties,
-                                nullptr);
+                                nullptr, getter_AddRefs(node));
 
     nsMutationGuard::DidMutate();
 
     return rv;
   }
 
   /**
    * Call registered userdata handlers for operation aOperation for the nodes in
@@ -223,17 +224,17 @@ public:
    *
    * @param aNode the node to clone
    * @param aDeep if true all descendants will be cloned too
    * @param aCallUserDataHandlers if true, user data handlers will be called
    * @param aResult the clone
    */
   static nsresult CloneNodeImpl(nsINode *aNode, bool aDeep,
                                 bool aCallUserDataHandlers,
-                                nsIDOMNode **aResult);
+                                nsINode **aResult);
 
   /**
    * Release the UserData and UserDataHandlers for aNode.
    *
    * @param aNode the node to release the UserData and UserDataHandlers for
    */
   static void UnlinkUserData(nsINode *aNode);
 
@@ -258,41 +259,16 @@ private:
    * @param aCx Context to use for reparenting the wrappers, or null if no
    *            reparenting should be done. Must be null if aClone is true or
    *            if aNewNodeInfoManager is null.
    * @param aNewScope New scope for the wrappers. May be null if aCx is null.
    * @param aNodesWithProperties All nodes (from amongst aNode and its
    *                             descendants) with properties. If aClone is
    *                             true every node will be followed by its
    *                             clone.
-   * @param aResult If aClone is false then aResult must be null, else
-   *                *aResult will contain the cloned node.
-   */
-  static nsresult CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
-                                nsNodeInfoManager *aNewNodeInfoManager,
-                                JSContext *aCx, JSObject *aNewScope,
-                                nsCOMArray<nsINode> &aNodesWithProperties,
-                                nsIDOMNode **aResult)
-  {
-    NS_ASSERTION(!aClone == !aResult,
-                 "aResult must be null when adopting and non-null when "
-                 "cloning");
-
-    nsCOMPtr<nsINode> clone;
-    nsresult rv = CloneAndAdopt(aNode, aClone, aDeep, aNewNodeInfoManager,
-                                aCx, aNewScope, aNodesWithProperties,
-                                nullptr, getter_AddRefs(clone));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    return clone ? CallQueryInterface(clone, aResult) : NS_OK;
-  }
-
-  /**
-   * See above for arguments that aren't described here.
-   *
    * @param aParent If aClone is true the cloned node will be appended to
    *                aParent's children. May be null. If not null then aNode
    *                must be an nsIContent.
    * @param aResult If aClone is true then *aResult will contain the cloned
    *                node.
    */
   static nsresult CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
                                 nsNodeInfoManager *aNewNodeInfoManager,
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -1668,17 +1668,17 @@ nsObjectLoadingContent::LoadObject(bool 
   // reason click-to-play instead
   FallbackType clickToPlayReason;
   if (mType == eType_Plugin && !ShouldPlay(clickToPlayReason)) {
     LOG(("OBJLC [%p]: Marking plugin as click-to-play", this));
     mType = eType_Null;
     fallbackType = clickToPlayReason;
   }
 
-  if (!mActivated && mType != eType_Null) {
+  if (!mActivated && mType == eType_Plugin) {
     // Object passed ShouldPlay and !ShouldPreview, so it should be considered
     // activated until it changes content type
     LOG(("OBJLC [%p]: Object implicitly activated", this));
     mActivated = true;
   }
 
   // Sanity check: We shouldn't have any loaded resources, pending events, or
   // a final listener at this point
--- a/content/base/src/nsRange.cpp
+++ b/content/base/src/nsRange.cpp
@@ -95,17 +95,17 @@ nsRange::CompareNodeToRange(nsINode* aNo
   // if (RANGE(start) <= NODE(start))  and (RANGE(end) => NODE(end))
   // then the Node is contained (completely) by the Range.
   
   if (!aRange || !aRange->IsPositioned()) 
     return NS_ERROR_UNEXPECTED; 
   
   // gather up the dom point info
   int32_t nodeStart, nodeEnd;
-  nsINode* parent = aNode->GetNodeParent();
+  nsINode* parent = aNode->GetParentNode();
   if (!parent) {
     // can't make a parent/offset pair to represent start or 
     // end of the root node, because it has no parent.
     // so instead represent it by (node,0) and (node,numChildren)
     parent = aNode;
     nodeStart = 0;
     nodeEnd = aNode->GetChildCount();
   }
@@ -168,32 +168,32 @@ FindSelectedRange(nsPtrHashKey<nsRange>*
 
 static nsINode*
 GetNextRangeCommonAncestor(nsINode* aNode)
 {
   while (aNode && !aNode->IsCommonAncestorForRangeInSelection()) {
     if (!aNode->IsDescendantOfCommonAncestorForRangeInSelection()) {
       return nullptr;
     }
-    aNode = aNode->GetNodeParent();
+    aNode = aNode->GetParentNode();
   }
   return aNode;
 }
 
 /* static */ bool
 nsRange::IsNodeSelected(nsINode* aNode, uint32_t aStartOffset,
                         uint32_t aEndOffset)
 {
   NS_PRECONDITION(aNode, "bad arg");
 
   FindSelectedRangeData data = { aNode, nullptr, aStartOffset, aEndOffset };
   nsINode* n = GetNextRangeCommonAncestor(aNode);
   NS_ASSERTION(n || !aNode->IsSelectionDescendant(),
                "orphan selection descendant");
-  for (; n; n = GetNextRangeCommonAncestor(n->GetNodeParent())) {
+  for (; n; n = GetNextRangeCommonAncestor(n->GetParentNode())) {
     RangeHashTable* ranges =
       static_cast<RangeHashTable*>(n->GetProperty(nsGkAtoms::range));
     ranges->EnumerateEntries(FindSelectedRange, &data);
     if (data.mResult) {
       return true;
     }
   }
   return false;
@@ -417,31 +417,31 @@ nsRange::CharacterDataChanged(nsIDocumen
     }
   }
 
   // Do the same thing for the end boundary, except for splitText of a node
   // with no parent then only switch to the new node if the start boundary
   // did so too (otherwise the range would end up with disconnected nodes).
   if (aContent == mEndParent &&
       aInfo->mChangeStart < static_cast<uint32_t>(mEndOffset)) {
-    if (aInfo->mDetails && (aContent->GetNodeParent() || newStartNode)) {
+    if (aInfo->mDetails && (aContent->GetParentNode() || newStartNode)) {
       // splitText(), aInfo->mDetails->mNextSibling is the new text node
       NS_ASSERTION(aInfo->mDetails->mType ==
                    CharacterDataChangeInfo::Details::eSplit,
                    "only a split can start before the end");
       NS_ASSERTION(static_cast<uint32_t>(mEndOffset) <= aInfo->mChangeEnd + 1,
                    "mEndOffset is beyond the end of this node");
       newEndOffset = static_cast<uint32_t>(mEndOffset) - aInfo->mChangeStart;
       newEndNode = aInfo->mDetails->mNextSibling;
 
       bool isCommonAncestor = IsInSelection() && mStartParent == mEndParent;
       if (isCommonAncestor && !newStartNode) {
         // The split occurs inside the range.
         UnregisterCommonAncestor(mStartParent);
-        RegisterCommonAncestor(mStartParent->GetNodeParent());
+        RegisterCommonAncestor(mStartParent->GetParentNode());
         newEndNode->SetDescendantOfCommonAncestorForRangeInSelection();
       } else if (mEndParent->IsDescendantOfCommonAncestorForRangeInSelection()) {
         newEndNode->SetDescendantOfCommonAncestorForRangeInSelection();
       }
     } else {
       mEndOffset = static_cast<uint32_t>(mEndOffset) <= aInfo->mChangeEnd ?
         aInfo->mChangeStart :
         mEndOffset + aInfo->mChangeStart - aInfo->mChangeEnd +
@@ -475,17 +475,17 @@ nsRange::CharacterDataChanged(nsIDocumen
       newStartOffset = mStartOffset;
     }
     if (!newEndNode) {
       newEndNode = mEndParent;
       newEndOffset = mEndOffset;
     }
     DoSetRange(newStartNode, newStartOffset, newEndNode, newEndOffset,
                newRoot ? newRoot : mRoot.get(),
-               !newEndNode->GetNodeParent() || !newStartNode->GetNodeParent());
+               !newEndNode->GetParentNode() || !newStartNode->GetParentNode());
   }
 }
 
 void
 nsRange::ContentAppended(nsIDocument* aDocument,
                          nsIContent*  aContainer,
                          nsIContent*  aFirstNewContent,
                          int32_t      aNewIndexInContainer)
@@ -657,17 +657,17 @@ nsRange::IntersectsNode(nsIDOMNode* aNod
 
   nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
   // TODO: This should throw a TypeError.
   NS_ENSURE_ARG(node);
 
   NS_ENSURE_TRUE(mIsPositioned, NS_ERROR_NOT_INITIALIZED);
 
   // Step 3.
-  nsINode* parent = node->GetNodeParent();
+  nsINode* parent = node->GetParentNode();
   if (!parent) {
     // Steps 2 and 4. 
     // |parent| is null, so |node|'s root is |node| itself.
     *aResult = (GetRoot() == node);
     return NS_OK;
   }
 
   // Step 5.
@@ -715,17 +715,17 @@ nsRange::DoSetRange(nsINode* aStartN, in
                   "Wrong root");
   NS_PRECONDITION(!aRoot ||
                   (aStartN->IsNodeOfType(nsINode::eCONTENT) &&
                    aEndN->IsNodeOfType(nsINode::eCONTENT) &&
                    aRoot ==
                     static_cast<nsIContent*>(aStartN)->GetBindingParent() &&
                    aRoot ==
                     static_cast<nsIContent*>(aEndN)->GetBindingParent()) ||
-                  (!aRoot->GetNodeParent() &&
+                  (!aRoot->GetParentNode() &&
                    (aRoot->IsNodeOfType(nsINode::eDOCUMENT) ||
                     aRoot->IsNodeOfType(nsINode::eATTRIBUTE) ||
                     aRoot->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT) ||
                      /*For backward compatibility*/
                     aRoot->IsNodeOfType(nsINode::eCONTENT))),
                   "Bad root");
 
   if (mRoot != aRoot) {
@@ -769,17 +769,17 @@ IndexOf(nsIDOMNode* aChildNode)
 {
   // convert node to nsIContent, so that we can find the child index
 
   nsCOMPtr<nsINode> child = do_QueryInterface(aChildNode);
   if (!child) {
     return -1;
   }
 
-  nsINode *parent = child->GetNodeParent();
+  nsINode *parent = child->GetParentNode();
 
   // finally we get the index
   return parent ? parent->IndexOf(child) : -1;
 }
 
 nsINode*
 nsRange::GetCommonAncestor() const
 {
@@ -890,17 +890,17 @@ nsRange::IsValidBoundary(nsINode* aNode)
   // Elements etc. must be in document or in document fragment,
   // text nodes in document, in document fragment or in attribute.
   nsINode* root = aNode->GetCurrentDoc();
   if (root) {
     return root;
   }
 
   root = aNode;
-  while ((aNode = aNode->GetNodeParent())) {
+  while ((aNode = aNode->GetParentNode())) {
     root = aNode;
   }
 
   NS_ASSERTION(!root->IsNodeOfType(nsINode::eDOCUMENT),
                "GetCurrentDoc should have returned a doc");
 
 #ifdef DEBUG_smaug
   NS_WARN_IF_FALSE(root->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT) ||
@@ -1057,17 +1057,17 @@ nsRange::Collapse(bool aToStart)
 NS_IMETHODIMP
 nsRange::SelectNode(nsIDOMNode* aN)
 {
   VALIDATE_ACCESS(aN);
   
   nsCOMPtr<nsINode> node = do_QueryInterface(aN);
   NS_ENSURE_TRUE(node, NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
 
-  nsINode* parent = node->GetNodeParent();
+  nsINode* parent = node->GetParentNode();
   nsINode* newRoot = IsValidBoundary(parent);
   NS_ENSURE_TRUE(newRoot, NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
 
   int32_t index = parent->IndexOf(node);
   if (index < 0) {
     return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
   }
 
@@ -1435,29 +1435,16 @@ CollapseRangeAfterDelete(nsIDOMRange *aR
 
   res = aRange->SelectNode(nodeToSelect);
   if (NS_FAILED(res)) return res;
 
   return aRange->Collapse(false);
 }
 
 /**
- * Remove a node from the DOM entirely.
- *
- * @param aNode The node to remove.
- */
-static nsresult
-RemoveNode(nsIDOMNode* aNode)
-{
-  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-  nsCOMPtr<nsINode> parent = node->GetNodeParent();
-  return parent ? parent->RemoveChild(node) : NS_OK;
-}
-
-/**
  * Split a data node into two parts.
  *
  * @param aStartNode          The original node we are trying to split.
  * @param aStartIndex         The index at which to split.
  * @param aEndNode            The second node.
  * @param aCloneAfterOriginal Set false if the original node should be the
  *                            latter one after split.
  */
@@ -1755,18 +1742,23 @@ nsresult nsRange::CutContents(nsIDOMDocu
       nodeToResult->GetParentNode(getter_AddRefs(parent));
       rv = closestAncestor ? PrependChild(closestAncestor, nodeToResult)
                            : PrependChild(commonCloneAncestor, nodeToResult);
       NS_ENSURE_SUCCESS(rv, rv);
       NS_ENSURE_STATE(!guard.Mutated(parent ? 2 : 1) ||
                       ValidateCurrentNode(this, iter));
     } else if (nodeToResult) {
       nsMutationGuard guard;
-      rv = RemoveNode(nodeToResult);
-      NS_ENSURE_SUCCESS(rv, rv);
+      nsCOMPtr<nsINode> node = do_QueryInterface(nodeToResult);
+      nsINode* parent = node->GetParentNode();
+      if (parent) {
+        mozilla::ErrorResult error;
+        parent->RemoveChild(*node, error);
+        NS_ENSURE_FALSE(error.Failed(), error.ErrorCode());
+      }
       NS_ENSURE_STATE(!guard.Mutated(1) ||
                       ValidateCurrentNode(this, iter));
     }
 
     if (!iter.IsDone() && retval) {
       // Find the equivalent of commonAncestor in the cloned tree.
       nsCOMPtr<nsIDOMNode> newCloneAncestor = nodeToResult;
       for (uint32_t i = parentCount; i; --i)
@@ -2190,18 +2182,18 @@ nsRange::SurroundContents(nsIDOMNode* aN
   VALIDATE_ACCESS(aNewParent);
 
   NS_ENSURE_TRUE(mRoot, NS_ERROR_DOM_INVALID_STATE_ERR);
   // INVALID_STATE_ERROR: Raised if the Range partially selects a non-text
   // node.
   if (mStartParent != mEndParent) {
     bool startIsText = mStartParent->IsNodeOfType(nsINode::eTEXT);
     bool endIsText = mEndParent->IsNodeOfType(nsINode::eTEXT);
-    nsINode* startGrandParent = mStartParent->GetNodeParent();
-    nsINode* endGrandParent = mEndParent->GetNodeParent();
+    nsINode* startGrandParent = mStartParent->GetParentNode();
+    nsINode* endGrandParent = mEndParent->GetParentNode();
     NS_ENSURE_TRUE((startIsText && endIsText &&
                     startGrandParent &&
                     startGrandParent == endGrandParent) ||
                    (startIsText &&
                     startGrandParent &&
                     startGrandParent == mEndParent) ||
                    (endIsText &&
                     endGrandParent &&
@@ -2625,17 +2617,17 @@ nsRange::GetRegisteredCommonAncestor()
                "GetRegisteredCommonAncestor only valid for range in selection");
   nsINode* ancestor = GetNextRangeCommonAncestor(mStartParent);
   while (ancestor) {
     RangeHashTable* ranges =
       static_cast<RangeHashTable*>(ancestor->GetProperty(nsGkAtoms::range));
     if (ranges->GetEntry(this)) {
       break;
     }
-    ancestor = GetNextRangeCommonAncestor(ancestor->GetNodeParent());
+    ancestor = GetNextRangeCommonAncestor(ancestor->GetParentNode());
   }
   NS_ASSERTION(ancestor, "can't find common ancestor for selected range");
   return ancestor;
 }
 
 /* static */ bool nsRange::AutoInvalidateSelection::mIsNested;
 
 nsRange::AutoInvalidateSelection::~AutoInvalidateSelection()
--- a/content/base/src/nsTextNode.h
+++ b/content/base/src/nsTextNode.h
@@ -19,17 +19,17 @@ class nsTextNode : public nsGenericDOMDa
 public:
   nsTextNode(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsTextNode();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericDOMDataNode::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMCharacterData
   NS_FORWARD_NSIDOMCHARACTERDATA(nsGenericDOMDataNode::)
 
   // nsIDOMText
   NS_FORWARD_NSIDOMTEXT(nsGenericDOMDataNode::)
 
   // nsINode
--- a/content/base/src/nsTreeSanitizer.cpp
+++ b/content/base/src/nsTreeSanitizer.cpp
@@ -1408,17 +1408,17 @@ nsTreeSanitizer::SanitizeChildren(nsINod
 
       if (MustPrune(ns, localName, elt)) {
         RemoveAllAttributes(node);
         nsIContent* descendant = node;
         while ((descendant = descendant->GetNextNode(node))) {
           RemoveAllAttributes(descendant);
         }
         nsIContent* next = node->GetNextNonChildNode(aRoot);
-        node->GetParent()->RemoveChild(node);
+        node->RemoveFromParent();
         node = next;
         continue;
       }
       if (nsGkAtoms::style == localName) {
         // If styles aren't allowed, style elements got pruned above. Even
         // if styles are allowed, non-HTML, non-SVG style elements got pruned
         // above.
         NS_ASSERTION(ns == kNameSpaceID_XHTML || ns == kNameSpaceID_SVG,
@@ -1454,24 +1454,24 @@ nsTreeSanitizer::SanitizeChildren(nsINod
         node = node->GetNextNonChildNode(aRoot);
         continue;
       }
       if (MustFlatten(ns, localName)) {
         RemoveAllAttributes(node);
         nsIContent* next = node->GetNextNode(aRoot);
         nsIContent* parent = node->GetParent();
         nsCOMPtr<nsIContent> child; // Must keep the child alive during move
-        nsresult rv;
+        ErrorResult rv;
         while ((child = node->GetFirstChild())) {
-          parent->InsertBefore(child, node, &rv);
-          if (NS_FAILED(rv)) {
+          parent->InsertBefore(*child, node, rv);
+          if (rv.Failed()) {
             break;
           }
         }
-        parent->RemoveChild(node);
+        node->RemoveFromParent();
         node = next;
         continue;
       }
       NS_ASSERTION(ns == kNameSpaceID_XHTML ||
                    ns == kNameSpaceID_SVG ||
                    ns == kNameSpaceID_MathML,
           "Should have only HTML, MathML or SVG here!");
       if (ns == kNameSpaceID_XHTML) {
@@ -1497,17 +1497,17 @@ nsTreeSanitizer::SanitizeChildren(nsINod
                            false);
       }
       node = node->GetNextNode(aRoot);
       continue;
     }
     NS_ASSERTION(!node->GetFirstChild(), "How come non-element node had kids?");
     nsIContent* next = node->GetNextNonChildNode(aRoot);
     if (!mAllowComments && node->IsNodeOfType(nsINode::eCOMMENT)) {
-      node->GetNodeParent()->RemoveChild(node);
+      node->RemoveFromParent();
     }
     node = next;
   }
 }
 
 void
 nsTreeSanitizer::RemoveAllAttributes(nsIContent* aElement)
 {
--- a/content/base/src/nsTreeWalker.cpp
+++ b/content/base/src/nsTreeWalker.cpp
@@ -130,17 +130,17 @@ NS_IMETHODIMP nsTreeWalker::ParentNode(n
 {
     *_retval = nullptr;
 
     nsresult rv;
 
     nsCOMPtr<nsINode> node = mCurrentNode;
 
     while (node && node != mRoot) {
-        node = node->GetNodeParent();
+        node = node->GetParentNode();
 
         if (node) {
             int16_t filtered;
             rv = TestNode(node, &filtered);
             NS_ENSURE_SUCCESS(rv, rv);
             if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT) {
                 mCurrentNode = node;
                 return CallQueryInterface(node, _retval);
@@ -204,17 +204,17 @@ NS_IMETHODIMP nsTreeWalker::PreviousNode
                 mCurrentNode = node;
                 return CallQueryInterface(node, _retval);
             }
         }
 
         if (node == mRoot)
             break;
 
-        node = node->GetNodeParent();
+        node = node->GetParentNode();
         if (!node)
             break;
 
         rv = TestNode(node, &filtered);
         NS_ENSURE_SUCCESS(rv, rv);
 
         if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT) {
             mCurrentNode = node;
@@ -257,17 +257,17 @@ NS_IMETHODIMP nsTreeWalker::NextNode(nsI
         do {
             if (temp == mRoot)
                 break;
 
             sibling = temp->GetNextSibling();
             if (sibling)
                 break;
 
-            temp = temp->GetNodeParent();
+            temp = temp->GetParentNode();
         } while (temp);
 
         if (!sibling)
             break;
 
         node = sibling;
 
         // Found a sibling. Either ours or ancestor's
@@ -331,17 +331,17 @@ nsresult nsTreeWalker::FirstChildInterna
         do {
             nsINode *sibling = aReversed ? node->GetPreviousSibling()
                                          : node->GetNextSibling();
             if (sibling) {
                 node = sibling;
                 break;
             }
 
-            nsINode *parent = node->GetNodeParent();
+            nsINode *parent = node->GetParentNode();
 
             if (!parent || parent == mRoot || parent == mCurrentNode) {
                 return NS_OK;
             }
 
             node = parent;
 
         } while (node);
@@ -389,17 +389,17 @@ nsresult nsTreeWalker::NextSiblingIntern
             if (filtered == nsIDOMNodeFilter::FILTER_REJECT ||
                 !(sibling = aReversed ? node->GetLastChild()
                                       : node->GetFirstChild())) {
                 sibling = aReversed ? node->GetPreviousSibling()
                                     : node->GetNextSibling();
             }
         }
 
-        node = node->GetNodeParent();
+        node = node->GetParentNode();
 
         if (!node || node == mRoot)
             return NS_OK;
 
         // Is parent transparent in filtered view?
         rv = TestNode(node, &filtered);
         NS_ENSURE_SUCCESS(rv, rv);
         if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT)
--- a/content/base/src/nsXMLContentSerializer.cpp
+++ b/content/base/src/nsXMLContentSerializer.cpp
@@ -1209,17 +1209,17 @@ nsXMLContentSerializer::MaybeAddNewlineF
   if (mAddNewlineForRootNode) {
     AppendNewLineToString(aStr);
   }
 }
 
 void
 nsXMLContentSerializer::MaybeFlagNewlineForRootNode(nsINode* aNode)
 {
-  nsINode* parent = aNode->GetNodeParent();
+  nsINode* parent = aNode->GetParentNode();
   if (parent) {
     mAddNewlineForRootNode = parent->IsNodeOfType(nsINode::eDOCUMENT);
   }
 }
 
 void
 nsXMLContentSerializer::MaybeEnterInPreContent(nsIContent* aNode)
 {
--- a/content/events/src/nsContentEventHandler.cpp
+++ b/content/events/src/nsContentEventHandler.cpp
@@ -370,17 +370,17 @@ nsContentEventHandler::SetRangeFromFlatT
                               bool aExpandToClusterBoundaries)
 {
   nsCOMPtr<nsIContentIterator> iter = NS_NewContentIterator();
   nsresult rv = iter->Init(mRootContent);
   NS_ENSURE_SUCCESS(rv, rv);
 
   uint32_t nativeOffset = 0;
   uint32_t nativeEndOffset = aNativeOffset + aNativeLength;
-  nsCOMPtr<nsIContent> content;
+  bool startSet = false;
   for (; !iter->IsDone(); iter->Next()) {
     nsINode* node = iter->GetCurrentNode();
     if (!node)
       break;
     if (!node->IsNodeOfType(nsINode::eCONTENT))
       continue;
     nsIContent* content = static_cast<nsIContent*>(node);
 
@@ -400,16 +400,17 @@ nsContentEventHandler::SetRangeFromFlatT
 
       if (aExpandToClusterBoundaries) {
         rv = ExpandToClusterBoundary(content, false, &xpOffset);
         NS_ENSURE_SUCCESS(rv, rv);
       }
 
       rv = aRange->SetStart(domNode, int32_t(xpOffset));
       NS_ENSURE_SUCCESS(rv, rv);
+      startSet = true;
       if (aNativeLength == 0) {
         // Ensure that the end offset and the start offset are same.
         rv = aRange->SetEnd(domNode, int32_t(xpOffset));
         NS_ENSURE_SUCCESS(rv, rv);
         return NS_OK;
       }
     }
     if (nativeEndOffset <= nativeOffset + nativeTextLength) {
@@ -441,18 +442,19 @@ nsContentEventHandler::SetRangeFromFlatT
     nativeOffset += nativeTextLength;
   }
 
   if (nativeOffset < aNativeOffset)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(mRootContent));
   NS_ASSERTION(domNode, "lastContent doesn't have nsIDOMNode!");
-  if (!content) {
-    rv = aRange->SetStart(domNode, 0);
+  if (!startSet) {
+    MOZ_ASSERT(!mRootContent->IsNodeOfType(nsINode::eTEXT));
+    rv = aRange->SetStart(domNode, int32_t(mRootContent->GetChildCount()));
     NS_ENSURE_SUCCESS(rv, rv);
   }
   rv = aRange->SetEnd(domNode, int32_t(mRootContent->GetChildCount()));
   NS_ASSERTION(NS_SUCCEEDED(rv), "nsIDOMRange::SetEnd failed");
   return rv;
 }
 
 nsresult
--- a/content/events/src/nsIMEStateManager.cpp
+++ b/content/events/src/nsIMEStateManager.cpp
@@ -896,17 +896,17 @@ static bool IsEditable(nsINode* node) {
 static nsINode* GetRootEditableNode(nsPresContext* aPresContext,
                                     nsIContent* aContent)
 {
   if (aContent) {
     nsINode* root = nullptr;
     nsINode* node = aContent;
     while (node && IsEditable(node)) {
       root = node;
-      node = node->GetNodeParent();
+      node = node->GetParentNode();
     }
     return root;
   }
   if (aPresContext) {
     nsIDocument* document = aPresContext->Document();
     if (document && document->IsEditable())
       return document;
   }
--- a/content/events/src/nsXMLEventsElement.cpp
+++ b/content/events/src/nsXMLEventsElement.cpp
@@ -6,17 +6,16 @@
 #include "nsXMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsIDocument.h"
 
 class nsXMLEventsElement : public nsXMLElement {
 public:
   nsXMLEventsElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsXMLEventsElement();
-  NS_FORWARD_NSIDOMNODE(nsXMLElement::)
 
   virtual nsIAtom *GetIDAttributeName() const;
   virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName, 
                            nsIAtom* aPrefix, const nsAString& aValue,
                            bool aNotify);
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 };
 
--- a/content/html/content/public/nsHTMLAudioElement.h
+++ b/content/html/content/public/nsHTMLAudioElement.h
@@ -20,17 +20,17 @@ class nsHTMLAudioElement : public nsHTML
 public:
   nsHTMLAudioElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLAudioElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsHTMLMediaElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsHTMLMediaElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsHTMLMediaElement::)
 
   // nsIDOMHTMLMediaElement
--- a/content/html/content/public/nsHTMLCanvasElement.h
+++ b/content/html/content/public/nsHTMLCanvasElement.h
@@ -46,17 +46,17 @@ public:
       return nullptr;
     }
     return static_cast<nsHTMLCanvasElement*>(aPossibleCanvas);
   }
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLCanvasElement
--- a/content/html/content/public/nsHTMLVideoElement.h
+++ b/content/html/content/public/nsHTMLVideoElement.h
@@ -23,17 +23,17 @@ public:
     }
     return static_cast<nsHTMLVideoElement*>(aPossibleVideo);
   }
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsHTMLMediaElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsHTMLMediaElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsHTMLMediaElement::)
 
   // nsIDOMHTMLMediaElement
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -1236,17 +1236,17 @@ Serialize(Element* aRoot, bool aDescende
         return builder.ToString(aOut);
       }
 
       if ((next = current->GetNextSibling())) {
         current = next;
         break;
       }
 
-      current = current->GetNodeParent();
+      current = current->GetParentNode();
       if (aDescendentsOnly && current == aRoot) {
         return builder.ToString(aOut);
       }
     }
   }
 }
 
 nsresult
@@ -1387,28 +1387,26 @@ nsGenericHTMLElement::SetInnerHTML(const
                                                       getter_AddRefs(df));
     nsCOMPtr<nsINode> fragment = do_QueryInterface(df);
     if (!aError.Failed()) {
       // Suppress assertion about node removal mutation events that can't have
       // listeners anyway, because no one has had the chance to register mutation
       // listeners on the fragment that comes from the parser.
       nsAutoScriptBlockerSuppressNodeRemoved scriptBlocker;
 
-      nsresult rv = NS_OK;
-      static_cast<nsINode*>(this)->AppendChild(fragment, &rv);
-      aError = rv;
+      static_cast<nsINode*>(this)->AppendChild(*fragment, aError);
       mb.NodesAdded();
     }
   }
 }
 
 NS_IMETHODIMP
 nsGenericHTMLElement::SetOuterHTML(const nsAString& aOuterHTML)
 {
-  nsCOMPtr<nsINode> parent = GetNodeParent();
+  nsCOMPtr<nsINode> parent = GetParentNode();
   if (!parent) {
     return NS_OK;
   }
 
   if (parent->NodeType() == nsIDOMNode::DOCUMENT_NODE) {
     return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
   }
 
@@ -1432,18 +1430,19 @@ nsGenericHTMLElement::SetOuterHTML(const
     nsContentUtils::ParseFragmentHTML(aOuterHTML,
                                       fragment,
                                       localName,
                                       namespaceID,
                                       OwnerDoc()->GetCompatibilityMode() ==
                                         eCompatibility_NavQuirks,
                                       true);
     nsAutoMutationBatch mb(parent, true, false);
-    parent->ReplaceChild(fragment, this, &rv);
-    return rv;
+    ErrorResult error;
+    parent->ReplaceChild(*fragment, *this, error);
+    return error.ErrorCode();
   }
 
   nsCOMPtr<nsINode> context;
   if (parent->IsElement()) {
     context = parent;
   } else {
     NS_ASSERTION(parent->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE,
       "How come the parent isn't a document, a fragment or an element?");
@@ -1458,18 +1457,19 @@ nsGenericHTMLElement::SetOuterHTML(const
   nsCOMPtr<nsIDOMDocumentFragment> df;
   nsresult rv = nsContentUtils::CreateContextualFragment(context,
                                                          aOuterHTML,
                                                          true,
                                                          getter_AddRefs(df));
   NS_ENSURE_SUCCESS(rv, rv);
   nsCOMPtr<nsINode> fragment = do_QueryInterface(df);
   nsAutoMutationBatch mb(parent, true, false);
-  parent->ReplaceChild(fragment, this, &rv);
-  return rv;
+  ErrorResult error;
+  parent->ReplaceChild(*fragment, *this, error);
+  return error.ErrorCode();
 }
 
 enum nsAdjacentPosition {
   eBeforeBegin,
   eAfterBegin,
   eBeforeEnd,
   eAfterEnd
 };
@@ -1546,32 +1546,33 @@ nsGenericHTMLElement::InsertAdjacentHTML
   nsCOMPtr<nsINode> fragment = do_QueryInterface(df);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Suppress assertion about node removal mutation events that can't have
   // listeners anyway, because no one has had the chance to register mutation
   // listeners on the fragment that comes from the parser.
   nsAutoScriptBlockerSuppressNodeRemoved scriptBlocker;
 
+  ErrorResult error;
   nsAutoMutationBatch mb(destination, true, false);
   switch (position) {
     case eBeforeBegin:
-      destination->InsertBefore(fragment, this, &rv);
+      destination->InsertBefore(*fragment, this, error);
       break;
     case eAfterBegin:
-      static_cast<nsINode*>(this)->InsertBefore(fragment, GetFirstChild(), &rv);
+      static_cast<nsINode*>(this)->InsertBefore(*fragment, GetFirstChild(), error);
       break;
     case eBeforeEnd:
-      static_cast<nsINode*>(this)->AppendChild(fragment, &rv);
+      static_cast<nsINode*>(this)->AppendChild(*fragment, error);
       break;
     case eAfterEnd:
-      destination->InsertBefore(fragment, GetNextSibling(), &rv);
+      destination->InsertBefore(*fragment, GetNextSibling(), error);
       break;
   }
-  return rv;
+  return error.ErrorCode();
 }
 
 nsresult
 nsGenericHTMLElement::ScrollIntoView(bool aTop, uint8_t optional_argc)
 {
   nsIDocument *document = GetCurrentDoc();
 
   if (!document) {
@@ -4227,23 +4228,24 @@ nsGenericHTMLElement::SetItemValue(nsIVa
   aValue->GetAsAString(string);
   SetItemValueText(string);
   return NS_OK;
 }
 
 void
 nsGenericHTMLElement::GetItemValueText(nsAString& text)
 {
-  GetTextContent(text);
+  GetTextContentInternal(text);
 }
 
 void
 nsGenericHTMLElement::SetItemValueText(const nsAString& text)
 {
-  SetTextContent(text);
+  mozilla::ErrorResult rv;
+  SetTextContentInternal(text, rv);
 }
 
 static void
 nsDOMSettableTokenListPropertyDestructor(void *aObject, nsIAtom *aProperty,
                                          void *aPropertyValue, void *aData)
 {
   nsDOMSettableTokenList* list =
     static_cast<nsDOMSettableTokenList*>(aPropertyValue);
--- a/content/html/content/src/nsHTMLAnchorElement.cpp
+++ b/content/html/content/src/nsHTMLAnchorElement.cpp
@@ -30,17 +30,17 @@ public:
 
   nsHTMLAnchorElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLAnchorElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
   virtual bool Draggable() const MOZ_OVERRIDE;
--- a/content/html/content/src/nsHTMLAreaElement.cpp
+++ b/content/html/content/src/nsHTMLAreaElement.cpp
@@ -24,17 +24,17 @@ public:
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // DOM memory reporter participant
   NS_DECL_SIZEOF_EXCLUDING_THIS
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
 
--- a/content/html/content/src/nsHTMLBRElement.cpp
+++ b/content/html/content/src/nsHTMLBRElement.cpp
@@ -22,17 +22,17 @@ class nsHTMLBRElement : public nsGeneric
 public:
   nsHTMLBRElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLBRElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLBRElement
--- a/content/html/content/src/nsHTMLBodyElement.cpp
+++ b/content/html/content/src/nsHTMLBodyElement.cpp
@@ -57,17 +57,17 @@ public:
 
   nsHTMLBodyElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLBodyElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLBodyElement
--- a/content/html/content/src/nsHTMLButtonElement.cpp
+++ b/content/html/content/src/nsHTMLButtonElement.cpp
@@ -58,17 +58,17 @@ public:
   nsHTMLButtonElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                       FromParser aFromParser = NOT_FROM_PARSER);
   virtual ~nsHTMLButtonElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
 
--- a/content/html/content/src/nsHTMLDataListElement.cpp
+++ b/content/html/content/src/nsHTMLDataListElement.cpp
@@ -17,17 +17,17 @@ class nsHTMLDataListElement : public nsG
 public:
   nsHTMLDataListElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLDataListElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLDataListElement
--- a/content/html/content/src/nsHTMLDivElement.cpp
+++ b/content/html/content/src/nsHTMLDivElement.cpp
@@ -20,17 +20,17 @@ class nsHTMLDivElement : public nsGeneri
 public:
   nsHTMLDivElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLDivElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLDivElement
--- a/content/html/content/src/nsHTMLElement.cpp
+++ b/content/html/content/src/nsHTMLElement.cpp
@@ -17,17 +17,17 @@ class nsHTMLElement : public nsGenericHT
 public:
   nsHTMLElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
   virtual void GetInnerHTML(nsAString& aInnerHTML,
                             mozilla::ErrorResult& aError) MOZ_OVERRIDE;
--- a/content/html/content/src/nsHTMLFieldSetElement.h
+++ b/content/html/content/src/nsHTMLFieldSetElement.h
@@ -29,17 +29,17 @@ public:
     }
     return static_cast<nsHTMLFieldSetElement*>(aContent);
   }
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLFieldSetElement
--- a/content/html/content/src/nsHTMLFontElement.cpp
+++ b/content/html/content/src/nsHTMLFontElement.cpp
@@ -26,17 +26,17 @@ class nsHTMLFontElement : public nsGener
 public:
   nsHTMLFontElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLFontElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLFontElement
--- a/content/html/content/src/nsHTMLFormElement.cpp
+++ b/content/html/content/src/nsHTMLFormElement.cpp
@@ -521,17 +521,17 @@ nsHTMLFormElement::UnbindFromTree(bool a
   MarkOrphans(mControls->mElements);
   MarkOrphans(mControls->mNotInElements);
 
   nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
 
   nsINode* ancestor = this;
   nsINode* cur;
   do {
-    cur = ancestor->GetNodeParent();
+    cur = ancestor->GetParentNode();
     if (!cur) {
       break;
     }
     ancestor = cur;
   } while (1);
   
   CollectOrphans(ancestor, mControls->mElements
 #ifdef DEBUG
--- a/content/html/content/src/nsHTMLFormElement.h
+++ b/content/html/content/src/nsHTMLFormElement.h
@@ -35,17 +35,17 @@ public:
   virtual ~nsHTMLFormElement();
 
   nsresult Init();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLFormElement
--- a/content/html/content/src/nsHTMLFrameElement.cpp
+++ b/content/html/content/src/nsHTMLFrameElement.cpp
@@ -22,17 +22,17 @@ public:
   nsHTMLFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                      mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
   virtual ~nsHTMLFrameElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLFrameElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFrameElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFrameElement::)
 
   // nsIDOMHTMLFrameElement
--- a/content/html/content/src/nsHTMLFrameSetElement.h
+++ b/content/html/content/src/nsHTMLFrameSetElement.h
@@ -46,17 +46,17 @@ class nsHTMLFrameSetElement : public nsG
 public:
   nsHTMLFrameSetElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLFrameSetElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLFrameSetElement
--- a/content/html/content/src/nsHTMLHRElement.cpp
+++ b/content/html/content/src/nsHTMLHRElement.cpp
@@ -25,17 +25,17 @@ class nsHTMLHRElement : public nsGeneric
 public:
   nsHTMLHRElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLHRElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLHRElement
--- a/content/html/content/src/nsHTMLHeadingElement.cpp
+++ b/content/html/content/src/nsHTMLHeadingElement.cpp
@@ -22,17 +22,17 @@ class nsHTMLHeadingElement : public nsGe
 public:
   nsHTMLHeadingElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLHeadingElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLHeadingElement
--- a/content/html/content/src/nsHTMLIFrameElement.h
+++ b/content/html/content/src/nsHTMLIFrameElement.h
@@ -16,17 +16,17 @@ public:
   nsHTMLIFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                       mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
   virtual ~nsHTMLIFrameElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLFrameElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFrameElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFrameElement::)
 
   // nsIDOMHTMLIFrameElement
--- a/content/html/content/src/nsHTMLImageElement.h
+++ b/content/html/content/src/nsHTMLImageElement.h
@@ -19,17 +19,17 @@ class nsHTMLImageElement : public nsGene
 public:
   nsHTMLImageElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLImageElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
   virtual bool Draggable() const MOZ_OVERRIDE;
 
--- a/content/html/content/src/nsHTMLInputElement.h
+++ b/content/html/content/src/nsHTMLInputElement.h
@@ -64,17 +64,17 @@ public:
   nsHTMLInputElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                      mozilla::dom::FromParser aFromParser);
   virtual ~nsHTMLInputElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
   virtual void Click() MOZ_OVERRIDE;
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
--- a/content/html/content/src/nsHTMLLIElement.cpp
+++ b/content/html/content/src/nsHTMLLIElement.cpp
@@ -22,17 +22,17 @@ class nsHTMLLIElement : public nsGeneric
 public:
   nsHTMLLIElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLLIElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLLIElement
--- a/content/html/content/src/nsHTMLLabelElement.h
+++ b/content/html/content/src/nsHTMLLabelElement.h
@@ -27,17 +27,17 @@ public:
 
     return nullptr;
   }
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLLabelElement
   NS_DECL_NSIDOMHTMLLABELELEMENT
 
   // nsIDOMHTMLElement
--- a/content/html/content/src/nsHTMLLegendElement.h
+++ b/content/html/content/src/nsHTMLLegendElement.h
@@ -22,17 +22,17 @@ public:
     }
     return nullptr;
   }
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLLegendElement
   NS_DECL_NSIDOMHTMLLEGENDELEMENT
 
   // nsIDOMHTMLElement
--- a/content/html/content/src/nsHTMLLinkElement.cpp
+++ b/content/html/content/src/nsHTMLLinkElement.cpp
@@ -41,17 +41,17 @@ public:
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // CC
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLLinkElement,
                                            nsGenericHTMLElement)
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLLinkElement
--- a/content/html/content/src/nsHTMLMapElement.cpp
+++ b/content/html/content/src/nsHTMLMapElement.cpp
@@ -16,17 +16,17 @@ class nsHTMLMapElement : public nsGeneri
 {
 public:
   nsHTMLMapElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLMapElement
--- a/content/html/content/src/nsHTMLMenuElement.h
+++ b/content/html/content/src/nsHTMLMenuElement.h
@@ -22,17 +22,17 @@ public:
       return static_cast<nsHTMLMenuElement*>(aContent);
     return nullptr;
   }
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLMenuElement
--- a/content/html/content/src/nsHTMLMenuItemElement.h
+++ b/content/html/content/src/nsHTMLMenuItemElement.h
@@ -26,17 +26,17 @@ public:
     }
     return nullptr;
   }
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLCommandElement
--- a/content/html/content/src/nsHTMLMetaElement.cpp
+++ b/content/html/content/src/nsHTMLMetaElement.cpp
@@ -17,17 +17,17 @@ class nsHTMLMetaElement : public nsGener
 public:
   nsHTMLMetaElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLMetaElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLMetaElement
--- a/content/html/content/src/nsHTMLMeterElement.cpp
+++ b/content/html/content/src/nsHTMLMeterElement.cpp
@@ -17,17 +17,17 @@ class nsHTMLMeterElement : public nsGene
 public:
   nsHTMLMeterElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLMeterElement();
 
   /* nsISupports */
   NS_DECL_ISUPPORTS_INHERITED
 
   /* nsIDOMNode */
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   /* nsIDOMElement */
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   /* nsIDOMHTMLElement */
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   /* nsIDOMHTMLMeterElement */
--- a/content/html/content/src/nsHTMLModElement.cpp
+++ b/content/html/content/src/nsHTMLModElement.cpp
@@ -15,17 +15,17 @@ class nsHTMLModElement : public nsGeneri
 public:
   nsHTMLModElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLModElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLModElement
--- a/content/html/content/src/nsHTMLOListElement.cpp
+++ b/content/html/content/src/nsHTMLOListElement.cpp
@@ -26,17 +26,17 @@ class nsHTMLSharedListElement : public n
 public:
   nsHTMLSharedListElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLSharedListElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLOListElement
--- a/content/html/content/src/nsHTMLObjectElement.cpp
+++ b/content/html/content/src/nsHTMLObjectElement.cpp
@@ -38,17 +38,17 @@ public:
   nsHTMLObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                       mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
   virtual ~nsHTMLObjectElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
 
--- a/content/html/content/src/nsHTMLOptGroupElement.h
+++ b/content/html/content/src/nsHTMLOptGroupElement.h
@@ -15,17 +15,17 @@ class nsHTMLOptGroupElement : public nsG
 public:
   nsHTMLOptGroupElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLOptGroupElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLOptGroupElement
--- a/content/html/content/src/nsHTMLOptionElement.h
+++ b/content/html/content/src/nsHTMLOptionElement.h
@@ -28,17 +28,17 @@ public:
       return static_cast<nsHTMLOptionElement*>(aContent);
     return nullptr;
   }
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLOptionElement
--- a/content/html/content/src/nsHTMLOutputElement.cpp
+++ b/content/html/content/src/nsHTMLOutputElement.cpp
@@ -24,17 +24,17 @@ public:
 
   nsHTMLOutputElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLOutputElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLOutputElement
--- a/content/html/content/src/nsHTMLParagraphElement.cpp
+++ b/content/html/content/src/nsHTMLParagraphElement.cpp
@@ -23,17 +23,17 @@ class nsHTMLParagraphElement : public ns
 public:
   nsHTMLParagraphElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLParagraphElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLParagraphElement
--- a/content/html/content/src/nsHTMLPreElement.cpp
+++ b/content/html/content/src/nsHTMLPreElement.cpp
@@ -22,17 +22,17 @@ class nsHTMLPreElement : public nsGeneri
 public:
   nsHTMLPreElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLPreElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLPreElement
--- a/content/html/content/src/nsHTMLProgressElement.cpp
+++ b/content/html/content/src/nsHTMLProgressElement.cpp
@@ -16,17 +16,17 @@ class nsHTMLProgressElement : public nsG
 public:
   nsHTMLProgressElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLProgressElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLProgressElement
--- a/content/html/content/src/nsHTMLScriptElement.cpp
+++ b/content/html/content/src/nsHTMLScriptElement.cpp
@@ -38,17 +38,17 @@ public:
   nsHTMLScriptElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                       FromParser aFromParser);
   virtual ~nsHTMLScriptElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
   virtual void GetInnerHTML(nsAString& aInnerHTML,
                             mozilla::ErrorResult& aError) MOZ_OVERRIDE;
--- a/content/html/content/src/nsHTMLSelectElement.h
+++ b/content/html/content/src/nsHTMLSelectElement.h
@@ -243,17 +243,17 @@ public:
       return static_cast<nsHTMLSelectElement*>(aContent);
     return nullptr;
   }
  
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
 
--- a/content/html/content/src/nsHTMLSharedElement.cpp
+++ b/content/html/content/src/nsHTMLSharedElement.cpp
@@ -36,17 +36,17 @@ class nsHTMLSharedElement : public nsGen
 public:
   nsHTMLSharedElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLSharedElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLParamElement
--- a/content/html/content/src/nsHTMLSharedObjectElement.cpp
+++ b/content/html/content/src/nsHTMLSharedObjectElement.cpp
@@ -33,17 +33,17 @@ public:
   nsHTMLSharedObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                             mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
   virtual ~nsHTMLSharedObjectElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
 
--- a/content/html/content/src/nsHTMLSourceElement.cpp
+++ b/content/html/content/src/nsHTMLSourceElement.cpp
@@ -20,17 +20,17 @@ class nsHTMLSourceElement : public nsGen
 public:
   nsHTMLSourceElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLSourceElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLSourceElement
--- a/content/html/content/src/nsHTMLSpanElement.cpp
+++ b/content/html/content/src/nsHTMLSpanElement.cpp
@@ -16,17 +16,17 @@ class nsHTMLSpanElement : public nsGener
 public:
   nsHTMLSpanElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLSpanElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
--- a/content/html/content/src/nsHTMLStyleElement.cpp
+++ b/content/html/content/src/nsHTMLStyleElement.cpp
@@ -33,17 +33,17 @@ public:
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // CC
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLStyleElement,
                                            nsGenericHTMLElement)
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
   virtual void GetInnerHTML(nsAString& aInnerHTML,
                             mozilla::ErrorResult& aError) MOZ_OVERRIDE;
--- a/content/html/content/src/nsHTMLTableCaptionElement.cpp
+++ b/content/html/content/src/nsHTMLTableCaptionElement.cpp
@@ -22,17 +22,17 @@ class nsHTMLTableCaptionElement :  publi
 public:
   nsHTMLTableCaptionElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLTableCaptionElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLTableCaptionElement
--- a/content/html/content/src/nsHTMLTableCellElement.cpp
+++ b/content/html/content/src/nsHTMLTableCellElement.cpp
@@ -28,17 +28,17 @@ class nsHTMLTableCellElement : public ns
 public:
   nsHTMLTableCellElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLTableCellElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLTableCellElement
--- a/content/html/content/src/nsHTMLTableColElement.cpp
+++ b/content/html/content/src/nsHTMLTableColElement.cpp
@@ -26,17 +26,17 @@ class nsHTMLTableColElement : public nsG
 public:
   nsHTMLTableColElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLTableColElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLTableColElement
--- a/content/html/content/src/nsHTMLTableElement.h
+++ b/content/html/content/src/nsHTMLTableElement.h
@@ -17,17 +17,17 @@ class nsHTMLTableElement :  public nsGen
 public:
   nsHTMLTableElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLTableElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLTableElement
--- a/content/html/content/src/nsHTMLTableRowElement.cpp
+++ b/content/html/content/src/nsHTMLTableRowElement.cpp
@@ -28,17 +28,17 @@ class nsHTMLTableRowElement : public nsG
 {
 public:
   nsHTMLTableRowElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLTableRowElement
--- a/content/html/content/src/nsHTMLTableSectionElement.cpp
+++ b/content/html/content/src/nsHTMLTableSectionElement.cpp
@@ -27,17 +27,17 @@ class nsHTMLTableSectionElement : public
 {
 public:
   nsHTMLTableSectionElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLTableSectionElement
--- a/content/html/content/src/nsHTMLTextAreaElement.cpp
+++ b/content/html/content/src/nsHTMLTextAreaElement.cpp
@@ -66,17 +66,17 @@ public:
 
   nsHTMLTextAreaElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                         mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
   virtual int32_t TabIndexDefault() MOZ_OVERRIDE;
 
--- a/content/html/content/src/nsHTMLTitleElement.cpp
+++ b/content/html/content/src/nsHTMLTitleElement.cpp
@@ -20,17 +20,17 @@ public:
 
   nsHTMLTitleElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLTitleElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLTitleElement
--- a/content/html/content/src/nsHTMLUnknownElement.cpp
+++ b/content/html/content/src/nsHTMLUnknownElement.cpp
@@ -12,17 +12,17 @@ class nsHTMLUnknownElement : public nsGe
 public:
   nsHTMLUnknownElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsHTMLUnknownElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
--- a/content/html/document/src/ImageDocument.cpp
+++ b/content/html/document/src/ImageDocument.cpp
@@ -636,17 +636,19 @@ ImageDocument::CreateSyntheticDocument()
   if (nsContentUtils::IsChildOfSameType(this)) {
     nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::style, nullptr,
                                              kNameSpaceID_XHTML,
                                              nsIDOMNode::ELEMENT_NODE);
     NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
     nsRefPtr<nsGenericHTMLElement> styleContent = NS_NewHTMLStyleElement(nodeInfo.forget());
     NS_ENSURE_TRUE(styleContent, NS_ERROR_OUT_OF_MEMORY);
 
-    styleContent->SetTextContent(NS_LITERAL_STRING("img { display: block; }"));
+    ErrorResult error;
+    styleContent->SetTextContent(NS_LITERAL_STRING("img { display: block; }"),
+                                 error);
     head->AppendChildTo(styleContent, false);
   }
 
   // Add the image element
   Element* body = GetBodyElement();
   if (!body) {
     NS_WARNING("no body on image document!");
     return NS_ERROR_FAILURE;
--- a/content/html/document/src/nsHTMLDocument.h
+++ b/content/html/document/src/nsHTMLDocument.h
@@ -82,17 +82,17 @@ public:
   virtual NS_HIDDEN_(nsContentList*) GetForms();
  
   virtual NS_HIDDEN_(nsContentList*) GetFormControls();
  
   // nsIDOMDocument interface
   NS_FORWARD_NSIDOMDOCUMENT(nsDocument::)
 
   // nsIDOMNode interface
-  NS_FORWARD_NSIDOMNODE(nsDocument::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMHTMLDocument interface
   NS_DECL_NSIDOMHTMLDOCUMENT
 
   /**
    * Returns the result of document.all[aID] which can either be a node
    * or a nodelist depending on if there are multiple nodes with the same
    * id.
--- a/content/mathml/content/src/nsMathMLElement.h
+++ b/content/mathml/content/src/nsMathMLElement.h
@@ -29,17 +29,17 @@ public:
       mIncrementScriptLevel(false)
   {}
 
   // Implementation of nsISupports is inherited from nsMathMLElementBase
   NS_DECL_ISUPPORTS_INHERITED
 
   // Forward implementations of parent interfaces of nsMathMLElement to 
   // our base class
-  NS_FORWARD_NSIDOMNODE(nsMathMLElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsMathMLElementBase::)
 
   nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                       nsIContent* aBindingParent,
                       bool aCompileEventHandlers);
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true);
 
--- a/content/svg/content/src/nsSVGAElement.h
+++ b/content/svg/content/src/nsSVGAElement.h
@@ -31,17 +31,17 @@ protected:
 public:
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGAELEMENT
   NS_DECL_NSIDOMSVGURIREFERENCE
 
   // XXX: I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGAElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGAElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGAElementBase::)
 
   // nsINode interface methods
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
   virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
--- a/content/svg/content/src/nsSVGAltGlyphElement.cpp
+++ b/content/svg/content/src/nsSVGAltGlyphElement.cpp
@@ -29,17 +29,17 @@ public:
   // interfaces:
   
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGALTGLYPHELEMENT
   NS_DECL_NSIDOMSVGURIREFERENCE
 
   // xxx If xpcom allowed virtual inheritance we wouldn't need to
   // forward here :-(
-  NS_FORWARD_NSIDOMNODE(nsSVGAltGlyphElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGAltGlyphElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGAltGlyphElementBase::)
   NS_FORWARD_NSIDOMSVGTEXTCONTENTELEMENT(nsSVGAltGlyphElementBase::)
   NS_FORWARD_NSIDOMSVGTEXTPOSITIONINGELEMENT(nsSVGAltGlyphElementBase::)
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 
--- a/content/svg/content/src/nsSVGAnimateElement.cpp
+++ b/content/svg/content/src/nsSVGAnimateElement.cpp
@@ -19,17 +19,17 @@ protected:
 
   nsSMILAnimationFunction mAnimationFunction;
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGANIMATEELEMENT
 
-  NS_FORWARD_NSIDOMNODE(nsSVGAnimateElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGAnimateElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGAnimateElementBase::)
   NS_FORWARD_NSIDOMSVGANIMATIONELEMENT(nsSVGAnimateElementBase::)
   
   // nsIDOMNode
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   // nsISMILAnimationElement
--- a/content/svg/content/src/nsSVGAnimateMotionElement.h
+++ b/content/svg/content/src/nsSVGAnimateMotionElement.h
@@ -23,17 +23,17 @@ protected:
 
   mozilla::SVGMotionSMILAnimationFunction mAnimationFunction;
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGANIMATEMOTIONELEMENT
 
-  NS_FORWARD_NSIDOMNODE(nsSVGAnimateMotionElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGAnimateMotionElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGAnimateMotionElementBase::)
   NS_FORWARD_NSIDOMSVGANIMATIONELEMENT(nsSVGAnimateMotionElementBase::)
 
   // nsIDOMNode specializations
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   // nsISMILAnimationElement
--- a/content/svg/content/src/nsSVGAnimateTransformElement.cpp
+++ b/content/svg/content/src/nsSVGAnimateTransformElement.cpp
@@ -22,17 +22,17 @@ protected:
 
   nsSMILAnimationFunction mAnimationFunction;
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGANIMATETRANSFORMELEMENT
 
-  NS_FORWARD_NSIDOMNODE(nsSVGAnimateTransformElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGAnimateTransformElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGAnimateTransformElementBase::)
   NS_FORWARD_NSIDOMSVGANIMATIONELEMENT(nsSVGAnimateTransformElementBase::)
 
   // nsIDOMNode specializations
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   // nsGenericElement specializations
--- a/content/svg/content/src/nsSVGCircleElement.cpp
+++ b/content/svg/content/src/nsSVGCircleElement.cpp
@@ -24,17 +24,17 @@ protected:
   nsSVGCircleElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGCIRCLEELEMENT
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGCircleElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGCircleElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGCircleElementBase::)
 
   // nsSVGSVGElement methods:
   virtual bool HasValidDimensions() const;
 
   // nsSVGPathGeometryElement methods:
   virtual void ConstructPath(gfxContext *aCtx);
--- a/content/svg/content/src/nsSVGClipPathElement.h
+++ b/content/svg/content/src/nsSVGClipPathElement.h
@@ -28,17 +28,17 @@ protected:
 
 public:
   // interfaces:
   
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGCLIPPATHELEMENT
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGClipPathElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGClipPathElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGClipPathElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
--- a/content/svg/content/src/nsSVGDefsElement.cpp
+++ b/content/svg/content/src/nsSVGDefsElement.cpp
@@ -24,17 +24,17 @@ protected:
   
 public:
   // interfaces:
   
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGDEFSELEMENT
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGDefsElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGDefsElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGDefsElementBase::)
 
   // nsIContent
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
--- a/content/svg/content/src/nsSVGDescElement.cpp
+++ b/content/svg/content/src/nsSVGDescElement.cpp
@@ -19,17 +19,17 @@ protected:
 
 public:
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGDESCELEMENT
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGDescElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGDescElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGDescElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -1010,17 +1010,18 @@ nsSVGElement::sLightingEffectsMap[] = {
 };
 
 //----------------------------------------------------------------------
 // nsIDOMNode methods
 
 NS_IMETHODIMP
 nsSVGElement::IsSupported(const nsAString& aFeature, const nsAString& aVersion, bool* aReturn)
 {
-  return nsGenericElement::IsSupported(aFeature, aVersion, aReturn); 
+  *aReturn = nsGenericElement::IsSupported(aFeature, aVersion);
+  return NS_OK;
 }
 
 //----------------------------------------------------------------------
 // nsIDOMElement methods
 
 // forwarded to nsGenericElement implementations
 
 
--- a/content/svg/content/src/nsSVGEllipseElement.cpp
+++ b/content/svg/content/src/nsSVGEllipseElement.cpp
@@ -24,17 +24,17 @@ protected:
   nsSVGEllipseElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGELLIPSEELEMENT
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGEllipseElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGEllipseElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGEllipseElementBase::)
 
   // nsSVGSVGElement methods:
   virtual bool HasValidDimensions() const;
 
   // nsSVGPathGeometryElement methods:
   virtual void ConstructPath(gfxContext *aCtx);
--- a/content/svg/content/src/nsSVGFilterElement.h
+++ b/content/svg/content/src/nsSVGFilterElement.h
@@ -35,17 +35,17 @@ protected:
 public:
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGFILTERELEMENT
   NS_DECL_NSIDOMSVGURIREFERENCE
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGFilterElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFilterElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFilterElementBase::)
 
   // nsIContent
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 
   // Invalidate users of this filter
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/nsSVGFilters.cpp
@@ -351,17 +351,17 @@ public:
   virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
           const nsSVGFilterInstance& aInstance);
 
   // Gaussian
   NS_DECL_NSIDOMSVGFEGAUSSIANBLURELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEGaussianBlurElementBase::)
 
-  NS_FORWARD_NSIDOMNODE(nsSVGFEGaussianBlurElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEGaussianBlurElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 protected:
@@ -829,17 +829,17 @@ public:
   virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
   virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
 
   // Blend
   NS_DECL_NSIDOMSVGFEBLENDELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEBlendElementBase::)
 
-  NS_FORWARD_NSIDOMNODE(nsSVGFEBlendElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEBlendElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 protected:
@@ -1046,17 +1046,17 @@ public:
   virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
   virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
 
   // Color Matrix
   NS_DECL_NSIDOMSVGFECOLORMATRIXELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEColorMatrixElementBase::)
 
-  NS_FORWARD_NSIDOMNODE(nsSVGFEColorMatrixElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEColorMatrixElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 protected:
@@ -1366,17 +1366,17 @@ public:
   virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
           const nsSVGFilterInstance& aInstance);
 
   // Composite
   NS_DECL_NSIDOMSVGFECOMPOSITEELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFECompositeElementBase::)
 
-  NS_FORWARD_NSIDOMNODE(nsSVGFECompositeElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFECompositeElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 protected:
@@ -1677,17 +1677,17 @@ public:
   virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
   virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
 
   // Component Transfer
   NS_DECL_NSIDOMSVGFECOMPONENTTRANSFERELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEComponentTransferElementBase::)
 
-  NS_FORWARD_NSIDOMNODE(nsSVGFEComponentTransferElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEComponentTransferElementBase::)
 
   // nsIContent
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
@@ -2091,17 +2091,17 @@ public:
 
   NS_FORWARD_NSIDOMSVGCOMPONENTTRANSFERFUNCTIONELEMENT(nsSVGComponentTransferFunctionElement::)
 
   NS_DECL_NSIDOMSVGFEFUNCRELEMENT
 
   virtual int32_t GetChannel() { return 0; }
   
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGComponentTransferFunctionElement::)
-  NS_FORWARD_NSIDOMNODE(nsSVGComponentTransferFunctionElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGComponentTransferFunctionElement::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 };
@@ -2138,17 +2138,17 @@ public:
 
   NS_FORWARD_NSIDOMSVGCOMPONENTTRANSFERFUNCTIONELEMENT(nsSVGComponentTransferFunctionElement::)
 
   NS_DECL_NSIDOMSVGFEFUNCGELEMENT
 
   virtual int32_t GetChannel() { return 1; }
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGComponentTransferFunctionElement::)
-  NS_FORWARD_NSIDOMNODE(nsSVGComponentTransferFunctionElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGComponentTransferFunctionElement::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 };
@@ -2185,17 +2185,17 @@ public:
 
   NS_FORWARD_NSIDOMSVGCOMPONENTTRANSFERFUNCTIONELEMENT(nsSVGComponentTransferFunctionElement::)
 
   NS_DECL_NSIDOMSVGFEFUNCBELEMENT
 
   virtual int32_t GetChannel() { return 2; }
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGComponentTransferFunctionElement::)
-  NS_FORWARD_NSIDOMNODE(nsSVGComponentTransferFunctionElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGComponentTransferFunctionElement::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 };
@@ -2232,17 +2232,17 @@ public:
 
   NS_FORWARD_NSIDOMSVGCOMPONENTTRANSFERFUNCTIONELEMENT(nsSVGComponentTransferFunctionElement::)
 
   NS_DECL_NSIDOMSVGFEFUNCAELEMENT
 
   virtual int32_t GetChannel() { return 3; }
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGComponentTransferFunctionElement::)
-  NS_FORWARD_NSIDOMNODE(nsSVGComponentTransferFunctionElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGComponentTransferFunctionElement::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 };
@@ -2290,17 +2290,17 @@ public:
   virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
   virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
 
   // Merge
   NS_DECL_NSIDOMSVGFEMERGEELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEMergeElementBase::)
 
-  NS_FORWARD_NSIDOMNODE(nsSVGFEMergeElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEMergeElementBase::)
 
   // nsIContent
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
@@ -2332,17 +2332,17 @@ public:
 
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMSVGFEMERGENODEELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEMergeNodeElementBase::)
 
-  NS_FORWARD_NSIDOMNODE(nsSVGFEMergeNodeElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEMergeNodeElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual bool AttributeAffectsRendering(
           int32_t aNameSpaceID, nsIAtom* aAttribute) const;
 
   const nsSVGString* In1() { return &mStringAttributes[IN1]; }
@@ -2527,17 +2527,17 @@ public:
   virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
           const nsSVGFilterInstance& aInstance);
 
   // Offset
   NS_DECL_NSIDOMSVGFEOFFSETELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEOffsetElementBase::)
 
-  NS_FORWARD_NSIDOMNODE(nsSVGFEOffsetElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEOffsetElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 protected:
@@ -2726,17 +2726,17 @@ public:
   virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
           const nsSVGFilterInstance& aInstance);
 
   // Flood
   NS_DECL_NSIDOMSVGFEFLOODELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEFloodElementBase::)
   
-  NS_FORWARD_NSIDOMNODE(nsSVGFEFloodElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEFloodElementBase::)
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
@@ -2876,17 +2876,17 @@ public:
   virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
           const nsSVGFilterInstance& aInstance);
 
   // Tile
   NS_DECL_NSIDOMSVGFETILEELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFETileElementBase::)
 
-  NS_FORWARD_NSIDOMNODE(nsSVGFETileElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFETileElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 protected:
@@ -3075,17 +3075,17 @@ public:
   virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
           const nsSVGFilterInstance& aInstance);
 
   // Turbulence
   NS_DECL_NSIDOMSVGFETURBULENCEELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFETurbulenceElementBase::)
 
-  NS_FORWARD_NSIDOMNODE(nsSVGFETurbulenceElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFETurbulenceElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 protected:
@@ -3624,17 +3624,17 @@ public:
   virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
           const nsSVGFilterInstance& aInstance);
 
   // Morphology
   NS_DECL_NSIDOMSVGFEMORPHOLOGYELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEMorphologyElementBase::)
 
-  NS_FORWARD_NSIDOMNODE(nsSVGFEMorphologyElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEMorphologyElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 protected:
@@ -3936,17 +3936,17 @@ public:
   virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
           const nsSVGFilterInstance& aInstance);
 
   // Color Matrix
   NS_DECL_NSIDOMSVGFECONVOLVEMATRIXELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEConvolveMatrixElementBase::)
 
-  NS_FORWARD_NSIDOMNODE(nsSVGFEConvolveMatrixElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEConvolveMatrixElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 protected:
@@ -4430,17 +4430,17 @@ protected:
     : nsSVGFEDistantLightElementBase(aNodeInfo) {}
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGFEDISTANTLIGHTELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEDistantLightElementBase::)
-  NS_FORWARD_NSIDOMNODE(nsSVGFEDistantLightElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEDistantLightElementBase::)
 
   virtual bool AttributeAffectsRendering(
           int32_t aNameSpaceID, nsIAtom* aAttribute) const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
@@ -4535,17 +4535,17 @@ protected:
     : nsSVGFEPointLightElementBase(aNodeInfo) {}
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGFEPOINTLIGHTELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEPointLightElementBase::)
-  NS_FORWARD_NSIDOMNODE(nsSVGFEPointLightElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEPointLightElementBase::)
 
   virtual bool AttributeAffectsRendering(
           int32_t aNameSpaceID, nsIAtom* aAttribute) const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
@@ -4647,17 +4647,17 @@ protected:
     : nsSVGFESpotLightElementBase(aNodeInfo) {}
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGFESPOTLIGHTELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFESpotLightElementBase::)
-  NS_FORWARD_NSIDOMNODE(nsSVGFESpotLightElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFESpotLightElementBase::)
 
   virtual bool AttributeAffectsRendering(
           int32_t aNameSpaceID, nsIAtom* aAttribute) const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
@@ -4815,17 +4815,16 @@ public:
   // 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_FORWARD_NSIDOMNODE(nsSVGFELightingElementBase::)
   NS_FORWARD_NSIDOMELEMENT(nsSVGFELightingElementBase::)
 
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 
 protected:
   virtual void
   LightPixel(const float *N, const float *L,
              nscolor color, uint8_t *targetData) = 0;
@@ -5195,17 +5194,17 @@ public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
 
   // DiffuseLighting
   NS_DECL_NSIDOMSVGFEDIFFUSELIGHTINGELEMENT
 
   NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFEDiffuseLightingElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEDiffuseLightingElementBase::)
-  NS_FORWARD_NSIDOMNODE(nsSVGFEDiffuseLightingElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEDiffuseLightingElementBase::)
 
   virtual bool AttributeAffectsRendering(
           int32_t aNameSpaceID, nsIAtom* aAttribute) const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
@@ -5326,17 +5325,17 @@ public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
 
   // DiffuseLighting
   NS_DECL_NSIDOMSVGFESPECULARLIGHTINGELEMENT
 
   NS_FORWARD_NSIDOMSVGFILTERPRIMITIVESTANDARDATTRIBUTES(nsSVGFESpecularLightingElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFESpecularLightingElementBase::)
-  NS_FORWARD_NSIDOMNODE(nsSVGFESpecularLightingElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFESpecularLightingElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsresult Filter(nsSVGFilterInstance* aInstance,
                           const nsTArray<const Image*>& aSources,
                           const Image* aTarget,
                           const nsIntRect& aDataRect);
@@ -5827,17 +5826,17 @@ public:
   virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
           const nsSVGFilterInstance& aInstance);
 
   // DisplacementMap
   NS_DECL_NSIDOMSVGFEDISPLACEMENTMAPELEMENT
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEDisplacementMapElementBase::)
 
-  NS_FORWARD_NSIDOMNODE(nsSVGFEDisplacementMapElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEDisplacementMapElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 protected:
--- a/content/svg/content/src/nsSVGFilters.h
+++ b/content/svg/content/src/nsSVGFilters.h
@@ -246,17 +246,17 @@ public:
   virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
           const nsSVGFilterInstance& aInstance);
 
   NS_DECL_NSIDOMSVGFEIMAGEELEMENT
   NS_DECL_NSIDOMSVGURIREFERENCE
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEImageElementBase::)
 
-  NS_FORWARD_NSIDOMNODE(nsSVGFEImageElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEImageElementBase::)
 
   // nsIContent
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
--- a/content/svg/content/src/nsSVGForeignObjectElement.h
+++ b/content/svg/content/src/nsSVGForeignObjectElement.h
@@ -26,17 +26,17 @@ protected:
 
 public:
   // interfaces:
   
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGFOREIGNOBJECTELEMENT
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGForeignObjectElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGForeignObjectElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGForeignObjectElementBase::)
 
   // nsSVGElement specializations:
   virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
                       TransformTypes aWhich = eAllTransforms) const;
   virtual bool HasValidDimensions() const;
 
--- a/content/svg/content/src/nsSVGGElement.cpp
+++ b/content/svg/content/src/nsSVGGElement.cpp
@@ -24,17 +24,17 @@ protected:
   
 public:
   // interfaces:
   
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGGELEMENT
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGGElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGGElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGGElementBase::)
 
   // nsIContent
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
--- a/content/svg/content/src/nsSVGGradientElement.h
+++ b/content/svg/content/src/nsSVGGradientElement.h
@@ -88,17 +88,17 @@ public:
   NS_FORWARD_NSIDOMSVGGRADIENTELEMENT(nsSVGLinearGradientElementBase::)
 
   // Linear Gradient
   NS_DECL_NSIDOMSVGLINEARGRADIENTELEMENT
 
   // The Gradient Element base class implements these
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGLinearGradientElementBase::)
 
-  NS_FORWARD_NSIDOMNODE(nsSVGLinearGradientElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGLinearGradientElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
 protected:
@@ -132,17 +132,17 @@ public:
 
   // Gradient Element
   NS_FORWARD_NSIDOMSVGGRADIENTELEMENT(nsSVGRadialGradientElementBase::)
 
   // Radial Gradient
   NS_DECL_NSIDOMSVGRADIALGRADIENTELEMENT
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGRadialGradientElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGRadialGradientElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGRadialGradientElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
--- a/content/svg/content/src/nsSVGImageElement.h
+++ b/content/svg/content/src/nsSVGImageElement.h
@@ -34,17 +34,17 @@ public:
 
   // interfaces:
   
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGIMAGEELEMENT
   NS_DECL_NSIDOMSVGURIREFERENCE
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGImageElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGImageElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGImageElementBase::)
 
   // nsIContent interface
   virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
                                 const nsAttrValue* aValue, bool aNotify);
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
--- a/content/svg/content/src/nsSVGLineElement.cpp
+++ b/content/svg/content/src/nsSVGLineElement.cpp
@@ -24,17 +24,17 @@ protected:
   nsSVGLineElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGLINEELEMENT
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGLineElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGLineElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGLineElementBase::)
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;
 
   // nsSVGPathGeometryElement methods:
   virtual bool IsMarkable() { return true; }
--- a/content/svg/content/src/nsSVGMarkerElement.h
+++ b/content/svg/content/src/nsSVGMarkerElement.h
@@ -86,17 +86,17 @@ public:
 
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGMARKERELEMENT
   NS_DECL_NSIDOMSVGFITTOVIEWBOX
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGElement::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGElement::)
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;
 
   virtual bool GetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                          nsAString& aResult) const;
--- a/content/svg/content/src/nsSVGMaskElement.h
+++ b/content/svg/content/src/nsSVGMaskElement.h
@@ -31,17 +31,17 @@ protected:
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
 
   // Mask Element
   NS_DECL_NSIDOMSVGMASKELEMENT
 
-  NS_FORWARD_NSIDOMNODE(nsSVGElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGElement::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGElement::)
 
   // nsIContent interface
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
--- a/content/svg/content/src/nsSVGMetadataElement.cpp
+++ b/content/svg/content/src/nsSVGMetadataElement.cpp
@@ -19,17 +19,17 @@ protected:
 
 public:
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGMETADATAELEMENT
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGElement::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGElement::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
--- a/content/svg/content/src/nsSVGMpathElement.h
+++ b/content/svg/content/src/nsSVGMpathElement.h
@@ -36,17 +36,17 @@ public:
   NS_DECL_NSIDOMSVGURIREFERENCE
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsSVGMpathElement,
                                            nsSVGMpathElementBase)
 
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
 
   // Forward interface implementations to base class
-  NS_FORWARD_NSIDOMNODE(nsSVGMpathElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGMpathElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGMpathElementBase::)
 
   // nsIContent interface
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers);
--- a/content/svg/content/src/nsSVGPathElement.h
+++ b/content/svg/content/src/nsSVGPathElement.h
@@ -31,17 +31,17 @@ public:
   typedef mozilla::SVGAnimatedPathSegList SVGAnimatedPathSegList;
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGPATHELEMENT
   NS_DECL_NSIDOMSVGANIMATEDPATHDATA
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGPathElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGPathElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGPathElementBase::)
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;
 
   // nsSVGSVGElement methods:
   virtual bool HasValidDimensions() const;
--- a/content/svg/content/src/nsSVGPatternElement.h
+++ b/content/svg/content/src/nsSVGPatternElement.h
@@ -47,17 +47,17 @@ public:
   NS_DECL_NSIDOMSVGPATTERNELEMENT
 
   // URI Reference
   NS_DECL_NSIDOMSVGURIREFERENCE
 
   // FitToViewbox
   NS_DECL_NSIDOMSVGFITTOVIEWBOX
 
-  NS_FORWARD_NSIDOMNODE(nsSVGElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGElement::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGElement::)
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
--- a/content/svg/content/src/nsSVGPolygonElement.cpp
+++ b/content/svg/content/src/nsSVGPolygonElement.cpp
@@ -20,17 +20,17 @@ protected:
 
 public:
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGPOLYGONELEMENT
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGPolygonElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGPolygonElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGPolygonElementBase::)
 
   // nsSVGPathGeometryElement methods:
   virtual void GetMarkPoints(nsTArray<nsSVGMark> *aMarks);
   virtual void ConstructPath(gfxContext *aCtx);
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
--- a/content/svg/content/src/nsSVGPolylineElement.cpp
+++ b/content/svg/content/src/nsSVGPolylineElement.cpp
@@ -18,17 +18,17 @@ protected:
 
 public:
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGPOLYLINEELEMENT
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGPolylineElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGPolylineElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGPolylineElementBase::)
 
   // nsIContent interface
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
   virtual nsXPCClassInfo* GetClassInfo();
   virtual nsIDOMNode* AsDOMNode() { return this; }
 };
--- a/content/svg/content/src/nsSVGRectElement.cpp
+++ b/content/svg/content/src/nsSVGRectElement.cpp
@@ -24,17 +24,17 @@ protected:
   nsSVGRectElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGRECTELEMENT
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGRectElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGRectElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGRectElementBase::)
 
   // nsSVGSVGElement methods:
   virtual bool HasValidDimensions() const;
 
   // nsSVGPathGeometryElement methods:
   virtual void ConstructPath(gfxContext *aCtx);
--- a/content/svg/content/src/nsSVGSVGElement.h
+++ b/content/svg/content/src/nsSVGSVGElement.h
@@ -125,17 +125,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsSVGSVGElement, nsSVGSVGElementBase)
   NS_DECL_NSIDOMSVGSVGELEMENT
   NS_DECL_NSIDOMSVGFITTOVIEWBOX
   NS_DECL_NSIDOMSVGLOCATABLE
   NS_DECL_NSIDOMSVGZOOMANDPAN
   
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGSVGElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGSVGElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGSVGElementBase::)
 
   /**
    * For use by zoom controls to allow currentScale, currentTranslate.x and
    * currentTranslate.y to be set by a single operation that dispatches a
    * single SVGZoom event (instead of one SVGZoom and two SVGScroll events).
    */
--- a/content/svg/content/src/nsSVGScriptElement.cpp
+++ b/content/svg/content/src/nsSVGScriptElement.cpp
@@ -39,17 +39,17 @@ public:
   // interfaces:
   
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGSCRIPTELEMENT
   NS_DECL_NSIDOMSVGURIREFERENCE
 
   // xxx If xpcom allowed virtual inheritance we wouldn't need to
   // forward here :-(
-  NS_FORWARD_NSIDOMNODE(nsSVGScriptElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGScriptElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGScriptElementBase::)
 
   // nsIScriptElement
   virtual void GetScriptType(nsAString& type);
   virtual void GetScriptText(nsAString& text);
   virtual void GetScriptCharset(nsAString& charset);
   virtual void FreezeUriAsyncDefer();
--- a/content/svg/content/src/nsSVGSetElement.cpp
+++ b/content/svg/content/src/nsSVGSetElement.cpp
@@ -19,17 +19,17 @@ protected:
 
   nsSMILSetAnimationFunction mAnimationFunction;
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGSETELEMENT
 
-  NS_FORWARD_NSIDOMNODE(nsSVGSetElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGSetElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGSetElementBase::)
   NS_FORWARD_NSIDOMSVGANIMATIONELEMENT(nsSVGSetElementBase::)
   
   // nsIDOMNode
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   // nsISMILAnimationElement
--- a/content/svg/content/src/nsSVGStopElement.cpp
+++ b/content/svg/content/src/nsSVGStopElement.cpp
@@ -25,17 +25,17 @@ protected:
 public:
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGSTOPELEMENT
 
   // xxx If xpcom allowed virtual inheritance we wouldn't need to
   // forward here :-(
-  NS_FORWARD_NSIDOMNODE(nsSVGStopElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGStopElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGStopElementBase::)
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
--- a/content/svg/content/src/nsSVGStyleElement.cpp
+++ b/content/svg/content/src/nsSVGStyleElement.cpp
@@ -29,17 +29,17 @@ protected:
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGSTYLEELEMENT
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsSVGStyleElement,
                                            nsSVGStyleElementBase)
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGStyleElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGStyleElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGStyleElementBase::)
 
   // nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers);
   virtual void UnbindFromTree(bool aDeep = true,
--- a/content/svg/content/src/nsSVGSwitchElement.h
+++ b/content/svg/content/src/nsSVGSwitchElement.h
@@ -30,17 +30,17 @@ public:
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsSVGSwitchElement,
                                            nsSVGSwitchElementBase)
   NS_DECL_NSIDOMSVGSWITCHELEMENT
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGSwitchElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGSwitchElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGSwitchElementBase::)
 
   // nsINode
   virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex,
                                  bool aNotify);
   virtual void RemoveChildAt(uint32_t aIndex, bool aNotify);
 
--- a/content/svg/content/src/nsSVGSymbolElement.cpp
+++ b/content/svg/content/src/nsSVGSymbolElement.cpp
@@ -29,17 +29,17 @@ protected:
 public:
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGSYMBOLELEMENT
   NS_DECL_NSIDOMSVGFITTOVIEWBOX
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGElement::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGElement::)
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
--- a/content/svg/content/src/nsSVGTSpanElement.cpp
+++ b/content/svg/content/src/nsSVGTSpanElement.cpp
@@ -26,17 +26,17 @@ protected:
 public:
   // interfaces:
   
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGTSPANELEMENT
 
   // xxx If xpcom allowed virtual inheritance we wouldn't need to
   // forward here :-(
-  NS_FORWARD_NSIDOMNODE(nsSVGTSpanElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGTSpanElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGTSpanElementBase::)
   NS_FORWARD_NSIDOMSVGTEXTCONTENTELEMENT(nsSVGTSpanElementBase::)
   NS_FORWARD_NSIDOMSVGTEXTPOSITIONINGELEMENT(nsSVGTSpanElementBase::)
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 
--- a/content/svg/content/src/nsSVGTextElement.cpp
+++ b/content/svg/content/src/nsSVGTextElement.cpp
@@ -51,17 +51,17 @@ public:
   
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGTEXTELEMENT
   NS_DECL_NSIDOMSVGTEXTPOSITIONINGELEMENT
   NS_DECL_NSIDOMSVGTEXTCONTENTELEMENT
 
   // xxx If xpcom allowed virtual inheritance we wouldn't need to
   // forward here :-(
-  NS_FORWARD_NSIDOMNODE(nsSVGTextElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGTextElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGTextElementBase::)
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
--- a/content/svg/content/src/nsSVGTextPathElement.h
+++ b/content/svg/content/src/nsSVGTextPathElement.h
@@ -40,17 +40,17 @@ public:
   // interfaces:
   
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGTEXTPATHELEMENT
   NS_DECL_NSIDOMSVGURIREFERENCE
 
   // xxx If xpcom allowed virtual inheritance we wouldn't need to
   // forward here :-(
-  NS_FORWARD_NSIDOMNODE(nsSVGTextPathElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGTextPathElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGTextPathElementBase::)
   NS_FORWARD_NSIDOMSVGTEXTCONTENTELEMENT(nsSVGTextPathElementBase::)
 
   // nsIContent interface
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
--- a/content/svg/content/src/nsSVGTitleElement.cpp
+++ b/content/svg/content/src/nsSVGTitleElement.cpp
@@ -21,17 +21,17 @@ protected:
 
 public:
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGTITLEELEMENT
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGTitleElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGTitleElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGTitleElementBase::)
 
   // nsIMutationObserver
   NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
--- a/content/svg/content/src/nsSVGUnknownElement.cpp
+++ b/content/svg/content/src/nsSVGUnknownElement.cpp
@@ -18,17 +18,17 @@ protected:
                                           already_AddRefed<nsINodeInfo> aNodeInfo);
   nsSVGUnknownElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
   
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGUnknownElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGUnknownElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGUnknownElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
--- a/content/svg/content/src/nsSVGUseElement.cpp
+++ b/content/svg/content/src/nsSVGUseElement.cpp
@@ -275,17 +275,17 @@ nsSVGUseElement::CreateAnonymousContent(
                                    getter_AddRefs(useImpl));
 
         if (useImpl && useImpl->mOriginal == mOriginal)
           return nullptr;
       }
     }
   }
 
-  nsCOMPtr<nsIDOMNode> newnode;
+  nsCOMPtr<nsINode> newnode;
   nsCOMArray<nsINode> unused;
   nsNodeInfoManager* nodeInfoManager =
     targetContent->OwnerDoc() == OwnerDoc() ?
       nullptr : OwnerDoc()->NodeInfoManager();
   nsNodeUtils::Clone(targetContent, true, nodeInfoManager, unused,
                      getter_AddRefs(newnode));
 
   nsCOMPtr<nsIContent> newcontent = do_QueryInterface(newnode);
--- a/content/svg/content/src/nsSVGUseElement.h
+++ b/content/svg/content/src/nsSVGUseElement.h
@@ -57,17 +57,17 @@ public:
   NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
   NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
 
   // xxx I wish we could use virtual inheritance
-  NS_FORWARD_NSIDOMNODE(nsSVGUseElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGUseElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGUseElementBase::)
 
   // for nsSVGUseFrame's nsIAnonymousContentCreator implementation.
   nsIContent* CreateAnonymousContent();
   nsIContent* GetAnonymousContent() const { return mClone; }
   void DestroyAnonymousContent();
 
--- a/content/svg/content/src/nsSVGViewElement.h
+++ b/content/svg/content/src/nsSVGViewElement.h
@@ -38,17 +38,17 @@ public:
   
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGVIEWELEMENT
   NS_DECL_NSIDOMSVGFITTOVIEWBOX
   NS_DECL_NSIDOMSVGZOOMANDPAN
 
   // xxx If xpcom allowed virtual inheritance we wouldn't need to
   // forward here :-(
-  NS_FORWARD_NSIDOMNODE(nsSVGViewElementBase::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT(nsSVGViewElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGViewElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
--- a/content/svg/document/src/nsSVGDocument.h
+++ b/content/svg/document/src/nsSVGDocument.h
@@ -15,15 +15,15 @@ class nsSVGDocument : public nsXMLDocume
 public:
   using nsDocument::GetElementById;
   using nsDocument::SetDocumentURI;
   nsSVGDocument();
   virtual ~nsSVGDocument();
 
   NS_DECL_NSIDOMSVGDOCUMENT
   NS_FORWARD_NSIDOMDOCUMENT(nsXMLDocument::)
-  NS_FORWARD_NSIDOMNODE(nsXMLDocument::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_DECL_ISUPPORTS_INHERITED
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
   virtual nsXPCClassInfo* GetClassInfo();
 };
 
 #endif
--- a/content/xbl/src/nsBindingManager.cpp
+++ b/content/xbl/src/nsBindingManager.cpp
@@ -687,17 +687,17 @@ nsBindingManager::GetContentListFor(nsIC
   nsINodeList* result = nullptr;
 
   if (mContentListTable.ops) {
     result = static_cast<nsAnonymousContentList*>
       (LookupObject(mContentListTable, aContent));
   }
 
   if (!result) {
-    result = aContent->GetChildNodesList();
+    result = aContent->ChildNodes();
   }
 
   return result;
 }
 
 nsresult
 nsBindingManager::SetContentListFor(nsIContent* aContent,
                                     nsInsertionPointList* aList)
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -685,17 +685,17 @@ RealizeDefaultContent(nsISupports* aKey,
         // actual default content (through cloning).
         // Clone this insertion point element.
         nsCOMPtr<nsIContent> insParent = currPoint->GetInsertionParent();
         if (!insParent) {
           data->mRv = NS_ERROR_FAILURE;
           return PL_DHASH_STOP;
         }
         nsIDocument *document = insParent->OwnerDoc();
-        nsCOMPtr<nsIDOMNode> clonedNode;
+        nsCOMPtr<nsINode> clonedNode;
         nsCOMArray<nsINode> nodesWithProperties;
         nsNodeUtils::Clone(defContent, true, document->NodeInfoManager(),
                            nodesWithProperties, getter_AddRefs(clonedNode));
 
         // Now that we have the cloned content, install the default content as
         // if it were additional anonymous content.
         nsCOMPtr<nsIContent> clonedContent(do_QueryInterface(clonedNode));
         binding->InstallAnonymousContent(clonedContent, insParent,
@@ -801,17 +801,17 @@ nsXBLBinding::GenerateAnonymousContent()
              localName != nsGkAtoms::_template)) {
           hasContent = false;
           break;
         }
       }
     }
 
     if (hasContent || hasInsertionPoints) {
-      nsCOMPtr<nsIDOMNode> clonedNode;
+      nsCOMPtr<nsINode> clonedNode;
       nsCOMArray<nsINode> nodesWithProperties;
       nsNodeUtils::Clone(content, true, doc->NodeInfoManager(),
                          nodesWithProperties, getter_AddRefs(clonedNode));
 
       mContent = do_QueryInterface(clonedNode);
       InstallAnonymousContent(mContent, mBoundElement,
                               mPrototypeBinding->ChromeOnlyContent());
 
@@ -1684,16 +1684,16 @@ nsXBLBinding::ImplementsInterface(REFNSI
   return mPrototypeBinding->ImplementsInterface(aIID) ||
     (mNextBinding && mNextBinding->ImplementsInterface(aIID));
 }
 
 nsINodeList*
 nsXBLBinding::GetAnonymousNodes()
 {
   if (mContent) {
-    return mContent->GetChildNodesList();
+    return mContent->ChildNodes();
   }
 
   if (mNextBinding)
     return mNextBinding->GetAnonymousNodes();
 
   return nullptr;
 }
--- a/content/xml/content/src/nsXMLCDATASection.cpp
+++ b/content/xml/content/src/nsXMLCDATASection.cpp
@@ -13,17 +13,17 @@ class nsXMLCDATASection : public nsGener
 public:
   nsXMLCDATASection(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsXMLCDATASection();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericDOMDataNode::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMCharacterData
   NS_FORWARD_NSIDOMCHARACTERDATA(nsGenericDOMDataNode::)
 
   // nsIDOMText
   NS_FORWARD_NSIDOMTEXT(nsGenericDOMDataNode::)
 
   // nsIDOMCDATASection
--- a/content/xml/content/src/nsXMLElement.h
+++ b/content/xml/content/src/nsXMLElement.h
@@ -17,17 +17,17 @@ public:
     : nsGenericElement(aNodeInfo)
   {
   }
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericElement::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericElement::)
 
   // nsINode interface methods
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
--- a/content/xml/content/src/nsXMLProcessingInstruction.h
+++ b/content/xml/content/src/nsXMLProcessingInstruction.h
@@ -18,17 +18,17 @@ public:
   nsXMLProcessingInstruction(already_AddRefed<nsINodeInfo> aNodeInfo,
                              const nsAString& aData);
   virtual ~nsXMLProcessingInstruction();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericDOMDataNode::)
+  NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
   // nsIDOMCharacterData
   NS_FORWARD_NSIDOMCHARACTERDATA(nsGenericDOMDataNode::)
 
   // nsIDOMProcessingInstruction
   NS_DECL_NSIDOMPROCESSINGINSTRUCTION
 
   // nsINode
--- a/content/xml/content/src/nsXMLStylesheetPI.cpp
+++ b/content/xml/content/src/nsXMLStylesheetPI.cpp
@@ -11,32 +11,35 @@
 #include "nsStyleLinkElement.h"
 #include "nsNetUtil.h"
 #include "nsXMLProcessingInstruction.h"
 #include "nsUnicharUtils.h"
 #include "nsGkAtoms.h"
 #include "nsThreadUtils.h"
 #include "nsContentUtils.h"
 
+using namespace mozilla;
+
 class nsXMLStylesheetPI : public nsXMLProcessingInstruction,
                           public nsStyleLinkElement
 {
 public:
   nsXMLStylesheetPI(already_AddRefed<nsINodeInfo> aNodeInfo, const nsAString& aData);
   virtual ~nsXMLStylesheetPI();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // CC
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXMLStylesheetPI,
                                            nsXMLProcessingInstruction)
 
   // nsIDOMNode
-  NS_IMETHOD SetNodeValue(const nsAString& aData);
+  virtual void SetNodeValueInternal(const nsAString& aNodeValue,
+                                    mozilla::ErrorResult& aError);
 
   // nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers);
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true);
 
@@ -118,24 +121,24 @@ nsXMLStylesheetPI::UnbindFromTree(bool a
   nsCOMPtr<nsIDocument> oldDoc = GetCurrentDoc();
 
   nsXMLProcessingInstruction::UnbindFromTree(aDeep, aNullParent);
   UpdateStyleSheetInternal(oldDoc);
 }
 
 // nsIDOMNode
 
-NS_IMETHODIMP
-nsXMLStylesheetPI::SetNodeValue(const nsAString& aNodeValue)
+void
+nsXMLStylesheetPI::SetNodeValueInternal(const nsAString& aNodeValue,
+                                        ErrorResult& aError)
 {
-  nsresult rv = nsGenericDOMDataNode::SetNodeValue(aNodeValue);
-  if (NS_SUCCEEDED(rv)) {
+  nsGenericDOMDataNode::SetNodeValue(aNodeValue, aError);
+  if (!aError.Failed()) {
     UpdateStyleSheetInternal(nullptr, true);
   }
-  return rv;
 }
 
 // nsStyleLinkElement
 
 NS_IMETHODIMP
 nsXMLStylesheetPI::GetCharset(nsAString& aCharset)
 {
   return GetAttrValue(nsGkAtoms::charset, aCharset) ? NS_OK : NS_ERROR_FAILURE;
--- a/content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
+++ b/content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
@@ -249,17 +249,17 @@ txXPathTreeWalker::moveToParent()
     }
 
     if (mPosition.isAttribute()) {
         mPosition.mIndex = txXPathNode::eContent;
 
         return true;
     }
 
-    nsINode* parent = mPosition.mNode->GetNodeParent();
+    nsINode* parent = mPosition.mNode->GetParentNode();
     if (!parent) {
         return false;
     }
 
     uint32_t count = mDescendants.Length();
     if (count) {
         mCurrentIndex = mDescendants.ValueAt(--count);
         mDescendants.RemoveValueAt(count);
@@ -276,17 +276,17 @@ txXPathTreeWalker::moveToParent()
 }
 
 bool
 txXPathTreeWalker::moveToSibling(int32_t aDir)
 {
     NS_ASSERTION(mPosition.isContent(),
                  "moveToSibling should only be called for content");
 
-    nsINode* parent = mPosition.mNode->GetNodeParent();
+    nsINode* parent = mPosition.mNode->GetParentNode();
     if (!parent) {
         return false;
     }
     if (mCurrentIndex == kUnknownIndex) {
         mCurrentIndex = parent->IndexOf(mPosition.mNode);
     }
 
     // if mCurrentIndex is 0 we rely on GetChildAt returning null for an
@@ -563,17 +563,17 @@ txXPathNodeUtils::getXSLTId(const txXPat
 
     return NS_OK;
 }
 
 /* static */
 void
 txXPathNodeUtils::getBaseURI(const txXPathNode& aNode, nsAString& aURI)
 {
-    aNode.mNode->GetDOMBaseURI(aURI);
+    aNode.mNode->GetBaseURI(aURI);
 }
 
 /* static */
 int
 txXPathNodeUtils::comparePosition(const txXPathNode& aNode,
                                   const txXPathNode& aOtherNode)
 {
     // First check for equal nodes or attribute-nodes on the same element.
@@ -607,18 +607,18 @@ txXPathNodeUtils::comparePosition(const 
     // same tree.
 
     // Get parents up the tree.
     nsAutoTArray<nsINode*, 8> parents, otherParents;
     nsINode* node = aNode.mNode;
     nsINode* otherNode = aOtherNode.mNode;
     nsINode* parent, *otherParent;
     while (node && otherNode) {
-        parent = node->GetNodeParent();
-        otherParent = otherNode->GetNodeParent();
+        parent = node->GetParentNode();
+        otherParent = otherNode->GetParentNode();
 
         // Hopefully this is a common case.
         if (parent == otherParent) {
             if (!parent) {
                 // Both node and otherNode are root nodes in respective orphan
                 // tree.
                 return node < otherNode ? -1 : 1;
             }
@@ -630,21 +630,21 @@ txXPathNodeUtils::comparePosition(const 
         parents.AppendElement(node);
         otherParents.AppendElement(otherNode);
         node = parent;
         otherNode = otherParent;
     }
 
     while (node) {
         parents.AppendElement(node);
-        node = node->GetNodeParent();
+        node = node->GetParentNode();
     }
     while (otherNode) {
         otherParents.AppendElement(otherNode);
-        otherNode = otherNode->GetNodeParent();
+        otherNode = otherNode->GetParentNode();
     }
 
     // Walk back down along the parent-chains until we find where they split.
     int32_t total = parents.Length() - 1;
     int32_t otherTotal = otherParents.Length() - 1;
     NS_ASSERTION(total != otherTotal, "Can't have same number of parents");
 
     int32_t lastIndex = NS_MIN(total, otherTotal);
--- a/content/xslt/src/xpath/txXPathNode.h
+++ b/content/xslt/src/xpath/txXPathNode.h
@@ -48,17 +48,17 @@ private:
         if (aRoot) {
             NS_ADDREF(aRoot);
         }
     }
 
     static nsINode *RootOf(nsINode *aNode)
     {
         nsINode *ancestor, *root = aNode;
-        while ((ancestor = root->GetNodeParent())) {
+        while ((ancestor = root->GetParentNode())) {
             root = ancestor;
         }
         return root;
     }
     nsINode *Root() const
     {
         return RootOf(mNode);
     }
--- a/content/xslt/src/xpath/txXPathTreeWalker.h
+++ b/content/xslt/src/xpath/txXPathTreeWalker.h
@@ -226,17 +226,17 @@ txXPathNodeUtils::localNameEquals(const 
 
     return localName == aLocalName;
 }
 
 /* static */
 inline bool
 txXPathNodeUtils::isRoot(const txXPathNode& aNode)
 {
-    return !aNode.isAttribute() && !aNode.mNode->GetNodeParent();
+    return !aNode.isAttribute() && !aNode.mNode->GetParentNode();
 }
 
 /* static */
 inline bool
 txXPathNodeUtils::isElement(const txXPathNode& aNode)
 {
     return aNode.isContent() &&
            aNode.Content()->IsElement();
--- a/content/xslt/src/xslt/txMozillaXMLOutput.cpp
+++ b/content/xslt/src/xslt/txMozillaXMLOutput.cpp
@@ -348,17 +348,17 @@ txMozillaXMLOutput::endElement()
             NS_ASSERTION(!mRootContentCreated,
                          "Parent to add to shouldn't be a document if we "
                          "have a root content");
             mRootContentCreated = true;
         }
 
         // Check to make sure that script hasn't inserted the node somewhere
         // else in the tree
-        if (!mCurrentNode->GetNodeParent()) {
+        if (!mCurrentNode->GetParentNode()) {
             parent->AppendChildTo(mNonAddedNode, true);
         }
         mNonAddedNode = nullptr;
     }
 
     mCurrentNode = parent;
 
     mTableState =
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -393,17 +393,17 @@ public:
      * The template-generated flag is used to indicate that a
      * template-generated element has already had its children generated.
      */
     void SetTemplateGenerated() { SetFlags(XUL_ELEMENT_TEMPLATE_GENERATED); }
     void ClearTemplateGenerated() { UnsetFlags(XUL_ELEMENT_TEMPLATE_GENERATED); }
     bool GetTemplateGenerated() { return HasFlag(XUL_ELEMENT_TEMPLATE_GENERATED); }
 
     // nsIDOMNode
-    NS_FORWARD_NSIDOMNODE(nsGenericElement::)
+    NS_FORWARD_NSIDOMNODE_TO_NSINODE
 
     // nsIDOMElement
     NS_FORWARD_NSIDOMELEMENT(nsGenericElement::)
 
     // nsIDOMXULElement
     NS_DECL_NSIDOMXULELEMENT
 
     virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
--- a/dom/activities/src/ActivitiesService.jsm
+++ b/dom/activities/src/ActivitiesService.jsm
@@ -276,23 +276,25 @@ let Activities = {
 
   receiveMessage: function activities_receiveMessage(aMessage) {
     let mm = aMessage.target;
     let msg = aMessage.json;
 
     let caller;
     let obsData;
 
-    if (aMessage.name == "Activity:FireSuccess" ||
-        aMessage.name == "Activity:FireError") {
+    if (aMessage.name == "Activity:PostResult" ||
+        aMessage.name == "Activity:PostError") {
       caller = this.callers[msg.id];
       if (caller) {
         obsData = JSON.stringify({ manifestURL: caller.manifestURL,
                                    pageURL: caller.pageURL,
-                                   success: aMessage.name == "Activity:FireSuccess" });
+                                   success: aMessage.name == "Activity:PostResult" });
+      } else {
+        debug("!! caller is null for msg.id=" + msg.id);
       }
     }
 
     switch(aMessage.name) {
       case "Activity:Start":
         this.callers[msg.id] = { mm: aMessage.target,
                                  manifestURL: msg.manifestURL,
                                  pageURL: msg.pageURL };
--- a/dom/apps/src/Webapps.js
+++ b/dom/apps/src/Webapps.js
@@ -182,16 +182,18 @@ WebappsRegistry.prototype = {
   get mgmt() {
     if (!this._mgmt)
       this._mgmt = new WebappsApplicationMgmt(this._window);
     return this._mgmt;
   },
 
   uninit: function() {
     this._mgmt = null;
+    cpmm.sendAsyncMessage("Webapps:UnregisterForMessages",
+                          ["Webapps:Install:Return:OK"]);
   },
 
   // mozIDOMApplicationRegistry2 implementation
 
   installPackage: function(aURL, aParams) {
     let installURL = this._window.location.href;
     let installOrigin = this._getOrigin(installURL);
     this._validateScheme(aURL);
@@ -486,16 +488,19 @@ WebappsApplication.prototype = {
       BrowserElementPromptService.getBrowserElementChildForWindow(this._window);
     if (browserChild) {
       browserChild.messageManager.sendAsyncMessage("Webapps:ClearBrowserData");
     }
   },
 
   uninit: function() {
     this._onprogress = null;
+    cpmm.sendAsyncMessage("Webapps:UnregisterForMessages",
+                          ["Webapps:Uninstall:Return:OK", "Webapps:OfflineCache",
+                           "Webapps:PackageEvent"]);
   },
 
   _fireEvent: function(aName, aHandler) {
     if (aHandler) {
       let event = new this._window.MozApplicationEvent(aName, { application: this });
       aHandler.handleEvent(event);
     }
   },
@@ -650,16 +655,18 @@ WebappsApplicationMgmt.prototype = {
                       getNotInstalled: "r",
                       oninstall: "rw",
                       onuninstall: "rw"
                      },
 
   uninit: function() {
     this._oninstall = null;
     this._onuninstall = null;
+    cpmm.sendAsyncMessage("Webapps:UnregisterForMessages",
+                          ["Webapps:Install:Return:OK", "Webapps:Uninstall:Return:OK"]);
   },
 
   applyDownload: function(aApp) {
     if (!aApp.readyToApplyDownload) {
       return;
     }
 
     cpmm.sendAsyncMessage("Webapps::ApplyDownload",
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -62,16 +62,17 @@ let DOMApplicationRegistry = {
 
   init: function() {
     this.messages = ["Webapps:Install", "Webapps:Uninstall",
                      "Webapps:GetSelf", "Webapps:CheckInstalled",
                      "Webapps:GetInstalled", "Webapps:GetNotInstalled",
                      "Webapps:Launch", "Webapps:GetAll",
                      "Webapps:InstallPackage", "Webapps:GetBasePath",
                      "Webapps:GetList", "Webapps:RegisterForMessages",
+                     "Webapps:UnregisterForMessages",
                      "Webapps:CancelDownload", "Webapps:CheckForUpdate",
                      "Webapps::Download", "Webapps::ApplyDownload",
                      "child-process-shutdown"];
 
     this.frameMessages = ["Webapps:ClearBrowserData"];
 
     this.messages.forEach((function(msgName) {
       ppmm.addMessageListener(msgName, this);
@@ -477,31 +478,75 @@ let DOMApplicationRegistry = {
     }
   },
 
   addMessageListener: function(aMsgNames, aMm) {
     aMsgNames.forEach(function (aMsgName) {
       if (!(aMsgName in this.children)) {
         this.children[aMsgName] = [];
       }
-      this.children[aMsgName].push(aMm);
+
+      let mmFound = this.children[aMsgName].some(function(mmRef) {
+        if (mmRef.mm === aMm) {
+          mmRef.refCount++;
+          return true;
+        }
+        return false;
+      });
+
+      if (!mmFound) {
+        this.children[aMsgName].push({
+          mm: aMm,
+          refCount: 1
+        });
+      }
     }, this);
   },
 
+  removeMessageListener: function(aMsgNames, aMm) {
+    if (aMsgNames.length === 1 &&
+        aMsgNames[0] === "Webapps:Internal:AllMessages") {
+      for (let i = this.children.length - 1; i >= 0; i -= 1) {
+        let msg = this.children[i];
 
-  removeMessageListener: function(aMm) {
-    for (let i = this.children.length - 1; i >= 0; i -= 1) {
-      msg = this.children[i];
+        for (let mmI = msg.length - 1; mmI >= 0; mmI -= 1) {
+          let mmRef = msg[mmI];
+          if (mmRef.mm === aMm) {
+            msg.splice(mmI, 1);
+          }
+        }
+
+        if (msg.length === 0) {
+          this.children.splice(i, 1);
+        }
+      }
+      return;
+    }
 
-      let index;
-      if ((index = msg.indexOf(aMm)) != -1) {
-         debug("Remove dead mm at index " + index);
-         msg.splice(index, 1);
+    aMsgNames.forEach(function(aMsgName) {
+      if (!(aMsgName in this.children)) {
+        return;
       }
-    };
+
+      let removeIndex;
+      this.children[aMsgName].some(function(mmRef, index) {
+        if (mmRef.mm === aMm) {
+          mmRef.refCount--;
+          if (mmRef.refCount === 0) {
+            removeIndex = index;
+          }
+          return true;
+        }
+        return false;
+      });
+
+      if (removeIndex) {
+        this.children[aMsgName].splice(removeIndex, 1);
+      }
+    }, this);
   },
 
   receiveMessage: function(aMessage) {
     // nsIPrefBranch throws if pref does not exist, faster to simply write
     // the pref instead of first checking if it is false.
     Services.prefs.setBoolPref("dom.mozApps.used", true);
 
     // We need to check permissions for calls coming from mozApps.mgmt.
@@ -555,16 +600,22 @@ let DOMApplicationRegistry = {
         Services.obs.notifyObservers(mm, "webapps-ask-install", JSON.stringify(msg));
         break;
       case "Webapps:GetBasePath":
         return this.webapps[msg.id].basePath;
         break;
       case "Webapps:RegisterForMessages":
         this.addMessageListener(msg, mm);
         break;
+      case "Webapps:UnregisterForMessages":
+        this.removeMessageListener(msg, mm);
+        break;
+      case "child-process-shutdown":
+        this.removeMessageListener(["Webapps:Internal:AllMessages"], mm);
+        break;
       case "Webapps:GetList":
         this.addMessageListener(["Webapps:AddApp", "Webapps:RemoveApp"], mm);
         return this.webapps;
       case "Webapps:Download":
         this.startDownload(msg.manifestURL);
         break;
       case "Webapps:CancelDownload":
         this.cancelDownload(msg.manifestURL);
@@ -573,46 +624,32 @@ let DOMApplicationRegistry = {
         this.checkForUpdate(msg, mm);
         break;
       case "Webapps::ApplyDownload":
         this.ApplyDownload(msg.manifestURL);
         break;
       case "Activities:Register:OK":
         this.notifyAppsRegistryReady();
         break;
-      case "child-process-shutdown":
-        this.removeMessageListener(mm);
-        break;
     }
   },
 
   // Some messages can be listened by several content processes:
   // Webapps:AddApp
   // Webapps:RemoveApp
   // Webapps:Install:Return:OK
   // Webapps:Uninstall:Return:OK
   // Webapps:OfflineCache
   broadcastMessage: function broadcastMessage(aMsgName, aContent) {
     if (!(aMsgName in this.children)) {
       return;
     }
-    let i;
-    for (i = this.children[aMsgName].length - 1; i >= 0; i -= 1) {
-      let msgMgr = this.children[aMsgName][i];
-      try {
-        msgMgr.sendAsyncMessage(aMsgName, aContent);
-      } catch (e) {
-        // Remove once 777508 lands.
-        let index;
-        if ((index = this.children[aMsgName].indexOf(msgMgr)) != -1) {
-          this.children[aMsgName].splice(index, 1);
-          dump("Remove dead MessageManager!\n");
-        }
-      }
-    };
+    this.children[aMsgName].forEach(function(mmRef) {
+      mmRef.mm.sendAsyncMessage(aMsgName, aContent);
+    });
   },
 
   _getAppDir: function(aId) {
     return FileUtils.getDir(DIRECTORY_NAME, ["webapps", aId], true, true);
   },
 
   _writeFile: function ss_writeFile(aFile, aData, aCallbak) {
     // Initialize the file output stream.
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -1769,17 +1769,17 @@ nsFocusManager::Focus(nsPIDOMWindow* aWi
 
   // check to ensure that the element is still focusable, and that nothing
   // else was focused during the events above.
   if (CheckIfFocusable(aContent, aFlags) &&
       mFocusedWindow == aWindow && mFocusedContent == nullptr) {
     mFocusedContent = aContent;
 
     nsIContent* focusedNode = aWindow->GetFocusedNode();
-    bool isRefocus = focusedNode && focusedNode->IsEqualTo(aContent);
+    bool isRefocus = focusedNode && focusedNode->IsEqualNode(aContent);
 
     aWindow->SetFocusedNode(aContent, focusMethod);
 
     bool sendFocusEvent =
       aContent && aContent->IsInDoc() && !IsNonFocusableRoot(aContent);
     nsPresContext* presContext = presShell->GetPresContext();
     if (sendFocusEvent) {
       // if the focused element changed, scroll it into view
--- a/dom/base/nsLocation.cpp
+++ b/dom/base/nsLocation.cpp
@@ -34,60 +34,26 @@
 #include "nsReadableUtils.h"
 #include "nsITextToSubURI.h"
 #include "nsJSUtils.h"
 #include "jsfriendapi.h"
 #include "nsContentUtils.h"
 #include "nsEventStateManager.h"
 
 static nsresult
-GetContextFromStack(nsIJSContextStack *aStack, JSContext **aContext)
-{
-  nsCOMPtr<nsIJSContextStackIterator>
-    iterator(do_CreateInstance("@mozilla.org/js/xpc/ContextStackIterator;1"));
-  NS_ENSURE_TRUE(iterator, NS_ERROR_FAILURE);
-
-  nsresult rv = iterator->Reset(aStack);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  bool done;
-  while (NS_SUCCEEDED(iterator->Done(&done)) && !done) {
-    rv = iterator->Prev(aContext);
-    NS_ASSERTION(NS_SUCCEEDED(rv), "Broken iterator implementation");
-
-    // Consider a null context the end of the line.
-    if (!*aContext) {
-      break;
-    }
-
-    if (nsJSUtils::GetDynamicScriptContext(*aContext)) {
-      return NS_OK;
-    }
-  }
-
-  *aContext = nullptr;
-
-  return NS_OK;
-}
-
-static nsresult
 GetDocumentCharacterSetForURI(const nsAString& aHref, nsACString& aCharset)
 {
   aCharset.Truncate();
 
   nsresult rv;
 
   nsCOMPtr<nsIJSContextStack> stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  JSContext *cx;
-
-  rv = GetContextFromStack(stack, &cx);
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  JSContext *cx = nsContentUtils::GetCurrentJSContext();
   if (cx) {
     nsCOMPtr<nsIDOMWindow> window =
       do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(cx));
     NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
 
     nsCOMPtr<nsIDOMDocument> domDoc;
     rv = window->GetDocument(getter_AddRefs(domDoc));
     NS_ENSURE_SUCCESS(rv, rv);
@@ -163,53 +129,36 @@ GetScriptDocument(JSContext *cx, JSScrip
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
   return doc.forget();
 }
 
 nsresult
 nsLocation::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo)
 {
   *aLoadInfo = nullptr;
-  JSContext* cx;
-  if ((cx = nsContentUtils::GetCurrentJSContext())) {
-    nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
-    NS_ENSURE_STATE(ssm);
-    // Check to see if URI is allowed.
-    nsresult rv = ssm->CheckLoadURIFromScript(cx, aURI);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
 
   nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell));
   NS_ENSURE_TRUE(docShell, NS_ERROR_NOT_AVAILABLE);
 
-  nsresult rv;
-  // Get JSContext from stack.
-  nsCOMPtr<nsIJSContextStack>
-    stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  NS_ENSURE_SUCCESS(GetContextFromStack(stack, &cx), NS_ERROR_FAILURE);
-
   nsCOMPtr<nsISupports> owner;
   nsCOMPtr<nsIURI> sourceURI;
 
-  if (cx) {
+  if (JSContext *cx = nsContentUtils::GetCurrentJSContext()) {
     // No cx means that there's no JS running, or at least no JS that
     // was run through code that properly pushed a context onto the
     // context stack (as all code that runs JS off of web pages
     // does). We won't bother with security checks in this case, but
     // we need to create the loadinfo etc.
 
     // Get security manager.
-    nsCOMPtr<nsIScriptSecurityManager>
-      secMan(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv));
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
+    NS_ENSURE_STATE(ssm);
 
     // Check to see if URI is allowed.
-    rv = secMan->CheckLoadURIFromScript(cx, aURI);
+    nsresult rv = ssm->CheckLoadURIFromScript(cx, aURI);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Make the load's referrer reflect changes to the document's URI caused by
     // push/replaceState, if possible.  First, get the document corresponding to
     // fp.  If the document's original URI (i.e. its URI before
     // push/replaceState) matches the principal's URI, use the document's
     // current URI as the referrer.  If they don't match, use the principal's
     // URI.
@@ -236,17 +185,17 @@ nsLocation::CheckURL(nsIURI* aURI, nsIDo
 
     if (urisEqual) {
       sourceURI = docCurrentURI;
     }
     else {
       sourceURI = principalURI;
     }
 
-    owner = do_QueryInterface(secMan->GetCxSubjectPrincipal(cx));
+    owner = do_QueryInterface(ssm->GetCxSubjectPrincipal(cx));
   }
 
   // Create load info
   nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
   docShell->CreateLoadInfo(getter_AddRefs(loadInfo));
   NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);
 
   loadInfo->SetOwner(owner);
@@ -529,27 +478,17 @@ nsLocation::GetHref(nsAString& aHref)
 }
 
 NS_IMETHODIMP
 nsLocation::SetHref(const nsAString& aHref)
 {
   nsAutoString oldHref;
   nsresult rv = NS_OK;
 
-  // Get JSContext from stack.
-  nsCOMPtr<nsIJSContextStack>
-    stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv));
-
-  if (NS_FAILED(rv))
-    return NS_ERROR_FAILURE;
-
-  JSContext *cx;
-
-  if (NS_FAILED(GetContextFromStack(stack, &cx)))
-    return NS_ERROR_FAILURE;
+  JSContext *cx = nsContentUtils::GetCurrentJSContext();
 
   // According to HTML5 spec, |location.href = ...| must act as if
   // it were |location.replace(...)| before the page load finishes.
   //
   // http://www.w3.org/TR/2011/WD-html5-20110113/history.html#location
   //
   // > The href attribute must return the current address of the
   // > associated Document object, as an absolute URL.
@@ -918,29 +857,18 @@ nsLocation::Reload(bool aForceget)
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsLocation::Replace(const nsAString& aUrl)
 {
   nsresult rv = NS_OK;
-
-  // Get JSContext from stack.
-  nsCOMPtr<nsIJSContextStack>
-  stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1"));
-
-  if (stack) {
-    JSContext *cx;
-
-    rv = GetContextFromStack(stack, &cx);
-    NS_ENSURE_SUCCESS(rv, rv);
-    if (cx) {
-      return SetHrefWithContext(cx, aUrl, true);
-    }
+  if (JSContext *cx = nsContentUtils::GetCurrentJSContext()) {
+    return SetHrefWithContext(cx, aUrl, true);
   }
 
   nsAutoString oldHref;
 
   rv = GetHref(oldHref);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIURI> oldUri;
@@ -978,60 +906,37 @@ nsLocation::Assign(const nsAString& aUrl
 NS_IMETHODIMP
 nsLocation::ToString(nsAString& aReturn)
 {
   // NB: GetHref checks CallerSubsumes().
   return GetHref(aReturn);
 }
 
 nsresult
-nsLocation::GetSourceDocument(JSContext* cx, nsIDocument** aDocument)
-{
-  // XXX Code duplicated from nsHTMLDocument
-  // XXX Tom said this reminded him of the "Six Degrees of
-  // Kevin Bacon" game. We try to get from here to there using
-  // whatever connections possible. The problem is that this
-  // could break if any of the connections along the way change.
-  // I wish there were a better way.
-
-  nsresult rv = NS_ERROR_FAILURE;
-
-  // We need to use the dynamically scoped global and assume that the
-  // current JSContext is a DOM context with a nsIScriptGlobalObject so
-  // that we can get the url of the caller.
-  // XXX This will fail on non-DOM contexts :(
-
-  nsCOMPtr<nsIDOMWindow> window =
-    do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(cx), &rv);
-
-  if (window) {
-    nsCOMPtr<nsIDOMDocument> domDoc;
-    rv = window->GetDocument(getter_AddRefs(domDoc));
-    if (domDoc) {
-      return CallQueryInterface(domDoc, aDocument);
-    }
-  } else {
-    *aDocument = nullptr;
-  }
-
-  return rv;
-}
-
-nsresult
 nsLocation::GetSourceBaseURL(JSContext* cx, nsIURI** sourceURL)
 {
-  nsCOMPtr<nsIDocument> doc;
-  nsresult rv = GetSourceDocument(cx, getter_AddRefs(doc));
-  if (doc) {
-    *sourceURL = doc->GetBaseURI().get();
-  } else {
-    *sourceURL = nullptr;
+
+  *sourceURL = nullptr;
+  nsCOMPtr<nsIScriptGlobalObject> sgo = nsJSUtils::GetDynamicScriptGlobal(cx);
+  // If this JS context doesn't have an associated DOM window, we effectively
+  // have no script entry point stack. This doesn't generally happen with the DOM,
+  // but can sometimes happen with extension code in certain IPC configurations.
+  // If this happens, try falling back on the current document associated with
+  // the docshell. If that fails, just return null and hope that the caller passed
+  // an absolute URI.
+  if (!sgo && GetDocShell()) {
+    sgo = do_GetInterface(GetDocShell());
   }
-
-  return rv;
+  NS_ENSURE_TRUE(sgo, NS_OK);
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(sgo);
+  NS_ENSURE_TRUE(window, NS_ERROR_UNEXPECTED);
+  nsIDocument* doc = window->GetDoc();
+  NS_ENSURE_TRUE(doc, NS_OK);
+  *sourceURL = doc->GetBaseURI().get();
+  return NS_OK;
 }
 
 bool
 nsLocation::CallerSubsumes()
 {
   // Get the principal associated with the location object.
   nsCOMPtr<nsIDOMWindow> outer = do_QueryReferent(mOuter);
   if (NS_UNLIKELY(!outer))
--- a/dom/base/nsLocation.h
+++ b/dom/base/nsLocation.h
@@ -44,18 +44,16 @@ protected:
   nsresult GetWritableURI(nsIURI** aURL);
   nsresult SetURI(nsIURI* aURL, bool aReplace = false);
   nsresult SetHrefWithBase(const nsAString& aHref, nsIURI* aBase,
                            bool aReplace);
   nsresult SetHrefWithContext(JSContext* cx, const nsAString& aHref,
                               bool aReplace);
 
   nsresult GetSourceBaseURL(JSContext* cx, nsIURI** sourceURL);
-  nsresult GetSourceDocument(JSContext* cx, nsIDocument** aDocument);
-
   nsresult CheckURL(nsIURI *url, nsIDocShellLoadInfo** aLoadInfo);
   bool CallerSubsumes();
 
   nsString mCachedHash;
   nsWeakPtr mDocShell;
   nsWeakPtr mOuter;
 };
 
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -738,80 +738,146 @@ WrapObject<JSObject>(JSContext* cx, JSOb
   vp->setObjectOrNull(p);
   return true;
 }
 
 bool
 WrapCallbackInterface(JSContext *cx, JSObject *scope, nsISupports* callback,
                       JS::Value* vp);
 
-// This checks whether class T implements WrapObject itself, if so then
-// HasWrapObject<T>::Value will be true. Note that if T inherits WrapObject from
-// a base class but doesn't override it then HasWrapObject<T>::Value will be
-// false. This is a little annoying in some cases (multiple C++ classes using
-// the same binding), but it saves us in the case where a class inherits from
-// nsWrapperCache but doesn't actually override WrapObject. For now we assume
-// that HasWrapObject<T>::Value being false means we have an nsISupports object.
+#ifdef _MSC_VER
+#define HAS_MEMBER_CHECK(_name)                                           \
+  template<typename V> static yes& Check(char (*)[(&V::_name == 0) + 1])
+#else
+#define HAS_MEMBER_CHECK(_name)                                           \
+  template<typename V> static yes& Check(char (*)[sizeof(&V::_name) + 1])
+#endif
+
+#define HAS_MEMBER(_name)                                                 \
+template<typename T>                                                      \
+class Has##_name##Member {                                                \
+  typedef char yes[1];                                                    \
+  typedef char no[2];                                                     \
+  HAS_MEMBER_CHECK(_name);                                                \
+  template<typename V> static no& Check(...);                             \
+                                                                          \
+public:                                                                   \
+  static bool const Value = sizeof(Check<T>(nullptr)) == sizeof(yes);     \
+};
+
+HAS_MEMBER(AddRef)
+HAS_MEMBER(Release)
+HAS_MEMBER(QueryInterface)
+
+template<typename T>
+struct IsRefCounted
+{
+  static bool const Value = HasAddRefMember<T>::Value &&
+                            HasReleaseMember<T>::Value;
+};
+
+template<typename T>
+struct IsISupports
+{
+  static bool const Value = IsRefCounted<T>::Value &&
+                            HasQueryInterfaceMember<T>::Value;
+};
+
+HAS_MEMBER(WrapObject)
+
+// HasWrapObject<T>::Value will be true if T has a WrapObject member but it's
+// not nsWrapperCache::WrapObject.
 template<typename T>
 struct HasWrapObject
 {
 private:
   typedef char yes[1];
   typedef char no[2];
-  typedef JSObject* (T::*WrapObject)(JSContext*, JSObject*, bool*);
+  typedef JSObject* (nsWrapperCache::*WrapObject)(JSContext*, JSObject*, bool*);
   template<typename U, U> struct SFINAE;
-  template <typename V> static yes& Check(SFINAE<WrapObject, &V::WrapObject>*);
-  template <typename V> static no& Check(...);
+  template <typename V> static no& Check(SFINAE<WrapObject, &V::WrapObject>*);
+  template <typename V> static yes& Check(...);
 
 public:
-  static bool const Value = sizeof(Check<T>(nullptr)) == sizeof(yes);
+  static bool const Value = HasWrapObjectMember<T>::Value &&
+                            sizeof(Check<T>(nullptr)) == sizeof(yes);
+};
+
+template<typename T>
+static inline JSObject*
+WrapNativeISupportsParent(JSContext* cx, JSObject* scope, T* p,
+                          nsWrapperCache* cache)
+{
+  qsObjectHelper helper(ToSupports(p), cache);
+  JS::Value v;
+  return XPCOMObjectToJsval(cx, scope, helper, nullptr, false, &v) ?
+         JSVAL_TO_OBJECT(v) :
+         nullptr;
+}
+
+template<typename T, bool isISupports=IsISupports<T>::Value >
+struct WrapNativeParentFallback
+{
+  static inline JSObject* Wrap(JSContext* cx, JSObject* scope, T* parent,
+                               nsWrapperCache* cache)
+  {
+    MOZ_NOT_REACHED("Don't know how to deal with triedToWrap == false for "
+                    "non-nsISupports classes");
+    return nullptr;
+  }
+};
+
+template<typename T >
+struct WrapNativeParentFallback<T, true >
+{
+  static inline JSObject* Wrap(JSContext* cx, JSObject* scope, T* parent,
+                               nsWrapperCache* cache)
+  {
+    return WrapNativeISupportsParent(cx, scope, parent, cache);
+  }
 };
 
 template<typename T, bool hasWrapObject=HasWrapObject<T>::Value >
 struct WrapNativeParentHelper
 {
   static inline JSObject* Wrap(JSContext* cx, JSObject* scope, T* parent,
                                nsWrapperCache* cache)
   {
     MOZ_ASSERT(cache);
 
     JSObject* obj;
     if ((obj = cache->GetWrapper())) {
       return obj;
     }
 
     bool triedToWrap;
-    return parent->WrapObject(cx, scope, &triedToWrap);
+    obj = parent->WrapObject(cx, scope, &triedToWrap);
+    if (!triedToWrap) {
+      obj = WrapNativeParentFallback<T>::Wrap(cx, scope, parent, cache);
+    }
+    return obj;
   }
 };
 
 template<typename T>
-struct WrapNativeParentHelper<T, false>
+struct WrapNativeParentHelper<T, false >
 {
   static inline JSObject* Wrap(JSContext* cx, JSObject* scope, T* parent,
                                nsWrapperCache* cache)
   {
     JSObject* obj;
     if (cache && (obj = cache->GetWrapper())) {
 #ifdef DEBUG
-      qsObjectHelper helper(ToSupports(parent), cache);
-      JS::Value debugVal;
-
-      bool ok = XPCOMObjectToJsval(cx, scope, helper, NULL, false, &debugVal);
-      NS_ASSERTION(ok && JSVAL_TO_OBJECT(debugVal) == obj,
+      NS_ASSERTION(WrapNativeISupportsParent(cx, scope, parent, cache) == obj,
                    "Unexpected object in nsWrapperCache");
 #endif
       return obj;
     }
 
-    qsObjectHelper helper(ToSupports(parent), cache);
-    JS::Value v;
-    return XPCOMObjectToJsval(cx, scope, helper, NULL, false, &v) ?
-           JSVAL_TO_OBJECT(v) :
-           NULL;
+    return WrapNativeISupportsParent(cx, scope, parent, cache);
   }
 };
 
 template<typename T>
 static inline JSObject*
 WrapNativeParent(JSContext* cx, JSObject* scope, T* p, nsWrapperCache* cache)
 {
   if (!p) {
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -643,20 +643,23 @@ addExternalIface('DOMStringList', native
 addExternalIface('Element', nativeType='nsGenericElement')
 addExternalIface('File')
 addExternalIface('HitRegionOptions', nativeType='nsISupports')
 addExternalIface('HTMLElement')
 addExternalIface('ImageData', nativeType='mozilla::dom::ImageData')
 addExternalIface('MediaStream')
 addExternalIface('Node', nativeType='nsINode')
 addExternalIface('PaintRequest')
+addExternalIface('Principal', nativeType='nsIPrincipal',
+                 headerFile='nsIPrincipal.h')
 addExternalIface('SVGLength')
 addExternalIface('SVGMatrix')
 addExternalIface('SVGNumber')
 addExternalIface('SVGPathSeg')
 addExternalIface('SVGPoint')
 addExternalIface('SVGTransform')
 addExternalIface('TextMetrics', headerFile='nsIDOMCanvasRenderingContext2D.h')
 addExternalIface('Touch', headerFile='nsIDOMTouchEvent.h')
+addExternalIface('URI', nativeType='nsIURI', headerFile='nsIURI.h')
 addExternalIface('WebGLContextAttributes', nativeType='JSObject',
                  headerFile='jsapi.h')
 addExternalIface('Window')
 addExternalIface('XULElement')
--- a/dom/interfaces/core/nsIDOMElement.idl
+++ b/dom/interfaces/core/nsIDOMElement.idl
@@ -8,17 +8,17 @@
 /**
  * The nsIDOMElement interface represents an element in an HTML or 
  * XML document. 
  *
  * For more information on this interface please see 
  * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-element
  */
 
-[scriptable, uuid(69D44CE2-B544-49A8-BB5F-87804B971EE4)]
+[scriptable, uuid(f1465e67-577f-4546-a7a3-bb1293c0dd15)]
 interface nsIDOMElement : nsIDOMNode
 {
   readonly attribute DOMString        tagName;
 
   /**
    * Returns a DOMTokenList object reflecting the class attribute.
    */
   readonly attribute nsIDOMDOMTokenList classList;
@@ -42,24 +42,24 @@ interface nsIDOMElement : nsIDOMNode
   nsIDOMAttr         getAttributeNode(in DOMString name);
   nsIDOMAttr         setAttributeNode(in nsIDOMAttr newAttr);
   nsIDOMAttr         removeAttributeNode(in nsIDOMAttr oldAttr);
   nsIDOMAttr         getAttributeNodeNS(in DOMString namespaceURI, 
                                         in DOMString localName);
   nsIDOMAttr         setAttributeNodeNS(in nsIDOMAttr newAttr)
                                         raises(DOMException);
 
-  nsIDOMNodeList     getElementsByTagName(in DOMString name);
-  nsIDOMNodeList     getElementsByTagNameNS(in DOMString namespaceURI, 
-                                            in DOMString localName);
+  nsIDOMHTMLCollection getElementsByTagName(in DOMString name);
+  nsIDOMHTMLCollection getElementsByTagNameNS(in DOMString namespaceURI, 
+                                              in DOMString localName);
   /**
    * Retrieve elements matching all classes listed in a
    * space-separated string.
    */
-  nsIDOMNodeList getElementsByClassName(in DOMString classes);
+  nsIDOMHTMLCollection getElementsByClassName(in DOMString classes);
 
   /**
    * Returns a live nsIDOMNodeList of the current child elements.
    */
   [binaryname(ChildElements)]
   readonly attribute nsIDOMNodeList children;
   /**
    * Similar as the attributes on nsIDOMNode, but navigates just elements
--- a/dom/locales/en-US/chrome/dom/dom.properties
+++ b/dom/locales/en-US/chrome/dom/dom.properties
@@ -52,37 +52,17 @@ GetAttributeNodeWarning=Use of getAttrib
 SetAttributeNodeWarning=Use of setAttributeNode() is deprecated. Use setAttribute() instead.
 GetAttributeNodeNSWarning=Use of getAttributeNodeNS() is deprecated. Use getAttributeNS() instead.
 SetAttributeNodeNSWarning=Use of setAttributeNodeNS() is deprecated. Use setAttributeNS() instead.
 RemoveAttributeNodeWarning=Use of removeAttributeNode() is deprecated. Use removeAttribute() instead.
 CreateAttributeWarning=Use of document.createAttribute() is deprecated. Use element.setAttribute() instead.
 CreateAttributeNSWarning=Use of document.createAttributeNS() is deprecated. Use element.setAttributeNS() instead.
 SpecifiedWarning=Use of attributes' specified attribute is deprecated. It always returns true.
 OwnerElementWarning=Use of attributes' ownerElement attribute is deprecated.
-NodeNameWarning=Use of attributes' nodeName attribute is deprecated. Use name instead.
 NodeValueWarning=Use of attributes' nodeValue attribute is deprecated. Use value instead.
-NodeTypeWarning=Use of attributes' nodeType attribute is deprecated. It always returns 2.
-ParentNodeWarning=Use of attributes' parentNode attribute is deprecated. It always returns null.
-ChildNodesWarning=Use of attributes' childNodes attribute is deprecated. It always returns null.
-HasChildNodesWarning=Use of attributes' hasChildNodes() is deprecated. It always returns false.
-HasAttributesWarning=Use of attributes' hasAttributes() is deprecated. It always returns false.
-FirstChildWarning=Use of attributes' firstChild attribute is deprecated. Use value instead.
-LastChildWarning=Use of attributes' lastChild attribute is deprecated. Use value instead.
-PreviousSiblingWarning=Use of attributes' previousSibling attribute is deprecated. It always returns null.
-NextSiblingWarning=Use of attributes' nextSibling attribute is deprecated. It always returns null.
-AttributesWarning=Use of attributes' attributes attribute is deprecated. It always returns null.
-InsertBeforeWarning=Use of attributes' insertBefore() is deprecated. Use value instead.
-ReplaceChildWarning=Use of attributes' replaceChild() is deprecated. Use value instead.
-RemoveChildWarning=Use of attributes' removeChild() is deprecated. Use value instead.
-AppendChildWarning=Use of attributes' appendChild() is deprecated. Use value instead.
-CloneNodeWarning=Use of attributes' cloneNode() is deprecated.
-OwnerDocumentWarning=Use of attributes' ownerDocument attribute is deprecated.
-NormalizeWarning=Use of attributes' normalize() is deprecated.
-IsSupportedWarning=Use of attributes' isSupported() is deprecated.
-IsEqualNodeWarning=Use of attributes' isEqualNode() is deprecated.
 TextContentWarning=Use of attributes' textContent attribute is deprecated. Use value instead.
 EnablePrivilegeWarning=Use of enablePrivilege is deprecated.  Please use code that runs with the system principal (e.g. an extension) instead.
 PositionWarning=Use of XMLHttpRequest's progress events' position attribute is deprecated.
 TotalSizeWarning=Use of XMLHttpRequest's progress events' totalSize attribute is deprecated.
 nsIJSONDecodeDeprecatedWarning=nsIJSON.decode is deprecated.  Please use JSON.parse instead.
 nsIJSONEncodeDeprecatedWarning=nsIJSON.encode is deprecated.  Please use JSON.stringify instead.
 nsIDOMWindowInternalWarning=Use of nsIDOMWindowInternal is deprecated. Use nsIDOMWindow instead.
 InputEncodingWarning=Use of inputEncoding is deprecated.
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -670,16 +670,18 @@ MediaManager::GetUserMedia(bool aPrivile
   nsIMediaStreamOptions* aParams,
   nsIDOMGetUserMediaSuccessCallback* aOnSuccess,
   nsIDOMGetUserMediaErrorCallback* aOnError)
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
   NS_ENSURE_TRUE(aParams, NS_ERROR_NULL_POINTER);
   NS_ENSURE_TRUE(aWindow, NS_ERROR_NULL_POINTER);
+  NS_ENSURE_TRUE(aOnError, NS_ERROR_NULL_POINTER);
+  NS_ENSURE_TRUE(aOnSuccess, NS_ERROR_NULL_POINTER);
 
   nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> onSuccess(aOnSuccess);
   nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onError(aOnError);
 
   /* Get options */
   nsresult rv;
   bool fake, audio, video, picture;
 
@@ -859,16 +861,19 @@ MediaManager::GetUserMedia(bool aPrivile
 
 nsresult
 MediaManager::GetUserMediaDevices(nsPIDOMWindow* aWindow,
   nsIGetUserMediaDevicesSuccessCallback* aOnSuccess,
   nsIDOMGetUserMediaErrorCallback* aOnError)
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
+  NS_ENSURE_TRUE(aOnError, NS_ERROR_NULL_POINTER);
+  NS_ENSURE_TRUE(aOnSuccess, NS_ERROR_NULL_POINTER);
+
   nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback> onSuccess(aOnSuccess);
   nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onError(aOnError);
 
   nsCOMPtr<nsIRunnable> gUMDRunnable = new GetUserMediaDevicesRunnable(
     onSuccess.forget(), onError.forget()
   );
 
   nsCOMPtr<nsIThread> deviceThread;
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/crashtests/780790.html
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=780790
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Simple gUM test - null success callback</title>
+  <script type="application/javascript">
+    navigator.mozGetUserMedia({video: true, fake: true}, null, null);
+  </script>
+</head>
+
+<body>
+</body>
+</html>
--- a/dom/media/tests/crashtests/crashtests.list
+++ b/dom/media/tests/crashtests/crashtests.list
@@ -1,2 +1,3 @@
+pref(media.peerconnection.enabled,true) load 780790.html
 pref(media.peerconnection.enabled,true) load 791270.html
 pref(media.peerconnection.enabled,true) load 791278.html
--- a/dom/network/src/MobileConnection.cpp
+++ b/dom/network/src/MobileConnection.cpp
@@ -54,16 +54,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MobileConnection,
                                                 nsDOMEventTargetHelper)
   tmp->mProvider = nullptr;
   tmp->mIccManager = nullptr;
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MobileConnection)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozMobileConnection)
+  NS_INTERFACE_MAP_ENTRY(nsIObserver)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozMobileConnection)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozMobileConnection)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(MobileConnection, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(MobileConnection, nsDOMEventTargetHelper)
 
 NS_IMPL_EVENT_HANDLER(MobileConnection, cardstatechange)
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -52,16 +52,17 @@ using mozilla::DefaultXDisplay;
 #include "nsIDOMHTMLAppletElement.h"
 #include "nsAttrName.h"
 #include "nsIFocusManager.h"
 #include "nsFocusManager.h"
 #include "nsIDOMDragEvent.h"
 #include "nsIScrollableFrame.h"
 #include "nsIDocShell.h"
 #include "ImageContainer.h"
+#include "nsIDOMHTMLCollection.h"
 
 #include "nsContentCID.h"
 #include "nsWidgetsCID.h"
 static NS_DEFINE_CID(kWidgetCID, NS_CHILD_CID);
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 #ifdef XP_WIN
 #include <wtypes.h>
@@ -1137,17 +1138,17 @@ nsresult nsPluginInstanceOwner::EnsureCa
 
   // Get all dependent PARAM tags, even if they are not direct children.
   nsCOMPtr<nsIDOMElement> mydomElement = do_QueryInterface(mContent);
   NS_ENSURE_TRUE(mydomElement, NS_ERROR_NO_INTERFACE);
 
   // Making DOM method calls can cause our frame to go away.
   nsCOMPtr<nsIPluginInstanceOwner> kungFuDeathGrip(this);
 
-  nsCOMPtr<nsIDOMNodeList> allParams;
+  nsCOMPtr<nsIDOMHTMLCollection> allParams;
   NS_NAMED_LITERAL_STRING(xhtml_ns, "http://www.w3.org/1999/xhtml");
   mydomElement->GetElementsByTagNameNS(xhtml_ns, NS_LITERAL_STRING("param"),
                                        getter_AddRefs(allParams));
   if (allParams) {
     uint32_t numAllParams; 
     allParams->GetLength(&numAllParams);
     for (uint32_t i = 0; i < numAllParams; i++) {
       nsCOMPtr<nsIDOMNode> pnode;
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -2323,16 +2323,38 @@ let RIL = {
     let mmi = this._parseMMI(mmiString);
 
     let _sendMMIError = (function _sendMMIError(errorMsg) {
       options.rilMessageType = "sendMMI";
       options.errorMsg = errorMsg;
       this.sendDOMMessage(options);
     }).bind(this);
 
+    function _isValidPINPUKRequest() {
+      // The only allowed MMI procedure for ICC PIN, PIN2, PUK and PUK2 handling
+      // is "Registration" (**).
+      if (!mmi.procedure || mmi.procedure != MMI_PROCEDURE_REGISTRATION ) {
+        _sendMMIError("WRONG_MMI_PROCEDURE");
+        return;
+      }
+
+      if (!mmi.sia || !mmi.sia.length || !mmi.sib || !mmi.sib.length ||
+          !mmi.sic || !mmi.sic.length) {
+        _sendMMIError("MISSING_SUPPLEMENTARY_INFORMATION");
+        return;
+      }
+
+      if (mmi.sib != mmi.sic) {
+        _sendMMIError("NEW_PIN_MISMATCH");
+        return;
+      }
+
+      return true;
+    }
+
     if (mmi == null) {
       if (this._ussdSession) {
         options.ussd = mmiString;
         this.sendUSSD(options);
         return;
       }
       _sendMMIError("NO_VALID_MMI_STRING");
       return;
@@ -2353,23 +2375,78 @@ let RIL = {
       case MMI_SC_CF_NO_REPLY:
       case MMI_SC_CF_NOT_REACHABLE:
       case MMI_SC_CF_ALL:
       case MMI_SC_CF_ALL_CONDITIONAL:
         // TODO: Bug 793192 - MMI Codes: support call forwarding.
         _sendMMIError("CALL_FORWARDING_NOT_SUPPORTED_VIA_MMI");
         return;
 
-      // PIN/PIN2/PUK/PUK2
+      // Change the current ICC PIN number.
       case MMI_SC_PIN:
+        // As defined in TS.122.030 6.6.2 to change the ICC PIN we should expect
+        // an MMI code of the form **04*OLD_PIN*NEW_PIN*NEW_PIN#, where old PIN
+        // should be entered as the SIA parameter and the new PIN as SIB and
+        // SIC.
+        if (!_isValidPINPUKRequest()) {
+          return;
+        }
+
+        options.rilRequestType = "sendMMI";
+        options.pin = mmi.sia;
+        options.newPin = mmi.sib;
+        this.changeICCPIN(options);
+        return;
+
+      // Change the current ICC PIN2 number.
       case MMI_SC_PIN2:
+        // As defined in TS.122.030 6.6.2 to change the ICC PIN2 we should
+        // enter and MMI code of the form **042*OLD_PIN2*NEW_PIN2*NEW_PIN2#,
+        // where the old PIN2 should be entered as the SIA parameter and the
+        // new PIN2 as SIB and SIC.
+        if (!_isValidPINPUKRequest()) {
+          return;
+        }
+
+        options.rilRequestType = "sendMMI";
+        options.pin = mmi.sia;
+        options.newPin = mmi.sib;
+        this.changeICCPIN2(options);
+        return;
+
+      // Unblock ICC PIN.
       case MMI_SC_PUK:
+        // As defined in TS.122.030 6.6.3 to unblock the ICC PIN we should
+        // enter an MMI code of the form **05*PUK*NEW_PIN*NEW_PIN#, where PUK
+        // should be entered as the SIA parameter and the new PIN as SIB and
+        // SIC.
+        if (!_isValidPINPUKRequest()) {
+          return;
+        }
+
+        options.rilRequestType = "sendMMI";
+        options.puk = mmi.sia;
+        options.newPin = mmi.sib;
+        this.enterICCPUK(options);
+        return;
+
+      // Unblock ICC PIN2.
       case MMI_SC_PUK2:
-        // TODO: Bug 793187 - MMI Codes: Support PIN/PIN2/PUK handling.
-        _sendMMIError("SIM_FUNCTION_NOT_SUPPORTED_VIA_MMI");
+        // As defined in TS.122.030 6.6.3 to unblock the ICC PIN2 we should
+        // enter an MMI code of the form **052*PUK2*NEW_PIN2*NEW_PIN2#, where
+        // PUK2 should be entered as the SIA parameter and the new PIN2 as SIB
+        // and SIC.
+        if (!_isValidPINPUKRequest()) {
+          return;
+        }
+
+        options.rilRequestType = "sendMMI";
+        options.puk = mmi.sia;
+        options.newPin = mmi.sib;
+        this.enterICCPUK2(options);
         return;
 
       // IMEI
       case MMI_SC_IMEI:
         // A device's IMEI can't change, so we only need to request it once.
         if (this.IMEI == null) {
           this.getIMEI({mmi: true});
           return;
--- a/dom/system/gonk/tests/test_ril_worker_mmi.js
+++ b/dom/system/gonk/tests/test_ril_worker_mmi.js
@@ -311,19 +311,204 @@ add_test(function test_sendMMI_dial_stri
 
 add_test(function test_sendMMI_call_forwarding() {
   // TODO: Bug 793192 - MMI Codes: support call forwarding
   testSendMMI("*21#", "CALL_FORWARDING_NOT_SUPPORTED_VIA_MMI");
 
   run_next_test();
 });
 
-add_test(function test_sendMMI_sim_function() {
-  // TODO: Bug 793187 - MMI Codes: Support PIN/PIN2/PUK handling via MMI codes
-  testSendMMI("*04#", "SIM_FUNCTION_NOT_SUPPORTED_VIA_MMI");
+add_test(function test_sendMMI_change_PIN() {
+  let postedMessage;
+  let worker = newWorker({
+    postRILMessage: function fakePostRILMessage(data) {
+    },
+    postMessage: function fakePostMessage(message) {
+      postedMessage = message;
+    },
+  });
+
+  worker.RIL.changeICCPIN = function fakeChangeICCPIN(options){
+    worker.RIL[REQUEST_ENTER_SIM_PIN](0, {
+      rilRequestError: ERROR_SUCCESS
+    });
+  }
+
+  worker.RIL.sendMMI({mmi: "**04*1234*4567*4567#"});
+
+  do_check_eq (postedMessage.errorMsg, GECKO_ERROR_SUCCESS);
+  do_check_true(postedMessage.success);
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_change_PIN_no_new_PIN() {
+  testSendMMI("**04*1234**4567#", "MISSING_SUPPLEMENTARY_INFORMATION");
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_change_PIN_no_old_PIN() {
+  testSendMMI("**04**1234*4567#", "MISSING_SUPPLEMENTARY_INFORMATION");
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_change_PIN_wrong_procedure() {
+  testSendMMI("*04*1234*4567*4567#", "WRONG_MMI_PROCEDURE");
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_change_PIN_new_PIN_mismatch() {
+  testSendMMI("**04*4567*1234*4567#", "NEW_PIN_MISMATCH");
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_change_PIN2() {
+  let postedMessage;
+  let worker = newWorker({
+    postRILMessage: function fakePostRILMessage(data) {
+    },
+    postMessage: function fakePostMessage(message) {
+      postedMessage = message;
+    },
+  });
+
+  worker.RIL.changeICCPIN2 = function fakeChangeICCPIN2(options){
+    worker.RIL[REQUEST_ENTER_SIM_PIN2](0, {
+      rilRequestError: ERROR_SUCCESS
+    });
+  }
+
+  worker.RIL.sendMMI({mmi: "**042*1234*4567*4567#"});
+
+  do_check_eq (postedMessage.errorMsg, GECKO_ERROR_SUCCESS);
+  do_check_true(postedMessage.success);
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_change_PIN2_no_new_PIN2() {
+  testSendMMI("**042*1234**4567#", "MISSING_SUPPLEMENTARY_INFORMATION");
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_change_PIN2_no_old_PIN2() {
+  testSendMMI("**042**1234*4567#", "MISSING_SUPPLEMENTARY_INFORMATION");
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_change_PIN2_wrong_procedure() {
+  testSendMMI("*042*1234*4567*4567#", "WRONG_MMI_PROCEDURE");
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_change_PIN2_new_PIN2_mismatch() {
+  testSendMMI("**042*4567*1234*4567#", "NEW_PIN_MISMATCH");
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_unblock_PIN() {
+  let postedMessage;
+  let worker = newWorker({
+    postRILMessage: function fakePostRILMessage(data) {
+    },
+    postMessage: function fakePostMessage(message) {
+      postedMessage = message;
+    },
+  });
+
+  worker.RIL.enterICCPUK = function fakeEnterICCPUK(options){
+    worker.RIL[REQUEST_ENTER_SIM_PUK](0, {
+      rilRequestError: ERROR_SUCCESS
+    });
+  }
+
+  worker.RIL.sendMMI({mmi: "**05*1234*4567*4567#"});
+
+  do_check_eq (postedMessage.errorMsg, GECKO_ERROR_SUCCESS);
+  do_check_true(postedMessage.success);
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_unblock_PIN_no_new_PIN() {
+  testSendMMI("**05*1234**4567#", "MISSING_SUPPLEMENTARY_INFORMATION");
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_unblock_PIN_no_PUK() {
+  testSendMMI("**05**1234*4567#", "MISSING_SUPPLEMENTARY_INFORMATION");
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_unblock_PIN_wrong_procedure() {
+  testSendMMI("*05*1234*4567*4567#", "WRONG_MMI_PROCEDURE");
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_unblock_PIN_new_PIN_mismatch() {
+  testSendMMI("**05*4567*1234*4567#", "NEW_PIN_MISMATCH");
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_unblock_PIN2() {
+  let postedMessage;
+  let worker = newWorker({
+    postRILMessage: function fakePostRILMessage(data) {
+    },
+    postMessage: function fakePostMessage(message) {
+      postedMessage = message;
+    },
+  });
+
+  worker.RIL.enterICCPUK2 = function fakeEnterICCPUK2(options){
+    worker.RIL[REQUEST_ENTER_SIM_PUK2](0, {
+      rilRequestError: ERROR_SUCCESS
+    });
+  }
+
+  worker.RIL.sendMMI({mmi: "**052*1234*4567*4567#"});
+
+  do_check_eq (postedMessage.errorMsg, GECKO_ERROR_SUCCESS);
+  do_check_true(postedMessage.success);
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_unblock_PIN2_no_new_PIN2() {
+  testSendMMI("**052*1234**4567#", "MISSING_SUPPLEMENTARY_INFORMATION");
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_unblock_PIN2_no_PUK2() {
+  testSendMMI("**052**1234*4567#", "MISSING_SUPPLEMENTARY_INFORMATION");
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_unblock_PIN2_wrong_procedure() {
+  testSendMMI("*052*1234*4567*4567#", "WRONG_MMI_PROCEDURE");
+
+  run_next_test();
+});
+
+add_test(function test_sendMMI_unblock_PIN2_new_PIN_mismatch() {
+  testSendMMI("**052*4567*1234*4567#", "NEW_PIN_MISMATCH");
 
   run_next_test();
 });
 
 add_test(function test_sendMMI_get_IMEI() {
   let postedMessage;
   let mmiOptions;
   let worker = newWorker({
--- a/dom/webidl/EventHandler.webidl
+++ b/dom/webidl/EventHandler.webidl
@@ -1,15 +1,19 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.